--- myst: substitutions: macro: python: 1-5,17-67,70-76,79-81,84-87,90-91 cpp: 26-77,80-85,88-93,96-97 bloc1: python: "30" cpp: "38" bloc2: python: 35-45 cpp: 43-55 bloc3: python: 57-61 cpp: 67-71 bloc4: python: 63-67,70-71 cpp: 73-77,80-81 bloc5: python: 73-76,79-81,84-87,90-91 cpp: 83-85,88-93,96-97 console: python: 2-13 cpp: 4-15 --- (use_cases_macro_calibration_linBayes)= # Macro "**calibrationLinBayesFlowrate1D.{{extension}}**" ## Objective The goal here is to calibrate the parameter $H_l$ within the `flowrate` model, while varying only two inputs ($r_{\omega}$ and $L$). The remaining variables are fixed to the following values: $r=25050$, $T_u=89335$, $T_l=89.55$, $H_u=1050$, $K_{\omega}=10950$. The context of this example has already been presented in [](#calibration_classes_functions_observations_use_case), including the model (implemented here as a C++ function) and the initial lines defining the {{tds}} objects. This macro demonstrates how to apply a linear Bayesian estimation technique using a **Relauncher**-based architecture. ## Macro {{uranie}} {{ "```{literalinclude} " + parent_dir + "/roottest/uranie/doc/calibration/use_cases/" + language + "/calibrationLinBayesFlowrate1D." + extension + "\n" + ":language: " + language + "\n" + ":lines: " + macro[language] + "\n" + "```" }} Much of this code has already been covered in the previous section [](#use_cases_macro_calibration_minimisation) (up to the sequential run). The main difference here is that the input parameter is now defined as a `TStochasticDistribution`, representing the *a priori* chosen distribution. In this example, it can be either a `TNormalDistribution` or a `TUniformDistribution` (see {{metho}}), with the latter being selected here: {{ "```{literalinclude} " + parent_dir + "/roottest/uranie/doc/calibration/use_cases/" + language + "/calibrationLinBayesFlowrate1D." + extension + "\n" + ":language: " + language + "\n" + ":lines: " + bloc1[language] + "\n" + "```" }} Another difference from the previous example is that the method must be slightly adapted to obtain values for the regressor. As discussed in {{metho}}, linear Bayesian estimation can be applied when the model is approximately linear. This requires linearising the `flowrate` function, as demonstrated here: ```{math} f_{\theta}(x) = \left(2 \pi T_u\right)\left(\ln(\frac{r}{r_{\omega}})\left[ 1 + \frac{2 L T_u}{\ln(\frac{r}{r_{\omega}}) r_{\omega}^2 K_{\omega}} + \frac{T_u}{T_l}\right]\right)^{-1} \theta = H \times \theta ``` Here, the regressor can be expressed as ```{math} H = \left(2 \pi T_u\right)\left(\ln(\frac{r}{r_{\omega}}) \left[ 1 + \frac{2 L T_u}{\ln(\frac{r}{r_{\omega}}) r_{\omega}^2 K_{\omega}} + \frac{T_u}{T_l}\right]\right)^{-1} ``` From this expression, it is clear that we will be calibrating a newly defined parameter $\theta = \left( H_u - H_l\right)$, which must later be converted back into the parameter of interest. To obtain the regressor estimation, we simply use another C++ function, `flowrateModelnoH`, together with the standard **Relauncher** approach: {{ "```{literalinclude} " + parent_dir + "/roottest/uranie/doc/calibration/use_cases/" + language + "/calibrationLinBayesFlowrate1D." + extension + "\n" + ":language: " + language + "\n" + ":lines: " + bloc2[language] + "\n" + "```" }} This method also requires the input covariance matrix. The provided dataset (`Ex2DoE_n100_sd1.75.dat`) contains an estimate of the uncertainty affecting the reference measurements. Since this uncertainty is constant across all samples, the input covariance matrix is diagonal, with each diagonal element equal to the square of the standard deviation, as illustrated below: {{ "```{literalinclude} " + parent_dir + "/roottest/uranie/doc/calibration/use_cases/" + language + "/calibrationLinBayesFlowrate1D." + extension + "\n" + ":language: " + language + "\n" + ":lines: " + bloc3[language] + "\n" + "```" }} The model is defined (from a `TCIntEval` instance with the three input variables discussed above, in the **correct order**) along with the computation distribution method (sequential). The calibration object is then created using a Mahalanobis distance function, which is used here for illustrative purposes (see [](#calibration_linear_bayesian) for more details). The three key steps are: - Providing the input covariance matrix via the `setObservationCovarianceMatrix` method; - Specifying the regressors’ names using `setRegressorName`; - Defining the parameter transformation function (optional) with `setParameterTransformationFunction`. The final step is more involved: since we are calibrating $\theta$, we need to recover the corresponding parameter value at the end. This is achieved by providing a C++ function that transforms the parameter estimated from the linearisation back into the parameter of interest. For illustration, this is implemented in `UserFunctions.C` via the `transf` function, shown below: {{ "```{literalinclude} " + parent_dir + "/roottest/uranie/doc/UserFunctions.C" + "\n" + ":language: cpp\n" + ":lines: 83-86\n" + "```" }} The complete block of code discussed in this section is as follows: {{ "```{literalinclude} " + parent_dir + "/roottest/uranie/doc/calibration/use_cases/" + language + "/calibrationLinBayesFlowrate1D." + extension + "\n" + ":language: " + language + "\n" + ":lines: " + bloc4[language] + "\n" + "```" }} The final part demonstrates how to display the results. Since this method produces normal *a posteriori* distributions, they are represented by a vector of means and a covariance structure, both easily accessible. The means are displayed on screen, as illustrated in [](#use_cases_macro_calibration_linBayes_console). Two additional pieces of *a posteriori* information are presented as plots: the residuals ({numref}`usecases_calibrationLinBayesFlowrate1D_Res`), which show the expected normal distribution behavior, as discussed in {{metho}} and the posterior distribution ({numref}`usecases_calibrationLinBayesFlowrate1D_Par`). {{ "```{literalinclude} " + parent_dir + "/roottest/uranie/doc/calibration/use_cases/" + language + "/calibrationLinBayesFlowrate1D." + extension + "\n" + ":language: " + language + "\n" + ":lines: " + bloc5[language] + "\n" + "```" }} (use_cases_macro_calibration_linBayes_console)= ## Console {{ "```{literalinclude} " + parent_dir + "/roottest/build/uranie/doc/calibration/use_cases/" + language + "/calibrationLinBayesFlowrate1D_clean.log" + "\n" + ":language: none\n" + ":lines: " + console[language] + "\n" + "```" }} ## Graphs {{ "```{" "figure" "} " + parent_dir + "/roottest/build/uranie/doc/calibration/use_cases/" + language + "/linBayes/calibrationLinBayesFlowrate1D_Res.png\n" ":align: center\n" ":name: usecases_calibrationLinBayesFlowrate1D_Res\n" + figure_scale + "\n" "\n" "Residuals graph of the macro **\"calibrationLinBayesFlowrate1D." + extension + "\"**\n" "```" }} {{ "```{" "figure" "} " + parent_dir + "/roottest/build/uranie/doc/calibration/use_cases/" + language + "/linBayes/calibrationLinBayesFlowrate1D_Par.png\n" ":align: center\n" ":name: usecases_calibrationLinBayesFlowrate1D_Par\n" + figure_scale + "\n" "\n" "Parameter graph of the macro **\"calibrationLinBayesFlowrate1D." + extension + "\"**\n" "```" }}