Salome HOME
Python 3 compatibility improvement (Salome/Adao)
[modules/adao.git] / bin / AdaoCatalogGenerator.py
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright (C) 2008-2017 EDF R&D
4 #
5 # This file is part of SALOME ADAO module
6 #
7 # This library is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU Lesser General Public
9 # License as published by the Free Software Foundation; either
10 # version 2.1 of the License.
11 #
12 # This library is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 # Lesser General Public License for more details.
16 #
17 # You should have received a copy of the GNU Lesser General Public
18 # License along with this library; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
20 #
21 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 #
23 # Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
24
25 import logging
26 import traceback
27 import sys
28 import io
29 import os
30
31 import module_version
32
33 logging.basicConfig(level=logging.WARNING)
34
35 if sys.version_info.major > 2:
36     def unicode(text, encoding='utf-8'): return text
37
38 #----------- Templates Part ---------------#
39 begin_catalog_file = """# -*- coding: utf-8 -*-
40 #
41 # Copyright (C) 2008-2017 EDF R&D
42 #
43 # This file is part of SALOME ADAO module
44 #
45 # This library is free software; you can redistribute it and/or
46 # modify it under the terms of the GNU Lesser General Public
47 # License as published by the Free Software Foundation; either
48 # version 2.1 of the License.
49 #
50 # This library is distributed in the hope that it will be useful,
51 # but WITHOUT ANY WARRANTY; without even the implied warranty of
52 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
53 # Lesser General Public License for more details.
54 #
55 # You should have received a copy of the GNU Lesser General Public
56 # License along with this library; if not, write to the Free Software
57 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
58 #
59 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
60 #
61 # Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
62
63 # --------------------------------------------------------
64 # Generated by AdaoCatalogGenerator on {date}
65 # --------------------------------------------------------
66
67 import os, re
68 import Accas
69 from Accas import *
70
71 JdC = JDC_CATA (
72     code = '%s',
73     execmodul = None,
74     regles = ( AU_MOINS_UN ('ASSIMILATION_STUDY','CHECKING_STUDY'), AU_PLUS_UN ('ASSIMILATION_STUDY','CHECKING_STUDY')),
75     )
76 VERSION_CATALOGUE='%s'
77
78 def NoCheckInNS(filename):
79     return 1
80 NoCheckInNS.info = u""
81 def DirectOperatorInNS(filename):
82     if os.path.exists(filename):
83         fc = open(filename, 'r').readlines()
84         cr = re.compile("^def[\s]*DirectOperator[\s]*\(")
85         for ln in fc:
86             if cr.match(ln): return 1
87         cr = re.compile("^DirectOperator[\s]*=")
88         for ln in fc:
89             if cr.match(ln): return 1
90     return 0
91 DirectOperatorInNS.info = u"The Python file has to contain explicitly a \\"DirectOperator\\" function definition with only one vector as argument."
92 def TangentOperatorInNS(filename):
93     if os.path.exists(filename):
94         fc = open(filename, 'r').readlines()
95         cr = re.compile("^def[\s]*TangentOperator[\s]*\(")
96         for ln in fc:
97             if cr.match(ln): return 1
98         cr = re.compile("^TangentOperator[\s]*=")
99         for ln in fc:
100             if cr.match(ln): return 1
101     return 0
102 TangentOperatorInNS.info = u"The Python file has to contain explicitly a \\"TangentOperator\\" function definition with only one pair of vectors as argument."
103 def AdjointOperatorInNS(filename):
104     if os.path.exists(filename):
105         fc = open(filename, 'r').readlines()
106         cr = re.compile("^def[\s]*AdjointOperator[\s]*\(")
107         for ln in fc:
108             if cr.match(ln): return 1
109         cr = re.compile("^AdjointOperator[\s]*=")
110         for ln in fc:
111             if cr.match(ln): return 1
112     return 0
113 AdjointOperatorInNS.info = u"The Python file has to contain explicitly an \\"AdjointOperator\\" function definition with only one pair of vectors as argument."
114 """%(module_version.name,module_version.version)
115
116 # Important : validators=[...] pour que les conditions soient traitees simultanement, en "ET", et pas en "OU" (choisi dans le cas du tuple a la place de la liste)
117 # validators=[OnlyStr(), FileExtVal('py'), FunctionVal(fv)]
118 data_method = """
119 def F_{data_name}(statut, fv=NoCheckInNS) : return FACT(
120     statut = statut,
121     FROM = SIMP(statut = "o", typ = "TXM", into=({data_into}), defaut={data_default}),
122     SCRIPT_DATA = BLOC ( condition = " FROM in ( 'Script', ) ",
123         SCRIPT_FILE = SIMP(statut = "o", typ = "FichierNoAbs", validators=[OnlyStr(), FileExtVal('py'), FunctionVal(fv)], 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"),
124         ),
125     STRING_DATA = BLOC ( condition = " FROM in ( 'String', ) ",
126         STRING = SIMP(statut = "o", typ = "TXM",{ms_default} 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"),
127         ),
128     SCRIPTWITHFUNCTIONS_DATA = BLOC ( condition = " FROM in ( 'ScriptWithFunctions', ) ",
129         SCRIPTWITHFUNCTIONS_FILE = SIMP(statut = "o", typ = "FichierNoAbs", validators=[OnlyStr(), FileExtVal('py'), FunctionVal(DirectOperatorInNS), FunctionVal(TangentOperatorInNS), FunctionVal(AdjointOperatorInNS)], 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"),
130         ),
131     SCRIPTWITHONEFUNCTION_DATA = BLOC ( condition = " FROM in ( 'ScriptWithOneFunction', ) ",
132         SCRIPTWITHONEFUNCTION_FILE = SIMP(statut = "o", typ = "FichierNoAbs", validators=[OnlyStr(), FileExtVal('py'), FunctionVal(DirectOperatorInNS)], 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"),
133         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"),
134         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"),
135         EnableMultiProcessing = SIMP(statut="f", typ = "I", into=(0, 1), defaut=0, fr="Calculs élémentaires effectués en séquentiel (0) ou en parallèle (1) dans la méthode des différences finies", ang="Elementary calculations done sequentially (0) or in parallel (1) in the finite differences method"),
136         NumberOfProcesses = SIMP(statut="f", typ = "I", val_min=0, defaut=0, fr="Nombre de processus parallèles, 0 pour un contrôle automatique", ang="Number of parallel processes, 0 for automatic control"),
137         ),
138     SCRIPTWITHSWITCH_DATA = BLOC ( condition = " FROM in ( 'ScriptWithSwitch', ) ",
139         SCRIPTWITHSWITCH_FILE = SIMP(statut = "o", typ = "FichierNoAbs", validators=[OnlyStr(), FileExtVal('py')], 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"),
140         ),
141     TEMPLATE_DATA =  BLOC (condition = " FROM in ( 'Template', ) ",
142         Template = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "AnalysisPrinter", into=("AnalysisPrinter", "AnalysisSaver", "AnalysisPrinterAndSaver")),
143         AnalysisPrinter = BLOC (condition = " Template == 'AnalysisPrinter' ",
144             ValueTemplate = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "import numpy\\nxa=numpy.ravel(ADD.get('Analysis')[-1])\\nprint 'Analysis:',xa" ),
145             ),
146         AnalysisSaver = BLOC (condition = " Template == 'AnalysisSaver' ",
147             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)" ),
148             ),
149         AnalysisPrinterAndSaver = BLOC (condition = " Template == 'AnalysisPrinterAndSaver' ",
150             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)" ),
151             ),
152         ),
153     )
154 """
155
156 init_method = """
157 def F_InitChoice() : return  ("Background",
158                               "BackgroundError",
159                               "Observation",
160                               "ObservationError",
161                               "ObservationOperator",
162                               "EvolutionModel",
163                               "EvolutionError",
164                               "AlgorithmParameters",
165                               "UserPostAnalysis",
166                              )
167
168 def F_Init(statut) : return FACT(statut = statut,
169     INIT_FILE = SIMP(statut = "o", typ = "FichierNoAbs", validators=[OnlyStr(), FileExtVal('py')]),
170     TARGET_LIST = SIMP(statut = "o", typ = "TXM", min=1, max="**", into=F_InitChoice(),  validators=(VerifExiste(2))),
171     )
172 """
173
174 assim_data_method = """
175 def {assim_name}InNS(filename):
176     if os.path.exists(filename):
177         fc = open(filename, 'r').readlines()
178         cr = re.compile("^{assim_name}[\s]*=")
179         for ln in fc:
180             if cr.match(ln): return 1
181     return 0
182 {assim_name}InNS.info = u"The Python file has to contain explicitly a \\"{assim_name}\\" variable."
183 def F_{assim_name}(statut, fv=NoCheckInNS) : return FACT(
184     statut=statut,
185 {storage}
186     INPUT_TYPE = SIMP(statut="o", typ = "TXM", into=({choices}), defaut={default_choice}),{decl_choices}
187     )
188 """
189
190 assim_data_choice = """
191     {choice_name} = BLOC ( condition = " INPUT_TYPE in ( '{choice_name}', ) ",
192         data = F_{choice_name}("o", fv),
193         ),"""
194
195 observers_choice = """
196     {var_name} = BLOC (condition=" '{var_name}' in set(SELECTION) ",
197         {var_name}_data = FACT(statut = "o",
198             Scheduler    = SIMP(statut = "f", typ = "TXM"),
199             Info         = SIMP(statut = "o", typ = "TXM", defaut = "{var_name}"),
200             NodeType     = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "Template", into=("String", "Script", "Template")),
201             PythonScript = BLOC (condition = " NodeType == 'String' ",
202                 Value = SIMP(statut = "o", typ = "TXM")
203                 ),
204             UserFile = BLOC (condition = " NodeType == 'Script' ",
205                 Value = SIMP(statut = "o", typ = "FichierNoAbs", validators=[OnlyStr(), FileExtVal('py')])
206                 ),
207             ObserverTemplate = F_ObserverTemplate(),
208             ),
209         ),"""
210
211 from daCore.Templates import ObserverTemplates
212 observers_list = ObserverTemplates.keys_in_presentation_order()
213 observers_list = '"%s"'%str('", "'.join(observers_list))
214 observers_cont = ""
215 for k in ObserverTemplates.keys_in_presentation_order():
216     observers_cont += """                %s = BLOC (condition = " Template == '%s' ",\n"""%(k,k)
217     observers_cont += """                    ValueTemplate = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "%s", fr="%s", ang="%s" ),\n"""%(
218         ObserverTemplates[k].replace("\n","\\n").replace('"','\\"'),
219         ObserverTemplates.getdoc(k, "fr_FR"),
220         ObserverTemplates.getdoc(k, "en_EN"),
221         )
222     observers_cont += """                    ),\n"""
223 observers_method = """
224 def F_ObserverTemplate() : return BLOC(condition = " NodeType == 'Template' ",
225                 Template = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "ValuePrinter", into=(%s)),
226 %s                )
227
228 def F_Observers(statut) : return FACT(
229     statut=statut,
230     SELECTION = SIMP(statut="o", defaut=[], typ="TXM", min=0, max="**", homo="SansOrdreNiDoublon", validators=NoRepeat(), into=({choices})),{decl_choices}
231     )
232 """%(observers_list,observers_cont)
233
234 algo_choices = """
235 def AlgorithmParametersInNS(filename):
236     if os.path.exists(filename):
237         fc = open(filename, 'r').readlines()
238         cr = re.compile("^AlgorithmParameters[\s]*=")
239         for ln in fc:
240             if cr.match(ln): return 1
241     return 0
242 AlgorithmParametersInNS.info = u"The Python file has to contain explicitly an \\"AlgorithmParameters\\" variable."
243 def F_AlgorithmParameters(statut, algos_names, fv=NoCheckInNS) : return FACT(
244     statut = statut,
245     Algorithm = SIMP(statut="o", typ = "TXM", into = algos_names ),
246     Parameters = SIMP(statut="f", typ = "TXM", into=("Defaults", "Dict") ),
247     Dict = BLOC ( condition = " Parameters == 'Dict' ",
248         statut="f",
249         data = F_Dict("o", fv),
250         ),{all_algo_defaults}
251     )
252 """
253 one_algo_choices = """
254     Parameters{algo_name} = BLOC (condition = " (Parameters == 'Defaults') and (Algorithm == '{algo_name}') ",
255         statut="f",
256 {algo_parameters}        ),"""
257
258 assim_study = """
259 def F_variables(statut) : return FACT(
260     statut=statut,
261     regles = ( MEME_NOMBRE ('NAMES', 'SIZES')),
262     NAMES = SIMP(statut="o", typ="TXM", max="**", validators=NoRepeat()),
263     SIZES = SIMP(statut="o", typ="I", val_min=1, max="**")
264     )
265 def ChDir(dirname):
266     os.chdir(os.path.abspath(dirname))
267     return 1
268 ChDir.info = u"This has to be a regular directory path."
269
270 ASSIMILATION_STUDY = PROC(nom="ASSIMILATION_STUDY",
271     op=None,
272     repetable           = "n",
273     StudyName           = SIMP(statut="o", typ = "TXM", defaut="ADAO Calculation Case"),
274     StudyRepertory      = SIMP(statut="f", typ = "Repertoire", validators=FunctionVal(ChDir), min=1, max=1),
275     Debug               = SIMP(statut="f", typ = "I", into=(0, 1), defaut=0),
276     AlgorithmParameters = F_AlgorithmParameters("o",({algos_names}), AlgorithmParametersInNS),
277     Background          = F_Background("o", BackgroundInNS),
278     BackgroundError     = F_BackgroundError("o", BackgroundErrorInNS),
279     Observation         = F_Observation("o", ObservationInNS),
280     ObservationError    = F_ObservationError("o", ObservationErrorInNS),
281     ObservationOperator = F_ObservationOperator("o"),
282     EvolutionModel      = F_EvolutionModel("f"),
283     EvolutionError      = F_EvolutionError("f", EvolutionErrorInNS),
284     ControlInput        = F_ControlInput("f"),
285     UserDataInit        = F_Init("f"),
286     UserPostAnalysis    = F_UserPostAnalysis("o"),
287     InputVariables      = F_variables("f"),
288     OutputVariables     = F_variables("f"),
289     Observers           = F_Observers("f")
290     )
291
292 CHECKING_STUDY = PROC(nom="CHECKING_STUDY",
293     op=None,
294     repetable           = "n",
295     StudyName           = SIMP(statut="o", typ = "TXM", defaut="ADAO Checking Case"),
296     StudyRepertory      = SIMP(statut="f", typ = "Repertoire", validators=FunctionVal(ChDir), min=1, max=1),
297     Debug               = SIMP(statut="f", typ = "I", into=(0, 1), defaut=0),
298     AlgorithmParameters = F_AlgorithmParameters("o", ({check_names}), AlgorithmParametersInNS),
299     CheckingPoint       = F_CheckingPoint("o", CheckingPointInNS),
300     BackgroundError     = F_BackgroundError("f", BackgroundErrorInNS),
301     Observation         = F_Observation("f", ObservationInNS),
302     ObservationError    = F_ObservationError("f", ObservationErrorInNS),
303     ObservationOperator = F_ObservationOperator("o"),
304     UserDataInit        = F_Init("f"),
305     Observers           = F_Observers("f")
306     )
307 """
308
309 #----------- End of Templates Part ---------------#
310
311
312
313 #----------- Begin generation script -----------#
314 print("-- Starting AdaoCalatogGenerator.py --")
315
316 try:
317   import daEficas
318   import daYacsSchemaCreator
319   import daCore.AssimilationStudy
320   import daYacsSchemaCreator.infos_daComposant as infos
321 except:
322   logging.fatal("Import of ADAO python modules failed !" +
323                 "\n add ADAO python installation directory in your PYTHONPATH")
324   traceback.print_exc()
325   sys.exit(1)
326
327 # Parse arguments
328 from argparse import ArgumentParser
329 usage = "usage: %(prog)s [options] catalog_path catalog_name"
330 version="%(prog)s 0.1"
331 my_parser = ArgumentParser(usage=usage)
332 my_parser.add_argument('-v', '--version', action='version', version=version)
333 my_parser.add_argument('catalog_path')
334 my_parser.add_argument('catalog_name')
335 args = my_parser.parse_args()
336
337 # Generates into a string
338 mem_file = io.StringIO()
339
340 # Start file
341 from time import strftime
342 mem_file.write(unicode(begin_catalog_file, 'utf-8').format(**{'date':strftime("%Y-%m-%d %H:%M:%S")}))
343
344 # Step initial: on obtient la liste des algos
345 algos_names = ""
346 check_names = ""
347 decl_algos  = ""
348 assim_study_object = daCore.AssimilationStudy.AssimilationStudy()
349 algos_list = assim_study_object.get_available_algorithms()
350 del assim_study_object
351 for algo_name in algos_list:
352   if algo_name in infos.AssimAlgos:
353     logging.debug("An assimilation algorithm is found: " + algo_name)
354     algos_names += "\"" + algo_name + "\", "
355   elif algo_name in infos.CheckAlgos:
356     logging.debug("A checking algorithm is found: " + algo_name)
357     check_names += "\"" + algo_name + "\", "
358   else:
359     logging.debug("This algorithm is not considered: " + algo_name)
360
361 # Step 1: A partir des infos, on cree les fonctions qui vont permettre
362 # d'entrer les donnees utilisateur
363 for data_input_name in infos.DataTypeDict:
364   logging.debug('A data input Type is found: ' + data_input_name)
365   data_name = data_input_name
366   data_into = ""
367   data_default = ""
368   ms_default = ""
369
370   # On recupere les differentes facon d'entrer les donnees
371   for basic_type in infos.DataTypeDict[data_input_name]:
372     data_into += "\"" + basic_type + "\", "
373
374   # On choisit le default
375   data_default = "\"" + infos.DataTypeDefaultDict[data_input_name] + "\""
376   if data_input_name in infos.DataSValueDefaultDict:
377     ms_default = " defaut=\"" + infos.DataSValueDefaultDict[data_input_name] + "\","
378
379   mem_file.write(unicode(data_method, 'utf-8').format(**{
380     'data_name'    : data_name,
381     'data_into'    : data_into,
382     'data_default' : data_default,
383     'ms_default'   : ms_default,
384     'algos_names'  : algos_names+check_names,
385     }))
386
387 # Step 2: On cree les fonctions qui permettent de rentrer les donnees des algorithmes
388 for assim_data_input_name in infos.AssimDataDict:
389   logging.debug("An input function data input is found: " + assim_data_input_name)
390   # assim_name = assim_data_input_name
391   storage = ""
392   choices = ""
393   default_choice = ""
394   decl_choices = ""
395   decl_opts = ""
396   if infos.AssimDataDefaultDict[assim_data_input_name] in infos.StoredAssimData:
397     storage = "    Stored = SIMP(statut=\"f\", 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\"),"
398   for choice in infos.AssimDataDict[assim_data_input_name]:
399     choices += "\"" + choice + "\", "
400     decl_choices += assim_data_choice.format(**{'choice_name' : choice})
401     if choice in infos.StoredAssimData:
402       storage = "    Stored = SIMP(statut=\"f\", 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\"),"
403   default_choice = "\"" + infos.AssimDataDefaultDict[assim_data_input_name] + "\""
404
405   mem_file.write(unicode(assim_data_method, 'utf-8').format(**{
406     'assim_name'     : assim_data_input_name,
407     'storage'        : storage,
408     'choices'        : choices,
409     'decl_choices'   : decl_choices,
410     'default_choice' : default_choice,
411     }))
412
413 # Step 3: On ajoute les fonctions representant les options possibles
414 for opt_name in infos.OptDict:
415   logging.debug("An optional node is found: " + opt_name)
416   data_name = opt_name
417   data_into = ""
418   data_default = ""
419   ms_default = ""
420
421   for choice in infos.OptDict[opt_name]:
422     data_into += "\"" + choice + "\", "
423
424   # On choisit le default
425   data_default = "\"" + infos.OptDefaultDict[opt_name] + "\""
426   if opt_name in infos.DataSValueDefaultDict:
427     ms_default = " defaut=\"" + infos.DataSValueDefaultDict[opt_name] + "\","
428
429   mem_file.write(unicode(data_method, 'utf-8').format(**{
430     'data_name'    : data_name,
431     'data_into'    : data_into,
432     'data_default' : data_default,
433     'ms_default'   : ms_default,
434     'algos_names'  : algos_names+check_names,
435     }))
436
437 # Step 4: On ajoute la methode optionnelle init
438 # TODO uniformiser avec le step 3
439 mem_file.write(unicode(init_method, 'utf-8'))
440
441 # Step 5: Add observers
442 decl_choices = ""
443 for obs_var in infos.ObserversList:
444   decl_choices += observers_choice.format(**{'var_name':obs_var})
445 mem_file.write(unicode(observers_method, 'utf-8').format(**{
446   'choices' : infos.ObserversList,
447   'decl_choices' : decl_choices,
448   }))
449
450 # Step 5: Add algorithmic choices
451
452 all_names = eval((algos_names+check_names))
453 all_algo_defaults = ""
454 for algo in all_names:
455     assim_study_object = daCore.AssimilationStudy.AssimilationStudy()
456     assim_study_object.setAlgorithmParameters(Algorithm=algo)
457     par_dict = assim_study_object.get("AlgorithmRequiredParameters",False)
458     par_keys = sorted(par_dict.keys())
459     algo_parameters = ""
460     for pn in par_keys:
461         if pn in ("StoreInternalVariables", "PlotAndSave", "ResultFile", "ResultTitle", "ResultLabel"): continue # Cles a supprimer
462         pt = par_dict[pn]["typecast"] # Pointeur de type
463         pd = par_dict[pn]["default"]
464         pm = par_dict[pn]["message"]
465         if "minval" in par_dict[pn] and par_dict[pn]["minval"] is not None:
466             vi = ", val_min=%s"%par_dict[pn]["minval"]
467         else:
468             vi = ""
469         if "minval" in par_dict[pn] and par_dict[pn]["maxval"] is not None:
470             vs = ", val_max=%s"%par_dict[pn]["maxval"]
471         else:
472             vs = ""
473         if   pt is int:
474             algo_parameters += """        %s = SIMP(statut="f", typ="I"%s%s, min=1, max=1, defaut=%s, fr="%s"),\n"""%(pn,vi,vs,int(pd),pm)
475         elif pt is float:
476             algo_parameters += """        %s = SIMP(statut="f", typ="R"%s%s, min=1, max=1, defaut=%s, fr="%s"),\n"""%(pn,vi,vs,float(pd),pm)
477         elif pt is bool:
478             algo_parameters += """        %s = SIMP(statut="f", typ="I", min=1, max=1, defaut=%s, fr="%s"),\n"""%(pn,int(pd),pm)
479         elif pt is str and "listval" in par_dict[pn]:
480             algo_parameters += """        %s = SIMP(statut="f", typ="TXM", min=1, max=1, defaut="%s", into=%s, fr="%s"),\n"""%(pn,pd,par_dict[pn]["listval"],pm)
481         elif pt is tuple and "listval" in par_dict[pn]:
482             algo_parameters += """        %s = SIMP(statut="f", typ="TXM", max="**", into=%s, fr="%s"),\n"""%(pn,par_dict[pn]["listval"],pm)
483         else:
484             algo_parameters += """        %s = SIMP(statut="f", typ="TXM", fr="%s"),\n"""%(pn,pm)
485     del assim_study_object
486     if algo_parameters != "":
487         all_algo_defaults += one_algo_choices.format(**{
488             'algo_name':algo,
489             'algo_parameters':algo_parameters,
490             })
491 mem_file.write(unicode(algo_choices, 'utf-8').format(**{'all_algo_defaults':unicode(all_algo_defaults, 'utf-8')}))
492
493 # Final step: Add algorithm and assim_study
494 mem_file.write(unicode(assim_study, 'utf-8').format(**{
495   'algos_names':algos_names,
496   'check_names':check_names,
497   'decl_algos':decl_algos,
498   }))
499
500 # Write file
501 if sys.version_info.major > 2:
502     with open(os.path.join(args.catalog_path, args.catalog_name), "w", encoding='utf8') as final_file:
503         final_file.write(mem_file.getvalue())
504 else:
505     with open(os.path.join(args.catalog_path, args.catalog_name), "wr") as final_file:
506         final_file.write(mem_file.getvalue().encode('utf-8'))
507 mem_file.close()