Welcome to HABBY’s documentation!

HABBY is a program to estimate the habitat of fish using various hydrological models and preference curve as input.

How to execute HABBY

To execute HABBY:
  • Go to folder which contains habby.py using the command line.
  • Open the command line and type python habby.py.

The python version should be 3.4. HABBY should also function with most of the python 3 distributions.

If a module is missing, it is possible to install it using pip (“pip install -m module_name”). Obviously, pip needs to installed, which should be done by default in python 3.4. If you want to be sure to have the same version of the module than originally, go to the folder zen_file/wheele with the command line and install the missing module from there (something similar to “pip install -m .whl”). Not all modules are in this folder, only the ones which were difficult to install.

Main( ) and source code

The source code is separated in two folders: one folder which contain the code source for the graphical user interface (GUI) and one folder for the rest of the code source.

The dependency between the different part of the source code can be visualized in the mindmap real_GUI.xmind (xmind should be installed).

The main of HABBY is habby.py. It has the usual form for an application using PyQt5. The main() creates an application of QWidget and call the Main_Windows class, which we will discuss shortly. The last line closes the application.

It is also possible to call habby from the command line without the GUI. For this, the script called habby_cmd.py is used.

Graphical interface

Here is the list of all modules contains in the src_GUI folder.

Main_windows of HABBY

in src_GUI/Main_Windows_1.py

class src_GUI.Main_windows_1.CentralW(rech, path_prj, name_prj, lang_bio)

This class create the different tabs of the programm, which are then used as the central widget by the class MainWindows.

Parameters:
  • rech – A bollean which is True if the tabs for the “research option” are shown. False otherwise.
  • path_prj – A string with the path to the project xml file
  • name_prj – A string with the name of the project
  • lang_bio – A string with the word ‘English’, ‘French’ (or an other language). It is used to find the langugage in which the biological info should be shown. So lang_bio should have the same form than the attribute “langugage” in xml preference file.

Technical comments

In the attribute list, there are a series of name which finish by “tab” such as stathab_tab or output_tab. Each of these names corresponds to one tab and a new name should be added to the attributes to add a new tab.

During the creation of the class, each tab is created. Then, the signals to show the figures are connected between this class and all the children classes which need it (often this are the classes used to load the hydrological data). When a class emits the signal “show_fig”, CentralW collect this signal and show the figure, using the showfig function.

Show_fig is mostly a “plt.show()”. To avoid problem between matplotlib and PyQt, it is however important that matplotlib use the backend “Qt5Agg” in the .py where the “plt.plot” is called. Practically, this means modifying the matplotlib import.

Showfig shows only one figure. To show all existing figures, one can call the function show_fig2 from the menu. Show_fig2 call the instance child_win of the class ShowImageW to open a new Windows with all figure. However, this would only show the figure without any option for the zoom.

Then we call a function which connects all the signals from each class which need to write into the log. It is a good policy to create a “send_log” signal for each new important class. As there are a lot of signal to connect, these connections are written in the function “connect_signal_log”, where the signal for a new class can be added.

When this is done, the info for the general tab (created before) is filled. If the user has opened a project in HABBY before, the name of the project and the other info related to it will be shown on the general tab. If the general tab is modified in the class WelcomeW(), this part of the code which fill the general tab will probably needs to be modified.

Finally, each tab is filled. The tabs have been created before, but there were empty. Now we fill each one with the adequate widget. This is the link with many of the other classes that we describe below. Indeed, many of the widget are based on more complicated classes created for example in hydro_GUI_2.py.

Then, we create an area under it for the log. Here HABBY will write various infos for the user. Two things to note here: a) we should show the end of the scroll area. b) The size of the area should be controlled and not be changing even if a lot of text appears. Hence, the setSizePolicy should be fixed.

The write_log() and write_log_file() method are explained in the section about the log.

add_all_tab()

This function add the different tab to habby (used by init and by save_project). Careful, if you change the position of the Option tab, you should also modify the varaible self.opttab in init

closefig()

A small function to close the images open in HABBY and managed by matplotlib

connect_signal_fig_and_drop()

This function connect the PyQtsignal to show figure and to connect the log. It is a function to improve lisibility.

connect_signal_log()

connect all the signal linked to the log. This is in a function only to improve lisibility.

init_iu()

A function to initialize an instance of CentralW. Called by __init___().

optfig()

A small function which open the output tab.

save_info_projet()

This function is used to save the description of the project and the username in the xml project file

save_on_change_tab()

This function is used to save the data when the tab are changed. In most tab this is not needed as data is alredy saved by another functions. However, it is useful for the Welcome Tab and the Option Tab. This function can be modified if needed for new tabs.

Careful, the order of the tab is important here.

scrolldown()

Move the scroll bar to the bottow if the ScollArea is getting bigger

showfig()

A small function to show the last figure

showfig2()

A function to see all saved figures without possibility to zoom

update_hydro_hdf5_name()

This is a short function used to read all the hydrological data (contained in an hdf5 files) available in one project.

When these files are read, they are added to the drop-down menu on the hydrological tab an on the substrate tab. On the substrate Tab, if we have more than one hdf5 file, the first item is blank to insure that the user actively choose the hdf5 to reduce the risk of error (Otherwise the user might merge the substrate and an hydrological hdf5 without seeing that he needs to select the right hydrological hdf5).

This tasks should be in a function because an update to this list can be triggered by the loading of a new hydrological data. The class Hydro2W() and substrateW() noticed this through the signal drop_hydro send by the hydrological class. The signal drop_hydro is connected to this function is in the class CentralW in MainWindows.py.

update_merge_for_chronicle()

This function looks up the list of merge file in the QComBox in the bio_info tab and copy this list to the QCombobox in chronicle_GUI. So the two lists of merge file are the same

write_log(text_log)

A function to write the different log. Please read the section of the doc on the log.

Parameters:text_log – the text which should be added to the log (a string)
  • if text_log start with # -> added it to self.l2 (QLabel) and the .log file (comments)
  • if text_log start with restart -> added it restart_nameproject.txt
  • if text_log start with WARNING -> added it to self.l2 (QLabel) and the .log file
  • if text_log start with ERROR -> added it to self.l2 (QLabel) and the .log file
  • if text_log start with py -> added to the .log file (python command)
  • if text_log starts with Process -> Text added to the StatusBar only
  • if text_log == “clear status bar” -> the status bar is cleared
  • if text_log start with nothing -> just print to the Qlabel
  • if text_log out from stdout -> added it to self.l2 (QLabel) and the .log file (comments)

if logon = false, do not write in log.txt

write_log_file(text_log, pathname_logfile)

A function to write to the .log text. Called by write_log.

Parameters:
  • text_log – the text to be written (string)
  • pathname_logfile – the path+name where the log is
class src_GUI.Main_windows_1.CreateNewProjectDialog(lang, path_trans, file_langue, oldpath_prj)

A class which is used to help the user to create a new project

init_iu()
save_project

a signal to save the project

send_log

A PyQt signal used to write the log

setfolder()

This function is used by the user to select the folder where the xml project file will be located.

class src_GUI.Main_windows_1.EmptyTab

This class is used to fill empty tabs with something during the developement. It will not be use in the final version.

addtext()

This function print a string on the command line. This is useful if you need to check if a button (or similar). is connected.

init_iu()

Used in the initialization.

class src_GUI.Main_windows_1.MainWindows

The class MainWindows contains the menu and the title of all the HABBY windows. It also create all the widgets which can be called during execution

Technical comments and walk-through

First, we load the user setting using Qsettings: The settings by default of Qsettings are the name of the program (HABBY) and the name of the organization which develops the program (irstea). I have added three user settings (the name of the last project loaded into HABBY, the path to this project and the language used). The Qsetting are stored in the registry in Windows. Qsettings also function with Apple and Linux even if the information is stored differently

We set up the translation next. The translation of HABBY in different language is explained in more detail in the section “Translation of HABBY”. We give here the path to the data related to the translation. More precisely, we indicate here the path to the translation data and the name of the qm file containing the data related to the translation in each language. If a new qm is added for a new language, it should be added here to the list.

Now, two important attributes are defined: self.name_prj and self.path_prj. These attribute will be communicated to children classes. For each project, an xml file is created. This “project” file should be called name_prj.xml and should be situated in the path indicated by self.path_prj.

We call the central_widget which contains the different tabs.

We create the menu of HABBY calling the function my menu_bar().

Two signal are connected, one to save the project (i.e to update the xml project file) and another to save an ESTIMHAB calculation.

We show the created widget.

change_name_project()

This function is used to change the name of the current project. To do this, it copies the xml project with a new name and copy the file for the log with a new name

check_concurrency()

This function tests if the project which is opening by HABBY is not used by another instance of HABBY. It is dangerous to open two time the same project as we have problem with the writing of the xml files.

To check if a project is open, we have a text file in the project folder named “check_concurrency.txt”. In this text file, there is either the word “open” or “close”. When HABBY open a new project, it checks this file is set to close and change it to open. Hence, if a project is oen twice a warning is writtem/

clear_log()

Clear the log in the GUI.

closeEvent(event)

This is the function which handle the closing of the program. It use the function end_concurrency() to indicate to other habby instances that we do not use a particular project anymore.

We use os_exit instead of sys.exit so it also close the other thread if more than one is open.

Parameters:event – managed by the operating system.
close_project()

This function close the current project wihout opening a new project

close_rech()

Close the additional research menu (see open_rech for more information). For the moment, ONLY works with two research tabs. Modify this function if a different number of tab is needed.

create_menu_right()

This function create the menu for right click

do_log(save_log)

Save or not save the log

Parameters:save_log – an int which indicates if the log should be saved or not
  • 0: do not save log
  • 1: save the log in the .log file and restart file
empty_project()

This function open a new empty project

end_concurrency()

This functiion indicates to the project folder than this project is not used anymore. Hence, this project can be used freely by an other instance of HABBY.

erase_pict()

All files contained in the folder indicated by path_im will be deleted.

From the menu of HABBY, it is possible to ask to erase all files in the folder indicated by path_im (usually figure_HABBY). Of course, this is a bit dangerous. So the function asks the user for confirmation. However, it is practical because you do not have to go to the folder to erase all the images when there are too many of them.

init_ui()

Used by __init__() to create an instance of the class MainWindows

my_menu_bar(right_menu=False)

This function creates the menu bar of HABBY when call without argument or with the argument right_menu is False. if right menu is True, it creates a very similar menu but we use a QMenu() instead of a QMenuBar() as it is the menu open when the user right click

Parameters:right_menu – If call with True, we create a menu for the right click and not for the menu part on the top of the screen.
my_toolbar()
new_project()

This function open an empty project and guide the user to create a new project, using a new Windows of the class CreateNewProjectDialog

on_context_menu(point)

This function is used to show the menu on right click. If we are ont he Habitat Tab and that the focus is on the QListWidget, it shows the informatin concerning the fish

Parameters:point – Not understood, linke with the position of the menu.
open_help()

This function open the html which form the help from HABBY. For the moment, it is the full documentation with all the coding detail, but we should create a new html or a new pdf file which would be more pratical for the user.

open_project()

This function is used to open an existing habby project by selecting an xml project file. Called by my_menu_bar()

open_recent_project(j)

This function open a recent project of the user. The recent project are listed in the menu and can be selected by the user. When the user select a recent project to open, this function is called. Then, the name of the recent project is selected and the method save_project() is called.

Parameters:j – This indicates which project should be open, based on the order given in the menu
open_rech()

Open the additional research tab, which can be used to create Tab with more experimental contents.

Indeed, it is possible to show extra tab in HABBY. These supplementary tab correspond to open for researcher. The plan is that these options are less tested than other mainstream options. It is not clear yet what will be added to these options, but the tabs are already there when it will be needed.

save_project()

A function to save the xml file with the information on the project

Technical comments

This function saves or creates the xml file related to the projet. In this xml file, there are the path and the name to all files related to the project, notably the hdf5 files containing the hydrological data.

To find or create the xml file, we use the attribute self.path_prj and self.name_proj. If the path to the project directory is not found an error appears. The error is here sent though additional windows (to be sure that the user notice this problem), using the Qmesssage module. The user should give the general info about the project in the general tab of HABBY and they are collected here. User option (using Qsetting) is next updated so that the user will find his project open the next time it opens HABBY.

When HABBY open, there are therefore two choice: a) This is a new project b) the project exists already. If the project is new, the xml file is created and general information is written in this file. In addition, the text file which are necessary to log the action of HABBY are created now. This part of the reason why it is not possible to run other part of HABBY (such as loading hydrological data) before a project is saved. In addition, it would create a lot of problems on where to store the data created. Hence, a project is needed before using HABBY. If the project exists already (i.e. the name and the path of the project have not been modified), the xml file is just updated to change its attributes as needed.

Interesting path are a) the biology path (named “biology” by default) which contains the biological information such as the preference curve and b) the path_im which is the path where all figures and most outputs of HABBY is saved. If path_im is not given, HABBY automatically create a folder called figures when the user creates a new project. The user can however change this path if he wants. It also create other similar folders to sotre different type of outputs. The next step is to communicate to all the children widget than the name and path of the project have changed.

This function also changes the title of the Windows to reflect the project name and it adds the saved project to the list of recent project if it is not part of the list already. Because of this the menu must updated.

Finally the log is written (see “log and HABBY in the command line).

save_project_estimhab()

A function to save the information linked with Estimhab in an hdf5 file.

Technical comments

This function save the data and result from the estimhab calculation. It would look more logic if it was in the esimhab.py script, but it was easier to call it from here instead of in the child class.

This function get all estimhab input, create an hdf5 file using h5py and save the data in the hdf5. One specialty of hdf5 is that is cannot use Unicode. Hence all string have to be passed to ascii using the encode function. The size of each data should also be known.

Finally, we save the name and path of the estimhab file in the xml project file.

save_project_if_new_project()

This function is used to save a project when the project is created from the other Windows CreateNewProjectDialog. It can not be in the new_project function as the new_project function call CreateNewProjectDialog().

see_file()

This function allows the user to see the files in the project folder and to open them.

setlangue(nb_lang)

A function which change the language of the programme. It change the menu and the central widget. It uses the self.lang attribute which should be set to the new language before calling this function.

Parameters:nb_lang – the number representing the language (int)
  • 0 is for English
  • 1 for French
  • n for any additionnal language
test_entry_float(var_in)

An utility function to test if var_in are float or not the boolean self.does_it_work is used to know if the functions run until the end.

Parameters:var_in – the QlineEdit which contains the data (so var_in.text is a string)
Returns:the tested variable var_in
class src_GUI.Main_windows_1.MyFilter

This is a filter which is used to know when a QWidget is going out of focus. Practically this is used if the user goes away from a QLineEdit. If this events happends, the project is autmatically saved with the new info of the user.

eventFilter(widget, event)
outfocus_signal

A signal to change the user name and the description of the project

class src_GUI.Main_windows_1.ShowImageW(path_prj, name_prj)

The widget which shows the saved images. Used only to show all the saved figure together iwhtout zoom or other options. Not really used anymore in HABBY but it still there as it can be useful in the future.

Technical comments

The ShowImageW() class is used to show all the figures created by HABBY. It is a class which can only be called from the menu (In Option/Option Image). This is not the usual way of opening a figure which is usually done by plt.show from matplotlib. This is the way to look at all figures together, which can be useful, even if zooming is not possible anymore.

To show all image, HABBY open a separate window and show the saved image in .png format. Currently, the figures shown are in .png, but other formats could be used. For this, one can change the variable self.imtype.

An important point for the ShowImageW class is where the images were saved by the functions which created them. In HABBY, all figures are saved in the same folder called “path_im”. One “path_im” is chosen at the start of each project. By default, it is the folder “Figure_Habby”, but the user can modify this folder in the window created by ShowImageW(). The function for this is called “change_folder”, also in ShowImageW(). The path_im is written in the xml project file. The different functions which create image read this path and send the figure created to this folder. ShowImageW() reads all figure of “.png” type in the” path_im” folder and show the most recent figure. The user can use the drop-down menu to choose to see another figure. The names of the figure are added to the drop-down menu in the function update_namefig. The function “selectionchange” changes the figure shown based on the user action.

change_folder()

A function to change the folder where are stored the image (i.e., the path_im)

init_iu()

Used in the initialization.

selectionchange(i)

A function to change the figure shown by ShowImageW() :return:

send_log

A PyQt signal used to write the log

update_namefig()

This function add the different figure name to the drop-down list.

class src_GUI.Main_windows_1.WelcomeW(path_prj, name_prj)

The class WeLcomeW() creates the first tab of HABBY (the tab called “General”). This tab is there to create a new project or to change the name, path, etc. of a project.

change_name

A signal to change the name of the project for MainWindows

init_iu()

Used in the initialization of a new instance of the class WelcomeW()

new_proj_signal

A PyQt signal used to open a new project

open_example()

This function will be used to open a project example for HABBY, but the example is not prepared yet

open_proj

A signal for MainWindows to open an exisiting project

save_info_signal

A signal to change the user name and the description of the project

save_signal

A PyQt signal used to save the project

send_log

A PyQt signal used to write the log

setfolder2()

This function is used by the user to select the folder where the xml project file will be located. This is used in the case where the project exist already. A similar function is in the class CreateNewProjectDialog() for the case where the project is new.

Hydrological information - GUI

in src_GUI/hydro_GUI_2.py

This python module contains the class which forms the hydrological tab in HABBY. It contains the information for the graphical interface and make the link with the scripts used for the hydrological calculations.

class src_GUI.hydro_GUI_2.FreeSpace

Bases: PyQt5.QtWidgets.QWidget

Simple class with empty space, just to have only Qwidget in the stack.

Technical comment

The idea of this class is that the user see a free space when it opens the “Hydro” Tab instead of directly seeing one of the hydraulic model. The goal is to avoid the case where a user tries to load data before selecting the real model. For example, if a user wants to load mascaret data and that an item is selected by default in the stack of classes related to hydrology (such as HEC-RAS1D), it might be logical for the user to try to load masacret data using the HEC-RAS class. Because of the FreeSpace class, he actually has to select the model he wants to load.

class src_GUI.hydro_GUI_2.HEC_RAS1D(path_prj, name_prj)

Bases: src_GUI.hydro_GUI_2.SubHydroW

The class Hec_ras 1D is there to manage the link between the graphical interface and the functions in src/hec_ras06.py which loads the hec-ras data in 1D. The class HEC_RAS1D inherits from SubHydroW() so it have all the methods and the variables from the class ubHydroW(). The class hec-ras 1D is added to the self.stack of Hydro2W(). So the class Hec-Ras 1D is called when the user is on the hydrological tab and click on hec-ras1D as hydrological model.

init_iu()

This function is called by __init__() durring the initialization.

Technical comment

The self.attributexml variable is the name of the attribute in the xml file. To load a hec-ras file, one needs to give to HABBY one file containing the geometry data and one file containing the simulation result. The name and path to these two file are saved in the xml project file under the attribute given in the self.attributexml variable.

The variable self.extension is a list of list of the accepted file type. The first list is for the file with geometry data. The second list is the extension of the files containing the simulation results.

Using the function self.was_model_loaded_before, HABBY write the name of the hec-ras files which were loaded in HABBY in the same project before.

Hec-Ras is a 1.5D model and so HABBY create a 2D grid based on the 1.5D input. The user can choose the interpolation type and the number of extra profile. If the interpolation type is “interpolation by block”, the number of extra profile will always be one. See manage_grid.py for more information on how to create a grid.

We add a QLineEdit with the proposed name for the created hdf5 file. The user can modified this name if wished so.

load_hec_ras_gui()

A function to execute the loading and saving of the HEC-ras file using Hec_ras.py

Technical comments

This function is called when the user press on the button self.load_b. It is the function which really calls the load function for hec_ras. First, it updates the xml project file. It adds the name of the new file to xml project file under the attribute indicated by self.attributexml. It also gets the path_im by reading the path_im in the xml project file. If we want to create the 1D figure, the option show_all_fig should be selected in the figure option. It also manages the log as explained in the section about the log. It loads the hec-ras data as explained in the section on hec_ras06.py and creates the grid as explained in the manage_grid.py based on the interpolation type wished by the user (linear, nearest neighbor or by block). The variable self.name_hdf5() is taken from the GUI.

propose_next_file()

This function proposes the second hec-ras file when the first is selected. Indeed, to load hec-ras, we need one file with the geometry data and one file with the simulation results. If the user selects a file, this function looks if a file with the same name but with the extension of the other file type exists in the selected folder. Careful, when using hec-ras more than one extension type is possible.

class src_GUI.hydro_GUI_2.HEC_RAS2D(path_prj, name_prj)

Bases: src_GUI.hydro_GUI_2.SubHydroW

The class hec_RAS2D is there to manage the link between the graphical interface and the functions in src/hec_ras2D.py which loads the hec_ras2D data in 2D. It inherits from SubHydroW() so it have all the methods and the variables from the class SubHydroW(). It is very similar to RUBAR2D class and it has the same problem about node/cell which will need to be corrected.

init_iu()

This method is used to by __init__() during the initialization.

load_hec_2d_gui()

This function calls the function which load hecras 2d and save the names of file in the project file. It is similar to the function to load_rubar2D. It open a second thread to avoid freezing the GUI.

When this function starts, it also starts a timer. Every three seconds, the timer run the function send_data() which is the class SubHydroW(). This function checks if the thread is finished and, it is finished, manage figure and errors.

class src_GUI.hydro_GUI_2.HabbyHdf5(path_prj, name_prj)

Bases: src_GUI.hydro_GUI_2.SubHydroW

This class is used to load hdf5 hydrological file done by HABBY on another project. If the project was lost, it is there possible to just add a along hdf5 file to the current project without having to pass to the original hydrological files.

add_new_hdf5_to_xml()

This function is used to add the new hdf5 to the xml project file

add_two_hdf5(merge)

This functions is used to merge together two hydro/merge hdf5. For tis, it call the function ‘addition_hdf5’ from load_hdf5.py

Parameters:merge – A boolean which say if we load an hydrological or a merge file
drop_merge

A pyqtsignal which signal that new merge data is ready as it also possible to import merge data here.

get_new_hydro_hdf5()

This is a function which allows the user to select an hdf5 file containing the hydrological data from a previous project and add it to the current project. It modifies the xml project file and test that the data is in correct form by loading it. The hdf5 should have the same form than the hydrological data created by HABBY in the method save_hdf5 of the class SubHydroW.

get_new_merge_hdf5()

This is a function which allows the user to select an hdf5 file containing the hydrological and the substrate data from a previous project and add it to the current project. It modifies the xml project file and test that the data is in correct form by loading it. The hdf5 should have the same form than the merge data created by HABBY in the method save_hdf5 of the class SubHydroW.

init_iu()

Used in the initialization by __init__()

class src_GUI.hydro_GUI_2.Hydro2W(path_prj, name_prj)

Bases: PyQt5.QtWidgets.QWidget

The class Hydro2W is the second tab of HABBY. It is the class containing all the classes/Widgets which are used to load the hydrological data.

List of model supported by Hydro2W: files separetly. However, sometime the file was not found * Telemac (2D) * Hec-Ras (1.5D et 2D) * Rubar BE et 2(1D et 2D) * Mascaret (1D) * River2D (2D)

Technical comments

To call the different classes used to load the hydrological data, the user selects the name of the hydrological model from a QComboBox call self.mod. The method ‘selection_change” calls the class that the user chooses in self.mod. All the classes used to load the hydrological data are created when HABBY starts and are kept in a stack called self.stack. The function selection_change() just changes the selected item of the stack based on the user choice on self.mod.

Any new hydrological model should also be added to the stack and to the list of models contained in self.mod (name of the list: self.name_model).

In addition to the stack containing the hydrological information, hydro2W has two buttons. One button open a QMessageBox() which give information about the models, using the method “give_info_model”. It is useful if a special type of file is needed to load the data from a model or to give extra information about one hydrological model. The text which is shown on the QMessageBox is given in one text file for each model. These text file are contained in the folder ‘model_hydro” which is in the HABBY folder. For the moment, there are models for which no text files have been prepared. The text file should have the following format:

  • A short sentence with general info
  • The keyword: MORE INFO
  • All other infomation which are needed.

The second button allows the user to load an hdf5 file containing hydrological data from another project. As long as the hdf5 is in the right format, it does not matter from which hydrological model it was loaded from or even if this hydrological model is supported by HABBY.

give_info_model()

A function to show extra information about each hydrological model. The information should be in a text file with the same name as the model in the model_hydo folder. General info goes as the start of the text file. If the text is too long, add the keyword “MORE INFO” and add the longer text afterwards. The message box will show the supplementary information only if the user asks for detailed information.

This functins is not used anymore as it was long to maintain it and not very useful to the user. But I let it here is case, it becomes necessary again

init_iu()

Used in the initialization by __init__()

selectionchange(i)

Change the shown widget which represents each hydrological model (all widget are in a stack)

Parameters:i – the number of the model (0=no model, 1=hecras1d, 2= hecras2D,...)
send_log

A PyQt signal to send the log.

class src_GUI.hydro_GUI_2.LAMMI(path_prj, name_prj)

Bases: src_GUI.hydro_GUI_2.SubHydroW

The class LAMMI is there to manage the link between the graphical interface and the functions in src/lammi.py which loads the lammi data. It inherits from SubHydroW() so it have all the methods and the variables from the class SubHydroW().

drop_merge

A pyqtsignal which signal that hydro data from lammi is ready. The signal is for the bioinfo_tab and is collected by MainWindows1.py. Data from lammi contains substrate data.

init_iu()

Used by __init__() during the initialization.

load_lammi_gui()

This function loads the lammi data, save the text file to the xml project file and create the grid

show_dialog_lammi(i=0)

When using lammi data, the user selects a directory and not a file. Hence, we need to modify the ususal show_dialog function. Hence, function the show_dilaog_lammi() obtain the directory chosen by the user. This method open a dialog so that the user select a directory. The files are NOT loaded here. The name and path to the files are saved in an attribute.

Parameters:i – If i ==0, we obtain the Entree dirctory, if i == 1, the Resu directory.
class src_GUI.hydro_GUI_2.Mascaret(path_prj, name_prj)

Bases: src_GUI.hydro_GUI_2.SubHydroW

The class Mascaret is there to manage the link between the graphical interface and the functions in src/mascaret.py which loads the Masacret data in 1D. It inherits from SubHydroW() so it have all the methods and the variables from the class SubHydroW(). It is similar to the HEC-Ras1D class (see this class for more information). However, mascaret is 1D model, so the loading of mascaret has one additional step compared to the hec-ras load: The velocity must be distributed along the profile. For this, the load_masacret_gui call the self.distrbute _velocity function. In addition, it prepares the manning value which is necessary to distribute the velocity. The user has two choices to input the manning value. The easiest one is just to give a value constant for the whole river. In the second choice, the user loads a text file with a serie of lines with the following info: p, dist, n where p is the profile number (starting at zero), dist is the distance in meter along the profile and n in the manning value (see the method load_manning_text of the class SubHydroW for more information)

init_iu()

Used in the initialization by __init__()

load_mascaret_gui()

The function is used to load the mascaret data, calling the function contained in the script mascaret.py. It also create a 2D grid from the 1D data and distribute the velocity. All of theses tasks are done on a second thread to avoid freezing the GUI.

propose_next_file()

This function proposes the two other mascaret when the first is selected. If the user selects the first file, this function looks if a file with the same name but with the extension of the other file types exists in the selected folder.

class src_GUI.hydro_GUI_2.River2D(path_prj, name_prj)

Bases: src_GUI.hydro_GUI_2.SubHydroW

The class River2D t is there to manage the link between the graphical interface and the functions in src/river2D.py which loads the River2D data in 2D.

Technical comments

The class River2D inherits from SubHydroW() so it have all the methods and the variables from the class SubHydroW(). It is similar generally to the hec-ras2D class. However, the hydrological model River2D create one file per time step. Hence, it is necessary to have a way to load all the files automatically. Loading one file after one file would be annoying. There are four functions to manage the large number of file:

  • add_all_file: find all files in a folder selected by the user.
  • add_file_river2D: add just one selected file
  • Remove_all_file: remove all selected files
  • Remove_file: remove one selected file

None of this four functions load the data, it just add the name and path of the files to be loaded to self.namefile and self.pathfile. Generally, in HABBY, we load hydrological data in two steps: a) select the files, b) load the data. For river2D, the step b) is done by the function load_river2d_gui(). This function is similar to the one used by Rubar2D. It has the same problem about the grid which is identical for all time steps and which contains all reaches together. So a temporary correction was applied. Data in River2D is given on the nodes as in HABBY.

