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

TRT Digitization: Processing of a TRT Straws. More...

#include <TRTProcessingOfStraw.h>

Inheritance diagram for TRTProcessingOfStraw:

Classes

class  cluster
 Primary ionisation cluster. More...

Public Types

typedef TimedHitCollection< TRTUncompressedHit >::const_iterator hitCollConstIter

Public Member Functions

 TRTProcessingOfStraw (const TRTDigSettings *, const InDetDD::TRT_DetectorManager *, ITRT_PAITool *, ITRT_SimDriftTimeTool *, TRTElectronicsProcessing *ep, TRTNoise *noise, TRTDigCondBase *digcond, const HepPDT::ParticleDataTable *, const TRT_ID *, ITRT_PAITool *=nullptr, ITRT_PAITool *=nullptr, const ITRT_CalDbTool *=nullptr)
 Constructor: Calls Initialize method.
 ~TRTProcessingOfStraw ()
 Destructor.
void ProcessStraw (MagField::AtlasFieldCache &fieldCache, const InDetDD::TRT_DetElementContainer *detElements, hitCollConstIter i, hitCollConstIter e, TRTDigit &outdigit, bool &m_alreadyPrintedPDGcodeWarning, double m_cosmicEventPhase, int strawGasType, bool emulationArflag, bool emulationKrflag, CLHEP::HepRandomEngine *rndmEngine, CLHEP::HepRandomEngine *elecProcRndmEngine, CLHEP::HepRandomEngine *elecNoiseRndmEngine, CLHEP::HepRandomEngine *paiRndmEngine)
 Process this straw all the way from Geant4 hit to output digit.
bool msgLvl (const MSG::Level lvl) const
 Test the output level.
MsgStream & msg () const
 The standard message stream.
MsgStream & msg (const MSG::Level lvl) const
 The standard message stream.
void setLevel (MSG::Level lvl)
 Change the current logging level.

Protected Attributes

const TRT_IDm_id_helper

Private Member Functions

 TRTProcessingOfStraw (const TRTProcessingOfStraw &)
TRTProcessingOfStrawoperator= (const TRTProcessingOfStraw &)
void Initialize (const ITRT_CalDbTool *)
 Initialize.
void addClustersFromStep (const double &scaledKineticEnergy, const double &particleCharge, const double &timeOfHit, const double &prex, const double &prey, const double &prez, const double &postx, const double &posty, const double &postz, std::vector< cluster > &clusterlist, int strawGasType, CLHEP::HepRandomEngine *rndmEngine, CLHEP::HepRandomEngine *paiRndmEngine)
 This is the main function for re-simulation of the ionisation in the active gas via the PAI model.
void ClustersToDeposits (MagField::AtlasFieldCache &fieldCache, const int &hitID, const std::vector< cluster > &clusters, std::vector< TRTElectronicsProcessing::Deposit > &deposits, Amg::Vector3D TRThitGlobalPos, double m_cosmicEventPhase, int strawGasType, CLHEP::HepRandomEngine *rndmEngine)
 Transform the ioniation clusters along the particle trajectory inside a straw to energy deposits (i.e.
double setClusterZ (double cluster_z_in, bool isLong, bool isShort, bool isEC) const
Amg::Vector3D getGlobalPosition (int hitID, const TimedHitPtr< TRTUncompressedHit > *theHit, const InDetDD::TRT_DetElementContainer *detElements)
void initMessaging () const
 Initialize our message level and MessageSvc.

Private Attributes

const TRTDigSettingsm_settings
const InDetDD::TRT_DetectorManagerm_detmgr
ITRT_PAIToolm_pPAItoolXe
ITRT_PAIToolm_pPAItoolAr
ITRT_PAIToolm_pPAItoolKr
ITRT_SimDriftTimeToolm_pSimDriftTimeTool
bool m_timeCorrection = false
 Time to be corrected for flight and wire propagation delays false when beamType='cosmics'.
double m_signalPropagationSpeed = 0.0
double m_attenuationLength = 0.0
bool m_useAttenuation = false
bool m_useMagneticFieldMap = false
double m_maxCrossingTime = 0.0
double m_minCrossingTime = 0.0
double m_shiftOfZeroPoint = 0.0
double m_innerRadiusOfStraw = 0.0
double m_outerRadiusOfWire = 0.0
double m_solenoidFieldStrength = 0.0
TRTTimeCorrectionm_pTimeCorrection
TRTElectronicsProcessingm_pElectronicsProcessing
TRTNoisem_pNoise
TRTDigCondBasem_pDigConditions
const HepPDT::ParticleDataTable * m_pParticleTable
std::vector< clusterm_clusterlist
std::vector< TRTElectronicsProcessing::Depositm_depositList
std::vector< double > m_drifttimes
std::vector< double > m_expattenuation
unsigned int m_maxelectrons = 0U
bool m_alreadywarnedagainstpdg0
std::unique_ptr< CLHEP::RandBinomialFixedPm_randBinomialXe {}
std::unique_ptr< CLHEP::RandBinomialFixedPm_randBinomialKr {}
std::unique_ptr< CLHEP::RandBinomialFixedPm_randBinomialAr {}
std::string m_nm
 Message source name.
boost::thread_specific_ptr< MsgStream > m_msg_tls
 MsgStream instance (a std::cout like with print-out levels)
std::atomic< IMessageSvc * > m_imsg { nullptr }
 MessageSvc pointer.
std::atomic< MSG::Level > m_lvl { MSG::NIL }
 Current logging level.
std::atomic_flag m_initialized ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
 Messaging initialized (initMessaging)

Detailed Description

TRT Digitization: Processing of a TRT Straws.


The main controlling function in ProcessStraw(). See detailed description of this.

Definition at line 57 of file TRTProcessingOfStraw.h.

Member Typedef Documentation

◆ hitCollConstIter

Constructor & Destructor Documentation

◆ TRTProcessingOfStraw() [1/2]

TRTProcessingOfStraw::TRTProcessingOfStraw ( const TRTDigSettings * digset,
const InDetDD::TRT_DetectorManager * detmgr,
ITRT_PAITool * paitoolXe,
ITRT_SimDriftTimeTool * simdrifttool,
TRTElectronicsProcessing * ep,
TRTNoise * noise,
TRTDigCondBase * digcond,
const HepPDT::ParticleDataTable * pdt,
const TRT_ID * trt_id,
ITRT_PAITool * paitoolAr = nullptr,
ITRT_PAITool * paitoolKr = nullptr,
const ITRT_CalDbTool * calDbTool = nullptr )

Constructor: Calls Initialize method.

Definition at line 49 of file TRTProcessingOfStraw.cxx.

62: AthMessaging("TRTProcessingOfStraw"),
63 m_settings(digset),
64 m_detmgr(detmgr),
65 m_pPAItoolXe(paitoolXe),
66 m_pPAItoolAr(paitoolAr),
67 m_pPAItoolKr(paitoolKr),
68 m_pSimDriftTimeTool(simdrifttool),
69// m_time_y_eq_zero(0.0),
70// m_ComTime(NULL),
71 m_pTimeCorrection(nullptr),
73 m_pNoise(noise),
74 m_pDigConditions(digcond),
77 m_id_helper(trt_id)
78
79{
80 Initialize(calDbTool);
81}
AthMessaging()
Default constructor:
const HepPDT::ParticleDataTable * m_pParticleTable
TRTDigCondBase * m_pDigConditions
TRTElectronicsProcessing * m_pElectronicsProcessing
void Initialize(const ITRT_CalDbTool *)
Initialize.
TRTTimeCorrection * m_pTimeCorrection
const TRTDigSettings * m_settings
ITRT_SimDriftTimeTool * m_pSimDriftTimeTool
const InDetDD::TRT_DetectorManager * m_detmgr

◆ ~TRTProcessingOfStraw()

TRTProcessingOfStraw::~TRTProcessingOfStraw ( )

Destructor.

Definition at line 84 of file TRTProcessingOfStraw.cxx.

85{
86 delete m_pTimeCorrection;
87}

◆ TRTProcessingOfStraw() [2/2]

TRTProcessingOfStraw::TRTProcessingOfStraw ( const TRTProcessingOfStraw & )
private

Member Function Documentation

◆ addClustersFromStep()

void TRTProcessingOfStraw::addClustersFromStep ( const double & scaledKineticEnergy,
const double & particleCharge,
const double & timeOfHit,
const double & prex,
const double & prey,
const double & prez,
const double & postx,
const double & posty,
const double & postz,
std::vector< cluster > & clusterlist,
int strawGasType,
CLHEP::HepRandomEngine * rndmEngine,
CLHEP::HepRandomEngine * paiRndmEngine )
private

This is the main function for re-simulation of the ionisation in the active gas via the PAI model.

From the given G4 step, ionisation clusters are distributed randomly (mean free path given by TRT_PAI_Process::GetMeanFreePath()) along path. Cluster energies are given by TRT_PAI_Process::GetEnergyTransfer().

Parameters
scaledKineticEnergyThe kinetic energy a proton would have had if it had the same Lorentz gamma factor as the particle in question.
particleChargeParticle charge
timeOfHitTime of hit
prexPreStepPoint x coordinate
preyPreStepPoint y coordinate
prezPreStepPoint z coordinate
postxPostStepPoint x coordinate
postyPostStepPoint y coordinate
postzPostStepPoint z coordinate
clusterlistList of ionisation clusters along step

Definition at line 205 of file TRTProcessingOfStraw.cxx.

212{
213
214 // Choose the appropriate ITRT_PAITool for this straw
215 ITRT_PAITool* activePAITool;
216 if (strawGasType==0) { activePAITool = m_pPAItoolXe; }
217 else if (strawGasType==1) { activePAITool = m_pPAItoolKr; }
218 else if (strawGasType==2) { activePAITool = m_pPAItoolAr; }
219 else { activePAITool = m_pPAItoolXe; } // should never happen
220
221 //Differences and steplength:
222 const double deltaX(postx - prex);
223 const double deltaY(posty - prey);
224 const double deltaZ(postz - prez);
225 const double stepLength(sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ));
226
227 const double meanFreePath(activePAITool->GetMeanFreePath( scaledKineticEnergy, particleCharge*particleCharge ));
228
229 //How many clusters did we actually create:
230 const unsigned int numberOfClusters(CLHEP::RandPoisson::shoot(rndmEngine,stepLength / meanFreePath));
231 //fixme: use RandPoissionQ?
232
233 //Position each of those randomly along the step, and use PAI to get their energies:
234 for (unsigned int iclus(0); iclus<numberOfClusters; ++iclus)
235 {
236 //How far along the step did the cluster get produced:
237 const double lambda(CLHEP::RandFlat::shoot(rndmEngine));
238
239 //Append cluster (the energy is given by the PAI model):
240 double clusE(activePAITool->GetEnergyTransfer(scaledKineticEnergy, paiRndmEngine));
241 clusterlist.emplace_back(clusE, timeOfHit,
242 prex + lambda * deltaX,
243 prey + lambda * deltaY,
244 prez + lambda * deltaZ);
245 }
246
247
248}
virtual double GetMeanFreePath(double scaledKineticEnergy, double squaredCharge) const =0
GetMeanFreePath.
virtual double GetEnergyTransfer(double scaledKineticEnergy, CLHEP::HepRandomEngine *rndmEngine) const =0
GetEnergyTransfer.

