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->numberOfRtParameters() > 30) { nb_points = rt_Chebyshev->numberOfRtParameters(); }
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->numberOfRtParameters();
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();
839 for (
unsigned int k = 1;
k <
segment->mdtHitsOnTrack();
k++) {
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(); }
845 for (
unsigned int k = 0;
k <
segment->mdtCloseHits();
k++) {
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";
862 for (
unsigned int k = 0;
k <
segment->mdtHitsOnTrack();
k++) {
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() <<
" "
874 for (
unsigned int k = 0;
k <
segment->mdtCloseHits();
k++) {
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();