ATLAS Offline Software
HGTD_SurfaceChargesGenerator.cxx
Go to the documentation of this file.
1 
16 
17 #include "CLHEP/Random/RandGaussZiggurat.h"
18 #include "CLHEP/Random/RandomEngine.h"
19 #include "CLHEP/Units/SystemOfUnits.h"
20 #include "GaudiKernel/PhysicalConstants.h"
26 
28  const std::string &type, const std::string &name, const IInterface *parent)
29  : AthAlgTool(type, name, parent) {
30 }
31 
33  ATH_MSG_DEBUG("HGTD_SurfaceChargesGenerator::initialize()");
34 
36 
38 
39  return StatusCode::SUCCESS;
40 }
41 
43  const TimedHitPtr<SiHit>& timed_hit_ptr,
44  SiChargedDiodeCollection* diode_coll,
46  CLHEP::HepRandomEngine* rndm_engine,
47  const EventContext& ctx) const {
48 
49  const SiHit& hit = *timed_hit_ptr;
50 
51  float time_of_flight = timed_hit_ptr.eventTime() + hit.meanTime();
52 
53  //NB this "expected time" will change once we need to follow the beamspot!!
54  float tof_expected = element->center().norm() / Gaudi::Units::c_light;
55 
56  ATH_MSG_DEBUG("event time = " << timed_hit_ptr.eventTime() << ", mean time ="
57  << hit.meanTime() << ", tof =" << time_of_flight
58  << ", tof exp =" << tof_expected);
59 
60  // the ALTIROC ASIC has an active window of 2.5ns around the expected TOA, all
61  // hits outside that window are ignored (modulo some early hits with large
62  // TOT that spill over). So ignore hits outside of this time window
63  if (std::abs(time_of_flight - tof_expected) > m_active_time_window) {
64  return;
65  }
66 
67  // check the status of truth information for this SiHit
68  // some Truth information is cut for pile up events
69  const HepMcParticleLink trklink = HepMcParticleLink::getRedirectedLink(hit.particleLink(), timed_hit_ptr.eventId(), ctx); // This link should now correctly resolve to the TruthEvent McEventCollection in the main StoreGateSvc.
71  if (hit.truthID() != 0 || hit.truthBarcode() != 0) { // if the hit was not caused by a delta-ray then one of these must be true
72  if (not trklink.isValid()) {
73  // TODO consider extending this check to reject links to
74  // GenEvents other than the first one in the McEventCollection,
75  // so that the digitization output doesn't change if pile-up
76  // truth is saved.
77  hitproc = SiCharge::cut_track;
78  }
79  }
80 
81  float sensor_thickness = element->design().thickness();
82  int readout_side = element->design().readoutSide();
83 
84  float pixel_size_xphi = element->design().phiPitch();
85  float pixel_size_xeta = element->design().etaPitch();
86 
87  Amg::Vector3D element_center = element->center();
88  ATH_MSG_DEBUG("x and y, z are: " << element_center.x() << ", "
89  << element_center.y() << ", "
90  << element_center.z());
91  float element_r = sqrt(element_center.x() * element_center.x() +
92  element_center.y() * element_center.y());
93 
94  const CLHEP::Hep3Vector start_pos(hit.localStartPosition());
95  const CLHEP::Hep3Vector end_pos(hit.localEndPosition());
96 
97  ATH_MSG_DEBUG("start_pos xEta=" << start_pos[SiHit::xEta]
98  << ", xPhi=" << start_pos[SiHit::xPhi]
99  << ", xDep=" << start_pos[SiHit::xDep]);
100 
101  CLHEP::Hep3Vector direction = end_pos - start_pos;
102  float deposit_length = direction.mag();
103  int n_steps = deposit_length / m_small_step_length + 1;
104  // the start and end pos can sit at the same position. Resizing the
105  // zero-length Hep3Vector would cause an error, so this we protect against
106  if (deposit_length > 1.e-10) {
107  direction.setMag(deposit_length / static_cast<float>(n_steps));
108  }
109 
110  float tot_eloss = hit.energyLoss();
111  // FIXME using the mean ionization energy in Silicon
112  const float tot_charge = tot_eloss / (3.62 * CLHEP::eV);
113 
114  float charge_per_step = tot_charge / static_cast<float>(n_steps);
115 
116  // FIXME is this correct? does the eventTime include a "later" truth event and
117  // the meanTime is just the TOF?
118  ATH_MSG_DEBUG(">>>>>>> before processing, event_t, t, E, r: "
119  << timed_hit_ptr.eventTime() << ", " << hit.meanTime() << ", "
120  << tot_eloss << ", " << element_r);
121 
122  if (m_smear_meantime) {
123  // Smearing based on radius and luminosity, and substract the time shift
124  // due to pulse leading edge (0.408 ns)
125  time_of_flight = m_hgtd_timing_resolution_tool->calculateTime(
126  time_of_flight, tot_eloss, element_r, rndm_engine) -
127  0.408;
128  }
129  ATH_MSG_DEBUG(">>>>>>> after processing, t: " << time_of_flight);
130 
131  // FIXME needed to check for deposits in guardrings. This should be taken over
132  // by the module design class and not hardcoded here!
133 
134  float xphi_offset = 9.75;
135  float xeta_offset = 19.5;
136  // FIXME this should be handled by the module design class in the future
137  float interpad = 50 * CLHEP::micrometer;
138 
139  for (int i_step = 0; i_step < n_steps; i_step++) {
140  CLHEP::Hep3Vector surface_pos = start_pos + i_step * direction;
141  ATH_MSG_DEBUG("surface_pos x=" << surface_pos.x()
142  << ", y=" << surface_pos.y()
143  << ", z=" << surface_pos.z());
144  ATH_MSG_DEBUG("surface_pos xEta=" << surface_pos[SiHit::xEta]
145  << ", xPhi=" << surface_pos[SiHit::xPhi]
146  << ", xDep=" << surface_pos[SiHit::xDep]);
147  // NB! y aka xPhi is the long side of the module!
148  // DEBUG surface_pos x=9.08365, y=-1.17206, z=-0.025
149  // DEBUG surface_pos xEta=-0.025, xPhi=-1.17206, xDep=9.08365
150  // FIXME: eta, phi andd dep need to be revisited in Rel 22!
151 
152  // Distance between charge and readout side. p_design->readoutSide() is
153  // +1 if readout side is in +ve depth axis direction and visa-versa.
154  // FIXME ask Noemi about what happens here
155  float spess =
156  0.5 * sensor_thickness - readout_side * surface_pos[SiHit::xDep];
157  if (spess < 0) {
158  spess = 0; // FIXME this means I am on the surface already?
159  }
160  // diffusion sigma
161  // FIXME where is the 0.3 from?
162  float rdif = m_diffusion_constant * std::sqrt(spess / 0.3);
163 
164  // position at the surface, adding smearing
165  // FIXME currently no Lorentz angle considered, can be studied in the future
166  float surf_pos_xphi = surface_pos[SiHit::xPhi] +
167  rdif * CLHEP::RandGaussZiggurat::shoot(rndm_engine);
168  float surf_pos_xeta = surface_pos[SiHit::xEta] +
169  rdif * CLHEP::RandGaussZiggurat::shoot(rndm_engine);
170 
171  // if the deposit is outside the guard ring, don't consider it
172  if (fabs(surf_pos_xphi) > xphi_offset or
173  fabs(surf_pos_xeta) > xeta_offset) {
174  ATH_MSG_DEBUG("Hit in guard ring");
175  continue;
176  }
177 
178  int bin_xphi = floor(fabs(surf_pos_xphi + xphi_offset) / pixel_size_xphi);
179  int bin_xeta = floor(fabs(surf_pos_xeta + xeta_offset) / pixel_size_xeta);
180 
181  float pos_xphi_inpixel =
182  fabs(surf_pos_xphi + xphi_offset) - float(bin_xphi) * pixel_size_xphi;
183  float pos_xeta_inpixel =
184  fabs(surf_pos_xeta + xeta_offset) - float(bin_xeta) * pixel_size_xeta;
185 
186  bool is_interpad_xphi = (pos_xphi_inpixel < interpad or
187  pos_xphi_inpixel > (pixel_size_xphi - interpad));
188  bool is_interpad_xeta = (pos_xeta_inpixel < interpad or
189  pos_xeta_inpixel > (pixel_size_xeta - interpad));
190 
191  // check if the charge is sitting in the interpad region
192  if (is_interpad_xphi or is_interpad_xeta) {
193  ATH_MSG_DEBUG("Hit in interpad region");
194  continue;
195  }
196  // charges deposited within the active sensor get added
197  const InDetDD::SiLocalPosition position(
198  element->hitLocalToLocal(surf_pos_xeta, surf_pos_xphi));
199 
200  SiSurfaceCharge surface_charge(
201  position, SiCharge(charge_per_step, time_of_flight, hitproc,
202  trklink)); // FIXME is this obj even needed?
203 
204  InDetDD::SiCellId cell_id =
205  element->cellIdOfPosition(surface_charge.position());
206  ATH_MSG_DEBUG("cell_id x=" << cell_id);
207  if (cell_id.isValid()) {
208  // add this charge to the collection (or merge in existing charged diode)
209  diode_coll->add(cell_id, surface_charge.charge());
210  }
211  } // END LOOP over steps
212 }
HGTD_SurfaceChargesGenerator::HGTD_SurfaceChargesGenerator
HGTD_SurfaceChargesGenerator(const std::string &type, const std::string &name, const IInterface *parent)
constructor
Definition: HGTD_SurfaceChargesGenerator.cxx:27
SiHit::xPhi
@ xPhi
Definition: SiHit.h:162
SiSurfaceCharge::position
InDetDD::SiLocalPosition position() const
Definition: SiSurfaceCharge.h:75
SolidStateDetectorElementBase.h
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
InDetDD::DetectorDesign::thickness
double thickness() const
Method which returns thickness of the silicon wafer.
Definition: DetectorDesign.h:271
SiHit::localEndPosition
HepGeom::Point3D< double > localEndPosition() const
Definition: SiHit.cxx:153
InDetDD::SolidStateDetectorElementBase
Definition: SolidStateDetectorElementBase.h:132
HGTD_SurfaceChargesGenerator::m_active_time_window
FloatProperty m_active_time_window
Definition: HGTD_SurfaceChargesGenerator.h:55
InDetDD::SolidStateDetectorElementBase::center
virtual const Amg::Vector3D & center() const override final
Center in global coordinates.
InDetDD::DetectorDesign::etaPitch
virtual double etaPitch() const =0
SiCharge::track
@ track
Definition: SiCharge.h:28
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
TimedHitPtr< SiHit >
HGTD_SurfaceChargesGenerator::m_diffusion_constant
FloatProperty m_diffusion_constant
Definition: HGTD_SurfaceChargesGenerator.h:54
HGTD_SurfaceChargesGenerator::createSurfaceChargesFromHit
virtual void createSurfaceChargesFromHit(const TimedHitPtr< SiHit > &timed_hit_ptr, SiChargedDiodeCollection *diode_coll, const InDetDD::SolidStateDetectorElementBase *element, CLHEP::HepRandomEngine *rndm_engine, const EventContext &ctx) const override final
Definition: HGTD_SurfaceChargesGenerator.cxx:42
SiHit
Definition: SiHit.h:19
SiHit::meanTime
double meanTime() const
Definition: SiHit.h:180
TimedHitPtr::eventTime
float eventTime() const
t0 offset of the bunch xing containing the hit in ns.
Definition: TimedHitPtr.h:50
InDetDD::SiLocalPosition
Definition: SiLocalPosition.h:31
HGTD_SurfaceChargesGenerator::initialize
StatusCode initialize() override
AlgTool initialize.
Definition: HGTD_SurfaceChargesGenerator.cxx:32
HGTD_SurfaceChargesGenerator.h
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration.
SiSurfaceCharge::charge
const SiCharge & charge() const
Definition: SiSurfaceCharge.h:80
SiChargedDiodeCollection
Definition: SiChargedDiodeCollection.h:109
HGTD_SurfaceChargesGenerator::m_hgtd_timing_resolution_tool
ToolHandle< HGTD_TimingResolution > m_hgtd_timing_resolution_tool
Definition: HGTD_SurfaceChargesGenerator.h:57
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
InDetDD::SolidStateDetectorElementBase::design
virtual const DetectorDesign & design() const
access to the local description (inline):
SiHit::truthBarcode
int truthBarcode() const
Definition: SiHit.cxx:202
SiHit::particleLink
const HepMcParticleLink & particleLink() const
Definition: SiHit.h:190
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
python.SystemOfUnits.micrometer
int micrometer
Definition: SystemOfUnits.py:71
SiLocalPosition.h
InDetDD::SolidStateDetectorElementBase::hitLocalToLocal
Amg::Vector2D hitLocalToLocal(double xEta, double xPhi) const
Simulation/Hit local frame to reconstruction local frame.
Definition: SolidStateDetectorElementBase.cxx:95
DetectorDesign.h
SiHit::energyLoss
double energyLoss() const
Definition: SiHit.h:175
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
python.SystemOfUnits.eV
int eV
Definition: SystemOfUnits.py:155
HGTD_SurfaceChargesGenerator::m_small_step_length
FloatProperty m_small_step_length
Definition: HGTD_SurfaceChargesGenerator.h:53
SiHit::xDep
@ xDep
Definition: SiHit.h:162
SiHit::truthID
int truthID() const
Definition: SiHit.cxx:208
SiCharge::Process
Process
Definition: SiCharge.h:28
python.PhysicalConstants.c_light
float c_light
Definition: PhysicalConstants.py:63
SiHit::xEta
@ xEta
Definition: SiHit.h:162
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
SiChargedDiodeCollection::add
void add(const InDetDD::SiCellId &diode, const T &charge)
Definition: SiChargedDiodeCollection.h:299
InDetDD::SiCellId
Definition: SiCellId.h:29
SiCharge::cut_track
@ cut_track
Definition: SiCharge.h:28
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
TimedHitPtr::eventId
unsigned short eventId() const
the index of the component event in PileUpEventInfo.
Definition: TimedHitPtr.h:42
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
AthAlgTool
Definition: AthAlgTool.h:26
InDetDD::DetectorDesign::phiPitch
virtual double phiPitch() const =0
Pitch in phi direction.
readCCLHist.float
float
Definition: readCCLHist.py:83
SiHit::localStartPosition
HepGeom::Point3D< double > localStartPosition() const
Definition: SiHit.cxx:146
HGTD_SurfaceChargesGenerator::m_smear_meantime
BooleanProperty m_smear_meantime
Definition: HGTD_SurfaceChargesGenerator.h:56
SiChargedDiodeCollection.h