ATLAS Offline Software
Loading...
Searching...
No Matches
RtCalibrationIntegration.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <algorithm>
8#include <fstream>
9#include <iostream>
10
12#include "GaudiKernel/MsgStream.h"
15
18#include "TF1.h"
19#include "TList.h"
20
21using namespace MuonCalib;
22
23inline Double_t slope_function_C(Double_t *x, Double_t *par) {
24 Double_t &t(x[0]);
25 Double_t &a(par[0]), &b(par[1]), &t_0(par[2]), &back(par[3]);
26 return back + std::exp(a + b * (t - t_0));
27}
28
29inline void update_parameter_on_mttmax(TH1 *h, TF1 *f, const float &b, const float &T, const T0MTSettingsTMax &tmax_settings) {
30 Double_t rmin, rmax;
31 f->GetRange(rmin, rmax);
32 std::unique_ptr<TF1> slope_function =
33 std::make_unique<TF1>("slope_function", slope_function_C, rmin, rmin + tmax_settings.WidthAB(), 4);
34 slope_function->SetParameter(0, f->GetParameter(T0MTHistos::TMAX_PAR_NR_A));
35 slope_function->FixParameter(1, b);
36 slope_function->FixParameter(2, f->GetParameter(T0MTHistos::TMAX_PAR_NR_T0));
37 slope_function->FixParameter(3, f->GetParameter(T0MTHistos::TMAX_PAR_NR_BACK));
38 h->Fit("slope_function", "R+", "");
39 f->FixParameter(T0MTHistos::TMAX_PAR_NR_A, slope_function->GetParameter(0));
40 f->FixParameter(T0MTHistos::TMAX_PAR_NR_B, b);
41 f->FixParameter(T0MTHistos::TMAX_PAR_NR_T, T);
42}
43void RtCalibrationIntegration::init(bool close_hits, double r_max, double lower_extrapolation_radius, double upper_extrapolation_radius,
44 bool add_tmax_difference) {
45 m_close_hits = close_hits;
46 m_rt = nullptr;
47 m_r_max = r_max;
48 m_lower_extrapolation_radius = lower_extrapolation_radius;
49 m_upper_extrapolation_radius = upper_extrapolation_radius;
50 m_output = nullptr;
53 m_add_tmax_difference = add_tmax_difference;
54 return;
55}
57
59 for (const auto & k : seg) { handleSegment(*k); }
60 m_nb_segments_used = seg.size();
61 analyse();
62
63 return getResults();
64}
67 // LOOP OVER THE HITS OF THE SEGMENTS AND STORE THEM //
69
70 // start with hits on the segment //
71 for (unsigned int k = 0; k < seg.mdtHitsOnTrack(); k++) {
72 if (seg.mdtHOT()[k]->driftTime() < -8e8) continue;
73 m_t_drift.push_back(std::pair<double, bool>(seg.mdtHOT()[k]->driftTime(), seg.mdtHOT()[k]->identify().mdtMultilayer() == 2));
74 }
75
76 // continue with close hits if requested //
77 if (m_close_hits == true) {
78 for (unsigned int k = 0; k < seg.mdtCloseHits(); k++) {
79 m_t_drift.push_back(std::pair<double, bool>(seg.mdtHOT()[k]->driftTime(), seg.mdtHOT()[k]->identify().mdtMultilayer() == 2));
80 }
81 }
82
83 return true;
84}
85
86void RtCalibrationIntegration::setInput(const IMdtCalibrationOutput * /*rt_input*/) { return; }
89 // VARIABLES //
91
92 T0MTSettings t0_setting; // settings of the MT t0 fitter
93 t0_setting.AddFitfun() = true;
94 // t0_setting.DrawDebugGraphs()=true;
95 t0_setting.T0Settings()->ScrambleThreshold() = 2;
96 t0_setting.T0Settings()->SlicingThreshold() = 3;
97 t0_setting.TMaxSettings()->DistAB() += 50;
98 T0MTHistos drift_time_spec; // drift time spectrum used in the t0 and
99 // the tmax fit
100 std::array<T0MTHistos, 2> drift_time_spec_ml;
101
102 double t0, tmax; // t0 and tmax
103 int k_min(-1); //, k_max(-1); // first and last drift-time entry to be
104 // used in the integration procedure
105 unsigned int nb_bins(100); // number of integration bins
106 double bin_content; // number of entries per bin
107 std::vector<SamplePoint> point(nb_bins + 1); // (t, r) points
108 double radius(0.0); // r(t)
109 double scf = 0.; // scale factor (r_max/number of used hits)
110 RtFromPoints rt_from_points; // r-t converter
111
113 // STOP HERE, IF THERE ARE NOT ENOUGH ENTRIES IN THE DRIFT-TIME SPECTRUM //
115
116 if (m_t_drift.size() < 2000) {
117 MsgStream log(Athena::getMessageSvc(), "RtCalibrationIntegration");
118 log << MSG::WARNING << "analyse() - Less than 2000 drift-time entries! No r-t relationship will be determined!" << endmsg;
119 return false;
120 }
121
123 // INTEGRATION METHOD //
125
126 // sort the hits in ascending order of their drift times //
127 sort(m_t_drift.begin(), m_t_drift.end());
128
129 // perform a t0 and tmax fit //
130 // fill the histogram with the drift-time spectrum //
131 int n_bins = static_cast<int>(32 * (200.0 + m_t_drift[m_t_drift.size() - 1].first - m_t_drift[0].first) / 25.0);
132 float min_t = m_t_drift[0].first - 100.0;
133 float max_t = m_t_drift[m_t_drift.size() - 1].first + 100.0;
134 std::unique_ptr<TH1F> tspec = std::make_unique<TH1F>("tspec", "DRIFT-TIME SPECTRUM", n_bins, min_t, max_t);
135 std::array<std::unique_ptr<TH1F>, 2> tspec_ml;
136 tspec_ml[0] = std::make_unique<TH1F>("tspec_ml0", "DRIFT-TIME SPECTRUM ML 0", n_bins, min_t, max_t);
137 tspec_ml[1] = std::make_unique<TH1F>("tspec_ml1", "DRIFT-TIME SPECTRUM ML 1", n_bins, min_t, max_t);
138
139 for (auto & k : m_t_drift) {
140 tspec->Fill(k.first, 1.0);
141 tspec_ml[static_cast<unsigned int>(k.second)]->Fill(k.first, 1.0);
142 }
143 drift_time_spec.SetTSpec(1, tspec.get(), &t0_setting, false);
144 drift_time_spec_ml[0].SetTSpec(2, tspec_ml[0].get(), &t0_setting, false);
145 drift_time_spec_ml[1].SetTSpec(3, tspec_ml[1].get(), &t0_setting, false);
146
147 // t0 and tmax fits //
148
149 if (!drift_time_spec.FitT0() || !drift_time_spec.T0Ok()) {
150 MsgStream log(Athena::getMessageSvc(), "RtCalibrationIntegration");
151 log << MSG::WARNING << "analyse() - t0 fit not successful, no r-t relationship will be calculated!" << endmsg;
152 return false;
153 }
154 t0 = drift_time_spec.GetT0Function()->GetParameter(T0MTHistos::T0_PAR_NR_T0);
155
156 if (!drift_time_spec.FitTmax() || !drift_time_spec.TmaxOk()) {
157 MsgStream log(Athena::getMessageSvc(), "RtCalibrationIntegration");
158 log << MSG::WARNING << "analyse() - tmax fit not successful, no r-t relationship will be calculated!" << endmsg;
159 return false;
160 }
161 tmax = drift_time_spec.GetTMaxFunction()->GetParameter(T0MTHistos::TMAX_PAR_NR_TMAX) +
162 2.0 * drift_time_spec.GetTMaxFunction()->GetParameter(T0MTHistos::TMAX_PAR_NR_T);
163
164 // determine (t,r) points by integration //
165 m_nb_hits_used = 0;
166 for (unsigned int k = 0; k < m_t_drift.size(); k++) {
167 if (m_t_drift[k].first >= t0 && m_t_drift[k].first <= tmax) { m_nb_hits_used++; }
168 if (k_min < 0 && m_t_drift[k].first >= t0) { k_min = k; }
169 }
170 // k_max = k_min+m_nb_hits_used-1;
171
172 bin_content = static_cast<double>(m_nb_hits_used) / static_cast<double>(nb_bins);
173
174 if (m_nb_hits_used > 0) { scf = m_r_max / static_cast<double>(m_nb_hits_used); }
175
176 point[0].set_x1(t0);
177 point[0].set_x2(0.0);
178 point[0].set_error(0.1); // give a higher weight to the end point in
179
180 // the final fit
181 for (unsigned int k = 1; k < nb_bins; k++) {
182 radius = radius + scf * bin_content;
183 point[k].set_x1(m_t_drift[k_min + static_cast<int>(bin_content) * (k)].first);
184 point[k].set_x2(radius);
185 point[k].set_error(1.0);
186 }
187
188 point[nb_bins].set_x1(tmax);
189 point[nb_bins].set_x2(m_r_max);
190 point[nb_bins].set_error(1.);
191
192 // get the r-t relationship //
193 m_rt = rt_from_points.getRtChebyshev(point, 15);
194
196 // PARABOLIC EXTRAPOLATION FOR LARGE DRIFT RADII //
198 std::vector<SamplePoint> add_fit_point; // additional r-t points for r(t_max)
199 add_fit_point.push_back(SamplePoint(tmax, m_r_max, 1.0));
200 RtParabolicExtrapolation rt_extrapolated;
202 m_upper_extrapolation_radius, m_r_max, add_fit_point));
203 std::shared_ptr<IRtRelation> rt_new = std::make_shared<RtRelationLookUp>(tmp_rt);
204
206 // Get length difference between multilayers //
208
209 if (tspec_ml[0]->GetEntries() >= 10000 && tspec_ml[0]->GetEntries() > 10000) {
210 bool fit_ok(true);
211 std::array<float, 2> b{}, tmax{}, T{};
212 for (unsigned int i = 0; i < 2; i++) {
213 if (!drift_time_spec_ml[i].FitT0()) {
214 fit_ok = false;
215 break;
216 }
217 if (!drift_time_spec_ml[i].FitTmax()) {
218 fit_ok = false;
219 break;
220 }
221 b[i] = drift_time_spec_ml[i].GetTMaxFunction()->GetParameter(T0MTHistos::TMAX_PAR_NR_B);
222 tmax[i] = drift_time_spec_ml[i].GetTMaxFunction()->GetParameter(T0MTHistos::TMAX_PAR_NR_TMAX) -
223 drift_time_spec_ml[i].GetT0Function()->GetParameter(T0MTHistos::T0_PAR_NR_T0);
224 T[i] = drift_time_spec_ml[i].GetTMaxFunction()->GetParameter(T0MTHistos::TMAX_PAR_NR_T);
225 }
226 if (fit_ok) {
227 int refit = static_cast<int>((b[1] + 1.33717e-03) > (b[0] + 1.33717e-03));
228 int norefit = static_cast<bool>(refit) ? 0 : 1;
229 TF1 *fixfun = drift_time_spec_ml[refit].GetTMaxFunctionNC();
230 fixfun->FixParameter(T0MTHistos::TMAX_PAR_NR_B, b[norefit]);
231 update_parameter_on_mttmax(drift_time_spec_ml[refit].GetTSpec(), fixfun, b[norefit], T[norefit], *t0_setting.TMaxSettings());
232 TList *l = drift_time_spec_ml[refit].GetTSpec()->GetListOfFunctions();
233 l->Remove(l->FindObject("mt_tmax_fermi"));
234 fit_ok = drift_time_spec_ml[refit].FitTmax();
235 tmax[refit] = drift_time_spec_ml[refit].GetTMaxFunction()->GetParameter(T0MTHistos::TMAX_PAR_NR_TMAX) -
236 drift_time_spec_ml[refit].GetT0Function()->GetParameter(T0MTHistos::T0_PAR_NR_T0);
237 }
238
239 if (fit_ok && m_add_tmax_difference) rt_new->SetTmaxDiff(tmax[0] - tmax[1]);
240 }
241
243 // STORE THE RESULTS IN THE RtCalibrationOutput //
245
246 m_output = std::make_unique<RtCalibrationOutput>(
247 rt_new, std::make_shared<RtFullInfo>("RtCalibrationIntegration", 1, m_nb_segments_used, 0.0, 0.0, 0.0, 0.0));
248
249 return true;
250}
251
252//*****************************************************************************
253
254//::::::::::::::::::::::
255//:: METHOD converged ::
256//::::::::::::::::::::::
257
258bool RtCalibrationIntegration::converged() const { return (m_output != nullptr); }
259
260//*****************************************************************************
261
262//:::::::::::::::::::::::
263//:: METHOD getResults ::
264//:::::::::::::::::::::::
#define endmsg
static Double_t a
static Double_t t0
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
Double_t slope_function_C(Double_t *x, Double_t *par)
void update_parameter_on_mttmax(TH1 *h, TF1 *f, const float &b, const float &T, const T0MTSettingsTMax &tmax_settings)
TGraphErrors * GetEntries(TH2F *histo)
#define x
Header file for AthHistogramAlgorithm.
Interface to pass calibration output during calibration.
std::shared_ptr< IMdtCalibrationOutput > MdtCalibOutputPtr
std::vector< std::shared_ptr< MuonCalibSegment > > MuonSegVec
A MuonCalibSegment is a reconstructed three dimensional track segment in the MuonSpectrometer.
unsigned int mdtHitsOnTrack() const
retrieve the number of MdtCalibHitBase s assigned to this segment
unsigned int mdtCloseHits() const
retrieve the number of nearby mdt hits.
const MdtHitVec & mdtHOT() const
retrieve the full set of MdtCalibHitBase s assigned to this segment
MdtCalibOutputPtr analyseSegments(const MuonSegVec &seg) override
determine r(t)
double m_lower_extrapolation_radius
sets the lower radius to perform the
void setInput(const IMdtCalibrationOutput *rt_input) override
the method is empty as no initial r-t relationship is required by the algorithm
double m_upper_extrapolation_radius
parabolic extrapolation.
bool analyse()
perform the integration method
bool converged() const
returns true, if the integration method has been performed
std::shared_ptr< RtCalibrationOutput > m_output
std::vector< std::pair< double, bool > > m_t_drift
bool handleSegment(MuonCalibSegment &seg)
analyse the segment "seg"
unsigned int number_of_hits_used() const
get the number of hits used in the r-t determination
void init(bool close_hits, double r_max, double lower_extrapolation_radius, double higher_extrapolation_radius, bool add_tmax_difference)
MdtCalibOutputPtr getResults() const override
returns the final r-t relationship
This class allows the user to retrieve an RtChebyshev or RtRelationLookUp object corresponding to a s...
static std::unique_ptr< IRtRelation > getRtChebyshev(const std::vector< SamplePoint > &dataPoints, const unsigned order)
Converts a list of r-t data points into a r(t) relation expressed as a series of chebychev polynomial...
RtRelationLookUp getRtWithParabolicExtrapolation(const IRtRelation &in_rt, const double r_min=13.0, const double r_max=14.0) const
get an r-t relationship which is equivalent to the input relationship in_rt for r<r_min and has r(t) ...
Equidistant look up table for rt-relations with the time as key.
This class provides a sample point for the BaseFunctionFitter.
Definition SamplePoint.h:15
Histogram and fitter class for drift time and pulsehight spectra The rising slope is fitted by a ferm...
Definition T0MTHistos.h:40
static constexpr int T0_PAR_NR_T0
parameter numbers in t0 fit
Definition T0MTHistos.h:57
static constexpr int TMAX_PAR_NR_TMAX
parameters numbers for tmax fit
Definition T0MTHistos.h:61
static constexpr int TMAX_PAR_NR_T0
Definition T0MTHistos.h:62
bool T0Ok() const
returns true if t0-fit was successfull
Definition T0MTHistos.h:100
static constexpr int TMAX_PAR_NR_T
Definition T0MTHistos.h:61
static constexpr int TMAX_PAR_NR_B
Definition T0MTHistos.h:61
static constexpr int TMAX_PAR_NR_BACK
Definition T0MTHistos.h:61
bool FitT0()
Perform t0-fit Returns true if fit is successfull.
bool FitTmax()
Performs tmax-fit Returns true if fit is successfull.
void SetTSpec(int id, TH1F *spec, const T0MTSettings *settings, bool copy_spec=true)
set the pointer of the drift-time spectrum to an existing spectrum.
const TF1 * GetT0Function() const
returns function fitted to the riding edge of the spectrum
Definition T0MTHistos.h:104
static constexpr int TMAX_PAR_NR_A
Definition T0MTHistos.h:61
bool TmaxOk() const
returns true if tmax-fir was successfull
Definition T0MTHistos.h:108
const TF1 * GetTMaxFunction() const
returns function fitted to the riding edge of the spectrum
Definition T0MTHistos.h:110
double SlicingThreshold() const
the chi2 threshold at which the slicing method is used
double ScrambleThreshold() const
the chi2 threshold at which the scrambling method is used
double DistAB() const
Distance of the a/b region from the detected falling edge.
double WidthAB() const
Width of the region in which the parameters a and b are estimated.
Settings for the T0 calibration (histogram booking and fitting parameters) Parameters for pattern rec...
const bool & AddFitfun() const
If set to true the fitted functions are added to the histograms.
const T0MTSettingsT0 * T0Settings() const
get settings for the t0-fit
const T0MTSettingsTMax * TMaxSettings() const
get settings for the tmax-fit
singleton-like access to IMessageSvc via open function and helper
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:130
IMessageSvc * getMessageSvc(bool quiet=false)
CscCalcPed - algorithm that finds the Cathode Strip Chamber pedestals from an RDO.