]> SALOME platform Git repositories - tools/eficas.git/commitdiff
Salome HOME
Mise en place des résultats sous forme panda + csv (taylor et MC)
authorEric Fayolle <eric.fayolle@edf.fr>
Mon, 10 Oct 2022 14:16:34 +0000 (16:16 +0200)
committerEric Fayolle <eric.fayolle@edf.fr>
Mon, 10 Oct 2022 14:16:34 +0000 (16:16 +0200)
generator/generator_UQ.py
generator/textePersalys.py

index 03a7b6c3127cd02b9f0586020f7768a52a4d680d..69200c5ff6ac1389e8a744c3c8a4c2711c8a92ab 100644 (file)
@@ -41,7 +41,7 @@ from .textePersalys import optionalResultTaylor, optionalPrintResultTaylor
 from .textePersalys import centralTendencyMC, resultMC
 from .textePersalys import critereArretMC, advancedParameterMC
 from .textePersalys import optionalResultMC, optionalPrintResultMC
-from .textePersalys import printResult
+from .textePersalys import printResultMC, printResultTaylor
 from .textePersalys import yacsJobParameters, yacsJobClusterParameters, yacsJobClusterMultiJob
 
 def entryPoint():
@@ -162,6 +162,12 @@ class UQGenerator(PythonGenerator):
         from  functools import reduce as reduce
 
         self.txtScriptPersalys = ''
+        etapeScenarioData=self.jdc.getEtapesByName('Scenario_data')
+        if etapeScenarioData == [] : return(0, 'il faut au moins un mot-clef Scenario_data')    #TODO : à Résorber après modification du catalogue
+        if len(etapeScenarioData) !=1 : return(0, 'il faut au plus un mot-clef  Scenario_data')  #TODO : à Résorber après modification du catalogue
+        etapeScenarioData = etapeScenarioData[0]
+        self.ScenarioType = etapeScenarioData.getChildOrChildInBloc('scenario_type').valeur
+        
         etapeIncertitude=self.jdc.getEtapesByName('ExpressionIncertitude')
         if etapeIncertitude == [] : return(0, 'il faut au moins un mot-clef ExpressionIncertitude')
         if len(etapeIncertitude) !=1 : return(0, 'il faut au plus un mot-clef  ExpressionIncertitude')
@@ -180,6 +186,7 @@ class UQGenerator(PythonGenerator):
                 self.chaineDesVariablesInput+=mc.variableDeterministe.nom + ', '
                 self.nomsDesVariablesInput.append(mc.variableDeterministe.nom)
             self.mcIncertains.append(mc.variableDeterministe)
+            
         sectionOutput = etapeIncertitude.getChildOrChildInBloc('Output')[0]
         self.ScriptPosttraitement = sectionOutput.getChildOrChildInBloc('ScriptPosttraitement').valeur
         self.chaineDesVariablesInput=self.chaineDesVariablesInput[0:-2]
@@ -190,9 +197,6 @@ class UQGenerator(PythonGenerator):
         else : self.Result = sectionPropagation.getChildOrChildInBloc('Result')[0]
         if (self.Methode == 'MonteCarlo'):
             self.critereArret = sectionPropagation.getChildOrChildInBloc('CritereArret')[0]
-            # self.SimulationsNumber  = self.critereArret.getChildOrChildInBloc('SimulationsNumber')[0]
-            # self.MaximumElapsedTime  = self.critereArret.getChildOrChildInBloc('MaximumElapsedTime')[0]
-            # self.Accuracy  = self.critereArret.getChildOrChildInBloc('Accuracy')[0]
             sectionEvaluationParameter = sectionPropagation.getChildOrChildInBloc('EvaluationParameter')[0]
             self.Blocksize = sectionEvaluationParameter.getChildOrChildInBloc('BlockSize').valeur
             self.advancedParameter = sectionPropagation.getChildOrChildInBloc('AdvancedParameter')
@@ -206,7 +210,7 @@ class UQGenerator(PythonGenerator):
         self.chaineDesVariablesOutputEncodee=''
         #listeDesVariablesOutput=[]
         self.txtOutputVariableInitList=''
