ATLAS Offline Software
Loading...
Searching...
No Matches
CSC_Digitizer Class Reference

#include <CSC_Digitizer.h>

Collaboration diagram for CSC_Digitizer:

Public Member Functions

 CSC_Digitizer (const CscHitIdHelper *cscHitHelper, const MuonGM::MuonDetectorManager *muonMgr, ICscCalibTool *pcalib)
 ~CSC_Digitizer ()=default
StatusCode initialize ()
void setWindow (const double t1, const double t2)
void set (const double bunchTime)
void setAmplification (const double amplification)
void setDebug (int debug)
void setDriftVelocity (double v0)
void setElectronEnergy (double e)
void setNInterFixed ()
StatusCode digitize_hit (const CSCSimHit *cscHit, std::vector< IdentifierHash > &hashVec, std::map< IdentifierHash, std::pair< double, double > > &data_map, CLHEP::HepRandomEngine *rndmEngine)
 Old way before 10/2010.
StatusCode digitize_hit (const CSCSimHit *cscHit, std::vector< IdentifierHash > &hashVec, std::map< IdentifierHash, std::vector< float > > &data_SampleMap, std::map< IdentifierHash, std::vector< float > > &data_SampleMapOddPhase, CLHEP::HepRandomEngine *rndmEngine)
StatusCode digitize_hit (const CSCSimHit *cscHit, std::vector< IdentifierHash > &hashVec, std::map< IdentifierHash, std::vector< float > > &data_SampleMap, CLHEP::HepRandomEngine *rndmEngine)
IdentifierHash getHashId (const Identifier &input_id, const int stripId, const int measuresPhi) const

Private Member Functions

double qWire (const int &nElectrons, const double &gammaDist) const
double qStripR (const double x, const Identifier &id) const
 Charge sharing profile.
double qStripPhi (const double x, const Identifier &id) const
double getDriftTime (const MuonGM::CscReadoutElement *descriptor, const Amg::Vector3D &pos) const
bool outsideWindow (double time) const
void fillMaps (const IdentifierHash hash, const double driftTime, const double stripCharge, std::vector< IdentifierHash > &hashVec, std::map< IdentifierHash, std::pair< double, double > > &data_map)
void fillSampleMaps (const IdentifierHash hash, const double driftTime, const double stripCharge, std::vector< IdentifierHash > &hashVec, std::map< IdentifierHash, std::vector< float > > &data_map, bool phase=0)
Identifier to_identifier (const CSCSimHit *cscHit) const

Static Private Member Functions

static double qStripR (const double x)
static double fparamPhi (const double x, const std::array< double, 9 > &p)

Private Attributes

const CscHitIdHelperm_cscHitHelper {nullptr}
const MuonGM::MuonDetectorManagerm_muonMgr {nullptr}
const CscIdHelperm_cscIdHelper {nullptr}
ICscCalibToolm_pcalib {nullptr}
bool m_NInterFromEnergyLoss {true}
double m_electronEnergy {66.}
double m_Polia {0.}
std::array< double, s_maxElectronm_sprob {0.}
double m_timeWindowLowerOffset {0.}
double m_timeWindowUpperOffset {0.}
double m_bunchTime {0.}
double m_amplification {0.}
double m_driftVelocity {60.}
int m_debug {0}
std::map< char, int > m_stationDict {}
 Cache the csc id dictionary.

Static Private Attributes

static constexpr int s_maxElectron {21}

Detailed Description

Definition at line 37 of file CSC_Digitizer.h.

Constructor & Destructor Documentation

◆ CSC_Digitizer()

CSC_Digitizer::CSC_Digitizer ( const CscHitIdHelper * cscHitHelper,
const MuonGM::MuonDetectorManager * muonMgr,
ICscCalibTool * pcalib )

CSL / CSS

Definition at line 23 of file CSC_Digitizer.cxx.

23 :
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");
28}
const CscHitIdHelper * m_cscHitHelper
std::map< char, int > m_stationDict
Cache the csc id dictionary.
const CscIdHelper * m_cscIdHelper
const MuonGM::MuonDetectorManager * m_muonMgr
ICscCalibTool * m_pcalib

◆ ~CSC_Digitizer()

CSC_Digitizer::~CSC_Digitizer ( )
default

Member Function Documentation

◆ digitize_hit() [1/3]

StatusCode CSC_Digitizer::digitize_hit ( const CSCSimHit * cscHit,
std::vector< IdentifierHash > & hashVec,
std::map< IdentifierHash, std::pair< double, double > > & data_map,
CLHEP::HepRandomEngine * rndmEngine )

Old way before 10/2010.

Definition at line 396 of file CSC_Digitizer.cxx.

