def save_xml(self, attr): """ A function to save the loaded data in the xml file. This function adds the name and the path of the newly chosen hydrological data to the xml project file. First, it open the xml project file (and send an error if the project is not saved, or if it cannot find the project file). Then, it opens the xml file and add the path and name of the file to this xml file. If the model data was already loaded, it adds the new name without erasing the old name IF the switch append_name is True. Otherwise, it erase the old name and replace it by a new name. The variable āiā has the same role than in select_file_and_show_informations_dialog. :param i: a int for the case where there is more than one file to load :param append_name: A boolean. If True, the name found will be append to the existing name in the xml file, instead of remplacing the old name by the new name. """ filename_path_pro = os.path.join(self.path_prj, self.name_prj + '.habby') # save the name and the path in the xml .prj file if not os.path.isfile(filename_path_pro): self.end_log.emit( 'Error: The project is not saved. ' 'Save the project in the General tab before saving hydrological data. \n' ) else: # change path_last_file_loaded, model_type (path) self.project_properties = load_project_properties( self.path_prj) # load_project_properties self.project_properties[ "path_last_file_loaded"] = self.pathfile # change value self.project_properties[attr] = self.pathfile # change value save_project_properties( self.path_prj, self.project_properties) # save_project_properties
def find_path_hdf5_est(self): """ A function to find the path where to save the hdf5 file. Careful a simialar one is in sub_and_merge_GUI.py and in stathab_c. By default, path_hdf5 is in the project folder in the folder 'hdf5'. """ path_hdf5 = 'no_path' filename_path_pro = os.path.join(self.path_prj, self.name_prj + '.habby') if os.path.isfile(filename_path_pro): path_hdf5 = load_project_properties(self.path_prj)["path_hdf5"] # parser = ET.XMLParser(remove_blank_text=True) # doc = ET.parse(filename_path_pro, parser) # root = doc.getroot() # child = root.find(".//path_hdf5") # if child is None: # path_hdf5 = os.path.join(self.path_prj, 'hdf5') # else: # path_hdf5 = os.path.join(self.path_prj, child.text) else: self.send_log.emit( QCoreApplication.translate("StatModUseful", 'Warning: ') + QCoreApplication.translate( "StatModUseful", "The project is not saved. Save the project in the General tab." )) return path_hdf5
def read_attribute_xml(self, att_here): """ A function to read the text of an attribute in the xml project file. :param att_here: the attribute name (string). """ data = '' filename_path_pro = os.path.join(self.path_prj, self.name_prj + '.habby') if os.path.isfile(filename_path_pro): if att_here in {"path_last_file_loaded", "HS_input_class"}: data = load_project_properties(self.path_prj)[att_here] else: data = load_project_properties(self.path_prj)[att_here]["path"] else: pass return data
def __init__(self, path_prj, name_prj, send_log, title): super().__init__() self.path_prj = path_prj self.name_prj = name_prj self.send_log = send_log self.path_last_file_loaded = self.path_prj self.project_properties = load_project_properties(self.path_prj) self.setTitle(title) self.init_ui() # process_manager self.process_manager = MyProcessManager("hrr")
def export_chronicle(self): hvum = HydraulicVariableUnitManagement() # get fish selected for selection in self.fish_available_qlistwidget.selectedItems(): hvum.user_target_list.append(selection.data(Qt.UserRole)) # get filename hdf5name = self.hab_filenames_qcombobox.currentText() if not hdf5name: self.send_log.emit('Error: ' + self.tr('No .hab selected.')) return if self.mytablemodel: # fish names and units names from tableview fish_names_osi_wua = self.mytablemodel.colnames fish_names = [] for fish in fish_names_osi_wua: if "osi_" in fish: fish_names.append(fish.replace("osi_", "")) if "wua_" in fish: fish_names.append(fish.replace("wua_", "")) # seq or txt source = self.mytablemodel.source # reread from seq (tablemodel) if source == "seq": units = dict(units=list(map(float, self.mytablemodel.rownames))) # types text_unit = self.unit_type_qlabel.text() unit_type = dict(units=text_unit[text_unit.find('[') + 1:text_unit.find(']')]) # reread from text file (re-read file) else: units, unit_type = read_chronicle_from_text_file(source) # load figure option project_properties = load_project_properties(self.path_prj) interp_attr = lambda: None interp_attr.reach = self.hab_reach_qcombobox.currentText() interp_attr.units = units interp_attr.unit_type = unit_type interp_attr.hvum = hvum interp_attr.mode = "export" # process_manager self.process_manager.set_interpolation_hdf5_mode(self.path_prj, hdf5name, interp_attr, project_properties) # process_prog_show self.process_prog_show.start_show_prog(self.process_manager)
def read_attribute_xml(self, att_here): """ A function to read the text of an attribute in the xml project file. :param att_here: the attribute name (string). """ data = '' filename_path_pro = os.path.join(self.path_prj, self.name_prj + '.habby') if os.path.isfile(filename_path_pro): if att_here in {"path_last_file_loaded"}: data = load_project_properties(self.path_prj)[att_here] else: try: data = load_project_properties(self.path_prj)[att_here] except KeyError: self.save_xml("mesh_manager_file") data = load_project_properties(self.path_prj)[att_here] else: pass return data
def __init__(self, path_prj, name_prj, send_log, title): super().__init__() self.path_prj = path_prj self.name_prj = name_prj self.send_log = send_log self.path_last_file_loaded = self.path_prj self.classhv = None self.project_properties = load_project_properties(self.path_prj) self.setTitle(title) self.init_ui() self.input_class_file_info = self.read_attribute_xml("HS_input_class") self.read_input_class(os.path.join(self.input_class_file_info["path"], self.input_class_file_info["file"])) # process_manager self.process_manager = MyProcessManager("hs")
def plot_chronicle(self): hvum = HydraulicVariableUnitManagement() # get fish selected for selection in self.fish_available_qlistwidget.selectedItems(): hvum.user_target_list.append(selection.data(Qt.UserRole)) # get filename hdf5name = self.hab_filenames_qcombobox.currentText() if not hdf5name: self.send_log.emit('Error: ' + self.tr('No .hab selected.')) return if self.mytablemodel: # max if len(hvum.user_target_list) > 32: self.send_log.emit('Warning: ' + self.tr( 'You cannot display more than 32 habitat values per graph. Current selected : ') + str( len(hvum.user_target_list)) + ". " + self.tr("Only the first 32 will be displayed.") + " " + self.tr( 'You have to re-compute interpolation with 32 selected habitat values at maximum. There is no limit for txt exports.')) hvum.user_target_list = hvum.user_target_list[:32] # seq or txt source = self.mytablemodel.source # reread from seq (tablemodel) if source == "seq": units = dict(units=list(map(float, self.mytablemodel.rownames))) unit_type = dict(units=self.unit_type_qlabel.text()) # reread from text file (re-read file) else: units, unit_type = read_chronicle_from_text_file(source) # load figure option project_properties = load_project_properties(self.path_prj) interp_attr = lambda: None interp_attr.reach = self.hab_reach_qcombobox.currentText() interp_attr.units = units interp_attr.unit_type = unit_type interp_attr.hvum = hvum interp_attr.mode = "plot" # process_manager self.process_manager.set_interpolation_hdf5_mode(self.path_prj, self.hab_filenames_qcombobox.currentText(), interp_attr, project_properties) # process_prog_show self.process_prog_show.start_show_prog(self.process_manager)
def __init__(self, path_prj, name_prj, send_log, title): super().__init__() self.path_prj = path_prj self.name_prj = name_prj self.send_log = send_log self.path_last_file_loaded = self.path_prj self.project_properties = load_project_properties(self.path_prj) self.setTitle(title) self.init_ui() self.msg2 = QMessageBox() self.mesh_manager_file = self.read_attribute_xml("mesh_manager_file") self.read_mesh_manager_file(self.mesh_manager_file) # process_manager self.process_manager = MyProcessManager("mesh_manager")
def plot_hs_class(self): plot_attr = lambda: None plot_attr.nb_plot = 1 plot_attr.axe_mod_choosen = self.axe_mod_choosen plot_attr.hs_plot_type = "input_class" # process_manager self.process_manager.set_plot_hdf5_mode(self.path_prj, [self.file_selection_listwidget.selectedItems()[0].text()], plot_attr, load_project_properties(self.path_prj)) # process_prog_show self.process_prog_show_input.start_show_prog(self.process_manager)
def plot_hs_volume(self): plot_attr = lambda: None plot_attr.axe_mod_choosen = self.axe_mod_choosen plot_attr.hs_plot_type = "volume" plot_attr.reach = [element.row() for element in self.reach_QListWidget.selectedIndexes()] plot_attr.units = [element.row() for element in self.units_QListWidget.selectedIndexes()] plot_attr.nb_plot = len(plot_attr.units) # process_manager self.process_manager.set_plot_hdf5_mode(self.path_prj, [self.file_selection_listwidget.selectedItems()[0].text()], plot_attr, load_project_properties(self.path_prj)) # process_prog_show self.process_prog_show_volume.start_show_prog(self.process_manager)
def save_xml(self): # save the name and the path in the xml .prj file if not os.path.isfile( os.path.join(self.path_prj, self.name_prj + ".habby")): self.send_log.emit( 'Error: The project is not saved. ' 'Save the project in the General tab before saving hydrological data. \n' ) else: # change path_last_file_loaded, model_type (path) project_properties = load_project_properties( self.path_prj) # load_project_properties project_properties[ "path_last_file_loaded"] = self.dir_name # change value project_properties[ self.model_type]["path"] = self.dir_name # change value project_properties[self.model_type][ "fish_selected"] = self.fish_selected # change value save_project_properties( self.path_prj, project_properties) # save_project_properties
def __init__(self, path_prj, name_prj, steep=False): super().__init__() self.tab_name = "stathab" self.tab_position = 8 self.path_prj = path_prj self.name_prj = name_prj self.path_im = self.path_prj self.path_bio_stathab = './/biology/stathab' self.fish_selected = [] self.mystdout = StringIO() self.msge = QMessageBox() self.firstitemreach = [] # the first item of a reach self.list_file = QListWidget() self.list_needed = QListWidget() self.list_re = QListWidget() # name of all the text file (see stathabinfo.pdf) self.listrivname = 'listriv' self.end_file_reach = ['deb', 'qhw', 'gra', 'dis'] # .txt or .csv self.end_file_reach_trop = ['deb', 'qhw', 'ii'] # .txt or .csv self.name_file_allreach = [ 'bornh', 'bornv' ] # old : self.name_file_allreach = ['bornh', 'bornv', 'borng', 'Pref_latin.txt'] self.name_file_allreach_trop = [] self.hdf5_name = self.tr('No hdf5 selected') self.mystathab = stathab_mod.Stathab(self.name_prj, self.path_prj) self.dir_hdf5 = self.path_prj self.typeload = 'txt' # txt or hdf5 self.riverint = 0 # stathab or stathab_steep self.model_type = self.tr('Stathab') if steep: self.riverint = 1 self.model_type = self.tr('Stathab_steep') self.tab_position = 9 self.selected_aquatic_animal_list = [] project_properties = load_project_properties(self.path_prj) self.dir_name = project_properties[self.model_type]["path"] self.init_iu() self.fill_selected_models_listwidets( project_properties[self.model_type]["fish_selected"])
def name_last_hdf5(self, type): """ This function opens the xml project file to find the name of the last hdf5 merge file and to add it to the GUI on the QLabel self.lm2. It also add a QToolTip with the name of substrate and hydraulic files used to create this merge file. If there is no file found, this function do nothing. """ filename_path_pro = os.path.join(self.path_prj, self.name_prj + '.habby') name = QCoreApplication.translate("SubHydroW", 'no file') # save the name and the path in the xml .prj file if not os.path.isfile(filename_path_pro): self.send_log.emit('Error: ' + QCoreApplication.translate( "SubHydroW", 'The project is not saved. ' 'Save the project in the General tab before saving hydraulic data. \n' )) else: project_properties = load_project_properties(self.path_prj) if project_properties[type]["hdf5"]: name = project_properties[type]["hdf5"][-1] self.last_hydraulic_file_name_label.setText(name)
def select_dir(self): """ This function is used to select the directory and find the files to laod stathab from txt files. It calls load_from_txt_gui() when done. """ # load last dir self.project_properties = load_project_properties(self.path_prj) if not self.dir_name: self.dir_name = self.project_properties["path_last_file_loaded"] if not self.dir_name: self.dir_name = self.path_prj # get the directory self.dir_name = QFileDialog.getExistingDirectory( self, self.tr("Open Directory"), self.dir_name) if self.dir_name == '': # cancel case self.send_log.emit("Warning: No selected directory for stathab\n") return self.save_xml() # clear all list self.mystathab = stathab_mod.Stathab(self.name_prj, self.path_prj) self.list_re.clear() self.list_file.clear() self.list_needed.clear() self.list_f.clear() self.firstitemreach = [] filename_prj = os.path.join(self.path_prj, self.name_prj + '.habby') if not os.path.isfile(filename_prj): self.send_log.emit( 'Error: No project saved. Please create a project first in the General tab.' ) return else: # fill the lists with the existing files self.load_from_txt_gui()
def get_translator(path_prj): """ :param path_prj: path_prj :return: application with translate method. """ # get language from project_properties['language'] project_properties = load_project_properties(path_prj) language = project_properties['language'] # translator app = QApplication(sys.argv) languageTranslator = QTranslator(app) if language == 0: input_file_translation = 'Zen_EN' languageTranslator.load(input_file_translation, os.path.join(os.getcwd(), 'translation')) if language == 1: input_file_translation = 'Zen_FR' languageTranslator.load(input_file_translation, os.path.join(os.getcwd(), 'translation')) elif language == 2: input_file_translation = 'Zen_ES' languageTranslator.load(input_file_translation, os.path.join(os.getcwd(), 'translation')) app.installTranslator(languageTranslator) return app
def find_path_input_est(self): """ A function to find the path where to save the input file. Careful a similar one is in sub_and_merge_GUI.py. By default, path_input indicates the folder 'input' in the project folder. """ # path_input = 'no_path' # # filename_path_pro = os.path.join(self.path_prj, self.name_prj + '.habby') # if os.path.isfile(filename_path_pro): # parser = ET.XMLParser(remove_blank_text=True) # doc = ET.parse(filename_path_pro, parser) # root = doc.getroot() # child = root.find(".//path_input") # if child is None: # path_input = os.path.join(self.path_prj, r'/input') # else: # path_input = os.path.join(self.path_prj, child.text) # else: # self.send_log.emit('Warning: ' + QCoreApplication.translate("StatModUseful", "The project is not saved. Save the project in the General tab.")) project_properties = load_project_properties(self.path_prj) path_input = project_properties['path_input'] return path_input
def load_hydraulic_create_hdf5(self): """ The function which call the function which load telemac and save the name of files in the project file """ """ The function which call the function which load hec_ras2d and save the name of files in the project file """ if self.progress_layout.run_stop_button.isEnabled(): # get minimum water height as we might neglect very low water height self.project_properties = load_project_properties(self.path_prj) # get timestep and epsg selected for i in range(len(self.hydrau_description_list)): for reach_number in range( int(self.hydrau_description_list[i]["reach_number"])): if not any(self.hydrau_description_list[i]["unit_list_tf"] [reach_number]): self.send_log.emit( "Error: " + self.tr("No units selected for : ") + self.hydrau_description_list[i]["filename_source"] + "\n") return # check if extension is set by user (one hdf5 case) self.name_hdf5 = self.hdf5_name_lineedit.text() self.hydrau_description_list[self.input_file_combobox.currentIndex( )]["hdf5_name"] = self.name_hdf5 if self.name_hdf5 == "": self.send_log.emit('Error: ' + self.tr( '.hyd output filename is empty. Please specify it.')) return # check if extension is set by user (multi hdf5 case) hydrau_description_multiple = deepcopy( self.hydrau_description_list ) # create copy to not erase inital choices for hdf5_num in range(len(hydrau_description_multiple)): if not os.path.splitext( hydrau_description_multiple[hdf5_num]["hdf5_name"])[1]: hydrau_description_multiple[hdf5_num][ "hdf5_name"] = hydrau_description_multiple[hdf5_num][ "hdf5_name"] + ".hyd" # refresh filename_source if self.hydrau_case == '2.a' or self.hydrau_case == '2.b': filename_source_list = hydrau_description_multiple[ hdf5_num]["filename_source"].split(", ") new_filename_source_list = [] for reach_number in range( len(hydrau_description_multiple[hdf5_num] ["unit_list_tf"])): for file_num, file in enumerate(filename_source_list): if hydrau_description_multiple[hdf5_num][ "unit_list_tf"][reach_number][file_num]: new_filename_source_list.append( filename_source_list[file_num]) hydrau_description_multiple[hdf5_num][ "filename_source"] = ", ".join( new_filename_source_list) # process_manager self.progress_layout.process_manager.set_hyd_mode( self.path_prj, hydrau_description_multiple, self.project_properties) # process_prog_show self.progress_layout.start_process() # script self.create_script(hydrau_description_multiple)
def merge_grid_and_save(hdf5_name_hyd, hdf5_name_sub, hdf5_name_hab, path_prj, progress_value, q=[], print_cmd=False, project_properties={}): """ This function call the merging of the grid between the grid from the hydrological data and the substrate data. It then save the merged data and the substrate data in a common hdf5 file. This function is called in a second thread to avoid freezin gthe GUI. This is why we have this extra-function just to call save_hdf5() and merge_grid_hydro_sub(). :param hdf5_name_hyd: the name of the hdf5 file with the hydrological data :param hdf5_name_sub: the name of the hdf5 with the substrate data :param hdf5_name_hab: the name of the hdf5 merge output :param path_hdf5: the path to the hdf5 data :param name_prj: the name of the project :param path_prj: the path to the project :param model_type: the type of the "model". In this case, it is just 'SUBSTRATE' :param q: used to share info with the GUI when this thread have finsihed (print_cmd = False) :param print_cmd: If False, print to the GUI (usually False) :param path_shp: the path where to save the shp file with hydro and subtrate. If empty, the shp file is not saved. :param: erase_id should we erase old shapefile from the same model or not. """ if not print_cmd: sys.stdout = mystdout = StringIO() # progress progress_value.value = 10 if not project_properties: project_properties = load_project_properties(path_prj) # get_translator qt_tr = get_translator(project_properties['path_prj']) # if exists if not os.path.exists(os.path.join(path_prj, "hdf5", hdf5_name_hyd)): print('Error: ' + qt_tr.translate( "mesh_management_mod", "The specified file : " + hdf5_name_hyd + " don't exist.")) # warnings if not print_cmd: sys.stdout = sys.__stdout__ if q: q.put(mystdout) sleep(0.1) # to wait q.put() .. return if not os.path.exists(os.path.join(path_prj, "hdf5", hdf5_name_sub)): print('Error: ' + qt_tr.translate( "mesh_management_mod", "The specified file : " + hdf5_name_sub + " don't exist.")) # warnings if not print_cmd: sys.stdout = sys.__stdout__ if q: q.put(mystdout) sleep(0.1) # to wait q.put() .. return # load hdf5 hydro hdf5_hydro = hdf5_mod.Hdf5Management(path_prj, hdf5_name_hyd, new=False, edit=False) hdf5_hydro.load_hdf5(units_index="all", whole_profil=True) # load hdf5 sub hdf5_sub = hdf5_mod.Hdf5Management(path_prj, hdf5_name_sub, new=False, edit=False) hdf5_sub.load_hdf5_sub() # CONSTANT CASE if hdf5_sub.data_2d.sub_mapping_method == "constant": # set default value to all mesh data_2d_merge = hdf5_hydro.data_2d data_2d_whole_merge = hdf5_hydro.data_2d_whole data_2d_merge.set_sub_cst_value(hdf5_sub.data_2d) data_2d_merge.hyd_filename_source = hdf5_hydro.data_2d.filename_source data_2d_merge.hyd_path_filename_source = hdf5_hydro.data_2d.path_filename_source # POLYGON AND POINTS CASES elif hdf5_sub.data_2d.sub_mapping_method != "constant": # check if EPSG are integer and if TRUE they must be equal epsg_hyd = hdf5_hydro.data_2d.epsg_code epsg_sub = hdf5_sub.data_2d.epsg_code if epsg_hyd.isdigit() and epsg_sub.isdigit(): if epsg_hyd == epsg_sub: hab_epsg_code = epsg_hyd if epsg_hyd != epsg_sub: print( "Error : Merging failed. EPSG codes are different between hydraulic and substrate data : " + epsg_hyd + ", " + epsg_sub) return if not epsg_hyd.isdigit() and epsg_sub.isdigit(): print("Warning: EPSG code of hydraulic data is unknown (" + epsg_hyd + ") " "and EPSG code of substrate data is known (" + epsg_sub + "). " + "The merging data will still be calculated.") hab_epsg_code = epsg_sub if epsg_hyd.isdigit() and not epsg_sub.isdigit(): print("Warning: EPSG code of hydraulic data is known (" + epsg_hyd + ") " "and EPSG code of substrate data is unknown (" + epsg_sub + "). " + "The merging data will still be calculated.") hab_epsg_code = epsg_hyd if not epsg_hyd.isdigit() and not epsg_sub.isdigit(): print( "Warning: EPSG codes of hydraulic and substrate data are unknown : " + epsg_hyd + " ; " + epsg_sub + ". The merging data will still be calculated.") hab_epsg_code = epsg_hyd # check if extent match extent_hyd = hdf5_hydro.data_2d.data_extent extent_sub = hdf5_sub.data_2d.data_extent if (extent_hyd[2] < extent_sub[0] or extent_hyd[0] > extent_sub[2] or extent_hyd[3] < extent_sub[1] or extent_hyd[1] > extent_sub[3]): print( "Warning: No intersection found between hydraulic and substrate data (from extent intersection). Substrate default value applied on data as constant values." ) extent_intersect = False else: extent_intersect = True # check if whole profile is equal for all timestep if not hdf5_hydro.data_2d.hyd_varying_mesh: # have to check intersection for only one timestep pass else: # TODO : merge for all time step pass # no intersect if not extent_intersect: # set default value to all mesh data_2d_merge = hdf5_hydro.data_2d data_2d_whole_merge = hdf5_hydro.data_2d_whole data_2d_merge.set_sub_cst_value(hdf5_sub.data_2d) data_2d_merge.hyd_filename_source = hdf5_hydro.data_2d.filename_source data_2d_merge.hyd_path_filename_source = hdf5_hydro.data_2d.path_filename_source # intersect else: hyd_filename_source = hdf5_hydro.data_2d.filename_source hyd_path_filename_source = hdf5_hydro.data_2d.path_filename_source data_2d_merge = Data2d( reach_number=hdf5_hydro.data_2d.reach_number, unit_list=hdf5_hydro.data_2d.unit_list) # new hdf5_hydro.data_2d.__dict__.pop("path_filename_source") hdf5_hydro.data_2d.__dict__.pop("filename_source") data_2d_merge.__dict__ = hdf5_hydro.data_2d.__dict__.copy() data_2d_merge.hyd_filename_source = hyd_filename_source data_2d_merge.hyd_path_filename_source = hyd_path_filename_source # get sub attr for attribute_name in hdf5_sub.data_2d.__dict__.keys(): attribute_value = getattr(hdf5_sub.data_2d, attribute_name) if attribute_name in { "filename_source", "path_filename_source" }: setattr(data_2d_merge, "sub_" + attribute_name, attribute_value) if attribute_name[:3] == "sub": setattr(data_2d_merge, attribute_name, attribute_value) data_2d_merge.hab_animal_list = ", ".join([]) data_2d_merge.hab_animal_number = 0 data_2d_merge.hab_animal_pref_list = ", ".join([]) data_2d_merge.hab_animal_stage_list = ", ".join([]) data_2d_whole_merge = hdf5_hydro.data_2d_whole data_2d_merge.epsg_code = hab_epsg_code data_2d_merge.hvum = hdf5_hydro.data_2d.hvum # hyd variables data_2d_merge.hvum.hdf5_and_computable_list.extend( hdf5_sub.data_2d.hvum.hdf5_and_computable_list ) # sub variables hyd_xy_list = [] hyd_data_node_list = [] hyd_tin_list = [] iwholeprofile_list = [] i_split_list = [] hyd_data_mesh_list = [] sub_xy_list = [] sub_tin_list = [] sub_data_list = [] sub_default_list = [] coeffgrid_list = [] delta_mesh_list = [] # progress delta_reach = 80 / hdf5_hydro.data_2d.reach_number # for each reach for reach_number in range(0, hdf5_hydro.data_2d.reach_number): # progress delta_unit = delta_reach / hdf5_hydro.data_2d[ reach_number].unit_number # for each unit for unit_number in range( 0, hdf5_hydro.data_2d[reach_number].unit_number): # progress delta_mesh = delta_unit / hdf5_hydro.data_2d[reach_number][ unit_number]["mesh"]["tin"].shape[0] # conta args to list to Pool hyd_xy_list.append(hdf5_hydro.data_2d[reach_number] [unit_number]["node"]["xy"]) hyd_data_node_list.append( hdf5_hydro.data_2d[reach_number][unit_number]["node"] ["data"].to_numpy()) hyd_tin_list.append(hdf5_hydro.data_2d[reach_number] [unit_number]["mesh"]["tin"]) iwholeprofile_list.append( hdf5_hydro.data_2d[reach_number][unit_number]["mesh"] ["i_whole_profile"]) i_split_list.append( hdf5_hydro.data_2d[reach_number][unit_number]["mesh"] ["data"]["i_split"]) hyd_data_mesh_list.append( hdf5_hydro.data_2d[reach_number][unit_number]["mesh"] ["data"].to_numpy()) sub_xy_list.append(hdf5_sub.data_2d[0][0]["node"]["xy"]) sub_tin_list.append(hdf5_sub.data_2d[0][0]["mesh"]["tin"]) sub_data_list.append( hdf5_sub.data_2d[0][0]["mesh"]["data"].to_numpy()) sub_default_list.append( np.array(hdf5_sub.data_2d.sub_default_values)) coeffgrid_list.append(10) delta_mesh_list.append(delta_mesh) # Compute Pool input_data = zip(hyd_xy_list, hyd_data_node_list, hyd_tin_list, iwholeprofile_list, i_split_list, hyd_data_mesh_list, sub_xy_list, sub_tin_list, sub_data_list, sub_default_list, coeffgrid_list, delta_mesh_list) # start jobs lock = Lock() # to share progress_value pool = Pool(processes=2, initializer=setup, initargs=[progress_value, lock]) results = pool.starmap(merge, input_data) # for each reach index_loop = -1 for reach_number in range(0, hdf5_hydro.data_2d.reach_number): # for each unit for unit_number in range( 0, hdf5_hydro.data_2d[reach_number].unit_number): index_loop = index_loop + 1 merge_xy, merge_data_node, merge_tin, merge_i_whole_profile, merge_data_mesh, merge_data_sub = \ results[index_loop] # get mesh data data_2d_merge[reach_number][unit_number]["mesh"][ "tin"] = merge_tin data_2d_merge[reach_number][unit_number]["mesh"][ "data"] = DataFrame() for colname_num, colname in enumerate( hdf5_hydro.data_2d[0][0]["mesh"]["data"].columns): if colname == "i_whole_profile": data_2d_merge[reach_number][unit_number]["mesh"][ "data"][colname] = merge_i_whole_profile[:, 0] elif colname == "i_split": data_2d_merge[reach_number][unit_number]["mesh"][ "data"][colname] = merge_i_whole_profile[:, 1] else: data_2d_merge[reach_number][unit_number]["mesh"][ "data"][colname] = merge_data_mesh[:, colname_num] data_2d_merge[reach_number][unit_number]["mesh"][ "i_whole_profile"] = merge_i_whole_profile[:, 0] # sub_defaut data_2d_merge[reach_number][unit_number]["mesh"]["data"][ data_2d_merge.hvum.i_sub_defaut. name] = merge_i_whole_profile[:, 2] # get mesh sub data for sub_class_num, sub_class_name in enumerate( hdf5_sub.data_2d.hvum.hdf5_and_computable_list. hdf5s().names()): data_2d_merge[reach_number][unit_number]["mesh"][ "data"][ sub_class_name] = merge_data_sub[:, sub_class_num] # get node data data_2d_merge[reach_number][unit_number]["node"][ "xy"] = merge_xy data_2d_merge[reach_number][unit_number]["node"][ "data"] = DataFrame() for colname_num, colname in enumerate( hdf5_hydro.data_2d[0][0]["node"]["data"].columns): data_2d_merge[reach_number][unit_number]["node"][ "data"][colname] = merge_data_node[:, colname_num] # post process merge if data_2d_merge[reach_number][unit_number]["node"][ "data"][data_2d_merge.hvum.h.name].min() < 0: print( "Error: negative water height values detected after merging with substrate." ) # # plot_to_check_mesh_merging # plot_to_check_mesh_merging(hyd_xy=hdf5_hydro.data_2d[reach_number][unit_number]["node"]["xy"], # hyd_tin=hdf5_hydro.data_2d[reach_number][unit_number]["mesh"]["tin"], # # sub_xy=hdf5_sub.data_2d[reach_number][unit_number]["node"]["xy"], # sub_tin=hdf5_sub.data_2d[reach_number][unit_number]["mesh"]["tin"], # sub_data=hdf5_sub.data_2d[reach_number][unit_number]["mesh"]["data"]["sub_coarser"].to_numpy(), # # merge_xy=data_2d_merge[reach_number][unit_number]["node"]["xy"], # merge_tin=data_2d_merge[reach_number][unit_number]["mesh"]["tin"], # merge_data=data_2d_merge[reach_number][unit_number]["mesh"]["data"]["sub_coarser"].to_numpy()) # new variables data_2d_merge.hvum.i_sub_defaut.position = "mesh" data_2d_merge.hvum.i_sub_defaut.hdf5 = True data_2d_merge.hvum.hdf5_and_computable_list.append( data_2d_merge.hvum.i_sub_defaut) # compute area (always after merge) data_2d_merge.hvum.area.hdf5 = False data_2d_merge.hvum.area.position = "mesh" data_2d_merge.hvum.all_final_variable_list.append( data_2d_merge.hvum.area) data_2d_merge.compute_variables( data_2d_merge.hvum.all_final_variable_list.to_compute()) if not data_2d_merge.hvum.area.name in data_2d_merge.hvum.hdf5_and_computable_list.names( ): data_2d_merge.hvum.area.hdf5 = True data_2d_merge.hvum.hdf5_and_computable_list.append( data_2d_merge.hvum.area) # get_dimension data_2d_merge.get_dimension() # progress progress_value.value = 90 # create hdf5 hab data_2d_merge.filename = hdf5_name_hab hdf5 = hdf5_mod.Hdf5Management(path_prj, hdf5_name_hab, new=True) hdf5.create_hdf5_hab(data_2d_merge, data_2d_whole_merge, project_properties) if data_2d_merge.hs_calculated: # load_hydrosignature hyd hdf5_hydro = hdf5_mod.Hdf5Management(path_prj, hdf5_name_hyd, new=False, edit=False) hdf5_hydro.load_hydrosignature() # set to merged file hdf5 = hdf5_mod.Hdf5Management(path_prj, hdf5.filename, new=False, edit=True) hdf5.get_hdf5_attributes(close_file=False) hdf5.load_units_index() hdf5.load_data_2d() hdf5.load_whole_profile() hdf5.data_2d = hdf5_hydro.data_2d hdf5.write_hydrosignature(hs_export_mesh=hdf5_hydro.hs_mesh) hdf5.close_file() # export export_dict = dict() nb_export = 0 for key in hdf5.available_export_list: if project_properties[key][1]: nb_export += 1 export_dict[key + "_" + hdf5.extension[1:]] = project_properties[key][1] # warnings if not print_cmd: sys.stdout = sys.__stdout__ if q: q.put(mystdout) sleep(0.1) # to wait q.put() .. # prog progress_value.value = 100.0
def set_pref_gui_from_dict(self, default=False): if default: project_properties = create_default_project_properties_dict() else: # read actual figure option project_properties = load_project_properties(self.path_prj) # min_height_hyd self.min_height_lineedit.setText( str(project_properties['min_height_hyd'])) # CutMeshPartialyDry if project_properties[ 'cut_mesh_partialy_dry']: # is a string not a boolean self.cut_2d_grid_checkbox.setChecked(True) else: self.cut_2d_grid_checkbox.setChecked(False) # erase_id if project_properties['erase_id']: # is a string not a boolean self.erase_data_checkbox.setChecked(True) else: self.erase_data_checkbox.setChecked(False) # pvd_variable_z_combobox item_list = [ self.hvum.z.name_gui, self.hvum.h.name_gui, self.hvum.v.name_gui, self.hvum.level.name_gui, self.hvum.hydraulic_head_level.name_gui, self.hvum.conveyance.name_gui, self.hvum.froude.name_gui ] self.pvd_variable_z_combobox.clear() self.pvd_variable_z_combobox.addItems(item_list) self.pvd_variable_z_combobox.setCurrentIndex( item_list.index(project_properties["pvd_variable_z"])) # vertical_exaggeration self.vertical_exaggeration_lineedit.setText( str(project_properties["vertical_exaggeration"])) # check uncheck output checkboxs for checkbox in self.output_checkbox_list: type = checkbox.objectName()[-3:] if type == "hyd": index = 0 if type == "hab": index = 1 checkbox.setChecked( project_properties[checkbox.objectName()[:-4]][index]) # color_map self.color_map_combobox.setCurrentIndex( self.color_map_combobox.findText(project_properties['color_map'])) # fig_size self.fig_size_lineedit.setText( str(project_properties['width']) + ',' + str(project_properties['height'])) # font size self.font_size_lineedit.setText(str(project_properties['font_size'])) # font_family font_family_list = [ self.font_family_combobox.itemText(i) for i in range(self.font_family_combobox.count()) ] self.font_family_combobox.setCurrentIndex( font_family_list.index(project_properties['font_family'])) # line_width self.line_width_lineedit.setText(str(project_properties['line_width'])) # grid if project_properties['grid']: # is a string not a boolean self.grid_checkbox.setChecked(True) else: self.grid_checkbox.setChecked(False) # format fig_format_list = [ self.fig_format_combobox.itemText(i) for i in range(self.fig_format_combobox.count()) ] self.fig_format_combobox.setCurrentIndex( fig_format_list.index(project_properties['format'])) # resolution self.resolution_lineedit.setText(str(project_properties['resolution'])) # fish_name_type self.type_fishname_combobox.setCurrentIndex( int(project_properties['fish_name_type'])) # marker if project_properties['marker']: # is a string not a boolean self.marquers_hab_fig_checkbox.setChecked(True) else: self.marquers_hab_fig_checkbox.setChecked(False)
def collect_project_properties_choice(self): """ Function to collect user choices of project preferences GUI """ # get default option for security and facility project_properties = load_project_properties(self.path_prj) fig_size = self.fig_size_lineedit.text() if fig_size: fig_size = fig_size.split(',') try: project_properties['width'] = np.float(fig_size[0]) project_properties['height'] = np.float(fig_size[1]) except IndexError: self.send_log.emit('Error: ' + self.tr( 'The size of the figure should be in the format: num1,num2.\n' )) except ValueError: self.send_log.emit('Error: ' + self.tr( 'The size of the figure should be in the format: num1,num2.\n' )) # color map c1 = str(self.color_map_combobox.currentText()) if c1: project_properties['color_map'] = c1 # font size font_size = self.font_size_lineedit.text() if font_size: try: project_properties['font_size'] = int(font_size) except ValueError: self.send_log.emit( 'Error: ' + self.tr('Font size should be an integer. \n')) # font_family font_family = self.font_family_combobox.currentText() if font_family: try: project_properties['font_family'] = font_family except ValueError: self.send_log.emit('Error: ' + self.tr('Font family not recognized. \n')) # line width line_width = self.line_width_lineedit.text() if line_width: try: project_properties['line_width'] = int(line_width) except ValueError: self.send_log.emit( 'Error: ' + self.tr('Line width should be an integer. \n')) # grid if self.grid_checkbox.isChecked(): project_properties['grid'] = True else: project_properties['grid'] = False # format project_properties['format'] = self.fig_format_combobox.currentText() # resolution try: project_properties['resolution'] = int( self.resolution_lineedit.text()) except ValueError: self.send_log.emit( 'Error: ' + self.tr('The resolution should be an integer. \n')) if project_properties['resolution'] < 0: self.send_log.emit( 'Error: ' + self.tr('The resolution should be higher than zero \n')) return if project_properties['resolution'] > 2000: self.send_log.emit( self.tr('Warning: ') + self. tr('The resolution is higher than 2000 dpi. Figures might be very large.\n' )) # fish name type project_properties['fish_name_type'] = int( self.type_fishname_combobox.currentIndex()) # marker if self.marquers_hab_fig_checkbox.isChecked(): project_properties['marker'] = True else: project_properties['marker'] = False # outputs for checkbox in self.output_checkbox_list: type = checkbox.objectName()[-3:] if type == "hyd": index = 0 if type == "hab": index = 1 if checkbox.isChecked(): project_properties[checkbox.objectName()[:-4]][index] = True else: project_properties[checkbox.objectName()[:-4]][index] = False # vertical_exaggeration try: project_properties['vertical_exaggeration'] = int( self.vertical_exaggeration_lineedit.text()) if int(self.vertical_exaggeration_lineedit.text()) < 1: self.send_log.emit("Error: " + self.tr( "Vertical exaggeration value must be superior than 1. Value set to 1." )) project_properties['vertical_exaggeration'] = 1 except: self.send_log.emit("Error: " + self.tr( "Vertical exaggeration value is not integer. Value set to 1.")) project_properties['vertical_exaggeration'] = 1 # pvd_variable_z project_properties[ 'pvd_variable_z'] = self.pvd_variable_z_combobox.currentText() # other option try: project_properties['min_height_hyd'] = float( self.min_height_lineedit.text()) except ValueError: self.send_log.emit('Error: ' + self.tr('Minimum Height should be a number')) if self.erase_data_checkbox.isChecked(): project_properties['erase_id'] = True else: project_properties['erase_id'] = False # CutMeshPartialyDry if self.cut_2d_grid_checkbox.isChecked(): project_properties['cut_mesh_partialy_dry'] = True else: project_properties['cut_mesh_partialy_dry'] = False return project_properties
def runsave_fstress(self): """ This function save the data related to FStress and call the model Fstress. It is the method which makes the link between the GUI and fstress_mod.py. """ self.send_log.emit(self.tr('# Running: FStress')) self.save_river_data() if not self.save_ok: self.msge.setIcon(QMessageBox.Warning) self.msge.setWindowTitle(self.tr("FStress")) self.msge.setText( self. tr("FStress data could not be transformed to float. Cannot run FStress." )) self.msge.setStandardButtons(QMessageBox.Ok) self.msge.show() return # get the name of the selected fish fish_list = [] for i in range(0, self.selected_aquatic_animal_qtablewidget.count()): fish_item = self.selected_aquatic_animal_qtablewidget.item(i) # if latin name fish_item_latin = fish_item.text() foundlatin = False for idx, d in enumerate(self.latin_names): if d == fish_item_latin: fish_list.append(self.all_inv_name[idx]) foundlatin = True break # if abbrev if not foundlatin: fish_item_str = fish_item.text() fish_list.append(fish_item_str) # check internal logic ( a bit like estihab) if not fish_list: self.msge.setIcon(QMessageBox.Warning) self.msge.setWindowTitle(self.tr("run FStress")) self.msge.setText(self.tr("No fish selected. Cannot run FStress.")) self.msge.setStandardButtons(QMessageBox.Ok) self.msge.show() return for i in range(0, len(self.riv_name)): if len(self.qrange[i]) < 2: self.msge.setIcon(QMessageBox.Warning) self.msge.setWindowTitle(self.tr("run FStress")) self.msge.setText( self.tr("No discharge range. Cannot run FStress.")) self.msge.setStandardButtons(QMessageBox.Ok) self.msge.show() return if self.qrange[i][0] >= self.qrange[i][1]: self.msge.setIcon(QMessageBox.Warning) self.msge.setWindowTitle(self.tr("run FStress")) self.msge.setText( self. tr("Minimum dicharge bigger or equal to max discharge. Cannot run FStress." )) self.msge.setStandardButtons(QMessageBox.Ok) self.msge.show() return if self.qhw[i][1][0] == self.qhw[i][0][0]: self.msge.setIcon(QMessageBox.Warning) self.msge.setWindowTitle(self.tr("run FStress")) self.msge.setText( self.tr("FStress needs two different measured discharge.")) self.msge.setStandardButtons(QMessageBox.Ok) self.msge.show() return if self.qhw[i][0][2] == self.qhw[i][1][2]: self.msge.setIcon(QMessageBox.Warning) self.msge.setWindowTitle(self.tr("run FStress")) self.msge.setText( self.tr("FStress needs two different measured height.")) self.msge.setStandardButtons(QMessageBox.Ok) self.msge.show() return if self.qhw[i][0][1] == self.qhw[i][1][1]: self.msge.setIcon(QMessageBox.Warning) self.msge.setWindowTitle(self.tr("run FStress")) self.msge.setText( self.tr("FStress needs two different measured width.")) self.msge.setStandardButtons(QMessageBox.Ok) self.msge.show() return if any(i < 0 for i in self.qhw[i][0]) or any(i < 0 for i in self.qhw[i][1]) \ or self.qrange[i][0] < 0 or self.qrange[i][1] < 0: self.msge.setIcon(QMessageBox.Warning) self.msge.setWindowTitle(self.tr("run FStress")) self.msge.setText( self.tr("FStress do not accept negative value")) self.msge.setStandardButtons(QMessageBox.Ok) self.msge.show() return # check than one qhw is bigger than the other qhw if (self.qhw[i][0][0] > self.qhw[i][1][0] and self.qhw[i][0][1] < self.qhw[i][1][1]) \ or (self.qhw[i][0][0] > self.qhw[i][1][0] and self.qhw[i][0][2] < self.qhw[i][1][2]) \ or (self.qhw[i][1][0] > self.qhw[i][0][0] and self.qhw[i][1][1] < self.qhw[i][0][1]) \ or (self.qhw[i][1][0] > self.qhw[i][0][0] and self.qhw[i][1][2] < self.qhw[i][0][2]): self.msge.setIcon(QMessageBox.Warning) self.msge.setWindowTitle(self.tr("run FSTRESS")) self.msge.setText( self.tr( "Discharge, width, and height data are not coherent \n" )) self.msge.setStandardButtons(QMessageBox.Ok) self.msge.show() return # check if the discharge range is realistic with the result self.qall = [ self.qhw[i][0][0], self.qhw[i][1][0], self.qrange[i][0], self.qrange[i][1], -99 ] self.check_all_q() # run sys.stdout = self.mystdout = StringIO() [vh, qmod, inv_select] = fstress_mod.run_fstress( self.qhw, self.qrange, self.riv_name, fish_list, self.pref_inver, self.all_inv_name, self.name_prj, self.path_prj) sys.stdout = sys.__stdout__ self.send_err_log() if isinstance(qmod, int): if qmod == -99: return # find the latin name again (might be different as FStress might have failed on some species) inv_select_latin = [] for n in inv_select: for idx, n2 in enumerate(self.all_inv_name): if n == n2: inv_select_latin.append(self.latin_names[idx]) break # figures self.path_im = self.find_path_im_est() project_properties = load_project_properties(self.path_prj) fstress_mod.figure_fstress(qmod, vh, inv_select_latin, self.path_im, self.riv_name, project_properties) plt.show() #self.show_fig.emit() path_txt = self.find_path_text_est() # text file # abbreviation written in the textfile so no space in invertebrate name fstress_mod.write_txt(qmod, vh, inv_select, path_txt, self.riv_name) # log str_found = self.mystdout.getvalue() str_found = str_found.split('\n') for i in range(0, len(str_found)): if len(str_found[i]) > 1: self.send_log.emit(str_found[i]) strhydro = np.array_repr(np.array(self.qhw)) strhydro = strhydro[6:-1] self.send_log.emit("py data = " + strhydro) strhydro2 = np.array_repr(np.array(self.qrange)) strhydro2 = strhydro2[6:-1] self.send_log.emit("py qrange =" + strhydro2) fish_list_str = "py fish_list = [" for i in range(0, len(fish_list)): fish_list_str += "'" + fish_list[i] + "'," fish_list_str = fish_list_str[:-1] + ']' self.send_log.emit(fish_list_str) riv_name_str = "py riv_name = [" for i in range(0, len(self.riv_name)): riv_name_str += "'" + self.riv_name[i] + "'," riv_name_str = riv_name_str[:-1] + ']' self.send_log.emit(riv_name_str) self.send_log.emit( "py [pref_inver, all_inv_name] = fstress.read_pref(path_bio, 'pref_fstress.txt')" ) self.send_log.emit( "py [vh, qmod, inv_select] = fstress.run_fstress(data, qrange, riv_name, fish_list, " "pref_inver, all_inv_name, name_prj, path_prj)") self.send_log.emit( "py fstress.figure_fstress(qmod, vh, inv_select,'.', riv_name)") self.send_log.emit("restart RUN_FSTRESS") self.send_log.emit("restart path_fstress: " + self.path_fstress)
if not print_cmd: sys.stdout = sys.__stdout__ if q: q.put(mystdout) sleep(0.1) # to wait q.put() .. # prog progress_value.value = 100.0 if __name__ == '__main__': # set working directory to "C:\habby_dev\habby" # path_prj = r"C:\Users\Quent\Documents\HABBY_projects\DefaultProj" # C:\Users\yann.lecoarer\Documents\HABBY_projects\DefaultProj path_prj = r"C:\Users\yann.lecoarer\Documents\HABBY_projects\DefaultProj" project_properties = load_project_properties(path_prj) hrr_description_dict = dict(deltatlist=[0, 3.6 * 3600, 2.5 * 3600, 1.8 * 3600], hdf5_name="d1_d2_d3_d4.hyd") # class MyProcess progress_value = Value("d", 0.0) q = Queue() hrr(hrr_description_dict, progress_value, q, print_cmd=True, project_properties=project_properties) # xy = hdf5_1.data_2d[reach_number][unit_number]["node"]["xy"] # z_fond_node = hdf5_1.data_2d[reach_number][unit_number]["node"]["data"]["z"] # h_node = hdf5_1.data_2d[reach_number][unit_number]["node"]["data"]["h"] # h_mesh = hdf5_1.data_2d[reach_number][unit_number]["mesh"]["data"]["h"]
def run_estmihab(self): """ A function to execute Estimhab by calling the estimhab function. **Technical comment** This is the function making the link between the GUI and the source code proper. The source code for Estimhab is in src/Estimhab.py. This function loads in memory the data given in the graphical interface and call sthe Estimhab model. The data could be written by the user now or it could be data which was saved in the hdf5 file before and loaded when HABBY was open (and the init function called). We check that all necessary data is present and that the data given makes sense (e.g.,the minimum discharge should not be bigger than the maximal discharge, the data should be a float, etc.). We then remove the duplicate fish species (in case the user select one specie twice) and the Estimhab model is called. The log is then written (see the paragraph on the log for more information). Next, the figures created by Estimmhab are shown. As there is only a short number of outputs for Estimhab, we create a figure in all cases (it could be changed by adding a checkbox on the GUI like in the Telemac or other hydrological class). """ # prepare data try: q = [ float(self.eq1.text().replace(",", ".")), float(self.eq2.text().replace(",", ".")) ] w = [ float(self.ew1.text().replace(",", ".")), float(self.ew2.text().replace(",", ".")) ] h = [ float(self.eh1.text().replace(",", ".")), float(self.eh2.text().replace(",", ".")) ] q50 = float(self.eq50.text().replace(",", ".")) qrange = [ float(self.eqmin.text().replace(",", ".")), float(self.eqmax.text().replace(",", ".")) ] qtarget_values_list = [] for qtarg_lineedit in self.target_lineedit_list: if qtarg_lineedit.text(): qtarget_values_list.append( float(qtarg_lineedit.text().replace(",", "."))) substrate = float(self.esub.text().replace(",", ".")) except ValueError: self.send_log.emit('Error: ' + self.tr( 'Some data are empty or not float. Cannot run Estimhab')) return # get the list of xml file fish_list = [] fish_name2 = [] for i in range(0, self.selected_aquatic_animal_qtablewidget.count()): fish_item = self.selected_aquatic_animal_qtablewidget.item(i) fish_item_str = fish_item.text() fish_list.append(os.path.basename(fish_item.data(1))) fish_name2.append(fish_item_str) # check internal logic if not fish_list: self.send_log.emit( 'Error: ' + self.tr('No fish selected. Cannot run Estimhab.')) return if qrange[0] >= qrange[1]: self.send_log.emit('Error: ' + self.tr( 'Minimum discharge bigger or equal to max discharge. Cannot run Estimhab.' )) return if qtarget_values_list: for qtarg in qtarget_values_list: if qtarg < qrange[0] or qtarg > qrange[1]: self.send_log.emit('Error: ' + self.tr( 'Target discharge is not between Qmin and Qmax. Cannot run Estimhab.' )) return if q[0] == q[1]: self.send_log.emit( 'Error: ' + self.tr('Estimhab needs two differents measured discharges.')) return if h[0] == h[1]: self.send_log.emit( 'Error: ' + self.tr('Estimhab needs two different measured height.')) return if w[0] == w[1]: self.send_log.emit( 'Error: ' + self.tr('Estimhab needs two different measured width.')) return if (q[0] > q[1] and h[0] < h[1]) or (q[0] > q[1] and w[0] < w[1]) or (q[1] > q[0] and h[1] < h[0]) \ or (q[1] > q[0] and w[1] < w[0]): self.send_log.emit( 'Error: ' + self.tr('Discharge, width, and height data are not coherent.')) return if q[0] <= 0 or q[1] <= 0 or w[0] <= 0 or w[1] <= 0 or h[0] <= 0 or h[1] <= 0 or qrange[0] <= 0 or qrange[1] <= 0 \ or substrate <= 0 or q50 <= 0: self.send_log.emit('Error: ' + self.tr( 'Negative or zero data found. Could not run Estimhab.')) return if substrate > 3: self.send_log.emit( 'Error: ' + self.tr('Substrate is too large. Could not run Estimhab.')) return self.send_log.emit(self.tr('# Computing: Estimhab...')) # check if the discharge range is realistic with the result self.qall = [q[0], q[1], qrange[0], qrange[1], q50] self.check_all_q() # run and save project_properties = load_project_properties(self.path_prj) sys.stdout = mystdout = StringIO() self.estimhab_dict = dict(q=q, w=w, h=h, q50=q50, qrange=qrange, qtarg=qtarget_values_list, substrate=substrate, path_bio=self.path_bio_estimhab, xml_list=fish_list, fish_list=fish_name2) # change_specific_properties change_specific_properties(self.path_prj, ["Estimhab"], [self.estimhab_dict]) # process state = Value("d", 0) self.p = Process(target=estimhab_mod.estimhab_process, args=(self.estimhab_dict, project_properties, self.path_prj, state), name="Estimhab") self.p.start() self.p.join() # plot plot_attr = lambda: None plot_attr.name_hdf5 = self.name_prj + '_ESTIMHAB' + '.hab' plot_attr.nb_plot = 1 self.process_manager.set_estimhab_plot_mode( self.path_prj, plot_attr, load_project_properties(self.path_prj)) self.process_manager.start() # log info str_found = mystdout.getvalue() str_found = str_found.split('\n') for i in range(0, len(str_found)): if len(str_found[i]) > 1: self.send_log.emit(str_found[i]) self.send_log.emit( self. tr("Estimhab computation done. Figure and text files created in output project folder." )) self.send_log.emit("py data = [" + str(q) + ',' + str(w) + ',' + str(h) + ',' + str(q50) + ',' + str(substrate) + ']') self.send_log.emit("py qrange =[" + str(qrange[0]) + ',' + str(qrange[1]) + ']') self.send_log.emit( "py path1= os.path.join(os.path.dirname(path_bio),'" + self.path_bio_estimhab + "')") fish_list_str = "py fish_list = [" for i in range(0, len(fish_list)): fish_list_str += "'" + fish_list[i] + "'," fish_list_str = fish_list_str[:-1] + ']' self.send_log.emit(fish_list_str) self.send_log.emit( "py [OSI, WUA] = estimhab.estimhab(data[0], data[1], data[2], data[3] ," " qrange, data[4], path1, fish_list, '.', True, {}, '.')\n")
def init_iu(self): """ Used in the initialization of a new instance of the class WelcomeW() """ # Welcome windows self.habby_title_label = QLabel('<b>HABitat suitaBilitY</b>') self.habby_title_label.setAlignment(Qt.AlignCenter) font = QFont() font.setPointSize(20) self.habby_title_label.setFont(font) self.habby_title_label.setStyleSheet( "QLabel {background-color:None; color : rgb(71, 181, 230); }") # background image self.background_image_label = QLabel() self.background_image_label.setAlignment( Qt.AlignTop | Qt.AlignLeft) # Qt.AlignCenter self.background_image_label.setContentsMargins(0, 0, 0, 0) self.background_image_label.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) self.background_image_label.setMaximumHeight(150) self.background_image_pixmap = QPixmap( self.image_background_path).scaled(500, 500, Qt.KeepAspectRatio, Qt.SmoothTransformation) # , self.background_image_label.setPixmap(self.background_image_pixmap) self.background_image_label.setScaledContents(True) # general into to put in the xml .prj file name_prj_title_label = QLabel(self.tr('Name:')) self.name_prj_label = QLabel(self.name_prj) path_prj_title_label = QLabel(self.tr('Path:')) self.path_prj_label = QLabel(self.path_prj) user_name_title_label = QLabel(self.tr('User name:')) self.user_name_lineedit = QLineEdit() # this is used to save the data if the QLineEdit is going out of Focus self.user_name_lineedit.installEventFilter(self.outfocus_filter) self.outfocus_filter.outfocus_signal.connect( self.save_info_signal.emit) description_prj_title_label = QLabel(self.tr('Description:')) self.description_prj_textedit = QTextEdit() # this is used to save the data if the QLineEdit is going out of Focus self.description_prj_textedit.installEventFilter(self.outfocus_filter) self.outfocus_filter.outfocus_signal.connect( self.save_info_signal.emit) # insist on white background color (for linux, mac) p = self.palette() p.setColor(self.backgroundRole(), Qt.white) self.setPalette(p) # if the directory of the project does not exist, let the general tab empty fname = os.path.join(self.path_prj, self.name_prj + '.habby') if not os.path.isdir(self.path_prj) or not os.path.isfile(fname): pass # otherwise, fill it else: project_properties = load_project_properties(self.path_prj) self.user_name_lineedit.setText(project_properties["user_name"]) self.description_prj_textedit.setText( project_properties["description"]) # current_prj_groupbox self.current_prj_groupbox = QGroupBox(self.tr("Current project")) current_prj_layout = QGridLayout(self.current_prj_groupbox) current_prj_layout.addWidget(name_prj_title_label, 1, 0) current_prj_layout.addWidget(self.name_prj_label, 1, 1) current_prj_layout.addWidget(path_prj_title_label, 2, 0) current_prj_layout.addWidget(self.path_prj_label, 2, 1) current_prj_layout.addWidget(user_name_title_label, 3, 0) current_prj_layout.addWidget(self.user_name_lineedit, 3, 1) current_prj_layout.addWidget(description_prj_title_label, 4, 0) current_prj_layout.addWidget(self.description_prj_textedit, 4, 1) # empty frame scrolable general_frame = QFrame() self.general_layout = QGridLayout(general_frame) self.general_layout.addWidget(self.current_prj_groupbox, 1, 0) self.general_layout.addWidget(self.background_image_label, 0, 0) self.general_layout.addWidget(self.habby_title_label, 0, 0) # self.setLayout(self.general_layout) self.setWidgetResizable(True) self.setFrameShape(QFrame.NoFrame) self.setWidget(general_frame)
def select_file_and_show_informations_dialog(self): """ A function to obtain the name of the file chosen by the user. This method open a dialog so that the user select a file. This file is NOT loaded here. The name and path to this file is saved in an attribute. This attribute is then used to loaded the file in other function, which are different for each children class. Based on the name of the chosen file, a name is proposed for the hdf5 file. :param i: an int for the case where there is more than one file to load """ # get minimum water height as we might neglect very low water height self.project_properties = load_project_properties(self.path_prj) # prepare the filter to show only useful files if len(self.extension.split(", ")) <= 4: filter2 = "File (" for e in self.extension.split(", "): filter2 += '*' + e + ' ' filter2 = filter2[:-1] filter2 += ')' + ";; All File (*.*)" else: filter2 = '' # get last path if self.read_attribute_xml( self.model_type) != self.path_prj and self.read_attribute_xml( self.model_type) != "": model_path = self.read_attribute_xml(self.model_type) # path spe elif self.read_attribute_xml( "path_last_file_loaded" ) != self.path_prj and self.read_attribute_xml( "path_last_file_loaded") != "": model_path = self.read_attribute_xml( "path_last_file_loaded") # path last else: model_path = self.path_prj # path proj # find the filename based on user choice if self.extension: filename_list = QFileDialog().getOpenFileNames( self, self.tr("Select file(s)"), model_path, filter2) else: filename_list = QFileDialog().getExistingDirectory( self, self.tr("Select directory"), model_path) filename_list = [filename_list] # if file has been selected if filename_list[0]: # disconnect function for multiple file cases try: self.input_file_combobox.disconnect() except: pass try: self.reach_name_combobox.disconnect() except: pass try: self.units_QListWidget.disconnect() except: pass # init self.hydrau_case = "unknown" self.multi_hdf5 = False self.multi_reach = False self.index_hydrau_presence = False # get_hydrau_description_from_source hsra_value = HydraulicSimulationResultsAnalyzer( filename_list[0], self.path_prj, self.model_type) # warnings if hsra_value.warning_list: for warn in hsra_value.warning_list: self.send_log.emit(warn) if "Error:" in warn: self.clean_gui() return # error if type(hsra_value.hydrau_description_list) == str: self.clean_gui() self.send_log.emit(hsra_value.hydrau_description_list) return # set to attribute self.hydrau_description_list = hsra_value.hydrau_description_list # display first hydrau_description_list self.hydrau_case = self.hydrau_description_list[0]["hydrau_case"] # change suffix if not self.project_properties[ "cut_mesh_partialy_dry"] and self.hydrau_description_list[ 0]["model_dimension"] == "2": for telemac_description_num in range( len(self.hydrau_description_list)): namehdf5_old = os.path.splitext( self.hydrau_description_list[telemac_description_num] ["hdf5_name"])[0] exthdf5_old = os.path.splitext( self.hydrau_description_list[telemac_description_num] ["hdf5_name"])[1] self.hydrau_description_list[telemac_description_num][ "hdf5_name"] = namehdf5_old + "_no_cut" + exthdf5_old # save last path self.pathfile = self.hydrau_description_list[0][ "path_filename_source"] # source file path self.namefile = self.hydrau_description_list[0][ "filename_source"] # source file name self.name_hdf5 = self.hydrau_description_list[0]["hdf5_name"] self.save_xml() # multi if len(self.hydrau_description_list) > 1: self.multi_hdf5 = True # multi if len(self.hydrau_description_list[0]["reach_list"]) > 1: self.multi_reach = True # get names names = [ description["filename_source"] for description in self.hydrau_description_list ] # clean GUI self.clean_gui() self.input_file_combobox.addItems(names) self.update_reach_from_input_file() self.input_file_combobox.currentIndexChanged.connect( self.update_reach_from_input_file) self.reach_name_combobox.currentIndexChanged.connect( self.update_unit_from_reach) self.units_QListWidget.itemSelectionChanged.connect( self.unit_counter) self.hdf5_name_lineedit.setFocus()