1 # -*- coding: utf-8 -*-
3 # Copyright (C) 2008-2018 EDF R&D
5 # This file is part of SALOME ADAO module
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.
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.
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
21 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 # Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
33 logging.basicConfig(level=logging.WARNING)
35 if sys.version_info.major > 2:
36 def unicode(text, encoding='utf-8'): return text
38 print("-- Starting AdaoCalatogGenerator.py --")
43 import daYacsSchemaCreator
44 import daCore.AssimilationStudy
45 import daYacsSchemaCreator.infos_daComposant as infos
47 logging.fatal("Import of ADAO python modules failed !" +
48 "\n add ADAO python installation directory in your PYTHONPATH")
52 #----------- Templates Part ---------------#
53 begin_catalog_file = """# -*- coding: utf-8 -*-
55 # Copyright (C) 2008-2018 EDF R&D
57 # This file is part of SALOME ADAO module
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.
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.
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
73 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
75 # Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
77 # --------------------------------------------------------
78 # Generated by AdaoCatalogGenerator on {date}
79 # --------------------------------------------------------
88 regles = ( AU_MOINS_UN ('ASSIMILATION_STUDY','CHECKING_STUDY'), AU_PLUS_UN ('ASSIMILATION_STUDY','CHECKING_STUDY')),
90 VERSION_CATALOGUE='%s'
92 def NoCheckInNS(filename):
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]*\(")
100 if cr.match(ln): return 1
101 cr = re.compile("^DirectOperator[\s]*=")
103 if cr.match(ln): return 1
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]*\(")
111 if cr.match(ln): return 1
112 cr = re.compile("^TangentOperator[\s]*=")
114 if cr.match(ln): return 1
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]*\(")
122 if cr.match(ln): return 1
123 cr = re.compile("^AdjointOperator[\s]*=")
125 if cr.match(ln): return 1
127 AdjointOperatorInNS.info = u"The Python file has to contain explicitly an \\"AdjointOperator\\" function definition with only one pair of vectors as argument."
128 """%(module_version.name,module_version.cata)
130 # 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)
131 # validators=[OnlyStr(), FileExtVal('py'), FunctionVal(fv)]
133 def F_{data_name}(statut, fv=NoCheckInNS) : return FACT(
135 FROM = SIMP(statut = "o", typ = "TXM", into=({data_into}), defaut={data_default}),
136 SCRIPT_DATA = BLOC ( condition = " FROM in ( 'Script', ) ",
137 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"),
139 STRING_DATA = BLOC ( condition = " FROM in ( 'String', ) ",
140 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"),
142 SCRIPTWITHFUNCTIONS_DATA = BLOC ( condition = " FROM in ( 'ScriptWithFunctions', ) ",
143 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"),
145 SCRIPTWITHONEFUNCTION_DATA = BLOC ( condition = " FROM in ( 'ScriptWithOneFunction', ) ",
146 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"),
147 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"),
148 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"),
149 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"),
150 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"),
152 SCRIPTWITHSWITCH_DATA = BLOC ( condition = " FROM in ( 'ScriptWithSwitch', ) ",
153 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"),
155 TEMPLATE_DATA = BLOC (condition = " FROM in ( 'Template', ) ",
156 Template = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "AnalysisPrinter", into=("AnalysisPrinter", "AnalysisSaver", "AnalysisPrinterAndSaver")),
157 AnalysisPrinter = BLOC (condition = " Template == 'AnalysisPrinter' ",
158 ValueTemplate = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "import numpy\\nxa=numpy.ravel(ADD.get('Analysis')[-1])\\nprint('Analysis:',xa)" ),
160 AnalysisSaver = BLOC (condition = " Template == 'AnalysisSaver' ",
161 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)" ),
163 AnalysisPrinterAndSaver = BLOC (condition = " Template == 'AnalysisPrinterAndSaver' ",
164 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 def F_InitChoice() : return ("Background",
175 "ObservationOperator",
178 "AlgorithmParameters",
182 def F_Init(statut) : return FACT(statut = statut,
183 INIT_FILE = SIMP(statut = "o", typ = "FichierNoAbs", validators=[OnlyStr(), FileExtVal('py')]),
184 TARGET_LIST = SIMP(statut = "o", typ = "TXM", min=1, max="**", into=F_InitChoice(), validators=(VerifExiste(2))),
188 assim_data_method = """
189 def {assim_name}InNS(filename):
190 if os.path.exists(filename):
191 fc = open(filename, 'r').readlines()
192 cr = re.compile("^{assim_name}[\s]*=")
194 if cr.match(ln): return 1
196 {assim_name}InNS.info = u"The Python file has to contain explicitly a \\"{assim_name}\\" variable."
197 def F_{assim_name}(statut, fv=NoCheckInNS) : return FACT(
200 INPUT_TYPE = SIMP(statut="o", typ = "TXM", into=({choices}), defaut={default_choice}),{decl_choices}
204 assim_data_choice = """
205 {choice_name} = BLOC ( condition = " INPUT_TYPE in ( '{choice_name}', ) ",
206 data = F_{choice_name}("o", fv),
209 observers_choice = """
210 {var_name} = BLOC (condition=" '{var_name}' in set(SELECTION) ",
211 {var_name}_data = FACT(statut = "o",
212 Scheduler = SIMP(statut = "f", typ = "TXM"),
213 Info = SIMP(statut = "o", typ = "TXM", defaut = "{var_name}"),
214 NodeType = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "Template", into=("String", "Script", "Template")),
215 PythonScript = BLOC (condition = " NodeType == 'String' ",
216 Value = SIMP(statut = "o", typ = "TXM")
218 UserFile = BLOC (condition = " NodeType == 'Script' ",
219 Value = SIMP(statut = "o", typ = "FichierNoAbs", validators=[OnlyStr(), FileExtVal('py')])
221 ObserverTemplate = F_ObserverTemplate(),
225 from daCore.Templates import ObserverTemplates
226 observers_list = ObserverTemplates.keys_in_presentation_order()
227 observers_list = '"%s"'%str('", "'.join(observers_list))
229 for k in ObserverTemplates.keys_in_presentation_order():
230 observers_cont += """ %s = BLOC (condition = " Template == '%s' ",\n"""%(k,k)
231 observers_cont += """ ValueTemplate = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "%s", fr="%s", ang="%s" ),\n"""%(
232 ObserverTemplates[k].replace("\n","\\n").replace('"','\\"'),
233 ObserverTemplates.getdoc(k, "fr_FR"),
234 ObserverTemplates.getdoc(k, "en_EN"),
236 observers_cont += """ ),\n"""
237 observers_method = """
238 def F_ObserverTemplate() : return BLOC(condition = " NodeType == 'Template' ",
239 Template = SIMP(statut = "o", typ = "TXM", min=1, max=1, defaut = "ValuePrinter", into=(%s)),
242 def F_Observers(statut) : return FACT(
244 SELECTION = SIMP(statut="o", defaut=[], typ="TXM", min=0, max="**", homo="SansOrdreNiDoublon", validators=NoRepeat(), into=({choices})),{decl_choices}
246 """%(observers_list,observers_cont)
249 def AlgorithmParametersInNS(filename):
250 if os.path.exists(filename):
251 fc = open(filename, 'r').readlines()
252 cr = re.compile("^AlgorithmParameters[\s]*=")
254 if cr.match(ln): return 1
256 AlgorithmParametersInNS.info = u"The Python file has to contain explicitly an \\"AlgorithmParameters\\" variable."
257 def F_AlgorithmParameters(statut, algos_names, fv=NoCheckInNS) : return FACT(
259 Algorithm = SIMP(statut="o", typ = "TXM", into = algos_names ),
260 Parameters = SIMP(statut="f", typ = "TXM", into=("Defaults", "Dict"), defaut="Defaults"),
261 Dict = BLOC ( condition = " Parameters == 'Dict' ",
263 data = F_Dict("o", fv),
264 ),{all_algo_defaults}
267 one_algo_choices = """
268 Parameters{algo_name} = BLOC (condition = " (Parameters == 'Defaults') and (Algorithm == '{algo_name}') ",
270 {algo_parameters} ),"""
273 def F_variables(statut) : return FACT(
275 regles = ( MEME_NOMBRE ('NAMES', 'SIZES')),
276 NAMES = SIMP(statut="o", typ="TXM", max="**", validators=NoRepeat()),
277 SIZES = SIMP(statut="o", typ="I", val_min=1, max="**")
280 os.chdir(os.path.abspath(dirname))
282 ChDir.info = u"This has to be a regular directory path."
284 ASSIMILATION_STUDY = PROC(nom="ASSIMILATION_STUDY",
287 StudyName = SIMP(statut="o", typ = "TXM", defaut="ADAO Calculation Case"),
288 StudyRepertory = SIMP(statut="f", typ = "Repertoire", validators=FunctionVal(ChDir), min=1, max=1),
289 Debug = SIMP(statut="f", typ = "I", into=(0, 1), defaut=0),
290 AlgorithmParameters = F_AlgorithmParameters("o",({algos_names}), AlgorithmParametersInNS),
291 Background = F_Background("o", BackgroundInNS),
292 BackgroundError = F_BackgroundError("o", BackgroundErrorInNS),
293 Observation = F_Observation("o", ObservationInNS),
294 ObservationError = F_ObservationError("o", ObservationErrorInNS),
295 ObservationOperator = F_ObservationOperator("o"),
296 EvolutionModel = F_EvolutionModel("f"),
297 EvolutionError = F_EvolutionError("f", EvolutionErrorInNS),
298 ControlInput = F_ControlInput("f"),
299 UserDataInit = F_Init("f"),
300 UserPostAnalysis = F_UserPostAnalysis("o"),
301 InputVariables = F_variables("f"),
302 OutputVariables = F_variables("f"),
303 Observers = F_Observers("f")
306 CHECKING_STUDY = PROC(nom="CHECKING_STUDY",
309 StudyName = SIMP(statut="o", typ = "TXM", defaut="ADAO Checking Case"),
310 StudyRepertory = SIMP(statut="f", typ = "Repertoire", validators=FunctionVal(ChDir), min=1, max=1),
311 Debug = SIMP(statut="f", typ = "I", into=(0, 1), defaut=0),
312 AlgorithmParameters = F_AlgorithmParameters("o", ({check_names}), AlgorithmParametersInNS),
313 CheckingPoint = F_CheckingPoint("o", CheckingPointInNS),
314 BackgroundError = F_BackgroundError("f", BackgroundErrorInNS),
315 Observation = F_Observation("f", ObservationInNS),
316 ObservationError = F_ObservationError("f", ObservationErrorInNS),
317 ObservationOperator = F_ObservationOperator("o"),
318 UserDataInit = F_Init("f"),
319 Observers = F_Observers("f")
323 #----------- End of Templates Part ---------------#
327 #----------- Begin generation script -----------#
330 from argparse import ArgumentParser
331 usage = "usage: %(prog)s [options] catalog_path catalog_name"
332 version="%(prog)s 0.1"
333 my_parser = ArgumentParser(usage=usage)
334 my_parser.add_argument('-v', '--version', action='version', version=version)
335 my_parser.add_argument('catalog_path')
336 my_parser.add_argument('catalog_name')
337 args = my_parser.parse_args()
339 # Generates into a string
340 mem_file = io.StringIO()
343 from time import strftime
344 mem_file.write(unicode(begin_catalog_file, 'utf-8').format(**{'date':strftime("%Y-%m-%d %H:%M:%S")}))
346 # Step initial: on obtient la liste des algos
350 assim_study_object = daCore.AssimilationStudy.AssimilationStudy()
351 algos_list = assim_study_object.get_available_algorithms()
352 del assim_study_object
353 for algo_name in algos_list:
354 if algo_name in infos.AssimAlgos:
355 logging.debug("An assimilation algorithm is found: " + algo_name)
356 algos_names += "\"" + algo_name + "\", "
357 elif algo_name in infos.CheckAlgos:
358 logging.debug("A checking algorithm is found: " + algo_name)
359 check_names += "\"" + algo_name + "\", "
361 logging.debug("This algorithm is not considered: " + algo_name)
363 # Step 1: A partir des infos, on cree les fonctions qui vont permettre
364 # d'entrer les donnees utilisateur
365 for data_input_name in infos.DataTypeDict:
366 logging.debug('A data input Type is found: ' + data_input_name)
367 data_name = data_input_name
372 # On recupere les differentes facon d'entrer les donnees
373 for basic_type in infos.DataTypeDict[data_input_name]:
374 data_into += "\"" + basic_type + "\", "
376 # On choisit le default
377 data_default = "\"" + infos.DataTypeDefaultDict[data_input_name] + "\""
378 if data_input_name in infos.DataSValueDefaultDict:
379 ms_default = " defaut=\"" + infos.DataSValueDefaultDict[data_input_name] + "\","
381 mem_file.write(unicode(data_method, 'utf-8').format(**{
382 'data_name' : data_name,
383 'data_into' : data_into,
384 'data_default' : data_default,
385 'ms_default' : ms_default,
386 'algos_names' : algos_names+check_names,
389 # Step 2: On cree les fonctions qui permettent de rentrer les donnees des algorithmes
390 for assim_data_input_name in infos.AssimDataDict:
391 logging.debug("An input function data input is found: " + assim_data_input_name)
392 # assim_name = assim_data_input_name
398 if infos.AssimDataDefaultDict[assim_data_input_name] in infos.StoredAssimData:
399 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\"),"
400 for choice in infos.AssimDataDict[assim_data_input_name]:
401 choices += "\"" + choice + "\", "
402 decl_choices += assim_data_choice.format(**{'choice_name' : choice})
403 if choice in infos.StoredAssimData:
404 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\"),"
405 default_choice = "\"" + infos.AssimDataDefaultDict[assim_data_input_name] + "\""
407 mem_file.write(unicode(assim_data_method, 'utf-8').format(**{
408 'assim_name' : assim_data_input_name,
411 'decl_choices' : decl_choices,
412 'default_choice' : default_choice,
415 # Step 3: On ajoute les fonctions representant les options possibles
416 for opt_name in infos.OptDict:
417 logging.debug("An optional node is found: " + opt_name)
423 for choice in infos.OptDict[opt_name]:
424 data_into += "\"" + choice + "\", "
426 # On choisit le default
427 data_default = "\"" + infos.OptDefaultDict[opt_name] + "\""
428 if opt_name in infos.DataSValueDefaultDict:
429 ms_default = " defaut=\"" + infos.DataSValueDefaultDict[opt_name] + "\","
431 mem_file.write(unicode(data_method, 'utf-8').format(**{
432 'data_name' : data_name,
433 'data_into' : data_into,
434 'data_default' : data_default,
435 'ms_default' : ms_default,
436 'algos_names' : algos_names+check_names,
439 # Step 4: On ajoute la methode optionnelle init
440 # TODO uniformiser avec le step 3
441 mem_file.write(unicode(init_method, 'utf-8'))
443 # Step 5: Add observers
445 for obs_var in infos.ObserversList:
446 decl_choices += observers_choice.format(**{'var_name':obs_var})
447 mem_file.write(unicode(observers_method, 'utf-8').format(**{
448 'choices' : infos.ObserversList,
449 'decl_choices' : decl_choices,
452 # Step 5: Add algorithmic choices
454 all_names = eval((algos_names+check_names))
455 all_algo_defaults = ""
456 for algo in all_names:
457 assim_study_object = daCore.AssimilationStudy.AssimilationStudy()
458 assim_study_object.setAlgorithmParameters(Algorithm=algo)
459 par_dict = assim_study_object.get("AlgorithmRequiredParameters",False)
460 par_keys = sorted(par_dict.keys())
463 if pn in ("StoreInternalVariables", "PlotAndSave", "ResultFile", "ResultTitle", "ResultLabel"): continue # Cles a supprimer
464 pt = par_dict[pn]["typecast"] # Pointeur de type
465 pd = par_dict[pn]["default"]
466 pm = par_dict[pn]["message"]
467 if "minval" in par_dict[pn] and par_dict[pn]["minval"] is not None:
468 vi = ", val_min=%s"%par_dict[pn]["minval"]
471 if "minval" in par_dict[pn] and par_dict[pn]["maxval"] is not None:
472 vs = ", val_max=%s"%par_dict[pn]["maxval"]
476 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)
478 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)
480 algo_parameters += """ %s = SIMP(statut="f", typ="I", min=1, max=1, defaut=%s, fr="%s"),\n"""%(pn,int(pd),pm)
481 elif pt is str and "listval" in par_dict[pn]:
482 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)
483 elif pt is tuple and "listval" in par_dict[pn]:
484 algo_parameters += """ %s = SIMP(statut="f", typ="TXM", max="**", into=%s, fr="%s"),\n"""%(pn,par_dict[pn]["listval"],pm)
486 algo_parameters += """ %s = SIMP(statut="f", typ="TXM", fr="%s"),\n"""%(pn,pm)
487 del assim_study_object
488 if algo_parameters != "":
489 all_algo_defaults += one_algo_choices.format(**{
491 'algo_parameters':algo_parameters,
493 mem_file.write(unicode(algo_choices, 'utf-8').format(**{'all_algo_defaults':unicode(all_algo_defaults, 'utf-8')}))
495 # Final step: Add algorithm and assim_study
496 mem_file.write(unicode(assim_study, 'utf-8').format(**{
497 'algos_names':algos_names,
498 'check_names':check_names,
499 'decl_algos':decl_algos,
503 if sys.version_info.major > 2:
504 with open(os.path.join(args.catalog_path, args.catalog_name), "w", encoding='utf8') as final_file:
505 final_file.write(mem_file.getvalue())
507 with open(os.path.join(args.catalog_path, args.catalog_name), "wr") as final_file:
508 final_file.write(mem_file.getvalue().encode('utf-8'))