Documentation / User's manual in Python :
The idea of this section is to show the basic usage of many of the classes defined in Chapter VIII, applied either on the flowrate
functions or the flowrate code,
whose purpose and behaviour have been already introduced in Section IV.1.2.1. All the following examples will load a tiny set of points which
is gathered in the file called flowrateUniformDesign.dat
(already introduced in Section XIV.3.4.1).
The goal of this macro is to show how to handle (in the most simple way) a C++-written function, compliant with the
ROOT (CINT) format. This function has been presented, at least its equation (see Equation IV.1) and would be interfaced through the TCIntEval
class in
the Relauncher module (which means that we'll use the function database from ROOT's catalog, see Section I.2.5 for more explanations). As this class is usually considered not thread-safe, it
can only be used with a TSequentialRun
runner.
"""
Example of function launching in sequential mode
"""
from rootlogon import ROOT, DataServer, Relauncher
# Create the DataServer.TDataServer
tds = DataServer.TDataServer("foo", "test")
tds.fileDataRead("flowrateUniformDesign.dat")
# Get the attributes
rw = tds.getAttribute("rw")
r = tds.getAttribute("r")
tu = tds.getAttribute("tu")
tl = tds.getAttribute("tl")
hu = tds.getAttribute("hu")
hl = tds.getAttribute("hl")
lvar = tds.getAttribute("l")
kw = tds.getAttribute("kw")
# Create the output attribute
yhat = DataServer.TAttribute("yhat")
# Constructing the code
ROOT.gROOT.LoadMacro("UserFunctions.C")
mycode = Relauncher.TCIntEval("flowrateModel")
mycode.addInput(rw)
mycode.addInput(r)
mycode.addInput(tu)
mycode.addInput(tl)
mycode.addInput(hu)
mycode.addInput(hl)
mycode.addInput(lvar)
mycode.addInput(kw)
mycode.addOutput(yhat) # Adding the output attributes
# Create the sequential runner
run = Relauncher.TSequentialRun(mycode)
run.startSlave() # Start the master (necessary even for a sequential)
if run.onMaster():
lanceur = Relauncher.TLauncher2(tds, run)
# resolution
lanceur.solverLoop()
run.stopSlave() # Stop the slaves (necessary even for a sequential)
# Draw the result
can = ROOT.TCanvas("pouet", "foo", 1)
tds.Draw("yhat:rw", "", "colZ")
The first part of the macro is the definition of the flowrateModel
function, already
discussed throughout this documentation. The dataserver object is then created and filled using the database file
and pointers to the corresponding input attributes are created, along with the new attribute for the output
provided by the function. The following part is then specific to the Relauncher organisation: a
TCIntEval
object is created with the function as only argument. Both the input and output
attributes are provided (here in a contracted way for input, but it could have been done one-by-one, as for
output).
## Constructing the code
TCIntEval mycode(flowrateModel);
mycode.addInput(rw)
...
mycode.addInput(kw); ## Adding the input attributes
mycode.addOutput(yhat); ## Adding the output attributes
The methods setInputs
and setOutputs
are not allowed in python, so attributes has to be added one-by-one.
The following part is the heart of the relauncher strategy: the assessor is provided to the chosen runner, which should always start the slaves (even in the case of a sequential one like here). On the main CPU, the master is created as well (with the dataserver and the runner) and the resolution is requested.
# Create the sequential runner
run=Relauncher.TSequentialRun(mycode);
run.startSlave(); #Start the master (necessary even for a sequential)
if run.onMaster() :
lanceur=Relauncher.TLauncher2(tds, run);
# resolution
lanceur.solverLoop();
run.stopSlave(); # Stop the slaves (necessary even for a sequential)
pass
Once this is done, the slaves are stopped and the results is displayed for cross-check in the following subsection.
The goal of this macro is to show how to handle the Python-written function in a full python-script. This function
has been presented, at least its equation (see Equation IV.1) and would be
interface through the TPythonEval
class in the Relauncher module.
#!/usr/bin/env python
from ROOT import TCanvas, URANIE
import math
def flowrateModel(drw, dr, dtu, dtl, dhu, dhl, dl, dkw):
dnum = 2.0 * math.pi * dtu * ( dhu - dhl);
dlnronrw = math.log( dr / drw);
dden = dlnronrw * ( 1.0 + ( 2.0 * dl * dtu ) / ( dlnronrw * drw * drw * dkw) + dtu / dtl );
return [dnum / dden,]
# Create the TDataServer
tds = URANIE.DataServer.TDataServer("foo","test");
tds.fileDataRead("flowrateUniformDesign.dat");
# Get the attributes
rw = tds.getAttribute("rw");
r = tds.getAttribute("r");
tu = tds.getAttribute("tu");
tl = tds.getAttribute("tl");
hu = tds.getAttribute("hu");
hl = tds.getAttribute("hl");
l = tds.getAttribute("l");
kw = tds.getAttribute("kw");
# Create the output attribute
yhat = URANIE.DataServer.TAttribute("yhat");
# Constructing the code
mycode = URANIE.Relauncher.TPythonEval(flowrateModel);
# Adding the input file
mycode.addInput(rw);
mycode.addInput(r);
mycode.addInput(tu);
mycode.addInput(tl);
mycode.addInput(hu);
mycode.addInput(hl);
mycode.addInput(l);
mycode.addInput(kw);
# Adding the output file
mycode.addOutput(yhat);
# Create the sequential runner
run = URANIE.Relauncher.TSequentialRun(mycode);
run.startSlave(); # Start the master (necessary even for a sequential)
if run.onMaster() :
launch = URANIE.Relauncher.TLauncher2(tds, run);
# resolution
launch.solverLoop();
run.stopSlave(); # Stop the slaves (necessary even for a sequential)
pass
#Export the Data
tds.exportData("_outputFile_functionflowrate_python_.dat");
Obviously the code is now different from the other macros already introduced, but unless some python-specificity,
the discussion has been largely done in Section XIV.9.1.2.
The first interesting part is the definition of the function flowrateModel
. It is a
classical python-function, for which every input is either a double, a list (for vectors) or a string. Disregarding
the inner part, where the computation is done, the other interesting part is the return line: it should always be a
list of all the objects that should be returned.
def flowrateModel(drw, dr, dtu, dtl, dhu, dhl, dl, dkw):
dnum = 2.0 * math.pi * dtu * ( dhu - dhl);
dlnronrw = math.log( dr / drw);
dden = dlnronrw * ( 1.0 + ( 2.0 * dl * dtu ) / ( dlnronrw * drw * drw * dkw) + dtu / dtl );
return [dnum / dden,]
Apart from this, the only other difference is the assessor construction which is an instance of the
TPythonEval
class as shown here:
# Constructing the code
mycode = URANIE.Relauncher.TPythonEval(flowrateModel);
The macro is also leading to the creation of the following plot.
The goal of this macro is to show how to handle a code with a sequential runner. The flowrate
code is
provided with Uranie and has been also used and discussed throughout these macros.
"""
Example of code launching in sequential mode
"""
from rootlogon import ROOT, DataServer, Relauncher
# Create the DataServer.TDataServer
tds = DataServer.TDataServer("foo", "test")
tds.fileDataRead("flowrateUniformDesign.dat")
# Get the attributes
rw = tds.getAttribute("rw")
r = tds.getAttribute("r")
tu = tds.getAttribute("tu")
tl = tds.getAttribute("tl")
hu = tds.getAttribute("hu")
hl = tds.getAttribute("hl")
lvar = tds.getAttribute("l")
kw = tds.getAttribute("kw")
# Create the output attribute
yhat = DataServer.TAttribute("yhat")
d = DataServer.TAttribute("d")
# Set the reference input file and the key for each input attributes
fin = Relauncher.TFlatScript("flowrate_input_with_values_rows.in")
fin.addInput(rw)
fin.addInput(r)
fin.addInput(tu)
fin.addInput(tl)
fin.addInput(hu)
fin.addInput(hl)
fin.addInput(lvar)
fin.addInput(kw)
# The output file of the code
fout = Relauncher.TFlatResult("_output_flowrate_withRow_.dat")
fout.addOutput(yhat)
fout.addOutput(d) # Passing the attributes to the output file
# Constructing the code
mycode = Relauncher.TCodeEval("flowrate -s -r")
mycode.setOldTmpDir()
mycode.addInputFile(fin) # Adding the input file
mycode.addOutputFile(fout) # Adding the output file
# Create the sequential runner
run = Relauncher.TSequentialRun(mycode)
run.startSlave() # Start the master (necessary even for a sequential)
if run.onMaster():
lanceur = Relauncher.TLauncher2(tds, run)
# resolution
lanceur.solverLoop()
run.stopSlave() # Stop the slaves (necessary even for a sequential)
# Draw the result
can = ROOT.TCanvas("pouet", "foo", 1)
tds.Draw("yhat:rw", "", "colZ")
Here again, a comparison is drawn with the first Relauncher macro (see Section XIV.9.1.2) and only the differences are pointed out. The first obvious one, in the very first steps in defining the dataserver and the attributes, is that there are two output attributes. The second one (called 'd') will not be used here. The second (and only other difference) with respect to the CINT function code, is the assessor creation shown below:
## Set the reference input file and the key for each input attributes
TFlatScript fin("flowrate_input_with_values_rows.in");
fin.setInputs(8, rw, r, tu, tl, hu, hl, l, kw);
## The output file of the code
TFlatResult fout("_output_flowrate_withRow_.dat");
fout.setOutputs(2, yhat, d);## Passing the attributes to the output file
## Constructing the code
TCodeEval mycode( "flowrate -s -r" );
mycode.setOldTmpDir();
mycode.addInputFile(&fin); ## Adding the input file
mycode.addOutputFile(&fout); ## Adding the output file
The first three lines create the input file instance. It is here a TFlatScript
object which
can basically be compared to a DataServer (or Salome-table) format of the Launcher module for its organisation
(particularly with vectors and strings) but without the compulsory header: the order in which you introduce the
attribute is then of uttermost importance. The second block of lines is creating the output file object from the
TFlatResult
class (the same remark applies to this object).
Finally the assessor itself is created as an instance of the TCodeEval
class. The only
argument is the command to be run, and it needs at least one input and output file. Apart from that, the runner is
created and the rest is crystal clear, leading to the following plot.
The goal of this macro is to show how to set one of the evaluator's input attribute to a constant value, with a
sequential runner. The flowrate
code is provided with Uranie and has been also used and discussed
throughout these macros.
"""
Example of code launching in sequential mode with constant variable
"""
from rootlogon import DataServer, Relauncher, Sampler
# Create the TDataServer
tds = DataServer.TDataServer("foo", "test")
# Define the attribute that should be considered as constant
r = DataServer.TAttribute("r")
# Add the study attributes (min, max and nominal values)
tds.addAttribute(DataServer.TUniformDistribution("rw", 0.05, 0.15))
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
sIn = "flowrate_input_with_keys.in"
nS = 15
# Generate the Design of Experiments
sampling = Sampler.TSampling(tds, "lhs", nS)
sampling.generateSample()
# Create the input files
inputFile = Relauncher.TKeyScript(sIn)
inputFile.addInput(tds.getAttribute("rw"), "Rw")
inputFile.addInput(r, "R") # Add the constant attribute as an input
inputFile.addInput(tds.getAttribute("tu"), "Tu")
inputFile.addInput(tds.getAttribute("tl"), "Tl")
inputFile.addInput(tds.getAttribute("hu"), "Hu")
inputFile.addInput(tds.getAttribute("hl"), "Hl")
inputFile.addInput(tds.getAttribute("l"), "L")
inputFile.addInput(tds.getAttribute("kw"), "Kw")
# Create the output attribute
yhat = DataServer.TAttribute("yhat")
d = DataServer.TAttribute("d")
# Create the output files
outputFile = Relauncher.TKeyResult("_output_flowrate_withKey_.dat")
outputFile.addOutput(yhat, "yhat")
outputFile.addOutput(d, "d")
# Create the user's evaluation function
myeval = Relauncher.TCodeEval("flowrate -s -k")
myeval.addInputFile(inputFile)
myeval.addOutputFile(outputFile)
# Create the sequential runner
run = Relauncher.TSequentialRun(myeval)
run.startSlave() # Start the master (necessary even for a sequential)
if run.onMaster():
lanceur = Relauncher.TLauncher2(tds, run)
# State to the master : r is constant with value 108
# By default the value is not kept in the tds.
# The third argument says : yes, keep it for bookkeeping
lanceur.addConstantValue(r, 108, True)
# resolution
lanceur.solverLoop()
run.stopSlave() # Stop the slaves (necessary even for a sequential)
tds.scan("*")
Here again, a comparison is drawn with the first Relauncher macro (see Section XIV.9.3.2) and only the differences are pointed out. The first obvious one, in the very first steps in defining the dataserver and the attributes, is that instead of reading a database-file, we are generating a design-of-experiments with one big specificity: all the input attributes are properly defined, but r.
## Define the attribute that should be considered as constant
r = DataServer.TAttribute("r");
## Add the study attributes ( min, max and nominal values)
tds.addAttribute( DataServer.TUniformDistribution("rw", 0.05, 0.15));
tds.addAttribute( DataServer.TUniformDistribution("tu", 63070.0, 115600.0));
## ....
A simple design-of-experiments is generated and all the input attributes are provided to the input file of the assessor, event the constant one r.
## Create the input files
inputFile = Relauncher.TKeyScript( sIn );
inputFile.addInput(tds.getAttribute("rw"),"Rw");
inputFile.addInput(r,"R"); ## Add the constant attribute as an input
inputFile.addInput(tds.getAttribute("tu"),"Tu");
##...
The rest is fairly common, up to the TMaster
-inheriting object specification: the
addConstantValue
method is called to specify that r is
about to be constant for all ongoing estimation, and it provides it value. The last argument states that the value
under consideration should be stored in the ntuple of the dataserver object, as shown in the next section (from the
scan
method).
lanceur = Relauncher.TLauncher2(tds, run);
## State to the master : r is constant with value 108
## By default the value is not kept in the tds.
## The third argument says : yes, keep it for bookkeeping
lanceur.addConstantValue(r,108,True);
*************************************************************************************************************** * Row * foo__n * rw.rw * tu.tu * tl.tl * hu.hu * hl.hl * l.l * kw.kw * yhat.y * d.d * r.r * *************************************************************************************************************** * 0 * 0 * 0.1495 * 111790 * 73.820 * 990.90 * 779.83 * 1474.3 * 11220. * 112.01 * 3588.9 * 108 * * 1 * 1 * 0.1394 * 104140 * 95.150 * 1101.5 * 707.21 * 1422.7 * 11493. * 193.62 * 6597.5 * 108 * * 2 * 2 * 0.0557 * 95387. * 84.809 * 1056.2 * 752.94 * 1184.6 * 11967. * 29.880 * 330.58 * 108 * * 3 * 3 * 0.0836 * 74144. * 103.17 * 1051.6 * 819.27 * 1587.4 * 11031. * 35.400 * 2431.1 * 108 * * 4 * 4 * 0.0586 * 65396. * 72.161 * 1003.1 * 710.34 * 1327.5 * 10484. * 24.990 * 5757 * 108 * * 5 * 5 * 0.1203 * 92149. * 65.263 * 1031.6 * 797.34 * 1265.5 * 11638. * 97.386 * 1084.8 * 108 * * 6 * 6 * 0.1319 * 67464. * 93.378 * 1039.4 * 722.54 * 1514.3 * 10996. * 125.33 * 2362.4 * 108 * * 7 * 7 * 0.1059 * 80448. * 112.87 * 1027.1 * 794.32 * 1555.4 * 11846 * 62.403 * 1116.3 * 108 * * 8 * 8 * 0.0784 * 100260 * 105.79 * 1072.7 * 767.70 * 1304.1 * 10152. * 45.867 * 521.41 * 108 * * 9 * 9 * 0.0697 * 105158 * 82.544 * 1020.4 * 726.05 * 1640.3 * 10380. * 28.412 * 2802.5 * 108 * * 10 * 10 * 0.1252 * 89522. * 100.65 * 1006.2 * 742.35 * 1123.9 * 10743. * 123.70 * 2676.1 * 108 * * 11 * 11 * 0.1165 * 73139. * 69.083 * 1108.5 * 809.59 * 1199.0 * 10620. * 112.27 * 4991.3 * 108 * * 12 * 12 * 0.0992 * 86004. * 112.12 * 1069.4 * 763.84 * 1345.2 * 9951.0 * 69.808 * 414.71 * 108 * * 13 * 13 * 0.0718 * 113775 * 90.580 * 1079.1 * 782.95 * 1416.6 * 10076. * 34.135 * 1016.8 * 108 * * 14 * 14 * 0.0902 * 83779. * 80.244 * 1090.6 * 734.33 * 1644.2 * 11443 * 63.236 * 2922.3 * 108 * ***************************************************************************************************************
The goal of this macro is to show how to handle a code run on several threads. In order to this, the usual
sequential runner will be removed and another runner will be called to do the job. The flowrate
code
is provided with Uranie and has been also used and discussed throughout these macros.
"""
Example of code launching in threaded mode
"""
from rootlogon import ROOT, DataServer, Relauncher
# Create input attributes
rw = DataServer.TAttribute("rw")
r = DataServer.TAttribute("r")
tu = DataServer.TAttribute("tu")
tl = DataServer.TAttribute("tl")
hu = DataServer.TAttribute("hu")
hl = DataServer.TAttribute("hl")
lvar = DataServer.TAttribute("l")
kw = DataServer.TAttribute("kw")
# Create the output attribute
yhat = DataServer.TAttribute("yhat")
d = DataServer.TAttribute("d")
# Set the reference input file and the key for each input attributes
fin = Relauncher.TFlatScript("flowrate_input_with_values_rows.in")
fin.addInput(rw)
fin.addInput(r)
fin.addInput(tu)
fin.addInput(tl)
fin.addInput(hu)
fin.addInput(hl)
fin.addInput(lvar)
fin.addInput(kw)
# The output file of the code
fout = Relauncher.TFlatResult("_output_flowrate_withRow_.dat")
fout.addOutput(yhat)
fout.addOutput(d) # Passing the attributes to the output file
# Constructing the code
mycode = Relauncher.TCodeEval("flowrate -s -r")
mycode.setOldTmpDir()
mycode.addInputFile(fin) # Adding the input file
mycode.addOutputFile(fout) # Adding the output file
# Fix the number of threads
nthread = 3
# Create the Threaded runner
run = Relauncher.TThreadedRun(mycode, nthread)
run.startSlave() # Start the master
if run.onMaster():
# Define the DataServer
tds = DataServer.TDataServer("tdsflowrate", "Design of Experiments")
mycode.addAllInputs(tds)
tds.fileDataRead("flowrateUniformDesign.dat", False, True)
lanceur = Relauncher.TLauncher2(tds, run)
# resolution
lanceur.solverLoop()
run.stopSlave() # Stop the slaves (necessary even for a sequential)
# Draw the result
can = ROOT.TCanvas("pouet", "foo", 1)
tds.Draw("yhat:rw", "", "colZ")
The only difference when comparing this macro to the previous one (see Section XIV.9.3.2) is the runner creation:
## Fix the number of threads
int nthread = 3;
## Create the Threaded runner
TThreadedRun run(&mycode, nthread);
The TSequentialRun
object becomes a TThreadedRun
object whose
construction request on top of the assessor, the number of threads to be used. Apart from that, the master is
created and the rest is crystal clear, leading to the following plot.
The goal of this macro is to show how to handle a code run on several threads with another memory paradigm:
when the TThreadedRun
instance is relying on shared memory (leading to possible thread-safe
problem, as discussed in Section VIII.4.2), the MPI implementation is based on the separation of
the memory. The communication is made through messages. In order to this, the usual sequential runner will be
removed and another runner will be called to do the job. The flowrate
code is provided with Uranie
and has been also used and discussed throughout these macros.
"""
Example of MPi usage for code launching
"""
from rootlogon import ROOT, DataServer, Relauncher, MpiRelauncher
# Create input attributes
rw = DataServer.TAttribute("rw")
r = DataServer.TAttribute("r")
tu = DataServer.TAttribute("tu")
tl = DataServer.TAttribute("tl")
hu = DataServer.TAttribute("hu")
hl = DataServer.TAttribute("hl")
lvar = DataServer.TAttribute("l")
kw = DataServer.TAttribute("kw")
# Create the output attribute
yhat = DataServer.TAttribute("yhat")
d = DataServer.TAttribute("d")
# Set the reference input file and the key for each input attributes
fin = Relauncher.TFlatScript("flowrate_input_with_values_rows.in")
fin.addInput(rw)
fin.addInput(r)
fin.addInput(tu)
fin.addInput(tl)
fin.addInput(hu)
fin.addInput(hl)
fin.addInput(lvar)
fin.addInput(kw)
# The output file of the code
fout = Relauncher.TFlatResult("_output_flowrate_withRow_.dat")
fout.addOutput(yhat)
fout.addOutput(d) # Passing the attributes to the output file
# Instanciation de mon code
mycode = Relauncher.TCodeEval("flowrate -s -r")
# mycode.setOldTmpDir()
mycode.addInputFile(fin)
mycode.addOutputFile(fout)
# Create the MPI runner
run = MpiRelauncher.TMpiRun(mycode)
run.startSlave()
if run.onMaster():
# Define the DataServer
tds = DataServer.TDataServer("tdsflowrate",
"Design of Experiments for Flowrate")
mycode.addAllInputs(tds)
tds.fileDataRead("flowrateUniformDesign.dat", False, True)
lanceur = Relauncher.TLauncher2(tds, run)
# resolution
lanceur.solverLoop()
tds.exportData("_output_testFlowrateMPI_py_.dat")
ROOT.SetOwnership(run, True)
run.stopSlave()
Here the first difference when comparing this macro to the previous one (see Section XIV.9.5.2) is the runner creation:
## Create the MPI runner
run = MpiRelauncher.TMpiRun(mycode);
The TThreadedRun
object becomes a TMpiRun
object whose construction
only requests a pointer to the assessor. Another line is different as it is specific to the language: because of
the way ROOT and python deal with object destruction (though the garbage collector approach for the latter),
there is problem in the way one of the main key method for MPI treatment MPI_Finalize
is
called. To prevent this from happening in python the following line should be added as soon as the runner object is
created:
ROOT.SetOwnership(run, True)
It allows ROOT to destroy the object injected, calling the finalize method in order for every slave to be properly released. Apart from that, the code is very similar, the only difference being the way to call this macro. It should not be run with the usual command:
python relauncherCodeFlowrateMPI.py
Instead, the command line should start with the mpirun
command as such:
mpirun -np N python relauncherCodeFlowrateMPI.py
where the N part should be replaced by the number of requested threads. Once run, this macro
also leads to the following plots. Beware never to use the -i
argument with the python command line as
the macro would never end.
The goal of this macro is to show how to handle when a code is returning an error status. Up to version v4.5.0, the
input configuration was simply discarded while from any version now, there are discarded but they can be retrieved
and store in a dedicated TDataServer
object. The code used here is the usual
flowrate
model which has been modified to return a non zero exit status without producing
an output file.
"""
Example of code launching in sequential mode with failure
"""
from rootlogon import ROOT, DataServer, Relauncher
# Create the DataServer.TDataServer
tds = DataServer.TDataServer("foo", "test")
tds.fileDataRead("flowrateUniformDesign.dat")
# Get the attributes
rw = tds.getAttribute("rw")
r = tds.getAttribute("r")
tu = tds.getAttribute("tu")
tl = tds.getAttribute("tl")
hu = tds.getAttribute("hu")
hl = tds.getAttribute("hl")
lvar = tds.getAttribute("l")
kw = tds.getAttribute("kw")
# Create the output attribute
yhat = DataServer.TAttribute("yhat")
d = DataServer.TAttribute("d")
# Set the reference input file and the key for each input attributes
fin = Relauncher.TFlatScript("flowrate_input_with_values_rows.in")
fin.addInput(rw)
fin.addInput(r)
fin.addInput(tu)
fin.addInput(tl)
fin.addInput(hu)
fin.addInput(hl)
fin.addInput(lvar)
fin.addInput(kw)
# The output file of the code
fout = Relauncher.TFlatResult("_output_flowrate_withRow_.dat")
fout.addOutput(yhat) # Passing the attributes to the output file
fout.addOutput(d) # Passing the attributes to the output file
# Constructing the code
mycode = Relauncher.TCodeEval("flowrate -s -rf")
mycode.addInputFile(fin) # Adding the input file
mycode.addOutputFile(fout) # Adding the output file
# Create the sequential runner
run = Relauncher.TSequentialRun(mycode)
run.startSlave() # Start the master (necessary even for a sequential)
if run.onMaster():
lanceur = Relauncher.TLauncher2(tds, run)
# Store the wrong calculation
error = DataServer.TDataServer("WrongComputations", "pouet")
lanceur.setSaveError(error)
# resolution
lanceur.solverLoop()
run.stopSlave() # Stop the slaves (necessary even for a sequential)
# dump all wrong configurations
error.getTuple().SetScanField(-1)
error.scan("*")
# Draw the result
can = ROOT.TCanvas("pouet", "foo", 1)
tds.Draw("hu:hl")
Here there are very few differences with the one already introduced in Section XIV.9.3.2. The first one is obviously the command line which is called using
"-rf"
argument, the f being introduced for failure.
mycode=Relauncher.TCodeEval( "flowrate -s -rf" )
The second difference is the creation of the failure dataserver object in which all wrong configurations will be
stored. Once created, it is simply passed to the launcher object through the dedicated method
setSaveError
:
# Store the wrong calculation
error=DataServer.TDataServer("WrongComputations","pouet")
lanceur.setSaveError(error)
Once done the code is run and two things are looked at: the fact that in a peculiar area of the input space there
are no data anymore (by construction, as shown in Figure XIV.88) and the fact that all configurations are now stored in a
dedicated TDataServer
object which one can dump on screen with the command line below to
obtain the second part of the console output seen in Section XIV.9.7.4
# dump all wrong configurations
error.getTuple().SetScanField(-1)
error.scan("*")
The first part of the console output shown in Section XIV.9.7.4 is a perfect illustration of the way the relauncher module is discussion failure: the first part is stating that a non-zero return value has been detected
Command cd ${RUNNINGDIR}/URA_XXXXXX ; flowrate -s -rf has returned non-zero exit code (255). If any different from 127 (usually for unknown command) and 139 (usually for SIGSEV), the exit code meaning is "command" dependent.
The second part is letting the user know that no output file has been found (a second reason to consider this configuration as a failure).
Cannot open :: ${RUNNINGDIR}/URA_XXXXXX/_output_flowrate_withRow_.dat
This pattern is repeated every time a configuration is wrong.
Processing relauncherCodeFlowrateSequentialFailure.py... --- Uranie v0.0/0 --- Developed with ROOT (6.32.02) Copyright (C) 2013-2024 CEA/DES Contact: support-uranie@cea.fr Date: Tue Jan 09, 2024 Command cd ${RUNNINGDIR}/URA_XXXXXX ; flowrate -s -rf has returned non-zero exit code (255). If any different from 127 (usually for unknown command) and 139 (usually for SIGSEV), the exit code meaning is "command" dependent. Cannot open :: ${RUNNINGDIR}/URA_XXXXXX/_output_flowrate_withRow_.dat Command cd ${RUNNINGDIR}/URA_XXXXXX ; flowrate -s -rf has returned non-zero exit code (255). If any different from 127 (usually for unknown command) and 139 (usually for SIGSEV), the exit code meaning is "command" dependent. Cannot open :: ${RUNNINGDIR}/URA_XXXXXX/_output_flowrate_withRow_.dat Command cd ${RUNNINGDIR}/URA_XXXXXX ; flowrate -s -rf has returned non-zero exit code (255). If any different from 127 (usually for unknown command) and 139 (usually for SIGSEV), the exit code meaning is "command" dependent. Cannot open :: ${RUNNINGDIR}/URA_XXXXXX/_output_flowrate_withRow_.dat Command cd ${RUNNINGDIR}/URA_XXXXXX ; flowrate -s -rf has returned non-zero exit code (255). If any different from 127 (usually for unknown command) and 139 (usually for SIGSEV), the exit code meaning is "command" dependent. Cannot open :: ${RUNNINGDIR}/URA_XXXXXX/_output_flowrate_withRow_.dat Command cd ${RUNNINGDIR}/URA_XXXXXX ; flowrate -s -rf has returned non-zero exit code (255). If any different from 127 (usually for unknown command) and 139 (usually for SIGSEV), the exit code meaning is "command" dependent. Cannot open :: ${RUNNINGDIR}/URA_XXXXXX/_output_flowrate_withRow_.dat ************************************************************************************************************************************ * Row * WrongComp * rw.rw * r.r * tu.tu * tl.tl * hu.hu * hl.hl * l.l * kw.kw * ystar.yst * ************************************************************************************************************************************ * 0 * 4 * 0.0633 * 100 * 115600 * 80.73 * 1075.71 * 751.43 * 1600 * 11106.43 * 28.33 * * 1 * 5 * 0.0633 * 16733.33 * 80580 * 80.73 * 1058.57 * 785.71 * 1680 * 12045 * 24.6 * * 2 * 8 * 0.0767 * 100 * 115600 * 80.73 * 1075.71 * 751.43 * 1520 * 10793.57 * 42.44 * * 3 * 12 * 0.09 * 16733.33 * 63070 * 116 * 1075.71 * 751.43 * 1120 * 11419.29 * 83.77 * * 4 * 23 * 0.1233 * 16733.33 * 63070 * 63.1 * 1041.43 * 785.71 * 1680 * 12045 * 86.73 * ************************************************************************************************************************************
The objective of this macro is to test the case where vectors and strings are produced as outputs, using the code described in Section XIV.5.22.1, with a Key format, obtained by doing:
multitype -mtKey
The resulting output file, named _output_multitype_mt_Key_.dat
looks like:
w1 = nine v1 = -0.512095 v1 = 0.039669 v1 = -1.3834 v1 = 1.37667 v1 = 0.220672 v1 = 0.633267 v1 = 1.37027 v1 = -0.765636 v2 = 14.1981 v2 = 14.0855 v2 = 10.7848 v2 = 9.45476 v2 = 9.17308 v2 = 6.60804 v2 = 10.0711 v2 = 14.1761 v2 = 10.318 v2 = 12.5095 v2 = 15.6614 v2 = 10.3452 v2 = 9.41101 v2 = 7.47887 f1 = 32.2723 w2 = eight
"""
Example of multitype code launching
"""
from rootlogon import ROOT, DataServer, Relauncher, Sampler
# Create the DataServer.TDataServer and create the seed attribute
tds = DataServer.TDataServer("foo", "multitype usecase")
tds.addAttribute(DataServer.TUniformDistribution("seed", 0, 100000))
# Create DOE
tsam = Sampler.TSampling(tds, "lhs", 100)
tsam.generateSample()
# Create output attribute pointers
w1 = DataServer.TAttribute("w1", DataServer.TAttribute.kString)
w2 = DataServer.TAttribute("w2", DataServer.TAttribute.kString)
v1 = DataServer.TAttribute("v1", DataServer.TAttribute.kVector)
v2 = DataServer.TAttribute("v2", DataServer.TAttribute.kVector)
f1 = DataServer.TAttribute("f1")
# Create the input files
inputFile = Relauncher.TFlatScript("multitype_input.dat")
inputFile.addInput(tds.getAttribute("seed"))
# Create the output files
outputFile = Relauncher.TKeyResult("_output_multitype_mt_Key_.dat")
outputFile.addOutput(w1, "w1")
outputFile.addOutput(v1, "v1")
outputFile.addOutput(v2, "v2")
outputFile.addOutput(f1, "f1")
outputFile.addOutput(w2, "w2")
# Create the user's evaluation function
myeval = Relauncher.TCodeEval("multitype -mtKey")
myeval.addInputFile(inputFile) # Add the input file
myeval.addOutputFile(outputFile) # Add the output file
# Create the runner
runner = Relauncher.TSequentialRun(myeval)
# Start the slaves
runner.startSlave()
if runner.onMaster():
# Create the launcher
lanceur = Relauncher.TLauncher2(tds, runner)
lanceur.solverLoop()
# Stop the slave processes
runner.stopSlave()
# Produce control plot
Can = ROOT.TCanvas("Can", "Can", 10, 10, 1000, 800)
pad = ROOT.TPad("pad", "pad", 0, 0.03, 1, 1)
pad.Draw()
pad.cd()
tds.drawPairs("w1:v1:v2:f1:w2")
The beginning of the code is pretty common to many other macros: creating a dataserver and input attributes (here the only one is the seed, needed for the random generator to produce vectors and strings). A sampling object is created as well to produce a 100-points design-of-experiments and the output attributes are created, as such:
## Create output attribute pointers
w1 = DataServer.TAttribute("w1", DataServer.TAttribute.kString);
w2 = DataServer.TAttribute("w2", DataServer.TAttribute.kString);
v1 = DataServer.TAttribute("v1", DataServer.TAttribute.kVector);
v2 = DataServer.TAttribute("v2", DataServer.TAttribute.kVector);
f1 = DataServer.TAttribute("f1");
This is where the specificity of the vector and string is precised. It will be passed on to the rest of the code automatically. The rest is common to many relauncher job (for instance Section XIV.9.3) with the only difference being that the output file is a key type one. It results in the following plots.
The objective of this macro is to test the case where vectors and strings are produced as outputs, using the code described in Section XIV.5.22.1, with a Key format, obtained by doing:
multitype -mtKey -empty
Unlike what's done to in Section XIV.9.8, the "-empty"
allows the code to generate empty vectors and not only vectors whose size would be between 1 and 15 elements.
The resulting output file used is a key-format one in a condensate form, named
_output_multitype_mt_Key_condensate_.dat
looks like:
w1 = nine v1 = [ -0.512095,0.039669,-1.3834,1.37667,0.220672,0.633267,1.37027,-0.765636 ] v2 = [ 14.1981,14.0855,10.7848,9.45476,9.17308,6.60804,10.0711,14.1761,10.318,12.5095,15.6614,10.3452,9.41101,7.47887 ] f1 = 32.2723 w2 = eight
"""
Example of code launching for which empty vectors are possible
"""
from rootlogon import ROOT, DataServer, Relauncher, Sampler
# Create the DataServer.TDataServer and create the seed attribute
tds = DataServer.TDataServer("foo", "multitype usecase")
tds.addAttribute(DataServer.TUniformDistribution("seed", 0, 100000))
# Create DOE
tsam = Sampler.TSampling(tds, "lhs", 100)
tsam.generateSample()
# Create output attribute pointers
w1 = DataServer.TAttribute("w1", DataServer.TAttribute.kString)
w2 = DataServer.TAttribute("w2", DataServer.TAttribute.kString)
v1 = DataServer.TAttribute("v1", DataServer.TAttribute.kVector)
v2 = DataServer.TAttribute("v2", DataServer.TAttribute.kVector)
f1 = DataServer.TAttribute("f1")
# Create the input files
inputFile = Relauncher.TFlatScript("multitype_input.dat")
inputFile.addInput(tds.getAttribute("seed"))
# Create the output files
outputFile = Relauncher.TKeyResult("_output_multitype_mt_Key_condensate_.dat")
outputFile.addOutput(w1, "w1")
outputFile.addOutput(v1, "v1")
outputFile.addOutput(v2, "v2")
outputFile.addOutput(f1, "f1")
outputFile.addOutput(w2, "w2")
outputFile.setVectorProperties("[", ", ", "]")
# Create the user's evaluation function
myeval = Relauncher.TCodeEval("multitype -mtKey -empty")
myeval.addInputFile(inputFile) # Add the input file
myeval.addOutputFile(outputFile) # Add the output file
# Create the runner
runner = Relauncher.TSequentialRun(myeval)
# Start the slaves
runner.startSlave()
if runner.onMaster():
# Create the launcher
lanceur = Relauncher.TLauncher2(tds, runner)
lanceur.solverLoop()
# Stop the slave processes
runner.stopSlave()
# Produce control plot
Can = ROOT.TCanvas("Can", "Can", 10, 10, 1000, 800)
pad = ROOT.TPad("pad", "pad", 0, 0.03, 1, 1)
pad.Draw()
pad.Divide(1, 2)
pad.cd(1)
tds.getTuple().SetLineColor(2)
tds.getTuple().SetLineWidth(2)
tds.Draw("size__v1")
pad.cd(2)
tds.Draw("size__v2")
The beginning of the code is pretty common to the macro already discussed in Section XIV.9.8.2. Apart from the command difference discussed in the objective above through
the "-empty" argument, the main difference with previous macro is the way the output file is
declared. Despite from changing the name, the vector properties are set by calling the
setVectorProperties
method to emphasize how to read the information.
# Create the output files
outputFile=Relauncher.TKeyResult("_output_multitype_mt_Key_condensate_.dat")
outputFile.addOutput(w1, "w1")
outputFile.addOutput(v1, "v1")
outputFile.addOutput(v2, "v2")
outputFile.addOutput(f1, "f1")
outputFile.addOutput(w2, "w2")
outputFile.setVectorProperties("[",",","]")
Apart from this, the code is smooth and the final results one can be interested in the size of the vectors produced when empty vectors are allowed. This is produced though the following lines, and the resulting plots are shown in Figure XIV.90.
#Produce control plot
Can=ROOT.TCanvas("Can","Can",10,10,1000,800)
pad=ROOT.TPad("pad","pad",0, 0.03, 1, 1); pad.Draw(); pad.Divide(1,2)
pad.cd(1)
tds.getTuple().SetLineColor(2); tds.getTuple().SetLineWidth(2)
tds.Draw("size__v1")
pad.cd(2)
tds.Draw("size__v2")
If the output file was not properly formatted, then one can have issues with this specific case (empty vectors). The consequences are shown in Section XIV.9.10.
The objective of this macro is to test the case where vectors and strings are produced as outputs, using the code described in Section XIV.5.22.1, with a Key format, obtained by doing:
multitype -mtKey -empty
Unlike what's done to in Section XIV.9.8, the "-empty"
allows the code to generate empty vectors and not only vectors whose size would be between 1 and 15 elements.
The resulting output file used is a key-format in a very row form, meaning that evey new element of the vectors are
written as a new key-line. This file, named _output_multitype_mt_Key_.dat
could looks like this:
w1 = nine v1 = -0.512095 v1 = 0.039669 v1 = -1.3834 v1 = 1.37667 v1 = 0.220672 v1 = 0.633267 v1 = 1.37027 v1 = -0.765636 v2 = 14.1981 v2 = 14.0855 v2 = 10.7848 v2 = 9.45476 v2 = 9.17308 v2 = 6.60804 v2 = 10.0711 v2 = 14.1761 v2 = 10.318 v2 = 12.5095 v2 = 15.6614 v2 = 10.3452 v2 = 9.41101 v2 = 7.47887 f1 = 32.2723 w2 = eight
"""
Example of code launching with empy vectors as failure
"""
from rootlogon import ROOT, DataServer, Relauncher, Sampler
# Create the DataServer.TDataServer and create the seed attribute
tds = DataServer.TDataServer("foo", "multitype usecase")
tds.addAttribute(DataServer.TUniformDistribution("seed", 0, 100000))
# Create DOE
tsam = Sampler.TSampling(tds, "lhs", 100)
tsam.generateSample()
# Create output attribute pointers
w1 = DataServer.TAttribute("w1", DataServer.TAttribute.kString)
w2 = DataServer.TAttribute("w2", DataServer.TAttribute.kString)
v1 = DataServer.TAttribute("v1", DataServer.TAttribute.kVector)
v2 = DataServer.TAttribute("v2", DataServer.TAttribute.kVector)
f1 = DataServer.TAttribute("f1")
# Create the input files
inputFile = Relauncher.TFlatScript("multitype_input.dat")
inputFile.addInput(tds.getAttribute("seed"))
# Create the output files
outputFile = Relauncher.TKeyResult("_output_multitype_mt_Key_.dat")
outputFile.addOutput(w1, "w1")
outputFile.addOutput(v1, "v1")
outputFile.addOutput(v2, "v2")
outputFile.addOutput(f1, "f1")
outputFile.addOutput(w2, "w2")
# Create the user's evaluation function
myeval = Relauncher.TCodeEval("multitype -mtKey -empty")
myeval.addInputFile(inputFile) # Add the input file
myeval.addOutputFile(outputFile) # Add the output file
# Create the runner
runner = Relauncher.TSequentialRun(myeval)
# Start the slaves
runner.startSlave()
if runner.onMaster():
# Create the launcher
lanceur = Relauncher.TLauncher2(tds, runner)
# Store the wrong calculation
error = DataServer.TDataServer("WrongComputations", "pouet")
lanceur.setSaveError(error)
lanceur.solverLoop()
# dump all wrong configurations
error.getTuple().SetScanField(-1)
error.scan("*")
# Stop the slave processes
runner.stopSlave()
# Produce control plot
Can = ROOT.TCanvas("Can", "Can", 10, 10, 1000, 800)
pad = ROOT.TPad("pad", "pad", 0, 0.03, 1, 1)
pad.Draw()
pad.cd()
tds.drawPairs("w1:v1:v2:f1:w2")
The beginning of the code is pretty common to the macro already discussed in Section XIV.9.8.2. Apart from the command difference discussed in the objective above through the "-empty" argument, the main difference with previous macro is the failure dataserver declaration and the output console that would be discussed later-on. The former is done through the following lines:
# Store the wrong calculation
error=DataServer.TDataServer("WrongComputations","pouet")
lanceur.setSaveError(error)
Once the code is run, the configuration leading to empty vectors are gathered in the failure dataserver and dumped on screen through the following lines:
# dump all wrong configurations
error.getTuple().SetScanField(-1)
error.scan("*")
The final part is the way to represent the results: as for the use-case macro discussed in Section XIV.9.8, all data are plotted in a pair plot and this is summarised in Figure XIV.91. From this picture one should really pay attention to the number of entries to spot that some configuration are missing. Luckily when looking at the console in Section XIV.9.10.4. This time (unlike the failure in Section XIV.9.7) the code is returning a zero output status (because the code actually worked fine) but as from time to time one the two vectors is empty, no entry is written in the output whose format is too simple (as it consist only in dumping vector elements by elements) this is why the only message is the fact that, from time to time, one vector information is missing.
Processing relauncherMultiTypeKeyEmptyVectorsAsFailure.py... --- Uranie v0.0/0 --- Developed with ROOT (6.32.02) Copyright (C) 2013-2024 CEA/DES Contact: support-uranie@cea.fr Date: Tue Jan 09, 2024 TKeyResult(_output_multitype_mt_Key_.dat): v1 Not found TKeyResult(_output_multitype_mt_Key_.dat): v2 Not found TKeyResult(_output_multitype_mt_Key_.dat): v1 Not found TKeyResult(_output_multitype_mt_Key_.dat): v2 Not found TKeyResult(_output_multitype_mt_Key_.dat): v1 Not found TKeyResult(_output_multitype_mt_Key_.dat): v2 Not found TKeyResult(_output_multitype_mt_Key_.dat): v1 Not found TKeyResult(_output_multitype_mt_Key_.dat): v1 Not found TKeyResult(_output_multitype_mt_Key_.dat): v2 Not found TKeyResult(_output_multitype_mt_Key_.dat): v2 Not found TKeyResult(_output_multitype_mt_Key_.dat): v1 Not found TKeyResult(_output_multitype_mt_Key_.dat): v1 Not found TKeyResult(_output_multitype_mt_Key_.dat): v1 Not found TKeyResult(_output_multitype_mt_Key_.dat): v2 Not found ************************************ * Row * WrongComp * seed.seed * ************************************ * 0 * 9 * 93759.29 * * 1 * 33 * 74051.957 * * 2 * 35 * 71909.957 * * 3 * 50 * 4183.9188 * * 4 * 54 * 41806.234 * * 5 * 57 * 28298.703 * * 6 * 66 * 64903.722 * * 7 * 69 * 47690.947 * * 8 * 73 * 89415.222 * * 9 * 79 * 30656.411 * * 10 * 84 * 31627.094 * * 11 * 86 * 63698.481 * * 12 * 89 * 13461.926 * * 13 * 99 * 52994.014 * ************************************
The objective of this macro is to test the case where vectors and strings are used as inputs, using the code described in Section XIV.5.22.2, with a Key format, obtained by doing:
multitype -ReadmtKey
The input values will be read from a database which
is produced with the multitype -mt
code, as no sampling is available yet to produce vectors and
strings. The database file is readmultitype_sampling.dat
which looks like this:
#NAME: foo #TITLE: TDS for flowrate #DATE: Mon Oct 3 23:50:34 2016 #COLUMN_NAMES: v1| w1| v2| w2| f1| foo__n__iter__ #COLUMN_TYPES: V|S|V|S|D|D -6.901933299378e-02,-1.292435959913e-01,4.558876683004e-01,5.638486368789e-01,-4.767582766745e-02,7.102109543136e-03,2.819049677902e-01,-2.019788081790e+00,-2.604401028584e+00,-1.617682380292e+00,2.894560949798e-02,-3.493905850261e-01 six 1.142449011404e+01,7.318948216271e+00,1.502260859231e+01,6.041193793062e+00,6.729445145907e+00,1.128096968597e+01 zero 3.425632316777e+01 0.000000000000e+00 -6.923200061823e-01,-4.798721931875e-01,-1.329893204384e+00,1.292933726829e+00 zero 1.249911290435e+01,6.309239169117e+00,1.596653626442e+01,5.500878012739e+00,1.322535550082e+01,7.070984389647e+00,1.708574150702e+00,1.265915339220e+01 two 4.295175025115e+01 1.000000000000e+00 5.773813268848e-01,-3.512405673973e-01,-6.870089014992e-01,1.273074555211e-01 nine 1.242682578759e+01,1.109680842701e+01,1.670410641828e+01,7.296321908492e+00,8.732800753443e+00,1.262906549132e+01,8.882310687564e+00,1.104280818003e+01 five 5.591437936893e+01 2.000000000000e+00 5.518508915499e-01,2.438158138873e-01,1.111784497742e+00,-1.517566514667e+00,7.146879916125e-01,2.328439269321e+00,-1.251913839951e+00,8.876684186954e-01,-1.383023165632e+00,-8.192089693621e-01,-1.079524713568e-01,6.595650273375e-01,-2.275345802432e-03,1.304354557600e+00 nine 1.021975159505e+01,4.995433740783e+00,1.108628156181e+01,1.041110604995e+01,1.111365770153e+01,6.365695806343e+00,6.374053973239e+00,6.854423942510e+00,7.144262333164e+00 two 4.093776591421e+01 3.000000000000e+00 2.403942476958e-01,6.868091212609e-01,-1.561012830108e+00,1.937806684989e+00,-1.465851888061e+00,5.367279844359e-02,-1.263005327899e+00,-1.132259472701e+00 two 7.382048319627e+00,5.874867917970e+00,1.158191378461e+01,1.073321314846e+01 six 6.980549752305e+01 4.000000000000e+00 2.220485143391e+00,-5.787212569267e-01,8.843648237689e-01,2.020662891124e+00,1.066403357312e+00,-5.817432767992e-01,3.063023900800e-01,-7.393588637933e-01 two 2.049656723853e+00,9.679003878866e+00,7.338089623518e+00,1.235630702472e+01,1.509238505697e+01,1.034077492413e+01,1.116077550501e+01,7.179221834787e+00,1.582041236432e+01,9.204085091129e+00,4.707490792498e+00,1.618155764288e+01 five 3.507773555061e+01 5.000000000000e+00 8.908373817765e-01,-2.446355046704e-01,-1.900125532005e+00 seven 1.351254851860e+01,9.297087139459e+00,1.130966904782e+01,1.219245848701e+01,1.012996566249e+01,7.150071600452e+00,1.097549218518e+01,1.443074761657e+01 five 4.464560504112e+01 6.000000000000e+00 -2.514644600888e+00,1.633579305804e+00 one 1.229098312451e+01,1.013486836958e+01,1.243386772880e+01,1.071783135260e+01,1.453735777922e+01,7.995593455015e+00,9.753966962919e+00,5.924583770352e+00,6.187713988125e+00,1.061975242996e+01,6.650425922126e+00 four 4.553396475968e+01 7.000000000000e+00 -1.347811599520e+00,-1.259450135534e+00,1.812553405758e+00 five 7.717018655412e+00,1.053283796180e+01,7.404059210327e+00 eight 6.695868880279e+01 8.000000000000e+00 -1.258360863204e-01,-9.000566818602e-01,7.039146852797e-01,1.015917277706e+00,-2.397650482929e-01 four 4.346717386417e+00,1.033024889324e+01,7.183787459050e+00,8.742095837835e+00,1.277095440277e+01,8.685683828779e+00,9.321006265935e+00,6.353438157123e+00,8.552570119034e+00 six 4.381313066586e+01 9.000000000000e+00
For every pattern, an input file is created with the Key condensate format, as the other key format is not practical (and usable). This input file looks like this:
w1 = nine v1 = [ -0.512095,0.039669,-1.3834,1.37667,0.220672,0.633267,1.37027,-0.765636 ] v2 = [ 14.1981,14.0855,10.7848,9.45476,9.17308,6.60804,10.0711,14.1761,10.318,12.5095,15.6614,10.3452,9.41101,7.47887 ] f1 = 32.2723 w2 = eight
The resulting output file, named _output_multitype_readmt_Key_.dat
looks like:
thev1 = -0.2397650482929 thev2 = 9.321006265935
"""
Example of multitype code launching in sequential mode
"""
from rootlogon import DataServer, Relauncher
# inputs
tds = DataServer.TDataServer("foo", "TDS for flowrate")
tds.fileDataRead("readmultitype_sampling.dat")
# Input attribute
w1 = tds.getAttribute("w1")
w2 = tds.getAttribute("w2")
v1 = tds.getAttribute("v1")
v2 = tds.getAttribute("v2")
f1 = tds.getAttribute("f1")
# output attribute
thev1 = DataServer.TAttribute("thev1")
thev2 = DataServer.TAttribute("thev2")
# Create the output files
inputFile = Relauncher.TKeyScript("_output_multitype_mt_Key_condensate_.dat")
inputFile.addInput(w1, "w1")
inputFile.addInput(v1, "v1")
inputFile.addInput(v2, "v2")
inputFile.addInput(f1, "f1")
inputFile.addInput(w2, "w2")
# Create the output files
outputFile = Relauncher.TKeyResult("_output_multitype_readmt_Key_.dat")
outputFile.addOutput(thev1, "thev1")
outputFile.addOutput(thev2, "thev2")
# Create the user's evaluation function
myeval = Relauncher.TCodeEval("multitype -ReadmtKey")
myeval.addInputFile(inputFile)
myeval.addOutputFile(outputFile)
runner = Relauncher.TSequentialRun(myeval)
runner.startSlave()
if runner.onMaster():
# Create the launcher
lanceur = Relauncher.TLauncher2(tds, runner)
lanceur.solverLoop()
# Stop the slave processes
runner.stopSlave()
tds.Scan("thev1:thev2")
The code is pretty straightforward, the fact that input attributes are vectors and strings is explained in the input
file readmultitype_sampling.dat
.
One line is added to be sure that an example of input file is present (the file _output_multitype_mt_Key_condensate_.dat
)
by calling:
gSystem.Exec("multitype -mtKey");
The rest is very common and a screenshot of the result displayed in console is provided in the following subsection.
Processing relauncherCodeReadMultiType.py... ************************************ * Row * thev1 * thev2 * ************************************ * 0 * 0.2819049 * 11.424490 * * 1 * -0.692320 * 15.966536 * * 2 * -12345678 * 12.629065 * * 3 * -0.819208 * 11.086281 * * 4 * -1.561012 * -12345678 * * 5 * 0.8843648 * 10.340774 * * 6 * -12345678 * 7.1500716 * * 7 * 1.6335793 * 14.537357 * * 8 * -12345678 * -12345678 * * 9 * -0.239765 * 9.3210062 * ************************************
The objective of this macro is to to combine two different assessor in a chain, so that output attributes of the
first assessor is the input attributes of the second one. This example combined the multitype
code to
produce vectors and strings as outputs (as explained in Section XIV.5.22.1) and use these vectors and strings as inputs, using the
code described in Section XIV.5.22.2.
"""
Example of code composition with multitype code
"""
from rootlogon import DataServer, Relauncher
# inputs
tds = DataServer.TDataServer("foo", "TDS for flowrate")
tds.fileDataRead("multitype_sampling.dat")
# output attributes...
# ... for code 1
w1 = DataServer.TAttribute("w1", DataServer.TAttribute.kString)
w2 = DataServer.TAttribute("w2", DataServer.TAttribute.kString)
v1 = DataServer.TAttribute("v1", DataServer.TAttribute.kVector)
v2 = DataServer.TAttribute("v2", DataServer.TAttribute.kVector)
f1 = DataServer.TAttribute("f1")
# ... for code 2
thev1 = DataServer.TAttribute("thev1")
thev2 = DataServer.TAttribute("thev2")
# ==================================================================
# ========================== Code 1 ================================
# ==================================================================
# Create the input files
inputFile1 = Relauncher.TFlatScript("multitype_input.dat")
inputFile1.addInput(tds.getAttribute("seed"))
# Create the output files
outputFile1 = Relauncher.TKeyResult("_output_multitype_mt_Key_.dat")
outputFile1.addOutput(w1, "w1")
outputFile1.addOutput(v1, "v1")
outputFile1.addOutput(v2, "v2")
outputFile1.addOutput(f1, "f1")
outputFile1.addOutput(w2, "w2")
# Create the user's evaluation function
eval1 = Relauncher.TCodeEval("multitype -mtKey")
eval1.addInputFile(inputFile1)
eval1.addOutputFile(outputFile1)
# ==================================================================
# ========================== Code 2 ================================
# ==================================================================
# Create the output files
inputFile2 = Relauncher.TKeyScript("_output_multitype_mt_Key_condensate_.dat")
inputFile2.addInput(w1, "w1")
inputFile2.addInput(v1, "v1")
inputFile2.addInput(v2, "v2")
inputFile2.addInput(f1, "f1")
inputFile2.addInput(w2, "w2")
# Create the output files
outputFile2 = Relauncher.TKeyResult("_output_multitype_readmt_Key_.dat")
outputFile2.addOutput(thev1, "thev1")
outputFile2.addOutput(thev2, "thev2")
# Create the user's evaluation function
eval2 = Relauncher.TCodeEval("multitype -ReadmtKey")
eval2.addInputFile(inputFile2)
eval2.addOutputFile(outputFile2)
# ==================================================================
# ======================= Composition ==============================
# ==================================================================
# Create the composition
compo = Relauncher.TComposeEval()
# Add the code one-by-one, in the right order
compo.addEval(eval1)
compo.addEval(eval2)
# Create the runner by providing the TComposeEval
runner = Relauncher.TSequentialRun(compo)
runner.startSlave() # compulsory
if runner.onMaster(): # compulsory
# Create the launcher
lanceur = Relauncher.TLauncher2(tds, runner)
lanceur.solverLoop() # run the code
# Stop the slave processes
runner.stopSlave()
# Get the results
tds.exportData("pouet_py.dat")
tds.Scan("thev1:thev2")
The code looks very much as the one in two previous examples. First a sample of 10 seed values are read from an input file. Then, output attributes are defined for the first code, as in Section XIV.9.8.2.
w1 = DataServer.TAttribute("w1", URANIE::DataServer::DataServer.TAttribute.kString);
w2 = DataServer.TAttribute("w2", URANIE::DataServer::DataServer.TAttribute.kString);
v1 = DataServer.TAttribute("v1", URANIE::DataServer::DataServer.TAttribute.kVector);
v2 = DataServer.TAttribute("v2", URANIE::DataServer::DataServer.TAttribute.kVector);
f1 = DataServer.TAttribute("f1");
The output attributes are defined for the first code, as in in Section XIV.9.11.2.
thev1 = DataServer.TAttribute("thev1");
thev2 = DataServer.TAttribute("thev2");
The assessor are then defined with input and output files and the composition is finally done: it is an assessor in in which we store the other assessors that should be run, in the correct order, as follows:
TComposeEval eval;
## Add the code one-by-one, in the right order
eval.addEval(eval1);
eval.addEval(eval2);
The rest is very common and a screenshot of the result displayed in console is provided in the following subsection.
Processing relauncherComposeMultitypeAndReadMultiType.py... ************************************ * Row * thev1 * thev2 * ************************************ * 0 * 0.2819049 * 11.424490 * * 1 * -0.692320 * 15.966536 * * 2 * -12345678 * 12.629065 * * 3 * -0.819208 * 11.086281 * * 4 * -1.561012 * -12345678 * * 5 * 0.8843648 * 10.340774 * * 6 * -12345678 * 7.1500716 * * 7 * 1.6335793 * 14.537357 * * 8 * -12345678 * -12345678 * * 9 * -0.239765 * 9.3210062 * ************************************
The goal of this macro is to show how to hide one of the evaluator's attribute and not to store it in the final
dataserver. This is considered when a composition is done for instance, in which many variables might be
intermediate needed ones, resulting from an assessor and used as input to one of the following, but of no interest
to the user at the end. The flowrate
code is provided with Uranie and has been also used and
discussed throughout these macros.
"""
Example of code launching in sequential mode with temporary variable
"""
from rootlogon import DataServer, Relauncher, Sampler
def increase_d(local_x):
"""Dummy function that increase by one the input."""
local_y = local_x + 1
return [local_y, ]
# Create the TDataServer
tds = DataServer.TDataServer("foo", "test")
# Define the attribute that should be considered as constant
r = DataServer.TAttribute("r")
# Add the study attributes (min, max and nominal values)
tds.addAttribute(DataServer.TUniformDistribution("rw", 0.05, 0.15))
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
sIn = "flowrate_input_with_keys.in"
nS = 15
# Generate the Design of Experiments
sampling = Sampler.TSampling(tds, "lhs", nS)
sampling.generateSample()
# Create the input files
inputFile = Relauncher.TKeyScript(sIn)
inputFile.addInput(tds.getAttribute("rw"), "Rw")
inputFile.addInput(r, "R")
inputFile.addInput(tds.getAttribute("tu"), "Tu")
inputFile.addInput(tds.getAttribute("tl"), "Tl")
inputFile.addInput(tds.getAttribute("hu"), "Hu")
inputFile.addInput(tds.getAttribute("hl"), "Hl")
inputFile.addInput(tds.getAttribute("l"), "L")
inputFile.addInput(tds.getAttribute("kw"), "Kw")
# Create the output attributes
yhat = DataServer.TAttribute("yhat")
d = DataServer.TAttribute("d")
# Create the output files
outputFile = Relauncher.TKeyResult("_output_flowrate_withKey_.dat")
outputFile.addOutput(yhat, "yhat")
outputFile.addOutput(d, "d")
# Create the user's evaluation function
eval1 = Relauncher.TCodeEval("flowrate -s -k")
eval1.addInputFile(inputFile)
eval1.addOutputFile(outputFile)
# Create a second evaluation function that uses d to change it slightly
incd = DataServer.TAttribute("incd")
eval2 = Relauncher.TPythonEval(increase_d)
eval2.addInput(d)
eval2.addOutput(incd)
# Create the composition
evalC = Relauncher.TComposeEval()
# Add the code one-by-one, in the right order
evalC.addEval(eval1)
evalC.addEval(eval2)
# Create the sequential runner
run = Relauncher.TSequentialRun(evalC)
run.startSlave() # Start the master (necessary even for a sequential)
if run.onMaster():
lanceur = Relauncher.TLauncher2(tds, run)
# State to the master : d is an output and I'm interested in its value
# I don't want to keep it in the end. It might be useful for an evaluator
lanceur.addTemporary(d)
lanceur.addConstantValue(r, 108)
# resolution
lanceur.solverLoop()
run.stopSlave() # Stop the slaves (necessary even for a sequential)
tds.scan("*")
Here again, a comparison is drawn with the macro in which we set an attribute to a constant value (see Section XIV.9.4), so only the differences are pointed out. The very first one is contained in the beginning lines: a new dummy function, so that we can have a composition of two assessors, this function only adding one to the provided parameter.
def IncreaseD(x):
y = x + 1;
return [y,]
The rest is exactly as for Section XIV.9.4, up to the interface with the newy create function:
## Create a second evaluation function that uses d to change it slightly
incd = DataServer.TAttribute("incd");
eval2 = Relauncher.TPythonEval(IncreaseD);
eval2.addInput(d);
eval2.addOutput(incd);
## Create the composition
eval = Relauncher.TComposeEval()
## Add the code one-by-one, in the right order
eval.addEval(eval1);
eval.addEval(eval2);
A new output attribute is created, called incd for increased d, and the dummy function is defined as taking d as input and
incd as output. Then the composition is done by chaining flowrate with the new dummy function.
The rest is fairly common, up to the TMaster
-inheriting object specification: the
addTemporary
method is called to specify that d is read
from the output of flowrate and can be pass to the rest of the chain, but it will not be kept in the final
dataserver. The addConstantValue
is also used just changing the final parameters to show
that if nothing is specified, then the value of r is not stored and this might
be tricky for bookkeeping. The results is shown in the next section (from the scan
method)
and can be compared to Section XIV.9.4.3 for
consistency check.
lanceur = Relauncher.TLauncher2(tds, run);
## State to the master : d is an output attribute and I'm interested in its value
## but I don't want to keep it in the end. It might be usefull for another evaluator
lanceur.addTemporary(d);
lanceur.addConstantValue(r,108);
****************************************************************************************************** * Row * foo__n * rw.rw * tu.tu * tl.tl * hu.hu * hl.hl * l.l * kw.kw * yhat.y * incd.i * ****************************************************************************************************** * 0 * 0 * 0.1495 * 111790 * 73.820 * 990.90 * 779.83 * 1474.3 * 11220. * 112.01 * 3589.9 * * 1 * 1 * 0.1394 * 104140 * 95.150 * 1101.5 * 707.21 * 1422.7 * 11493. * 193.62 * 6598.5 * * 2 * 2 * 0.0557 * 95387. * 84.809 * 1056.2 * 752.94 * 1184.6 * 11967. * 29.880 * 331.58 * * 3 * 3 * 0.0836 * 74144. * 103.17 * 1051.6 * 819.27 * 1587.4 * 11031. * 35.400 * 2432.1 * * 4 * 4 * 0.0586 * 65396. * 72.161 * 1003.1 * 710.34 * 1327.5 * 10484. * 24.990 * 5758 * * 5 * 5 * 0.1203 * 92149. * 65.263 * 1031.6 * 797.34 * 1265.5 * 11638. * 97.386 * 1085.8 * * 6 * 6 * 0.1319 * 67464. * 93.378 * 1039.4 * 722.54 * 1514.3 * 10996. * 125.33 * 2363.4 * * 7 * 7 * 0.1059 * 80448. * 112.87 * 1027.1 * 794.32 * 1555.4 * 11846 * 62.403 * 1117.3 * * 8 * 8 * 0.0784 * 100260 * 105.79 * 1072.7 * 767.70 * 1304.1 * 10152. * 45.867 * 522.41 * * 9 * 9 * 0.0697 * 105158 * 82.544 * 1020.4 * 726.05 * 1640.3 * 10380. * 28.412 * 2803.5 * * 10 * 10 * 0.1252 * 89522. * 100.65 * 1006.2 * 742.35 * 1123.9 * 10743. * 123.70 * 2677.1 * * 11 * 11 * 0.1165 * 73139. * 69.083 * 1108.5 * 809.59 * 1199.0 * 10620. * 112.27 * 4992.3 * * 12 * 12 * 0.0992 * 86004. * 112.12 * 1069.4 * 763.84 * 1345.2 * 9951.0 * 69.808 * 415.71 * * 13 * 13 * 0.0718 * 113775 * 90.580 * 1079.1 * 782.95 * 1416.6 * 10076. * 34.135 * 1017.8 * * 14 * 14 * 0.0902 * 83779. * 80.244 * 1090.6 * 734.33 * 1644.2 * 11443 * 63.236 * 2923.3 * ******************************************************************************************************