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);
138 }
139
140 std::unique_ptr<TgcDigitCollection> digits =
141 std::make_unique<TgcDigitCollection>(elemId, coll_hash);
142
144 float height = tgcChamber->
getRsize();
145 float hmin = sqrt(
pow(centreChamber.x(), 2) +
pow(centreChamber.y(), 2)) -
146 height / 2.;
147
148
150
151
153
154
155 float distanceZ = 1.4 * CLHEP::mm / direCos[0] * direCos[2];
156 float zLocal = localPos.z() + distanceZ;
157
158
159 float distanceY = 1.4 * CLHEP::mm / direCos[0] * direCos[1];
160
161
163 float yLocal = ySign * (localPos.y() + distanceY);
164
165
166
167
168 double tofCorrection =
169 (sqrt(
pow(hmin + zwidth_frame, 2) +
pow(centreChamber.z(), 2)) /
170 (299792458. * (CLHEP::m / CLHEP::s)));
171
172
173 float bunchTime = globalHitTime - tofCorrection;
174
175 static const float jitterInitial = 9999.;
176 float jitter = jitterInitial;
177
178
180
182
183
184
185
186
187
188
190
191 if ((energyDeposit >= -1. &&
193 stationName, stationEta, stationPhi, ilyr,
kWIRE,
194 energyDeposit)) ||
195 (energyDeposit < -1. &&
197 kWIRE, rndmEngine))) {
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 ||
204 ? 1
205 : 0;
206
207
208
209
210 double zPosInSensArea =
211 zLocal +
static_cast<double>(tgcChamber->
nWires(ilyr) -
212 nWireOffset) *
213 wire_pitch / 2.;
214
215
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)
252 (iWireGroup[0] <= iWireGroup[1]) ? (
unsigned int)(1)
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
262 for (int iwg = iWG[0]; iwg <= iWG[1]; iwg++) {
263 if (1 <= iwg && iwg <= tgcChamber->nWireGangs(ilyr)) {
264
265 float wire_timeOffset =
266 (TOffset != nullptr)
269 : 0.;
270
271 if (iStationName > 46)
272 wire_timeOffset +=
273 (iwg < 17) ? 0.5 * CLHEP::ns : -0.5 * CLHEP::
ns;
274
275
277 if (jit < jitter)
278 jitter = jit;
279 float ySignPhi = (
stationPhi % 2 == 1) ? -1. : +1.;
280
281
282
283 float wTimeDiffByRadiusOfInner =
285 iwg);
286 double digit_time =
287 bunchTime + jitter + wTimeDiffByRadiusOfInner;
288 float wASDDis{-1000.};
289 if (ASDpos != nullptr) {
291 ASDpos, iStationName, abs(stationEta), stationPhi,
293 float wCableDis =
294 wASDDis + (ySignPhi * yLocal +
296 float wPropTime =
297 sensor_propagation_time *
298 (ySignPhi * yLocal +
300 cable_propagation_time * wASDDis;
301 digit_time +=
303 }
304
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 +
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]) {
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 }
355
358
359 if ((ilyr != 2 || (
stationName.compare(0, 2,
"T1") !=
360 0)) &&
361 ((energyDeposit < -1. &&
363 sensor, rndmEngine)) ||
364 (energyDeposit >= -1. &&
366 stationName, stationEta, stationPhi, ilyr, sensor,
367 energyDeposit)))
368 ) {
369
370
371 int iStrip[2];
372 float posInStrip[2] = {0., 0.};
373
374 for (int iPosition = 0; iPosition < 2; iPosition++) {
375
376
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 {
397
398
399
400
401
402
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) {
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) {
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 }
447 }
448
449 unsigned int jStr[2] = {
450 (iStrip[0] <= iStrip[1]) ? (
unsigned int)(0) : (
unsigned int)(1),
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]) {
456 << iStr[1]);
457 }
458
459
460 float strip_timeOffset =
461 (TOffset != nullptr)
463 : 0.;
464
465 for (int istr = iStr[0]; istr <= iStr[1]; istr++) {
466 if (1 <= istr && istr <= 32) {
467
468 if (jitter > jitterInitial - 0.1) {
470 }
471 float zSignEta =
472 (abs(stationEta) % 2 == 1 && abs(stationEta) != 5) ? -1.
473 : +1.;
474
475
476
477 float sTimeDiffByRadiusOfInner =
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) {
488 ASDpos, iStationName, abs(stationEta), stationPhi,
489 sensor, istr,
491 float sCableDis = sASDDis + (height / 2. + zwidth_frame +
492 zSignEta * zLocal);
494 sASDDis * cable_propagation_time;
495 }
496
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]) {
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 {
538 << ilyr << " " << istr);
539 }
540 }
541 }
542
543 return digits.release();
544}
#define ATH_MSG_WARNING(x)
size_type begin_index() const
size_type end_index() const
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