add_all_file()

The function finds all .cdg file in one directory to add there names to the list of files to be loaded

add_file_river2d()

This function is used to add one file to the list of file to be loaded. It let the user select one or more than one file, prepare some data for it and update the QWidgetList with the name of the file containted in the variable self.namefile.

We can not call show_dialog() direclty here as the user can select more than one file

add_file_to_list()

This function to add all file contained in self.namefile to the QWidgetlist. Called by add_file_river2D and add_all_file.

init_iu()

used by __init__ in the initialization

load_river2d_gui()

This function is used to load the river 2d data. It use a second thread to avoid freezing the GUI

remove_all_file()

This function removes all files from the list of files to be loaded and from the QlistWidget.

remove_file()

This is small function to remove one or more .cdg file from the list of files to be loaded and from the QlistWidget.

Technical Comments

The function selectedIndexes does not return an int but an object called QModelIndex. We should start removing object from the end of the list to avoid problem. However, it is not possible to sort QModelIndex. Hence, It is necessary to use the row() function to get the index as int.

class src_GUI.hydro_GUI_2.Rubar1D(path_prj, name_prj)

Bases: src_GUI.hydro_GUI_2.SubHydroW

The class Rubar1D is there to manage the link between the graphical interface and the functions in src/rubar.py which loads the Rubar1D data in 1D. It inherits from SubHydroW() so it have all the methods and the variables from the class SubHydroW(). It is very similar to Mascaret class.

init_iu()

Used in the initalizatin by __init__()

load_rubar1d()

A function to execute the loading and saving the the rubar file using rubar.py. After loading the data, it distribute the velocity along the profiles by calling self.distribute_velocity() and it created the 2D grid by calling the method self.grid_and_interpo.

propose_next_file()

This function proposes the other rubar file when the first is selected. If the user selects the first file, this function looks if a file of the form profil.name exist

class src_GUI.hydro_GUI_2.Rubar2D(path_prj, name_prj)

Bases: src_GUI.hydro_GUI_2.SubHydroW

The class Rubar2D is there to manage the link between the graphical interface and the functions in src/rubar.py which loads the RUBAR data in 2D. It inherits from SubHydroW() so it have all the methods and the variables from the class SubHydroW(). The form of the function is similar to hec-ras, but it does not have the part about the grid creation as we look here as the data created in 2D by RUBAR.

init_iu()

used by ___init__() in the initialization.

load_rubar()

A function to execture the loading and saving the the rubar file using rubar.py. It is similar to the load_hec_ras_gui() function. Obviously, it calls rubar and not hec_ras this time. A small difference is that the rubar2D outputs are only given in one grid for all time steps and all reaches. Moreover, it is necessary to cut the grid for each time step as a function of the wetted area and maybe to separate the grid by reaches. Another problem is that the data of Rubar2D is given on the cells of the grid and not the nodes. So we use linear interpolation to correct for this.

A second thread is used to avoid “freezing” the GUI.

propose_next_file()

This function proposes the second RUBAR file when the first is selected. Indeed, to load rubar, we need one file with the geometry data and one file with the simulation results. If the user selects a file, this function looks if a file with the same name but with the extension of the other file type exists in the selected folder.

class src_GUI.hydro_GUI_2.SubHydroW(path_prj, name_prj)

Bases: PyQt5.QtWidgets.QWidget

SubHydroW is class which is the parent of the classes which can be used to open the hydrological models. This class is a bit special. It is not called directly by HABBY but by the classes which load the hydrological data and which inherits from this class. The advantage of this architecture is that all the children classes can use the methods written in SubHydroW(). Indeed, all the children classes load hydrological data and therefore they are similar and can use similar functions.

In other word, there are MainWindows() which provides the windows around the widget and Hydro2W which provide the widget for the hydrological Tab and one class by hydrological model to really load the model. The latter classes have various methods in common, so they inherit from SubHydroW, this class.

create_image(save_fig=True, show_info=False)

This function is used to create the images related to the grid and the hydrology. It is called by send_data and recreate_image. This function exists because the two functions above have similar needs and that we do not copy too much codes. It can also show basic information about the data in the log windows and in the log file if the variable show_info is True.

Parameters:
  • save_fig – a boolean to save the figure or not
  • show_info – If True, basic information about the data will be displayed into the log window.
dis_enable_nb_profile()

This function enable and disable the QLineEdit where the user gives the number of additional profile needed to create the gird and the related QLabel. If the user choose the interpolation by bloc, the QLineEdit will be disabled. If it chooses linear or nearest neighbour interpolation, it will be enabled. Careful, this function only works with 1D and 1.5D model.

drop_hydro

A PyQtsignal signal for the substrate tab so it can account for the new hydrological info.

find_path_hdf5()

A function to find the path where to save the hdf5 file. Careful a simialar one is in estimhab_GUI.py. By default, path_hdf5 is in the project folder in the folder ‘hdf5_files’.

find_path_im()

A function to find the path where to save the figues. Careful a simialar one is in estimhab_GUI.py. By default, path_im is in the project folder in the folder ‘figure’.

This is practical to have in a function form as it should be called repeatably (in case the project have been changed since the last start of HABBY).

find_path_input()

A function to find the path where to save the input file. Careful a simialar one is in estimhab_GUI.py. By default, path_input indicates the folder ‘input’ in the project folder.

gethdf5_name_gui()

This function get the name of the hdf5 file for the hydrological and write down in the QLineEdit on the GUI. It is possible to have more than one hdf5 file for a model type. For example, we could have created two hdf5 based on hec-ras output. The default here is to write the last model loaded. It is the same default behaviour than for the function was_model_loaded_before(). To keep the coherence between the filename and hdf5 name, a change in this behaviour should be reflected in both function.

This function calls the function get_hdf5_name in the load_hdf5.py file

load_manning_text()

This function loads the manning data in case where manning number is not simply a constant. In this case, the manning parameter is given in a .txt file. The manning parameter used by 1D model such as mascaret or Rubar BE to distribute velocity along the profiles. The format of the txt file is “p, dist, n” where p is the profile number (start at zero), dist is the distance along the profile in meter and n is the manning value (in SI unit). One point per line so something like:

0, 150, 0.035

0, 200, 0.025

1, 120, 0.035, etc.

White space is neglected and a line starting with the character # is also neglected.

A very similar function to this ones exists in func_for_cmd. It is used to so the same thing but called from the cmd. Changes should be copied in both functions if necessary.

read_attribute_xml(att_here)

A function to read the text of an attribute in the xml project file.

Parameters:att_here – the attribute name (string).
recreate_image()

This function is used to recreate the images related to the grid and the hydrology. We do not call create_image directly as we might add other command here.

save_xml(i=0, append_name=False)

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 show_dialog.

Parameters:
  • i – a int for the case where there is more than one file to load
  • 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.
send_data()

This function is call regularly by the methods which have a second thread (so moslty the function to load the hydrological data). To call this functin regularly, the variable self.timer of QTimer type is used. The variable self.timer is connected to this function in the initiation of SubHydroW() and so in the initation of all class which inherits from SubHydroW().

This function just wait while the thread is alive. When it has terminated, it creates the figure and the error messages.

send_err_log(check_ok=False)

This function sends the errors and the warnings to the logs. The stdout was redirected to self.mystdout before calling this function. It only sends the hundred first errors to avoid freezing the GUI. A similar function exists in estimhab_GUI.py. Correct both if necessary.

Parameters:check_ok – This is an optional paramter. If True, it checks if the function returns any error
send_log

A Pyqtsignal to write the log.

show_dialog(i=0)

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.

Parameters:i – a int for the case where there is more than one file to load
show_fig

A PyQtsignal to show the figure.

was_model_loaded_before(i=0, many_file=False)

A function to test if the model loaded before. If yes, it updates the attibutes anf the widgets of the hydrological model on consideration.

Parameters:
  • i – an int used in cases where there is more than one file to load (geometry and output for example)
  • many_file – A bollean. If true this function will load more than one file, separated by ‘,’. If False, it will only loads the file of one model (see the comment below).

Technical comment

This method opens the xml project file and look in the attribute of the xml file to see if data from the hydrological model have been loaded before. If yes, the name of the data is written on the GUI of HABBY in the Widget related to the hydrological model. Now, there are often more than one data loaded. This method allows choosing what should be written. There are two different case to be separated: a) We have loaded two different models (like two rivers modeled by HEC-RAS) b) One model type needs two data file (like HEC-RAS would need a geometry and output data). For the case a), the default is to write only the last model loaded. If this default behaviour is changed, the behaviour of gethdf5_name_GUI should also be changed. If we wish to write all data, the switch “many_file” should be True. This switch is also useful for the river2D model, because this model create one output file per time step. For the case b), the argument “i”(which is an int) allows us to choose which data type should be shown. “i” is in the order of the self.attributexml variable. The definition of this order is given in the definition of the class of each hydrological model.

class src_GUI.hydro_GUI_2.SubstrateW(path_prj, name_prj)

Bases: src_GUI.hydro_GUI_2.SubHydroW

This is the widget used to load the substrate. It is practical to re-use some of the method from SubHydroW. So this class inherit from SubHydroW.

add_const_widgets()

This function shows the widgets realted to the loading of constatns subtrate

add_file_widgets()

This functions shows the widgets

btnstate(rb_sel, rb_del)

This function is used to select and deslect radiobutton :param rb_sel: the radio button which was just selected :param rb_del: the radio button which should be deselected

drop_merge

A pyqtsignal which signal that merged hydro data is ready. The signal is for the bioinfo_tab and is collected by MainWindows1.py.

get_att_name()

A function to get the attribute name of the shapefile which contains the substrate data. it is given by the user in the GUI.

get_attribute_from_shp()

This function opens a shapefile and obtain the attribute. It then update the GUI to reflect this and also update the label as needed.

init_iu()

Used in the initialization by __init__().

load_sub_gui(const_sub=False)

This function is used to load the substrate data. The substrate data can be in two forms: a) in the form of a shp file form ArGIS (or another GIS-program). b) in the form of a text file (x,y, substrate data line by line). Generally this function has some similarities to the functions used to load the hydrological data and it re-uses some of the methods developed for them.

It is possible to have a constant substrate if const_sub= True. In this case, an hdf5 is created with only the default value marked. This form of hdf5 file is then managed by the merge function.

Parameters:const_sub – If True, a constant substrate is being loaded. Usually it is set to False.
log_txt(code_type)

This function gives the log for the substrate in text form. this is in a function because it is used twice in the function load_sub_gui()

name_last_merge()

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.

recreate_image_sub(save_fig=False)

This function is used to recreate the image linked with the subtrate. So this is not the figure for the “merge” part, but only to show the substrat alone.

Param:save_fig: A boolean to save or not the figure
send_merge_grid()

This function calls the function merge grid in substrate.py. The goal is to have the substrate and hydrological data on the same grid. Hence, the hydrological grid will need to be cut to the form of the substrate grid.

This function can be slow so it call on a second thread.

update_sub_hdf5_name()

This function update the QComBox on substrate data which is on the substrate tab. The similiar function for hydrology is in Main_Windows_1.py as it is more practical to have it there to collect all the signals.

class src_GUI.hydro_GUI_2.TELEMAC(path_prj, name_prj)

Bases: src_GUI.hydro_GUI_2.SubHydroW

The class Telemac is there to manage the link between the graphical interface and the functions in src/selafin_habby1.py which loads the Telemac data in 2D. It inherits from SubHydroW() so it have all the methods and the variables from the class SubHydroW(). It is very similar to RUBAR2D class, but data from Telemac is on the node as in HABBY.

init_iu()

Used by __init__() during the initialization.

load_telemac_gui()

The function which call the function which load telemac and save the name of files in the project file

Figure Option - GUI

in src_GUI/output_fig_GUI.py

This python module lets the user select various options to create the figures, notably the colormap or the size of the text. It is also wehre the user select the needed outputs.

src_GUI.output_fig_GUI.create_default_figoption()

This function creates the default dictionnary of option for the figure.

src_GUI.output_fig_GUI.load_fig_option(path_prj, name_prj)

This function loads the figure option saved in the xml file and create a dictionnary will be given to the functions which create the figures to know the different options chosen by the user. If the options are not written, this function uses data by default which are in the fonction create_default_fig_options().

Parameters:
  • path_prj – the path to the xml project file
  • name_prj – the name to this file
Returns:

the dictionary containing the figure options

class src_GUI.output_fig_GUI.ProjectPropertiesDialog(path_prj, name_prj)

The class which support the creation and management of the output. It is notably used to select the options to create the figures.

check_uncheck(main_checkbox, other_checkbox)

This function is used to check a box when the user clied on it and unckeked another passed as parameter

Parameters:
  • main_checkbox – A QCheckBox which sould by selected
  • other_checkbox – A QCheckbox which should be “unticked” when main_checkbox is selected by the user
init_iu()
save_option_fig()

A function which save the options for the figures in the xlm project file. The options for the figures are contained in a dictionnary. The idea is to give this dictinnory in argument to all the fonction which create figures. In the xml project file, the options for the figures are saved under the attribute “Figure_Option”.

If you change things here, it is necessary to start a new project as the old projects will not be compatible. For the new version of HABBY, it will be necessary to insure compatibility by adding xml attribute.

send_log

A PyQtsignal used to write the log.

src_GUI.output_fig_GUI.set_lang_fig(nb_lang, path_prj, name_prj)

This function write in the xml file in which langugage the figures should be done. This is kept in the group of attribute in the Figure_Option :param lang: An int indicating the langugage (0 for english, 1 for french,...) :param path_prj: the path to the project :param name_prj: the name of the project

The Stathab model - GUI

in src_GUI/stathab_GUI.py

class src_GUI.stathab_GUI.StathabW(path_prj, name_prj)

The class to load and manage the widget controlling the Stathab model.

Technical comments

The class StathabW makes the link between the data prepared by the user for Stathab and the Stathab model which is in the src folder (stathab_c.py) using the graphical interface. Most of the Stathab input are given in form of text file. For more info on the preparation of text files for stathab, read the document called ‘stathabinfo.pdf”. To use Stathab in HABBY, all Stathab input should be in the same directory. The user select this directory (using the button “loadb”) and HABBY tries to find the file it needs. All found files are added to the list called “file found”. If file are missing, they are added to the “file still needed” list. The user can then select the fishes on which it wants to run stathab, then it run it by pressing on the “runb” button.

If file where loaded before by the user in the same project, StathabW looks for them and load them again. Here we can have two cases: a) the data was saved in hdf5 format (as it is done when a stathab run was done) and the path to this file noted in the xml project file. b) Only the name of the directory was written in the xml project file, indicated that data was loaded but not saved in hdf5 yet. HABBY manages both cases.

Next, we check in the xml project file where the folder to save the figure (path_im) is. In case, there are no path_im saved, Stathab create one folder to save the figure outputs. This should not be the usual case. Generally, path_im is created with the xml project file, but you cannot be sure.

There is a list of error message which are there for the case where the data which was loaded before do not exist anymore. For example, somebody erased the directory with the Stathab data in the meantime. In this case, a pop-up message open and warn the user.

An important attribute of StathabW() is self.mystathab. This is an object fo the stahab class. The stathab model, which is in the form of a class and not a function, will be run on this object.

StathabW inherit StatModUseful, which is a class mostly used to manage the exchange of the fish name between the two QListWidget (selected fish and available fish).

add_all_fish()

This function add the name of all known fish (the ones in Pref.txt) to the QListWidget. Careful, a similar function exists in Fstress_GUI. Modify both if needed.

change_riv_type()

This function manage the changes which needs to happends to the GUI when the user want to pass from tropical river to temperate river and vice-versa. Indeed the fish species and the input files are not the same for tropical and temperate river.

init_iu()
load_from_hdf5_gui()

This function calls from the GUI the load_stathab_from_hdf5 function. In addition to call the function to load the hdf5, it also updates the GUI according to the info contained in the hdf5.

Technical comments

This functino updates the Qlabel similarly to the function “load_from_txt_gui()”. It also loads the data calling the load_stathab_from_hdf5 function from the Stathab class in src. The info contains in the hdf5 file are now in the memory in various variables called self.mystathab.”something”. HABBY used them to update the GUI. First, it updates the list which contains the name of the reaches (self.list_re.). Next, it checks that each of the variable needed exists and that they contain some data. Afterwards, HABBY looks which preference file to use. Either, it will use the default preference file (contained in HABBY/biology) or a custom preference prepared by the user. This custom preference file should be in the same folder than the hdf5 file. When the preference file was found, HABBY reads all the fish type which are described and add their name to the self.list_f list which show the available fish to the user in the GUI. Finally it checks if all the variables were found or if some were missing

load_from_txt_gui()

The main roles of load_from_text_gui() are to call the load_function of the stathab class (which is in stathab_c.py in the folder src) and to call the function which create an hdf5 file. However, it does some modifications to the GUI before.

Technical comments

Here is the list of the modifications done to the graphical user interface before calling the load_function of Stathab.

First, it updates the label. Because a new directory was selected, we need to update the label containing the directory’s name. We only show the 30 last character of the directory name. In addition, we also need to update the other label. Indeed, it is possible that the data used by Stathab would be loaded from an hdf5 file. In this case, the labels on the top of the list of file are slightly modified. Here, we insure that we are in the “text” version since we will load the data from text file.

Next, it gets the name of all the reach and adds them to the list of reach name. For this, it calls a function from the stathab class (in src). Then, it looks which files are present and add them to the list which contains the reach name called self.list_re.

Afterwards, it checks if the files needed by Stathab are here. The list of file is given in the self.end_file_reach list. The form of the file is always the name of the reach + one item of self.end_file_reach. If it does not find all files, it add the name of the files not found to self.list_needed, so that the user can be aware of which file he needs. The exception is Pref.txt. If HABBY do not find it in the directory, it uses the default “Pref.txt”. All files (apart from Pref.txt) should be in the same directory. If the river is temperate, the files needed are not the same than if the river is in the tropic. This is accounted using the variable rivint. If rivint is zero, the river is temparate and this function looks for the file needed for temperate type (list of file contained in self.end_file_reach and self.name_file_allreach). If riverin is equal to 1 or 2, the river is tropical (list of file contained in self.end_file_reach_top and biological data in the stathab folder in the biology folder (many files). If the river is temperate, all preference coeff are in one file called Pref.txt (also in the stathab folder of the biology folder).

Then, it calls a method of the Stathab class (in src) which reads the “pref.txt” file and adds the name of the fish to the GUI. If the “tropical river” option is selected, it looks which preference file are present in self.path_bio_stathab. The name of the tropical preference file needs to be in this form: YuniYh_XXX.csv and YuniYh_XX.csv for the univariate case and YbivYXXX.csv for the bivarate where XX is the three letter fish code from ONEMA and Y is whatever string. The form of the preference file is the form from the R version of stathab 2.

Next, if all files are present, it loads the data using the method written in Stathab (in the src folder). When the data is loaded, it creates an hdf5 file from this data and save the name of this new hdf5 file in the xml project file (also using a method in the stathab class).

Finally, it sends the log info as explained in the log section of the documentation

reach_selected()

A function which indcates which files are linked with which reach.

Technical comment

This is a small function which only impacts the GUI. When a Stathab model has more than one reach, the user can click on the name of the reach. When he does this, HABBY selects the first file linked with this reach and shows it in self.list_f. This first file is highlighted and the list is scrolled down so that the files linked with the selected reach are shown. This function manages this. It is connected with the list self.list_re, which is the list with the name of the reaches.

recreate_image()

This function redo the figures from Stahtab

run_stathab_gui()

This is the function which calls the function to run the Stathab model. First it read the list called self.list_s. This is the list with the fishes selected by the user. Then, it calls the function to run stathab and the one to create the figure if the figures were asked by the user. Finally, it writes the log.

select_dir()

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.

select_hdf5()

This function allows the user to choose an hsdf5 file as input from Stathab.

Technical comment

This function is for example useful if the user would have created an hdf5 file for a Stathab model in another project and he would like to send the same model on other fish species.

This function writes the name of the new hdf5 file in the xml project file. It also notes that the last data loaded was of hdf5 type. This is useful when HABBY is restarting because it is possible to have a directory name and the address of an hdf5 file in the part of the xml project file concerning Stathab. HABBY should know if the last file loaded was this hdf5 or the files in the directory. Finally, it calls the function to load the hdf5 called load_from_hdf5_gui.

send_err_log()

Send the errors and warnings to the logs. It is useful to note that the stdout was redirected to self.mystdout.

send_log

A PyQtsignal used to write the log.

show_fig

A PyQtsignal used to show the figures.

FStress model - GUI

in src_GUI/fstress_GUI.py

class src_GUI.fstress_GUI.FstressW(path_prj, name_prj)

This class provides the graphical user interface for the habby version of Fstress. The Fstress model is described in fstress.py. FstressW just loads the data given by the user. He/She can write this data in the GUI or loads it from files. The following files are needed:

  • listriv.txt the list of the river (if the file does not exist, the river is called river1).
  • rivqwh.txt discharge, width, height for two discharge (measured) for each rivers.
  • rivdeb.txt max and min discharge.

FStress inherits from the class StatModUseful. This class is a “parent” class with some functions which are the same for estimhab and fstress. Hence, we can re-use these function without re.writing them (a bit like SubHydroW)

add_all_fish()

This function add the name of all known fish (the ones in Pref.txt) to the QListWidget which cintains selected fish. This function was copied from the one in SStathab_GUI.py

erase_name()

This function erases the data from the river selected by the user.

init_iu()

This function is used to initialized an instance of the FstressW() class. It is called by __init__(). It is very similar to EstihabW but it is possible to get more than one river and it can load the data from folder.

load_all_fish()

This function find the preference file, load the preference coefficient for each invertebrate and show their name on QListWidget. It is run at the start of the program. FStress cannot be run as long as a preference file is not found.

load_data_fstress(rind)

This function loads the data for fstress and add it to the variable self.qrange and self.qhw for the river rind. :param rind: The indices of the river is self.river_name. So it is which river should be loaded

load_hdf5_fstress()

This function loads an hdf5 file in the fstress format and add it to the project. This hdf5 file was not part of the project previously.

load_txt()

In this function, the user select a listriv.txt file. This files are loaded and written on the GUI.

Before it was also possible to select just one qhw file. This is still part of the code, but it is not advised to do this as the river name tends to mix each other, which is more trouble to maintain that it worths it. If a qhw.txt is loaded and if there are more than one qhw.txt in the folder, we ask the user if all files must be loaded.

The needed text files are the following:

  • listriv.txt is a text file with one river name by line
  • rivnameqhw.txt is a text file with minimum two lines which the measured discharge, height and width for 2 measureement (necessary)
  • rivernamedeb.txt is a text file which has two lines. The first line is the minimum discharge and the second is the maximum discharge to be modelled. It is chosen by the user (necessary to run, but can be given by the user on the GUI)

All data should be in SI unit.

modify_name()

This function is used to modify the name of a river. It will only be saved if FStress is run. Otherwise it is not kept in the data.

runsave_fstress()

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.py.

save_river_data()

This function save the data for one river based on the data from the GUI (i.e., after modification by the user). It can be used to save the data given directely by the user or modified by him.

show_data_one_river()

This function shows the qhw and the [qmin, qmax] data on the GUI for the river selected by the user. The river must have been loaded before. It also show the selected fish

update_list_riv()

This function is a small function to update the QCombobox which contains the river name

was_loaded_before()

This function looks in the xml project file is an hdf5 exists already. If yes, it loads this data and show it on the GUI.

Estimhab - GUI

in src_GUI/estimhab_GUI.py

class src_GUI.estimhab_GUI.EstimhabW(path_prj, name_prj)

The Estimhab class provides the graphical interface for the version of the Estimhab model written in HABBY. The Estimhab model is described elsewhere. EstimhabW() just loads the data for Estimhab given by the user.

change_folder()

A small method to change the folder which indicates where is the biological data

init_iu()

This function is used to initialized an instance of the EstimhabW() class. It is called by __init__().

Technical comments and walk-through

First we looked if some data for Estimhab was saved before by an user. If yes, we will fill the GUI with the information saved before. Estimhab information is saved in hdf5 file format and the path/name of the hdf5 file is saved in the xml project file. So we open the xml project file and look if the name of an hdf5 file was saved for Estimhab. If yes, the hdf5 file is read.

The format of hdf5 file is relatively simple. Each input data for Estimhab has its own dataset (qmes, hmes, wmes, q50, qrange, and substrate). Then, we have a list of string which are a code for the fish species which were analyzed. All the data contained in hdf5 file is loaded into variable.

The different label are written on the graphical interface. Then, two QListWidget are modified. The first list contains all the fish species on which HABBY has info (see XML Estimhab format for more info). The second list is the fish selected by the user on which Estimhab will be run. Here, we link these lists with two functions so that the user can select/deselect fish using the mouse. The function name are add_fish() and remove_fish().

Then, we fill the first list. HABBY look up all file of xml type in the “Path_bio” folder (the one indicated in the xml project file under the attribute “Path_bio”). The name are them modified so that the only the name of species appears (and not the full path). We set the layout with all the different QLineEdit where the user can write the needed data.

Estimhab model is saved using a function situated in MainWindows_1.py (frankly, I am not so sure why I did put the save function there, but anyway). So the save button just send a signal to MainWindows here, which save the data.

open_estimhab_hdf5()

This function opens the hdf5 data created by estimhab

run_estmihab()

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).

save_signal_estimhab

PyQtsignal to save the Estimhab data.

class src_GUI.estimhab_GUI.StatModUseful

This class is not called directly by HABBY, but it is the parent class of EstihabW and FstressW. As fstress and estimhab have a similar graphical user interface, this architecture allows to re-use some functions between the two classes, which saves a bit of coding.

add_fish()

The function is used to select a new fish species (or inverterbrate)

add_sel_fish()

This function loads the xml file and check if some fish were selected before. If yes, we add them to the list

check_all_q()

This function checks the range of the different discharge and send a warning if we are out of the range estimated reasonable (based on the manual from Estimhab and FStress). This is not used by Stathab.

It uses the variable self.qall which is a list of float composed of q1, q2, qsim1, qsim2, q50. This function only send warning and it used to check the entry before the calculation.

find_path_hdf5_est()

A function to find the path where to save the hdf5 file. Careful a simialar one is in hydro_GUI_2.py and in stathab_c. By default, path_hdf5 is in the project folder in the folder ‘hdf5_files’.

find_path_im_est()

A function to find the path where to save the figues. Careful there is similar function in hydro_GUI_2.py. Do not mix it up

Returns:path_im a string which indicates the path to the folder where are save the images.
find_path_input_est()

A function to find the path where to save the input file. Careful a simialar one is in estimhab_GUI.py. By default, path_input indicates the folder ‘input’ in the project folder.

find_path_output_est(att)

A function to find the path where to save the shapefile, paraview files and other future format. Here, we gave the xml attribute as argument so this functin can be used to find all path needed. However, it is less practical to use as the function above as one should remember the xml tribute to call this function. However, it can be practical to use to add new folder.

Parameters:att – the xml attribute (from the xml project file) linked to the path needed, without the .//
find_path_text_est()

A function to find the path where to save the hdf5 file. Careful a simialar one is in estimhab_GUI.py. By default, path_hdf5 is in the project folder in the folder ‘hdf5_files’.

remove_all_fish()

This function removes all fishes from the selected fish

remove_fish()

The function is used to remove fish species (or inverterbates species)

send_err_log()

This function sends the errors and the warnings to the logs. The stdout was redirected to self.mystdout before calling this function. It only sends the hundred first errors to avoid freezing the GUI. A similar function exists in hydro_GUI_2.py. Correct both if necessary.

send_log

PyQtsignal to write the log.

show_fig

PyQtsignal to show the figures.

Information Biological and Run habitat

in src_GUI/bio_info_GUI.py

This python module is where the biological info is managed and shown to the user. It is also where the user can run the habitat calculation.

class src_GUI.bio_info_GUI.BioInfo(path_prj, name_prj, lang='French')

This class contains the tab with the biological information (the curves of preference). It inherites from StatModUseful. StatModuseful is a QWidget, with some practical signal (send_log and show_fig) and some functions to find path_im and path_bio (the path wher to save image) and to manage lists.

get_autocompletion()

This function update the auto-complexton model as a function of the QComboxBox next to it

get_list_merge

A Pyqtsignal which indicates to chronice_GUI.py that the merge list should be changed. In Main_Windows.py, the new list of merge file is found and send to the ChonicleGui class.

init_iu()

