From: Eric Fayolle Date: Mon, 10 Oct 2022 14:16:34 +0000 (+0200) Subject: Mise en place des résultats sous forme panda + csv (taylor et MC) X-Git-Tag: merge_uncertainty_odysee_1210~3 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=c76c30881a2c8415a5e66fc388f4671a578932a2;p=tools%2Feficas.git Mise en place des résultats sous forme panda + csv (taylor et MC) --- diff --git a/generator/generator_UQ.py b/generator/generator_UQ.py index 03a7b6c3..69200c5f 100644 --- a/generator/generator_UQ.py +++ b/generator/generator_UQ.py @@ -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 ) - - - diff --git a/generator/textePersalys.py b/generator/textePersalys.py index d047c782..e1e698b8 100644 --- a/generator/textePersalys.py +++ b/generator/textePersalys.py @@ -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__":