6. [DocU] Tutoriaux sur l’utilisation du module ADAO dans Python

Cette section présente quelques exemples d’utilisation du module ADAO en Python. Le premier montre comment construire un cas simple d’assimilation de données définissant explicitement toutes les données d’entrée requises à travers l’interface utilisateur textuelle (TUI) décrite en partie [DocR] Interface textuelle pour l’utilisateur (TUI/API). Le second montre, sur le même cas, comment définir les données d’entrée à partir de sources externes à travers des scripts. On présente ici toujours des scripts Python car ils sont directement insérables dans les définitions de script de l’interface Python, mais les fichiers externes peuvent utiliser d’autres langages.

Ces exemples sont intentionnellement décrits de manière semblable aux [DocU] Tutoriaux sur l’utilisation du module ADAO dans SALOME car ils sont similaires à ceux que l’on peut traiter dans l’interface graphique SALOME. On peut d’ailleurs directement obtenir une forme scriptée d’un cas construit dans l’interface graphique à l’aide du bouton d’export TUI eficas_totui intégré dans l’interface. Les notations mathématiques utilisées ci-dessous sont expliquées dans la section [DocT] Une brève introduction à l’Assimilation de Données et à l’Optimisation.

D’autres exemples simples, et leurs illustrations, sont insérés à la fin de la documentation de référence de certains algorithmes. C’est le cas, de manière non limitative, des Algorithme de calcul « 3DVAR », Algorithme de calcul « KalmanFilter » et Algorithme de calcul « ExtendedBlue ».

6.1. Construire un cas d’estimation avec une définition explicite des données

Cet exemple très simple est un cas de démonstration, et il décrit comment mettre au point un environnement d’estimation par BLUE de manière à obtenir un état estimé par méthode de moindres carrés pondérés d’un système à partir d’une observation de l’état et d’une connaissance a priori (ou ébauche) de cet état. En d’autres termes, on cherche l’intermédiaire pondéré entre les vecteurs d’observation et d’ébauche. Toutes les valeurs numériques de cet exemple sont arbitraires.

6.1.1. Conditions d’expérience

On choisit d’opérer dans un espace d’observation à 3 dimensions. La 3D est choisie de manière à restreindre la taille des objets numériques à entrer explicitement par l’utilisateur, mais le problème n’est pas dépendant de la dimension et peut être posé en dimension 10, 100, 1000… L’observation \mathbf{y}^o vaut 1 dans chaque direction, donc :

Yo = [1 1 1]

L’ébauche \mathbf{x}^b de l’état , qui représente une connaissance a priori ou une régularisation mathématique, est choisie comme valant 0 dans chaque cas, ce qui donne donc :

Xb = [0 0 0]

La mise en oeuvre de l’assimilation de données requiert des informations sur les covariances d’erreur \mathbf{R} et \mathbf{B}, respectivement pour les variables d’erreur d’observation et d’ébauche. On choisit ici des erreurs décorrélées (c’est-à-dire des matrices diagonales) et d’avoir la même variance de 1 pour toutes les variables (c’est-à-dire des matrices identité). On pose donc :

B = R = Id = [1 0 0 ; 0 1 0 ; 0 0 1]

Enfin, on a besoin d’un opérateur d’observation \mathbf{H} pour convertir l’état d’ébauche dans l’espace des observations. Ici, comme les dimensions d’espace sont les mêmes et que l’on postule un opérateur linéaire de sélection, on peut choisir l’identité comme opérateur d’observation :

H = Id = [1 0 0 ; 0 1 0 ; 0 0 1]

Avec de tels choix, l’estimateur « Best Linear Unbiased Estimator » (BLUE) sera le vecteur moyen entre \mathbf{y}^o et \mathbf{x}^b, nommé analysis, noté \mathbf{x}^a, et valant :

Xa = [0.5 0.5 0.5]

