ATLAS Offline Software
FPGATrackSimTrack.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
6 
9 #include <iostream>
10 #include <iomanip>
11 #include <cmath>
12 using namespace std;
13 
15 // first stage only
16 
17 
18 std::vector<float> FPGATrackSimTrack::getCoords(unsigned ilayer) const
19 {
20  std::vector<float> coords;
21  if (ilayer >= m_hits.size())
22  throw std::range_error("FPGATrackSimTrack::getCoords() out of bounds");
23 
24  if (m_trackCorrType == TrackCorrType::None)
25  {
26  coords.push_back(m_hits[ilayer].getEtaCoord());
27  coords.push_back(m_hits[ilayer].getPhiCoord());
28  }
29  else
30  {
31  coords = computeIdealCoords(ilayer);
32  }
33 
34  return coords;
35 }
36 
37 std::vector<float> FPGATrackSimTrack::computeIdealCoords(unsigned ilayer) const
38 {
39  std::vector<float> coords;
40 
41  // rho = 0.33 m * (pT / GeV) / (B/T)
42  // B = 2 T so
43  // rho = 0.33 m * (pT / GeV) / (2)
44  // and then 2*rho = 0.33 m * (pT / GeV)
45  // but distances for us are in mm, so 2*rho = 330 * (pT / GeV)
46  // and 1/(2*rho) = (1 / (pT in GeV)) / 330
47 
48  double target_r = m_idealRadii[ilayer];
49  if (m_hits[ilayer].getHitType() == HitType::spacepoint) {
50  unsigned other_layer = (m_hits[ilayer].getSide() == 0) ? ilayer + 1 : ilayer - 1;
51  target_r = (target_r + m_idealRadii[other_layer]) / 2.;
52  }
53 
54  double hitGPhi = m_hits[ilayer].getGPhi();
55  double houghRho = 0.0003 * getHoughY(); //A*q/pT
56 
57  if (m_doDeltaGPhis) {
58  double expectedGPhi = getHoughX();
59 
60  hitGPhi += (m_hits[ilayer].getR() - target_r) * houghRho; //first order
61  expectedGPhi -= target_r * houghRho; //first order
62 
63  if (m_trackCorrType == TrackCorrType::Second) {
64  hitGPhi += (std::pow(m_hits[ilayer].getR() * houghRho, 3.0) / 6.0); //higher order
65  expectedGPhi -= (std::pow(target_r * houghRho, 3.0) / 6.0); //higher order
66  }
67 
68  double hitZ = m_hits[ilayer].getZ();
69  if (m_hits[ilayer].getR() > 1e-8) {
70  hitZ -= m_hits[ilayer].getGCotTheta() * (m_hits[ilayer].getR() - target_r); //first order
71  if (m_trackCorrType == TrackCorrType::Second)
72  hitZ -= (m_hits[ilayer].getGCotTheta() * std::pow(m_hits[ilayer].getR(), 3.0) * houghRho * houghRho) / 6.0; //higher order
73  }
74 
75  coords.push_back(hitZ);
76  coords.push_back(hitGPhi - expectedGPhi);
77  }
78  else {
79  double houghRho = 0.0003 * getHoughY(); //A*q/pT
80 
81  hitGPhi += (m_hits[ilayer].getR() - target_r) * houghRho; //first order
82  if (m_trackCorrType == TrackCorrType::Second) {
83  hitGPhi += (pow(m_hits[ilayer].getR() * houghRho, 3.0) / 6.0); //higher order
84  }
85 
86  double z = m_hits[ilayer].getZ();
87  if (m_hits[ilayer].getR() > 1e-8) {
88  z -= m_hits[ilayer].getGCotTheta() * (m_hits[ilayer].getR() - target_r); //first order
89  if (m_trackCorrType == TrackCorrType::Second)
90  z -= m_hits[ilayer].getGCotTheta() * (std::pow(m_hits[ilayer].getR(), 3.0) * houghRho * houghRho) / 6.0; //higher order
91  }
92 
93  coords.push_back(z);
94  coords.push_back(hitGPhi);
95  }
96 
97  return coords;
98 }
99 
100 float FPGATrackSimTrack::getEtaCoord(int ilayer) const {
101  auto coords = getCoords(ilayer);
102  if (coords.size() > 0) {
103  return coords.at(0);
104  }
105  else {
106  throw std::range_error("FPGATrackSimTrack::getCoord(layer,coord) out of bounds");
107  }
108 }
109 
110 float FPGATrackSimTrack::getPhiCoord(int ilayer) const {
111  auto coords = getCoords(ilayer);
112 
113  // If this is a spacepoint, and if this is the "outer" hit on a strip module
114  // (side = 1) then we actually return the z/eta coord.
115  // Since spacepoints are duplicated, this avoids using the same phi coord
116  // twice and alsp avoids having to teach the code that strip spacepoints are
117  // "2D" hits despite being in the strips, which everything assumes is 1D.
118  // This makes it easy to mix and match spacepoints with strip hits that aren't
119  // spacepoints (since the number of strip layers is held fixed).
120  unsigned target_coord = 1;
121  if (m_hits[ilayer].getHitType() == HitType::spacepoint && (m_hits[ilayer].getPhysLayer() % 2) == 1) {
122  target_coord = 0;
123  }
124 
125  if (coords.size() > target_coord) {
126  return coords.at(target_coord);
127  }
128  else {
129  throw std::range_error("FPGATrackSimTrack::getCoord(layer,coord) out of bounds");
130  }
131 }
132 
133 int FPGATrackSimTrack::getNCoords() const {
134  int nCoords = 0;
135  for (const auto& hit : m_hits) {
136  nCoords += hit.getDim();
137  }
138  return nCoords;
139 }
140 
141 //set a specific position in m_hits
143 {
144  if (m_hits.size() > i)
145  m_hits[i] = hit;
146  else
147  throw std::range_error("FPGATrackSimTrack::setFPGATrackSimHit() out of bounds");
148 }
149 
152 {
153  if (m_hits.size() > 0) m_hits.clear();
154  m_hits.resize(dim);
155 }
156 
157 
158 // if ForceRange==true, then phi = [-pi..pi)
159 void FPGATrackSimTrack::setPhi(float phi, bool ForceRange) {
160  if (ForceRange) {
161  // when phi is ridiculously large, there is no point in adjusting it
162  if (std::abs(phi) > 100) {
163  if (m_chi2 < 100) { // this is a BAD track, so fail it if chi2 hasn't done so already
164  m_chi2 += 100; // we want to fail this event anyway
165  }
166  }
167  else {
168  while (phi >= M_PI) phi -= (2. * M_PI);
169  while (phi < -M_PI) phi += (2. * M_PI);
170  }
171  }
172  m_phi = phi;
173 }
174 
175 float FPGATrackSimTrack::getParameter(int ipar) const
176 {
177  switch (ipar) {
178  case 0:
179  return m_qoverpt;
180  break;
181  case 1:
182  return m_d0;
183  break;
184  case 2:
185  return m_phi;
186  break;
187  case 3:
188  return m_z0;
189  break;
190  case 4:
191  return m_eta;
192  break;
193  }
194 
195  return 0.;
196 }
197 
198 
200 {
201  switch (ipar) {
202  case 0:
203  m_qoverpt = val;
204  break;
205  case 1:
206  m_d0 = val;
207  break;
208  case 2:
209  m_phi = val;
210  break;
211  case 3:
212  m_z0 = val;
213  break;
214  case 4:
215  m_eta = val;
216  break;
217  }
218 }
219 
220 
221 ostream& operator<<(ostream& out, const FPGATrackSimTrack& track)
222 {
223 
224  out << "TRACK: ID=" << std::left << setw(8) << track.m_trackID;
225  out << " SECTOR1=" << std::left << setw(8) << track.m_firstSectorID;
226  out << " BANK=" << std::left << setw(8) << track.m_bankID;
227  out << " BARCODE=" << std::left << setw(6) << track.m_barcode;
228  out << " BARCODE_F=" << std::left << setw(9) << track.m_barcode_frac;
229  out << " EVENT=" << std::left << setw(6) << track.m_eventindex;
230  out << " HITMAP=" << std::left << setw(8) << track.getHitMap();
231  out << " TYPE=" << std::left << setw(3) << track.m_typemask;
232  out << " NMISS=" << std::left << setw(3) << track.getNMissing();
233  out << "\n";
234  streamsize oldprec = out.precision();
235  out.precision(4);
236  out << " PHI=" << std::left << setw(10) << track.m_phi;
237  out.setf(ios_base::scientific);
238  out.precision(2);
239  out << " Q/PT=" << std::left << setw(10) << track.m_qoverpt;
240  out.unsetf(ios_base::scientific);
241  out.precision(4);
242  out << " d0=" << std::left << setw(10) << track.m_d0;
243  out << " ETA=" << std::left << setw(10) << track.m_eta;
244  out << " z0=" << std::left << setw(10) << track.m_z0;
245  out << " Chi2=" << std::left << setw(12) << track.m_chi2;
246  out << " OChi2=" << std::left << setw(12) << track.m_origchi2;
247 
248  out << endl;
249  out.precision(oldprec);
250 
251  out << endl;
252 
253  // print the hits
254  int iter = 0;
255  for (const auto& hit : track.m_hits) {
256  out << "Hit " << iter << ": " << hit << "\n";
257  iter++;
258  }
259 
260  return out;
261 }
262 
263 
265 {
266  vector<FPGATrackSimMultiTruth> mtv;
267  mtv.reserve(m_hits.size());
268 
269  // don't loop over coordinates, since we only calculate truth *per hit* and not per coordinate, though hitmap is saved for coordinates, so be careful
270  for (const auto& thishit : m_hits)
271  {
272  if (thishit.isReal())
273  {
274  FPGATrackSimMultiTruth this_mt(thishit.getTruth());
275  this_mt.assign_equal_normalization();
276  if (thishit.isPixel())
277  for ( auto& x : this_mt)
278  x.second *= 2;
279  mtv.push_back(this_mt);
280  }
281  }
282 
283  // compute the best geant match, the barcode with the largest number of hits contributing to the track.
284  // frac is then the fraction of the total number of hits on the track attributed to the barcode.
288  const bool ok = mt.best(tbarcode, tfrac);
289  if (ok)
290  {
291  setEventIndex(tbarcode.first);
292  setBarcode(tbarcode.second);
293  setBarcodeFrac(tfrac);
294  }
295  else
296  {
297  setEventIndex(-1);
298  setBarcode(-1);
299  setBarcodeFrac(0);
300  }
301 }
302 
304 {
305  m_ORcode = code;
306 }
307 
308 
FPGATrackSimTrack::getPhiCoord
float getPhiCoord(int ilayer) const
FPGATrackSimTrack::calculateTruth
void calculateTruth()
Definition: FPGATrackSimTrack.cxx:264
yodamerge_tmp.dim
dim
Definition: yodamerge_tmp.py:239
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:64
FPGATrackSimTrack::computeIdealCoords
std::vector< float > computeIdealCoords(unsigned ilayer) const
FPGATrackSimTrack
Definition: FPGATrackSimTrack.h:16
FPGATrackSimMultiTruth::Weight
float Weight
Definition: FPGATrackSimMultiTruth.h:50
accumulate
bool accumulate(AccumulateMap &map, std::vector< module_t > const &modules, FPGATrackSimMatrixAccumulator const &acc)
Accumulates an accumulator (e.g.
Definition: FPGATrackSimMatrixAccumulator.cxx:22
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
TrackCorrType::Second
@ Second
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
M_PI
#define M_PI
Definition: ActiveFraction.h:11
FPGATrackSimTrack::setPassedOR
void setPassedOR(unsigned int)
Definition: FPGATrackSimTrack.cxx:303
HitType::spacepoint
@ spacepoint
FPGATrackSimTrack::getNCoords
int getNCoords() const
x
#define x
FPGATrackSimTrack::setFPGATrackSimHit
void setFPGATrackSimHit(unsigned i, const FPGATrackSimHit &hit)
FPGATrackSimMultiTruth::best
bool best(FPGATrackSimMultiTruth::Barcode &code, FPGATrackSimMultiTruth::Weight &weight) const
Definition: FPGATrackSimMultiTruth.h:86
FPGATrackSimConstants.h
FPGATrackSimHit
Definition: FPGATrackSimHit.h:38
FPGATrackSimTrack::setPhi
void setPhi(float v, bool ForceRange=true)
Definition: FPGATrackSimTrack.cxx:159
operator<<
ostream & operator<<(ostream &out, const FPGATrackSimTrack &track)
Definition: FPGATrackSimTrack.cxx:221
lumiFormat.i
int i
Definition: lumiFormat.py:92
z
#define z
FPGATrackSimMultiTruth::Barcode
std::pair< unsigned long, unsigned long > Barcode
Definition: FPGATrackSimMultiTruth.h:49
FPGATrackSimTrack::getEtaCoord
float getEtaCoord(int ilayer) const
FPGATrackSimTrack::getParameter
float getParameter(int) const
Definition: FPGATrackSimTrack.cxx:175
FPGATrackSimTrack::getCoords
std::vector< float > getCoords(unsigned ilayer) const
ClassImp
ClassImp(FPGATrackSimTrack) std
Definition: FPGATrackSimTrack.cxx:14
FPGATrackSimTrack::setParameter
void setParameter(int, float)
Definition: FPGATrackSimTrack.cxx:199
pmontree.code
code
Definition: pmontree.py:443
FPGATrackSimMultiTruth
Definition: FPGATrackSimMultiTruth.h:46
FPGATrackSimMultiTruth::AddAccumulator
Definition: FPGATrackSimMultiTruth.h:57
TrackCorrType::None
@ None
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
IDTPM::getR
float getR(const xAOD::TrackParticle &)
Accessor utility function for getting the value of prodR.
Definition: TrackParametersHelper.h:95
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
FPGATrackSimTrack::setNLayers
void setNLayers(int)
set the number of layers in the track.
Definition: FPGATrackSimTrack.cxx:151
FPGATrackSimTrack.h
FPGATrackSimMultiTruth::assign_equal_normalization
void assign_equal_normalization()
Definition: FPGATrackSimMultiTruth.cxx:70