397 {
398 // method to digitize a single hit. Must be called in a loop over hits
399 // after a call to the method "StatusCode CSC_Digitize::initialize()"
400 // get the step vector from the begining and end vectors of the G4 step
401 Amg::Vector3D startHit = cscHit->getHitStart();
402 Amg::Vector3D endHit = cscHit->getHitEnd();
403
404 // decode the hit ID
405 const Identifier HitId = to_identifier(cscHit);
406 const int chamberLayer = m_cscHitHelper->GetChamberLayer(cscHit->CSCid());
407 // find the detector descriptor
408 const CscReadoutElement* descriptor = m_muonMgr->getCscReadoutElement(HitId);
409 if (!descriptor) {
410 std::cout << "CSC_Digitizer::ERROR : Cannot get descriptor for GeoModel = " << std::endl;
411 return StatusCode::FAILURE;
412 }
413
414 // particle ID
415 int ipart = cscHit->particleID();
416
417 Amg::Vector3D stepHit = endHit - startHit;
418 double step = stepHit.mag();
419
420 if (step == 0) return StatusCode::SUCCESS;
421
422 // get average number of interaction::one interaction for photons
423 // std::cout << "The particle ID = " << ipart << std::endl;
424
425 int nInter = 0;
426 if (ipart == 1)
427 nInter = 1;
428 else {
429 double average_int = 30; // average interactions per cm
430 double pois = CLHEP::RandPoisson::shoot(rndmEngine, average_int);
431 nInter = int(step * pois / 10.0 + 0.5); // number of interaction according to Poisson
432 if (m_debug)
433 std::cout << "[CSC_Digitizer::digitize_hit] nInter info from random number pois:step:nInter " << pois << " " << step << " "
434 << nInter << std::endl;
435 }
436
437 if (nInter <= 0) return StatusCode::SUCCESS;
438
439 double wireCharge;
440 int nElectrons = 0;
441
442 // loop over number of interactions and do digitization
443 for (int i = 0; i < nInter; ++i) {
444 double t = 0.0;
445 if (ipart == 1 || ipart == 999)
446 t = step * 0.50; // one interaction for photons & geantinos
447 else
448 t = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0); // for other particles
449
450 const Amg::Vector3D pos_vec = startHit + t * stepHit;
451 // pileup - check if within time window
452 double preDriftTime = getDriftTime(descriptor, pos_vec); // before geant hit time addition.
453 double driftTime = m_bunchTime + cscHit->meanTime() + preDriftTime;
454
455 if (m_debug) {
456 std::cout << "[CSC_Digitizer::digitize_hit] totTime:driftTime:hitTime:bunchTime (ns) = " << driftTime << " "
457 << cscHit->meanTime() << " " << preDriftTime << " " << m_bunchTime << std::endl;
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;
460 }
461
462 // Prompt muon case::
463 // CSL 25.02ns CSS 26.3ns :: Dec03 2009 geant hit time was not added but it's added now.
464 // so previous +- 50ns time window may not work. We need to tune it. Temporally, I put -inf +inf.
465
466 // it should be decided by bunchtime. -400 to +200
467 if (outsideWindow(m_bunchTime)) continue;
468
469 // number of electrons in this interaction
470 double flat = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0);
471 double p = m_sprob[s_maxElectron - 1] * flat;
472 for (int k = 0; k < s_maxElectron; ++k) {
473 if (p <= m_sprob[k]) {
474 nElectrons = k + 1;
475 break;
476 }
477 }
478
479 // find the charge on the wire in electron-equivalent charge
480 m_Polia = 0.38; // parmeter for charge loss:: random gamma function
481 double gammaDist = CLHEP::RandGamma::shoot(rndmEngine, (1.0 + m_Polia), 1.0);
482 wireCharge = qWire(nElectrons, gammaDist);
483
484 if (m_debug) {
485 std::cout << "[CSC_Digitizer::digitize_hit] flat:p:maxEle:nEle:gammaDist:wireCharge " << flat << " " << p << " "
486 << s_maxElectron << " " << nElectrons << " " << gammaDist << " " << wireCharge << std::endl;
487 }
488
489 // now digitize hits for R- and phi-strips
490 for (int measuresPhi = 0; measuresPhi <= 1; ++measuresPhi) {
491 float stripWidth = descriptor->cathodeReadoutPitch(chamberLayer, measuresPhi);
492 const int maxStrip = descriptor->maxNumberOfStrips(measuresPhi, stripWidth);
493
494 // now digitize hits for R-strips/phi-strips
495
496 if (measuresPhi == 0) { // R-strips :: find the charge+noise
497 double zz = pos_vec.z() + maxStrip * stripWidth * 0.50; // assuming zero offset
498 int strip = int(zz / stripWidth) + 1;
499 // find the charges induced on the phi strips
500
501 for (int j = strip - 4; j <= strip + 4; j++) {
502 double zpos = stripWidth * j - stripWidth * 0.50;
503 if (j > 0 && j <= maxStrip) {
504 double stripCharge = wireCharge * qStripR((zpos - zz) / stripWidth, HitId) * 0.50;
505
506 if (m_debug)
507 std::cout << "[CSC_Digitizer::digitize_hit] zpos = " << zpos << " zz = " << zz
508 << " diff = " << std::abs(zz - zpos) << " strip = " << j << " charge = " << stripCharge << std::endl;
509
510 IdentifierHash hashId = getHashId(HitId, j, measuresPhi);
511
512 fillMaps(hashId, driftTime, stripCharge, hashVec, data_map);
513
514 if (m_debug)
515 std::cout << "[CSC_Digitizer::digitize_hit] DriftTimeVSstripCharge " << driftTime << " " << stripCharge
516 << std::endl;
517 }
518 }
519 } else { // Phi-strips :: find the charge+noise
520 double yy = 0.0;
521 int strip = 0;
522
523 yy = pos_vec.y() + maxStrip * stripWidth * 0.5; // non-pointing phi-strips :: assuming zero offset
524 if (m_cscHitHelper->GetZSector(cscHit->CSCid()) > 0)
525 yy = -pos_vec.y() + maxStrip * stripWidth * 0.5; // non-pointing phi-strips :: assuming zero offset
526 strip = int(yy / stripWidth) + 1;
527
528 // find the charges induced on the phi strips
529 for (int j = strip - 1; j <= strip + 1; ++j) {
530 if (j > 0 && j <= maxStrip) {
531 double ypos = stripWidth * (j - 0.5);
532 double stripCharge = wireCharge * qStripPhi(ypos - yy, HitId) * 0.50;
533 if (m_debug)
534 std::cout << "[CSC_Digitizer::digitize_hit] ypos = " << ypos << " yy = " << yy
535 << " diff = " << std::abs(yy - ypos) << " strip = " << j << " charge = " << stripCharge << std::endl;
536
537 IdentifierHash hashId = getHashId(HitId, j, measuresPhi);
538
539 fillMaps(hashId, driftTime, stripCharge, hashVec, data_map);
540 }
541 }
542 }
543 }
544 }
545
546 return StatusCode::SUCCESS;
547}
const Amg::Vector3D & getHitEnd() const
Definition CSCSimHit.h:52
int CSCid() const
Definition CSCSimHit.h:54
int particleID() const
Definition CSCSimHit.h:53
const Amg::Vector3D & getHitStart() const
Definition CSCSimHit.h:51
double meanTime() const
Definition CSCSimHit.h:90
void fillMaps(const IdentifierHash hash, const double driftTime, const double stripCharge, std::vector< IdentifierHash > &hashVec, std::map< IdentifierHash, std::pair< double, double > > &data_map)
static constexpr int s_maxElectron
double qStripPhi(const double x, const Identifier &id) const
double getDriftTime(const MuonGM::CscReadoutElement *descriptor, const Amg::Vector3D &pos) const
static double qStripR(const double x)
std::array< double, s_maxElectron > m_sprob
IdentifierHash getHashId(const Identifier &input_id, const int stripId, const int measuresPhi) const
double qWire(const int &nElectrons, const double &gammaDist) const
bool outsideWindow(double time) const
Identifier to_identifier(const CSCSimHit *cscHit) const
double cathodeReadoutPitch(int chLayer, int measuresPhi) const
int maxNumberOfStrips(int measuresPhi) const
Eigen::Matrix< double, 3, 1 > Vector3D
@ driftTime
Definition HitInfo.h:43