◆ ClustersToDeposits()

void TRTProcessingOfStraw::ClustersToDeposits ( MagField::AtlasFieldCache & fieldCache,
const int & hitID,
const std::vector< cluster > & clusters,
std::vector< TRTElectronicsProcessing::Deposit > & deposits,
Amg::Vector3D TRThitGlobalPos,
double m_cosmicEventPhase,
int strawGasType,
CLHEP::HepRandomEngine * rndmEngine )
private

Transform the ioniation clusters along the particle trajectory inside a straw to energy deposits (i.e.

potential fluctuations) reaching the front-end electronics. Effects taken into effect are:

  • number of primary electrons from deposited energy
  • stocastic recapture of drift electrons
  • electron drift in the magnetic field (different direction end-cap/barrel). Optionally the drift time includes spread.
  • Optionally signal wire propagation dealys are included. Each drift electron then gives rise to two signal: direct and reflected.
Parameters
hitIDId of straw
clustersionisation clusters along particle trajectory
depositsenergy deposits on wire

Definition at line 523 of file TRTProcessingOfStraw.cxx.

530{
531
532 //
533 // Some initial work before looping over the cluster
534 //
535
536 deposits.clear();
537
538 unsigned int region(TRTDigiHelper::getRegion(hitID));
539 const bool isBarrel(region<3 );
540 const bool isEC (!isBarrel);
541 const bool isShort (region==1);
542 const bool isLong (region==2);
543 //const bool isECA (region==3);
544 //const bool isECB (region==4);
545
546 CLHEP::RandBinomialFixedP *randBinomial{};
547 if (strawGasType == 0) { randBinomial = m_randBinomialXe.get(); }
548 else if (strawGasType == 1) { randBinomial = m_randBinomialKr.get(); }
549 else if (strawGasType == 2) { randBinomial = m_randBinomialAr.get(); }
550 else { randBinomial = m_randBinomialXe.get(); } // should never happen
551
552 double ionisationPotential = m_settings->ionisationPotential(strawGasType);
553 double smearingFactor = m_settings->smearingFactor(strawGasType);
554
555 std::vector<cluster>::const_iterator currentClusterIter(clusters.begin());
556 const std::vector<cluster>::const_iterator endOfClusterList(clusters.end());
557
558 // if (m_settings->doCosmicTimingPit()) {
559 // if (m_ComTime) { m_time_y_eq_zero = m_ComTime->getTime(); }
560 // else { ATH_MSG_WARNING("Configured to use ComTime tool, but did not find tool. All hits will get the same t0"); }
561 // }
562
563 // The average drift time is affected by the magnetic field which is not uniform so we need to use the
564 // detailed magnetic field map to obtain an effective field for this straw (used in SimDriftTimeTool).
565 // This systematically affects O(ns) drift times in the end cap, but has a very small effect in the barrel.
566 Amg::Vector3D globalPosition;
567 Amg::Vector3D mField;
568 double map_x2(0.),map_y2(0.),map_z2(0.);
569 double effectiveField2(0.); // effective field squared.
570
571 // Magnetic field is the same for all clusters in the straw so this can be called before the cluster loop.
573 {
574 globalPosition[0]=TRThitGlobalPos[0]*CLHEP::mm;
575 globalPosition[1]=TRThitGlobalPos[1]*CLHEP::mm;
576 globalPosition[2]=TRThitGlobalPos[2]*CLHEP::mm;
577
578 // MT Field cache is stored in cache
579 fieldCache.getField (globalPosition.data(), mField.data());
580
581 map_x2 = mField.x()*mField.x(); // would be zero for a uniform field
582 map_y2 = mField.y()*mField.y(); // would be zero for a uniform field
583 map_z2 = mField.z()*mField.z(); // would be m_solenoidfieldstrength^2 for uniform field
584 }
585
586 // Now we are ready to loop over clusters and form timed energy deposits at the wire:
587 //
588 // 1. First determine the number of surviving drift electrons and the energy of their deposits.
589 // 2. Then determine the timing of these deposits.
590
591 // Notes
592 //
593 // 1) It turns out that the total energy deposited (Ed) is, on average, equal to the cluster energy (Ec):
594 // <Ed> = m_ionisationPotential/m_smearingFactor * Ec/m_ionisationPotential * m_smearingFactor = Ec.
595 // Actually it exceeds this *slightly* due to the +1 electron in the calculation of nprimaryelectrons below.
596 // The energy processing below therefore exists only to model the energy *fluctuations*.
597 //
598 // 2) Gaussian approximation (for photons, HIPs etc):
599 // For large Ec (actually nprimaryelectrons > 99) a much faster Gaussian shoot replaces
600 // the Binomial and many exponential shoots. The Gaussian pdf has a mean of Ec and variance
601 // given by sigma^2 = Ec*ionisationPotential*(2-smearingFactor)/smearingFactor. That expression
602 // comes from the sum of the variances from the Binomial and Exponential. In this scheme it is
603 // sufficient (for diffusion) to divided the energy equally amongst 100 (maxelectrons) electrons.
604
605 // straw radius
606 const double wire_r2 = m_outerRadiusOfWire*m_outerRadiusOfWire;
607 const double straw_r2 = m_innerRadiusOfStraw*m_innerRadiusOfStraw;
608
609 // Cluster loop
610 for (;currentClusterIter!=endOfClusterList;++currentClusterIter)
611 {
612 // Get the cluster radius and energy.
613 const double cluster_x(currentClusterIter->xpos);
614 const double cluster_y(currentClusterIter->ypos);
615 const double cluster_z(this->setClusterZ(currentClusterIter->zpos, isLong, isShort, isEC));
616 const double cluster_x2(cluster_x*cluster_x);
617 const double cluster_y2(cluster_y*cluster_y);
618 double cluster_r2(cluster_x2+cluster_y2);
619
620 // These may never occur, but could be very problematic for getAverageDriftTime(), so check and correct this now.
621 if (cluster_r2<wire_r2) cluster_r2=wire_r2; // Compression may (v. rarely) cause r to be smaller than the wire radius. If r=0 then NaN's later!
622 if (cluster_r2>straw_r2) cluster_r2=straw_r2; // Should never occur
623
624 const double cluster_r(std::sqrt(cluster_r2)); // cluster radius
625 const double cluster_E(currentClusterIter->energy); // cluster energy
626 const unsigned int nprimaryelectrons( static_cast<unsigned int>( cluster_E / ionisationPotential + 1.0 ) );
627
628 // Determine the number of surviving electrons and their energy sum.
629 // If nprimaryelectrons > 100 then a Gaussian approximation is good (and much quicker)
630
631 double depositEnergy(0.); // This will be the energy deposited at the wire.
632
633 if (nprimaryelectrons<m_maxelectrons) // Use the detailed Binomial and Exponential treatment at this low energy.
634 {
635 unsigned int nsurvivingprimaryelectrons = static_cast<unsigned int>(randBinomial->fire(rndmEngine,nprimaryelectrons) + 0.5);
636 if (nsurvivingprimaryelectrons==0) continue; // no electrons survived; move on to the next cluster.
637 const double meanElectronEnergy(ionisationPotential / smearingFactor);
638 for (unsigned int ielec(0); ielec<nsurvivingprimaryelectrons; ++ielec) {
639 depositEnergy += CLHEP::RandExpZiggurat::shoot(rndmEngine, meanElectronEnergy);
640 }
641 }
642 else // Use a Gaussian approximation
643 {
644 const double fluctSigma(sqrt(cluster_E * ionisationPotential * (2 - smearingFactor) / smearingFactor));
645 do {
646 depositEnergy = CLHEP::RandGaussZiggurat::shoot(rndmEngine, cluster_E, fluctSigma);
647 } while(depositEnergy<0.0); // very rare.
648 }
649
650 // Now we have the depositEnergy, we need to work out the timing and attenuation
651
652 // First calculate the "effective field" (it's never negative):
653 // Electron drift time is prolonged by the magnetic field according to an "effective field".
654 // For the endcap, the effective field is dependent on the relative (x,y) position of the cluster.
655 // It is assumed here (checked in initialize) that the local straw x-direction is parallel with
656 // the solenoid z-direction. After Garfield simulations and long thought it was found that only
657 // field perpendicular to the electron drift is of importance.
658
659 if (!isBarrel) // Endcap
660 {
661 if (m_useMagneticFieldMap) { // Using magnetic field map
662 effectiveField2 = map_z2*cluster_y2/cluster_r2 + map_x2 + map_y2;
663 }
664 else { // Not using magnetic field map (you really should not do this!):
665 effectiveField2 = m_solenoidFieldStrength*m_solenoidFieldStrength * cluster_y2 / cluster_r2;
666 }
667 }
668 else // Barrel
669 {
670 if (m_useMagneticFieldMap) { // Using magnetic field map (here bug #91830 is corrected)
671 effectiveField2 = map_z2 + (map_x2+map_y2)*cluster_y2/cluster_r2;
672 }
673 else { // Without the mag field map (very small change in digi output)
675 }
676 }
677
678 // If there is no field we might need to reset effectiveField2 to zero.
679 if (m_solenoidFieldStrength == 0. ) effectiveField2=0.;
680
681 // Now we need the deposit time which is the sum of three components:
682 // 1. Time of the hit(cluster): clusterTime.
683 // 2. Drift times: either commondrifttime, or diffused m_drifttimes
684 // 3. Wire propagation times: timedirect and timereflect.
685
686 // get the time of the hit(cluster)
687 double clusterTime(currentClusterIter->time);
688
689 if ( m_settings->doCosmicTimingPit() )
690 { // make (x,y) dependent? i.e: + f(x,y).
691 // clusterTime = clusterTime - m_time_y_eq_zero + m_settings->jitterTimeOffset()*( CLHEP::RandFlat::shoot(rndmEngine) );
692 clusterTime = clusterTime + cosmicEventPhase + m_settings->jitterTimeOffset()*( CLHEP::RandFlat::shoot(rndmEngine) );
693 // yes it is a '+' now. Ask Alex Alonso.
694 }
695
696 // get the wire propagation times (for direct and reflected signals)
697 double timedirect(0.), timereflect(0.);
698 m_pTimeCorrection->PropagationTime( hitID, cluster_z, timedirect, timereflect );
699
700 // While we have the propagation times, we can calculate the exponential attenuation factor
701 double expdirect(1.0), expreflect(1.0); // Initially set to "no attenuation".
703 {
704 //expdirect = exp( -timedirect *m_signalPropagationSpeed / m_attenuationLength);
705 //expreflect = exp( -timereflect*m_signalPropagationSpeed / m_attenuationLength);
706 // Tabulating exp(-dist/m_attenuationLength) with only 150 elements: index [0,149].
707 // > 99.9% of output digits are the same, saves 13% CPU time.
708 // Distances the signal propagate along the wire:
709 // * distdirect is rarely negative (<0.2%) by ~ mm. In such cases there is
710 // no attenuation, which is equivalent to distdirect=0 and so is good.
711 // * distreflect is always +ve and less than 1500, and so is good.
712 // The code is protected against out of bounds in any case.
713 // But need to explicitly make sure that the argument of the cast is
714 // positive; otherwise, we'll see FPEs on arm.
715 const double distdirect = timedirect *m_signalPropagationSpeed;
716 const double distreflect = timereflect*m_signalPropagationSpeed;
717 const unsigned int kdirect = static_cast<unsigned int>(std::max(distdirect,0.0)/10);
718 const unsigned int kreflect = static_cast<unsigned int>(distreflect/10);
719 if (kdirect<150) expdirect = m_expattenuation[kdirect]; // otherwise there
720 if (kreflect<150) expreflect = m_expattenuation[kreflect]; // is no attenuation.
721 }
722
723 // Finally, deposit the energy on the wire using the drift-time tool (diffusion is no longer available).
724 double commondrifttime = m_pSimDriftTimeTool->getAverageDriftTime(cluster_r,effectiveField2,strawGasType);
725 double dt = clusterTime + commondrifttime;
726 deposits.emplace_back(0.5*depositEnergy*expdirect, timedirect+dt);
727 deposits.emplace_back(0.5*depositEnergy*expreflect, timereflect+dt);
728
729 } // end of cluster loop
730
731 }
void getField(const double *ATH_RESTRICT xyz, double *ATH_RESTRICT bxyz, double *ATH_RESTRICT deriv=nullptr)
get B field value at given position xyz[3] is in mm, bxyz[3] is in kT if deriv[9] is given,...
std::unique_ptr< CLHEP::RandBinomialFixedP > m_randBinomialXe
std::unique_ptr< CLHEP::RandBinomialFixedP > m_randBinomialKr
std::unique_ptr< CLHEP::RandBinomialFixedP > m_randBinomialAr
std::vector< double > m_expattenuation
double setClusterZ(double cluster_z_in, bool isLong, bool isShort, bool isEC) const
Eigen::Matrix< double, 3, 1 > Vector3D
unsigned int getRegion(int hitID)

