ATLAS Offline Software
Loading...
Searching...
No Matches
MultilayerRtDifference.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7// MuonCalibEventBase
9
10// MdtCalibFitters
13
14// MdtCalibData
16#include "GaudiKernel/MsgStream.h"
19
20// root
21#include "TDirectory.h"
22#include "TF1.h"
23#include "TF2.h"
24#include "TH2F.h"
25#include "TProfile.h"
26
27// std
28#include "cmath"
29#include "iostream"
30#include "sstream"
31#include "utility"
32
33namespace MuonCalib {
34
35 Double_t MultilayerRtDifference_ScaleFunction(Double_t *x, Double_t *par) { return par[0] * RtScalePolynomial(x[0]); }
36
38 public:
39 inline MultilayerRtDifference_Histograms(TDirectory *control_histogram_dir);
43 inline TH2F *GetResHist(const int &ml);
44 inline TProfile *GetProfileDiff(const int &min_number_of_entries);
45
46 private:
47 std::list<TH2F *> m_residuals[2];
49 std::list<TProfile *> m_res_prov[2];
50 std::list<TProfile *> m_res_prov_diff;
52 };
53
55 m_control_histogram_dir(control_histogram_dir) {
56 for (auto & current_residual : m_current_residuals) { current_residual = nullptr; }
57 }
58
59 // copy constructor to keep Coverity happy
61 for (int i = 0; i < 2; i++) {
62 for (auto *res : MLRTDH.m_residuals[i]) { m_residuals[i].push_back(new TH2F(*res)); }
63 m_current_residuals[i] = new TH2F(*(MLRTDH.m_current_residuals[i]));
64 for (auto *res : MLRTDH.m_res_prov[i]) { m_res_prov[i].push_back(new TProfile(*res)); }
65 }
66 for (auto *res : MLRTDH.m_res_prov_diff) { m_res_prov_diff.push_back(new TProfile(*res)); }
67 m_control_histogram_dir = MLRTDH.m_control_histogram_dir; // not a deep copy, hope it is ok
68 }
69
71 if (this != &MLRTDH) {
72 for (int i = 0; i < 2; i++) {
73 m_residuals[i] = MLRTDH.m_residuals[i];
75 m_res_prov[i] = MLRTDH.m_res_prov[i];
76 }
79 }
80 return *this;
81 }
82
83 template <typename T> inline void clearall(T &container) {
84 typename T::iterator it = container.begin();
85 for (; it != container.end(); ++it) {
86 delete *it;
87 *it = NULL;
88 }
89 }
90
92 for (unsigned int i = 0; i < 2; i++) {
95 }
97 }
98
100 if (!m_current_residuals[ml]) {
101 for (int i = 0; i < 2; i++) {
102 TDirectory *prevdir = gDirectory;
104 std::ostringstream nm;
105 nm << "temporal_residual_ml" << i << "_iteration" << m_residuals[i].size();
106 m_current_residuals[i] = new TH2F(nm.str().c_str(), "", 15, 0., 15., 200, -100, 100);
108 prevdir->cd();
109 else
110 m_current_residuals[i]->SetDirectory(nullptr);
111 m_residuals[i].push_back(m_current_residuals[i]);
112 }
113 }
114 return m_current_residuals[ml];
115 }
116
117 inline TProfile *MultilayerRtDifference_Histograms::GetProfileDiff(const int &min_number_of_entries) {
118 TDirectory *prev = gDirectory;
120 bool ok(true);
121 TProfile *prof[2];
122 for (unsigned int i = 0; i < 2; i++) {
123 if (m_current_residuals[i] && m_current_residuals[i]->GetEntries() >= min_number_of_entries) {
124 prof[i] = m_current_residuals[i]->ProfileX();
125 if (!m_control_histogram_dir) { prof[i]->SetDirectory(nullptr); }
126 } else {
127 prof[i] = nullptr;
128 ok = false;
129 }
130 m_res_prov[i].push_back(prof[i]);
131 m_current_residuals[i] = nullptr;
132 }
133 if (!ok) {
134 prev->cd();
135 m_res_prov_diff.push_back(nullptr);
136 return nullptr;
137 }
138 std::ostringstream nm;
139 nm << "res_prov_diff_step" << m_res_prov_diff.size();
140 TProfile *prov_diff = new TProfile(nm.str().c_str(), "", 15, 0., 15.);
141 prov_diff->Add(prof[0], prof[1], 1., -1);
142 m_res_prov_diff.push_back(prov_diff);
143 if (!m_control_histogram_dir) { prov_diff->SetDirectory(nullptr); }
144 return prov_diff;
145 }
146
147 MultilayerRtDifference::MultilayerRtDifference(int min_hits, TDirectory *control_histogram_dir) :
148 m_histograms(new MultilayerRtDifference_Histograms(control_histogram_dir)), m_min_number_of_hits(min_hits) {
149 m_polfun = new TF1("polfun", MultilayerRtDifference_ScaleFunction, 4.0, 15.0, 1);
150 }
151
152 // Copy constructor, to keep Coverity happy
157
158 // Assignment operator, for Coverity happiness
160 if (this != &MLRTD) {
162 delete m_polfun;
163 m_polfun = new TF1(*MLRTD.m_polfun);
164 delete m_histograms;
166 }
167 return *this;
168 }
169
174
175 void MultilayerRtDifference::Fill(const MdtCalibHitBase &hit, const IRtRelation &rt_relation) {
176 int ml = hit.identify().mdtMultilayer() - 1;
177 double r_track = std::abs(hit.signedDistanceToTrack());
178 double res = std::abs(hit.driftRadius()) - r_track;
179 double v = rt_relation.driftVelocity(hit.driftTime());
180 m_histograms->GetResHist(ml)->Fill(r_track, res / v);
181 }
182
184 TProfile *prov_diff = m_histograms->GetProfileDiff(m_min_number_of_hits);
185 if (!prov_diff) {
186 MsgStream log(Athena::getMessageSvc(), "MultilayerRtDifference");
187 log << MSG::WARNING << "MultilayerRtDifference::DoFit: Not enough hits!" << endmsg;
188 return false;
189 }
190 if (prov_diff->Fit("polfun", "Q", "", 4., 15.) != 0) {
191 MsgStream log(Athena::getMessageSvc(), "MultilayerRtDifference");
192 log << MSG::WARNING << "MultilayerRtDifference: Fit of polinomial failed! Not updating scale!" << endmsg;
193 return false;
194 }
195 if (std::abs(m_polfun->GetParameter(0)) < m_polfun->GetParError(0)) {
196 MsgStream log(Athena::getMessageSvc(), "MultilayerRtDifference");
197 log << MSG::WARNING << "MultilayerRtDifference: No Scale update needed! Scale correction: " << m_polfun->GetParameter(0)
198 << " +- " << m_polfun->GetParError(0) << endmsg;
199 return true;
200 }
201 if (!rt_relation) return true;
202 float scale = m_polfun->GetParameter(0);
203 if (std::abs(scale) > 2) scale *= 4;
204 if (rt_relation->hasTmaxDiff()) { scale += rt_relation->GetTmaxDiff(); }
205 rt_relation->SetTmaxDiff(scale);
206 if (seg.empty()) return true;
207 // update input segments
208 for (const auto &segment : seg) {
209 for (const MuonCalibSegment::MdtHitPtr &hit : segment->mdtHOT()) {
210 float old_corr = hit->TemperatureTime();
211 float corr = RtScaleFunction(hit->driftTime(), hit->identify().mdtMultilayer() == 2, *rt_relation);
212 hit->setTemperatureTime(corr);
213 hit->setDriftTime(hit->driftTime() - corr + old_corr);
214 hit->setDriftRadius(rt_relation->radius(hit->driftTime()), hit->sigmaDriftRadius());
215 }
216 }
217 return true;
218 }
219
220} // namespace MuonCalib
#define endmsg
std::pair< std::vector< unsigned int >, bool > res
TGraphErrors * GetEntries(TH2F *histo)
#define x
std::vector< std::shared_ptr< MuonCalibSegment > > MuonSegVec
generic interface for a rt-relation
Definition IRtRelation.h:19
virtual double radius(double t) const =0
returns drift radius for a given time
double GetTmaxDiff() const
return the difference in total dirft time between the two multilayers (ML1 - ML2)
Definition IRtRelation.h:40
void SetTmaxDiff(const double d)
set the difference in total drift time betwene the two multilayers (ML1 - ML2)
Definition IRtRelation.h:45
bool hasTmaxDiff() const
Definition IRtRelation.h:42
virtual double driftVelocity(double t) const =0
Returns the drift velocity for a given time.
Athena-independent part of the MdtCalibHit.
float driftRadius() const
retrieve the radius of the drift circle
float driftTime() const
retrieve the drift time
const MuonFixedId & identify() const
retrieve the MuonFixedId of the hit
float signedDistanceToTrack() const
retrieve the distance of the track to the wire
TProfile * GetProfileDiff(const int &min_number_of_entries)
MultilayerRtDifference_Histograms & operator=(const MultilayerRtDifference_Histograms &MLRTDH)
MultilayerRtDifference_Histograms(TDirectory *control_histogram_dir)
MultilayerRtDifference_Histograms * m_histograms
void Fill(const MdtCalibHitBase &hit, const IRtRelation &rt_relation)
MultilayerRtDifference(int min_hits, TDirectory *control_histogram_dir=NULL)
bool DoFit(IRtRelation *rt_relation, const IMdtCalibration::MuonSegVec &seg)
MultilayerRtDifference & operator=(const MultilayerRtDifference &MLRTD)
std::shared_ptr< MdtCalibHitBase > MdtHitPtr
typedef for a collection of MdtCalibHitBase s
int mdtMultilayer() const
Mdt specific:
singleton-like access to IMessageSvc via open function and helper
IMessageSvc * getMessageSvc(bool quiet=false)
CscCalcPed - algorithm that finds the Cathode Strip Chamber pedestals from an RDO.
Double_t MultilayerRtDifference_ScaleFunction(Double_t *x, Double_t *par)
void clearall(T &container)
float RtScalePolynomial(const float r)
float RtScaleFunction(const float t, const bool ml2, const IRtRelation &rtrelation)