◆ digitize_hit() [2/3]

StatusCode CSC_Digitizer::digitize_hit ( const CSCSimHit * cscHit,
std::vector< IdentifierHash > & hashVec,
std::map< IdentifierHash, std::vector< float > > & data_SampleMap,
CLHEP::HepRandomEngine * rndmEngine )

Definition at line 235 of file CSC_Digitizer.cxx.

236 {
237 // method to digitize a single hit. Must be called in a loop over hits
238 // after a call to the method "StatusCode CSC_Digitize::initialize()"
239 // get the step vector from the begining and end vectors of the G4 step
240 Amg::Vector3D startHit = cscHit->getHitStart();
241 Amg::Vector3D endHit = cscHit->getHitEnd();
242
243 // decode the hit ID
244 const Identifier HitId = to_identifier(cscHit);
245 const int chamberLayer = m_cscHitHelper->GetChamberLayer(cscHit->CSCid());
246
247 // find the detector descriptor
248 const CscReadoutElement* descriptor = m_muonMgr->getCscReadoutElement(HitId);
249 if (!descriptor) {
250 std::cout << "CSC_Digitizer::ERROR : Cannot get descriptor for GeoModel = " << std::endl;
251 return StatusCode::FAILURE;
252 }
253
254 // particle ID
255 int ipart = cscHit->particleID();
256
257 Amg::Vector3D stepHit = endHit - startHit;
258 double step = stepHit.mag();
259
260 if (step == 0) return StatusCode::SUCCESS;
261
262 // get average number of interaction::one interaction for photons
263 // std::cout << "The particle ID = " << ipart << std::endl;
264
265 int nInter = 0;
266 if (ipart == 1)
267 nInter = 1;
268 else {
269 double average_int = 30; // average interactions per cm
270 double pois = CLHEP::RandPoisson::shoot(rndmEngine, average_int);
271 nInter = int(step * pois / 10.0 + 0.5); // number of interaction according to Poisson
272 if (m_debug)
273 std::cout << "[CSC_Digitizer::digitize_hit(NEW)] nInter info from random number pois:step:nInter " << pois << " " << step
274 << " " << nInter << std::endl;
275 }
276
277 if (nInter <= 0) return StatusCode::SUCCESS;
278
279 double wireCharge{0};
280 int nElectrons = 0;
281
282 // loop over number of interactions and do digitization
283 for (int i = 0; i < nInter; ++i) {
284 double t = 0.0;
285 if (ipart == 1 || ipart == 999)
286 t = step * 0.50; // one interaction for photons & geantinos
287 else
288 t = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0); // for other particles
289
290 Amg::Vector3D pos_vec = startHit + t * stepHit;
291
292 // pileup - check if within time window
293 double preDriftTime = getDriftTime(descriptor, pos_vec); // before geant hit time addition.
294 double driftTime = m_bunchTime + cscHit->meanTime() + preDriftTime;
295
296 if (m_debug) {
297 std::cout << "[CSC_Digitizer::digitize_hit(NEW)] totTime:driftTime:hitTime:bunchTime (ns) = " << driftTime << " "
298 << cscHit->meanTime() << " " << preDriftTime << " " << m_bunchTime << std::endl;
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;
301 }
302
303 // Prompt muon case::
304 // CSL 25.02ns CSS 26.3ns :: Dec03 2009 geant hit time was not added but it's added now.
305 // so previous +- 50ns time window may not work. We need to tune it. Temporally, I put -inf +inf.
306
307 // it should be decided by bunchtime. -400 to +200
308 if (outsideWindow(m_bunchTime)) continue;
309
310 // number of electrons in this interaction
311 double flat = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0);
312 double p = m_sprob[s_maxElectron - 1] * flat;
313 for (int k = 0; k < s_maxElectron; ++k) {
314 if (p <= m_sprob[k]) {
315 nElectrons = k + 1;
316 break;
317 }
318 }
319
320 // find the charge on the wire in electron-equivalent charge
321
322 m_Polia = 0.38; // parmeter for charge loss:: random gamma function
323 double gammaDist = CLHEP::RandGamma::shoot(rndmEngine, (1.0 + m_Polia), 1.0);
324 wireCharge = qWire(nElectrons, gammaDist);
325
326 if (m_debug) {
327 std::cout << "[CSC_Digitizer::digitize_hit(NEW)] flat:p:maxEle:nEle:gammaDist:wireCharge " << flat << " " << p << " "
328 << s_maxElectron << " " << nElectrons << " " << gammaDist << " " << wireCharge << std::endl;
329 }
330
331 // now digitize hits for R- and phi-strips
332 for (int measuresPhi = 0; measuresPhi <= 1; ++measuresPhi) {
333 float stripWidth = descriptor->cathodeReadoutPitch(chamberLayer, measuresPhi);
334 const int maxStrip = descriptor->maxNumberOfStrips(measuresPhi, stripWidth);
335
336 if (m_debug) {
337 std::cout << "[CSC_Digitizer::digitize_hit(NEW)] CSC_Digitizer::digitize_hit: Chamber Parameters"
338 << " measuresPhi= " << measuresPhi << " stripWidth= " << stripWidth << " maxStrip= " << maxStrip << std::endl;
339 }
340
341 // now digitize hits for R-strips/phi-strips
342
343 if (measuresPhi == 0) { // R-strips :: find the charge+noise
344 double zz = pos_vec.z() + maxStrip * stripWidth * 0.50; // assuming zero offset
345 int strip = int(zz / stripWidth) + 1;
346 // find the charges induced on the phi strips
347 for (int j = strip - 4; j <= strip + 4; ++j) {
348 double zpos = stripWidth * j - stripWidth * 0.50;
349 if (j > 0 && j <= maxStrip) {
350 double stripCharge = wireCharge * qStripR((zpos - zz) / stripWidth, HitId) * 0.50;
351
352 if (m_debug)
353 std::cout << "[CSC_Digitizer::digitize_hit(NEW)] zpos = " << zpos << " zz = " << zz
354 << " diff = " << std::abs(zz - zpos) << " strip = " << j << " charge = " << stripCharge << std::endl;
355
356 IdentifierHash hashId = getHashId(HitId, j, measuresPhi);
357 fillSampleMaps(hashId, driftTime, stripCharge, hashVec, data_SampleMap);
358
359 if (m_debug)
360 std::cout << "[CSC_Digitizer::digitize_hit(NEW)] DriftTimeVSstripCharge " << driftTime << " " << stripCharge
361 << std::endl;
362 }
363 }
364 } else { // Phi-strips :: find the charge+noise
365 double yy = 0.0;
366 int strip = 0;
367
368 yy = pos_vec.y() + maxStrip * stripWidth * 0.5; // non-pointing phi-strips :: assuming zero offset
369 if (m_cscHitHelper->GetZSector(cscHit->CSCid()) > 0)
370 yy = -pos_vec.y() + maxStrip * stripWidth * 0.5; // non-pointing phi-strips :: assuming zero offset
371 strip = int(yy / stripWidth) + 1;
372
373 // find the charges induced on the phi strips
374 for (int j = strip - 1; j <= strip + 1; j++) {
375 if (j > 0 && j <= maxStrip) {
376 double ypos = stripWidth * (j - 0.5);
377 double stripCharge = wireCharge * qStripPhi(ypos - yy, HitId) * 0.50;
378 if (m_debug)
379 std::cout << "[CSC_Digitizer::digitize_hit(NEW)] ypos = " << ypos << " yy = " << yy
380 << " diff = " << std::abs(yy - ypos) << " strip = " << j << " charge = " << stripCharge << std::endl;
381
382 IdentifierHash hashId = getHashId(HitId, j, measuresPhi);
383 fillSampleMaps(hashId, driftTime, stripCharge, hashVec, data_SampleMap);
384 }
385 }
386 }
387 }
388 }
389
390 return StatusCode::SUCCESS;
391}
void fillSampleMaps(const IdentifierHash hash, const double driftTime, const double stripCharge, std::vector< IdentifierHash > &hashVec, std::map< IdentifierHash, std::vector< float > > &data_map, bool phase=0)

