2 Copyright (C) 2008-2021 EDF R&D
4 This file is part of SALOME ADAO module.
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
24 .. index:: single: TUI
25 .. index:: single: API/TUI
26 .. index:: single: adaoBuilder
29 ================================================================================
30 **[DocR]** Interface textuelle pour l'utilisateur (TUI/API)
31 ================================================================================
33 Cette section présente des méthodes avancées d'usage du module ADAO à l'aide de
34 son interface de programmation textuelle (API/TUI). Cette interface permet de
35 créer un objet de calcul de manière similaire à la construction d'un cas par
36 l'interface graphique (GUI). Dans le cas où l'on désire réaliser à la main le
37 cas de calcul TUI, on recommande de bien s'appuyer sur l'ensemble de la
38 documentation du module ADAO, et de se reporter si nécessaire à l'interface
39 graphique (GUI), pour disposer de l'ensemble des éléments permettant de
40 renseigner correctement les commandes. Les notions générales et termes utilisés
41 ici sont définis dans :ref:`section_theory`. Comme dans l'interface graphique,
42 on note que la démarche en TUI est destinée à créer et gérer un unique cas de
45 .. _subsection_tui_creating:
47 Création de cas de calcul TUI ADAO et exemples
48 ----------------------------------------------
50 .. _subsection_tui_example:
52 Un exemple simple de création d'un cas de calcul TUI ADAO
53 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
55 Pour introduire l'interface TUI, on commence par un exemple simple mais complet
56 de cas de calcul ADAO. Toutes les données sont explicitement définies dans le
57 corps du script pour faciliter la lecture. L'ensemble des commandes est le
60 from numpy import array, matrix
61 from adao import adaoBuilder
62 case = adaoBuilder.New()
63 case.set( 'AlgorithmParameters', Algorithm='3DVAR' )
64 case.set( 'Background', Vector=[0, 1, 2] )
65 case.set( 'BackgroundError', ScalarSparseMatrix=1.0 )
66 case.set( 'Observation', Vector=array([0.5, 1.5, 2.5]) )
67 case.set( 'ObservationError', DiagonalSparseMatrix='1 1 1' )
68 case.set( 'ObservationOperator', Matrix='1 0 0;0 2 0;0 0 3' )
69 case.set( 'Observer', Variable="Analysis", Template="ValuePrinter" )
72 Le résultat de l'exécution de ces commandes dans SALOME (que ce soit par la
73 commande "*shell*" de SALOME, dans la console Python de l'interface, ou par le
74 menu d'exécution d'un script) est le suivant::
76 Analysis [ 0.25000264 0.79999797 0.94999939]
78 Création détaillée d'un cas de calcul TUI ADAO
79 ++++++++++++++++++++++++++++++++++++++++++++++
81 On décrit ici plus en détail les différentes étapes de création d'un cas de
82 calcul TUI ADAO. Les commandes elles-mêmes sont détaillées juste après dans
83 l':ref:`subsection_tui_commands`.
85 La création et l'initialisation d'une étude se font par les commandes
86 suivantes, le nom ``case`` de l'objet du cas de calcul TUI ADAO étant
87 quelconque, au choix de l'utilisateur::
89 from numpy import array, matrix
90 from adao import adaoBuilder
91 case = adaoBuilder.New()
93 Il est recommandé d'importer par principe le module ``numpy`` ou ses
94 constructeurs particuliers comme celui d'``array``, pour faciliter ensuite son
95 usage dans les commandes elle-mêmes.
97 Ensuite, le cas doit être construit par une préparation et un enregistrement
98 des données définissant l'étude. L'ordre de ces commandes n'a pas d'importance,
99 il suffit que les concepts requis par l'algorithme utilisé soient présents. On
100 se reportera à :ref:`section_reference` et à ses sous-parties pour avoir le
101 détail des commandes par algorithme. Ici, on définit successivement
102 l'algorithme d'assimilation de données ou d'optimisation choisi et ses
103 paramètres, puis l'ébauche :math:`\mathbf{x}^b` (nommée ``Background``) et sa
104 covariance d'erreurs :math:`\mathbf{B}` (nommée ``BackgroundError``), et enfin
105 l'observation :math:`\mathbf{y}^o` (nommée ``Observation``) et sa covariance
106 d'erreurs :math:`\mathbf{R}` (nommée ``ObservationError``)::
108 case.set( 'AlgorithmParameters', Algorithm='3DVAR' )
110 case.set( 'Background', Vector=[0, 1, 2] )
111 case.set( 'BackgroundError', ScalarSparseMatrix=1.0 )
113 case.set( 'Observation', Vector=array([0.5, 1.5, 2.5]) )
114 case.set( 'ObservationError', DiagonalSparseMatrix='1 1 1' )
116 On remarque que l'on peut donner, en entrée des quantités vectorielles ou
117 matricielles, des objets de type ``str``, ``list`` ou ``tuple`` de Python, ou
118 de type ``array`` ou ``matrix`` de Numpy. Dans ces deux derniers cas, il faut
119 simplement importer le module Numpy avant.
121 On doit ensuite définir les opérateurs :math:`H` d'observation et
122 éventuellement :math:`M` d'évolution. Dans tous les cas, linéaire ou
123 non-linéaire, on peut les définir comme des fonctions. Dans le cas simple d'un
124 opérateur linéaire, on peut aussi le définir à l'aide de la matrice qui
125 correspond à l'opérateur linéaire. Dans le cas présent le plus simple
126 d'opérateur linéaire, on utilise la syntaxe suivante pour un opérateur de
127 :math:`\mathbf{R}^3` sur lui-même::
129 case.set( 'ObservationOperator', Matrix = "1 0 0;0 2 0;0 0 3")
131 Dans le cas beaucoup plus courant d'un opérateur non-linéaire de
132 :math:`\mathbf{R}^n` dans :math:`\mathbf{R}^p`, il doit être préalablement
133 disponible sous la forme d'une fonction Python, connue dans l'espace de nommage
134 courant, qui prend en entrée un vecteur ``numpy`` (ou une liste ordonnée) de
135 taille :math:`n` et qui restitue en sortie un vecteur ``numpy`` de taille
136 :math:`p`. Lorsque seul l'opérateur non-linéaire est défini par l'argument
137 "*OneFunction*", son adjoint est directement établi de manière numérique et il
138 est paramétrable par l'argument "*Parameters*". L'exemple suivant montre une
139 fonction ``simulation`` (qui réalise ici le même opérateur linéaire que
140 ci-dessus) et l'enregistre dans le cas ADAO::
144 "Fonction de simulation H pour effectuer Y=H(X)"
145 __x = numpy.matrix(numpy.ravel(numpy.matrix(x))).T
146 __H = numpy.matrix("1 0 0;0 2 0;0 0 3")
149 case.set( 'ObservationOperator',
150 OneFunction = simulation,
151 Parameters = {"DifferentialIncrement":0.01},
154 Pour connaître les résultats intermédiaire ou finaux du calcul du cas, on peut
155 ajouter des "*observer*", qui permettent d'associer l'exécution d'un script à
156 une variable intermédiaire ou finale du calcul. On se reportera à la
157 description de la manière d':ref:`section_advanced_observer`, et à la
158 :ref:`section_reference` pour savoir quelles sont les quantités observables.
159 Cette association d'"*observer*" avec une quantité existante se fait de manière
160 similaire à la définition des données du calcul::
162 case.set( 'Observer', Variable="Analysis", Template="ValuePrinter" )
164 Enfin, lorsque toutes les informations requises sont disponibles dans le cas
165 ``case`` de calcul ADAO, on peut en demander l'exécution de manière très
166 simple dans l'environnement de l'interpréteur Python::
170 Au final, on obtient le script très compact proposé précédemment dans
171 :ref:`subsection_tui_example`.
173 Fournir des données ou informations de calcul plus complexes
174 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
176 Une telle interface s'écrivant en Python, il est possible d'utiliser toute la
177 puissance du langage pour entrer des données plus complexes qu'une déclaration
180 L'enregistrement des données d'entrées supporte différents types de variables,
181 mais surtout, ces entrées peuvent recevoir des variables courantes disponibles
182 dans l'espace de nommage du script. Il est donc aisé d'utiliser des variables
183 calculées préalablement ou obtenues par l'import de scripts "utilisateur". Si
184 par exemple les observations sont disponibles sous la forme d'une liste dans un
185 fichier Python externe nommé ``observations.py`` sous le nom ``table``, il
186 suffit de réaliser les opérations suivantes pour enregistrer les observations
187 dans le cas de calcul TUI ADAO::
189 from observations import table
190 case.set( 'Observation', Vector=table )
192 La première ligne importe la variable ``table`` depuis le fichier externe, et
193 la seconde enregistre directement cette table comme la donnée "*Observation*".
195 La simplicité de cet enregistrement montre bien la facilité d'obtenir les
196 données de calcul depuis des sources externes, fichiers ou flux informatiques
197 atteignables en Python. Comme d'habitude, il est recommandé à l'utilisateur de
198 vérifier ses données avant de les enregistrer dans le cas de calcul TUI ADAO
199 pour éviter les erreurs compliquées à corriger.
201 Obtenir et utiliser les résultats de calcul de manière plus riche
202 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
204 De la même manière, il est possible d'obtenir et traiter les résultats de
205 calcul de manière plus riche, pour enchaîner sur des post-traitements après le
208 Les variables de résultats de calcul, ou les variables internes issues de
209 l'optimisation ou de l'assimilation de données, sont disponibles à travers la
210 méthode ``get`` du cas de calcul TUI ADAO, qui renvoie un objet de type liste
211 de la variable demandée. On se reportera aux
212 :ref:`section_ref_output_variables` pour une description détaillée sur ce
215 A titre d'exemple, on donne quelques lignes de script qui permettent d'obtenir
216 le nombre d'itérations de l'optimisation et la valeur optimale ainsi que sa
220 print(" Nombre d'iterations : %i"%len(case.get("CostFunctionJ")))
221 Xa = case.get("Analysis")
222 print(" Analyse optimale : %s"%(Xa[-1],))
223 print(" Taille de l'analyse : %i"%len(Xa[-1]))
226 Ces lignes peuvent être très simplement additionnées à l'exemple initial de cas
227 de calcul TUI ADAO proposé dans :ref:`subsection_tui_example`.
229 De même que pour l'entrée des données, la simplicité de récupération des
230 résultats permet d'envisager aisément des post-traitements enchaînés dans
231 SALOME, pour utiliser par exemple de la visualisation avec MatPlotLib ou
232 PARAVIS [PARAVIS]_, de l'adaptation de maillage avec HOMARD [HOMARD]_, ou pour
235 .. _subsection_tui_commands:
237 Ensemble des commandes disponibles en interface textuelle TUI
238 -------------------------------------------------------------
240 Dans l'interface TUI du module ADAO, on suit les conventions et recommandations
241 courantes en Python pour la distinction entre ce qui est public, et ce qui est
242 privé ou réservé car relevant des détails d'implémentation. De manière
243 pratique, tout nom d'objet ou de fonction commençant par au moins un signe "_"
244 est privé au sens courant de programmation ("*private*"). Néanmoins, l'absence
245 d'un tel signe au début d'un nom ne le désigne pas comme public. De manière
246 générale, en Python, et contrairement à d'autres langages, on peut accéder aux
247 objets ou aux fonctions privés. Cela peut parfois être utile, mais un tel usage
248 dans vos codes conduira à des plantages sans avertissement lors de futures
249 versions. Il est donc fortement recommandé de ne pas le faire.
251 Pour clarifier et faciliter l'utilisation du module pour du script, **cette
252 section définit donc l'interface de programmation (API) textuelle publique pour
253 l'utilisateur (TUI) de manière complète et limitative**. L'usage en script
254 d'objets ou fonctions ADAO autres que ceux qui sont définis ici est fortement
255 déconseillé, car cela conduira vraisemblablement à des plantages sans
256 avertissement lors de futures versions.
258 Syntaxes d'appel équivalentes pour les commandes TUI
259 ++++++++++++++++++++++++++++++++++++++++++++++++++++
261 La définition des données lors de la création de cas de calcul TUI ADAO
262 supporte **deux syntaxes entièrement équivalentes**. On peut :
264 - soit utiliser la commande ``set`` et comme premier argument le concept
265 ``XXXXX`` sur lequel appliquer la commande dont les arguments suivent,
266 - soit utiliser la commande ``setXXXXX`` contenant les arguments de la commande
269 Pour illustrer cette équivalence, on prend l'exemple des deux commandes
270 suivantes qui conduisent au même résultat::
272 case.set( 'Background', Vector=[0, 1, 2] )
276 case.setBackground( Vector=[0, 1, 2] )
278 Le choix de l'une ou l'autre des syntaxes est librement laissé à l'utilisateur,
279 selon son contexte d'usage. Dans la suite, par souci de clarté, on définit les
280 commandes selon la seconde syntaxe.
282 Création d'un cas de calcul en interface textuelle TUI
283 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
285 La création et l'initialisation d'un cas de calcul en interface textuelle TUI
286 se font en important le module d'interface "*adaoBuilder*" et en invoquant sa
287 méthode "*New()*" comme illustré dans les quelques lignes suivantes (le nom
288 ``case`` de l'objet étant quelconque, au choix de l'utilisateur)::
290 from numpy import array, matrix
291 from adao import adaoBuilder
292 case = adaoBuilder.New()
294 Il est recommandé par principe de toujours importer le module ``numpy`` (ou ses
295 constructeurs particuliers, comme celui d'``array``) pour faciliter ensuite son
296 usage dans les commandes elles-mêmes.
298 Définir les données de calcul
299 +++++++++++++++++++++++++++++
301 Les commandes qui suivent permettent de définir les données d'un cas de calcul
302 TUI ADAO. Le pseudo-type des arguments est similaire et compatible avec ceux
303 des entrées en interface GUI, décrits dans la section des
304 :ref:`section_reference_entry` et en particulier par la
305 :ref:`section_ref_entry_types`. La vérification de l'adéquation des grandeurs
306 se fait soit lors de leur définition, soit lors de l'exécution.
308 .. index:: single: Stored
310 Dans chaque commande, le mot-clé booléen "*Stored*" permet d'indiquer si l'on
311 veut éventuellement stocker la grandeur définie, pour en disposer en cours de
312 calcul ou en sortie. Le choix par défaut est de ne pas stocker, et il est
313 recommandé de conserver cette valeur par défaut. En effet, pour un cas de
314 calcul TUI, on dispose déjà souvent des grandeurs données en entrées qui sont
315 présentes dans l'espace de nommage courant du cas.
317 Les commandes disponibles sont les suivantes :
319 .. index:: single: Background
320 .. index:: single: setBackground
322 **setBackground** (*Vector, VectorSerie, Script, DataFile, ColNames, ColMajor, Stored*)
323 Cette commande permet de définir l'ébauche :math:`\mathbf{x}^b`. Selon les
324 algorithmes, on peut la définir comme un vecteur simple par "*Vector*", ou
325 comme une liste de vecteurs par "*VectorSerie*". Si on la définit par un
326 script dans "*Script*", le vecteur est de type "*Vector*" (par défaut) ou
327 "*VectorSerie*" selon que l'une de ces variables est placée à "*True*". Si
328 on utilise un fichier de données par "*DataFile*" (en sélectionnant, en
329 colonne par défaut ou en ligne selon "*ColMajor*", toutes les variables par
330 défaut ou celles de la liste "*ColNames*"), le vecteur est de type
333 .. index:: single: BackgroundError
334 .. index:: single: setBackgroundError
336 **setBackgroundError** (*Matrix, ScalarSparseMatrix, DiagonalSparseMatrix, Script, Stored*)
337 Cette commande permet de définir la matrice :math:`\mathbf{B}` de
338 covariance des erreurs d'ébauche. La matrice peut être définie de manière
339 complète par le mot-clé "*Matrix*", ou de manière parcimonieuse, comme une
340 matrice diagonale dont on donne la variance unique sur la diagonale par
341 "*ScalarSparseMatrix*", ou comme une matrice diagonale dont on donne le
342 vecteur des variances situé sur la diagonale par "*DiagonalSparseMatrix*".
343 Si on la définit par un script dans "*Script*", la matrice est de type
344 "*Matrix*" (par défaut), "*ScalarSparseMatrix*" ou "*DiagonalSparseMatrix*"
345 selon que l'une de ces variables est placée à "*True*".
347 .. index:: single: CheckingPoint
348 .. index:: single: setCheckingPoint
350 **setCheckingPoint** (*Vector, VectorSerie, Script, DataFile, ColNames, ColMajor, Stored*)
351 Cette commande permet de définir un point courant :math:`\mathbf{x}`
352 utilisé pour un algorithme de vérification. Selon les algorithmes, on peut
353 le définir comme un vecteur simple par "*Vector*", ou comme une liste de
354 vecteurs par "*VectorSerie*". Si on le définit par un script dans
355 "*Script*", le vecteur est de type "*Vector*" (par défaut) ou
356 "*VectorSerie*" selon que l'une de ces variables est placée à "*True*". Si
357 on utilise un fichier de données par "*DataFile*" (en sélectionnant, en
358 colonne par défaut ou en ligne selon "*ColMajor*", toutes les variables par
359 défaut ou celles de la liste "*ColNames*"), le vecteur est de type
362 .. index:: single: ControlModel
363 .. index:: single: setControlModel
364 .. index:: single: ExtraArguments
366 **setControlModel** (*Matrix, OneFunction, ThreeFunctions, Parameters, Script, ExtraArguments, Stored*)
367 Cette commande permet de définir l'opérateur de contrôle :math:`O`, qui
368 décrit un contrôle d'entrée linéaire externe de l'opérateur d'évolution ou
369 d'observation. On se reportera :ref:`section_ref_operator_control`. Sa
370 valeur est définie comme un objet de type fonction ou de type "*Matrix*".
371 Dans le cas d'une fonction, différentes formes fonctionnelles peuvent être
372 utilisées, comme décrit dans la section
373 :ref:`section_ref_operator_requirements`, et entrées par les mots-clés
374 "*OneFunction*" ou "*ThreeFunctions*". Dans le cas d'une définition par
375 "*Script*", l'opérateur est de type "*Matrix*", "*OneFunction*" ou
376 "*ThreeFunctions*" selon que l'une de ces variables est placée à "*True*".
377 Les paramètres de contrôle de l'approximation numérique de l'opérateur
378 adjoint, dans le cas "*OneFunction*", peuvent être renseignés par un
379 dictionnaire à travers le mot-clé "*Parameters*". Les entrées potentielles
380 de ce dictionnaire de paramètres sont "*DifferentialIncrement*",
381 "*CenteredFiniteDifference*" (similaires à celles de l'interface
382 graphique). Si l'opérateur nécessite des arguments fixes complémentaires,
383 ils peuvent être fournis par la variable "*ExtraArguments*" sous la forme
384 d'un dictionnaire de paramètres nommés.
386 .. index:: single: ControlInput
387 .. index:: single: setControlInput
389 **setControlInput** (*Vector, VectorSerie, Script, DataFile, ColNames, ColMajor, Stored*)
390 Cette commande permet de définir le vecteur de contrôle :math:`\mathbf{u}`.
391 Selon les algorithmes, on peut le définir comme un vecteur simple par
392 "*Vector*", ou comme une liste de vecteurs par "*VectorSerie*". Si on le
393 définit par un script dans "*Script*", le vecteur est de type "*Vector*"
394 (par défaut) ou "*VectorSerie*" selon que l'une de ces variables est placée
395 à "*True*". Si on utilise un fichier de données par "*DataFile*" (en
396 sélectionnant, en colonne par défaut ou en ligne selon "*ColMajor*", toutes
397 les variables par défaut ou celles de la liste "*ColNames*"), le vecteur
398 est de type "*Vector*".
400 .. index:: single: EvolutionError
401 .. index:: single: setEvolutionError
403 **setEvolutionError** (*Matrix, ScalarSparseMatrix, DiagonalSparseMatrix, Script, Stored*)
404 Cette commande permet de définir la matrice :math:`\mathbf{Q}` de
405 covariance des erreurs d'évolution. La matrice peut être définie de manière
406 complète par le mot-clé "*Matrix*", ou de manière parcimonieuse, comme une
407 matrice diagonale dont on donne la variance unique sur la diagonale par
408 "*ScalarSparseMatrix*", ou comme une matrice diagonale dont on donne le
409 vecteur des variances situé sur la diagonale par "*DiagonalSparseMatrix*".
410 Si on la définit par un script dans "*Script*", la matrice est de type
411 "*Matrix*" (par défaut), "*ScalarSparseMatrix*" ou "*DiagonalSparseMatrix*"
412 selon que l'une de ces variables est placée à "*True*".
414 .. index:: single: EvolutionModel
415 .. index:: single: setEvolutionModel
416 .. index:: single: ExtraArguments
418 **setEvolutionModel** (*Matrix, OneFunction, ThreeFunctions, Parameters, Script, ExtraArguments, Stored*)
419 Cette commande permet de définir l'opérateur d'evolution :math:`M`, qui
420 décrit un pas élémentaire d'évolution de l'état :math:`\mathbf{x}`. Sa
421 valeur est définie comme un objet de type fonction ou de type "*Matrix*".
422 Dans le cas d'une fonction, différentes formes fonctionnelles peuvent être
423 utilisées, comme décrit dans la section
424 :ref:`section_ref_operator_requirements`, et entrées par les mots-clés
425 "*OneFunction*" ou "*ThreeFunctions*". Dans le cas d'une définition par
426 "*Script*", l'opérateur est de type "*Matrix*", "*OneFunction*" ou
427 "*ThreeFunctions*" selon que l'une de ces variables est placée à "*True*".
428 Les paramètres de contrôle de l'approximation numérique de l'opérateur
429 adjoint, dans le cas "*OneFunction*", peuvent être renseignés par un
430 dictionnaire dans "*Parameters*". Les entrées potentielles de ce
431 dictionnaire de paramètres sont "*DifferentialIncrement*",
432 "*CenteredFiniteDifference*", "*EnableMultiProcessing*",
433 "*NumberOfProcesses*" (similaires à celles de l'interface graphique). Si
434 l'opérateur nécessite des paramètres fixes complémentaires en plus de
435 l'état :math:`\mathbf{x}`, ils peuvent être fournis par la variable
436 "*ExtraArguments*" sous la forme d'un dictionnaire de paramètres nommés.
438 .. index:: single: Observation
439 .. index:: single: setObservation
441 **setObservation** (*Vector, VectorSerie, Script, DataFile, ColNames, ColMajor, Stored*)
442 Cette commande permet de définir le vecteur d'observation
443 :math:`\mathbf{y}^o`. Selon les algorithmes, on peut le définir comme un
444 vecteur simple par "*Vector*", ou comme une liste de vecteurs par
445 "*VectorSerie*". Si on le définit par un script dans "*Script*", le vecteur
446 est de type "*Vector*" (par défaut) ou "*VectorSerie*" selon que l'une de
447 ces variables est placée à "*True*". Si on utilise un fichier de données
448 par "*DataFile*" (en sélectionnant, en colonne par défaut ou en ligne selon
449 "*ColMajor*", toutes les variables par défaut ou celles de la liste
450 "*ColNames*"), le vecteur est de type "*Vector*".
452 .. index:: single: ObservationError
453 .. index:: single: setObservationError
455 **setObservationError** (*Matrix, ScalarSparseMatrix, DiagonalSparseMatrix, Script, Stored*)
456 Cette commande permet de définir la matrice :math:`\mathbf{R}` de
457 covariance des erreurs d'observation. La matrice peut être définie de
458 manière complète par le mot-clé "*Matrix*", ou de manière parcimonieuse,
459 comme une matrice diagonale dont on donne la variance unique sur la
460 diagonale par "*ScalarSparseMatrix*", ou comme une matrice diagonale dont
461 on donne le vecteur des variances situé sur la diagonale par
462 "*DiagonalSparseMatrix*". Si on la définit par un script dans "*Script*",
463 la matrice est de type "*Matrix*" (par défaut), "*ScalarSparseMatrix*" ou
464 "*DiagonalSparseMatrix*" selon que l'une de ces variables est placée à
467 .. index:: single: ObservationOperator
468 .. index:: single: setObservationOperator
469 .. index:: single: ExtraArguments
471 **setObservationOperator** (*Matrix, OneFunction, ThreeFunctions, AppliedInXb, Parameters, Script, ExtraArguments, Stored*)
472 Cette commande permet de définir l'opérateur d'observation :math:`H`, qui
473 transforme les paramètres d'entrée :math:`\mathbf{x}` en résultats
474 :math:`\mathbf{y}` qui sont à comparer aux observations
475 :math:`\mathbf{y}^o`. Sa valeur est définie comme un objet de type fonction
476 ou de type "*Matrix*". Dans le cas d'une fonction, différentes formes
477 fonctionnelles peuvent être utilisées, comme décrit dans la section
478 :ref:`section_ref_operator_requirements`, et entrées par les mots-clés
479 "*OneFunction*" ou "*ThreeFunctions*". Dans le cas d'une définition par
480 "*Script*", l'opérateur est de type "*Matrix*", "*OneFunction*" ou
481 "*ThreeFunctions*" selon que l'une de ces variables est placée à "*True*".
482 Dans le cas où l'opérateur :math:`H` évalué en :math:`\mathbf{x}^b` est
483 disponible, il peut être donné en utilisant "*AppliedInXb*" et sera
484 considéré comme un vecteur. Les paramètres de contrôle de l'approximation
485 numérique de l'opérateur adjoint, dans le cas "*OneFunction*", peuvent être
486 renseignés par un dictionnaire dans "*Parameters*". Les entrées
487 potentielles de ce dictionnaire de paramètres sont
488 "*DifferentialIncrement*", "*CenteredFiniteDifference*",
489 "*EnableMultiProcessing*", "*NumberOfProcesses*" (similaires à celles de
490 l'interface graphique). Si l'opérateur nécessite des paramètres fixes
491 complémentaires en plus de l'état :math:`\mathbf{x}`, ils peuvent être
492 fournis par la variable "*ExtraArguments*" sous la forme d'un dictionnaire
493 de paramètres nommés.
495 .. index:: single: set
497 **set** (*Concept,...*)
498 Cette commande permet de disposer d'une syntaxe équivalente pour toutes les
499 commandes de ce paragraphe. Son premier argument est le nom du concept à
500 définir (par exemple "*Background*" ou "*ObservationOperator*"), sur lequel
501 s'applique ensuite les arguments qui suivent, qui sont les mêmes que dans
502 les commandes individuelles précédentes. Lors de l'usage de cette commande,
503 il est indispensable de nommer les arguments (par exemple "*Vector=...*").
505 Paramétrer le calcul, les sorties, etc.
506 +++++++++++++++++++++++++++++++++++++++
508 .. index:: single: AlgorithmParameters
509 .. index:: single: setAlgorithmParameters
511 **setAlgorithmParameters** (*Algorithm, Parameters, Script*)
512 Cette commande permet de choisir l'algorithme de calcul ou de vérification
513 par l'argument "*Algorithm*" sous la forme d'un nom d'algorithme (on se
514 reportera utilement aux listes des :ref:`section_reference_assimilation` et
515 des :ref:`section_reference_checking`), et de définir les paramètres de
516 calcul par l'argument "*Parameters*". Dans le cas d'une définition par
517 "*Script*", le fichier indiqué doit contenir les deux variables
518 "*Algorithm*" et "*Parameters*" (ou "*AlgorithmParameters*" de manière
521 .. index:: single: setName
523 **setName** (*String*)
524 Cette commande permet de donner un titre court au cas de calcul.
526 .. index:: single: setDirectory
528 **setDirectory** (*String*)
529 Cette commande permet d'indiquer le répertoire courant d'exécution.
531 .. index:: single: setDebug
534 Cette commande permet d'activer le mode d'information détaillé lors de
537 .. index:: single: setNoDebug
540 Cette commande permet de désactiver le mode d'information détaillé lors de
543 .. index:: single: Observer
544 .. index:: single: Observer Template
545 .. index:: single: setObserver
546 .. index:: single: setObserver Template
548 **setObserver** (*Variable, Template, String, Script, Info*)
549 Cette commande permet de définir un *observer* sur une variable courante ou
550 finale du calcul. On se reportera à la description des
551 :ref:`section_ref_observers_requirements` pour avoir leur liste et leur
552 format, et à la :ref:`section_reference` pour savoir quelles sont les
553 quantités observables. On définit comme un "*String*" le corps de
554 l'*observer*, en utilisant une chaîne de caractères incluant si nécessaire
555 des sauts de lignes. On recommande d'utiliser les patrons disponibles par
556 l'argument "*Template*". Dans le cas d'une définition par "*Script*", le
557 fichier indiqué doit contenir uniquement le corps de la fonction, comme
558 décrit dans les :ref:`section_ref_observers_requirements`. La variable
559 "*Info*" contient une chaîne de caractère d'information ou une chaine vide.
561 .. index:: single: UserPostAnalysis
562 .. index:: single: UserPostAnalysis Template
563 .. index:: single: setUserPostAnalysis
564 .. index:: single: setUserPostAnalysis Template
566 **setUserPostAnalysis** (*Template, String, Script*)
567 Cette commande permet de définir le traitement des paramètres ou des
568 résultats après le déroulement de l'algorithme de calcul. Sa valeur est
569 définie soit par un nom de patron prédéfini, soit par un nom de fichier
570 script, soit par une chaîne de caractères. Cela permet de produire
571 directement du code de post-processing dans un cas ADAO. On peut d'utiliser
572 les patrons disponibles par l'argument "*Template*" (qui peut valoir
573 "*AnalysisPrinter*", "*AnalysisSaver*" et "*AnalysisPrinterAndSaver*").
574 Dans le cas d'une définition par "*Script*", le fichier indiqué doit
575 contenir uniquement les commandes que l'on aurait pu mettre à la suite de
576 l'exécution du calcul. Remarque importante : ce traitement n'est exécuté
577 que lorsque le cas est exécuté en TUI ou exporté en YACS.
582 .. index:: single: execute
583 .. index:: single: Executor
584 .. index:: single: SaveCaseInFile
585 .. index:: single: nextStep
587 **execute** (*Executor, SaveCaseInFile, nextStep*)
588 Cette commande lance le calcul complet dans l'environnement d'exécution
589 choisi par le mot-clé *Executor*, qui est défini par défaut selon
590 l'environnement de lancement. Cet environnement peut être celui de
591 l'interpréteur Python, sans interaction avec YACS (demandé par la valeur
592 "*Python*"), ou celui de YACS (demandé par la valeur "*YACS*" [YACS]_). Si
593 un fichier est indiqué dans le mot-clé *SaveCaseInFile*, il sera utilisé
594 pour enregistrer la version associée du fichier de commande pour
595 l'environnement d'exécution requis. Le mot-clé booléen "*nextStep*" indique
596 que l'exécution repart du résultat de la précédente exécution sans la
597 stocker (valeur "*True*") ou non (valeur "*False*", par défaut). Lors de
598 l'exécution, les sorties courantes (standard et d'erreur) sont celles de
599 l'environnement choisi. On dispose si nécessaire (ou si possible) du
600 parallélisme interne des algorithmes dans ADAO, du parallélisme de YACS, et
601 du parallélisme interne du ou des codes de simulation utilisés.
603 Obtenir séparément les résultats de calcul
604 ++++++++++++++++++++++++++++++++++++++++++
606 .. index:: single: get
609 Cette commande permet d'extraire explicitement les variables disponibles en
610 sortie du cas de calcul TUI ADAO pour les utiliser dans la suite du
611 scripting, par exemple en visualisation. Elle a pour argument le nom d'un
612 variable dans "*Concept*", et renvoie en retour la grandeur sous la forme
613 d'une liste (même s'il n'y en a qu'un exemplaire) de cette variable de
614 base. Pour connaître la liste des variables et les utiliser, on se
615 reportera à l':ref:`subsection_r_o_v_Inventaire`, et plus généralement à la
616 fois aux :ref:`section_ref_output_variables` et aux documentations
617 individuelles des algorithmes.
619 Enregistrer, charger ou convertir les commandes de cas de calcul
620 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
622 L'enregistrement ou le chargement d'un cas de calcul concernent les quantités
623 et les actions qui lui sont liées par les commandes précédentes, à l'exclusion
624 d'opérations externes au cas (comme par exemple le post-processing qui peut
625 être développé après le cas de calcul). Les commandes enregistrées ou chargées
626 restent néanmoins parfaitement compatibles avec ces opérations en Python
629 .. index:: single: load
630 .. index:: single: FileName
631 .. index:: single: Content
632 .. index:: single: Object
633 .. index:: single: Formater
635 **load** (*FileName, Content, Object, Formater*)
636 Cette commande permet de lire ou charger un cas d'étude, à partir d'un
637 fichier "*FileName*" ou d'un contenu en mémoire par "*Content*" ou
638 "*Object*". Le mot-clé "*Formater*" peut désigner le format "*TUI*" pour
639 les commandes du type interface de programmation textuelle (défaut), et le
640 format "*COM*" pour les commandes du type COMM provenant de l'interface
643 .. index:: single: dump
645 **dump** (*FileName, Formater*)
646 Cette commande permet d'enregistrer, dans un fichier "*FileName*", les
647 commandes du cas d'étude en cours. Le mot-clé "*Formater*" peut désigner
648 les formats "*TUI*" pour les commandes du type interface de programmation
649 textuelle (défaut), et "*YACS*" pour les commandes du type YACS.
651 .. index:: single: convert
652 .. index:: single: FileNameFrom
653 .. index:: single: ContentFrom
654 .. index:: single: ObjectFrom
655 .. index:: single: FormaterFrom
656 .. index:: single: FileNameTo
657 .. index:: single: FormaterTo
659 **convert** (*FileNameFrom, ContentFrom, ObjectFrom, FormaterFrom, FileNameTo, FormaterTo*)
660 Cette commande permet de convertir directement d'un format reconnu à un
661 autre les commandes établissant le cas de calcul en cours. Certains
662 formats ne sont disponibles qu'en entrée ou qu'en sortie.
664 De plus, on peut obtenir une information simple sur le cas d'étude tel que
665 défini par l'utilisateur en utilisant directement la commande "*print*" de Python
666 sur le cas, à toute étape lors de sa construction. Par exemple::
668 from numpy import array, matrix
669 from adao import adaoBuilder
670 case = adaoBuilder.New()
671 case.set( 'AlgorithmParameters', Algorithm='3DVAR' )
672 case.set( 'Background', Vector=[0, 1, 2] )
675 dont le résultat est ici::
677 ================================================================================
679 ================================================================================
681 - AlgorithmParameters command has been set with values:
684 - Background command has been set with values:
687 .. _subsection_tui_advanced:
689 Exemples plus avancés de cas de calcul TUI ADAO
690 -----------------------------------------------
692 On propose ici des exemples plus complets de cas de calcul TUI ADAO, en donnant
693 l'objectif de l'exemple et un jeu de commandes qui permet de parvenir à cet
696 Exploitation indépendante des résultats d'un cas de calcul
697 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
699 L'objectif est d'effectuer en TUI la mise en données d'un cas de calcul ADAO,
700 son exécution, puis la récupération des résultats pour ensuite enchaîner sur
701 une exploitation indépendante de ces résultats (cette dernière n'étant pas
702 décrite ici, puisque dépendante de l'utilisateur).
704 Les hypothèses du cas utilisateur sont les suivantes. On suppose :
706 #. que l'on veut recaler 3 paramètres ``alpha``, ``beta`` et ``gamma`` dans un domaine borné,
707 #. que l'on dispose d'observations nommées ``observations``,
708 #. que l'utilisateur dispose en Python d'une fonction de simulation physique appelée ``simulation``, préalablement (bien) testée, qui transforme les 3 paramètres en résultats similaires aux observations,
709 #. que l'exploitation indépendante, que l'utilisateur veut faire, est représentée ici par l'affichage simple de l'état initial, de l'état optimal, de la simulation en ce point, des états intermédiaires et du nombre d'itérations d'optimisation.
711 Pour effectuer de manière simple cet essai de cas de calcul TUI, on se donne
712 par exemple les entrées suivantes, parfaitement arbitraires, en construisant
713 les observations par simulation pour se placer dans un cas d'expériences
714 jumelles (pour mémoire, voir la démarche :ref:`section_methodology_twin`)::
717 # Construction artificielle d'un exemple de données utilisateur
718 # -------------------------------------------------------------
723 alphamin, alphamax = 0., 10.
724 betamin, betamax = 3, 13
725 gammamin, gammamax = 1.5, 15.5
728 "Fonction de simulation H pour effectuer Y=H(X)"
730 __x = numpy.matrix(numpy.ravel(numpy.matrix(x))).T
731 __H = numpy.matrix("1 0 0;0 2 0;0 0 3; 1 2 3")
734 # Observations obtenues par simulation
735 # ------------------------------------
736 observations = simulation((2, 3, 4))
738 Le jeu de commandes que l'on peut utiliser est le suivant::
741 from adao import adaoBuilder
743 # Mise en forme des entrées
744 # -------------------------
745 Xb = (alpha, beta, gamma)
747 (alphamin, alphamax),
749 (gammamin, gammamax))
753 case = adaoBuilder.New()
755 'AlgorithmParameters',
759 "MaximumNumberOfSteps":100,
760 "StoreSupplementaryCalculations":[
763 "SimulatedObservationAtOptimum",
767 case.set( 'Background', Vector = numpy.array(Xb), Stored = True )
768 case.set( 'Observation', Vector = numpy.array(observations) )
769 case.set( 'BackgroundError', ScalarSparseMatrix = 1.0e10 )
770 case.set( 'ObservationError', ScalarSparseMatrix = 1.0 )
772 'ObservationOperator',
773 OneFunction = simulation,
774 Parameters = {"DifferentialIncrement":0.0001},
776 case.set( 'Observer', Variable="CurrentState", Template="ValuePrinter" )
779 # Exploitation indépendante
780 # -------------------------
781 Xbackground = case.get("Background")
782 Xoptimum = case.get("Analysis")[-1]
783 FX_at_optimum = case.get("SimulatedObservationAtOptimum")[-1]
784 J_values = case.get("CostFunctionJ")[:]
786 print("Nombre d'itérations internes...: %i"%len(J_values))
787 print("Etat initial...................: %s"%(numpy.ravel(Xbackground),))
788 print("Etat optimal...................: %s"%(numpy.ravel(Xoptimum),))
789 print("Simulation à l'état optimal....: %s"%(numpy.ravel(FX_at_optimum),))
792 L'exécution de jeu de commandes donne le résultat suivant::
794 CurrentState [ 5. 7. 9.]
795 CurrentState [ 0. 3. 1.5]
796 CurrentState [ 1.40006418 3.86705307 3.7061137 ]
797 CurrentState [ 1.42580231 3.68474804 3.81008738]
798 CurrentState [ 1.60220353 3.0677108 4.06146069]
799 CurrentState [ 1.72517855 3.03296953 4.04915706]
800 CurrentState [ 2.00010755 3. 4.00055409]
801 CurrentState [ 1.99995528 3. 3.99996367]
802 CurrentState [ 2.00000007 3. 4.00000011]
803 CurrentState [ 2. 3. 4.]
805 Nombre d'itérations internes...: 10
806 Etat initial...................: [ 5. 7. 9.]
807 Etat optimal...................: [ 2. 3. 4.]
808 Simulation à l'état optimal....: [ 2. 6. 12. 20.]
810 Comme il se doit en expériences jumelles, avec une confiance majoritairement
811 placée dans les observations, on constate que l'on retrouve bien les paramètres
812 qui ont servi à construire artificiellement les observations.
814 .. Réconciliation de courbes à l'aide de MedCoupling
815 .. +++++++++++++++++++++++++++++++++++++++++++++++++
817 .. Utilisation de fonctions de surveillance de type "observer"
818 .. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
820 .. Equivalences entre l'interface graphique (GUI) et l'interface textuelle (TUI)
821 .. -----------------------------------------------------------------------------
823 .. [HOMARD] Pour de plus amples informations sur HOMARD, voir le *module HOMARD* et son aide intégrée disponible dans le menu principal *Aide* de l'environnement SALOME.
825 .. [PARAVIS] 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.
827 .. [YACS] 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.