The information is restored by MuonGeoModel and accessible from the class of TGCReadOutElement. As described the preceding section, R direction is digitized based on the wire ganging information in the database. Digits in phi direction are calculated based on the formula in which the structure of strips in TGC is well expressed for amdb_simrec.P.03. For amdb_simrec.Q or later, phi direction is digitized based on the parameter in the database as the same manner of those in R direction. The method determines the response time for digits which is commonly used for signals from wire gangs and strips, and signal propagation time along wires and strips. In case that response time is outside of the time window to be set, that hit is removed. This method also removes some hits based on the detection efficiency to be set.
92 {
93
94 constexpr float sensor_propagation_time =
95 3.3 * CLHEP::ns /
96 CLHEP::m;
97
98
99 constexpr float cable_propagation_time = 5.0 * CLHEP::ns / CLHEP::m;
100
101
102 constexpr float wire_pitch = 1.8 * CLHEP::mm;
103 constexpr float zwidth_frame = 17. * CLHEP::mm;
104
106
108 int Id = hit->
TGCid();
113
114
115 if (
isDeadChamber(stationName, stationEta, stationPhi, ilyr))
116 return nullptr;
117
118 const Identifier elemId =
119 m_idHelper->elementID(stationName, stationEta, stationPhi);
122
123 const MuonGM::TgcReadoutElement* tgcChamber =
125 if (!tgcChamber) {
128 return nullptr;
129 }
130
131 IdContext tgcContext =
m_idHelper->module_context();
132 IdentifierHash coll_hash;
133 if (
m_idHelper->get_hash(elemId, coll_hash, &tgcContext)) {
135 <<
"context begin_index = " << tgcContext.
begin_index()
136 <<
" context end_index = " << tgcContext.
end_index()
137 << " the identifier is " << elemId);
139 }
140
141 std::unique_ptr<TgcDigitCollection> digits =
142 std::make_unique<TgcDigitCollection>(elemId, coll_hash);
143
145 float height = tgcChamber->
getRsize();
146 float hmin = sqrt(
pow(centreChamber.x(), 2) +
pow(centreChamber.y(), 2)) -
147 height / 2.;
148
149
151
152
154
155
156 float distanceZ = 1.4 * CLHEP::mm / direCos[0] * direCos[2];
157 float zLocal = localPos.z() + distanceZ;
158
159
160 float distanceY = 1.4 * CLHEP::mm / direCos[0] * direCos[1];
161
162
164 float yLocal = ySign * (localPos.y() + distanceY);
165
166
167
168
169 double tofCorrection =
170 (sqrt(
pow(hmin + zwidth_frame, 2) +
pow(centreChamber.z(), 2)) /
171 (299792458. * (CLHEP::m / CLHEP::s)));
172
173
174 float bunchTime = globalHitTime - tofCorrection;
175
176 static const float jitterInitial = 9999.;
177 float jitter = jitterInitial;
178
179
181
183
184
185
186
187
188
189
191
192 if ((energyDeposit >= -1. &&
194 stationName, stationEta, stationPhi, ilyr,
kWIRE,
195 energyDeposit)) ||
196 (energyDeposit < -1. &&
198 kWIRE, rndmEngine))) {
199
200 int iWireGroup[2];
201 float posInWireGroup[2] = {0., 0.};
202 for (int iPosition = 0; iPosition < 2; iPosition++) {
203 int nWireOffset = (std::abs(stationEta) == 5 ||
205 ? 1
206 : 0;
207
208
209
210
211 double zPosInSensArea =
212 zLocal +
static_cast<double>(tgcChamber->
nWires(ilyr) -
213 nWireOffset) *
214 wire_pitch / 2.;
215
216
217 if (zPosInSensArea < 0. ||
218 zPosInSensArea > tgcChamber->
nWires(ilyr) * wire_pitch) {
219 iWireGroup[iPosition] = 0;
220 posInWireGroup[iPosition] = 0.;
222 "executeDigi(): Wire: Hit position located at outside of a "
223 "sensitive volume, "
224 << " id: " << stationName << "/" << stationEta << "/"
225 << stationPhi << "/" << ilyr
226 << " position: " << zPosInSensArea << " xlocal: " << zLocal
227 << " dir cosine: " << direCos[0] << "/" << direCos[1] << "/"
228 << direCos[2]
229 << " active region: " << height - zwidth_frame * 2.);
230 } else {
231 int igang = 1;
232 int wire_index = 0;
233 while (wire_pitch * (static_cast<float>(wire_index)) <
234 zPosInSensArea &&
235 igang <= tgcChamber->nWireGangs(ilyr)) {
236 wire_index += tgcChamber->
nWires(ilyr, igang);
237 igang++;
238 }
239 posInWireGroup[iPosition] =
240 (zPosInSensArea / wire_pitch -
241 (static_cast<float>(wire_index))) /
242 (static_cast<float>(
243 tgcChamber->
nWires(ilyr, igang - 1))) +
244 1.;
245
246 iWireGroup[iPosition] = ((1 == igang) ? 1 : igang - 1);
247 }
248 }
249
250 unsigned int jWG[2] = {
251 (iWireGroup[0] <= iWireGroup[1]) ? (unsigned int)(0)
253 (iWireGroup[0] <= iWireGroup[1]) ? (
unsigned int)(1)
255 int iWG[2] = {iWireGroup[jWG[0]], iWireGroup[jWG[1]]};
256 float posInWG[2] = {posInWireGroup[jWG[0]], posInWireGroup[jWG[1]]};
257 if (iWG[0] != iWG[1]) {
258 ATH_MSG_DEBUG(
"executeDigi(): Multihits found in WIRE GROUPs:"
259 << iWG[0] << " " << iWG[1]);
260 }
261
262
263 for (int iwg = iWG[0]; iwg <= iWG[1]; iwg++) {
264 if (1 <= iwg && iwg <= tgcChamber->nWireGangs(ilyr)) {
265
266 float wire_timeOffset =
267 (TOffset != nullptr)
270 : 0.;
271
272 if (iStationName > 46)
273 wire_timeOffset +=
274 (iwg < 17) ? 0.5 * CLHEP::ns : -0.5 * CLHEP::
ns;
275
276
278 if (jit < jitter)
279 jitter = jit;
280 float ySignPhi = (
stationPhi % 2 == 1) ? -1. : +1.;
281
282
283
284 float wTimeDiffByRadiusOfInner =
286 iwg);
287 double digit_time =
288 bunchTime + jitter + wTimeDiffByRadiusOfInner;
289 float wASDDis{-1000.};
290 if (ASDpos != nullptr) {
292 ASDpos, iStationName, abs(stationEta), stationPhi,
294 float wCableDis =
295 wASDDis + (ySignPhi * yLocal +
297 float wPropTime =
298 sensor_propagation_time *
299 (ySignPhi * yLocal +
301 cable_propagation_time * wASDDis;
302 digit_time +=
304 }
305
310 wire_timeOffset);
311
312 if (bctag == 0x0) {
314 "WireGroup: digitized time "
315 << digit_time << " ns is outside of time window from "
316 << wire_timeOffset << ". bunchTime: " << bunchTime
317 << " time jitter: " << jitter << " propagation time: "
318 << sensor_propagation_time *
319 (ySignPhi * yLocal +
321 cable_propagation_time * wASDDis
322 << " time difference by cable radius of inner station: "
323 << wTimeDiffByRadiusOfInner);
324 } else {
326 stationName, stationEta, stationPhi, ilyr, (
int)
kWIRE,
327 iwg);
328 addDigit(newId, bctag, digits.get());
329
330 if (iwg == iWG[0]) {
332 posInWG[0], digit_time, wire_timeOffset,
333 rndmEngine, digits.get());
334 }
335
337 "WireGroup: newid breakdown digitTime x/y/z direcos "
338 "height_gang bctag: "
339 << newId << " " << stationName << "/" << stationEta
340 << "/" << stationPhi << "/" << ilyr << "/"
341 << "WIRE/" << iwg << " " << digit_time << " "
342 << localPos.x() << "/" << localPos.y() << "/"
343 << localPos.z() << " " << direCos.x() << "/"
344 << direCos.y() << "/" << direCos.z() << " " << height
345 <<
" " << tgcChamber->
nWires(ilyr, iwg) <<
" "
346 << bctag);
347 }
348 } else {
350 "Wire Gang id is out of range. id, x/y/z, height: "
351 << iwg << " " << localPos.x() << "/" << localPos.y() << "/"
352 << localPos.z() << " " << height);
353 }
354 }
355 }
356
359
360 if ((ilyr != 2 || (
stationName.compare(0, 2,
"T1") !=
361 0)) &&
362 ((energyDeposit < -1. &&
364 sensor, rndmEngine)) ||
365 (energyDeposit >= -1. &&
367 stationName, stationEta, stationPhi, ilyr, sensor,
368 energyDeposit)))
369 ) {
370
371
372 int iStrip[2];
373 float posInStrip[2] = {0., 0.};
374
375 for (int iPosition = 0; iPosition < 2; iPosition++) {
376
377
378 float zPos = zLocal + height / 2. - zwidth_frame;
379 if (zPos < 0.) {
380 iStrip[iPosition] = 0;
381 posInStrip[iPosition] = 0.;
383 "Strip: Hit position located at outside of a sensitive "
384 "volume, id, position, xlocal0/1, dir cosine: "
385 << stationName << "/" << stationEta << "/" << stationPhi
386 << "/" << ilyr << zPos << " " << zLocal << " " << direCos[0]
387 << "/" << direCos[1] << "/" << direCos[2]);
388 } else if (zPos > height - zwidth_frame * 2.) {
389 iStrip[iPosition] = tgcChamber->
nStrips(ilyr) + 1;
390 posInStrip[iPosition] = 0.;
392 "Strip: Hit position located at outside of a sensitive "
393 "volume, id, position, active region: "
394 << stationName << "/" << stationEta << "/" << stationPhi
395 << "/" << ilyr << zPos << " "
396 << height - zwidth_frame * 2.);
397 } else {
398
399
400
401
402
403
405 float phiLocal = atan2(yLocal, zLocal + height / 2. + hmin);
406
408 "dphi, phiLocal, yLocal, zLocall+ height/2.+hmin: "
409 << dphi << " " << phiLocal << " " << yLocal << " "
410 << zLocal + height / 2. + hmin);
411
412 int istr = 0;
413 if ((stationEta > 0 && ilyr == 1) ||
414 (stationEta < 0 && ilyr != 1)) {
415 istr = static_cast<int>(floor(phiLocal / dphi + 15.75)) + 1;
416 posInStrip[iPosition] =
417 phiLocal / dphi + 15.75 - static_cast<float>(istr - 1);
418 if (istr > 30) {
419 istr = static_cast<int>(floor(
420 (phiLocal - dphi * 14.25) / (dphi / 2.))) +
421 31;
422 posInStrip[iPosition] =
423 (phiLocal - dphi * 14.25) / (dphi / 2.) -
424 static_cast<float>(istr - 31);
425 }
426 } else {
427 istr = static_cast<int>(floor(phiLocal / dphi + 16.25)) + 1;
428 posInStrip[iPosition] =
429 phiLocal / dphi + 16.25 - static_cast<float>(istr - 1);
430 if (istr < 3) {
431 istr = static_cast<int>(floor(
432 (phiLocal + dphi * 14.25) / (dphi / 2.))) +
433 3;
434 posInStrip[iPosition] =
435 (phiLocal + dphi * 14.25) / (dphi / 2.) -
436 static_cast<float>(istr - 3);
437 }
438 }
439 if (istr < 1) {
440 istr = 0;
441 posInStrip[iPosition] = 0.;
442 } else if (32 < istr) {
443 istr = 33;
444 posInStrip[iPosition] = 0.;
445 }
446 iStrip[iPosition] = istr;
447 }
448 }
449
450 unsigned int jStr[2] = {
451 (iStrip[0] <= iStrip[1]) ? (
unsigned int)(0) : (
unsigned int)(1),
453 int iStr[2] = {iStrip[jStr[0]], iStrip[jStr[1]]};
454 float posInStr[2] = {posInStrip[jStr[0]], posInStrip[jStr[1]]};
455 if (iStr[0] != iStr[1]) {
457 << iStr[1]);
458 }
459
460
461 float strip_timeOffset =
462 (TOffset != nullptr)
464 : 0.;
465
466 for (int istr = iStr[0]; istr <= iStr[1]; istr++) {
467 if (1 <= istr && istr <= 32) {
468
469 if (jitter > jitterInitial - 0.1) {
471 }
472 float zSignEta =
473 (abs(stationEta) % 2 == 1 && abs(stationEta) != 5) ? -1.
474 : +1.;
475
476
477
478 float sTimeDiffByRadiusOfInner =
480 istr);
481 float sDigitTime =
482 bunchTime + jitter +
483 sensor_propagation_time *
484 (height / 2. + zwidth_frame + zSignEta * zLocal) +
485 sTimeDiffByRadiusOfInner;
486 float sASDDis{-1000};
487 if (ASDpos != nullptr) {
489 ASDpos, iStationName, abs(stationEta), stationPhi,
490 sensor, istr,
492 float sCableDis = sASDDis + (height / 2. + zwidth_frame +
493 zSignEta * zLocal);
495 sASDDis * cable_propagation_time;
496 }
497
502 strip_timeOffset);
503
504 if (bctag == 0x0) {
506 "Strip: Digitized time is outside of time window. "
507 << sDigitTime << " bunchTime: " << bunchTime
508 << " time jitter: " << jitter << " propagation time: "
509 << sensor_propagation_time *
510 (height / 2. + zwidth_frame + zSignEta * zLocal)
511 << " time difference by cable radius of inner station: "
512 << sTimeDiffByRadiusOfInner);
513 } else {
515 stationName, stationEta, stationPhi, ilyr, (int)sensor,
516 istr);
517 addDigit(newId, bctag, digits.get());
518
519 if (istr == iStr[0]) {
521 iStr[0], posInStr[0], sDigitTime,
522 strip_timeOffset, rndmEngine,
523 digits.get());
524 }
525
527 "Strip: newid breakdown digitTime x/y/z direcos "
528 "r_center bctag: "
529 << newId << " " << stationName << "/" << stationEta
530 << "/" << stationPhi << "/" << ilyr << "/" << sensor
531 << "/" << istr << " " << sDigitTime << " "
532 << localPos.x() << "/" << localPos.y() << "/"
533 << localPos.z() << " " << direCos.x() << "/"
534 << direCos.y() << "/" << direCos.z() << " "
535 << height / 2. + hmin << " " << bctag);
536 }
537 } else {
539 << ilyr << " " << istr);
540 }
541 }
542 }
543
544 return digits.release();
545}
#define ATH_MSG_WARNING(x)
constexpr int pow(int base, int exp) noexcept
size_type begin_index() const
size_type end_index() const
void show() const
Print out in hex form.
const Amg::Vector3D globalPosition() const
double stripDeltaPhi() const
double chamberWidth(double z) const
int nWires(int gasGap) const
Returns the total number of wires in a given gas gap.
int nStrips(int gasGap) const
Returns the number of strips in a given gas gap.
double energyDeposit() const
const Amg::Vector3D & localDireCos() const
const Amg::Vector3D & localPosition() const
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.
static double getSigPropTimeDelay(const float cableDistance)
Method to get signal propagation time delay.
static void addDigit(const Identifier id, const uint16_t bctag, TgcDigitCollection *digits)
bool efficiencyCheck(const TgcSensor sensor, CLHEP::HepRandomEngine *rndmEngine) const
Determines whether a hit is detected or not.
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.
static int getIStationName(const std::string &staionName)
Get stationName integer from stationName string.
static float timeDiffByCableRadiusOfInner(const int iStationName, const int stationPhi, const int channel)
Method to get time difference by cable radius of inner.
float getStripPosition(const std::string &stationName, int stationEta, int channel) const
Method to get position of Strip channel.
bool isDeadChamber(const std::string &stationName, int stationEta, int stationPhi, int gasGap)
Method to check a chamber is dead or active.
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...
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
uint16_t bcTagging(const double digittime, const double window, const double offset) const
Eigen::Matrix< double, 3, 1 > Vector3D
constexpr uint8_t stationPhi
station Phi 1 to 8
constexpr uint8_t stationEta
1 to 3