2 Copyright (C) 2008-2022 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 Requirements for functions describing an "*observer*"
27 -----------------------------------------------------
29 .. index:: single: Observer
30 .. index:: single: setObserver
31 .. index:: single: Observer Template
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:
40 .. ref_observer_simple:
41 .. image:: images/ref_observer_simple.png
45 **Conceptual definition of an "observer" function**
47 These "*observer*" functions are described in the next subsections.
49 Register and activate of an "*observer*" function
50 +++++++++++++++++++++++++++++++++++++++++++++++++
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
57 .. eficas_observer_nodetype:
58 .. image:: images/eficas_observer_nodetype.png
62 **Choosing its entry type for an "observer" function**
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.
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).
82 General form for a script describing an "*observer*" function
83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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
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.
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::
101 print(" --->",info," Value =",var[-1])
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.
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!
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.
129 Hereinafter we give the identifier and the contents of all the available
132 .. _section_ref_observers_templates:
134 Inventory of available "*observer*" function models ("*Template*")
135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
137 .. index:: single: ValuePrinter (Observer)
139 Template **ValuePrinter**
140 .........................
142 Print on standard output the current value of the variable.
146 print(str(info)+" "+str(var[-1]))
148 .. index:: single: ValueAndIndexPrinter (Observer)
150 Template **ValueAndIndexPrinter**
151 .................................
153 Print on standard output the current value of the variable, adding its index.
157 print(str(info)+(" index %i:"%(len(var)-1))+" "+str(var[-1]))
159 .. index:: single: ValueSeriePrinter (Observer)
161 Template **ValueSeriePrinter**
162 ..............................
164 Print on standard output the value series of the variable.
168 print(str(info)+" "+str(var[:]))
170 .. index:: single: ValueSaver (Observer)
172 Template **ValueSaver**
173 .......................
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.
180 v=numpy.array(var[-1], ndmin=1)
186 f='/tmp/value_%s_%05i.txt'%(info,istep)
188 print('Value saved in "%s"'%f)
191 .. index:: single: ValueSerieSaver (Observer)
193 Template **ValueSerieSaver**
194 ............................
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.
201 v=numpy.array(var[:], ndmin=1)
207 f='/tmp/value_%s_%05i.txt'%(info,istep)
209 print('Value saved in "%s"'%f)
212 .. index:: single: ValuePrinterAndSaver (Observer)
214 Template **ValuePrinterAndSaver**
215 .................................
217 Print on standard output and, in the same time save in a file of the '/tmp' directory, the current value of the variable.
222 v=numpy.array(var[-1], ndmin=1)
223 print(str(info)+" "+str(v))
229 f='/tmp/value_%s_%05i.txt'%(info,istep)
231 print('Value saved in "%s"'%f)
234 .. index:: single: ValueIndexPrinterAndSaver (Observer)
236 Template **ValueIndexPrinterAndSaver**
237 ......................................
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.
244 v=numpy.array(var[-1], ndmin=1)
245 print(str(info)+(" index %i:"%(len(var)-1))+" "+str(v))
251 f='/tmp/value_%s_%05i.txt'%(info,istep)
253 print('Value saved in "%s"'%f)
256 .. index:: single: ValueSeriePrinterAndSaver (Observer)
258 Template **ValueSeriePrinterAndSaver**
259 ......................................
261 Print on standard output and, in the same time, save in a file of the '/tmp' directory, the value series of the variable.
266 v=numpy.array(var[:], ndmin=1)
267 print(str(info)+" "+str(v))
273 f='/tmp/value_%s_%05i.txt'%(info,istep)
275 print('Value saved in "%s"'%f)
278 .. index:: single: ValueGnuPlotter (Observer)
280 Template **ValueGnuPlotter**
281 ............................
283 Graphically plot with Gnuplot the current value of the variable.
287 import numpy, Gnuplot
288 v=numpy.array(var[-1], ndmin=1)
292 gp('set style data lines')
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' ) )
300 .. index:: single: ValueSerieGnuPlotter (Observer)
302 Template **ValueSerieGnuPlotter**
303 .................................
305 Graphically plot with Gnuplot the value series of the variable.
309 import numpy, Gnuplot
310 v=numpy.array(var[:], ndmin=1)
314 gp('set style data lines')
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' ) )
322 .. index:: single: ValuePrinterAndGnuPlotter (Observer)
324 Template **ValuePrinterAndGnuPlotter**
325 ......................................
327 Print on standard output and, in the same time, graphically plot with Gnuplot the current value of the variable.
331 print(str(info)+' '+str(var[-1]))
332 import numpy, Gnuplot
333 v=numpy.array(var[-1], ndmin=1)
337 gp('set style data lines')
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' ) )
345 .. index:: single: ValueSeriePrinterAndGnuPlotter (Observer)
347 Template **ValueSeriePrinterAndGnuPlotter**
348 ...........................................
350 Print on standard output and, in the same time, graphically plot with Gnuplot the value series of the variable.
354 print(str(info)+' '+str(var[:]))
355 import numpy, Gnuplot
356 v=numpy.array(var[:], ndmin=1)
360 gp('set style data lines')
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' ) )
368 .. index:: single: ValuePrinterSaverAndGnuPlotter (Observer)
370 Template **ValuePrinterSaverAndGnuPlotter**
371 ...........................................
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.
377 print(str(info)+' '+str(var[-1]))
379 v=numpy.array(var[-1], ndmin=1)
385 f='/tmp/value_%s_%05i.txt'%(info,istep)
387 print('Value saved in "%s"'%f)
393 gp('set style data lines')
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' ) )
401 .. index:: single: ValueSeriePrinterSaverAndGnuPlotter (Observer)
403 Template **ValueSeriePrinterSaverAndGnuPlotter**
404 ................................................
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.
410 print(str(info)+' '+str(var[:]))
412 v=numpy.array(var[:], ndmin=1)
418 f='/tmp/value_%s_%05i.txt'%(info,istep)
420 print('Value saved in "%s"'%f)
426 gp('set style data lines')
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' ) )
434 .. index:: single: ValueMean (Observer)
436 Template **ValueMean**
437 ......................
439 Print on standard output the mean of the current value of the variable.
444 print(str(info)+' '+str(numpy.nanmean(var[-1])))
446 .. index:: single: ValueStandardError (Observer)
448 Template **ValueStandardError**
449 ...............................
451 Print on standard output the standard error of the current value of the variable.
456 print(str(info)+' '+str(numpy.nanstd(var[-1])))
458 .. index:: single: ValueVariance (Observer)
460 Template **ValueVariance**
461 ..........................
463 Print on standard output the variance of the current value of the variable.
468 print(str(info)+' '+str(numpy.nanvar(var[-1])))
470 .. index:: single: ValueL2Norm (Observer)
472 Template **ValueL2Norm**
473 ........................
475 Print on standard output the L2 norm of the current value of the variable.
480 v = numpy.ravel( var[-1] )
481 print(str(info)+' '+str(float( numpy.linalg.norm(v) )))
483 .. index:: single: ValueRMS (Observer)
485 Template **ValueRMS**
486 .....................
488 Print on standard output the root mean square (RMS), or quadratic mean, of the current value of the variable.
493 v = numpy.ravel( var[-1] )
494 print(str(info)+' '+str(float( numpy.sqrt((1./v.size)*numpy.dot(v,v)) )))