Salome HOME
Code and documentation update for ControledFunctionTest
[modules/adao.git] / doc / fr / ref_observers_requirements.rst
1 ..
2    Copyright (C) 2008-2023 EDF R&D
3
4    This file is part of SALOME ADAO module.
5
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.
10
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.
15
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
19
20    See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21
22    Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
23
24 .. _section_ref_observers_requirements:
25
26 Conditions requises pour les fonctions décrivant un "*observer*"
27 ----------------------------------------------------------------
28
29 .. index:: single: Observer
30 .. index:: single: setObserver
31 .. index:: single: Observer Template
32
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
39 suivante :
40
41   .. ref_observer_simple:
42   .. image:: images/ref_observer_simple.png
43     :align: center
44     :width: 75%
45   .. centered::
46     **Définition conceptuelle d'une fonction "observer"**
47
48 Ces fonctions "*observer*" sont décrites dans les sous-sections suivantes.
49
50 Enregistrer et activer une fonction "*observer*"
51 ++++++++++++++++++++++++++++++++++++++++++++++++
52
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 :
57
58   .. eficas_observer_nodetype:
59   .. image:: images/eficas_observer_nodetype.png
60     :align: center
61     :width: 100%
62   .. centered::
63     **Choisir son type d'entrée pour une fonction "observer"**
64
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*"). Les modèles sont fournis par défaut dans ADAO, lors de l'usage
69 de l'éditeur graphique EFICAS d'ADAO ou de l'interface TUI, et sont détaillés
70 dans la partie :ref:`section_ref_observers_templates` qui suit. Ces derniers
71 sont des scripts simples qui peuvent être adaptés par l'utilisateur, soit dans
72 l'étape d'édition intégrée du cas avec EFICAS d'ADAO, soit dans l'étape
73 d'édition du schéma avant l'exécution, pour améliorer la performance du calcul
74 ADAO dans le superviseur d'exécution de SALOME.
75
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 modèle (argument "*Template*") désignant
81 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*").
85
86 Forme générale d'un script permettant de définir une fonction "*observer*"
87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
88
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.
94
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 et/ou de
100 temps. Seul le corps de la fonction "*observer*" doit être spécifié par
101 l'utilisateur, pas l'appel Python ``def`` de fonction lui-même.
102
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
105 surveillée :
106 ::
107
108     print("    --->",info," Value =",var[-1])
109
110 Stockées comme un fichier Python ou une chaîne de caractères explicite, cette
111 ou ces lignes de script peuvent être associées à chaque variable présente dans
112 le mot-clé "*SELECTION*" de la commande "*Observers*" du cas ADAO :
113 "*Analysis*", "*CurrentState*", "*CostFunction*"... La valeur courante de la
114 variable sera par exemple affichée à chaque étape de l'algorithme
115 d'optimisation ou d'assimilation. Les "*observer*" peuvent inclure des
116 capacités d'affichage graphique, de stockage, de traitement complexe, d'analyse
117 statistique, etc. Si une variable, à laquelle est lié un "*observer*", n'est
118 pas requise dans le calcul et par l'utilisateur, l'exécution de cet
119 "*observer*" n'est tout simplement jamais activée.
120
121 .. warning::
122
123     Si les modèles disponibles par défaut ne sont pas utilisés, il revient à
124     l'utilisateur de faire des scripts de fonctions soigneusement établis ou
125     des programmes externes qui ne se plantent pas avant d'être enregistrés
126     comme une fonction "*observer*". Le débogage peut sinon être vraiment
127     difficile !
128
129 Certains "*observer*" permettent de créer des fichiers ou des figures
130 successives, qui sont numérotées de manière unique et, le cas échéant,
131 enregistrées par défaut dans le répertoire standard ``/tmp``. Dans le cas où
132 ces informations sont à modifier (comme par exemple lorsque le répertoire
133 ``/tmp`` est un dossier virtuel ou local non pérenne, ou lorsque l'on désire
134 une numérotation en fonction de l'itération), l'utilisateur est invité à
135 s'inspirer d'un modèle lui convenant pour le modifier en spécifiant
136 différemment ces informations communes. Ensuite, la fonction modifiée peut être
137 utilisée dans une entrée de type "*String*" ou de type "*Script*".
138
139 .. note::
140
141     Une partie des "*observer*" permet de créer des figures en utilisant le
142     module Python intégré Gnuplot.py [Gnuplot.py]_, qui est une interface de
143     contrôle et transmission d'arguments à l'utilitaire classique de tracé
144     graphique Gnuplot [Gnuplot]_. Disponible sous la grande majorité des
145     environnements, ce dernier est indépendant et doit être correctement
146     préinstallé. Gnuplot.py est ici mis à jour pour supporter Python 3
147
148 On donne ci-après l'identifiant et le contenu de tous les modèles "*observer*"
149 disponibles.
150
151 .. _section_ref_observers_templates:
152
153 Inventaire des modèles de fonctions "*observer*" disponibles ("*Template*")
154 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
155
156 .. index:: single: ValuePrinter (Observer)
157
158 Modèle **ValuePrinter**
159 .......................
160
161 Imprime sur la sortie standard la valeur courante de la variable.
162
163 ::
164
165     print(str(info)+" "+str(var[-1]))
166
167 .. index:: single: ValueAndIndexPrinter (Observer)
168
169 Modèle **ValueAndIndexPrinter**
170 ...............................
171
172 Imprime sur la sortie standard la valeur courante de la variable, en ajoutant son index.
173
174 ::
175
176     print(str(info)+(" index %i:"%(len(var)-1))+" "+str(var[-1]))
177
178 .. index:: single: ValueSeriePrinter (Observer)
179
180 Modèle **ValueSeriePrinter**
181 ............................
182
183 Imprime sur la sortie standard la série des valeurs de la variable.
184
185 ::
186
187     print(str(info)+" "+str(var[:]))
188
189 .. index:: single: ValueSaver (Observer)
190
191 Modèle **ValueSaver**
192 .....................
193
194 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.
195
196 ::
197
198     import numpy, re
199     v=numpy.array(var[-1], ndmin=1)
200     global istep
201     try:
202         istep+=1
203     except:
204         istep=0
205     f='/tmp/value_%s_%05i.txt'%(info,istep)
206     f=re.sub('\s','_',f)
207     print('Value saved in "%s"'%f)
208     numpy.savetxt(f,v)
209
210 .. index:: single: ValueSerieSaver (Observer)
211
212 Modèle **ValueSerieSaver**
213 ..........................
214
215 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.
216
217 ::
218
219     import numpy, re
220     v=numpy.array(var[:], ndmin=1)
221     global istep
222     try:
223         istep+=1
224     except:
225         istep=0
226     f='/tmp/value_%s_%05i.txt'%(info,istep)
227     f=re.sub('\s','_',f)
228     print('Value saved in "%s"'%f)
229     numpy.savetxt(f,v)
230
231 .. index:: single: ValuePrinterAndSaver (Observer)
232
233 Modèle **ValuePrinterAndSaver**
234 ...............................
235
236 Imprime sur la sortie standard et, en même temps enregistre dans un fichier du répertoire '/tmp', la valeur courante de la variable.
237
238 ::
239
240     import numpy, re
241     v=numpy.array(var[-1], ndmin=1)
242     print(str(info)+" "+str(v))
243     global istep
244     try:
245         istep+=1
246     except:
247         istep=0
248     f='/tmp/value_%s_%05i.txt'%(info,istep)
249     f=re.sub('\s','_',f)
250     print('Value saved in "%s"'%f)
251     numpy.savetxt(f,v)
252
253 .. index:: single: ValueIndexPrinterAndSaver (Observer)
254
255 Modèle **ValueIndexPrinterAndSaver**
256 ....................................
257
258 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.
259
260 ::
261
262     import numpy, re
263     v=numpy.array(var[-1], ndmin=1)
264     print(str(info)+(" index %i:"%(len(var)-1))+" "+str(v))
265     global istep
266     try:
267         istep+=1
268     except:
269         istep=0
270     f='/tmp/value_%s_%05i.txt'%(info,istep)
271     f=re.sub('\s','_',f)
272     print('Value saved in "%s"'%f)
273     numpy.savetxt(f,v)
274
275 .. index:: single: ValueSeriePrinterAndSaver (Observer)
276
277 Modèle **ValueSeriePrinterAndSaver**
278 ....................................
279
280 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.
281
282 ::
283
284     import numpy, re
285     v=numpy.array(var[:], ndmin=1)
286     print(str(info)+" "+str(v))
287     global istep
288     try:
289         istep+=1
290     except:
291         istep=0
292     f='/tmp/value_%s_%05i.txt'%(info,istep)
293     f=re.sub('\s','_',f)
294     print('Value saved in "%s"'%f)
295     numpy.savetxt(f,v)
296
297 .. index:: single: ValueGnuPlotter (Observer)
298
299 Modèle **ValueGnuPlotter**
300 ..........................
301
302 Affiche graphiquement avec Gnuplot la valeur courante de la variable.
303
304 ::
305
306     import numpy, Gnuplot
307     v=numpy.array(var[-1], ndmin=1)
308     global ifig, gp
309     try:
310         ifig+=1
311         gp('set style data lines')
312     except:
313         ifig=0
314         gp=Gnuplot.Gnuplot(persist=1)
315         gp('set style data lines')
316     gp('set title "%s (Figure %i)"'%(info,ifig))
317     gp.plot( Gnuplot.Data( v, with_='lines lw 2' ) )
318
319 .. index:: single: ValueSerieGnuPlotter (Observer)
320
321 Modèle **ValueSerieGnuPlotter**
322 ...............................
323
324 Affiche graphiquement avec Gnuplot la série des valeurs de la variable.
325
326 ::
327
328     import numpy, Gnuplot
329     v=numpy.array(var[:], ndmin=1)
330     global ifig, gp
331     try:
332         ifig+=1
333         gp('set style data lines')
334     except:
335         ifig=0
336         gp=Gnuplot.Gnuplot(persist=1)
337         gp('set style data lines')
338     gp('set title "%s (Figure %i)"'%(info,ifig))
339     gp.plot( Gnuplot.Data( v, with_='lines lw 2' ) )
340
341 .. index:: single: ValuePrinterAndGnuPlotter (Observer)
342
343 Modèle **ValuePrinterAndGnuPlotter**
344 ....................................
345
346 Imprime sur la sortie standard et, en même temps, affiche graphiquement avec Gnuplot la valeur courante de la variable.
347
348 ::
349
350     print(str(info)+' '+str(var[-1]))
351     import numpy, Gnuplot
352     v=numpy.array(var[-1], ndmin=1)
353     global ifig,gp
354     try:
355         ifig+=1
356         gp('set style data lines')
357     except:
358         ifig=0
359         gp=Gnuplot.Gnuplot(persist=1)
360         gp('set style data lines')
361     gp('set title "%s (Figure %i)"'%(info,ifig))
362     gp.plot( Gnuplot.Data( v, with_='lines lw 2' ) )
363
364 .. index:: single: ValueSeriePrinterAndGnuPlotter (Observer)
365
366 Modèle **ValueSeriePrinterAndGnuPlotter**
367 .........................................
368
369 Imprime sur la sortie standard et, en même temps, affiche graphiquement avec Gnuplot la série des valeurs de la variable.
370
371 ::
372
373     print(str(info)+' '+str(var[:]))
374     import numpy, Gnuplot
375     v=numpy.array(var[:], ndmin=1)
376     global ifig,gp
377     try:
378         ifig+=1
379         gp('set style data lines')
380     except:
381         ifig=0
382         gp=Gnuplot.Gnuplot(persist=1)
383         gp('set style data lines')
384     gp('set title "%s (Figure %i)"'%(info,ifig))
385     gp.plot( Gnuplot.Data( v, with_='lines lw 2' ) )
386
387 .. index:: single: ValuePrinterSaverAndGnuPlotter (Observer)
388
389 Modèle **ValuePrinterSaverAndGnuPlotter**
390 .........................................
391
392 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.
393
394 ::
395
396     print(str(info)+' '+str(var[-1]))
397     import numpy, re
398     v=numpy.array(var[-1], ndmin=1)
399     global istep
400     try:
401         istep+=1
402     except:
403         istep=0
404     f='/tmp/value_%s_%05i.txt'%(info,istep)
405     f=re.sub('\s','_',f)
406     print('Value saved in "%s"'%f)
407     numpy.savetxt(f,v)
408     import Gnuplot
409     global ifig,gp
410     try:
411         ifig+=1
412         gp('set style data lines')
413     except:
414         ifig=0
415         gp=Gnuplot.Gnuplot(persist=1)
416         gp('set style data lines')
417     gp('set title "%s (Figure %i)"'%(info,ifig))
418     gp.plot( Gnuplot.Data( v, with_='lines lw 2' ) )
419
420 .. index:: single: ValueSeriePrinterSaverAndGnuPlotter (Observer)
421
422 Modèle **ValueSeriePrinterSaverAndGnuPlotter**
423 ..............................................
424
425 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.
426
427 ::
428
429     print(str(info)+' '+str(var[:]))
430     import numpy, re
431     v=numpy.array(var[:], ndmin=1)
432     global istep
433     try:
434         istep+=1
435     except:
436         istep=0
437     f='/tmp/value_%s_%05i.txt'%(info,istep)
438     f=re.sub('\s','_',f)
439     print('Value saved in "%s"'%f)
440     numpy.savetxt(f,v)
441     import Gnuplot
442     global ifig,gp
443     try:
444         ifig+=1
445         gp('set style data lines')
446     except:
447         ifig=0
448         gp=Gnuplot.Gnuplot(persist=1)
449         gp('set style data lines')
450     gp('set title "%s (Figure %i)"'%(info,ifig))
451     gp.plot( Gnuplot.Data( v, with_='lines lw 2' ) )
452
453 .. index:: single: ValueMean (Observer)
454
455 Modèle **ValueMean**
456 ....................
457
458 Imprime sur la sortie standard la moyenne de la valeur courante de la variable.
459
460 ::
461
462     import numpy
463     print(str(info)+' '+str(numpy.nanmean(var[-1])))
464
465 .. index:: single: ValueStandardError (Observer)
466
467 Modèle **ValueStandardError**
468 .............................
469
470 Imprime sur la sortie standard l'écart-type de la valeur courante de la variable.
471
472 ::
473
474     import numpy
475     print(str(info)+' '+str(numpy.nanstd(var[-1])))
476
477 .. index:: single: ValueVariance (Observer)
478
479 Modèle **ValueVariance**
480 ........................
481
482 Imprime sur la sortie standard la variance de la valeur courante de la variable.
483
484 ::
485
486     import numpy
487     print(str(info)+' '+str(numpy.nanvar(var[-1])))
488
489 .. index:: single: ValueL2Norm (Observer)
490
491 Modèle **ValueL2Norm**
492 ......................
493
494 Imprime sur la sortie standard la norme L2 de la valeur courante de la variable.
495
496 ::
497
498     import numpy
499     v = numpy.ravel( var[-1] )
500     print(str(info)+' '+str(float( numpy.linalg.norm(v) )))
501
502 .. index:: single: ValueRMS (Observer)
503
504 Modèle **ValueRMS**
505 ...................
506
507 Imprime sur la sortie standard la racine de la moyenne des carrés (RMS), ou moyenne quadratique, de la valeur courante de la variable.
508
509 ::
510
511     import numpy
512     v = numpy.ravel( var[-1] )
513     print(str(info)+' '+str(float( numpy.sqrt((1./v.size)*numpy.dot(v,v)) )))