◆ digitize_hit() [3/3]

StatusCode CSC_Digitizer::digitize_hit ( const CSCSimHit * cscHit,
std::vector< IdentifierHash > & hashVec,
std::map< IdentifierHash, std::vector< float > > & data_SampleMap,
std::map< IdentifierHash, std::vector< float > > & data_SampleMapOddPhase,
CLHEP::HepRandomEngine * rndmEngine )

Definition at line 67 of file CSC_Digitizer.cxx.

70 {
71 // method to digitize a single hit. Must be called in a loop over hits
72 // after a call to the method "StatusCode CSC_Digitize::initialize()"
73 // get the step vector from the begining and end vectors of the G4 step
74
75 Amg::Vector3D startHit = cscHit->getHitStart();
76 Amg::Vector3D endHit = cscHit->getHitEnd();
77
78 // decode the hit ID
79 const Identifier HitId = to_identifier(cscHit);
80 const int chamberLayer = m_cscHitHelper->GetChamberLayer(cscHit->CSCid());
81
82 // find the detector descriptor
83 const CscReadoutElement* descriptor = m_muonMgr->getCscReadoutElement(HitId);
84 if (!descriptor) {
85 std::cout << "CSC_Digitizer::ERROR : Cannot get descriptor for GeoModel = " << std::endl;
86 return StatusCode::FAILURE;
87 }
88
89 // particle ID
90 int ipart = cscHit->particleID();
91
92 Amg::Vector3D stepHit = endHit - startHit;
93 double step = stepHit.mag(); // path length in a layer
94
95 if (step == 0) return StatusCode::SUCCESS;
96
97 // get average number of interaction::one interaction for photons
98 int nInter = 0;
99 if (ipart == 1)
100 nInter = 1;
101 else {
103 double energyLoss = cscHit->energyDeposit(); // MeV peaking at 0.001MeV for on time track (25ns from IP)
104 double elecEnergy = m_electronEnergy *
105 0.000001; // each ionized electron has 66eV (66 is from 0.001MeV/15 (average interaction per layer 0.5cm)
106 nInter = energyLoss / elecEnergy;
107 } else {
108 double average_int = 30; // average interactions per cm
109 double pois = CLHEP::RandPoisson::shoot(rndmEngine, average_int);
110 nInter = int(step * pois / 10.0 + 0.5); // number of interaction according to Poisson
111 if (m_debug)
112 std::cout << "[CSC_Digitizer::digitize_hit(NEW)] nInter info from random number pois:step:nInter " << pois << " " << step
113 << " " << nInter << std::endl;
114 }
115 }
116
117 if (nInter <= 0) return StatusCode::SUCCESS;
118
119 double wireCharge{0.};
120 int nElectrons{0};
121
122 // loop over number of interactions and do digitization
123 for (int i = 0; i < nInter; ++i) {
124 double t = 0.0;
125 if (ipart == 1 || ipart == 999)
126 t = step * 0.50; // one interaction for photons & geantinos
127 else
128 t = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0); // for other particles
129
130 const Amg::Vector3D pos_vec = startHit + t * stepHit;
131
132 // pileup - check if within time window
133 double preDriftTime = getDriftTime(descriptor, pos_vec); // before geant hit time addition.
134 double driftTime = m_bunchTime + cscHit->meanTime() + preDriftTime;
135
136 if (m_debug) {
137 std::cout << "[CSC_Digitizer::digitize_hit(NEW)] totTime:driftTime:hitTime:bunchTime (ns) = " << driftTime << " "
138 << cscHit->meanTime() << " " << preDriftTime << " " << m_bunchTime << std::endl;
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;
141 }
142
143 // Prompt muon case::
144 // CSL 25.02ns CSS 26.3ns :: Dec03 2009 geant hit time was not added but it's added now.
145 // so previous +- 50ns time window may not work. We need to tune it. Temporally, I put -inf +inf.
146
147 // it should be decided by bunchtime. -400 to +200
148 if (outsideWindow(m_bunchTime)) continue;
149
150 // number of electrons in this interaction
151 double flat = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0);
152 double p = m_sprob[s_maxElectron - 1] * flat;
153 for (int k = 0; k < s_maxElectron; ++k) {
154 if (p <= m_sprob[k]) {
155 nElectrons = k + 1;
156 break;
157 }
158 }
159
160 // find the charge on the wire in electron-equivalent charge
161
162 m_Polia = 0.38; // parmeter for charge loss:: random gamma function
163 double gammaDist = CLHEP::RandGamma::shoot(rndmEngine, (1.0 + m_Polia), 1.0);
164 wireCharge = qWire(nElectrons, gammaDist);
165
166 if (m_debug) {
167 std::cout << "[CSC_Digitizer::digitize_hit(NEW)] flat:p:maxEle:nEle:gammaDist:wireCharge " << flat << " " << p << " "
168 << s_maxElectron << " " << nElectrons << " " << gammaDist << " " << wireCharge << std::endl;
169 }
170
171 // now digitize hits for R- and phi-strips
172 for (int measuresPhi = 0; measuresPhi <= 1; ++measuresPhi) {
173 float stripWidth = descriptor->cathodeReadoutPitch(chamberLayer, measuresPhi);
174 const int maxStrip = descriptor->maxNumberOfStrips(measuresPhi, stripWidth);
175
176 if (m_debug) {
177 std::cout << "[CSC_Digitizer::digitize_hit(NEW)] CSC_Digitizer::digitize_hit: Chamber Parameters"
178 << " measuresPhi= " << measuresPhi << " stripWidth= " << stripWidth << " maxStrip= " << maxStrip << std::endl;
179 }
180
181 // now digitize hits for R-strips/phi-strips
182
183 if (measuresPhi == 0) { // R-strips :: find the charge+noise
184 double zz = pos_vec.z() + maxStrip * stripWidth * 0.50; // assuming zero offset
185 int strip = int(zz / stripWidth) + 1;
186 // find the charges induced on the phi strips
187 for (int j = strip - 4; j <= strip + 4; ++j) {
188 double zpos = stripWidth * j - stripWidth * 0.50;
189 if (j > 0 && j <= maxStrip) {
190 double stripCharge = wireCharge * qStripR((zpos - zz) / stripWidth, HitId) * 0.50;
191 // if (stripCharge < 0) stripCharge = 0.0;
192
193 if (m_debug)
194 std::cout << "[CSC_Digitizer::digitize_hit(NEW)] zpos = " << zpos << " zz = " << zz
195 << " diff = " << std::abs(zz - zpos) << " strip = " << j << " charge = " << stripCharge << std::endl;
196
197 IdentifierHash hashId = getHashId(HitId, j, measuresPhi);
198 fillSampleMaps(hashId, driftTime, stripCharge, hashVec, data_SampleMap);
199 fillSampleMaps(hashId, driftTime, stripCharge, hashVec, data_SampleMapOddPhase, 1);
200 if (m_debug)
201 std::cout << "[CSC_Digitizer::digitize_hit(NEW)] DriftTimeVSstripCharge " << driftTime << " " << stripCharge
202 << std::endl;
203 }
204 }
205 } else { // Phi-strips :: find the charge+noise
206 double yy = 0.0;
207 int strip = 0;
208
209 yy = pos_vec.y() + maxStrip * stripWidth * 0.5; // non-pointing phi-strips :: assuming zero offset
210 if (m_cscHitHelper->GetZSector(cscHit->CSCid()) > 0)
211 yy = -pos_vec.y() + maxStrip * stripWidth * 0.5; // non-pointing phi-strips :: assuming zero offset
212 strip = int(yy / stripWidth) + 1;
213
214 // find the charges induced on the phi strips
215 for (int j = strip - 1; j <= strip + 1; ++j) {
216 if (j > 0 && j <= maxStrip) {
217 double ypos = stripWidth * (j - 0.5);
218 double stripCharge = wireCharge * qStripPhi(ypos - yy, HitId) * 0.50;
219 if (m_debug)
220 std::cout << "[CSC_Digitizer::digitize_hit(NEW)] ypos = " << ypos << " yy = " << yy
221 << " diff = " << std::abs(yy - ypos) << " strip = " << j << " charge = " << stripCharge << std::endl;
222
223 IdentifierHash hashId = getHashId(HitId, j, measuresPhi);
224 fillSampleMaps(hashId, driftTime, stripCharge, hashVec, data_SampleMap);
225 fillSampleMaps(hashId, driftTime, stripCharge, hashVec, data_SampleMapOddPhase, 1);
226 }
227 }
228 }
229 }
230 }
231
232 return StatusCode::SUCCESS;
233}
double energyDeposit() const
Definition CSCSimHit.h:50
double m_electronEnergy
bool m_NInterFromEnergyLoss