Used in the initialization by __init__()

next_completion()

A small function to use the enter key to select the fish with auto-completion. Adapted from https://stackoverflow.com/questions/9044001/qcompleter-and-tab-key It would be nice to mek it work with tab also but it si quite complcated because it is quite complicated.

recreate_fig()

This function use show_image_hab() to recreate the habitat figures shown before

run_habitat_value()

This function runs HABBY to get the habitat value based on the data in a “merged” hdf5 file and the chosen preference files.

We should not add a comma in the name of the selected fish.

select_fish()

This function select the fish which corresponds at the chosen criteria by the user. The type of criteria is given in the list self.keys and the criteria is given in self.cond1. The condition should exactly match the criteria. Sign such as * does not work.

show_hydrosignature()

This function make the link with function in bio_info.py which allows to load and plot the data realted to the hydrosignature.

show_image_hab()

This function is linked with the timer started in run_habitat_value. It is run regulary and check if the function on the second thread have finised created the figures. If yes, this function create the 1d figure for the HABBY GUI.

show_info_fish(select=False)

This function shows the useful information concerning the selected fish on the GUI.

:param select:If False, the selected items comes from the QListWidgetcontaining the available fish.
If True, the items comes the QListWidget with the selected fish
show_info_fish_avai()

This function shows the useful information concerning the available fish on the GUI and add the fish to the selected fish This is what happens when the user click on the first QListWidget (the one called available fish).

show_info_fish_sel()

This function shows the useful information concerning the already selected fish on the GUI and remove the selected fish from the list of selected fish. This is what happens when the user click on the second QListWidget (the one called selected fish and guild).

show_pref()

This function shows the image of the preference curve of the selected xml file. For this it calls, the functions read_pref and figure_pref of bio_info.py. Hence, this function justs makes the link between the GUI and the functions effectively doing the image.

update_merge_list()

This function goes in the projet xml file and gets all available merged data. Usually, it is called by Substrate() (when finished to merge some data) or at the start of HABBY.

We add a “tooltip” which indicates the orginal hydraulic and substrate files.

Biological data - Estimhab

The biological data, i.e., the preference curves of Estimhab, are saved in xml files situated in the folder given by the path written in the xml project file under the attribute Path_bio. By default, it is HABBY/biology. It is possible to change this folder using the GUI.

Estimhab is a statistical model, which functions using mathematical regressions. The different regressions (or preference curve) of each fish are described in an xml file whose format is given here.

Conceptually, the regressions R are of two types:

  • Type 0 R = C * Q^{m1} * exp(m2*Q)
  • Type 1 R = C * (1+m1*exp(m2*Q))

Where Q is the discharge, m1 and m2 are coefficients which depend on the fish type, and C is a constant which depends on the stream characteristic and the fish type.

The constant C is of the form C = a + sum ai * ln(Si) where a and ai are coefficients which depend on the fish type. Si are particular stream characteristics. Which characteristics should be used is a function of the fish type and is so given in the xml file. The value of S i is a function of the stream and is calculated by the program.

In the xml file,

  • Attribute coeff_q: Give the main coefficients of the regression (m1 and m2)
  • Attribute func_q : Give the type of regression R used. Type 0 and type 1, as described above, are known by HABBY.
  • Attribute coeff_const: Give the coefficient used to construct the constant C (a, a1, a2, a3,…). The number of coefficient differs for each fish, but should be at least one.
  • Attribute var_const: Give which type of stream characteristics is used. This is not the value of the particular characteristic, but only which type is used. The following list of type is accepted:
    • 0 for Q50, natural median discharge
    • 1 for H50, the height of the stream at q50
    • 2 for L50, the width of the stream at q50
    • 3 for V50, the velocity of the stream at q50
    • 4 for Re50, the discharge divided by 10 times the width at Q50
    • 5 for Fr50, the Froude number at Q50
    • 6 for Dh50, the mean substrate height divided by h50
    • 7 for Exp(Dh50). Erase the log() of this particular term of the constant

Calculation of fish’s habitat

The src folder contains the python module which are not linked with the graphical user interface.

Hec-ras model 1D

in src/Hec_ras06.py

This module contains the functions used to load the outputs from the hec-ras model in 1.5D.

src.Hec_ras06.coord_profile_non_georeferenced(data_bank_all, data_dist_all, data_river_all, data_profile_all, nb_pro_reach)

This is a function to create the coordinates of the profile in the non-georeferenced case. This function is called by open geo_file(). Hypothesis: The profile are straight and perpendicular to the river. The last profile is at the end of the river.

Parameters:
  • data_bank_all – distance along the profile of bank station
  • data_dist_all – the distance between the profile (left, center channel, right)
  • data_river_all – the coordinate of the river
  • data_profile_all – the (d,z) data of the profile
  • nb_pro_reach – the number of profile by reach
Returns:

the coordinates of the profile

Technical comments

For each profile, we create an array composed of five points: Start of profile, left bank, intersection between river and profile, right bank and end of profile. The intersection with the river is directly given as input to the function. Then we find the vector perpendicular to this river and we get the four other points on the same line.

To get the distance for these four other point, we must be careful to pass from the distance given in meter and the distance in the model coordinates (scaled between [0, 1] usually). The way to go from one coordinate system to another is to use the “alpha” variable. We only need to correct distance, no problem with a system of coordinate which would not be in the same direction (as the data is given along a profile). The river passes in the middle of the right and left bank, so we can find where is left and right bank is. Because we know the total length of the profile, we can also find the beginning and end of the profile.

src.Hec_ras06.figure_xml(data_profile, coord_pro_old, coord_r, xy_h_all, zone_v_all, pro, path_im, fig_opt, nb_sim=0, name_profile='no_name', coord_p2=-99)

A function to plot the results of the loading of hec-ras data.

Parameters:
  • data_profile – (list with np.array)
  • coord_pro_old – (x,y) data of the profile (list with np.array)
  • coord_r – (x,y) data of the river (list with np.array)
  • xy_h_all – (x,y, h) for the height data for each simulation (list with np.array)
  • zone_v_all – (x,y, v) for the velocity data. velocity is by zone of profile. for each simulation. the (x,y) indicates the start of the zone which end with the next velocity
  • pro – a list of int with the profile whcih should be ploted [2,3,4]
  • nb_sim – which simulation should be plotted. In fact, it often relates to the time step.
  • name_profile – a list of string with the name of the profiles
  • coord_p2 – the data of the profile when non geo-referenced, optional
  • path_im – the path where the figure should be saved (string)
  • fig_opt – the figure options

Technical comments

We first choose the size of the font to be written. At term, it should be given by the options.

Two main groups of figure will be done: One list of figure with the form of the profil, the water height, and the velocity for the chosen profiles and one (x,y) view of the position of each profile.

We chose the time step to be written (the variable nb_sim here). The variable pro is a list which says which profiles are to be plotted. Hence, we get the velocity and water height for the time step and profile of interest.

To plot the velocity, we first get the distance along the profile where the water level cut the profile elevation. This is the variable xint1 and xint2. We then get the velocity data for the region under the water. We add three points for velocity at 0, xint1 and xint2. We then used the step function to plot the vecloity. Because of the added point, we will have a zero velocity from 0 to xint1, then the velocity data, then again zeros from xint2 to the end.

To plot the elevation of the profile, we plot the variable xz and we use the function fill_between to fill in blue the region under water. This function creates a line at the water elevation and fills in blue between this line and the profile elevation. We add some titles and save the figures.

For the second type of figure (view in x,y coordinates), We first plot the river position which is saved in the coord_r variable. Then we plot the coordinate of each profile and their names. If the name of the profile is not known, we plot the profile number. We also plot the position of each velocity data and height data (as it could be useful). If the figure gets too complicated, this can be taken away by changing the two lines which finish with height or velocity as comment. We add some titles and save the figures.

src.Hec_ras06.find_coord_height_velocity(coord_pro, data_profile, vel, wse, nb_sim, max_vel_dist=0)

This function finds the coordinates of the height/velocity. In hec-ras outputs the data are often written in the form (profile, distance along the profile, data). This function passes this type of information in the usual coordinate form.

Parameters:
  • coord_pro – the coordinate (x,y) of the profile. List of np.array.
  • data_profile – data concening the geometry of the profile, notably its elevation (x,z). List of np.array.
  • vel – the velocity data. List of np.array.
  • wse – the water surface elevation. List of np.array.
  • nb_sim – the number of simulation in case there is more than one
  • max_vel_dist – the minimum number of velocity point by ten meter before a warnings appears
Returns:

for each simulation, a list of np.array representing (x,y,v) and (x,y,h,)

Technical comments

This is a function called after having loaded the data. Hec-Ras present the data in (profil, distance along profile, data) form for the height. For the velocity, it is similar but the distance is given by a number between 0 and 1 (0 is the start of the profile, 1 is the end of the profile). This function transforms this data in the form (x,y, dist, data) using the (x,y) coordinates given in the coord_pro variable. In other word, we have the coordinate of the profile, not of the coordinates of the height and velocity data.

First, we get the distance between all points in (x,y) system. Then, we get the length of the profile in meter or feet. It is possible to have a (x,y) coordinate system in a different unit. Hence, the length of the profil is valid for the (profile, distance along profile, data) view. We multiply the velocity distance data by this length. Hence, the distance information is now in meter or feet along the profile for water height and velocity.

There are some lines added to account for the last and first points of the profile (annoying in hec-ras). We then calculate the new coordinates. For each velocity and water height point, we find the last known point in the (x,y) coordinates. We do a vectorial addition from this point plus the vector between this point and the next multiplied by the distance from this point to the point that we tried to calculate. The variable alpha is used to pass from one coordinate system to the next one.

Careful the height is on the node and the velocity is by zone.

src.Hec_ras06.get_rid_of_white_space(stream_str)

This is a small fonction to get rid of white space at the end of name which could contain white space. Not used anymore as str.strip() functions well. But, as it was done already, we let it here.

Parameters:stream_str – the name of the string
Returns:the same name without white space.
src.Hec_ras06.load_xml(xml_file, path)

This is a function used by openxml_file and opengml_file to load an xml file.

Parameters:
  • xml_file – the name of an xml file (string)
  • path – the path where the xml file is (string)
Returns:

the loaded data from the XML file in the form of the root of the xml file.

src.Hec_ras06.main()

This is not the main() of HABBY. This function is used to test this module independently of the rest of HABBY.

src.Hec_ras06.open_geofile(geo_file, path)

This function opens the geometry file (.g0X) from Hecr-rad. It extracts the (x,z) from each profile and the (x,y) if georeferenced,

Parameters:
  • geo_file – the name of the Hec-Ras geometry file (string)
  • path – the path to the geo file (string)
Returns:

A list with each river profile (each profile is represented by a numpy array with the x and the altitude of each point in the profile), the coordinate of the profile (list of np.array), the coordinate of the river and the name of the reaches/ river in the file order (list of string)

Technical comments

The geofile is a text file with contains the geographical information. Because it is written to be read by human, it is complicated to load and regular expression are needed. It is written profile by profile.

Generally, to give a position, hec-ras indicates the profile number and the distance along this profile. In addition, data can be georeferenced or not. If it is geo-referenced we have some data in an (x,y) form. Otherwise, we only have geometrical data in the form (profile, dist).

First, for each profile, we get the elevation of the points forming each profile in the form (dist, elevation). The list of elevation for each profile starts with the keyword “Sta/Elev”. The data found in the text file is in a string format. We use the function pass_in_float_from_geo to pass it in float. It is usually done using the function float. However, there are cases where there are no space between two number. However, in this case, the number of character per number is constant. In this case, we separate the number first.

Then, we get the coordinate of the river. If no coordinate are available the river is assumed to be straight. Next, we get the bank limit (even if we do not really used afterwards), and the name of the reach. It is also important to save the order in which the names of the reach are given. Indeed, we want this order to be the same in all functions, but they can be different between the geo file and the data output.

Next, we want to get the position (x,y) of each profile. If it is georeferenced, we will be able to get this position directly from the file and put it in the data_dist_str variable. We will then pass it to float. If not, we will use the function coord_profil_non_georeferenced to estimate the position of the profile (see below).

If the profile is not georeferenced, it is important to have the distance between two profile, so we extract the information from the geo file in all cases (georeferenced or not). The last profile of a reach does not have a distance to the next (not existing) profile. However, if a profile does not have a distance to the next profile and is not the last profile, we ignore this profile. It is usually not a problem because this profile is usually not a “real” profile, but the representation of a bridge or a culvert.

src.Hec_ras06.open_hec_hec_ras_and_create_grid(name_hdf5, path_hdf5, name_prj, path_prj, model_type, namefile, pathfile, interpo_choice, path_im, save_fig1d, pro_add=1, q=[], print_cmd=False, fig_opt=[])

This function open the hec_ras data and creates the 2D grid from the 1.5 data. It is called by the class HEC_RAS1D in a second thread to not freeze the GUI.

Parameters:
  • name_hdf5 – the name of the hdf5 to be created (string)
  • path_hdf5 – the path to the hdf5 to be created (string)
  • model_type – the name of the model (hec_ras in most case, but given as argument in case we change the form of the name)
  • name_prj – the name of the project (string)
  • path_prj – the path of the project
  • namefile – the name of the geo file and the data file, which contains respectively geographical data and the ouput data (see open_hec_ras() for more precision) -> list of string
  • pathfile – the absolute path to the file chosen into namefile
  • interpo_choice – the interpolation type (int: 0,1,2 or 3). See grid_and_interpo() for mroe details.
  • path_im – the path to where to save the image
  • save_fig1d – create and save the figure related to the loading of the data (profile and so on)
  • pro_add – the number of addictional profile (one used for interpolation_choice 1 and 2)
  • q – used in the second thread
  • print_cmd – if True the print command is directed in the cmd, False if directed to the GUI
  • fig_opt – the options to crete the figure if save_fig1d is True

** Technical comments**

This function redirect the sys.stdout. The point of doing this is because this function will be call by the GUI or by the cmd. If it is called by the GUI, we want the output to be redirected to the windows for the log under HABBY. If it is called by the cmd, we want the print function to be sent to the command line. We make the switch here.

src.Hec_ras06.open_hecras(geo_file, res_file, path_geo, path_res, path_im, save_fig=False, fig_opt=[])

This function will open HEC-RAS outputs, i.e. the .geo file and the outputs (either .XML, .sdf or .rep) from HEC-RAS. All arguments from this function are string.

Parameters:
  • geo_file – the name of .goX (example .go3) file which is an output from hec-ras containg the profile data
  • res_file – the name of O0X.xml file for the name of the .sdf file or the name of the .rep file (output data)
  • path_res – path to the result file
  • path_geo – path to the geo file
  • path_im – the path to the folder where the images should be saved
  • save_fig – if True image is saved
  • fig_opt – the figure option is save_fig is True
Returns:

coord_pro (for each profile, x,y,elev, dist along the profile), vh_pro (for each profile, dist along the profile, water height, velocity). Both variable are a list of numpy array.

How to obtain the input files

To obtain the xml file in HEC-RAS version 4:

  • open the project in HEC-RAS.
  • click on File , then export geometry and result (RAS Mapper), then OK

To obtain the sdf file in HEC-RAS version 5 which should be used if the model is georeferenced:

  • click on File, then Export GIS data
  • Export all reaches (select Reaches to export -. Full List -> Ok)
  • Export all needed profile (select Profile to export -> Select all -> ok)

To obtain the report file .rep in HEC-RAS version which should be used if the model is NOT geo-referenced

  • click on File, generate report
  • Select Flow data and Geometry data in input data and, in Specific Table, select Flow distribution and Cross section Table

Technical comments

This is function which loads the hec_ras inputs in 1D for the version 4 and 5 of HEC-RAS. It accepts different type of hec-ras output as input and calls the appropriate sub-function for each input file. The geometrical data is always given in the geo file (with the extension g01, G01, g02, G02, g03, etc.). The output data can be in an xml file for the hec-ras in the version 4, an sdf file for hec-ras in version 5 or a .rep file in the version 5 if the model is not georeferenced. The xml file is the format which has been tested the most.

First, it loads the geometrical data. Then it select the function to load the output data and loads it. Then, it transforms the loaded data in a (x,y) coordinates system. Indeed, most of the data in hec-ras is given by indicating a profile (which crossed the modelled river) and the distance along this profile. For HABBY, it is better to get (x,y) coordinates. Then it create figure if asked by the switch “save_fig”. Finally, it updates the forms of the output to be coherent with the dist_velocity_hecras function. This way, in HABBY, the output from mascaret and rubar after the velocity distribution have the same form than the output from hec-ras, which is useful afterwards to save all these data in the hdf5 file.

src.Hec_ras06.open_repfile(report_file, reach_name, path, data_profile, data_bank)

A function to open the report file (.rep) from HEC-RAS. To obtain the report file, see the doc of the function open_hecras.

Parameters:
  • report_file – a string with the name of the report file (.rep)
  • reach_name – a list of string containing the name of the reaches/rivers in the order of the geo file, which might not be the order of the sdf file.
  • path – the path where the report file is stored (string)
  • data_profile – the data from each profile from the geofile (output from the open_geofile function)
  • data_bank – the position of the bank limit (output from the open_geofile function)
Returns:

velocity and the water surface elevation for each river profiles in a list of np.array, the number of simulation (int) and the name of the river profile (list of string)

Technical comments and walk-through

This function is used to open output from models which were not geo-referenced in hec-ras v5. It cannot be used if the model was georeferenced (or at least one should make some tests before).

First, we obtain the water height. Then, we obtain the number of time step (which is called the number of simulation by hec-ras). To get the number of time step, we count each outputs given (one by profiles) and we divided it by the number of profile in the river. It is a bit indirect, but I did not find a simpler solution.

We get the name of each profile and reach. Then, we get the velocity data. We have in a case which is not geo-referenced. By consequence, there are only three velocities: one the left bank, one in the main river channel and one the right bank. Next we get the distance along the profile for these three velocities. Finally, we use the function reoder_reach for the same reason than in open_sdffile and open_xml.

src.Hec_ras06.open_sdffile(sdf_file, reach_name, path)

This is a function to load .sdf file from HEC-RAS v5 used if the model is georeferenced. To find how to obtain the sdf file, read the doc of open_hecras.

Parameters:
  • sdf_file – the name of the sdf file (string)
  • reach_name – a list of string containing the name of the reaches/rivers in the order of the geo file which might not be the one of the sdf file. Output from open_geofile.
  • path – the path where the file is stored (string)
Returns:

velocity, water height, river_name, number of time step (nb_sim)

Technical comments

To strat loading the sdf file, we open the sdf file. It is mostly a text file. Then we find velocity data and we pass this velocity data from string to float. The process is a bit similar to the one used in the function open_geofile with a healthy dose of regular expressions. We do this again for height data.

We also extract the name of the river, reaches and profile. The number of simulation (nb_sim) is a bit confusing for a variable name. In fact, it is the number of time step. Hec-Ras considers that one simulation is the simulation for one time step. Hence, nb_sim is more or less nb_timestep.

As in the xml file, we finally re-order the data as in the geo file. Indeed, it is possible to have different order between the reaches in the geo file and in the sdf file. Here, we use the function reorder_reach for this.

src.Hec_ras06.open_xmlfile(xml_file, reach_name, path)

This function open the xml file from HEC-RAS v4 to get the velocity and water surface elevation. To know how to obtain this xml file, read the doc of open_hecras.

Parameters:
  • xml_file – the name of O0X.xml file from HEC-RAS. (string)
  • reach_name – a list of string containing the name of the reaches/rivers in the order of the geo file which might not be the one of the xml file.
  • path – path to the xml file (string)
Returns:

velocity and the water surface elevation for each river profiles (list of np.array), the number of simulation(int) and the name of the river profile (list of string)

Technical comments

To load the xml file, we first call the load_xml function. It is a function which check that the xml file is well formed and which return the “root” part fo the xml. With this “root”, it is possible to load other part of the xml file using the Etree module.

Then, we load the velocity and water height data from the xml file. We also load the name of the profiles and of the reach names. Next, we pass the data into float. For each velocity of height point, we get its position along the profile (see below for format) and the value at this point.

Finally, we re-order the data as in the geo file. Indeed, it is possible to have different order between the reaches in the geo file and in the xml file. The last part of this function is there to order all the data as in the geo file. There is a function reorder_reach which does something similar, but could not be used by the output from the xml file (it is slighty different). However the reorder_reach function and this part of the open_xml function is very similar.

src.Hec_ras06.pass_in_float_from_geo(data_str, len_number)

This is a function to pass the string data into float for open_geofile() and open_sdffile(). It is in a function because it is possible that two number are not separated by a space in the input data.

Parameters:
  • data_str – the data in a string form
  • len_number – the number of digit for one number (int)
Returns:

a np.array of float with 2 columns (x,y) or (x,z)

src.Hec_ras06.reorder_reach(wse, vel, riv_name, reach_name, reach_str, stream_str, nb_sim)

The order of the reach in HABBY is in the order given in the geo file. However, it can be given in any order in the other file. (xml, sdf, rep,...). This function re-order the reaches based on their name.

Parameters:
  • wse – water height data (list of np.array for each profile)
  • vel – velocity data (list of np.array for each profile)
  • riv_name – the name of the profile (yeah I know it is not really logical as a name)
  • reach_name – the name of the reach and stream (stream,reach) in the geo file order
  • reach_str – the name of the reach in the anaylsed file order
  • stream_str – the name of the stream in the anaylsed file order
  • nb_sim – the number of simulation
Returns:

wse, vel, riv_name all re-ordered

Technical comments

The reach name should not have white space at the end/start but can have white space into them.

src.Hec_ras06.update_output(zone_v, coord_pro_old, data_profile, xy_h, nb_pro_reach_old)

This function updates the form of the output so it is coherent with mascaret and rubar after the lateral distribution of velocity for these two models. There are three important changes. First, coord_pro contains dist along the profile (x) and height in addition to the coordinates. Secondly, vh_pro contains only height if height is above or equal to zero. Thirdly, a point is created at the water limits and v and height are given at the same points. nb_pro_reach is also modified as in mascaret. We want to modify it so it start by zero and is additive, i.e., that it gives total number of profile before, not the number of profile by reach.

Parameters:
  • zone_v – (x,y, dist along profile, v) for each time step. However, the zone are the one from the models. They are different than the one from xy_h, which is unpractical for the rest of HABBY.
  • coord_pro_old – the (x,y) coordinate for the profile
  • data_profile – the distance along the porfile and height of each profile
  • xy_h – the water height
  • nb_pro_reach_old – the number of the profile by reach in the old form.
Returns:

coord_pro, vh_pro, nb_pro_reach

[doc to be finished]

Notes on hec-ras outputs

  • Data in HEC-RAS can be geo-referenced or not georeferenced. It is advised to geo-reference all model in HEC-RAS. If the model is not geo-referenced, the function makes some assumptions to load the data: 1) the river profile are straight and perpendicular to the river. 2) the last profile is at the end of the river.
  • To geo-reference a model in hec_ras: In the “geometric data” window, GIS tool, GIS Cut Line, Accept Display location, choose all profile
  • Numerical data are sometime not separated (0.4556 0.3453233.454 05.343). In this case, the number of digit is assumed to be 8 for the profile and 16 for the river coordinates.
  • Part of the profile can be vertical: The function also functions in this case.
  • There is sometimes more than one reach in the modelled river and these reaches sometimes form loops: The function load each reach one after the other.
  • The river reaches are sometimes not in the same order in the xml file and in the .goX file. The order of the .goX is used by the function. Reach are automatically re-ordered.
  • If the river is straight, the coordinates of the river are given differently. The function try to load the river in the “straight” style if the usual style fail.
  • The .goX file includes data on bridges and culvert. Currently, the function neglects this information.
  • Sometimes distances between profiles are not given in the .goX file. The function neglects the distance data of this profile as long as it is not the last profile.
  • The velocity data for the end and the beginning of the river profile is indicated by a large number (example 1.23e35 or -1.234e36). The function considers that velocity info is situated at the start of the profile if x>-1e30 and at the end of the profile if x> 1e30.
  • There are two concepts called “profile” in HEC-RAS: The river profiles and the simulation profiles. The river profiles are the geometry perpendicular to the river and the simulation profile are the different simulations.
  • Data in many of the example cases of HEC-RAS are in foot and miles. 1 miles = 5280 foot, and not 1000 foot.

Hec-ras model 2D

in src/Hec_ras2D.py

This module contains the functions used to load the outputs from the hec-ras model in 2D.

src.hec_ras2D.figure_hec_ras2d(v_all, h_all, elev_all, coord_p_all, coord_c_all, ikle_all, path_im, time_step=[0], flow_area=[0], max_point=-99)

This is a function to plot figure of the output from hec-ras 2D. This function is only used to debug, not directly by HABBY.

Parameters:
  • v_all – a list of np array representing the velocity at the center of the cells
  • h_all – a list of np array representing the water depth at the center of the cells
  • elev_all – a list of np array representing the mimium elevation of each cells
  • coord_p_all – a list of np array representing the coordinates of the points of the grid
  • coord_c_all – a list of np array representing the coordinates of the centers of the grid
  • ikle_all – a list of np array representing the connectivity table one array by flow area
  • time_step – which time_step should be plotted (default, the first one)
  • flow_area – which flow_area should be plotted (default, the first one)
  • max_point – the number of cell to be drawn when reconstructing the grid (it might long)
  • path_im – the path where the figure should be saved

Technical comment

This function creates three figures which represent: a) the grid of the loaded models b) the water height and c) the velocity.

The two last figures will be modified when the data will be loaded by node and not by cells. So we will not explai n them here as they should be re-written.

The first figure is used to plot the gird. If we would plot the grid by drawing one side of each triangle separately, it would be very long to draw. To optimize the process, we use the prepare_grid function.

src.hec_ras2D.get_triangular_grid_hecras(ikle_all, coord_c_all, point_all, h, v)

In Hec-ras, it is possible to have non-triangular cells, often rectangular cells This function transform the “mixed” grid to a triangular grid. For this, it uses the centroid of each cell with more than three side and it create a triangle by side (linked with the center of the cell). A similar function exists in rubar.py, but, as there are only one reach in rubar and because ikle is different in hec-ras, it was hard to marge both functions together.

Parameters:
  • ikle_all – the connectivity table by reach (list of np.array)
  • coord_c_all – the coordinate of the centroid of the cell by reach
  • point_all – the points of the grid
  • h – data on water height by reach by time step
  • v – data on velocity by reach by time step
Returns:

the updated ikle, coord_c (the center of the cell , must be updated ) and xy (the grid coordinate)

src.hec_ras2D.load_hec_ras2d(filename, path)

The goal of this function is to load 2D data from Hec-RAS in the version 5.

Parameters:
  • filename – the name of the file containg the results of HEC-RAS in 2D. (string)
  • path – the path where the file is (string)
Returns:

velocity and height at the center of the cells, the coordinate of the point of the cells, the coordinates of the center of the cells and the connectivity table. Each output is a list of numpy array (one array by 2D flow area)

How to obtain the input file

The file neede as input is an hdf5 file (.hdf) created automatically by Hec-Ras. There are many .hdf created by Hec-Ras. The one to choose is the one with the extension p0X.hdf (not g0x.hdf). It is usually the largest file in the results folder.

Technical comments

Outputs from HEC-RAS in 2D are in the hdf5 format. However, it is not possible to directly use the output of HEC-RAS as an hdf5 input for HABBY. Indeed, even if they are both in hdf5, the formats of the hdf5 files are different (and would miss some important info for HABBY). So we still need to load the HEC-RAS data in HABBY even if in 2D.

This function call the function get_trianglar grid which is in rubar.py.

Walk-through

The name and path of the file is given as input to the load_hec_ras_2D function. Usually this is done by the class HEC_RAS() in the GUI. We load the file using the h5py module. This module opens and reads hdf5 file.

Then we can read different part of the hdf5 file when we know the address of it (this is a bit like a file system). In hdf5 file of Hec-RAS, this first thing is to get the names of the flow area in “Geometry/2D Flow Area”. In general, this is the name of each reach, but it could be lake or pond also. In an hdf5 file, to see the name of the member in a group, use: list(“group”.keys())

Then, we go to “Geometry/2D Flow Area/<name>/FacePoint Coordinates” to get the points forming the grid. We can also get the connectivity table (or ikle) to the path “Geometry/2D Flow Area/<name>/Cells Face Point Indexes” We also get the elevations of the cells. However, this is just the minimum elevation of the cells, so it is to be used only for a quick estimation. We then get the water depth by cell. The velocity is given by face of the cells and is averaged to get it on the middle of the cells.