Pour étendre cet exemple, on peut modifier les variances représentées par \mathbf{B} ou \mathbf{R} indépendamment, et l’analyse \mathbf{x}^a se déplacera vers \mathbf{y}^o ou vers \mathbf{x}^b, en proportion inverse des variances dans \mathbf{B} et \mathbf{R}. Comme autre extension, on peut aussi dire qu’il est équivalent de rechercher l’analyse à l’aide d’un algorithme de « Blue » ou d’un algorithme de « 3DVAR ».

6.1.2. Utiliser l’interface textuelle (TUI) pour construire le cas ADAO

On va renseigner les variables pour construire le cas ADAO en utilisant les conditions d’expérience décrites ci-dessus. L’ensemble des informations techniques données au-dessus sont à insérer directement dans la définition du cas ADAO, en utilisant au choix une liste, un vecteur ou une chaîne de caractères pour chaque variable. On s’appuie sur la documentation de référence [DocR] Interface textuelle pour l’utilisateur (TUI/API). On constitue ainsi un cas ADAO, qui peut être enregistré en fichier Python standard.

L’entête du fichier doit comporter les déclarations habituelles du cas :

from adao import adaoBuilder
case = adaoBuilder.New()
case.set( 'AlgorithmParameters', Algorithm='Blue' )

La définition des observations et des covariances d’erreurs sont les suivantes :

case.set( 'Observation',         Vector=[1, 1, 1] )
case.set( 'ObservationError',    Matrix="1 0 0 ; 0 1 0 ; 0 0 1" )

De la même manière, l’information a priori est définie avec ses covariances d’erreur par :

case.set( 'Background',          Vector=[0, 0, 0] )
case.set( 'BackgroundError',     Matrix="1 0 0 ; 0 1 0 ; 0 0 1" )

L’opérateur d’observation, très simple et ici linéaire, peut être défini par:

case.set( 'ObservationOperator', Matrix="1 0 0 ; 0 1 0 ; 0 0 1" )

Pour obtenir un affichage automatique de l’état optimal analysé, on peut ajouter une commande d” »observer », ou ajouter après l’exécution des commandes de traitement des résultats de l’assimilation de données. On peut se contenter dans ce cas très simple d’ajouter :

case.set( 'Observer',            Variable="Analysis", Template="ValuePrinter" )

La démarche d’exécution est extrêmement simple et consiste à effectuer à la ligne de commande, ou dans le fichier enregistrant le cas, la commande suivante :

case.execute()

Le résultat de l’exécution de ces commandes (que ce soit en console Python, par la commande « shell » de SALOME, dans la console Python de l’interface, ou par le menu d’exécution d’un script) est le suivant :

Analysis [0.5 0.5 0.5]

comme montré ci-après :

adao@python$ python
Python 3.6.5 (default, Feb 01 2019, 12:12:12)
[GCC] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> from adao import adaoBuilder
>>> case = adaoBuilder.New()
>>> case.set( 'AlgorithmParameters', Algorithm='Blue' )
>>> case.set( 'Observation',         Vector=[1, 1, 1] )
>>> case.set( 'ObservationError',    Matrix="1 0 0 ; 0 1 0 ; 0 0 1" )
>>> case.set( 'Background',          Vector=[0, 0, 0] )
>>> case.set( 'BackgroundError',     Matrix="1 0 0 ; 0 1 0 ; 0 0 1" )
>>> case.set( 'ObservationOperator', Matrix="1 0 0 ; 0 1 0 ; 0 0 1" )
>>> case.set( 'Observer',            Variable="Analysis", Template="ValuePrinter" )
>>> case.execute()
Analysis [0.5 0.5 0.5]
0
>>>

Pour étendre cet exemple, on peut remarquer que le même problème résolu par un algorithme de « 3DVAR » donne le même résultat. Cet algorithme peut être choisi lors de l’étape de construction du cas ADAO en changeant simplement l’argument « Algorithm » en entête. Le reste du cas ADAO en « 3DVAR » est alors entièrement similaire au cas algorithmique du « Blue ».

6.2. Construire un cas d’estimation avec une définition de données externes par scripts

Il est utile d’acquérir une partie ou la totalité des données du cas ADAO depuis une définition externe, en utilisant des scripts Python pour donner accès à ces données. À titre d’exemple, on construit ici un cas ADAO présentant le même dispositif expérimental que dans l’exemple ci-dessus Construire un cas d’estimation avec une définition explicite des données, mais en utilisant des données issues d’un unique fichier script Python externe.

