8 #include "CLHEP/GenericFunctions/CumulativeChiSquare.hh" 
    9 #include "CLHEP/Matrix/Matrix.h" 
   10 #include "GaudiKernel/MsgStream.h" 
   36     init(0.5 * 
CLHEP::mm, 1, 15, 
true, 
false, 15, 
false, 
false, 
false);
 
   40                                          const unsigned int &ord, 
const bool &fix_min, 
const bool &fix_max, 
const int &max_it,
 
   41                                          bool do_parabolic_extrapolation, 
bool do_smoothing, 
bool do_multilayer_rt_scale) :
 
   43     init(rt_accuracy, func_type, ord, fix_min, fix_max, max_it, do_parabolic_extrapolation, do_smoothing, do_multilayer_rt_scale);
 
   71     m_cut_evolution = std::make_unique<TH1F>(
"m_cut_evolution", 
"CUT EVOLUTION", 11, -0.5, 10.5);
 
   72     m_nb_segment_hits = std::make_unique<TH1F>(
"m_nb_segment_hits", 
"NUMBER OF HITS ON THE REFITTED SEGMENTS", 11, -0.5, 10.5);
 
   73     m_pull_initial = std::make_unique<TH1F>(
"m_pull_initial", 
"INITIAL PULL DISTRIBUTION", 200, -5.05, 5.05);
 
   75         std::make_unique<TH2F>(
"m_residuals_initial", 
"INITIAL OF THE REFITTED SEGMENTS", 100, -0.5, 15.0, 300, -1.5, 1.5);
 
   76     m_residuals_initial_all = std::make_unique<TH2F>(
"m_residuals_initial_all", 
"INITIAL OF THE REFITTED SEGMENTS BEFORE CONVERGENCE", 300,
 
   77                                                      -15.0, 15.0, 1000, -5, 5);
 
   78     m_residuals_final = std::make_unique<TH2F>(
"m_residuals_final", 
"FINAL OF THE REFITTED SEGMENTS", 100, -0.5, 15.0, 300, -1.5, 1.5);
 
   80         std::make_unique<TH2F>(
"m_driftTime_final", 
"FINAL DRIFTTIME OF THE REFITTED SEGMENTS", 300, -15.0, 15.0, 300, -15.0, 15.0);
 
   82         std::make_unique<TH2F>(
"m_driftTime_initial", 
"FINAL DRIFTTIME OF THE REFITTED SEGMENTS", 300, -15.0, 15.0, 1300, -100, 1200);
 
   84         std::make_unique<TH2F>(
"m_adc_resi_initial", 
"FINAL ADC VS RESIDUAL OF THE REFITTED SEGMENTS", 1350, 0, 1350, 300, -15, 15);
 
  102     std::shared_ptr<const IRtRelation> tmp_rt;
 
  107     for (
const auto & 
k : seg) {
 
  108         for (
unsigned int l = 0; 
l < 
k->hitsOnTrack(); 
l++) {
 
  110             double dd = (
k->mdtHOT())[
l]->signedDistanceToTrack();
 
  123             log << MSG::WARNING << 
"analyseSegments() - analyse failed, segments:" << 
endmsg;
 
  124             for (
unsigned int i = 0; 
i < seg.size(); 
i++) {
 
  125                 log << MSG::WARNING << 
i << 
" " << seg[
i]->direction() << 
" " << seg[
i]->position() << 
endmsg;
 
  133         tmp_rt = rtOut->
rt();
 
  139         m_output = std::make_shared<RtCalibrationOutput>(
 
  150         double r{0}, 
d{0}, 
adc{0};
 
  151         for (
const auto & 
k : seg) {
 
  152             for (
unsigned int l = 0; 
l < 
k->hitsOnTrack(); 
l++) {
 
  153                 adc = (
k->mdtHOT())[
l]->adcCount();
 
  155                 d = (
k->mdtHOT())[
l]->signedDistanceToTrack();
 
  165     int max_smoothing_iterations(
static_cast<int>(
m_max_it));
 
  166     if (max_smoothing_iterations == 0) { max_smoothing_iterations = 1; }
 
  169     double convergence_RMS(0.002);
 
  178     while (it < max_smoothing_iterations && RMS > convergence_RMS) {
 
  185         for (
const auto & 
k : seg) {
 
  186             if (
k->mdtHitsOnTrack() < 4) { 
continue; }
 
  188             for (
unsigned int h = 0; 
h < 
k->mdtHitsOnTrack(); 
h++) {
 
  189                 k->mdtHOT()[
h]->setDriftRadius(tmp_rt->
radius(
k->mdtHOT()[
h]->driftTime()),
 
  190                                                     k->mdtHOT()[
h]->sigmaDriftRadius());
 
  191                 if (
k->mdtHOT()[
h]->sigmaDriftRadius() < 0.5 * 
m_r_max) {
 
  192                     avres = avres + 
k->mdtHOT()[
h]->sigma2DriftRadius();
 
  194                     avres = avres + 0.01;
 
  197             avres = avres / 
static_cast<double>(
k->mdtHitsOnTrack());
 
  198             avres = std::sqrt(avres);
 
  205             log << MSG::WARNING << 
"analyseSegments() - too small number of reconstructed segments!" << 
endmsg;
 
  207             for (
const auto & 
k : seg) {
 
  208                 for (
unsigned int l = 0; 
l < 
k->hitsOnTrack(); 
l++) {
 
  210                     double d = (
k->mdtHOT())[
l]->signedDistanceToTrack();
 
  226         RMS = std::sqrt(0.01 * 
RMS);
 
  232         tmp_rt = std::make_shared<RtRelationLookUp>(smooth_rt);
 
  238     m_output = std::make_shared<RtCalibrationOutput>(
 
  244     for (
const auto & 
k : seg) {
 
  245         for (
unsigned int l = 0; 
l < 
k->hitsOnTrack(); 
l++) {
 
  246             double adc = (
k->mdtHOT())[
l]->adcCount();
 
  248             double d = (
k->mdtHOT())[
l]->signedDistanceToTrack();
 
  282     if (std::abs(seg.
direction().y()) > 100) { 
return true; }
 
  291     double chi2_scale_factor;  
 
  296     unsigned int nb_hits_in_ml;   
 
  298     std::vector<double> d_track;  
 
  300     std::vector<MTStraightLine> 
w;      
 
  305     std::vector<CLHEP::HepVector> 
F;  
 
  307     CLHEP::HepVector residual_value;     
 
  308     CLHEP::HepVector weighted_residual;  
 
  323         aux_res = seg.
mdtHOT()[
k]->sigmaDriftRadius();
 
  324         if (
m_rt->radius(seg.
mdtHOT()[
k]->driftTime()) < 0.75) {
 
  325             if (aux_res < 0.5 - m_rt->
radius(seg.
mdtHOT()[
k]->driftTime())) { aux_res = 0.5 - 
m_rt->radius(seg.
mdtHOT()[
k]->driftTime()); }
 
  332         hit_selection[
k] = 0;
 
  337             hit_selection[
k] = 1;
 
  341         if (hit_selection[
k] == 0) {
 
  345                 av_res = av_res + 0.01;
 
  350         nb_hits_in_ml = nb_hits_in_ml + (1 - hit_selection[
k]);
 
  354     av_res = std::sqrt(av_res / 
static_cast<double>(seg.
mdtHitsOnTrack()));
 
  355     chi2_scale_factor = std::hypot(av_res, 
m_rt_accuracy) / av_res;
 
  365     if (nb_hits_in_ml < 4) { 
return true; }
 
  372     if (std::isnan(
track.chi2())) { 
return true; }
 
  375     if (
track.chi2PerDegreesOfFreedom() > 5 * chi2_scale_factor) { 
return true; }
 
  379     if (
track.numberOfTrackHits() < 4) { 
return true; }
 
  384     if (std::abs(
track.getTangent(seg.
mdtHOT()[0]->localPosition().z()).a_x2()) > 8.0e8) { 
return true; }
 
  393     F = std::vector<CLHEP::HepVector>(
track.numberOfTrackHits());
 
  394     for (
unsigned int h = 0; 
h < 
track.numberOfTrackHits(); 
h++) {
 
  399         for (
int p = 0; 
p < 
F[
h].num_row(); 
p++) {
 
  400             double x = std::sqrt(1.0 + 
std::pow(
track.getTangent((
track.trackHits()[
h]->localPosition()).z()).a_x2(), 2));
 
  402                 (
F[
h])[
p] = std::legendre(
p, (
track.trackHits()[
h]->localPosition()).z()) / 
x;
 
  411             for (
unsigned int h = 0; 
h < 
track.numberOfTrackHits(); 
h++) {
 
  421         log << MSG::WARNING << 
"handleSegment() - Could not invert track matrix!" << 
endmsg;
 
  427     d_track = std::vector<double>(
track.numberOfTrackHits());
 
  428     w = std::vector<MTStraightLine>(
track.numberOfTrackHits());
 
  429     residual_value = CLHEP::HepVector(
track.numberOfTrackHits());
 
  430     weighted_residual = CLHEP::HepVector(
track.numberOfTrackHits());
 
  432         m_U[
l] = CLHEP::HepVector(
track.numberOfTrackHits());
 
  435     for (
unsigned int h = 0; 
h < 
track.numberOfTrackHits(); 
h++) {
 
  438         d_track[
h] = 
track.getTangent((
track.trackHits()[
h]->localPosition()).z()).signDistFrom(
w[
h]);
 
  450     D = CLHEP::HepMatrix(
track.numberOfTrackHits(), 
track.numberOfTrackHits());
 
  451     for (
unsigned int h = 0; 
h < 
track.numberOfTrackHits(); 
h++) {
 
  452         for (
unsigned int hp = 0; hp < 
track.numberOfTrackHits(); hp++) {
 
  454                                        (
track.trackHits()[hp])->sigma2DriftRadius();
 
  460     std::vector<double> sigma_residual(
track.numberOfTrackHits(), 0.0);
 
  461     for (
unsigned int h = 0; 
h < 
track.numberOfTrackHits(); 
h++) {
 
  462         for (
unsigned int hp = 0; hp < 
track.numberOfTrackHits(); hp++) {
 
  463             sigma_residual[
h] = sigma_residual[
h] + 
std::pow(D[
h][hp] * (
track.trackHits()[hp])->sigmaDriftRadius(), 2);
 
  465         sigma_residual[
h] = std::sqrt(sigma_residual[
h]);
 
  466         if (sigma_residual[
h] < av_res / 
track.numberOfTrackHits()) { sigma_residual[
h] = av_res / std::sqrt(
track.numberOfTrackHits()); }
 
  470     for (
unsigned int h = 0; 
h < 
track.numberOfTrackHits(); 
h++) {
 
  471         weighted_residual[
h] = residual_value[
h] / sigma_residual[
h];
 
  479     CLHEP::HepSymMatrix A_tmp(
m_A);
 
  483         for (
unsigned int pp = 
p; pp < 
m_order; pp++) {
 
  485             if (std::isnan(A_tmp[
p][pp])) { 
return true; }
 
  489     CLHEP::HepVector b_tmp(
m_b);
 
  492         if (std::isnan(b_tmp[
p])) { 
return true; }
 
  515     if (input == 
nullptr) {
 
  516         throw std::runtime_error(
 
  517             Form(
"File: %s, Line: %d\nRtCalibrationCurved::setInput - Calibration input class not supported.", __FILE__, __LINE__));
 
  539     if (!rt_Chebyshev && !rt_LookUp) {
 
  540         throw std::runtime_error(Form(
"File: %s, Line: %d\nRtCalibrationCurved::setInput - r-t class not supported.", __FILE__, __LINE__));
 
  545         m_t_length = rt_Chebyshev->tUpper() - rt_Chebyshev->tLower();
 
  546         m_t_mean = 0.5 * (rt_Chebyshev->tLower() + rt_Chebyshev->tUpper());
 
  551         m_t_length = rt_LookUp->par(1) * (rt_LookUp->nPar() - 2) - rt_LookUp->par(0);
 
  552         m_t_mean = 0.5 * (rt_LookUp->par(1) * (rt_LookUp->nPar() - 2) + rt_LookUp->par(0));
 
  568     unsigned int nb_points(30);  
 
  573     std::vector<double> rt_param(
m_rt->nPar());  
 
  583         log << MSG::WARNING << 
"analyse() - Could not solve the autocalibration equation!" << 
endmsg;
 
  594         if (rt_Chebyshev->nDoF() > 30) { nb_points = rt_Chebyshev->nDoF(); }
 
  600         std::vector<SamplePoint> x_r(nb_points + 1);
 
  605         for (
unsigned int k = 0; 
k < nb_points + 1; 
k++) {
 
  607             x_r[
k].set_x2(rt_Chebyshev->radius(x_r[
k].x1()));
 
  608             x_r[
k].set_x1(rt_Chebyshev->getReducedTime(x_r[
k].x1()));
 
  609             x_r[
k].set_error(1.0);
 
  621                 x_r[
k].set_error(0.01);
 
  623             x_r[
k].set_x2(x_r[
k].
x2() - r_corr);
 
  628             for (
unsigned int k = 0; 
k < nb_points; 
k++) {
 
  629                 if (x_r[
k].
x2() > x_r[
k + 1].
x2()) { x_r[
k + 1].set_x2(x_r[
k].
x2()); }
 
  634         fitter.fit_parameters(x_r, 1, nb_points + 1, chebyshev);
 
  635         rt_param[0] = rt_Chebyshev->tLower();
 
  636         rt_param[1] = rt_Chebyshev->tUpper();
 
  637         for (
unsigned int k = 0; 
k < rt_Chebyshev->nDoF(); 
k++) { rt_param[
k + 2] = 
fitter.coefficients()[
k]; }
 
  639         m_rt_new = std::make_shared<RtChebyshev>(rt_param);
 
  645         rt_param = rt_LookUp->parameters();
 
  646         unsigned int min_k(2), max_k(rt_param.size());
 
  648         if (
m_fix_max) { max_k = rt_param.size() - 1; }
 
  649         for (
unsigned int k = min_k; 
k < max_k; 
k++) {
 
  653             rt_param[
k] = rt_param[
k] - r_corr;
 
  655                 if (rt_param[
k] < rt_param[
k - 1]) { rt_param[
k] = rt_param[
k - 1]; }
 
  659         m_rt_new = std::make_shared<RtRelationLookUp>(rt_param);
 
  670     double r_corr_max = 0.0;
 
  672     for (
unsigned int k = 0; 
k < 100; 
k++) {
 
  675         if (std::abs(r_corr) > r_corr_max) { r_corr_max = std::abs(r_corr); }
 
  712     m_output = std::make_shared<RtCalibrationOutput>(
 
  726                                const bool &fix_max, 
const int &max_it, 
bool do_parabolic_extrapolation, 
bool do_smoothing,
 
  727                                bool do_multilayer_rt_scale) {
 
  750     m_tracker = std::make_unique<CurvedPatRec>();
 
  753         throw std::runtime_error(
 
  754             Form(
"File: %s, Line: %d\nRtCalibrationCurved::init - Order of the correction polynomial must be >0!", __FILE__, __LINE__));
 
  769     if (func_type < 1 || func_type > 3) {
 
  770         throw std::runtime_error(
 
  771             Form(
"File: %s, Line: %d\nRtCalibrationCurved::init - Illegal correction function type!", __FILE__, __LINE__));
 
  774         case 1: 
m_base_function = std::make_unique<LegendrePolynomial>(); 
break;
 
  775         case 2: 
m_base_function = std::make_unique<ChebyshevPolynomial>(); 
break;
 
  778                 throw std::runtime_error(
 
  779                     Form(
"File: %s, Line: %d\nRtCalibrationCurved::init - Order must be >2 for polygons! It is set to %i by the user.",
 
  807     double precision(0.001);                            
 
  814     while (t_max - t_min > 0.1 && std::abs(
m_rt->radius(0.5 * (t_min + t_max)) - 
r) > precision) {
 
  815         if (
m_rt->radius(0.5 * (t_min + t_max)) > 
r) {
 
  816             t_max = 0.5 * (t_min + t_max);
 
  818             t_min = 0.5 * (t_min + t_max);
 
  822     return 0.5 * (t_min + t_max);
 
  828     double y_min, y_max, z_min, z_max;  
 
  835     y_min = (segment->
mdtHOT()[0])->localPosition().y();
 
  837     z_min = (segment->
mdtHOT()[0])->localPosition().z();
 
  840         if ((segment->
mdtHOT()[
k])->localPosition().y() < y_min) { y_min = (segment->
mdtHOT()[
k])->localPosition().y(); }
 
  841         if ((segment->
mdtHOT()[
k])->localPosition().y() > y_max) { y_max = (segment->
mdtHOT()[
k])->localPosition().y(); }
 
  842         if ((segment->
mdtHOT()[
k])->localPosition().z() < z_min) { z_min = (segment->
mdtHOT()[
k])->localPosition().z(); }
 
  843         if ((segment->
mdtHOT()[
k])->localPosition().z() > z_max) { z_max = (segment->
mdtHOT()[
k])->localPosition().z(); }
 
  846         if ((segment->
mdtClose()[
k])->localPosition().y() < y_min) { y_min = (segment->
mdtClose()[
k])->localPosition().y(); }
 
  847         if ((segment->
mdtClose()[
k])->localPosition().y() > y_max) { y_max = (segment->
mdtClose()[
k])->localPosition().y(); }
 
  848         if ((segment->
mdtClose()[
k])->localPosition().z() < z_min) { z_min = (segment->
mdtClose()[
k])->localPosition().z(); }
 
  849         if ((segment->
mdtClose()[
k])->localPosition().z() > z_max) { z_max = (segment->
mdtClose()[
k])->localPosition().z(); }
 
  853     if (y_max - y_min > z_max - z_min) {
 
  854         outfile << 
"nullptr " << y_min - 30.0 << 
" " << y_max + 30.0 << 
" " << 0.5 * (z_min + z_max) - 0.5 * (y_max - y_min) - 30.0 << 
" " 
  855                 << 0.5 * (z_min + z_max) + 0.5 * (y_max - y_min) + 30.0 << 
"\n";
 
  857         outfile << 
"nullptr " << 0.5 * (y_min + y_max) - 0.5 * (z_max - z_min) - 30.0 << 
" " 
  858                 << 0.5 * (y_min + y_max) + 0.5 * (z_max - z_min) + 30.0 << 
" " << z_min - 30.0 << 
" " << z_max + 30.0 << 
"\n";
 
  865                 << 
"ARC " << (segment->
mdtHOT()[
k])->localPosition().y() << 
" " << (segment->
mdtHOT()[
k])->localPosition().z() << 
" 15.0\n";
 
  869                 << 
"ARC " << (segment->
mdtHOT()[
k])->localPosition().y() << 
" " << (segment->
mdtHOT()[
k])->localPosition().z() << 
" " 
  877                 << 
"ARC " << (segment->
mdtClose()[
k])->localPosition().y() << 
" " << (segment->
mdtClose()[
k])->localPosition().z()
 
  882                 << 
"ARC " << (segment->
mdtClose()[
k])->localPosition().y() << 
" " << (segment->
mdtClose()[
k])->localPosition().z() << 
" " 
  888     if (curved_segment == 
nullptr) {
 
  891                 << 
"LINE " << aux_track.
a_x2() * (z_min - 30.0) + aux_track.
b_x2() << 
" " << z_min - 30.0 << 
" " 
  892                 << aux_track.
a_x2() * (z_max + 30.0) + aux_track.
b_x2() << 
" " << z_max + 30.0 << 
"\n";
 
  896     if (curved_segment != 
nullptr) {
 
  897         double step_size((60.0 + z_max - z_min) / 50.0);
 
  898         for (
double aux_z = z_min; aux_z <= z_max; aux_z = aux_z + step_size) {
 
  900                     << 
"LINE " << curved_segment->
getPointOnLine(aux_z).y() << 
" " << aux_z << 
" " 
  901                     << curved_segment->
getPointOnLine(aux_z + step_size).y() << 
" " << aux_z + step_size << 
"\n";
 
  916     std::shared_ptr<RtRelationLookUp> rt_low, rt_high;  
 
  917     std::vector<SamplePoint> add_fit_point;             
 
  923         add_fit_point.clear();
 
  939         add_fit_point.clear();