ATLAS Offline Software
Tracking/TrkUtilityPackages/TrkDriftCircleMath/src/DCSLFitter.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include <iostream>
8 
9 namespace TrkDriftCircleMath {
10 
11 bool DCSLFitter::fit(Segment& result, const Line& line, const DCOnTrackVec& dcs,
12  const HitSelection& selection, double) const{
13 
14  unsigned int N = dcs.size();
15 
16  if (N < 2) {
17  return false;
18  }
19 
20  if (selection.size() != N) {
21  return false;
22  } else {
23  int used(0);
24  for (unsigned int i = 0; i < N; ++i) {
25  if (selection[i] == 0)
26  ++used;
27  }
28  if (used < 2) {
29  return false;
30  }
31  }
32 
33  double S{0}, Sz{0}, Sy{0};
34  double Zc{0}, Yc{0};
35  // reserve enough space for hits
36  std::vector<FitData> data;
37  data.reserve(N);
38  unsigned int ii = 0;
39  for (const DCOnTrack& it : dcs) {
40  FitData datum{};
41  datum.y = it.y();
42  datum.z = it.x();
43  datum.r = std::abs(it.r());
44  datum.w = std::pow(it.dr() > 0. ? 1. / it.dr() : 0., 2);
45 
46  if (selection[ii] == 0) {
47  S += datum.w;
48  Sz += datum.w * datum.z;
49  Sy += datum.w * datum.y;
50  }
51  data.push_back(std::move(datum));
52  ++ii;
53  }
54  Zc = Sz / S;
55  Yc = Sy / S;
56 
57  //
58  // shift hits
59  //
60  Sy = 0;
61  Sz = 0;
62  double Syy{0}, Szy{0}, Syyzz{0};
63 
64  for (unsigned int i = 0; i < N; ++i) {
65  FitData& datum = data[i];
66 
67  datum.y -= Yc;
68  datum.z -= Zc;
69 
70  if (selection[i])
71  continue;
72 
73  datum.rw = datum.r * datum.w;
74  datum.ryw = datum.rw * datum.y;
75  datum.rzw = datum.rw * datum.z;
76 
77  Syy += datum.y * datum.y * datum.w;
78  Szy += datum.y * datum.z * datum.w;
79  Syyzz += (datum.y - datum.z) * (datum.y + datum.z) * datum.w;
80  }
81 
82  unsigned int count{0};
83  double R{0}, Ry{0}, Rz{0}, Att{0}, Add{S}, Bt{0}, Bd{0}, Stt{0}, Sd{0};
84 
85  double theta = line.phi();
86  double cosin = std::cos(theta);
87  double sinus = std::sin(theta);
88 
89  // make sure 0 <= theta < PI
90  if (sinus < 0.0) {
91  sinus = -sinus;
92  cosin = -cosin;
93  } else if (sinus == 0.0 && cosin < 0.0) {
94  cosin = -cosin;
95  }
96  //
97  // calculate shift
98  double d = line.y0() + Zc * sinus - Yc * cosin;
99 
100  while (count < 100) {
101  R = Ry = Rz = 0;
102 
103  for (unsigned int i = 0; i < N; ++i) {
104  if (selection[i])
105  continue;
106 
107  FitData& datum = data[i];
108 
109  double dist = datum.y * cosin - datum.z * sinus;
110  if (dist > d) {
111  R -= datum.rw;
112  Ry -= datum.ryw;
113  Rz -= datum.rzw;
114  } else {
115  R += datum.rw;
116  Ry += datum.ryw;
117  Rz += datum.rzw;
118  }
119  }
120  Att = Syy + cosin * (2 * sinus * Szy - cosin * Syyzz);
121  Bt = -Szy + cosin * (sinus * Syyzz + 2 * cosin * Szy + Rz) + sinus * Ry;
122  Bd = -S * d + R;
123  if (Att == 0) {
124  if (data.capacity() > 100) {
125  data.reserve(100);
126  result.dcs().reserve(100);
127  }
128  return false;
129  }
130  theta += Bt / Att;
131  if (theta < 0.0)
132  theta += M_PI;
133  if (theta >= M_PI)
134  theta -= M_PI;
135  cosin = std::cos(theta);
136  sinus = std::sqrt(1 - cosin * cosin);
137  d = R / S;
138  if (std::abs(Bt / Att) < 0.001 && std::abs(Bd / Add) < 0.001) {
139  Stt = std::sqrt(1 / Att);
140  Sd = std::sqrt(1 / Add);
141  break;
142  }
143  ++count;
144  }
145  // Fit did not converge
146  if (count >= 100) {
147  return false;
148  }
149 
150  double yl{0}, chi2{0};
151 
152  double dtheta = Stt;
153  double dy0 = Sd;
154 
155  result.dcs().clear();
156  result.clusters().clear();
157  result.emptyTubes().clear();
158 
159  unsigned int nhits{0};
160 
161  // calculate predicted hit positions from track parameters
162  result.dcs().reserve(N);
163  for (unsigned int i = 0; i < N; ++i) {
164  FitData& datum = data[i];
165  yl = cosin * datum.y - sinus * datum.z - d;
166  double dth = -(sinus * datum.y + cosin * datum.z) * Stt;
167  double errorResiduals = std::hypot(dth, Sd);
168  double residuals = std::abs(yl) - datum.r;
169  if (selection[i] == 0) {
170  ++nhits;
171  chi2 += residuals * residuals * datum.w;
172  }
173  result.dcs().emplace_back(dcs[i]);
174  result.dcs().back().residual(residuals);
175  result.dcs().back().errorTrack(errorResiduals);
176  }
177 
178  result.set(chi2, nhits - 2, dtheta, dy0);
179  result.line().set(LocVec2D(Zc - sinus * d, Yc + cosin * d), theta);
180 
181  return true;
182 }
183 } // namespace TrkDriftCircleMath
used
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
checkFileSG.line
line
Definition: checkFileSG.py:75
TrkDriftCircleMath::DCSLFitter::FitData::rw
double rw
Definition: Tracking/TrkUtilityPackages/TrkDriftCircleMath/TrkDriftCircleMath/DCSLFitter.h:24
get_generator_info.result
result
Definition: get_generator_info.py:21
TrkDriftCircleMath::DCOnTrackVec
std::vector< DCOnTrack > DCOnTrackVec
Definition: DCOnTrack.h:59
TrkDriftCircleMath::DCSLFitter::fit
virtual bool fit(Segment &result, const Line &line, const DCOnTrackVec &dcs, double t0Seed=-99999.) const
Definition: Tracking/TrkUtilityPackages/TrkDriftCircleMath/TrkDriftCircleMath/DCSLFitter.h:38
hist_file_dump.d
d
Definition: hist_file_dump.py:137
theta
Scalar theta() const
theta method
Definition: AmgMatrixBasePlugin.h:71
TrkDriftCircleMath::HitSelection
std::vector< bool > HitSelection
Definition: HitSelection.h:9
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
TrkDriftCircleMath::DCSLFitter::FitData::rzw
double rzw
Definition: Tracking/TrkUtilityPackages/TrkDriftCircleMath/TrkDriftCircleMath/DCSLFitter.h:26
skel.it
it
Definition: skel.GENtoEVGEN.py:423
M_PI
#define M_PI
Definition: ActiveFraction.h:11
TrkDriftCircleMath
Function object to check whether two Segments are sub/super sets or different.
Definition: IMdtSegmentFinder.h:13
DCSLFitter.h
JetTiledMap::N
@ N
Definition: TiledEtaPhiMap.h:44
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
JetTiledMap::S
@ S
Definition: TiledEtaPhiMap.h:44
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
TrkDriftCircleMath::Segment
Definition: TrkUtilityPackages/TrkDriftCircleMath/TrkDriftCircleMath/Segment.h:18
TrkDriftCircleMath::LocVec2D
Implementation of 2 dimensional vector class.
Definition: LocVec2D.h:16
TrkDriftCircleMath::Line
Definition: Line.h:17
TrkDriftCircleMath::DCSLFitter::FitData
Definition: Tracking/TrkUtilityPackages/TrkDriftCircleMath/TrkDriftCircleMath/DCSLFitter.h:19
lumiFormat.i
int i
Definition: lumiFormat.py:92
chi2
double chi2(TH1 *h0, TH1 *h1)
Definition: comparitor.cxx:522
TrkDriftCircleMath::DCSLFitter::FitData::r
double r
Definition: Tracking/TrkUtilityPackages/TrkDriftCircleMath/TrkDriftCircleMath/DCSLFitter.h:22
selection
std::string selection
Definition: fbtTestBasics.cxx:73
TrkDriftCircleMath::DCSLFitter::FitData::w
double w
Definition: Tracking/TrkUtilityPackages/TrkDriftCircleMath/TrkDriftCircleMath/DCSLFitter.h:23
python.grid.Add
def Add(name)
Definition: grid.py:41
TrkDriftCircleMath::DCSLFitter::FitData::z
double z
Definition: Tracking/TrkUtilityPackages/TrkDriftCircleMath/TrkDriftCircleMath/DCSLFitter.h:21
TrkDriftCircleMath::DCSLFitter::FitData::ryw
double ryw
Definition: Tracking/TrkUtilityPackages/TrkDriftCircleMath/TrkDriftCircleMath/DCSLFitter.h:25
TrkDriftCircleMath::DCOnTrack
class representing a drift circle meaurement on segment
Definition: DCOnTrack.h:16
TrkDriftCircleMath::DCSLFitter::FitData::y
double y
Definition: Tracking/TrkUtilityPackages/TrkDriftCircleMath/TrkDriftCircleMath/DCSLFitter.h:20
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36