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