-        self.txtGetAllResults = ""
+        self.txtGetAllResults = ''
         #TODO? from cata_UQ import FonctionDAggregationDict
         fctAggPy={
             'valeur à t=O':'vInitialTime',
@@ -225,7 +229,7 @@ class UQGenerator(PythonGenerator):
             nomFctAggPyList=''
             nomOutputList=''
             nomVar  =  mc.getChildOrChildInBloc('VariablePhysique').valeur
-            nomVarEncode = nomVar.replace(' ','__')
+            nomVarEncode = nomVar.replace(' ','__') #TODO : function
             nomVarPostraite =  mc.getChildOrChildInBloc('VariablePosttraiteeAssociee').valeur
             nomFctAggList = mc.getChildOrChildInBloc('FonctionDAggregation').valeur
             for nomFctAgg in nomFctAggList:
@@ -276,23 +280,49 @@ class UQGenerator(PythonGenerator):
           #else : 
           # TODO : creer ici le script URANIE
         return (1, '')
-        # listeDesVariables, nomDesVariables, dicoDesVariables)
 
-    def creeTexteInputVariables(self,indent):
-        texte=''
-        for v in self.lesVariablesInput :
-           if v.variableDeterministe.etape.nature == 'OPERATEUR' :
-               nomVariableInput=v.variableDeterministe.etape.sd.nom +'__' + v.variableDeterministe.nom
+    # def creeTexteInputVariables(self,indent):
+    #     texte=''
+    #     for v in self.lesVariablesInput :
+    #        if v.variableDeterministe.etape.nature == 'OPERATEUR' :
+    #            nomVariableInput=v.variableDeterministe.etape.sd.nom +'__' + v.variableDeterministe.nom
+    #        else :
+    #            nomVariableInput=v.variableDeterministe.nom
+    #        loiDistribution =  v.getChildOrChildInBloc('Distribution').valeur
+    #        # on cherche le bloc qui contient ce qui est necessaire a la loi
+    #        # on est confiant !!!! sur l adequation du catalogue et des attributs des lois persalys
+    #        # reflechir a cela
+    #        texte+="{}{} = persalys.Input('{}', ot.{}(".format(indent,nomVariableInput,nomVariableInput,loiDistribution)
+    #        chaineArgs=''
+    #        leBlocDesArgs=None
+    #        for mc in v.mcListe :
+    #            if (mc.nom).find('b_Model_Variable_') == 0 :
+    #               for mcFils in mc.mcListe :
+    #                   if mcFils.nom.find(loiDistribution) > 1: 
+    #                       leBlocDesArgs=mcFils 
+    #                       break
+    #        if not leBlocDesArgs :
+    #           print ('souci pour dumper la loi')
+    #           return ''
+    #        for  mcFils in leBlocDesArgs.mcListe :
+    #              chaineArgs+=str(mcFils.valeur) +', '
+    #        texte+=chaineArgs[0:-2]+'))\n'
+    #     return texte
+
+    def parseMcInputVariable(self,mc,indent):
+        
+           if mc.variableDeterministe.etape.nature == 'OPERATEUR' :
+               nom=mc.variableDeterministe.etape.sd.nom +'__' + mc.variableDeterministe.nom
            else :
-               nomVariableInput=v.variableDeterministe.nom
-           loiDistribution =  v.getChildOrChildInBloc('Distribution').valeur
+               nom=mc.variableDeterministe.nom
+           loiDistribution =  mc.getChildOrChildInBloc('Distribution').valeur
+           
            # on cherche le bloc qui contient ce qui est necessaire a la loi
            # on est confiant !!!! sur l adequation du catalogue et des attributs des lois persalys
            # reflechir a cela
-           texte+="{}{} = persalys.Input('{}', ot.{}(".format(indent,nomVariableInput,nomVariableInput,loiDistribution)
            chaineArgs=''
            leBlocDesArgs=None
-           for mc in v.mcListe :
+           for mc in mc.mcListe :
                if (mc.nom).find('b_Model_Variable_') == 0 :
                   for mcFils in mc.mcListe :
                       if mcFils.nom.find(loiDistribution) > 1: 
@@ -303,24 +333,50 @@ class UQGenerator(PythonGenerator):
               return ''
            for  mcFils in leBlocDesArgs.mcListe :
                  chaineArgs+=str(mcFils.valeur) +', '
-           texte+=chaineArgs[0:-2]+'))\n'
+
+           return nom,loiDistribution,chaineArgs[0:-2]
+
+    def creeTexteInputVariables(self,indent):
+            
+        texte=''
+        for v in self.lesVariablesInput :
+           nomVariableInput,loiDistribution,chaineArgs = self.parseMcInputVariable(v,indent)
+           texte+="{}{} = persalys.Input('{}', ot.{}(".format(indent,nomVariableInput,nomVariableInput,loiDistribution)
+           texte+=chaineArgs+'))\n'
+           
         return texte
 
+    def creeTexteInputVariablesSummary(self,indent):
+            
+        texte=''
+        for v in self.lesVariablesInput :
+           nomVariableInput,loiDistribution,chaineArgs = self.parseMcInputVariable(v,indent)
+           texte+="{}'{}{} : {}({})\\n'\n".format(2*indent, indent, nomVariableInput, loiDistribution,chaineArgs)
+           #texte+=chaineArgs[0:-2]+'))\n'
+           #texte+='\n'
+       
+        return texte[0:-1]
+
     def creeScriptPersalys(self, debug=True) :
         from functools import reduce
 
         # chaineDesVariablesInput=reduce(lambda x,y:x+','+y,l)
         def getStrVarList(l,sep=','):
             return reduce(lambda x,y:str(x)+sep+str(y), l)
+        
         def getStrVarStrList(l,sep=','):
-            return reduce(lambda x,y:"'"+str(x)+"'"+sep+"'"+str(y)+"'", l)
+            return reduce(lambda x,y:x+sep+y, 
+                          map(lambda x:"'"+str(x)+"'",l) )
+        
         def getStrInitList(l):
             return getStrVarList( map(lambda x:'self.{} = {}'.format(x,x),l), '\n'+2*self.indent1 )
+        
         def getStrReplaceVarList(l):
             return getStrVarList( map(lambda x:"'@ {} @': repr(self.{})".format(x,x), l), ',' )
+        
         def getStrSelfVarList(l):
             return getStrVarList( map(lambda x:'self.{}'.format(x),l), ',' )
-        
+                
         generatorDir = os.path.abspath(os.path.dirname(__file__))
         nomEtude = "monEtude" #TODO
         if debug : print ('nomEtude : ', nomEtude, 'generatorDir :', generatorDir)
@@ -361,6 +417,7 @@ class UQGenerator(PythonGenerator):
             txtCentralTendencyPersalys = centralTendencyTaylor
             optionalResult = optionalResultTaylor
             optionalPrintResult = optionalPrintResultTaylor
+            printResult = printResultTaylor
             txtResultCT = resultTaylor
         elif (self.Methode == 'MonteCarlo' ):
             critereArret = ""
@@ -380,6 +437,7 @@ class UQGenerator(PythonGenerator):
             )
             optionalResult = optionalResultMC
             optionalPrintResult = optionalPrintResultMC
