89 const TGCSimHit* hit,
const double globalHitTime,
92 CLHEP::HepRandomEngine* rndmEngine) {
94 constexpr float sensor_propagation_time =
99 constexpr float cable_propagation_time = 5.0 * CLHEP::ns / CLHEP::m;
102 constexpr float wire_pitch = 1.8 * CLHEP::mm;
103 constexpr float zwidth_frame = 17. * CLHEP::mm;
108 int Id = hit->
TGCid();
115 if (
isDeadChamber(stationName, stationEta, stationPhi, ilyr))
119 m_idHelper->elementID(stationName, stationEta, stationPhi);
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);
141 std::unique_ptr<TgcDigitCollection> digits =
142 std::make_unique<TgcDigitCollection>(elemId, coll_hash);
145 float height = tgcChamber->
getRsize();
146 float hmin = sqrt(
pow(centreChamber.x(), 2) +
pow(centreChamber.y(), 2)) -
156 float distanceZ = 1.4 * CLHEP::mm / direCos[0] * direCos[2];
157 float zLocal = localPos.z() + distanceZ;
160 float distanceY = 1.4 * CLHEP::mm / direCos[0] * direCos[1];
163 float ySign = (stationEta < 0) ? +1. : -1.;
164 float yLocal = ySign * (localPos.y() + distanceY);
169 double tofCorrection =
170 (sqrt(
pow(hmin + zwidth_frame, 2) +
pow(centreChamber.z(), 2)) /
171 (299792458. * (CLHEP::m / CLHEP::s)));
174 float bunchTime = globalHitTime - tofCorrection;
176 static const float jitterInitial = 9999.;
177 float jitter = jitterInitial;
192 if ((energyDeposit >= -1. &&
194 stationName, stationEta, stationPhi, ilyr,
kWIRE,
196 (energyDeposit < -1. &&
198 kWIRE, rndmEngine))) {
201 float posInWireGroup[2] = {0., 0.};
202 for (
int iPosition = 0; iPosition < 2; iPosition++) {
203 int nWireOffset = (std::abs(stationEta) == 5 ||
204 stationName.compare(0, 2,
"T4") == 0)
211 double zPosInSensArea =
212 zLocal +
static_cast<double>(tgcChamber->
nWires(ilyr) -
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 "
224 <<
" id: " << stationName <<
"/" << stationEta <<
"/"
225 << stationPhi <<
"/" << ilyr
226 <<
" position: " << zPosInSensArea <<
" xlocal: " << zLocal
227 <<
" dir cosine: " << direCos[0] <<
"/" << direCos[1] <<
"/"
229 <<
" active region: " << height - zwidth_frame * 2.);
233 while (wire_pitch * (
static_cast<float>(wire_index)) <
235 igang <= tgcChamber->nWireGangs(ilyr)) {
236 wire_index += tgcChamber->
nWires(ilyr, igang);
239 posInWireGroup[iPosition] =
240 (zPosInSensArea / wire_pitch -
241 (
static_cast<float>(wire_index))) /
243 tgcChamber->
nWires(ilyr, igang - 1))) +
246 iWireGroup[iPosition] = ((1 == igang) ? 1 : igang - 1);
250 unsigned int jWG[2] = {
251 (iWireGroup[0] <= iWireGroup[1]) ? (
unsigned int)(0)
253 (iWireGroup[0] <= iWireGroup[1]) ? (
unsigned int)(1)
254 : (
unsigned int)(0)};
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]);
263 for (
int iwg = iWG[0]; iwg <= iWG[1]; iwg++) {
264 if (1 <= iwg && iwg <= tgcChamber->nWireGangs(ilyr)) {
266 float wire_timeOffset =
272 if (iStationName > 46)
274 (iwg < 17) ? 0.5 * CLHEP::ns : -0.5 * CLHEP::ns;
280 float ySignPhi = (stationPhi % 2 == 1) ? -1. : +1.;
284 float wTimeDiffByRadiusOfInner =
288 bunchTime + jitter + wTimeDiffByRadiusOfInner;
289 float wASDDis{-1000.};
290 if (ASDpos !=
nullptr) {
292 ASDpos, iStationName, abs(stationEta), stationPhi,
295 wASDDis + (ySignPhi * yLocal +
298 sensor_propagation_time *
301 cable_propagation_time * wASDDis;
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 *
321 cable_propagation_time * wASDDis
322 <<
" time difference by cable radius of inner station: "
323 << wTimeDiffByRadiusOfInner);
326 stationName, stationEta, stationPhi, ilyr, (
int)
kWIRE,
328 addDigit(newId, bctag, digits.get());
332 posInWG[0], digit_time, wire_timeOffset,
333 rndmEngine, digits.get());
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) <<
" "
350 "Wire Gang id is out of range. id, x/y/z, height: "
351 << iwg <<
" " << localPos.x() <<
"/" << localPos.y() <<
"/"
352 << localPos.z() <<
" " << height);
360 if ((ilyr != 2 || (stationName.compare(0, 2,
"T1") !=
362 ((energyDeposit < -1. &&
364 sensor, rndmEngine)) ||
365 (energyDeposit >= -1. &&
367 stationName, stationEta, stationPhi, ilyr, sensor,
373 float posInStrip[2] = {0., 0.};
375 for (
int iPosition = 0; iPosition < 2; iPosition++) {
378 float zPos = zLocal + height / 2. - zwidth_frame;
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.);
405 float phiLocal = atan2(yLocal, zLocal + height / 2. + hmin);
408 "dphi, phiLocal, yLocal, zLocall+ height/2.+hmin: "
409 << dphi <<
" " << phiLocal <<
" " << yLocal <<
" "
410 << zLocal + height / 2. + hmin);
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);
419 istr =
static_cast<int>(floor(
420 (phiLocal - dphi * 14.25) / (dphi / 2.))) +
422 posInStrip[iPosition] =
423 (phiLocal - dphi * 14.25) / (dphi / 2.) -
424 static_cast<float>(istr - 31);
427 istr =
static_cast<int>(floor(phiLocal / dphi + 16.25)) + 1;
428 posInStrip[iPosition] =
429 phiLocal / dphi + 16.25 -
static_cast<float>(istr - 1);
431 istr =
static_cast<int>(floor(
432 (phiLocal + dphi * 14.25) / (dphi / 2.))) +
434 posInStrip[iPosition] =
435 (phiLocal + dphi * 14.25) / (dphi / 2.) -
436 static_cast<float>(istr - 3);
441 posInStrip[iPosition] = 0.;
442 }
else if (32 < istr) {
444 posInStrip[iPosition] = 0.;
446 iStrip[iPosition] = istr;
450 unsigned int jStr[2] = {
451 (iStrip[0] <= iStrip[1]) ? (
unsigned int)(0) : (
unsigned int)(1),
452 (iStrip[0] <= iStrip[1]) ? (
unsigned int)(1) : (
unsigned int)(0)};
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]) {
461 float strip_timeOffset =
466 for (
int istr = iStr[0]; istr <= iStr[1]; istr++) {
467 if (1 <= istr && istr <= 32) {
469 if (jitter > jitterInitial - 0.1) {
473 (abs(stationEta) % 2 == 1 && abs(stationEta) != 5) ? -1.
478 float sTimeDiffByRadiusOfInner =
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,
492 float sCableDis = sASDDis + (height / 2. + zwidth_frame +
495 sASDDis * cable_propagation_time;
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);
515 stationName, stationEta, stationPhi, ilyr, (
int)sensor,
517 addDigit(newId, bctag, digits.get());
519 if (istr == iStr[0]) {
521 iStr[0], posInStr[0], sDigitTime,
522 strip_timeOffset, rndmEngine,
527 "Strip: newid breakdown digitTime x/y/z direcos "
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);
539 << ilyr <<
" " << istr);
544 return digits.release();
1016 const int gasGap,
const TgcSensor sensor,
const int channel,
1017 const float posInChan,
const float digitTime,
const float time_offset,
1019 uint16_t station_number =
m_idHelper->stationName(elemId);
1020 uint16_t station_eta = std::abs(
m_idHelper->stationEta(elemId));
1021 uint16_t layer = gasGap;
1022 uint16_t layer_id = (station_number << 5) + (station_eta << 2) + layer;
1032 float prob1CrossTalk =
1034 float prob11CrossTalk =
1036 float prob20CrossTalk =
1038 float prob21CrossTalk =
1041 int nCrossTalks_neg = 0;
1042 int nCrossTalks_pos = 0;
1044 if (posInChan < prob1CrossTalk) {
1045 nCrossTalks_neg = 1;
1046 }
else if (posInChan > 1. - prob1CrossTalk) {
1047 nCrossTalks_pos = 1;
1049 double prob = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0);
1050 if (prob < prob11CrossTalk / (1. - 2. * prob1CrossTalk)) {
1051 nCrossTalks_neg = 1;
1052 nCrossTalks_pos = 1;
1053 }
else if (prob < (prob20CrossTalk + prob11CrossTalk) /
1054 (1. - 2. * prob1CrossTalk)) {
1055 if (posInChan < 0.5) {
1056 nCrossTalks_neg = 2;
1059 nCrossTalks_pos = 2;
1063 (prob20CrossTalk + prob11CrossTalk + 2. * prob21CrossTalk) /
1064 (1. - 2. * prob1CrossTalk)) {
1065 if (posInChan < 0.5) {
1066 nCrossTalks_neg = 2;
1067 nCrossTalks_pos = 1;
1070 nCrossTalks_neg = 1;
1071 nCrossTalks_pos = 2;
1077 if (nCrossTalks_neg == 0 && nCrossTalks_pos == 0)
1081 float dt = digitTime;
1087 m_idHelper->channelID(elemId, gasGap, (
int)sensor, channel);
1088 int maxChannelNumber =
m_idHelper->channelMax(thisId);
1090 for (
int jChan = channel - nCrossTalks_neg;
1091 jChan <= channel + nCrossTalks_pos; jChan++) {
1092 if (jChan == channel || jChan < 1 || jChan > maxChannelNumber)
1096 m_idHelper->channelID(elemId, gasGap, (
int)sensor, jChan);