Salome HOME
Code and documentation update
[modules/adao.git] / doc / en / ref_observers_requirements.rst
1 ..
2    Copyright (C) 2008-2022 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 Requirements for functions describing an "*observer*"
27 -----------------------------------------------------
28
29 .. index:: single: Observer
30 .. index:: single: setObserver
31 .. index:: single: Observer Template
32
33 Some special variables, internal to the optimization process and used inside
34 calculation, can be monitored during an ADAO calculation. These variables can
35 be printed, plotted, saved, etc. by the user. This can be done using some
36 "*observer*", sometimes also called "callback", on a variable. They are special
37 Python functions, each one associated with a given variable, as conceptually
38 described in the following figure:
39
40   .. ref_observer_simple:
41   .. image:: images/ref_observer_simple.png
42     :align: center
43     :width: 75%
44   .. centered::
45     **Conceptual definition of an "observer" function**
46
47 These "*observer*" functions are described in the next subsections.
48
49 Register and activate of an "*observer*" function
50 +++++++++++++++++++++++++++++++++++++++++++++++++
51
52 In the graphical interface EFICAS of ADAO, there are 3 practical methods to
53 provide an "*observer*" function in an ADAO case. The method is chosen with the
54 "*NodeType*" keyword of each "*observer*" entry type, as shown in the following
55 figure:
56
57   .. eficas_observer_nodetype:
58   .. image:: images/eficas_observer_nodetype.png
59     :align: center
60     :width: 100%
61   .. centered::
62     **Choosing its entry type for an "observer" function**
63
64 An "*observer*" function can be given as an explicit script (entry of type
65 "*String*"), as a script in an external file (entry of type "*Script*"), or by
66 using a template or pattern (entry of type"*Template*"). The templates are
67 available by default in ADAO, using the graphical interface EFICAS or the text
68 interface TUI, and are detailed in the following
69 :ref:`section_ref_observers_templates`. These templates are simple scripts that
70 can be tuned by the user, either in the integrated edition stage of the case
71 with ADAO EFICAS, or in the edition stage of the schema before execution, to
72 improve the ADAO case performance in the SALOME execution supervisor YACS.
73
74 In the textual interface (TUI) of ADAO (see the part :ref:`section_tui`), the
75 same information can be given with the command "*setObserver*" applied to a
76 specific variable indicated using the "*Variable*" argument. The other
77 arguments of this command allow to define an "*observer*" either as a template
78 ("*Template*" argument) representing one of the scripts detailed in the part
79 :ref:`section_ref_observers_templates`, or as an explicit script ("*String*"
80 argument), or as a script in an external file ("*Script*" argument).
81
82 General form for a script describing an "*observer*" function
83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
84
85 An "*observer*" function is a special Python script, associated with a given
86 variable, and that is automatically activated for each variable modification
87 during calculation. Every (carefully established) function that applies to the
88 selected variable can be used. Many "*observer*" functions are available by
89 default.
90
91 To use directly this "*observer*" capability, the user must use or build a
92 script that have on standard input (that is, in the naming space) the variables
93 ``var`` and ``info``. The variable ``var`` is to be used as an object of
94 list/tuple type, that contains the history of the variable of interest, indexed
95 by the iterating and/or time steps. Only the body of the "*observer*" function
96 has to be specified by the user, not the  Python ``def`` function call itself.
97
98 As an example, here is a very simple script (similar to the "*ValuePrinter*"
99 template), that can be used to print the value of the monitored variable::
100
101     print("    --->",info," Value =",var[-1])
102
103 Stored as a Python file or as an explicit string, this or these script lines
104 can be associated to each variable found in the keyword "*SELECTION*" of the
105 "*Observers*" command of the ADAO case: "*Analysis*", "*CurrentState*",
106 "*CostFunction*"... The current value of the variable will for example be
107 printed at each step of the optimization or data assimilation algorithm. The
108 "*observer*" can include graphical output, storage capacities, complex
109 treatment, statistical analysis, etc. If the variable, to which the
110 "*observer*" is linked, is not required in the calculation and by the user, the
111 execution of this "*observer*" is simply never activated.
112
113 .. warning::
114
115     If not using the default available templates, it is up to the user to make
116     carefully established function scripts or external programs that do not
117     crash before being registered as an "*observer*" function. The debugging
118     can otherwise be really difficult!
119
120 Some "*observer*" allow the creation of successive files or figures, which are
121 uniquely numbered and, if applicable, stored by default in the standard
122 ``/tmp`` directory. In the case where this information needs to be modified (as
123 for example when the ``/tmp`` directory is a virtual or local non-permanent
124 folder, or when one wishes to have a numbering according to the iteration), the
125 user is encouraged to take inspiration from a model that is suitable for him
126 and to modify it by specifying differently this shared information. Then, the
127 modified function can be used in a "*String*" or "*Script*" input.
128
129 Hereinafter we give the identifier and the contents of all the available
130 "*observer*" models.
131
132 .. _section_ref_observers_templates:
133
134 Inventory of available "*observer*" function models ("*Template*")
135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
136
137 .. index:: single: ValuePrinter (Observer)
138
139 Template **ValuePrinter**
140 .........................
141
142 Print on standard output the current value of the variable.
143
144 ::
145
146     print(str(info)+" "+str(var[-1]))
147
148 .. index:: single: ValueAndIndexPrinter (Observer)
149
150 Template **ValueAndIndexPrinter**
151 .................................
152
153 Print on standard output the current value of the variable, adding its index.
154
155 ::
156
157     print(str(info)+(" index %i:"%(len(var)-1))+" "+str(var[-1]))
158
159 .. index:: single: ValueSeriePrinter (Observer)
160
161 Template **ValueSeriePrinter**
162 ..............................
163
164 Print on standard output the value series of the variable.
165
166 ::
167
168     print(str(info)+" "+str(var[:]))
169
170 .. index:: single: ValueSaver (Observer)
171
172 Template **ValueSaver**
173 .......................
174
175 Save the current value of the variable in a file of the '/tmp' directory named 'value...txt' from the variable name and the saving step.
176
177 ::
178
179     import numpy, re
180     v=numpy.array(var[-1], ndmin=1)
181     global istep
182     try:
183         istep+=1
184     except:
185         istep=0
186     f='/tmp/value_%s_%05i.txt'%(info,istep)
187     f=re.sub('\s','_',f)
188     print('Value saved in "%s"'%f)
189     numpy.savetxt(f,v)
190
191 .. index:: single: ValueSerieSaver (Observer)
192
193 Template **ValueSerieSaver**
194 ............................
195
196 Save the value series of the variable in a file of the '/tmp' directory named 'value...txt' from the variable name and the saving step.
197
198 ::
199
200     import numpy, re
201     v=numpy.array(var[:], ndmin=1)
202     global istep
203     try:
204         istep+=1
205     except:
206         istep=0
207     f='/tmp/value_%s_%05i.txt'%(info,istep)
208     f=re.sub('\s','_',f)
209     print('Value saved in "%s"'%f)
210     numpy.savetxt(f,v)
211
212 .. index:: single: ValuePrinterAndSaver (Observer)
213
214 Template **ValuePrinterAndSaver**
215 .................................
216
217 Print on standard output and, in the same time save in a file of the '/tmp' directory, the current value of the variable.
218
219 ::
220
221     import numpy, re
222     v=numpy.array(var[-1], ndmin=1)
223     print(str(info)+" "+str(v))
224     global istep
225     try:
226         istep+=1
227     except:
228         istep=0
229     f='/tmp/value_%s_%05i.txt'%(info,istep)
230     f=re.sub('\s','_',f)
231     print('Value saved in "%s"'%f)
232     numpy.savetxt(f,v)
233
234 .. index:: single: ValueIndexPrinterAndSaver (Observer)
235
236 Template **ValueIndexPrinterAndSaver**
237 ......................................
238
239 Print on standard output and, in the same time save in a file of the '/tmp' directory, the current value of the variable, adding its index.
240
241 ::
242
243     import numpy, re
244     v=numpy.array(var[-1], ndmin=1)
245     print(str(info)+(" index %i:"%(len(var)-1))+" "+str(v))
246     global istep
247     try:
248         istep+=1
249     except:
250         istep=0
251     f='/tmp/value_%s_%05i.txt'%(info,istep)
252     f=re.sub('\s','_',f)
253     print('Value saved in "%s"'%f)
254     numpy.savetxt(f,v)
255
256 .. index:: single: ValueSeriePrinterAndSaver (Observer)
257
258 Template **ValueSeriePrinterAndSaver**
259 ......................................
260
261 Print on standard output and, in the same time, save in a file of the '/tmp' directory, the value series of the variable.
262
263 ::
264
265     import numpy, re
266     v=numpy.array(var[:], ndmin=1)
267     print(str(info)+" "+str(v))
268     global istep
269     try:
270         istep+=1
271     except:
272         istep=0
273     f='/tmp/value_%s_%05i.txt'%(info,istep)
274     f=re.sub('\s','_',f)
275     print('Value saved in "%s"'%f)
276     numpy.savetxt(f,v)
277
278 .. index:: single: ValueGnuPlotter (Observer)
279
280 Template **ValueGnuPlotter**
281 ............................
282
283 Graphically plot with Gnuplot the current value of the variable.
284
285 ::
286
287     import numpy, Gnuplot
288     v=numpy.array(var[-1], ndmin=1)
289     global ifig, gp
290     try:
291         ifig+=1
292         gp('set style data lines')
293     except:
294         ifig=0
295         gp=Gnuplot.Gnuplot(persist=1)
296         gp('set style data lines')
297     gp('set title "%s (Figure %i)"'%(info,ifig))
298     gp.plot( Gnuplot.Data( v, with_='lines lw 2' ) )
299
300 .. index:: single: ValueSerieGnuPlotter (Observer)
301
302 Template **ValueSerieGnuPlotter**
303 .................................
304
305 Graphically plot with Gnuplot the value series of the variable.
306
307 ::
308
309     import numpy, Gnuplot
310     v=numpy.array(var[:], ndmin=1)
311     global ifig, gp
312     try:
313         ifig+=1
314         gp('set style data lines')
315     except:
316         ifig=0
317         gp=Gnuplot.Gnuplot(persist=1)
318         gp('set style data lines')
319     gp('set title "%s (Figure %i)"'%(info,ifig))
320     gp.plot( Gnuplot.Data( v, with_='lines lw 2' ) )
321
322 .. index:: single: ValuePrinterAndGnuPlotter (Observer)
323
324 Template **ValuePrinterAndGnuPlotter**
325 ......................................
326
327 Print on standard output and, in the same time, graphically plot with Gnuplot the current value of the variable.
328
329 ::
330
331     print(str(info)+' '+str(var[-1]))
332     import numpy, Gnuplot
333     v=numpy.array(var[-1], ndmin=1)
334     global ifig,gp
335     try:
336         ifig+=1
337         gp('set style data lines')
338     except:
339         ifig=0
340         gp=Gnuplot.Gnuplot(persist=1)
341         gp('set style data lines')
342     gp('set title "%s (Figure %i)"'%(info,ifig))
343     gp.plot( Gnuplot.Data( v, with_='lines lw 2' ) )
344
345 .. index:: single: ValueSeriePrinterAndGnuPlotter (Observer)
346
347 Template **ValueSeriePrinterAndGnuPlotter**
348 ...........................................
349
350 Print on standard output and, in the same time, graphically plot with Gnuplot the value series of the variable.
351
352 ::
353
354     print(str(info)+' '+str(var[:]))
355     import numpy, Gnuplot
356     v=numpy.array(var[:], ndmin=1)
357     global ifig,gp
358     try:
359         ifig+=1
360         gp('set style data lines')
361     except:
362         ifig=0
363         gp=Gnuplot.Gnuplot(persist=1)
364         gp('set style data lines')
365     gp('set title "%s (Figure %i)"'%(info,ifig))
366     gp.plot( Gnuplot.Data( v, with_='lines lw 2' ) )
367
368 .. index:: single: ValuePrinterSaverAndGnuPlotter (Observer)
369
370 Template **ValuePrinterSaverAndGnuPlotter**
371 ...........................................
372
373 Print on standard output and, in the same, time save in a file of the '/tmp' directory and graphically plot the current value of the variable.
374
375 ::
376
377     print(str(info)+' '+str(var[-1]))
378     import numpy, re
379     v=numpy.array(var[-1], ndmin=1)
380     global istep
381     try:
382         istep+=1
383     except:
384         istep=0
385     f='/tmp/value_%s_%05i.txt'%(info,istep)
386     f=re.sub('\s','_',f)
387     print('Value saved in "%s"'%f)
388     numpy.savetxt(f,v)
389     import Gnuplot
390     global ifig,gp
391     try:
392         ifig+=1
393         gp('set style data lines')
394     except:
395         ifig=0
396         gp=Gnuplot.Gnuplot(persist=1)
397         gp('set style data lines')
398     gp('set title "%s (Figure %i)"'%(info,ifig))
399     gp.plot( Gnuplot.Data( v, with_='lines lw 2' ) )
400
401 .. index:: single: ValueSeriePrinterSaverAndGnuPlotter (Observer)
402
403 Template **ValueSeriePrinterSaverAndGnuPlotter**
404 ................................................
405
406 Print on standard output and, in the same, time save in a file of the '/tmp' directory and graphically plot the value series of the variable.
407
408 ::
409
410     print(str(info)+' '+str(var[:]))
411     import numpy, re
412     v=numpy.array(var[:], ndmin=1)
413     global istep
414     try:
415         istep+=1
416     except:
417         istep=0
418     f='/tmp/value_%s_%05i.txt'%(info,istep)
419     f=re.sub('\s','_',f)
420     print('Value saved in "%s"'%f)
421     numpy.savetxt(f,v)
422     import Gnuplot
423     global ifig,gp
424     try:
425         ifig+=1
426         gp('set style data lines')
427     except:
428         ifig=0
429         gp=Gnuplot.Gnuplot(persist=1)
430         gp('set style data lines')
431     gp('set title "%s (Figure %i)"'%(info,ifig))
432     gp.plot( Gnuplot.Data( v, with_='lines lw 2' ) )
433
434 .. index:: single: ValueMean (Observer)
435
436 Template **ValueMean**
437 ......................
438
439 Print on standard output the mean of the current value of the variable.
440
441 ::
442
443     import numpy
444     print(str(info)+' '+str(numpy.nanmean(var[-1])))
445
446 .. index:: single: ValueStandardError (Observer)
447
448 Template **ValueStandardError**
449 ...............................
450
451 Print on standard output the standard error of the current value of the variable.
452
453 ::
454
455     import numpy
456     print(str(info)+' '+str(numpy.nanstd(var[-1])))
457
458 .. index:: single: ValueVariance (Observer)
459
460 Template **ValueVariance**
461 ..........................
462
463 Print on standard output the variance of the current value of the variable.
464
465 ::
466
467     import numpy
468     print(str(info)+' '+str(numpy.nanvar(var[-1])))
469
470 .. index:: single: ValueL2Norm (Observer)
471
472 Template **ValueL2Norm**
473 ........................
474
475 Print on standard output the L2 norm of the current value of the variable.
476
477 ::
478
479     import numpy
480     v = numpy.ravel( var[-1] )
481     print(str(info)+' '+str(float( numpy.linalg.norm(v) )))
482
483 .. index:: single: ValueRMS (Observer)
484
485 Template **ValueRMS**
486 .....................
487
488 Print on standard output the root mean square (RMS), or quadratic mean, of the current value of the variable.
489
490 ::
491
492     import numpy
493     v = numpy.ravel( var[-1] )
494     print(str(info)+' '+str(float( numpy.sqrt((1./v.size)*numpy.dot(v,v)) )))