Salome HOME
Default behavior improvement for UserPostAnalysis
[modules/adao.git] / bin / AdaoCatalogGenerator.py
1 #-*-coding:iso-8859-1-*-
2 #
3 # Copyright (C) 2008-2014 EDF R&D
4 #
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License.
9 #
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # Lesser General Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 #
19 # Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
20
21 import logging
22 import traceback
23 import sys
24 import string
25 import StringIO
26
27 import module_version
28
29 logging.basicConfig(level=logging.WARNING)
30
31 #----------- Templates Part ---------------#
32 begin_catalog_file = """# -*- coding: utf-8 -*-
33
34 # --------------------------------------------------------
35 # generated by AdaoCatalogGenerator at ${date}
36 # --------------------------------------------------------
37
38 import Accas
39 from Accas import *
40
41 JdC = JDC_CATA (code = '%s',
42                 execmodul = None,
43                 regles = ( AU_MOINS_UN ('ASSIMILATION_STUDY','CHECKING_STUDY'), AU_PLUS_UN ('ASSIMILATION_STUDY','CHECKING_STUDY')),
44                )
45 VERSION_CATALOGUE='%s'
46 """%(module_version.name,module_version.version)
47
48 data_method = """
49 def F_${data_name}(statut) : return FACT(statut = statut,
50                                          FROM = SIMP(statut = "o", typ = "TXM", into=(${data_into}), defaut=${data_default}),
51                                          SCRIPT_DATA = BLOC ( condition = " FROM in ( 'Script', ) ",
52
53                                                       SCRIPT_FILE = SIMP(statut = "o", typ = "FichierNoAbs", validators=(OnlyStr()), fr="En attente d'un nom de fichier script, avec ou sans le chemin complet pour le trouver, contenant si nécessaire la définition d'une variable interne de même nom que le concept parent", ang="Waiting for a script file name, with or without the full path to find it, containing if necessary the definition of an internal variable of the same name as the parent concept"),
54                                                      ),
55                                          STRING_DATA = BLOC ( condition = " FROM in ( 'String', ) ",
56
57                                                       STRING = SIMP(statut = "o", typ = "TXM", fr="En attente d'une chaine de caractères entre guillements. Pour construire un vecteur ou une matrice, ce doit être une suite de nombres, utilisant un espace ou une virgule pour séparer deux éléments et un point-virgule pour séparer deux lignes", ang="Waiting for a string in quotes. To build a vector or a matrix, it has to be a float serie, using a space or comma to separate two elements in a line, a semi-colon to separate rows"),
58                                                      ),
59                                          SCRIPTWITHFUNCTIONS_DATA = BLOC ( condition = " FROM in ( 'ScriptWithFunctions', ) ",
60
61                                                       SCRIPTWITHFUNCTIONS_FILE = SIMP(statut = "o", typ = "FichierNoAbs", validators=(OnlyStr()), fr="En attente d'un nom de fichier script, avec ou sans le chemin complet pour le trouver, contenant en variables internes trois fonctions de calcul nommées DirectOperator, TangentOperator et AdjointOperator", ang="Waiting for a script file name, with or without the full path to find it, containing as internal variables three computation functions named DirectOperator, TangentOperator and AdjointOperator"),
62                                                      ),
63                                          SCRIPTWITHONEFUNCTION_DATA = BLOC ( condition = " FROM in ( 'ScriptWithOneFunction', ) ",
64
65                                                       SCRIPTWITHONEFUNCTION_FILE = SIMP(statut = "o", typ = "FichierNoAbs", validators=(OnlyStr()), fr="En attente d'un nom de fichier script, avec ou sans le chemin complet pour le trouver, contenant en variable interne une seule fonction de calcul nommée DirectOperator", ang="Waiting for a script file name, with or without the full path to find it, containing as internal variable only one function named DirectOperator"),
66                                                       DifferentialIncrement = SIMP(statut="o", typ = "R", val_min=0, val_max=1, defaut=0.01, fr="Incrément de la perturbation dX pour calculer la dérivée, construite en multipliant X par l'incrément en évitant les valeurs nulles", ang="Increment of dX perturbation to calculate the derivative, build multiplying X by the increment avoiding null values"),
67                                                       CenteredFiniteDifference = SIMP(statut="o", typ = "I", into=(0, 1), defaut=0, fr="Formulation centrée (1) ou décentrée (0) pour la méthode des différences finies", ang="Centered (1) or uncentered (0) formulation for the finite differences method"),
68                                                       EnableMultiProcessing = SIMP(statut="f", typ = "I", into=(0, 1), defaut=0, fr="EXPERIMENTAL : Calculs élémentaires effectués en séquentiel (0) ou en parallèle (1) dans la méthode des différences finies", ang="EXPERIMENTAL: Elementary calculations done sequentially (0) or in parallel (1) in the finite differences method"),
69                                                      ),
70                                          SCRIPTWITHSWITCH_DATA = BLOC ( condition = " FROM in ( 'ScriptWithSwitch', ) ",
71
72                                                       SCRIPTWITHSWITCH_FILE = SIMP(statut = "o", typ = "FichierNoAbs", validators=(OnlyStr()), fr="En attente d'un nom de fichier script, avec ou sans le chemin complet pour le trouver, contenant un switch pour les calculs direct, tangent et adjoint", ang="Waiting for a script file name, with or without the full path to find it, containing a switch for direct, tangent and adjoint computations"),
73                                                      ),
74                                          FUNCTIONDICT_DATA = BLOC ( condition = " FROM in ( 'FunctionDict', ) ",
75
76                                                       FUNCTIONDICT_FILE = SIMP(statut = "o", typ = "FichierNoAbs", validators=(OnlyStr()), fr="OBSOLETE : conservé pour compatibilité avec la version 6.5, sera supprimé dans le futur", ang="OBSOLETE: keeped for compatibility with the 6.5 version, will be removed in the future"),
77                                                      ),
78                                          TEMPLATE_DATA =  BLOC (condition = " FROM in ( 'Template', ) ",
79                                              Template = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "AnalysisPrinter", into=("AnalysisPrinter", "AnalysisSaver", "AnalysisPrinterAndSaver")),
80                                              AnalysisPrinter = BLOC (condition = " Template == 'AnalysisPrinter' ",
81                                                  ValueTemplate = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "import numpy\\nxa=numpy.ravel(ADD.get('Analysis')[-1])\\nprint 'Analysis:',xa" ),
82                                              ),
83                                              AnalysisSaver = BLOC (condition = " Template == 'AnalysisSaver' ",
84                                                  ValueTemplate = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "import numpy\\nxa=numpy.ravel(ADD.get('Analysis')[-1])\\nf='/tmp/analysis.txt'\\nprint 'Analysis saved in \\"%s\\"'%f\\nnumpy.savetxt(f,xa)" ),
85                                              ),
86                                              AnalysisPrinterAndSaver = BLOC (condition = " Template == 'AnalysisPrinterAndSaver' ",
87                                                  ValueTemplate = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "import numpy\\nxa=numpy.ravel(ADD.get('Analysis')[-1])\\nprint 'Analysis:',xa\\nf='/tmp/analysis.txt'\\nprint 'Analysis saved in \\"%s\\"'%f\\nnumpy.savetxt(f,xa)" ),
88                                              ),
89                                          ),
90                                     )
91 """
92
93 init_method = """
94 def F_InitChoice() : return  ("Background",
95                               "BackgroundError",
96                               "Observation",
97                               "ObservationError",
98                               "ObservationOperator",
99                               "EvolutionModel",
100                               "EvolutionError",
101                               "AlgorithmParameters",
102                               "UserPostAnalysis",
103                              )
104
105 def F_Init(statut) : return FACT(statut = statut,
106                                  INIT_FILE = SIMP(statut = "o", typ = "FichierNoAbs", validators=(OnlyStr())),
107                                  TARGET_LIST = SIMP(statut = "o", typ = "TXM", min=1, max="**", into=F_InitChoice(),  validators=(VerifExiste(2))),
108                                 )
109 """
110
111 assim_data_method = """
112 def F_${assim_name}(statut) : return FACT(statut=statut,
113 ${storage}
114                                           INPUT_TYPE = SIMP(statut="o", typ = "TXM", into=(${choices}), defaut=${default_choice}),
115 ${decl_choices}
116                                                 )
117 """
118
119 assim_data_choice = """
120                                                  ${choice_name} = BLOC ( condition = " INPUT_TYPE in ( '${choice_name}', ) ",
121                                                  data = F_${choice_name}("o"),
122                                                  ),
123 """
124
125 observers_choice = """
126                                        ${var_name} = BLOC (condition=" '${var_name}' in set(SELECTION) ",
127                                            ${var_name}_data = FACT(statut = "o",
128                                                Scheduler    = SIMP(statut = "f", typ = "TXM"),
129                                                Info         = SIMP(statut = "o", typ = "TXM", defaut = "${var_name}"),
130                                                NodeType     = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "Template", into=("String", "Script", "Template")),
131                                                PythonScript = BLOC (condition = " NodeType == 'String' ",
132                                                    Value = SIMP(statut = "o", typ = "TXM")
133                                                ),
134                                                UserFile = BLOC (condition = " NodeType == 'Script' ",
135                                                    Value = SIMP(statut = "o", typ = "FichierNoAbs", validators=(OnlyStr()))
136                                                ),
137                                                ObserverTemplate =  BLOC (condition = " NodeType == 'Template' ",
138                                                    Template = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "ValuePrinter", into=("ValuePrinter", "ValueSeriePrinter", "ValueSaver", "ValueSerieSaver", "ValuePrinterAndSaver", "ValueSeriePrinterAndSaver", "ValueGnuPlotter", "ValueSerieGnuPlotter")),
139                                                    ValuePrinter = BLOC (condition = " Template == 'ValuePrinter' ",
140                                                        ValueTemplate = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "print info,var[-1]" ),
141                                                    ),
142                                                    ValueSeriePrinter = BLOC (condition = " Template == 'ValueSeriePrinter' ",
143                                                        ValueTemplate = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "print info,var[:]" ),
144                                                    ),
145                                                    ValueSaver = BLOC (condition = " Template == 'ValueSaver' ",
146                                                        ValueTemplate = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "import numpy,re\\nv=numpy.array((var[-1]))\\nglobal istep\\ntry:\\n    istep += 1\\nexcept:\\n    istep = 0\\nf='/tmp/value_%s_%05i.txt'%(info,istep)\\nf=re.sub('\\s','_',f)\\nprint 'Value saved in \\"%s\\"'%f\\nnumpy.savetxt(f,v)" ),
147                                                    ),
148                                                    ValueSerieSaver = BLOC (condition = " Template == 'ValueSerieSaver' ",
149                                                        ValueTemplate = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "import numpy,re\\nv=numpy.array((var[:])) \\nglobal istep\\ntry:\\n    istep += 1\\nexcept:\\n    istep = 0\\nf='/tmp/value_%s_%05i.txt'%(info,istep)\\nf=re.sub('\\s','_',f)\\nprint 'Value saved in \\"%s\\"'%f\\nnumpy.savetxt(f,v)" ),
150                                                    ),
151                                                    ValuePrinterAndSaver = BLOC (condition = " Template == 'ValuePrinterAndSaver' ",
152                                                        ValueTemplate = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "import numpy,re\\nv=numpy.array((var[-1]))\\nprint info,v\\nglobal istep\\ntry:\\n    istep += 1\\nexcept:\\n    istep = 0\\nf='/tmp/value_%s_%05i.txt'%(info,istep)\\nf=re.sub('\\s','_',f)\\nprint 'Value saved in \\"%s\\"'%f\\nnumpy.savetxt(f,v)" ),
153                                                    ),
154                                                    ValueSeriePrinterAndSaver = BLOC (condition = " Template == 'ValueSeriePrinterAndSaver' ",
155                                                        ValueTemplate = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "import numpy,re\\nv=numpy.array((var[:])) \\nprint info,v\\nglobal istep\\ntry:\\n    istep += 1\\nexcept:\\n    istep = 0\\nf='/tmp/value_%s_%05i.txt'%(info,istep)\\nf=re.sub('\\s','_',f)\\nprint 'Value saved in \\"%s\\"'%f\\nnumpy.savetxt(f,v)" ),
156                                                    ),
157                                                    ValueGnuPlotter = BLOC (condition = " Template == 'ValueGnuPlotter' ",
158                                                        ValueTemplate = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "import Gnuplot\\nglobal ifig,gp\\ntry:\\n    ifig += 1\\n    gp('set style data lines')\\nexcept:\\n    ifig = 0\\n    gp = Gnuplot.Gnuplot(persist=1)\\n    gp('set style data lines')\\ngp('set title  \\"%s (Figure %i)\\"'%(info,ifig))\\ngp.plot( Gnuplot.Data( var[-1], with_='lines lw 2' ) )" ),
159                                                    ),
160                                                    ValueSerieGnuPlotter = BLOC (condition = " Template == 'ValueSerieGnuPlotter' ",
161                                                        ValueTemplate = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "import Gnuplot\\nglobal ifig,gp\\ntry:\\n    ifig += 1\\n    gp('set style data lines')\\nexcept:\\n    ifig = 0\\n    gp = Gnuplot.Gnuplot(persist=1)\\n    gp('set style data lines')\\ngp('set title  \\"%s (Figure %i)\\"'%(info,ifig))\\ngp.plot( Gnuplot.Data( var[:], with_='lines lw 2' ) )" ),
162                                                    ),
163                                                ),
164                                            ),
165                                        ),
166 """
167
168 observers_method = """
169 def F_Observers(statut) : return FACT(statut=statut,
170                                       SELECTION = SIMP(statut="o", defaut=[], typ="TXM", min=0, max="**", validators=NoRepeat(), into=(${choices})),
171 ${decl_choices}
172                                      )
173 """
174
175 assim_study = """
176
177 def F_variables(statut) : return FACT(statut=statut,
178                                       regles = ( MEME_NOMBRE ('NAMES', 'SIZES')),
179                                       NAMES = SIMP(statut="o", typ="TXM", max="**", validators=NoRepeat()),
180                                       SIZES = SIMP(statut="o", typ="I", val_min=1, max="**")
181                                       )
182
183 ASSIMILATION_STUDY = PROC(nom="ASSIMILATION_STUDY",
184                           op=None,
185                           repetable           = "n",
186                           Study_name          = SIMP(statut="o", typ = "TXM", defaut="ADAO Calculation Case"),
187                           Study_repertory     = SIMP(statut="f", typ = "Repertoire", min=1, max=1),
188                           Debug               = SIMP(statut="f", typ = "I", into=(0, 1), defaut=0),
189                           Algorithm           = SIMP(statut="o", typ = "TXM", into=(${algos_names})),
190                           Background          = F_Background("o"),
191                           BackgroundError     = F_BackgroundError("o"),
192                           Observation         = F_Observation("o"),
193                           ObservationError    = F_ObservationError("o"),
194                           ObservationOperator = F_ObservationOperator("o"),
195                           EvolutionModel      = F_EvolutionModel("f"),
196                           EvolutionError      = F_EvolutionError("f"),
197                           ControlInput        = F_ControlInput("f"),
198                           AlgorithmParameters = F_AlgorithmParameters("f"),
199                           UserDataInit        = F_Init("f"),
200                           UserPostAnalysis    = F_UserPostAnalysis("o"),
201                           InputVariables      = F_variables("f"),
202                           OutputVariables     = F_variables("f"),
203                           Observers           = F_Observers("f")
204                          )
205
206 CHECKING_STUDY = PROC(nom="CHECKING_STUDY",
207                           op=None,
208                           repetable           = "n",
209                           Study_name          = SIMP(statut="o", typ = "TXM", defaut="ADAO Checking Case"),
210                           Study_repertory     = SIMP(statut="f", typ = "Repertoire", min=1, max=1),
211                           Debug               = SIMP(statut="f", typ = "I", into=(0, 1), defaut=0),
212                           Algorithm           = SIMP(statut="o", typ = "TXM", into=(${check_names})),
213                           CheckingPoint       = F_CheckingPoint("o"),
214                           ObservationOperator = F_ObservationOperator("o"),
215                           AlgorithmParameters = F_AlgorithmParameters("f"),
216                           UserDataInit        = F_Init("f"),
217                           Observers           = F_Observers("f")
218                          )
219 """
220
221 begin_catalog_file = string.Template(begin_catalog_file)
222 data_method = string.Template(data_method)
223 assim_data_method = string.Template(assim_data_method)
224 assim_data_choice = string.Template(assim_data_choice)
225 assim_study = string.Template(assim_study)
226 observers_method = string.Template(observers_method)
227 observers_choice = string.Template(observers_choice)
228
229 #----------- End of Templates Part ---------------#
230
231
232
233 #----------- Begin generation script -----------#
234 print "-- Starting AdaoCalatogGenerator.py --"
235
236 try:
237   import daEficas
238   import daYacsSchemaCreator
239   import daCore.AssimilationStudy
240   import daYacsSchemaCreator.infos_daComposant as infos
241 except:
242   logging.fatal("Import of ADAO python modules failed !" +
243                 "\n add ADAO python installation directory in your PYTHONPATH")
244   traceback.print_exc()
245   sys.exit(1)
246
247 def check_args(args):
248   logging.debug("Arguments are :" + str(args))
249   if len(args) != 2:
250     logging.fatal("Bad number of arguments: you have to provide two arguments (%d given)" % (len(args)))
251     sys.exit(1)
252
253 # Parse arguments
254 from optparse import OptionParser
255 usage = "usage: %prog [options] catalog_path catalog_name"
256 version="%prog 0.1"
257 my_parser = OptionParser(usage=usage, version=version)
258 (options, args) = my_parser.parse_args()
259 check_args(args)
260
261 catalog_path =  args[0]
262 catalog_name =  args[1]
263
264 # Generates into a string
265 mem_file = StringIO.StringIO()
266
267 # Start file
268 from time import strftime
269 mem_file.write(begin_catalog_file.substitute(date=strftime("%Y-%m-%d %H:%M:%S")))
270
271 # Step 1: A partir des infos, on cree les fonctions qui vont permettre
272 # d'entrer les donnees utilisateur
273 for data_input_name in infos.DataTypeDict.keys():
274   logging.debug('A data input Type is found: ' + data_input_name)
275   data_name = data_input_name
276   data_into = ""
277   data_default = ""
278
279   # On recupere les differentes facon d'entrer les donnees
280   for basic_type in infos.DataTypeDict[data_input_name]:
281     data_into += "\"" + basic_type + "\", "
282
283   # On choisit le default
284   data_default = "\"" + infos.DataTypeDefaultDict[data_input_name] + "\""
285
286   mem_file.write(data_method.substitute(data_name    = data_name,
287                                         data_into    = data_into,
288                                         data_default = data_default))
289
290 # Step 2: On cree les fonctions qui permettent de rentrer les donnees des algorithmes
291 for assim_data_input_name in infos.AssimDataDict.keys():
292   logging.debug("An assimilation algorithm data input is found: " + assim_data_input_name)
293   assim_name = assim_data_input_name
294   storage = ""
295   choices = ""
296   default_choice = ""
297   decl_choices = ""
298   decl_opts = ""
299   if infos.AssimDataDefaultDict[assim_data_input_name] in infos.StoredAssimData:
300     storage = "                                          Stored = SIMP(statut=\"o\", typ = \"I\", into=(0, 1), defaut=0, fr=\"Choix de stockage interne ou non du concept parent\", ang=\"Choice of the storage or not of the parent concept\"),"
301   for choice in infos.AssimDataDict[assim_data_input_name]:
302     choices += "\"" + choice + "\", "
303     decl_choices += assim_data_choice.substitute(choice_name = choice)
304     if choice in infos.StoredAssimData:
305       storage = "                                          Stored = SIMP(statut=\"o\", typ = \"I\", into=(0, 1), defaut=0, fr=\"Choix de stockage interne ou non du concept parent\", ang=\"Choice of the storage or not of the parent concept\"),"
306   default_choice = "\"" + infos.AssimDataDefaultDict[assim_data_input_name] + "\""
307
308   mem_file.write(assim_data_method.substitute(assim_name = assim_name,
309                                               storage = storage,
310                                               choices = choices,
311                                               decl_choices = decl_choices,
312                                               default_choice=default_choice))
313
314 # Step 3: On ajoute les fonctions representant les options possibles
315 for opt_name in infos.OptDict.keys():
316   logging.debug("An optional node is found: " + opt_name)
317   data_name = opt_name
318   data_into = ""
319   data_default = ""
320
321   for choice in infos.OptDict[opt_name]:
322     data_into += "\"" + choice + "\", "
323   data_default = "\"" + infos.OptDefaultDict[opt_name] + "\""
324
325   mem_file.write(data_method.substitute(data_name = data_name,
326                                         data_into = data_into,
327                                         data_default = data_default))
328
329 # Step 4: On ajoute la methode optionnelle init
330 # TODO uniformiser avec le step 3
331 mem_file.write(init_method)
332
333 # Step 5: Add observers
334 decl_choices = ""
335 for obs_var in infos.ObserversList:
336   decl_choices += observers_choice.substitute(var_name=obs_var)
337 mem_file.write(observers_method.substitute(choices = infos.ObserversList,
338                                            decl_choices = decl_choices))
339
340 # Final step: Add algorithm and assim_study
341 algos_names = ""
342 check_names = ""
343 decl_algos  = ""
344
345 assim_study_object = daCore.AssimilationStudy.AssimilationStudy()
346 algos_list = assim_study_object.get_available_algorithms()
347 for algo_name in algos_list:
348   if algo_name in infos.AssimAlgos:
349     logging.debug("An assimilation algorithm is found: " + algo_name)
350     algos_names += "\"" + algo_name + "\", "
351   elif algo_name in infos.CheckAlgos:
352     logging.debug("A checking algorithm is found: " + algo_name)
353     check_names += "\"" + algo_name + "\", "
354   else:
355     logging.debug("This algorithm is not considered: " + algo_name)
356
357 mem_file.write(assim_study.substitute(algos_names=algos_names,
358                                       check_names=check_names,
359                                       decl_algos=decl_algos))
360 # Write file
361 final_file = open(catalog_path + "/" + catalog_name, "wr")
362 final_file.write(mem_file.getvalue())
363 mem_file.close()
364 final_file.close()
365