+            printResult = printResultMC
             txtResultCT = resultMC
         else :
             return(0, "Impossible de gérer la méthode :",self.Methode)
@@ -414,7 +472,8 @@ class UQGenerator(PythonGenerator):
         txtPrintResult=printResult.format(
             optionalResultList = optionalResultList,
             optionalResultStrList = optionalResultStrList,
-            resultSkList = getStrVarList(self.resultSkList))
+            resultSkList = getStrVarList(self.resultSkList),
+            Uncertain_inputs = self.creeTexteInputVariablesSummary(self.indent1) )
         txtResult= txtResultCT.format( optionalResult=result )
         txtResult+=txtPrintResult
 
@@ -467,8 +526,6 @@ class UQGenerator(PythonGenerator):
             chaineDesVariablesOutput = self.chaineDesVariablesOutputEncodee,
             yacsJobParameters = txtYacsJobParameters,
             centralTendencyPersalys = txtCentralTendencyPersalys,
+            scenarioType = self.ScenarioType,
             resultPersalys = txtResult
         )
-
-
-
index d047c78213126a3af0235332b72ddf3564f03708..e1e698b891b37f04ed300b9b3305b8fd178e8148 100644 (file)
@@ -186,6 +186,8 @@ mainPersalys="""
 # ------------------
 if __name__ == '__main__':
 
+    from datetime import datetime
+
     {nomEtude} = persalys.Study('{nomEtude}')
     persalys.Study.Add({nomEtude})
 
@@ -194,9 +196,11 @@ if __name__ == '__main__':
 
 {inputHeaderPersalys}
     inputs = [{chaineDesVariablesInput}]
+    nInputs = len(inputs)
 
 {outputHeaderPersalys}
     outputs = [{chaineDesVariablesOutput}]
+    nOutputs = len(outputs)
 
     yacsPhysicalModel = persalys.YACSPhysicalModel('PhysicalModel', inputs, outputs, code)
 {yacsJobParameters}
@@ -207,6 +211,8 @@ if __name__ == '__main__':
 
 ################ CUT THE FILE HERE IF YOU WANT TO IMPORT IT IN THE SALOME PERSALYS MODULE ################
 
+    head_study = str(datetime.now()) +" {scenarioType} "+""
+
     centralTendency.run()
 {resultPersalys}
 
@@ -217,10 +223,53 @@ if __name__ == '__main__':
 #    inputs = [a, b]
 #    outputs = [d]
 
-printResult="""    import numpy as np
+# empiricalMean = ot.Sample(result.getMean())[nInputs:]
+# empiricalStandardDeviation = ot.Sample(result.getStandardDeviation())[nInputs:]
+# resultNp.reshape(nbindex,nbsorties)
+
+printResultMC="""    import numpy as np
+    from post_csv_rn import write_result_from_persalys
+
+    #Noms de lignes
+    #index = ['meanFirstOrder', 'meanSecondOrderOrder', 'standardDeviationFirstOrder' ]
+    indexNp = [ {optionalResultStrList} ]
+    nResult = len(indexNp)
+
+    #resultNp = np.array([meanFirstOrder, meanSecondOrderOrder, standardDeviationFirstOrder ])
+    #Lignes de résultats demandés pour toutes les fcts d'aggrégation en colonne
+    resultNp = np.array([ {optionalResultList} ])
+    resultNp = resultNp.reshape(nResult, nOutputs)  #En MC à cause du ot.Sample( PointsCollection) il y a un niveau de liste en trop
+
+    #Tableau skyline localisant les variables (hors fctAgg) dans le tableau de résultat global  
+    # ex pour deux variables et respectivement 7 et 3 fcts aggrégation :  resultSk = [0,7,10]
+    #nOutVar = len(resSk)-1
+    resSk = [ {resultSkList} ]
+
+    print('\\n\\n')
+    print('*********************************************************************************\\n')
+    print('                   UNCERTAINTY QUANTIFICATION RESULTS\\n')
+   
+    print(head_study,'\\n')
+
+    print('Uncertain inputs list :','\\n')
+    print(
+{Uncertain_inputs}'\\n'
+    )
+    print('\\nElapsed Time : ', centralTendency.getElapsedTime(),'\\n') #Monte Carlo ou Taylor
+
+    print('\\nDesign of Experiment :')
+    print(result.getDesignOfExperiment().getInputSample(),'\\n') #TODO: générer un fichier csv
+
+    print('\\nCoefficient of Variation :')
+    print(ot.Sample(result.getCoefficientOfVariation())[nInputs:],'\\n') #TODO: générer un fichier csv
+    write_result_from_persalys(resultNp, indexNp, resSk, outputs)
+
+    print('\\n*********************************************************************************\\n')
+"""
+
+
+printResultTaylor="""    import numpy as np
     from post_csv_rn import write_result_from_persalys
-    # import pandas as pnd
-    # from functools import reduce
 
     #resultNp = np.array([meanFirstOrder, meanSecondOrderOrder, standardDeviationFirstOrder ])
     #Lignes de résultats demandés pour toutes les fcts d'aggrégation en colonne
@@ -228,41 +277,35 @@ printResult="""    import numpy as np
 
     #Noms de lignes
     #index = ['meanFirstOrder', 'meanSecondOrderOrder', 'standardDeviationFirstOrder' ]
