1 #-*-coding:iso-8859-1-*-
3 # Copyright (C) 2008-2017 EDF R&D
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License.
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Lesser General Public License for more details.
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 # Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
24 Interface de scripting pour une étude ADAO
26 __author__ = "Jean-Philippe ARGAUD"
30 from daCore import AssimilationStudy, Templates
32 # ==============================================================================
35 Creation TUI d'un cas ADAO
37 def __init__(self, name = ""):
38 self.__adaoStudy = AssimilationStudy.AssimilationStudy(name)
39 self.__dumper = _DumpLogger(name)
41 # -----------------------------------------------------------
47 DiagonalSparseMatrix = None,
52 ScalarSparseMatrix = None,
57 ThreeFunctions = None,
62 "Interface unique de définition de variables d'entrées par argument"
63 self.__dumper.register("set",dir(),locals(),None,True)
65 if Concept == "Background":
66 self.setBackground(Vector,VectorSerie,Script,Stored)
67 elif Concept == "BackgroundError":
68 self.setBackgroundError(Matrix,ScalarSparseMatrix,
69 DiagonalSparseMatrix,Script,Stored)
70 elif Concept == "CheckingPoint":
71 self.setCheckingPoint(Vector,VectorSerie,Script,Stored)
72 elif Concept == "ControlModel":
73 self.setControlModel(Matrix,OneFunction,ThreeFunctions,
74 Parameters,Script,Stored)
75 elif Concept == "ControlInput":
76 self.setControlInput(Vector,VectorSerie,Script,Stored)
77 elif Concept == "EvolutionError":
78 self.setEvolutionError(Matrix,ScalarSparseMatrix,
79 DiagonalSparseMatrix,Script,Stored)
80 elif Concept == "EvolutionModel":
81 self.setEvolutionModel(Matrix,OneFunction,ThreeFunctions,
82 Parameters,Script,Stored)
83 elif Concept == "Observation":
84 self.setObservation(Vector,VectorSerie,Script,Stored)
85 elif Concept == "ObservationError":
86 self.setObservationError(Matrix,ScalarSparseMatrix,
87 DiagonalSparseMatrix,Script,Stored)
88 elif Concept == "ObservationOperator":
89 self.setObservationOperator(Matrix,OneFunction,ThreeFunctions,
90 AppliedInXb, Parameters,Script,Stored)
91 elif Concept == "AlgorithmParameters":
92 self.setAlgorithmParameters(Algorithm,Parameters,Script)
93 elif Concept == "Debug":
95 elif Concept == "NoDebug":
97 elif Concept == "Observer":
98 self.setObserver(Variable,Template,String,Script,Info)
100 raise ValueError("the variable named '%s' is not allowed."%str(Concept))
101 except Exception as e:
102 if isinstance(e, SyntaxError): msg = "at %s: %s"%(e.offset, e.text)
104 raise ValueError("during settings, the following error occurs:\n\n%s %s\n\nSee also the potential messages, which can show the origin of the above error, in the launching terminal."%(str(e),msg))
106 # -----------------------------------------------------------
114 "Définition d'une entrée de calcul"
115 self.__dumper.register("setBackground", dir(), locals())
116 if Script is not None:
117 __Vector, __PersistentVector = None, None
119 __PersistentVector = _ImportFromScript(Script).getvalue( "Background" )
121 __Vector = _ImportFromScript(Script).getvalue( "Background" )
123 __Vector, __PersistentVector = Vector, VectorSerie
125 self.__adaoStudy.setBackground(
127 asPersistentVector = __PersistentVector,
131 def setBackgroundError(
134 ScalarSparseMatrix = None,
135 DiagonalSparseMatrix = None,
138 "Définition d'une entrée de calcul"
139 self.__dumper.register("setBackgroundError", dir(), locals())
140 if Script is not None:
141 __Covariance, __Scalar, __Vector = None, None, None
142 if ScalarSparseMatrix:
143 __Scalar = _ImportFromScript(Script).getvalue( "BackgroundError" )
144 elif DiagonalSparseMatrix:
145 __Vector = _ImportFromScript(Script).getvalue( "BackgroundError" )
147 __Covariance = _ImportFromScript(Script).getvalue( "BackgroundError" )
149 __Covariance, __Scalar, __Vector = Matrix, ScalarSparseMatrix, DiagonalSparseMatrix
151 self.__adaoStudy.setBackgroundError(
152 asCovariance = __Covariance,
153 asEyeByScalar = __Scalar,
154 asEyeByVector = __Vector,
158 def setCheckingPoint(
164 "Définition d'une entrée de vérification"
165 self.__dumper.register("setCheckingPoint", dir(), locals())
166 if Script is not None:
167 __Vector, __PersistentVector = None, None
169 __PersistentVector = _ImportFromScript(Script).getvalue( "CheckingPoint" )
171 __Vector = _ImportFromScript(Script).getvalue( "CheckingPoint" )
173 __Vector, __PersistentVector = Vector, VectorSerie
175 self.__adaoStudy.setBackground(
177 asPersistentVector = __PersistentVector,
185 ThreeFunctions = None,
189 "Définition d'une entrée de calcul"
190 self.__dumper.register("setControlModel", dir(), locals())
192 if (Parameters is not None) and isinstance(Parameters, dict):
193 if "DifferentialIncrement" in Parameters:
194 __Parameters["withIncrement"] = Parameters["DifferentialIncrement"]
195 if "CenteredFiniteDifference" in Parameters:
196 __Parameters["withCenteredDF"] = Parameters["CenteredFiniteDifference"]
197 if Script is not None:
198 __Matrix, __Function = None, None
200 __Matrix = _ImportFromScript(Script).getvalue( "ObservationOperator" )
202 __Function = { "Direct":_ImportFromScript(Script).getvalue( "DirectOperator" ) }
203 __Function.update({"useApproximatedDerivatives":True})
204 __Function.update(__Parameters)
207 "Direct" :_ImportFromScript(Script).getvalue( "DirectOperator" ),
208 "Tangent":_ImportFromScript(Script).getvalue( "TangentOperator" ),
209 "Adjoint":_ImportFromScript(Script).getvalue( "AdjointOperator" ),
211 __Function.update(__Parameters)
214 if OneFunction is not None:
215 __Function = { "Direct":OneFunction }
216 __Function.update({"useApproximatedDerivatives":True})
217 __Function.update(__Parameters)
218 elif ThreeFunctions is not None:
219 if (not isinstance(ThreeFunctions, dict)) or \
220 "Direct" not in ThreeFunctions or \
221 "Tangent" not in ThreeFunctions or \
222 "Adjoint" not in ThreeFunctions:
223 raise ValueError("ThreeFunctions has to be a dictionnary and to have the 3 keys Direct, Tangent, Adjoint")
224 __Function = ThreeFunctions
225 __Function.update(__Parameters)
229 self.__adaoStudy.setControlModel(
230 asFunction = __Function,
241 "Définition d'une entrée de calcul"
242 self.__dumper.register("setControlInput", dir(), locals())
243 if Script is not None:
244 __Vector, __PersistentVector = None, None
246 __PersistentVector = _ImportFromScript(Script).getvalue( "ControlInput" )
248 __Vector = _ImportFromScript(Script).getvalue( "ControlInput" )
250 __Vector, __PersistentVector = Vector, VectorSerie
252 self.__adaoStudy.setControlInput(
254 asPersistentVector = __PersistentVector,
258 def setEvolutionError(
261 ScalarSparseMatrix = None,
262 DiagonalSparseMatrix = None,
265 "Définition d'une entrée de calcul"
266 self.__dumper.register("setEvolutionError", dir(), locals())
267 if Script is not None:
268 __Covariance, __Scalar, __Vector = None, None, None
269 if ScalarSparseMatrix:
270 __Scalar = _ImportFromScript(Script).getvalue( "EvolutionError" )
271 elif DiagonalSparseMatrix:
272 __Vector = _ImportFromScript(Script).getvalue( "EvolutionError" )
274 __Covariance = _ImportFromScript(Script).getvalue( "EvolutionError" )
276 __Covariance, __Scalar, __Vector = Matrix, ScalarSparseMatrix, DiagonalSparseMatrix
278 self.__adaoStudy.setEvolutionError(
279 asCovariance = __Covariance,
280 asEyeByScalar = __Scalar,
281 asEyeByVector = __Vector,
285 def setEvolutionModel(
289 ThreeFunctions = None,
293 "Définition d'une entrée de calcul"
294 self.__dumper.register("setEvolutionModel", dir(), locals())
296 if (Parameters is not None) and isinstance(Parameters, dict):
297 if "DifferentialIncrement" in Parameters:
298 __Parameters["withIncrement"] = Parameters["DifferentialIncrement"]
299 if "CenteredFiniteDifference" in Parameters:
300 __Parameters["withCenteredDF"] = Parameters["CenteredFiniteDifference"]
301 if "EnableMultiProcessing" in Parameters:
302 __Parameters["withmpEnabled"] = Parameters["EnableMultiProcessing"]
303 if "NumberOfProcesses" in Parameters:
304 __Parameters["withmpWorkers"] = Parameters["NumberOfProcesses"]
305 if Script is not None:
306 __Matrix, __Function = None, None
308 __Matrix = _ImportFromScript(Script).getvalue( "ObservationOperator" )
310 __Function = { "Direct":_ImportFromScript(Script).getvalue( "DirectOperator" ) }
311 __Function.update({"useApproximatedDerivatives":True})
312 __Function.update(__Parameters)
315 "Direct" :_ImportFromScript(Script).getvalue( "DirectOperator" ),
316 "Tangent":_ImportFromScript(Script).getvalue( "TangentOperator" ),
317 "Adjoint":_ImportFromScript(Script).getvalue( "AdjointOperator" ),
319 __Function.update(__Parameters)
322 if OneFunction is not None:
323 __Function = { "Direct":OneFunction }
324 __Function.update({"useApproximatedDerivatives":True})
325 __Function.update(__Parameters)
326 elif ThreeFunctions is not None:
327 if (not isinstance(ThreeFunctions, dict)) or \
328 "Direct" not in ThreeFunctions or \
329 "Tangent" not in ThreeFunctions or \
330 "Adjoint" not in ThreeFunctions:
331 raise ValueError("ThreeFunctions has to be a dictionnary and to have the 3 keys Direct, Tangent, Adjoint")
332 __Function = ThreeFunctions
333 __Function.update(__Parameters)
337 self.__adaoStudy.setEvolutionModel(
338 asFunction = __Function,
349 "Définition d'une entrée de calcul"
350 self.__dumper.register("setObservation", dir(), locals())
351 if Script is not None:
352 __Vector, __PersistentVector = None, None
354 __PersistentVector = _ImportFromScript(Script).getvalue( "Observation" )
356 __Vector = _ImportFromScript(Script).getvalue( "Observation" )
358 __Vector, __PersistentVector = Vector, VectorSerie
360 self.__adaoStudy.setObservation(
362 asPersistentVector = __PersistentVector,
366 def setObservationError(
369 ScalarSparseMatrix = None,
370 DiagonalSparseMatrix = None,
373 "Définition d'une entrée de calcul"
374 self.__dumper.register("setObservationError", dir(), locals())
375 if Script is not None:
376 __Covariance, __Scalar, __Vector = None, None, None
377 if ScalarSparseMatrix:
378 __Scalar = _ImportFromScript(Script).getvalue( "ObservationError" )
379 elif DiagonalSparseMatrix:
380 __Vector = _ImportFromScript(Script).getvalue( "ObservationError" )
382 __Covariance = _ImportFromScript(Script).getvalue( "ObservationError" )
384 __Covariance, __Scalar, __Vector = Matrix, ScalarSparseMatrix, DiagonalSparseMatrix
386 self.__adaoStudy.setObservationError(
387 asCovariance = __Covariance,
388 asEyeByScalar = __Scalar,
389 asEyeByVector = __Vector,
393 def setObservationOperator(
397 ThreeFunctions = None,
402 "Définition d'une entrée de calcul"
403 self.__dumper.register("setObservationOperator", dir(), locals())
405 if (Parameters is not None) and isinstance(Parameters, dict):
406 if "DifferentialIncrement" in Parameters:
407 __Parameters["withIncrement"] = Parameters["DifferentialIncrement"]
408 if "CenteredFiniteDifference" in Parameters:
409 __Parameters["withCenteredDF"] = Parameters["CenteredFiniteDifference"]
410 if "EnableMultiProcessing" in Parameters:
411 __Parameters["EnableMultiProcessing"] = Parameters["EnableMultiProcessing"]
412 __Parameters["withmpEnabled"] = Parameters["EnableMultiProcessing"]
413 if "NumberOfProcesses" in Parameters:
414 __Parameters["NumberOfProcesses"] = Parameters["NumberOfProcesses"]
415 __Parameters["withmpWorkers"] = Parameters["NumberOfProcesses"]
416 if Script is not None:
417 __Matrix, __Function = None, None
419 __Matrix = _ImportFromScript(Script).getvalue( "ObservationOperator" )
421 __Function = { "Direct":_ImportFromScript(Script).getvalue( "DirectOperator" ) }
422 __Function.update({"useApproximatedDerivatives":True})
423 __Function.update(__Parameters)
426 "Direct" :_ImportFromScript(Script).getvalue( "DirectOperator" ),
427 "Tangent":_ImportFromScript(Script).getvalue( "TangentOperator" ),
428 "Adjoint":_ImportFromScript(Script).getvalue( "AdjointOperator" ),
430 __Function.update(__Parameters)
433 if OneFunction is not None:
434 __Function = { "Direct":OneFunction }
435 __Function.update({"useApproximatedDerivatives":True})
436 __Function.update(__Parameters)
437 elif ThreeFunctions is not None:
438 if (not isinstance(ThreeFunctions, dict)) or \
439 "Direct" not in ThreeFunctions or \
440 "Tangent" not in ThreeFunctions or \
441 "Adjoint" not in ThreeFunctions:
442 raise ValueError("ThreeFunctions has to be a dictionnary and to have the 3 keys Direct, Tangent, Adjoint")
443 __Function = ThreeFunctions
444 __Function.update(__Parameters)
447 if AppliedInXb is not None:
448 __appliedToX = {"HXb":AppliedInXb}
452 self.__adaoStudy.setObservationOperator(
453 asFunction = __Function,
455 appliedToX = __appliedToX,
459 # -----------------------------------------------------------
461 def setAlgorithmParameters(
466 "Définition d'un paramétrage du calcul"
467 self.__dumper.register("setAlgorithmParameters", dir(), locals())
468 if Script is not None:
469 __Algorithm = _ImportFromScript(Script).getvalue( "Algorithm" )
470 __Parameters = _ImportFromScript(Script).getvalue( "AlgorithmParameters", "Parameters" )
472 __Algorithm = Algorithm
473 __Parameters = Parameters
474 self.__adaoStudy.setAlgorithm( choice = __Algorithm )
475 self.__adaoStudy.setAlgorithmParameters( asDico = __Parameters )
478 "Définition d'un paramétrage du calcul"
479 self.__dumper.register("setDebug",dir(),locals())
480 return self.__adaoStudy.setDebug()
482 def setNoDebug(self):
483 "Définition d'un paramétrage du calcul"
484 self.__dumper.register("setNoDebug",dir(),locals())
485 return self.__adaoStudy.unsetDebug()
494 "Définition d'un paramétrage du calcul"
495 self.__dumper.register("setObserver", dir(), locals())
497 raise ValueError("setting an observer has to be done over a variable name, not over None.")
499 __Variable = str(Variable)
501 __Info = str(Variable)
505 if String is not None:
506 __FunctionText = String
507 elif (Template is not None) and (Template in Templates.ObserverTemplates):
508 __FunctionText = Templates.ObserverTemplates[Template]
509 elif Script is not None:
510 __FunctionText = _ImportFromScript(Script).getstring()
513 __Function = _ObserverF(__FunctionText)
515 self.__adaoStudy.setDataObserver(
516 VariableName = __Variable,
517 HookFunction = __Function.getfunc(),
518 HookParameters = __Info,
521 # -----------------------------------------------------------
523 def executePythonScheme(self):
524 "Lancement du calcul"
525 self.__dumper.register("executePythonScheme", dir(), locals())
527 self.__adaoStudy.analyze()
528 except Exception as e:
529 if isinstance(e, SyntaxError): msg = "at %s: %s"%(e.offset, e.text)
531 raise ValueError("during execution, the following error occurs:\n\n%s %s\n\nSee also the potential messages, which can show the origin of the above error, in the launching terminal."%(str(e),msg))
533 execute = executePythonScheme
535 def executeYACSScheme(self, File=None):
536 "Lancement du calcul"
537 self.__dumper.register("executeYACSScheme", dir(), locals())
538 raise NotImplementedError()
540 # -----------------------------------------------------------
542 def get(self, Concept=None):
543 "Récupération d'une sortie du calcul"
544 self.__dumper.register("get",dir(),locals(),Concept)
545 return self.__adaoStudy.get(Concept)
547 def dumpNormalizedCommands(self, filename=None):
548 "Récupération de la liste des commandes du cas"
549 return self.__dumper.dump(filename)
552 return ['set', 'get', 'execute', '__doc__', '__init__', '__module__']
554 class _DumpLogger(object):
556 Conservation des commandes de création d'un cas
558 def __init__(self, __name="", __objname="case"):
559 self.__name = str(__name)
560 self.__objname = str(__objname)
562 self.__switchoff = False
563 self.__logSerie.append("#\n# Python script for ADAO TUI\n#")
564 self.__logSerie.append("from numpy import array, matrix")
565 self.__logSerie.append("import adaoBuilder")
566 self.__logSerie.append("%s = adaoBuilder.New('%s')"%(self.__objname, self.__name))
567 def register(self, __command=None, __keys=None, __local=None, __pre=None, __switchoff=False):
568 "Enregistrement d'une commande individuelle"
569 if __command is not None and __keys is not None and __local is not None and not self.__switchoff:
571 if __pre is not None:
572 __text += "%s = "%__pre
573 __text += "%s.%s( "%(self.__objname,str(__command))
574 __keys.remove("self")
577 if __v is None: continue
578 __text += "%s=%s, "%(k,repr(__v))
580 self.__logSerie.append(__text)
582 self.__switchoff = True
584 self.__switchoff = False
585 def dump(self, __filename=None):
586 "Restitution de la liste des commandes de création d'un cas"
587 __text = "\n".join(self.__logSerie)
588 if __filename is not None:
589 fid = open(__filename,"w")
594 class _ObserverF(object):
596 Création d'une fonction d'observateur à partir de son texte
598 def __init__(self, corps=""):
600 def func(self,var,info):
601 "Fonction d'observation"
604 "Restitution du pointeur de fonction dans l'objet"
607 class _ImportFromScript(object):
609 Obtention d'une variable nommée depuis un fichier script importé
611 def __init__(self, __filename=None):
612 "Verifie l'existence et importe le script"
613 __filename = __filename.rstrip(".py")
614 if __filename is None:
615 raise ValueError("The name of the file containing the variable to be imported has to be specified.")
616 if not os.path.isfile(str(__filename)+".py"):
617 raise ValueError("The file containing the variable to be imported doesn't seem to exist. The given file name is:\n \"%s\""%__filename)
618 self.__scriptfile = __import__(__filename, globals(), locals(), [])
619 self.__scriptstring = open(__filename+".py",'r').read()
620 def getvalue(self, __varname=None, __synonym=None ):
621 "Renvoie la variable demandee"
622 if __varname is None:
623 raise ValueError("The name of the variable to be imported has to be specified.")
624 if not hasattr(self.__scriptfile, __varname):
625 if __synonym is None:
626 raise ValueError("The imported script file doesn't contain the specified variable \"%s\"."%__varname)
627 elif not hasattr(self.__scriptfile, __synonym):
628 raise ValueError("The imported script file doesn't contain the specified variable \"%s\"."%__synonym)
630 return getattr(self.__scriptfile, __synonym)
632 return getattr(self.__scriptfile, __varname)
634 "Renvoie le script complet"
635 return self.__scriptstring
637 # ==============================================================================
638 if __name__ == "__main__":
639 print('\n AUTODIAGNOSTIC \n')