◆ getGlobalPosition()

Amg::Vector3D TRTProcessingOfStraw::getGlobalPosition ( int hitID,
const TimedHitPtr< TRTUncompressedHit > * theHit,
const InDetDD::TRT_DetElementContainer * detElements )
private

Definition at line 734 of file TRTProcessingOfStraw.cxx.

737{
738
739 const int mask(0x0000001F);
740 int word_shift(5);
741 int trtID, ringID, moduleID, layerID, strawID;
742 int wheelID, planeID, sectorID;
743
744 const InDetDD::TRT_BarrelElement *barrelElement;
745 const InDetDD::TRT_EndcapElement *endcapElement;
746
747 if ( !(hitID & 0x00200000) ) { // barrel
748
749 strawID = hitID & mask;
750 hitID >>= word_shift;
751 layerID = hitID & mask;
752 hitID >>= word_shift;
753 moduleID = hitID & mask;
754 hitID >>= word_shift;
755 ringID = hitID & mask;
756 trtID = hitID >> word_shift;
757
758 barrelElement = detElements->getBarrelDetElement(trtID, ringID, moduleID, layerID);
759
760 if (barrelElement) {
761 const Amg::Vector3D v( (*theHit)->GetPreStepX(),(*theHit)->GetPreStepY(),(*theHit)->GetPreStepZ());
762 return barrelElement->strawTransform(strawID)*v;
763 }
764
765 } else { // endcap
766
767 strawID = hitID & mask;
768 hitID >>= word_shift;
769 planeID = hitID & mask;
770 hitID >>= word_shift;
771 sectorID = hitID & mask;
772 hitID >>= word_shift;
773 wheelID = hitID & mask;
774 trtID = hitID >> word_shift;
775
776 // change trtID (which is 2/3 for endcaps) to use 0/1 in getEndcapElement
777 if (trtID == 3) trtID = 0;
778 else trtID = 1;
779
780 endcapElement = detElements->getEndcapDetElement(trtID, wheelID, planeID, sectorID);
781
782 if ( endcapElement ) {
783 const Amg::Vector3D v( (*theHit)->GetPreStepX(),(*theHit)->GetPreStepY(),(*theHit)->GetPreStepZ());
784 return endcapElement->strawTransform(strawID)*v;
785 }
786
787 }
788
789 ATH_MSG_WARNING ( "Could not find global coordinate of a straw - drifttime calculation will be inaccurate" );
790 return {0.0,0.0,0.0};
791
792}
#define ATH_MSG_WARNING(x)
const Amg::Transform3D & strawTransform(unsigned int straw) const
Straw transform - fast access in array, in Tracking frame: Amg.
const TRT_EndcapElement * getEndcapDetElement(unsigned int positive, unsigned int wheelIndex, unsigned int strawLayerIndex, unsigned int phiIndex) const
const TRT_BarrelElement * getBarrelDetElement(unsigned int positive, unsigned int moduleIndex, unsigned int phiIndex, unsigned int strawLayerIndex) const

