wolfhece 2.1.128__py3-none-any.whl → 2.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wolfhece/PyDraw.py +109 -46
- wolfhece/PyGui.py +3 -0
- wolfhece/PyGuiHydrology.py +24 -24
- wolfhece/PyPalette.py +27 -11
- wolfhece/PyParams.py +5 -1
- wolfhece/PyVertexvectors.py +52 -7
- wolfhece/Results2DGPU.py +17 -0
- wolfhece/acceptability/acceptability_gui.py +29 -18
- wolfhece/acceptability/func.py +23 -21
- wolfhece/apps/version.py +2 -2
- wolfhece/eikonal.py +1 -1
- wolfhece/hydrology/Catchment.py +113 -12
- wolfhece/hydrology/Comparison.py +54 -52
- wolfhece/hydrology/Optimisation.py +309 -178
- wolfhece/hydrology/PostProcessHydrology.py +6 -3
- wolfhece/hydrology/RetentionBasin.py +21 -14
- wolfhece/hydrology/SubBasin.py +128 -12
- wolfhece/hydrology/constant.py +3 -0
- wolfhece/hydrology/cst_exchanges.py +364 -38
- wolfhece/hydrology/plot_hydrology.py +34 -18
- wolfhece/hydrology/read.py +16 -6
- wolfhece/lagrangian/particle_system_ui.py +1 -1
- wolfhece/lagrangian/particles.py +1 -1
- wolfhece/lazviewer/processing/estimate_normals/estimate_normals.cp310-win_amd64.pyd +0 -0
- wolfhece/lazviewer/vfuncsdir/vfuncs.cp310-win_amd64.pyd +0 -0
- wolfhece/lazviewer/viewer/viewer.exe +0 -0
- wolfhece/lazviewer/viewer/viewer_np1_23_5.exe +0 -0
- wolfhece/libs/WolfDll.dll +0 -0
- wolfhece/libs/Wolf_tools.dll +0 -0
- wolfhece/libs/get_infos.cp310-win_amd64.pyd +0 -0
- wolfhece/libs/verify_wolf.cp310-win_amd64.pyd +0 -0
- wolfhece/libs/wolfogl.cp310-win_amd64.pyd +0 -0
- wolfhece/radar/wolfradar.py +75 -22
- wolfhece/shapes/__init__.py +0 -0
- wolfhece/shapes/circle.py +335 -0
- wolfhece/tools2d_dll.py +359 -0
- wolfhece/wolf_array.py +3 -2
- wolfhece/wolfresults_2D.py +162 -33
- {wolfhece-2.1.128.dist-info → wolfhece-2.2.1.dist-info}/METADATA +15 -9
- {wolfhece-2.1.128.dist-info → wolfhece-2.2.1.dist-info}/RECORD +43 -39
- wolfhece/libs/wolfpy.cp310-win_amd64.pyd +0 -0
- {wolfhece-2.1.128.dist-info → wolfhece-2.2.1.dist-info}/WHEEL +0 -0
- {wolfhece-2.1.128.dist-info → wolfhece-2.2.1.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.1.128.dist-info → wolfhece-2.2.1.dist-info}/top_level.txt +0 -0
| @@ -32,8 +32,9 @@ import traceback | |
| 32 32 |  | 
| 33 33 |  | 
| 34 34 | 
             
            # %% Constants
         | 
| 35 | 
            -
            DLL_FILE = "WolfDll.dll"
         | 
| 36 | 
            -
            DLL_FILE_DEBUG = "WolfDll_debug.dll"
         | 
| 35 | 
            +
            DLL_FILE = "WolfDll.dll"                # Name of the release DLL
         | 
| 36 | 
            +
            DLL_FILE_DEBUG = "WolfDll_debug.dll"    # Name of the debug DLL
         | 
| 37 | 
            +
            DLL_FILE_TEST = "WolfDll_test.dll"      # Name of the test DLL (to deactivate random numbers generation)
         | 
| 37 38 |  | 
| 38 39 |  | 
| 39 40 |  | 
| @@ -63,7 +64,7 @@ class CaseOpti(GenMapManager): | |
| 63 64 | 
             
                    # super().__init__(splash=splash, *args, **kw)
         | 
| 64 65 |  | 
| 65 66 | 
             
                    self.launcherDir = ""
         | 
| 66 | 
            -
             | 
| 67 | 
            +
             | 
| 67 68 | 
             
                def read_param(self, dir, copyDefault=False, callback=None, workingDir=""):
         | 
| 68 69 |  | 
| 69 70 | 
             
                    self.launcherDir = dir
         | 
| @@ -131,13 +132,13 @@ class Optimisation(wx.Frame): | |
| 131 132 | 
             
                # FIXME : this variable is just there before the seperation between the object optimisation and GUI optimisation
         | 
| 132 133 | 
             
                wx_exists:bool
         | 
| 133 134 |  | 
| 134 | 
            -
                def __init__(self, parent=None, title="", w=500, h=500, init_wx=True, debugDLL=False):
         | 
| 135 | 
            +
                def __init__(self, parent=None, title="", w=500, h=500, init_wx=True, debugDLL=False, for_test:bool=False):
         | 
| 135 136 |  | 
| 136 137 | 
             
                    self.wx_exists = wx.App.Get() is not None # test if wx App is running
         | 
| 137 138 |  | 
| 138 139 | 
             
                    if self.wx_exists:
         | 
| 139 140 | 
             
                        super(Optimisation, self).__init__(parent, title=title, size=(w,h))
         | 
| 140 | 
            -
             | 
| 141 | 
            +
             | 
| 141 142 | 
             
                    self.debugDLL = debugDLL
         | 
| 142 143 |  | 
| 143 144 | 
             
                    self.workingDir = ""
         | 
| @@ -161,12 +162,15 @@ class Optimisation(wx.Frame): | |
| 161 162 | 
             
                    if self.debugDLL:
         | 
| 162 163 | 
             
                        self.load_dll(self.pathDll, DLL_FILE_DEBUG)
         | 
| 163 164 | 
             
                    else:
         | 
| 164 | 
            -
                         | 
| 165 | 
            +
                        if for_test:
         | 
| 166 | 
            +
                            self.load_dll(self.pathDll, DLL_FILE_TEST)
         | 
| 167 | 
            +
                        else:
         | 
| 168 | 
            +
                            self.load_dll(self.pathDll, DLL_FILE)
         | 
| 165 169 |  | 
| 166 170 | 
             
                    # FIXME
         | 
| 167 171 | 
             
                    if self.wx_exists:
         | 
| 168 172 | 
             
                        self.initGUI()
         | 
| 169 | 
            -
             | 
| 173 | 
            +
             | 
| 170 174 |  | 
| 171 175 | 
             
                def initGUI(self):
         | 
| 172 176 |  | 
| @@ -224,7 +228,7 @@ class Optimisation(wx.Frame): | |
| 224 228 | 
             
                    self.Bind(wx.EVT_MENU, self.test_equifinality_with_Nash, testEquiFinClick)
         | 
| 225 229 | 
             
                    plotEquiFinClick = toolMenu.Append(wx.ID_ANY, 'Plot equifinality with Nash')
         | 
| 226 230 | 
             
                    self.Bind(wx.EVT_MENU, self.plot_equifinality, plotEquiFinClick)
         | 
| 227 | 
            -
             | 
| 231 | 
            +
             | 
| 228 232 |  | 
| 229 233 | 
             
                    # Creation of the Lauch Menu
         | 
| 230 234 | 
             
                    launchMenu = wx.Menu()
         | 
| @@ -345,10 +349,10 @@ class Optimisation(wx.Frame): | |
| 345 349 | 
             
                    self.enable_MenuBar("Param files")
         | 
| 346 350 | 
             
                    self.enable_MenuBar("Launch")
         | 
| 347 351 |  | 
| 348 | 
            -
             | 
| 352 | 
            +
             | 
| 349 353 | 
             
                def load(self, event, workingDir:str="", fileName:str=""):
         | 
| 350 354 |  | 
| 351 | 
            -
                    # Selection of the main | 
| 355 | 
            +
                    # Selection of the main
         | 
| 352 356 | 
             
                    if workingDir=="":
         | 
| 353 357 | 
             
                        idir=wx.FileDialog(None,"Choose an optimatimisation file",wildcard='Fichiers param (*.param)|*.param')
         | 
| 354 358 | 
             
                        if idir.ShowModal() == wx.ID_CANCEL:
         | 
| @@ -369,7 +373,11 @@ class Optimisation(wx.Frame): | |
| 369 373 | 
             
                    self.optiParam = Wolf_Param(to_read=True, filename=fileOpti, title="test_opti",toShow=False)
         | 
| 370 374 | 
             
                    initDir = self.optiParam.get_param("Optimizer","dir")
         | 
| 371 375 | 
             
                    isOk, initDir = check_path(initDir, prefix=readDir, applyCWD=True)
         | 
| 372 | 
            -
             | 
| 376 | 
            +
             | 
| 377 | 
            +
                    if initDir is None:
         | 
| 378 | 
            +
                        logging.error("ERROR: in path of initDir")
         | 
| 379 | 
            +
                        return
         | 
| 380 | 
            +
                    #
         | 
| 373 381 | 
             
                    if os.path.samefile(readDir, initDir):
         | 
| 374 382 | 
             
                        self.workingDir = initDir
         | 
| 375 383 | 
             
                    else:
         | 
| @@ -409,14 +417,14 @@ class Optimisation(wx.Frame): | |
| 409 417 | 
             
                                curCase = paramMenu.Append(newId, curName, caseMenu)
         | 
| 410 418 | 
             
                            else:
         | 
| 411 419 | 
             
                                print("WARNING : this scenario was not implemented yet. This might induce an error!")
         | 
| 412 | 
            -
                                # iItem = | 
| 420 | 
            +
                                # iItem =
         | 
| 413 421 | 
             
                                curCase = paramMenu.Replace(iItem)
         | 
| 422 | 
            +
                            self.Bind(wx.EVT_MENU, newCase.show_launcherParam, curCase)
         | 
| 423 | 
            +
                            newCase.idMenuItem = newId
         | 
| 414 424 | 
             
                        else:
         | 
| 415 425 | 
             
                            refDir = newCase.launcherParam.get_param("Calculs","Répertoire simulation de référence")
         | 
| 416 426 | 
             
                            isOk, refDir = check_path(refDir, prefix=launcherDir, applyCWD=True)
         | 
| 417 427 | 
             
                            newCase.mydro = HydrologyModel(dir=refDir)
         | 
| 418 | 
            -
                        self.Bind(wx.EVT_MENU, newCase.show_launcherParam, curCase)
         | 
| 419 | 
            -
                        newCase.idMenuItem = newId
         | 
| 420 428 | 
             
                        self.myCases.append(newCase)
         | 
| 421 429 |  | 
| 422 430 |  | 
| @@ -433,14 +441,15 @@ class Optimisation(wx.Frame): | |
| 433 441 | 
             
                    self.init_with_default_lumped()
         | 
| 434 442 |  | 
| 435 443 | 
             
                    # Let all the menu bars be available in GUI
         | 
| 436 | 
            -
                    self. | 
| 437 | 
            -
             | 
| 438 | 
            -
             | 
| 439 | 
            -
             | 
| 440 | 
            -
                        self. | 
| 441 | 
            -
             | 
| 444 | 
            +
                    if self.wx_exists:
         | 
| 445 | 
            +
                        self.enable_MenuBar("Param files")
         | 
| 446 | 
            +
                        self.enable_MenuBar("Launch")
         | 
| 447 | 
            +
                        self.enable_MenuBar("Tools")
         | 
| 448 | 
            +
                        if self.debugDLL:
         | 
| 449 | 
            +
                            self.enable_MenuBar("Debug")
         | 
| 442 450 |  | 
| 443 | 
            -
             | 
| 451 | 
            +
             | 
| 452 | 
            +
                def apply_optim(self, event, idLauncher:int=0,
         | 
| 444 453 | 
             
                                replace_only_if_better:bool=False, optim_params:np.ndarray=None):
         | 
