11 #include "CLHEP/Random/RandFlat.h"
12 #include "CLHEP/Random/RandGamma.h"
13 #include "CLHEP/Random/RandPoisson.h"
14 #include "CLHEP/Random/RandomEngine.h"
15 #include "GaudiKernel/ISvcLocator.h"
16 #include "GaudiKernel/MsgStream.h"
24 m_cscHitHelper{cscHitHelper}, m_muonMgr{muonMgr}, m_cscIdHelper{m_muonMgr->cscIdHelper()}, m_pcalib{pcalib} {
26 m_stationDict[
'S'] = m_cscIdHelper->stationNameIndex(
"CSS");
27 m_stationDict[
'L'] = m_cscIdHelper->stationNameIndex(
"CSL");
39 static constexpr std::array<double, s_maxElectron>
prob{79.4, 12., 3.4, 1.6, 0.95, 0.6, 0.44, 0.34, 0.27, 0.21, 0.17,
40 0.13, 0.1, 0.08, 0.06, 0.05, 0.042, 0.037, 0.033, 0.029, 0.};
48 return StatusCode::SUCCESS;
52 const int hitId = cscHit->
CSCid();
56 throw std::runtime_error(Form(
"%s:%d Failed to convert station name %s to an valid offline identifier", __FILE__, __LINE__,
68 std::map<IdentifierHash, std::vector<float>>& data_SampleMap,
69 std::map<IdentifierHash, std::vector<float>>& data_SampleMapOddPhase,
70 CLHEP::HepRandomEngine* rndmEngine) {
85 std::cout <<
"CSC_Digitizer::ERROR : Cannot get descriptor for GeoModel = " << std::endl;
86 return StatusCode::FAILURE;
93 double step = stepHit.mag();
95 if (
step == 0)
return StatusCode::SUCCESS;
106 nInter = energyLoss / elecEnergy;
108 double average_int = 30;
109 double pois = CLHEP::RandPoisson::shoot(rndmEngine, average_int);
110 nInter =
int(
step * pois / 10.0 + 0.5);
112 std::cout <<
"[CSC_Digitizer::digitize_hit(NEW)] nInter info from random number pois:step:nInter " << pois <<
" " <<
step
113 <<
" " << nInter << std::endl;
117 if (nInter <= 0)
return StatusCode::SUCCESS;
119 double wireCharge{0.};
123 for (
int i = 0;
i < nInter; ++
i) {
125 if (ipart == 1 || ipart == 999)
128 t = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0);
133 double preDriftTime =
getDriftTime(descriptor, pos_vec);
137 std::cout <<
"[CSC_Digitizer::digitize_hit(NEW)] totTime:driftTime:hitTime:bunchTime (ns) = " <<
driftTime <<
" "
139 std::cout <<
"[CSC_Digitizer::digitize_hit(NEW)] start hit coordinates (xc,yc,zc) / step hit and t / the hit are " << startHit
140 <<
" " << stepHit <<
" " <<
t <<
" " << pos_vec << std::endl;
151 double flat = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0);
163 double gammaDist = CLHEP::RandGamma::shoot(rndmEngine, (1.0 +
m_Polia), 1.0);
164 wireCharge =
qWire(nElectrons, gammaDist);
167 std::cout <<
"[CSC_Digitizer::digitize_hit(NEW)] flat:p:maxEle:nEle:gammaDist:wireCharge " << flat <<
" " <<
p <<
" "
168 <<
s_maxElectron <<
" " << nElectrons <<
" " << gammaDist <<
" " << wireCharge << std::endl;
172 for (
int measuresPhi = 0; measuresPhi <= 1; ++measuresPhi) {
177 std::cout <<
"[CSC_Digitizer::digitize_hit(NEW)] CSC_Digitizer::digitize_hit: Chamber Parameters"
178 <<
" measuresPhi= " << measuresPhi <<
" stripWidth= " << stripWidth <<
" maxStrip= " <<
maxStrip << std::endl;
183 if (measuresPhi == 0) {
184 double zz = pos_vec.z() +
maxStrip * stripWidth * 0.50;
185 int strip =
int(zz / stripWidth) + 1;
187 for (
int j =
strip - 4; j <=
strip + 4; ++j) {
188 double zpos = stripWidth * j - stripWidth * 0.50;
190 double stripCharge = wireCharge *
qStripR((zpos - zz) / stripWidth, HitId) * 0.50;
194 std::cout <<
"[CSC_Digitizer::digitize_hit(NEW)] zpos = " << zpos <<
" zz = " << zz
195 <<
" diff = " << std::abs(zz - zpos) <<
" strip = " << j <<
" charge = " << stripCharge << std::endl;
197 IdentifierHash hashId =
getHashId(HitId, j, measuresPhi);
201 std::cout <<
"[CSC_Digitizer::digitize_hit(NEW)] DriftTimeVSstripCharge " <<
driftTime <<
" " << stripCharge
209 yy = pos_vec.y() +
maxStrip * stripWidth * 0.5;
211 yy = -pos_vec.y() +
maxStrip * stripWidth * 0.5;
215 for (
int j =
strip - 1; j <=
strip + 1; ++j) {
217 double ypos = stripWidth * (j - 0.5);
218 double stripCharge = wireCharge *
qStripPhi(ypos -
yy, HitId) * 0.50;
220 std::cout <<
"[CSC_Digitizer::digitize_hit(NEW)] ypos = " << ypos <<
" yy = " <<
yy
221 <<
" diff = " << std::abs(
yy - ypos) <<
" strip = " << j <<
" charge = " << stripCharge << std::endl;
223 IdentifierHash hashId =
getHashId(HitId, j, measuresPhi);
232 return StatusCode::SUCCESS;
236 std::map<IdentifierHash, std::vector<float>>& data_SampleMap, CLHEP::HepRandomEngine* rndmEngine) {
250 std::cout <<
"CSC_Digitizer::ERROR : Cannot get descriptor for GeoModel = " << std::endl;
251 return StatusCode::FAILURE;
258 double step = stepHit.mag();
260 if (
step == 0)
return StatusCode::SUCCESS;
269 double average_int = 30;
270 double pois = CLHEP::RandPoisson::shoot(rndmEngine, average_int);
271 nInter =
int(
step * pois / 10.0 + 0.5);
273 std::cout <<
"[CSC_Digitizer::digitize_hit(NEW)] nInter info from random number pois:step:nInter " << pois <<
" " <<
step
274 <<
" " << nInter << std::endl;
277 if (nInter <= 0)
return StatusCode::SUCCESS;
279 double wireCharge{0};
283 for (
int i = 0;
i < nInter; ++
i) {
285 if (ipart == 1 || ipart == 999)
288 t = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0);
293 double preDriftTime =
getDriftTime(descriptor, pos_vec);
297 std::cout <<
"[CSC_Digitizer::digitize_hit(NEW)] totTime:driftTime:hitTime:bunchTime (ns) = " <<
driftTime <<
" "
299 std::cout <<
"[CSC_Digitizer::digitize_hit(NEW)] start hit coordinates (xc,yc,zc) / step hit and t / the hit are " << startHit
300 <<
" " << stepHit <<
" " <<
t <<
" " << pos_vec << std::endl;
311 double flat = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0);
323 double gammaDist = CLHEP::RandGamma::shoot(rndmEngine, (1.0 +
m_Polia), 1.0);
324 wireCharge =
qWire(nElectrons, gammaDist);
327 std::cout <<
"[CSC_Digitizer::digitize_hit(NEW)] flat:p:maxEle:nEle:gammaDist:wireCharge " << flat <<
" " <<
p <<
" "
328 <<
s_maxElectron <<
" " << nElectrons <<
" " << gammaDist <<
" " << wireCharge << std::endl;
332 for (
int measuresPhi = 0; measuresPhi <= 1; ++measuresPhi) {
337 std::cout <<
"[CSC_Digitizer::digitize_hit(NEW)] CSC_Digitizer::digitize_hit: Chamber Parameters"
338 <<
" measuresPhi= " << measuresPhi <<
" stripWidth= " << stripWidth <<
" maxStrip= " <<
maxStrip << std::endl;
343 if (measuresPhi == 0) {
344 double zz = pos_vec.z() +
maxStrip * stripWidth * 0.50;
345 int strip =
int(zz / stripWidth) + 1;
347 for (
int j =
strip - 4; j <=
strip + 4; ++j) {
348 double zpos = stripWidth * j - stripWidth * 0.50;
350 double stripCharge = wireCharge *
qStripR((zpos - zz) / stripWidth, HitId) * 0.50;
353 std::cout <<
"[CSC_Digitizer::digitize_hit(NEW)] zpos = " << zpos <<
" zz = " << zz
354 <<
" diff = " << std::abs(zz - zpos) <<
" strip = " << j <<
" charge = " << stripCharge << std::endl;
356 IdentifierHash hashId =
getHashId(HitId, j, measuresPhi);
360 std::cout <<
"[CSC_Digitizer::digitize_hit(NEW)] DriftTimeVSstripCharge " <<
driftTime <<
" " << stripCharge
368 yy = pos_vec.y() +
maxStrip * stripWidth * 0.5;
370 yy = -pos_vec.y() +
maxStrip * stripWidth * 0.5;
374 for (
int j =
strip - 1; j <=
strip + 1; j++) {
376 double ypos = stripWidth * (j - 0.5);
377 double stripCharge = wireCharge *
qStripPhi(ypos -
yy, HitId) * 0.50;
379 std::cout <<
"[CSC_Digitizer::digitize_hit(NEW)] ypos = " << ypos <<
" yy = " <<
yy
380 <<
" diff = " << std::abs(
yy - ypos) <<
" strip = " << j <<
" charge = " << stripCharge << std::endl;
382 IdentifierHash hashId =
getHashId(HitId, j, measuresPhi);
390 return StatusCode::SUCCESS;
397 std::map<IdentifierHash, std::pair<double, double>>& data_map, CLHEP::HepRandomEngine* rndmEngine) {
410 std::cout <<
"CSC_Digitizer::ERROR : Cannot get descriptor for GeoModel = " << std::endl;
411 return StatusCode::FAILURE;
418 double step = stepHit.mag();
420 if (
step == 0)
return StatusCode::SUCCESS;
429 double average_int = 30;
430 double pois = CLHEP::RandPoisson::shoot(rndmEngine, average_int);
431 nInter =
int(
step * pois / 10.0 + 0.5);
433 std::cout <<
"[CSC_Digitizer::digitize_hit] nInter info from random number pois:step:nInter " << pois <<
" " <<
step <<
" "
434 << nInter << std::endl;
437 if (nInter <= 0)
return StatusCode::SUCCESS;
443 for (
int i = 0;
i < nInter; ++
i) {
445 if (ipart == 1 || ipart == 999)
448 t = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0);
452 double preDriftTime =
getDriftTime(descriptor, pos_vec);
456 std::cout <<
"[CSC_Digitizer::digitize_hit] totTime:driftTime:hitTime:bunchTime (ns) = " <<
driftTime <<
" "
458 std::cout <<
"[CSC_Digitizer::digitize_hit] start hit coordinates (xc,yc,zc) / step hit and t / the hit are " << startHit
459 <<
" " << stepHit <<
" " <<
t <<
" " << pos_vec << std::endl;
470 double flat = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0);
481 double gammaDist = CLHEP::RandGamma::shoot(rndmEngine, (1.0 +
m_Polia), 1.0);
482 wireCharge =
qWire(nElectrons, gammaDist);
485 std::cout <<
"[CSC_Digitizer::digitize_hit] flat:p:maxEle:nEle:gammaDist:wireCharge " << flat <<
" " <<
p <<
" "
486 <<
s_maxElectron <<
" " << nElectrons <<
" " << gammaDist <<
" " << wireCharge << std::endl;
490 for (
int measuresPhi = 0; measuresPhi <= 1; ++measuresPhi) {
496 if (measuresPhi == 0) {
497 double zz = pos_vec.z() +
maxStrip * stripWidth * 0.50;
498 int strip =
int(zz / stripWidth) + 1;
501 for (
int j =
strip - 4; j <=
strip + 4; j++) {
502 double zpos = stripWidth * j - stripWidth * 0.50;
504 double stripCharge = wireCharge *
qStripR((zpos - zz) / stripWidth, HitId) * 0.50;
507 std::cout <<
"[CSC_Digitizer::digitize_hit] zpos = " << zpos <<
" zz = " << zz
508 <<
" diff = " << std::abs(zz - zpos) <<
" strip = " << j <<
" charge = " << stripCharge << std::endl;
510 IdentifierHash hashId =
getHashId(HitId, j, measuresPhi);
515 std::cout <<
"[CSC_Digitizer::digitize_hit] DriftTimeVSstripCharge " <<
driftTime <<
" " << stripCharge
523 yy = pos_vec.y() +
maxStrip * stripWidth * 0.5;
525 yy = -pos_vec.y() +
maxStrip * stripWidth * 0.5;
529 for (
int j =
strip - 1; j <=
strip + 1; ++j) {
531 double ypos = stripWidth * (j - 0.5);
532 double stripCharge = wireCharge *
qStripPhi(ypos -
yy, HitId) * 0.50;
534 std::cout <<
"[CSC_Digitizer::digitize_hit] ypos = " << ypos <<
" yy = " <<
yy
535 <<
" diff = " << std::abs(
yy - ypos) <<
" strip = " << j <<
" charge = " << stripCharge << std::endl;
537 IdentifierHash hashId =
getHashId(HitId, j, measuresPhi);
546 return StatusCode::SUCCESS;
557 std::vector<IdentifierHash>& hashVec, std::map<IdentifierHash, std::vector<float>>& data_map,
559 if (stripCharge == 0.0)
return;
562 if (data_map.find(hashId) != data_map.end()) {
563 float phaseOffset = (
phase) ? +25 : 0;
565 std::vector<float> existingSamples = data_map[hashId];
568 std::cout <<
"[CSC_Digitizer::fillSampleMaps] ";
570 for (
unsigned int i = 0;
i < samples.size(); ++
i) std::cout << samples[
i] <<
" ";
573 for (
unsigned int i = 0;
i < existingSamples.size(); ++
i) std::cout << existingSamples[
i] <<
" ";
575 std::cout <<
" ==> ";
578 for (
unsigned int i = 0;
i < samples.size(); ++
i) { existingSamples[
i] += samples[
i]; }
581 for (
unsigned int i = 0;
i < existingSamples.size(); ++
i) std::cout << existingSamples[
i] <<
" ";
582 std::cout << std::endl;
585 data_map[hashId] = existingSamples;
589 hashVec.push_back(hashId);
607 double wireCharge = 0.0;
609 for (
int i = 0;
i < nElectrons; ++
i) {
612 wireCharge += amplification * RNDpol;
622 double rStripCharge = 0.0;
623 static constexpr std::array<double,4> Par{0.185, 2.315, 0.48, 5.2};
624 double xx = std::abs(
x) / 10.0;
626 rStripCharge = Par[0] *
exp(-Par[1] * xx) + Par[2] *
exp(-Par[3] * (xx * xx));
638 double stripCharge = 0.0;
642 stripCharge = 0.7001 / (1.0 + 1.38 * xx + 2.255 * xx * xx);
644 stripCharge = 0.7 / (1.0 + 1.381 * xx + 2.248 * xx * xx);
651 static constexpr std::array<double, 9> pSmall{.9092, .0634, -1.051, 8.05, -35.477, 58.883, -46.111, 17.446, -2.5824};
652 static constexpr std::array<double, 9> pLarge{.98, -.36, 5.07, -27.81, 72.257, -99.456, 72.778, -26.779, 3.9054};
653 double xx = std::abs(
x) / 10.0;
654 double phiStripCharge = 0.0;
664 return phiStripCharge;
668 double fparam{0},
pow {1.};
669 for (
size_t i = 0;
i <
p.size(); ++
i) {
670 fparam +=
p[
i] *
pow;
684 double time = -1000.0;
691 float yy =
pos.y() + longWidth * 0.5;
693 int wire =
int(
yy / anodeCathodeDist) + 1;
694 float y0 = (
yy - wire * anodeCathodeDist);
695 if (std::abs(y0) > anodeCathodeDist / 2) y0 = std::abs(y0) - anodeCathodeDist * 0.5;
696 float driftDist = std::hypot(x0, y0);
710 std::vector<IdentifierHash>& hashVec, std::map<IdentifierHash, std::pair<double, double>>& data_map) {
711 if (stripCharge == 0.0)
return;
714 if (data_map.find(hashId) != data_map.end()) {
721 std::cout <<
"[CSC_Digitizer::fillMaps] (" << data_map[hashId].first <<
":" <<
int(data_map[hashId].
second) <<
")"
723 <<
" ==> " <<
result.first <<
":" <<
int(
result.second) <<
" e- which was "
724 <<
int(data_map[hashId].
second + stripCharge) << std::endl;
726 data_map[hashId].first =
result.first;
727 data_map[hashId].second =
result.second;
731 data_map[hashId].second = stripCharge;
732 hashVec.push_back(hashId);
740 IdentifierHash hashId;
742 throw std::runtime_error(
743 Form(
"File: %s, Line: %d\nCSC_Digitizer::getHashId() - Failed to retrieve channel hash from identifier %llu", __FILE__,
744 __LINE__, realHitId.get_compact()));