ATLAS Offline Software
CurvedPatRec.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include <TString.h> // for Form
8 
10 #include "GaudiKernel/MsgStream.h"
13 #include "cmath"
14 #include "time.h"
15 using namespace MuonCalib;
16 CurvedPatRec::CurvedPatRec() = default;
17 
18 CurvedPatRec::CurvedPatRec(const double road_width) { m_road_width = road_width; }
19 
20 double CurvedPatRec::roadWidth() const { return m_road_width; }
21 void CurvedPatRec::setRoadWidth(const double r_road_width) { m_road_width = r_road_width; }
22 void CurvedPatRec::setTimeOut(const double time_out) { m_time_out = time_out; }
23 bool CurvedPatRec::fit(MuonCalibSegment &r_segment) const {
24  // select all hits //
25  HitSelection selection(r_segment.mdtHitsOnTrack(), 0);
26  // call the other fit function //
27  return fit(r_segment, selection);
28 }
29 bool CurvedPatRec::fit(MuonCalibSegment &r_segment, HitSelection r_selection) const {
30  CurvedLine curved_track;
31  return fit(r_segment, r_selection, curved_track);
32 }
33 bool CurvedPatRec::fit(MuonCalibSegment &r_segment, HitSelection r_selection, CurvedLine &curved_track) const {
35  // VARIABLES //
37  std::unique_ptr<StraightPatRec> sfitter = std::make_unique<StraightPatRec>();
38  time_t start, end; // start and end times (needed for time-out)
39  double diff; // difference of start and end time (needed for time-out)
40  Combination combination;
41  std::vector<unsigned int> hit_index; // hit indices for a given combination
42  unsigned int try_nb_hits; // try to find a segment with try_nb_hits hits
43  bool segment_found(false); // flag indicating the a segment has been found
44  MdtHitVec cand_track_hits; // vector of the track hits
45  // found so far
46  CurvedLine aux_line; // memory for reconstructed curved lines
47  Amg::Vector3D null(0.0, 0.0, 0.0);
48  Amg::Vector3D xhat(1.0, 0.0, 0.0);
49  std::vector<Amg::Vector3D> points; // hit points for the track fit
50  MdtHitVec loc_track_hits; // track hit store
51 
53  // RESETS //
55  time(&start);
56 
58  // CHECK SIZE OF THE SELECTION VECTOR //
60 
61  if (r_selection.size() != r_segment.mdtHitsOnTrack()) {
62  throw std::runtime_error(
63  Form("File: %s, Line: %d\nCurvedPatRec::fit - Size of selection vector does not match the number of hits on track!", __FILE__,
64  __LINE__));
65  }
66 
68  // PREPARATORY WORK //
70 
71  // perform a straight track fit to get an estimate of the incidence angle //
72  Amg::Vector3D est_dir(0.0, 0.0, 1.0);
73  sfitter->setRoadWidth(2.0 * m_road_width);
74  sfitter->setTimeOut(0.5 * m_time_out);
76  if (sfitter->fit(r_segment, r_selection, track)) { est_dir = track.directionVector(); }
77 
78  // store track hits //
79  unsigned int k = 0;
80  for (const MuonCalibSegment::MdtHitPtr &hit : r_segment.mdtHOT()) {
81  if (r_selection[k] == 0 && hit->sigmaDriftRadius() < 100) { loc_track_hits.push_back(hit); };
82  ++k;
83  }
84 
85  // return, if there are too few hits //
86  if (loc_track_hits.size() < 4) { return false; }
88  // PATTERN RECOGNITION //
90 
91  // try to find a segment with as many hits on it as possible //
92  try_nb_hits = loc_track_hits.size();
93 
94  MdtHitVec stored_track_hits;
95  double chi2 = -1.;
96 
97  while (!segment_found && try_nb_hits > 3) {
98  // loop over the combinations //
99  combination.setNewParameters(loc_track_hits.size(), try_nb_hits);
100  for (unsigned int cb = 0; cb < combination.numberOfCombinations(); cb++) {
101  // time-out //
102  time(&end);
103  diff = difftime(end, start);
104  if (diff > m_time_out) {
105  MsgStream log(Athena::getMessageSvc(), "CurvedPatRec");
106  log << MSG::WARNING << "Class CurvedPatRec, method fit: time-out for track finding after " << m_time_out << " seconds!"
107  << endmsg;
108  return false;
109  }
110 
111  // analyse the hit combination //
112  if (cb == 0) {
113  combination.currentCombination(hit_index);
114  } else {
115  combination.nextCombination(hit_index);
116  }
117  MdtHitVec track_hits;
118  for (unsigned int k = 0; k < try_nb_hits; ++k) { track_hits.push_back(loc_track_hits[hit_index[k] - 1]); }
119 
120  // find candidates //
121  CurvedCandidateFinder finder(track_hits);
122  const std::vector<CurvedLine> candidates(finder.getCandidates(m_road_width, est_dir));
123  if (candidates.empty()) { continue; }
124 
125  segment_found = true;
126 
127  for (const auto & candidate : candidates) {
128  std::vector<Amg::Vector3D> errors(track_hits.size());
129  for (unsigned int k = 0; k < errors.size(); k++) {
130  if (track_hits[k]->sigmaDriftRadius() > 0.0) {
131  errors[k] = Amg::Vector3D(1.0, track_hits[k]->sigmaDriftRadius(), 0.0);
132  } else {
133  errors[k] = Amg::Vector3D(1.0, 1.0, 0.0);
134  }
135  }
136 
137  // get hit points //
138  points = getHitPoints(track_hits, candidate);
139 
140  // fit a curved line through the points //
141  aux_line = CurvedLine(points, errors);
142 
143  // calculate chi^2 //
144  double tmp_chi2(0.0);
145  for (auto & track_hit : track_hits) {
146  MTStraightLine tang(curved_track.getTangent((track_hit->localPosition()).z()));
147  MTStraightLine wire(Amg::Vector3D(0.0, track_hit->localPosition().y(), track_hit->localPosition().z()), xhat,
148  null, null);
149  double d(std::abs(tang.signDistFrom(wire)));
150  if (track_hit->sigma2DriftRadius() != 0) {
151  tmp_chi2 = tmp_chi2 + std::pow(d - track_hit->driftRadius(), 2) / track_hit->sigma2DriftRadius();
152  } else {
153  tmp_chi2 = tmp_chi2 + std::pow(d - track_hit->driftRadius(), 2) / 0.01;
154  }
155  }
156 
157  // compare chi^2 with chi^2 values found so far //
158  if (chi2 < 0 || tmp_chi2 < chi2) {
159  chi2 = tmp_chi2;
160  curved_track = aux_line;
161  // store the track hits //
162  stored_track_hits = track_hits;
163  }
164  }
165  }
166 
167  try_nb_hits = try_nb_hits - 1;
168  }
169 
170  if (!segment_found) { return false; }
171 
173  // SECOND REFINED CURVED FIT //
175 
176  // get hit points //
177  points = getHitPoints(stored_track_hits, curved_track);
178  std::vector<Amg::Vector3D> errors(stored_track_hits.size());
179  for (unsigned int k = 0; k < errors.size(); k++) {
180  if (stored_track_hits[k]->sigmaDriftRadius() > 0.0) {
181  errors[k] = Amg::Vector3D(1.0, stored_track_hits[k]->sigmaDriftRadius(), 0.0);
182  } else {
183  errors[k] = Amg::Vector3D(1.0, 1.0, 0.0);
184  }
185  }
186 
187  // fit a curved line through the points //
188  curved_track = CurvedLine(points, errors);
189 
191  // CALCULATE CHI^2 //
193 
194  chi2 = 0.0;
195  for (auto & stored_track_hit : stored_track_hits) {
196  MTStraightLine tang(curved_track.getTangent((stored_track_hit->localPosition()).z()));
197  MTStraightLine wire(Amg::Vector3D(0.0, stored_track_hit->localPosition().y(), stored_track_hit->localPosition().z()), xhat,
198  null, null);
199  double d(std::abs(tang.signDistFrom(wire)));
200  if (stored_track_hit->sigma2DriftRadius() != 0) {
201  chi2 += std::pow(d - stored_track_hit->driftRadius(), 2) / stored_track_hit->sigma2DriftRadius();
202  } else {
203  chi2 += std::pow(d - stored_track_hit->driftRadius(), 2) / 0.01;
204  }
205  }
206 
208  // UPDATE HIT RESIDUALS //
210 
211  for (const MdtHitPtr& hit : r_segment.mdtHOT()) {
212  Amg::Vector3D pos(0.0, hit->localPosition().y(), hit->localPosition().z());
213  MTStraightLine aux_line(pos, xhat, null, null);
214 
215  MTStraightLine tang(curved_track.getTangent(pos.z()));
216 
217  double dist(tang.signDistFrom(aux_line)); // track distance
218  double dist_err(1.0); // unknown error of the track distance
219  hit->setDistanceToTrack(dist, dist_err);
220  }
221 
222  if (std::isnan(chi2)) { chi2 = 1.0e6; }
223 
225  // UPDATE SEGMENT POSITION, DIRECTION, CHI^2 //
227 
228  MTStraightLine tangent(curved_track.getTangent((r_segment.position()).z()));
229  r_segment.set(chi2 / (stored_track_hits.size() - 3), tangent.positionVector(), tangent.directionVector());
230  curved_track.setChi2(chi2);
231  curved_track.setNumberOfTrackHits(stored_track_hits.size());
232  curved_track.setUsedHits(stored_track_hits);
233  return true;
234 }
235 
236 Amg::Vector3D CurvedPatRec::getHitPoint(const MdtHitPtr &hit, const MTStraightLine &straight_track) const {
238  // CALCULATE HIT POINT //
240 
241  Amg::Vector3D point = straight_track.positionVector() +
242  (straight_track.directionVector().unit().dot(hit->localPosition() - straight_track.positionVector())) *
243  straight_track.directionVector().unit();
244  Amg::Vector3D point_2 = hit->localPosition() + hit->driftRadius() * (point - hit->localPosition()).unit();
245 
246  return point_2;
247 }
248 
249 std::vector<Amg::Vector3D> CurvedPatRec::getHitPoints(const MdtHitVec &track_hits, const MTStraightLine &straight_track) const {
251  // VARIABLES //
253 
254  std::vector<Amg::Vector3D> hit_vec;
255 
257  // FILL HIT VECTOR //
259 
260  for (const auto & track_hit : track_hits) { hit_vec.emplace_back(getHitPoint(track_hit, straight_track)); }
261 
263  // RETURN THE HIT VECTOR //
265 
266  return hit_vec;
267 }
268 
269 std::vector<Amg::Vector3D> CurvedPatRec::getHitPoints(const MdtHitVec &track_hits, const CurvedLine &curved_track) const {
271  // VARIABLES //
273 
274  std::vector<Amg::Vector3D> hit_vec;
275 
277  // FILL HIT VECTOR //
279 
280  for (const auto & track_hit : track_hits) {
281  hit_vec.emplace_back(getHitPoint(track_hit, curved_track.getTangent((track_hit->localPosition()).z())));
282  }
283 
285  // RETURN THE HIT VECTOR //
287 
288  return hit_vec;
289 }
MuonCalib::CurvedPatRec::MdtHitPtr
MuonCalibSegment::MdtHitPtr MdtHitPtr
Definition: CurvedPatRec.h:38
MuonCalib::StraightPatRec::setRoadWidth
void setRoadWidth(const double r_road_width)
set the road width for the pattern recognition = r_road_width
Definition: StraightPatRec.cxx:279
MuonCalib::CurvedPatRec::CurvedPatRec
CurvedPatRec()
Default constructor: road width of 0.5 mm is used.
getMessageSvc.h
singleton-like access to IMessageSvc via open function and helper
MuonCalib::CurvedPatRec::getHitPoints
std::vector< Amg::Vector3D > getHitPoints(const MdtHitVec &track_hits, const MTStraightLine &straight_track) const
Definition: CurvedPatRec.cxx:249
MuonCalib::CurvedPatRec::m_time_out
double m_time_out
Definition: CurvedPatRec.h:100
CurvedPatRec.h
drawFromPickle.candidates
candidates
Definition: drawFromPickle.py:271
hist_file_dump.d
d
Definition: hist_file_dump.py:137
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:14
MuonCalib::CurvedLine
Definition: CurvedLine.h:30
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
MuonCalib::MTStraightLine::directionVector
Amg::Vector3D directionVector() const
get the direction vector of the straight line
Definition: MTStraightLine.cxx:43
MuonCalib::Combination
Definition: MuonSpectrometer/MuonCalib/MuonCalibUtils/MuonCalibMath/MuonCalibMath/Combination.h:33
MuonCalib::MuonCalibSegment
Definition: MuonCalibSegment.h:39
mc.diff
diff
Definition: mc.SFGenPy8_MuMu_DD.py:14
MuonCalib::MuonCalibSegment::position
const Amg::Vector3D & position() const
retrieve local position of segment (on station level)
Definition: MuonCalibSegment.cxx:185
MuonCalib::CurvedPatRec::fit
bool fit(MuonCalibSegment &r_segment) const
reconstruction of the track using all hits in the segment "r_segment", returns true in case of succes...
Definition: CurvedPatRec.cxx:23
MuonCalib::CurvedPatRec::m_road_width
double m_road_width
Definition: CurvedPatRec.h:99
MuonCalib::Combination::currentCombination
void currentCombination(std::vector< unsigned int > &index_array) const
get the current combination; the result is stored in the vector index_array
Definition: MuonSpectrometer/MuonCalib/MuonCalibUtils/MuonCalibMath/src/Combination.cxx:125
MuonCalib::CurvedLine::getTangent
MTStraightLine getTangent(const double loc_z) const
get the tangent to the line a the local z coordinate "loc_z"
Definition: CurvedLine.cxx:112
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
MuonCalib::StraightPatRec::setTimeOut
void setTimeOut(const double time_out)
set the time-out for the track finding to time_out (in seconds)
Definition: StraightPatRec.cxx:283
MuonCalib::CurvedLine::setChi2
void setChi2(double chi2)
Cache the chi2.
Definition: CurvedLine.cxx:181
MuonCalib::CurvedPatRec::setRoadWidth
void setRoadWidth(const double r_road_width)
set the road width [mm] for the pattern recognition = r_road_width
Definition: CurvedPatRec.cxx:21
CurvedCandidateFinder.h
MuonCalib::CurvedLine::setNumberOfTrackHits
void setNumberOfTrackHits(unsigned int n_hits)
cache the number of track hits
Definition: CurvedLine.cxx:183
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
MuonCalib::Combination::setNewParameters
void setNewParameters(const unsigned int &nb_elements, const unsigned int &wh_class)
set the number of elements = nb_elements; set the class of which the combination is = wh_class
Definition: MuonSpectrometer/MuonCalib/MuonCalibUtils/MuonCalibMath/src/Combination.cxx:230
chi2
double chi2(TH1 *h0, TH1 *h1)
Definition: comparitor.cxx:522
MuonCalib::Combination::numberOfCombinations
unsigned int numberOfCombinations() const
get the number of combinations
Definition: MuonSpectrometer/MuonCalib/MuonCalibUtils/MuonCalibMath/src/Combination.cxx:103
MuonCalib
CscCalcPed - algorithm that finds the Cathode Strip Chamber pedestals from an RDO.
Definition: CscCalcPed.cxx:22
Combination.h
selection
std::string selection
Definition: fbtTestBasics.cxx:75
mergePhysValFiles.errors
list errors
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:43
MuonCalib::MuonCalibSegment::mdtHitsOnTrack
unsigned int mdtHitsOnTrack() const
retrieve the number of MdtCalibHitBase s assigned to this segment
Definition: MuonCalibSegment.cxx:146
MuonCalib::StraightPatRec::fit
bool fit(MuonCalibSegment &r_segment) const
reconstruction of the track using all hits in the segment "r_segment", returns true in case of succes...
Definition: StraightPatRec.cxx:289
MuonCalib::CurvedCandidateFinder
Definition: CurvedCandidateFinder.h:35
MuonCalib::MTStraightLine::signDistFrom
double signDistFrom(const MTStraightLine &h) const
get the signed distance of two lines (if both are parallel, dist>0)
Definition: MTStraightLine.cxx:89
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
MuonCalib::MuonCalibSegment::set
void set(double chi2, const Amg::Vector3D &pos, const Amg::Vector3D &dir)
Definition: MuonCalibSegment.cxx:128
MuonCalib::CurvedLine::setUsedHits
void setUsedHits(const MdtHitVec &hits)
Definition: CurvedLine.cxx:188
unit
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
Definition: AmgMatrixBasePlugin.h:21
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
MuonCalib::MTStraightLine
Definition: MTStraightLine.h:16
MuonCalib::CurvedPatRec::MdtHitVec
MuonCalibSegment::MdtHitVec MdtHitVec
Definition: CurvedPatRec.h:37
MuonCalib::Combination::nextCombination
void nextCombination(std::vector< unsigned int > &index_array)
get the next combination; the results is stored in the array index_array
Definition: MuonSpectrometer/MuonCalib/MuonCalibUtils/MuonCalibMath/src/Combination.cxx:145
MuonCalib::MTStraightLine::positionVector
Amg::Vector3D positionVector() const
get the position vector of the straight line
Definition: MTStraightLine.cxx:42
MuonCalib::MuonCalibSegment::mdtHOT
const MdtHitVec & mdtHOT() const
retrieve the full set of MdtCalibHitBase s assigned to this segment
Definition: MuonCalibSegment.cxx:147
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
python.TrkVertexSeedFinderToolsConfig.finder
finder
Definition: TrkVertexSeedFinderToolsConfig.py:99
MuonCalib::CurvedPatRec::getHitPoint
Amg::Vector3D getHitPoint(const MdtHitPtr &hit, const MTStraightLine &straight_track) const
Definition: CurvedPatRec.cxx:236
jobOptions.points
points
Definition: jobOptions.GenevaPy8_Zmumu.py:97
MuonCalib::CurvedPatRec::roadWidth
double roadWidth() const
get the road width used in the pattern recognition [mm]
Definition: CurvedPatRec.cxx:20
MuonCalib::MuonCalibSegment::MdtHitPtr
std::shared_ptr< MdtCalibHitBase > MdtHitPtr
typedef for a collection of MdtCalibHitBase s
Definition: MuonCalibSegment.h:44
fitman.k
k
Definition: fitman.py:528
MuonCalib::IMdtSegmentFitter::HitSelection
std::vector< unsigned int > HitSelection
Definition: IMdtSegmentFitter.h:32
MuonCalib::CurvedPatRec::setTimeOut
void setTimeOut(const double time_out)
set the time-out for the track finding to time_out (in seconds)
Definition: CurvedPatRec.cxx:22