| 445 454 | 
             
                    """
         | 
| 446 455 | 
             
                    Apply optimal parameters based on the results file of the optimisation : ".rpt".
         | 
| @@ -474,7 +483,7 @@ class Optimisation(wx.Frame): | |
| 474 483 | 
             
                        return bestParams
         | 
| 475 484 | 
             
                    else:
         | 
| 476 485 | 
             
                        return None
         | 
| 477 | 
            -
             | 
| 486 | 
            +
             | 
| 478 487 |  | 
| 479 488 |  | 
| 480 489 | 
             
                # Initialisation of the Optimizer from Fortran
         | 
| @@ -483,7 +492,7 @@ class Optimisation(wx.Frame): | |
| 483 492 | 
             
                    self.init_optimizer()
         | 
| 484 493 |  | 
| 485 494 |  | 
| 486 | 
            -
             | 
| 495 | 
            +
             | 
| 487 496 | 
             
                def init_with_default_lumped(self, replace:bool=False):
         | 
| 488 497 | 
             
                    # if replace:
         | 
| 489 498 | 
             
                    #     r = wx.ID_NO
         | 
| @@ -613,7 +622,7 @@ class Optimisation(wx.Frame): | |
| 613 622 | 
             
                            if sorted_id == 0:
         | 
| 614 623 | 
             
                                self.myParams[i]["junction_name"] = curCatch.junctionOut
         | 
| 615 624 | 
             
                            else:
         | 
| 616 | 
            -
                                cur_id = list(curCatch.dictIdConversion.keys())[list(curCatch.dictIdConversion.values()).index(sorted_id)] | 
| 625 | 
            +
                                cur_id = list(curCatch.dictIdConversion.keys())[list(curCatch.dictIdConversion.values()).index(sorted_id)]
         | 
| 617 626 | 
             
                                self.myParams[i]["junction_name"] = curCatch.subBasinDict[cur_id].name
         | 
| 618 627 |  | 
| 619 628 | 
             
                        else:
         | 
| @@ -640,7 +649,7 @@ class Optimisation(wx.Frame): | |
| 640 649 |  | 
| 641 650 | 
             
                    optimFileTxt = os.path.join(self.workingDir, nameTMP+".rpt")
         | 
| 642 651 | 
             
                    optimFileBin = os.path.join(self.workingDir, nameTMP+".rpt.dat")
         | 
| 643 | 
            -
             | 
| 652 | 
            +
             | 
| 644 653 | 
             
                    isOk, optimFileBin = check_path(optimFileBin)
         | 
| 645 654 | 
             
                    if isOk>0:
         | 
| 646 655 | 
             
                        optimFile = optimFileBin
         | 
| @@ -671,7 +680,7 @@ class Optimisation(wx.Frame): | |
| 671 680 |  | 
| 672 681 |  | 
| 673 682 | 
             
                def init_with_reference(self, idLauncher=0):
         | 
| 674 | 
            -
             | 
| 683 | 
            +
             | 
| 675 684 | 
             
                    curCase = self.myCases[idLauncher]
         | 
| 676 685 | 
             
                    refCatch = curCase.refCatchment
         | 
| 677 686 |  | 
| @@ -728,14 +737,19 @@ class Optimisation(wx.Frame): | |
| 728 737 | 
             
                        isOk, defaultPath = check_path(defaultPath, launcherDir)
         | 
| 729 738 | 
             
                        if isOk<0:
         | 
| 730 739 | 
             
                            defaultPath = ""
         | 
| 731 | 
            -
                         | 
| 732 | 
            -
             | 
| 733 | 
            -
                             | 
| 740 | 
            +
                        if self.wx_exists:
         | 
| 741 | 
            +
                            idir=wx.FileDialog(None,"Choose a reference file",wildcard='Fichiers post-processing (*.postPro)|*.postPro',defaultDir=defaultPath)
         | 
| 742 | 
            +
                            if idir.ShowModal() == wx.ID_CANCEL:
         | 
| 743 | 
            +
                                print("Post process cancelled!")
         | 
| 744 | 
            +
                                idir.Destroy()
         | 
| 745 | 
            +
                            refFileName = idir.GetPath()
         | 
| 746 | 
            +
                            refDir = idir.GetDirectory()
         | 
| 734 747 | 
             
                            idir.Destroy()
         | 
| 735 | 
            -
             | 
| 736 | 
            -
             | 
| 737 | 
            -
             | 
| 738 | 
            -
             | 
| 748 | 
            +
                        else:
         | 
| 749 | 
            +
                            refDir = defaultPath
         | 
| 750 | 
            +
                            refFileName = join(refDir, "Input.postPro")
         | 
| 751 | 
            +
             | 
| 752 | 
            +
             | 
| 739 753 |  | 
| 740 754 | 
             
                    myPostPro = PostProcessHydrology(postProFile=refFileName)
         | 
| 741 755 | 
             
                    # Recover the Catchment object
         | 
| @@ -855,14 +869,14 @@ class Optimisation(wx.Frame): | |
| 855 869 |  | 
| 856 870 | 
             
                def plot_optim_jct(self, event, idLauncher=0):
         | 
| 857 871 | 
             
                    # this function will plot the hydrographs with the optimal parameters compared to the objective
         | 
| 858 | 
            -
             | 
| 872 | 
            +
             | 
| 859 873 | 
             
                    refCatch:Catchment = self.myCases[idLauncher].refCatchment
         | 
| 860 874 |  | 
| 861 875 | 
             
                    # Construction of the Measures, in other words the references
         | 
| 862 876 | 
             
                    compMeas = []
         | 
| 863 877 | 
             
                    if self.myStations==[]:
         | 
| 864 878 | 
             
                        self.set_compare_stations(idLauncher=idLauncher)
         | 
| 865 | 
            -
             | 
| 879 | 
            +
             | 
| 866 880 | 
             
                    compMeas = list(self.compareSubBasins.values())
         | 
| 867 881 |  | 
| 868 882 | 
             
                    # Construction of the wx window for plot
         | 
| @@ -870,7 +884,7 @@ class Optimisation(wx.Frame): | |
| 870 884 |  | 
| 871 885 | 
             
                    self.axes = figure.add_subplot(111)
         | 
| 872 886 |  | 
| 873 | 
            -
             | 
| 887 | 
            +
             | 
| 874 888 | 
             
                    r = wx.MessageDialog(
         | 
| 875 889 | 
             
                        None, "Do you want to add a table?", "Plot question",
         | 
| 876 890 | 
             
                        wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION
         | 
| @@ -960,7 +974,7 @@ class Optimisation(wx.Frame): | |
| 960 974 | 
             
                    pointer_p = p.ctypes.data_as(ct.POINTER(ct.c_double))
         | 
| 961 975 |  | 
| 962 976 | 
             
                    print("Launch a Fortran procedure")
         | 
| 963 | 
            -
                    obj_fct = self.dllFortran.evaluate_model_optimizer_py(ct.byref(ct.c_int(idOpti)), | 
| 977 | 
            +
                    obj_fct = self.dllFortran.evaluate_model_optimizer_py(ct.byref(ct.c_int(idOpti)),
         | 
| 964 978 | 
             
                                                                       pointerDims,
         | 
| 965 979 | 
             
                                                                       pointer_p)
         | 
| 966 980 | 
             
                    print("End of Fortran procedure")
         | 
| @@ -1296,7 +1310,7 @@ class Optimisation(wx.Frame): | |
| 1296 1310 | 
             
                        self.set_compare_stations(idLauncher=idLauncher)
         | 
| 1297 1311 | 
             
                        sortJct = self.myStations
         | 
| 1298 1312 | 
             
                        readDict = self.compareFilesDict
         | 
| 1299 | 
            -
                        # Get the initial number of intervals | 
| 1313 | 
            +
                        # Get the initial number of intervals
         | 
| 1300 1314 | 
             
                        # -> these can evolve according to the measurement available at each station
         | 
| 1301 1315 | 
             
                        is_ok = self._save_opti_intervals()
         | 
| 1302 1316 | 
             
                        if is_ok<0:
         | 
| @@ -1325,7 +1339,7 @@ class Optimisation(wx.Frame): | |
| 1325 1339 | 
             
                            cur_intervals = self.select_opti_intervals(all_intervals=all_intervals, stationOut=stationOut, filter_nan=True)
         | 
| 1326 1340 | 
             
                            self.save_opti_dates_to_file(cur_intervals)
         | 
| 1327 1341 | 
             
                            is_ok = self._save_opti_intervals(stationOut=stationOut, intervals=cur_intervals)
         | 
| 1328 | 
            -
             | 
| 1342 | 
            +
             | 
| 1329 1343 | 
             
                            # Rename the result file
         | 
| 1330 1344 | 
             
                            self.optiParam.change_param("Optimizer", "fname", stationOut)
         | 
| 1331 1345 | 
             
                            self.optiParam.SavetoFile(None)
         | 
| @@ -1336,7 +1350,7 @@ class Optimisation(wx.Frame): | |
| 1336 1350 | 
             
                            # Prepare the potential discontinuous simulation
         | 
| 1337 1351 | 
             
                            # FIXME : to potentially uncomment or removed : probably remove because we want to generate the complete event simulations to progress in the optimisation
         | 
| 1338 1352 | 
             
                            # self.prepare_simulation(opti_intervals=cur_intervals, idLauncher=idLauncher)
         | 
| 1339 | 
            -
                            # Check the initial parameters and if they are forced | 
| 1353 | 
            +
                            # Check the initial parameters and if they are forced
         | 
| 1340 1354 | 
             
                            init_params = self.get_initial_parameters()
         | 
| 1341 1355 | 
             
                            ## loop on the number of different optimisation attempt we would like for each station
         | 
| 1342 1356 | 
             
                            best_params_overall = None
         | 
| @@ -1361,12 +1375,12 @@ class Optimisation(wx.Frame): | |
| 1361 1375 | 
             
                                        if best_params_overall is None:
         | 
| 1362 1376 | 
             
                                            best_params_overall = best_params
         | 
| 1363 1377 | 
             
                                        elif best_params[-1] > best_params_overall[-1]:
         | 
| 1364 | 
            -
                                            best_params_overall = best_params | 
| 1365 | 
            -
                                            i_best_overal = cur_i | 
| 1378 | 
            +
                                            best_params_overall = best_params
         | 
| 1379 | 
            +
                                            i_best_overal = cur_i
         | 
| 1366 1380 | 
             
                                    # copy the optimisation results to save it on the disk
         | 
| 1367 | 
            -
                                    shutil.copyfile(os.path.join(self.workingDir, stationOut+".rpt.dat"), | 
| 1381 | 
            +
                                    shutil.copyfile(os.path.join(self.workingDir, stationOut+".rpt.dat"),
         | 
| 1368 1382 | 
             
                                                    os.path.join(self.workingDir, stationOut+"_"+str(cur_i+1)+".rpt.dat"))
         | 
| 1369 | 
            -
                                    shutil.copyfile(os.path.join(self.workingDir, stationOut+".rpt"), | 
| 1383 | 
            +
                                    shutil.copyfile(os.path.join(self.workingDir, stationOut+".rpt"),
         | 
| 1370 1384 | 
             
                                                    os.path.join(self.workingDir, stationOut+"_"+str(cur_i+1)+".rpt"))
         | 
| 1371 1385 | 
             
                                    cur_i += 1
         | 
| 1372 1386 | 
             
                            # Apply the best parameters overall attemps
         | 
| @@ -1374,12 +1388,12 @@ class Optimisation(wx.Frame): | |
| 1374 1388 | 
             
                            # Reset the init parameters
         | 
| 1375 1389 | 
             
                            self.reset_init_params(init_params)
         | 
| 1376 1390 | 
             
                            # copy the optimisation results to save it on the disk
         | 
| 1377 | 
            -
                            shutil.copyfile(os.path.join(self.workingDir, stationOut+"_"+str(i_best_overal+1)+".rpt.dat"), | 
| 1391 | 
            +
                            shutil.copyfile(os.path.join(self.workingDir, stationOut+"_"+str(i_best_overal+1)+".rpt.dat"),
         | 
| 1378 1392 | 
             
                                            os.path.join(self.workingDir, stationOut+".rpt.dat"))
         | 
| 1379 | 
            -
                            shutil.copyfile(os.path.join(self.workingDir, stationOut+"_"+str(i_best_overal+1)+".rpt"), | 
| 1393 | 
            +
                            shutil.copyfile(os.path.join(self.workingDir, stationOut+"_"+str(i_best_overal+1)+".rpt"),
         | 
| 1380 1394 | 
             
                                            os.path.join(self.workingDir, stationOut+".rpt"))
         | 
| 1381 | 
            -
             | 
| 1382 | 
            -
             | 
| 1395 | 
            +
             | 
| 1396 | 
            +
             | 
| 1383 1397 | 
             
                            # Simulation with the best parameters
         | 
| 1384 1398 | 
             
                            self.compute_distributed_hydro_model()
         | 
| 1385 1399 | 
             
                            cur_p = best_params_overall[:-1]
         | 
| @@ -1448,8 +1462,8 @@ class Optimisation(wx.Frame): | |
| 1448 1462 | 
             
                    tf = time_mod.process_time()
         | 
| 1449 1463 | 
             
                    print("Time in update_hydro() : ", tf-t0)
         | 
| 1450 1464 | 
             
                    return isOk
         | 
| 1451 | 
            -
             | 
| 1452 | 
            -
             | 
| 1465 | 
            +
             | 
| 1466 | 
            +
             | 
| 1453 1467 | 
             
                def reload_hydro(self, idCompar, firstLevel:int=1, lastLevel:int=-1, fromStation:str="", updateAll:bool=False):
         | 
| 1454 1468 |  | 
| 1455 1469 | 
             
                    curCatch:Catchment = self.myCases[0].refCatchment
         | 
| @@ -1683,7 +1697,7 @@ class Optimisation(wx.Frame): | |
| 1683 1697 |  | 
| 1684 1698 | 
             
                    return isOk
         | 
| 1685 1699 |  | 
| 1686 | 
            -
             | 
| 1700 | 
            +
             | 
| 1687 1701 | 
             
                ## Update the dictionnaries of myParams if any changes is identified
         | 
| 1688 1702 | 
             
                # TODO : Generalised for all type of changes and all the necessary tests -> So far just update the junction name
         | 
| 1689 1703 | 
             
                def update_myParams(self, idLauncher=0):
         | 
| @@ -1699,10 +1713,10 @@ class Optimisation(wx.Frame): | |
| 1699 1713 | 
             
                        if sorted_id == 0:
         | 
| 1700 1714 | 
             
                            self.myParams[i]["junction_name"] = curCatch.junctionOut
         | 
| 1701 1715 | 
             
                        else:
         | 
| 1702 | 
            -
                            cur_id = list(curCatch.dictIdConversion.keys())[list(curCatch.dictIdConversion.values()).index(sorted_id)] | 
| 1716 | 
            +
                            cur_id = list(curCatch.dictIdConversion.keys())[list(curCatch.dictIdConversion.values()).index(sorted_id)]
         | 
| 1703 1717 | 
             
                            self.myParams[i]["junction_name"] = curCatch.subBasinDict[cur_id].name
         | 
| 1704 1718 |  | 
| 1705 | 
            -
             | 
| 1719 | 
            +
             | 
| 1706 1720 |  | 
| 1707 1721 | 
             
                ## Function to determine the compare stations, compare files and the compare station SubBasin objects for each station
         | 
| 1708 1722 | 
             
                def set_compare_stations(self, idLauncher):
         | 
| @@ -1721,7 +1735,7 @@ class Optimisation(wx.Frame): | |
| 1721 1735 | 
             
                        # Sort all the junctions by level
         | 
| 1722 1736 | 
             
                        self.myStations = refCatch.sort_level_given_junctions(list(readDict.keys()), changeNames=False)
         | 
| 1723 1737 | 
             
                        # Prepare the SubBasin compare objects for each station.
         | 
| 1724 | 
            -
                        self.compareSubBasins = {stationOut: SubBasin(name=stationOut, _model=cst.compare_opti, _workingDir=self.workingDir) | 
| 1738 | 
            +
                        self.compareSubBasins = {stationOut: SubBasin(name=stationOut, _model=cst.compare_opti, _workingDir=self.workingDir)
         | 
| 1725 1739 | 
             
                                                 for stationOut in self.myStations}
         | 
| 1726 1740 | 
             
                        # This loop read all the measure and init the hydro surface of each SubBasin element
         | 
| 1727 1741 | 
             
                        for key, cur_obj in self.compareSubBasins.items():
         | 
| @@ -1742,11 +1756,11 @@ class Optimisation(wx.Frame): | |
| 1742 1756 | 
             
                    self.Destroy()
         | 
| 1743 1757 |  | 
| 1744 1758 | 
             
                    wx.Exit()
         | 
| 1745 | 
            -
             | 
| 1746 | 
            -
             | 
| 1759 | 
            +
             | 
| 1760 | 
            +
             | 
| 1747 1761 | 
             
                def get_all_outlets(self, event, idLauncher:int=0):
         | 
| 1748 1762 | 
             
                    # this function will save all the hydrographs with the optimal parameters
         | 
| 1749 | 
            -
             | 
| 1763 | 
            +
             | 
| 1750 1764 | 
             
                    refCatch:Catchment = self.myCases[idLauncher].refCatchment
         | 
| 1751 1765 | 
             
                    refCatch.save_ExcelFile_noLagTime()
         | 
| 1752 1766 |  | 
| @@ -1756,7 +1770,7 @@ class Optimisation(wx.Frame): | |
| 1756 1770 | 
             
                    refCatch:Catchment = self.myCases[idLauncher].refCatchment
         | 
| 1757 1771 | 
             
                    refCatch.save_ExcelFile_inlets_noLagTime()
         | 
| 1758 1772 |  | 
| 1759 | 
            -
             | 
| 1773 | 
            +
             | 
| 1760 1774 | 
             
                def plot_all_landuses(self, event, idLauncher:int=0):
         | 
| 1761 1775 | 
             
                    # this function plots the landuses of all hydro subbasins
         | 
| 1762 1776 | 
             
                    refCatch:Catchment = self.myCases[idLauncher].refCatchment
         | 
| @@ -1773,7 +1787,7 @@ class Optimisation(wx.Frame): | |
| 1773 1787 | 
             
                #   - the ".rpt" file of the results of an optimisation should be present
         | 
| 1774 1788 | 
             
                #   - the optimal paramters will be replaced in their respective param files
         | 
| 1775 1789 | 
             
                #   - the timeDelays will then be updated either with :
         | 
| 1776 | 
            -
                #           - Python paramters itself | 
| 1790 | 
            +
                #           - Python paramters itself
         | 
| 1777 1791 | 
             
                #           - an estimation from the runnof model
         | 
| 1778 1792 | 
             
                # Once all the optimal parameters are applied, a new simulation is launched to generate the "best" hydrograph
         | 
| 1779 1793 | 
             
                def generate_semiDist_optim_simul(self, event, idOpti=1,idLauncher:int=0):
         | 
| @@ -1811,7 +1825,7 @@ class Optimisation(wx.Frame): | |
| 1811 1825 | 
             
                            self.optiParam.change_param("Optimizer", "fname", stationOut)
         | 
| 1812 1826 | 
             
                            self.optiParam.SavetoFile(None)
         | 
| 1813 1827 | 
             
                            self.optiParam.Reload(None)
         | 
| 1814 | 
            -
                            # | 
| 1828 | 
            +
                            #
         | 
| 1815 1829 | 
             
                            self.update_myParams(idLauncher)
         | 
| 1816 1830 | 
             
                            # Preparing the dictionnaries of Parameters to be updated -> not just useful for calibration here !
         | 
| 1817 1831 | 
             
                            self.prepare_calibration_timeDelay(stationOut=stationOut)
         | 
| @@ -1828,7 +1842,7 @@ class Optimisation(wx.Frame): | |
| 1828 1842 | 
             
                            # All upstream elements of a reference will be fixed
         | 
| 1829 1843 | 
             
                            doneList.append(stationOut)
         | 
| 1830 1844 |  | 
| 1831 | 
            -
             | 
| 1845 | 
            +
             | 
| 1832 1846 | 
             
                def generate_semiDist_debug_simul(self, event, idOpti=1,idLauncher:int=0):
         | 
| 1833 1847 |  | 
| 1834 1848 | 
             
                    curCatch:Catchment = self.myCases[idLauncher].refCatchment
         | 
| @@ -1864,7 +1878,7 @@ class Optimisation(wx.Frame): | |
| 1864 1878 | 
             
                            self.optiParam.change_param("Optimizer", "fname", stationOut)
         | 
| 1865 1879 | 
             
                            self.optiParam.SavetoFile(None)
         | 
| 1866 1880 | 
             
                            self.optiParam.Reload(None)
         | 
| 1867 | 
            -
                            # | 
| 1881 | 
            +
                            #
         | 
| 1868 1882 | 
             
                            self.update_myParams(idLauncher)
         | 
| 1869 1883 | 
             
                            # TO DO -> adapt all the debug_info files
         | 
| 1870 1884 | 
             
                            # write it here !!!!
         | 
| @@ -1879,9 +1893,13 @@ class Optimisation(wx.Frame): | |
| 1879 1893 | 
             
                            doneList.append(stationOut)
         | 
| 1880 1894 |  | 
| 1881 1895 |  | 
| 1882 | 
            -
                def read_all_attempts_SA(self, format="rpt", all_attempts=False, filter_repetitions=True):
         | 
| 1896 | 
            +
                def read_all_attempts_SA(self, format="rpt", all_attempts=False, filter_repetitions=True, stationOut:str=""):
         | 
| 1897 | 
            +
             | 
| 1898 | 
            +
                    if stationOut=="":
         | 
| 1899 | 
            +
                        nameTMP = self.optiParam.get_param("Optimizer","fname")
         | 
| 1900 | 
            +
                    else:
         | 
| 1901 | 
            +
                        nameTMP = stationOut
         | 
| 1883 1902 |  | 
| 1884 | 
            -
                    nameTMP = self.optiParam.get_param("Optimizer","fname")
         | 
| 1885 1903 | 
             
                    if all_attempts:
         | 
| 1886 1904 | 
             
                        nb_iter_from_random = self.optiParam.get_param("Optimizer","nb iter from random initial conditions",
         | 
| 1887 1905 | 
             
                                                                   default_value=1)
         | 
| @@ -1906,7 +1924,7 @@ class Optimisation(wx.Frame): | |
| 1906 1924 | 
             
                                    list_ObjFct = []
         | 
| 1907 1925 | 
             
                                    line = 0
         | 
| 1908 1926 | 
             
                                    for raw in data_reader:
         | 
| 1909 | 
            -
                                        if(line<3): | 
| 1927 | 
            +
                                        if(line<3):
         | 
| 1910 1928 | 
             
                                            line += 1
         | 
| 1911 1929 | 
             
                                            continue
         | 
| 1912 1930 | 
             
                                        if(len(raw)<=1):
         | 
| @@ -1918,11 +1936,11 @@ class Optimisation(wx.Frame): | |
| 1918 1936 | 
             
                                        line += 1
         | 
| 1919 1937 | 
             
                                matrixParam = np.vstack((matrixParam,
         | 
| 1920 1938 | 
             
                                                        np.array(list_param).astype("double")))
         | 
| 1921 | 
            -
                                vectorObjFct = np.append(vectorObjFct, | 
| 1939 | 
            +
                                vectorObjFct = np.append(vectorObjFct,
         | 
| 1922 1940 | 
             
                                                        np.array(list_ObjFct).astype("double"))
         | 
| 1923 1941 | 
             
                            except:
         | 
| 1924 1942 | 
             
                                wx.MessageBox(_('The best parameters file is not found!'), _('Error'), wx.OK|wx.ICON_ERROR)
         | 
| 1925 | 
            -
             | 
| 1943 | 
            +
             | 
| 1926 1944 | 
             
                    elif format==".dat":
         | 
| 1927 1945 | 
             
                        for cur_file in all_names:
         | 
| 1928 1946 | 
             
                            optimFile = os.path.join(self.workingDir, cur_file+".rpt.dat")
         | 
| @@ -1935,17 +1953,17 @@ class Optimisation(wx.Frame): | |
| 1935 1953 |  | 
| 1936 1954 | 
             
                    if filter_repetitions:
         | 
| 1937 1955 | 
             
                        logging.info("Filtering the repetitions in the attempts!")
         | 
| 1938 | 
            -
                        filter_matrix, indices, inverse, counts = np.unique(matrixParam, axis=0, | 
| 1939 | 
            -
                                                                            return_index=True, | 
| 1940 | 
            -
                                                                            return_inverse=True, | 
| 1956 | 
            +
                        filter_matrix, indices, inverse, counts = np.unique(matrixParam, axis=0,
         | 
| 1957 | 
            +
                                                                            return_index=True,
         | 
| 1958 | 
            +
                                                                            return_inverse=True,
         | 
| 1941 1959 | 
             
                                                                            return_counts=True)
         | 
| 1942 1960 | 
             
                        vectorObjFct = vectorObjFct[indices]
         | 
| 1943 1961 | 
             
                        matrixParam = filter_matrix
         | 
| 1944 1962 | 
             
                        logging.info("The max number of repetitions = "+ str(np.max(counts)))
         | 
| 1945 | 
            -
             | 
| 1963 | 
            +
             | 
| 1946 1964 | 
             
                    return matrixParam, vectorObjFct
         | 
| 1947 | 
            -
             | 
| 1948 | 
            -
             | 
| 1965 | 
            +
             | 
| 1966 | 
            +
             | 
| 1949 1967 | 
             
                def apply_optim_2_params(self, params:np.array, idLauncher=0):
         | 
| 1950 1968 |  | 
| 1951 1969 | 
             
                    refCatch:Catchment = self.myCases[idLauncher].refCatchment
         | 
| @@ -1955,9 +1973,9 @@ class Optimisation(wx.Frame): | |
| 1955 1973 | 
             
                        or len(self.curParams_vec_F) != self.nbParams:
         | 
| 1956 1974 |  | 
| 1957 1975 | 
             
                        self.curParams_vec_F = np.empty((self.nbParams,), dtype=ct.c_double, order='F')
         | 
| 1958 | 
            -
             | 
| 1976 | 
            +
             | 
| 1959 1977 | 
             
                    myModelDict = cste.modelParamsDict[myModel]["Parameters"]
         | 
| 1960 | 
            -
             | 
| 1978 | 
            +
             | 
| 1961 1979 | 
             
                    for cur_effsub in range(len(refCatch.myEffSubBasins)):
         | 
| 1962 1980 |  | 
| 1963 1981 | 
             
                        filePath = os.path.join(refCatch.workingDir, "Subbasin_" + str(refCatch.myEffSortSubBasins[cur_effsub]))
         | 
| @@ -1972,20 +1990,24 @@ class Optimisation(wx.Frame): | |
| 1972 1990 | 
             
                                    if cur_sub.iDSorted != refCatch.myEffSortSubBasins[cur_effsub]:
         | 
| 1973 1991 | 
             
                                        continue
         | 
| 1974 1992 | 
             
                                self.myParams[i+1]["value"] = params[i]
         | 
| 1975 | 
            -
                                fileName = myModelDict[int(myType)]["File"]
         | 
| 1976 | 
            -
                                myGroup = myModelDict[int(myType)]["Group"]
         | 
| 1977 | 
            -
                                myKey = myModelDict[int(myType)]["Key"]
         | 
| 1978 1993 | 
             
                                if "Convertion Factor" in myModelDict[int(myType)]:
         | 
| 1979 1994 | 
             
                                    convFact = myModelDict[int(myType)]["Convertion Factor"]
         | 
| 1980 1995 | 
             
                                else:
         | 
| 1981 1996 | 
             
                                    convFact = 1.0
         | 
| 1982 | 
            -
                                 | 
| 1983 | 
            -
                                 | 
| 1984 | 
            -
             | 
| 1985 | 
            -
             | 
| 1986 | 
            -
             | 
| 1997 | 
            +
                                all_files = myModelDict[int(myType)]["File"]
         | 
| 1998 | 
            +
                                if type(all_files) is not list:
         | 
| 1999 | 
            +
                                    fileName = myModelDict[int(myType)]["File"]
         | 
| 2000 | 
            +
                                    myGroup = myModelDict[int(myType)]["Group"]
         | 
| 2001 | 
            +
                                    myKey = myModelDict[int(myType)]["Key"]
         | 
| 2002 | 
            +
                                    self.write_one_opti_param(filePath, fileName, myGroup, myKey, params[i], convers_factor=convFact)
         | 
| 2003 | 
            +
                                else:
         | 
| 2004 | 
            +
                                    for iFile in range(len(all_files)):
         | 
| 2005 | 
            +
                                        fileName = all_files[iFile]
         | 
| 2006 | 
            +
                                        myGroup = myModelDict[int(myType)]["Group"][iFile]
         | 
| 2007 | 
            +
                                        myKey = myModelDict[int(myType)]["Key"][iFile]
         | 
| 2008 | 
            +
                                        self.write_one_opti_param(filePath, fileName, myGroup, myKey, params[i], convers_factor=convFact)
         | 
| 1987 2009 | 
             
                            else:
         | 
| 1988 | 
            -
             | 
| 2010 | 
            +
             | 
| 1989 2011 | 
             
                                self.curParams_vec_F[i] = params[i]
         | 
| 1990 2012 | 
             
                                self.update_timeDelay(i+1)
         | 
| 1991 2013 | 
             
                                refCatch.save_timeDelays([self.myParams[i+1]["junction_name"]])
         | 
| @@ -2026,7 +2048,7 @@ class Optimisation(wx.Frame): | |
| 2026 2048 |  | 
| 2027 2049 | 
             
                        myModel = self.myCases[idLauncher].refCatchment.myModel
         | 
| 2028 2050 | 
             
                        nbParamsModel = cste.modelParamsDict[myModel]["Nb"]*len(cur_opti.refCatchment.myEffSubBasins)
         | 
| 2029 | 
            -
             | 
| 2051 | 
            +
             | 
| 2030 2052 | 
             
                        for i in range(1,nb_params+1):
         | 
| 2031 2053 | 
             
                            curParam = "param_" + str(i)
         | 
| 2032 2054 | 
             
                            curType = int(paramDict.get_param(curParam, "type_of_data"))
         | 
| @@ -2044,7 +2066,7 @@ class Optimisation(wx.Frame): | |
| 2044 2066 | 
             
                        self.myCases[idLauncher].launcherParam.change_param("Paramètres à varier", "Nombre de paramètres à varier", nb_params)
         | 
| 2045 2067 |  | 
| 2046 2068 | 
             
                        return
         | 
| 2047 | 
            -
             | 
| 2069 | 
            +
             | 
| 2048 2070 |  | 
| 2049 2071 | 
             
                def _read_opti_intervals(self, idLauncher:int=0)->list[tuple[datetime.datetime, datetime.datetime]]:
         | 
| 2050 2072 | 
             
                    """
         | 