En premier lieu, on écrit le fichier script suivant, utilisant des noms conventionnels pour les variables requises. Ici toutes les variables sont définies dans le même script, mais l’utilisateur peut choisir de séparer le fichier en plusieurs autres, ou de mélanger une définition explicite des données dans l’interface textuelle ADAO et une définition implicite dans des fichiers externes. Le fichier script actuel ressemble à :

import numpy
#
# Definition of the Background as a vector
# ----------------------------------------
Background = [0, 0, 0]
#
# Definition of the Observation as a vector
# -----------------------------------------
Observation = "1 1 1"
#
# Definition of the Background Error covariance as a matrix
# ---------------------------------------------------------
BackgroundError = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])
#
# Definition of the Observation Error covariance as a matrix
# ----------------------------------------------------------
ObservationError = numpy.matrix("1 0 0 ; 0 1 0 ; 0 0 1")
#
# Definition of the Observation Operator as a matrix
# --------------------------------------------------
ObservationOperator = numpy.identity(3)

Les noms des variables Python sont obligatoires, de manière à définir les bonnes variables dans le cas ADAO, mais le script Python peut être plus conséquent et définir des classes, des fonctions, des accès à des fichiers ou des bases de données, etc. avec des noms différents. De plus, le fichier ci-dessus présente différentes manières de définir des vecteurs ou des matrices, utilisant des listes, des chaînes de caractères (comme dans Numpy ou Octave), des types vecteur ou matrice de Numpy, et des fonctions spéciales de Numpy. Toutes ces syntaxes sont valides.

Après avoir enregistré ce script dans un fichier (nommé ici « script.py » pour l’exemple) à un endroit quelconque dans l’arborescence de l’utilisateur, on utilise l’interface textuelle pour construire le cas ADAO. La procédure pour compléter le cas est similaire à celle de l’exemple précédent à part le fait que, au lieu de choisir l’option « Vector » ou « Matrix » pour construire chaque variable, on choisit l’option « Script » en indiquant simultanément le type « Vector » ou « Matrix » de la variable. Cela permet d’obtenir les commandes suivantes (que ce soit en console Python, par la commande « shell » de SALOME, dans la console Python de l’interface, ou par le menu d’exécution d’un script) :

adao@python$ python
Python 3.6.5 (default, Feb 01 2019, 12:12:12)
[GCC] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> from adao import adaoBuilder
>>> case = adaoBuilder.New()
>>> case.set( 'AlgorithmParameters', Algorithm='Blue' )
>>> case.set( 'Observation',         Vector=True, Script="script.py" )
>>> case.set( 'ObservationError',    Matrix=True, Script="script.py" )
>>> case.set( 'Background',          Vector=True, Script="script.py" )
>>> case.set( 'BackgroundError',     Matrix=True, Script="script.py" )
>>> case.set( 'ObservationOperator', Matrix=True, Script="script.py" )
>>> case.set( 'Observer',            Variable="Analysis", Template="ValuePrinter" )
>>> case.execute()
Analysis [0.5 0.5 0.5]
0
>>>

Les autres étapes et résultats sont exactement les mêmes que dans l’exemple précédent Construire un cas d’estimation avec une définition explicite des données.

Dans la pratique, cette démarche par scripts est la manière la plus facile pour récupérer des informations depuis des calculs en ligne ou préalables, depuis des fichiers statiques, depuis des bases de données ou des flux informatiques, chacun pouvant être dans ou hors SALOME. Cela permet aussi de modifier aisément des données d’entrée, par exemple à des fins de débogage ou pour des traitements répétitifs, et c’est la méthode la plus polyvalente pour paramétrer les données d’entrée. Mais attention, la méthodologie par scripts n’est pas une procédure « sûre », en ce sens que des données erronées ou des erreurs dans les calculs, peuvent être directement introduites dans l’exécution du cas ADAO. L’utilisateur doit vérifier avec soin le contenu de ses scripts.