ATLAS Offline Software
TRTProcessingOfStraw.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "TRTProcessingOfStraw.h"
6 
7 #include "TRTDigit.h"
8 #include "TRTTimeCorrection.h"
10 #include "TRTNoise.h"
11 #include "TRTDigCondBase.h"
12 
14 #include "ITRT_SimDriftTimeTool.h"
15 #include "TRTDigSettings.h"
16 #include "TRTDigiHelper.h"
17 
18 //TRT detector information:
21 
22 //helpers for identifiers and hitids (only for debug methods):
23 #include "InDetIdentifier/TRT_ID.h"
25 
27 
28 // Units & Constants
29 #include "CLHEP/Units/SystemOfUnits.h"
30 #include "CLHEP/Units/PhysicalConstants.h"
31 
32 // Particle data table
33 #include "HepPDT/ParticleData.hh"
36 
37 // For the Athena-based random numbers.
38 #include "CLHEP/Random/RandPoisson.h" //randpoissonq? (fixme)
39 #include "CLHEP/Random/RandFlat.h"
40 #include "CLHEP/Random/RandBinomial.h"
41 #include "CLHEP/Random/RandExpZiggurat.h"
42 #include "CLHEP/Random/RandGaussZiggurat.h"
43 #include <cmath>
44 #include <cstdlib> //Always include this when including cmath!
45 
46 
47 //________________________________________________________________________________
49  const InDetDD::TRT_DetectorManager* detmgr,
50  ITRT_PAITool* paitoolXe,
51  ITRT_SimDriftTimeTool* simdrifttool,
53  TRTNoise * noise,
54  TRTDigCondBase* digcond,
55  const HepPDT::ParticleDataTable* pdt,
56  const TRT_ID* trt_id,
57  ITRT_PAITool* paitoolAr,
58  ITRT_PAITool* paitoolKr,
59  const ITRT_CalDbTool* calDbTool)
60 
61 : AthMessaging("TRTProcessingOfStraw"),
62  m_settings(digset),
63  m_detmgr(detmgr),
64  m_pPAItoolXe(paitoolXe),
65  m_pPAItoolAr(paitoolAr),
66  m_pPAItoolKr(paitoolKr),
67  m_pSimDriftTimeTool(simdrifttool),
68 // m_time_y_eq_zero(0.0),
69 // m_ComTime(NULL),
70  m_pTimeCorrection(nullptr),
71  m_pElectronicsProcessing(ep),
72  m_pNoise(noise),
73  m_pDigConditions(digcond),
74  m_pParticleTable(pdt),
75  m_alreadywarnedagainstpdg0(false),
76  m_id_helper(trt_id)
77 
78 {
79  Initialize(calDbTool);
80 }
81 
82 //________________________________________________________________________________
84 {
85  delete m_pTimeCorrection;
86 }
87 
88 //________________________________________________________________________________
90 {
91 
98  m_timeCorrection = m_settings->timeCorrection(); // false for beamType='cosmics'
100 
101  m_maxelectrons = 100; // 100 gives good Gaussian approximation
102 
103  if (m_pPAItoolXe==nullptr) {
104  ATH_MSG_FATAL ( "TRT_PAITool for Xenon not defined! no point in continuing!" );
105  }
106  if (m_pPAItoolKr==nullptr) {
107  ATH_MSG_ERROR ( "TRT_PAITool for Krypton is not defined!!! Xenon TRT_PAITool will be used for Krypton straws!" );
109  }
110  if (m_pPAItoolAr==nullptr) {
111  ATH_MSG_ERROR ( "TRT_PAITool for Argon is not defined!!! Xenon TRT_PAITool will be used for Argon straws!" );
113  }
114 
115  ATH_MSG_INFO ( "Xe barrel drift-time at r = 2 mm is " << m_pSimDriftTimeTool->getAverageDriftTime(2.0, 0.002*0.002, 0) << " ns." );
116  ATH_MSG_INFO ( "Kr barrel drift-time at r = 2 mm is " << m_pSimDriftTimeTool->getAverageDriftTime(2.0, 0.002*0.002, 1) << " ns." );
117  ATH_MSG_INFO ( "Ar barrel drift-time at r = 2 mm is " << m_pSimDriftTimeTool->getAverageDriftTime(2.0, 0.002*0.002, 2) << " ns." );
118 
120 
121  const double intervalBetweenCrossings(m_settings->timeInterval() / 3.);
122  m_minCrossingTime = - (intervalBetweenCrossings * 2. + 1.*CLHEP::ns);
123  m_maxCrossingTime = intervalBetweenCrossings * 3. + 1.*CLHEP::ns;
124  m_shiftOfZeroPoint = static_cast<double>( m_settings->numberOfCrossingsBeforeMain() ) * intervalBetweenCrossings;
125 
126  // Tabulate exp(-dist/m_attenuationLength) as a function of dist = time*m_signalPropagationSpeed [0.0 mm, 1500 mm)
127  // otherwise we are doing an exp() for every cluster! > 99.9% of output digits are the same, saves 13% CPU time.
128  m_expattenuation.reserve(150);
129  for (unsigned int k=0; k<150; k++) {
130  double dist = 10.0*(k+0.5); // [5mm, 1415mm] max 5 mm error (sigma = 3 mm)
131  m_expattenuation.push_back(exp(-dist/m_attenuationLength));
132  }
133 
134  //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
135  //local y-direction is parallel to the global z-direction. As a sanity check against future code developments we will test this
136  //assumption on one straw from each endcap layer.
137 
138  if (m_solenoidFieldStrength!=0.0)
139  {
141  for (unsigned int iwheel = 0; iwheel < num->getNEndcapWheels(); ++iwheel)
142  {
143  for (unsigned int iside = 0; iside < 2; ++iside)
144  { //positive and negative endcap
145  for (unsigned int ilayer = 0; ilayer < num->getNEndcapLayers(iwheel); ++ilayer)
146  {
147  const InDetDD::TRT_EndcapElement * ec_element
148  = m_detmgr->getEndcapElement(iside,//positive or negative endcap
149  iwheel,//wheelIndex,
150  ilayer,//strawLayerIndex,
151  0);//phiIndex
152  //Local straw center and local straw point one unit along x:
153  if (!ec_element)
154  {
155  ATH_MSG_VERBOSE ( "Failed to retrieve endcap element for (iside,iwheel,ilayer)=("
156  << iside<<", "<<iwheel<<", "<<ilayer<<")." );
157  continue;
158  }
159  Amg::Vector3D strawcenter(0.0,0.0,0.0);
160  Amg::Vector3D strawx(1.0,0.0,0.0);
161  //Transform to global coordinate (use first straw in element):
162  strawcenter = ec_element->strawTransform(0) * strawcenter;
163  strawx = ec_element->strawTransform(0) * strawx;
164  const Amg::Vector3D v(strawx-strawcenter);
165  const double zcoordfrac((v.z()>0?v.z():-v.z())/v.mag());
166  if (zcoordfrac<0.98 || zcoordfrac > 1.02)
167  {
168  ATH_MSG_WARNING ( "Found endcap straw where the assumption that local x-direction"
169  <<" is parallel to global z-direction is NOT valid."
170  <<" Drift times will be somewhat off." );
171  }
172  }
173  }
174  }
175 
176  //check local barrel coordinates at four positions.
177  for (unsigned int phi_it = 0; phi_it < 32; phi_it++)
178  {
179  const InDetDD::TRT_BarrelElement * bar_element = m_detmgr->getBarrelElement(1,1,phi_it,1);
180 
181  Amg::Vector3D strawcenter(0.0,0.0,0.0);
182  Amg::Vector3D straw(cos((double)phi_it*2*M_PI/32.),sin((double)phi_it*2*M_PI/32.),0.0);
183  strawcenter = bar_element->strawTransform(0) * strawcenter;
184  straw = bar_element->strawTransform(0) * straw;
185  const Amg::Vector3D v(straw-strawcenter);
186  const double coordfrac(atan2(v.x(),v.y()));
187  if (coordfrac>0.2 || coordfrac < -0.2)
188  {
189  ATH_MSG_WARNING ( "Found barrel straw where the assumption that local y-direction"
190  <<" is along the straw is NOT valid."
191  <<" Drift times will be somewhat off." );
192  }
193  }
194  }
195 
196  m_randBinomialXe = std::make_unique<CLHEP::RandBinomialFixedP>(nullptr, 1, m_settings->smearingFactor(0), m_maxelectrons);
197  m_randBinomialKr = std::make_unique<CLHEP::RandBinomialFixedP>(nullptr, 1, m_settings->smearingFactor(1), m_maxelectrons);
198  m_randBinomialAr = std::make_unique<CLHEP::RandBinomialFixedP>(nullptr, 1, m_settings->smearingFactor(2), m_maxelectrons);
199 
200  ATH_MSG_VERBOSE ( "Initialization done" );
201 }
202 
203 //________________________________________________________________________________
204 void TRTProcessingOfStraw::addClustersFromStep ( const double& scaledKineticEnergy, const double& particleCharge,
205  const double& timeOfHit,
206  const double& prex, const double& prey, const double& prez,
207  const double& postx, const double& posty, const double& postz,
208  std::vector<cluster>& clusterlist, int strawGasType,
209  CLHEP::HepRandomEngine* rndmEngine,
210  CLHEP::HepRandomEngine* paiRndmEngine)
211 {
212 
213  // Choose the appropriate ITRT_PAITool for this straw
214  ITRT_PAITool* activePAITool;
215  if (strawGasType==0) { activePAITool = m_pPAItoolXe; }
216  else if (strawGasType==1) { activePAITool = m_pPAItoolKr; }
217  else if (strawGasType==2) { activePAITool = m_pPAItoolAr; }
218  else { activePAITool = m_pPAItoolXe; } // should never happen
219 
220  //Differences and steplength:
221  const double deltaX(postx - prex);
222  const double deltaY(posty - prey);
223  const double deltaZ(postz - prez);
224  const double stepLength(sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ));
225 
226  const double meanFreePath(activePAITool->GetMeanFreePath( scaledKineticEnergy, particleCharge*particleCharge ));
227 
228  //How many clusters did we actually create:
229  const unsigned int numberOfClusters(CLHEP::RandPoisson::shoot(rndmEngine,stepLength / meanFreePath));
230  //fixme: use RandPoissionQ?
231 
232  //Position each of those randomly along the step, and use PAI to get their energies:
233  for (unsigned int iclus(0); iclus<numberOfClusters; ++iclus)
234  {
235  //How far along the step did the cluster get produced:
236  const double lambda(CLHEP::RandFlat::shoot(rndmEngine));
237 
238  //Append cluster (the energy is given by the PAI model):
239  double clusE(activePAITool->GetEnergyTransfer(scaledKineticEnergy, paiRndmEngine));
240  clusterlist.emplace_back(clusE, timeOfHit,
241  prex + lambda * deltaX,
242  prey + lambda * deltaY,
243  prez + lambda * deltaZ);
244  }
245 
246 
247 }
248 
249 //________________________________________________________________________________
253  TRTDigit& outdigit,
254  bool & alreadyPrintedPDGcodeWarning,
255  double cosmicEventPhase, // const ComTime* m_ComTime,
256  int strawGasType,
257  bool emulationArflag,
258  bool emulationKrflag,
259  CLHEP::HepRandomEngine* rndmEngine,
260  CLHEP::HepRandomEngine* elecProcRndmEngine,
261  CLHEP::HepRandomEngine* elecNoiseRndmEngine,
262  CLHEP::HepRandomEngine* paiRndmEngine)
263 {
264 
266  // We need the straw id several times in the following //
268  const int hitID((*i)->GetHitID());
269  unsigned int region(TRTDigiHelper::getRegion(hitID));
270  const bool isBarrel(region<3 );
271  //const bool isEC (!isBarrel);
272  //const bool isShort (region==1);
273  //const bool isLong (region==2);
274  const bool isECA (region==3);
275  const bool isECB (region==4);
276 
278  //======================================================//
280  // First step is to loop over the simhits in this straw //
281  // and produce a list of primary ionisation clusters. //
282  // Each cluster needs the following information: //
283  // //
284  // * The total energy of the cluster. //
285  // * Its location in local straw (x,y,z) coordinates. //
286  // * The time the cluster was created. //
287  // //
289  //======================================================//
291  // TimeShift is the same for all the simhits in the straw.
292  const double timeShift(m_pTimeCorrection->TimeShift(hitID)); // rename hitID to strawID
293 
294  m_clusterlist.clear();
295 
296  //For magnetic field evaluation
297  Amg::Vector3D TRThitGlobalPos(0.0,0.0,0.0);
298 
299  //Now we loop over all the simhits
300  for (hitCollConstIter hit_iter= i; hit_iter != e; ++hit_iter)
301  {
302  //Get the hit:
303  const TimedHitPtr<TRTUncompressedHit> *theHit = &(*hit_iter);
304 
305  TRThitGlobalPos = getGlobalPosition(hitID, theHit);
306 
307  //Figure out the global time of the hit (all clusters from the hit
308  //will get same timing).
309 
310  double timeOfHit(0.0); // remains zero if timeCorrection is false (beamType='cosmics')
311  if (m_timeCorrection) {
312  const double globalHitTime(hitTime(*theHit));
313  const double globalTime = static_cast<double>((*theHit)->GetGlobalTime());
314  const double bunchCrossingTime(globalHitTime - globalTime);
315  if ( (bunchCrossingTime < m_minCrossingTime) || (bunchCrossingTime > m_maxCrossingTime) ) continue;
316  timeOfHit = m_shiftOfZeroPoint + globalHitTime - timeShift; //is this shiftofzeropoint correct pileup-wise?? [fixme]
317  }
318 
319  //if (timeOfHit>125.0) continue; // Will give 3% speed up (but changes seeds!). Needs careful thought though.
320 
321  //What kind of particle are we dealing with?
322  const int particleEncoding((*theHit)->GetParticleEncoding());
323 
324  //Safeguard against pdgcode 0.
325  if (particleEncoding == 0)
326  {
327  //According to Andrea this is usually nuclear fragments from
328  //hadronic interactions. They therefore ought to be allowed to
329  //contribute, but we ignore them for now - until it can be studied
330  //that it is indeed safe to stop doing so
333  ATH_MSG_WARNING ( "Ignoring sim. particle with pdgcode 0. This warning is only shown once per job" );
334  }
335  continue;
336  }
337 
338  // If it is a photon we assume it was absorbed entirely at the point of interaction.
339  // we simply deposit the entire energy into the last point of the sim. step.
340  if ( MC::isPhoton(particleEncoding) ) {
341 
342  const double energyDeposit = (*theHit)->GetEnergyDeposit(); // keV (see comment below)
343  // Apply radiator efficiency "fudge factor" to ignore some TR photons (assuming they are over produced in the sim. step.
344  // The fraction removed is based on tuning pHT for electrons to data, after tuning pHT for muons (which do not produce TR).
345  // The efficiency is different for Xe, Kr and Ar. Avoid fudging non-TR photons (TR is < 30 keV).
346  // Also: for |eta|<0.5 apply parabolic scale; see "Parabolic Fudge" https://indico.cern.ch/event/304066/
347 
348  if ( energyDeposit<30.0 ) {
349 
350  // Improved Argon Emulation tuning October 2018 by Hassane Hamdaoui https://cds.cern.ch/record/2643784
351  // Previously 0.15, 0.28, 0.28
352  double ArEmulationScaling_BA = 0.05;
353  double ArEmulationScaling_ECA = 0.20;
354  double ArEmulationScaling_ECB = 0.20;
355 
356  // ROUGH GUESSES RIGHT NOW
357  double KrEmulationScaling_BA = 0.20;
358  double KrEmulationScaling_ECA = 0.39;
359  double KrEmulationScaling_ECB = 0.39;
360 
361  if (isBarrel) { // Barrel
362  double trEfficiencyBarrel = m_settings->trEfficiencyBarrel(strawGasType);
363  double hitx = TRThitGlobalPos[0];
364  double hity = TRThitGlobalPos[1];
365  double hitz = TRThitGlobalPos[2];
366  double hitEta = std::abs(log(tan(0.5*atan2(sqrt(hitx*hitx+hity*hity),hitz))));
367  if ( hitEta < 0.5 ) { trEfficiencyBarrel *= ( 0.833333+0.6666667*hitEta*hitEta ); }
368  // scale down the TR efficiency if we are emulating
369  if ( strawGasType == 0 && emulationArflag ) { trEfficiencyBarrel *= ArEmulationScaling_BA; }
370  if ( strawGasType == 0 && emulationKrflag ) { trEfficiencyBarrel *= KrEmulationScaling_BA; }
371  if ( CLHEP::RandFlat::shoot(rndmEngine) > trEfficiencyBarrel ) continue; // Skip this photon
372  } // close if barrel
373  else { // Endcap - no eta dependence here.
374  if (isECA) {
375  double trEfficiencyEndCapA = m_settings->trEfficiencyEndCapA(strawGasType);
376  // scale down the TR efficiency if we are emulating
377  if ( strawGasType == 0 && emulationArflag ) { trEfficiencyEndCapA *= ArEmulationScaling_ECA; }
378  if ( strawGasType == 0 && emulationKrflag ) { trEfficiencyEndCapA *= KrEmulationScaling_ECA; }
379  if ( CLHEP::RandFlat::shoot(rndmEngine) > trEfficiencyEndCapA ) continue; // Skip this photon
380  }
381  if (isECB) {
382  double trEfficiencyEndCapB = m_settings->trEfficiencyEndCapB(strawGasType);
383  // scale down the TR efficiency if we are emulating
384  if ( strawGasType == 0 && emulationArflag ) { trEfficiencyEndCapB *= ArEmulationScaling_ECB; }
385  if ( strawGasType == 0 && emulationKrflag ) { trEfficiencyEndCapB *= KrEmulationScaling_ECB; }
386  if ( CLHEP::RandFlat::shoot(rndmEngine) > trEfficiencyEndCapB ) continue; // Skip this photon
387  }
388  } // close else (end caps)
389  } // energyDeposit < 30.0
390 
391  // Append this (usually highly energetic) cluster to the list:
392  m_clusterlist.emplace_back( energyDeposit*CLHEP::keV, timeOfHit, (*theHit)->GetPostStepX(), (*theHit)->GetPostStepY(), (*theHit)->GetPostStepZ() );
393 
394  // Regarding the CLHEP::keV above: In TRT_G4_SD we converting the hits to keV,
395  // so here we convert them back to CLHEP units by multiplying by CLHEP::keV.
396  }
397  else if ( MC::isMonopole(particleEncoding)
398  || ( MC::isGenericMultichargedParticle(particleEncoding) && MC::charge(particleEncoding) > 10. )
399  ) {
400  //Special treatment of magnetic monopoles && highly charged Qballs (charge > 10)
401  m_clusterlist.emplace_back( (*theHit)->GetEnergyDeposit()*CLHEP::keV, timeOfHit, (*theHit)->GetPostStepX(), (*theHit)->GetPostStepY(), (*theHit)->GetPostStepZ() );
402  }
403  else { // It's not a photon, monopole or Qball with charge > 10, so we proceed with regular ionization using the PAI model
404 
405  // Lookup mass and charge from the PDG info in CLHEP HepPDT:
406  const HepPDT::ParticleData *particle(m_pParticleTable->particle(HepPDT::ParticleID(abs(particleEncoding))));
407  double particleCharge(0.);
408  double particleMass(0.);
409 
410  if (particle) {
411  particleCharge = particle->charge();
412  particleMass = particle->mass().value();
413  // Override ParticleData charge value for Qballs and similar exotic multi-charged particles
414  if (MC::isGenericMultichargedParticle(particleEncoding)) {
415  particleCharge =MC::charge(particleEncoding);
416  }
417  }
418  else {
419  // TODO Should we handle charged Geantinos gracefully here?
420  if (!MC::isNucleus(particleEncoding)) {
421  ATH_MSG_WARNING ( "Data for sim. particle with pdgcode "<<particleEncoding
422  <<" is not a nucleus and could not be retrieved from PartPropSvc. Assuming mass and charge as pion. Please investigate." );
423  particleCharge = 1.;
425  }
426  else {
427  particleCharge = MC::charge(particleEncoding);
428 
429  const int A(static_cast<int>(MC::baryonNumber(particleEncoding)));
430  const int Z(static_cast<int>(std::abs(MC::numberOfProtons(particleEncoding))));
431  static constexpr double Mp(ParticleConstants::protonMassInMeV);
432  static constexpr double Mn(ParticleConstants::neutronMassInMeV);
433  particleMass = std::abs( Z*Mp+(A-Z)*Mn );
434 
435  if (!alreadyPrintedPDGcodeWarning) {
436  ATH_MSG_WARNING ( "Data for sim. particle with pdgcode "<<particleEncoding
437  <<" could not be retrieved from PartPropSvc (unexpected ion)."
438  <<" Please Investigate the PDGTABLE.MeV file."
439  <<" Calculating mass and charge from pdg code."
440  <<" The result is: Charge = "<<particleCharge<<" Mass = "<<particleMass<<"MeV" );
441  alreadyPrintedPDGcodeWarning = true;
442  }
443  }
444  }
445  // Abort if uncharged particle.
446  if (!particleCharge) { continue; }
447  // Abort if weird massless charged particle.
448  if (!particleMass) {
449  ATH_MSG_WARNING ( "Ignoring ionization from particle with pdg code "<<particleEncoding
450  <<" since it appears to be a massless charged particle. Please investigate." );
451  continue;
452  }
453 
454  //We are now in the most likely case: A normal ionizing
455  //particle. Using the PAI model we are going to distribute
456  //ionization clusters along the step taken by the sim particle.
457 
458  const double scaledKineticEnergy( static_cast<double>((*theHit)->GetKineticEnergy()) * ( CLHEP::proton_mass_c2 / particleMass ));
459 
460  addClustersFromStep ( scaledKineticEnergy, particleCharge, timeOfHit,
461  (*theHit)->GetPreStepX(),(*theHit)->GetPreStepY(),(*theHit)->GetPreStepZ(),
462  (*theHit)->GetPostStepX(),(*theHit)->GetPostStepY(),(*theHit)->GetPostStepZ(),
463  m_clusterlist, strawGasType, rndmEngine, paiRndmEngine);
464 
465  }
466  }//end of hit loop
467 
469  //======================================================//
471  // Second step is, using the cluster list along with //
472  // gas and wire properties, to create a list of energy //
473  // deposits (i.e. potential fluctuations) reaching the //
474  // frontend electronics. Each deposit needs: //
475  // //
476  // * The energy of the deposit. //
477  // * The time it arrives at the FE electronics //
478  // //
480  //======================================================//
482 
483  m_depositList.clear();
484 
485  ClustersToDeposits(fieldCache, hitID, m_clusterlist, m_depositList, TRThitGlobalPos, cosmicEventPhase, strawGasType, rndmEngine );
486 
487 
489  //======================================================//
491  // The third and final step is to simulate how the FE //
492  // turns the results into an output digit. This //
493  // includes the shaping/amplification and subsequent //
494  // discrimination as well as addition of noise. //
495  // //
497  //======================================================//
499 
500  //If no deposits, and no electronics noise we might as well stop here:
501  if ( m_depositList.empty() && !m_pNoise )
502  {
503  outdigit = TRTDigit(hitID, 0);
504  return;
505  }
506 
507  //Get straw conditions data:
508  double lowthreshold, noiseamplitude;
509  if (m_settings->noiseInSimhits()) {
510  m_pDigConditions->getStrawData( hitID, lowthreshold, noiseamplitude );
511  } else {
512  lowthreshold = isBarrel ? m_settings->lowThresholdBar(strawGasType) : m_settings->lowThresholdEC(strawGasType);
513  noiseamplitude = 0.0;
514  }
515 
516  //Electronics processing:
517  m_pElectronicsProcessing->ProcessDeposits( m_depositList, hitID, outdigit, lowthreshold, noiseamplitude, strawGasType, elecProcRndmEngine, elecNoiseRndmEngine );
518 }
519 
520 //________________________________________________________________________________
522  const std::vector<cluster>& clusters,
523  std::vector<TRTElectronicsProcessing::Deposit>& deposits,
524  Amg::Vector3D TRThitGlobalPos,
525  double cosmicEventPhase, // was const ComTime* m_ComTime,
526  int strawGasType,
527  CLHEP::HepRandomEngine* rndmEngine)
528 {
529 
530  //
531  // Some initial work before looping over the cluster
532  //
533 
534  deposits.clear();
535 
536  unsigned int region(TRTDigiHelper::getRegion(hitID));
537  const bool isBarrel(region<3 );
538  const bool isEC (!isBarrel);
539  const bool isShort (region==1);
540  const bool isLong (region==2);
541  //const bool isECA (region==3);
542  //const bool isECB (region==4);
543 
544  CLHEP::RandBinomialFixedP *randBinomial{};
545  if (strawGasType == 0) { randBinomial = m_randBinomialXe.get(); }
546  else if (strawGasType == 1) { randBinomial = m_randBinomialKr.get(); }
547  else if (strawGasType == 2) { randBinomial = m_randBinomialAr.get(); }
548  else { randBinomial = m_randBinomialXe.get(); } // should never happen
549 
550  double ionisationPotential = m_settings->ionisationPotential(strawGasType);
551  double smearingFactor = m_settings->smearingFactor(strawGasType);
552 
553  std::vector<cluster>::const_iterator currentClusterIter(clusters.begin());
554  const std::vector<cluster>::const_iterator endOfClusterList(clusters.end());
555 
556  // if (m_settings->doCosmicTimingPit()) {
557  // if (m_ComTime) { m_time_y_eq_zero = m_ComTime->getTime(); }
558  // else { ATH_MSG_WARNING("Configured to use ComTime tool, but did not find tool. All hits will get the same t0"); }
559  // }
560 
561  // The average drift time is affected by the magnetic field which is not uniform so we need to use the
562  // detailed magnetic field map to obtain an effective field for this straw (used in SimDriftTimeTool).
563  // This systematically affects O(ns) drift times in the end cap, but has a very small effect in the barrel.
564  Amg::Vector3D globalPosition;
565  Amg::Vector3D mField;
566  double map_x2(0.),map_y2(0.),map_z2(0.);
567  double effectiveField2(0.); // effective field squared.
568 
569  // Magnetic field is the same for all clusters in the straw so this can be called before the cluster loop.
571  {
572  globalPosition[0]=TRThitGlobalPos[0]*CLHEP::mm;
573  globalPosition[1]=TRThitGlobalPos[1]*CLHEP::mm;
574  globalPosition[2]=TRThitGlobalPos[2]*CLHEP::mm;
575 
576  // MT Field cache is stored in cache
577  fieldCache.getField (globalPosition.data(), mField.data());
578 
579  map_x2 = mField.x()*mField.x(); // would be zero for a uniform field
580  map_y2 = mField.y()*mField.y(); // would be zero for a uniform field
581  map_z2 = mField.z()*mField.z(); // would be m_solenoidfieldstrength^2 for uniform field
582  }
583 
584  // Now we are ready to loop over clusters and form timed energy deposits at the wire:
585  //
586  // 1. First determine the number of surviving drift electrons and the energy of their deposits.
587  // 2. Then determine the timing of these deposits.
588 
589  // Notes
590  //
591  // 1) It turns out that the total energy deposited (Ed) is, on average, equal to the cluster energy (Ec):
592  // <Ed> = m_ionisationPotential/m_smearingFactor * Ec/m_ionisationPotential * m_smearingFactor = Ec.
593  // Actually it exceeds this *slightly* due to the +1 electron in the calculation of nprimaryelectrons below.
594  // The energy processing below therefore exists only to model the energy *fluctuations*.
595  //
596  // 2) Gaussian approximation (for photons, HIPs etc):
597  // For large Ec (actually nprimaryelectrons > 99) a much faster Gaussian shoot replaces
598  // the Binomial and many exponential shoots. The Gaussian pdf has a mean of Ec and variance
599  // given by sigma^2 = Ec*ionisationPotential*(2-smearingFactor)/smearingFactor. That expression
600  // comes from the sum of the variances from the Binomial and Exponential. In this scheme it is
601  // sufficient (for diffusion) to divided the energy equally amongst 100 (maxelectrons) electrons.
602 
603  // straw radius
604  const double wire_r2 = m_outerRadiusOfWire*m_outerRadiusOfWire;
605  const double straw_r2 = m_innerRadiusOfStraw*m_innerRadiusOfStraw;
606 
607  // Cluster loop
608  for (;currentClusterIter!=endOfClusterList;++currentClusterIter)
609  {
610  // Get the cluster radius and energy.
611  const double cluster_x(currentClusterIter->xpos);
612  const double cluster_y(currentClusterIter->ypos);
613  const double cluster_z(this->setClusterZ(currentClusterIter->zpos, isLong, isShort, isEC));
614  const double cluster_x2(cluster_x*cluster_x);
615  const double cluster_y2(cluster_y*cluster_y);
616  double cluster_r2(cluster_x2+cluster_y2);
617 
618  // These may never occur, but could be very problematic for getAverageDriftTime(), so check and correct this now.
619  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!
620  if (cluster_r2>straw_r2) cluster_r2=straw_r2; // Should never occur
621 
622  const double cluster_r(std::sqrt(cluster_r2)); // cluster radius
623  const double cluster_E(currentClusterIter->energy); // cluster energy
624  const unsigned int nprimaryelectrons( static_cast<unsigned int>( cluster_E / ionisationPotential + 1.0 ) );
625 
626  // Determine the number of surviving electrons and their energy sum.
627  // If nprimaryelectrons > 100 then a Gaussian approximation is good (and much quicker)
628 
629  double depositEnergy(0.); // This will be the energy deposited at the wire.
630 
631  if (nprimaryelectrons<m_maxelectrons) // Use the detailed Binomial and Exponential treatment at this low energy.
632  {
633  unsigned int nsurvivingprimaryelectrons = static_cast<unsigned int>(randBinomial->fire(rndmEngine,nprimaryelectrons) + 0.5);
634  if (nsurvivingprimaryelectrons==0) continue; // no electrons survived; move on to the next cluster.
635  const double meanElectronEnergy(ionisationPotential / smearingFactor);
636  for (unsigned int ielec(0); ielec<nsurvivingprimaryelectrons; ++ielec) {
637  depositEnergy += CLHEP::RandExpZiggurat::shoot(rndmEngine, meanElectronEnergy);
638  }
639  }
640  else // Use a Gaussian approximation
641  {
642  const double fluctSigma(sqrt(cluster_E * ionisationPotential * (2 - smearingFactor) / smearingFactor));
643  do {
644  depositEnergy = CLHEP::RandGaussZiggurat::shoot(rndmEngine, cluster_E, fluctSigma);
645  } while(depositEnergy<0.0); // very rare.
646  }
647 
648  // Now we have the depositEnergy, we need to work out the timing and attenuation
649 
650  // First calculate the "effective field" (it's never negative):
651  // Electron drift time is prolonged by the magnetic field according to an "effective field".
652  // For the endcap, the effective field is dependent on the relative (x,y) position of the cluster.
653  // It is assumed here (checked in initialize) that the local straw x-direction is parallel with
654  // the solenoid z-direction. After Garfield simulations and long thought it was found that only
655  // field perpendicular to the electron drift is of importance.
656 
657  if (!isBarrel) // Endcap
658  {
659  if (m_useMagneticFieldMap) { // Using magnetic field map
660  effectiveField2 = map_z2*cluster_y2/cluster_r2 + map_x2 + map_y2;
661  }
662  else { // Not using magnetic field map (you really should not do this!):
663  effectiveField2 = m_solenoidFieldStrength*m_solenoidFieldStrength * cluster_y2 / cluster_r2;
664  }
665  }
666  else // Barrel
667  {
668  if (m_useMagneticFieldMap) { // Using magnetic field map (here bug #91830 is corrected)
669  effectiveField2 = map_z2 + (map_x2+map_y2)*cluster_y2/cluster_r2;
670  }
671  else { // Without the mag field map (very small change in digi output)
673  }
674  }
675 
676  // If there is no field we might need to reset effectiveField2 to zero.
677  if (m_solenoidFieldStrength == 0. ) effectiveField2=0.;
678 
679  // Now we need the deposit time which is the sum of three components:
680  // 1. Time of the hit(cluster): clusterTime.
681  // 2. Drift times: either commondrifttime, or diffused m_drifttimes
682  // 3. Wire propagation times: timedirect and timereflect.
683 
684  // get the time of the hit(cluster)
685  double clusterTime(currentClusterIter->time);
686 
687  if ( m_settings->doCosmicTimingPit() )
688  { // make (x,y) dependent? i.e: + f(x,y).
689  // clusterTime = clusterTime - m_time_y_eq_zero + m_settings->jitterTimeOffset()*( CLHEP::RandFlat::shoot(rndmEngine) );
690  clusterTime = clusterTime + cosmicEventPhase + m_settings->jitterTimeOffset()*( CLHEP::RandFlat::shoot(rndmEngine) );
691  // yes it is a '+' now. Ask Alex Alonso.
692  }
693 
694  // get the wire propagation times (for direct and reflected signals)
695  double timedirect(0.), timereflect(0.);
696  m_pTimeCorrection->PropagationTime( hitID, cluster_z, timedirect, timereflect );
697 
698  // While we have the propagation times, we can calculate the exponential attenuation factor
699  double expdirect(1.0), expreflect(1.0); // Initially set to "no attenuation".
700  if (m_useAttenuation)
701  {
702  //expdirect = exp( -timedirect *m_signalPropagationSpeed / m_attenuationLength);
703  //expreflect = exp( -timereflect*m_signalPropagationSpeed / m_attenuationLength);
704  // Tabulating exp(-dist/m_attenuationLength) with only 150 elements: index [0,149].
705  // > 99.9% of output digits are the same, saves 13% CPU time.
706  // Distances the signal propagate along the wire:
707  // * distdirect is rarely negative (<0.2%) by ~ mm. In such cases there is
708  // no attenuation, which is equivalent to distdirect=0 and so is good.
709  // * distreflect is always +ve and less than 1500, and so is good.
710  // The code is protected against out of bounds in anycase.
711  const double distdirect = timedirect *m_signalPropagationSpeed;
712  const double distreflect = timereflect*m_signalPropagationSpeed;
713  const unsigned int kdirect = static_cast<unsigned int>(distdirect/10);
714  const unsigned int kreflect = static_cast<unsigned int>(distreflect/10);
715  if (kdirect<150) expdirect = m_expattenuation[kdirect]; // otherwise there
716  if (kreflect<150) expreflect = m_expattenuation[kreflect]; // is no attenuation.
717  }
718 
719  // Finally, deposit the energy on the wire using the drift-time tool (diffusion is no longer available).
720  double commondrifttime = m_pSimDriftTimeTool->getAverageDriftTime(cluster_r,effectiveField2,strawGasType);
721  double dt = clusterTime + commondrifttime;
722  deposits.emplace_back(0.5*depositEnergy*expdirect, timedirect+dt);
723  deposits.emplace_back(0.5*depositEnergy*expreflect, timereflect+dt);
724 
725  } // end of cluster loop
726 
727  }
728 
729 //________________________________________________________________________________
731 
732  const int mask(0x0000001F);
733  int word_shift(5);
734  int trtID, ringID, moduleID, layerID, strawID;
735  int wheelID, planeID, sectorID;
736 
737  const InDetDD::TRT_BarrelElement *barrelElement;
738  const InDetDD::TRT_EndcapElement *endcapElement;
739 
740  if ( !(hitID & 0x00200000) ) { // barrel
741 
742  strawID = hitID & mask;
743  hitID >>= word_shift;
744  layerID = hitID & mask;
745  hitID >>= word_shift;
746  moduleID = hitID & mask;
747  hitID >>= word_shift;
748  ringID = hitID & mask;
749  trtID = hitID >> word_shift;
750 
751  barrelElement = m_detmgr->getBarrelElement(trtID, ringID, moduleID, layerID);
752 
753  if (barrelElement) {
754  const Amg::Vector3D v( (*theHit)->GetPreStepX(),(*theHit)->GetPreStepY(),(*theHit)->GetPreStepZ());
755  return barrelElement->strawTransform(strawID)*v;
756  }
757 
758  } else { // endcap
759 
760  strawID = hitID & mask;
761  hitID >>= word_shift;
762  planeID = hitID & mask;
763  hitID >>= word_shift;
764  sectorID = hitID & mask;
765  hitID >>= word_shift;
766  wheelID = hitID & mask;
767  trtID = hitID >> word_shift;
768 
769  // change trtID (which is 2/3 for endcaps) to use 0/1 in getEndcapElement
770  if (trtID == 3) trtID = 0;
771  else trtID = 1;
772 
773  endcapElement = m_detmgr->getEndcapElement(trtID, wheelID, planeID, sectorID);
774 
775  if ( endcapElement ) {
776  const Amg::Vector3D v( (*theHit)->GetPreStepX(),(*theHit)->GetPreStepY(),(*theHit)->GetPreStepZ());
777  return endcapElement->strawTransform(strawID)*v;
778  }
779 
780  }
781 
782  ATH_MSG_WARNING ( "Could not find global coordinate of a straw - drifttime calculation will be inaccurate" );
783  return {0.0,0.0,0.0};
784 
785 }
786 
787 
788 double TRTProcessingOfStraw::setClusterZ(double cluster_z_in, bool isLong, bool isShort, bool isEC) const {
789  double cluster_z(cluster_z_in);
790 
791  // 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.
792  // 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
793  // can go several mm outside these ranges; 30 mm is plenty allowance in the checks below.
794  const double longBarrelStrawHalfLength(349.315*CLHEP::mm);
795  const double shortBarrelStrawHalfLength(153.375*CLHEP::mm);
796  const double EndcapStrawHalfLength(177.150*CLHEP::mm);
797  if ( isLong && std::abs(cluster_z)>longBarrelStrawHalfLength+30 ) {
798  double d = cluster_z<0 ? cluster_z+longBarrelStrawHalfLength : cluster_z-longBarrelStrawHalfLength;
799  ATH_MSG_WARNING ("Long barrel straw cluster is outside the active gas volume z = +- 349.315 mm by " << d << " mm.");
800  ATH_MSG_WARNING ("Setting cluster_z = 0.0");
801  cluster_z = 0.0;
802  }
803  if ( isShort && std::abs(cluster_z)>shortBarrelStrawHalfLength+30 ) {
804  double d = cluster_z<0 ? cluster_z+shortBarrelStrawHalfLength : cluster_z-shortBarrelStrawHalfLength;
805  ATH_MSG_WARNING ("Short barrel straw cluster is outside the active gas volume z = +- 153.375 mm by " << d << " mm.");
806  ATH_MSG_WARNING ("Setting cluster_z = 0.0");
807  cluster_z = 0.0;
808  }
809  if ( isEC && std::abs(cluster_z)>EndcapStrawHalfLength+30 ) {
810  double d = cluster_z<0 ? cluster_z+EndcapStrawHalfLength : cluster_z-EndcapStrawHalfLength;
811  ATH_MSG_WARNING ("End cap straw cluster is outside the active gas volume z = +- 177.150 mm by " << d << " mm.");
812  ATH_MSG_WARNING ("Setting cluster_z = 0.0");
813  cluster_z = 0.0;
814  }
815  return cluster_z;
816 }
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
TRTProcessingOfStraw.h
ITRT_PAITool::GetMeanFreePath
virtual double GetMeanFreePath(double scaledKineticEnergy, double squaredCharge) const =0
GetMeanFreePath.
TRTProcessingOfStraw::m_pElectronicsProcessing
TRTElectronicsProcessing * m_pElectronicsProcessing
Definition: TRTProcessingOfStraw.h:144
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
Trk::ParticleSwitcher::particle
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:79
TRTDigSettings::doCosmicTimingPit
bool doCosmicTimingPit() const
Cosmics timing corresponding to pit setup?
TRTProcessingOfStraw::m_pDigConditions
TRTDigCondBase * m_pDigConditions
Definition: TRTProcessingOfStraw.h:146
InDetDD::TRT_BarrelElement
Definition: TRT_BarrelElement.h:43
TRT::Hit::straw
@ straw
Definition: HitInfo.h:82
isNucleus
bool isNucleus(const T &p)
PDG rule 16 Nuclear codes are given as 10-digit numbers ±10LZZZAAAI.
Definition: AtlasPID.h:697
python.SystemOfUnits.mm
float mm
Definition: SystemOfUnits.py:98
TRTDigSettings::lowThresholdEC
double lowThresholdEC(int strawGasType) const
TRTProcessingOfStraw::m_innerRadiusOfStraw
double m_innerRadiusOfStraw
Definition: TRTProcessingOfStraw.h:137
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
TRT_DetectorManager.h
TRTDigSettings::timeCorrection
bool timeCorrection() const
Query whether time is corrected for flight and wire propagation delays.
makeComparison.deltaY
int deltaY
Definition: makeComparison.py:44
baryonNumber
double baryonNumber(const T &p)
Definition: AtlasPID.h:763
TRTDigSettings.h
TRTDigSettings::useMagneticFieldMap
bool useMagneticFieldMap() const
TRTDigiHelper::getRegion
unsigned int getRegion(int hitID)
Definition: TRTDigiHelper.cxx:48
ITRT_PAITool
Definition: ITRT_PAITool.h:20
TRTProcessingOfStraw::m_detmgr
const InDetDD::TRT_DetectorManager * m_detmgr
Definition: TRTProcessingOfStraw.h:118
Monitored::Z
@ Z
Definition: HistogramFillerUtils.h:24
hist_file_dump.d
d
Definition: hist_file_dump.py:142
InDetDD::TRT_DetectorManager::getBarrelElement
const TRT_BarrelElement * getBarrelElement(unsigned int positive, unsigned int moduleIndex, unsigned int phiIndex, unsigned int strawLayerIndex) const
Access Barrel Elements:---------------—(Fast)-------------------------—.
Definition: TRT_DetectorManager.cxx:100
ITRT_PAITool::GetEnergyTransfer
virtual double GetEnergyTransfer(double scaledKineticEnergy, CLHEP::HepRandomEngine *rndmEngine) const =0
GetEnergyTransfer.
TRTProcessingOfStraw::m_signalPropagationSpeed
double m_signalPropagationSpeed
Definition: TRTProcessingOfStraw.h:127
TRTDigSettings::solenoidFieldStrength
double solenoidFieldStrength() const
Get solenoid field strength.
TRTDigCondBase::getStrawData
void getStrawData(const int &hitID, double &lowthreshold, double &noiseamplitude) const
Get straw data mixed condition is implemented function will return both Argon and Xenon straws (with ...
Definition: TRTDigCondBase.h:193
TRTProcessingOfStraw::m_pPAItoolKr
ITRT_PAITool * m_pPAItoolKr
Definition: TRTProcessingOfStraw.h:121
TRT_ID.h
This is an Identifier helper class for the TRT subdetector. This class is a factory for creating comp...
TRTProcessingOfStraw::Initialize
void Initialize(const ITRT_CalDbTool *)
Initialize.
Definition: TRTProcessingOfStraw.cxx:89
M_PI
#define M_PI
Definition: ActiveFraction.h:11
InDetDD::TRT_EndcapElement
Definition: TRT_EndcapElement.h:43
TRTTimeCorrection::PropagationTime
void PropagationTime(const int &strawID, const double &meanZ, double &propagationTime1, double &propagationTime2)
Calculates the time between the signal reaching the wire and when it reaches the electronics.
Definition: TRTTimeCorrection.cxx:287
TRTElectronicsProcessing
Electronics Processing.
Definition: TRTElectronicsProcessing.h:23
TRTProcessingOfStraw::TRTProcessingOfStraw
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.
Definition: TRTProcessingOfStraw.cxx:48
TRTProcessingOfStraw::~TRTProcessingOfStraw
~TRTProcessingOfStraw()
Destructor.
Definition: TRTProcessingOfStraw.cxx:83
TimedHitPtr< TRTUncompressedHit >
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
TRTProcessingOfStraw::m_id_helper
const TRT_ID * m_id_helper
Definition: TRTProcessingOfStraw.h:237
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
TRTProcessingOfStraw::m_randBinomialXe
std::unique_ptr< CLHEP::RandBinomialFixedP > m_randBinomialXe
Definition: TRTProcessingOfStraw.h:232
TRTProcessingOfStraw::m_maxCrossingTime
double m_maxCrossingTime
Definition: TRTProcessingOfStraw.h:133
TRTDigSettings::jitterTimeOffset
double jitterTimeOffset() const
In cosmics, events not correlated with LHC clock.
TRTProcessingOfStraw::m_randBinomialAr
std::unique_ptr< CLHEP::RandBinomialFixedP > m_randBinomialAr
Definition: TRTProcessingOfStraw.h:234
TRTProcessingOfStraw::m_pSimDriftTimeTool
ITRT_SimDriftTimeTool * m_pSimDriftTimeTool
Definition: TRTProcessingOfStraw.h:122
TRTProcessingOfStraw::m_outerRadiusOfWire
double m_outerRadiusOfWire
Definition: TRTProcessingOfStraw.h:138
python.utils.AtlRunQueryLookup.mask
string mask
Definition: AtlRunQueryLookup.py:459
TRTDigSettings::smearingFactor
double smearingFactor(int strawGasType) const
Get smearing factor.
Trk::energyDeposit
@ energyDeposit
Definition: MeasurementType.h:32
isGenericMultichargedParticle
bool isGenericMultichargedParticle(const T &p)
In addition, there is a need to identify ”Q-ball” and similar very exotic (multi-charged) particles w...
Definition: AtlasPID.h:679
TRTTimeCorrection::TimeShift
double TimeShift(const int &strawID)
Returns the time it would take to travel at light-speed from (0,0,0) to the farthest end of the wire ...
Definition: TRTTimeCorrection.cxx:96
dqt_zlumi_alleff_HIST.A
A
Definition: dqt_zlumi_alleff_HIST.py:110
ParticleConstants::PDG2011::chargedPionMassInMeV
constexpr double chargedPionMassInMeV
the mass of the charged pion (in MeV)
Definition: ParticleConstants.h:41
TRTProcessingOfStraw::addClustersFromStep
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.
Definition: TRTProcessingOfStraw.cxx:204
TRTProcessingOfStraw::m_useAttenuation
bool m_useAttenuation
Definition: TRTProcessingOfStraw.h:130
TRTHitIdHelper.h
GeoPrimitives.h
TRTDigSettings::trEfficiencyEndCapA
double trEfficiencyEndCapA(int strawGasType) const
Get assumed Transition Radiation efficiency in end caps.
TRTProcessingOfStraw::m_settings
const TRTDigSettings * m_settings
Definition: TRTProcessingOfStraw.h:117
InDetDD::TRT_DetectorManager::getNumerology
TRT_Numerology * getNumerology()
Access Numerological information:---------------------------------------—.
Definition: TRT_DetectorManager.cxx:43
A
TRTProcessingOfStraw::m_maxelectrons
unsigned int m_maxelectrons
Definition: TRTProcessingOfStraw.h:226
InDetDD::TRT_Numerology
Definition: TRT_Numerology.h:22
ITRT_PAITool.h
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
TRTProcessingOfStraw::m_shiftOfZeroPoint
double m_shiftOfZeroPoint
Definition: TRTProcessingOfStraw.h:135
ParticleConstants.h
lumiFormat.i
int i
Definition: lumiFormat.py:85
TRTProcessingOfStraw::m_depositList
std::vector< TRTElectronicsProcessing::Deposit > m_depositList
Definition: TRTProcessingOfStraw.h:163
TRTProcessingOfStraw::m_pNoise
TRTNoise * m_pNoise
Definition: TRTProcessingOfStraw.h:145
isMonopole
bool isMonopole(const T &p)
PDG rule 11i Magnetic monopoles and dyons are assumed to have one unit of Dirac monopole charge and a...
Definition: AtlasPID.h:642
CaloNoise_fillDB.dt
dt
Definition: CaloNoise_fillDB.py:56
TRTDigSettings::attenuationLength
double attenuationLength() const
TRTDigSettings::lowThresholdBar
double lowThresholdBar(int strawGasType) const
Get discriminator setting for low threshold.
TRTNoise
Simulation of noise hits in the TRT.
Definition: TRTNoise.h:39
TRTProcessingOfStraw::m_timeCorrection
bool m_timeCorrection
Time to be corrected for flight and wire propagation delays false when beamType='cosmics'.
Definition: TRTProcessingOfStraw.h:125
TRTProcessingOfStraw::setClusterZ
double setClusterZ(double cluster_z_in, bool isLong, bool isShort, bool isEC) const
Definition: TRTProcessingOfStraw.cxx:788
jobOptions.ParticleID
ParticleID
Definition: jobOptions.decayer.py:85
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
TRTProcessingOfStraw::m_pParticleTable
const HepPDT::ParticleDataTable * m_pParticleTable
Definition: TRTProcessingOfStraw.h:148
drawFromPickle.tan
tan
Definition: drawFromPickle.py:36
TRTElectronicsProcessing.h
TRTDigiHelper.h
TRTProcessingOfStraw::m_clusterlist
std::vector< cluster > m_clusterlist
Definition: TRTProcessingOfStraw.h:162
TRTProcessingOfStraw::m_useMagneticFieldMap
bool m_useMagneticFieldMap
Definition: TRTProcessingOfStraw.h:131
TRTDigit
Class for TRT digits.
Definition: TRTDigit.h:11
CLHEP::RandBinomialFixedP
Definition: RandBinomialFixedP.h:18
ITRT_CalDbTool
Definition: ITRT_CalDbTool.h:30
TRTProcessingOfStraw::m_pTimeCorrection
TRTTimeCorrection * m_pTimeCorrection
Definition: TRTProcessingOfStraw.h:143
compareGeometries.deltaX
float deltaX
Definition: compareGeometries.py:32
TRTDigSettings::innerRadiusOfStraw
double innerRadiusOfStraw() const
Get inner radius of straw.
TRTProcessingOfStraw::getGlobalPosition
Amg::Vector3D getGlobalPosition(int hitID, const TimedHitPtr< TRTUncompressedHit > *theHit)
Definition: TRTProcessingOfStraw.cxx:730
TRTDigSettings::noiseInSimhits
bool noiseInSimhits() const
Query whether simulation of noise in hit straws.
TRTProcessingOfStraw::m_solenoidFieldStrength
double m_solenoidFieldStrength
Definition: TRTProcessingOfStraw.h:140
TRTProcessingOfStraw::ProcessStraw
void ProcessStraw(MagField::AtlasFieldCache &fieldCache, 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.
Definition: TRTProcessingOfStraw.cxx:250
trigbs_pickEvents.num
num
Definition: trigbs_pickEvents.py:76
InDetDD::TRT_DetectorManager::getEndcapElement
const TRT_EndcapElement * getEndcapElement(unsigned int positive, unsigned int wheelIndex, unsigned int strawLayerIndex, unsigned int phiIndex) const
Access Endcap Elements:---------------—(Fast)--------------------------—.
Definition: TRT_DetectorManager.cxx:116
TRTProcessingOfStraw::hitCollConstIter
TimedHitCollection< TRTUncompressedHit >::const_iterator hitCollConstIter
Definition: TRTProcessingOfStraw.h:73
python.PhysicalConstants.proton_mass_c2
float proton_mass_c2
Definition: PhysicalConstants.py:97
TRTDigSettings::trEfficiencyEndCapB
double trEfficiencyEndCapB(int strawGasType) const
TRTProcessingOfStraw::m_minCrossingTime
double m_minCrossingTime
Definition: TRTProcessingOfStraw.h:134
TRTDigit.h
charge
double charge(const T &p)
Definition: AtlasPID.h:986
TRTDigSettings::numberOfCrossingsBeforeMain
unsigned int numberOfCrossingsBeforeMain() const
Get number of simulated bunch crossings before main event (pile up)
TRTDigCondBase.h
TRTProcessingOfStraw::m_randBinomialKr
std::unique_ptr< CLHEP::RandBinomialFixedP > m_randBinomialKr
Definition: TRTProcessingOfStraw.h:233
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
TRTProcessingOfStraw::m_attenuationLength
double m_attenuationLength
Definition: TRTProcessingOfStraw.h:128
TRTDigSettings::trEfficiencyBarrel
double trEfficiencyBarrel(int strawGasType) const
Get assumed Transition Radiation efficiency in barrel.
python.PyAthena.v
v
Definition: PyAthena.py:154
TRT_ID
Definition: TRT_ID.h:82
TRTProcessingOfStraw::m_pPAItoolAr
ITRT_PAITool * m_pPAItoolAr
Definition: TRTProcessingOfStraw.h:120
InDetDD::TRT_DetectorManager
The Detector Manager for all TRT Detector elements, it acts as the interface to the detector elements...
Definition: TRT_DetectorManager.h:63
InDetDD::TRT_BaseElement::strawTransform
const Amg::Transform3D & strawTransform(unsigned int straw) const
Straw transform - fast access in array, in Tracking frame: Amg.
Definition: TRT_BaseElement.cxx:89
python.SystemOfUnits.keV
float keV
Definition: SystemOfUnits.py:174
TRTElectronicsProcessing::ProcessDeposits
void ProcessDeposits(const std::vector< Deposit > &, const int &hitID, TRTDigit &outdigit, double lowthreshold, const double &noiseamplitude, int strawGasType, CLHEP::HepRandomEngine *rndmEngine, CLHEP::HepRandomEngine *elecNoiseRndmEngine, double highthreshold=-1.0)
Process deposits in a straw.
Definition: TRTElectronicsProcessing.cxx:203
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
TRTDigSettings::timeInterval
double timeInterval() const
Get time interval covered by each digit.
numberOfProtons
int numberOfProtons(const T &p)
Definition: AtlasPID.h:823
TRTNoise.h
xAOD::EgammaHelpers::isPhoton
bool isPhoton(const xAOD::Egamma *eg)
is the object a photon
Definition: EgammaxAODHelpers.cxx:21
ITRT_SimDriftTimeTool::getAverageDriftTime
virtual double getAverageDriftTime(const double &dist, const double &effectivefield_squared, int strawGasType=0) const =0
MagField::AtlasFieldCache
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
Definition: AtlasFieldCache.h:43
TRTTimeCorrection
Time correction.
Definition: TRTTimeCorrection.h:26
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
RunTileMonitoring.clusters
clusters
Definition: RunTileMonitoring.py:133
python.LArCondContChannels.isBarrel
isBarrel
Definition: LArCondContChannels.py:659
ITRT_SimDriftTimeTool.h
ITRT_SimDriftTimeTool
Definition: ITRT_SimDriftTimeTool.h:30
MagField::AtlasFieldCache::getField
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,...
Definition: AtlasFieldCache.cxx:42
TRT_Numerology.h
ParticleConstants::PDG2011::protonMassInMeV
constexpr double protonMassInMeV
the mass of the proton (in MeV)
Definition: ParticleConstants.h:71
TRTDigSettings::useAttenuation
bool useAttenuation() const
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
hitTime
float hitTime(const AFP_SIDSimHit &hit)
Definition: AFP_SIDSimHit.h:39
TRTDigSettings
Class containing parameters and settings used by TRT digitization.
Definition: TRTDigSettings.h:34
makeComparison.deltaZ
int deltaZ
Definition: makeComparison.py:46
TRTDigSettings::outerRadiusOfWire
double outerRadiusOfWire() const
Get radius of signal wire.
TRTDigSettings::signalPropagationSpeed
double signalPropagationSpeed() const
Get wire signal propagation speed.
TRTProcessingOfStraw::m_expattenuation
std::vector< double > m_expattenuation
Definition: TRTProcessingOfStraw.h:225
WriteCellNoiseToCool.noise
noise
Definition: WriteCellNoiseToCool.py:380
HepMCHelpers.h
TRTDigSettings::ionisationPotential
double ionisationPotential(int strawGasType) const
Get ionisation potential.
TRTProcessingOfStraw::ClustersToDeposits
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....
Definition: TRTProcessingOfStraw.cxx:521
fitman.k
k
Definition: fitman.py:528
python.SystemOfUnits.ns
float ns
Definition: SystemOfUnits.py:146
TRTTimeCorrection.h
ParticleConstants::PDG2011::neutronMassInMeV
constexpr double neutronMassInMeV
the mass of the neutron (in MeV)
Definition: ParticleConstants.h:68
TRTProcessingOfStraw::m_pPAItoolXe
ITRT_PAITool * m_pPAItoolXe
Definition: TRTProcessingOfStraw.h:119
TRTProcessingOfStraw::m_alreadywarnedagainstpdg0
bool m_alreadywarnedagainstpdg0
Definition: TRTProcessingOfStraw.h:228
TRTDigCondBase
Communication with CondDB.
Definition: TRTDigCondBase.h:34