◆ fillMaps()

void CSC_Digitizer::fillMaps ( const IdentifierHash hash,
const double driftTime,
const double stripCharge,
std::vector< IdentifierHash > & hashVec,
std::map< IdentifierHash, std::pair< double, double > > & data_map )
private

Definition at line 709 of file CSC_Digitizer.cxx.

710 {
711 if (stripCharge == 0.0) return;
712
713 // fill the CSC specific charge map the conversion hash -. id is done later !
714 if (data_map.find(hashId) != data_map.end()) {
715 /*
716 http://indico.cern.ch/getFile.py/access?contribId=9&resId=0&materialId=slides&confId=106902
717 */
718 std::pair<double, double> result = m_pcalib->addBipfunc(data_map[hashId].first, data_map[hashId].second, driftTime, stripCharge);
719 // To check out conversion is correct...
720 if (m_debug)
721 std::cout << "[CSC_Digitizer::fillMaps] (" << data_map[hashId].first << ":" << int(data_map[hashId].second) << ")"
722 << "+(" << driftTime << ":" << int(stripCharge) << ")"
723 << " ==> " << result.first << ":" << int(result.second) << " e- which was "
724 << int(data_map[hashId].second + stripCharge) << std::endl;
725
726 data_map[hashId].first = result.first;
727 data_map[hashId].second = result.second;
728
729 } else {
730 data_map[hashId].first = driftTime;
731 data_map[hashId].second = stripCharge;
732 hashVec.push_back(hashId);
733 }
734}