| @@ -2060,7 +2082,7 @@ class Optimisation(wx.Frame): | |
| 2060 2082 | 
             
                    # if isOk<0:
         | 
| 2061 2083 | 
             
                    #     logging.error("The file compare.txt is not found!")
         | 
| 2062 2084 | 
             
                    #     return
         | 
| 2063 | 
            -
             | 
| 2085 | 
            +
             | 
| 2064 2086 | 
             
                    # Read the comparison file
         | 
| 2065 2087 | 
             
                    if self.myStations==[]:
         | 
| 2066 2088 | 
             
                        self.set_compare_stations(idLauncher=idLauncher)
         | 
| @@ -2068,7 +2090,7 @@ class Optimisation(wx.Frame): | |
| 2068 2090 | 
             
                    nb_comparison = self.comparHowParam.get_param("Comparison global characteristics", "nb")
         | 
| 2069 2091 | 
             
                    str_di = "date begin"
         | 
| 2070 2092 | 
             
                    str_df = "date end"
         | 
| 2071 | 
            -
             | 
| 2093 | 
            +
             | 
| 2072 2094 | 
             
                    intervals = []
         | 
| 2073 2095 | 
             
                    for icomp in range(1, nb_comparison+1):
         | 
| 2074 2096 | 
             
                        cur_key = " ".join(["Comparison", str(icomp)])
         | 