+    #nResult = len(indexNp)
     indexNp = [ {optionalResultStrList} ]
 
-    #nResult = len(indexNp)
 
     #Tableau skyline localisant les variables (hors fctAgg) dans le tableau de résultat global  
-    #resultSk = [0,7,10]
+    # ex pour deux variables et respectivement 7 et 3 fcts aggrégation :  resultSk = [0,7,10]
+    #nOutVar = len(resSk)-1
     resSk = [ {resultSkList} ]
 
-    #nOutVar = len(resSk)-1
+    print('\\n\\n')
+    print('*********************************************************************************\\n')
+    print('                   UNCERTAINTY QUANTIFICATION RESULTS\\n')
+   
+    print(head_study,'\\n')
 
-    write_result_from_persalys(resultNp, indexNp, resSk, outputs)
+    print('Uncertain inputs list :','\\n')
+    print(
+{Uncertain_inputs}'\\n'
+    )
+    print('\\nElapsed Time : ', centralTendency.getElapsedTime(),'\\n') #Monte Carlo ou Taylor
 
-    # print('\\n')
-    # for i in range(nOutVar):
-    #     # Récupère les couples (fctAggrégation,Nom de variable ss fct Agg)
-    #     #  des champs de description des sorties.
-    #     #  Les sorties concernées proviennent de la section de résultatNp
-    #     #  qui doit correspondre à une même variable hors fct Agg
-    #     fctAgg_outVarName = list( map(lambda o: eval(o.getDescription()),
-    #                                   outputs[resSk[i]:resSk[i+1]]) )
-    #     outVarName        = fctAgg_outVarName[0][1]
-    #     checkOutVarName   = reduce( lambda n1,n2: n1 == n2,
-    #                                 [True]+list( map(lambda o: o[1] == outVarName,
-    #                                           fctAgg_outVarName) ) )
-    #     assert(checkOutVarName == True)
-    #     print(outVarName)
-    #     columns  = list(map(lambda o1: o1[0], fctAgg_outVarName) )
-    #     resultDf = pnd.DataFrame(resultNp[:,resSk[i]:(resSk[i+1])],
-    #                             index = indexNp,
-    #                             columns = columns )
-    #     print(resultDf,'\\n')
-    #     #name_csv = str.replace(str.replace(outVarName,"@","_"),' ','-')
-    #     name_csv = outVarName
-    #     resultDf.to_csv(name_csv+'-uncertainty.csv')
+    # print('\\nDesign of Experiment :')
+    # print(result.getDesignOfExperiment().getInputSample(),'\\n') #TODO: Activer uniquement en MC + fichier csv
 
