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 .. _section_ref_observers_requirements:
26 Exigences pour les fonctions décrivant un "*observer*"
27 ------------------------------------------------------
29 .. index:: single: Observer
30 .. index:: single: setObserver
31 .. index:: single: Observer Template
33 Certaines variables spéciales, internes à l'optimisation et utilisées au cours
34 des calculs, peuvent être surveillées durant un calcul ADAO. Ces variables
35 peuvent être affichées, tracées, enregistrées, etc. par l'utilisateur. C'est
36 réalisable en utilisant des "*observer*", parfois aussi appelés des "callback"
37 sur une variable. Ce sont des fonctions Python spéciales, qui sont chacune
38 associées à une variable donnée, comme décrit conceptuellement dans la figure
41 .. ref_observer_simple:
42 .. image:: images/ref_observer_simple.png
46 **Définition conceptuelle d'une fonction "observer"**
48 Ces fonctions "*observer*" sont décrites dans les sous-sections suivantes.
50 Enregistrer et activer une fonction "*observer*"
51 ++++++++++++++++++++++++++++++++++++++++++++++++
53 Dans l'interface graphique EFICAS d'ADAO, il y a 3 méthodes pratiques pour
54 intégrer une fonction "*observer*" dans un cas ADAO. La méthode est choisie à
55 l'aide du mot-clé "*NodeType*" de chaque entrée de type "*observer*", comme
56 montré dans la figure qui suit :
58 .. eficas_observer_nodetype:
59 .. image:: images/eficas_observer_nodetype.png
63 **Choisir son type d'entrée pour une fonction "observer"**
65 Une fonction "*observer*" peut être fourni sous la forme d'un script explicite
66 (entrée de type "*String*"), d'un script contenu dans un fichier externe
67 (entrée de type "*Script*"), ou en utilisant un modèle (entrée de type
68 "*Template*") fourni par défaut dans ADAO lors de l'usage de l'éditeur
69 graphique EFICAS d'ADAO et détaillé dans la partie
70 :ref:`section_ref_observers_templates` qui suit. Ces derniers sont des scripts
71 simples qui peuvent être adaptés par l'utilisateur, soit dans l'étape d'édition
72 intégrée du cas avec EFICAS d'ADAO, soit dans l'étape d'édition du schéma avant
73 l'exécution, pour améliorer la performance du calcul ADAO dans le superviseur
74 d'exécution de SALOME.
76 Dans l'interface textuelle (TUI) d'ADAO (voir la partie :ref:`section_tui`),
77 les mêmes informations peuvent être données à l'aide de la commande
78 "*setObserver*" appliquée pour une variable donnée indiquée en utilisant
79 l'argument "*Variable*". Les autres arguments de cette commande permettent de
80 définir un "*observer*" soit comme un template (argument "*Template*")
81 désignant l'un des scripts détaillés dans la partie
82 :ref:`section_ref_observers_templates`, soit comme un script explicite
83 (argument "*String*"), soit comme un script contenu dans un fichier externe
84 (argument "*Script*").
86 Forme générale d'un script permettant de définir une fonction "*observer*"
87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
89 Une fonction "*observer*" est un script Python spécial, associé à une variable
90 donnée, et qui est automatiquement activée à chaque modification de la variable
91 lors du calcul. Chaque fonction (soigneusement établie) qui s'applique à la
92 variable sélectionnée peut être utilisée. De nombreuses fonctions "*observer*"
93 sont disponibles par défaut.
95 Pour pouvoir utiliser directement cette capacité "*observer*", l'utilisateur
96 doit utiliser ou construire un script utilisant en entrée standard (i.e.
97 disponible dans l'espace de nommage) les variables ``var`` et ``info``. La
98 variable ``var`` est à utiliser comme un objet de type liste/tuple, contenant
99 l'historique de la variable d'intérêt, indicé par les pas d'itérations. Seul le
100 corps de la fonction "*observer*" doit être spécifié par l'utilisateur, pas
101 l'appel de fonction lui-même.
103 A titre d'exemple, voici un script très simple (similaire au modèle
104 "*ValuePrinter*"), utilisable pour afficher la valeur d'une variable
107 print(" --->",info," Value =",var[-1])
109 Stockées comme un fichier Python ou une chaîne de caractères explicite, ces
110 lignes de script peuvent être associées à chaque variable présente dans le
111 mot-clé "*SELECTION*" de la commande "*Observers*" du cas ADAO : "*Analysis*",
112 "*CurrentState*", "*CostFunction*"... La valeur courante de la variable sera
113 par exemple affichée à chaque étape de l'algorithme d'optimisation ou
114 d'assimilation. Les "*observer*" peuvent inclure des capacités d'affichage
115 graphique, de stockage, de traitement complexe, d'analyse statistique, etc. Si
116 une variable, à laquelle est lié un "*observer*", n'est pas requise dans le
117 calcul et par l'utilisateur, l'exécution de cet "*observer*" n'est tout
118 simplement jamais activée.
121 Si les modèles disponibles par défaut ne sont pas utilisés, il revient à
122 l'utilisateur de faire des scripts de fonctions soigneusement établis ou
123 des programmes externes qui ne se plantent pas avant d'être enregistrés
124 comme une fonction "*observer*". Le débogage peut sinon être vraiment
127 On donne ci-après l'identifiant et le contenu de tous les modèles "*observer*"
130 .. _section_ref_observers_templates:
132 Inventaire des modèles de fonctions "*observer*" disponibles ("*Template*")
133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
135 .. index:: single: ValuePrinter (Observer)
137 Modèle **ValuePrinter** :
138 .........................
140 Imprime sur la sortie standard la valeur courante de la variable.
144 print(str(info)+" "+str(var[-1]))
146 .. index:: single: ValueAndIndexPrinter (Observer)
148 Modèle **ValueAndIndexPrinter** :
149 .................................
151 Imprime sur la sortie standard la valeur courante de la variable, en ajoutant son index.
155 print(str(info)+(" index %i:"%(len(var)-1))+" "+str(var[-1]))
157 .. index:: single: ValueSeriePrinter (Observer)
159 Modèle **ValueSeriePrinter** :
160 ..............................
162 Imprime sur la sortie standard la série des valeurs de la variable.
166 print(str(info)+" "+str(var[:]))
168 .. index:: single: ValueSaver (Observer)
170 Modèle **ValueSaver** :
171 .......................
173 Enregistre la valeur courante de la variable dans un fichier du répertoire '/tmp' nommé 'value...txt' selon le nom de la variable et l'étape d'enregistrement.
178 v=numpy.array(var[-1], ndmin=1)
184 f='/tmp/value_%s_%05i.txt'%(info,istep)
186 print('Value saved in "%s"'%f)
189 .. index:: single: ValueSerieSaver (Observer)
191 Modèle **ValueSerieSaver** :
192 ............................
194 Enregistre la série des valeurs de la variable dans un fichier du répertoire '/tmp' nommé 'value...txt' selon le nom de la variable et l'étape.
199 v=numpy.array(var[:], ndmin=1)
205 f='/tmp/value_%s_%05i.txt'%(info,istep)
207 print('Value saved in "%s"'%f)
210 .. index:: single: ValuePrinterAndSaver (Observer)
212 Modèle **ValuePrinterAndSaver** :
213 .................................
215 Imprime sur la sortie standard et, en même temps enregistre dans un fichier du répertoire '/tmp', la valeur courante de la variable.
220 v=numpy.array(var[-1], ndmin=1)
221 print(str(info)+" "+str(v))
227 f='/tmp/value_%s_%05i.txt'%(info,istep)
229 print('Value saved in "%s"'%f)
232 .. index:: single: ValueIndexPrinterAndSaver (Observer)
234 Modèle **ValueIndexPrinterAndSaver** :
235 ......................................
237 Imprime sur la sortie standard et, en même temps enregistre dans un fichier du répertoire '/tmp', la valeur courante de la variable, en ajoutant son index.
242 v=numpy.array(var[-1], ndmin=1)
243 print(str(info)+(" index %i:"%(len(var)-1))+" "+str(v))
249 f='/tmp/value_%s_%05i.txt'%(info,istep)
251 print('Value saved in "%s"'%f)
254 .. index:: single: ValueSeriePrinterAndSaver (Observer)
256 Modèle **ValueSeriePrinterAndSaver** :
257 ......................................
259 Imprime sur la sortie standard et, en même temps, enregistre dans un fichier du répertoire '/tmp', la série des valeurs de la variable.
264 v=numpy.array(var[:], ndmin=1)
265 print(str(info)+" "+str(v))
271 f='/tmp/value_%s_%05i.txt'%(info,istep)
273 print('Value saved in "%s"'%f)
276 .. index:: single: ValueGnuPlotter (Observer)
278 Modèle **ValueGnuPlotter** :
279 ............................
281 Affiche graphiquement avec Gnuplot la valeur courante de la variable.
285 import numpy, Gnuplot
286 v=numpy.array(var[-1], ndmin=1)
290 gp(' set style data lines')
293 gp = Gnuplot.Gnuplot(persist=1)
294 gp(' set style data lines')
295 gp('set title "%s (Figure %i)"'%(info,ifig))
296 gp.plot( Gnuplot.Data( v, with_='lines lw 2' ) )
298 .. index:: single: ValueSerieGnuPlotter (Observer)
300 Modèle **ValueSerieGnuPlotter** :
301 .................................
303 Affiche graphiquement avec Gnuplot la série des valeurs de la variable.
307 import numpy, Gnuplot
308 v=numpy.array(var[:], ndmin=1)
312 gp(' set style data lines')
315 gp = Gnuplot.Gnuplot(persist=1)
316 gp(' set style data lines')
317 gp('set title "%s (Figure %i)"'%(info,ifig))
318 gp.plot( Gnuplot.Data( v, with_='lines lw 2' ) )
320 .. index:: single: ValuePrinterAndGnuPlotter (Observer)
322 Modèle **ValuePrinterAndGnuPlotter** :
323 ......................................
325 Imprime sur la sortie standard et, en même temps, affiche graphiquement avec Gnuplot la valeur courante de la variable.
329 print(str(info)+" "+str(var[-1]))
330 import numpy, Gnuplot
331 v=numpy.array(var[-1], ndmin=1)
335 gp(' set style data lines')
338 gp = Gnuplot.Gnuplot(persist=1)
339 gp(' set style data lines')
340 gp('set title "%s (Figure %i)"'%(info,ifig))
341 gp.plot( Gnuplot.Data( v, with_='lines lw 2' ) )
343 .. index:: single: ValueSeriePrinterAndGnuPlotter (Observer)
345 Modèle **ValueSeriePrinterAndGnuPlotter** :
346 ...........................................
348 Imprime sur la sortie standard et, en même temps, affiche graphiquement avec Gnuplot la série des valeurs de la variable.
352 print(str(info)+" "+str(var[:]))
353 import numpy, Gnuplot
354 v=numpy.array(var[:], ndmin=1)
358 gp(' set style data lines')
361 gp = Gnuplot.Gnuplot(persist=1)
362 gp(' set style data lines')
363 gp('set title "%s (Figure %i)"'%(info,ifig))
364 gp.plot( Gnuplot.Data( v, with_='lines lw 2' ) )
366 .. index:: single: ValuePrinterSaverAndGnuPlotter (Observer)
368 Modèle **ValuePrinterSaverAndGnuPlotter** :
369 ...........................................
371 Imprime sur la sortie standard et, en même temps, enregistre dans un fichier du répertoire '/tmp' et affiche graphiquement la valeur courante de la variable.
375 print(str(info)+" "+str(var[-1]))
377 v=numpy.array(var[-1], ndmin=1)
383 f='/tmp/value_%s_%05i.txt'%(info,istep)
385 print('Value saved in "%s"'%f)
391 gp(' set style data lines')
394 gp = Gnuplot.Gnuplot(persist=1)
395 gp(' set style data lines')
396 gp('set title "%s (Figure %i)"'%(info,ifig))
397 gp.plot( Gnuplot.Data( v, with_='lines lw 2' ) )
399 .. index:: single: ValueSeriePrinterSaverAndGnuPlotter (Observer)
401 Modèle **ValueSeriePrinterSaverAndGnuPlotter** :
402 ................................................
404 Imprime sur la sortie standard et, en même temps, enregistre dans un fichier du répertoire '/tmp' et affiche graphiquement la série des valeurs de la variable.
408 print(str(info)+" "+str(var[:]))
410 v=numpy.array(var[:], ndmin=1)
416 f='/tmp/value_%s_%05i.txt'%(info,istep)
418 print('Value saved in "%s"'%f)
424 gp(' set style data lines')
427 gp = Gnuplot.Gnuplot(persist=1)
428 gp(' set style data lines')
429 gp('set title "%s (Figure %i)"'%(info,ifig))
430 gp.plot( Gnuplot.Data( v, with_='lines lw 2' ) )
432 .. index:: single: ValueMean (Observer)
434 Modèle **ValueMean** :
435 ......................
437 Imprime sur la sortie standard la moyenne de la valeur courante de la variable.
442 print(str(info)+" "+str(numpy.nanmean(var[-1])))
444 .. index:: single: ValueStandardError (Observer)
446 Modèle **ValueStandardError** :
447 ...............................
449 Imprime sur la sortie standard l'écart-type de la valeur courante de la variable.
454 print(str(info)+" "+str(numpy.nanstd(var[-1])))
456 .. index:: single: ValueVariance (Observer)
458 Modèle **ValueVariance** :
459 ..........................
461 Imprime sur la sortie standard la variance de la valeur courante de la variable.
466 print(str(info)+" "+str(numpy.nanvar(var[-1])))
468 .. index:: single: ValueL2Norm (Observer)
470 Modèle **ValueL2Norm** :
471 ........................
473 Imprime sur la sortie standard la norme L2 de la valeur courante de la variable.
478 v = numpy.ravel( var[-1] )
479 print(str(info)+" "+str(float( numpy.linalg.norm(v) )))
481 .. index:: single: ValueRMS (Observer)
483 Modèle **ValueRMS** :
484 .....................
486 Imprime sur la sortie standard la racine de la moyenne des carrés (RMS), ou moyenne quadratique, de la valeur courante de la variable.
491 v = numpy.ravel( var[-1] )
492 print(str(info)+" "+str(float( numpy.sqrt((1./v.size)*numpy.dot(v,v)) )))