10 #include "CLHEP/GenericFunctions/CumulativeChiSquare.hh"
11 #include "GaudiKernel/MsgStream.h"
26 #include "TGraphErrors.h"
39 init(0.5 *
CLHEP::mm, 1, 5,
true,
true,
true,
true, 100,
false,
false);
43 const unsigned int &ord,
const bool &
split,
const bool &full_matrix,
const bool &fix_min,
44 const bool &fix_max,
const int &max_it,
bool do_smoothing,
bool do_parabolic_extrapolation) :
46 init(rt_accuracy, func_type, ord,
split, full_matrix, fix_min, fix_max, max_it, do_smoothing, do_parabolic_extrapolation);
57 const bool &full_matrix,
const bool &fix_min,
const bool &fix_max,
const int &max_it,
bool do_smoothing,
58 bool do_parabolic_extrapolation) {
87 throw std::runtime_error(
88 Form(
"File: %s, Line: %d\nRtCalibrationAnalytic::init - Order of the correction polynomial must be >0!", __FILE__, __LINE__));
102 if (func_type < 1 || func_type > 3) {
104 throw std::runtime_error(
105 Form(
"File: %s, Line: %d\nRtCalibrationAnalytic::init - Illegal correction function type!", __FILE__, __LINE__));
108 case 1:
m_base_function = std::make_unique<LegendrePolynomial>();
break;
109 case 2:
m_base_function = std::make_unique<ChebyshevPolynomial>();
break;
112 throw std::runtime_error(
113 Form(
"File: %s, Line: %d\nRtCalibrationAnalytic::init - Order must be >2 for polygons! It is set to %i by the user.",
147 double precision(0.001);
154 while (t_max - t_min > 0.1 && std::abs(
m_rt->radius(0.5 * (t_min + t_max)) -
r) > precision) {
155 if (
m_rt->radius(0.5 * (t_min + t_max)) >
r) {
156 t_max = 0.5 * (t_min + t_max);
158 t_min = 0.5 * (t_min + t_max);
162 return 0.5 * (t_min + t_max);
174 double y_min, y_max, z_min, z_max;
182 y_min = (
segment->mdtHOT()[0])->localPosition().y();
184 z_min = (
segment->mdtHOT()[0])->localPosition().z();
186 for (
unsigned int k = 1;
k <
segment->mdtHitsOnTrack();
k++) {
187 if ((
segment->mdtHOT()[
k])->localPosition().y() < y_min) { y_min = (
segment->mdtHOT()[
k])->localPosition().y(); }
188 if ((
segment->mdtHOT()[
k])->localPosition().y() > y_max) { y_max = (
segment->mdtHOT()[
k])->localPosition().y(); }
189 if ((
segment->mdtHOT()[
k])->localPosition().z() < z_min) { z_min = (
segment->mdtHOT()[
k])->localPosition().z(); }
190 if ((
segment->mdtHOT()[
k])->localPosition().z() > z_max) { z_max = (
segment->mdtHOT()[
k])->localPosition().z(); }
192 for (
unsigned int k = 0;
k <
segment->mdtCloseHits();
k++) {
193 if ((
segment->mdtClose()[
k])->localPosition().y() < y_min) { y_min = (
segment->mdtClose()[
k])->localPosition().y(); }
194 if ((
segment->mdtClose()[
k])->localPosition().y() > y_max) { y_max = (
segment->mdtClose()[
k])->localPosition().y(); }
195 if ((
segment->mdtClose()[
k])->localPosition().z() < z_min) { z_min = (
segment->mdtClose()[
k])->localPosition().z(); }
196 if ((
segment->mdtClose()[
k])->localPosition().z() > z_max) { z_max = (
segment->mdtClose()[
k])->localPosition().z(); }
200 if (y_max - y_min > z_max - z_min) {
201 outfile <<
"nullptr " << y_min - 30.0 <<
" " << y_max + 30.0 <<
" " << 0.5 * (z_min + z_max) - 0.5 * (y_max - y_min) - 30.0 <<
" "
202 << 0.5 * (z_min + z_max) + 0.5 * (y_max - y_min) + 30.0 <<
"\n";
204 outfile <<
"nullptr " << 0.5 * (y_min + y_max) - 0.5 * (z_max - z_min) - 30.0 <<
" "
205 << 0.5 * (y_min + y_max) + 0.5 * (z_max - z_min) + 30.0 <<
" " << z_min - 30.0 <<
" " << z_max + 30.0 <<
"\n";
209 for (
unsigned int k = 0;
k <
segment->mdtHitsOnTrack();
k++) {
212 <<
"ARC " << (
segment->mdtHOT()[
k])->localPosition().y() <<
" " << (
segment->mdtHOT()[
k])->localPosition().z() <<
" 15.0\n";
216 <<
"ARC " << (
segment->mdtHOT()[
k])->localPosition().y() <<
" " << (
segment->mdtHOT()[
k])->localPosition().z() <<
" "
221 for (
unsigned int k = 0;
k <
segment->mdtCloseHits();
k++) {
224 <<
"ARC " << (
segment->mdtClose()[
k])->localPosition().y() <<
" " << (
segment->mdtClose()[
k])->localPosition().z()
229 <<
"ARC " << (
segment->mdtClose()[
k])->localPosition().y() <<
" " << (
segment->mdtClose()[
k])->localPosition().z() <<
" "
236 <<
"LINE " << aux_track.
a_x2() * (z_min - 30.0) + aux_track.
b_x2() <<
" " << z_min - 30.0 <<
" "
237 << aux_track.
a_x2() * (z_max + 30.0) + aux_track.
b_x2() <<
" " << z_max + 30.0 <<
"\n";
314 m_cut_evolution = std::make_unique<TH1F>(
"m_cut_evolution",
"CUT EVOLUTION", 11, -0.5, 10.5);
316 m_nb_segment_hits = std::make_unique<TH1F>(
"m_nb_segment_hits",
"NUMBER OF HITS ON THE REFITTED SEGMENTS", 11, -0.5, 10.5);
318 m_CL = std::make_unique<TH1F>(
"m_CL",
"CONFIDENCE LEVELS OF THE REFITTED SEGMENTS", 100, 0.0, 1.0);
320 m_residuals = std::make_unique<TH2F>(
"m_residuals",
"RESIDUALS OF THE REFITTED SEGMENTS", 100, -0.5, 15.0, 300, -1.5, 1.5);
340 std::shared_ptr<const IRtRelation> tmp_rt;
341 std::shared_ptr<const IRtRelation> conv_rt;
350 log << MSG::WARNING <<
"analyseSegments() - analyse failed, segments:" <<
endmsg;
351 for (
unsigned int i = 0;
i < seg.size();
i++) {
352 log << MSG::WARNING <<
i <<
" " << seg[
i]->direction() <<
" " << seg[
i]->position() <<
endmsg;
360 tmp_rt = rtOut->
rt();
362 std::vector<double>
params;
366 conv_rt = std::make_shared<RtRelationLookUp>(
params);
372 m_output = std::make_shared<RtCalibrationOutput>(
383 int max_smoothing_iterations(
static_cast<int>(
m_max_it));
384 if (max_smoothing_iterations == 0) { max_smoothing_iterations = 1; }
387 double convergence_RMS(0.002);
396 while (it < max_smoothing_iterations && RMS > convergence_RMS) {
404 for (
const auto &
k : seg) {
405 if (
k->mdtHitsOnTrack() < 3) {
continue; }
407 for (
unsigned int h = 0;
h <
k->mdtHitsOnTrack();
h++) {
408 k->mdtHOT()[
h]->setDriftRadius(tmp_rt->
radius(
k->mdtHOT()[
h]->driftTime()),
409 k->mdtHOT()[
h]->sigmaDriftRadius());
410 if (
k->mdtHOT()[
h]->sigmaDriftRadius() < 0.5 *
m_r_max) {
411 avres = avres +
k->mdtHOT()[
h]->sigma2DriftRadius();
416 avres = avres /
static_cast<double>(
k->mdtHitsOnTrack());
417 avres = std::sqrt(avres);
418 if (
k->mdtHitsOnTrack() > 3) {
428 log << MSG::WARNING <<
"analyseSegments() - no smoothing applied due to too small number of reconstructed segments" <<
endmsg;
441 RMS = std::sqrt(0.01 *
RMS);
447 tmp_rt = std::make_shared<RtRelationLookUp>(smooth_rt);
454 m_output = std::make_shared<RtCalibrationOutput>(
482 if (std::abs(seg.
direction().y()) > 100)
return true;
491 double chi2_scale_factor;
497 unsigned int nb_hits_in_ml[2];
499 std::vector<double> d_track;
500 std::vector<double> residual_value;
501 std::vector<MTStraightLine>
w;
507 std::vector<double> zeta;
519 nb_hits_in_ml[0] = 0;
520 nb_hits_in_ml[1] = 0;
523 aux_res = seg.
mdtHOT()[
k]->sigmaDriftRadius();
524 if (
m_rt->radius(seg.
mdtHOT()[
k]->driftTime()) < 0.5) {
525 if (aux_res < 0.5 - m_rt->
radius(seg.
mdtHOT()[
k]->driftTime())) { aux_res = 0.5 -
m_rt->radius(seg.
mdtHOT()[
k]->driftTime()); }
538 av_res = av_res + 0.01;
542 (hit_selection[0])[
k] = 0;
553 (hit_selection[0])[
k] = 1;
554 (hit_selection[1])[
k] = 1;
558 nb_hits_in_ml[0] = nb_hits_in_ml[0] + (1 - (hit_selection[0])[
k]);
559 nb_hits_in_ml[1] = nb_hits_in_ml[1] + (1 - (hit_selection[1])[
k]);
567 av_res = std::sqrt(av_res /
static_cast<double>(seg.
mdtHitsOnTrack()));
583 if (nb_hits_in_ml[
k] < 3) {
continue; }
590 if (std::isnan(
track.a_x1()) || std::isnan(
track.a_x2()) || std::isnan(
track.b_x1()) || std::isnan(
track.b_x2())) {
continue; }
593 if (
track.chi2PerDegreesOfFreedom() > 5 * chi2_scale_factor) {
continue; }
597 if (
track.numberOfTrackHits() < 3) {
continue; }
600 if (std::abs(
track.a_x2()) > 8e8)
continue;
614 d_track = std::vector<double>(
track.numberOfTrackHits());
615 residual_value = std::vector<double>(
track.numberOfTrackHits());
616 w = std::vector<MTStraightLine>(
track.numberOfTrackHits());
617 G = CLHEP::HepVector(
track.numberOfTrackHits());
618 zeta = std::vector<double>(
track.numberOfTrackHits());
622 m_U[
l] = CLHEP::HepVector(
track.numberOfTrackHits());
623 for (
unsigned int m = 0;
m <
track.numberOfTrackHits();
m++) {
630 for (
unsigned int l = 0;
l <
track.numberOfTrackHits();
l++) {
634 d_track[
l] =
track.signDistFrom(
w[
l]);
635 residual_value[
l] =
track.trackHits()[
l]->driftRadius() - std::abs(d_track[
l]);
640 for (
unsigned int l = 0;
l <
track.numberOfTrackHits();
l++) {
642 for (
unsigned int m = 0;
m <
track.numberOfTrackHits();
m++) {
643 zeta[
m] = std::sqrt(1.0 +
std::pow(
track.a_x2(), 2)) * (
w[
m].positionVector()).
z() -
track.a_x2() * d_track[
m];
645 for (
unsigned int m = 0;
m <
track.numberOfTrackHits();
m++) {
646 double sum1(0.0), sum2(0.0), sum3(0.0), sum4(0.0);
647 for (
unsigned int ll = 0;
ll <
track.numberOfTrackHits();
ll++) {
648 sum1 = sum1 + (zeta[
l] - zeta[
ll]) * (zeta[
ll] - zeta[
m]) /
649 (
track.trackHits()[
m]->sigma2DriftRadius() *
track.trackHits()[
ll]->sigma2DriftRadius());
650 sum2 = sum2 + zeta[
ll] /
track.trackHits()[
ll]->sigma2DriftRadius();
651 sum3 = sum3 + 1.0 /
track.trackHits()[
ll]->sigma2DriftRadius();
654 if (d_track[
m] * d_track[
l] >= 0.0) {
660 CLHEP::HepSymMatrix A_tmp(
m_A);
663 for (
unsigned int pp =
p; pp <
m_order; pp++) {
665 if (std::isnan(A_tmp[
p][pp]))
return true;
669 CLHEP::HepVector b_tmp(
m_b);
671 b_tmp[
p] =
m_b[
p] - residual_value[
l] *
dot(
G,
m_U[
p]) /
track.trackHits()[
l]->sigma2DriftRadius();
672 if (std::isnan(b_tmp[
p]))
return true;
697 if (
input ==
nullptr) {
698 throw std::runtime_error(
699 Form(
"File: %s, Line: %d\nRtCalibrationAnalytic::setInput - Calibration input class not supported.", __FILE__, __LINE__));
722 if (!rt_Chebyshev && !rt_LookUp) {
723 throw std::runtime_error(
724 Form(
"File: %s, Line: %d\nRtCalibrationAnalytic::setInput - r-t class not supported.", __FILE__, __LINE__));
729 m_t_length = rt_Chebyshev->tUpper() - rt_Chebyshev->tLower();
730 m_t_mean = 0.5 * (rt_Chebyshev->tLower() + rt_Chebyshev->tUpper());
735 m_t_length = rt_LookUp->par(1) * (rt_LookUp->nPar() - 2) - rt_LookUp->par(0);
736 m_t_mean = 0.5 * (rt_LookUp->par(1) * (rt_LookUp->nPar() - 2) + rt_LookUp->par(0));
747 unsigned int nb_points(30);
752 std::vector<double> rt_param(
m_rt->nPar());
761 log << MSG::WARNING <<
"analyse() - Could not solve the autocalibration equation!" <<
endmsg;
772 if (rt_Chebyshev->numberOfRtParameters() > 30) { nb_points = rt_Chebyshev->numberOfRtParameters(); }
778 std::vector<SamplePoint> x_r(nb_points + 1);
783 for (
unsigned int k = 0;
k < nb_points + 1;
k++) {
785 x_r[
k].set_x2(rt_Chebyshev->radius(x_r[
k].x1()));
786 x_r[
k].set_x1(rt_Chebyshev->getReducedTime(x_r[
k].x1()));
787 x_r[
k].set_error(1.0);
799 x_r[
k].set_error(0.01);
801 x_r[
k].set_x2(x_r[
k].
x2() + r_corr);
806 for (
unsigned int k = 0;
k < nb_points;
k++) {
807 if (x_r[
k].
x2() > x_r[
k + 1].
x2()) { x_r[
k + 1].set_x2(x_r[
k].
x2()); }
812 std::unique_ptr<TGraphErrors> gre = std::make_unique<TGraphErrors>(x_r.size());
813 for (
unsigned int i = 0;
i < 1;
i++) {
814 gre->SetPoint(
i, x_r[
i].
x1(), x_r[
i].
x2());
815 gre->SetPointError(
i, 0, x_r[
i].
error());
817 std::ostringstream str_str;
819 gre->Write(str_str.str().c_str());
823 fitter.fit_parameters(x_r, 1, nb_points + 1, chebyshev);
824 rt_param[0] = rt_Chebyshev->tLower();
825 rt_param[1] = rt_Chebyshev->tUpper();
826 for (
unsigned int k = 0;
k < rt_Chebyshev->numberOfRtParameters();
k++) { rt_param[
k + 2] =
fitter.coefficients()[
k]; }
828 m_rt_new = std::make_unique<RtChebyshev>(rt_param);
833 rt_param = rt_LookUp->parameters();
834 unsigned int min_k(2), max_k(rt_param.size());
836 if (
m_fix_max) { max_k = rt_param.size() - 1; }
838 std::unique_ptr<TGraph>
gr;
841 for (
unsigned int k = min_k;
k < max_k;
k++) {
845 rt_param[
k] = rt_param[
k] + r_corr;
848 if (rt_param[
k] < rt_param[
k - 1]) { rt_param[
k] = rt_param[
k - 1]; }
852 m_rt_new = std::make_unique<RtRelationLookUp>(rt_param);
854 std::ostringstream str_str;
856 gr->Write(str_str.str().c_str());
867 double r_corr_max = 0.0;
869 for (
unsigned int k = 0;
k < 100;
k++) {
872 if (std::abs(r_corr) > r_corr_max) { r_corr_max = std::abs(r_corr); }
900 m_output = std::make_shared<RtCalibrationOutput>(
913 std::shared_ptr<RtRelationLookUp> rt_low, rt_high;
916 std::vector<SamplePoint> add_fit_point;
923 add_fit_point.clear();
930 rt_high = std::make_shared<RtRelationLookUp>(
939 add_fit_point.clear();
953 if (
min &&
max) {
return rt_low; }
954 if (
min) {
return rt_low; }