(calibration_classes_functions_observations_calibration_classes_tcode)= # Construction with a `TCode` This constructor uses the **Launcher** architecture. Unlike the **Relauncher** approach, it is specifically designed for code-based models. In this case, the constructor has the following form: ````{only} cpp ```cpp // Constructor with a TCode TCalClass(TDataServer *tds, TCode *code, Int_t ns=1, Option_t *option=""); ``` ```` ````{only} py ```python # Constructor with a TCode TCalClass(tds, code, 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. **code**: a `TCode` instance containing the output file (or files) listing the output attributes while all input attributes are associated with input files using the standard methods (`setFileKey`, `setFileFlag`, etc.). 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 option 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). Unlike the runner-based constructor, this construction does not define how the computation is performed. By default, the `run` method is called for each configuration with the following options: - **noIntermediateSteps**: prevents results from being saved every five estimates. - **quiet**: suppresses verbose output from the launcher. Two methods can be applied on `TDistanceLikelihoodFunction` objects to change these options: `addCodeLauncherOpt` and `changeCodeLauncherOpt` (see [](#calibration_classes_functions_observations_data_and_distance_distance_options_specify_launcher)). ````{only} cpp ```cpp // Adding more options to the code launcher void addCodeLauncherOpt(TString opt); // Change the code launcher option void changeCodeLauncherOpt(TString opt); ``` ```` ````{only} py ```python # Adding more options to the code launcher addCodeLauncherOpt(opt) # Change the code launcher option changeCodeLauncherOpt(opt) ``` ```` The first method retains the default configuration and appends additional options, for example an option that enables distributed computation using the fork process (recall that this option is **"localhost=X"**, where X denotes the number of threads to use). In contrast, the second method resets the configuration entirely, allowing the user to define a new set of options from scratch. Using the formalism introduced in [](#calibration_classes_functions_observations_data_and_distance_recommended_distance), a model instance based on the code `Foo`, initialised with `TCode`, 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 ... TString sIn = TString("code_foo_input.in"); // Set the reference input file and assign keys to each input attribute tdsRef->getAttribute("ref_var1")->setFileKey(sIn, "var1"); tdsRef->getAttribute("ref_var2")->setFileKey(sIn, "var2"); tdsPar->getAttribute("par1")->setFileKey(sIn, "par1"); // Direct the output attribute towards the file TOutputFileRow *fout = new TOutputFileRow("_output_code_foo_.dat"); // The attribute in the output file fout->addAttribute(new TAttribute("out")); // Creation of the code TCode *mycode = new TCode(tdsRef, "foo -s -k"); mycode->addOutputFile( fout ); ... // Create the instance of TCalClass int ns=1; TCalClass *cal = new TCalClass(tdsPar, mycode, 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") ... tdsPar = DataServer.TDataServer("parameters", "myParameters") tdsPar.addAttribute(DataServer.TNormalDistribution("par1", 0, 1)) # parameter to calibrate ... sIn = TString("code_foo_input.in") # Set the reference input file and the key for each input attributes tdsRef.getAttribute("ref_var1").setFileKey(sIn, "var1") tdsRef.getAttribute("ref_var2").setFileKey(sIn, "var2") tdsPar.getAttribute("par1").setFileKey(sIn, "par1") # The output file of the code fout = Launcher.TOutputFileRow("_output_code_foo_.dat") # The attribute in the output file fout.addAttribute(DataServer.TAttribute("out")) # Creation of the code mycode = Launcher.TCode(tdsRef, "foo -s -k") mycode.addOutputFile( fout ) ... # Create the instance of TCalClass int ns=1 cal = Calibration.TCalClass(tdsPar, mycode, ns, "") ``` ````