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);
140 std::unique_ptr<TgcDigitCollection> digits =
141 std::make_unique<TgcDigitCollection>(elemId, coll_hash);
144 float height = tgcChamber->
getRsize();
145 float hmin = sqrt(pow(centreChamber.x(), 2) + pow(centreChamber.y(), 2)) -
155 float distanceZ = 1.4 * CLHEP::mm / direCos[0] * direCos[2];
156 float zLocal = localPos.z() + distanceZ;
159 float distanceY = 1.4 * CLHEP::mm / direCos[0] * direCos[1];
162 float ySign = (stationEta < 0) ? +1. : -1.;
163 float yLocal = ySign * (localPos.y() + distanceY);
168 double tofCorrection =
169 (sqrt(pow(hmin + zwidth_frame, 2) + pow(centreChamber.z(), 2)) /
170 (299792458. * (CLHEP::m / CLHEP::s)));
173 float bunchTime = globalHitTime - tofCorrection;
175 static const float jitterInitial = 9999.;
176 float jitter = jitterInitial;
191 if ((energyDeposit >= -1. &&
193 stationName, stationEta, stationPhi, ilyr,
kWIRE,
195 (energyDeposit < -1. &&
197 kWIRE, rndmEngine))) {
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)
210 double zPosInSensArea =
211 zLocal +
static_cast<double>(tgcChamber->
nWires(ilyr) -
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 "
223 <<
" id: " << stationName <<
"/" << stationEta <<
"/"
224 << stationPhi <<
"/" << ilyr
225 <<
" position: " << zPosInSensArea <<
" xlocal: " << zLocal
226 <<
" dir cosine: " << direCos[0] <<
"/" << direCos[1] <<
"/"
228 <<
" active region: " << height - zwidth_frame * 2.);
232 while (wire_pitch * (
static_cast<float>(wire_index)) <
234 igang <= tgcChamber->nWireGangs(ilyr)) {
235 wire_index += tgcChamber->
nWires(ilyr, igang);
238 posInWireGroup[iPosition] =
239 (zPosInSensArea / wire_pitch -
240 (
static_cast<float>(wire_index))) /
242 tgcChamber->
nWires(ilyr, igang - 1))) +
245 iWireGroup[iPosition] = ((1 == igang) ? 1 : igang - 1);
249 unsigned int jWG[2] = {
250 (iWireGroup[0] <= iWireGroup[1]) ? (
unsigned int)(0)
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]);
262 for (
int iwg = iWG[0]; iwg <= iWG[1]; iwg++) {
263 if (1 <= iwg && iwg <= tgcChamber->nWireGangs(ilyr)) {
265 float wire_timeOffset =
271 if (iStationName > 46)
273 (iwg < 17) ? 0.5 * CLHEP::ns : -0.5 * CLHEP::ns;
279 float ySignPhi = (stationPhi % 2 == 1) ? -1. : +1.;
283 float wTimeDiffByRadiusOfInner =
287 bunchTime + jitter + wTimeDiffByRadiusOfInner;
288 float wASDDis{-1000.};
289 if (ASDpos !=
nullptr) {
291 ASDpos, iStationName, abs(stationEta), stationPhi,
294 wASDDis + (ySignPhi * yLocal +
297 sensor_propagation_time *
300 cable_propagation_time * wASDDis;
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 *
320 cable_propagation_time * wASDDis
321 <<
" time difference by cable radius of inner station: "
322 << wTimeDiffByRadiusOfInner);
325 stationName, stationEta, stationPhi, ilyr, (
int)
kWIRE,
327 addDigit(newId, bctag, digits.get());
331 posInWG[0], digit_time, wire_timeOffset,
332 rndmEngine, digits.get());
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) <<
" "
349 "Wire Gang id is out of range. id, x/y/z, height: "
350 << iwg <<
" " << localPos.x() <<
"/" << localPos.y() <<
"/"
351 << localPos.z() <<
" " << height);
359 if ((ilyr != 2 || (stationName.compare(0, 2,
"T1") !=
361 ((energyDeposit < -1. &&
363 sensor, rndmEngine)) ||
364 (energyDeposit >= -1. &&
366 stationName, stationEta, stationPhi, ilyr, sensor,
372 float posInStrip[2] = {0., 0.};
374 for (
int iPosition = 0; iPosition < 2; iPosition++) {
377 float zPos = zLocal + height / 2. - zwidth_frame;
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.);
404 float phiLocal = atan2(yLocal, zLocal + height / 2. + hmin);
407 "dphi, phiLocal, yLocal, zLocall+ height/2.+hmin: "
408 << dphi <<
" " << phiLocal <<
" " << yLocal <<
" "
409 << zLocal + height / 2. + hmin);
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);
418 istr =
static_cast<int>(floor(
419 (phiLocal - dphi * 14.25) / (dphi / 2.))) +
421 posInStrip[iPosition] =
422 (phiLocal - dphi * 14.25) / (dphi / 2.) -
423 static_cast<float>(istr - 31);
426 istr =
static_cast<int>(floor(phiLocal / dphi + 16.25)) + 1;
427 posInStrip[iPosition] =
428 phiLocal / dphi + 16.25 -
static_cast<float>(istr - 1);
430 istr =
static_cast<int>(floor(
431 (phiLocal + dphi * 14.25) / (dphi / 2.))) +
433 posInStrip[iPosition] =
434 (phiLocal + dphi * 14.25) / (dphi / 2.) -
435 static_cast<float>(istr - 3);
440 posInStrip[iPosition] = 0.;
441 }
else if (32 < istr) {
443 posInStrip[iPosition] = 0.;
445 iStrip[iPosition] = istr;
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]) {
460 float strip_timeOffset =
465 for (
int istr = iStr[0]; istr <= iStr[1]; istr++) {
466 if (1 <= istr && istr <= 32) {
468 if (jitter > jitterInitial - 0.1) {
472 (abs(stationEta) % 2 == 1 && abs(stationEta) != 5) ? -1.
477 float sTimeDiffByRadiusOfInner =
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,
491 float sCableDis = sASDDis + (height / 2. + zwidth_frame +
494 sASDDis * cable_propagation_time;
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);
514 stationName, stationEta, stationPhi, ilyr, (
int)sensor,
516 addDigit(newId, bctag, digits.get());
518 if (istr == iStr[0]) {
520 iStr[0], posInStr[0], sDigitTime,
521 strip_timeOffset, rndmEngine,
526 "Strip: newid breakdown digitTime x/y/z direcos "
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);
538 << ilyr <<
" " << istr);
543 return digits.release();
1015 const int gasGap,
const TgcSensor sensor,
const int channel,
1016 const float posInChan,
const float digitTime,
const float time_offset,
1018 uint16_t station_number =
m_idHelper->stationName(elemId);
1019 uint16_t station_eta = std::abs(
m_idHelper->stationEta(elemId));
1020 uint16_t layer = gasGap;
1021 uint16_t layer_id = (station_number << 5) + (station_eta << 2) + layer;
1031 float prob1CrossTalk =
1033 float prob11CrossTalk =
1035 float prob20CrossTalk =
1037 float prob21CrossTalk =
1040 int nCrossTalks_neg = 0;
1041 int nCrossTalks_pos = 0;
1043 if (posInChan < prob1CrossTalk) {
1044 nCrossTalks_neg = 1;
1045 }
else if (posInChan > 1. - prob1CrossTalk) {
1046 nCrossTalks_pos = 1;
1048 double prob = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0);
1049 if (prob < prob11CrossTalk / (1. - 2. * prob1CrossTalk)) {
1050 nCrossTalks_neg = 1;
1051 nCrossTalks_pos = 1;
1052 }
else if (prob < (prob20CrossTalk + prob11CrossTalk) /
1053 (1. - 2. * prob1CrossTalk)) {
1054 if (posInChan < 0.5) {
1055 nCrossTalks_neg = 2;
1058 nCrossTalks_pos = 2;
1062 (prob20CrossTalk + prob11CrossTalk + 2. * prob21CrossTalk) /
1063 (1. - 2. * prob1CrossTalk)) {
1064 if (posInChan < 0.5) {
1065 nCrossTalks_neg = 2;
1066 nCrossTalks_pos = 1;
1069 nCrossTalks_neg = 1;
1070 nCrossTalks_pos = 2;
1076 if (nCrossTalks_neg == 0 && nCrossTalks_pos == 0)
1080 float dt = digitTime;
1086 m_idHelper->channelID(elemId, gasGap, (
int)sensor, channel);
1087 int maxChannelNumber =
m_idHelper->channelMax(thisId);
1089 for (
int jChan = channel - nCrossTalks_neg;
1090 jChan <= channel + nCrossTalks_pos; jChan++) {
1091 if (jChan == channel || jChan < 1 || jChan > maxChannelNumber)
1095 m_idHelper->channelID(elemId, gasGap, (
int)sensor, jChan);