ATLAS Offline Software
TgcDigitMaker.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 #include "TgcDigitMaker.h"
6 
7 #include <cmath>
8 #include <fstream>
9 #include <iostream>
10 #include <memory>
11 
13 #include "CLHEP/Random/RandFlat.h"
14 #include "CLHEP/Random/RandomEngine.h"
15 #include "CLHEP/Units/SystemOfUnits.h"
16 #include "GaudiKernel/MsgStream.h"
21 #include "MuonSimEvent/TGCSimHit.h"
24 
25 
26 //---------------------------------------------------
27 // Constructor and Destructor
28 //---------------------------------------------------
29 
30 //----- Constructor
32  const MuonGM::MuonDetectorManager* mdManager,
33  unsigned int runperiod, const bool doFourBunch)
34  : AthMessaging("TgcDigitMaker"), m_doFourBunchDigitization(doFourBunch) {
35  m_hitIdHelper = hitIdHelper;
36  m_mdManager = mdManager;
38  m_idHelper = nullptr;
40  1.000; // 100% efficiency for TGCSimHit_p1
42  29.32; // 29.32ns = 26ns + 4 * 0.83ns(outer station)
44  40.94; // 40.94ns = 26ns + 18 * 0.83ns(outer station)
46  33.47; // 33.47ns = 26ns + 9 * 0.83ns(inner station)
48  45.09; // 45.09ns = 26ns + 23 * 0.83ns(inner station)
49  m_bunchCrossingTime = 24.95; // 24.95 ns =(40.08 MHz)^(-1)
50 }
51 
52 //----- Destructor
54 
55 //------------------------------------------------------
56 // Initialize
57 //------------------------------------------------------
59  // Initialize TgcIdHelper
60  if (!m_hitIdHelper) {
62  }
63 
64  // initialize the TGC identifier helper
66 
68 
69  // Read share/TGC_Digitization_energyThreshold.dat file and store values in
70  // m_energyThreshold.
72 
73  // Read share/TGC_Digitization_deadChamber.dat file and store values in
74  // m_isDeadChamber.
76 
77  // Read share/TGC_Digitization_StripPosition.dat file and store values in
78  // m_StripPosition.
80 
81  return StatusCode::SUCCESS;
82 }
83 
84 //---------------------------------------------------
85 // Execute Digitization
86 //---------------------------------------------------
88  const TGCSimHit* hit, const double globalHitTime,
89  const TgcDigitASDposData* ASDpos, const TgcDigitTimeOffsetData* TOffset,
90  const TgcDigitCrosstalkData* Crosstalk,
91  CLHEP::HepRandomEngine* rndmEngine) {
92  // timing constant parameters
93  constexpr float sensor_propagation_time =
94  3.3 * CLHEP::ns /
95  CLHEP::m; // Until MC10, 8.5*ns/m for wire, 8.7*ns/m for strip.
96  // Since MC11, 3.3*ns/m (the speed of light) is used
97  // from the Z->mumu data/MC comparison.
98  constexpr float cable_propagation_time = 5.0 * CLHEP::ns / CLHEP::m;
99 
100  // position constant parameters
101  constexpr float wire_pitch = 1.8 * CLHEP::mm;
102  constexpr float zwidth_frame = 17. * CLHEP::mm;
103 
104  ATH_MSG_DEBUG("executeDigi() Got HIT Id.");
105 
107  int Id = hit->TGCid();
108  std::string stationName = m_hitIdHelper->GetStationName(Id);
111  int ilyr = m_hitIdHelper->GetGasGap(Id);
112 
113  // Check the chamber is dead or not.
115  return nullptr;
116 
117  const Identifier elemId =
119  ATH_MSG_DEBUG("executeDigi() - element identifier is: "
120  << m_idHelper->show_to_string(elemId));
121 
122  const MuonGM::TgcReadoutElement* tgcChamber =
124  if (!tgcChamber) {
125  ATH_MSG_WARNING("executeDigi() - no ReadoutElement found for "
126  << m_idHelper->show_to_string(elemId));
127  return nullptr;
128  }
129 
130  IdContext tgcContext = m_idHelper->module_context();
131  IdentifierHash coll_hash;
132  if (m_idHelper->get_hash(elemId, coll_hash, &tgcContext)) {
133  ATH_MSG_WARNING("Unable to get TGC hash id from TGC Digit collection "
134  << "context begin_index = " << tgcContext.begin_index()
135  << " context end_index = " << tgcContext.end_index()
136  << " the identifier is " << elemId);
137  elemId.show();
138  }
139 
140  std::unique_ptr<TgcDigitCollection> digits =
141  std::make_unique<TgcDigitCollection>(elemId, coll_hash);
142 
143  const Amg::Vector3D centreChamber = tgcChamber->globalPosition();
144  float height = tgcChamber->getRsize();
145  float hmin = sqrt(pow(centreChamber.x(), 2) + pow(centreChamber.y(), 2)) -
146  height / 2.;
147 
148  // Direction cosine of incident angle of this track
149  Amg::Vector3D direCos = hit->localDireCos();
150 
151  // local position
152  Amg::Vector3D localPos = hit->localPosition();
153 
154  // Local z direction is global r direction.
155  float distanceZ = 1.4 * CLHEP::mm / direCos[0] * direCos[2];
156  float zLocal = localPos.z() + distanceZ;
157 
158  // Local y direction is global phi direction.
159  float distanceY = 1.4 * CLHEP::mm / direCos[0] * direCos[1];
160  // This ySign depends on the implementation of TGC geometry in G4 simulation
161  // left-handed coordinate in A side(+z, stationEta>0)
162  float ySign = (stationEta < 0) ? +1. : -1.;
163  float yLocal = ySign * (localPos.y() + distanceY);
164 
165  // Time of flight correction for each chamber
166  // the offset is set to 0 for ASD located at the postion where tof is
167  // minimum in each chamber, i.e. the ASD at the smallest R in each chamber
168  double tofCorrection =
169  (sqrt(pow(hmin + zwidth_frame, 2) + pow(centreChamber.z(), 2)) /
170  (299792458. * (CLHEP::m / CLHEP::s))); // FIXME use CLHEP::c_light
171 
172  // bunch time
173  float bunchTime = globalHitTime - tofCorrection;
174 
175  static const float jitterInitial = 9999.;
176  float jitter = jitterInitial; // calculated at wire group calculation and
177  // used also for strip calculation
178 
179  int iStationName = getIStationName(stationName);
180 
181  double energyDeposit = hit->energyDeposit(); // Energy deposit in MeV
182  // If TGCSimHit_p1 is used, energyDeposit is the default value of -9999.
183  // If TGCSimHit_p2 is used, energyDeposit is equal to or greater than 0.
184  // Therefore, the energyDeposit value can be used to distinguish
185  // TGCSimHit_p1 and TGCSimHit_p2. For TGCSimHit_p1, old efficiency check
186  // with only isStrip variable is used. For TGCSimHit_p2, new efficiency
187  // check with chamber dependent energy threshold is used.
188 
190 
191  if ((energyDeposit >= -1. &&
194  energyDeposit)) || // efficiency check for TGCSimHit_p2 at first,
195  (energyDeposit < -1. &&
197  kWIRE, rndmEngine))) { // Old efficiencyCheck for TGCSimHit_p1
198 
199  int iWireGroup[2];
200  float posInWireGroup[2] = {0., 0.};
201  for (int iPosition = 0; iPosition < 2; iPosition++) {
202  int nWireOffset = (std::abs(stationEta) == 5 ||
203  stationName.compare(0, 2, "T4") == 0)
204  ? 1
205  : 0;
206  // for chambers in which only the first wire is not connected : 1
207  // for chambers in which the first and last wires are not connected
208  // OR all wires are connected : 0
209 
210  double zPosInSensArea =
211  zLocal + static_cast<double>(tgcChamber->nWires(ilyr) -
212  nWireOffset) *
213  wire_pitch / 2.;
214 
215  // check a hit in the sensitive area
216  if (zPosInSensArea < 0. ||
217  zPosInSensArea > tgcChamber->nWires(ilyr) * wire_pitch) {
218  iWireGroup[iPosition] = 0;
219  posInWireGroup[iPosition] = 0.;
221  "executeDigi(): Wire: Hit position located at outside of a "
222  "sensitive volume, "
223  << " id: " << stationName << "/" << stationEta << "/"
224  << stationPhi << "/" << ilyr
225  << " position: " << zPosInSensArea << " xlocal: " << zLocal
226  << " dir cosine: " << direCos[0] << "/" << direCos[1] << "/"
227  << direCos[2]
228  << " active region: " << height - zwidth_frame * 2.);
229  } else {
230  int igang = 1;
231  int wire_index = 0;
232  while (wire_pitch * (static_cast<float>(wire_index)) <
233  zPosInSensArea &&
234  igang <= tgcChamber->nWireGangs(ilyr)) {
235  wire_index += tgcChamber->nWires(ilyr, igang);
236  igang++;
237  }
238  posInWireGroup[iPosition] =
239  (zPosInSensArea / wire_pitch -
240  (static_cast<float>(wire_index))) /
241  (static_cast<float>(
242  tgcChamber->nWires(ilyr, igang - 1))) +
243  1.;
244 
245  iWireGroup[iPosition] = ((1 == igang) ? 1 : igang - 1);
246  }
247  }
248 
249  unsigned int jWG[2] = {
250  (iWireGroup[0] <= iWireGroup[1]) ? (unsigned int)(0)
251  : (unsigned int)(1),
252  (iWireGroup[0] <= iWireGroup[1]) ? (unsigned int)(1)
253  : (unsigned int)(0)};
254  int iWG[2] = {iWireGroup[jWG[0]], iWireGroup[jWG[1]]};
255  float posInWG[2] = {posInWireGroup[jWG[0]], posInWireGroup[jWG[1]]};
256  if (iWG[0] != iWG[1]) {
257  ATH_MSG_DEBUG("executeDigi(): Multihits found in WIRE GROUPs:"
258  << iWG[0] << " " << iWG[1]);
259  }
260 
261  // === BC tagging from the hit timing ===
262  for (int iwg = iWG[0]; iwg <= iWG[1]; iwg++) {
263  if (1 <= iwg && iwg <= tgcChamber->nWireGangs(ilyr)) {
264  // timing window offset
265  float wire_timeOffset =
266  (TOffset != nullptr)
267  ? this->getTimeOffset(TOffset, iStationName, stationEta,
268  kWIRE)
269  : 0.;
270  // EI/FI has different offset between two ASDs.
271  if (iStationName > 46)
272  wire_timeOffset +=
273  (iwg < 17) ? 0.5 * CLHEP::ns : -0.5 * CLHEP::ns;
274 
275  // TGC response time calculation
276  float jit = timeJitter(direCos, rndmEngine);
277  if (jit < jitter)
278  jitter = jit;
279  float ySignPhi = (stationPhi % 2 == 1) ? -1. : +1.;
280  // stationPhi%2==0 : +1. : ASD attached at the smaller phi side
281  // of TGC stationPhi%2==1 : -1. : ASD attached at the larger phi
282  // side of TGC
283  float wTimeDiffByRadiusOfInner =
284  this->timeDiffByCableRadiusOfInner(iStationName, stationPhi,
285  iwg);
286  double digit_time =
287  bunchTime + jitter + wTimeDiffByRadiusOfInner;
288  float wASDDis{-1000.};
289  if (ASDpos != nullptr) {
290  wASDDis = this->getDistanceToAsdFromSensor(
291  ASDpos, iStationName, abs(stationEta), stationPhi,
292  kWIRE, iwg, zLocal);
293  float wCableDis =
294  wASDDis + (ySignPhi * yLocal +
295  tgcChamber->chamberWidth(zLocal) / 2.);
296  float wPropTime =
297  sensor_propagation_time *
298  (ySignPhi * yLocal +
299  tgcChamber->chamberWidth(zLocal) / 2.) +
300  cable_propagation_time * wASDDis;
301  digit_time +=
302  this->getSigPropTimeDelay(wCableDis) + wPropTime;
303  }
304 
305  TgcStation station =
306  (m_idHelper->stationName(elemId) > 46) ? kINNER : kOUTER;
307  uint16_t bctag =
308  bcTagging(digit_time, m_gateTimeWindow[station][kWIRE],
309  wire_timeOffset);
310 
311  if (bctag == 0x0) {
313  "WireGroup: digitized time "
314  << digit_time << " ns is outside of time window from "
315  << wire_timeOffset << ". bunchTime: " << bunchTime
316  << " time jitter: " << jitter << " propagation time: "
317  << sensor_propagation_time *
318  (ySignPhi * yLocal +
319  tgcChamber->chamberWidth(zLocal) / 2.) +
320  cable_propagation_time * wASDDis
321  << " time difference by cable radius of inner station: "
322  << wTimeDiffByRadiusOfInner);
323  } else {
325  stationName, stationEta, stationPhi, ilyr, (int)kWIRE,
326  iwg);
327  addDigit(newId, bctag, digits.get());
328 
329  if (iwg == iWG[0]) {
330  randomCrossTalk(Crosstalk, elemId, ilyr, kWIRE, iwg,
331  posInWG[0], digit_time, wire_timeOffset,
332  rndmEngine, digits.get());
333  }
334 
336  "WireGroup: newid breakdown digitTime x/y/z direcos "
337  "height_gang bctag: "
338  << newId << " " << stationName << "/" << stationEta
339  << "/" << stationPhi << "/" << ilyr << "/"
340  << "WIRE/" << iwg << " " << digit_time << " "
341  << localPos.x() << "/" << localPos.y() << "/"
342  << localPos.z() << " " << direCos.x() << "/"
343  << direCos.y() << "/" << direCos.z() << " " << height
344  << " " << tgcChamber->nWires(ilyr, iwg) << " "
345  << bctag);
346  }
347  } else {
349  "Wire Gang id is out of range. id, x/y/z, height: "
350  << iwg << " " << localPos.x() << "/" << localPos.y() << "/"
351  << localPos.z() << " " << height);
352  }
353  }
354  } // end of wire group calculation
355 
357  TgcSensor sensor = kSTRIP;
358 
359  if ((ilyr != 2 || (stationName.compare(0, 2, "T1") !=
360  0)) && // no stip in middle layers of T1*
361  ((energyDeposit < -1. &&
363  sensor, rndmEngine)) || // Old efficiencyCheck for TGCSimHit_p1.
364  (energyDeposit >= -1. &&
366  stationName, stationEta, stationPhi, ilyr, sensor,
367  energyDeposit))) // New efficiencyCheck for TGCSimHit_p2
368  ) {
369 
370 
371  int iStrip[2];
372  float posInStrip[2] = {0., 0.};
373  // Take into account of charge spread on cathod plane
374  for (int iPosition = 0; iPosition < 2; iPosition++) {
375 
376  // check a hit in the sensitive area
377  float zPos = zLocal + height / 2. - zwidth_frame;
378  if (zPos < 0.) {
379  iStrip[iPosition] = 0;
380  posInStrip[iPosition] = 0.;
382  "Strip: Hit position located at outside of a sensitive "
383  "volume, id, position, xlocal0/1, dir cosine: "
384  << stationName << "/" << stationEta << "/" << stationPhi
385  << "/" << ilyr << zPos << " " << zLocal << " " << direCos[0]
386  << "/" << direCos[1] << "/" << direCos[2]);
387  } else if (zPos > height - zwidth_frame * 2.) {
388  iStrip[iPosition] = tgcChamber->nStrips(ilyr) + 1;
389  posInStrip[iPosition] = 0.;
391  "Strip: Hit position located at outside of a sensitive "
392  "volume, id, position, active region: "
393  << stationName << "/" << stationEta << "/" << stationPhi
394  << "/" << ilyr << zPos << " "
395  << height - zwidth_frame * 2.);
396  } else { // sensitive area
397 
398  //
399  // for layout P03
400  //
401  // number of strips in exclusive phi coverage of a chamber in
402  // T[1-3] and T4
403  const float dphi = tgcChamber->stripDeltaPhi();
404  float phiLocal = atan2(yLocal, zLocal + height / 2. + hmin);
405 
407  "dphi, phiLocal, yLocal, zLocall+ height/2.+hmin: "
408  << dphi << " " << phiLocal << " " << yLocal << " "
409  << zLocal + height / 2. + hmin);
410 
411  int istr = 0;
412  if ((stationEta > 0 && ilyr == 1) ||
413  (stationEta < 0 && ilyr != 1)) {
414  istr = static_cast<int>(floor(phiLocal / dphi + 15.75)) + 1;
415  posInStrip[iPosition] =
416  phiLocal / dphi + 15.75 - static_cast<float>(istr - 1);
417  if (istr > 30) { // treatment for two half strips
418  istr = static_cast<int>(floor(
419  (phiLocal - dphi * 14.25) / (dphi / 2.))) +
420  31;
421  posInStrip[iPosition] =
422  (phiLocal - dphi * 14.25) / (dphi / 2.) -
423  static_cast<float>(istr - 31);
424  }
425  } else {
426  istr = static_cast<int>(floor(phiLocal / dphi + 16.25)) + 1;
427  posInStrip[iPosition] =
428  phiLocal / dphi + 16.25 - static_cast<float>(istr - 1);
429  if (istr < 3) { // treatment for two half strips
430  istr = static_cast<int>(floor(
431  (phiLocal + dphi * 14.25) / (dphi / 2.))) +
432  3;
433  posInStrip[iPosition] =
434  (phiLocal + dphi * 14.25) / (dphi / 2.) -
435  static_cast<float>(istr - 3);
436  }
437  }
438  if (istr < 1) {
439  istr = 0;
440  posInStrip[iPosition] = 0.;
441  } else if (32 < istr) {
442  istr = 33;
443  posInStrip[iPosition] = 0.;
444  }
445  iStrip[iPosition] = istr;
446  } // sensitive area
447  }
448 
449  unsigned int jStr[2] = {
450  (iStrip[0] <= iStrip[1]) ? (unsigned int)(0) : (unsigned int)(1),
451  (iStrip[0] <= iStrip[1]) ? (unsigned int)(1) : (unsigned int)(0)};
452  int iStr[2] = {iStrip[jStr[0]], iStrip[jStr[1]]};
453  float posInStr[2] = {posInStrip[jStr[0]], posInStrip[jStr[1]]};
454  if (iStr[0] != iStr[1]) {
455  ATH_MSG_DEBUG("Multihits found in STRIPs:" << iStr[0] << " "
456  << iStr[1]);
457  }
458 
459  // BC tagging from the timing
460  float strip_timeOffset =
461  (TOffset != nullptr)
462  ? this->getTimeOffset(TOffset, iStationName, stationEta, kSTRIP)
463  : 0.;
464 
465  for (int istr = iStr[0]; istr <= iStr[1]; istr++) {
466  if (1 <= istr && istr <= 32) {
467  // TGC response time calculation
468  if (jitter > jitterInitial - 0.1) {
469  jitter = timeJitter(direCos, rndmEngine);
470  }
471  float zSignEta =
472  (abs(stationEta) % 2 == 1 && abs(stationEta) != 5) ? -1.
473  : +1.;
474  // if(abs(stationEta)%2 == 1 && abs(stationEta) != 5) : -1. :
475  // ASD attached at the longer base of TGC else : +1. : ASD
476  // attached at the shorter base of TGC
477  float sTimeDiffByRadiusOfInner =
478  this->timeDiffByCableRadiusOfInner(iStationName, stationPhi,
479  istr);
480  float sDigitTime =
481  bunchTime + jitter +
482  sensor_propagation_time *
483  (height / 2. + zwidth_frame + zSignEta * zLocal) +
484  sTimeDiffByRadiusOfInner;
485  float sASDDis{-1000};
486  if (ASDpos != nullptr) {
487  sASDDis = this->getDistanceToAsdFromSensor(
488  ASDpos, iStationName, abs(stationEta), stationPhi,
489  sensor, istr,
491  float sCableDis = sASDDis + (height / 2. + zwidth_frame +
492  zSignEta * zLocal);
493  sDigitTime += this->getSigPropTimeDelay(sCableDis) +
494  sASDDis * cable_propagation_time;
495  }
496 
497  TgcStation station =
498  (m_idHelper->stationName(elemId) > 46) ? kINNER : kOUTER;
499  uint16_t bctag =
500  bcTagging(sDigitTime, m_gateTimeWindow[station][sensor],
501  strip_timeOffset);
502 
503  if (bctag == 0x0) {
505  "Strip: Digitized time is outside of time window. "
506  << sDigitTime << " bunchTime: " << bunchTime
507  << " time jitter: " << jitter << " propagation time: "
508  << sensor_propagation_time *
509  (height / 2. + zwidth_frame + zSignEta * zLocal)
510  << " time difference by cable radius of inner station: "
511  << sTimeDiffByRadiusOfInner);
512  } else {
514  stationName, stationEta, stationPhi, ilyr, (int)sensor,
515  istr);
516  addDigit(newId, bctag, digits.get());
517 
518  if (istr == iStr[0]) {
519  randomCrossTalk(Crosstalk, elemId, ilyr, sensor,
520  iStr[0], posInStr[0], sDigitTime,
521  strip_timeOffset, rndmEngine,
522  digits.get());
523  }
524 
526  "Strip: newid breakdown digitTime x/y/z direcos "
527  "r_center bctag: "
528  << newId << " " << stationName << "/" << stationEta
529  << "/" << stationPhi << "/" << ilyr << "/" << sensor
530  << "/" << istr << " " << sDigitTime << " "
531  << localPos.x() << "/" << localPos.y() << "/"
532  << localPos.z() << " " << direCos.x() << "/"
533  << direCos.y() << "/" << direCos.z() << " "
534  << height / 2. + hmin << " " << bctag);
535  }
536  } else {
537  ATH_MSG_DEBUG("Strip id is out of range: gap, id: "
538  << ilyr << " " << istr);
539  }
540  }
541  } // end of strip number calculation
542 
543  return digits.release();
544 }
545 
546 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
548  const char* const fileName = "TGC_Digitization_timejitter.dat";
549  std::string fileWithPath = PathResolver::find_file(fileName, "DATAPATH");
550 
551  std::ifstream ifs;
552  if (!fileWithPath.empty()) {
553  ifs.open(fileWithPath.c_str(), std::ios::in);
554  } else {
555  ATH_MSG_FATAL("readFileOfTimeJitter(): Could not find file "
556  << fileName);
557  return StatusCode::FAILURE;
558  }
559 
560  if (ifs.bad()) {
561  ATH_MSG_FATAL("readFileOfTimeJitter(): Could not open file "
562  << fileName);
563  return StatusCode::FAILURE;
564  }
565 
566  int angle = 0;
567  int bins = 0;
568  int i = 0;
569  float prob = 0.;
570  bool verbose = msgLvl(MSG::VERBOSE);
571 
572  while (ifs.good()) {
573  ifs >> angle >> bins;
574  if (ifs.eof())
575  break;
577  "readFileOfTimeJitter(): Timejitter, angle, Number of bins, prob. "
578  "dist.: "
579  << angle << " " << bins << " ");
580  m_vecAngle_Time.resize(i + 1);
581  for (int j = 0; j < 41 /*bins*/; j++) {
582  ifs >> prob;
583  m_vecAngle_Time[i].push_back(prob);
584  if (j == 0 && verbose)
585  msg(MSG::VERBOSE) << "readFileOfTimeJitter(): ";
586  if (verbose)
587  msg(MSG::VERBOSE) << prob << " ";
588  }
589  if (verbose)
590  msg(MSG::VERBOSE) << endmsg;
591  i++;
592  }
593  ifs.close();
594  return StatusCode::SUCCESS;
595 }
596 //+++++++++++++++++++++++++++++++++++++++++++++++
597 float TgcDigitMaker::timeJitter(const Amg::Vector3D& direCosLocal,
598  CLHEP::HepRandomEngine* rndmEngine) const {
599  float injectionAngle =
600  atan2(fabs(direCosLocal[2]), fabs(direCosLocal[0])) / CLHEP::degree;
601 
602  int ithAngle = static_cast<int>(injectionAngle / 5.);
603  float wAngle = injectionAngle / 5. - static_cast<float>(ithAngle);
604  int jthAngle;
605  if (ithAngle > 11) {
606  ithAngle = 12;
607  jthAngle = 12;
608  } else {
609  jthAngle = ithAngle + 1;
610  }
611 
612  float jitter = 0.;
613  float prob = 1.;
614  float probRef = 0.;
615 
616  while (prob > probRef) {
617  prob = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0);
618  jitter = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0) * 40. *
619  CLHEP::ns; // trial time jitter
620  int ithJitter = static_cast<int>(jitter);
621  // probability distribution calculated from weighted sum between
622  // neighboring bins of angles
623  probRef = (1. - wAngle) * m_vecAngle_Time[ithAngle][ithJitter] +
624  wAngle * m_vecAngle_Time[jthAngle][ithJitter];
625  }
626  return jitter;
627 }
628 //+++++++++++++++++++++++++++++++++++++++++++++++
630  CLHEP::HepRandomEngine* rndmEngine) const {
631  if (CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0) < m_efficiency[sensor])
632  return true;
633  ATH_MSG_DEBUG("efficiencyCheck(): Hit removed for sensor= "
634  << sensor << "(0=WIRE,1=STRIP)");
635  return false;
636 }
637 //+++++++++++++++++++++++++++++++++++++++++++++++
639  const int stationEta, const int stationPhi,
640  const int gasGap, const TgcSensor sensor,
641  const double energyDeposit) const {
642  // If the energy deposit is equal to or greater than the threshold value of
643  // the chamber, return true.
645  stationPhi, gasGap, sensor));
646 }
647 //+++++++++++++++++++++++++++++++++++++++++++++++
648 uint16_t TgcDigitMaker::bcTagging(const double digitTime, const double window,
649  const double offset) const {
650  const double calc_coll_time =
651  digitTime - offset; // calculated collision time
652  uint16_t bctag = 0;
653  if (-m_bunchCrossingTime < calc_coll_time &&
654  calc_coll_time < window - m_bunchCrossingTime) {
655  bctag |= 0x1;
656  }
657  if (0. < calc_coll_time && calc_coll_time < window) {
658  bctag |= 0x2;
659  }
660  if (m_bunchCrossingTime < calc_coll_time &&
661  calc_coll_time < window + m_bunchCrossingTime) {
662  bctag |= 0x4;
663  }
664  if (2. * m_bunchCrossingTime < calc_coll_time &&
665  calc_coll_time < window + 2. * m_bunchCrossingTime &&
667  bctag |= 0x8;
668  }
669  return bctag;
670 }
671 //+++++++++++++++++++++++++++++++++++++++++++++++
672 void TgcDigitMaker::addDigit(const Identifier id, const uint16_t bctag,
673  TgcDigitCollection* digits) {
674  for (int bc = TgcDigit::BC_PREVIOUS; bc <= TgcDigit::BC_NEXTNEXT; bc++) {
675  if ((bctag >> (bc - 1)) & 0x1) {
676  bool duplicate = false;
677  for (const auto digit : *digits) {
678  if (id == digit->identify() && digit->bcTag() == bc) {
679  duplicate = true;
680  break;
681  }
682  }
683  if (!duplicate) {
684  std::unique_ptr<TgcDigit> multihitDigit =
685  std::make_unique<TgcDigit>(id, bc);
686  digits->push_back(multihitDigit.release());
687  }
688  }
689  }
690  }
691 
693  // Indices to be used
694  int iStationName, stationEta, stationPhi, gasGap, isStrip;
695 
696  for (iStationName = 0; iStationName < N_STATIONNAME; iStationName++) {
697  for (stationEta = 0; stationEta < N_STATIONETA; stationEta++) {
698  for (stationPhi = 0; stationPhi < N_STATIONPHI; stationPhi++) {
699  for (gasGap = 0; gasGap < N_GASGAP; gasGap++) {
700  for (isStrip = 0; isStrip < N_ISSTRIP; isStrip++) {
701  m_energyThreshold[iStationName][stationEta][stationPhi]
702  [gasGap][isStrip] = -999999.;
703  }
704  }
705  }
706  }
707  }
708 
709  // Find path to the TGC_Digitization_energyThreshold.dat file
710  const std::string fileName = "TGC_Digitization_energyThreshold.dat";
711  std::string fileWithPath = PathResolver::find_file(fileName, "DATAPATH");
712  if (fileWithPath.empty()) {
713  ATH_MSG_FATAL("readFileOfEnergyThreshold(): Could not find file "
714  << fileName);
715  return StatusCode::FAILURE;
716  }
717 
718  // Open the TGC_Digitization_energyThreshold.dat file
719  std::ifstream ifs;
720  ifs.open(fileWithPath.c_str(), std::ios::in);
721  if (ifs.bad()) {
722  ATH_MSG_FATAL("readFileOfEnergyThreshold(): Could not open file "
723  << fileName);
724  return StatusCode::FAILURE;
725  }
726 
727  double energyThreshold;
728  // Read the TGC_Digitization_energyThreshold.dat file
729  while (ifs.good()) {
730  ifs >> iStationName >> stationEta >> stationPhi >> gasGap >> isStrip >>
731  energyThreshold;
732  ATH_MSG_DEBUG("readFileOfEnergyThreshold"
733  << " stationName= " << iStationName << " stationEta= "
734  << stationEta << " stationPhi= " << stationPhi
735  << " gasGap= " << gasGap << " isStrip= " << isStrip
736  << " energyThreshold(MeV)= " << energyThreshold);
737 
738  // Subtract offsets to use indices of energyThreshold array
739  iStationName -= OFFSET_STATIONNAME;
744 
745  // Check the indices are valid
746  if (iStationName < 0 || iStationName >= N_STATIONNAME)
747  continue;
748  if (stationEta < 0 || stationEta >= N_STATIONETA)
749  continue;
750  if (stationPhi < 0 || stationPhi >= N_STATIONPHI)
751  continue;
752  if (gasGap < 0 || gasGap >= N_GASGAP)
753  continue;
754  if (isStrip < 0 || isStrip >= N_ISSTRIP)
755  continue;
756 
758  [isStrip] = energyThreshold;
759 
760  // If it is the end of the file, get out from while loop.
761  if (ifs.eof())
762  break;
763  }
764 
765  // Close the TGC_Digitization_energyThreshold.dat file
766  ifs.close();
767 
768  return StatusCode::SUCCESS;
769 }
770 
772  // Indices to be used
773  int iStationName, stationEta, stationPhi, gasGap;
774 
775  for (iStationName = 0; iStationName < N_STATIONNAME; iStationName++) {
776  for (stationEta = 0; stationEta < N_STATIONETA; stationEta++) {
777  for (stationPhi = 0; stationPhi < N_STATIONPHI; stationPhi++) {
778  for (gasGap = 0; gasGap < N_GASGAP; gasGap++) {
779  m_isDeadChamber[iStationName][stationEta][stationPhi]
780  [gasGap] = false;
781  }
782  }
783  }
784  }
785 
786  // Find path to the TGC_Digitization_deadChamber.dat file
787  std::string fileName;
788  if (m_runperiod == 1)
789  fileName = "TGC_Digitization_deadChamber.dat";
790  else if (m_runperiod == 2)
791  fileName = "TGC_Digitization_2016deadChamber.dat";
792  else if (m_runperiod == 3)
793  fileName = "TGC_Digitization_NOdeadChamber.dat";
794  else {
795  ATH_MSG_ERROR("Run Period " << m_runperiod
796  << " is unexpected in TgcDigitMaker - "
797  "using NOdeadChamber configuration.");
798  return StatusCode::FAILURE;
799  }
800  std::string fileWithPath = PathResolver::find_file(fileName, "DATAPATH");
801  if (fileWithPath.empty()) {
802  ATH_MSG_FATAL("readFileOfDeadChamber(): Could not find file "
803  << fileName);
804  return StatusCode::FAILURE;
805  }
806 
807  // Open the TGC_Digitization_deadChamber.dat file
808  std::ifstream ifs;
809  ifs.open(fileWithPath.c_str(), std::ios::in);
810  if (ifs.bad()) {
811  ATH_MSG_FATAL("readFileOfDeadChamber(): Could not open file "
812  << fileName);
813  return StatusCode::FAILURE;
814  }
815 
816  // Read the TGC_Digitization_deadChamber.dat file
817  unsigned int nDeadChambers = 0;
818  std::string comment;
819  while (ifs.good()) {
820  ifs >> iStationName >> stationEta >> stationPhi >> gasGap;
821  bool valid = getline(ifs, comment).good();
822  if (!valid)
823  break;
824 
825  ATH_MSG_DEBUG("TgcDigitMaker::readFileOfDeadChamber"
826  << " stationName= " << iStationName << " stationEta= "
827  << stationEta << " stationPhi= " << stationPhi
828  << " gasGap= " << gasGap << " comment= " << comment);
829 
830  // Subtract offsets to use indices of isDeadChamber array
831  iStationName -= OFFSET_STATIONNAME;
835 
836  // Check the indices are valid
837  if (iStationName < 0 || iStationName >= N_STATIONNAME)
838  continue;
839  if (stationEta < 0 || stationEta >= N_STATIONETA)
840  continue;
841  if (stationPhi < 0 || stationPhi >= N_STATIONPHI)
842  continue;
843  if (gasGap < 0 || gasGap >= N_GASGAP)
844  continue;
845 
846  m_isDeadChamber[iStationName][stationEta][stationPhi][gasGap] = true;
847  nDeadChambers++;
848 
849  // If it is the end of the file, get out from while loop.
850  if (ifs.eof())
851  break;
852  }
853 
854  // Close the TGC_Digitization_deadChamber.dat file
855  ifs.close();
856 
857  ATH_MSG_INFO("readFileOfDeadChamber: the number of dead chambers = "
858  << nDeadChambers);
859 
860  return StatusCode::SUCCESS;
861 }
862 
864  // Indices to be used
865  int iStationName, stationEta, channel;
866 
867  for (iStationName = 0; iStationName < N_STATIONNAME; iStationName++) {
869  for (channel = 0; channel < N_STRIPCHANNEL; channel++) {
870  m_StripPos[iStationName][stationEta][channel] = 0.;
871  }
872  }
873  }
874 
875  // Find path to the TGC_Digitization_StripPosition.dat file
876  const std::string fileName = "TGC_Digitization_StripPosition.dat";
877  std::string fileWithPath = PathResolver::find_file(fileName, "DATAPATH");
878  if (fileWithPath.empty()) {
879  ATH_MSG_FATAL("readFileOfStripPosition(): Could not find file "
880  << fileName);
881  return StatusCode::FAILURE;
882  }
883 
884  // Open the TGC_Digitization_StripPosition.dat file
885  std::ifstream ifs;
886  ifs.open(fileWithPath.c_str(), std::ios::in);
887  if (ifs.bad()) {
888  ATH_MSG_FATAL("readFileOfStripPosition(): Could not open file "
889  << fileName);
890  return StatusCode::FAILURE;
891  }
892 
893  // Read the TGC_Digitization_StripPosition.dat file
894  double strippos;
895  while (ifs.good()) {
896  ifs >> iStationName >> stationEta >> channel >> strippos;
897  ATH_MSG_DEBUG("readFileOfStripPosition"
898  << " stationName= " << iStationName << " stationEta= "
899  << stationEta << " channel= " << channel
900  << " StripPosition= " << strippos);
901 
902  iStationName -= OFFSET_STATIONNAME;
905 
906  // Check the indices are valid
907  if (iStationName < 0 || iStationName >= N_STATIONNAME)
908  continue;
909  if (stationEta < 0 || stationEta >= N_ABSSTATIONETA)
910  continue;
911  if (channel < 0 || channel >= N_STRIPCHANNEL)
912  continue;
913 
914  m_StripPos[iStationName][stationEta][channel] = strippos;
915  // If it is the end of the file, get out from while loop.
916  if (ifs.eof())
917  break;
918  }
919  // Close the TGC_Digitization_StripPosition.dat file
920  ifs.close();
921 
922  return StatusCode::SUCCESS;
923 }
924 
926  int stationEta, int stationPhi,
927  int gasGap,
928  const TgcSensor sensor) const {
929  // Convert std::string stationName to int iStationName from 41 to 48
930  int iStationName = getIStationName(stationName);
931 
932  // Subtract offsets to use these as the indices of the energyThreshold array
933  iStationName -= OFFSET_STATIONNAME;
937 
938  double energyThreshold = +999999.;
939 
940  // If the indices are valid, the energyThreshold array is fetched.
941  if ((iStationName >= 0 && iStationName < N_STATIONNAME) &&
942  (stationEta >= 0 && stationEta < N_STATIONETA) &&
943  (stationPhi >= 0 && stationPhi < N_STATIONPHI) &&
944  (gasGap >= 0 && gasGap < N_GASGAP)) {
945  energyThreshold = m_energyThreshold[iStationName][stationEta]
946  [stationPhi][gasGap][sensor];
947  }
948 
949  // Show the energy threshold value
950  ATH_MSG_VERBOSE("getEnergyThreshold"
951  << " stationName= " << iStationName + OFFSET_STATIONNAME
952  << " stationEta= " << stationEta + OFFSET_STATIONETA
953  << " stationPhi= " << stationPhi + OFFSET_STATIONPHI
954  << " gasGap= " << gasGap + OFFSET_GASGAP << " sensor= "
955  << sensor << " energyThreshold(MeV)= " << energyThreshold);
956 
957  return energyThreshold;
958 }
959 
960 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
962  const TgcDigitCrosstalkData* crosstalk, const Identifier elemId,
963  const int gasGap, const TgcSensor sensor, const int channel,
964  const float posInChan, const float digitTime, const float time_offset,
965  CLHEP::HepRandomEngine* rndmEngine, TgcDigitCollection* digits) const {
966  uint16_t station_number = m_idHelper->stationName(elemId);
967  uint16_t station_eta = std::abs(m_idHelper->stationEta(elemId));
969  uint16_t layer_id = (station_number << 5) + (station_eta << 2) + layer;
970 
971  if (station_number < OFFSET_STATIONNAME ||
972  station_number >= OFFSET_STATIONNAME + N_STATIONNAME ||
973  station_eta <= 0 || station_eta > N_ABSSTATIONETA || layer <= 0 ||
974  layer > N_GASGAP) {
975  ATH_MSG_ERROR("Unexpected indices are provided!");
976  return;
977  }
978 
979  float prob1CrossTalk =
980  this->getCrosstalkProbability(crosstalk, layer_id, sensor, 0);
981  float prob11CrossTalk =
982  this->getCrosstalkProbability(crosstalk, layer_id, sensor, 1);
983  float prob20CrossTalk =
984  this->getCrosstalkProbability(crosstalk, layer_id, sensor, 2);
985  float prob21CrossTalk =
986  this->getCrosstalkProbability(crosstalk, layer_id, sensor, 3);
987 
988  int nCrossTalks_neg = 0;
989  int nCrossTalks_pos = 0;
990 
991  if (posInChan < prob1CrossTalk) {
992  nCrossTalks_neg = 1; // 1-0
993  } else if (posInChan > 1. - prob1CrossTalk) {
994  nCrossTalks_pos = 1; // 0-1
995  } else {
996  double prob = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0);
997  if (prob < prob11CrossTalk / (1. - 2. * prob1CrossTalk)) {
998  nCrossTalks_neg = 1;
999  nCrossTalks_pos = 1; // 1-1
1000  } else if (prob < (prob20CrossTalk + prob11CrossTalk) /
1001  (1. - 2. * prob1CrossTalk)) {
1002  if (posInChan < 0.5) {
1003  nCrossTalks_neg = 2;
1004  } // 2-0
1005  else {
1006  nCrossTalks_pos = 2;
1007  } // 0-2
1008  } else {
1009  if (prob <
1010  (prob20CrossTalk + prob11CrossTalk + 2. * prob21CrossTalk) /
1011  (1. - 2. * prob1CrossTalk)) {
1012  if (posInChan < 0.5) {
1013  nCrossTalks_neg = 2;
1014  nCrossTalks_pos = 1;
1015  } // 2-1
1016  else {
1017  nCrossTalks_neg = 1;
1018  nCrossTalks_pos = 2;
1019  } // 1-2
1020  }
1021  }
1022  }
1023 
1024  if (nCrossTalks_neg == 0 && nCrossTalks_pos == 0)
1025  return; // No cross-talk case
1026 
1027  // No time structure is implemented yet.
1028  float dt = digitTime;
1029  TgcStation station = (station_number > 46) ? kINNER : kOUTER;
1030  uint16_t bctag =
1031  bcTagging(dt, m_gateTimeWindow[station][sensor], time_offset);
1032  // obtain max channel number
1033  Identifier thisId =
1034  m_idHelper->channelID(elemId, gasGap, (int)sensor, channel);
1035  int maxChannelNumber = m_idHelper->channelMax(thisId);
1036 
1037  for (int jChan = channel - nCrossTalks_neg;
1038  jChan <= channel + nCrossTalks_pos; jChan++) {
1039  if (jChan == channel || jChan < 1 || jChan > maxChannelNumber)
1040  continue;
1041 
1042  Identifier newId =
1043  m_idHelper->channelID(elemId, gasGap, (int)sensor, jChan);
1044  addDigit(newId, bctag, digits); // TgcDigit can be duplicated.
1045  }
1046 }
1047 
1049  int stationEta, int stationPhi, int gasGap) {
1050  bool v_isDeadChamber = true;
1051 
1052  // Convert std::string stationName to int iStationName from 41 to 48
1053  int iStationName = getIStationName(stationName);
1054 
1055  // Subtract offsets to use these as the indices of the energyThreshold array
1056  iStationName -= OFFSET_STATIONNAME;
1059  gasGap -= OFFSET_GASGAP;
1060 
1061  // If the indices are valid, the energyThreshold array is fetched.
1062  if ((iStationName >= 0 && iStationName < N_STATIONNAME) &&
1063  (stationEta >= 0 && stationEta < N_STATIONETA) &&
1064  (stationPhi >= 0 && stationPhi < N_STATIONPHI) &&
1065  (gasGap >= 0 && gasGap < N_GASGAP)) {
1066  v_isDeadChamber =
1067  m_isDeadChamber[iStationName][stationEta][stationPhi][gasGap];
1068  }
1069 
1070  // Show the energy threshold value
1071  ATH_MSG_VERBOSE("TgcDigitMaker::getEnergyThreshold"
1072  << " stationName= " << iStationName + OFFSET_STATIONNAME
1073  << " stationEta= " << stationEta + OFFSET_STATIONETA
1074  << " stationPhi= " << stationPhi + OFFSET_STATIONPHI
1075  << " gasGap= " << gasGap + OFFSET_GASGAP
1076  << " isDeadChamber= " << v_isDeadChamber);
1077 
1078  return v_isDeadChamber;
1079 }
1080 
1082  int iStationName = 0;
1083  if (stationName == "T1F")
1084  iStationName = 41;
1085  else if (stationName == "T1E")
1086  iStationName = 42;
1087  else if (stationName == "T2F")
1088  iStationName = 43;
1089  else if (stationName == "T2E")
1090  iStationName = 44;
1091  else if (stationName == "T3F")
1092  iStationName = 45;
1093  else if (stationName == "T3E")
1094  iStationName = 46;
1095  else if (stationName == "T4F")
1096  iStationName = 47;
1097  else if (stationName == "T4E")
1098  iStationName = 48;
1099 
1100  return iStationName;
1101 }
1102 
1104  int stationEta, int channel) const {
1105  // Convert std::string stationName to int iStationName from 41 to 48
1106  int iStationName = getIStationName(stationName);
1107 
1108  // Subtract offsets to use these as the indices of the energyThreshold array
1109  iStationName -= OFFSET_STATIONNAME;
1112 
1113  // Check the indices are valid
1114  if (iStationName < 0 || iStationName >= N_STATIONNAME)
1115  return 0.;
1116  if (stationEta < 0 || stationEta >= N_ABSSTATIONETA)
1117  return 0.;
1118  if (channel < 0 || channel >= N_STRIPCHANNEL)
1119  return 0.;
1120 
1121  return m_StripPos[iStationName][stationEta][channel];
1122 }
1123 
1124 float TgcDigitMaker::timeDiffByCableRadiusOfInner(const int iStationName,
1125  const int stationPhi,
1126  const int channel) {
1127  float delay{0.};
1128  if (iStationName != 47 && iStationName != 48)
1129  return delay; // Big Wheel has no delay for this.
1130 
1131  if (channel < 12 || (channel > 16 && channel < 27)) {
1132  int cablenum = (stationPhi >= 13) ? 25 - stationPhi : stationPhi;
1133  delay += 2.3 * CLHEP::ns - 0.06 * CLHEP::ns * float(cablenum);
1134  }
1135  return delay;
1136 }
1137 
1138 double TgcDigitMaker::getSigPropTimeDelay(const float cableDistance) {
1139  constexpr std::array<double, 2> par{0.0049 * CLHEP::ns, 0.0002 * CLHEP::ns};
1140  return par[0] * std::pow(cableDistance / CLHEP::m, 2) +
1141  par[1] * cableDistance / CLHEP::m;
1142 }
1143 
1145  const TgcDigitASDposData* readCdo, const int iStationName,
1146  const int stationEta, const int stationPhi, const TgcSensor sensor,
1147  const int channel, const float position) const {
1148  // EIFI has different parameter for phi, BW is same parameter for phi (i.e.
1149  // -99 in DB).
1150  int phiId = (iStationName >= 47) ? stationPhi : 0x1f;
1151  uint16_t chamberId = (iStationName << 8) + (stationEta << 5) + phiId;
1152 
1153  unsigned int asdNo = static_cast<unsigned int>(channel - 1) /
1155 
1156  float asd_position = 0.;
1157  const auto& map = (sensor == kSTRIP) ? readCdo->stripAsdPos : readCdo->wireAsdPos;
1158  auto it = map.find(chamberId);
1159 
1160  if (it != map.end()) {
1161  asd_position = it->second[asdNo] * CLHEP::m;
1162  } else {
1163  ATH_MSG_WARNING("Undefined chamberID is provided! station="
1164  << iStationName << ", eta=" << stationEta
1165  << ", phi=" << phiId);
1166  }
1167 
1168  float distance = fabs(position - asd_position);
1169  return distance;
1170 }
1171 
1173  const uint16_t station_num,
1174  const int station_eta,
1175  const TgcSensor sensor) {
1176  uint16_t chamberId =
1177  (station_num << 3) + static_cast<uint16_t>(std::abs(station_eta));
1178  return ((sensor == TgcSensor::kSTRIP)
1179  ? readCdo->stripOffset.find(chamberId)->second
1180  : readCdo->wireOffset.find(chamberId)->second);
1181 }
1182 
1184  const TgcDigitCrosstalkData* readCdo, const uint16_t layer_id,
1185  const TgcSensor sensor, const unsigned int index_prob) {
1186  if (readCdo == nullptr)
1187  return 0.; // no crosstalk
1188  return ((sensor == TgcSensor::kSTRIP)
1189  ? readCdo->getStripProbability(layer_id, index_prob)
1190  : readCdo->getWireProbability(layer_id, index_prob));
1191 }
TGCSimHit::energyDeposit
double energyDeposit() const
Definition: TGCSimHit.h:46
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
TgcDigitMaker.h
Muon::nsw::STGTPSegments::moduleIDBits::stationPhi
constexpr uint8_t stationPhi
station Phi 1 to 8
Definition: NSWSTGTPDecodeBitmaps.h:129
dumpTgcDigiDeadChambers.gasGap
list gasGap
Definition: dumpTgcDigiDeadChambers.py:33
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
TgcDigitMaker::m_StripPos
float m_StripPos[N_STATIONNAME][N_ABSSTATIONETA][N_STRIPCHANNEL]
Position of Strip Channel (Longer base or Shorter base)
Definition: TgcDigitMaker.h:186
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
MuonGM::TgcReadoutElement::chamberWidth
double chamberWidth(double z) const
plotting.yearwise_efficiency.channel
channel
Definition: yearwise_efficiency.py:28
TgcDigitMaker::TgcDigitMaker
TgcDigitMaker(const TgcHitIdHelper *hitIdHelper, const MuonGM::MuonDetectorManager *mdManager, unsigned int runperiod, const bool doFourBunch)
Definition: TgcDigitMaker.cxx:31
AthCheckMacros.h
TgcDigitMaker::readFileOfDeadChamber
StatusCode readFileOfDeadChamber()
Read share/TGC_Digitization_deadChamber.dat file.
Definition: TgcDigitMaker.cxx:771
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
PathResolver::find_file
static std::string find_file(const std::string &logical_file_name, const std::string &search_path, SearchType search_type=LocalSearch)
Definition: PathResolver.cxx:251
TgcIdHelper::channelMax
static int channelMax()
Definition: TgcIdHelper.cxx:671
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
TgcDigitMaker::getTimeOffset
static float getTimeOffset(const TgcDigitTimeOffsetData *readCdo, const uint16_t station_num, const int station_eta, const TgcSensor sensor)
Method to get time offset to absorb signal delay.
Definition: TgcDigitMaker.cxx:1172
TgcHitIdHelper::GetGasGap
int GetGasGap(const int &hid) const
Definition: TgcHitIdHelper.cxx:71
TgcDigitTimeOffsetData
Definition: TgcDigitTimeOffsetData.h:20
python.App.bins
bins
Definition: App.py:410
TgcDigitMaker::~TgcDigitMaker
virtual ~TgcDigitMaker()
TgcDigitMaker::kOUTER
@ kOUTER
Definition: TgcDigitMaker.h:101
dumpTgcDigiDeadChambers.stationName
dictionary stationName
Definition: dumpTgcDigiDeadChambers.py:30
MuonGM::TgcReadoutElement::stripDeltaPhi
double stripDeltaPhi() const
Definition: MuonDetDescr/MuonReadoutGeometry/src/TgcReadoutElement.cxx:99
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
skel.it
it
Definition: skel.GENtoEVGEN.py:423
TgcDigitASDposData::stripAsdPos
std::map< uint16_t, std::vector< float > > stripAsdPos
Definition: TgcDigitASDposData.h:35
TgcDigitMaker::TgcSensor
TgcSensor
Definition: TgcDigitMaker.h:102
TgcDigitMaker::OFFSET_STRIPCHANNEL
@ OFFSET_STRIPCHANNEL
Definition: TgcDigitMaker.h:99
TgcDigitMaker::getStripPosition
float getStripPosition(const std::string &stationName, int stationEta, int channel) const
Method to get position of Strip channel.
Definition: TgcDigitMaker.cxx:1103
TgcDigit::BC_PREVIOUS
@ BC_PREVIOUS
Definition: TgcDigit.h:37
TgcDigitCrosstalkData
Definition: TgcDigitCrosstalkData.h:22
TgcDigitMaker::getDistanceToAsdFromSensor
float getDistanceToAsdFromSensor(const TgcDigitASDposData *readCdo, const int iStationName, const int stationEta, const int stationPhi, const TgcSensor sensor, const int channel, const float position) const
Method to get propagation time to the ASD from the sensor.
Definition: TgcDigitMaker.cxx:1144
IdContext::end_index
size_type end_index(void) const
Definition: IdContext.h:106
TgcDigitMaker::readFileOfEnergyThreshold
StatusCode readFileOfEnergyThreshold()
Read share/TGC_Digitization_energyThreshold.dat file.
Definition: TgcDigitMaker.cxx:692
MuonIdHelper::stationName
int stationName(const Identifier &id) const
Definition: MuonIdHelper.cxx:804
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
checkRpcDigits.digit
digit
Definition: checkRpcDigits.py:186
covarianceTool.prob
prob
Definition: covarianceTool.py:678
TgcDigitMaker::m_mdManager
const MuonGM::MuonDetectorManager * m_mdManager
Definition: TgcDigitMaker.h:193
TgcDigitTimeOffsetData::wireOffset
std::map< uint16_t, float > wireOffset
Definition: TgcDigitTimeOffsetData.h:26
TgcDigitMaker::OFFSET_STATIONPHI
@ OFFSET_STATIONPHI
Definition: TgcDigitMaker.h:91
TgcDigitMaker::timeDiffByCableRadiusOfInner
static float timeDiffByCableRadiusOfInner(const int iStationName, const int stationPhi, const int channel)
Method to get time difference by cable radius of inner.
Definition: TgcDigitMaker.cxx:1124
Trk::energyDeposit
@ energyDeposit
Definition: MeasurementType.h:32
TgcHitIdHelper
Definition: TgcHitIdHelper.h:13
TgcDigitMaker::OFFSET_STATIONNAME
@ OFFSET_STATIONNAME
Definition: TgcDigitMaker.h:87
TgcDigitMaker::OFFSET_ISSTRIP
@ OFFSET_ISSTRIP
Definition: TgcDigitMaker.h:95
MuonGM::MuonDetectorManager::getTgcReadoutElement
const TgcReadoutElement * getTgcReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
Definition: MuonDetDescr/MuonReadoutGeometry/src/MuonDetectorManager.cxx:247
TGCSimHit::localPosition
const Amg::Vector3D & localPosition() const
Definition: TGCSimHit.h:43
TgcDigitMaker::initialize
StatusCode initialize()
Initializes TgcHitIdHelper, TgcIdHelper and random number of a stream for the digitization.
Definition: TgcDigitMaker.cxx:58
TgcDigitMaker::N_STATIONETA
@ N_STATIONETA
Definition: TgcDigitMaker.h:88
calibdata.valid
list valid
Definition: calibdata.py:45
FortranAlgorithmOptions.fileName
fileName
Definition: FortranAlgorithmOptions.py:13
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
TgcDigitMaker::kINNER
@ kINNER
Definition: TgcDigitMaker.h:101
AthMessaging::msgLvl
bool msgLvl(const MSG::Level lvl) const
Test the output level.
Definition: AthMessaging.h:151
TgcDigitMaker::OFFSET_ABSSTATIONETA
@ OFFSET_ABSSTATIONETA
Definition: TgcDigitMaker.h:97
DeMoScan.runperiod
runperiod
Definition: DeMoScan.py:324
xAOD::uint16_t
setWord1 uint16_t
Definition: eFexEMRoI_v1.cxx:88
lumiFormat.i
int i
Definition: lumiFormat.py:92
TgcDigitMaker::m_hitIdHelper
const TgcHitIdHelper * m_hitIdHelper
Definition: TgcDigitMaker.h:190
TgcDigitASDposData::N_CHANNELINPUT_TOASD
@ N_CHANNELINPUT_TOASD
Definition: TgcDigitASDposData.h:32
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
TgcHitIdHelper::GetStationName
std::string GetStationName(const int &hid) const
Definition: TgcHitIdHelper.cxx:52
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
angle
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
Definition: TRTDetectorFactory_Full.cxx:73
CaloNoise_fillDB.dt
dt
Definition: CaloNoise_fillDB.py:58
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
MuonGM::TgcReadoutElement::nWires
int nWires(int gasGap) const
Returns the total number of wires in a given gas gap.
TgcDigitCollection
Definition: TgcDigitCollection.h:17
TgcDigitMaker::N_ISSTRIP
@ N_ISSTRIP
Definition: TgcDigitMaker.h:94
TgcDigitMaker::efficiencyCheck
bool efficiencyCheck(const TgcSensor sensor, CLHEP::HepRandomEngine *rndmEngine) const
Determines whether a hit is detected or not.
Definition: TgcDigitMaker.cxx:629
TgcDigitMaker::m_gateTimeWindow
double m_gateTimeWindow[N_STATION][N_SENSOR]
define the time windows for signals from wiregangs and strips.
Definition: TgcDigitMaker.h:203
TgcDigitCollection.h
MuonGM::TgcReadoutElement
A TgcReadoutElement corresponds to a single TGC chamber; therefore typically a TGC station contains s...
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/TgcReadoutElement.h:42
TgcDigitTimeOffsetData::stripOffset
std::map< uint16_t, float > stripOffset
Definition: TgcDigitTimeOffsetData.h:25
TgcDigitMaker::m_vecAngle_Time
std::vector< std::vector< float > > m_vecAngle_Time
Definition: TgcDigitMaker.h:188
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
delay
double delay(std::size_t d)
Definition: JetTrigTimerTest.cxx:14
TgcDigitMaker::N_ABSSTATIONETA
@ N_ABSSTATIONETA
Definition: TgcDigitMaker.h:96
TgcHitIdHelper::GetHelper
static const TgcHitIdHelper * GetHelper()
Definition: TgcHitIdHelper.cxx:23
TgcDigitMaker::randomCrossTalk
void randomCrossTalk(const TgcDigitCrosstalkData *crosstalk, const Identifier elemId, const int gasGap, const TgcSensor sensor, const int channel, const float posInStrip, const float digitTime, const float time_offset, CLHEP::HepRandomEngine *rndmEngine, TgcDigitCollection *digits) const
Definition: TgcDigitMaker.cxx:961
MuonGM::MuonReadoutElement::globalPosition
const Amg::Vector3D globalPosition() const
Definition: MuonDetDescr/MuonReadoutGeometry/src/MuonReadoutElement.cxx:47
TgcDigitASDposData
Definition: TgcDigitASDposData.h:24
TgcDigitMaker::addDigit
static void addDigit(const Identifier id, const uint16_t bctag, TgcDigitCollection *digits)
Definition: TgcDigitMaker.cxx:672
MuonGM::TgcReadoutElement::nStrips
int nStrips(int gasGap) const
Returns the number of strips in a given gas gap.
Identifier::show
void show() const
Print out in hex form.
Definition: Identifier.cxx:36
AthMessaging::msg
MsgStream & msg() const
The standard message stream.
Definition: AthMessaging.h:164
TgcIdHelper::elementID
Identifier elementID(int stationName, int stationEta, int stationPhi) const
Definition: TgcIdHelper.cxx:556
TgcDigitMaker::kWIRE
@ kWIRE
Definition: TgcDigitMaker.h:102
CaloCondBlobAlgs_fillNoiseFromASCII.comment
string comment
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:27
TgcHitIdHelper::GetStationPhi
int GetStationPhi(const int &hid) const
Definition: TgcHitIdHelper.cxx:61
TgcDigitASDposData::wireAsdPos
std::map< uint16_t, std::vector< float > > wireAsdPos
Definition: TgcDigitASDposData.h:36
IdContext::begin_index
size_type begin_index(void) const
Definition: IdContext.h:100
dumpTgcDigiThreshold.isStrip
list isStrip
Definition: dumpTgcDigiThreshold.py:33
TgcDigitMaker::N_STRIPCHANNEL
@ N_STRIPCHANNEL
Definition: TgcDigitMaker.h:98
PathResolver.h
MuonGM::MuonDetectorManager::tgcIdHelper
const TgcIdHelper * tgcIdHelper() const
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/MuonDetectorManager.h:230
TGCSimHit::TGCid
int TGCid() const
Definition: TGCSimHit.h:45
TgcDigit::BC_NEXTNEXT
@ BC_NEXTNEXT
Definition: TgcDigit.h:37
createCoolChannelIdFile.par
par
Definition: createCoolChannelIdFile.py:29
TgcDigitMaker::TgcStation
TgcStation
Definition: TgcDigitMaker.h:101
MuonIdHelper::stationEta
int stationEta(const Identifier &id) const
Definition: MuonIdHelper.cxx:809
TgcDigitMaker::readFileOfStripPosition
StatusCode readFileOfStripPosition()
Read share/TGC_Digitization_StripPosition.dat file.
Definition: TgcDigitMaker.cxx:863
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
MuonDetectorManager.h
TGCSimHit
Definition: TGCSimHit.h:19
TgcDigitMaker::OFFSET_STATIONETA
@ OFFSET_STATIONETA
Definition: TgcDigitMaker.h:89
CalibCoolCompareRT.station_eta
station_eta
Definition: CalibCoolCompareRT.py:88
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
TgcDigitMaker::N_STATIONPHI
@ N_STATIONPHI
Definition: TgcDigitMaker.h:90
TgcDigitMaker::getIStationName
static int getIStationName(const std::string &staionName)
Get stationName integer from stationName string.
Definition: TgcDigitMaker.cxx:1081
TgcDigitMaker::executeDigi
TgcDigitCollection * executeDigi(const TGCSimHit *hit, const double globalHitTime, const TgcDigitASDposData *ASDpos, const TgcDigitTimeOffsetData *TOffset, const TgcDigitCrosstalkData *Crosstalk, CLHEP::HepRandomEngine *rndmEngine)
A single hit can be digitized in the two directions independently: R and phi directions.
Definition: TgcDigitMaker.cxx:87
MuonGM::MuonReadoutElement::getRsize
double getRsize() const
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/MuonReadoutElement.h:197
TgcDigitMaker::m_energyThreshold
double m_energyThreshold[N_STATIONNAME][N_STATIONETA][N_STATIONPHI][N_GASGAP][N_ISSTRIP]
Energy threshold value for each chamber.
Definition: TgcDigitMaker.h:181
AtlasDetectorID::show_to_string
std::string show_to_string(Identifier id, const IdContext *context=0, char sep='.') const
or provide the printout in string form
Definition: AtlasDetectorID.cxx:574
MuonGM::MuonDetectorManager
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/MuonDetectorManager.h:49
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
MuonIdHelper::get_hash
virtual int get_hash(const Identifier &id, IdentifierHash &hash_id, const IdContext *context=0) const override
Create hash id from compact id (return == 0 for OK)
Definition: MuonIdHelper.cxx:143
TgcDigitCrosstalkData::getStripProbability
float getStripProbability(const uint16_t layer_id, const unsigned int index_prob) const
Definition: TgcDigitCrosstalkData.cxx:15
TGCSimHit.h
TgcDigitMaker::m_runperiod
unsigned int m_runperiod
Definition: TgcDigitMaker.h:191
TgcDigitMaker::OFFSET_GASGAP
@ OFFSET_GASGAP
Definition: TgcDigitMaker.h:93
TgcDigitMaker::N_STATIONNAME
@ N_STATIONNAME
Definition: TgcDigitMaker.h:86
python.TriggerHandler.verbose
verbose
Definition: TriggerHandler.py:297
TgcDigitMaker::kSTRIP
@ kSTRIP
Definition: TgcDigitMaker.h:102
TgcDigitMaker::N_GASGAP
@ N_GASGAP
Definition: TgcDigitMaker.h:92
MuonIdHelper::module_context
IdContext module_context() const
id for module
Definition: MuonIdHelper.cxx:735
convertTimingResiduals.offset
offset
Definition: convertTimingResiduals.py:71
TgcDigitMaker::m_bunchCrossingTime
double m_bunchCrossingTime
Definition: TgcDigitMaker.h:204
TGCSimHit::localDireCos
const Amg::Vector3D & localDireCos() const
Definition: TGCSimHit.h:44
TgcDigitMaker::m_efficiency
float m_efficiency[N_SENSOR]
Definition: TgcDigitMaker.h:195
TgcDigitMaker::getEnergyThreshold
double getEnergyThreshold(const std::string &stationName, int stationEta, int stationPhi, int gasGap, const TgcSensor sensor) const
Get energy threshold value for each chamber.
Definition: TgcDigitMaker.cxx:925
python.SystemOfUnits.ns
int ns
Definition: SystemOfUnits.py:130
TgcHitIdHelper::GetStationEta
int GetStationEta(const int &hid) const
Definition: TgcHitIdHelper.cxx:66
TgcIdHelper::channelID
Identifier channelID(int stationName, int stationEta, int stationPhi, int gasGap, int isStrip, int channel) const
Definition: TgcIdHelper.cxx:583
TgcReadoutElement.h
TgcIdHelper.h
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
TgcDigitMaker::m_isDeadChamber
bool m_isDeadChamber[N_STATIONNAME][N_STATIONETA][N_STATIONPHI][N_GASGAP]
Dead chamber flag for each chamber.
Definition: TgcDigitMaker.h:183
Muon::nsw::STGTPSegments::moduleIDBits::stationEta
constexpr uint8_t stationEta
1 to 3
Definition: NSWSTGTPDecodeBitmaps.h:127
IdentifierHash
Definition: IdentifierHash.h:38
TgcDigitMaker::readFileOfTimeJitter
StatusCode readFileOfTimeJitter()
Reads parameters for intrinsic time response from timejitter.dat.
Definition: TgcDigitMaker.cxx:547
TgcDigitMaker::m_doFourBunchDigitization
bool m_doFourBunchDigitization
Activate four bunch digitization.
Definition: TgcDigitMaker.h:207
TgcDigitMaker::getCrosstalkProbability
static float getCrosstalkProbability(const TgcDigitCrosstalkData *readCdo, const uint16_t layer_id, const TgcSensor sensor, const unsigned int index_prob)
Method to get the channel crosstalk probability.
Definition: TgcDigitMaker.cxx:1183
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
IdContext
class IdContext
Definition: IdContext.h:34
TgcDigitMaker::m_idHelper
const TgcIdHelper * m_idHelper
Definition: TgcDigitMaker.h:194
readCCLHist.float
float
Definition: readCCLHist.py:83
TgcHitIdHelper.h
TgcDigitMaker::bcTagging
uint16_t bcTagging(const double digittime, const double window, const double offset) const
Definition: TgcDigitMaker.cxx:648
python.SystemOfUnits.degree
tuple degree
Definition: SystemOfUnits.py:106
TgcDigitMaker::isDeadChamber
bool isDeadChamber(const std::string &stationName, int stationEta, int stationPhi, int gasGap)
Method to check a chamber is dead or active.
Definition: TgcDigitMaker.cxx:1048
TgcDigitMaker::getSigPropTimeDelay
static double getSigPropTimeDelay(const float cableDistance)
Method to get signal propagation time delay.
Definition: TgcDigitMaker.cxx:1138
TgcDigitMaker::timeJitter
float timeJitter(const Amg::Vector3D &, CLHEP::HepRandomEngine *rndmEngine) const
Calculates intrinsic time response according to incident angle of a track based on time response para...
Definition: TgcDigitMaker.cxx:597
TgcDigitCrosstalkData::getWireProbability
float getWireProbability(const uint16_t layer_id, const unsigned int index_prob) const
Definition: TgcDigitCrosstalkData.cxx:26