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