English Français

Documentation / User's manual in Python : PDF version

XIV.9. Macros Relauncher

XIV.9. Macros Relauncher

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).

XIV.9.1. Macro "relauncherFunctionFlowrateCInt.py"

XIV.9.1.1. Objective

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.

XIV.9.1.2. Macro

"""
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.

XIV.9.1.3. Graph

Figure XIV.83. Representation of the output as a function of the first input with a colZ option

Representation of the output as a function of the first input with a colZ option

XIV.9.2. Macro "relauncherFunctionFlowratePython.py"

XIV.9.2.1. Objective

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.

XIV.9.2.2. Macro

#!/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.

XIV.9.2.3. Graph

Figure XIV.84. Representation of the output as a function of the first input with a colZ option

Representation of the output as a function of the first input with a colZ option

XIV.9.3. Macro "relauncherCodeFlowrateSequential.py"

XIV.9.3.1. Objective

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.

XIV.9.3.2. Macro

"""
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.

XIV.9.3.3. Graph

Figure XIV.85. Representation of the output as a function of the first input with a colZ option

Representation of the output as a function of the first input with a colZ option

XIV.9.4. Macro "relauncherCodeFlowrateSequential_ConstantVar.py"

XIV.9.4.1. Objective

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.

XIV.9.4.2. Macro

"""
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);

XIV.9.4.3. Console

***************************************************************************************************************
*    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 *
***************************************************************************************************************

XIV.9.5. Macro "relauncherCodeFlowrateThreaded.py"

XIV.9.5.1. Objective

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.

XIV.9.5.2. Macro

"""
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.

XIV.9.5.3. Graph

Figure XIV.86. Representation of the output as a function of the first input with a colZ option

Representation of the output as a function of the first input with a colZ option

XIV.9.6. Macro "relauncherCodeFlowrateMPI.py"

XIV.9.6.1. Objective

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.

XIV.9.6.2. Macro

"""
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.

XIV.9.6.3. Graph

Figure XIV.87. Representation of the output as a function of the first input with a colZ option

Representation of the output as a function of the first input with a colZ option

XIV.9.7. Macro "relauncherCodeFlowrateSequentialFailure.py"

XIV.9.7.1. Objective

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.

XIV.9.7.2. Macro

"""
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.

XIV.9.7.3. Graph

Figure XIV.88. Representation of the output data point when the code is asked to fail on purpose.

Representation of the output data point when the code is asked to fail on purpose.

XIV.9.7.4. Console

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 *
************************************************************************************************************************************

XIV.9.8. Macro "relauncherCodeMultiTypeKey.py"

XIV.9.8.1. Objective

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

XIV.9.8.2. Macro Uranie

"""
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.

XIV.9.8.3. Graph

Figure XIV.89. Graph of the macro "relauncherCodeMultiTypeKey.py"

Graph of the macro "relauncherCodeMultiTypeKey.py"

XIV.9.9. Macro "relauncherCodeMultiTypeKeyEmptyVectors.py"

XIV.9.9.1. Objective

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

XIV.9.9.2. Macro Uranie

"""
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.

XIV.9.9.3. Graph

Figure XIV.90. Graph of the macro "relauncherCodeMultiTypeKeyEmptyVectors.py"

Graph of the macro "relauncherCodeMultiTypeKeyEmptyVectors.py"

XIV.9.10. Macro "relauncherCodeMultiTypeKeyEmptyVectorsAsFailure.py"

XIV.9.10.1. Objective

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

XIV.9.10.2. Macro Uranie

"""
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.

XIV.9.10.3. Graph

Figure XIV.91. Graph of the macro "relauncherCodeMultiTypeKeyEmptyVectorsAsFailure.py"

Graph of the macro "relauncherCodeMultiTypeKeyEmptyVectorsAsFailure.py"

XIV.9.10.4. Console

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 *
************************************

XIV.9.11. Macro "relauncherCodeReadMultiType.py"

XIV.9.11.1. Objective

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

XIV.9.11.2. Macro Uranie

"""
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.

XIV.9.11.3. Console

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 *
************************************

XIV.9.12. Macro "relauncherComposeMultitypeAndReadMultiType.py"

XIV.9.12.1. Objective

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.

XIV.9.12.2. Macro Uranie

"""
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.

XIV.9.12.3. Console

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 *
************************************

XIV.9.13. Macro "relauncherCodeFlowrateSequential_TemporaryVar.py"

XIV.9.13.1. Objective

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.

XIV.9.13.2. Macro

"""
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);

XIV.9.13.3. Console

******************************************************************************************************
*    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 *
******************************************************************************************************
/language/en