+    # print('\\nCoefficient of Variation :')
+    # print(result.getCoefficientOfVariation(),'\\n') #TODO: Activer uniquement en MC + fichier csv
+    write_result_from_persalys(resultNp, indexNp, resSk, outputs)
+
+    print('\\n*********************************************************************************\\n')
 """
 
 ## Tendance Centrale Taylor 
@@ -305,7 +348,7 @@ critereArretMC = {
 }
 
 advancedParameterMC = {
-    'Seed' : 'centralTendency.setSeed({Seed})',
+    'Seed' : 'centralTendency.setSeed({Seed})', #TODO : A ajouter dans le catalogue
     'ComputeConfidenceIntervalAt' : 'centralTendency.setLevelConfidenceInterval({ComputeConfidenceIntervalAt})'
 }
 
@@ -316,9 +359,9 @@ resultMC="""
 """
 
 optionalResultMC={
-    'EmpiricalMean' : 'empiricalMean = result.getMean()', #TOCHECK
-    'Variance' : 'variance = result.getVariance()',
-    'EmpiricalStandardDeviation' : 'empiricalStandardDeviation = result.getStandardDeviation()',  #TOCHECK
+    'EmpiricalMean' : 'empiricalMean = ot.Sample(result.getMean())[nInputs:]', #En MC les inputs apparaissent en début de résultat !
+    'Variance' : 'variance = ot.Sample(result.getVariance())[nInputs:]',              # et on utilise ot.Sample pour accéder aux valeurs des Points
+    'EmpiricalStandardDeviation' : 'empiricalStandardDeviation = ot.Sample(result.getStandardDeviation())[nInputs:]',  #Idem.
     'EmpiricalQuantile' : """
     designOfExperiment=result.getDesignOfExperiment()
     outputSample=designOfExperiment.getOutputSample()