To get Hec-Ras data by nodes, it is necessary to intepolate the data. There is a function to do this in manage_grid_8.

src.hec_ras2D.load_hec_ras_2d_and_cut_grid(name_hdf5, filename, path, name_prj, path_prj, model_type, nb_dim, path_hdf5, q=[], print_cmd=False, fig_opt={})

This function calls load_hec_ras_2d and the cut_2d_grid function. Hence, it loads the data, pass it from cell to node (as data output in hec-ras is by cells) and it cut the grid to get only the wetted area. This was done before in the HEC_RAS2D Class in hydro_gui_2.py, but it was necessary to create a separate function to called this task in a second thread to avoid freezing the GUI.

Parameters:
  • name_hdf5 – the base name of the created hdf5 (string)
  • filename – the name of the file containg the results of HEC-RAS in 2D. (string)
  • path – the path where the file is (string)
  • name_prj – the name of the project (string)
  • path_prj – the path of the project
  • model_type – the name of the model such as Rubar, hec-ras, etc. (string)
  • nb_dim – the number of dimension (model, 1D, 1,5D, 2D) in a float
  • path_hdf5 – A string which gives the adress to the folder in which to save the hdf5
  • q – used by the second thread to get the error back to the GUI at the end of the thread
  • print_cmd – If True will print the error and warning to the cmd. If False, send it to the GUI.
  • fig_opt – the figure option, used here to get the minimum water height to have a wet node (can be > 0)

** Technical comments**

This function redirect the sys.stdout. The point of doing this is because this function will be call by the GUI or by the cmd. If it is called by the GUI, we want the output to be redirected to the windoows for the log under HABBY. If it is called by the cmd, we want the print function to be sent to the command line.

src.hec_ras2D.main()

Used to test this module independantly of HABBY.

src.hec_ras2D.prepare_grid(ikle, coord_p, max_point=-99)

This is a function to put in the new form the data forming the grid to accelerate the plotting of the grid. This function creates a list of points of the grid which are re-ordered compared to the usual list of grid point (the variable coord_p here). These points are reordered so that it is possible to draw only one line to form the grid (one point can appears more than once). The grid is drawn as one long line and not as a succession of small lines, which is quicker. When this new list is created by prepare_function(), it is send back to figure-hec_ras_2D and plotted.

Parameters:
  • ikle – the connectivity table
  • coord_p – the coordinates of the point
  • max_point – if the grid is very big, it is possible to only plot the first points, up to max_points (int)
Returns:

a list of x and y coordinates ordered.

src.hec_ras2D.scatter_plot(coord, data, data_name, my_cmap, s1, t)

The function to plot the scatter of the data. Will not be used in the final version, but can be useful to plot data by cells.

Parameters:
  • coord – the coordinates of the point
  • data – the data to be plotted (np.array)
  • data_name – the name of the data (string)
  • my_cmap – the color map (string with matplotlib colormap name)
  • s1 – the size of the dot for the scatter
  • t – the time step being plotted

Mascaret

in src/mascaret.py

This module contains the functions used to load the outputs from the mascaret model.

src.mascaret.correct_duplicate(seq, send_warn, idfun=None)

It is possible to have a vertical line on a profile (different h, identical x). This is not possible for HABBY and the 2D grid. So this function correct duplicates along the profile.

A similiar function exists in rubar, for the case where input is (x,y) coordinates and not distance along the profile. This function is inspired by https://www.peterbe.com/plog/uniqifiers-benchmark

It should be tested more as manage_grid sometime still send warning about duplicate data in profile.

Parameters:
  • seq – the list to be corrected (list)
  • send_warn – a bool to avoid printing certains warning too many time
  • idfun – support an optional transform function (not used)
Returns:

the profile data without duplicate and the bollean which manages the warning.

src.mascaret.define_stream_network(node_number, start_node, end_node, angles, nb_pro_reach, nb_reach, abcisse)

This function extracts the stream network from the node and angle data. This is used if we have more than one reach to define the geometry of the junction.

Parameters:
  • node_number – the start/end number of the reaches for each nodes (list of list)
  • start_node – the numbers indicating the start of each reach (list)
  • end_node – the numbers indicating the end of each reach
  • angles – for each node the angle between the reach
  • nb_pro_reach – the number of profile by reach
  • nb_reach – the number of reach
  • abcisse – the distance along the river of each reach
Returns:

the river coordinates and the unit vector indicating the river direction

src.mascaret.figure_mascaret(coord_pro, coord_r, xhzv_data, on_profile, nb_pro_reach, fig_opt, name_pro, name_reach, path_im, pro, plot_timestep=[-1], reach_plot=[0])

The function to plot the figures related to mascaret.

Parameters:
  • coord_pro – the cordinates (x,y,h, dist along the river) of the profiles
  • coord_r – the coordinate (x,y) of the river
  • name_pro – the name of the profile
  • name_reach – the name of the reach
  • on_profile – which result are on the profile. Some output are not the profiles.
  • nb_pro_reach – the number of profile by reach (careful this is the number of profile, not the number of output)
  • fig_opt – the figure option
  • xhzv_data – the height and velcoity (x,h,v) list by time step
  • profile (pro) – which profile to be plotted (list of int)
  • plot_timestep – which timestep to be plotted
  • reach_plot – the reach to be plotted for the river view
  • path_im – the path where to save the figure
src.mascaret.find_node(node_number, reach_to_find)

This function finds which node is a stream end or a stream start. It is associated by the function define_stream_network()

Parameters:
  • node_number – the list of list of the reaches linked with one node
  • reach_to_find – the number indicating the start or end of the reach
Returns:

the node number, ordered as in the xcas file

src.mascaret.flat_coord_pro(coord_pro)

This function is not used anymroe.

The variable coord_pro was a list of profile by reach. Finally, it was useful to have each profile one after the other with accounting for the reach. So we stop to use this function whose goal was to pass from one form of coord_pro to the other form 9with or wihtout reach information).

Parameters:coord_pro – the list of profile (x,y,h, dist along the river) by reach
Returns:coord_pro_f: a list of profile without the reach information. The list is flatten
src.mascaret.get_geo_name_from_xcas(file_gen, path_gen)

This function gets the name of the .geo file from the .xcas xml file. It is not used yet, but it could be useful in the GUI to simplify the loading of mascaret. The user would not need to give the name of the geo and the xcas files separetly. However, it is not written in yet.

Parameters:
  • file_gen – the xcas file
  • path_gen – the path to the xcas file
Returns:

the name of the .geo file (no path indicated)

src.mascaret.get_name_from_cas(file_gen, path_gen)

This function gets the name of the .geo file from the .cas text file. It is not used yet, but it could be useful in the GUI to simplify the loading of mascaret. The user would not need to give the name of the geo and the cas files separetly. However, it is not written in yet.

