Documentation
/ User's manual in Python
:
In Uranie, an external code is defined by a command line, and input and output attributes which are stored in ASCII files, named respectively input files and output files.
If, because of the way the function are defined, a TLauncherFunction is bound to have
only double-precision attributes as input, dealing with a code allows more flexibility and it is now possible to handle
both vectors and strings as inputs and outputs.
To launch an external code, it is necessary to define a TLauncher object. This object is used to
launch the code defined in a TCode object and that use TInputFile input files and TOutputFile output files (as shown in Figure IV.2).
This section is organised as follow: we first describe the definition of TInputFile and TOutputFile in Section IV.3.1, then the construction of a TCode in Section IV.3.2, and finally the construction of a TLauncher in Section IV.3.3. A schematic view of the code launching process is represented in Figure IV.3.
Figure IV.3. Schematic description of the launcher procedure when using an external code. Yellow boxes show instances of class, and green ones are precision about attributes. The design-of-experiments part can be replaced by an already-existing database.
![]() |
The paragraphs below describe the main part of this procedure, as it is displayed by Figure IV.3, remaining at the class level. It can indeed be decomposed as follow:
A design-of-experiments is produced (the corresponding part is highlighted in the red-dashed rectangle). On top of this, a file is "attached" to every input attribute, defining a way to spot the place where to find information when the launcher would have to run the code. This part is furthered discussed in Section IV.3.1.2
One or more
TOutputFileare created and the output attributes are attached to them, specifying, as for previous step, how to extract the information once the launcher will be running the code. This part is also described in more details in Section IV.3.1.3.A
TCodeis created by giving the inputTDataServeralong with the string used to launch the code in a terminal. The output files are then attached to theTCodeobject.The
TLauncherobject is created by giving the inputTDataServerand the previously definedTCode. During the creation, a working directory is made where input files are copied. Then the loop is performed, running the code as many times as there are points in the design-of-experiments. This loop can be decomposed as well in few key-steps:An initialisation: a sub-directory is created for this specific computation, in which the input files are copied and modified to used the requested input values defined in the design-of-experiments and stored in the
TDSNtupleD.Running the external code itself
Parsing the output files to collect the desired values and send them back to the launcher which fills the ntuple of results. This ntuple is merged to the input one at the end of the process.
Uranie can manage different kinds of input and output files. We'll describe below these different IO file formats after a short introduction on the way these files are implemented.
All the input/output files that will be discussed in the following sections (meaning restrained to the Launcher
module) are based on a class named TamponTexte, which comprehends a file as a group of field,
apart one to another thanks to separators. It is absolutely crucial to keep this is mind.
With the introduction of the vectors and strings in version 3.10.0, more complex interactions with files were introduced: how to differ two iterations of a single vector and how to differentiate a double from a string. This depends highly on the nature of the input/output file under consideration, whether it is just a text file used as database (in this case it depends mostly on the way you've written the code that generates/parses it) or whether it corresponds to a stricter kind of file, for instance a piece of code (c++/python/zsh). In the latter case, strings and vectors are not written in the same way. To take this into account, a rule has been defined (commonly to both input and output files, both in the Launcher and Relauncher module). There is a method for any kind of file to define properties of vector and string objects:
setVectorProperties(string beg, string delim, string end): the first element is the string beginning of the vector (usually "[" for python, "(" for zsh/sh, nothing...), the second one is the delimiter between iterators (usually "," for c++/python, blank for zsh/sh...) and the last one is the end of the string (usually the opposite character of the beginning one).setStringProperties(string beg, string end): the first and second elements are respectively the beginning and ending character used for string (oftenly """).
In order to illustrate how to deal with a complicated case (when the order provided by the database is not the one needed by the code, but also dealing with vectors and strings as inputs), one can have a look at the examples provided from Section XIV.5.29 to Section XIV.5.33. The output files, on the other hand, are more thoroughly (and explicitly) discussed in Section IV.3.1.3.
When a code needs input parameters from one or more input files, Uranie must be able to duplicate and modify these files in order to set the input parameter under discussion to its requested value. Uranie can do this using different kinds of input files. Before going through the following sections, which will present the way input files are used with the flowrate problem presented in Section IV.1.2, a small discussion will introduced the different kinds of input file, some of their properties and the way they are usually declared.
The classes used to either do the substitution in the input file or to recreate a new input file to feed the code,
were not much discussed up to now in this documentation as they were created on the fly, by the
TCode itself at the initialisation. This is done by the mean of checking the list of
EFileType for every attribute (one attribute can indeed have more than one file and type in case the
code, or codes, need to have this information in different files, with different formats). An explicit declaration
is however possibly needed for two reasons:
Letting the
TCodeobject do, as described above, one can not choose the order to which the attribute are attached to the corresponding dumper object, and so, the order in which they will be written (which can be of uttermost importance for some format). Indeed theTCodeobject will follow the order in which the attribute have been added to theTDataServerby hand (but in the case the user just has to invert the corresponding attributes) or, more likely, through a database (e.g. using thefileDataReadmethod).In the case of vector and strings handling, it might be necessary to specify the delimiter, beginning and ending sign (as already introduced above and in the last part of Section II.3.1.1).
The classes to handles inputs files can be split into two different types:
the one creating an input file from scratch: done with
TInputFileRecreateclass, it can use different implementations according to the type requested by the user, through theTAttribute::EFileTypeprovided in thesetFileKeymethod (discussed below). The possible values are:kNewKey,kNewTDS,kNewRowandkNewColumn. These flags are discussed below.the ones which modify an existing file: this is done with specific classes, depending on the type of inputs used by the code and this is also precised by the user through the
TAttribute::EFileTypeprovided in thesetFileKeymethod. The possible values are:kKey(creating implicitly aTInputFileKeyobject),kFlag(creating aTInputFileFlagobject), and bothkXMLAttributeandkXMLField(used in theTInputFileXMLinstance).
Let us consider the flowrate input file with "key = value" format, with the eight parameters
(
,
,
,
,
,
,
,
):
# # # INPUT FILE with KEYS for the "FLOWREATE" code # \date 2008-04-22 12:53:35 # date = 123456 ; ######################### ## ## exclude points ## chu = 1050; chl = 770; cr = 1100; ## ######################### ######################### ## ## parameters : 8 ## Rw = 0.0500 ; R = 33366.67 ; Tu = 63070.0 ; Tl = 116.00 ; Hu = 1110.00 ; Hl = 768.57; L = 1200.0 ; Kw = 11732.14 ; ## ######################### ######################### ## ## to simulate CPU time ## ## normal 1 : ## min 10000000 : 1.160u 0.000s 0:01.16 100.0% ## max 100000000 : 11.600u 0.010s 0:11.61 100.0% ## nLoop = 1; ## ######################### end = 6;
Please note that this file has been created out of Uranie and that the values are not managed by Uranie yet: it is just a model of input file for the code.
Now we write the beginning of the Uranie script that is going to define attributes and assign them a place in the input file:
# Define the DataServer
tds = DataServer.TDataServer("tdsFlowrate", "Doe for Flowrate")
# Add the study attributes ( min, max and nominal values)
tds.addAttribute(DataServer.TUniformDistribution("rw", 0.05, 0.15))
tds.addAttribute(DataServer.TUniformDistribution("r", 100.0, 50000.0))
tds.addAttribute(DataServer.TUniformDistribution("tu", 63070.0, 115600.0))
tds.addAttribute(DataServer.TUniformDistribution("tl", 63.1, 116.0))
tds.addAttribute(DataServer.TUniformDistribution("hu", 990.0, 1110.0))
tds.addAttribute(DataServer.TUniformDistribution("hl", 700.0, 820.0))
tds.addAttribute(DataServer.TUniformDistribution("l", 1120.0, 1680.0))
tds.addAttribute(DataServer.TUniformDistribution("kw", 9855.0, 12045.0))
# The reference input file
sJDDReference = "flowrate_input_with_keys.in"
# Set the reference input file and the key for each input attributes
tds.getAttribute("rw").setFileKey(sJDDReference, "Rw")
tds.getAttribute("r").setFileKey(sJDDReference, "R")
tds.getAttribute("tu").setFileKey(sJDDReference, "Tu")
tds.getAttribute("tl").setFileKey(sJDDReference, "Tl")
tds.getAttribute("hu").setFileKey(sJDDReference, "Hu")
tds.getAttribute("hl").setFileKey(sJDDReference, "Hl")
tds.getAttribute("l").setFileKey(sJDDReference, "L")
tds.getAttribute("kw").setFileKey(sJDDReference, "Kw")
...
Specification of a "key=value" input file for the input variables
In this first part, definition of the attributes of the | |
Definition of the reference input file (the file copied before); | |
At each of these lines, definition of the place the parameter will be set, thanks to the
|
After these definitions, if we create the code launcher and launch it (what will be presented in the following sections), then the input file would be modified by writing each sample value in a new input file. For example, the following input file is one of the generated ones:
# # # INPUT FILE with KEYS for the "FLOWREATE" code # \date 2008-04-22 12:53:35 # date = 123456 ; ######################### ## ## exclude points ## chu = 1050; chl = 770; cr = 1100; ## ######################### ######################### ## ## parameters : 8 ## Rw = 5.194485e-02 ; R = 8.610663e+03 ; Tu = 7.644908e+04 ; Tl = 1.003881e+02 ; Hu = 1.058603e+03 ; Hl = 7.224698e+02; L = 1.148747e+03 ; Kw = 1.003128e+04 ; ## ######################### ######################### ## ## to simulate CPU time ## ## normal 1 : ## min 10000000 : 1.160u 0.000s 0:01.16 100.0% ## max 100000000 : 11.600u 0.010s 0:11.61 100.0% ## nLoop = 1; ## ######################### end = 6;
In this file, we will note the different values of the parameters, that have been modified compared to the "model" presented in the beginning of this section.
Tip
No matter the number of times the key appears in the input file, the value will only be replaced once!
Let us consider the flowrate input file with flag format, with the eight parameters
(
,
,
,
,
,
,
,
). As seen in Section IV.1.2.3.1.2, it is
necessary to write "flags" where the values will be written, as in the example below:
#
# INPUT FILE with FLAG for the "FLOWREATE" code
# \date 2008-04-22 12:55:17
#
new Implicit_Steady_State sch {
frottement_paroi { @Rw@ @R@ }
tinit 0.0
tmax 1000000.
nb_pas_dt_max 1500
dt_min @Hu@
dt_max @Hl@
facsec 1000000.
kW @Kw@
information_Tu Champ_Uniforme 1 @Tu@
information_Tl Champ_Uniforme 1 @Tl@
information_L {
precision @L@
}
convergence {
criterion relative_max_du_dt
precision @Rw@
}
stop_criterium {
ch_abcsissa_hu 1050
ch_ordinate_hl 770
c_radius 1100
}
Solveur Newton3 {
max_iter_matrice 1
max_iter_implicite 1
date 5654321
seuil_convg_implicite 1.e-6
assemblage_implicite 10
solveur_lineaire BiCGS
preconditionneur ILU
seuil_resol_implicite 1.e-5
}
}
Please note that this file has not been created out of Uranie since the flags have been written manually: this file is just a model of input files for the code.
Now we write the beginning of the Uranie script that is going to define attributes and to assign them a place in the input file:
# Define the DataServer
tds = DataServer.TDataServer("tdsFlowrate", "Doe for Flowrate")
# Add the study attributes ( min, max and nominal values)
tds.addAttribute(DataServer.TUniformDistribution("rw", 0.05, 0.15))
tds.addAttribute(DataServer.TUniformDistribution("r", 100.0, 50000.0))
tds.addAttribute(DataServer.TUniformDistribution("tu", 63070.0, 115600.0))
tds.addAttribute(DataServer.TUniformDistribution("tl", 63.1, 116.0))
tds.addAttribute(DataServer.TUniformDistribution("hu", 990.0, 1110.0))
tds.addAttribute(DataServer.TUniformDistribution("hl", 700.0, 820.0))
tds.addAttribute(DataServer.TUniformDistribution("l", 1120.0, 1680.0))
tds.addAttribute(DataServer.TUniformDistribution("kw", 9855.0, 12045.0))
# The reference input file
sJDDReference = "flowrate_input_with_flags.in"
# Set the reference input file and the key for each input attributes
tds.getAttribute("rw").setFileFlag(sJDDReference, "@Rw@")
tds.getAttribute("r").setFileFlag(sJDDReference, "@R@")
tds.getAttribute("tu").setFileFlag(sJDDReference, "@Tu@")
tds.getAttribute("tl").setFileFlag(sJDDReference, "@Tl@")
tds.getAttribute("hu").setFileFlag(sJDDReference, "@Hu@")
tds.getAttribute("hl").setFileFlag(sJDDReference, "@Hl@")
tds.getAttribute("l").setFileFlag(sJDDReference, "@L@")
tds.getAttribute("kw").setFileFlag(sJDDReference, "@Kw@")
Specification of a flag input file for the input variables
In this first part, definition of the attributes of the | |
Definition of the reference input file (the file copied before); | |
For every attribe, the position to write the information in the file is specified thanks to the
|
After these definitions, if we create the code launcher and run it (what will be presented in the following sections), then the input file would be modified by writing each sample value in a new input file. For example, the following input file is one of the generated ones:
#
# INPUT FILE with FLAG for the "FLOWREATE" code
# \date 2008-04-22 12:55:17
#
new Implicit_Steady_State sch {
frottement_paroi { 6.371966e-02 4.913216e+04 }
tinit 0.0
tmax 1000000.
nb_pas_dt_max 1500
dt_min 1.086881e+03
dt_max 7.372423e+02
facsec 1000000.
kW 1.190644e+04
information_Tu Champ_Uniforme 1 7.628909e+04
information_Tl Champ_Uniforme 1 7.386808e+01
information_L {
precision 1.402143e+03
}
convergence {
criterion relative_max_du_dt
precision 1.e-6
}
stop_criterium {
ch_abcsissa_hu 1050
ch_ordinate_hl 770
c_radius 1100
}
Solveur Newton3 {
max_iter_matrice 1
max_iter_implicite 1
date 5654321
seuil_convg_implicite 1.e-6
assemblage_implicite 10
solveur_lineaire BiCGS
preconditionneur ILU
seuil_resol_implicite 1.e-5
}
}In this file, we will note the different values of the parameters that have been modified compared to the "model" presented in the beginning of this section.
Tip
If a flag exists several times in a file, the value will be replaced at all the occurrences of the flag.
In case the user does not want to create a model file, it is possible to fully create the input file. To do so,
it is necessary to use the setFileKey method on an attribute and to specify the format of the file
to be created. Uranie is able to generate input files with "key = value" format, "values in row" or "values in
column".
For the "key = value" format, the
setFileKeymethod must be called with a string that describes the input format (see the C++ reference page for the available formats) as third parameter (if the string is empty, the default format will be used), and the flagTAttributeFileKey::kNewKeyas fourth parameter. As an example the definition below:sIn = "test_input_with_keys.in" tds.getAttribute("rw").setFileKey(sIn, "Rw", "%e", DataServer.TAttributeFileKey.kNewKey) tds.getAttribute("r").setFileKey(sIn, "R", "%e", DataServer.TAttributeFileKey.kNewKey) tds.getAttribute("tu").setFileKey(sIn, "Tu", "%e", DataServer.TAttributeFileKey.kNewKey) tds.getAttribute("tl").setFileKey(sIn, "Tl", "%e", DataServer.TAttributeFileKey.kNewKey) tds.getAttribute("hu").setFileKey(sIn, "Hu", "", DataServer.TAttributeFileKey.kNewKey) tds.getAttribute("hl").setFileKey(sIn, "Hl", "", DataServer.TAttributeFileKey.kNewKey) tds.getAttribute("l").setFileKey(sIn, "L", "", DataServer.TAttributeFileKey.kNewKey) tds.getAttribute("kw").setFileKey(sIn, "Kw", "", DataServer.TAttributeFileKey.kNewKey)will lead in the creation of files
test_input_with_keys.in, as:Rw = 1.136676e-01 ; R = 2.705506e+04 ; Tu = 9.259556e+04 ; Tl = 6.400877e+01 ; Hu = 1.087919e+03 ; Hl = 7.600170e+02 ; L = 1.537756e+03 ; Kw = 1.060694e+04 ;
For the "value in row" format, the
setFileKeymethod must be called with a string that describes the input format (see the C++ reference page for the available formats) as third parameter (if the string is empty, the default format will be used), and the flagTAttributeFileKey::kNewRowas fourth parameter. As an example the definition below:sInR = "test_input_with_row.in" tds.getAttribute("rw").setFileKey(sInR, "Rw", "%e", DataServer.TAttributeFileKey.kNewRow) tds.getAttribute("r").setFileKey(sInR, "R", "%e", DataServer.TAttributeFileKey.kNewRow) tds.getAttribute("tu").setFileKey(sInR, "Tu", "%e", DataServer.TAttributeFileKey.kNewRow) tds.getAttribute("tl").setFileKey(sInR, "Tl", "%e", DataServer.TAttributeFileKey.kNewRow) tds.getAttribute("hu").setFileKey(sInR, "Hu", "", DataServer.TAttributeFileKey.kNewRow) tds.getAttribute("hl").setFileKey(sInR, "Hl", "", DataServer.TAttributeFileKey.kNewRow) tds.getAttribute("l").setFileKey(sInR, "L", "", DataServer.TAttributeFileKey.kNewRow) tds.getAttribute("kw").setFileKey(sInR, "Kw", "", DataServer.TAttributeFileKey.kNewRow)will lead in the creation of files
test_input_with_row.in, as:1.136676e-01 2.705506e+04 9.259556e+04 6.400877e+01 1.087919e+03 7.600170e+02 1.537756e+03 1.060694e+04
Caution must be taken with vectors: before this version, the Row format and the DataServer format (for output files) were equivalent up to the headers. Now this is different, as vector are dumped on a single line for DataServer format (also called Salome-table) and with one value per line in Row files. A new flag as then be created as can be seen for instance when comparing Section XIV.5.30 and Section XIV.5.32. For the new DataServer format, the
setFileKeymethod must be called with a string that describes the input format (see the C++ reference page for the available formats) as third parameter (if the string is empty, the default format will be used), and the flagTAttributeFileKey::kNewTDSas fourth parameter. As an example the definition below:sInTds = "test_input_tds.in" tds.getAttribute("rw").setFileKey(sInTds, "Rw", "%e", DataServer.TAttributeFileKey.kNewTDS) tds.getAttribute("r").setFileKey(sInTds, "R", "%e", DataServer.TAttributeFileKey.kNewTDS) tds.getAttribute("tu").setFileKey(sInTds, "Tu", "%e", DataServer.TAttributeFileKey.kNewTDS) tds.getAttribute("tl").setFileKey(sInTds, "Tl", "%e", DataServer.TAttributeFileKey.kNewTDS) tds.getAttribute("hu").setFileKey(sInTds, "Hu", "", DataServer.TAttributeFileKey.kNewTDS) tds.getAttribute("hl").setFileKey(sInTds, "Hl", "", DataServer.TAttributeFileKey.kNewTDS) tds.getAttribute("l").setFileKey(sInTds, "L", "", DataServer.TAttributeFileKey.kNewTDS) tds.getAttribute("kw").setFileKey(sInTds, "Kw", "", DataServer.TAttributeFileKey.kNewTDS)will lead in the creation of files
test_input_with_tds.in, as:#COLUMN_NAMES: rw|r|tu|tl|hu|hl|l|kw #COLUMN_TYPES: D|D|D|D|D|D|D|D 1.136676e-01 2.705506e+04 9.259556e+04 6.400877e+01 1.087919e+03 7.600170e+02 1.537756e+03 1.060694e+04
Once again, this file and the previous one looks very familiar, but the input file created with vectors, using respectively DataServer and Row format in Section XIV.5.30 and Section XIV.5.32 are not.
For the "values in column" format, the
setFileKeymethod must be called with a string that describes the input format (see the C++ reference page for the available formats) as third parameter (if the string is empty, the default format will be used), and the flagTAttributeFileKey::kNewColumnas fourth parameter. As an example the definition below:sInC = "test_input_with_column.in" tds.getAttribute("rw").setFileKey(sInC, "Rw", "%e", DataServer.TAttributeFileKey.kNewColumn) tds.getAttribute("r").setFileKey(sInC, "R", "%e", DataServer.TAttributeFileKey.kNewColumn) tds.getAttribute("tu").setFileKey(sInC, "Tu", "%e", DataServer.TAttributeFileKey.kNewColumn) tds.getAttribute("tl").setFileKey(sInC, "Tl", "%e", DataServer.TAttributeFileKey.kNewColumn) tds.getAttribute("hu").setFileKey(sInC, "Hu", "", DataServer.TAttributeFileKey.kNewColumn) tds.getAttribute("hl").setFileKey(sInC, "Hl", "", DataServer.TAttributeFileKey.kNewColumn) tds.getAttribute("l").setFileKey(sInC, "L", "", DataServer.TAttributeFileKey.kNewColumn) tds.getAttribute("kw").setFileKey(sInC, "Kw", "", DataServer.TAttributeFileKey.kNewColumn)will lead in the creation of files
test_input_with_column.in, as:1.136676e-01 2.705506e+04 9.259556e+04 6.400877e+01 1.087919e+03 7.600170e+02 1.537756e+03 1.060694e+04
Uranie is also able to generate data in XML input files. For example, let us consider the following input file
that contains the eight parameters previously seen (
,
,
,
,
,
,
,
):
<?xml version="1.0"?>
<problem>
<description name="flowrate" version="1.0" title="UseCase flowrate with XML input file" date="2008-04-22 12:55:17">
<tool name="uranie" version="0.3"/>
</description>
<steady_state name="sch">
<frottement_paroi rw="0.0500" r="33366.67"/>
<tinit>0.0</tinit>
<tmax>1000000</tmax>
<nb_pas_dt_max>1500</nb_pas_dt_max>
<parameter>
<tonode>mailleur</tonode><toport>dt_min</toport>
<value><double>1110.00</double></value>
</parameter>
<parameter>
<tonode>mailleur</tonode><toport>dt_max</toport>
<value><double>768.57</double></value>
</parameter>
<facsec>1000000.</facsec>
<kW value="11732.14"/>
<informations>
<parameter name="Tu">
<Champ_Uniforme>1</Champ_Uniforme>
<value><double>63070.0</double></value>
</parameter>
<parameter name="Tl">
<Champ_Uniforme>1</Champ_Uniforme>
<value><double>116.00</double></value>
</parameter>
<parameter name="L" precision="1200.0"/>
</informations>
<convergence>
<criterion>relative_max_du_dt</criterion>
<precision>1.e-6</precision>
</convergence>
<stop_criterium ch_abcsissa_hu="1050" ch_ordinate_hl="770" c_radius="1100" nLoop="1"/>
<solveur name="Newton3">
<max_iter_matrice>1</max_iter_matrice>
<max_iter_implicite>1</max_iter_implicite>
<date>5654321</date>
<seuil_convg_implicite>1.e-6</seuil_convg_implicite>
<assemblage_implicite>10</assemblage_implicite>
<solveur_lineaire name="BiCGS">
<preconditionneur>ILU</preconditionneur>
<seuil_resol_implicite>1.e-5</seuil_resol_implicite>
</solveur_lineaire>
</solveur>
</steady_state>
</problem>
The transformation of an XML file is described by using XSLT transformation directives. When these directives have been described in the script, Uranie generates an XSLT transformation file, that will be directly applied on the input XML file to transform it. This XSLT file will describe how to copy the reference XML file to an XML file whose values are changed. So the description of the location of the values to change is naturally written with XSLT directives. Below is a short summary of the main XSLT commands:
We can see above that there are two kinds of place a variable value may be changed: in an attribute or in a
field. For Uranie to be able to modify the value, it is necessary to specify the kind of replacement to make,
using the TAttributeFileKey::kXMLAttribute key for an attribute, or the
TAttributeFileKey::kXMLField key for a field.
The example below demonstrates how to modify the attribute values in the file presented earlier:
sJDDReferenceXML = "flowrate_input_with_xml.xml"
tds.getAttribute("rw").setFileKey(sJDDReferenceXML, "frottement_paroi/@rw", "%e", DataServer.TAttributeFileKey.kXMLAttribute)
tds.getAttribute("r").setFileKey(sJDDReferenceXML, "frottement_paroi/@r", "%e", DataServer.TAttributeFileKey.kXMLAttribute)
tds.getAttribute("tu").setFileKey(sJDDReferenceXML, "parameter[@name='Tu']/value/double", "%e", DataServer.TAttributeFileKey.kXMLField)
tds.getAttribute("tl").setFileKey(sJDDReferenceXML, "parameter[@name='Tl']/value/double", "%e", DataServer.TAttributeFileKey.kXMLField)
tds.getAttribute("hu").setFileKey(sJDDReferenceXML, "parameter[tonode='mailleur' and toport='dt_max']/value/double", "%e", DataServer.TAttributeFileKey.kXMLField)
tds.getAttribute("hl").setFileKey(sJDDReferenceXML, "parameter[tonode='mailleur' and toport='dt_min']/value/double", "%e", DataServer.TAttributeFileKey.kXMLField)
tds.getAttribute("l").setFileKey(sJDDReferenceXML, "parameter[name='L']/@precision", "%e", DataServer.TAttributeFileKey.kXMLAttribute)
tds.getAttribute("kw").setFileKey(sJDDReferenceXML, "kW/@value", "%e", DataServer.TAttributeFileKey.kXMLAttribute)
Note that the key that describes the kind of replacement is different depending on whether the value is stored as
an attribute (kXMLAttribute) or a field (kXMLField).
When Uranie is run, an XSLT file is created to describe the changes to make in the original XML file. Below is an example of such a generated XSLT file:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="frottement_paroi/@rw">
<xsl:attribute name="rw">
<xsl:value-of select="0.133648"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="frottement_paroi/@r">
<xsl:attribute name="r">
<xsl:value-of select="6989.96"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="parameter[@name='Tu']/value/double">
<double>
<xsl:value-of select="63442"/>
</double>
</xsl:template>
<xsl:template match="parameter[@name='Tl']/value/double">
<double>
<xsl:value-of select="77.2926"/>
</double>
</xsl:template>
<xsl:template match="parameter[tonode='mailleur' and toport='dt_max']/value/double">
<double>
<xsl:value-of select="1051.48"/>
</double>
</xsl:template>
<xsl:template match="parameter[tonode='mailleur' and toport='dt_min']/value/double">
<double>
<xsl:value-of select="750.107"/>
</double>
</xsl:template>
<xsl:template match="parameter[name='L']/@precision">
<xsl:attribute name="precision">
<xsl:value-of select="1543.31"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="kW/@value">
<xsl:attribute name="value">
<xsl:value-of select="11745.4"/>
</xsl:attribute>
</xsl:template>
<!-- Copy all the rest of the file -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
When applied to the flowrate_input_with_xml.xml reference input file, this XSLT file produces the
XML file Uranie will effectively use:
<?xml version="1.0"?>
<problem>
<description name="flowrate" version="1.0" title="UseCase flowrate with XML input file" date="2008-04-22 12:55:17">
<tool name="uranie" version="0.3"/>
</description>
<steady_state name="sch">
<frottement_paroi rw="0.133648" r="6989.96"/>
<tinit>0.0</tinit>
<tmax>1000000</tmax>
<nb_pas_dt_max>1500</nb_pas_dt_max>
<parameter>
<tonode>mailleur</tonode><toport>dt_min</toport>
<value><double>750.107</double></value>
</parameter>
<parameter>
<tonode>mailleur</tonode><toport>dt_max</toport>
<value><double>1051.48</double></value>
</parameter>
<facsec>1000000.</facsec>
<kW value="11745.4"/>
<informations>
<parameter name="Tu">
<Champ_Uniforme>1</Champ_Uniforme>
<value><double>63442</double></value>
</parameter>
<parameter name="Tl">
<Champ_Uniforme>1</Champ_Uniforme>
<value><double>77.2926</double></value>
</parameter>
<parameter name="L" precision="1200.0"/>
</informations>
<convergence>
<criterion>relative_max_du_dt</criterion>
<precision>1.e-6</precision>
</convergence>
<stop_criterium ch_abcsissa_hu="1050" ch_ordinate_hl="770" c_radius="1100" nLoop="1"/>
<solveur name="Newton3">
<max_iter_matrice>1</max_iter_matrice>
<max_iter_implicite>1</max_iter_implicite>
<date>5654321</date>
<seuil_convg_implicite>1.e-6</seuil_convg_implicite>
<assemblage_implicite>10</assemblage_implicite>
<solveur_lineaire name="BiCGS">
<preconditionneur>ILU</preconditionneur>
<seuil_resol_implicite>1.e-5</seuil_resol_implicite>
</solveur_lineaire>
</solveur>
</steady_state>
</problem>
Warning
Obviously, the use of the XML input needs an XSLT processor installed.
Tip
It is important to note that Uranie can manage inputs split between multiple input files, just by specifying the name of these different files, whatever the kind of input file under consideration.
After the code has run, it has created output files we want to extract values from. We present here the different kinds of output files Uranie can manage, and how to retrieve information from them.
Uranie can retrieve information from files whose formats are "key = value", "values in row", "values in column", "dataserver value" and XML.
TOutputFileKey retrieves data from a file where values are stored in the format "key = value". An
example of such a file is given below:
yhat = 6.757218e+01; d = 4.092561e+03;
To get data from such a file, it is necessary to create a TOutputFileKey object, and add
to it the attributes of the file:
foutk = Launcher.TOutputFileKey("_output_flowrate_withKey_.dat")
foutk.addAttribute(DataServer.TAttribute("yhat"))
foutk.addAttribute(DataServer.TAttribute("d"))
When working with "key = value" files, the default name of the attribute to create (here yhat or
d) is the name of the attribute in the output file. In order to create an attribute with a name
different from the name in the file, it is necessary to create an attribute and set it to the output file:
attr = DataServer.TAttribute("y")
attr.setFileKey("_output_flowrate_withKey_.dat", "yhat")
foutk.addAttribute(attr)
It is also possible to retrieve only the values of the desired variables. In the previous example, it would
have been possible to retrieve only the values of d just by deleting the line that treats
yhat output.
TOutputFileRow retrieves data from a file where values are stored in rows. An example of
such a file is given below:
#COLUMN_NAMES: yhat | d 6.757218e+01 4.092561e+03
To get data from such a file, it is necessary to create a TOutputFileRow object, and add
to it the attributes of the file:
foutr = Launcher.TOutputFileRow("_output_flowrate_withRow_.dat")
foutr.addAttribute(DataServer.TAttribute("yhat"))
foutr.addAttribute(DataServer.TAttribute("d"))
When working with "values in row" files, the addition order of the attributes determines which value will be
stored in each variable. In the previous example, the first value encountered in the file will be stored in the
yhat attribute, and the second one in d. As a consequence, in order to get only the
values from a given column, it is necessary to specify the column number (first column is number 1, not 0). When
this number is not specified, the value used is the one following the previous value. For example, if we suppose
the file test.dat contains 8 values stored in row, we can have:
foutr = Launcher.TOutputFileRow("test.dat")
foutr.addAttribute(DataServer.TAttribute("y2"), 2) # get the 2nd column value
foutr.addAttribute(DataServer.TAttribute("y3")) # get the 3rd column value
foutr.addAttribute(DataServer.TAttribute("y8"), 8) # get the 8th column value
foutr.addAttribute(DataServer.TAttribute("y5"), 5) # get the 5th column value
foutr.addAttribute(DataServer.TAttribute("y6")) # get the 6th column valueWarning
If one is not considering vectors, Row and DataServer (Salome-table) format output are equivalent. Else, it differs a lot as it can be seen by comparing Section XIV.5.25 and Section XIV.5.27.
TOutputFileColumn retrieves data from a file where values are stored in columns. An
example of such a file is given below:
2.618019e+01 3.602045e+03
To get data from such a file, it is necessary to create a TOutputFileColumns object, and
add to it the attributes of the file:
foutc = Launcher.TOutputFileColumn("_output_flowrate_withColumn_.dat")
foutc.addAttribute(DataServer.TAttribute("yhat"))
foutc.addAttribute(DataServer.TAttribute("d"))
When working with "values in column" files, the addition order of the attributes determines which value will be
stored in each variable. In the example, the first value encountered in the file will be stored in the
yhat attribute, and the second one in d. As a consequence, in order to get only the
values from a given row, it is necessary to specify the row number (first row is number 1, not 0). When this
number is not specified, the value caught is supposed to have the next index that the previous value. For
example, if we suppose the file test.dat contains 8 values stored in column, we can have:
foutc = Launcher.TOutputFileColumn("test.dat")
foutc.addAttribute(DataServer.TAttribute("y2"), 2) # get the 2nd row value
foutc.addAttribute(DataServer.TAttribute("y3")) # get the 3rd row value
foutc.addAttribute(DataServer.TAttribute("y8"), 8) # get the 8th row value
foutc.addAttribute(DataServer.TAttribute("y5"), 5) # get the 5th row value
foutc.addAttribute(DataServer.TAttribute("y6")) # get the 6th row value
Another output format is the format of the TDataServer: the first line describes the
data and the data follows.
#COLUMN_NAMES: yhat | d 6.757218e+01 4.092561e+03
To get data from such a file, it is necessary to create a TOutputFileDataServer object,
and add to it the attributes to be read from the file:
foutds = Launcher.TOutputFileDataServer("_output_flowrate_withRow_.dat")
foutds.addAttribute(DataServer.TAttribute("yhat"))
foutds.addAttribute(DataServer.TAttribute("d"))
Here the order in which the parameters are retrieved is not important: when looking for the "d"
attribute for example, as the name "d" is the second name of the #COLUMN_NAMES: line, Uranie
will retrieve the second value of the line (i.e. 3.602045e+03).
Warning
If one is not considering vectors, Row and DataServer (Salome-table) format output are equivalent. Else, it differs a lot as can be seen by comparing Section XIV.5.25 and Section XIV.5.27.The last output format is the XML format, where values can be retrieved from XML fields or attributes. Note this kind of output needs the LibXML2 library.
<?xml version="1.0"?>
<steady_state name="flowrate">
<parameter>
<tonode>mesher</tonode>
<toport>dt_hl</toport>
<value>
<double>2.618019e+01</double>
</value>
</parameter>
<distance value="3.602045e+03"/>
</steady_state>
To get data from such a file, it is necessary to create a TOutputFileXML object, and add
to it the attributes to catch from the file. When adding attributes, it is necessary to pass the name of the
attribute to create or the attribute itself to the addAttribute method, as well as its XSL path and
the kind of XML object to get data between kXMLAttribute and kXMLField. For example to
get values from the XML file generated by flowrate, use the following code:
foutXML = Launcher.TOutputFileXML("_output_flowrate_withXML_.dat")
foutXML.addAttribute("yhat", "/steady_state[@name='flowrate']/parameter/value/double", DataServer.TAttributeFileKey.kXMLField)
foutXML.addAttribute(DataServer.TAttribute("d"), "/steady_state[@name='flowrate']/distance/@value", DataServer.TAttributeFileKey.kXMLAttribute)As for the "key=value" and the DataServer formats, the order the parameters are provided is not important.
A TCode object is used to define an external code. In order to create such an object, the user must call the
constructor whose arguments are a pointer on the useful TDataServer and a TString that contains the
command to execute the external code. For example:
mycode = Launcher.TCode(tds, "flowrate -s -k")
This line will create the TCode object mycode, link it with the TDataServer, and assign the command line
flowrate -s -k to it.
Some parameters can be set to the code: its working directory (Section IV.3.2.1), the definition of unmodified input files (Section IV.3.2.2), and the location of output files (Section IV.3.2.3).
By default, the computations are made in a new directory named URANIE in the current folder. To
modify this behaviour, it is possible to specify the working directory by using the
setWorkingDirectory method:
mycode.setWorkingDirectory(ROOT.gSystem.pwd()+"/working_directory")
With the previous line, the code will run in sub-directories of the newly created working_directory
folder.
Tip
It is also possible to specify the working directory by using the setWorkingDirectory method on a
TLauncher object (see Section IV.3.3). In case both methods are used, the code will
use the path defined in the TLauncher, then the one defined in the TCode.
While the variables with modifiable values are stored in the TDataServer (see Section IV.3.1), the code may need input files that contain parameters Uranie
does not have to modify. To add such a file to the TCode object, just use the addInputFile method
after having specified the directory to find it with the setReferenceDirectory method.
mycode2 = Launcher.TCode(tds, "flowrate -s -k")
mycode2.setReferenceDirectory(ROOT.gSystem.pwd()+"/reference_directory")
mycode2.addInputFile("flowrate_input_with_flags_1.in")
mycode2.addInputFile("flowrate_input_with_flags_2.in")
The previous lines will lead in the copy of the files
$PWD/reference_directory/flowrate_input_with_flags_1.in and
$PWD/reference_directory/flowrate_input_with_flags_2.in in the working directory of the code. Note
that the reference directory definition should be made with an absolute path.
The method getReferenceDirectory will return this reference directory as a
TString.
In order to specify the name of the output file of the code, it is necessary to use the
addOutputFile(outfile) method, that defines the TOutputfile object
outfile as an output file for the code:
foutk = Launcher.TOutputFileKey("_output_flowrate_withKey_.dat")
mycode3 = Launcher.TCode(tds, "flowrate -s -k")
mycode3.addOutputFile(foutk)
After having created the output file object fout, this code adds it as an output file to the
mycode TCode object.
In order to run an external code, it is necessary to define an object that can launch this code. This object is a
TLauncher. To create it, the constructor just needs a TDataServer and a TCode reference, as shown in the example below:
tds = DataServer.TDataServer("tdsFlowrate", "Doe for Flowrate")
# (add data to the TDataServer)
mycode = Launcher.TCode(tds, "command")
mylauncher = Launcher.TLauncher(tds, mycode) 
Creating a TLauncher
Creation of a | |
Creation of a | |
Construction of a |
In order to manipulate the code, different methods can be used:
setWorkingDirectory: set the directory in which the code will be run and where the temporary folders needed by the code will be stored.mylauncher.setWorkingDirectory(ROOT.gSystem.Getenv("HOME") + "/tmp/")The code runs in
$HOME/tmp/. Note that, as seen in Section IV.3.2.1, if this function is not called on the currentTLauncherobject, the working directory can be set on theTCodeobject. If none of these methods are used, it will be set to a directory namedURANIEcreated in the reference directory.The method
getWorkingDirectorywill return this directory as aTString.setSave(i): activate the save mode and set the maximum number i of folders to be kept. A positive value for i stands for the explicit maximum number of saves, while no value or -1 value allow to keep all the patterns (all patterns are launched in a different working directoryUranieLauncher_i). Default parameter is -1.If
setSaveis not called, the temporary output folders of the code will be overwritten at each computing step, while they will be left unmodified if the method is called.mylauncher.setSave() # will save each launch mylauncher.setSave(-1) # will save each launch mylauncher.setSave(10) # will save 10 launchesThe method
getSavewill return a boolean describing the state of the save flag, and the methodunsetSavewill deactivate the save mode.Warning
In case of multi-process distributed computation, in order to prevent all the processes from trying and accessing the same data at the same time, a call to the
setSavemethod is mandatory. As a consequence, if it is not manually set, Uranie will set it automatically.setClean(kTrue/kFalse): set the clean flag to the value true or false. If it is set tokTrue, all the working directories are cleaned before launching. Then if the save flag is set tokTRUE, the working directories are cleaned a second time after theTLauncherrun. If not specified, default parameter iskTrue, which means the working directory will be cleaned (i.e. temporary folders will be erased).mylauncher.setClean() # set the clean flag to "true" mylauncher.setClean(True) # set the clean flag to "true" mylauncher.setClean(False) # set the clean flag to "false"The method
getCleanwill return the clean flag as a boolean.setVarDraw(str,select,opt): activate and define the graphics during the launching. By default, there is no graphic during the launching process. To activate it, it is necessary to define the information of the graphics (the X, Y and Z attributes, the selection and the options of the graphic). The method's parameters are:str: the list of attributes to be drawn;select: the selection of patterns to visualise (default value is "");opt: the option of the graphics. Default value is "". To see all available values, please refer to the ROOT THistPainter reference page.
mylauncher.setVarDraw("hu:hl") # draw hu function of hl mylauncher.setVarDraw("hu:hl", "yhat>0") # same for data where yhat>0 mylauncher.setVarDraw("hu:hl", "yhat>0", "SURF") # same drawn as surface plotsetDrawProgressBar(bool): activate and draw the progress bar that gives an idea of the remaining time before finishing the loop. The default is to have this bar drawn, so this method is usually only used when one decides not to displays the progress bar (if the output is redirected in an output file for instance).mylauncher.setDrawProgressBar() # draw the progress bar mylauncher.setDrawProgressBar(False) # do not draw the progress bar draw = mylauncher.getDrawProgressBar() # check if progress bar is drawnAfter all the Launcher elements are set, it is then possible to launch it, by using the
runmethod.mylauncher.run()
We present below an example that uses the different methods described above:
tds = DataServer.TDataServer("tdsFlowrate", "DataBase flowrate")
# (add data to the TDataServer)
mycode = Launcher.TCode(tds, "command")
mylauncher = Launcher.TLauncher(tds, mycode)
mylauncher.setSave()
mylauncher.setClean()
mylauncher.setVarDraw("hu:hl", "yhat>0", "")
mylauncher.setWorkingDirectory(ROOT.gSystem.pwd() + "/tmpLanceurUranie/flowrate")
mylauncher.run()