| @@ -2087,15 +2109,15 @@ class Optimisation(wx.Frame): | |
| 2087 2109 |  | 
| 2088 2110 |  | 
| 2089 2111 | 
             
                    return intervals
         | 
| 2090 | 
            -
                
         | 
| 2091 2112 |  | 
| 2092 | 
            -
             | 
| 2113 | 
            +
             | 
| 2114 | 
            +
                def _save_opti_intervals(self, idLauncher:int=0, stationOut:str="",
         | 
| 2093 2115 | 
             
                                         intervals:list[tuple[datetime.datetime, datetime.datetime]]=None)->int:
         | 
| 2094 2116 | 
             
                    if stationOut == "":
         | 
| 2095 2117 | 
             
                        suffix = "0"
         | 
| 2096 2118 | 
             
                    else:
         | 
| 2097 2119 | 
             
                        suffix = stationOut
         | 
| 2098 | 
            -
             | 
| 2120 | 
            +
             | 
| 2099 2121 | 
             
                    if intervals is None:
         | 
| 2100 2122 | 
             
                        self.all_intervals = self._read_opti_intervals(idLauncher=idLauncher)
         | 
| 2101 2123 |  | 
| @@ -2116,7 +2138,7 @@ class Optimisation(wx.Frame): | |
| 2116 2138 | 
             
                        return -1
         | 
| 2117 2139 | 
             
                    else:
         | 
| 2118 2140 | 
             
                        return 0
         | 
| 2119 | 
            -
             | 
| 2141 | 
            +
             | 
| 2120 2142 |  | 
| 2121 2143 | 
             
                def select_opti_intervals(self, all_intervals:list[tuple[datetime.datetime, datetime.datetime]]=None,
         | 
| 2122 2144 | 
             
                                          idLauncher:int=0, stationOut="", filter_nan:bool=True)->list[tuple]:
         | 
| @@ -2130,7 +2152,7 @@ class Optimisation(wx.Frame): | |
| 2130 2152 | 
             
                    """
         | 
| 2131 2153 | 
             
                    cur_opti = self.myCases[idLauncher]
         | 
| 2132 2154 | 
             
                    cur_ref = cur_opti.refCatchment
         | 
| 2133 | 
            -
             | 
| 2155 | 
            +
             | 
| 2134 2156 | 
             
                    if stationOut == "":
         | 
| 2135 2157 | 
             
                        stationOut = cur_ref.junctionOut
         | 
| 2136 2158 |  | 
| @@ -2140,30 +2162,30 @@ class Optimisation(wx.Frame): | |
| 2140 2162 | 
             
                            # id_ok= self._save_opti_intervals(idLauncher=idLauncher)
         | 
| 2141 2163 | 
             
                            # if id_ok<0:
         | 
| 2142 2164 | 
             
                            #     return None
         | 
| 2143 | 
            -
             | 
| 2165 | 
            +
             | 
| 2144 2166 | 
             
                        else:
         | 
| 2145 2167 | 
             
                            all_intervals = self.all_intervals
         | 
| 2146 2168 |  | 
| 2147 2169 | 
             
                    if self.myStations==[]:
         | 
| 2148 2170 | 
             
                        self.set_compare_stations(idLauncher=idLauncher)
         | 
| 2149 | 
            -
             | 
| 2171 | 
            +
             | 
| 2150 2172 | 
             
                    keyBasin = cur_ref.get_key_catchmentDict(stationOut)
         | 
| 2151 2173 | 
             
                    cur_basin = cur_ref.catchmentDict[keyBasin]
         | 
| 2152 2174 |  | 
| 2153 2175 | 
             
                    # Select the optimisation intervals that are relevant according to the available measures
         | 
| 2154 2176 | 
             
                    effective_intv = [interv for interv in all_intervals if interv[0]>=cur_basin.dateBegin and interv[1]<=cur_basin.dateEnd]
         | 
| 2155 2177 | 
             
                    if filter_nan:
         | 
| 2156 | 
            -
                        effective_intv = self._define_intervals_with_nan_measures(effective_intv, self.compareSubBasins, | 
| 2178 | 
            +
                        effective_intv = self._define_intervals_with_nan_measures(effective_intv, self.compareSubBasins,
         | 
| 2157 2179 | 
             
                                                                                  idLauncher=idLauncher, stationOut=stationOut)
         | 
| 2158 2180 |  | 
| 2159 2181 | 
             
                    return effective_intv
         | 
| 2160 | 
            -
             | 
| 2161 | 
            -
             | 
| 2162 | 
            -
                def _define_intervals_with_nan_measures(self, intervals: list[tuple[datetime.datetime, datetime.datetime]], measures: dict[str, SubBasin], | 
| 2182 | 
            +
             | 
| 2183 | 
            +
             | 
| 2184 | 
            +
                def _define_intervals_with_nan_measures(self, intervals: list[tuple[datetime.datetime, datetime.datetime]], measures: dict[str, SubBasin],
         | 
| 2163 2185 | 
             
                                                        idLauncher: int = 0, stationOut: str = ""):
         | 
| 2164 2186 | 
             
                    """
         | 
| 2165 2187 | 
             
                    Defines new intervals excluding all NaN measures based on the given intervals and measures dictionary.
         | 
