ATLAS Offline Software
SensorSimPlanarTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 #include "SensorSimPlanarTool.h"
8 #include "InDetSimEvent/SiHit.h"
11 
14 
15 #include "CLHEP/Random/RandFlat.h"
16 #include "CLHEP/Random/RandGaussZiggurat.h"
17 
18 #include "CLHEP/Units/PhysicalConstants.h"
20 
21 #include "GaudiKernel/SystemOfUnits.h"
22 
23 #include "TFile.h"
24 
25 #include <cmath>
26 #include <memory>
27 
28 using namespace InDetDD;
29 
30 //===============================================
31 // C O N S T R U C T O R
32 //===============================================
33 SensorSimPlanarTool::SensorSimPlanarTool(const std::string& type, const std::string& name, const IInterface* parent) :
35 }
36 
38 
39 //===============================================
40 // I N I T I A L I Z E
41 //===============================================
43  ATH_MSG_DEBUG("SensorSimPlanarTool::initialize()");
45 
46  ATH_CHECK(m_radDamageUtil.retrieve());
47  ATH_MSG_DEBUG("RadDamageUtil tool retrieved successfully");
48 
49  ATH_CHECK(m_lorentzAngleTool.retrieve());
50 
52  //If any fluence or voltage initialized negative use benchmark maps and not interpolation
53  std::vector<std::string> mapsPath_list;
54  std::vector<std::string> TCADpath_list;
55 
56  // Use all TCAD E field files in this directory for creating E field via interpolation (pruned filed excluded)
57  std::string iblFiles = PathResolverFindCalibDirectory("PixelDigitization/TCAD_IBL_efields/fei4-200um/");
58  std::string sensorFiles = PathResolverFindCalibDirectory("PixelDigitization/TCAD_Blayer_efields/fei4-250um/");
59 
60  // For each layer one configuration
61  TCADpath_list = {
62  iblFiles, sensorFiles, sensorFiles, sensorFiles
63  };
64 
65  if (m_fluenceMap.size() == 0 || m_fluenceLayer.size() == 0 || m_voltageLayer.size() == 0 ||
66  m_fluenceMap.size() != m_fluenceLayer.size() || m_fluenceMap.size() != m_voltageLayer.size()) {
67  ATH_MSG_INFO("Use interpolation, but the input map/fluence/valtage are not set.");
68  return StatusCode::FAILURE;
69  }
70  ATH_MSG_INFO("No benchmark value set for fluence. Use interpolation.");
71 
72  mapsPath_list.clear();
73  for (size_t i = 0; i < m_fluenceMap.size(); i++) {
74  mapsPath_list.push_back(PathResolverFindCalibFile(m_fluenceMap[i]));
75  }
76 
77  // *****************************
78  // *** Setup Maps ****
79  // *****************************
80  //TODO This is only temporary until remotely stored maps and locally generated maps can be implemented
81  //E field already implemented: needs fluence and bias voltage given as Property m_fluence, m_fluenceB, ...,
82  // m_fluence1, ...
83  for (unsigned int i = 0; i < mapsPath_list.size(); i++) {
84  ATH_MSG_INFO("Using maps located in: " << mapsPath_list.at(i) << " for layer No." << i);
85  ATH_MSG_INFO("Create E field via interpolation based on files from: " << TCADpath_list.at(i));
86  std::unique_ptr<TFile> mapsFile(TFile::Open((mapsPath_list.at(i)).c_str(), "READ")); //this is the ramo potential.
87  if (!mapsFile) {
88  ATH_MSG_ERROR("Cannot open file: " << mapsPath_list.at(i));
89  return StatusCode::FAILURE;
90  }
91 
92  //Setup ramo weighting field map
93  std::unique_ptr<TH3F> ramoPotentialMap_hold(mapsFile->Get<TH3F>("hramomap1"));
94  if (!ramoPotentialMap_hold) {
95  ramoPotentialMap_hold.reset(mapsFile->Get<TH3F>("ramo3d"));
96  ATH_MSG_INFO("Did not find a Ramo potential map. Will use an approximate form.");
97  }
98  if (!ramoPotentialMap_hold) {
99  ATH_MSG_WARNING("Not implemented yet - exit");
100  return StatusCode::FAILURE; //Obviously, remove this when gen. code is set up
101  }
102  ramoPotentialMap_hold->SetDirectory(nullptr);
103  m_ramoPotentialMap.emplace_back();
104  ATH_CHECK(m_ramoPotentialMap.back().setHisto3D(ramoPotentialMap_hold.get()));
105  //Now setup the E-field.
106  TH1F* eFieldMap_hold(nullptr);
107  CHECK(m_radDamageUtil->generateEfieldMap(eFieldMap_hold, nullptr, m_fluenceLayer[i], m_voltageLayer[i], i,
108  TCADpath_list.at(i), true));
109 
110  eFieldMap_hold->SetDirectory(nullptr);
111 
112  TH2F* lorentzMap_e_hold(nullptr);
113  TH2F* lorentzMap_h_hold(nullptr);
114  TH2F* distanceMap_h_hold(nullptr);
115  TH2F* distanceMap_e_hold(nullptr);
116  TH1F* timeMap_e_hold(nullptr);
117  TH1F* timeMap_h_hold(nullptr);
118 
119  ATH_CHECK(m_radDamageUtil->generateDistanceTimeMap(distanceMap_e_hold, distanceMap_h_hold, timeMap_e_hold,
120  timeMap_h_hold, lorentzMap_e_hold, lorentzMap_h_hold,
121  eFieldMap_hold, nullptr));
122 
123  // For debugging and documentation: uncomment to save different maps which are based on the interpolated E field
124  if (m_radDamageUtil->saveDebugMaps()) {
125  TString prename = "map_layer_";
126  prename += i;
127  prename += "distance_e.root";
128  distanceMap_e_hold->SaveAs(prename, "");
129  prename.ReplaceAll("_e", "_h");
130  distanceMap_h_hold->SaveAs(prename, "");
131  prename.ReplaceAll("distance", "time");
132  timeMap_h_hold->SaveAs(prename, "");
133  prename.ReplaceAll("_h", "_e");
134  timeMap_e_hold->SaveAs(prename, "");
135  prename.ReplaceAll("time", "lorentz");
136  lorentzMap_e_hold->SaveAs(prename, "");
137  prename.ReplaceAll("_e", "_h");
138  lorentzMap_h_hold->SaveAs(prename, "");
139  }
140  //Safetycheck
141  if (!distanceMap_e_hold || !distanceMap_h_hold || !timeMap_e_hold || !timeMap_h_hold ||
142  !lorentzMap_e_hold || !lorentzMap_h_hold) {
143  ATH_MSG_ERROR("Unable to load at least one of the distance/time/Lorentz angle maps.");
144  return StatusCode::FAILURE;//Obviously, remove this when gen. code is set up
145  }
146 
147  lorentzMap_e_hold->SetDirectory(nullptr);
148  lorentzMap_h_hold->SetDirectory(nullptr);
149  distanceMap_e_hold->SetDirectory(nullptr);
150  distanceMap_h_hold->SetDirectory(nullptr);
151  timeMap_e_hold->SetDirectory(nullptr);
152  timeMap_h_hold->SetDirectory(nullptr);
153 
154  m_distanceMap_e.emplace_back();
155  m_distanceMap_h.emplace_back();
156  ATH_CHECK(m_distanceMap_e.back().setHisto2D(distanceMap_e_hold));
157  ATH_CHECK(m_distanceMap_h.back().setHisto2D(distanceMap_h_hold));
158  m_lorentzMap_e.emplace_back();
159  m_lorentzMap_h.emplace_back();
160  ATH_CHECK(m_lorentzMap_e.back().setHisto2D(lorentzMap_e_hold));
161  ATH_CHECK(m_lorentzMap_h.back().setHisto2D(lorentzMap_h_hold));
162 
163  delete eFieldMap_hold;
164  delete lorentzMap_e_hold;
165  delete lorentzMap_h_hold;
166  delete distanceMap_e_hold;
167  delete distanceMap_h_hold;
168  delete timeMap_e_hold;
169  delete timeMap_h_hold;
170 
171  mapsFile->Close();
172  }
173  }
174 
175  // read the correction histograms
176  if (m_radiationDamageSimulationType == RadiationDamageSimulationType::TEMPLATE_CORRECTION) {
177 
178  constexpr std::size_t numberOfLayers = 4;
179 
180  ATH_MSG_INFO("Opening file: " << m_templateCorrectionRootFile << " for radiation damage correction");
181  std::unique_ptr<TFile> file(TFile::Open(PathResolverFindCalibFile(m_templateCorrectionRootFile).c_str(), "READ"));
182  if (!file) {
183  ATH_MSG_ERROR("Unable to read the ROOT file needed for radiation damage correction at: " << m_templateCorrectionRootFile);
184  return StatusCode::FAILURE;
185  }
186 
187  if (m_lorentzAngleCorrectionHistos.size() != numberOfLayers) {
188  ATH_MSG_ERROR("The size of the vector of Lorentz angle histogram paths is " << m_lorentzAngleCorrectionHistos.size() << " instead of " << numberOfLayers);
189  return StatusCode::FAILURE;
190  }
191 
192  if (m_chargeCorrectionHistos.size() != numberOfLayers) {
193  ATH_MSG_ERROR("The size of the vector of charge correction histogram paths is " << m_chargeCorrectionHistos.size() << " instead of " << numberOfLayers);
194  return StatusCode::FAILURE;
195  }
196 
197  if (m_distanceCorrectionHistos.size() != numberOfLayers) {
198  ATH_MSG_ERROR("The size of the vector of distance correction histogram paths is " << m_distanceCorrectionHistos.size() << " instead of " << numberOfLayers);
199  return StatusCode::FAILURE;
200  }
201 
202  for (const std::string& i : m_lorentzAngleCorrectionHistos) {
203  ATH_MSG_INFO("Reading histogram: " << i << " for Lorentz angle correction needed for Pixel radiation damage simulation");
204  std::unique_ptr<TH1> h(file->Get<TH1>(i.c_str()));
205  if (!h) {
206  ATH_MSG_ERROR("Cannot read histogram " << i << " needed for Lorentz angle correction");
207  return StatusCode::FAILURE;
208  }
209 
210  m_lorentzCorrection.emplace_back();
211  ATH_CHECK(m_lorentzCorrection.back().setHisto1D(h.get()));
212  }
213 
214  for (const std::string& i : m_chargeCorrectionHistos) {
215  ATH_MSG_INFO("Reading histogram: " << i << " for charge correction needed for Pixel radiation damage simulation");
216  std::unique_ptr<TH1> h(file->Get<TH1>(i.c_str()));
217  if (!h) {
218  ATH_MSG_ERROR("Cannot read histogram " << i << " needed for charge correction");
219  return StatusCode::FAILURE;
220  }
221 
222  m_chargeCorrection.emplace_back();
223  ATH_CHECK(m_chargeCorrection.back().setHisto1D(h.get()));
224  }
225 
226  for (const std::string& i : m_distanceCorrectionHistos) {
227  ATH_MSG_INFO("Reading histogram: " << i << " for distance correction needed for Pixel radiation damage simulation");
228  std::unique_ptr<TH1> h(file->Get<TH1>(i.c_str()));
229  if (!h) {
230  ATH_MSG_ERROR("Cannot read histogram " << i << " needed for distance correction");
231  return StatusCode::FAILURE;
232  }
233 
234  m_distanceCorrection.emplace_back();
235  ATH_CHECK(m_distanceCorrection.back().setHisto1D(h.get()));
236  }
237 
238  file->Close();
239  }
240 
241  return StatusCode::SUCCESS;
242 }
243 
244 //===============================================
245 // F I N A L I Z E
246 //===============================================
248  ATH_MSG_DEBUG("SensorSimPlanarTool::finalize()");
249  return StatusCode::SUCCESS;
250 }
251 
252 //===============================================
253 // I N D U C E C H A R G E
254 //===============================================
256  SiChargedDiodeCollection& chargedDiodes,
257  const InDetDD::SiDetectorElement& Module,
258  const InDetDD::PixelModuleDesign& p_design,
259  std::vector< std::pair<double, double> >& trfHitRecord,
260  std::vector<double>& initialConditions,
261  CLHEP::HepRandomEngine* rndmEngine,
262  const EventContext &ctx) const {
263 
264  bool isITk(false);
266  isITk = true;
267  if (p_design.is3D() && m_digitizeITk3Das3D) {
268  return StatusCode::SUCCESS;
269  }
270  } else {
271  // So far, this is only discriminating variable from 3D sensor.
272  if (p_design.numberOfCircuits() < 2) {
273  if (!Module.isDBM()) { //DBM modules also processed here
274  return StatusCode::SUCCESS;
275  }
276  }
277  }
278 
279  const PixelID* p_pixelId = static_cast<const PixelID*>(Module.getIdHelper());
280  int layer = p_pixelId->layer_disk(Module.identify());
281 
282  //Load values from energyDeposition
283  double eta_0 = initialConditions[0];
284  double phi_0 = initialConditions[1];
285  double depth_0 = initialConditions[2];
286  double dEta = initialConditions[3];
287  double dPhi = initialConditions[4];
288  double dDepth = initialConditions[5];
289  double ncharges = initialConditions[6];
290  double iTotalLength = initialConditions[7];
291 
292  const double oneOverNchargesTimes1e6 = 1./(1.E+6 * ncharges);
293 
294  //Set up physical detector properties, switch on detector material
295  ATH_MSG_DEBUG("Applying planar sensor simulation");
296  double sensorThickness = Module.design().thickness();
297  const InDet::SiliconProperties& siProperties = m_siPropertiesTool->getSiProperties(Module.identifyHash(), ctx);
298 
299  int etaCells = p_design.columns();
300  int phiCells = p_design.rows();
301 
302  double eleholePairEnergy = 0;
303  double smearRand = 0;
304 
305  double diffusionConstant;
306  if (Module.isDBM()) {
307  eleholePairEnergy = 1. / (13. * CLHEP::eV); // was 3.62 eV.
308  diffusionConstant = .00265;
309  smearRand = CLHEP::RandGaussZiggurat::shoot(rndmEngine);
310  } else {
311  eleholePairEnergy = siProperties.electronHolePairsPerEnergy();
312  diffusionConstant = .007;
313  }
314 
315  double collectionDist = 0.2 * CLHEP::mm;
316  double smearScale = 1. + 0.35 * smearRand;
317  double tanLorentz(0);
318  double coLorentz(0);
319  if (m_radiationDamageSimulationType != RadiationDamageSimulationType::TEMPLATE_CORRECTION) {
320  tanLorentz = m_lorentzAngleTool->getTanLorentzAngle(Module.identifyHash(), ctx);
321  coLorentz = std::sqrt(1.0 + (tanLorentz*tanLorentz));
322  }
323 
324  //**************************************//
325  //*** Now diffuse charges to surface *** //
326  //**************************************//
327  // pre-make HepMcParticleLink
328  const HepMcParticleLink particleLink = HepMcParticleLink::getRedirectedLink(phit->particleLink(), phit.eventId(), ctx); // This link should now correctly resolve to the TruthEvent McEventCollection in the main StoreGateSvc.
329  const double pHitTime = hitTime(phit);
330 
331  const double halfEtaPitch = 0.5*Module.etaPitch();
332  const double halfPhiPitch = 0.5*Module.phiPitch();
333 
334  if (m_radiationDamageSimulationType == RadiationDamageSimulationType::RAMO_POTENTIAL && !(Module.isDBM()) && Module.isBarrel()) {
336  const PixelRadiationDamageFluenceMapData *fluenceData = *fluenceDataHandle;
337 
338  std::pair<double, double> trappingTimes;
339  if (m_doInterpolateEfield) {
340  trappingTimes = m_radDamageUtil->getTrappingTimes(m_fluenceLayer[layer]);
341  }
342  else {
343  trappingTimes = m_radDamageUtil->getTrappingTimes(fluenceData->getFluenceLayer(layer));
344  }
345 
346  const PixelHistoConverter& distanceMap_e = m_doInterpolateEfield ? m_distanceMap_e[layer] : fluenceData->getDistanceMap_e(layer);
347  const PixelHistoConverter& distanceMap_h = m_doInterpolateEfield ? m_distanceMap_h[layer] : fluenceData->getDistanceMap_h(layer);
348  const PixelHistoConverter& lorentzMap_e = m_doInterpolateEfield ? m_lorentzMap_e[layer] : fluenceData->getLorentzMap_e(layer);
349  const PixelHistoConverter& lorentzMap_h = m_doInterpolateEfield ? m_lorentzMap_h[layer] : fluenceData->getLorentzMap_h(layer);
350  const PixelHistoConverter& ramoPotentialMap = m_doInterpolateEfield ? m_ramoPotentialMap[layer] : fluenceData->getRamoPotentialMap(layer);
351 
352  std::map<unsigned, std::pair<SiLocalPosition, double>> cachedChargeMap;
353  std::map<unsigned, SiCellId> diodeCellMap;
354  for (const auto& iHitRecord : trfHitRecord) {
355 
356  double eta_i = eta_0;
357  double phi_i = phi_0;
358  double depth_i = depth_0;
359  if (iTotalLength) {
360  eta_i += 1.0 * iHitRecord.first / iTotalLength * dEta;
361  phi_i += 1.0 * iHitRecord.first / iTotalLength * dPhi;
362  depth_i += 1.0 * iHitRecord.first / iTotalLength * dDepth;
363  }
364 
365  //Find the position of the centre of the pixel in which the charge carriers are created, wrt centre of module
366  SiLocalPosition pos_i = Module.hitLocalToLocal(eta_i, phi_i);
367  SiCellId pixel_i = Module.cellIdOfPosition(pos_i);
368  if (!pixel_i.isValid()) continue;
369 
370  // Distance between charge and readout side. p_design->readoutSide() is
371  // +1 if readout side is in +ve depth axis direction and visa-versa.
372  double dist_electrode = 0.5 * sensorThickness - Module.design().readoutSide() * depth_i;
373  if (dist_electrode < 0) {
374  dist_electrode = 0;
375  }
376 
377  SiLocalPosition centreOfPixel_i = p_design.positionFromColumnRow(pixel_i.etaIndex(), pixel_i.phiIndex());
378 
379  //Make limits for NN loop
380  const int nnLoop_pixelEtaMax = std::min(1, pixel_i.etaIndex());
381  const int nnLoop_pixelEtaMin = std::max(-1, pixel_i.etaIndex() + 1 - etaCells);
382  const int nnLoop_pixelPhiMax = std::min(1, pixel_i.phiIndex());
383  const int nnLoop_pixelPhiMin = std::max(-1, pixel_i.phiIndex() + 1 - phiCells);
384 
385  std::array<double, 3> sensorScales{};
386 
387  const std::size_t distance_f_e_bin_x = distanceMap_e.getBinX(dist_electrode);
388  const std::size_t distance_f_h_bin_x = distanceMap_h.getBinX(dist_electrode);
389  const std::size_t tanLorentz_e_bin_x = lorentzMap_e.getBinX(dist_electrode);
390  const std::size_t tanLorentz_h_bin_x = lorentzMap_h.getBinX(dist_electrode);
391 
392  const std::size_t sizePhi = std::abs(nnLoop_pixelPhiMax - nnLoop_pixelPhiMin) + 1;
393 
394  const auto pixel_eta = pixel_i.etaIndex();
395  const auto pixel_phi = pixel_i.phiIndex();
396 
397  // According to a comment: need at most 3x3 elements
398  std::array<std::pair<double,double>,9 > centrePixelNNEtaPhi;
399  for (int p = nnLoop_pixelEtaMin; p <= nnLoop_pixelEtaMax; p++) {
400  const std::size_t ieta = p - nnLoop_pixelEtaMin;
401  // scale factors accounting for different pixel sizes
402  double scale_f = 1.;
403  double columnWidth = p_design.widthFromColumnRange(pixel_eta - p, pixel_eta - p);
404  if (std::abs(columnWidth - 0.6) < 1e-9) {
405  scale_f = 4. / 6.;
406  } else if (std::abs(columnWidth - 0.45) < 1e-9) {
407  scale_f = 25. / 45.;
408  } else if (std::abs(columnWidth - 0.5) < 1e-9) {
409  scale_f = 25. / 50.;
410  }
411  sensorScales[ieta] = scale_f;
412 
413  for (int q = nnLoop_pixelPhiMin; q <= nnLoop_pixelPhiMax; q++) {
414  const SiLocalPosition& centreOfPixel_nn = p_design.positionFromColumnRow(pixel_eta - p,
415  pixel_phi - q);
416  const std::size_t iphi = q - nnLoop_pixelPhiMin;
417  const std::size_t index = iphi + ieta*sizePhi;
418  centrePixelNNEtaPhi.at(index).first = centreOfPixel_nn.xEta();
419  centrePixelNNEtaPhi[index].second = centreOfPixel_nn.xPhi();
420  }
421  }
422 
423 
424  for (int j = 0; j < ncharges; j++) {
425  // amount of energy to be converted into charges at current step
426  double energy_per_step = oneOverNchargesTimes1e6 * iHitRecord.second;
427  double u = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0);
428  // need to update to std::logf when we update gcc - this is a known bug in gcc libc
429  const double drifttime_e = (-1.) * (trappingTimes.first) * logf(u); //ns
430  u = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0);
431  const double drifttime_h = (-1.) * (trappingTimes.second) * logf(u); //ns
432 
433  //Now, need the z-position at the trap.
434  //TODO: the holes map does not currently extend for a drift time long enough that, any hole will reach
435  //the corresponding electrode. This needs to be rectified by either (a) extrapolating the current map or
436  //(b) making a new map with a y-axis (drift time) that extends to at least 18 ns so all charge carriers reach
437  // electrode.
438  //However, if choose (b), will need to reduce granularity of map.
439  const double depth_f_e = distanceMap_e.getContent(distance_f_e_bin_x, distanceMap_e.getBinY(drifttime_e));
440  const double depth_f_h = distanceMap_h.getContent(distance_f_h_bin_x, distanceMap_h.getBinY(drifttime_h));
441  const double tanLorentz_e = lorentzMap_e.getContent(tanLorentz_e_bin_x, lorentzMap_e.getBinY(depth_f_e));
442  const double tanLorentz_h = lorentzMap_h.getContent(tanLorentz_h_bin_x, lorentzMap_h.getBinY(depth_f_h));
443  const double dz_e = std::abs(dist_electrode - depth_f_e);
444  const double dz_h = std::abs(depth_f_h - dist_electrode);
445  const double coLorentz_e = std::sqrt(1.0 + (tanLorentz_e*tanLorentz_e));
446 
447  //Apply drift due to Lorentz force and diffusion
448  double phiRand = CLHEP::RandGaussZiggurat::shoot(rndmEngine);
449 
450  //Apply diffusion. rdif is teh max. diffusion
451  const double rdif_e = diffusionConstant * std::sqrt(dz_e * coLorentz_e / 0.3);
452  const double phi_f_e = phi_i + dz_e * tanLorentz_e + rdif_e * phiRand;
453  double etaRand = CLHEP::RandGaussZiggurat::shoot(rndmEngine);
454  double eta_f_e = eta_i + rdif_e * etaRand;
455 
456  phiRand = CLHEP::RandGaussZiggurat::shoot(rndmEngine);
457  const double coLorentz_h = std::sqrt(1.0 + (tanLorentz_h*tanLorentz_h));
458  const double rdif_h = diffusionConstant * std::sqrt(dz_h * coLorentz_h / 0.3);
459  const double phi_f_h = phi_i + dz_h * tanLorentz_h + rdif_h * phiRand;
460  etaRand = CLHEP::RandGaussZiggurat::shoot(rndmEngine);
461  double eta_f_h = eta_i + rdif_h * etaRand;
462 
463 
464  // Slim Edge for IBL planar sensors:
466  applyIBLSlimEdges(energy_per_step, eta_f_e);
467  applyIBLSlimEdges(energy_per_step, eta_f_h);
468  }
469 
470  const std::size_t ramo_f_e_bin_z = ramoPotentialMap.getBinZ(1e3*depth_f_e);
471  const std::size_t ramo_f_h_bin_z = ramoPotentialMap.getBinZ(1e3*depth_f_h);
472 
473  const bool isFirstZ_e = ramoPotentialMap.isFirstZ(1e3*depth_f_e);
474  const bool isOverflowZ_h = ramoPotentialMap.isOverflowZ(1e3*depth_f_h);
475 
476  const double pixelEta_f_e = eta_f_e - centreOfPixel_i.xEta();
477  const double pixelPhi_f_e = phi_f_e - centreOfPixel_i.xPhi();
478 
479  const double pixelEta_f_h = eta_f_h - centreOfPixel_i.xEta();
480  const double pixelPhi_f_h = phi_f_h - centreOfPixel_i.xPhi();
481 
482  //Loop over nearest neighbours in x and y
483  //We assume that the lateral diffusion is minimal
484  for (int p = nnLoop_pixelEtaMin; p <= nnLoop_pixelEtaMax; p++) {
485  const std::size_t ieta = p - nnLoop_pixelEtaMin;
486 
487  for (int q = nnLoop_pixelPhiMin; q <= nnLoop_pixelPhiMax; q++) {
488  //Since both e-h charge carriers start in the same place, they have the same initial ramo value
489  //Centre of nearest neighbour (nn) pixel
490 
491  const std::size_t iphi = q - nnLoop_pixelPhiMin;
492  const std::size_t index = iphi + ieta*sizePhi;
493  //What is the displacement of the nn pixel from the primary pixel.
494  //This is to index the correct entry in the Ramo weighting potential map
495  const std::pair<double,double>& centrePixelNN = centrePixelNNEtaPhi.at(index);
496  const double dPhi_nn_centre = centrePixelNN.second - centreOfPixel_i.xPhi(); //in mm
497  const double dEta_nn_centre = centrePixelNN.first - centreOfPixel_i.xEta(); //in mm
498 
499  //This all has to be done relative to the (0,0) position since the
500  //Ramo weighting potential is only mapped out for 1/8th of a pixel. Much of this logic is reflecting the
501  // charge carrier across the boundaries.
502  //Find the displacment of the charge carriers from the centre of the pixel in +ve quadrant
503 
504  //Final position of charge carriers wrt nn centre
505  const double dEta_f_e = std::abs(pixelEta_f_e - dEta_nn_centre)*sensorScales[ieta];
506  const double dPhi_f_e = std::abs(pixelPhi_f_e - dPhi_nn_centre);
507  const double dEta_f_h = 1e3*std::abs(pixelEta_f_h - dEta_nn_centre)*sensorScales[ieta];
508  const double dPhi_f_h = 1e3*std::abs(pixelPhi_f_h - dPhi_nn_centre);
509 
510  //Boundary check on maps
511  double ramo_f_e = 0.0;
512  double ramo_f_h = 0.0;
513 
514  if (isFirstZ_e) {
515  if (dEta_f_e >= halfEtaPitch || dPhi_f_e >= halfPhiPitch) {
516  ramo_f_e = 0.0;
517  } else {
518  ramo_f_e = 1.0;
519  }
520  } else {
521  ramo_f_e = ramoPotentialMap.getContent(ramoPotentialMap.getBinX(1e3*dPhi_f_e), ramoPotentialMap.getBinY(1e3*dEta_f_e), ramo_f_e_bin_z);
522  }
523 
524  //Account for the imperfect binning that would cause charge to be double-counted
525  if (isOverflowZ_h) {
526  ramo_f_h = 0;
527  } else {
528  ramo_f_h = ramoPotentialMap.getContent(ramoPotentialMap.getBinX(dPhi_f_h), ramoPotentialMap.getBinY(dEta_f_h), ramo_f_h_bin_z);
529  }
530 
531  //Given final position of charge carrier, find induced charge. The difference in Ramo weighting potential
532  // gives the fraction of charge induced.
533  //The energy_per_step is transformed into charge with the eleholePair per Energy
534  const double potentialDiff = ramo_f_e - ramo_f_h;
535  // this variable ^ can be used to apply some cut to skip the loop
536  const double induced_charge = potentialDiff * energy_per_step * eleholePairEnergy;
537 
538  unsigned key = (static_cast<unsigned>(pixel_eta-p) << 16) | static_cast<unsigned>(pixel_phi-q);
539  auto cacheIterator = cachedChargeMap.find(key);
540  if(cacheIterator == cachedChargeMap.end()) {
541  cachedChargeMap.insert(std::make_pair(key, std::make_pair(Module.hitLocalToLocal(centrePixelNN.first, centrePixelNN.second), induced_charge)));
542  } else {
543  cacheIterator->second.second += induced_charge;
544  }
545  } //For q
546  } //for p
547  }//end cycle for charge
548  } //trfHitRecord.size()
549 
550  std::for_each(cachedChargeMap.begin(), cachedChargeMap.end(), [&diodeCellMap, &Module, &chargedDiodes, &pHitTime, &particleLink](auto& pos_charge_pair){
551  auto& key = pos_charge_pair.first;
552  auto& chargePos = pos_charge_pair.second.first;
553  auto& charge_value = pos_charge_pair.second.second;
554 
555  const SiSurfaceCharge scharge(chargePos, SiCharge(charge_value, pHitTime, SiCharge::track, particleLink));
556  auto diodeIterator = diodeCellMap.find(key);
557  if(diodeIterator == diodeCellMap.end()) diodeIterator = diodeCellMap.insert(std::make_pair(key, Module.cellIdOfPosition(scharge.position()))).first;
558  const SiCellId& thisDiode = diodeIterator->second;
559  if (thisDiode.isValid()) {
560  const SiCharge& charge = scharge.charge();
561  chargedDiodes.add(thisDiode, charge);
562  }
563  });
564 
565  }
566  else if (m_radiationDamageSimulationType == RadiationDamageSimulationType::TEMPLATE_CORRECTION && !(Module.isDBM()) && Module.isBarrel()){ // will run radiation damage but with the template method
567 
568  // For Pixel, the layers in the barrel are 0, 1, 2 and 3
569  // But for ITk Pixel, these are 1, 2, 3 and 4
570  // So, we need to adjust for the position in the vector for ITk
571 
572  int layerToRead = isITk && m_digitizeITk3Das3D ? layer - 1 : layer;
573 
574  // temporary solution for treating 3D as planar in the digitisation
575  if (layerToRead > 3) {
576  layerToRead = 3;
577  }
578 
579  const PixelHistoConverter& distanceCorrectionHist = m_distanceCorrection[layerToRead];
580  const PixelHistoConverter& lorentzCorrectionHist = m_lorentzCorrection[layerToRead];
581  const PixelHistoConverter& chargeCorrectionHist = m_chargeCorrection[layerToRead];
582 
583  for (const auto & iHitRecord : trfHitRecord) {
584  double eta_i = eta_0;
585  double phi_i = phi_0;
586  double depth_i = depth_0;
587  if (iTotalLength) {
588  eta_i += 1.0 * iHitRecord.first / iTotalLength * dEta;
589  phi_i += 1.0 * iHitRecord.first / iTotalLength * dPhi;
590  depth_i += 1.0 * iHitRecord.first / iTotalLength * dDepth;
591  }
592 
593  const double depthZ = (depth_i + 0.5*sensorThickness)/Gaudi::Units::micrometer; // to get it in micro meters
594 
595  const double dist_electrode = distanceCorrectionHist.getContent(depthZ)*Gaudi::Units::micrometer; // to get it in mm
596 
597  // get corrected LA
598  tanLorentz = lorentzCorrectionHist.getContent(depthZ);
599  coLorentz = std::sqrt(1.0 + (tanLorentz*tanLorentz));
600 
601  // for charge corrections
602  const double chargeCorrection = chargeCorrectionHist.getContent(depthZ);
603 
604  // nonTrapping probability
605  double nontrappingProbability = 1.0;
606  if (Module.isDBM()) {
607  nontrappingProbability = exp(-dist_electrode / collectionDist);
608  }
609 
610  for (int j = 0; j < ncharges; j++) {
611  // amount of energy to be converted into charges at current step
612  double energy_per_step = oneOverNchargesTimes1e6 * iHitRecord.second;
613  // diffusion sigma
614  double rdif = diffusionConstant * std::sqrt(dist_electrode * coLorentz / 0.3);
615 
616  // position at the surface
617  double phiRand = CLHEP::RandGaussZiggurat::shoot(rndmEngine);
618  double phi_drifted = phi_i + dist_electrode * tanLorentz + rdif * phiRand;
619  double etaRand = CLHEP::RandGaussZiggurat::shoot(rndmEngine);
620  double eta_drifted = eta_i + rdif * etaRand;
621 
622  // Slim Edge for IBL planar sensors:
623  if (!(Module.isDBM()) && p_design.getReadoutTechnology() == InDetDD::PixelReadoutTechnology::FEI4) {
624  applyIBLSlimEdges(energy_per_step, eta_drifted);
625  }
626 
627  // Get the charge position in Reconstruction local coordinates.
628  const SiLocalPosition& chargePos = Module.hitLocalToLocal(eta_drifted, phi_drifted);
629 
630  // The parametrization of the sensor efficiency (if needed)
631  double ed = 0;
632  if (Module.isDBM()) {
633  ed = energy_per_step * eleholePairEnergy * nontrappingProbability * smearScale;
634  } else {
635  ed = energy_per_step * eleholePairEnergy;
636  }
637  // apply the correction from radiation damage
638  ed *= chargeCorrection;
639 
640  //The following lines are adapted from SiDigitization's Inserter class
641  const SiSurfaceCharge scharge(chargePos, SiCharge(ed, pHitTime, SiCharge::track, particleLink));
642 
643  const SiCellId& diode = Module.cellIdOfPosition(scharge.position());
644 
645  if (diode.isValid()) {
646  const SiCharge& charge = scharge.charge();
647  chargedDiodes.add(diode, charge);
648  }
649  }//end cycle for charge
650  }//trfHitRecord.size()
651  } else { // run without radiation damage
652  for (const auto & iHitRecord : trfHitRecord) {
653  double eta_i = eta_0;
654  double phi_i = phi_0;
655  double depth_i = depth_0;
656  if (iTotalLength) {
657  eta_i += 1.0 * iHitRecord.first / iTotalLength * dEta;
658  phi_i += 1.0 * iHitRecord.first / iTotalLength * dPhi;
659  depth_i += 1.0 * iHitRecord.first / iTotalLength * dDepth;
660  }
661 
662  // Distance between charge and readout side. p_design->readoutSide() is
663  // +1 if readout side is in +ve depth axis direction and visa-versa.
664  double dist_electrode = 0.5 * sensorThickness - Module.design().readoutSide() * depth_i;
665  if (dist_electrode < 0) {
666  dist_electrode = 0;
667  }
668 
669  // nonTrapping probability
670  double nontrappingProbability = 1.0;
671  if (Module.isDBM()) {
672  nontrappingProbability = exp(-dist_electrode / collectionDist);
673  }
674 
675  for (int j = 0; j < ncharges; j++) {
676  // amount of energy to be converted into charges at current step
677  double energy_per_step = oneOverNchargesTimes1e6 * iHitRecord.second;
678  // diffusion sigma
679  double rdif = diffusionConstant * std::sqrt(dist_electrode * coLorentz / 0.3);
680 
681  // position at the surface
682  double phiRand = CLHEP::RandGaussZiggurat::shoot(rndmEngine);
683  double phi_drifted = phi_i + dist_electrode * tanLorentz + rdif * phiRand;
684  double etaRand = CLHEP::RandGaussZiggurat::shoot(rndmEngine);
685  double eta_drifted = eta_i + rdif * etaRand;
686 
687  // Slim Edge for IBL planar sensors:
688  if (!(Module.isDBM()) && p_design.getReadoutTechnology() == InDetDD::PixelReadoutTechnology::FEI4) {
689  applyIBLSlimEdges(energy_per_step, eta_drifted);
690  }
691 
692  // Get the charge position in Reconstruction local coordinates.
693  const SiLocalPosition& chargePos = Module.hitLocalToLocal(eta_drifted, phi_drifted);
694 
695  // The parametrization of the sensor efficiency (if needed)
696  double ed = 0;
697  if (Module.isDBM()) {
698  ed = energy_per_step * eleholePairEnergy * nontrappingProbability * smearScale;
699  } else {
700  ed = energy_per_step * eleholePairEnergy;
701  }
702 
703  //The following lines are adapted from SiDigitization's Inserter class
704  const SiSurfaceCharge scharge(chargePos, SiCharge(ed, pHitTime, SiCharge::track, particleLink));
705 
706  const SiCellId& diode = Module.cellIdOfPosition(scharge.position());
707 
708  if (diode.isValid()) {
709  const SiCharge& charge = scharge.charge();
710  chargedDiodes.add(diode, charge);
711  }
712  }//end cycle for charge
713  }
714  }
715 
716  return StatusCode::SUCCESS;
717 }
718 
719 void SensorSimPlanarTool::applyIBLSlimEdges(double& energy_per_step, double& eta_drifted) {
720  if (std::abs(eta_drifted) > 20.440) {
721  energy_per_step = 0.0;
722  }
723  if (std::abs(eta_drifted) < 20.440 && std::abs(eta_drifted) > 20.200) {
724  if (eta_drifted > 0) {
725  energy_per_step = energy_per_step * (68.13 - eta_drifted * 3.333);
726  eta_drifted = eta_drifted - 0.250;
727  } else {
728  energy_per_step = energy_per_step * (68.13 + eta_drifted * 3.333);
729  eta_drifted = eta_drifted + 0.250;
730  }
731  }
732  if (std::abs(eta_drifted) < 20.200 && std::abs(eta_drifted) > 20.100) {
733  if (eta_drifted > 0) {
734  energy_per_step = energy_per_step * (41.2 - eta_drifted * 2.0);
735  eta_drifted = eta_drifted - 0.250;
736  } else {
737  energy_per_step = energy_per_step * (41.2 + eta_drifted * 2.0);
738  eta_drifted = eta_drifted + 0.250;
739  }
740  }
741 }
PixelID.h
This is an Identifier helper class for the Pixel subdetector. This class is a factory for creating co...
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
SiSurfaceCharge
Definition: SiSurfaceCharge.h:23
InDetDD::SolidStateDetectorElementBase::cellIdOfPosition
SiCellId cellIdOfPosition(const Amg::Vector2D &localPos) const
As in previous method but returns SiCellId.
Definition: SolidStateDetectorElementBase.cxx:224
SensorSimPlanarTool::m_fluenceLayer
Gaudi::Property< std::vector< double > > m_fluenceLayer
Definition: SensorSimPlanarTool.h:79
SensorSimPlanarTool::m_distanceCorrection
std::vector< PixelHistoConverter > m_distanceCorrection
Definition: SensorSimPlanarTool.h:55
SensorSimPlanarTool::m_distanceMap_e
std::vector< PixelHistoConverter > m_distanceMap_e
Definition: SensorSimPlanarTool.h:49
python.SystemOfUnits.mm
float mm
Definition: SystemOfUnits.py:98
InDetDD::DetectorDesign::thickness
double thickness() const
Method which returns thickness of the silicon wafer.
Definition: DetectorDesign.h:271
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
PixelHistoConverter::getBinY
std::size_t getBinY(Args &&...args) const
Definition: PixelHistoConverter.h:79
InDetDD::PixelModuleDesign
Definition: PixelModuleDesign.h:45
InDetDD::PixelModuleDesign::columns
int columns() const
Number of cell columns per module:
Definition: PixelModuleDesign.h:331
SensorSimTool::m_radiationDamageSimulationType
Gaudi::Property< int > m_radiationDamageSimulationType
Definition: SensorSimTool.h:87
SiHit.h
index
Definition: index.py:1
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
InDetDD::PixelModuleDesign::rows
int rows() const
Number of cell rows per module:
Definition: PixelModuleDesign.h:336
SensorSimPlanarTool::m_chargeCorrection
std::vector< PixelHistoConverter > m_chargeCorrection
Definition: SensorSimPlanarTool.h:54
SiCharge::track
@ track
Definition: SiCharge.h:28
SensorSimPlanarTool::m_distanceMap_h
std::vector< PixelHistoConverter > m_distanceMap_h
Definition: SensorSimPlanarTool.h:50
InDetDD::SiCellId::isValid
bool isValid() const
Test if its in a valid state.
Definition: SiCellId.h:136
InDetDD::DetectorDesign::readoutSide
int readoutSide() const
ReadoutSide.
Definition: DetectorDesign.h:291
SiCharge
Definition: SiCharge.h:25
InDetDD::SiCellId::phiIndex
int phiIndex() const
Get phi index. Equivalent to strip().
Definition: SiCellId.h:122
TimedHitPtr< SiHit >
SensorSimTool::m_fluenceDataKey
SG::ReadCondHandleKey< PixelRadiationDamageFluenceMapData > m_fluenceDataKey
Definition: SensorSimTool.h:116
SensorSimTool::m_chargeCorrectionHistos
Gaudi::Property< std::vector< std::string > > m_chargeCorrectionHistos
Definition: SensorSimTool.h:104
SensorSimPlanarTool::m_lorentzCorrection
std::vector< PixelHistoConverter > m_lorentzCorrection
Definition: SensorSimPlanarTool.h:53
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
SensorSimPlanarTool::induceCharge
virtual StatusCode induceCharge(const TimedHitPtr< SiHit > &phit, SiChargedDiodeCollection &chargedDiodes, const InDetDD::SiDetectorElement &Module, const InDetDD::PixelModuleDesign &p_design, std::vector< std::pair< double, double > > &trfHitRecord, std::vector< double > &initialConditions, CLHEP::HepRandomEngine *rndmEngine, const EventContext &ctx) const override
Definition: SensorSimPlanarTool.cxx:255
python.TrigEgammaMonitorHelper.TH2F
def TH2F(name, title, nxbins, bins_par2, bins_par3, bins_par4, bins_par5=None, bins_par6=None, path='', **kwargs)
Definition: TrigEgammaMonitorHelper.py:45
SensorSimTool::m_siPropertiesTool
ToolHandle< ISiPropertiesTool > m_siPropertiesTool
Definition: SensorSimTool.h:77
InDetDD::SolidStateDetectorElementBase::etaPitch
double etaPitch() const
Pitch (inline methods)
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
InDetDD::SolidStateDetectorElementBase::identifyHash
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
PixelRadiationDamageFluenceMapData::getLorentzMap_e
const PixelHistoConverter & getLorentzMap_e(int layer) const
Definition: PixelRadiationDamageFluenceMapData.cxx:38
InDetDD::SolidStateDetectorElementBase::getIdHelper
const AtlasDetectorID * getIdHelper() const
Returns the id helper (inline)
PathResolverFindCalibDirectory
std::string PathResolverFindCalibDirectory(const std::string &logical_file_name)
Definition: PathResolver.cxx:288
InDetDD::PixelReadoutTechnology::RD53
@ RD53
InDetDD::SiLocalPosition
Definition: SiLocalPosition.h:31
InDetDD::PixelModuleDesign::positionFromColumnRow
SiLocalPosition positionFromColumnRow(const int column, const int row) const
Given row and column index of a diode, return position of diode center ALTERNATIVE/PREFERED way is to...
Definition: PixelModuleDesign.cxx:260
InDetDD::SiLocalPosition::xPhi
double xPhi() const
position along phi direction:
Definition: SiLocalPosition.h:123
PixelHistoConverter::getBinZ
std::size_t getBinZ(Args &&...args) const
Definition: PixelHistoConverter.h:84
SensorSimTool::initialize
virtual StatusCode initialize()
Definition: SensorSimTool.h:54
InDetDD::SiDetectorElement::phiPitch
double phiPitch() const
Pitch (inline methods)
python.SystemOfUnits.eV
float eV
Definition: SystemOfUnits.py:173
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
InDetDD::PixelModuleDesign::widthFromColumnRange
double widthFromColumnRange(const int colMin, const int colMax) const
Method to calculate eta width from a column range.
Definition: PixelModuleDesign.cxx:167
InDetDD::SiCellId::etaIndex
int etaIndex() const
Get eta index.
Definition: SiCellId.h:114
SensorSimPlanarTool::m_lorentzMap_h
std::vector< PixelHistoConverter > m_lorentzMap_h
Definition: SensorSimPlanarTool.h:52
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
CheckAppliedSFs.e3
e3
Definition: CheckAppliedSFs.py:264
SiChargedDiodeCollection
Definition: SiChargedDiodeCollection.h:109
PixelHistoConverter
Definition: PixelHistoConverter.h:25
PixelRadiationDamageFluenceMapData
Definition: PixelRadiationDamageFluenceMapData.h:25
lumiFormat.i
int i
Definition: lumiFormat.py:85
InDetDD::SiLocalPosition::xEta
double xEta() const
position along eta direction:
Definition: SiLocalPosition.h:118
h
python.SystemOfUnits.micrometer
float micrometer
Definition: SystemOfUnits.py:80
SensorSimPlanarTool::finalize
virtual StatusCode finalize() override
Definition: SensorSimPlanarTool.cxx:247
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
extractSporadic.h
list h
Definition: extractSporadic.py:96
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
PixelRadiationDamageFluenceMapData::getLorentzMap_h
const PixelHistoConverter & getLorentzMap_h(int layer) const
Definition: PixelRadiationDamageFluenceMapData.cxx:39
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
TauGNNUtils::Variables::Track::dPhi
bool dPhi(const xAOD::TauJet &tau, const xAOD::TauTrack &track, double &out)
Definition: TauGNNUtils.cxx:549
SensorSimPlanarTool::m_doInterpolateEfield
Gaudi::Property< bool > m_doInterpolateEfield
Definition: SensorSimPlanarTool.h:63
InDetDD::PixelModuleDesign::numberOfCircuits
int numberOfCircuits() const
Total number of circuits:
Definition: PixelModuleDesign.h:306
PixelHistoConverter::isFirstZ
bool isFirstZ(const float value) const
Definition: PixelHistoConverter.cxx:101
file
TFile * file
Definition: tile_monitor.h:29
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
SensorSimPlanarTool::m_voltageLayer
Gaudi::Property< std::vector< float > > m_voltageLayer
Definition: SensorSimPlanarTool.h:86
SensorSimPlanarTool::m_fluenceMap
Gaudi::Property< std::vector< std::string > > m_fluenceMap
Definition: SensorSimPlanarTool.h:68
SensorSimPlanarTool::m_radDamageUtil
ToolHandle< RadDamageUtil > m_radDamageUtil
Definition: SensorSimPlanarTool.h:93
InDetDD::SolidStateDetectorElementBase::hitLocalToLocal
Amg::Vector2D hitLocalToLocal(double xEta, double xPhi) const
Simulation/Hit local frame to reconstruction local frame.
Definition: SolidStateDetectorElementBase.cxx:95
PixelID::layer_disk
int layer_disk(const Identifier &id) const
Definition: PixelID.h:622
PathResolver.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
PixelRadiationDamageFluenceMapData::getDistanceMap_e
const PixelHistoConverter & getDistanceMap_e(int layer) const
Definition: PixelRadiationDamageFluenceMapData.cxx:40
SensorSimPlanarTool::initialize
virtual StatusCode initialize() override
Definition: SensorSimPlanarTool.cxx:42
charge
double charge(const T &p)
Definition: AtlasPID.h:986
InDetDD::SiDetectorElement
Definition: SiDetectorElement.h:109
InDetDD::PixelReadoutTechnology::FEI4
@ FEI4
InDetDD::SiDetectorElement::isBarrel
bool isBarrel() const
SensorSimPlanarTool::SensorSimPlanarTool
SensorSimPlanarTool()
SensorSimTool::m_distanceCorrectionHistos
Gaudi::Property< std::vector< std::string > > m_distanceCorrectionHistos
Definition: SensorSimTool.h:110
InDet::SiliconProperties
Definition: SiliconProperties.h:24
InDetDD::PixelModuleDesign::getReadoutTechnology
PixelReadoutTechnology getReadoutTechnology() const
Definition: PixelModuleDesign.h:391
SiDetectorElement.h
PathResolverFindCalibFile
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Definition: PathResolver.cxx:283
PixelRadiationDamageFluenceMapData::getFluenceLayer
double getFluenceLayer(int layer) const
Definition: PixelRadiationDamageFluenceMapData.cxx:30
InDetDD::SiCellId
Definition: SiCellId.h:29
PixelHistoConverter::isOverflowZ
bool isOverflowZ(const float value) const
Definition: PixelHistoConverter.h:44
DeMoScan.index
string index
Definition: DeMoScan.py:362
SensorSimTool::m_digitizeITk3Das3D
Gaudi::Property< bool > m_digitizeITk3Das3D
Definition: SensorSimTool.h:122
InDetDD::PixelModuleDesign::is3D
virtual bool is3D() const
Definition: PixelModuleDesign.h:386
PixelRadiationDamageFluenceMapData::getDistanceMap_h
const PixelHistoConverter & getDistanceMap_h(int layer) const
Definition: PixelRadiationDamageFluenceMapData.cxx:41
SensorSimPlanarTool.h
TimedHitPtr::eventId
unsigned short eventId() const
the index of the component event in PileUpEventInfo.
Definition: TimedHitPtr.h:47
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
InDetDD
Message Stream Member.
Definition: FakeTrackBuilder.h:8
PixelModuleDesign.h
InDetDD::SiDetectorElement::isDBM
bool isDBM() const
InDet::SiliconProperties::electronHolePairsPerEnergy
double electronHolePairsPerEnergy() const
Definition: SiliconProperties.cxx:238
SensorSimPlanarTool::m_lorentzMap_e
std::vector< PixelHistoConverter > m_lorentzMap_e
Definition: SensorSimPlanarTool.h:51
extractSporadic.q
list q
Definition: extractSporadic.py:97
SensorSimPlanarTool::m_lorentzAngleTool
ToolHandle< ISiLorentzAngleTool > m_lorentzAngleTool
Definition: SensorSimPlanarTool.h:98
SensorSimTool
Definition: SensorSimTool.h:38
SensorSimPlanarTool::m_ramoPotentialMap
std::vector< PixelHistoConverter > m_ramoPotentialMap
Definition: SensorSimPlanarTool.h:48
python.TrigEgammaMonitorHelper.TH1F
def TH1F(name, title, nxbins, bins_par2, bins_par3=None, path='', **kwargs)
Definition: TrigEgammaMonitorHelper.py:24
hitTime
float hitTime(const AFP_SIDSimHit &hit)
Definition: AFP_SIDSimHit.h:39
SensorSimTool::m_templateCorrectionRootFile
Gaudi::Property< std::string > m_templateCorrectionRootFile
Definition: SensorSimTool.h:92
PixelHistoConverter::getBinX
std::size_t getBinX(Args &&...args) const
Definition: PixelHistoConverter.h:74
InDetDD::SiDetectorElement::design
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
TauGNNUtils::Variables::Track::dEta
bool dEta(const xAOD::TauJet &tau, const xAOD::TauTrack &track, double &out)
Definition: TauGNNUtils.cxx:538
SensorSimPlanarTool::~SensorSimPlanarTool
virtual ~SensorSimPlanarTool()
PixelID
Definition: PixelID.h:67
SensorSimPlanarTool::applyIBLSlimEdges
static void applyIBLSlimEdges(double &energyPerStep, double &eta_drifted)
Definition: SensorSimPlanarTool.cxx:719
SiSurfaceCharge.h
PixelRadiationDamageFluenceMapData::getRamoPotentialMap
const PixelHistoConverter & getRamoPotentialMap(int layer) const
Definition: PixelRadiationDamageFluenceMapData.cxx:42
InDetDD::SolidStateDetectorElementBase::identify
virtual Identifier identify() const override final
identifier of this detector element (inline)
SiliconProperties.h
SensorSimTool::m_lorentzAngleCorrectionHistos
Gaudi::Property< std::vector< std::string > > m_lorentzAngleCorrectionHistos
Definition: SensorSimTool.h:98
SiChargedDiodeCollection.h
PixelHistoConverter::getContent
float getContent(std::size_t x) const
Definition: PixelHistoConverter.h:34
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37