◆ fillSampleMaps()

void CSC_Digitizer::fillSampleMaps ( const IdentifierHash hash,
const double driftTime,
const double stripCharge,
std::vector< IdentifierHash > & hashVec,
std::map< IdentifierHash, std::vector< float > > & data_map,
bool phase = 0 )
private

Definition at line 556 of file CSC_Digitizer.cxx.

558 {
559 if (stripCharge == 0.0) return;
560
561 // fill the CSC specific charge map the conversion hash -. id is done later !
562 if (data_map.find(hashId) != data_map.end()) {
563 float phaseOffset = (phase) ? +25 : 0;
564 std::vector<float> samples = m_pcalib->getSamplesFromBipolarFunc(driftTime + phaseOffset, stripCharge);
565 std::vector<float> existingSamples = data_map[hashId]; // assuming that there are four elements...
566
567 if (m_debug) {
568 std::cout << "[CSC_Digitizer::fillSampleMaps] ";
569
570 for (unsigned int i = 0; i < samples.size(); ++i) std::cout << samples[i] << " ";
571 std::cout << " + ";
572
573 for (unsigned int i = 0; i < existingSamples.size(); ++i) std::cout << existingSamples[i] << " ";
574
575 std::cout << " ==> ";
576 }
577
578 for (unsigned int i = 0; i < samples.size(); ++i) { existingSamples[i] += samples[i]; }
579
580 if (m_debug) {
581 for (unsigned int i = 0; i < existingSamples.size(); ++i) std::cout << existingSamples[i] << " ";
582 std::cout << std::endl;
583 }
584
585 data_map[hashId] = existingSamples;
586
587 } else {
588 data_map.insert(std::pair<IdentifierHash, std::vector<float>>(hashId, m_pcalib->getSamplesFromBipolarFunc(driftTime, stripCharge)));
589 hashVec.push_back(hashId);
590 }
591}

◆ fparamPhi()

double CSC_Digitizer::fparamPhi ( const double x,
const std::array< double, 9 > & p )
staticprivate

Definition at line 667 of file CSC_Digitizer.cxx.

667 {
668 double fparam{0}, pow {1.};
669 for (size_t i = 0; i < p.size(); ++i) {
670 fparam += p[i] * pow;
671 pow *= x;
672 }
673 return fparam;
674}
#define x
constexpr int pow(int base, int exp) noexcept

◆ getDriftTime()

double CSC_Digitizer::getDriftTime ( const MuonGM::CscReadoutElement * descriptor,
const Amg::Vector3D & pos ) const
private

