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"
26#include "GaudiKernel/SystemOfUnits.h"
27
29 const std::string &type, const std::string &name, const IInterface *parent)
30 : AthAlgTool(type, name, parent) {
31}
32
34 ATH_MSG_DEBUG("HGTD_SurfaceChargesGenerator::initialize()");
35
36 m_small_step_length.setValue(m_small_step_length.value() * CLHEP::micrometer);
37
39
40 return StatusCode::SUCCESS;
41}
42
44 const TimedHitPtr<SiHit>& timed_hit_ptr,
45 SiChargedDiodeCollection* diode_coll,
47 CLHEP::HepRandomEngine* rndm_engine,
48 const EventContext& ctx) const {
49
50 const SiHit& hit = *timed_hit_ptr;
51
52 float time_of_flight = timed_hit_ptr.eventTime() + hit.meanTime();
53
54 //NB this "expected time" will change once we need to follow the beamspot!!
55 float tof_expected = element->center().norm() / Gaudi::Units::c_light;
56
57 ATH_MSG_DEBUG("event time = " << timed_hit_ptr.eventTime() << ", mean time ="
58 << hit.meanTime() << ", tof =" << time_of_flight
59 << ", tof exp =" << tof_expected);
60
61 // the ALTIROC ASIC has an active window of 2.5ns around the expected TOA, all
62 // hits outside that window are ignored (modulo some early hits with large
63 // TOT that spill over). So ignore hits outside of this time window
64 if (std::abs(time_of_flight - tof_expected) > m_active_time_window) {
65 return;
66 }
67
68 // check the status of truth information for this SiHit
69 // some Truth information is cut for pile up events
70 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.
72 if (hit.truthID() != 0 || hit.truthBarcode() != 0) { // if the hit was not caused by a delta-ray then one of these must be true
73 if (not trklink.isValid()) {
74 // TODO consider extending this check to reject links to
75 // GenEvents other than the first one in the McEventCollection,
76 // so that the digitization output doesn't change if pile-up
77 // truth is saved.
78 hitproc = SiCharge::cut_track;
79 }
80 }
81
82 float sensor_thickness = element->design().thickness();
83 int readout_side = element->design().readoutSide();
84
85 float pixel_size_xphi = element->design().phiPitch();
86 float pixel_size_xeta = element->design().etaPitch();
87
88 Amg::Vector3D element_center = element->center();
89 ATH_MSG_DEBUG("x and y, z are: " << element_center.x() << ", "
90 << element_center.y() << ", "
91 << element_center.z());
92 float element_r = sqrt(element_center.x() * element_center.x() +
93 element_center.y() * element_center.y());
94
95 const CLHEP::Hep3Vector start_pos(hit.localStartPosition());
96 const CLHEP::Hep3Vector end_pos(hit.localEndPosition());
97
98 ATH_MSG_DEBUG("start_pos xEta=" << start_pos[SiHit::xEta]
99 << ", xPhi=" << start_pos[SiHit::xPhi]
100 << ", xDep=" << start_pos[SiHit::xDep]);
101
102 CLHEP::Hep3Vector direction = end_pos - start_pos;
103 float deposit_length = direction.mag();
104 int n_steps = deposit_length / m_small_step_length + 1;
105 // the start and end pos can sit at the same position. Resizing the
106 // zero-length Hep3Vector would cause an error, so this we protect against
107 if (deposit_length > 1.e-10) {
108 direction.setMag(deposit_length / static_cast<float>(n_steps));
109 }
110
111 float tot_eloss = hit.energyLoss();
112 // FIXME using the mean ionization energy in Silicon
113 const float tot_charge = tot_eloss / (3.62 * CLHEP::eV) * Gaudi::Units::eplus;
114
115 float charge_per_step = tot_charge / static_cast<float>(n_steps);
116
117 // FIXME is this correct? does the eventTime include a "later" truth event and
118 // the meanTime is just the TOF?
119 ATH_MSG_DEBUG(">>>>>>> before processing, event_t, t, E, r: "
120 << timed_hit_ptr.eventTime() << ", " << hit.meanTime() << ", "
121 << tot_eloss << ", " << element_r);
122
123 if (m_smear_meantime) {
124 time_of_flight += CLHEP::RandGaussZiggurat::shoot(
125 rndm_engine, 0.0f,
126 m_hgtd_time_resolution_tool->timeResolution(tot_charge, element_r,
127 0.0));
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}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x)
Copyright (C) 2002-2025 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