| 2166 | 
            -
                    For instance, if there is continuous NaN measures within a given interval, the function will split | 
| 2188 | 
            +
                    For instance, if there is continuous NaN measures within a given interval, the function will split
         | 
| 2167 2189 | 
             
                    that interval into smaller that do not contain NaN measures.
         | 
| 2168 2190 |  | 
| 2169 2191 | 
             
                    Args:
         | 
| @@ -2182,15 +2204,15 @@ class Optimisation(wx.Frame): | |
| 2182 2204 | 
             
                    if stationOut not in measures:
         | 
| 2183 2205 | 
             
                        logging.error("The stationOut is not in the measures dictionary!")
         | 
| 2184 2206 | 
             
                        return None
         | 
| 2185 | 
            -
             | 
| 2207 | 
            +
             | 
| 2186 2208 | 
             
                    cur_el = measures[stationOut]
         | 
| 2187 2209 | 
             
                    hydro = cur_el.get_myHydro()
         | 
| 2188 2210 | 
             
                    time = cur_el.time
         | 
| 2189 2211 | 
             
                    # get the indices of the nan values
         | 
| 2190 2212 | 
             
                    non_nan_locations = ~np.isnan(hydro)
         | 
| 2191 2213 | 
             
                    within_intervals = np.sum(
         | 
| 2192 | 
            -
                        [(time >= datetime.datetime.timestamp(interv[0])) * | 
| 2193 | 
            -
                         (time <= datetime.datetime.timestamp(interv[1])) | 
| 2214 | 
            +
                        [(time >= datetime.datetime.timestamp(interv[0])) *
         | 
| 2215 | 
            +
                         (time <= datetime.datetime.timestamp(interv[1]))
         | 
| 2194 2216 | 
             
                         for interv in intervals],
         | 
| 2195 2217 | 
             
                        axis=0) > 0
         | 
| 2196 2218 | 
             
                    # Both conditions should be satisfied
         | 
| @@ -2200,7 +2222,7 @@ class Optimisation(wx.Frame): | |
| 2200 2222 | 
             
                    # i.e. when the index difference is not 1
         | 
| 2201 2223 | 
             
                    # +1 as the np.diff is one element sooner than nan_locations: diff[0]=v[1]-v[0]
         | 
| 2202 2224 | 
             
                    group_starts = np.where(np.diff(all_conditions) != 1)[0] + 1
         | 
| 2203 | 
            -
             | 
| 2225 | 
            +
             | 
| 2204 2226 | 
             
                    # Add 0 as it is the first index of the first group
         | 
| 2205 2227 | 
             
                    group_starts = np.insert(group_starts, 0, 0)
         | 
| 2206 2228 |  | 
| @@ -2209,18 +2231,18 @@ class Optimisation(wx.Frame): | |
| 2209 2231 |  | 
| 2210 2232 | 
             
                    # Get the timestamps of the first and last nan element and form groups of discontinuities
         | 
| 2211 2233 | 
             
                    iterv_timestamp = [(time[all_conditions[i_i]], time[all_conditions[i_f]]) for i_i, i_f in zip(group_starts, group_ends)]
         | 
| 2212 | 
            -
                    interv_dates = [(datetime.datetime.fromtimestamp(iterv[0],tz=datetime.timezone.utc), | 
| 2234 | 
            +
                    interv_dates = [(datetime.datetime.fromtimestamp(iterv[0],tz=datetime.timezone.utc),
         | 
| 2213 2235 | 
             
                                     datetime.datetime.fromtimestamp(iterv[1], tz=datetime.timezone.utc))
         | 
| 2214 2236 | 
             
                                     for iterv in iterv_timestamp]
         | 
| 2215 2237 |  | 
| 2216 2238 | 
             
                    return interv_dates
         | 
| 2217 | 
            -
             | 
| 2239 | 
            +
             | 
| 2218 2240 |  | 
| 2219 2241 | 
             
                def save_opti_dates_to_file(self, opti_dates:list[tuple[datetime.datetime,datetime.datetime]]):
         | 
| 2220 2242 | 
             
                    """
         | 
| 2221 2243 | 
             
                    Here the procedure is saving the intervals of dates for calibration in the compare.how.param
         | 
| 2222 2244 | 
             
                    """
         | 
| 2223 | 
            -
                    # Verifications | 
| 2245 | 
            +
                    # Verifications
         | 
| 2224 2246 | 
             
                    assert len(opti_dates)>0, "The list of dates is empty!"
         | 
| 2225 2247 | 
             
                    for i_opti in opti_dates:
         | 
| 2226 2248 | 
             
                        assert i_opti[1]>i_opti[0], "The start date is not lower than the end date!"
         | 
| @@ -2251,16 +2273,16 @@ class Optimisation(wx.Frame): | |
| 2251 2273 | 
             
                        # Force the initial parameters to be defined randomly
         | 
| 2252 2274 | 
             
                        self.saParam.change_param("Initial parameters", "Read initial parameters?", 0)
         | 
| 2253 2275 | 
             
                        return
         | 
| 2254 | 
            -
             | 
| 2276 | 
            +
             | 
| 2255 2277 | 
             
                    # In the following code, we apply the best parameters to the initial parameters
         | 
| 2256 2278 | 
             
                    self.saParam.change_param("Initial parameters", "Read initial parameters?", 1)
         | 
| 2257 2279 | 
             
                    for i in range(self.nbParams):
         | 
| 2258 2280 | 
             
                        self.saParam.change_param("Initial parameters", " ".join(["Parameter",str(i+1)]), best_params[i])
         | 
| 2259 | 
            -
             | 
| 2281 | 
            +
             | 
| 2260 2282 | 
             
                    self.saParam.SavetoFile(None)
         | 
| 2261 2283 | 
             
                    self.saParam.Reload(None)
         | 
| 2262 2284 |  | 
| 2263 | 
            -
             | 
| 2285 | 
            +
             | 
| 2264 2286 | 
             
                def get_initial_parameters(self)-> np.array:
         | 
| 2265 2287 | 
             
                    read_IP = self.saParam.get_param("Initial parameters", "Read initial parameters?")
         | 
| 2266 2288 | 
             
                    if read_IP == 1:
         | 
| @@ -2268,12 +2290,12 @@ class Optimisation(wx.Frame): | |
| 2268 2290 | 
             
                        init_params = np.zeros(self.nbParams+1)
         | 
| 2269 2291 | 
             
                        for i in range(self.nbParams):
         | 
| 2270 2292 | 
             
                            init_params[i] = self.saParam.get_param("Initial parameters", " ".join(["Parameter",str(i+1)]))
         | 
| 2271 | 
            -
                        init_params[-1] = -sys.float_info.max | 
| 2293 | 
            +
                        init_params[-1] = -sys.float_info.max
         | 
| 2272 2294 | 
             
                    else:
         | 
| 2273 2295 | 
             
                        init_params = None
         | 
| 2274 | 
            -
             | 
| 2296 | 
            +
             | 
| 2275 2297 | 
             
                    return init_params
         | 
| 2276 | 
            -
             | 
| 2298 | 
            +
             | 
| 2277 2299 |  | 
| 2278 2300 | 
             
                def reset_init_params(self, init_params:np.array):
         | 
| 2279 2301 | 
             
                    if init_params is None:
         | 
| @@ -2283,7 +2305,7 @@ class Optimisation(wx.Frame): | |
| 2283 2305 | 
             
                    print("Reset init params : ", init_params)
         | 
| 2284 2306 | 
             
                    self.saParam.SavetoFile(None)
         | 
| 2285 2307 | 
             
                    self.saParam.Reload(None)
         | 
| 2286 | 
            -
             | 
| 2308 | 
            +
             | 
| 2287 2309 |  | 
| 2288 2310 | 
             
                def extract_internal_variables(self, event, idLauncher:int=0, to_plot:bool=True):
         | 
| 2289 2311 | 
             
                    curCatch:Catchment = self.myCases[idLauncher].refCatchment
         | 
| @@ -2311,7 +2333,7 @@ class Optimisation(wx.Frame): | |
| 2311 2333 | 
             
                            dlg = wx.MessageDialog(None, "Internal variables were detected! Do you still want to launch a detailed simulation ?", "Warning", wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
         | 
| 2312 2334 | 
             
                            r = dlg.ShowModal()
         | 
| 2313 2335 | 
             
                            if r == wx.ID_YES:
         | 
| 2314 | 
            -
                                to_generate = True | 
| 2336 | 
            +
                                to_generate = True
         | 
| 2315 2337 | 
             
                            dlg.Destroy()
         | 
| 2316 2338 | 
             
                            # FIXME :  ADD the terminal
         | 
| 2317 2339 | 
             
                        else:
         | 
| @@ -2319,7 +2341,7 @@ class Optimisation(wx.Frame): | |
| 2319 2341 | 
             
                    # Enter here if a detailed simulation is required
         | 
| 2320 2342 | 
             
                    if to_generate:
         | 
| 2321 2343 | 
             
                        curCatch.activate_all_internal_variables()
         | 
| 2322 | 
            -
                        self.generate_semiDist_optim_simul(None, idLauncher=idLauncher) | 
| 2344 | 
            +
                        self.generate_semiDist_optim_simul(None, idLauncher=idLauncher)
         | 
| 2323 2345 | 
             
                        all_x = curCatch.get_all_x_production()
         | 
| 2324 2346 | 
             
                        all_iv = curCatch.get_all_iv_production()
         | 
| 2325 2347 |  | 
| @@ -2333,18 +2355,18 @@ class Optimisation(wx.Frame): | |
| 2333 2355 | 
             
                            all_frac = curCatch.plot_all_fractions(all_fractions=all_frac, to_show=True, range_data=list(interv))
         | 
| 2334 2356 |  | 
| 2335 2357 | 
             
                    return all_x, all_iv, all_frac
         | 
| 2336 | 
            -
             | 
| 2358 | 
            +
             | 
| 2337 2359 |  | 
| 2338 2360 | 
             
                def _check_presence_of_iv(self, idLauncher:int=0):
         | 
| 2339 2361 | 
             
                    curCatch:Catchment = self.myCases[idLauncher].refCatchment
         | 
| 2340 2362 | 
             
                    return curCatch.check_presence_of_iv()
         | 
| 2341 | 
            -
             | 
| 2342 | 
            -
             | 
| 2363 | 
            +
             | 
| 2364 | 
            +
             | 
| 2343 2365 | 
             
                def plot_Nash_vs_Qexcess(self, event, idLauncher:int=0):
         | 
| 2344 2366 | 
             
                    curCatch:Catchment = self.myCases[idLauncher].refCatchment
         | 
| 2345 2367 | 
             
                    all_params, all_nash = self.read_all_attempts_SA(format=".dat")
         | 
| 2346 2368 | 
             
                    nb_tests = np.shape(all_nash)[0]
         | 
| 2347 | 
            -
             | 
| 2369 | 
            +
             | 
| 2348 2370 | 
             
                    if self.myStations==[]:
         | 
| 2349 2371 | 
             
                        self.set_compare_stations(idLauncher=idLauncher)
         | 
| 2350 2372 |  | 
| @@ -2359,17 +2381,17 @@ class Optimisation(wx.Frame): | |
| 2359 2381 | 
             
                        compMeas.append(SubBasin(dateBegin, dateEnd, deltaT, cst.compare_opti, dir_Meas))
         | 
| 2360 2382 | 
             
                        _,cur_comp = compMeas[iOpti].get_hydro(1, workingDir=dir_Meas, fileNames=compareFileName)
         | 
| 2361 2383 | 
             
                        keyBasin = curCatch.get_key_catchmentDict(stationOut)
         | 
| 2362 | 
            -
                        cur_basin = curCatch.catchmentDict[keyBasin] | 
| 2384 | 
            +
                        cur_basin = curCatch.catchmentDict[keyBasin]
         | 
| 2363 2385 | 
             
                        cur_comp = cur_comp*cur_basin.surfaceDrained/3.6
         | 
| 2364 2386 | 
             
                        all_qtests = curCatch.get_all_Qtest(nb_atttempts=nb_tests, selection_by_iD=[stationOut])
         | 
| 2365 2387 | 
             
                        # FIXME : Check the type of interpolation to use
         | 
| 2366 2388 | 
             
                        interp_qcomp = np.interp(curCatch.time, compMeas[iOpti].time, cur_comp)
         | 
| 2367 | 
            -
                        q_diff = np.array([np.count_nonzero((qtest-interp_qcomp <0.0) & (qtest != 0.0))/np.count_nonzero((qtest != 0.0)) | 
| 2389 | 
            +
                        q_diff = np.array([np.count_nonzero((qtest-interp_qcomp <0.0) & (qtest != 0.0))/np.count_nonzero((qtest != 0.0))
         | 
| 2368 2390 | 
             
                                           for qtest in all_qtests[0]])
         | 
| 2369 2391 | 
             
                        fig, ax = plt.subplots()
         | 
| 2370 2392 | 
             
                        for i in range(nb_tests-1):
         | 
| 2371 2393 | 
             
                            ax.scatter(q_diff[i], all_nash[i], s=0.5, c='b', marker='o', alpha=i/nb_tests)
         | 
| 2372 | 
            -
                        ax.scatter(q_diff[-1], all_nash[-1], s=0.5, c='b', marker='o', label="test", alpha=1) | 
| 2394 | 
            +
                        ax.scatter(q_diff[-1], all_nash[-1], s=0.5, c='b', marker='o', label="test", alpha=1)
         | 
| 2373 2395 | 
             
                        # ax.scatter(q_diff, all_nash, s=0.5, c='b', marker='o', label="test")
         | 
| 2374 2396 | 
             
                        ax.set_xlabel("Non-exceedance fraction. Portion of the observations below the simulated series (Qs>Qo)")
         | 
| 2375 2397 | 
             
                        ax.set_ylabel("Nash-Sutcliffe efficiency")
         | 
| @@ -2383,20 +2405,20 @@ class Optimisation(wx.Frame): | |
| 2383 2405 | 
             
                        ax.legend()
         | 
| 2384 2406 | 
             
                        fig.savefig(os.path.join(curCatch.workingDir, "PostProcess/Nash_vs_Qexcess_"+stationOut+".png"))
         | 
| 2385 2407 |  | 
| 2386 | 
            -
             | 
| 2408 | 
            +
             | 
| 2387 2409 | 
             
                    plt.show()
         | 
| 2388 2410 |  | 
| 2389 2411 |  | 
| 2390 2412 | 
             
                def get_all_Nash(self):
         | 
| 2391 | 
            -
             | 
| 2413 | 
            +
             | 
| 2392 2414 | 
             
                    return {cur_file: self.collect_optim(cur_file)[-1] for cur_file in self.myStations}
         | 
| 2393 | 
            -
             | 
| 2415 | 
            +
             | 
| 2394 2416 | 
             
                # FIXME this function is not correct -> to be corrected and delete the remove_py_params and updtate_myParams calls
         | 
| 2395 2417 | 
             
                def get_all_params(self, idLauncher:int=0):
         | 
| 2396 2418 | 
             
                    curCatch:Catchment = self.myCases[idLauncher].refCatchment
         | 
| 2397 2419 |  | 
| 2398 2420 | 
             
                    hydro_model = curCatch.myModel
         | 
| 2399 | 
            -
             | 
| 2421 | 
            +
             | 
| 2400 2422 | 
             
                    # Read the comparison file
         | 
| 2401 2423 | 
             
                    if self.myStations==[]:
         | 
| 2402 2424 | 
             
                        self.set_compare_stations(idLauncher=idLauncher)
         | 
| @@ -2414,13 +2436,13 @@ class Optimisation(wx.Frame): | |
| 2414 2436 | 
             
                        names = [myModelDict[cur_id]["Name"] for cur_id in id_params if cur_id>0]
         | 
| 2415 2437 | 
             
                        all_names[stationOut] = names
         | 
| 2416 2438 | 
             
                        if calibrate_timeDelay:
         | 
| 2417 | 
            -
                            # Get_nb inlets | 
| 2439 | 
            +
                            # Get_nb inlets
         | 
| 2418 2440 | 
             
                            inletsNames = self.myCases[idLauncher].refCatchment.get_inletsName(stationOut)
         | 
| 2419 2441 | 
             
                            nbInlets = len(inletsNames)
         | 
| 2420 2442 | 
             
                            for i in range(nbInlets):
         | 
| 2421 2443 | 
             
                                names.append("TimeDelay "+inletsNames[i])
         | 
| 2422 2444 | 
             
                        # Complete the names according to the stations concerned
         | 
| 2423 | 
            -
             | 
| 2445 | 
            +
             | 
| 2424 2446 | 
             
                    optim = {cur_file: self.collect_optim(cur_file) for cur_file in self.myStations}
         | 
| 2425 2447 |  | 
| 2426 2448 | 
             
                    # all_params = {}
         | 
| @@ -2428,20 +2450,20 @@ class Optimisation(wx.Frame): | |
| 2428 2450 | 
             
                    #     all_params[key] = {}
         | 
| 2429 2451 | 
             
                    #     for i, cur_name in enumerate(all_names):
         | 
| 2430 2452 | 
             
                    #         all_params[key][cur_name] = value[i]
         | 
| 2431 | 
            -
             | 
| 2432 | 
            -
                    all_params = {key: | 
| 2453 | 
            +
             | 
| 2454 | 
            +
                    all_params = {key:
         | 
| 2433 2455 | 
             
                                  {cur_name : value[i] for i, cur_name in enumerate(all_names)}
         | 
| 2434 2456 | 
             
                                  for key, value in optim.items()}
         | 
| 2435 2457 |  | 
| 2436 2458 | 
             
                    return all_params
         | 
| 2437 | 
            -
             | 
| 2438 | 
            -
             | 
| 2459 | 
            +
             | 
| 2460 | 
            +
             | 
| 2439 2461 | 
             
                def save_all_params(self, all_params:dict={}, idLauncher:int=0):
         | 
| 2440 | 
            -
             | 
| 2462 | 
            +
             | 
| 2441 2463 | 
             
                    all_keys = list(all_params.keys())
         | 
| 2442 | 
            -
             | 
| 2443 | 
            -
                    return | 
| 2444 | 
            -
             | 
| 2464 | 
            +
             | 
| 2465 | 
            +
                    return
         | 
| 2466 | 
            +
             | 
| 2445 2467 |  | 
| 2446 2468 | 
             
                def save_current_compare_file(self, stationOut: str):
         | 
| 2447 2469 | 
             
                    """
         | 
| @@ -2475,11 +2497,11 @@ class Optimisation(wx.Frame): | |
| 2475 2497 | 
             
                        comments="",
         | 
| 2476 2498 | 
             
                        delimiter="\t",
         | 
| 2477 2499 | 
             
                    )
         | 
| 2478 | 
            -
             | 
| 2479 | 
            -
             | 
| 2500 | 
            +
             | 
| 2501 | 
            +
             | 
| 2480 2502 | 
             
                def prepare_simulation(self, opti_intervals:list[tuple[datetime.datetime, datetime.datetime]],
         | 
| 2481 2503 | 
             
                                       idLauncher:int=0):
         | 
| 2482 | 
            -
             | 
| 2504 | 
            +
             | 
| 2483 2505 | 
             
                    cur_catch = self.myCases[idLauncher].refCatchment
         | 
| 2484 2506 | 
             
                    # TODO : Create an object hydro intervals with activate property and a method to retrun a list of tuples
         | 
| 2485 2507 | 
             
                    simul_intevals = cur_catch.simulation_intervals
         | 
| @@ -2493,20 +2515,20 @@ class Optimisation(wx.Frame): | |
| 2493 2515 | 
             
                                break
         | 
| 2494 2516 | 
             
                        if to_activate:
         | 
| 2495 2517 | 
             
                            eff_simul_intervals.append(simul_intrv)
         | 
| 2496 | 
            -
             | 
| 2518 | 
            +
             | 
| 2497 2519 | 
             
                    cur_catch.simulation_intervals = eff_simul_intervals
         | 
| 2498 | 
            -
             | 
| 2520 | 
            +
             | 
| 2499 2521 | 
             
                    return
         | 
| 2500 | 
            -
                
         | 
| 2501 2522 |  | 
| 2502 | 
            -
             | 
| 2523 | 
            +
             | 
| 2524 | 
            +
                def reset_simulation_intervals(self, default_interval:list[tuple[datetime.datetime, datetime.datetime]],
         | 
| 2503 2525 | 
             
                                               idLauncher:int=0):
         | 
| 2504 | 
            -
             | 
| 2526 | 
            +
             | 
| 2505 2527 | 
             
                    cur_catch = self.myCases[idLauncher].refCatchment
         | 
| 2506 2528 | 
             
                    cur_catch.simulation_intervals = default_interval
         | 
| 2507 2529 |  | 
| 2508 2530 | 
             
                    return
         | 
| 2509 | 
            -
             | 
| 2531 | 
            +
             | 
| 2510 2532 | 
             
                # FIXME : this function has been dashed off -> functionnal but not well written!!
         | 
| 2511 2533 | 
             
                # TODO : to improve !!!!!!
         | 
| 2512 2534 | 
             
                def test_equifinality_with_Nash(self, event, idLauncher:int=0, idOpti:int=1, quantile_Nash:float=0.01, std_Nash:float=0.3, clustering_Nash:bool=True):
         | 
| @@ -2528,11 +2550,11 @@ class Optimisation(wx.Frame): | |
| 2528 2550 | 
             
                    if onlyOwnSub is None:
         | 
| 2529 2551 | 
             
                        onlyOwnSub = False
         | 
| 2530 2552 | 
             
                    doneList = []
         | 
| 2531 | 
            -
                    previousLevel = 1 | 
| 2553 | 
            +
                    previousLevel = 1
         | 
| 2532 2554 | 
             
                    # Collect sort and save the compare stations
         | 
| 2533 2555 | 
             
                    self.set_compare_stations(idLauncher=idLauncher)
         | 
| 2534 2556 | 
             
                    sortJct = self.myStations
         | 
| 2535 | 
            -
                    # Get the initial number of intervals | 
| 2557 | 
            +
                    # Get the initial number of intervals
         | 
| 2536 2558 | 
             
                    # -> these can evolve according to the measurement available at each station
         | 
| 2537 2559 | 
             
                    is_ok = self._save_opti_intervals()
         | 
| 2538 2560 | 
             
                    all_intervals = self.all_intervals
         | 
| @@ -2564,14 +2586,14 @@ class Optimisation(wx.Frame): | |
| 2564 2586 | 
             
                        # Reload the useful modules
         | 
| 2565 2587 | 
             
                        self.reload_hydro(idCompar=0, fromStation=stationOut, lastLevel=previousLevel, updateAll=True)
         | 
| 2566 2588 | 
             
                        ## =======
         | 
| 2567 | 
            -
                        ## Init | 
| 2589 | 
            +
                        ## Init
         | 
| 2568 2590 | 
             
                        ## =======
         | 
| 2569 2591 | 
             
                        self.init_optimizer(idOpti)
         | 
| 2570 2592 | 
             
                        self.associate_ptr(None, idOpti=idOpti)
         | 
| 2571 2593 | 
             
                        # Get the best parameters to test
         | 
| 2572 2594 | 
             
                        all_params = self.get_best_params(stationOut=stationOut, quantile=quantile_Nash, std=std_Nash, apply_clustering=clustering_Nash)
         | 
| 2573 2595 | 
             
                        ## =======
         | 
| 2574 | 
            -
                        ## Compute | 
| 2596 | 
            +
                        ## Compute
         | 
| 2575 2597 | 
             
                        ## =======
         | 
| 2576 2598 | 
             
                        all_frac = []
         | 
| 2577 2599 |  | 
| @@ -2608,7 +2630,7 @@ class Optimisation(wx.Frame): | |
| 2608 2630 | 
             
                                    + list(frac_dict.keys()) \
         | 
| 2609 2631 | 
             
                                    + list(frac_vol_dict.keys()) \
         | 
| 2610 2632 | 
             
                                    + ["% max runoff", "P. of exceedance", "Qmax_simul/Q_max_measure", "Nash"]
         | 
| 2611 | 
            -
             | 
| 2633 | 
            +
             | 
| 2612 2634 | 
             
                        cur_df = pd.DataFrame(all_frac, columns=var_names)
         | 
| 2613 2635 | 
             
                        # write first the tempory results for each station
         | 
| 2614 2636 | 
             
                        writer_stat = pd.ExcelWriter(os.path.join(self.workingDir, stationOut+"_tests.xlsx"), engine = 'xlsxwriter')
         | 
| @@ -2638,12 +2660,12 @@ class Optimisation(wx.Frame): | |
| 2638 2660 |  | 
| 2639 2661 | 
             
                    writer_tot.close()
         | 
| 2640 2662 | 
             
                    logging.info("The equifinality test is finished!")
         | 
| 2641 | 
            -
                    
         | 
| 2642 2663 |  | 
| 2643 | 
            -
             | 
| 2664 | 
            +
             | 
| 2665 | 
            +
                def get_best_params(self, stationOut:str,
         | 
| 2644 2666 | 
             
                                    criterion:str="Nash", quantile:float=0.99, std:float=0.05, eps:float=0.1,
         | 
| 2645 2667 | 
             
                                    objective_fct:bool= True, apply_clustering:bool=False):
         | 
| 2646 | 
            -
                    from sklearn.cluster import DBSCAN | 
| 2668 | 
            +
                    from sklearn.cluster import DBSCAN
         | 
| 2647 2669 | 
             
                    """
         | 
| 2648 2670 | 
             
                    Get the best parameters for a given station.
         | 
| 2649 2671 |  | 
| @@ -2662,7 +2684,7 @@ class Optimisation(wx.Frame): | |
| 2662 2684 | 
             
                    all_params, all_obj_fct = self.read_all_attempts_SA(format=".dat", all_attempts=True)
         | 
| 2663 2685 |  | 
| 2664 2686 | 
             
                    quantile_cond = (all_obj_fct > np.quantile(all_obj_fct, quantile))
         | 
| 2665 | 
            -
                    std_cond = (all_obj_fct > best_objfct*(1-std)) | 
| 2687 | 
            +
                    std_cond = (all_obj_fct > best_objfct*(1-std))
         | 
| 2666 2688 | 
             
                    all_cond = np.where(np.logical_and(quantile_cond, std_cond))[0]
         | 
| 2667 2689 | 
             
                    eff_params = all_params[all_cond]
         | 
| 2668 2690 | 
             
                    eff_obj = all_obj_fct[all_cond]
         | 
| @@ -2670,7 +2692,7 @@ class Optimisation(wx.Frame): | |
| 2670 2692 | 
             
                    if objective_fct:
         | 
| 2671 2693 | 
             
                        eff_params = np.column_stack((eff_params, eff_obj))
         | 
| 2672 2694 |  | 
| 2673 | 
            -
                    # In this part we filter abd remove the parameters that are almost equivalent | 
| 2695 | 
            +
                    # In this part we filter abd remove the parameters that are almost equivalent
         | 
| 2674 2696 | 
             
                    # To do so, we use the DBSCAN clustering algorithm to group the parameters that are close to each other
         | 
| 2675 2697 | 
             
                    # and only keep the set of parameter that has the best Nash-Sutcliffe efficiency per group
         | 
| 2676 2698 | 
             
                    # The parameters that are not grouped are considered had "particular" and are still kept in the final set
         | 
| @@ -2690,7 +2712,7 @@ class Optimisation(wx.Frame): | |
| 2690 2712 | 
             
                        grouped_ind = db.core_sample_indices_
         | 
| 2691 2713 | 
             
                        grouped_params = eff_params[grouped_ind]
         | 
| 2692 2714 | 
             
                        grouped_labels = labels[grouped_ind]
         | 
| 2693 | 
            -
             | 
| 2715 | 
            +
             | 
| 2694 2716 | 
             
                        # Init of the filtered parameters vector
         | 
| 2695 2717 | 
             
                        filtered_params = np.zeros((n_clusters+n_noise, np.shape(eff_params)[1]))
         | 
| 2696 2718 | 
             
                        # Loop to determine the best set of parameter per group
         | 
| @@ -2708,10 +2730,10 @@ class Optimisation(wx.Frame): | |
| 2708 2730 | 
             
                        return filtered_params
         | 
| 2709 2731 |  | 
| 2710 2732 | 
             
                    return eff_params
         | 
| 2711 | 
            -
             | 
| 2733 | 
            +
             | 
| 2712 2734 |  | 
| 2713 2735 | 
             
                # FIXME :  interp function used -> add the method of interpolation as an argument
         | 
| 2714 | 
            -
                def _get_exceedance(self, idLauncher:int=0, stationOut:str="", | 
| 2736 | 
            +
                def _get_exceedance(self, idLauncher:int=0, stationOut:str="",
         | 
| 2715 2737 | 
             
                                     intervals:list[tuple[datetime.datetime, datetime.datetime]]=[]) -> float:
         | 
| 2716 2738 | 
             
                    curCatch:Catchment = self.myCases[idLauncher].refCatchment
         | 
| 2717 2739 | 
             
                    cur_key = curCatch.get_key_catchmentDict(stationOut)
         | 
| @@ -2737,9 +2759,9 @@ class Optimisation(wx.Frame): | |
| 2737 2759 |  | 
| 2738 2760 | 
             
                    return q_diff
         | 
| 2739 2761 |  | 
| 2740 | 
            -
             | 
| 2762 | 
            +
             | 
| 2741 2763 | 
             
                # FIXME :  to improve and generalise
         | 
| 2742 | 
            -
                def _get_cur_fractions(self, idLauncher:int=0, stationOut:str="", | 
| 2764 | 
            +
                def _get_cur_fractions(self, idLauncher:int=0, stationOut:str="",
         | 
| 2743 2765 | 
             
                                     intervals:list[tuple[datetime.datetime, datetime.datetime]]=[]) -> dict[list[str], list[float]]:
         | 
| 2744 2766 | 
             
                    """
         | 
| 2745 2767 | 
             
                    Save the evaluations of the model.
         | 
| @@ -2764,12 +2786,12 @@ class Optimisation(wx.Frame): | |
| 2764 2786 | 
             
                    cur_fracts = curBasin.get_summary_fractions(summary="mean", interval=intervals)
         | 
| 2765 2787 |  | 
| 2766 2788 | 
             
                    return cur_fracts
         | 
| 2767 | 
            -
             | 
| 2789 | 
            +
             | 
| 2768 2790 |  | 
| 2769 2791 | 
             
                # TODO : to finish this function
         | 
| 2770 | 
            -
                def _get_volume_fractions(self, idLauncher:int=0, stationOut:str="", | 
| 2792 | 
            +
                def _get_volume_fractions(self, idLauncher:int=0, stationOut:str="",
         | 
| 2771 2793 | 
             
                                     intervals:list[tuple[datetime.datetime, datetime.datetime]]=[]) -> dict[list[str], list[float]]:
         | 
| 2772 | 
            -
             | 
| 2794 | 
            +
             | 
| 2773 2795 | 
             
                    curCatch:Catchment = self.myCases[idLauncher].refCatchment
         | 
| 2774 2796 | 
             
                    cur_key = curCatch.get_key_catchmentDict(stationOut)
         | 
| 2775 2797 | 
             
                    curBasin: SubBasin = curCatch.catchmentDict[cur_key]
         | 
| @@ -2780,7 +2802,7 @@ class Optimisation(wx.Frame): | |
| 2780 2802 | 
             
                    return cur_fracts
         | 
| 2781 2803 |  | 
| 2782 2804 | 
             
                # FIXME :  to improve and generalise
         | 
| 2783 | 
            -
                def _get_max_runoff(self, idLauncher:int=0, stationOut:str="", | 
| 2805 | 
            +
                def _get_max_runoff(self, idLauncher:int=0, stationOut:str="",
         | 
| 2784 2806 | 
             
                                     intervals:list[tuple[datetime.datetime, datetime.datetime]]=[]) -> dict[list[str], list[float]]:
         | 
| 2785 2807 |  | 
| 2786 2808 | 
             
                    curCatch:Catchment = self.myCases[idLauncher].refCatchment
         | 
| @@ -2789,11 +2811,11 @@ class Optimisation(wx.Frame): | |
| 2789 2811 | 
             
                    cur_fracts = curBasin.get_summary_fractions(summary="max", interval=intervals)
         | 
| 2790 2812 |  | 
| 2791 2813 | 
             
                    return cur_fracts["% qof"]
         | 
| 2792 | 
            -
                
         | 
| 2793 2814 |  | 
| 2794 | 
            -
             | 
| 2815 | 
            +
             | 
| 2816 | 
            +
                def _get_ratio_max_sim_obs(self, idLauncher:int=0, stationOut:str="",
         | 
| 2795 2817 | 
             
                                     intervals:list[tuple[datetime.datetime, datetime.datetime]]=[]) -> float:
         | 
| 2796 | 
            -
             | 
| 2818 | 
            +
             | 
| 2797 2819 | 
             
                    curCatch:Catchment = self.myCases[idLauncher].refCatchment
         | 
| 2798 2820 | 
             
                    cur_key = curCatch.get_key_catchmentDict(stationOut)
         | 
| 2799 2821 | 
             
                    curBasin: SubBasin = curCatch.catchmentDict[cur_key]
         | 
| @@ -2814,9 +2836,9 @@ class Optimisation(wx.Frame): | |
| 2814 2836 | 
             
                    simul = curBasin.outFlow[interv_simul]
         | 
| 2815 2837 | 
             
                    compare = measure.outFlow[interv_meas]
         | 
| 2816 2838 | 
             
                    ratio = np.nanmax(simul)/np.nanmax(compare)
         | 
| 2817 | 
            -
             | 
| 2839 | 
            +
             | 
| 2818 2840 | 
             
                    return ratio
         | 
| 2819 | 
            -
             | 
| 2841 | 
            +
             | 
| 2820 2842 |  | 
| 2821 2843 | 
             
                # Here, we condider that the parameters were already sorted, i.e. model parameters first and Python parameters (<0) after
         | 
| 2822 2844 | 
             
                def get_param_names(self, idLauncher:int=0, stationOut:str=""):
         | 
| @@ -2827,7 +2849,7 @@ class Optimisation(wx.Frame): | |
| 2827 2849 |  | 
| 2828 2850 | 
             
                    calibrate_timeDelay = bool(int(self.optiParam.get_param("Semi-Distributed", "Calibrate_times")))
         | 
| 2829 2851 | 
             
                    if calibrate_timeDelay:
         | 
| 2830 | 
            -
                        # Get_nb inlets | 
| 2852 | 
            +
                        # Get_nb inlets
         | 
| 2831 2853 | 
             
                        inletsNames = self.myCases[idLauncher].refCatchment.get_inletsName(stationOut)
         | 
| 2832 2854 | 
             
                        nbInlets = len(inletsNames)
         | 
| 2833 2855 | 
             
                        for i in range(nbInlets):
         | 
| @@ -2835,7 +2857,7 @@ class Optimisation(wx.Frame): | |
| 2835 2857 |  | 
| 2836 2858 |  | 
| 2837 2859 | 
             
                    return names
         | 
| 2838 | 
            -
             | 
| 2860 | 
            +
             | 
| 2839 2861 | 
             
                # Plot the equifinalty test for each station
         | 
| 2840 2862 | 
             
                def plot_equifinality(self, event, idLauncher:int=0):
         | 
| 2841 2863 |  | 
| @@ -2860,7 +2882,7 @@ class Optimisation(wx.Frame): | |
| 2860 2882 | 
             
                                cur_columns = [col for col in df.columns if cur_prop in col.replace(" ", "")]
         | 
| 2861 2883 | 
             
                                if cur_columns != []:
         | 
| 2862 2884 | 
             
                                    corr_prop = cur_columns[0]
         | 
| 2863 | 
            -
                                    ax.scatter(df.loc[:,corr_prop], df.loc[:,y_label], s=0.5, c=cur_color, | 
| 2885 | 
            +
                                    ax.scatter(df.loc[:,corr_prop], df.loc[:,y_label], s=0.5, c=cur_color,
         | 
| 2864 2886 | 
             
                                               marker='o', label=cur_prop, alpha=0.4)
         | 
| 2865 2887 | 
             
                            ax.set_xlabel("% of the rain [-]")
         | 
| 2866 2888 | 
             
                            ax.set_ylabel(y_label+" [-]")
         | 
| @@ -2873,7 +2895,7 @@ class Optimisation(wx.Frame): | |
| 2873 2895 | 
             
                                cur_columns = [col for col in df.columns if cur_prop.replace(" ", "") in col.replace(" ", "")]
         | 
| 2874 2896 | 
             
                                if cur_columns != []:
         | 
| 2875 2897 | 
             
                                    corr_prop = cur_columns[0]
         | 
| 2876 | 
            -
                                    ax.scatter(df.loc[:,corr_prop], df.loc[:,y_label], s=0.5, c=cur_color, | 
| 2898 | 
            +
                                    ax.scatter(df.loc[:,corr_prop], df.loc[:,y_label], s=0.5, c=cur_color,
         | 
| 2877 2899 | 
             
                                               marker='o', label=cur_prop, alpha=0.4)
         | 
| 2878 2900 | 
             
                            ax.set_xlabel("% of the rain volume [-]")
         | 
| 2879 2901 | 
             
                            ax.set_ylabel(y_label+" [-]")
         | 
| @@ -2913,10 +2935,10 @@ class Optimisation(wx.Frame): | |
| 2913 2935 | 
             
                            fig.savefig(os.path.join(self.workingDir, "Equifinality_max_runoff_"+stationOut+".png"))
         | 
| 2914 2936 | 
             
                        else:
         | 
| 2915 2937 | 
             
                            logging.error("The file "+filename+" does not exist!")
         | 
| 2916 | 
            -
             | 
| 2938 | 
            +
             | 
| 2917 2939 | 
             
                    plt.show()
         | 
| 2918 2940 |  | 
| 2919 | 
            -
             | 
| 2941 | 
            +
             | 
| 2920 2942 | 
             
                def add_Case(self, idLauncher:int=0):
         | 
| 2921 2943 |  | 
| 2922 2944 | 
             
                    i = idLauncher
         | 
| @@ -2948,7 +2970,7 @@ class Optimisation(wx.Frame): | |
| 2948 2970 | 
             
                            curCase = paramMenu.Append(newId, curName, caseMenu)
         | 
| 2949 2971 | 
             
                        else:
         | 
| 2950 2972 | 
             
                            print("WARNING : this scenario was not implemented yet. This might induce an error!")
         | 
| 2951 | 
            -
                            # iItem = | 
| 2973 | 
            +
                            # iItem =
         | 
| 2952 2974 | 
             
                            curCase = paramMenu.Replace(iItem)
         | 
| 2953 2975 | 
             
                    else:
         | 
| 2954 2976 | 
             
                        refDir = newCase.launcherParam.get_param("Calculs","Répertoire simulation de référence")
         | 
| @@ -2960,6 +2982,116 @@ class Optimisation(wx.Frame): | |
| 2960 2982 | 
             
                    self.myCases.append(newCase)
         | 
| 2961 2983 |  | 
| 2962 2984 |  | 
| 2985 | 
            +
                def launch_semi_dist_parameters(self, idLauncher:int=0, idOpti:int=1,
         | 
| 2986 | 
            +
                                                params_to_test:dict[str, np.ndarray]={},
         | 
| 2987 | 
            +
                                                return_outflows:bool=False) -> dict[str, np.ndarray]:
         | 
| 2988 | 
            +
                    # Return variable
         | 
| 2989 | 
            +
                    all_outlets = {}
         | 
| 2990 | 
            +
                    # Useful variables
         | 
| 2991 | 
            +
                    curCatch:Catchment = self.myCases[idLauncher].refCatchment
         | 
| 2992 | 
            +
                    doneList = []
         | 
| 2993 | 
            +
                    previousLevel = 1
         | 
| 2994 | 
            +
                    # Get if the optimisation or the set of parameters is only for 1 subbasin severals
         | 
| 2995 | 
            +
                    onlyOwnSub = self.optiParam.get_param("Semi-Distributed", "Own_SubBasin")
         | 
| 2996 | 
            +
                    if onlyOwnSub is None:
         | 
| 2997 | 
            +
                        onlyOwnSub = False
         | 
| 2998 | 
            +
                    # Collect sort and save the compare stations
         | 
| 2999 | 
            +
                    self.set_compare_stations(idLauncher=idLauncher)
         | 
| 3000 | 
            +
                    sortJct = self.myStations
         | 
| 3001 | 
            +
                    # Get the initial number of intervals
         | 
| 3002 | 
            +
                    # -> these can evolve according to the measurement available at each station
         | 
| 3003 | 
            +
                    is_ok = self._save_opti_intervals()
         | 
| 3004 | 
            +
                    all_intervals = self.all_intervals
         | 
| 3005 | 
            +
                    # Extract the number of time steps to initialise the matrices
         | 
| 3006 | 
            +
                    nb_time_steps = len(curCatch.time)
         | 
| 3007 | 
            +
                    # Loop over all stations to apply the set of parameters
         | 
| 3008 | 
            +
                    for stationOut in sortJct:
         | 
| 3009 | 
            +
                        if not stationOut in list(params_to_test.keys()):
         | 
| 3010 | 
            +
                            continue
         | 
| 3011 | 
            +
                        # Definition of the current subbasin
         | 
| 3012 | 
            +
                        cur_key = curCatch.get_key_catchmentDict(stationOut)
         | 
| 3013 | 
            +
                        curBasin: SubBasin = curCatch.catchmentDict[cur_key]
         | 
| 3014 | 
            +
                        # Extract all the parameters to test
         | 
| 3015 | 
            +
                        all_params = params_to_test[stationOut]
         | 
| 3016 | 
            +
                        logging.info("==================")
         | 
| 3017 | 
            +
                        logging.info("Station : "+stationOut)
         | 
| 3018 | 
            +
                        # Prepare all the file in the hydrology optimisation and simulation directories
         | 
| 3019 | 
            +
                        self._prepare_opti_hydro_files(stationOut=stationOut, idLauncher=idLauncher,
         | 
| 3020 | 
            +
                                                      onlyOwnSub=onlyOwnSub, doneList=doneList, previousLevel=previousLevel)
         | 
| 3021 | 
            +
                        # Select correct calibration intervals -> remove the intervals with NaN
         | 
| 3022 | 
            +
                        cur_intervals = self.select_opti_intervals(all_intervals=all_intervals, stationOut=stationOut, filter_nan=True)
         | 
| 3023 | 
            +
                        self.save_opti_dates_to_file(cur_intervals)
         | 
| 3024 | 
            +
                        ## ===================================================================================================================
         | 
| 3025 | 
            +
                        ## Init
         | 
| 3026 | 
            +
                        ## ===================================================================================================================
         | 
| 3027 | 
            +
                        self.init_optimizer(idOpti)
         | 
| 3028 | 
            +
                        self.associate_ptr(None, idOpti=idOpti)
         | 
| 3029 | 
            +
                        ## ===================================================================================================================
         | 
| 3030 | 
            +
                        ## Compute
         | 
| 3031 | 
            +
                        ## ===================================================================================================================
         | 
| 3032 | 
            +
                        all_outlets[stationOut] = np.zeros((len(all_params), nb_time_steps))
         | 
| 3033 | 
            +
                        for i in range(len(all_params)):
         | 
| 3034 | 
            +
                            cur_p = all_params[i, :-1]
         | 
| 3035 | 
            +
                            cur_obj2 = self.evaluate_model_optimizer(cur_p, idOpti=idOpti)
         | 
| 3036 | 
            +
                            all_outlets[stationOut][i,:] = curBasin.outFlow
         | 
| 3037 | 
            +
                            # Small test
         | 
| 3038 | 
            +
                            cur_obj = all_params[i, -1]
         | 
| 3039 | 
            +
                            print("cur_obj : ", cur_obj, " ; cur_obj2 : ", cur_obj2)
         | 
| 3040 | 
            +
                            if cur_obj != cur_obj2:
         | 
| 3041 | 
            +
                                logging.error("The objective function is not the same as the one computed by the model!")
         | 
| 3042 | 
            +
                                logging.error("cur_obj : "+str(cur_obj)+" ; cur_obj2 : "+str(cur_obj2))
         | 
| 3043 | 
            +
                        ## ===================================================================================================================
         | 
| 3044 | 
            +
                        ## ===================================================================================================================
         | 
| 3045 | 
            +
                        # Collect the best parameters and their objective function(s)
         | 
| 3046 | 
            +
                        best_params = self.apply_optim(None)
         | 
| 3047 | 
            +
                        # Simulation with the best parameters
         | 
| 3048 | 
            +
                        self.compute_distributed_hydro_model()
         | 
| 3049 | 
            +
                        # Update myHydro of all effective subbasins to get the best configuration upstream
         | 
| 3050 | 
            +
                        curCatch.read_hydro_eff_subBasin()
         | 
| 3051 | 
            +
                        # Update timeDelays according to time wolf_array
         | 
| 3052 | 
            +
                        self.apply_timeDelay_dist(idOpti=idOpti, idLauncher=idLauncher, junctionKey=stationOut)
         | 
| 3053 | 
            +
                        # Update the outflows
         | 
| 3054 | 
            +
                        curCatch.update_hydro(idCompar=0)
         | 
| 3055 | 
            +
             | 
| 3056 | 
            +
                        # All upstream elements of a reference will be fixed
         | 
| 3057 | 
            +
                        doneList.append(stationOut)
         | 
| 3058 | 
            +
                        previousLevel = curCatch.levelOut
         | 
| 3059 | 
            +
             | 
| 3060 | 
            +
                    logging.info("All the parameters have been tested!")
         | 
| 3061 | 
            +
                    if return_outflows:
         | 
| 3062 | 
            +
                        return all_outlets
         | 
| 3063 | 
            +
             | 
| 3064 | 
            +
             | 
| 3065 | 
            +
                def _prepare_opti_hydro_files(self, stationOut:str, idLauncher:int=0, onlyOwnSub:bool=False,
         | 
| 3066 | 
            +
                                             doneList:list[str]=[], previousLevel:int=1):
         | 
| 3067 | 
            +
                    # Useful variables
         | 
| 3068 | 
            +
                    curCatch:Catchment = self.myCases[idLauncher].refCatchment
         | 
| 3069 | 
            +
             | 
| 3070 | 
            +
                    # Build the current compare.txt file and replace all nan values by 0.0
         | 
| 3071 | 
            +
                    self.save_current_compare_file(stationOut=stationOut)
         | 
| 3072 | 
            +
                    # Save the name of the station that will be the output
         | 
| 3073 | 
            +
                    curCatch.define_station_out(stationOut)
         | 
| 3074 | 
            +
                    # Activate all the useful subs and write it in the param file
         | 
| 3075 | 
            +
                    curCatch.activate_usefulSubs(blockJunction=doneList, onlyItself=onlyOwnSub)
         | 
| 3076 | 
            +
                    # Rename the result file
         | 
| 3077 | 
            +
                    self.optiParam.change_param("Optimizer", "fname", stationOut)
         | 
| 3078 | 
            +
                    self.optiParam.SavetoFile(None)
         | 
| 3079 | 
            +
                    self.optiParam.Reload(None)
         | 
| 3080 | 
            +
                    self.update_myParams(idLauncher)
         | 
| 3081 | 
            +
                    # Prepare the paramPy dictionnary before calibration
         | 
| 3082 | 
            +
                    self.prepare_calibration_timeDelay(stationOut=stationOut)
         | 
| 3083 | 
            +
                    # Reload the useful modules
         | 
| 3084 | 
            +
                    self.reload_hydro(idCompar=0, fromStation=stationOut, lastLevel=previousLevel, updateAll=True)
         | 
| 3085 | 
            +
             | 
| 3086 | 
            +
             | 
| 3087 | 
            +
             | 
| 3088 | 
            +
                def write_one_opti_param(self, filPath:Path, fileName:Path, myGroup:str, myKey:str, value:float, convers_factor:int=1.0):
         | 
| 3089 | 
            +
                    tmpWolf = Wolf_Param(to_read=True, filename=os.path.join(filPath,fileName),toShow=False, init_GUI=False)
         | 
| 3090 | 
            +
                    tmpWolf.change_param(myGroup, myKey, value/convers_factor)
         | 
| 3091 | 
            +
                    tmpWolf.SavetoFile(None)
         | 
| 3092 | 
            +
                    # tmpWolf.OnClose(None)
         | 
| 3093 | 
            +
                    tmpWolf = None
         | 
| 3094 | 
            +
             | 
| 2963 3095 |  | 
| 2964 3096 | 
             
                def make_nd_array(self, c_pointer, shape, dtype=np.float64, order='C', own_data=True,readonly=False):
         | 
| 2965 3097 | 
             
                    arr_size = np.prod(shape[:]) * np.dtype(dtype).itemsize
         | 
| @@ -2977,4 +3109,3 @@ class Optimisation(wx.Frame): | |
| 2977 3109 | 
             
                        return arr.copy()
         | 
| 2978 3110 | 
             
                    else:
         | 
| 2979 3111 | 
             
                        return arr
         | 
| 2980 | 
            -
             |