Definition at line 681 of file CSC_Digitizer.cxx.

681 {
682 // need to be calculated correct - Garfield?
683 // assumption on the field lines not good but of for pileup stuff!
684 double time = -1000.0;
685 // tested with 60, 45, 30 and 60 looks the best 12/7/2009
686 double v0 = m_driftVelocity * 1.e-3; // mm/microsecond 6 cm/microsecond -> mm/ns
687 float anodeCathodeDist = descriptor->anodeCathodeDistance();
688 float roxacellWidth = descriptor->roxacellWidth();
689 float beta = std::atan((descriptor->longWidth() - descriptor->shortWidth()) / (2. * descriptor->lengthUpToMaxWidth()));
690 float longWidth = descriptor->longWidth() - 2 * roxacellWidth * (1 + std::sin(beta)) / std::cos(beta);
691 float yy = pos.y() + longWidth * 0.5;
692 float x0 = pos.x();
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); // Lorentz effect small
697 time = driftDist / v0;
698 return time;
699}
double m_driftVelocity
time(flags, cells_name, *args, **kw)

◆ getHashId()

IdentifierHash CSC_Digitizer::getHashId ( const Identifier & input_id,
const int stripId,
const int measuresPhi ) const

Definition at line 736 of file CSC_Digitizer.cxx.

736 {
737 const int chamberLayer = m_cscIdHelper->chamberLayer(input_id);
738 const int wireLayer = m_cscIdHelper->wireLayer(input_id);
739 Identifier realHitId = m_cscIdHelper->channelID(input_id, chamberLayer, wireLayer, measuresPhi, stripId);
740 IdentifierHash hashId;
741 if (m_cscIdHelper->get_channel_hash(realHitId, 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()));
745 }
746 return hashId;
747}
value_type get_compact() const
Get the compact id.

◆ initialize()

StatusCode CSC_Digitizer::initialize ( )

Definition at line 31 of file CSC_Digitizer.cxx.

31 {
32 // initialize random number generators
33 // then initialize the CSC identifier helper
34 // This method must be called before looping over the hits
35 // to digitize them using the method digitize_hit below
36 m_bunchTime = 0.0;
37
38 // calculate the probability densities
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.};
41
42 double sump = 0;
43 for (int i = 0; i < s_maxElectron; ++i) {
44 sump += prob[i];
45 m_sprob[i] = sump;
46 }
47
48 return StatusCode::SUCCESS;
49}

◆ outsideWindow()

bool CSC_Digitizer::outsideWindow ( double time) const
private

Definition at line 676 of file CSC_Digitizer.cxx.

676 {
677 // m_bunchTime is included already....updated one..
678 return driftTime < m_timeWindowLowerOffset || driftTime > m_timeWindowUpperOffset;
679}
double m_timeWindowUpperOffset

◆ qStripPhi()

double CSC_Digitizer::qStripPhi ( const double x,
const Identifier & id ) const
private

Definition at line 649 of file CSC_Digitizer.cxx.

649 {
650 // parameters obtained from test beam
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; // divide by 10 to convert to cm!
654 double phiStripCharge = 0.0;
655
656 if (xx < 1.75) {
657 if (m_cscIdHelper->isSmall(id)) {
658 phiStripCharge = fparamPhi(xx, pSmall);
659 } else {
660 phiStripCharge = fparamPhi(xx, pLarge);
661 }
662 }
663
664 return phiStripCharge;
665}
static double fparamPhi(const double x, const std::array< double, 9 > &p)

◆ qStripR() [1/2]

double CSC_Digitizer::qStripR ( const double x)
staticprivate

Definition at line 618 of file CSC_Digitizer.cxx.

618 {
619 // induced charge on the r-strip
620 // parametrization based on experimental data
621
622 double rStripCharge = 0.0;
623 static constexpr std::array<double,4> Par{0.185, 2.315, 0.48, 5.2}; // obtained from test beam
624 double xx = std::abs(x) / 10.0; // divide by 10 to convert to cm!
625
626 rStripCharge = Par[0] * exp(-Par[1] * xx) + Par[2] * exp(-Par[3] * (xx * xx));
627
628 return rStripCharge;
629}

◆ qStripR() [2/2]

double CSC_Digitizer::qStripR ( const double x,
const Identifier & id ) const
private

Charge sharing profile.

New implementation Jan 2012 from fit to segment hits in run 186049.

Parameters
xdistance between strip and hit center in strip widths
stationTypesmall or large chamber
Returns
the charge fraction for this strip

Definition at line 637 of file CSC_Digitizer.cxx.

637 {
638 double stripCharge = 0.0;
639 double xx = x * x; // distance in strip widths squared
640
641 if (m_cscIdHelper->isSmall(id)) { // small chamber
642 stripCharge = 0.7001 / (1.0 + 1.38 * xx + 2.255 * xx * xx);
643 } else { // large chamber
644 stripCharge = 0.7 / (1.0 + 1.381 * xx + 2.248 * xx * xx);
645 }
646 return stripCharge;
647}

◆ qWire()

double CSC_Digitizer::qWire ( const int & nElectrons,
const double & gammaDist ) const
private

Definition at line 602 of file CSC_Digitizer.cxx.

602 {
603 // find the charge on the wire
604
605 // double amplification = 0.58e5;
606 double amplification = m_amplification;
607 double wireCharge = 0.0;
608
609 for (int i = 0; i < nElectrons; ++i) {
610 double RNDpol = 0.0;
611 if (m_Polia > -1.0) { RNDpol = gammaDist / (1.0 + m_Polia); }
612 wireCharge += amplification * RNDpol;
613 }
614 return wireCharge;
615}
double m_amplification

◆ set()

