Salome HOME
Minor dev documentation corrections
[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     DATA_DATA = BLOC ( condition = " FROM in ( 'DataFile', ) ",
146         DATA_FILE = SIMP(statut = "o", typ = ("FichierNoAbs",'CSV Text Files (*.csv);;TSV Text Files (*.tsv);;TXT Text Files (*.txt);;NPY Binary Numpy Files (*.npy);;NPZ Binary Numpy Files (*.npz);;All Files (*)", ',), validators=[OnlyStr(), FunctionVal(ColDataFileExtVal)], fr="En attente d'un nom de fichier de données, avec ou sans le chemin complet pour le trouver, contenant ou plusieurs colonnes pour définir un unique vecteur continu", ang="Waiting for a data file name, with or without the full path to find it, containing one or more columns to define a unique continuous vector"),
147         ColMajor = SIMP(statut="f", typ = "I", into=(0, 1), defaut=0, fr="Variables en colonnes acquises ligne par ligne (0) ou colonne par colonne (1)", ang="Variables in columns acquired line by line (0) or column by column (1)"),
148         ),
149     STRING_DATA = BLOC ( condition = " FROM in ( 'String', ) ",
150         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"),
151         ),
152     SCRIPTWITHFUNCTIONS_DATA = BLOC ( condition = " FROM in ( 'ScriptWithFunctions', ) ",
153         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"),
154         ),
155     SCRIPTWITHONEFUNCTION_DATA = BLOC ( condition = " FROM in ( 'ScriptWithOneFunction', ) ",
156         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"),
157         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"),
158         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"),
159         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"),
160         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"),
161         ),
162     SCRIPTWITHSWITCH_DATA = BLOC ( condition = " FROM in ( 'ScriptWithSwitch', ) ",
163         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"),
164         ),
165     TEMPLATE_DATA =  BLOC (condition = " FROM in ( 'Template', ) ",
166         Template = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "AnalysisPrinter", into=("AnalysisPrinter", "AnalysisSaver", "AnalysisPrinterAndSaver")),
167         AnalysisPrinter = BLOC (condition = " Template == 'AnalysisPrinter' ",
168             ValueTemplate = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "import numpy\\nxa=numpy.ravel(ADD.get('Analysis')[-1])\\nprint('Analysis:',xa)" ),
169             ),
170         AnalysisSaver = BLOC (condition = " Template == 'AnalysisSaver' ",
171             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)" ),
172             ),
173         AnalysisPrinterAndSaver = BLOC (condition = " Template == 'AnalysisPrinterAndSaver' ",
174             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)" ),
175             ),
176         ),
177     )
178 """
179
180 init_method = """
181 def F_InitChoice() : return  ("Background",
182                               "BackgroundError",
183                               "Observation",
184                               "ObservationError",
185                               "ObservationOperator",
186                               "EvolutionModel",
187                               "EvolutionError",
188                               "AlgorithmParameters",
189                               "UserPostAnalysis",
190                              )
191
192 def F_Init(statut) : return FACT(statut = statut,
193     INIT_FILE = SIMP(statut = "o", typ = "FichierNoAbs", validators=[OnlyStr(), FileExtVal('py')]),
194     TARGET_LIST = SIMP(statut = "o", typ = "TXM", min=1, max="**", into=F_InitChoice(),  validators=(VerifExiste(2))),
195     )
196 """
197
198 assim_data_method = """
199 def {assim_name}InNS(filename):
200     if os.path.exists(filename):
201         fc = open(filename, 'r').readlines()
202         cr = re.compile("^{assim_name}[\s]*=")
203         for ln in fc:
204             if cr.match(ln): return 1
205     return 0
206 {assim_name}InNS.info = u"The Python file has to contain explicitly a \\"{assim_name}\\" variable."
207 def F_{assim_name}(statut, fv=NoCheckInNS) : return FACT(
208     statut=statut,
209 {storage}
210     INPUT_TYPE = SIMP(statut="o", typ = "TXM", into=({choices}), defaut={default_choice}),{decl_choices}
211     )
212 """
213
214 assim_data_choice = """
215     {choice_name} = BLOC ( condition = " INPUT_TYPE in ( '{choice_name}', ) ",
216         data = F_{choice_name}("o", fv),
217         ),"""
218
219 observers_choice = """
220     {var_name} = BLOC (condition=" '{var_name}' in set(SELECTION) ",
221         {var_name}_data = FACT(statut = "o",
222             Scheduler    = SIMP(statut = "f", typ = "TXM"),
223             Info         = SIMP(statut = "o", typ = "TXM", defaut = "{var_name}"),
224             NodeType     = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "Template", into=("String", "Script", "Template")),
225             PythonScript = BLOC (condition = " NodeType == 'String' ",
226                 Value = SIMP(statut = "o", typ = "TXM")
227                 ),
228             UserFile = BLOC (condition = " NodeType == 'Script' ",
229                 Value = SIMP(statut = "o", typ = "FichierNoAbs", validators=[OnlyStr(), FileExtVal('py')])
230                 ),
231             ObserverTemplate = F_ObserverTemplate(),
232             ),
233         ),"""
234
235 from daCore.Templates import ObserverTemplates
236 observers_list = ObserverTemplates.keys_in_presentation_order()
237 observers_list = '"%s"'%str('", "'.join(observers_list))
238 observers_cont = ""
239 for k in ObserverTemplates.keys_in_presentation_order():
240     observers_cont += """                %s = BLOC (condition = " Template == '%s' ",\n"""%(k,k)
241     observers_cont += """                    ValueTemplate = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "%s", fr="%s", ang="%s" ),\n"""%(
242         ObserverTemplates[k].replace("\n","\\n").replace('"','\\"'),
243         ObserverTemplates.getdoc(k, "fr_FR"),
244         ObserverTemplates.getdoc(k, "en_EN"),
245         )
246     observers_cont += """                    ),\n"""
247 observers_method = """
248 def F_ObserverTemplate() : return BLOC(condition = " NodeType == 'Template' ",
249                 Template = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "ValuePrinter", into=(%s)),
250 %s                )
251
252 def F_Observers(statut) : return FACT(
253     statut=statut,
254     SELECTION = SIMP(statut="o", defaut=[], typ="TXM", min=0, max="**", homo="SansOrdreNiDoublon", validators=NoRepeat(), into=({choices})),{decl_choices}
255     )
256 """%(observers_list,observers_cont)
257
258 algo_choices = """
259 def AlgorithmParametersInNS(filename):
260     if os.path.exists(filename):
261         fc = open(filename, 'r').readlines()
262         cr = re.compile("^AlgorithmParameters[\s]*=")
263         for ln in fc:
264             if cr.match(ln): return 1
265     return 0
266 AlgorithmParametersInNS.info = u"The Python file has to contain explicitly an \\"AlgorithmParameters\\" variable."
267 def F_AlgorithmParameters(statut, algos_names, fv=NoCheckInNS) : return FACT(
268     statut = statut,
269     Algorithm = SIMP(statut="o", typ = "TXM", into = algos_names ),
270     Parameters = SIMP(statut="f", typ = "TXM", into=("Defaults", "Dict"), defaut="Defaults"),
271     Dict = BLOC ( condition = " Parameters == 'Dict' ",
272         statut="f",
273         data = F_Dict("o", fv),
274         ),{all_algo_defaults}
275     )
276 """
277 one_algo_choices = """
278     Parameters{algo_name} = BLOC (condition = " (Parameters == 'Defaults') and (Algorithm == '{algo_name}') ",
279         statut="f",
280 {algo_parameters}        ),"""
281
282 assim_study = """
283 def F_variables(statut) : return FACT(
284     statut=statut,
285     regles = ( MEME_NOMBRE ('NAMES', 'SIZES')),
286     NAMES = SIMP(statut="o", typ="TXM", max="**", validators=NoRepeat()),
287     SIZES = SIMP(statut="o", typ="I", val_min=1, max="**")
288     )
289 def ChDir(dirname):
290     os.chdir(os.path.abspath(dirname))
291     return 1
292 ChDir.info = u"This has to be a regular directory path."
293
294 ASSIMILATION_STUDY = PROC(nom="ASSIMILATION_STUDY",
295     op=None,
296     repetable           = "n",
297     StudyName           = SIMP(statut="o", typ = "TXM", defaut="ADAO Calculation Case"),
298     StudyRepertory      = SIMP(statut="f", typ = "Repertoire", validators=FunctionVal(ChDir), min=1, max=1),
299     Debug               = SIMP(statut="f", typ = "I", into=(0, 1), defaut=0),
300     AlgorithmParameters = F_AlgorithmParameters("o",({algos_names}), AlgorithmParametersInNS),
301     Background          = F_Background("o", BackgroundInNS),
302     BackgroundError     = F_BackgroundError("o", BackgroundErrorInNS),
303     Observation         = F_Observation("o", ObservationInNS),
304     ObservationError    = F_ObservationError("o", ObservationErrorInNS),
305     ObservationOperator = F_ObservationOperator("o"),
306     EvolutionModel      = F_EvolutionModel("f"),
307     EvolutionError      = F_EvolutionError("f", EvolutionErrorInNS),
308     ControlInput        = F_ControlInput("f"),
309     UserDataInit        = F_Init("f"),
310     UserPostAnalysis    = F_UserPostAnalysis("o"),
311     InputVariables      = F_variables("f"),
312     OutputVariables     = F_variables("f"),
313     Observers           = F_Observers("f")
314     )
315
316 CHECKING_STUDY = PROC(nom="CHECKING_STUDY",
317     op=None,
318     repetable           = "n",
319     StudyName           = SIMP(statut="o", typ = "TXM", defaut="ADAO Checking Case"),
320     StudyRepertory      = SIMP(statut="f", typ = "Repertoire", validators=FunctionVal(ChDir), min=1, max=1),
321     Debug               = SIMP(statut="f", typ = "I", into=(0, 1), defaut=0),
322     AlgorithmParameters = F_AlgorithmParameters("o", ({check_names}), AlgorithmParametersInNS),
323     CheckingPoint       = F_CheckingPoint("o", CheckingPointInNS),
324     Background          = F_Background("f", BackgroundInNS),
325     BackgroundError     = F_BackgroundError("f", BackgroundErrorInNS),
326     Observation         = F_Observation("f", ObservationInNS),
327     ObservationError    = F_ObservationError("f", ObservationErrorInNS),
328     ObservationOperator = F_ObservationOperator("o"),
329     UserDataInit        = F_Init("f"),
330     Observers           = F_Observers("f")
331     )
332 """
333
334 #----------- End of Templates Part ---------------#
335
336
337
338 #----------- Begin generation script -----------#
339
340 # Parse arguments
341 from argparse import ArgumentParser
342 usage = "usage: %(prog)s [options] catalog_path catalog_name"
343 version="%(prog)s 0.1"
344 my_parser = ArgumentParser(usage=usage)
345 my_parser.add_argument('-v', '--version', action='version', version=version)
346 my_parser.add_argument('catalog_path')
347 my_parser.add_argument('catalog_name')
348 args = my_parser.parse_args()
349
350 # Generates into a string
351 mem_file = io.StringIO()
352
353 # Start file
354 from time import strftime
355 mem_file.write(unicode(begin_catalog_file, 'utf-8').format(**{'date':strftime("%Y-%m-%d %H:%M:%S")}))
356
357 # Step initial: on obtient la liste des algos
358 algos_names = ""
359 check_names = ""
360 decl_algos  = ""
361 assim_study_object = daCore.AssimilationStudy.AssimilationStudy()
362 algos_list = assim_study_object.get_available_algorithms()
363 del assim_study_object
364 for algo_name in algos_list:
365   if algo_name in infos.AssimAlgos:
366     logging.debug("An assimilation algorithm is found: " + algo_name)
367     algos_names += "\"" + algo_name + "\", "
368   elif algo_name in infos.CheckAlgos:
369     logging.debug("A checking algorithm is found: " + algo_name)
370     check_names += "\"" + algo_name + "\", "
371   else:
372     logging.debug("This algorithm is not considered: " + algo_name)
373
374 # Step 1: A partir des infos, on cree les fonctions qui vont permettre
375 # d'entrer les donnees utilisateur
376 for data_input_name in infos.DataTypeDict:
377   logging.debug('A data input Type is found: ' + data_input_name)
378   data_name = data_input_name
379   data_into = ""
380   data_default = ""
381   ms_default = ""
382
383   # On recupere les differentes facon d'entrer les donnees
384   for basic_type in infos.DataTypeDict[data_input_name]:
385     data_into += "\"" + basic_type + "\", "
386
387   # On choisit le default
388   data_default = "\"" + infos.DataTypeDefaultDict[data_input_name] + "\""
389   if data_input_name in infos.DataSValueDefaultDict:
390     ms_default = " defaut=\"" + infos.DataSValueDefaultDict[data_input_name] + "\","
391
392   mem_file.write(unicode(data_method, 'utf-8').format(**{
393     'data_name'    : data_name,
394     'data_into'    : data_into,
395     'data_default' : data_default,
396     'ms_default'   : ms_default,
397     'algos_names'  : algos_names+check_names,
398     }))
399
400 # Step 2: On cree les fonctions qui permettent de rentrer les donnees des algorithmes
401 for assim_data_input_name in infos.AssimDataDict:
402   logging.debug("An input function data input is found: " + assim_data_input_name)
403   # assim_name = assim_data_input_name
404   storage = ""
405   choices = ""
406   default_choice = ""
407   decl_choices = ""
408   decl_opts = ""
409   if infos.AssimDataDefaultDict[assim_data_input_name] 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   for choice in infos.AssimDataDict[assim_data_input_name]:
412     choices += "\"" + choice + "\", "
413     decl_choices += assim_data_choice.format(**{'choice_name' : choice})
414     if choice in infos.StoredAssimData:
415       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\"),"
416   default_choice = "\"" + infos.AssimDataDefaultDict[assim_data_input_name] + "\""
417
418   mem_file.write(unicode(assim_data_method, 'utf-8').format(**{
419     'assim_name'     : assim_data_input_name,
420     'storage'        : storage,
421     'choices'        : choices,
422     'decl_choices'   : decl_choices,
423     'default_choice' : default_choice,
424     }))
425
426 # Step 3: On ajoute les fonctions representant les options possibles
427 for opt_name in infos.OptDict:
428   logging.debug("An optional node is found: " + opt_name)
429   data_name = opt_name
430   data_into = ""
431   data_default = ""
432   ms_default = ""
433
434   for choice in infos.OptDict[opt_name]:
435     data_into += "\"" + choice + "\", "
436
437   # On choisit le default
438   data_default = "\"" + infos.OptDefaultDict[opt_name] + "\""
439   if opt_name in infos.DataSValueDefaultDict:
440     ms_default = " defaut=\"" + infos.DataSValueDefaultDict[opt_name] + "\","
441
442   mem_file.write(unicode(data_method, 'utf-8').format(**{
443     'data_name'    : data_name,
444     'data_into'    : data_into,
445     'data_default' : data_default,
446     'ms_default'   : ms_default,
447     'algos_names'  : algos_names+check_names,
448     }))
449
450 # Step 4: On ajoute la methode optionnelle init
451 # TODO uniformiser avec le step 3
452 mem_file.write(unicode(init_method, 'utf-8'))
453
454 # Step 5: Add observers
455 decl_choices = ""
456 for obs_var in infos.ObserversList:
457   decl_choices += observers_choice.format(**{'var_name':obs_var})
458 mem_file.write(unicode(observers_method, 'utf-8').format(**{
459   'choices' : infos.ObserversList,
460   'decl_choices' : decl_choices,
461   }))
462
463 # Step 5: Add algorithmic choices
464
465 all_names = eval((algos_names+check_names))
466 all_algo_defaults = ""
467 for algo in all_names:
468     assim_study_object = daCore.AssimilationStudy.AssimilationStudy()
469     assim_study_object.setAlgorithmParameters(Algorithm=algo)
470     par_dict = assim_study_object.get("AlgorithmRequiredParameters",False)
471     par_keys = sorted(par_dict.keys())
472     algo_parameters = ""
473     for pn in par_keys:
474         if pn in ("StoreInternalVariables", "PlotAndSave", "ResultFile", "ResultTitle", "ResultLabel"): continue # Cles a supprimer
475         pt = par_dict[pn]["typecast"] # Pointeur de type
476         pd = par_dict[pn]["default"]
477         pm = par_dict[pn]["message"]
478         if "minval" in par_dict[pn] and par_dict[pn]["minval"] is not None:
479             vi = ", val_min=%s"%par_dict[pn]["minval"]
480         else:
481             vi = ""
482         if "minval" in par_dict[pn] and par_dict[pn]["maxval"] is not None:
483             vs = ", val_max=%s"%par_dict[pn]["maxval"]
484         else:
485             vs = ""
486         if   pt is int:
487             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)
488         elif pt is float:
489             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)
490         elif pt is bool:
491             algo_parameters += """        %s = SIMP(statut="f", typ="I", min=1, max=1, defaut=%s, fr="%s"),\n"""%(pn,int(pd),pm)
492         elif pt is str and "listval" in par_dict[pn]:
493             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)
494         elif pt is tuple and "listval" in par_dict[pn]:
495             algo_parameters += """        %s = SIMP(statut="f", typ="TXM", max="**", into=%s, fr="%s"),\n"""%(pn,par_dict[pn]["listval"],pm)
496         else:
497             algo_parameters += """        %s = SIMP(statut="f", typ="TXM", fr="%s"),\n"""%(pn,pm)
498     del assim_study_object
499     if algo_parameters != "":
500         all_algo_defaults += one_algo_choices.format(**{
501             'algo_name':algo,
502             'algo_parameters':algo_parameters,
503             })
504 mem_file.write(unicode(algo_choices, 'utf-8').format(**{'all_algo_defaults':unicode(all_algo_defaults, 'utf-8')}))
505
506 # Final step: Add algorithm and assim_study
507 mem_file.write(unicode(assim_study, 'utf-8').format(**{
508   'algos_names':algos_names,
509   'check_names':check_names,
510   'decl_algos':decl_algos,
511   }))
512
513 # Write file
514 if sys.version_info.major > 2:
515     with open(os.path.join(args.catalog_path, args.catalog_name), "w", encoding='utf8') as final_file:
516         final_file.write(mem_file.getvalue())
517 else:
518     with open(os.path.join(args.catalog_path, args.catalog_name), "wr") as final_file:
519         final_file.write(mem_file.getvalue().encode('utf-8'))
520 mem_file.close()