◆ Initialize()

void TRTProcessingOfStraw::Initialize ( const ITRT_CalDbTool * calDbTool)
private

Initialize.

Definition at line 90 of file TRTProcessingOfStraw.cxx.

91{
92
93 m_useMagneticFieldMap = m_settings->useMagneticFieldMap();
94 m_signalPropagationSpeed = m_settings->signalPropagationSpeed() ;
95 m_attenuationLength = m_settings->attenuationLength();
96 m_useAttenuation = m_settings->useAttenuation();
97 m_innerRadiusOfStraw = m_settings->innerRadiusOfStraw();
98 m_outerRadiusOfWire = m_settings->outerRadiusOfWire();
99 m_timeCorrection = m_settings->timeCorrection(); // false for beamType='cosmics'
100 m_solenoidFieldStrength = m_settings->solenoidFieldStrength();
101
102 m_maxelectrons = 100; // 100 gives good Gaussian approximation
103
104 if (m_pPAItoolXe==nullptr) {
105 ATH_MSG_FATAL ( "TRT_PAITool for Xenon not defined! no point in continuing!" );
106 }
107 if (m_pPAItoolKr==nullptr) {
108 ATH_MSG_ERROR ( "TRT_PAITool for Krypton is not defined!!! Xenon TRT_PAITool will be used for Krypton straws!" );
110 }
111 if (m_pPAItoolAr==nullptr) {
112 ATH_MSG_ERROR ( "TRT_PAITool for Argon is not defined!!! Xenon TRT_PAITool will be used for Argon straws!" );
114 }
115
116 ATH_MSG_INFO ( "Xe barrel drift-time at r = 2 mm is " << m_pSimDriftTimeTool->getAverageDriftTime(2.0, 0.002*0.002, 0) << " ns." );
117 ATH_MSG_INFO ( "Kr barrel drift-time at r = 2 mm is " << m_pSimDriftTimeTool->getAverageDriftTime(2.0, 0.002*0.002, 1) << " ns." );
118 ATH_MSG_INFO ( "Ar barrel drift-time at r = 2 mm is " << m_pSimDriftTimeTool->getAverageDriftTime(2.0, 0.002*0.002, 2) << " ns." );
119
120 m_pTimeCorrection = new TRTTimeCorrection(m_settings, m_detmgr, m_id_helper, calDbTool);
121
122 const double intervalBetweenCrossings(m_settings->timeInterval() / 3.);
123 m_minCrossingTime = - (intervalBetweenCrossings * 2. + 1.*CLHEP::ns);
124 m_maxCrossingTime = intervalBetweenCrossings * 3. + 1.*CLHEP::ns;
125 m_shiftOfZeroPoint = static_cast<double>( m_settings->numberOfCrossingsBeforeMain() ) * intervalBetweenCrossings;
126
127 // Tabulate exp(-dist/m_attenuationLength) as a function of dist = time*m_signalPropagationSpeed [0.0 mm, 1500 mm)
128 // otherwise we are doing an exp() for every cluster! > 99.9% of output digits are the same, saves 13% CPU time.
129 m_expattenuation.reserve(150);
130 for (unsigned int k=0; k<150; k++) {
131 double dist = 10.0*(k+0.5); // [5mm, 1415mm] max 5 mm error (sigma = 3 mm)
132 m_expattenuation.push_back(exp(-dist/m_attenuationLength));
133 }
134
135 //For the field effect on drifttimes in this class we will assume that the local x,y coordinates of endcap straws are such that the
136 //local y-direction is parallel to the global z-direction. As a sanity check against future code developments we will test this
137 //assumption on one straw from each endcap layer.
138
140 {
141 const InDetDD::TRT_Numerology * num = m_detmgr->getNumerology();
142 for (unsigned int iwheel = 0; iwheel < num->getNEndcapWheels(); ++iwheel)
143 {
144 for (unsigned int iside = 0; iside < 2; ++iside)
145 { //positive and negative endcap
146 for (unsigned int ilayer = 0; ilayer < num->getNEndcapLayers(iwheel); ++ilayer)
147 {
148 const InDetDD::TRT_EndcapElement * ec_element
149 = m_detmgr->getEndcapElement(iside,//positive or negative endcap
150 iwheel,//wheelIndex,
151 ilayer,//strawLayerIndex,
152 0);//phiIndex
153 //Local straw center and local straw point one unit along x:
154 if (!ec_element)
155 {
156 ATH_MSG_VERBOSE ( "Failed to retrieve endcap element for (iside,iwheel,ilayer)=("
157 << iside<<", "<<iwheel<<", "<<ilayer<<")." );
158 continue;
159 }
160 Amg::Vector3D strawcenter(0.0,0.0,0.0);
161 Amg::Vector3D strawx(1.0,0.0,0.0);
162 //Transform to global coordinate (use first straw in element):
163 strawcenter = ec_element->strawTransform(0) * strawcenter;
164 strawx = ec_element->strawTransform(0) * strawx;
165 const Amg::Vector3D v(strawx-strawcenter);
166 const double zcoordfrac((v.z()>0?v.z():-v.z())/v.mag());
167 if (zcoordfrac<0.98 || zcoordfrac > 1.02)
168 {
169 ATH_MSG_WARNING ( "Found endcap straw where the assumption that local x-direction"
170 <<" is parallel to global z-direction is NOT valid."
171 <<" Drift times will be somewhat off." );
172 }
173 }
174 }
175 }
176
177 //check local barrel coordinates at four positions.
178 for (unsigned int phi_it = 0; phi_it < 32; phi_it++)
179 {
180 const InDetDD::TRT_BarrelElement * bar_element = m_detmgr->getBarrelElement(1,1,phi_it,1);
181
182 Amg::Vector3D strawcenter(0.0,0.0,0.0);
183 Amg::Vector3D straw(cos((double)phi_it*2*M_PI/32.),sin((double)phi_it*2*M_PI/32.),0.0);
184 strawcenter = bar_element->strawTransform(0) * strawcenter;
185 straw = bar_element->strawTransform(0) * straw;
186 const Amg::Vector3D v(straw-strawcenter);
187 const double coordfrac(atan2(v.x(),v.y()));
188 if (coordfrac>0.2 || coordfrac < -0.2)
189 {
190 ATH_MSG_WARNING ( "Found barrel straw where the assumption that local y-direction"
191 <<" is along the straw is NOT valid."
192 <<" Drift times will be somewhat off." );
193 }
194 }
195 }
196
197 m_randBinomialXe = std::make_unique<CLHEP::RandBinomialFixedP>(nullptr, 1, m_settings->smearingFactor(0), m_maxelectrons);
198 m_randBinomialKr = std::make_unique<CLHEP::RandBinomialFixedP>(nullptr, 1, m_settings->smearingFactor(1), m_maxelectrons);
199 m_randBinomialAr = std::make_unique<CLHEP::RandBinomialFixedP>(nullptr, 1, m_settings->smearingFactor(2), m_maxelectrons);
200
201 ATH_MSG_VERBOSE ( "Initialization done" );
202}
#define M_PI
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
bool m_timeCorrection
Time to be corrected for flight and wire propagation delays false when beamType='cosmics'.
@ straw
Definition HitInfo.h:82

◆ initMessaging()

void AthMessaging::initMessaging ( ) const
privateinherited

Initialize our message level and MessageSvc.

This method should only be called once.

Definition at line 39 of file AthMessaging.cxx.

40{
42 // If user did not set an explicit level, set a default
43 if (m_lvl == MSG::NIL) {
44 m_lvl = m_imsg ?
45 static_cast<MSG::Level>( m_imsg.load()->outputLevel(m_nm) ) :
46 MSG::INFO;
47 }
48}
std::string m_nm
Message source name.
std::atomic< IMessageSvc * > m_imsg
MessageSvc pointer.
std::atomic< MSG::Level > m_lvl
Current logging level.
IMessageSvc * getMessageSvc(bool quiet=false)

◆ msg() [1/2]

MsgStream & AthMessaging::msg ( ) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 167 of file AthMessaging.h.

168{
169 MsgStream* ms = m_msg_tls.get();
170 if (!ms) {
171 if (!m_initialized.test_and_set()) initMessaging();
172 ms = new MsgStream(m_imsg,m_nm);
173 m_msg_tls.reset( ms );
174 }
175
176 ms->setLevel (m_lvl);
177 return *ms;
178}
boost::thread_specific_ptr< MsgStream > m_msg_tls
MsgStream instance (a std::cout like with print-out levels)
void initMessaging() const
Initialize our message level and MessageSvc.

◆ msg() [2/2]

MsgStream & AthMessaging::msg ( const MSG::Level lvl) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 182 of file AthMessaging.h.

183{ return msg() << lvl; }
MsgStream & msg() const
The standard message stream.

◆ msgLvl()

bool AthMessaging::msgLvl ( const MSG::Level lvl) const
inlineinherited

Test the output level.

Parameters
lvlThe message level to test against
Returns
boolean Indicating if messages at given level will be printed
Return values
trueMessages at level "lvl" will be printed

Definition at line 151 of file AthMessaging.h.

152{
153 // If user did not set explicit message level we have to initialize
154 // the messaging and retrieve the default via the MessageSvc.
155 if (m_lvl==MSG::NIL && !m_initialized.test_and_set()) initMessaging();
156
157 if (m_lvl <= lvl) {
158 msg() << lvl;
159 return true;
160 } else {
161 return false;
162 }
163}

◆ operator=()

TRTProcessingOfStraw & TRTProcessingOfStraw::operator= ( const TRTProcessingOfStraw & )
private

◆ ProcessStraw()

void TRTProcessingOfStraw::ProcessStraw ( MagField::AtlasFieldCache & fieldCache,
const InDetDD::TRT_DetElementContainer * detElements,
hitCollConstIter i,
hitCollConstIter e,
TRTDigit & outdigit,
bool & m_alreadyPrintedPDGcodeWarning,
double m_cosmicEventPhase,
int strawGasType,
bool emulationArflag,
bool emulationKrflag,
CLHEP::HepRandomEngine * rndmEngine,
CLHEP::HepRandomEngine * elecProcRndmEngine,
CLHEP::HepRandomEngine * elecNoiseRndmEngine,
CLHEP::HepRandomEngine * paiRndmEngine )

Process this straw all the way from Geant4 hit to output digit.


Steps:

  1. Loop over the simhits in this straw and produce a list of primary ionisation clusters.
  2. Use the cluster list along with gas and wire properties, to create a list of energy deposits (i.e. potential fluctuations) reaching the frontend electronics.
  3. Simulate how the FE turns the results into an output digit. This includes the shaping/amplification and subsequent discrimination as well as addition of noise.
Parameters
iGeant4 hit collection iterator
elast hit in collection
outdigitThe 27 bit digit (bits: 8 low + 1 high + 8 low + 1 high + 8 low + 1 high)

Definition at line 251 of file TRTProcessingOfStraw.cxx.

265{
266
268 // We need the straw id several times in the following //
270 const int hitID((*i)->GetHitID());
271 unsigned int region(TRTDigiHelper::getRegion(hitID));
272 const bool isBarrel(region<3 );
273 //const bool isEC (!isBarrel);
274 //const bool isShort (region==1);
275 //const bool isLong (region==2);
276 const bool isECA (region==3);
277 const bool isECB (region==4);
278
280 //======================================================//
282 // First step is to loop over the simhits in this straw //
283 // and produce a list of primary ionisation clusters. //
284 // Each cluster needs the following information: //
285 // //
286 // * The total energy of the cluster. //
287 // * Its location in local straw (x,y,z) coordinates. //
288 // * The time the cluster was created. //
289 // //
291 //======================================================//
293 // TimeShift is the same for all the simhits in the straw.
294 const double timeShift(m_pTimeCorrection->TimeShift(hitID, detElements)); // rename hitID to strawID
295
296 m_clusterlist.clear();
297
298 //For magnetic field evaluation
299 Amg::Vector3D TRThitGlobalPos(0.0,0.0,0.0);
300
301 //Now we loop over all the simhits
302 for (hitCollConstIter hit_iter= i; hit_iter != e; ++hit_iter)
303 {
304 //Get the hit:
305 const TimedHitPtr<TRTUncompressedHit> *theHit = &(*hit_iter);
306
307 TRThitGlobalPos = getGlobalPosition(hitID, theHit, detElements);
308
309 //Figure out the global time of the hit (all clusters from the hit
310 //will get same timing).
311
312 double timeOfHit(0.0); // remains zero if timeCorrection is false (beamType='cosmics')
313 if (m_timeCorrection) {
314 const double globalHitTime(hitTime(*theHit));
315 const double globalTime = static_cast<double>((*theHit)->GetGlobalTime());
316 const double bunchCrossingTime(globalHitTime - globalTime);
317 if ( (bunchCrossingTime < m_minCrossingTime) || (bunchCrossingTime > m_maxCrossingTime) ) continue;
318 timeOfHit = m_shiftOfZeroPoint + globalHitTime - timeShift; //is this shiftofzeropoint correct pileup-wise?? [fixme]
319 }
320
321 //if (timeOfHit>125.0) continue; // Will give 3% speed up (but changes seeds!). Needs careful thought though.
322
323 //What kind of particle are we dealing with?
324 const int particleEncoding((*theHit)->GetParticleEncoding());
325
326 //Safeguard against pdgcode 0.
327 if (particleEncoding == 0)
328 {
329 //According to Andrea this is usually nuclear fragments from
330 //hadronic interactions. They therefore ought to be allowed to
331 //contribute, but we ignore them for now - until it can be studied
332 //that it is indeed safe to stop doing so
335 ATH_MSG_WARNING ( "Ignoring sim. particle with pdgcode 0. This warning is only shown once per job" );
336 }
337 continue;
338 }
339
340 // If it is a photon we assume it was absorbed entirely at the point of interaction.
341 // we simply deposit the entire energy into the last point of the sim. step.
342 if ( MC::isPhoton(particleEncoding) ) {
343
344 const double energyDeposit = (*theHit)->GetEnergyDeposit(); // keV (see comment below)
345 // Apply radiator efficiency "fudge factor" to ignore some TR photons (assuming they are over produced in the sim. step.
346 // The fraction removed is based on tuning pHT for electrons to data, after tuning pHT for muons (which do not produce TR).
347 // The efficiency is different for Xe, Kr and Ar. Avoid fudging non-TR photons (TR is < 30 keV).
348 // Also: for |eta|<0.5 apply parabolic scale; see "Parabolic Fudge" https://indico.cern.ch/event/304066/
349
350 if ( energyDeposit<30.0 ) {
351
352 // Improved Argon Emulation tuning October 2018 by Hassane Hamdaoui https://cds.cern.ch/record/2643784
353 // Previously 0.15, 0.28, 0.28
354 double ArEmulationScaling_BA = 0.05;
355 double ArEmulationScaling_ECA = 0.20;
356 double ArEmulationScaling_ECB = 0.20;
357
358 // ROUGH GUESSES RIGHT NOW
359 double KrEmulationScaling_BA = 0.20;
360 double KrEmulationScaling_ECA = 0.39;
361 double KrEmulationScaling_ECB = 0.39;
362
363 if (isBarrel) { // Barrel
364 double trEfficiencyBarrel = m_settings->trEfficiencyBarrel(strawGasType);
365 double hitx = TRThitGlobalPos[0];
366 double hity = TRThitGlobalPos[1];
367 double hitz = TRThitGlobalPos[2];
368 double hitEta = std::abs(log(tan(0.5*atan2(sqrt(hitx*hitx+hity*hity),hitz))));
369 if ( hitEta < 0.5 ) { trEfficiencyBarrel *= ( 0.833333+0.6666667*hitEta*hitEta ); }
370 // scale down the TR efficiency if we are emulating
371 if ( strawGasType == 0 && emulationArflag ) { trEfficiencyBarrel *= ArEmulationScaling_BA; }
372 if ( strawGasType == 0 && emulationKrflag ) { trEfficiencyBarrel *= KrEmulationScaling_BA; }
373 if ( CLHEP::RandFlat::shoot(rndmEngine) > trEfficiencyBarrel ) continue; // Skip this photon
374 } // close if barrel
375 else { // Endcap - no eta dependence here.
376 if (isECA) {
377 double trEfficiencyEndCapA = m_settings->trEfficiencyEndCapA(strawGasType);
378 // scale down the TR efficiency if we are emulating
379 if ( strawGasType == 0 && emulationArflag ) { trEfficiencyEndCapA *= ArEmulationScaling_ECA; }
380 if ( strawGasType == 0 && emulationKrflag ) { trEfficiencyEndCapA *= KrEmulationScaling_ECA; }
381 if ( CLHEP::RandFlat::shoot(rndmEngine) > trEfficiencyEndCapA ) continue; // Skip this photon
382 }
383 if (isECB) {
384 double trEfficiencyEndCapB = m_settings->trEfficiencyEndCapB(strawGasType);
385 // scale down the TR efficiency if we are emulating
386 if ( strawGasType == 0 && emulationArflag ) { trEfficiencyEndCapB *= ArEmulationScaling_ECB; }
387 if ( strawGasType == 0 && emulationKrflag ) { trEfficiencyEndCapB *= KrEmulationScaling_ECB; }
388 if ( CLHEP::RandFlat::shoot(rndmEngine) > trEfficiencyEndCapB ) continue; // Skip this photon
389 }
390 } // close else (end caps)
391 } // energyDeposit < 30.0
392
393 // Append this (usually highly energetic) cluster to the list:
394 m_clusterlist.emplace_back( energyDeposit*CLHEP::keV, timeOfHit, (*theHit)->GetPostStepX(), (*theHit)->GetPostStepY(), (*theHit)->GetPostStepZ() );
395
396 // Regarding the CLHEP::keV above: In TRT_G4_SD we converting the hits to keV,
397 // so here we convert them back to CLHEP units by multiplying by CLHEP::keV.
398 }
399 else if ( MC::isMonopole(particleEncoding)
400 || ( MC::isGenericMultichargedParticle(particleEncoding) && MC::charge(particleEncoding) > 10. )
401 ) {
402 //Special treatment of magnetic monopoles && highly charged Qballs (charge > 10)
403 m_clusterlist.emplace_back( (*theHit)->GetEnergyDeposit()*CLHEP::keV, timeOfHit, (*theHit)->GetPostStepX(), (*theHit)->GetPostStepY(), (*theHit)->GetPostStepZ() );
404 }
405 else { // It's not a photon, monopole or Qball with charge > 10, so we proceed with regular ionization using the PAI model
406
407 // Lookup mass and charge from the PDG info in CLHEP HepPDT:
408 const HepPDT::ParticleData *particle(m_pParticleTable->particle(HepPDT::ParticleID(abs(particleEncoding))));
409 double particleCharge(0.);
410 double particleMass(0.);
411
412 if (particle) {
413 particleCharge = particle->charge();
414 particleMass = particle->mass().value();
415 // Override ParticleData charge value for Qballs and similar exotic multi-charged particles
416 if (MC::isGenericMultichargedParticle(particleEncoding)) {
417 particleCharge =MC::charge(particleEncoding);
418 }
419 }
420 else {
421 // TODO Should we handle charged Geantinos gracefully here?
422 if (!MC::isNucleus(particleEncoding)) {
423 ATH_MSG_WARNING ( "Data for sim. particle with pdgcode "<<particleEncoding
424 <<" is not a nucleus and could not be retrieved from PartPropSvc. Assuming mass and charge as pion. Please investigate." );
425 particleCharge = 1.;
427 }
428 else {
429 particleCharge = MC::charge(particleEncoding);
430
431 const int A(static_cast<int>(MC::baryonNumber(particleEncoding)));
432 const int Z(static_cast<int>(std::abs(MC::numberOfProtons(particleEncoding))));
433 static constexpr double Mp(ParticleConstants::protonMassInMeV);
434 static constexpr double Mn(ParticleConstants::neutronMassInMeV);
435 particleMass = std::abs( Z*Mp+(A-Z)*Mn );
436
437 if (!alreadyPrintedPDGcodeWarning) {
438 ATH_MSG_WARNING ( "Data for sim. particle with pdgcode "<<particleEncoding
439 <<" could not be retrieved from PartPropSvc (unexpected ion)."
440 <<" Please Investigate the PDGTABLE.MeV file."
441 <<" Calculating mass and charge from pdg code."
442 <<" The result is: Charge = "<<particleCharge<<" Mass = "<<particleMass<<"MeV" );
443 alreadyPrintedPDGcodeWarning = true;
444 }
445 }
446 }
447 // Abort if uncharged particle.
448 if (!particleCharge) { continue; }
449 // Abort if weird massless charged particle.
450 if (!particleMass) {
451 ATH_MSG_WARNING ( "Ignoring ionization from particle with pdg code "<<particleEncoding
452 <<" since it appears to be a massless charged particle. Please investigate." );
453 continue;
454 }
455
456 //We are now in the most likely case: A normal ionizing
457 //particle. Using the PAI model we are going to distribute
458 //ionization clusters along the step taken by the sim particle.
459
460 const double scaledKineticEnergy( static_cast<double>((*theHit)->GetKineticEnergy()) * ( CLHEP::proton_mass_c2 / particleMass ));
461
462 addClustersFromStep ( scaledKineticEnergy, particleCharge, timeOfHit,
463 (*theHit)->GetPreStepX(),(*theHit)->GetPreStepY(),(*theHit)->GetPreStepZ(),
464 (*theHit)->GetPostStepX(),(*theHit)->GetPostStepY(),(*theHit)->GetPostStepZ(),
465 m_clusterlist, strawGasType, rndmEngine, paiRndmEngine);
466
467 }
468 }//end of hit loop
469
471 //======================================================//
473 // Second step is, using the cluster list along with //
474 // gas and wire properties, to create a list of energy //
475 // deposits (i.e. potential fluctuations) reaching the //
476 // frontend electronics. Each deposit needs: //
477 // //
478 // * The energy of the deposit. //
479 // * The time it arrives at the FE electronics //
480 // //
482 //======================================================//
484
485 m_depositList.clear();
486
487 ClustersToDeposits(fieldCache, hitID, m_clusterlist, m_depositList, TRThitGlobalPos, cosmicEventPhase, strawGasType, rndmEngine );
488
489
491 //======================================================//
493 // The third and final step is to simulate how the FE //
494 // turns the results into an output digit. This //
495 // includes the shaping/amplification and subsequent //
496 // discrimination as well as addition of noise. //
497 // //
499 //======================================================//
501
502 //If no deposits, and no electronics noise we might as well stop here:
503 if ( m_depositList.empty() && !m_pNoise )
504 {
505 outdigit = TRTDigit(hitID, 0);
506 return;
507 }
508
509 //Get straw conditions data:
510 double lowthreshold, noiseamplitude;
511 if (m_settings->noiseInSimhits()) {
512 m_pDigConditions->getStrawData( hitID, lowthreshold, noiseamplitude );
513 } else {
514 lowthreshold = isBarrel ? m_settings->lowThresholdBar(strawGasType) : m_settings->lowThresholdEC(strawGasType);
515 noiseamplitude = 0.0;
516 }
517
518 //Electronics processing:
519 m_pElectronicsProcessing->ProcessDeposits( m_depositList, hitID, outdigit, lowthreshold, noiseamplitude, strawGasType, elecProcRndmEngine, elecNoiseRndmEngine );
520}
float hitTime(const AFP_SIDSimHit &hit)
Amg::Vector3D getGlobalPosition(int hitID, const TimedHitPtr< TRTUncompressedHit > *theHit, const InDetDD::TRT_DetElementContainer *detElements)
std::vector< cluster > m_clusterlist
void ClustersToDeposits(MagField::AtlasFieldCache &fieldCache, const int &hitID, const std::vector< cluster > &clusters, std::vector< TRTElectronicsProcessing::Deposit > &deposits, Amg::Vector3D TRThitGlobalPos, double m_cosmicEventPhase, int strawGasType, CLHEP::HepRandomEngine *rndmEngine)
Transform the ioniation clusters along the particle trajectory inside a straw to energy deposits (i....
void addClustersFromStep(const double &scaledKineticEnergy, const double &particleCharge, const double &timeOfHit, const double &prex, const double &prey, const double &prez, const double &postx, const double &posty, const double &postz, std::vector< cluster > &clusterlist, int strawGasType, CLHEP::HepRandomEngine *rndmEngine, CLHEP::HepRandomEngine *paiRndmEngine)
This is the main function for re-simulation of the ionisation in the active gas via the PAI model.
std::vector< TRTElectronicsProcessing::Deposit > m_depositList
TimedHitCollection< TRTUncompressedHit >::const_iterator hitCollConstIter
int numberOfProtons(const T &p)
bool isGenericMultichargedParticle(const T &p)
In addition, there is a need to identify ”Q-ball” and similar very exotic (multi-charged) particles w...
bool isPhoton(const T &p)
bool isMonopole(const T &p)
PDG rule 11i Magnetic monopoles and dyons are assumed to have one unit of Dirac monopole charge and a...
double charge(const T &p)
bool isNucleus(const T &p)
PDG rule 16 Nuclear codes are given as 10-digit numbers ±10LZZZAAAI.
double baryonNumber(const T &p)
constexpr double protonMassInMeV
the mass of the proton (in MeV)
constexpr double chargedPionMassInMeV
the mass of the charged pion (in MeV)
constexpr double neutronMassInMeV
the mass of the neutron (in MeV)
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
@ energyDeposit

◆ setClusterZ()

double TRTProcessingOfStraw::setClusterZ ( double cluster_z_in,
bool isLong,
bool isShort,
bool isEC ) const
private

Definition at line 795 of file TRTProcessingOfStraw.cxx.

795 {
796 double cluster_z(cluster_z_in);
797
798 // The active gas volume along the straw z-axis is: Barrel long +-349.315 mm; Barrel short +-153.375 mm; End caps +-177.150 mm.
799 // Here we give a warning for clusters that are outside of the straw gas volume in in z. Since T/P version 3 cluster z values
800 // can go several mm outside these ranges; 30 mm is plenty allowance in the checks below.
801 const double longBarrelStrawHalfLength(349.315*CLHEP::mm);
802 const double shortBarrelStrawHalfLength(153.375*CLHEP::mm);
803 const double EndcapStrawHalfLength(177.150*CLHEP::mm);
804 if ( isLong && std::abs(cluster_z)>longBarrelStrawHalfLength+30 ) {
805 double d = cluster_z<0 ? cluster_z+longBarrelStrawHalfLength : cluster_z-longBarrelStrawHalfLength;
806 ATH_MSG_WARNING ("Long barrel straw cluster is outside the active gas volume z = +- 349.315 mm by " << d << " mm.");
807 ATH_MSG_WARNING ("Setting cluster_z = 0.0");
808 cluster_z = 0.0;
809 }
810 if ( isShort && std::abs(cluster_z)>shortBarrelStrawHalfLength+30 ) {
811 double d = cluster_z<0 ? cluster_z+shortBarrelStrawHalfLength : cluster_z-shortBarrelStrawHalfLength;
812 ATH_MSG_WARNING ("Short barrel straw cluster is outside the active gas volume z = +- 153.375 mm by " << d << " mm.");
813 ATH_MSG_WARNING ("Setting cluster_z = 0.0");
814 cluster_z = 0.0;
815 }
816 if ( isEC && std::abs(cluster_z)>EndcapStrawHalfLength+30 ) {
817 double d = cluster_z<0 ? cluster_z+EndcapStrawHalfLength : cluster_z-EndcapStrawHalfLength;
818 ATH_MSG_WARNING ("End cap straw cluster is outside the active gas volume z = +- 177.150 mm by " << d << " mm.");
819 ATH_MSG_WARNING ("Setting cluster_z = 0.0");
820 cluster_z = 0.0;
821 }
822 return cluster_z;
823}

◆ setLevel()

void AthMessaging::setLevel ( MSG::Level lvl)
inherited

Change the current logging level.

Use this rather than msg().setLevel() for proper operation with MT.

Definition at line 28 of file AthMessaging.cxx.

29{
30 m_lvl = lvl;
31}

Member Data Documentation

◆ ATLAS_THREAD_SAFE

std::atomic_flag m_initialized AthMessaging::ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
mutableprivateinherited

Messaging initialized (initMessaging)

Definition at line 141 of file AthMessaging.h.

◆ m_alreadywarnedagainstpdg0

bool TRTProcessingOfStraw::m_alreadywarnedagainstpdg0
private

Definition at line 232 of file TRTProcessingOfStraw.h.

◆ m_attenuationLength

double TRTProcessingOfStraw::m_attenuationLength = 0.0
private

Definition at line 132 of file TRTProcessingOfStraw.h.

◆ m_clusterlist

std::vector<cluster> TRTProcessingOfStraw::m_clusterlist
private

Definition at line 166 of file TRTProcessingOfStraw.h.

◆ m_depositList

std::vector<TRTElectronicsProcessing::Deposit> TRTProcessingOfStraw::m_depositList
private

Definition at line 167 of file TRTProcessingOfStraw.h.

◆ m_detmgr

const InDetDD::TRT_DetectorManager* TRTProcessingOfStraw::m_detmgr
private

Definition at line 122 of file TRTProcessingOfStraw.h.

◆ m_drifttimes

std::vector<double> TRTProcessingOfStraw::m_drifttimes
private

Definition at line 228 of file TRTProcessingOfStraw.h.

◆ m_expattenuation

std::vector<double> TRTProcessingOfStraw::m_expattenuation
private

Definition at line 229 of file TRTProcessingOfStraw.h.

◆ m_id_helper

const TRT_ID* TRTProcessingOfStraw::m_id_helper
protected

Definition at line 243 of file TRTProcessingOfStraw.h.

◆ m_imsg

std::atomic<IMessageSvc*> AthMessaging::m_imsg { nullptr }
mutableprivateinherited

MessageSvc pointer.

Definition at line 135 of file AthMessaging.h.

135{ nullptr };

◆ m_innerRadiusOfStraw

double TRTProcessingOfStraw::m_innerRadiusOfStraw = 0.0
private

Definition at line 141 of file TRTProcessingOfStraw.h.

◆ m_lvl

std::atomic<MSG::Level> AthMessaging::m_lvl { MSG::NIL }
mutableprivateinherited

Current logging level.

Definition at line 138 of file AthMessaging.h.

138{ MSG::NIL };

◆ m_maxCrossingTime

double TRTProcessingOfStraw::m_maxCrossingTime = 0.0
private

Definition at line 137 of file TRTProcessingOfStraw.h.

◆ m_maxelectrons

unsigned int TRTProcessingOfStraw::m_maxelectrons = 0U
private

Definition at line 230 of file TRTProcessingOfStraw.h.

◆ m_minCrossingTime

double TRTProcessingOfStraw::m_minCrossingTime = 0.0
private

Definition at line 138 of file TRTProcessingOfStraw.h.

◆ m_msg_tls

boost::thread_specific_ptr<MsgStream> AthMessaging::m_msg_tls
mutableprivateinherited

MsgStream instance (a std::cout like with print-out levels)

Definition at line 132 of file AthMessaging.h.

◆ m_nm

std::string AthMessaging::m_nm
privateinherited

Message source name.

Definition at line 129 of file AthMessaging.h.

◆ m_outerRadiusOfWire

double TRTProcessingOfStraw::m_outerRadiusOfWire = 0.0
private

Definition at line 142 of file TRTProcessingOfStraw.h.

◆ m_pDigConditions

TRTDigCondBase* TRTProcessingOfStraw::m_pDigConditions
private

Definition at line 150 of file TRTProcessingOfStraw.h.

◆ m_pElectronicsProcessing

TRTElectronicsProcessing* TRTProcessingOfStraw::m_pElectronicsProcessing
private

Definition at line 148 of file TRTProcessingOfStraw.h.

◆ m_pNoise

TRTNoise* TRTProcessingOfStraw::m_pNoise
private

Definition at line 149 of file TRTProcessingOfStraw.h.

◆ m_pPAItoolAr

ITRT_PAITool* TRTProcessingOfStraw::m_pPAItoolAr
private

Definition at line 124 of file TRTProcessingOfStraw.h.

◆ m_pPAItoolKr

ITRT_PAITool* TRTProcessingOfStraw::m_pPAItoolKr
private

Definition at line 125 of file TRTProcessingOfStraw.h.

◆ m_pPAItoolXe

ITRT_PAITool* TRTProcessingOfStraw::m_pPAItoolXe
private

Definition at line 123 of file TRTProcessingOfStraw.h.

◆ m_pParticleTable

const HepPDT::ParticleDataTable* TRTProcessingOfStraw::m_pParticleTable
private

Definition at line 152 of file TRTProcessingOfStraw.h.

◆ m_pSimDriftTimeTool

ITRT_SimDriftTimeTool* TRTProcessingOfStraw::m_pSimDriftTimeTool
private

Definition at line 126 of file TRTProcessingOfStraw.h.

◆ m_pTimeCorrection

TRTTimeCorrection* TRTProcessingOfStraw::m_pTimeCorrection
private

Definition at line 147 of file TRTProcessingOfStraw.h.

◆ m_randBinomialAr

std::unique_ptr<CLHEP::RandBinomialFixedP> TRTProcessingOfStraw::m_randBinomialAr {}
private

Definition at line 240 of file TRTProcessingOfStraw.h.

240{};

◆ m_randBinomialKr

std::unique_ptr<CLHEP::RandBinomialFixedP> TRTProcessingOfStraw::m_randBinomialKr {}
private

Definition at line 239 of file TRTProcessingOfStraw.h.

239{};

◆ m_randBinomialXe

std::unique_ptr<CLHEP::RandBinomialFixedP> TRTProcessingOfStraw::m_randBinomialXe {}
private

Definition at line 238 of file TRTProcessingOfStraw.h.

238{};

◆ m_settings

const TRTDigSettings* TRTProcessingOfStraw::m_settings
private

Definition at line 121 of file TRTProcessingOfStraw.h.

◆ m_shiftOfZeroPoint

double TRTProcessingOfStraw::m_shiftOfZeroPoint = 0.0
private

Definition at line 139 of file TRTProcessingOfStraw.h.

◆ m_signalPropagationSpeed

double TRTProcessingOfStraw::m_signalPropagationSpeed = 0.0
private

Definition at line 131 of file TRTProcessingOfStraw.h.

◆ m_solenoidFieldStrength

double TRTProcessingOfStraw::m_solenoidFieldStrength = 0.0
private

Definition at line 144 of file TRTProcessingOfStraw.h.

◆ m_timeCorrection

bool TRTProcessingOfStraw::m_timeCorrection = false
private

Time to be corrected for flight and wire propagation delays false when beamType='cosmics'.

Definition at line 129 of file TRTProcessingOfStraw.h.

◆ m_useAttenuation

bool TRTProcessingOfStraw::m_useAttenuation = false
private

Definition at line 134 of file TRTProcessingOfStraw.h.

◆ m_useMagneticFieldMap

bool TRTProcessingOfStraw::m_useMagneticFieldMap = false
private

Definition at line 135 of file TRTProcessingOfStraw.h.


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