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