void CSC_Digitizer::set ( const double bunchTime)

Definition at line 598 of file CSC_Digitizer.cxx.

598{ m_bunchTime = bunchTime; }

◆ setAmplification()

void CSC_Digitizer::setAmplification ( const double amplification)
inline

Definition at line 54 of file CSC_Digitizer.h.

54{ m_amplification = amplification; }

◆ setDebug()

void CSC_Digitizer::setDebug ( int debug)
inline

Definition at line 56 of file CSC_Digitizer.h.

56{ m_debug = debug; }
const bool debug

◆ setDriftVelocity()

void CSC_Digitizer::setDriftVelocity ( double v0)
inline

Definition at line 58 of file CSC_Digitizer.h.

◆ setElectronEnergy()

void CSC_Digitizer::setElectronEnergy ( double e)
inline

Definition at line 59 of file CSC_Digitizer.h.

◆ setNInterFixed()

void CSC_Digitizer::setNInterFixed ( )
inline

Definition at line 60 of file CSC_Digitizer.h.

60{ m_NInterFromEnergyLoss = false; }

◆ setWindow()

void CSC_Digitizer::setWindow ( const double t1,
const double t2 )

Definition at line 593 of file CSC_Digitizer.cxx.

593 {
596}
double m_timeWindowLowerOffset
std::vector< ALFA_RawDataContainer_p1 > t2
std::vector< ALFA_RawDataCollection_p1 > t1

◆ to_identifier()

Identifier CSC_Digitizer::to_identifier ( const CSCSimHit * cscHit) const
private

Definition at line 51 of file CSC_Digitizer.cxx.

51 {
52 const int hitId = cscHit->CSCid();
53 const std::string st_str = m_cscHitHelper->GetStationName(hitId);
54 std::map<char, int>::const_iterator itr = m_stationDict.find(st_str[2]);
55 if (itr == m_stationDict.end()) {
56 throw std::runtime_error(Form("%s:%d Failed to convert station name %s to an valid offline identifier", __FILE__, __LINE__,
57 st_str.c_str()));
58 }
59 const int stationName = itr->second;
60 const int eta = m_cscHitHelper->GetZSector(hitId);
61 const int phi = m_cscHitHelper->GetPhiSector(hitId);
62 const int chamberLayer = m_cscHitHelper->GetChamberLayer(hitId);
63 const int wireLayer = m_cscHitHelper->GetWireLayer(hitId);
64 return m_cscIdHelper->channelID(stationName, eta, phi, chamberLayer, wireLayer, 0, 1);
65}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method

Member Data Documentation

◆ m_amplification

double CSC_Digitizer::m_amplification {0.}
private

Definition at line 107 of file CSC_Digitizer.h.

107{0.};

◆ m_bunchTime

double CSC_Digitizer::m_bunchTime {0.}
private

Definition at line 106 of file CSC_Digitizer.h.

106{0.};

◆ m_cscHitHelper

const CscHitIdHelper* CSC_Digitizer::m_cscHitHelper {nullptr}
private

Definition at line 93 of file CSC_Digitizer.h.

93{nullptr};

◆ m_cscIdHelper

const CscIdHelper* CSC_Digitizer::m_cscIdHelper {nullptr}
private

Definition at line 95 of file CSC_Digitizer.h.

95{nullptr};

◆ m_debug

int CSC_Digitizer::m_debug {0}
private

Definition at line 109 of file CSC_Digitizer.h.

109{0};

◆ m_driftVelocity

double CSC_Digitizer::m_driftVelocity {60.}
private

Definition at line 108 of file CSC_Digitizer.h.

108{60.}; // (1e-6 * 1e9); // 6 cm/microsecond -> mm/ns // 0.06

◆ m_electronEnergy

double CSC_Digitizer::m_electronEnergy {66.}
private

Definition at line 100 of file CSC_Digitizer.h.

100{66.}; // unit is eV

◆ m_muonMgr

const MuonGM::MuonDetectorManager* CSC_Digitizer::m_muonMgr {nullptr}
private

Definition at line 94 of file CSC_Digitizer.h.

94{nullptr}; // cannot use ReadCondHandleKey since no athena component

◆ m_NInterFromEnergyLoss

bool CSC_Digitizer::m_NInterFromEnergyLoss {true}
private

Definition at line 99 of file CSC_Digitizer.h.

99{true};

◆ m_pcalib

ICscCalibTool* CSC_Digitizer::m_pcalib {nullptr}
private

Definition at line 96 of file CSC_Digitizer.h.

96{nullptr};

◆ m_Polia

double CSC_Digitizer::m_Polia {0.}
private

Definition at line 102 of file CSC_Digitizer.h.

102{0.};

◆ m_sprob

std::array<double, s_maxElectron> CSC_Digitizer::m_sprob {0.}
private

Definition at line 103 of file CSC_Digitizer.h.

103{0.};

◆ m_stationDict

std::map<char, int> CSC_Digitizer::m_stationDict {}
private

Cache the csc id dictionary.

Definition at line 111 of file CSC_Digitizer.h.

111{};

◆ m_timeWindowLowerOffset

double CSC_Digitizer::m_timeWindowLowerOffset {0.}
private

Definition at line 104 of file CSC_Digitizer.h.

104{0.};

◆ m_timeWindowUpperOffset

double CSC_Digitizer::m_timeWindowUpperOffset {0.}
private

Definition at line 105 of file CSC_Digitizer.h.

105{0.};

◆ s_maxElectron

int CSC_Digitizer::s_maxElectron {21}
staticconstexprprivate

Definition at line 98 of file CSC_Digitizer.h.

98{21}; // max electron per interaction :not configurable

The documentation for this class was generated from the following files: