diff --git a/README.md b/README.md index c723d29..c165c2d 100644 --- a/README.md +++ b/README.md @@ -205,10 +205,9 @@ De tool genereert verschillende output-bestanden: - `Template_PVtool5_0.xlsx` - Gevalideerde dataset met analysekolommen - `Validation_log_##_critical_errors.xlsx` - Kritieke fouten - `Validation_log_##_warnings.xlsx` - Waarschuwingen - - `c_phi_data_geforceerd.xlsx` - Tussenresultaten C-phi analyse - **PDF-bestanden:** - - `c_phi_pdf_export_[verzameling]_[type]_[rek].pdf` - Grafische rapportage + - `[type_analyse]_export_[verzameling]_[type]_[rek].pdf` - Grafische rapportage - **HTML-bestanden:** - Interactieve Plotly visualisaties van spanningspaden diff --git a/main_nathan.py b/main_nathan.py index fb98850..7c653c3 100644 --- a/main_nathan.py +++ b/main_nathan.py @@ -63,7 +63,7 @@ def database_import_test(source: Literal['Stowa', 'PV-tool', 'Dbase'], file_name_import: str, file_name_export: str = 'Template_PVtool5_0.xlsx', short=False, validate=False, export=False): """Test de database import en validatie functionaliteit.""" repo_root = Path(get_repo_root()) - path_to_data = repo_root / "import_files" / file_name_import + path_to_data = repo_root / "test_files" / file_name_import save_test = Path(r"c:\Users\gebraadn0645\ARCADIS\103076457 - STOWA PV Tool - 05 Project execution\Deliverables\2. validatie\Test output") # Check if input file exists @@ -280,6 +280,8 @@ def shansep_analysis_test(dbase: Dbase, export_path: Path, export_file: str, plo # Pas instellingen toe analyse.apply_settings(alpha=0.75) + # eerst moeten de korte resultaten geplot worden en daarna de eerste plots. Dan daarna handmatige parameters + # Print en exporteer resultaten print('\nResultaten SHANSEP analyse:') analyse.add_results_to_template(path=str(export_path), export_name=export_file) @@ -370,8 +372,8 @@ def sutabel_analysis_test(dbase: Dbase, export_path: Path, export_file: str, plo # Test verschillende analyses print("\nUitvoeren van verschillende test cases...") - print("\nTXT C-phi analyse test") - cphi_analysis_txt_test(dbase, export_dir, export_name, plot_extra_dataset=plot_extra_dataset, plot_spanningspaden=plot_spanningspaden) + # print("\nTXT C-phi analyse test") + # cphi_analysis_txt_test(dbase, export_dir, export_name, plot_extra_dataset=plot_extra_dataset, plot_spanningspaden=plot_spanningspaden) # print("\nDSS C-phi analyse test") # cphi_analysis_dss_test(dbase, export_dir, export_name, plot_extra_dataset=plot_extra_dataset, plot_spanningspaden=plot_spanningspaden) @@ -384,8 +386,8 @@ def sutabel_analysis_test(dbase: Dbase, export_path: Path, export_file: str, plo # # plot_extra_dataset = ['TXT_SAFE_klei_zwaar'] # - # print("\nTXT SHANSEP analyse test") - # shansep_analysis_test(dbase, export_dir, export_name, plot_extra_dataset=plot_extra_dataset) + print("\nTXT SHANSEP analyse test") + shansep_analysis_test(dbase, export_dir, export_name, plot_extra_dataset=plot_extra_dataset) # # print("\nSUTABEL analyse test") # sutabel_analysis_test(dbase, export_dir, export_name, plot_extra_dataset=plot_extra_dataset) diff --git a/pv_tool/cphi_analysis/c_phi_analysis.py b/pv_tool/cphi_analysis/c_phi_analysis.py index 8c13564..3a36890 100644 --- a/pv_tool/cphi_analysis/c_phi_analysis.py +++ b/pv_tool/cphi_analysis/c_phi_analysis.py @@ -604,111 +604,92 @@ def get_short_results(self): # ========== Export Methodes ========== - def add_results_to_dbase(self, path, file_name: str = 'Template_PVtool5_0.xlsx'): + def add_results_to_template(self, path, export_name=None): """ - Voegt analyseresultaten toe aan de database export. - - Voegt de resultaten toe aan een tabblad 'Resultaten c-phi' in de Template_PVtool5_0.xlsx. - Als het tabblad al bestaat wordt het aangevuld, anders wordt het aangemaakt. - - Parameters - ---------- - path : str - Map locatie waar het Excel-bestand staat of moet komen - file_name : str, optioneel - Naam van het Excel-bestand (standaard 'Template_PVtool5_0.xlsx') - - Returns - ------- - DataFrame - DataFrame met alle resultaten in het tabblad + Voegt een nieuwe resultatenrij toe aan tabblad 'Resultaten c-phi' in het Excel-template. + Als het tabblad niet bestaat, wordt het aangemaakt en worden de kolomnamen weggeschreven. """ - file_path = f"{path}/{file_name}" - - if self.analysis_type in ['TXT_SH', 'DSS_SH']: - self._run_sh() - else: - self._run() - - try: - with open(file_path, 'r'): - pass - except FileNotFoundError: - raise FileNotFoundError(f"Er is geen dbase aanwezig onder de naam {file_name}") + if export_name is None: + export_name = "Template_PVtool5_0.xlsx" + file_path = Path(path) / export_name + sheet_name = 'Resultaten c-phi' expected_columns = [ - 'PV_RESULTAAT_ID', 'PVNAAM', 'PV_REK', 'PV_TYPE_PROEF', 'PV_ANALYSE', - 'PV_A1_COH_GEM [kPa]', 'PV_A2_TAN_PHI_GEM [-]', 'PV_A1_COH_KAR [kPa]', 'PV_A2_TAN_PHI_KAR [-]', - 'PV_PARTPHI [-]', 'PV_PARTCOH [-]', 'PV_TYPEVERZAMELING', 'PV_COH_GEM [kPa]', 'PV_PHI_GEM [graden]', - 'PV_COH_KAR [kPa]', 'PV_PHI_KAR [graden]', 'PV_COH_SD_DSTAB [-]', 'PV_PHI_SD_DSTAB [-]', - 'PV_VGWNAT_GEM [kN/m3]', 'PV_VGWNAT_SD [kN/m3]', 'PV_WATERGEHALTE_GEM', 'PV_WATERGEHALTE_SD', 'Timestamp' + 'PV_RESULTAAT_ID', 'PV_NAAM', 'PV_REK', 'PV_TYPE_PROEF', 'PV_ANALYSE', + 'PV_A1_COH_GEM', 'PV_A2_TAN_PHI_GEM', 'PV_A1_COH_KAR', 'PV_A2_TAN_PHI_KAR', + 'PV_PARTPHI', 'PV_PARTCOH', 'PV_TYPEVERZAMELING', 'PV_COH_GEM', 'PV_PHI_GEM', + 'PV_COH_KAR', 'PV_PHI_KAR', 'PV_COH_SD_DSTAB', 'PV_PHI_SD_DSTAB', + 'PV_VGWNAT_GEM', 'PV_VGWNAT_SD', 'PV_WATERGEHALTE_GEM', 'PV_WATERGEHALTE_SD', 'Timestamp' ] + # Maak de resultaat-rij aan new_row = { - 'PVNAAM': self.investigation_groups[0], + 'PV_NAAM': self.investigation_groups[0], 'PV_REK': self.effective_stress, 'PV_TYPE_PROEF': self.analysis_type.split('_')[0], 'PV_ANALYSE': self.analysis_type.split('_')[1], - 'PV_RESULTAAT_ID': f"{self.investigation_groups[0]}_{self.effective_stress}_{self.analysis_type.split('_')[0]}_{self.analysis_type.split('_')[1]}", + 'PV_RESULTAAT_ID': f"{self.investigation_groups[0]}_{self.effective_stress}_" + f"{self.analysis_type.split('_')[0]}_{self.analysis_type.split('_')[1]}", 'PV_TYPEVERZAMELING': self.alpha, - 'PV_A1_COH_GEM [kPa]': round(self.gem_a1, 3) if self.gem_a1 is not None else None, - 'PV_A2_TAN_PHI_GEM [-]': round(self.gem_a2, 3) if self.gem_a2 is not None else None, - 'PV_A1_COH_KAR [kPa]': round(self.kar_a1, 3) if self.kar_a1 is not None else None, - 'PV_A2_TAN_PHI_KAR [-]': round(self.kar_a2, 3) if self.kar_a2 is not None else None, - 'PV_COH_GEM [kPa]': (round(self.c_gem, 3) if self.c_gem is not None and self.c_gem >= 0 - else "[-]" if self.c_gem is None - else f"{round(self.c_gem, 3)} (kan niet - aanpassen!)" - ), - 'PV_PHI_GEM [graden]': round(self.phi_gem, 3) if self.phi_gem is not None else None, - 'PV_COH_KAR [kPa]': (round(self.c_kar, 3) if self.c_kar is not None and self.c_kar >= 0 - else "[-]" if self.c_kar is None - else f"{round(self.c_kar, 3)} (kan niet - aanpassen!)" - ), - 'PV_PHI_KAR [graden]': round(self.phi_kar, 3) if self.phi_kar is not None else None, - 'PV_COH_SD_DSTAB [-]': (round(self.st_dev_c, 3) if self.c_gem is not None and self.c_kar is not None - and self.c_gem >= 0 and self.c_kar >= 0 - else "[-]" if self.c_gem is None or self.c_kar is None - else "[-] (c < 0)"), - 'PV_PHI_SD_DSTAB [-]': round(self.st_dev_phi, 3) if self.st_dev_phi is not None else None, - 'PV_PARTPHI [-]': self.material_tan_phi, - 'PV_PARTCOH [-]': self.material_cohesie, - 'PV_VGWNAT_GEM [kN/m3]': round(self.calc_vgwnat_gem, 3) if self.calc_vgwnat_gem is not None else None, - 'PV_VGWNAT_SD [kN/m3]': round(self.calc_vgwnat_sd, 3) if self.calc_vgwnat_sd is not None else None, - 'PV_WATERGEHALTE_GEM': round(self.calc_watergehalte_gem, 3) if self.calc_watergehalte_gem is not None else None, - 'PV_WATERGEHALTE_SD': round(self.calc_watergehalte_sd, 3) if self.calc_watergehalte_sd is not None else None, + 'PV_A1_COH_GEM': round(self.gem_a1, 3) if self.gem_a1 is not None else None, + 'PV_A2_TAN_PHI_GEM': round(self.gem_a2, 3) if self.gem_a2 is not None else None, + 'PV_A1_COH_KAR': round(self.kar_a1, 3) if self.kar_a1 is not None else None, + 'PV_A2_TAN_PHI_KAR': round(self.kar_a2, 3) if self.kar_a2 is not None else None, + + 'PV_COH_GEM': ( + round(self.c_gem, 3) if self.c_gem is not None and self.c_gem >= 0 + else "[-]" if self.c_gem is None + else f"{round(self.c_gem, 3)} (kan niet - aanpassen!)" + ), + 'PV_PHI_GEM': round(self.phi_gem, 3) if self.phi_gem is not None else None, + + 'PV_COH_KAR': ( + round(self.c_kar, 3) if self.c_kar is not None and self.c_kar >= 0 + else "[-]" if self.c_kar is None + else f"{round(self.c_kar, 3)} (kan niet - aanpassen!)" + ), + 'PV_PHI_KAR': round(self.phi_kar, 3) if self.phi_kar is not None else None, + + 'PV_COH_SD_DSTAB': ( + round(self.st_dev_c, 3) if ( + self.c_gem is not None and self.c_kar is not None and self.c_gem >= 0 and self.c_kar >= 0 + ) else "[-]" if self.c_gem is None or self.c_kar is None + else "[-] (c < 0)" + ), + 'PV_PHI_SD_DSTAB': round(self.st_dev_phi, 3) if self.st_dev_phi is not None else None, + + 'PV_PARTPHI': self.material_tan_phi, + 'PV_PARTCOH': self.material_cohesie, + 'PV_VGWNAT_GEM': round(self.calc_vgwnat_gem, 3) if self.calc_vgwnat_gem is not None else None, + 'PV_VGWNAT_SD': round(self.calc_vgwnat_sd, 3) if self.calc_vgwnat_sd is not None else None, + 'PV_WATERGEHALTE_GEM': round(self.calc_watergehalte_gem, + 3) if self.calc_watergehalte_gem is not None else None, + 'PV_WATERGEHALTE_SD': round(self.calc_watergehalte_sd, + 3) if self.calc_watergehalte_sd is not None else None, 'Timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S") } - workbook = load_workbook(file_path) + if file_path.exists(): + wb = load_workbook(file_path) + else: + template_path = Path(get_repo_root()) / "pv_tool" / "templates" / "Template_PVtool5_0.xlsx" + wb = load_workbook(template_path) - if 'Resultaten c-phi' in workbook.sheetnames: - print('Tabblad Resultaten c-phi in dbase excel bestaat al en wordt aangevuld') - df_existing = read_excel(file_path, sheet_name='Resultaten c-phi') - # Filter out empty rows and ensure consistent types before concatenation - df_existing = df_existing.dropna(how='all') - new_row_df = DataFrame([new_row], columns=df_existing.columns) - df_updated = concat([df_existing, new_row_df], ignore_index=True) + if sheet_name in wb.sheetnames: + ws = wb[sheet_name] + first_empty_row = ws.max_row + 1 if any( + ws.iter_rows(min_row=ws.max_row, max_row=ws.max_row, values_only=True)) else ws.max_row else: - print('Tabblad Resultaten c-phi in dbase excel bestaat nog niet en wordt aangemaakt') - df_updated = DataFrame([new_row], columns=expected_columns) - - # Write data to Excel - with ExcelWriter(file_path, engine='openpyxl', mode='a', if_sheet_exists='replace') as writer: - df_updated.to_excel(writer, sheet_name='Resultaten c-phi', index=False) - - # Formatting - num_columns = df_updated.shape[1] - num_rows = df_updated.shape[0] - format_excel_sheet( - file_path=file_path, - sheet_name='Resultaten c-phi', - num_columns=num_columns, - num_rows=num_rows, - table_name='Resultaten_CPHI_Table', - index=False # Changed from True to False to match the to_excel call - ) - - return df_updated + ws = wb.create_sheet(sheet_name) + for col_idx, col_name in enumerate(expected_columns, start=1): + ws.cell(row=1, column=col_idx, value=col_name) + first_empty_row = 2 + + for col_idx, col_name in enumerate(expected_columns, start=1): + ws.cell(row=first_empty_row, column=col_idx, value=new_row.get(col_name, "")) + + wb.save(file_path) + print(f"Resultaat toegevoegd aan template in tabblad '{sheet_name}'.") @property def save_total_to_excel(self): diff --git a/pv_tool/cphi_analysis/save_and_export.py b/pv_tool/cphi_analysis/save_and_export.py index c2ddb34..e7cbbd5 100644 --- a/pv_tool/cphi_analysis/save_and_export.py +++ b/pv_tool/cphi_analysis/save_and_export.py @@ -308,5 +308,14 @@ def save_to_pdf(self: "CPhiAnalyse", path: str) -> str: # Bouw de PDF doc.build(story) + # Ruim tijdelijke plot bestanden op + import os + try: + if os.path.exists(fig_path): + os.remove(fig_path) + print(f"Tijdelijk plot bestand verwijderd: {fig_path}") + except Exception as e: + print(f"Waarschuwing: Kon tijdelijk plot bestand niet verwijderen {fig_path}: {e}") + print(f"PDF succesvol opgeslagen op: {file_path}") return file_path diff --git a/pv_tool/shansep_analysis/save_and_export.py b/pv_tool/shansep_analysis/save_and_export.py index d5ecc24..817d8c6 100644 --- a/pv_tool/shansep_analysis/save_and_export.py +++ b/pv_tool/shansep_analysis/save_and_export.py @@ -1006,4 +1006,15 @@ def save_to_pdf(self: "SHANSEP", path: str) -> str: doc.build(story) print(f"SHANSEP PDF export voltooid: {file_path}") + # Ruim tijdelijke plot bestanden op + import os + temp_files = [f"{path}/temp_plot1.png", f"{path}/temp_plot2.png", f"{path}/temp_plot3.png"] + for temp_file in temp_files: + try: + if os.path.exists(temp_file): + os.remove(temp_file) + print(f"Tijdelijk plot bestand verwijderd: {temp_file}") + except Exception as e: + print(f"Waarschuwing: Kon tijdelijk plot bestand niet verwijderen {temp_file}: {e}") + return file_path diff --git a/pv_tool/shansep_analysis/shansep_analysis.py b/pv_tool/shansep_analysis/shansep_analysis.py index 962ef19..74b2b32 100644 --- a/pv_tool/shansep_analysis/shansep_analysis.py +++ b/pv_tool/shansep_analysis/shansep_analysis.py @@ -741,6 +741,7 @@ def show_figure_sv_su(self, plot_extra_dataset: Optional[List] = None): self._run_shansep() self.figure = go.Figure() self.set_figure_sv_su(plot_extra_dataset) + self.figure.show() def show_figure_ln_ocr_ln_s(self, plot_extra_dataset: Optional[List] = None): """ diff --git a/pv_tool/shansep_analysis/test_shansep_analysis.py b/pv_tool/shansep_analysis/test_shansep_analysis.py index 5099f93..b7e097c 100644 --- a/pv_tool/shansep_analysis/test_shansep_analysis.py +++ b/pv_tool/shansep_analysis/test_shansep_analysis.py @@ -13,7 +13,6 @@ ) export_dir = Path(export_dir) - def test_shansep_analyse(): """ Test voor SHANSEP analyse. Voert een volledige SHANSEP analyse uit met verschillende analyse types. @@ -34,29 +33,39 @@ def test_shansep_analyse(): for analysis_type in analysis_types: # Test met een representatieve effective stress voor elk analysis type - effective_stress = '15% rek' # Deze werkt voor beide types + # effective_stress = '15% rek' # Deze werkt voor beide types + + if analysis_type == 'DSS_S_POP': + ig = ['DSS_SAFE_veen'] + es = '20% rek' + at = 'DSS_S_POP' + else: + ig = ['TXT_SAFE_klei_licht_16_175'] + es = '15% rek' + at = 'TXT_S_POP' analyse = SHANSEP( dbase=dbase, - investigation_groups=['TXT_SAFE_klei_licht_16_175'], - effective_stress=effective_stress, - analysis_type=analysis_type + investigation_groups=ig, + effective_stress=es, + analysis_type=at ) # Apply settings analyse.apply_settings(alpha=0.75) - # Run de shansep analyse - analyse._run_shansep() - - # Test het ophalen van data - analyse.get_shansep_data() + # # Run de shansep analyse - dit mag niet worden aangeroepen + # analyse._run_shansep() - # Test parameters ophalen - analyse.get_shansep_parameters() + # # Test het ophalen van data + # analyse.get_shansep_data() + # + # # Test parameters ophalen + # analyse.get_shansep_parameters() # Test korte resultaten - analyse.get_short_results() + analyse_df = analyse.get_short_results() + print(analyse_df) # Test geschatte parameters ophalen voor eerste benadering try: @@ -100,16 +109,49 @@ def test_shansep_analyse(): print("Handmatige parameters ingesteld met geschatte waardes") else: # Fallback naar default waardes als geschatte parameters niet beschikbaar zijn - analyse.set_parameters_handmatig( - snijpunt_gem=0.25, s_gem=0.8, m_gem=0.9, - snijpunt_kar=0.20, s_kar=0.7, m_kar=0.8 - ) - print("Handmatige parameters ingesteld met default waardes") + # analyse.set_parameters_handmatig(snijpunt_gem=11, s_gem=0.31, + # m_gem=0.9, snijpunt_kar=7, + # s_kar=0.28, m_kar=0.9) + print("geschatte waardes niet beschikbaar, handmatige parameters nog niet ingesteld") except Exception as e: print(f"Instellen handmatige parameters mislukt: {e}") # Parameters kunnen afhangen van specifieke data pass + # eerst normaal testen + # Test sutabel berekeningen (na het instellen van parameters) + try: + analyse.calculate_sutabel() + analyse.calculate_sutabel_nc() + except Exception: + # Sutabel berekeningen kunnen falen zonder juiste parameters + pass + + # Test figure generatie + analyse.set_figure_sv_su() + analyse.set_figure_sv_su_nc() + analyse.set_figure_ln_ocr_ln_s() + + # Test show figures (deze kunnen visualisatie genereren) + try: + analyse.show_figure_sv_su() + analyse.show_figure_sv_su_nc() + analyse.show_figure_ln_ocr_ln_s() + except Exception: + # Figures kunnen falen in test environment zonder display + pass + + # Test exports + analyse.export_shansep_results_excel(str(export_dir / f"shansep_results_{analysis_type}.xlsx")) + analyse.write_analysis_to_excel(str(export_dir / f"shansep_analysis_{analysis_type}.xlsx")) + analyse.save_to_pdf(path=str(export_dir)) + + + #opnieuw maar nu met de handmatige parameters + analyse.set_parameters_handmatig(snijpunt_gem=11, s_gem=0.31, + m_gem=0.9, snijpunt_kar=7, + s_kar=0.28, m_kar=0.9) + # Test sutabel berekeningen (na het instellen van parameters) try: analyse.calculate_sutabel() @@ -164,208 +206,208 @@ def test_shansep_analyse(self): """Test de volledige SHANSEP analyse workflow.""" self.assertTrue(test_shansep_analyse()) - def test_shansep_initialization(self): - """Test de initialisatie van SHANSEP klasse met verschillende parameters.""" - dbase = Dbase() - source_dir = Path(os.path.join(FILE_PATH, "Dbase.xlsx")) - dbase.import_data(source="Dbase", source_dir=source_dir) - - # Test geldige initialisatie - analyse = SHANSEP( - dbase=dbase, - investigation_groups=['TXT_SAFE_klei_licht_16_175'], - effective_stress='15% rek', - analysis_type='TXT_S_POP' - ) - self.assertEqual(analyse.analysis_type, 'TXT_S_POP') - self.assertEqual(analyse.effective_stress, '15% rek') - self.assertEqual(analyse.investigation_groups, ['TXT_SAFE_klei_licht_16_175']) - self.assertEqual(analyse.alpha, 0.75) # Default waarde - - def test_invalid_effective_stress_combination(self): - """Test dat ongeldige combinaties van analysis_type en effective_stress een error geven.""" - dbase = Dbase() - source_dir = Path(os.path.join(FILE_PATH, "Dbase.xlsx")) - dbase.import_data(source="Dbase", source_dir=source_dir) - - # Test ongeldige combinatie: TXT_S_POP met 10% rek - with self.assertRaises(ValueError): - SHANSEP( - dbase=dbase, - investigation_groups=['TXT_SAFE_klei_licht_16_175'], - effective_stress='10% rek', - analysis_type='TXT_S_POP' - ) - - # Test ongeldige combinatie: TXT_S_POP met 20% rek - with self.assertRaises(ValueError): - SHANSEP( - dbase=dbase, - investigation_groups=['TXT_SAFE_klei_licht_16_175'], - effective_stress='20% rek', - analysis_type='TXT_S_POP' - ) - - def test_settings_application(self): - """Test het toepassen van instellingen.""" - dbase = Dbase() - source_dir = Path(os.path.join(FILE_PATH, "Dbase.xlsx")) - dbase.import_data(source="Dbase", source_dir=source_dir) - - analyse = SHANSEP( - dbase=dbase, - investigation_groups=['TXT_SAFE_klei_licht_16_175'], - effective_stress='15% rek', - analysis_type='TXT_S_POP' - ) - - # Test apply_settings - analyse.apply_settings(alpha=0.9) - self.assertEqual(analyse.alpha, 0.9) - - def test_estimated_parameters(self): - """Test het ophalen van geschatte parameters voor eerste benadering.""" - dbase = Dbase() - source_dir = Path(os.path.join(FILE_PATH, "Dbase.xlsx")) - dbase.import_data(source="Dbase", source_dir=source_dir) - - analyse = SHANSEP( - dbase=dbase, - investigation_groups=['TXT_SAFE_klei_licht_16_175'], - effective_stress='15% rek', - analysis_type='TXT_S_POP' - ) - - # Apply settings and run analysis - analyse.apply_settings(alpha=0.75) - analyse._run_shansep() - - # Test geschatte parameters ophalen - estimated_params = analyse.get_estimated_parameters() - - # Controleer dat de geschatte parameters zijn opgehaald - self.assertIsNotNone(estimated_params) - self.assertIsInstance(estimated_params, dict) - - # Controleer dat alle verwachte keys aanwezig zijn - expected_keys = ['snijpunt_gem', 's_gem', 'm_gem', 'pop_gem', - 'snijpunt_kar', 's_kar', 'm_kar', 'pop_kar'] - for key in expected_keys: - self.assertIn(key, estimated_params) - - # Controleer dat de waardes numeriek zijn (None of float) - for key, value in estimated_params.items(): - self.assertTrue(value is None or isinstance(value, (int, float)), - f"Parameter {key} heeft ongeldige waarde: {value}") - - # Test NC geschatte parameters - estimated_params_nc = analyse.get_estimated_parameters_nc() - - self.assertIsNotNone(estimated_params_nc) - self.assertIsInstance(estimated_params_nc, dict) - - # Controleer dat alle verwachte NC keys aanwezig zijn - expected_nc_keys = ['snijpunt_gem_nc', 's_gem_nc', 'm_gem_nc', 'pop_gem_nc', - 'snijpunt_kar_nc', 's_kar_nc', 'm_kar_nc', 'pop_kar_nc'] - for key in expected_nc_keys: - self.assertIn(key, estimated_params_nc) - - def test_creating_figures(self): - """Test het aanmaken van figuren en save_fig_html functionaliteit voor SHANSEP.""" - dbase = Dbase() - source_dir = Path(os.path.join(FILE_PATH, "Dbase.xlsx")) - dbase.import_data(source="Dbase", source_dir=source_dir) - - analyse = SHANSEP( - dbase=dbase, - investigation_groups=['TXT_SAFE_klei_licht_16_175'], - effective_stress='15% rek', - analysis_type='TXT_S_POP' - ) - - # Apply settings and run analysis - analyse.apply_settings(alpha=0.75) - analyse._run_shansep() - - # Test handmatige parameters (vereist voor de analyses) - try: - analyse.set_parameters_handmatig( - snijpunt_gem=0.25, s_gem=0.8, m_gem=0.9, - snijpunt_kar=0.20, s_kar=0.7, m_kar=0.8 - ) - except Exception: - # Parameters kunnen afhangen van specifieke data - pass - - # Test dat we figuren kunnen aanmaken en opslaan - figure_created = False - html_saved = False - - # Test sv-su figure - try: - analyse.show_figure_sv_su() - # Controleer dat figure object is aangemaakt - self.assertIsNotNone(analyse.figure) - figure_created = True - - # Test save_fig_html functionaliteit - analyse.save_fig_html(path=str(export_dir), export_name="test_shansep_sv_su.html") - # Controleer dat het HTML bestand bestaat - html_file = export_dir / "test_shansep_sv_su.html" - self.assertTrue(html_file.exists(), "HTML file should be created") - html_saved = True - - except Exception as e: - print(f"SHANSEP sv-su figure creation failed: {e}") - - # Test ln(OCR)-ln(s) figure - try: - analyse.show_figure_ln_ocr_ln_s() - # Controleer dat figure object is aangemaakt - self.assertIsNotNone(analyse.figure) - figure_created = True - - # Test save_fig_html functionaliteit - analyse.save_fig_html(path=str(export_dir), export_name="test_shansep_ln_ocr.html") - html_file = export_dir / "test_shansep_ln_ocr.html" - self.assertTrue(html_file.exists(), "HTML file should be created") - html_saved = True - - except Exception as e: - print(f"SHANSEP ln(OCR)-ln(s) figure creation failed: {e}") - - # Test sv-su NC figure - try: - analyse.show_figure_sv_su_nc() - # Controleer dat figure object is aangemaakt - self.assertIsNotNone(analyse.figure) - figure_created = True - - # Test save_fig_html functionaliteit - analyse.save_fig_html(path=str(export_dir), export_name="test_shansep_sv_su_nc.html") - html_file = export_dir / "test_shansep_sv_su_nc.html" - self.assertTrue(html_file.exists(), "HTML file should be created") - html_saved = True - - except Exception as e: - print(f"SHANSEP sv-su NC figure creation failed: {e}") - - # Test dat minstens één van de figure tests is gelukt - if not figure_created: - self.skipTest("Figure creation failed for all figure types - may require specific data conditions") - - # Test dat save_fig_html functionaliteit werkt - self.assertTrue(html_saved, "save_fig_html should successfully create HTML files") - - # Test default export name functionality - try: - analyse.show_figure_sv_su() - analyse.save_fig_html(path=str(export_dir)) # No export_name specified - # Check that a file with default name pattern was created - html_files = list(export_dir.glob("shansep_analyse_*.html")) - self.assertTrue(len(html_files) > 0, "Default export name should create a file") - except Exception as e: - print(f"Default export name test failed: {e}") + # def test_shansep_initialization(self): + # """Test de initialisatie van SHANSEP klasse met verschillende parameters.""" + # dbase = Dbase() + # source_dir = Path(os.path.join(FILE_PATH, "Dbase.xlsx")) + # dbase.import_data(source="Dbase", source_dir=source_dir) + # + # # Test geldige initialisatie + # analyse = SHANSEP( + # dbase=dbase, + # investigation_groups=['TXT_SAFE_klei_licht_16_175'], + # effective_stress='15% rek', + # analysis_type='TXT_S_POP' + # ) + # self.assertEqual(analyse.analysis_type, 'TXT_S_POP') + # self.assertEqual(analyse.effective_stress, '15% rek') + # self.assertEqual(analyse.investigation_groups, ['TXT_SAFE_klei_licht_16_175']) + # self.assertEqual(analyse.alpha, 0.75) # Default waarde + # + # def test_invalid_effective_stress_combination(self): + # """Test dat ongeldige combinaties van analysis_type en effective_stress een error geven.""" + # dbase = Dbase() + # source_dir = Path(os.path.join(FILE_PATH, "Dbase.xlsx")) + # dbase.import_data(source="Dbase", source_dir=source_dir) + # + # # Test ongeldige combinatie: TXT_S_POP met 10% rek + # with self.assertRaises(ValueError): + # SHANSEP( + # dbase=dbase, + # investigation_groups=['TXT_SAFE_klei_licht_16_175'], + # effective_stress='10% rek', + # analysis_type='TXT_S_POP' + # ) + # + # # Test ongeldige combinatie: TXT_S_POP met 20% rek + # with self.assertRaises(ValueError): + # SHANSEP( + # dbase=dbase, + # investigation_groups=['TXT_SAFE_klei_licht_16_175'], + # effective_stress='20% rek', + # analysis_type='TXT_S_POP' + # ) + # + # def test_settings_application(self): + # """Test het toepassen van instellingen.""" + # dbase = Dbase() + # source_dir = Path(os.path.join(FILE_PATH, "Dbase.xlsx")) + # dbase.import_data(source="Dbase", source_dir=source_dir) + # + # analyse = SHANSEP( + # dbase=dbase, + # investigation_groups=['TXT_SAFE_klei_licht_16_175'], + # effective_stress='15% rek', + # analysis_type='TXT_S_POP' + # ) + # + # # Test apply_settings + # analyse.apply_settings(alpha=0.9) + # self.assertEqual(analyse.alpha, 0.9) + # + # def test_estimated_parameters(self): + # """Test het ophalen van geschatte parameters voor eerste benadering.""" + # dbase = Dbase() + # source_dir = Path(os.path.join(FILE_PATH, "Dbase.xlsx")) + # dbase.import_data(source="Dbase", source_dir=source_dir) + # + # analyse = SHANSEP( + # dbase=dbase, + # investigation_groups=['TXT_SAFE_klei_licht_16_175'], + # effective_stress='15% rek', + # analysis_type='TXT_S_POP' + # ) + # + # # Apply settings and run analysis + # analyse.apply_settings(alpha=0.75) + # analyse._run_shansep() + # + # # Test geschatte parameters ophalen + # estimated_params = analyse.get_estimated_parameters() + # + # # Controleer dat de geschatte parameters zijn opgehaald + # self.assertIsNotNone(estimated_params) + # self.assertIsInstance(estimated_params, dict) + # + # # Controleer dat alle verwachte keys aanwezig zijn + # expected_keys = ['snijpunt_gem', 's_gem', 'm_gem', 'pop_gem', + # 'snijpunt_kar', 's_kar', 'm_kar', 'pop_kar'] + # for key in expected_keys: + # self.assertIn(key, estimated_params) + # + # # Controleer dat de waardes numeriek zijn (None of float) + # for key, value in estimated_params.items(): + # self.assertTrue(value is None or isinstance(value, (int, float)), + # f"Parameter {key} heeft ongeldige waarde: {value}") + # + # # Test NC geschatte parameters + # estimated_params_nc = analyse.get_estimated_parameters_nc() + # + # self.assertIsNotNone(estimated_params_nc) + # self.assertIsInstance(estimated_params_nc, dict) + # + # # Controleer dat alle verwachte NC keys aanwezig zijn + # expected_nc_keys = ['snijpunt_gem_nc', 's_gem_nc', 'm_gem_nc', 'pop_gem_nc', + # 'snijpunt_kar_nc', 's_kar_nc', 'm_kar_nc', 'pop_kar_nc'] + # for key in expected_nc_keys: + # self.assertIn(key, estimated_params_nc) + # + # def test_creating_figures(self): + # """Test het aanmaken van figuren en save_fig_html functionaliteit voor SHANSEP.""" + # dbase = Dbase() + # source_dir = Path(os.path.join(FILE_PATH, "Dbase.xlsx")) + # dbase.import_data(source="Dbase", source_dir=source_dir) + # + # analyse = SHANSEP( + # dbase=dbase, + # investigation_groups=['TXT_SAFE_klei_licht_16_175'], + # effective_stress='15% rek', + # analysis_type='TXT_S_POP' + # ) + # + # # Apply settings and run analysis + # analyse.apply_settings(alpha=0.75) + # analyse._run_shansep() + # + # # Test handmatige parameters (vereist voor de analyses) + # try: + # analyse.set_parameters_handmatig( + # snijpunt_gem=0.25, s_gem=0.8, m_gem=0.9, + # snijpunt_kar=0.20, s_kar=0.7, m_kar=0.8 + # ) + # except Exception: + # # Parameters kunnen afhangen van specifieke data + # pass + # + # # Test dat we figuren kunnen aanmaken en opslaan + # figure_created = False + # html_saved = False + # + # # Test sv-su figure + # try: + # analyse.show_figure_sv_su() + # # Controleer dat figure object is aangemaakt + # self.assertIsNotNone(analyse.figure) + # figure_created = True + # + # # Test save_fig_html functionaliteit + # analyse.save_fig_html(path=str(export_dir), export_name="test_shansep_sv_su.html") + # # Controleer dat het HTML bestand bestaat + # html_file = export_dir / "test_shansep_sv_su.html" + # self.assertTrue(html_file.exists(), "HTML file should be created") + # html_saved = True + # + # except Exception as e: + # print(f"SHANSEP sv-su figure creation failed: {e}") + # + # # Test ln(OCR)-ln(s) figure + # try: + # analyse.show_figure_ln_ocr_ln_s() + # # Controleer dat figure object is aangemaakt + # self.assertIsNotNone(analyse.figure) + # figure_created = True + # + # # Test save_fig_html functionaliteit + # analyse.save_fig_html(path=str(export_dir), export_name="test_shansep_ln_ocr.html") + # html_file = export_dir / "test_shansep_ln_ocr.html" + # self.assertTrue(html_file.exists(), "HTML file should be created") + # html_saved = True + # + # except Exception as e: + # print(f"SHANSEP ln(OCR)-ln(s) figure creation failed: {e}") + # + # # Test sv-su NC figure + # try: + # analyse.show_figure_sv_su_nc() + # # Controleer dat figure object is aangemaakt + # self.assertIsNotNone(analyse.figure) + # figure_created = True + # + # # Test save_fig_html functionaliteit + # analyse.save_fig_html(path=str(export_dir), export_name="test_shansep_sv_su_nc.html") + # html_file = export_dir / "test_shansep_sv_su_nc.html" + # self.assertTrue(html_file.exists(), "HTML file should be created") + # html_saved = True + # + # except Exception as e: + # print(f"SHANSEP sv-su NC figure creation failed: {e}") + # + # # Test dat minstens één van de figure tests is gelukt + # if not figure_created: + # self.skipTest("Figure creation failed for all figure types - may require specific data conditions") + # + # # Test dat save_fig_html functionaliteit werkt + # self.assertTrue(html_saved, "save_fig_html should successfully create HTML files") + # + # # Test default export name functionality + # try: + # analyse.show_figure_sv_su() + # analyse.save_fig_html(path=str(export_dir)) # No export_name specified + # # Check that a file with default name pattern was created + # html_files = list(export_dir.glob("shansep_analyse_*.html")) + # self.assertTrue(len(html_files) > 0, "Default export name should create a file") + # except Exception as e: + # print(f"Default export name test failed: {e}") if __name__ == '__main__': diff --git a/pv_tool/shansep_analysis/test_shansep_analysis_short.py b/pv_tool/shansep_analysis/test_shansep_analysis_short.py new file mode 100644 index 0000000..c02e07b --- /dev/null +++ b/pv_tool/shansep_analysis/test_shansep_analysis_short.py @@ -0,0 +1,160 @@ +import os.path +import unittest +from pv_tool.imports.import_data import Dbase +from pv_tool.utilities.utils import get_repo_root, make_temp_folder +from pathlib import Path +from pv_tool.shansep_analysis.shansep_analysis import SHANSEP +import shutil + +FILE_PATH = os.path.join(get_repo_root(), "test_files") +repo_root = get_repo_root() +export_dir = make_temp_folder( + parent_folder=os.path.join(repo_root, "temp_exports"), add_microseconds=True +) +export_dir = Path(export_dir) + +def test_shansep_analyse(): + """ + Test voor SHANSEP analyse. Voert een volledige SHANSEP analyse uit met verschillende analyse types. + Test geïmplementeerd. Verander de invoer niet. + """ + dbase = Dbase() + source_dir = Path(os.path.join(FILE_PATH, "Dbase.xlsx")) + dbase.import_data(source="Dbase", source_dir=source_dir) + export_name = 'Template_PVtool5_0.xlsx' + dbase.export_dbase_to_template(export_dir=export_dir) + + # Initialize analysis types voor SHANSEP + analysis_types = ['TXT_S_POP', 'DSS_S_POP'] + effective_stresses = { + 'TXT_S_POP': ['2% rek', '5% rek', '15% rek', 'pieksterkte', 'eindsterkte'], + 'DSS_S_POP': ['2% rek', '5% rek', '10% rek', '15% rek', '20% rek', 'pieksterkte', 'eindsterkte'] + } + + for analysis_type in analysis_types: + # Test met een representatieve effective stress voor elk analysis type + + if analysis_type == 'DSS_S_POP': + ig = ['DSS_SAFE_veen'] + es = '20% rek' + at = 'DSS_S_POP' + else: + ig = ['TXT_SAFE_klei_licht_16_175'] + es = '15% rek' + at = 'TXT_S_POP' + + analyse = SHANSEP( + dbase=dbase, + investigation_groups=ig, + effective_stress=es, + analysis_type=at + ) + + # Apply settings + analyse.apply_settings(alpha=0.75) + + df_results_shansep_gem, df_results_shansep_kar = analyse.get_result_values_shansep() + + print(df_results_shansep_gem) + print(df_results_shansep_kar) + + estimated_params = analyse.get_estimated_parameters() + estimated_params_nc = analyse.get_estimated_parameters_nc() + + # Test handmatige parameters (gebruik geschatte waardes als eerste benadering) + try: + if estimated_params and all(v is not None for v in [ + estimated_params['snijpunt_gem'], estimated_params['s_gem'], estimated_params['m_gem'], + estimated_params['snijpunt_kar'], estimated_params['s_kar'], estimated_params['m_kar'] + ]): + analyse.set_parameters_handmatig( + snijpunt_gem=estimated_params['snijpunt_gem'], + s_gem=estimated_params['s_gem'], + m_gem=estimated_params['m_gem'], + snijpunt_kar=estimated_params['snijpunt_kar'], + s_kar=estimated_params['s_kar'], + m_kar=estimated_params['m_kar'] + ) + print("Handmatige parameters ingesteld met geschatte waardes") + else: + print("geschatte waardes niet beschikbaar, handmatige parameters nog niet ingesteld") + except Exception as e: + print(f"Instellen handmatige parameters mislukt: {e}") + # Parameters kunnen afhangen van specifieke data + pass + + # eerst normaal testen + # Test sutabel berekeningen (na het instellen van parameters) + try: + analyse.calculate_sutabel() + analyse.calculate_sutabel_nc() + except Exception: + # Sutabel berekeningen kunnen falen zonder juiste parameters + pass + + # Test figure generatie + analyse.set_figure_sv_su() + analyse.set_figure_sv_su_nc() + analyse.set_figure_ln_ocr_ln_s() + + # Test show figures (deze kunnen visualisatie genereren) + try: + analyse.show_figure_sv_su() + analyse.save_fig_html(path=str(export_dir), export_name="test_shansep_sv_su.html") + analyse.show_figure_sv_su_nc() + analyse.save_fig_html(path=str(export_dir), export_name="test_shansep_sv_su_nc.html") + analyse.show_figure_ln_ocr_ln_s() + analyse.save_fig_html(path=str(export_dir), export_name="test_shansep_ln_ocr_ln_s.html") + except Exception: + # Figures kunnen falen in test environment zonder display + pass + + # Test exports + analyse.export_shansep_results_excel(str(export_dir / f"shansep_results_{analysis_type}.xlsx")) + analyse.write_analysis_to_excel(str(export_dir / f"shansep_analysis_{analysis_type}.xlsx")) + analyse.save_to_pdf(path=str(export_dir)) + + + #opnieuw maar nu met de handmatige parameters + analyse.set_parameters_handmatig(snijpunt_gem=11, s_gem=0.31, + m_gem=0.9, snijpunt_kar=7, + s_kar=0.28, m_kar=0.9) + + # Test sutabel berekeningen (na het instellen van parameters) + try: + analyse.calculate_sutabel() + analyse.calculate_sutabel_nc() + except Exception: + # Sutabel berekeningen kunnen falen zonder juiste parameters + pass + + # Test figure generatie + analyse.set_figure_sv_su() + analyse.set_figure_sv_su_nc() + analyse.set_figure_ln_ocr_ln_s() + + # Test show figures (deze kunnen visualisatie genereren) + try: + analyse.show_figure_sv_su() + analyse.show_figure_sv_su_nc() + analyse.show_figure_ln_ocr_ln_s() + except Exception: + # Figures kunnen falen in test environment zonder display + pass + + # Test exports + analyse.export_shansep_results_excel(str(export_dir / f"shansep_results_{analysis_type}.xlsx")) + analyse.write_analysis_to_excel(str(export_dir / f"shansep_analysis_{analysis_type}.xlsx")) + analyse.save_to_pdf(path=str(export_dir)) + + return True + +class TestShansepAnalyse(unittest.TestCase): + """Unit test klasse voor SHANSEP analyse methoden.""" + + def test_shansep_analyse(self): + """Test de volledige SHANSEP analyse workflow.""" + self.assertTrue(test_shansep_analyse()) + +if __name__ == '__main__': + unittest.main() diff --git a/pv_tool/sutabel_analysis/save_and_export.py b/pv_tool/sutabel_analysis/save_and_export.py index 0da416e..e6c09f9 100644 --- a/pv_tool/sutabel_analysis/save_and_export.py +++ b/pv_tool/sutabel_analysis/save_and_export.py @@ -616,6 +616,18 @@ def save_sutabel_to_pdf(self: "SUTABEL", path: str, vc_fit_kar: float = None) -> try: doc.build(story) print(f"Sutabel PDF export voltooid: {file_path}") + + # Ruim tijdelijke plot bestanden op + import os + temp_files = [f"{path}/temp_sutabel_plot1.png", f"{path}/temp_sutabel_plot2.png"] + for temp_file in temp_files: + try: + if os.path.exists(temp_file): + os.remove(temp_file) + print(f"Tijdelijk plot bestand verwijderd: {temp_file}") + except Exception as e: + print(f"Waarschuwing: Kon tijdelijk plot bestand niet verwijderen {temp_file}: {e}") + return file_path except Exception as e: print(f"Fout bij maken PDF: {e}") diff --git a/pv_tool/utilities/cleanup.py b/pv_tool/utilities/cleanup.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/pv_tool/utilities/cleanup.py @@ -0,0 +1 @@ + diff --git a/resultaten/temp_plot.png b/resultaten/temp_plot.png deleted file mode 100644 index 4c252e0..0000000 Binary files a/resultaten/temp_plot.png and /dev/null differ diff --git a/resultaten/temp_plot1.png b/resultaten/temp_plot1.png deleted file mode 100644 index 72adfe5..0000000 Binary files a/resultaten/temp_plot1.png and /dev/null differ diff --git a/resultaten/temp_plot2.png b/resultaten/temp_plot2.png deleted file mode 100644 index 6138305..0000000 Binary files a/resultaten/temp_plot2.png and /dev/null differ diff --git a/resultaten/temp_plot3.png b/resultaten/temp_plot3.png deleted file mode 100644 index 8a69a31..0000000 Binary files a/resultaten/temp_plot3.png and /dev/null differ