@@ -346,6 +389,8 @@ optionalPrintResultMC={
 
 
 #En local le nombre de procs est inutile
+#TODO: S'il on peut récupérer les fichiers .csv des tirages,
+#            il faut ajouter une ligne out_files
 yacsJobParameters="""
     yacsPhysicalModel.jobParameters().salome_parameters.resource_required.name = '{resourceName}'
     yacsPhysicalModel.jobParameters().salome_parameters.job_name = '{nomEtude}'
@@ -371,24 +416,24 @@ multiJobModel = pydefx.MultiJobStudy() # mode un job par évaluation
 yacsPhysicalModel.setJobModel(multiJobModel)
 """
 
-yacsJobParametersRef="""
-yacsPhysicalModel.jobParameters().salome_parameters.job_name = '{nomEtude}_idefix_job'
-yacsPhysicalModel.jobParameters().salome_parameters.work_directory = '/scratch/C65845/workingdir/persalys_light'
-yacsPhysicalModel.jobParameters().salome_parameters.result_directory = '/tmp/local_result'
-yacsPhysicalModel.jobParameters().salome_parameters.resource_required.name = 'gaia'
-yacsPhysicalModel.jobParameters().salome_parameters.resource_required.nb_proc = 1
-yacsPhysicalModel.jobParameters().salome_parameters.wckey = 'P11N0:SALOME'
-yacsPhysicalModel.jobParameters().salome_parameters.in_files = [] # Chemins des fichiers locaux à copier dans work_directory
-yacsPhysicalModel.jobParameters().nb_branches = 3 # nombre de jobs parallèles
-
-# Ces 4 lignes permettent de modifier le mode d'évaluation par défaut qui est
-# d'avoir toutes les évaluations dans un seul job.
-import pydefx
-import os
-myModel = pydefx.MultiJobStudy() # mode un job par évaluation
-
-PhysicalModel.setJobModel(myModel)
-"""
+yacsJobParametersRef="""
+yacsPhysicalModel.jobParameters().salome_parameters.job_name = '{nomEtude}_idefix_job'
+yacsPhysicalModel.jobParameters().salome_parameters.work_directory = '/scratch/C65845/workingdir/persalys_light'
+yacsPhysicalModel.jobParameters().salome_parameters.result_directory = '/tmp/local_result'
+yacsPhysicalModel.jobParameters().salome_parameters.resource_required.name = 'gaia'
+yacsPhysicalModel.jobParameters().salome_parameters.resource_required.nb_proc = 1
+yacsPhysicalModel.jobParameters().salome_parameters.wckey = 'P11N0:SALOME'
+yacsPhysicalModel.jobParameters().salome_parameters.in_files = [] # Chemins des fichiers locaux à copier dans work_directory
+yacsPhysicalModel.jobParameters().nb_branches = 3 # nombre de jobs parallèles
+
+# Ces 4 lignes permettent de modifier le mode d'évaluation par défaut qui est
+# d'avoir toutes les évaluations dans un seul job.
+import pydefx
+import os
+myModel = pydefx.MultiJobStudy() # mode un job par évaluation
+
+PhysicalModel.setJobModel(myModel)
+"""
 
 
 if __name__ == "__main__":