(calibration_classes_functions_observations_calibration_classes_runner)= # Construction with a `TRun` This constructor uses the **Relauncher** architecture. This approach provides a simple way to change the evaluator (e.g., switching from a C++ function to a Python function or another code). It also allows the use of either a sequential approach (for single-thread execution) or a threaded approach (to distribute estimates locally). This approach is partly discussed in [](#relauncher_module). In this case, the constructor has the following form: ````{only} cpp ```cpp // Constructor with a runner TCalClass(TDataServer *tds, TRun *runner, Int_t ns=1, Option_t *option="") ``` ```` ````{only} py ```python # Constructor with a runner TCalClass(tds, runner, ns=1, option="") ``` ```` It takes up to four arguments, two of which are optional: 1. **tds**: a {{tds}} object containing one attribute for each parameter to be calibrated. This is the {{tds}} object called `tdsPar`, defined in [](#calibration_classes_functions_observations_data_model). 2. **runner**: a `TRun`-inheriting instance that contains all the model information and whose type determines how the estimates are distributed: it can either be a `TSequentialRun` instance or `TThreadedRun` for distributed computations. 3. **ns** (optional): the number of samples to be produced. This parameter is only relevant for methods that return multiple configurations (either multiple solutions to the minimisation problem or samples from the posterior distribution). It is not used in local minimisation with single-point initialisation, nor in linear Bayesian analysis (see [](#calibration_linear_bayesian)). The **default** value is 1. 4. **option** (optional): the options that can be applied to the method. Options common to all calibration classes (those defined in the `TCalibration` class) are discussed in [](#calibration_classes_functions_observations_calibration_classes_running). A crucial step in this constructor is the creation of the instance that inherits from `TRun`. As mentioned earlier, its type determines how the estimates are distributed. To construct such an object, one needs to provide an evaluator (the available evaluators are described in detail in [](#relauncher_teval)). Using the formalism introduced in [](#calibration_classes_functions_observations_data_and_distance_recommended_distance), a model instance based on the code `Foo`, initialised with `TCIntEval`, can be created as shown below. This example assumes the model takes three inputs (**"ref_var1"**, **"par1"**, **"ref_var2"**) and it produces a single output, which is compared with the reference output **"ref_out1"** via the distance or likelihood function (see [](#calibration_classes_functions_observations_data_and_distance_recommended_distance)). ````{only} cpp ```cpp // Define the dataservers TDataServer *tdsRef = new TDataServer("reference","myReferenceData"); // Load the data, both inputs (ref_var1 and ref_var2) and a single output (ref_out1). tdsRef->fileDataRead("myInputData.dat"); ... TDataServer *tdsPar = new TDataServer("parameters","myParameters"); tdsPar->addAttribute( new TNormalDistribution("par1",0,1) ); // the parameter to calibrate ... // Define the model if a function Foo(double *x, double *y) is defined above // where x[0]=ref_var1, x[1]=par1 and x[2]=ref_var2 and y[0] is the model prediction TCIntEval *model = new TCIntEval("Foo"); // Add inputs in the correct order model->addInput(tdsRef->getAttribute("ref_var1")); model->addInput(tdsPar->getAttribute("par1")); model->addInput(tdsRef->getAttribute("ref_var2")); // Define the output attribute TAttribute *out = new TAttribute("out"); model->addOutput(out); // Define a sequential runner to be used TSequentialRun *runner = new TSequentialRun(model); ... // Create the instance of TCalClass int ns=1; TCalClass *cal = new TCalClass(tdsPar, runner, ns, ""); ``` ```` ````{only} py ```python # Define the dataservers tdsRef = DataServer.TDataServer("reference", "myReferenceData") # Load the data, both inputs (ref_var1 and ref_var2) and a single output (ref_out1). tdsRef.fileDataRead("myInputData.dat") ... TDataServer *tdsPar = new TDataServer("parameters", "myParameters") tdsPar.addAttribute(DataServer.TNormalDistribution("par1", 0, 1)) # parameter to calibrate ... # Define the model if a function Foo is loaded through ROOT.gROOT.LoadMacro(...) # for which x[0]=ref_var1, x[1]=par1 and x[2]=ref_var2 and y[0] is the model prediction model = Relauncher.TCIntEval(Foo) # Add inputs in the correct order model.addInput(tdsRef.getAttribute("ref_var1")) model.addInput(tdsPar.getAttribute("par1")) model.addInput(tdsRef.getAttribute("ref_var2")) # Define the output attribute out = DataServer.TAttribute("out") model.addOutput(out) # Define a sequential runner to be used runner = Relauncher.TSequentialRun(model) ... # Create the instance of TCalClass ns = 1 cal = Calibration.TCalClass(tdsPar, runner, ns, "") ``` ````