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