.. [Argaud09] Argaud J.-P., Bouriquet B., Hunt J., *Data Assimilation from Operational and Industrial Applications to Complex Systems*, Mathematics Today, pp.150-152, October 2009
-.. [Bouttier99] Bouttier B., Courtier P., *Data assimilation concepts and methods*, Meteorological Training Course Lecture Series, ECMWF, 1999, http://www.ecmwf.int/newsevents/training/rcourse_notes/pdf_files/Assim_concepts.pdf
+.. [Bouttier99] Bouttier B., Courtier P., *Data assimilation concepts and methods*, Meteorological Training Course Lecture Series, ECMWF, 1999, http://www.ecmwf.int/sites/default/files/Data%20assimilation%20concepts%20and%20methods.pdf
-.. [Bocquet04] Bocquet M., *Introduction aux principes et méthodes de l'assimilation de données en géophysique*, Lecture Notes, 2004-2008, http://cerea.enpc.fr/HomePages/bocquet/assim.pdf
+.. [Bocquet04] Bocquet M., *Introduction aux principes et méthodes de l'assimilation de données en géophysique*, Lecture Notes, 2014, http://cerea.enpc.fr/HomePages/bocquet/Doc/assim-mb.pdf
.. [Buchinsky98] Buchinsky M., *Recent Advances in Quantile Regression Models: A Practical Guidline for Empirical Research*, Journal of Human Resources, 33(1), pp.88-126, 1998
available in the "*YACS Container Log*" window, obtained through the right click
menu of the "*proc*" window in the YACS executed scheme.
-.. [#] For more information on YACS, see the *YACS module User's Guide* available in the main "*Help*" menu of SALOME platform.
+.. [#] For more information on YACS, see the *YACS module* and its integrated help available from the main menu *Help* of the SALOME platform.
See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
In addition, we expect that all publications describing work using this
-software, or all commercial products using it, quote at least one of the
+software, or all commercial or not products using it, quote at least one of the
references given below:
* *ADAO, a SALOME module for Data Assimilation and Optimization*,
Example : ``so2 = ADD.get("SigmaObs")[-1]``
+ SimulatedObservationAtBackground
+ *List of vectors*. Each element is a vector of observation simulated from
+ the background :math:`\mathbf{x}^b`.
+
+ Example : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]``
+
+ SimulatedObservationAtOptimum
+ *List of vectors*. Each element is a vector of observation simulated from
+ the analysis or optimal state :math:`\mathbf{x}^a`.
+
+ Example : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]``
+
SimulationQuantiles
*List of vectors*. Each element is a vector corresponding to the observed
state which realize the required quantile, in the same order than the
Example : ``so2 = ADD.get("SigmaObs")[-1]``
+ SimulatedObservationAtBackground
+ *List of vectors*. Each element is a vector of observation simulated from
+ the background :math:`\mathbf{x}^b`.
+
+ Example : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]``
+
+ SimulatedObservationAtOptimum
+ *List of vectors*. Each element is a vector of observation simulated from
+ the analysis or optimal state :math:`\mathbf{x}^a`.
+
+ Example : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]``
+
SimulationQuantiles
*List of vectors*. Each element is a vector corresponding to the observed
state which realize the required quantile, in the same order than the
Example : ``sQuantiles = ADD.get("SimulationQuantiles")[:]``
+ SimulatedObservationAtBackground
+ *List of vectors*. Each element is a vector of observation simulated from
+ the background :math:`\mathbf{x}^b`.
+
+ Example : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]``
+
+ SimulatedObservationAtOptimum
+ *List of vectors*. Each element is a vector of observation simulated from
+ the analysis or optimal state :math:`\mathbf{x}^a`.
+
+ Example : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]``
+
See also
++++++++
Example : ``oma = ADD.get("OMA")[-1]``
+ SimulatedObservationAtOptimum
+ *List of vectors*. Each element is a vector of observation simulated from
+ the analysis or optimal state :math:`\mathbf{x}^a`.
+
+ Example : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]``
+
See also
++++++++
Example : ``omb = ADD.get("OMB")[-1]``
+ SimulatedObservationAtOptimum
+ *List of vectors*. Each element is a vector of observation simulated from
+ the analysis or optimal state :math:`\mathbf{x}^a`.
+
+ Example : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]``
+
See also
++++++++
Example : ``omb = ADD.get("OMB")[-1]``
+ SimulatedObservationAtBackground
+ *List of vectors*. Each element is a vector of observation simulated from
+ the background :math:`\mathbf{x}^b`.
+
+ Example : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]``
+
+ SimulatedObservationAtOptimum
+ *List of vectors*. Each element is a vector of observation simulated from
+ the analysis or optimal state :math:`\mathbf{x}^a`.
+
+ Example : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]``
+
See also
++++++++
Example : ``omb = ADD.get("OMB")[-1]``
+ SimulatedObservationAtBackground
+ *List of vectors*. Each element is a vector of observation simulated from
+ the background :math:`\mathbf{x}^b`.
+
+ Example : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]``
+
+ SimulatedObservationAtOptimum
+ *List of vectors*. Each element is a vector of observation simulated from
+ the analysis or optimal state :math:`\mathbf{x}^a`.
+
+ Example : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]``
+
See also
++++++++
Variables and informations available at the output
--------------------------------------------------
-How to obtain information available at the output
-+++++++++++++++++++++++++++++++++++++++++++++++++
+How to obtain the information available at the output
++++++++++++++++++++++++++++++++++++++++++++++++++++++
.. index:: single: UserPostAnalysis
.. index:: single: algoResults
+.. index:: single: getResults
.. index:: single: get
+.. index:: single: ADD
At the output, after executing data assimilation, optimization or checking
study, there are variables and information originating from the calculation. The
#. In the case where the user defines the post-processing in his ADAO case, it uses an external script file or commands in the field type "*String*" or "*Template*". The script it provides has a fixed variable "*ADD*" in the namespace.
#. In the case where the user defines the post-processing in its YACS scheme by a Python node located after the block of calculation, it should add a input port of type "*pyobj*" named for example "*Study*", graphically connected to the output port "*algoResults*" of the calculation block. The Python post-processing node must then start with ``ADD = Study.getResults()``.
-
-In all cases, the post-processing of the user has in the namespace a variable
-whose name is "*ADD*", and whose only available method is named ``get``. The
-arguments of this method are an output information name, as described in the
+Templates are given hereafter as :ref:`subsection_r_o_v_Template`. In all cases,
+the post-processing of the user has in the namespace a variable whose name is
+"*ADD*", and whose only available method is named ``get``. The arguments of this
+method are an output information name, as described in the
:ref:`subsection_r_o_v_Inventaire`.
For example, to have the optimal state after a data assimilation or optimization
One can then request a particular item in the list by the standard list commands
(especially ``[-1]`` for the last, and ``[:]`` for all items).
+.. _subsection_r_o_v_Template:
+
+Examples of Python scripts to obtain or treat the outputs
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+.. index:: single: Template
+.. index:: single: AnalysisPrinter
+.. index:: single: AnalysisSaver
+.. index:: single: AnalysisPrinterAndSaver
+
+These examples present Python commands or scripts which allow to obtain or to
+treat the ouput of an algorithm run. To help the user, they are directly
+available in the user interface, when building the ADAO case in EFICAS, in the
+"*Template*" type fields. In an equivalent way, these commands can be integrated
+in an external user script (and inserted in the ADAO case by a "*Script*" type
+input) or can exist as a string, including line feeds (and inserted in the ADAO
+case by a "*String*" type input). Lot of variants can be build from these
+simple examples, the main objective beeing to help the user to elaborate the
+exact procedure he needs in output.
+
+The first example (named "*AnalysisPrinter*" in the inputs of type
+"*Template*") consists in printing, in the standard log output, the value of the
+analysis or the optimal state, noted as :math:`\mathbf{x}^a` in the section
+:ref:`section_theory`. It is realized by the commands::
+
+ import numpy
+ xa=numpy.ravel(ADD.get('Analysis')[-1])
+ print 'Analysis:',xa"
+
+The ``numpy.ravel`` function is here to be sure that the ``xa`` variable will
+contain a real unidimensional vector, whatever the previoux computing choices
+are.
+
+A second example (named "*AnalysisSaver*" in the inputs of type "*Template*")
+consists in saving on file the value of the analysis or the optimal state
+:math:`\mathbf{x}^a`. It is realized by the commands::
+
+ import numpy
+ xa=numpy.ravel(ADD.get('Analysis')[-1])
+ f='/tmp/analysis.txt'
+ print 'Analysis saved in "%s"'%f
+ numpy.savetxt(f,xa)"
+
+The chosen recording file is a text one named ``/tmp/analysis.txt``.
+
+It is easy to combine these two examples by building a third one (named
+"*AnalysisPrinterAndSaver*" in the inputs of type "*Template*"). It consists in
+simultaneously printing in the standard log output and in saving on file the
+value of :math:`\mathbf{x}^a`. It is realized by the commands::
+
+ import numpy
+ xa=numpy.ravel(ADD.get('Analysis')[-1])
+ print 'Analysis:',xa
+ f='/tmp/analysis.txt'
+ print 'Analysis saved in "%s"'%f
+ numpy.savetxt(f,xa)
+
+To facilitate these examples extension for user needs, we recall that all the
+SALOME functions are available at the same level than these commands. The user
+can for example request for graphical representation with the PARAVIS [#]_ or
+other modules, for computating operations driven by YACS [#]_ or an another
+module, etc.
+
+Other usage examples are also given for :ref:`section_u_step4` of the
+:ref:`section_using` section, or in part :ref:`section_examples`.
+
Cross compliance of the information available at the output
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Example : ``so2 = ADD.get("SigmaObs")[-1]``
+ SimulatedObservationAtBackground
+ *List of vectors*. Each element is a vector of observation simulated from
+ the background :math:`\mathbf{x}^b`.
+
+ Example : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]``
+
+ SimulatedObservationAtOptimum
+ *List of vectors*. Each element is a vector of observation simulated from
+ the analysis or optimal state :math:`\mathbf{x}^a`.
+
+ Example : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]``
+
SimulationQuantiles
*List of vectors*. Each element is a vector corresponding to the observed
state which realize the required quantile, in the same order than the
quantiles required by the user.
Example : ``sQuantiles = ADD.get("SimulationQuantiles")[:]``
+
+.. [#] For more information on PARAVIS, see the *PARAVIS module* and its integrated help available from the main menu *Help* of the SALOME platform.
+
+.. [#] For more information on YACS, see the *YACS module* and its integrated help available from the main menu *Help* of the SALOME platform.
Each step will be detailed in the next section.
+.. _section_u_step1:
+
STEP 1: Activate the ADAO module and use the editor GUI
-------------------------------------------------------
.. centered::
**The EFICAS editor for cases definition in module ADAO**
+.. _section_u_step2:
+
STEP 2: Build and modify the ADAO case, and save it
---------------------------------------------------
ADAO case, with the same base name, the first one being completed by a "*.comm*"
extension and the second one by a "*.py*" extension [#]_.
+.. _section_u_step3:
+
STEP 3: Export the ADAO case as a YACS scheme
---------------------------------------------
its extension to "*.xml*". Be careful, *if the XML file name already exist, the
file will be overwritten without prompting for replacing the XML file*.
+.. _section_u_step4:
+
STEP 4: Supplement and modify the YACS scheme, and save it
----------------------------------------------------------
simulation used by the data assimilation procedure. The post-processing can be
provided through the "*UserPostAnalysis*" ADAO keyword as a script or a string,
by templates, or can be build as YACS nodes. These two ways of building the
-post-processing can use all the SALOME possibilities.
+post-processing can use all the SALOME possibilities. See the part describing
+:ref:`section_ref_output_variables`, or the help for each algorithm, for the
+full description of these elements.
-In details, the YACS scheme has an "*algoResults*" output port of the
+In practice, the YACS scheme has an "*algoResults*" output port of the
computation bloc, which gives access to an object of type "*pyobj*" named
hereafter "*ADD*", containing all the calculation results. These results can be
obtained by retrieving the named variables stored along the calculation. The
structures that can be used in the native or external SALOME post-processing. A
simple example is given in the section :ref:`section_examples`.
+.. _section_u_step5:
+
STEP 5: Execute the YACS case and obtain the results
----------------------------------------------------
The execution can also be done using a shell script, as described in the section
:ref:`section_advanced`.
-.. [#] For more information on EFICAS, see the *EFICAS module* available in SALOME platform.
+.. [#] For more information on EFICAS, see the *EFICAS module* and its integrated help available from the main menu *Help* of the SALOME platform.
.. [#] The use of physical simulation code in the data assimilation elementary operators is illustrated or described in the following main parts.
-.. [#] For more information on YACS, see the *YACS module User's Guide* available in the main "*Help*" menu of SALOME platform.
+.. [#] For more information on YACS, see the *YACS module* and its integrated help available from the main menu *Help* of the SALOME platform.
.. [#] This intermediary python file can also be used as described in the section :ref:`section_advanced`.
.. [Argaud09] Argaud J.-P., Bouriquet B., Hunt J., *Data Assimilation from Operational and Industrial Applications to Complex Systems*, Mathematics Today, pp.150-152, October 2009
-.. [Bouttier99] Bouttier B., Courtier P., *Data assimilation concepts and methods*, Meteorological Training Course Lecture Series, ECMWF, 1999, http://www.ecmwf.int/newsevents/training/rcourse_notes/pdf_files/Assim_concepts.pdf
+.. [Bouttier99] Bouttier B., Courtier P., *Data assimilation concepts and methods*, Meteorological Training Course Lecture Series, ECMWF, 1999, http://www.ecmwf.int/sites/default/files/Data%20assimilation%20concepts%20and%20methods.pdf
-.. [Bocquet04] Bocquet M., *Introduction aux principes et méthodes de l'assimilation de données en géophysique*, Lecture Notes, 2004-2008, http://cerea.enpc.fr/HomePages/bocquet/assim.pdf
+.. [Bocquet04] Bocquet M., *Introduction aux principes et méthodes de l'assimilation de données en géophysique*, Lecture Notes, 2014, http://cerea.enpc.fr/HomePages/bocquet/Doc/assim-mb.pdf
.. [Buchinsky98] Buchinsky M., *Recent Advances in Quantile Regression Models: A Practical Guidline for Empirical Research*, Journal of Human Resources, 33(1), pp.88-126, 1998
disponibles dans la fenêtre "*fenêtre de sortie de YACS*", que l'on obtient par
clic droit sur la fenêtre "*proc*" du schéma YACS exécuté.
-.. [#] Pour de plus amples informations sur YACS, voir le *Guide utilisateur du module YACS* disponible dans le menu principal *Aide* de l'environnement SALOME.
+.. [#] Pour de plus amples informations sur YACS, voir le *module YACS* et son aide intégrée disponible dans le menu principal *Aide* de l'environnement SALOME.
See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
En outre, nous souhaitons que toute publication décrivant des travaux utilisant
-ce module, ou tout produit commercial l'utilisant, cite au moins l'une des
-références ci-dessous :
+ce module, ou tout produit commercial ou non l'utilisant, cite au moins l'une
+des références ci-dessous :
* *ADAO, a SALOME module for Data Assimilation and Optimization*,
http://www.salome-platform.org/
Exemple : ``so2 = ADD.get("SigmaObs")[-1]``
+ SimulatedObservationAtBackground
+ *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à
+ partir de l'ébauche :math:`\mathbf{x}^b`.
+
+ Exemple : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]``
+
+ SimulatedObservationAtOptimum
+ *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à
+ partir de l'analyse ou de l'état optimal :math:`\mathbf{x}^a`.
+
+ Exemple : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]``
+
SimulationQuantiles
*Liste de vecteurs*. Chaque élément est un vecteur correspondant à l'état
observé qui réalise le quantile demandé, dans le même ordre que les
Exemple : ``so2 = ADD.get("SigmaObs")[-1]``
+ SimulatedObservationAtBackground
+ *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à
+ partir de l'ébauche :math:`\mathbf{x}^b`.
+
+ Exemple : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]``
+
+ SimulatedObservationAtOptimum
+ *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à
+ partir de l'analyse ou de l'état optimal :math:`\mathbf{x}^a`.
+
+ Exemple : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]``
+
SimulationQuantiles
*Liste de vecteurs*. Chaque élément est un vecteur correspondant à l'état
observé qui réalise le quantile demandé, dans le même ordre que les
Exemple : ``so2 = ADD.get("SigmaObs")[-1]``
+ SimulatedObservationAtBackground
+ *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à
+ partir de l'ébauche :math:`\mathbf{x}^b`.
+
+ Exemple : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]``
+
+ SimulatedObservationAtOptimum
+ *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à
+ partir de l'analyse ou de l'état optimal :math:`\mathbf{x}^a`.
+
+ Exemple : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]``
+
SimulationQuantiles
*Liste de vecteurs*. Chaque élément est un vecteur correspondant à l'état
observé qui réalise le quantile demandé, dans le même ordre que les
Exemple : ``oma = ADD.get("OMA")[-1]``
+ SimulatedObservationAtOptimum
+ *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à
+ partir de l'analyse ou de l'état optimal :math:`\mathbf{x}^a`.
+
+ Exemple : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]``
+
Voir aussi
++++++++++
Exemple : ``omb = ADD.get("OMB")[-1]``
+ SimulatedObservationAtOptimum
+ *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à
+ partir de l'analyse ou de l'état optimal :math:`\mathbf{x}^a`.
+
+ Exemple : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]``
+
Voir aussi
++++++++++
Exemple : ``omb = ADD.get("OMB")[-1]``
+ SimulatedObservationAtBackground
+ *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à
+ partir de l'ébauche :math:`\mathbf{x}^b`.
+
+ Exemple : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]``
+
+ SimulatedObservationAtOptimum
+ *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à
+ partir de l'analyse ou de l'état optimal :math:`\mathbf{x}^a`.
+
+ Exemple : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]``
+
Voir aussi
++++++++++
Exemple : ``omb = ADD.get("OMB")[-1]``
+ SimulatedObservationAtBackground
+ *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à
+ partir de l'ébauche :math:`\mathbf{x}^b`.
+
+ Exemple : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]``
+
+ SimulatedObservationAtOptimum
+ *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à
+ partir de l'analyse ou de l'état optimal :math:`\mathbf{x}^a`.
+
+ Exemple : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]``
+
Voir aussi
++++++++++
Variables et informations disponibles en sortie
-----------------------------------------------
-Comment obtenir des informations disponibles en sortie
+Comment obtenir les informations disponibles en sortie
++++++++++++++++++++++++++++++++++++++++++++++++++++++
.. index:: single: UserPostAnalysis
.. index:: single: algoResults
+.. index:: single: getResults
.. index:: single: get
+.. index:: single: ADD
En sortie, après exécution d'une assimilation de données, d'une optimisation
ou d'une vérification, on dispose de variables et d'informations issues du
calcul. L'obtention de ces informations se fait ensuite de manière standardisée
-à l'aide de l'étape de post-processing du calcul.
+à l'aide de l'étape de post-processing du calcul.
L'étape est aisément identifiée par l'utilisateur dans son cas ADAO de
définition (par la mot-clé "*UserPostAnalysis*") ou dans son schéma YACS
#. Dans le cas où l'utilisateur définit le post-processing dans son cas ADAO, il utilise un fichier script externe ou des commandes dans le champ de type "*String*" ou "*Template*". Le script qu'il fournit dispose d'une variable fixe "*ADD*" dans l'espace de noms.
#. Dans le cas où l'utilisateur définit le post-processing dans son schéma YACS par un noeud Python situé après le bloc de calcul, il doit ajouter un port d'entrée de type "*pyobj*" nommé par exemple "*Study*", relié graphiquement au port de sortie "*algoResults*" du bloc de calcul. Le noeud Python de post-processing doit ensuite débuter par ``ADD = Study.getResults()``.
-Dans tous les cas, le post-processing de l'utilisateur dispose dans l'espace de
-noms d'une variable dont le nom est "*ADD*", et dont l'unique méthode utilisable
-est nommée ``get``. Les arguments de cette méthode sont un nom d'information de
-sortie, comme décrit dans l':ref:`subsection_r_o_v_Inventaire`.
+Des patrons (ou "templates") sont donnés ci-après en
+:ref:`subsection_r_o_v_Template`. Dans tous les cas, le post-processing de
+l'utilisateur dispose dans l'espace de noms d'une variable dont le nom est
+"*ADD*", et dont l'unique méthode utilisable est nommée ``get``. Les arguments
+de cette méthode sont un nom d'information de sortie, comme décrit dans
+l':ref:`subsection_r_o_v_Inventaire`.
Par exemple, pour avoir l'état optimal après un calcul d'assimilation de données
ou d'optimisation, on utilise l'appel suivant::
les commandes standards de liste (en particulier ``[-1]`` pour le dernier, et
``[:]`` pour tous les éléments).
+.. _subsection_r_o_v_Template:
+
+Exemples de scripts Python pour obtenir ou traiter les sorties
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+.. index:: single: Template
+.. index:: single: AnalysisPrinter
+.. index:: single: AnalysisSaver
+.. index:: single: AnalysisPrinterAndSaver
+
+Ces exemples présentent des commandes ou scripts Python qui permettent d'obtenir
+ou de traiter les sorties d'une exécution d'algorithme. Pour aider l'utilisateur,
+ils sont directement disponibles dans l'interface, à la construction du cas ADAO
+dans EFICAS, dans les champs de type "*Template*". De manière équivalente, ces
+commandes peuvent être contenues dans un script utilisateur externe (et insérées
+dans le cas ADAO par l'entrée de type "*Script*") ou contenues dans une chaîne
+de caractères, y compris les retour à la ligne (et insérées dans le cas ADAO par
+l'entrée de type "*String*"). De nombreuses variantes peuvent être imaginées à
+partir de ces exemples simples, l'objectif étant surtout d'aider l'utilisateur à
+effectuer le traitement exact dont il a besoin en sortie.
+
+Le premier exemple (appelé "*AnalysisPrinter*" dans les entrées de type
+"*Template*") consiste à afficher, dans la sortie standard d'exécution, la
+valeur de l'analyse ou de l'état optimal, noté :math:`\mathbf{x}^a` dans la
+partie :ref:`section_theory`. Cela se réalise par les commandes::
+
+ import numpy
+ xa=numpy.ravel(ADD.get('Analysis')[-1])
+ print 'Analysis:',xa"
+
+La fonction ``numpy.ravel`` assure simplement que la variable ``xa`` contienne
+un vrai vecteur unidimensionnel, quels que soient les choix informatiques
+précédents.
+
+Un second exemple (appelé "*AnalysisSaver*" dans les entrées de type
+"*Template*") consiste à enregistrer sur fichier la valeur de l'analyse ou de
+l'état optimal :math:`\mathbf{x}^a`. Cela se réalise par les commandes::
+
+ import numpy
+ xa=numpy.ravel(ADD.get('Analysis')[-1])
+ f='/tmp/analysis.txt'
+ print 'Analysis saved in "%s"'%f
+ numpy.savetxt(f,xa)"
+
+Le fichier d'enregistrement choisi est un fichier texte ``/tmp/analysis.txt``.
+
+Il est aisé de combiner ces deux exemples pour en construire un troisième
+(appelé "*AnalysisPrinterAndSaver*" dans les entrées de type "*Template*"). Il
+consiste à simultanément afficher dans la sortie standard d'exécution et à
+enregistrer sur fichier la valeur de :math:`\mathbf{x}^a`. Cela se réalise par
+les commandes::
+
+ import numpy
+ xa=numpy.ravel(ADD.get('Analysis')[-1])
+ print 'Analysis:',xa
+ f='/tmp/analysis.txt'
+ print 'Analysis saved in "%s"'%f
+ numpy.savetxt(f,xa)
+
+Pour faciliter l'extension de ces exemples selon les besoins utilisateurs, on
+rappelle que l'ensemble des fonctions de SALOME sont disponibles au même niveau
+que ces commandes. L'utilisateur peut en particulier requérir des actions de
+représentation graphique avec le module PARAVIS [#]_ ou d'autres modules, des
+actions de calcul pilotés par YACS [#]_ ou un autre module, etc.
+
+D'autres exemples d'utilisation sont aussi donnés en :ref:`section_u_step4` de
+la partie :ref:`section_using`, ou en partie :ref:`section_examples`.
+
Conditionnalité des informations disponibles en sortie
++++++++++++++++++++++++++++++++++++++++++++++++++++++
Exemple : ``so2 = ADD.get("SigmaObs")[-1]``
+ SimulatedObservationAtBackground
+ *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à
+ partir de l'ébauche :math:`\mathbf{x}^b`.
+
+ Exemple : ``hxb = ADD.get("SimulatedObservationAtBackground")[-1]``
+
+ SimulatedObservationAtOptimum
+ *Liste de vecteurs*. Chaque élément est un vecteur d'observation simulé à
+ partir de l'analyse ou de l'état optimal :math:`\mathbf{x}^a`.
+
+ Exemple : ``hxa = ADD.get("SimulatedObservationAtOptimum")[-1]``
+
SimulationQuantiles
*Liste de vecteurs*. Chaque élément est un vecteur correspondant à l'état
observé qui réalise le quantile demandé, dans le même ordre que les
quantiles requis par l'utilisateur.
Exemple : ``sQuantiles = ADD.get("SimulationQuantiles")[:]``
+
+.. [#] Pour de plus amples informations sur PARAVIS, voir le *module PARAVIS* et son aide intégrée disponible dans le menu principal *Aide* de l'environnement SALOME.
+
+.. [#] Pour de plus amples informations sur YACS, voir le *module YACS* et son aide intégrée disponible dans le menu principal *Aide* de l'environnement SALOME.
Chaque étape est détaillée dans la section suivante.
+.. _section_u_step1:
+
ÉTAPE 1 : Activer le module ADAO et utiliser l'interface graphique d'édition (GUI)
----------------------------------------------------------------------------------
.. centered::
**L'éditeur EFICAS pour la définition des cas dans le module ADAO**
+.. _section_u_step2:
+
ÉTAPE 2 : Créer et modifier le cas ADAO, et l'enregistrer
---------------------------------------------------------
ADAO, avec le même nom de base, le premier présentant une extension "*.comm*" et
le second une extension "*.py*" [#]_.
+.. _section_u_step3:
+
ÉTAPE 3 : Exporter le cas ADAO comme un schéma YACS
---------------------------------------------------
XML existe déjà, le fichier est écrasé sans avertissement sur le remplacement du
fichier XML*.
+.. _section_u_step4:
+
ÉTAPE 4 : Compléter et modifier le schéma YACS, et l'enregistrer
----------------------------------------------------------------
d'ADAO sous la forme d'un fichier de script ou d'une chaîne de caractères, par
des patrons ("templates"), ou peut être construit comme des noeuds YACS. Ces
deux manières de construire le post-processing peuvent utiliser toutes les
-capacités de SALOME.
+capacités de SALOME. On se reportera à la partie traitant des
+:ref:`section_ref_output_variables`, ou à l'aide de chaque algorithme, pour la
+description complète de ces éléments.
-Dans le détail, le schéma YACS dispose d'un port de sortie "*algoResults*" dans
-le bloc de calcul, qui donne accès à un objet de type "*pyobj*" nommé ci-aprés
+En pratique, le schéma YACS dispose d'un port de sortie "*algoResults*" dans le
+bloc de calcul, qui donne accès à un objet de type "*pyobj*" nommé ci-aprés
"*ADD*", qui contient tous les résultats de calcul. Ces résultats peuvent être
obtenus en récupérant les variables nommées stockées au cours des calculs.
L'information principale est la variable "*Analysis*", qui peut être obtenue par
natif ou externe à SALOME. Un exemple simple est disponible dans la section
:ref:`section_examples`.
+.. _section_u_step5:
+
ÉTAPE 5 : Exécuter le schéma YACS et obtenir les résultats
----------------------------------------------------------
L'exécution peut aussi être conduite en utilisant un script de commandes shell,
comme décrit dans la section :ref:`section_advanced`.
-.. [#] Pour de plus amples informations sur EFICAS, voir le *module EFICAS* et son aide disponible dans l'environnement SALOME.
+.. [#] Pour de plus amples informations sur EFICAS, voir le *module EFICAS* et son aide intégrée disponible dans le menu principal *Aide* de l'environnement SALOME.
.. [#] L'utilisation du code de simulation physique dans les opérateurs de base de l'assimilation de données est illustrée ou décrite dans les parties principales qui suivent.
-.. [#] Pour de plus amples informations sur YACS, voir le *Guide utilisateur du module YACS* disponible dans le menu principal *Aide* de l'environnement SALOME.
+.. [#] Pour de plus amples informations sur YACS, voir le *module YACS* et son aide intégrée disponible dans le menu principal *Aide* de l'environnement SALOME.
.. [#] Ce fichier python intermédiaire peut aussi être utilisé comme décrit dans la section :ref:`section_advanced`.
default = [],
typecast = tuple,
message = "Liste de calculs supplémentaires à stocker et/ou effectuer",
- listval = ["APosterioriCovariance", "BMA", "OMA", "OMB", "Innovation", "SigmaObs2", "MahalanobisConsistency", "SimulationQuantiles"]
+ listval = ["APosterioriCovariance", "BMA", "OMA", "OMB", "Innovation", "SigmaObs2", "MahalanobisConsistency", "SimulationQuantiles", "SimulatedObservationAtBackground", "SimulatedObservationAtOptimum"]
)
self.defineRequiredParameter(
name = "Quantiles",
#
self.StoredVariables["Analysis"].store( Xa.A1 )
#
- if "OMA" in self._parameters["StoreSupplementaryCalculations"] or \
- "SigmaObs2" in self._parameters["StoreSupplementaryCalculations"] or \
- "SimulationQuantiles" in self._parameters["StoreSupplementaryCalculations"]:
+ if "OMA" in self._parameters["StoreSupplementaryCalculations"] or \
+ "SigmaObs2" in self._parameters["StoreSupplementaryCalculations"] or \
+ "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"] or \
+ "SimulationQuantiles" in self._parameters["StoreSupplementaryCalculations"]:
HXa = Hm(Xa)
#
# Calcul de la covariance d'analyse
if YQ is None: YQ = YfQ[:,indice]
else: YQ = numpy.hstack((YQ,YfQ[:,indice]))
self.StoredVariables["SimulationQuantiles"].store( YQ )
+ if "SimulatedObservationAtBackground" in self._parameters["StoreSupplementaryCalculations"]:
+ self.StoredVariables["SimulatedObservationAtBackground"].store( numpy.ravel(HXb) )
+ if "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]:
+ self.StoredVariables["SimulatedObservationAtOptimum"].store( numpy.ravel(HXa) )
#
self._post_run(HO)
return 0
default = [],
typecast = tuple,
message = "Liste de calculs supplémentaires à stocker et/ou effectuer",
- listval = ["APosterioriCovariance", "BMA", "OMA", "OMB", "Innovation", "SigmaBck2", "SigmaObs2", "MahalanobisConsistency", "SimulationQuantiles"]
+ listval = ["APosterioriCovariance", "BMA", "OMA", "OMB", "Innovation", "SigmaBck2", "SigmaObs2", "MahalanobisConsistency", "SimulationQuantiles", "SimulatedObservationAtBackground", "SimulatedObservationAtOptimum"]
)
self.defineRequiredParameter(
name = "Quantiles",
# Calcul de la fonction coût
# --------------------------
if self._parameters["StoreInternalVariables"] or \
- "OMA" in self._parameters["StoreSupplementaryCalculations"] or \
- "SigmaObs2" in self._parameters["StoreSupplementaryCalculations"] or \
- "MahalanobisConsistency" in self._parameters["StoreSupplementaryCalculations"] or \
- "SimulationQuantiles" in self._parameters["StoreSupplementaryCalculations"]:
+ "OMA" in self._parameters["StoreSupplementaryCalculations"] or \
+ "SigmaObs2" in self._parameters["StoreSupplementaryCalculations"] or \
+ "MahalanobisConsistency" in self._parameters["StoreSupplementaryCalculations"] or \
+ "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"] or \
+ "SimulationQuantiles" in self._parameters["StoreSupplementaryCalculations"]:
HXa = Hm * Xa
oma = Y - HXa
if self._parameters["StoreInternalVariables"] or \
# Calcul de la covariance d'analyse
# ---------------------------------
if "APosterioriCovariance" in self._parameters["StoreSupplementaryCalculations"] or \
- "SimulationQuantiles" in self._parameters["StoreSupplementaryCalculations"]:
+ "SimulationQuantiles" in self._parameters["StoreSupplementaryCalculations"]:
A = B - K * Hm * B
if min(A.shape) != max(A.shape):
raise ValueError("The %s a posteriori covariance matrix A is of shape %s, despites it has to be a squared matrix. There is an error in the observation operator, please check it."%(self._name,str(A.shape)))
if YQ is None: YQ = YfQ[:,indice]
else: YQ = numpy.hstack((YQ,YfQ[:,indice]))
self.StoredVariables["SimulationQuantiles"].store( YQ )
+ if "SimulatedObservationAtBackground" in self._parameters["StoreSupplementaryCalculations"]:
+ self.StoredVariables["SimulatedObservationAtBackground"].store( numpy.ravel(HXb) )
+ if "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]:
+ self.StoredVariables["SimulatedObservationAtOptimum"].store( numpy.ravel(HXa) )
#
self._post_run(HO)
return 0
default = [],
typecast = tuple,
message = "Liste de calculs supplémentaires à stocker et/ou effectuer",
- listval = ["APosterioriCovariance", "BMA", "OMA", "OMB", "Innovation", "SigmaBck2", "SigmaObs2", "MahalanobisConsistency", "SimulationQuantiles"]
+ listval = ["APosterioriCovariance", "BMA", "OMA", "OMB", "Innovation", "SigmaBck2", "SigmaObs2", "MahalanobisConsistency", "SimulationQuantiles", "SimulatedObservationAtBackground", "SimulatedObservationAtOptimum"]
)
self.defineRequiredParameter(
name = "Quantiles",
# Calcul de la fonction coût
# --------------------------
if self._parameters["StoreInternalVariables"] or \
- "OMA" in self._parameters["StoreSupplementaryCalculations"] or \
- "SigmaObs2" in self._parameters["StoreSupplementaryCalculations"] or \
- "MahalanobisConsistency" in self._parameters["StoreSupplementaryCalculations"] or \
- "SimulationQuantiles" in self._parameters["StoreSupplementaryCalculations"]:
+ "OMA" in self._parameters["StoreSupplementaryCalculations"] or \
+ "SigmaObs2" in self._parameters["StoreSupplementaryCalculations"] or \
+ "MahalanobisConsistency" in self._parameters["StoreSupplementaryCalculations"] or \
+ "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"] or \
+ "SimulationQuantiles" in self._parameters["StoreSupplementaryCalculations"]:
HXa = numpy.matrix(numpy.ravel( H( Xa ) )).T
oma = Y - HXa
if self._parameters["StoreInternalVariables"] or \
if YQ is None: YQ = YfQ[:,indice]
else: YQ = numpy.hstack((YQ,YfQ[:,indice]))
self.StoredVariables["SimulationQuantiles"].store( YQ )
+ if "SimulatedObservationAtBackground" in self._parameters["StoreSupplementaryCalculations"]:
+ self.StoredVariables["SimulatedObservationAtBackground"].store( numpy.ravel(HXb) )
+ if "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]:
+ self.StoredVariables["SimulatedObservationAtOptimum"].store( numpy.ravel(HXa) )
#
self._post_run(HO)
return 0
default = [],
typecast = tuple,
message = "Liste de calculs supplémentaires à stocker et/ou effectuer",
- listval = ["OMA"]
+ listval = ["OMA", "SimulatedObservationAtOptimum"]
)
def run(self, Xb=None, Y=None, U=None, HO=None, EM=None, CM=None, R=None, B=None, Q=None, Parameters=None):
#
# Calcul de la fonction coût
# --------------------------
- if self._parameters["StoreInternalVariables"] or "OMA" in self._parameters["StoreSupplementaryCalculations"]:
- oma = Y - Hm * Xa
+ if self._parameters["StoreInternalVariables"] or \
+ "OMA" in self._parameters["StoreSupplementaryCalculations"] or \
+ "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]:
+ HXa = Hm * Xa
+ oma = Y - HXa
if self._parameters["StoreInternalVariables"]:
Jb = 0.
Jo = 0.5 * oma.T * RI * oma
# ---------------------------------------
if "OMA" in self._parameters["StoreSupplementaryCalculations"]:
self.StoredVariables["OMA"].store( numpy.ravel(oma) )
+ if "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]:
+ self.StoredVariables["SimulatedObservationAtOptimum"].store( numpy.ravel(HXa) )
#
self._post_run(HO)
return 0
default = [],
typecast = tuple,
message = "Liste de calculs supplémentaires à stocker et/ou effectuer",
- listval = ["BMA", "OMA", "OMB", "Innovation"]
+ listval = ["BMA", "OMA", "OMB", "Innovation", "SimulatedObservationAtOptimum"]
)
def run(self, Xb=None, Y=None, U=None, HO=None, EM=None, CM=None, R=None, B=None, Q=None, Parameters=None):
if self._parameters.has_key("Minimizer") == "TNC":
self.setParameterValue("StoreInternalVariables",True)
#
- # Opérateur d'observation
- # -----------------------
+ # Opérateurs
+ # ----------
Hm = HO["Direct"].appliedTo
Ha = HO["Adjoint"].appliedInXTo
#
#
self.StoredVariables["Analysis"].store( Xa.A1 )
#
+ if "OMA" in self._parameters["StoreSupplementaryCalculations"] or \
+ "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]:
+ HXa = Hm(Xa)
+ #
+ #
# Calculs et/ou stockages supplémentaires
# ---------------------------------------
if "Innovation" in self._parameters["StoreSupplementaryCalculations"]:
if "BMA" in self._parameters["StoreSupplementaryCalculations"]:
self.StoredVariables["BMA"].store( numpy.ravel(Xb) - numpy.ravel(Xa) )
if "OMA" in self._parameters["StoreSupplementaryCalculations"]:
- self.StoredVariables["OMA"].store( numpy.ravel(Y) - numpy.ravel(Hm(Xa)) )
+ self.StoredVariables["OMA"].store( numpy.ravel(Y) - numpy.ravel(HXa) )
if "OMB" in self._parameters["StoreSupplementaryCalculations"]:
self.StoredVariables["OMB"].store( numpy.ravel(d) )
+ if "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]:
+ self.StoredVariables["SimulatedObservationAtOptimum"].store( numpy.ravel(HXa) )
#
self._post_run(HO)
return 0
default = [],
typecast = tuple,
message = "Liste de calculs supplémentaires à stocker et/ou effectuer",
- listval = ["BMA", "OMA", "OMB", "Innovation"]
+ listval = ["BMA", "OMA", "OMB", "Innovation", "SimulatedObservationAtBackground", "SimulatedObservationAtOptimum"]
)
def run(self, Xb=None, Y=None, U=None, HO=None, EM=None, CM=None, R=None, B=None, Q=None, Parameters=None):
#
self.StoredVariables["Analysis"].store( Xa.A1 )
#
+ if "Innovation" in self._parameters["StoreSupplementaryCalculations"] or \
+ "OMB" in self._parameters["StoreSupplementaryCalculations"] or \
+ "SimulatedObservationAtBackground" in self._parameters["StoreSupplementaryCalculations"]:
+ HXb = Hm(Xb)
+ d = Y - HXb
+ if "OMA" in self._parameters["StoreSupplementaryCalculations"] or \
+ "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]:
+ HXa = Hm(Xa)
+ #
# Calculs et/ou stockages supplémentaires
# ---------------------------------------
- if "Innovation" in self._parameters["StoreSupplementaryCalculations"] or "OMB" in self._parameters["StoreSupplementaryCalculations"]:
- d = Y - Hm(Xb)
if "Innovation" in self._parameters["StoreSupplementaryCalculations"]:
self.StoredVariables["Innovation"].store( numpy.ravel(d) )
if "BMA" in self._parameters["StoreSupplementaryCalculations"]:
self.StoredVariables["BMA"].store( numpy.ravel(Xb - Xa) )
if "OMA" in self._parameters["StoreSupplementaryCalculations"]:
- self.StoredVariables["OMA"].store( numpy.ravel(Y - Hm(Xa)) )
+ self.StoredVariables["OMA"].store( numpy.ravel(Y - HXa) )
if "OMB" in self._parameters["StoreSupplementaryCalculations"]:
self.StoredVariables["OMB"].store( numpy.ravel(d) )
+ if "SimulatedObservationAtBackground" in self._parameters["StoreSupplementaryCalculations"]:
+ self.StoredVariables["SimulatedObservationAtBackground"].store( numpy.ravel(HXb) )
+ if "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]:
+ self.StoredVariables["SimulatedObservationAtOptimum"].store( numpy.ravel(HXa) )
#
self._post_run(HO)
return 0
default = [],
typecast = tuple,
message = "Liste de calculs supplémentaires à stocker et/ou effectuer",
- listval = ["BMA", "OMA", "OMB", "Innovation"]
+ listval = ["BMA", "OMA", "OMB", "Innovation", "SimulatedObservationAtBackground", "SimulatedObservationAtOptimum"]
)
def run(self, Xb=None, Y=None, U=None, HO=None, EM=None, CM=None, R=None, B=None, Q=None, Parameters=None):
#
self.StoredVariables["Analysis"].store( Xa.A1 )
#
+ if "OMA" in self._parameters["StoreSupplementaryCalculations"] or \
+ "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]:
+ HXa = Hm(Xa)
+ #
# Calculs et/ou stockages supplémentaires
# ---------------------------------------
if "Innovation" in self._parameters["StoreSupplementaryCalculations"]:
if "BMA" in self._parameters["StoreSupplementaryCalculations"]:
self.StoredVariables["BMA"].store( numpy.ravel(Xb - Xa) )
if "OMA" in self._parameters["StoreSupplementaryCalculations"]:
- self.StoredVariables["OMA"].store( numpy.ravel(Y - Hm(Xa)) )
+ self.StoredVariables["OMA"].store( numpy.ravel(Y - HXa) )
if "OMB" in self._parameters["StoreSupplementaryCalculations"]:
self.StoredVariables["OMB"].store( numpy.ravel(d) )
+ if "SimulatedObservationAtBackground" in self._parameters["StoreSupplementaryCalculations"]:
+ self.StoredVariables["SimulatedObservationAtBackground"].store( numpy.ravel(HXb) )
+ if "SimulatedObservationAtOptimum" in self._parameters["StoreSupplementaryCalculations"]:
+ self.StoredVariables["SimulatedObservationAtOptimum"].store( numpy.ravel(HXa) )
#
self._post_run(HO)
return 0
asCovariance = None,
asEyeByScalar = None,
asEyeByVector = None,
+ asCovObject = None,
toBeStored = False,
):
"""
- asEyeByVector : entrée des données comme un seul vecteur de variance,
à mettre sur la diagonale d'une matrice de corrélation, aucune matrice
n'étant donc explicitement à donner
+ - asCovObject : entrée des données comme un objet ayant des méthodes
+ particulieres de type matriciel
- toBeStored : booléen indiquant si la donnée d'entrée est sauvée pour
être rendue disponible au même titre que les variables de calcul
"""
asCovariance = asCovariance,
asEyeByScalar = asEyeByScalar,
asEyeByVector = asEyeByVector,
+ asCovObject = asCovObject,
)
if toBeStored:
self.__StoredInputs["BackgroundError"] = self.__B
asCovariance = None,
asEyeByScalar = None,
asEyeByVector = None,
+ asCovObject = None,
toBeStored = False,
):
"""
- asEyeByVector : entrée des données comme un seul vecteur de variance,
à mettre sur la diagonale d'une matrice de corrélation, aucune matrice
n'étant donc explicitement à donner
+ - asCovObject : entrée des données comme un objet ayant des méthodes
+ particulieres de type matriciel
- toBeStored : booléen indiquant si la donnée d'entrée est sauvée pour
être rendue disponible au même titre que les variables de calcul
"""
asCovariance = asCovariance,
asEyeByScalar = asEyeByScalar,
asEyeByVector = asEyeByVector,
+ asCovObject = asCovObject,
)
if toBeStored:
self.__StoredInputs["ObservationError"] = self.__R
asCovariance = None,
asEyeByScalar = None,
asEyeByVector = None,
+ asCovObject = None,
toBeStored = False,
):
"""
- asEyeByVector : entrée des données comme un seul vecteur de variance,
à mettre sur la diagonale d'une matrice de corrélation, aucune matrice
n'étant donc explicitement à donner
+ - asCovObject : entrée des données comme un objet ayant des méthodes
+ particulieres de type matriciel
- toBeStored : booléen indiquant si la donnée d'entrée est sauvée pour
être rendue disponible au même titre que les variables de calcul
"""
asCovariance = asCovariance,
asEyeByScalar = asEyeByScalar,
asEyeByVector = asEyeByVector,
+ asCovObject = asCovObject,
)
if toBeStored:
self.__StoredInputs["EvolutionError"] = self.__Q
- GradientOfCostFunctionJo : gradient de la partie observations de la fonction-cout
- CurrentState : état courant lors d'itérations
- Analysis : l'analyse Xa
+ - SimulatedObservationAtBackground : l'état observé H(Xb) à l'ébauche
+ - SimulatedObservationAtOptimum : l'état observé H(Xa) à l'optimum
- ObservedState : l'état observé H(X)
- Innovation : l'innovation : d = Y - H(X)
- SigmaObs2 : indicateur de correction optimale des erreurs d'observation
self.__required_parameters = {}
self.StoredVariables = {}
#
- self.StoredVariables["CostFunctionJ"] = Persistence.OneScalar(name = "CostFunctionJ")
- self.StoredVariables["CostFunctionJb"] = Persistence.OneScalar(name = "CostFunctionJb")
- self.StoredVariables["CostFunctionJo"] = Persistence.OneScalar(name = "CostFunctionJo")
- self.StoredVariables["GradientOfCostFunctionJ"] = Persistence.OneVector(name = "GradientOfCostFunctionJ")
- self.StoredVariables["GradientOfCostFunctionJb"] = Persistence.OneVector(name = "GradientOfCostFunctionJb")
- self.StoredVariables["GradientOfCostFunctionJo"] = Persistence.OneVector(name = "GradientOfCostFunctionJo")
- self.StoredVariables["CurrentState"] = Persistence.OneVector(name = "CurrentState")
- self.StoredVariables["Analysis"] = Persistence.OneVector(name = "Analysis")
- self.StoredVariables["ObservedState"] = Persistence.OneVector(name = "ObservedState")
- self.StoredVariables["Innovation"] = Persistence.OneVector(name = "Innovation")
- self.StoredVariables["SigmaObs2"] = Persistence.OneScalar(name = "SigmaObs2")
- self.StoredVariables["SigmaBck2"] = Persistence.OneScalar(name = "SigmaBck2")
- self.StoredVariables["MahalanobisConsistency"] = Persistence.OneScalar(name = "MahalanobisConsistency")
- self.StoredVariables["OMA"] = Persistence.OneVector(name = "OMA")
- self.StoredVariables["OMB"] = Persistence.OneVector(name = "OMB")
- self.StoredVariables["BMA"] = Persistence.OneVector(name = "BMA")
- self.StoredVariables["APosterioriCovariance"] = Persistence.OneMatrix(name = "APosterioriCovariance")
- self.StoredVariables["SimulationQuantiles"] = Persistence.OneMatrix(name = "SimulationQuantiles")
+ self.StoredVariables["CostFunctionJ"] = Persistence.OneScalar(name = "CostFunctionJ")
+ self.StoredVariables["CostFunctionJb"] = Persistence.OneScalar(name = "CostFunctionJb")
+ self.StoredVariables["CostFunctionJo"] = Persistence.OneScalar(name = "CostFunctionJo")
+ self.StoredVariables["GradientOfCostFunctionJ"] = Persistence.OneVector(name = "GradientOfCostFunctionJ")
+ self.StoredVariables["GradientOfCostFunctionJb"] = Persistence.OneVector(name = "GradientOfCostFunctionJb")
+ self.StoredVariables["GradientOfCostFunctionJo"] = Persistence.OneVector(name = "GradientOfCostFunctionJo")
+ self.StoredVariables["CurrentState"] = Persistence.OneVector(name = "CurrentState")
+ self.StoredVariables["Analysis"] = Persistence.OneVector(name = "Analysis")
+ self.StoredVariables["SimulatedObservationAtBackground"] = Persistence.OneVector(name = "SimulatedObservationAtBackground")
+ self.StoredVariables["SimulatedObservationAtOptimum"] = Persistence.OneVector(name = "SimulatedObservationAtOptimum")
+ self.StoredVariables["ObservedState"] = Persistence.OneVector(name = "ObservedState")
+ self.StoredVariables["Innovation"] = Persistence.OneVector(name = "Innovation")
+ self.StoredVariables["SigmaObs2"] = Persistence.OneScalar(name = "SigmaObs2")
+ self.StoredVariables["SigmaBck2"] = Persistence.OneScalar(name = "SigmaBck2")
+ self.StoredVariables["MahalanobisConsistency"] = Persistence.OneScalar(name = "MahalanobisConsistency")
+ self.StoredVariables["OMA"] = Persistence.OneVector(name = "OMA")
+ self.StoredVariables["OMB"] = Persistence.OneVector(name = "OMB")
+ self.StoredVariables["BMA"] = Persistence.OneVector(name = "BMA")
+ self.StoredVariables["APosterioriCovariance"] = Persistence.OneMatrix(name = "APosterioriCovariance")
+ self.StoredVariables["SimulationQuantiles"] = Persistence.OneMatrix(name = "SimulationQuantiles")
def _pre_run(self):
logging.debug("%s Lancement"%self._name)
asCovariance = None,
asEyeByScalar = None,
asEyeByVector = None,
+ asCovObject = None,
):
"""
Permet de définir une covariance :
- asEyeByVector : entrée des données comme un seul vecteur de variance,
à mettre sur la diagonale d'une matrice de corrélation, aucune matrice
n'étant donc explicitement à donner
+ - asCovObject : entrée des données comme un objet python, qui a les
+ methodes obligatoires "getT", "getI", "diag", "trace", "__add__",
+ "__sub__", "__neg__", "__mul__", "__rmul__" et facultatives "shape",
+ "size", "cholesky", "choleskyI", "asfullmatrix", "__repr__", "__str__"
"""
self.__name = str(name)
#
- self.__B = None
+ self.__C = None
self.__is_scalar = False
self.__is_vector = False
self.__is_matrix = False
+ self.__is_object = False
if asEyeByScalar is not None:
self.__is_scalar = True
- self.__B = numpy.abs( float(asEyeByScalar) )
+ self.__C = numpy.abs( float(asEyeByScalar) )
self.shape = (0,0)
self.size = 0
elif asEyeByVector is not None:
self.__is_vector = True
- self.__B = numpy.abs( numpy.array( numpy.ravel( asEyeByVector ), float ) )
- self.shape = (self.__B.size,self.__B.size)
- self.size = self.__B.size**2
+ self.__C = numpy.abs( numpy.array( numpy.ravel( asEyeByVector ), float ) )
+ self.shape = (self.__C.size,self.__C.size)
+ self.size = self.__C.size**2
elif asCovariance is not None:
self.__is_matrix = True
- self.__B = numpy.matrix( asCovariance, float )
- self.shape = self.__B.shape
- self.size = self.__B.size
+ self.__C = numpy.matrix( asCovariance, float )
+ self.shape = self.__C.shape
+ self.size = self.__C.size
+ elif asCovObject is not None:
+ self.__is_object = True
+ self.__C = asCovObject
+ for at in ("getT","getI","diag","trace","__add__","__sub__","__neg__","__mul__","__rmul__"):
+ if not hasattr(self.__C,at):
+ raise ValueError("The matrix given for %s as an object has no attribute \"%s\". Please check your object input."%(self.__name,at))
+ if hasattr(self.__C,"shape"):
+ self.shape = self.__C.shape
+ else:
+ self.shape = (0,0)
+ if hasattr(self.__C,"size"):
+ self.size = self.__C.size
+ else:
+ self.size = 0
else:
pass
# raise ValueError("The %s covariance matrix has to be specified either as a matrix, a vector for its diagonal or a scalar multiplying an identity matrix."%self.__name)
def __validate(self):
if self.ismatrix() and min(self.shape) != max(self.shape):
raise ValueError("The given matrix for %s is not a square one, its shape is %s. Please check your matrix input."%(self.__name,self.shape))
- if self.isscalar() and self.__B <= 0:
- raise ValueError("The %s covariance matrix is not positive-definite. Please check your scalar input %s."%(self.__name,self.__B_scalar))
- if self.isvector() and (self.__B <= 0).any():
- raise ValueError("The %s covariance matrix is not positive-definite. Please check your vector input."%(self.__name,))
+ if self.isobject() and min(self.shape) != max(self.shape):
+ raise ValueError("The matrix given for \"%s\" is not a square one, its shape is %s. Please check your object input."%(self.__name,self.shape))
+ if self.isscalar() and self.__C <= 0:
+ raise ValueError("The \"%s\" covariance matrix is not positive-definite. Please check your scalar input %s."%(self.__name,self.__C))
+ if self.isvector() and (self.__C <= 0).any():
+ raise ValueError("The \"%s\" covariance matrix is not positive-definite. Please check your vector input."%(self.__name,))
if self.ismatrix() and logging.getLogger().level < logging.WARNING: # La verification n'a lieu qu'en debug
try:
- L = numpy.linalg.cholesky( self.__B )
+ L = numpy.linalg.cholesky( self.__C )
except:
raise ValueError("The %s covariance matrix is not symmetric positive-definite. Please check your matrix input."%(self.__name,))
def ismatrix(self):
return self.__is_matrix
+ def isobject(self):
+ return self.__is_object
+
def getI(self):
if self.ismatrix():
- return Covariance(self.__name+"I", asCovariance = self.__B.I )
+ return Covariance(self.__name+"I", asCovariance = self.__C.I )
elif self.isvector():
- return Covariance(self.__name+"I", asEyeByVector = 1. / self.__B )
+ return Covariance(self.__name+"I", asEyeByVector = 1. / self.__C )
elif self.isscalar():
- return Covariance(self.__name+"I", asEyeByScalar = 1. / self.__B )
+ return Covariance(self.__name+"I", asEyeByScalar = 1. / self.__C )
+ elif self.isobject():
+ return Covariance(self.__name+"I", asCovObject = self.__C.getI() )
else:
- return None
+ return None # Indispensable
def getT(self):
if self.ismatrix():
- return Covariance(self.__name+"T", asCovariance = self.__B.T )
+ return Covariance(self.__name+"T", asCovariance = self.__C.T )
elif self.isvector():
- return Covariance(self.__name+"T", asEyeByVector = self.__B )
+ return Covariance(self.__name+"T", asEyeByVector = self.__C )
elif self.isscalar():
- return Covariance(self.__name+"T", asEyeByScalar = self.__B )
+ return Covariance(self.__name+"T", asEyeByScalar = self.__C )
+ elif self.isobject():
+ return Covariance(self.__name+"T", asCovObject = self.__C.getT() )
def cholesky(self):
if self.ismatrix():
- return Covariance(self.__name+"C", asCovariance = numpy.linalg.cholesky(self.__B) )
+ return Covariance(self.__name+"C", asCovariance = numpy.linalg.cholesky(self.__C) )
elif self.isvector():
- return Covariance(self.__name+"C", asEyeByVector = numpy.sqrt( self.__B ) )
+ return Covariance(self.__name+"C", asEyeByVector = numpy.sqrt( self.__C ) )
elif self.isscalar():
- return Covariance(self.__name+"C", asEyeByScalar = numpy.sqrt( self.__B ) )
+ return Covariance(self.__name+"C", asEyeByScalar = numpy.sqrt( self.__C ) )
+ elif self.isobject() and hasattr(self.__C,"cholesky"):
+ return Covariance(self.__name+"C", asCovObject = self.__C.cholesky() )
def choleskyI(self):
if self.ismatrix():
- return Covariance(self.__name+"H", asCovariance = numpy.linalg.cholesky(self.__B).I )
+ return Covariance(self.__name+"H", asCovariance = numpy.linalg.cholesky(self.__C).I )
elif self.isvector():
- return Covariance(self.__name+"H", asEyeByVector = 1.0 / numpy.sqrt( self.__B ) )
+ return Covariance(self.__name+"H", asEyeByVector = 1.0 / numpy.sqrt( self.__C ) )
elif self.isscalar():
- return Covariance(self.__name+"H", asEyeByScalar = 1.0 / numpy.sqrt( self.__B ) )
+ return Covariance(self.__name+"H", asEyeByScalar = 1.0 / numpy.sqrt( self.__C ) )
+ elif self.isobject() and hasattr(self.__C,"choleskyI"):
+ return Covariance(self.__name+"H", asCovObject = self.__C.choleskyI() )
def diag(self, msize=None):
if self.ismatrix():
- return numpy.diag(self.__B)
+ return numpy.diag(self.__C)
elif self.isvector():
- return self.__B
+ return self.__C
elif self.isscalar():
if msize is None:
raise ValueError("the size of the %s covariance matrix has to be given in case of definition as a scalar over the diagonal."%(self.__name,))
else:
- return self.__B * numpy.ones(int(msize))
+ return self.__C * numpy.ones(int(msize))
+ elif self.isobject():
+ return self.__C.diag()
def asfullmatrix(self, msize=None):
if self.ismatrix():
- return self.__B
+ return self.__C
elif self.isvector():
- return numpy.matrix( numpy.diag(self.__B), float )
+ return numpy.matrix( numpy.diag(self.__C), float )
elif self.isscalar():
if msize is None:
raise ValueError("the size of the %s covariance matrix has to be given in case of definition as a scalar over the diagonal."%(self.__name,))
else:
- return numpy.matrix( self.__B * numpy.eye(int(msize)), float )
+ return numpy.matrix( self.__C * numpy.eye(int(msize)), float )
+ elif self.isobject() and hasattr(self.__C,"asfullmatrix"):
+ return self.__C.asfullmatrix()
def trace(self, msize=None):
if self.ismatrix():
- return numpy.trace(self.__B)
+ return numpy.trace(self.__C)
elif self.isvector():
- return float(numpy.sum(self.__B))
+ return float(numpy.sum(self.__C))
elif self.isscalar():
if msize is None:
raise ValueError("the size of the %s covariance matrix has to be given in case of definition as a scalar over the diagonal."%(self.__name,))
else:
- return self.__B * int(msize)
+ return self.__C * int(msize)
+ elif self.isobject():
+ return self.__C.trace()
def __repr__(self):
- return repr(self.__B)
+ return repr(self.__C)
def __str__(self):
- return str(self.__B)
+ return str(self.__C)
def __add__(self, other):
- if self.ismatrix():
- return self.__B + numpy.asmatrix(other)
+ if self.ismatrix() or self.isobject():
+ return self.__C + numpy.asmatrix(other)
elif self.isvector() or self.isscalar():
_A = numpy.asarray(other)
- _A.reshape(_A.size)[::_A.shape[1]+1] += self.__B
+ _A.reshape(_A.size)[::_A.shape[1]+1] += self.__C
return numpy.asmatrix(_A)
def __radd__(self, other):
raise NotImplementedError("%s covariance matrix __radd__ method not available for %s type!"%(self.__name,type(other)))
def __sub__(self, other):
- if self.ismatrix():
- return self.__B - numpy.asmatrix(other)
+ if self.ismatrix() or self.isobject():
+ return self.__C - numpy.asmatrix(other)
elif self.isvector() or self.isscalar():
_A = numpy.asarray(other)
- _A.reshape(_A.size)[::_A.shape[1]+1] = self.__B - _A.reshape(_A.size)[::_A.shape[1]+1]
+ _A.reshape(_A.size)[::_A.shape[1]+1] = self.__C - _A.reshape(_A.size)[::_A.shape[1]+1]
return numpy.asmatrix(_A)
def __rsub__(self, other):
raise NotImplementedError("%s covariance matrix __rsub__ method not available for %s type!"%(self.__name,type(other)))
def __neg__(self):
- return - self.__B
+ return - self.__C
def __mul__(self, other):
if self.ismatrix() and isinstance(other,numpy.matrix):
- return self.__B * other
+ return self.__C * other
elif self.ismatrix() and (isinstance(other,numpy.ndarray) \
or isinstance(other,list) \
or isinstance(other,tuple)):
if numpy.ravel(other).size == self.shape[1]: # Vecteur
- return self.__B * numpy.asmatrix(numpy.ravel(other)).T
+ return self.__C * numpy.asmatrix(numpy.ravel(other)).T
elif numpy.asmatrix(other).shape[0] == self.shape[1]: # Matrice
- return self.__B * numpy.asmatrix(other)
+ return self.__C * numpy.asmatrix(other)
else:
raise ValueError("operands could not be broadcast together with shapes %s %s in %s matrix"%(self.shape,numpy.asmatrix(other).shape,self.__name))
elif self.isvector() and (isinstance(other,numpy.matrix) \
or isinstance(other,list) \
or isinstance(other,tuple)):
if numpy.ravel(other).size == self.shape[1]: # Vecteur
- return numpy.asmatrix(self.__B * numpy.ravel(other)).T
+ return numpy.asmatrix(self.__C * numpy.ravel(other)).T
elif numpy.asmatrix(other).shape[0] == self.shape[1]: # Matrice
- return numpy.asmatrix((self.__B * (numpy.asarray(other).transpose())).transpose())
+ return numpy.asmatrix((self.__C * (numpy.asarray(other).transpose())).transpose())
else:
raise ValueError("operands could not be broadcast together with shapes %s %s in %s matrix"%(self.shape,numpy.ravel(other).shape,self.__name))
elif self.isscalar() and isinstance(other,numpy.matrix):
- return self.__B * other
+ return self.__C * other
elif self.isscalar() and (isinstance(other,numpy.ndarray) \
or isinstance(other,list) \
or isinstance(other,tuple)):
if len(numpy.asarray(other).shape) == 1 or numpy.asarray(other).shape[1] == 1 or numpy.asarray(other).shape[0] == 1:
- return self.__B * numpy.asmatrix(numpy.ravel(other)).T
+ return self.__C * numpy.asmatrix(numpy.ravel(other)).T
else:
- return self.__B * numpy.asmatrix(other)
+ return self.__C * numpy.asmatrix(other)
+ elif self.isobject():
+ return self.__C.__mul__(other)
else:
raise NotImplementedError("%s covariance matrix __mul__ method not available for %s type!"%(self.__name,type(other)))
def __rmul__(self, other):
if self.ismatrix() and isinstance(other,numpy.matrix):
- return other * self.__B
+ return other * self.__C
elif self.isvector() and isinstance(other,numpy.matrix):
if numpy.ravel(other).size == self.shape[0]: # Vecteur
- return numpy.asmatrix(numpy.ravel(other) * self.__B)
+ return numpy.asmatrix(numpy.ravel(other) * self.__C)
elif numpy.asmatrix(other).shape[1] == self.shape[0]: # Matrice
- return numpy.asmatrix(numpy.array(other) * self.__B)
+ return numpy.asmatrix(numpy.array(other) * self.__C)
else:
raise ValueError("operands could not be broadcast together with shapes %s %s in %s matrix"%(self.shape,numpy.ravel(other).shape,self.__name))
elif self.isscalar() and isinstance(other,numpy.matrix):
- return other * self.__B
+ return other * self.__C
+ elif self.isobject():
+ return self.__C.__rmul__(other)
else:
raise NotImplementedError("%s covariance matrix __rmul__ method not available for %s type!"%(self.__name,type(other)))
# ==============================================================================
class OneScalar(Persistence):
"""
- Classe définissant le stockage d'une valeur unique réelle (float) par pas
-
+ Classe définissant le stockage d'une valeur unique réelle (float) par pas.
+
Le type de base peut être changé par la méthode "basetype", mais il faut que
- le nouveau type de base soit compatible avec les types par éléments de
+ le nouveau type de base soit compatible avec les types par éléments de
numpy. On peut même utiliser cette classe pour stocker des vecteurs/listes
ou des matrices comme dans les classes suivantes, mais c'est déconseillé
pour conserver une signification claire des noms.
class OneVector(Persistence):
"""
- Classe définissant le stockage d'une liste (list) de valeurs homogènes par
- hypothèse par pas. Pour éviter les confusions, ne pas utiliser la classe
- "OneVector" pour des données hétérogènes, mais bien "OneList".
+ Classe de stockage d'une liste de valeurs numériques homogènes par pas. Ne
+ pas utiliser cette classe pour des données hétérogènes, mais "OneList".
"""
def __init__(self, name="", unit="", basetype = numpy.ravel):
Persistence.__init__(self, name, unit, basetype)
class OneMatrix(Persistence):
"""
- Classe définissant le stockage d'une matrice de valeurs (numpy.matrix) par
- pas
+ Classe de stockage d'une matrice de valeurs (numpy.matrix) par pas.
"""
def __init__(self, name="", unit="", basetype = numpy.matrix):
Persistence.__init__(self, name, unit, basetype)
class OneList(Persistence):
"""
- Classe définissant le stockage d'une liste de valeurs potentiellement
- hétérogènes (list) par pas. Pour éviter les confusions, ne pas utiliser la
- classe "OneVector" pour des données hétérogènes, mais bien "OneList".
+ Classe de stockage d'une liste de valeurs hétérogènes (list) par pas. Ne pas
+ utiliser cette classe pour des données numériques homogènes, mais
+ "OneVector".
"""
def __init__(self, name="", unit="", basetype = list):
Persistence.__init__(self, name, unit, basetype)
class OneNoType(Persistence):
"""
- Classe définissant le stockage d'un objet sans modification (cast) de type.
- Attention, selon le véritable type de l'objet stocké à chaque pas, les
- opérations arithmétiques à base de numpy peuvent être invalides ou donner
- des résultats inattendus. Cette classe n'est donc à utiliser qu'à bon escient
+ Classe de stockage d'un objet sans modification (cast) de type. Attention,
+ selon le véritable type de l'objet stocké à chaque pas, les opérations
+ arithmétiques à base de numpy peuvent être invalides ou donner des résultats
+ inattendus. Cette classe n'est donc à utiliser qu'à bon escient
volontairement, et pas du tout par défaut.
"""
def __init__(self, name="", unit="", basetype = NoType):