Parameters:
  • file_gen – the name of .cas file (string)
  • path_gen – the path to the cas file (string
Returns:

the name of the .geo file (no path indicated)

src.mascaret.is_this_res_on_the_profile(abscisse, xhzv_data_all)

The output of mascaret can be given at points of the river where there is no profile. The function here says which results are on the profiles. All profiles are linked with an output, but some output are not linked with a profile.

Parameters:
  • abscisse – the distance between each profile (list of float)
  • xhzv_data_all – the outputs from mascaret by time step
Returns:

a list of bool of the length of xhzv_data, True on profile, False not on profile

Technical comment

In the mascaret outputs, some rounding are suprising. For example, 0.49 can be transformed to 0.50 in an otehr file (not 0.5). To avoid this type of problem, we says that outputs with a distance smaller than 3cm of the profile are on the profile. If there are more than one output by profile, we takes the output which is the closest to the profile.

src.mascaret.load_mascaret(file_gen, file_geo, file_res, path_gen, path_geo, path_res)

The function is used to load the mascaret data. It load the geofile and the general file. Then, it re-forms the geometrical data. Next, it loads the output data from mascaret. Fianally, it looks which outputs is close to a profile and which outputs is not linked with a profile as there are some outputs given between profiles.

Parameters:
  • file_gen – the xcas .xml file giving general info about the model (string)
  • file_geo – the file containting the profile data (.geo) (string)
  • file_res – the files containting the mascaret output in the Optyca format (.opt) (string)
  • path_gen – the path to the xcas file or .cas file (string). By default, choose the xcas file.
  • path_geo – the path to the geo file (string)
  • path_res – the path to the res file (string)
Returns:

the coordinates of the profile (x,y,z, dist along the profile), the coordinate of the river (x,y), name of reach and profile, data height and velocity (list by time step), list of bollean indicating which data is on the profile and the number of profile by reach.

src.mascaret.load_mascaret_and_create_grid(name_hdf5, path_hdf5, name_prj, path_prj, model_type, namefile, pathfile, interpo_choice, manning_data, nb_point_vel, show_fig_1D, pro_add, q=[], path_im='.', print_cmd=False)

This function is used to load the mascaret data by calling the load_mascaret() function and to create the grid by calling the grid_and_interpo function in manage_grid_8. This function is called in a second thread by the class Mascaret() in Hydro_grid_2(). It also distribute the velocity by calling dist_vitess2.

Parameters:
  • name_hdf5 – the name of the hdf5 to be created (string)
  • path_hdf5 – the path to the hdf5 to be created (string)
  • model_type – the name of the model (mascaret in most case, but given as argument in case we change the form of the name)
  • name_prj – the name of the project (string)
  • path_prj – the path of the project
  • namefile – the name of the geo file and the data file, which contains respectively geographical data and the ouput data (see open_hec_ras() for more precision) -> list of string
  • pathfile – the absolute path to the file chosen into namefile -> list of string
  • interpo_choice – the interpolation type (int: 0,1,2 or 3). See grid_and_interpo() for mroe details.
  • manning_data – Contains the manning data. It can be in an array form (variable) or as a float (constant)
  • nb_point_vel – the number of velcoity point by whole profile
  • show_fig_1D – A boolean. If True, image from the 1D data are created and savec
  • q – used by the second thread.
  • pro_add – the number of addictional profile (one used for interpolation_choice 1 and 2)
  • path_im – the path where to save the figure
  • print_cmd – if True the print command is directed in the cmd, False if directed to the GUI

** Technical comments**

This function redirect the sys.stdout. The point of doing this is because this function will be call by the GUI or by the cmd. If it is called by the GUI, we want the output to be redirected to the windows for the log under HABBY. If it is called by the cmd, we want the print function to be sent to the command line. We make the switch here.

src.mascaret.main()

Used to test this module separately.

src.mascaret.open_geo_mascaret(file_geo, path_geo)

This function load the mascaret geo file. Generally, the profile are not geo-referenced when using this function.

Parameters:
  • file_geo – the name of the geo file (string)
  • path_geo – the path to the geo file (string)
Returns:

the profile data (x,y), profile name (list of string), brief name (list of string), the number of profile in each reach and distance along the river/abcisse (list)

src.mascaret.open_res_file(file_res, path_res)

The function to load the output from mascaret (.opt file). The format is Optyca.

Parameters:
  • file_res – the name of the .opt file (string)
  • path_res – the path to this file (string)
Returns:

src.mascaret.open_rub_file(file_res, path_res)

The function to open the binary output file from mascaret (.rub format).

Parameters:
  • file_res – the name of the rub binary file (string)
  • path_res – the path to this file (string)
Returns:

xhzv_data, timestep

Technical comment

The binary output file was done using a program written in FORTRAN. So there are often suprising octet which are added to the binary file. Be careful before changing anything.

src.mascaret.profil_coord_non_georef(coord_pro, coord_r, nr, nb_pro_reach, bt=None)

This function gets the coordinates (x,y) of the profile as masacret outputs are not georeferenced.

Hypothesis: The river and the profile are straight. The profile is perpendicular to the river. The river pass at the minimum elevation of the river bed. If there is a distinction between the main bed the secondary bed is given, we take the minimum elevation of the main bed

The origin of the coordinate system is the start of the river.

Parameters:
  • coord_pro – the coordinate of the profile. This variable is not in the general coordinate system, just distance along the profile and bed elevation (p, dist, h)
  • coord_r – the river coordinates
  • n – the vector indicating the river direction
  • nb_pro_reach – the number of profile by reach (additive)
  • bt – optional, it indicates which points in the profiles are in the minor/major bed
Returns:

the velocity and height data, the timestep

src.mascaret.river_coord_non_georef_from_cas(file_gen, path_gen, abcisse, nb_pro_reach)

Get the coordinates of the river based on the cas text file. If there are only one river, this is an easy task as the river is straight. If there are more than one reach, the junctions and the angles between the reach sould be managed using the define_stream_network function and the information in the .cas file.

Parameters:
  • file_gen – the .cas file whcih contains general info (string)
  • path_gen – the path to this file (string)
  • abcisse – ditance along the profiles
  • nb_pro_reach – the number of reach by profile
Returns:

the river coordinate and the unit vector indicating the river direction

src.mascaret.river_coord_non_georef_from_xcas(file_gen, path_gen, abcisse, nb_pro_reach)

Get the coordinates of the river based on the xcas xml file. If there are only one river, this is an easy task as the river is straight. If there are more than one reach, the junctions and the angles between the reach sould be managed using the define_stream_network function and the information in the .xcas file.

Parameters:
  • file_gen – the .xcas file with the information concerning the reach (string)
  • path_gen – the path to the xcas file (string)
  • abcisse – the distance along the river
  • nb_pro_reach – the number of profile by reach
Returns:

coord_r the coordinate of the river

River 2D

in src/river2D.py

This module contains the functions used to load the outputs from the River2D model.

src.river2d.figure_river2d(xyzhv, ikle, path_im, t=0)

A function to plot the output from river 2d. Need hec-ras2d as import because it re-used most of the plot from this script. It is only used to debug. It is not used directly by HABBY.

Plot only one time step because river 2d output have one file by time step.

Parameters:
  • xyzhv – the x,y, coordinates of the node (h,v are nodal output in river 2d), the river bed, the water height and the velocity (one data by column, row are node)
  • ikle – connectivity table
  • path_im – the path where to save the figure
  • t – the time step which is being plotted
Returns:

src.river2d.get_rid_of_lines(datahere, nb_data)

There are lines which are useless in the cdg file. This function is used to correct ikle and data_node

Parameters:
  • datahere – the data with the empty lines
  • nb_data – nb_node or nb_el
Returns:

datahere wihtout the useless lines

src.river2d.load_river2d_and_cut_grid(name_hdf5, namefiles, paths, name_prj, path_prj, model_type, nb_dim, path_hdf5, q=[], print_cmd=False, fig_opt={})

This function loads the river2d data and cut the grid to the wet area. Originally, this function was in the class River2D() in hydro_GUI_2. This function was added as it was practical to have a second thread to avoid freezing the GUI.

Parameters:
  • name_hdf5 – the base name of the created hdf5 (string)
  • namefiles – the names of all the cdg file (list of string)
  • paths – the path to the files (list of string).
  • name_prj – the name of the project (string)
  • path_prj – the path of the project
  • model_type – the name of the model such as Rubar, hec-ras, etc. (string)
  • nb_dim – the number of dimension (model, 1D, 1,5D, 2D) in a float
  • path_hdf5 – A string which gives the adress to the folder in which to save the hdf5
  • q – used to send the error back from the second thread (can be used to send other variable too)
  • print_cmd – if True the print command is directed in the cmd, False if directed to the GUI
  • fig_opt – the figure option, used here to get the minimum water height to have a wet node (can be > 0)
src.river2d.load_river2d_cdg(file_cdg, path)

The file to load the output data from River2D. Careful the input data of River2D has the same ending and nearly the same format as the output. However, it is nessary to have the output here. River2D gives one cdg. file by timestep. Hence, this function read only one timeste. HABBY read all time step by calling this function once for each time step.

Parameters:
  • file_cdg – the name of the cdg file (string)
  • path – the path to this file (string).
Returns:

the velocity and height data, the coordinate and the connectivity table.

src.river2d.main()

Used to test this module.

Rubar

in src/rubar.py

This module contains the functions used to load the Rubar data in 2D and 1D.

src.rubar.correct_duplicate_xy(seq3D, send_warn, idfun=None)

It is possible to have a vertical line on a profile (different h, identical x). This is not possible for HABBY and the 2D grid. So this function correct duplicates along the profile.

A similiar function exists in mascaret, for the case where the input is the distance along the profile and not (x,y) coordinates. This function is inspired by https://www.peterbe.com/plog/uniqifiers-benchmark.

It should be tested more as manage_grid sometime still send warning about duplicate data in profile.

Parameters:
  • seq3D – the list to be corrected in this case (x,y,z,dist along the profile)
  • send_warn – a bool to avoid printing the warning too many time
  • idfun – support an optional transform function (not tested)
Returns:

the list wihtout duplicate and the boolean which helps manage the warnings

src.rubar.figure_rubar1d(coord_pro, lim_riv, data_xhzv, name_profile, path_im, pro, plot_timestep, nb_pro_reach=[0, 10000000000], fig_opt={})

The function to plot the loaded RUBAR 1D data (Rubar BE).

Parameters:
  • coord_pro – the coordinate of the profile (x, y, z, dist along the river)
  • lim_riv – the right bank, river center, left bank
  • data_xhzv – the data by time step with x the distance along the river, h the water height and v the vlocity
  • cote – the altitude of the river center
  • name_profile – the name of the profile
  • path_im – the path where to save the image
  • pro – the profile number which should be plotted
  • plot_timestep – which timestep should be plotted
  • nb_pro_reach – the number of profile by reach
  • fig_opt – the dictionnary with the figure option
Returns:

none

src.rubar.figure_rubar2d(xy, coord_c, ikle, v, h, path_im, time_step=[-1])

This functions plots the rubar 2d data. This function is only used to debug. It is not used direclty by Habby.

Parameters:
  • xy – coordinates of the points
  • coord_c – the center of the point
  • ikle – connectivity table
  • v – speed
  • h – height
  • path_im – the path where to save the figure
  • time_step – The time step which will be plotted
src.rubar.get_triangular_grid(ikle, coord_c, xy, h, v)

In Rubar, it is possible to have non-triangular cells. It is possible to have a grid composed of a mix of pentagonal, 4-sided and triangualr cells. This function transform the “mixed” grid to a triangular grid. For this, it uses the centroid of each cell with more than three side and it create a triangle by side (linked with the center of the cell). A similar function exists in hec-ras2D.py, but, as there is only one reach in rubar and because ikle is different in hec-ras, it was hard to marge both functions together.

Parameters:
  • ikle – the connectivity table (list)
  • coord_c – the coordinate of the centroid of the cell (list)
  • xy – the points of the grid (np.array)
  • h – data on water height
  • v – data on velocity
Returns:

the updated ikle, coord_c (the center of the cell , must be updated ) and xy (the grid coordinate)

src.rubar.load_coord_1d(name_rbe, path)

the function to load the rbe file, which is an xml file. The gives the geometry of the river system.

Parameters:
  • name_rbe – The name fo the rbe file (string)
  • path – the path to this file (string)
Returns:

the coordinates of the profiles and the coordinates of the right bank, center of the river, left bank (list of np.array with x,y,z coordinate), name of the profile (list of string), dist along the river (list of float) number of cells (int)

src.rubar.load_dat_2d(geofile, path)

This function is used to load the geomtery info for the 2D case, using the .dat file The .dat file has the same role than the .mai file but with more information (number of side and more complicated connectivity table).

Parameters:
  • geofile – the .dat file which contain the connectivity table and the (x,y)
  • path – the path to this file
Returns:

connectivity table, point coordinates, coordinates of the cell centers

src.rubar.load_data_1d(name_data_vh, path, x)

This function loads the output data for Rubar BE (in 1D). The geometry data should be loaded before using this function.

Parameters:
  • name_data_vh – the name of the profile.ETUDE file (string)
  • path – the path to this file
  • x – the distance along the river (from the .geo file)
Returns:

data x, velocity height, cote for each time step (list of np.array), time step

src.rubar.load_mai_1d(mailfile, path)

This function is not used anymore. It was used to load the coordinate of the 1D data. It might become useful again in the case where we found a Rubar model with more than one reach (which we do not have yet).

Parameters:
  • mailfile – the name of the file which contain the (x,z) data
  • path – the path to this file
Returns:

x of the river, np.array and the number of mail

src.rubar.load_mai_2d(geofile, path)

The function to load the geomtery info for the 2D case when we use the .mai file. It would also be possible to use the .dat file. In fact, it is advised to use the dat file when possible as there are more info in the .dat file.

Parameters:
  • geofile – the .mai file which contain the connectivity table and the (x,y)
  • path – the path to this file
Returns:

connectivity table, point coordinates, coordinates of the cell centers

src.rubar.load_rubar1d(geofile, data_vh, pathgeo, pathdata, path_im, savefig, fig_opt=[])

the function to load the RUBAR BE data (in 1D).

Parameters:
  • geofile – the name of .rbe file which gives the coordinates of each profile (string)
  • data_vh – the name of the profile.ETUDE file which contains the height and velocity data (string)
  • pathgeo – the path to the geofile - string
  • pathdata – the path to the data_vh file
  • path_im – the file where to save the image
  • savefig – a boolean. If True create and save the figure.
  • fig_opt – A dictionarry with the figure option
Returns:

coordinates of the profile (x,y,z dist along the profile) coordinates (x,y) of the river and the bed, data xhzv by time step where x is the distance along the river, h the water height, z the elevation of the bed and v the velocity

src.rubar.load_rubar1d_and_create_grid(name_hdf5, path_hdf5, name_prj, path_prj, model_type, namefile, pathfile, interpo_choice, manning_data, nb_point_vel, show_fig_1D, pro_add, q=[], path_im='.', print_cmd=False)

This function is used to load rubar 1d data by calling the load_rubar1d() function and to create the grid by calling the grid_and_interpo function in manage_grid_8. This function is called in a second thread by the class Rubar() in Hydro_grid_2(). It also distribute the velocity by calling dist_vitess2.

Parameters:
  • name_hdf5 – the name of the hdf5 to be created (string)
  • path_hdf5 – the path to the hdf5 to be created (string)
  • name_prj – the name of the project (string)
  • path_prj – the path of the project
  • model_type – the name of the model (rubar in most case, but given as argument in case we change the form of the name)
  • namefile – the name of the geo file and the data file, which contains respectively geographical data and the ouput data (see open_hec_ras() for more precision) -> list of string
  • pathfile – the absolute path to the file chosen into namefile -> list of string
  • interpo_choice – the interpolation type (int: 0,1,2 or 3). See grid_and_interpo() for mroe details.
  • manning_data – Contains the manning data. It can be in an array form (variable) or as a float (constant)
  • nb_point_vel – the number of velcoity point by whole profile
  • show_fig_1D – A boolean. If True, image from the 1D data are created and savec
  • q – used by the second thread.
  • path_im – the path where to save the figure
  • print_cmd – if True the print command is directed in the cmd, False if directed to the GUI

** Technical comments**

This function redirect the sys.stdout. The point of doing this is because this function will be call by the GUI or by the cmd. If it is called by the GUI, we want the output to be redirected to the windows for the log under HABBY. If it is called by the cmd, we want the print function to be sent to the command line. We make the switch here.

src.rubar.load_rubar2d(geofile, tpsfile, pathgeo, pathtps, path_im, save_fig)

This is the function used to load the RUBAR data in 2D.

Parameters:
  • geofile – the name of the .mai or .dat file which contains the connectivity table and the coordinates (string)
  • tpsfile – the name of the .tps file (string)
  • pathgeo – path to the geo file (string)
  • pathtps – path to the tps file which contains the outputs (string)
  • path_im – the path where to save the figure (string)
  • save_fig – a boolean indicating if the figures should be created or not
Returns:

velocity and height at the center of the cells, the coordinate of the point of the cells, the coordinates of the center of the cells and the connectivity table.

src.rubar.load_rubar2d_and_create_grid(name_hdf5, geofile, tpsfile, pathgeo, pathtps, path_im, name_prj, path_prj, model_type, nb_dim, path_hdf5, q=[], print_cmd=False, fig_opt={})

This is the function used to load the RUBAR data in 2D, to pass the data from the cell to the node using interpolation and to save the whole in an hdf5 format

Parameters:
  • name_hdf5 – the base name of the created hdf5 (string)
  • geofile – the name of the .mai or .dat file which contains the connectivity table and the coordinates (string)
  • tpsfile – the name of the .tps file (string)
  • pathgeo – path to the geo file (string)
  • pathtps – path to the tps file which contains the outputs (string)
  • path_im – the path where to save the figure (string)
  • name_prj – the name of the project (string)
  • path_prj – the path of the project
  • model_type – the name of the model such as Rubar, hec-ras, etc. (string)
  • nb_dim – the number of dimension (model, 1D, 1,5D, 2D) in a float
  • path_hdf5 – A string which gives the adress to the folder in which to save the hdf5
  • q – used by the second thread to get the error back to the GUI at the end of the thread
  • print_cmd – if True the print command is directed in the cmd, False if directed to the GUI
  • fig_opt – the figure option, used here to get the minimum water height to have a wet node (can be > 0)
src.rubar.load_tps_2d(tpsfile, path, nb_cell)

The function to load the output data in the 2D rubar case. The geometry file (.mai or .dat) should be loaded before.

Parameters:
  • tpsfile – the name of the file with the data for the 2d case
  • path – the path to the tps file.
  • nb_cell – the number of cell extracted from the .mai file
Returns:

v, h, timestep (all in list of np.array)

src.rubar.m_file_load_coord_1d(geofile_name, pathgeo)

This function loads the m.ETUDE file which is based on .st format from cemagref. When we use the M.ETUDE file instead of the rbe file, more than one reach can be studied but the center and side of the river is not indicated anymore.

Parameters:
  • geofile_name – The name to the m.ETUDE file (string)
  • pathgeo – the path to this file (string)
Returns:

the coordinates of the profiles (list of np.array with x,y,z coordinate), name of the profile (list of string), dist along the river (list of float), number of profile by reach

src.rubar.main()

Used to test this module

Telemac

in src/selafin_habby1.py

This module contains the functions used to load the Telemac data.

class src.selafin_habby1.Selafin(filename)

Selafin file format reader for Telemac 2D. Create an object for reading data from a slf file. Adapted from the original script ‘parserSELAFIN.py’ from the open Telemac distribution.

Parameters:filename – the name of the binary Selafin file
addcontent(fileName, times, values)
appendcoretimeslf(t)
appendcorevarsslf(varsor)
appendheaderslf()

Write the header file

getheaderfloatsslf()

Get the mesh coordinates

getheaderintegersslf()

Get dimensions and descritions (mesh)

getheadermetadataslf()

Get header information

gettimehistoryslf()

Get the timesteps

getvalues(t)

Get the values for the variables at time t

getvariablesat(frame, varindexes)

Get the values for the variables at a particular time step

putcontent(fileName, times, values)
src.selafin_habby1.getendianfromchar(fileslf, nchar)
Get the endian encoding
“<” means little-endian “>” means big-endian
src.selafin_habby1.getfloattypefromfloat(fileslf, endian, nfloat)

Get float precision

src.selafin_habby1.load_telemac(namefilet, pathfilet)

A function which load the telemac data using the Selafin class.

Parameters:
  • namefilet – the name of the selafin file (string)
  • pathfilet – the path to this file (string)
Returns:

the velocity, the height, the coordinate of the points of the grid, the connectivity table.

src.selafin_habby1.load_telemac_and_cut_grid(name_hdf5, namefilet, pathfilet, name_prj, path_prj, model_type, nb_dim, path_hdf5, q=[], print_cmd=False, fig_opt={})

This function calls the function load_telemac and call the function cut_2d_grid(). Orginally, this function was part of the TELEMAC class in Hydro_GUI_2.py but it was separated to be able to have a second thread, which is useful to avoid freezing the GUI.

Parameters:
  • name_hdf5 – the base name of the created hdf5 (string)
  • namefilet – the name of the selafin file (string)
  • pathfilet – the path to this file (string)
  • name_prj – the name of the project (string)
  • path_prj – the path of the project
  • model_type – the name of the model such as Rubar, hec-ras, etc. (string)
  • nb_dim – the number of dimension (model, 1D, 1,5D, 2D) in a float
  • path_hdf5 – A string which gives the adress to the folder in which to save the hdf5
  • q – used by the second thread to get the error back to the GUI at the end of the thread
  • print_cmd – if True the print command is directed in the cmd, False if directed to the GUI
  • fig_opt – the figure option, used here to get the minimum water height to have a wet node (can be > 0)
src.selafin_habby1.plot_vel_h(coord_p2, h, v, path_im, timestep=[-1])

a function to plot the velocity and height which are the output from TELEMAC. It is used to debug. It is not used direclty by HABBY.

Parameters:
  • coord_p2 – the coordinates of the point forming the grid
  • h – the water height
  • v – the velocity
  • path_im – the path where the image should be saved (string)
  • timestep – which time step should be plotted

LAMMI

in src/lammi.py

This module contains functions used to load data from LAMMI. For more information on LAMMI, please see the pdf document LAMMI.pdf

src.lammi.check_code_change(facies_path)

If we can find the habitat.txt file, we check that the conversion from EDF to Cemagref code was done as in HABBY. In most case, the habiat.txt file will not be found. This is not a problem. :param facies_path: the path to the facies.txt file :return: a boolean

src.lammi.compare_lammi(filename_habby, filename_lammi, filename_lammi_sur)

This function compares the SPU for the trut done by lammi and by HABBY (using hydrological lammi output). It is not directly used by HABBY, but it can be useful to check the differences.

Parameters:
  • filename_habby – the name and path of the text file giving the spu from HABBY (spu_xxx.txt)
  • filename_lammi – the name and the file of the lammi spu (FaciesTRF.txt)
  • filename_lammi_sur – the name and the file of the lammi surface
src.lammi.coord_lammi(dist_all, vel_all, height_all, sub_all, length_all)

This function takes the data from the lammi outputs and get the coordinate for the river. It also reform the data to put it in the needed for HABBY (as the other 1.5D hydraulic model as hec_ras).

To get the coordinates, we assume that the river is straight, that each facies is one after the other and that the river passes by the deepest point of the profile. In addition we assume that the profile are straight and perpendicular to the river. We assume that each facies (or reach for HABBY) is separated by a constant value

We loop through all the profiles for all reach all time steps. For each profile, the x coordinate is identical for all point of the profile and is calculated using length_all. When a new reach starts, a x constant distance is added to the x coordinate. To find the y coordinate, we first pass from cell data (in lammi) to point data. The point are the center of each cell and the border of this cells. Then, we find the higher water height and we assume that the river passes there. Hence, this is the origin of y-coordinate axes.

We double the last and the first profile of each reach/facies. Indded, in HABBY,the information of a profile are given to the cells of the grid before and after the profile. If no cell would be done before or after the last/first profile, these profiles would have less wight than the other which is a problem to reproduce lammi results. This also avoid the case of a facies with only one profile, which is complicated to maange for the grid creation.

To keep as much as possible the same data than in Lammi, we create four points for each orginal lammi cells. The three first points have the cell value of lammi and the last one is the average of the value of these cells and the next. The point are disposed so that the first and last points are close to the end of the cells.

Parameters:
  • dist_all – the distance along profile by reach (or facies) and by time step
  • vel_all – the velocity along profile by reach (or facies) and by time step
  • height_all – the height along profile by reach (or facies) and by time step
  • sub_all – the substrate data along profile by reach (or facies) and by time step. Eacu subtrate data is a list of eight number representing the percentage of each of the eight subtrate class.
  • length_all – the distance between profile
Returns:

coord_pro, nb_pro_reach and vh_pro in the same form as in final form for hec-ras, a variable with the eight subtrate data in a percetage form (sub_pro) and a variable to find the position of the middle profile (used by manage grid)

src.lammi.fig_lammi(vh_pro, coord_pro, nb_pro_reach, pro_num, sim_num, fig_opt, path_im)

This function create a figure with the loaded lammi data. It work only for one time steps gven by the number sim_num.

Parameters:
  • vh_pro – dist along the profile, height, vel
  • coord_pro – x,y, dist along profile, height
  • nb_pro_reach – the number of profile by reach
  • pro_num – the profile to plot
  • sim_num – the time step (or simuation) to plot
  • fig_opt – the option for the figure
  • path_im – path path where to save the figure
src.lammi.get_transect_filename(facies_path, facies_name, transect_path, transect_name, new_dir)

For each facies, we obtain the name of the transect file and the length of this reach

Parameters:
  • facies_path – the path the facies.txt file
  • facies_name – the name of the facies file, usually ‘Facies.txt’
  • transect_path – the path to the transect.txt path
  • transect_name – the name of the transect file, usually ‘Transect.txt’
  • new_dir – If the folder with the transect have been moved, this argument allos it to be corrected without modification to transect.txt
Returns:

the length of each transect (arranged by facies and station) and the filename with the transect info

src.lammi.load_lammi(facies_path, transect_path, path_im, new_dir, fig_opt, savefig1d, transect_name, facies_name)

This function loads the data from the LAMMI model. A description of the LAMMI model is available in the documentation folder (LAMMIGuideMetho.pdf).

Parameters:
  • transect_path – the path to the transect.txt path
  • facies_path – the path the facies.txt file
  • path_im – the path where to save the image
  • fig_opt – the figure option
  • savefig1d – create and save the figure related to the loading of the data (profile and so on)
  • new_dir – if necessary, the path to the resultat file (.prn file). Be default, use the one in transect.txt
  • transect_name – the name of the transect file, usually ‘Transect.txt’
  • facies_name – the name of the facies file, usually ‘Facies.txt’
Returns:

Technical Comments

LAMMI is organised aroung group of transects. Transect are river profile which describe the river geometry. In LAMMI, there are four way of grouping transect. The facies is the a group a transect which is considered by HABBY to form a reach. The facies can then begroup in station. HABBY do not considered station directly, but it is possible to use the function “load_station” to get the station info if needed. The group Secteur are used in case where water is brought to the river.

To load LAMMI data, we first load the facies file, which gives which transect are in which facies. Then, we use the transect file to know the length of each transect (length between transects along the river) and the name of the file containing the transect precise data. The name of the file is an absolute path to the file. This can be annoying if one want to move the files. Hence, we add the variable new_dir which correct the transect file in case the files containing the transect data have been moved (they should however all be in the same directory). This is done by the function get_transect_name().

Then it uses the function load_transect_data to read all this data , file by file. Consequentely, we have the data in memory but no(x,y) coordinate. In addition, this data is is in the different form than in the other hydraulic model.

To obtain the coordainte of the river and to put the data is the form usually needed by HABBY for 1.5D model (coord_pro, vh_pro, nb_pro_reach), we use the coord_lammi() function.

There is also an optionnal check to control that the conversion between lammi and cemagref code is as normal. This check is only done if HABBY can find the habitat.txt file where the conversion can be modified by the user. Otherwise we assume that the normal conversion is used. Obviously, this check should be modifed if the edf to cemagref conversion is modified.

src.lammi.load_station(station_path, station_name)

This function loads the station data from the LAMMI model. This is the data contains in Station.txt. It is not used by HABBY but it could be useful.

Parameters:
  • station_path – the path to the station.txt file
  • station_name – the name of the station file, usually ‘Station.txt’
Returns:

the length of the station (list of float) and the id of the facies for each station (list of list)

src.lammi.load_transect_data(fac_filename_all)

This function loads the transect data. In this data, there are the subtrate, the height and the velocity data.

Parameters:fac_filename_all – the list of transect name organized by facies
src.lammi.main()

Used to test this module

src.lammi.open_lammi_and_create_grid(facies_path, transect_path, path_im, name_hdf5, name_prj, path_prj, path_hdf5, new_dir='', fig_opt=[], savefig1d=False, transect_name='Transect.txt', facies_name='Facies.txt', print_cmd=False, q=[], dominant_case=1, model_type='LAMMI')

This function loads the data from the LAMMI model using the load_lammi() function., create the grid and save the data in an hdf5 file. A description of the LAMMI model is available in the documentation folder (LAMMIGuideMetho.pdf).

Parameters:
  • transect_path – the path to the transect.txt path
  • facies_path – the path the facies.txt file
  • path_im – the path where to save the image
  • fig_opt – the figure option
  • savefig1d – create and save the figure related to the loading of the data (profile and so on)
  • name_hdf5 – the name of the hdf5 to be created
  • name_prj – the name of the project (string)
  • path_prj – the path of the project
  • path_hdf5 – the path to the hdf5 data
  • new_dir – if necessary, the path to the resultat file (.prn file). Be default, use the one in transect.txt
  • transect_name – the name of the transect file, usually ‘Transect.txt’
  • facies_name – the name of the facies file, ususally ‘Facies.txt
  • print_cmd – if True the print command is directed in the cmd, False if directed to the GUI
  • q – used if this function is send using the second thread
  • dominant_case – an int to manage the case where the transfomation form percentage to dominnat is unclear (two maxinimum percentage are equal from one element). if -1 take the smallest, if 1 take the biggest, if 0, we do not know.
  • model_type – which type of model (LAMMI in this case). It is as an argument just in case (lammi, Lammi, etc.)
Returns:

Technical comments

LAMMI has a special way of creating a grid from its data. Because spatial information is not very good in LAMMI, we can only used the create_grid_only_1_profile() function. The function which uses triangle to create the grid can not be used here as the developper fomr LAMMI did not wish to introduce an interpolation method in their outputs. In addition, LAMMI integrates substrate data which should be direclty added to the grid while other hydraulic model get their substrate data from another sources.

Load HABBY hdf5 file

in src/load_hdf5.py

This module contains some functions to load and manage hdf5 input/outputs.

src.load_hdf5.add_habitat_to_merge(hdf5_name, path_hdf5, vh_cell, h_cell, v_cell, fish_name)

This function takes a merge file and add habitat data to it. The habitat data is given by cell. It also save the velocity and the water height by cell (and not by node)

Parameters:
  • hdf5_name – the name of the merge file
  • path_hdf5 – the path to this file
  • vh_cell – the habitat value by cell
  • h_cell – the height data by cell
  • v_cell – the velcoity data by cell
  • fish_name – the name of the fish (with the stage in it)
src.load_hdf5.addition_hdf5(path1, hdf51, path2, hdf52, name_prj, path_prj, model_type, path_hdf5, merge=False, erase_id=True)

This function merge two hdf5 together. The hdf5 files should be of hydrological or merge type and both grid should in the same coordinate system. It is not possible to have one merge file and one hydrological hdf5 file. They both should be of the same type. The two grid are added as two separeted river reach.

Parameters:
  • path1 – the path to the first hydrological hdf5
  • hdf51 – the name of the first hdf5 file
  • path2 – the path to the second hdf5
  • hdf52 – the name of the second hdf5
  • name_prj – the name of the project
  • path_prj – the path to the project
  • model_type – the type of model (used to save the new file name into the project xml file)
  • path_hdf5 – the path where to save the hdf5 (ususally path_prj, but not always)
  • merge – If True, this is a merge hdf5 file and not only hydraulic data. Boolean.
  • erase_id – If true and if a similar hdf5 exist, il will be erased
src.load_hdf5.copy_files(names, paths, path_input)

This function copied the input files to the project file. The input files are usually contains in the input project file. It is ususally done on a second thread as it might be long.

For the moment this function cannot send warning and error to the GUI. As input should have been cheked before by HABBY, this should not be a problem.

Parameters:
  • names – the name of the files to be copied (list of string)
  • paths – the path to these files (list of string)
  • path_input – the path where to send the input (string)
src.load_hdf5.get_all_filename(dirname, ext)

This function gets the name of all file with a particular extension in a folder. Useful to get all the output from one hydraulic model.

Parameters:
  • dirname – the path to the directory (string)
  • ext – the extension (.txt for example). It is a string, the point needs to be the first character.
Returns:

a list with the filename (filename no dir) for each extension

src.load_hdf5.get_hdf5_name(model_name, name_prj, path_prj)

This function get the name of the hdf5 file containg the hydrological data for an hydrological model of type model_name. If there is more than one hdf5 file, it choose the last one. Tha path is the path from the project folder. Hence, it is not the absolute path.

Parameters:
  • model_name – the name of the hydrological model as written in the attribute of the xml project file
  • name_prj – the name of the project
  • path_prj – the path to the project
Returns:

the name of the hdf5 file

src.load_hdf5.get_initial_files(path_hdf5, hdf5_name)

This function looks into a merge file to find the hydraulic and subtrate file which were used to create this file. :param path_hdf5: the path to the hdf5 file :param hdf5_name: the name fo this hdf5 file :return: the name of the substrate and hydraulic file used to create the merge file

src.load_hdf5.load_hdf5_hyd(hdf5_name_hyd, path_hdf5='', merge=False)

A function to load the 2D hydrological data contains in the hdf5 file in the form required by HABBY. f hdf5_name_sub is an absolute path, the path_prj is not used. If it is a relative path, the path is composed of the path to the project (path_prj) composed with hdf5_name_sub.

Parameters:
  • hdf5_name_hyd – filename of the hdf5 file (string)
  • path_hdf5 – the path to the hdf5 file
  • merge – If merge is True. this is a merged file with substrate data added
Returns:

the connectivity table, the coordinates of the point, the height data, the velocity data on the coordinates.

src.load_hdf5.load_hdf5_sub(hdf5_name_sub, path_hdf5, ind_const=False)

A function to load the substrate data contained in the hdf5 file. It also manage the constant cases. If hdf5_name_sub is an absolute path, the path_prj is not used. If it is a relative path, the path is composed of the path to the ‘hdf5’ folder (path_prj/hdf5_files) composed with hdf5_name_sub. it manages constant and vairable (based on a grid) cases. The code should be of cemagref type and the data is given as coarser and dominant.

Parameters:
  • hdf5_name_sub – path and file name to the hdf5 file (string)
  • path_prj – the path to the hdf5 file
  • ind_const – If True this function return a boolean which indicates if the substrant is constant or not
src.load_hdf5.load_sub_percent(hdf5_name_hyd, path_hdf5='')

This function loads the substrate in percent form, if this info is present in the hdf5 file. It send a warning otherwise.

Parameters:
  • hdf5_name_hyd – filename of the hdf5 file (string)
  • path_hdf5 – the path to the hdf5 file
Returns:

src.load_hdf5.load_timestep_name(hdf5_name, path_hdf5='')

This function looks for the name of the timesteps in hydrological or merge hdf5. If it find the name of the time steps, it retruns them. If not, it return an empty lists.

Parameters:
  • hdf5_name – the name of the merge or hydrological hdf5 file
  • path_hdf5 – the path to the hdf5
Returns:

the name of the time step if they exist. Otherwise, an empty list

src.load_hdf5.open_hdf5(hdf5_name)

This is a function which open an hdf5 file and check that it exists. it does not load the data. It only opens the files. :param hdf5_name: the path and name of the hdf5 file (string)

src.load_hdf5.save_hdf5(name_hdf5, name_prj, path_prj, model_type, nb_dim, path_hdf5, ikle_all_t, point_all_t, point_c_all_t, inter_vel_all_t, inter_h_all_t, xhzv_data=[], coord_pro=[], vh_pro=[], nb_pro_reach=[], merge=False, sub_pg_all_t=[], sub_dom_all_t=[], sub_per_all_t=[], sim_name=[], sub_ini_name='', hydro_ini_name='', save_option=None, version=0)

This function save the hydrological data in the hdf5 format.

Parameters:
  • name_hdf5 – the base name for the hdf5 file to be created (string)
  • name_prj – the name of the project (string)
  • path_prj – the path of the project
  • model_type – the name of the model such as Rubar, hec-ras, etc. (string)
  • nb_dim – the number of dimension (model, 1D, 1,5D, 2D) in a float
  • path_hdf5 – A string which gives the adress to the folder in which to save the hdf5
  • ikle_all_t – the connectivity table for all discharge, for all reaches and all time steps
  • point_all_t – the point forming the grid, for all reaches and all time steps
  • point_c_all_t – the point at the center of the cells, for all reaches and all time steps
  • inter_vel_all_t – the velocity for all grid point, for all reaches and all time steps (by node)
  • inter_h_all_t – the height for all grid point, for all reaches and all time steps (by node)
  • xhzv_data – data linked with 1D model (only used when a 1D model was transformed to a 2D)
  • coord_pro – data linked with 1.5D model or data created by dist_vist from a 1D model (profile data)
  • vh_pro – data linked with 1.5D model or data created by dist_vist from a 1D model (velcoity and height data)
  • nb_pro_reach – data linked with 1.5D model or data created by dist_vist from a 1D model (nb profile)
  • merge – If True, the data is coming from the merging of substrate and hydrological data.
  • sub_pg_all_t – the data of the coarser substrate given on the merged grid by cell. Only used if merge is True.
  • sub_dom_all_t – the data of the dominant substrate given on the merged grid by cells. Only used if merge is True.
  • sub_per_all_t – the data of the substreate by percentage. Only used with lammi (mostly)
  • sim_name – the name of the simulation or the names of the time steps if the names are not [0,1,2,3, etc.]
  • sub_ini_name – The name of the substrate hdf5 file from which the data originates
  • hydro_ini_name – the name of the hydraulic hdf5 file from which the data originates
  • save_option – If save_option is not none, the variable erase_idem which is usually given in the figure option is overwritten by save_option which is boolean. This is useful for habby cmd.
  • version – The version number of HABBY

Technical comments

This function could look better inside the class SubHydroW where it was before. However, it was not possible to use it on the command line and it was not pratical for having two thread (it is impossible to have a method as a second thread)

This function creates an hdf5 file which contains the hydrological data. First it creates an empty hdf5. Then it fill the hdf5 with data. For 1D model, it fill the data in 1D (the original data), then the 1.5D data created by dist_vitess2.py and finally the 2D data. For model in 2D it only saved 2D data. Hence, the 2D data is the data which is common to all model and which can always be loaded from a hydrological hdf5 created by HABBY. The 1D and 1.5D data is only present if the model is 1D or 1.5D. Here is some general info about the created hdf5:

  • Name of the file: name_hdf5. If we save all file even if the model is re-run we add a time stamp. For example, test4_HEC-RAS_25_10_2016_12_23_23.h5.
  • Position of the file: in the folder figure_habby currently (probably in a project folder in the final software)
  • Format of the hdf5 file:
    • Dats_gen: number of time step and number of reach
    • Data_1D: xhzv_data_all (given profile by profile)
    • Data_15D : vh_pro, coord_pro (given profile by profile in a dict) and nb_pro_reach.
    • Data_2D : For each time step, for each reach: ikle, point, point_c, inter_h, inter_vel

If a list has elements with a changing number of variables, it is necessary to create a dictionary to save this list in hdf5. For example, a dictionary will be needed to save the following list: [[1,2,3,4], [1,2,3]]. This is used for example, to save data by profile as we can have profile with more or less points. We also note in the hdf5 attribute some important info such as the project name, path to the project, hdf5 version. This can be useful if an hdf5 is lost and is not linked with any project. We also add the name of the created hdf5 to the xml project file. Now we can load the hydrological data using this hdf5 file and the xml project file.

When saving habitat data, we add a time stamp so that if re-run an habitat simulation, we do not loos all the data. When loading, the last data should be used.

Hdf5 file do not support unicode. It is necessary to encode string to write them.

src.load_hdf5.save_hdf5_sub(path_hdf5, path_prj, name_prj, sub_pg, sub_dom, ikle_sub=[], coord_p=[], name_hdf5='', constsub=False, model_type='SUBSTRATE', return_name=False)

This function creates an hdf5 with the substrate data. This hdf5 does not have the same form than the hdf5 file used to store hydrological or merge data. This hdf5 store the substrate data alone before it is merged with the hydrological info. The substrate info should be given in the cemagref code.

Parameters:
  • path_hdf5 – the path where the hdf5 file should be saved
  • path_prj – the project path
  • name_prj – the name of the project
  • sub_pg – the coarser part of the substrate (array with length of ikle if const_sub is False, a float otherwise)
  • sub_dom – the dominant part of the substrate (array with length of ikle if const_sub is False, a float otherwise)
  • ikle_sub – the connectivity table for the substrate (only if constsub = False)
  • coord_p – the point of the grid of the substrate (only if constsub = False)
  • name_hdf5 – the name of the substrate h5 file (without the timestamp). If not given, a default name is used.
  • constsub – If True the substrate is a constant value
  • model_type – the attribute for the xml file (usually SUBSTRATE)
  • return_name – If True this function return the name of the substrate hdf5 name

Form of the hdf5 files

Here is the actual form of the hdf5 containing the 2D hydrological data.

  • Number of timestep: Data_gen/Nb_timestep
  • Number of reach: Data_gen/Nb_reach
  • Connectivity table for the whole profile: Data_2D/Whole_Profile/Reach_<r>/ikle
  • Connectivity table for the wetted area (by time step): Data_2D/Timestep<t>/Reach_<r>/ikle
  • Coordinates for the whole profile: Data_2D/Whole_Profile/Reach_<r>/point_all
  • Coordinates for the wetted area (by time steps): Data_2D/Timestep<t>/Reach_<r>/point_all
  • Data for the velocity: Data_2D/Timestep<t>/Reach_<r>/inter_vel_all
  • Data for the height: Data_2D/Timestep<t>/Reach_<r>/inter_h_all

Here is the actual form of the hdf5 containing the substrate data.

  • the coordinate of the point forming the substrate “grid”: coord_p_sub/
  • the connectivity table of the substrate “grid”: ikle_sub/
  • Substrate data; not done yet

Velocity distribution

in src/dist_vitesse2.py

The goal of this list of function is to distribute the velocity along the cross-section for 1D model such as mascaret or Rubar BE. Hec-Ras outputs do not need to uses this type of function as they are already distributed along the profiles.

The method of velocity distribution in HABBY is similar to the one used by Hec-Ras to distribute velocity.

src.dist_vistess2.dist_velocity_hecras(coord_pro, xhzv_data_all, manning_pro, nb_point=-99, eng=1.0, on_profile=[])

This function distribute the velocity along the profile using the method from hec-ras which is described in the hydraulic reference manual p 4-20 (Flow distribtion calculation)

Parameters:
  • coord_pro – the coordinates and elevation of the river bed for each profile (x,y, h, dist along the profile) this list is flatten No reach info.
  • xhzv_data_all – water height and velocity at each profile, 1D
  • manning_pro – the manning coefficient for zone between point of each profile. For a particular profile, the length of manning_pro is the length of coord_pro[0]
  • nb_point – number of velocity points (-99 takes the number of measured elevation as the number of velocity points).
  • eng – in case the output from hec-ras are in US unit (eng=1 for SI unit and 1.486 for US unit)
  • on_profile – Mascaret also gives outputs in poitns between profile. on_profile is true if the results are close or on the profile (les than 3cm of difference). This is not important for rubar or other models
Returns:

the velocity for each profile by time step (x,v)

Technical comment and walk-through

First, we decide on which point along the profile we will calculate the velocity. This is controlled by the variable nb_point. If nb_point=-99, we will calculate the velocity at the same point than the profile (i.e., the velocity will be calculated at each point on which the elevation of the profile was measured). There are cases where this is not adequate. Let’s imagine for example a rectangular canal. The calculation would only give two velocity points, which is not enough. So, it is possible to give the number of velocity point on which the calculation must be made, using the variable nb_point.

Currently, the velocity points are determined by dividing the whole profile in nb_point segments. This means that some velocity point are not used afterwards because they are in the dry part of the profile and that it is not possible to select for a part of the profile where more velocity points would be calculated. This could be modified in the future if it is judged necessary.

To determine the point where velocity should be calculated we need to get two array: one “x” array, the distance along the profile and one “h” array, the elevation of the profile at this point. As we choose the position of the velocity point as regularly placed along the profile, the “x” array is easy to determine using linespace. For the “h” array, we use the hypothesis that the elevation of the profile changes linearly between the measured elevation points. We find between which elevation point are the new point and we use a linear interpolation to find the new”h”. To find between which points we are, we use the bisect.bisect function. It is a bit like the np.where function, but it is quicker when the array is ordered (as it is the case here).

Then, we get the manning array as created by the get_manning_arr and the get_manning function. It should be a float.

Next, we cut the profile to keep only the part under water. For this, we do two things: First we had a point on the profile where h==0. We should account for the fact that we might have “islands” (part of the profile which are dry, but surrounded by water on both side.). So we cannot only looked which part are dry, we need to look for each point where we pass from “wet to dry” or from “dry to wet”. At this place, we add one point where h= 0. For these new points water height is obviously known, but x (the distlance along profile) should be determined. It is determined assuming a linear change between the measured points of the profile.

If the profile is not entirely dry, we will now distribute the velocity along the profile. First, for each part of the profile where velocity will be calculated, it looks where is the higher height (like if this part of the profile is going up or down). Next, we calculate the area, the wetted perimeter and the hydraulic radius of each part of the profile. By combining this geometrical information with the manning parameter, we can calculate the conveyance of each part of the profile. See manual of hec-ras p.4-20 for the conveyance definition.

We now calculate the conveyance of the whole profile. Normally, the sum of the conveyance of the part is higher than the total conveyance. The next part of the script corrects for this, using the ratio of the total conveyance and the sum of the parts of the conveyance. Next, we calculate the velocity using the modelled energy slope (Sf) and the manning equation. We then then add a velocity of zero where there are no water (velocity is not defined at his point).

src.dist_vistess2.distribute_velocity(manning_data, nb_point_vel, coord_pro, xhzv_data, on_profile=[])

This function make the link between the GUI and the functions of dist_vitesse2. It is used by 1D model, notably rubar and masacret.

Dist vitess needs a manning parameters. It can be given by the user in two forms: a constant (float) or an array created by the function load_manning_text.

Parameters:
  • manning_data – the manning data as a float (constant) or as an array (variable)
  • nb_point_vel – the number of velcoity point asked (if -99, the same number of point than the profile will be used)
  • coord_pro – the form of the profil (x,y, h, dist along the profile)
  • xhzv_data – the vecoity and height data
  • on_profile – Mascaret also gives outputs in poitns between profile. on_profile is true if the results are close or on the profile (les than 3cm of difference). This is not important for rubar or other models
src.dist_vistess2.get_manning(manning1, nb_point, nb_profil, coord_pro)

This function creates an array with the manning value when a single float is given, so when the manning value is a constant for the whole river.

Parameters:
  • manning1 – the manning value (can be a value or an array)
  • nb_point – the number of velocity point by profile
  • nb_profil – the number of profile
  • coord_pro – necessary if the number is -99 as we need to know the length of each profile

Technical comments

The function dist_velcoity_hec_ras needs a manning array with a length equal to the number of profile, where each row (representing a profile) have one value by velocity point which will be calculated. This function creates an array of this form based on a float. It creates a list of manning value which is identical for each point of the river. It can be used for the cases where the same number of point is asked for each profile or for the case where the number of point is defined by the form of the profile (nb_point = -99).

src.dist_vistess2.get_manning_arr(manning_arr, nb_point, coord_pro)

This function create the manning array when manning data is loaded using a text file. In this case, the manning value do not needs to be a constant.

Parameters:
  • manning_arr – the data for manning
  • nb_point – the number of velocity point by profile
  • coord_pro – x,y,dist

Technical comment

The user creates a txt file with a list of manning info. Each manning value is given the following way: the profile, the distance along the profile and the manning value. One value by line in SI unit.

This function automatically fills the missing value, so that the user do not needs to give each manning value. He can describe one profile and this profile will be replicated until the next profile written in the text file.

src.dist_vistess2.main()

Used to test this module.

src.dist_vistess2.plot_dist_vit(v_pro, coord_pro, xhzv_data, plot_timestep, pro, name_pro=[], on_profile=[], zone_v_all=[], data_profile=[], xy_h_all=[])

This is a function to plot the distribution of velocity and the elevation of the profile. It is quite close to the similar function which is in hec-ras (see this function for a more detailed explanation)

It can be used to test the program if we provide the variable zone_v_all where zone_v_all is an hec-ras output with a velocity distribution. In this case, it would plot the comparison between the output from this script and the output from hec-ras. Of course, for this, it is necessary to have prepared the 1D output from hec-ras (using the function preparetest_velocity) and to have the same points on which to calculate the velocity.

Parameters:
  • v_pro – the calculated velcocity distribution by time step
  • coord_pro – the coordinate of the profiles
  • xhzv_data – the output data from the model, before the velocity distrbution
  • plot_timestep – which time step to be plottied
  • name_pro – the name of the profile (optionnal just for the title)
  • pro – which porfile to be plotted
  • on_profile – select the data which is on the profile
  • zone_v – output from hec-ras used to test dist_vitesse
  • data_profile – output from hec-ras used to test dist_vitesse
  • xy_h – output from hec-ras used to test dist_vitesse
src.dist_vistess2.preparetest_velocity(coord_pro, vh_pro_orr, v_in)

This is a debugging function. It takes as input the output from the hec-ras model and gives a 1D velocity as output. This is only to test this program. It will not be used by HABBY directly. To use this function, it is necessary to use the function to load hec-ras data from HABBY, so that the hec-ras data is in the right form. The 1D-velocity is assumed to be the velocity as the lowest part of the profile. This is where a 1D-model would estimate the position of the river (the lowest part of the river bed).

A complicated point to test the program is to put the velocity point at the same point than hec-ras. As hec-ras calculate velocity between zones and not on one point, this is more or less impossible to do with precision. However, one can count the number of velocity zone and give this as an input to dist_velocity_hecras() for the variable nb_point. However, both line will not be exactly at the same place. The results should however be close enough.

Parameters:
  • coord_pro – the coordinate of the profile (x,y,h,dist along profile)
  • vh_pro_orr – the velocity distribution which is the output from hec ras (produced by hec-ras06.py)
  • v_in – the uni-dimensional velocity

Create a grid

in src/manage_grid_8

This module is composed of the functions used to manage the grid, notably to create 2D grid from the output from 1D model.

There are two main way to go from data in 1.5D in a profile form to a 2D grid:

  • through the usage of the triangle module in create_grid().
  • through the definition of a middle profile used as a guide to create the grid in create_grid_only_one_profile().

For an in-depth explanation on how to create the grids, please see the pdf document More info on the grid

src.manage_grid_8.add_point(point_all, point)

To manage the substrate data, we modify the hydrological grid to avoid to have cells with two substrate type. This function add one coordinate point to the list of coordinates which compose the hydrological grid. This point is the intersection between one side of one triangluar cell of the hydrological grid and one side of the sibstrate layer (which is a shp). It only adds this intersection point if it is not already in point_all.

Parameters:
  • point_all – the coordinates of the hydrological grid
  • point – one intersection point between substrat and hydrological grids
Returns:

the updated point_all (the coordinates of the hydrological grid)

src.manage_grid_8.create_dummy_substrate(coord_pro, sqrtnp)

For testing purposes, it can be useful to create a substrate input even if one does not exist. This substrate is compose of n triangle situated on the rivers in the same coodinates system.

Parameters:
  • coord_pro – the coordinate of each profile
  • sqrtnp – the number of point which will compose one side of the new substrate grid (so the total number of point is sqrtnb squared).
Returns:

dummy coord_sub, ikle_sub

src.manage_grid_8.create_grid(coord_pro, extra_pro, coord_sub, ikle_sub, nb_pro_reach=[0, 10000000000.0], vh_pro_t=[], q=[], pnew_add=1)

It creates a grid from the coord_pro data using the triangle module. It creates the grid up to the end of the profile if vh_pro_t is not present or up to the water limit if vh_pro_t is present

Parameters:
  • q – used in the secondary process when we do not call this function direclty, but we call it in a second process so that the GUI do not crash if something go wrong (not used anymore in this form)
  • coord_pro – the profile coordinates (x,y, h, dist along) the profile
  • extra_pro – the number of “extra” profiles to be added between profile to simplify the grid
  • coord_sub – (not used anymore) the coordinate of the point forming the substrate layer (often created with substrate.load_sub)
  • ikle_sub – (not used anymore) the connectivity table of the substrate grid (often created with substrate.load_sub)
  • nb_pro_reach – the number of reach by profile starting with 0
  • vh_pro_t – the velocity and height of the water (used to cut the limit of the river).
  • pnew_add – (not used anymore) a parameter to cut the substrate side in smaller part (improve grid quality) in the form dist along profile, h , v for the analyzed time step. f not given, gird is contructed on the whole profile.
Returns:

connectivity table and grid point

Form of the function in summary

  • if vh_pro_t:
    • find cordinate under water and used this to update coord_pro
    • see if there is islands, find the island limits and the holes indicating the inside/outside of the islands
  • find the point which give the end/start of the segment defining the grid limit
  • find all point which need to be added to the grid and add extra profile if needed
  • based on the start/end points and the island limits, create the segments which gives the grid limit
  • triangulate and so create the grid
  • flag point which are overlapping in two grids

For more info, see the document “More info on the grid”.

src.manage_grid_8.create_grid_only_1_profile(coord_pro, nb_pro_reach=[0, 10000000000.0], vh_pro_t=[], sub_pg=[], sub_dom=[], sub_per=[], virtual_startend=False, divgiv=[], h0ok=False)

This function creates the grid from the coord_pro data using one additional profil in the middle. No triangulation. The interpolation of the data is done in this function also, contrarily to create_grid().

Parameters:
  • coord_pro – the profile coordinates (x,y, h, dist along) the profile
  • nb_pro_reach – the number of profile by reach
  • vh_pro_t – the data with heigh and velocity, giving the river limits
  • sub_pg – the data from the coarser substrate, in case the hydraulic model already contains substrate data
  • sub_dom – the data from the dominant substrate, in case the hydraulic model already contains substrate data
  • sub_per – the data from the subtrate in a percentage form
  • virtual_startend – this indicates that the first and the lst profile is doubled. This is used so that the grid around the last and the first profile extend after or before this profile, so that all porfile have the same weight. Useful for LAMMI moslty.
  • divgiv – in case we do not want to middle profile to be at an equal distance of both profile(one value by profile)
  • h0ok – if we want to keep in the grid the cell with an height or velocity of zero (False usually)
Returns:

the connevtivity table, the coordinate of the grid, the centroid of the grid, the velocity data on this grid, the height data on this grid.

For more info on this function, see the document “More info on the grid”.

src.manage_grid_8.cut_2d_grid(ikle, point_all, water_height, velocity, min_height=0.001, get_ind_new=False)

This function cut the grid of the 2D model to have correct wet surface. If we have a node with h<0 and other node(s) with h>0, this function cut the cells to find the wetted perimeter, assuminga linear decrease in the water elevation. This function works for one time steps and for one reach

Parameters:
  • ikle – the connectivity table of the 2D grid
  • point_all – the coordinate of the points
  • water_height – the water height data given on the nodes
  • velocity – the velcoity given on the nodes
  • min_height – the minimum water height considered (as model sometime have cell with very low water height)
  • get_ind_new – If True, a np.array is returned which give the indices of the old cell in the order of the new cells
Returns:

the update connectivity table, the coodinate of the point, the height of the water and the velocity on the updated grid and (if get_ind_new is True) the indices of the old connectivity table in the new cell orders.

src.manage_grid_8.cut_2d_grid_all_reach(ikle_all, point_all, inter_height_all, inter_vel_all, min_height=0.001, get_ind_new=False)

This function si just use to call cut_2d-grid for all reach. So that if we have a river with more than reach, we do not need to add a for loops to call for all reach. Sometime it can save place. This can be only use for one time step.

Parameters:
  • ikle_all – the connectivity table of the 2D grid for all reach
  • point_all – the coordinate of the points for all reach
  • inter_height_all – the water height data given on the nodes for all reach
  • inter_vel_all – the velcoity given on the nodes for all reach
  • min_height – the minimum water height which is kept inthe grid
  • get_ind_new – If True, a list is returned which give the indices of the old cell in the order of the new cells One list by reach (so a list of np.array is returned)
Returns:

the update connectivity table, the coodinate of the point, the height of the water and the velocity on the updated grid fro all reaches

src.manage_grid_8.find_profile_between(coord_pro_p0, coord_pro_p1, nb_pro, trim=True, divgiv=[])

Find n profile between two profiles which are not straight. This functions is useful to create the grid from 1D model as profile in 1D model are often far away from another.

Parameters:
  • coord_pro_p0 – the coord_pro (x,y,h, z) of the first profile
  • coord_pro_p1 – the coord_pro (x,y,h, z) of the second profile
  • nb_pro – the number of profile to add
  • trim – If True cut the end and start of profile to avoid to have part of the grid outside of the water limit
  • divgiv – one value by profile, used to not put the middle profile at an euql distance of two profile
Returns:

a list with the updated profiles

src.manage_grid_8.get_crossing_segment_sub(p1sub, p2sub, lim_here, lim_by_reachr, point_all, island, ind_seg_sub_ini=[0])

This function looks at one substrate segment and find the crossing points of this semgent with the different segment which composed the hydrological grid. This function is useful to cut the grid as a function of the form of the substrate layer (to avoid having cells in the hydrological grid which have two substrate value).

If island switch is True, lim_here is the limit of the island, so inside the polygon is outside the river. If island is false, lim_here is the limit of the reach under investigation

Parameters:
  • p1sub – the start point of the substrate semgent
  • p2sub – the end point of the substrate segment
  • lim_here – the reach?island limit given in the coordinate system
  • lim_by_reachr – the limits for reach r which will be given to triangle given by point_all indices.
  • point_all – all the point (ccordinates) which will be given to triangle
  • island – a boolean indicating if we are on an island or not
  • ind_seg_sub_ini – the indices of the first segment add by p1sub et p2sub by the reach. Only used island = true
Returns:

the updated point_all and lim_by_reach

src.manage_grid_8.get_new_point_and_cell_1_profil(coord_pro_p, vh_pro_t_p, point_mid_x, point_mid_y, point_all, ikle, point_c, dir, h0ok=False)

This function is use by create_grid_one_profile. It creates the grid for one profile (one “line” of triangle). To create the whole grod this function is called for each profile.

Parameters:
  • coord_pro_p – the coordinates of the profile
  • vh_pro_t_p – the height and velocity data of the profile analysed
  • point_mid_x – the x coodinate of the points forming the middle profile
  • point_mid_y – the y coordinate of the points forming the middle profile
  • point_all – the point of the grid
  • ikle – the connectivity table of the grid
  • point_c – the central point of each cell
  • dir – in which direction are we going around the profile (upstream/downstram)
  • h0ok – if True, cell with a water height or a velocity of zero are kept
Returns:

point_all, ikle, point_c (the centroid of the cell)

For more info, see the document “More info on the grid”.

src.manage_grid_8.grid_and_interpo(vh_pro, coord_pro, nb_pro_reach, interpo_choice, pro_add=1)

This function forms the link between GUI and the various grid and interpolation functions. Is called by the “loading” function of hec-ras 1D, Mascaret and Rubar BE. It used to be a method in hydro_GUI2, but we have to move it as a function to create a second thread. Hence, the high amount of parameter.

Parameters:
  • vh_pro – Velcoity and height data
  • coord_pro – the position of the profile
  • nb_pro_reach – the number of profile by reach
  • interpo_choice – an int which gives the choice of interpolatin (see below)
  • pro_add – the number of profile for be added (for interpoation method 1 and 2)

Technical comments

Here are the list of the interpolation choice:

  • 0 Use the function create_grid_only_1_profile() from manage_grid_8.py for all time steps.
  • 1 Use the function create_grid() from manage_grid_8.py for all time steps followed by a linear interpolation
  • 2 Use the function create_grid() from manage_grid_8.py for all time steps followed by a nearest neighbour interpolation
  • 3 Use create_grid() for the whole profile, make a linear inteporlation on this grid for all time step
    and use the cut_2d_grid to get a grid with only the wet profile for all time step (This part was only started. It was not finished.)

For the interpolation case 1 and 2, it is possible that the triangle module crashes if the geometry of the river is too complicated. Generally, the interpolation method 1 and 2 gives smoother results with more control over the interpolation option and the size of the cells. However, these two interpolation methods are more sensitive to the inputs, especially if the river has a lot of “island” (strongly anastomotic). So the interpoliation method 0 is more adequate in this case.

src.manage_grid_8.inside_polygon(seg_poly, point)

This function find if a point is inside a polygon, using a ray casting algorythm.

Parameters:
  • seg_poly – the segmentS forming the polygon
  • point – the point which is indide or outside the polygon
Returns:

True is the point is inside the polygon, false otherwise

src.manage_grid_8.interp_weights(xyz, uvw)

This fucntion is used by the function pass_grid_cell_to_node_lin(). To optimize the interpolation when more than one time step is done on the same grid, the first step of scipy.griddata.interolate are done here and are called only once for all time step. Hence, this function is the first part of a quicker “scipy.interpolate.griddata”

Parameters:
  • xyz
  • uvw
src.manage_grid_8.interpo_linear(point_all, coord_pro, vh_pro_t)

Using scipy.gridata, this function interpolates the 1.5 D velocity and height to the new grid It can be used for only one time step. The interpolation is linear. It is usually called after create_grid have been called.

Parameters:
  • point_all – the coordinate of the grid point
  • coord_pro – the coordinate of the profile. It should be coherent with the coordinate from vh_pro. To insure this, pass coord_pro through the function “create_grid” with the same vh_pro as input
  • vh_pro_t – for each profile, dist along the profile, water height and velocity at a particular time step
Returns:

the new interpolated data for velocity and water height

src.manage_grid_8.interpo_nearest(point_all, coord_pro, vh_pro_t)

Using scipy.gridata, this function interpolates the 1.5 D velocity and height to the new grid It can be used for only one time step. The interpolation is nearest neighbours. It is usually called after create_grid have been called.

Parameters:
  • point_all – the coordinate of the grid point
  • coord_pro – the coordinate of the profile. It should be coherent with the coordinate from vh_pro. To insure this, pass coord_pro through the function “create_grid” with the same vh_pro as input
  • vh_pro_t – for each profile, dist along the profile, water height and velocity at a particular time step
Returns:

the new interpolated data for velocity and water height

src.manage_grid_8.interpolate_opti(values, vtx, wts)

This fucntion is called by interp_weights(). It is used in the optimization of the function pass_grid_cell_to_node_lin(). This idea of this optimization is to not re-do some calculation when many interpolation are done on the same grid.

Parameters:
  • values
  • vtx
  • wts
  • fill_value – A new value for point where
src.manage_grid_8.intersection_seg(p1hyd, p2hyd, p1sub, p2sub, col=True, wig=1e-07)

This function finds if there is an intersection between two segment (AB and CD). Idea from : http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect It is based on the caluclaion of the cross-product z= 0 for 2D

Careful there is many function using this function, so change here should be thought about. There is a precision management, so everythion smaller than 10**-8 is ok

Parameters:
  • p1hyd – point A
  • p2hyd – point B
  • p1sub – point C
  • p2sub – point D
  • col – if True, colinear segment crossed. If false, they do not cross
  • wig – “wiggle room”, how precise should the calculation be (careful, complicated!)
Returns:

intersect (True or False) and the crossing point (if True, empty is False)

src.manage_grid_8.linear_h_cross(p1, p2, h1, h2, minwh=0.0)

This function is called by cut_2D_grid. It find the intersection point along a side of the triangle if part of a cells is dry.

Parameters:
  • p1 – the coordinate (x,y) of the first point
  • p2 – the coordinate (x,y) of the first point
  • h1 – the water height at p1 (might be negative or positive)
  • h2 – the water height at p2 (might be negative or positive)
Returns:

the intersection point

src.manage_grid_8.main()

Used to test this module

src.manage_grid_8.newp(p0, p1, extra_pro)

This function find the start/end of the added profile. If only one profile is needed, it is just the point in the middle of the start/end of the profile. If mroe than one profile is needed, there are linearly distributed. This function only give the start and the end of the profile, the profile in full are constructed using find_profile_between()

Parameters:
  • p0 – the point at the profile p
  • p1 – the point at the profile p-1
  • extra_pro – the number of extra profile needed
Returns:

the start/end of the new profile

src.manage_grid_8.pass_grid_cell_to_node_lin(point_all, coord_c, vel_in, height_in, warn1=True, vtx_all=[], wts_all=[])

HABBY uses nodal information. Some hydraulic models have only ouput on the cells. This function pass from cells information to nodal information. The interpolation is linear and the cell centroid is used as the point where the cell information is carried. It can be used for one time step only.

This function is also used by hydraulic_chronic to pass from one discharge to another because each discharge has it own grid. hence, we need to interpolate

Parameters:
  • point_all – the coordinates of grid points (new grid here)
  • coord_c – the coordintes of the centroid of the cells (old grid here)
  • vel_in – the velocity data by cell
  • height_in – the height data by cell
  • warn1 – if True , show the warning (usually warn1 is True for t=0, False afterwards)
  • vtx_all – if it exists it means than the same grid was interpolated before. This info can be reused to speed up the interpolation of mulitple time step. (optional, need wts)
  • wts_all – if it exists it means than the same grid was interpolated before. This info can be reused to speed up the interpolation of mulitple time step. (optional, need vtx)
Returns:

velocity and height data by node

Technical Comment

This function can be very slow when a lot of time step needs to be interpolated if done directlty with scipy.interpolate. It was optimized for this case: http://stackoverflow.com/questions/20915502/speedup-scipy-griddata-for-multiple- interpolations-between-two-irregular-grids

src.manage_grid_8.plot_grid(point_all_reach, ikle_all, lim_by_reach, hole_all, overlap, point_c_all=[], inter_vel_all=[], inter_h_all=[], path_im=[])

This is a function to plot a grid and the output. It is mosty used to debug the grid creation. Contrarily to the more simple function plot_grid_simple, it is posible to plot the position of the holes (which indicates the dry area), the limits of the reaches used by triangle, the overlap between two reaches, and so on.

Parameters:
  • point_all_reach – the grid point by reach
  • ikle_all – the connectivity table by reach
  • lim_by_reach – the segment giving the limits of the grid
  • hole_all – the coordinates of the holes
  • overlap – the point of each reach which are also on an other reach
  • point_c_all – the centroid of each element
  • inter_vel_all – the interpolated velocity for each reach
  • inter_h_all – the interpolated height
  • path_im – the path where to save the image
src.manage_grid_8.plot_grid_simple(point_all_reach, ikle_all, fig_opt, inter_vel_all=[], inter_h_all=[], path_im=[], merge_case=False, time_step=0)

This is the function to plot grid output for one time step. The data is one the node. A more complicated function exists to plot the grid and additional information (manage-grid_8.plot_grid()) in case there are needed to debug. The present function only plot the grid and output without more information.

Parameters:
  • point_all_reach – the coordinate of the point. This is given by reaches.
  • ikle_all – the connectivity table. This is given by reaches.
  • fig_opt – the dictionary with the different options to create the figures
  • inter_vel_all – the velcoity data. This is given by reaches.
  • inter_h_all – the height data. This is given by reaches.
  • path_im – the path where the figure should be saved
  • merge_case – If True, we plot data from grid with merged substrate and hydrological data
  • time_step – time step to be added to the title
src.manage_grid_8.update_coord_pro_with_vh_pro(coord_pro, vh_pro_t)

The points describing the profile elevation and the points where velocity is measured might not be the same. Additionally,part of the profile might be dry and we have added points giving the wetted limit in vh_pro_t. They were are not in the original profil (coord_pro). In this function, coord_pro is recalculated to account for these modicfications. It is used by create_grid() and create_grid_one_profile, but only if vh_pro_t exists.

Parameters:
  • coord_pro – the original coord_pro
  • vh_pro_t – the value and position of h and velcoity measurement with the river limits
Returns:

updated coord_pro

More information in the document “More info on the grid” (linked above)

Estimhab -source

in src/estimhab.py

The module contains the Estimhab model. For an explanation on the estimhab model, please see the pdf document estimhab2008

src.estimhab.estimhab(qmes, width, height, q50, qrange, substrat, path_bio, fish_name, path_im, pict=False, fig_opt={}, path_txt=[])

This the function which forms the Estimhab model in HABBY. It is a reproduction in python of the excel file which forms the original Estimhab model.. Unit in meter amd m^3/sec

Parameters:
  • qmes – the two measured discharge
  • width – the two measured width
  • height – the two measured height
  • q50 – the natural median discharge
  • qrange – the range of discharge
  • substrat – mean height of substrat
  • path_im – the path where the image should be saved
  • path_bio – the path to the xml file with the information on the fishes
  • fish_name – the name of the fish which have to be analyzed
  • pict – if true the figure is shown. If false, the figure is not shown
  • fig_opt – a dictionnary with the figure option
  • path_txt – the path where to send the text data
Returns:

habitat value and useful surface (VH and SPU) as a function of discharge

Technical comments and walk-through

First, we get all the discharges on which we want to calculate the SPU (surface ponderée utile), using the inputs from the user.

Next we use hydrological rating curves (info on google if needed) to get the height and the width of the river for all discharge. The calculation is based on the width and height of the river measured at two discharges (given by the user).

Next, we get other parameters which are used in the preference curves such as the Froude number of the mean discharge or the Reynolds number.

Next, we load the fish data contains in the xml files in the biology folder. Careful, this is not the xml project file. This are the xml files described above in the “Class EstimhabW” section. There are one xml file per fish and they described the preference curves. For the argumentation on the form of the relationship, report yourself to the documentation of Estimhab (one pdf file should in the folder “doc “ in HABBY).

Then, we calculate the habitat values (VH and SPU). Finally, we plot the results in a figure and we save it as a text file.

src.estimhab.main()

Used to test this module.

src.estimhab.pass_to_float_estimhab(var_name, root)

This is a function to pass from an xml element to a float

Parameters:
  • root – the root of the open xml file
  • var_name – the name of the attribute in the xml file
Returns:

the float data

Stathab - source

in src/stathab_c

This module contains the function used to run the model stathab.For an explanation on the form of the stathab input, please see the pdf document stathabinfo

class src.stathab_c.Stathab(name_prj, path_prj)

The class for the Stathab model

create_hdf5()

A function to create an hdf5 file from the loaded txt. It creates “name_prj”_STATHAB.h5, an hdf5 file with the info from stathab

dengauss(x)

gaussian density, used only for debugging purposes. This is not used in Habby, but can be useful if scipy is not available (remplace all stat.norm.cdf with dengauss)

Parameters:x – the parameter of the gaussian
Returns:the gaussian density
dist_h(sh0, h0, bornh, h)

The calculation of height distribution acrros the river The distribution is a mix of an exponential and guassian.

Parameters:
  • sh0 – the sh of the original data sh is the parameter of the distribution, gives the relative importance of ganussian and exp distrbution
  • h – the mean height data
  • h0 – the mean height
  • bornh – the limits of each class of height
Returns:

disth the distribution of heights across the river for the mean height h.

dist_h_trop(v, h, mean_slope)

This function calulate the height distribution for steep tropical stream based on the R code from Girard et al. (stathab_hyd_steep). The frequency distribution is based on empirical data which is given in the list of numbers in the codes below. The final frequency distribution is in the form: t xf1 + (1-t) x f where t is a function of the froude number and the mean slope of the station.

The height limits are considered constant here (constrarily to dist_h where they are given in the parameter bornh).

Parameters:
  • v – the velcoity for this discharge
  • h – the height for this discharge
  • mean_slope – the mean slope of the station (usally in the data_ii[0] variable)
Returns:

the distribution of height

dist_v(h, d, bornv, v)

The calculation of velocity distribution across the river The distribution is a mix of an exponential and guassian.

Parameters:
  • h – the height which is related to the mean velocity v
  • d – granulo moyenne
  • bornv – the born of the velocity
  • v – the mean velocity
Returns:

the distribution of velocity across the river

dist_v_trop(v, h, h_waterfall, length_stat)

This function calulate the velocity distribution for steep tropical stream based on the R code from Girard et al. (stathab_hyd_steep). The frequency distribution is based on empirical data which is given in the list of numbers in the codes below. The final frequency distribution is in the form: t x f1 + (1-t) x f where t depends on the ratio of the length of station and the height of the waterfall.

Parameters:
  • v – the velcoity for this discharge
  • h – the height for this discharge
  • h_waterfall – the height of the waterfall
  • length_stat – the length of the station
Returns:

the distribution of velocity

find_path_hdf5_stat()

A function to find the path where to save the hdf5 file. Careful a simialar one is in hydro_GUI_2.py and in estimhab_GUI. By default, path_hdf5 is in the project folder in the folder ‘hdf5_files’.

find_sh0(disthmesr, h0)

the function to find sh0, using a minimzation technique. Not used because the output was string. Possibly an error on the bornes? We remplaced this function by the function find_sh0_maxvrais().

Parameters:
  • disthmesr – the measured distribution of height
  • h0 – the measured mean height
Returns:

the optimized sh0

find_sh0_maxvrais(disthmesr, h0)

the function to find sh0, using the maximum of vraisemblance. This function aims at reproducing the results from the c++ code. Hence, no use of scipy

Parameters:
  • disthmesr – the measured distribution of height
  • h0 – the measured mean height
Returns:

the optimized sh0

load_stathab_from_hdf5()

A function to load the file from an hdf5 whose name is given in the xml project file. If the name of the file is a relative path, use the path_prj to create an absolute path.

It works for tropical and temperate rivers. It checks the river type in the hdf5 files and used this river type regardless of the one curently used by the GUI. The method load_hdf5 in stathab_GUI get the value of self.riverint from the object mystathab to check the cohrenence between the GUI and the loaded hdf5.

load_stathab_from_txt(reachname_file, end_file_reach, name_file_allreach, path)

A function to read and check the input from stathab based on the text files. All files should be in the same folder. The file Pref.txt is read in run_stathab. If self.fish_chosen is not present, all fish in the preference file are read.

Parameters:
  • reachname_file – the file with the name of the reaches to study (usually listirv)
  • end_file_reach – the ending of the files whose names depends on the reach (with .txt or .csv)
  • name_file_allreach – the name of the file common to all reaches
  • path – the path to the file
Returns:

the inputs needed for run_stathab

power_law(qwh_r)

The function to calculate power law for discharge and width ln(h0 = a1 + a2 ln(Q)

Parameters:qwh_r – an array where each line in one observatino of Q, width and height
Returns:the coeff of the regression
save_xml_stathab(no_hdf5=False)

The function which saves the function related to stathab in the xml projexct files

Parameters:no_hdf5 – If True, no hdf5 file was created (usually because Stathab crashed at some points)
savefig_stahab(show_class=True)

A function to save the results in text and the figure. If the argument show_class is True, it shows an extra figure with the size of the different height, granulo, and velocity classes. The optional figure only works when stathab1 for temperate river is used.

savetxt_stathab()

A function to save the stathab result in .txt form

stathab_calc(path_pref='.', name_pref='Pref.txt')

The function to calculate stathab output.

Parameters:
  • path_pref – the path to the preference file
  • name_pref – the name of the preference file
Returns:

the biological preferrence index (np.array of [reach, specices, nbclaq] size), surface or volume by class, etc.

stathab_trop_biv(path_bio)

This function calculate the stathab outputs for the bivariate preference file in the case where the river is steep and in the tropical regions (usually the islands of Reunion and Guadeloupe).

Parameters:path_bio
Returns:
stathab_trop_univ(path_bio, by_vol)

This function calculate the stathab outputs for the univariate preference file in the case where the river is steep and in the tropical regions (usually the islands of Reunion and Guadeloupe).

Parameters:
  • path_bio – the path to the preference file usually biology/stathab
  • by_vol – If True the output is by volum (VPU instead of SPU) from the velcoity pref file
Returns:

the SPU or VPU

test_stathab(path_ori)

A short function to test part of the outputs of stathab in temperate rivers against the C++ code, It is not used in Habby but it is practical to debug.

Parameters:path_ori – the path to the files from stathab based on the c++ code
test_stathab_trop_biv(path_ori)

A short function to test part of the outputs of the stathab tropical rivers against the R code in the bivariate mode. It is not used in Habby but it is practical to debug. Stathab_trop+biv should be executed before. For the moment only the fish SIC is tested.

Parameters:path_ori – the path to the output files from stathab based on the R code
test_stathab_trop_uni(path_ori, by_vel=True)

A short function to test part of the outputs of the stathab tropical rivers against the R code in the univariate mode. It is not used in Habby but it is practical to debug. Stathab_trop_uni should be executed before. For the moment only the fish SIC is tested.

Parameters:
  • path_ori – the path to the output files from stathab based on the R code
  • by_vel – If True, the velcoity-based vpu is used. Otherise, it is height-based spu
src.stathab_c.load_float_stathab(filename, check_neg)

A function to load float with extra checks

Parameters:
  • filename – the file to load with the path
  • check_neg – if true negative value are not allowed in the data
Returns:

data if ok, -99 if failed

src.stathab_c.load_namereach(path, name_file_reach='listriv')

A function to only load the reach names (useful for the GUI). The extension must be .txt or .csv

:param path : the path to the file listriv.txt or listriv.csv :param name_file_reach: In case the file name is not listriv :return: the list of reach name

src.stathab_c.load_pref(filepref, path)

The function loads the different pref coeffficient contained in filepref, for the temperate river from Stathab

Parameters:
  • filepref – the name of the file (usually Pref.txt)
  • path – the path to this file
Returns:

the name of the fish, a np.array with the differen coeff

src.stathab_c.load_pref_trop_biv(code_fish, path)

This function loads the bivariate preference files for tropical rivers. The name of the file must be in the form of xbiv_XXX.csv where XXX is the three-letters fish code and x is whatever string.

Parameters:
  • code_fish – the code for the fish name in three letters (such as ASC)
  • path – the path to files
Returns:

the bivariate preferences

src.stathab_c.load_pref_trop_uni(code_fish, path)

This function loads the preference files for the univariate data. The file with the univariate data should be in the form of xuni-h_XXX where XX is the fish code and x is whatever string. The assumption is that the filename for velocity is very similar to the filename for height. In more detail that the string uni-h is changed to uni-v in the filename. Otherwise, the file are csv file with two columns: First is velocity or height, the second is the preference data.

Parameters:
  • code_fish – the code for the fish name in three letters (such as ASC)
  • path – the path to files
Returns:

the height data and velcoity data (h, pref) and (v,pref)

src.stathab_c.main()

used to test this module.

FStress - source

in src/fstress.py

This module contains the function used to run the model FStress.For an explanation on the form of the FStress text input, please see the last page of the pdf document stathabinfo

src.fstress.denstress(k, m, nbst)

This function calulates the stress distrbution function for FStress. This distribution has generally the form of k*exp() + (1-k)* Sigma(x-m)

Parameters:
  • k – the first parameter of the distribution
  • m – the second parameter of the disitribution
  • nbst – the number of stress class in the distribution
Returns:

the stress disitrbution for the (m,k) parameters

src.fstress.figure_fstress(qmod_all, vh_all, name_inv, path_im, name_river, fig_opt={})

This function creates the figures for Fstress, notably the suitability index as a function of discharge for all rivers

Parameters:
  • qmod_all – the modelled discharge for each river
  • vh_all – the suitability indoex for each invertebrate species for each river
  • name_inv – The four letter code of each selected invetebrate
  • path_im – the path where to save the figure
  • name_river – the name of the river
  • fig_opt – the figure option in a dictionnary
src.fstress.fstress_test(qmod_all, vh_all, name_inv, name_river, path_rre, fig_opt={})

This functions compares the output of the C programm of FStress and the output of this script. it is not used by HABBY, but it is practical to debug.

Parameters:
  • qmod_all – the modelled discharge for each river
  • vh_all – the suitability indoex for each invertebrate species for each river
  • name_inv – The four letter code of each selected invetebrate
  • name_river – the name of the river
  • path_rre – the path to the C output
src.fstress.func_stress(vm, h, tau)

This functions calculates the distrbution of stress on the bottom of the river based of height and velocity at one discharge. In other word, it calculate the distrbution of the “hemispheres”. This function is mainly a copy of stress function contains in the vitess2.c of the C source of FStress.

Parameters:
  • vm – the velocity for this diacharge value
  • h – the height for this discharge value
  • tau – the constraint values
Returns:

the stress distribution for this discharge

src.fstress.main()

This is not the main() of HABBY. This local function is used to test the Fstress model.

src.fstress.read_fstress_hdf5(hdf5_name, hdf5_path)

This functions reads an hdf5 file related to FStress and extract the relevant information.

Parameters:
  • hdf5_name – the name of the hdf5 file with the information realted to FStress
  • hdf5_path – the path to this file

:return:[[q,w,h], [q,w,h]] for each river, [qmin,qmax] for each river, the river names, and the selected fish

src.fstress.read_pref(path_bio, name_bio)

This function loads and read the preference file for FStress.

Parameters:
  • path_bio – the path to the preference file
  • name_bio – the name of the preference file
Returns:

the name invertebrate and their preference coefficient

src.fstress.run_fstress(data_hydro, qrange, riv_name, inv_select, pref_all, name_all, name_prj, path_prj)

This function run the model FStress for HABBY. FStress is based on the model of Nicolas Lamouroux. This model estimates suitability indices for invertebrate in relation with shear stress distributions. However, shear stress do not needs to be measured. It is statistically estimated based on velocity and height measurement.

Parameters:
  • riv_name – the name of the river-> string
  • data_hydro – the hydrological data (q,w,h for each river in riv name) -> list of list
  • qrange – the qmin and qmax for each river [qmin,qmax] -> list of list
  • inv_select – the name of the selected invetebrate
  • pref_all – the preference data for all invertebrate
  • name_all – the four letter code of all possible invertebrate
  • path_prj – the path to the project-> string
  • name_prj – the name of the project-> string
src.fstress.save_fstress(path_hdf5, path_prj, name_prj, name_bio, path_bio, riv_name, data_hydro, qrange, fish_list)

This function saves the data related to the fstress model in an hdf5 file and write the name of this hdf5 file in the xml project file.

Parameters:
  • path_hdf5 – the path where to sdave the hdf5-> string
  • path_prj – the path to the project-> string
  • name_prj – the name of the project-> string
  • name_bio – the name of the preference file-> string
  • path_bio – the path to the preference file-> string
  • riv_name – the name of the river-> string
  • data_hydro – the hydrological data (q,w,h for each river in riv name) -> list of list
  • qrange – the qmin and qmax for each river [qmin,qmax] -> list of list
  • fish_list – the name of the selected invertebrate (! no fish) -> list of string
src.fstress.write_txt(qmod_all, vh_all, name_inv, path_txt, name_river, timestamp=True)

This function writes the txt outputs for FStress

Parameters:
  • qmod_all – the modelled discharge for each river
  • vh_all – the suitability indoex for each invertebrate species for each river
  • name_inv – The four letter code of each selected invetebrate
  • path_txt – the path where to save the text file
  • name_river – the name of the river
  • timestamp – If True, the file is saved with time stamp. Otherwise, it is not.

Substrate

in src/substrate.py

This module contains the function to load and manage the substrate data.

src.substrate.create_dummy_substrate_from_hydro(h5name, path, new_name, code_type, attribute_type, nb_point=200, path_out='.')

This function takes an hydrological hdf5 as inputs and create a shapefile of substrate and a text file of substrate which can be used as input for habby. The substrate data is random. So it is mainly useful to test an hydrological input.

The created shape file is rectangular with a size based on min/max of the hydrological coordinates. The substrate grid is not the same as the hydrological grids (which is good to test the programm). In addition, one side of the shp is smaller than the hydrological grid to test the ‘default substrate’ option (which is used if the substrate shapefile is not big enough).

Parameters:
  • h5name – the name of the hydrological hdf5 file
  • path – the path to this file
  • new_name – the name of the create shape file wihtout the shp (string)
  • code_type – the code type for the substrate (Sandre, Cemagref, Const_cemagref, or EDF). All subtrate value to 4 for Const_cemagref.
  • attribute_type – if the substrate is given in the type coarser/dominant/..(0) or in percenctage (1)
  • nb_point – the number of point needed (more points results in smaller substrate form)
  • path_out – the path where to save the new substrate shape
src.substrate.edf_to_cemagref(records)

This function passes the substrate data from the code type ‘EDF” to the code type “Cemagref”. As the code 1 from EDF can be the code 2 or code 1 in Cemagref, a code 1 in EDF is code 1 in Cemagref half of the time and code 2 the other half of the time. This function is not optimized yet. For the definiction of the code, see the tabular at the 14 of the LAMMI manual. THIS IS NOT RIGHT AS CLASS ARE NOT SPEAREATED IDENTICALLY, TO BE CORRECTED !!!

Parameters:records – the substrate data in code edf
Returns:the substrate data in code cemagref
src.substrate.edf_to_cemagref_by_percentage(records)

This function change the subtrate in a percetage form from edf code to cemagref code :param records: the subtrate data (in 8x len tabular) :return:

src.substrate.fig_substrate(coord_p, ikle, sub_pg, sub_dom, path_im, fig_opt={}, xtxt=[-99], ytxt=[-99], subtxt=[-99])

The function to plot the substrate data, which was loaded before. This function will only work if the substrate data is given using the cemagref code.

Parameters:
  • coord_p – the coordinate of the point
  • ikle – the connectivity table
  • sub_pg – the information on subtrate by element for the “coarser part”
  • sub_dom – the information on subtrate by element for the “dominant part”
  • fig_opt – the figure option as a doctionnary
  • xtxt – if the data was given in txt form, the orignal x data
  • ytxt – if the data was given in txt form, the orignal y data
  • subtxt – if the data was given in txt form, the orignal sub data
  • path_im – the path where to save the figure
src.substrate.get_all_attribute(filename, path)

This function open a shapefile and get the list of all the attibute which is contains in it.

Parameters:
  • filename – the name of the shpae file
  • path – the path to this shapefile
Returns:

a list with the name and information of all attribute. The form of each element of the list is [name(str), type (F,N), int, int]

src.substrate.get_useful_attribute(attributes)

This function find if the substrate was given in percentage or coarser/dominant/accesory and get the attribute or header name useful to load the substrate. If the subtrate is given by percentage, it is important to get attribute in order (S1, S2, S3) and not (S3, S1,S2) for this function and the next functions.

Parameters:attributes – The list of attribute from the shp file or the header list from the text file
Returns:The attribute type as int (percentage=1 and coarser/... = 0 and failed = -99) and the attribute names If we are in the attribute type 0, attribute list is in the order of: coarser, dominant, and accessory
src.substrate.load_sub_shp(filename, path, code_type, dominant_case=0)

A function to load the substrate in form of shapefile.

Parameters:
  • filename – the name of the shapefile
  • path – the path where the shapefile is
  • code_type – the type of code used to define the substrate (string)
  • dominant_case – an int to manage the case where the transfomation form percentage to dominnat is unclear (two maxinimum percentage are equal from one element). if -1 take the smallest, if 1 take the biggest, if 0, we do not know.
Returns:

grid in form of list of coordinate and connectivity table (two list) and an array with substrate type and a boolean which allows to get the case where we have tow dominant case

src.substrate.load_sub_txt(filename, path, code_type, path_shp='.')

A function to load the substrate in form of a text file. The text file must have 4 columns x,y coordinate and coarser substrate type, dominant substrate type. It is transform to a grid using a voronoi transformation. There is one line of header (free texte).

The voronoi transformation might look strange as it is often bigger than the original point. However, this is just the mathematical result.

At the end of this fnuction, the resulting grid is exported in a shapefile form.

Parameters:
  • filename – the name of the shapefile
  • path – the path where the shapefile is
  • code_type – the type of code used to define the substrate (string)
  • path_shp – the path where to save the shapefile (usually the input folder)
Returns:

grid in form of list of coordinate and connectivity table (two list) and an array with substrate type and (x,y,sub) of the orginal data

src.substrate.main()

Used to test this module.

src.substrate.modify_grid_if_concave(ikle, point_all, sub_pg, sub_dom)

This function check if the grid in entry is composed of convex cell. Indeed, it is possible to have concave cells in the substrate grid. However, this is unpractical when the hydrological grid is merged with the subtrate grid. Hence, we find here the concave cells. These cells are then modified using the triangle module.

The algotithm is based on the idea that when you have a convex polygon you turn always in the same direction. When you have a concave polygon sometime you will turn left, sometime you will turn right. To check this, we can take the determinant betwen each vector which compose the cells and check if they have the same sign. Triangle are always convex.

Parameters:
  • ikle – the connectivity table of the grid (one reach, one time step as substrate grid is constant)
  • point_all – the point of the grid
  • sub_pg – the coarser substrate, one data by cell
  • sub_dom – the dominant subtrate, one data by cell
Returns:

ikle, point_all with only convexe cells

src.substrate.open_shp(filename, path)

This function open a ArcGIS shpaefile.

Parameters:
  • filename – the name of the shapefile
  • path – the path to this shapefile
Returns:

a shapefile object as define in the model

src.substrate.percentage_to_domcoarse(sub_data, dominant_case)

This function is used to pass from percentage data to dominant/coarse. As the code 8 from the subtrate in Cemagref code is slab, we do not the 8 code as the coarser substrate.

Parameters:
  • sub_data – the subtrate data in percentage from Lammi
  • dominant_case – an int to manage the case where the transfomation form percentage to dominnat is unclear (two maxinimum percentage are equal from one element). if -1 take the smallest, if 1 take the biggest, if 0, we do not know.
Returns:

src.substrate.sandre_to_cemagref(records)

This function passes the substrate data from the code type “Sandre” to the code type “Cemagref”. This function is not optimized yet. For the definition of the code, see the tabular at the 14 of the LAMMI manual.

Parameters:records – the substrate data in code samdre
Returns:the substrate data in code cemagref

Description of substrate code

Internally HABBY uses the Cemagref code to describe the substrate. It also accept the code Sandre in entry and modify it afterwards to Cemagref code. If data from the LAMMI model is used, the EDF code is transformed to the Cemagref code even if some uncertainties results from this conversion. This might have an impact on the results.

The following table describes the different substrate codes:

The different substrate codes used in HABBY.

Description of the format of the substrate input

There are tow types of intputs: Text and shapefile inputs.

The text inputs is composed of four columns: x,y, the coarser substrate type, and the dominant subtrate type. The substrate can be in Sandre or Cemagref code. The first line of the text file is ignored by HABBY and can be used as header or let empty.

The substrate shapefile is a polygon shapefile created by ArcMap or another GIS-Software. Its attribute table has two or three columns. The third column is the “accessory” substrate and is not necessary. It is not used by HABBY currenlty. The first and second columns are the dominant and corser substrate data (order as wished by the user). The name of the column with the coarser subtrate can be chosed from the following options: ‘plus gros’, ‘coarser’, ‘PG’, ‘PLUS GROS’, ‘COARSER’. The name of the column with the dominant subtrate can be chosed from the following options: ‘dominant’, ‘DOMINANT’, ‘DM’. The name of the column with the accesory subtrate can be chosed from the following options: ‘acc’, ‘ACC’, ‘ACCESSORY’, ‘accessoire’, ‘ACCESSOIRE’.

Merge the grid

in src/mesh_grid2.py

This module contains the function to merge the substrate grid and the hydrological grid. It cut the hydrological grid to the form of each of the substrate. An important hypothesis is that each polygon forming the subtrate should convex.

src.mesh_grid2.check_clockwise(ikle, point)

This function check that each grid cell is given in a clockwise order. This is useful because we might create shapefile afterward. ArcMap beleives that we have hole if a grid cell is in counter-clockwise order.

To check the clockwise order, we sum (x2-x1)*(y2+y1) over the three edges. Here is a more information on the algo: http://blog.element84.com/polygon-winding.html

Parameters:
  • ikle – the connectivity table
  • point – the grid point
Returns:

the connectivity table with the point in clockewise order

src.mesh_grid2.create_merge_grid(ikle, coord_p, data_sub_pg, data_sub_dom, vel, height, ikle_sub, default_data, data_crossing, sub_cell)

A function to update the grid after finding the crossing points. It also get the substrate_data for each cell of the new grid.

Parameters:
  • ikle – the hydrological grid to be merge with the substrate grid
  • coord_p – the coordinate of the point of the hydrological grid
  • data_sub_pg – the coarser substrate data by hydrological cell (3 information by cells realted to the three points)
  • data_sub_dom – the dominant substrate data by hydrological cell (3 information by cells realted to the three points)
  • vel – the velocity (one time step, one reach) for each point in coord_p
  • height – the water height (one time step, one reach) for each point in coord_p
  • ikle_sub – the connectivity table for the substrate
  • default_data – the default substrate data
  • data_crossing – the hydrological elment with a crossing and the info for this crossing (a list of list)
Returns:

the new grid

Technical comments

This function corrects all element of the grids where a crossing point have been found by the function find_sub_and_cross()

There are three cases:

  1. one crossing point -> no change
  2. two crossing points and subtrate point inside -> done manually. We take the two crossing point and the side on which the crossing is done. Based on this, we correct the grid.
  3. more than two crossing point on the elements -> We call the extrenal module triangle to re-do some triagulations into the element. This last cases covers many possible case, but it is slow. To optimize, we can think about writing more individual cases. To follow the border of each subtrate cell in the “special cell”, we do one triangulation by subtrate element, so we can have two or three triangulation. It is also important there that the substrate is convex as the triangulation is not constrained.
src.mesh_grid2.fig_merge_grid(point_all_both_t, ikle_both_t, path_im, name_add='', ikle_orr=[], point_all_orr=[])

A function to plot the grid after it was merged with the substrate data. It plots one time step at the time. This function is not used anymore by Habby. Indded, mesh_grid2 uses the function provided in manage_grid8.py to plot the grid and data after it is merged with the substrate. However, this function could be useful to debug if one wants to only plots teh grid and not the height/velocity data

Parameters:
  • point_all_both_t – the coordinate of the points of the updated grid
  • ikle_both_t – the connectivity table
  • path_im – the path where the image should be saved
  • name_add – the anem to be added to the figure name
  • ikle_orr – the orginial ikle
  • point_all_orr – the orginal point_all
src.mesh_grid2.find_sub_and_cross(ikle_sub, coord_p_sub, ikle, coord_p, data_sub_pg, data_sub_dom, first_time=False)

A function which find where the crossing points are. Crossing points are the points on the triangular side of the hydrological grid which cross with a side of the substrate grid. The algo based on finding if points of one elements are in the same polygon using a ray casting method. We assume that the polygon forming the subtrate grid are convex. Otherwise it would not work in all cases. We also neglect the case where a substrate cell at the border of the subtrate grid is fully in a hydrological cell.

IMPORTANT: polygon should be convex.

Parameters:
  • ikle_sub – the connectivity table for the substrate
  • coord_p_sub – the coordinates of the poitn forming the subtrate
  • ikle – the connectivity table for the hydrology
  • coord_p – the coordinate of the hydrology
  • data_sub_dom – the subtrate data by subtrate cell (dominant)
  • data_sub_pg – the substrate data by substrate cell (coarser)
  • first_time – If True, we preapre the subtrate data
Returns:

the new substrate grid (ikle_sub, coord_p_sub, data_sub_pg, data_sub_dom, sub_cell), the data for the crossing point (hydrological element with a crossing, crossing point, substrate element linked with the crossing point, point of substrate inside, substrate element linked with the substrate point, side of the crossing points, substrate leemnt link with hydro_point).

src.mesh_grid2.get_new_vel_height_data(newp, point_old, data_old)

This function gets the height and velcoity data for a new point in or on the side of an element. It does an average of the data (velocity or height) given at the node of the original (old) elements. This average is weighted as a function of the distance of the point.

Parameters:
  • newp – the coordinates of the new points
  • point_old – the coordinates of thre three old points (would work with more than three)
  • data_old – the data for the point in point_old
Returns:

the new data

src.mesh_grid2.inside_trigon(pt, p0, p1, p2)

This function check if a point is in a triangle using the barycentric coordinates.

Parameters:
  • pt – the point to determine if it is in or not
  • p0 – the first point of triangle
  • p1 – the second point of triangle
  • p2 – the third point of triangle
Returns:

A boolean (Ture if pt inside of triangle)

src.mesh_grid2.intersec_cross(hyd1, hyd2, sub1, sub2)

A function function to calculate the intersection, segment are not parrallel, used in case where we know that the intersection exists

Parameters:
  • hyd1 – the first hydrological point
  • hyd2 – the second
  • sub1 – the first substrate point
  • sub2 – the second
Returns:

intersection

src.mesh_grid2.main()

Used to test this module.

src.mesh_grid2.merge_grid_and_save(hdf5_name_hyd, hdf5_name_sub, path_hdf5, default_data, name_prj, path_prj, model_type, q=[], print_cmd=False)

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().

Parameters:
  • hdf5_name_hyd – the name of the hdf5 file with the hydrological data
  • hdf5_name_sub – the name of the hdf5 with the substrate data
  • path_hdf5 – the path to the hdf5 data
  • default_data – The substrate data given in the region of the hydrological grid where no substrate is given
  • name_prj – the name of the project
  • path_prj – the path to the project
  • model_type – the type of the “model”. In this case, it is just ‘SUBSTRATE’
  • q – used to share info with the GUI when this thread have finsihed (print_cmd = False)
  • print_cmd – If False, print to the GUI (usually False)
src.mesh_grid2.merge_grid_hydro_sub(hdf5_name_hyd, hdf5_name_sub, path_hdf5, default_data=1, path_prj='')

After the data for the substrate and the hydrological data are loaded, they are still in different grids. This functions will merge both grid together. This is done for all time step and all reaches. If a constant substrate is there, the hydrological hdf5 is just copied.

Parameters:
  • hdf5_name_hyd – the name of the hdf5 file with the hydrological data
  • hdf5_name_sub – the name of the hdf5 with the substrate data
  • path_hdf5 – the path to the hdf5 data
  • default_data – The substrate data given in the region of the hydrological grid where no substrate is given
  • path_prj – the path to the project
Returns:

the connectivity table, the coordinates, the substrated data, the velocity and height data all in a merge form.

Biological Info

in src/bio_info.py

This module contains the script to show and manage the biological models (preference curves) which are in the biology folder.

src.bio_info.change_unit(data, unit)

This function modify the unit of the data to SI unit. Currently it accept the following unit : Centimeter, Meter, CentimeterPerSecond, MeterPerSecond, Millimeter, “Code EVHA 2.0 (GINOT 1998)”

Parameters:
  • data – the data which has to be change to SI unti
  • unit – the unit code
src.bio_info.create_and_fill_database(path_bio, name_database, attribute)

This function create a new database when Habby starts. The goal of creating a database is to avoid freezing the GUI when info on the preference curve are asked. So it is possible to select one curve and have information without seeing too much of a delay.

This is not used anymore by HABBY as the xml file is really small. It could however be useful if the xml file becomes too big. In this case, this function could be called if modification are found in the pref_file folder and would create a database.

The attribute can be modified, but they should all be of text type. It is also important to keep stage at the first attribute. The modified attribute should reflect the attribute of the xml file. If it not possible, lines should be added in the “special case” attributes”. The main table with the data is called pref_bio.

Parameters:
  • path_bio – the path to the biological information (usually ./biology)
  • name_database – the name of the database (string) without the path
  • attribute – the attribute in the database (only text type)
Returns:

a boolean (True if everthing ok, False otherwise)

src.bio_info.create_pdf(xmlfiles, stages_chosen, path_bio, path_im_bio, path_out, fig_opt)

This functionc create a pdf with information about the fish. It tries to follow the chosen language, but the stage name are not translated and the decription are usually only given in French.

Parameters:
  • xmlfiles – the name of the xmlfile (without the path!)
  • stages_chosen – the stage chosen (might not be all stages)
  • path_bio – the path with the biological xml file
  • path_im_bio – the path with the images of the fish
  • path_out – the path where to save the .pdf file (usually other_outputs)
  • fig_opt – the figure options (contain the chosen language)
src.bio_info.execute_request(path_bio, name_database, request)

This function execute the SQL request given in the string called request. it saves the found data in a variable. The idea is to use this function for SELELCT X FROM X WHERE ... , not really to handle all possible request. It also opens and close the database name_database to do this. This is not used anymore by HABBY as we do not use a database. It could however be useful if the xml file becomes too big.

Parameters:
  • path_bio – the path to the biological information (usually ./biology)
  • name_database – the name of the database (string) without the path
  • request – the SQL request in a string form
Returns:

the result

src.bio_info.figure_pref(height, vel, sub, code_fish, name_fish, stade, get_fig=False, fig_opt={})

This function is used to plot the preference curves.

Parameters:
  • height – the height preference data (list of list)
  • vel – the height preference data (list of list)
  • sub – the height preference data (list of list)
  • code_fish – the three letter code which indiate which fish species is analyzed
  • name_fish – the name of the fish analyzed
  • stade – the name of the stade analyzed (ADU, JUV, ...)
  • get_fig – usually False, If True return the figure (to modfied it more)
src.bio_info.get_stage(names_bio, path_bio)

This function loads all the stages present in a list of xml preference files (JUV, ADU, etc) and the latin name of the fish species. All the files should be in the same folder indicated by path_bio. It is mainly used by habby_cmd but it can be useful in other cases also.

Parameters:
  • names_bio – A list of xml biological preference file
  • path_bio – the path to the xml preference files (usually ‘./biology’)
Returns:

the stages in a list of string

src.bio_info.load_evha_curve(filename, path)

This function is used to load the preference curve in the EVHA form . It will be useful to create xml preference file, but it is not used direclty by HABBY. This function does not have much control on user input as it is planned to be used only by people working on HABBY. The order of the data in the file must be height, velocity, substrate

Parameters:
  • filename – the name of file containing the preference curve for EVHA
  • path – the path to this file
Returns:

preference for height, vel, sub in a list of list form, name of the fish, code, stade and description

src.bio_info.load_xml_name(path_bio, attributes, preffiles=[])

This function looks for all preference curves found in the path_bio folder. It extract the fish name and the stage. to be corrected if more than one language. The name of attribute_acc should be coherent with the one from the xml file apart from the common name which should be in the form language_common_name (so we can wirte something in the GUI to get all langugage if we get something else than English or French).

If one use the argument preffiles, only part of the xml file are loaded. Otherwise all xml file are loaded.

Careful, the first attribute is relgated at the last place of the list return. This is confusing but it is really useful for the GUI.

Parameters:
  • path_bio – the path to the biological function
  • attributes – the list of attribute which should be possible to search from the GUI or, more generally which should be in data-fish which is returned.
  • preffiles – If there is a list of string there, it only read this files
Returns:

the list of stage/fish species with the info from [name for GUi, s, xmlfilename, attribute_acc without s]

src.bio_info.main()

Used to test the module on the biological preference

src.bio_info.plot_hydrosignature(xmlfile)

This function plots the hydrosignature in the vclass and hclass given in the xml file. It does only work if: units are SI (meter and m/s) and if the order of data is ‘velocity increasing and then height of water increasing”.

Parameters:xmlfile – the path and name of the xmlfile
src.bio_info.read_pref(xmlfile)

This function reads the preference curve from the xml file and get the subtrate, height and velocity data. It return the data in meter. Unit for space can be in centimeter, milimeter or meter. Unit for time should be in second .The unit attribute of the xml files should be coherent with the data.

Parameters:xmlfile – the path and name to the xml file (string)
Returns:height, vel, sub, code_fish, name_fish, stade
src.bio_info.test_evah_xml_pref(path_xml, path_evha)

This function is used to visually compared the evha (.PRF) curve and the xml curve based on the evah curve. Obviously the xml file should contain the same data than the evha curve (when the xml file are based on the evah curve). An important assumption of this function is that the data in the xml file is in the order: fry, juvenile, adult.

Parameters:
  • path_xml – the path to the folder which contains the xml files
  • path_evha – the path to the evha folder which contains the PRF files

Calculation habitat

in src/calcul_hab.py

This module calculates the habitat value for the fish and creates the outputs (text files, shapefile, and figures).

src.calcul_hab.calc_hab(merge_name, path_merge, bio_names, stages, path_bio, opt)

This function calculates the habitat value. It loads substrate and hydrology data from an hdf5 files and it loads the biology data from the xml files. It is possible to have more than one stage by xml file (usually the three stages are in the xml files). There are more than one method to calculte the habitat so the parameter opt indicate which metho to use. 0-> usde coarser substrate, 1 -> use dominant substrate

Parameters:
  • merge_name – the name of the hdf5 with the results
  • path_merge – the path to the merged file
  • bio_names – the name of the xml biological data
  • stages – the stage chosen (youngs, adults, etc.). List with the same length as bio_names.
  • path_bio – The path to the biological folder (with all files given in bio_names
  • opt – an int fron 0 to n. Gives which calculation method should be used
Returns:

the habiatat value for all species, all time, all reach, all cells.

src.calcul_hab.calc_hab_and_output(hdf5_file, path_hdf5, pref_list, stages_chosen, name_fish, name_fish_sh, run_choice, path_bio, path_txt, path_shp, path_para, path_im, q=[], print_cmd=False, fig_opt={}, path_im_bio='', xmlfiles=[])

This function calculates the habitat and create the outputs for the habitat calculation. The outputs are: text output (spu and cells by cells), shapefile, paraview files, one 2d figure by time step. The 1d figure is done on the main thread as we want to show it to the user on the GUI. This function is called by bio_info_GUI.py on a second thread to minimize the freezing on the GUI.

Parameters:
  • hdf5_file – the name of the hdf5 with the results
  • path_hdf5 – the path to the merged file
  • pref_list – the name of the xml biological data
  • stages_chosen – the stage chosen (youngs, adults, etc.). List with the same length as bio_names.
  • name_fish – the name of the chosen fish
  • name_fish_sh – In a shapefile, max 8 character for the column name. Hence, a modified name_fish is needed.
  • run_choice – an int fron 0 to n. Gives which calculation method should be used
  • path_bio – The path to the biological folder (with all files given in bio_names)
  • path_txt – the path where to save the text file
  • path_shp – the path where to save shapefile
  • path_para – the path where to save paraview output
  • path_im – the path where to save the image
  • path_im_bio – the path where are the image of the fish
  • q – used in the second thread
  • print_cmd – if True the print command is directed in the cmd, False if directed to the GUI
  • fig_opt – the options to crete the figure if save_fig1d is True
  • xmlfiles – the list of the xml file (only useful to get the preference curve report, so not used by habby_cmd)

** Technical comments**

This function redirect the sys.stdout. The point of doing this is because this function will be call by the GUI or by the cmd. If it is called by the GUI, we want the output to be redirected to the windows for the log under HABBY. If it is called by the cmd, we want the print function to be sent to the command line. We make the switch here.

src.calcul_hab.calc_hab_norm(ikle_all_t, point_all_t, vel, height, sub, pref_vel, pref_height, pref_sub, percent=False, take_sub=True)

This function calculates the habitat suitiabilty index (f(H)xf(v)xf(sub)) for each and the SPU which is the sum of all habitat suitability index weighted by the cell area for each reach. It is called by clac_hab_norm.

Parameters:
  • ikle_all_t – the connectivity table for all time step, all reach
  • point_all_t – the point of the grid
  • vel – the velocity data for all time step, all reach
  • height – the water height data for all time step, all reach
  • sub – the substrate data (can be coarser or dominant substrate based on function’s call)
  • pref_vel – the preference index for the velcoity (for one life stage)
  • pref_sub – the preference index for the substrate (for one life stage)
  • pref_height – the preference index for the height (for one life stage)
  • percent – If True, the variable sub is in percent form, not in the form dominant/coarser
  • take_sub – If False, the substrate data is neglected.
Returns:

vh of one life stage, area, habitat value

src.calcul_hab.find_pref_value(data, pref)

This function finds the preference value associated with the data for each cell. For this, it finds the last point of the preference curve under the data and it makes a linear interpolation with the next data to find the preference value. As preference value is sorted, it uses the module bisect to accelerate the process.

Parameters:
  • data – the data on the cells (for one time step, on reach)
  • pref – the pref data [pref, class data]
src.calcul_hab.plot_hist_biology(vh_all_t_sp, area_c_all_t, name_fish, fig_opt, path_im, timestep, name_base, sim_name=[], erase_id=False)

This function plot the historgram of the habitat value for the slected species and time step. This historgramm is weighted by the area of the cell.

Parameters:
  • vh_all_t_sp – The habitat value by cell by reach by time step by species
  • area_c_all_t – the area of each cell
  • name_fish – the name of the fish chosen :param fig_opt: the figure options
  • path_im – the path where to save the images
  • timestep – a list with the time step to be plotted
  • name_base – the base on which to form the figure name
  • sim_name – the name of the time steps when not 0,1,2,3
  • erase_id – If True, we erase a figure with an identical name
src.calcul_hab.plot_hist_hydro(hdf5_file, path_hdf5, vel_c_all_t, height_c_all_t, area_c_all_t, fig_opt, path_im, timestep, name_base, sim_name=[], erase_id=False)

This function plots an historgram of the hydraulic and substrate data for the selected timestep. This historgramm is weighted by the area of the cell. The data is based on the height and velocity data by cell and not on the node.

Parameters:
  • hdf5_file – the name of the hdf5 file
  • path_hdf5 – the path to this file
  • vel_c_all_t – the velcoity for all reach all time step by cell
  • height_c_all_t – the water height for all reach all time step by cell
  • area_c_all_t – the aire of cells for all reach, all time step
  • fig_opt – the figure options
  • path_im – the path where to save the images
  • timestep – a list with the time step to be plotted
  • name_base – the base on which to form the figure name
  • sim_name – the name of the time steps when not 0,1,2,3
  • erase_id – If True, we erase a figure with an identical name
src.calcul_hab.remove_image(name, path, format1)

This is a small function used to erase images if erase_id is True. We have a function because different format czan be used and because it is done often in the functions above.

Parameters:
  • name – the name of the file t be erase (without the extension)
  • path – the path to the file
  • format1 – the type of format
Returns:

src.calcul_hab.save_hab_fig_spu(area_all, spu_all, name_fish, path_im, name_base, fig_opt={}, sim_name=[], erase_id=False, do_save=True)

This function creates the figure of the spu as a function of time for each reach. if there is only one time step, it reverse to a bar plot. Otherwise it is a line plot.

Parameters:
  • area_all – the area for all reach
  • spu_all – the “surface pondere utile” (SPU) for each reach
  • name_fish – the list of fish latin name + stage
  • path_im – the path where to save the image
  • fig_opt – the dictionnary with the figure options
  • name_base – a string on which to base the name of the files
  • sim_name – the name of the time steps if not 0,1,2,3
  • erase_id – If True, figure from identical simuation are erased
  • do_save – If False, the figure is not saved, but the figure is returned to be used for something else
src.calcul_hab.save_hab_shape(name_merge_hdf5, path_hdf5, vh_data, vel_data, height_data, name_fish_sh, path_shp, name_base, sim_name=[], save_perc=False, erase_id=False)

This function create the output in the form of a shapefile. It creates one shapefile by time step. It put all the reaches together. If there is overlap between reaches, it does not care. It create an attribute table with the habitat value, velocity, height, substrate coarser, substrate dominant. It also create a shapefile 0 with the whole profile without data.

The name of the column of the attribute table should be less than 10 character. Hence, the variable name_fish has been adapted to be shorter. The shorter name_fish is called name_fish_sh.

Parameters:
  • name_merge_hdf5 – the name of the hdf5 merged file
  • path_hdf5 – the path to the hydrological hdf5 data
  • vel_data – the velocity by reach by time step on the cell (not node!)
  • height_data – the height by reach by time step on the cell (not node!)
  • vh_data – the habitat value data by speces by reach by tims tep
  • name_fish_sh – the list of fish latin name + stage
  • path_shp – the path where to save the shpaefile
  • name_base – a string on which to base the name of the files
  • sim_name – the time step’s name if not 0,1,2,3
  • save_perc – It true the substrate in percentage will be added to the shapefile
  • erase_id – If True, we erase old text file from identical hydraulic model
src.calcul_hab.save_hab_txt(name_merge_hdf5, path_hdf5, vh_data, vel_data, height_data, name_fish, path_txt, name_base, sim_name=[], erase_id=False)

This function print the text output. We create one set of text file by time step. Each Reach is separated by the key work REACH follwoed by the reach number (strating from 0). There are three files by time steps: one file which gives the connectivity table (starting at 0), one file with the point coordinates in the coordinate systems of the hydraulic models (x,y), one file wiche gives the results. In all three files, the first column is the reach number. In the results files, the next columns are velocity, height, substrate, habitat value for each species. Use tab instead of space to help with excel import.

The name and the form of the files do not change with the chosen language. The idea is that these files are quite big and that they will mostly be used by computer program. So it is easier for the user if the name and form is coherent.

Parameters:
  • name_merge_hdf5 – the name of the hdf5 merged file
  • path_hdf5 – the path to the hydrological hdf5 data
  • vel_data – the velocity by reach by time step on the cell (not node!)
  • height_data – the height by reach by time step on the cell (not node!)
  • vh_data – the habitat value data by speces by reach by tims tep
  • name_fish – the list of fish latin name + stage
  • path_txt – the path where to save the text file
  • name_base – a string on which to base the name of the files
  • sim_name – the name of the simulation/time step (list of strings)
  • erase_id – If True, we erase old text file from identical hydraulic model
src.calcul_hab.save_spu_txt(area_all, spu_all, name_fish, path_txt, name_base, sim_name=[], lang=0, erase_id=False)

This function create a text files with the folowing columns: the tiem step, the reach number, the area of the reach and the spu for each fish species. Use tab instead of space to help with excel import.

Parameters:
  • area_all – the area for all reach
  • spu_all – the “surface pondere utile” (SPU) for each reach
  • name_fish – the list of fish latin name + stage
  • path_txt – the path where to save the text file
  • name_base – a string on which to base the name of the files
  • sim_name – the name of the time step
  • lang – an int which indicates the chosen language (0 is english)
  • erase_id – If True, we erase old text file from identical hydraulic model
src.calcul_hab.save_vh_fig_2d(name_merge_hdf5, path_hdf5, vh_all_t_sp, path_im, name_fish, name_base, fig_opt={}, time_step=[-1], sim_name=[], save_fig=True, erase_id=False)

This function creates 2D map of the habitat value for each species at the time step asked. All reaches are ploted on the same figure.

Parameters:
  • name_merge_hdf5 – the name of the hdf5 merged file
  • path_hdf5 – the path to the hydrological hdf5 data
  • vh_all_t_sp – the habitat value for all reach all time step all species
  • path_im – the path where to save the figure
  • name_fish – the name and stage of the studied species
  • name_base – the string on which to base the figure name
  • fig_opt – the dictionnary with the figure options
  • time_step – which time step should be plotted
  • sim_name – the name of the time step if not 0,1,2,3
  • save_fig – If True the figure is saved

Create Paraview Files

in src/new_create_vtk.py in src/evtk.py in src/hl.py in src/vtk.py in src/xml_vk.py

Theses modules contain the scripts to create Paraview input which are binary xml-based vtu files. This part is heavily based on the module Pyevtk created by Paulo Herrera (https://bitbucket.org/pauloh/pyevtk). Hence, the only script written for HABBY is in new_create_vtk.py. This script then called one function in hl.py which then called the three other scripts as in Pyevtk (not documented here).

src.new_create_vtk.habitat_to_vtu(file_name_base, path_out, path_hdf5, name_hdf5, vh_all_t_sp, height_c_data, vel_c_data, name_fish, erase_id)

This function creates paraview input in the new, non-legacy xml format. This function called the evtk class written by Paulo Herrera, which is available at https://bitbucket.org/pauloh/pyevtk/downloads/

The format for paravier input file is descirbed in paraview_file_format.pdf in the doc folder of HABBY.

The data of the paraview file created here is usually in binary form. The idea of paraview for a binary file is to keep the same usual xml file. The data is encoded to base64. Before the binary array, there is a 32-bits interger which contains the data length in bytes. More info: http://www.earthmodels.org/software/vtk-and-paraview/vtk-file-formats.

Paraview can handle a group of file which compose an output with than one time step. This is the reason to create a pwd files which list the files composing all the time steps (one file by time step)

Parameters:
  • file_name_base – the base to create the name of the vtu file
  • path_hdf5 – the path to the hdf5 hydro file (to load the grid)
  • name_hdf5 – the name of the hdf5 containing the grid
  • vh_all_t_sp – the habitat data by reach, time step, species
  • height_c_data – the height by cell by reach by time step
  • vel_c_data – the velocity by cell by reach by time step
  • name_fish – the name of fish and stage
  • path_out – the path where to save the data
  • erase_id – if True, previous paraview file from identical merge file are erased
src.new_create_vtk.main()

Used to test this module

src.new_create_vtk.writePVD(fileName, fileNames)

This function write the file which indicates to paraview how to group the file. This “grouping” file is pvd file. With this file, paraview can open all the time steps together with one clic. This function is heavily inspired by the class given at the adress: https://github.com/cfinch/Shocksolution_Examples/blob/master/Visualization/vtktools.py. Because Element Tree was not used in the class from Shocksolution, we use minidom here instead of Element Tree.

Parameters:
  • fileName – the name of the pvd file
  • fileNames – the names of all the files for this time step (usually only for one reach but could be changed).

Function for the command lines

in src/func_for_cmd.py

This module contains functions which are used by habby.py when called on the command line (witjout using the GUI).

src.func_for_cmd.all_command(all_arg, name_prj, path_prj, path_bio, option_restart=False, erase_id=True)

This function is used to call HABBY from the command line. The general form is to call: habby_cmd command_name input1 input2 .. input n. The list of the command_name is given in the documentation and by calling the command “python habby_cmd.py LIST_COMMAND”. This functiion is usually called direclty by the main() or it is called by the function restart which read a list of function line by line. Careful, new command cannot contain the symbol ”:” as it is used by restart.

For the restart function, it is also important that the input folder is just in the folder “next” to the restart path. So the folder should not be moved randolmy inside the project folder or renamed.

Parameters:
  • all_arg – the list of argument (sys.argv more or less)
  • name_prj – the name of the project, created by default by the main()
  • path_prj – the path to the project created by default bu the main()
  • path_bio – the path to the project
  • option_restart – If True the command are coming from a restart log (which have an impact on file name and location)
  • erase_id – If True, the files with the same name are erased in merge. If False, ther kept with a time stamp
src.func_for_cmd.habby_on_all(all_arg, name_prj, path_prj, path_bio, option_restart=False)

This function is used to execute a command from habby_cmd on all files in a folder. The form of the command should be something like “habby_cmd ALL COMMAND path_to_file/*.ext arg2 ag3” with the arguments adated to the specific command.

In other words, the command should be the usual command with the keyword ALL before and with the name of the input files remplace by *.ext . where ext is the extension of the files. It is better to not add an output name. Indeed default name for output includes the input file name, which is practical if different files are given as input. If the default is overided, the same name will be applied, only the time stamps will be different. To be sure to not overwrite a file, this function waits one second between each command. Only the input argument should containts the string ‘*’. Otherwise, other commands would be treated as input files.

If there is more than one type of input, it is important that the name of the file are the same (or at least that there are in the same alphabetical order). If the variable # is used instead of *, the function will be applied to all second file one by one. So if we have two substrate file and two hydro file, name with * will result in two merged files while # will result in four merge file.

If more than one extension is possible (example g01, g02, g03, etc. in hec-ras), remplace the changing part of the extension with the symbol * (so path_to_folder/*.g0* arg1 argn). If the name of the file changed in the extension as in RUBAR (where the file have the name PROFIL.file), just change for PROFIL.* or something similar. Generally the matching is done using the function glob, so the shell-type wildcard can be used.

As there are a lot of hdf5 intput, one should be careful to avoid mixing between the different type of hdf5 files. For example, it is better to write ‘MERGE*.h5’ as just ‘*.h5’ if the folder contains hydraulic and merge files.

Parameters:
  • all_arg – the list of argument (sys.argv without the argument ALL so [sys.argv[0], sys.argv[2], sys.argv[n]])
  • name_prj – the name of the project, created by default by the main()
  • path_prj – the path to the project created by default bu the main()
  • path_bio – the path to the project
  • option_restart – If True the command are coming from a restart log (which have an impact on file name and location)
src.func_for_cmd.habby_restart(file_comm, name_prj, path_prj, path_bio)

This function reads a list of command from a text file called file_comm. It then calls all_command one each line which does contain the symbol ”:” . If the lines contains the symbol ”:”, it considered as an input. Careful, the intput should be in order!!!! The info on the left and sight of the symbol ”:” are just there so an human can read them more easily. Space does not matters here. We try to write the restart file created automatically by HABBY in a “nice” layout, but it just to read it more easily.

Parameters:
  • file_comm – a string wehich gives the name of the restart file (with the path)
  • name_prj – the name of the project, created by default by the main()
  • path_prj – the path to the project created by default bu the main()
  • path_bio – the path to the project
src.func_for_cmd.load_fstress_text(path_fstress)

This function loads the data for fstress from text files. The data is composed of the name of the rive, the discharge range, and the [discharge, height, width]. To read the files, the files listriv.txt is given. Form then, the function looks for the other files in the same folder. The other files are rivdeb.txt and rivqwh.txt. If more than one river is given in listriv.txt, it load the data for all rivers.

There is a very similar function as a method in the class FStressW() in fstress_GUI.py but it ised by the GUI and it includes a way to select the file using the GUI. Changes should be copied in both functions if necessary.

Parameters:path_fstress – the path to the listriv.txt function (the other fil should be in the same folder)
src.func_for_cmd.load_manning_txt(filename_path)

This function loads the manning data in case where manning number is not simply a constant. In this case, the manning parameter is given in a .txt file. The manning parameter used by 1D model such as mascaret or Rubar BE to distribute velocity along the profiles. The format of the txt file is “p, dist, n” where p is the profile number (start at zero), dist is the distance along the profile in meter and n is the manning value (in SI unit). White space is neglected and a line starting with the character # is also neglected.

There is a very similar function as a method in the class Sub_HydroW() in hydro_GUI.py but it used by the GUI and it includes a way to select the file using the GUI and it used a lot of class attribute. So it cannot be used by the command line. Changes should be copied in both functions if necessary.

Parameters:filename_path – the path and the name of the file containing the manning data
Returns:the manning as an array form

Various notes

Figures and matplotlib

The legend of the plots are not shown.

Generally HABBY is able to save the figure while showing the legend (which is often outside of the figure) appropriately. However, the figure shown to the user by matplotlib often have the legend outside of the visible area. To see the figure fully, one can modify the axes in the option of the figure (the menu in the axes on the top of the figure).

How to make figures editable in Adobe Illustrator

It is useful to have figures which we can edit in Adobe Illustrator. To achieve this, the following matplotlib option should be added: mpl.rcParams[‘pdf.fonttype’] = 42. Moreover, matplolib should be imported (import matplotlib as mpl). It is also useful to add the tranparent option to the function to save the figure (transparent=True). This renders modification easier in many cases. However, it is not good to use mpl.rcParams[‘ps.fonttype’] = 42 as the figure created in the eps format would be corrupted because of a bug in matplotlib.

Translation of HABBY

In HABBY, it is possible to translate all strings which are in a python file (.py) which is in the src_GUI folder.

To add a new string to translate:

  • Code as usual and write the string in English.
  • Add self.tr() around the string a = Qlabel(self.tr(“My message”))
  • If the code is in a new python file (like the .py was just created), open the habby_trans.pro file which is src_GUI. Then add the line SOURCES+= new_file.py where new_file.py is the new python file.
  • If you want to add a new language, add the line TRANSLATIONS += Zen_ES.ts in the case you want to add Spanish or any other language.
  • Copy the files ZEN_EN.ts and ZEN_FR.ts from HABBY/translation to /src_GUI
  • In the src_GUI folder, run the following command on the cmd: pylupdate5 habby_trans.pro. it will work if pylupdate is installed.
  • It should update the .ts file (which is an xml file)
  • Copy both .ts file back to HABBY/translation
  • Open Qt linguist. This is a program that you need to install before. Open the French .ts file. The English should not need translation.
  • Translate as needed and save in Qt Linguist.
  • A .qm file is the binary representing the .ts file with all the translation. To create .qm file, type (in the cmd) lrelease file.ts. It will create a file.qm file
  • Run HABBY. The string should be updated.

In the code

If the user asked for a new language, we need to reload the translator with the following lines:

app = QApplication.instance()

self.languageTranslator.load(file.qm, self.path_trans)

app.installTranslator(self.languageTranslator)

with the appropriate name for “file.qm”.

In HABBY, the list of the name of all qm file are in the variable self.file_langue in class MainWindows. Hence, we can follow the selected language using an integer self.lang (0 for English and 1 for French). We can now call self.file_langue[self.lang] to get the qm file in the right language. If a new language is added, it is necessary to add one string to this list and to modify the menu. If the new language is also present in the xml preference file (which contains the biological info), it is also necessary to update the variable “bioinfo_tab.lang” from central_widget in the function setlangue from Main_Windows(). If this is done, the description of the xml preference file in the “Biology” tab will be shown in the selected language. Otherwise, it will be the first language found.

When the translator has been created, it is necessary to re-do all Widgets and Windows. This is not a problem when we open HABBY, but it can be a bit of work if the user asks for a change in language when HABBY is running. This is the function of the setlangue function. This function would work for all language (it takes an integer as input to know which language to use), but it needs to be modified if one modifies the Main_Windows Class strongly (notably if one add signals). The language should be saved in the user setting using Qsettings as it is done at the end of the setlangue function.

In addition, every xml project file from HABBY has a part called “FigureOPtion”. In the list of available options, there is the language currently used under the attibute “LangFig”. The language is given using an int (0 for english, 1 for french). This is useful to translate the axis and the titles of the figures done by HABBY. To this end, one would first called the function “load_fig_option” in output_fig_GUI.py. This returns a dictionnary with a key called “language” (0 for english, 1 for french). Then, one can use an if statement to write the xlabel in french or english.

Create a .exe

Here are step to create a .exe using PyInstaller:

  • install Pyinstaller (pip install pyinstaller)
  • cd “folder with source code”
  • pyinstaller.exe [option] habby.py, with the option –onefile to get only one .exe and –windowed to not have the cmd which opens with the application.

Here are some common problems:

  • ImportError: (No module named ‘PyQt5.QtGui’): Copy the folder platform with qwindows.dll and add to the set_up.py “includes”: [“PyQt5.QtCore”, “PyQt5.QtGui”]
  • This application fails to start because ... the Qt platform pugin windows: Copy the folder platform with qwindows.dll in it
  • ImportError: h5Py “includes”: [“h5py”,”h5py.defs”, “h5py.utils”, “h5py.h5ac”, ‘h5py._proxy’ ] etc if necessary
  • Intel MKL fatal error copy the .dll missing (or just find an old dist and copy all mkl stuff) AND the libiomp5md.dll
  • The translation does not work: Add the translation folder into the dist folder
  • Do not find log0.txt (or crash when saving project): create a folder called src_GUI, copy the files log0.txt and restart_log0.txt from the src_GUI folder in the python module

Practically:

  • go to the folder called executable and copy the current HABBY source there.
  • copy createexe.bat in the habby folder.
  • run createexe.bat (only on Windows)
  • ignore the executable created in the “built” folder Use the one is in the “dist” folder.
  • copy all files in the mklall folder to the folder dist/habby.
  • copy all the files in the original src_GUI folder which are NOT python file to the src_GUI folder just created (or you know, improve the bat file...).
  • copy the doc folder in the dist/habby folder
  • run habby by writing habby on the cmd
  • test and correct problems. It can be long!

Logging

General information

There are two different logs for HABBY. By default, the first one is called “name_projet”.log and the second is called restart/_’name_project’.log. Their name and path can be changed in the xml project file. Both file are text file.

The first log is in the form of a python file with comments. If python and the necessary modules are installed on the machine, this log can be renamed “name.py” and started as a python file. In the command line, the following command should be used: python name.py. This file can be modified to create a new script to use HABBY in a different ways. For this, python syntax should be used.

The second log, called restart/_’name_project’.log, has limited functionalities but allows to re-start the HABBY simulation from the command line, without the need for python. Format of this file is described below. It is aimed to be readable and easily modifiable. To use the restart file, type in the command line: python habby.py restart/_’name_project’.log.

This part genreally needs more revisions and tests.

Type of log and format

Currently, there are five types of outputs, which can be sent to the log:

  • Comment, which should start with #. They will be sent to the python-type log file and to the GUI of Habby.
  • Errors, which should start with word “Error”. They will be sent to the python-type log file and to the GUI of Habby. In the GUI, they will appear in red.
  • Warnings, which should start with the word “Warning”. They will be sent to the python-type log file and to the GUI of Habby. In the GUI, they will appear in orange.
  • Restart info, which should start with the word “restart’. They will be sent to the restart_’name_project’.log. The format will be developed afterwards.
  • All types of text which do not start with these code words are only shown to the GUI of Habby.
  • Python code, which should start with the line py followed by four spaces. It will be sent to the python-type log file. It is usually a function which is part of Habby code. The different arguments of the function should be given in the preceding lines.

Example

Let’s write to the log a function which takes an integer and a string as input. The function is in the module called habby1, which is imported by default in the .log file. The strings to send as log would be:

  • “# this my fancy function”
  • “py my_int = ” + str(my_int_in_code)
  • “py my_string = ’” + my_string_in_the _code+ “’“
  • “py habby1.myfunc(my_int, my_string)”

A comment should be added before each chunk of python code to improve the readability.

Update the log

Let’s consider a scenario where a new function has been written in a non-GUI module (class or function) and has to be called in the GUI in a method of a class. Let’s call the new function new_func and the class in the GUI my_class.

To create a new line of log for new_func, one should follow these steps:

  • A PyQtsignal with a string as argument should be added to my_class: send_log = pyqtSignal(str, name=’send_log’)
  • If a log should be sent directly from my_class (for example, to say that new_func has been called), the signal should be emitted: self.send_log.emit(‘# new_func has been called’))
  • In the new function, error and warning are written as follows: print(“Error: here is an error.n”) or print(“Warning: This is just a warning.n”)
  • In my_class, error and warning are collected by redirecting stdout to a string. The following lines of code should be added around the calling of my_func():
    • sys.stdout = mystdout = StringIO() # redirect stdout
    • my_func(my_int,my_string)
    • sys.stdout = sys.__stdout__ # re-sent stdout to the cmd
    • str_found = mystdout.getvalue() # get all warning, error, text,…
    • str_found = str_found.split(‘n’) # separate each message
    • for i in range(0, len(str_found)):
      • if len(str_found[i]) > 1:
        • self.send_log.emit(str_found[i]) #send the text
  • To import StringIO, the following statement is needed at the start of the code: from io import StringIO
  • If new_func is called from the command line, stdout will not be redirected and the errors or warnings will be printed on the cmd as usual. Stderr should be re-directed in a similar manner if needed.
  • The signal should be collected in the function connect_signal_log in the Main_Windows_1.py. For this, a line should be added in the function: * self.my_class.send_log.connect(self.write_log)

restart file

The format of the restart file is based on the format asked by the functions in func_for_cmd.py. More information on this format in func_for_cmd.py (notably in the part list_command).

Git - code management

Pour commencer:

  • Choisir un dossier sur l’ordinateur local ou va se trouver les fichiers sources.
  • cd « dossier avec les codes source»
  • git config - - global user.name « username »
  • git config - - global user.email « mail »
  • git init
  • lier le repertoire local avec le repertoire distant sur forge.irstea.fr

** Pour cloner HABBY** * cd « dossier souhaité» * git clone https://git.irstea.fr/git/habby

Pour mettre une nouvelle version sur le site web

  • cd « dossier avec les codes source»
  • git pull (prend la dernière version à jour sur le site et mets tous les fichiers ensemble) ou git fetch (prend juste les derniers fichiers sans mettre tous les fichiers ensemble).
  • git add ‘my_file.py ou .pyc’ (choisit les fichiers qui doivent être envoyé), le signe * fonctionne.
  • git log (donne l’historique)
  • git status (donne les nouveaux fichiers locals)
  • git commit –m « description » (commit localement)
  • git push

Pour ajouter une nouvelle branche

  • Donc pour avoir une partie du travail sépare du reste
  • git checkout –b [branchname] pour créer la branche et y travailler
  • git checkout [branchname] pour y travailler

Test HABBY

For the moment, there are two automatic tests for HABBY which are in the HABBY folder. This is test_habby_quick which takes about 2 minutes to run and which only test one simple habitat calculation, and test_habby2 which tests the loading of the different hydraulic models, the creation of computational grid for 1D hydraulic models, the habitat calculation on diverse cases and the statistical models. It takes about two hours to run.

The test are bash codes so they run under Windows only, but it is relatively easy to modify the script to run it under another exploitation system. To run it under a new Windows computer, it is also necessary to change the first lines of the bash codes to give the paths of the folders with the original data. These folders are not in the HABBY folder as they need about 7 Giga of space.

There is no test for the GUI at the moment as we did not find a practical tool to test it.

Write the documentation

Habby uses Sphinx to document the code. Sphinx uses the docstring given in each function. Hence, it is necessary to write a docstring for each function which has to be documented.

To update the html documentation, go to the doc folder and execute the command: “make html”.

To update the Latex documentation, use the commande “make latex” and use Miketex to create the pdf. rts2pdf does not work with Python 3.

To add text in the documentation, modify the index.rst file in the doc folder. To add a new module to the documentation, add the module as written in the index.rts file in the doc folder. To add text comment, the index.rts file can also be direclty modified.

It is important to keep the formatting and the alignment.

If the module is in a new folder, the address of the folder must be added to the config.py file. It is better to not use absolute path for this, so it is possible to move the documentation on another computer. If the documentation does not run on a new computer, check the path given in the config.py file.

In the docstring, add as many blank lines as possible (in reasonable limit). This is easier for the formatting. To make a bullet list, one should use a tab and the symbol “*”. Using only the symbol “*” will fail.

To add a new title, do not start the title or the line of symbol under the title with a blank space.

License of used python modules

  • h5py: BSD License
  • Element tree (XML): MIT License
  • numpy: BSD License
  • matplotlib: BSD License
  • PyQt5: GNU License
  • Scipy: BSD license
  • shutil:

Indices and tables