ATLAS Offline Software
Loading...
Searching...
No Matches
TRTTimeCorrection.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 "TRTTimeCorrection.h"
6
7//TRT detector information:
10
11#include "TRTDigSettings.h"
12
14//For speed of light:
15#include "CLHEP/Units/PhysicalConstants.h"
16
17#include "Identifier/Identifier.h"
18#include "GaudiKernel/IService.h"
19
20
21//__________________________________________________________________________________________________________
23 const InDetDD::TRT_DetectorManager* detmgr,
24 const TRT_ID* trt_id,
25 const ITRT_CalDbTool* calDbTool)
26 : AthMessaging("TRTTimeCorrection"),
27 m_settings(digset), m_detmgr(detmgr), m_trt_id(trt_id),
28 m_subdetectorMask(0x00200000), m_right5Bits(0x0000001F),
29 m_shift5Bits(5), m_shift10Bits(10), m_shift15Bits(15), m_notInitVal(-999999.0), m_trtcaldbtool(calDbTool)
30{
31 Initialize();
32}
33
34
35//__________________________________________________________________________________________________________
37
38//__________________________________________________________________________________________________________
40
41 m_signalPropagationSpeed = m_settings->signalPropagationSpeed() ;
42 m_lengthDeadRegion = m_settings->lengthOfDeadRegion();
43 m_maxVertexDisplacement = m_settings->maxVertexDisplacement();
44 m_timeShiftPhiSectSymmetry = m_settings->timeshiftsSymmetricForPhiSectors();
45 m_getT0FromData = m_settings->getT0FromData();
46
48 ATH_MSG_ERROR("Could not find TRT_CalDbTool => cannot use t0 of data.");
49 m_getT0FromData=false;
50 }
51
52 const InDetDD::TRT_Numerology *numerology(m_detmgr->getNumerology());
53
54 const unsigned int nbarrelphi(m_timeShiftPhiSectSymmetry ? 1 : numerology->getNBarrelPhi());
55 const unsigned int nendcapphi(m_timeShiftPhiSectSymmetry ? 1 : numerology->getNEndcapPhi());
56
57 //Initialize barrel max timeshift arrays:
58 m_timeShiftForBarrelStraws.resize(nbarrelphi);
59 for (auto & timeShiftForBarrelStraw : m_timeShiftForBarrelStraws) {
60 timeShiftForBarrelStraw.resize(numerology->getNBarrelRings());
61 for (unsigned int iRing = 0; iRing < timeShiftForBarrelStraw.size(); ++iRing) {
62 timeShiftForBarrelStraw[iRing].resize(numerology->getNBarrelLayers(iRing));
63 for (unsigned int iLayer = 0; iLayer < timeShiftForBarrelStraw[iRing].size(); ++iLayer) {
64 if (m_detmgr->getBarrelElement(0,iRing,0,iLayer)) {
65 unsigned int nstraws_in_layer = m_detmgr->getBarrelElement(0,iRing,0,iLayer)->nStraws();
66 timeShiftForBarrelStraw[iRing][iLayer].assign(nstraws_in_layer,m_notInitVal);
67 }
68 }
69 }
70 }
71
72 //Initialize endcap max timeshift arrays:
73 m_timeShiftForEndCapPlanes.resize(nendcapphi);
74 for (auto & timeShiftForEndCapPlane : m_timeShiftForEndCapPlanes) {
75 timeShiftForEndCapPlane.resize(numerology->getNEndcapWheels());
76 for (unsigned int iWheel = 0; iWheel < timeShiftForEndCapPlane.size(); ++iWheel) {
77 timeShiftForEndCapPlane[iWheel].assign(numerology->getNEndcapLayers(iWheel),m_notInitVal);
78 }
79 }
80
81 //Initialize barrel direct/reflected distances array
84 for (unsigned int iRing = 0; iRing < m_directDistsForBarrelLayers.size(); ++iRing) {
85 m_directDistsForBarrelLayers[iRing].assign(numerology->getNBarrelLayers(iRing),m_notInitVal);
86 m_reflectedDistsForBarrelLayers[iRing].assign(numerology->getNBarrelLayers(iRing),m_notInitVal);
87 };
88
89 //Initialize endcap direct/reflected distances array
92
93}
94
95//__________________________________________________________________________________________________________
96double TRTTimeCorrection::TimeShift(const int& strawID) {
97
98 //TODO: Use hit id helpers (but resolve efficiency issues first).
99
100 double timeshift=0.;
101
102 //Layer and phi index are needed for both endcap and barrel:
103 const unsigned int iLayer((strawID >> m_shift5Bits) & m_right5Bits);
104 const unsigned int iPhi(m_timeShiftPhiSectSymmetry ? 0 : ( (strawID >> m_shift10Bits) & m_right5Bits ));
105
106 if (strawID & m_subdetectorMask) {
107
108 //===// EndCap //===//
109
110 const unsigned int iWheel((strawID >> m_shift15Bits) & m_right5Bits);
111
112 //Sanity check:
113 if (iPhi>=m_timeShiftForEndCapPlanes.size()||
114 iWheel>=m_timeShiftForEndCapPlanes[iPhi].size()||
115 iLayer>=m_timeShiftForEndCapPlanes[iPhi][iWheel].size()) {
117 ATH_MSG_ERROR("TimeCorrection::TimeShift: (iWheel,iLayer) = ("
118 << iWheel << ", " << iLayer << ") out of bounds! Returning 0.");
119 } else {
120 ATH_MSG_ERROR("TimeCorrection::TimeShift: (iPhi,iWheel,iLayer) = ("
121 << iPhi << ", " << iWheel << ", " << iLayer << ") out of bounds! Returning 0.");
122 }
123 return 0.0;
124 }
125
126 timeshift = m_timeShiftForEndCapPlanes[iPhi][iWheel][iLayer];
127
128 if (timeshift==m_notInitVal) {
129 //We need to initialize
130 timeshift = calculateTimeShift_EndCap(iPhi,iWheel,iLayer,strawID);
131 m_timeShiftForEndCapPlanes[iPhi][iWheel][iLayer] = timeshift;
132 }
133
134 } else {
135
136 //===// Barrel //===//
137
138 const unsigned int iRing((strawID >> m_shift15Bits) & m_right5Bits);
139 const unsigned int iStraw(strawID & m_right5Bits);
140
141 //Sanity check:
142 if (iPhi>=m_timeShiftForBarrelStraws.size()||
143 iRing>=m_timeShiftForBarrelStraws[iPhi].size()||
144 iLayer>=m_timeShiftForBarrelStraws[iPhi][iRing].size()||
145 iStraw>=m_timeShiftForBarrelStraws[iPhi][iRing][iLayer].size()) {
147 ATH_MSG_ERROR("TimeCorrection::TimeShift: (iRing,iLayer,iStraw) = ("
148 << iRing << ", " << iLayer << ", " << iStraw
149 << ") out of bounds! Returning 0.");
150 } else {
151 ATH_MSG_ERROR("TimeCorrection::TimeShift: (iPhi,iRing,iLayer,iStraw) = ("
152 << iPhi << ", " << iRing << ", " << iLayer << ", " << iStraw
153 << ") out of bounds! Returning 0.");
154 }
155 return 0.0;
156 }
157
158 timeshift = m_timeShiftForBarrelStraws[iPhi][iRing][iLayer][iStraw];
159
160 if (timeshift==m_notInitVal) {
161 //We need to initialize
162 timeshift = calculateTimeShift_Barrel(iPhi,iRing,iLayer,iStraw,strawID);
163 m_timeShiftForBarrelStraws[iPhi][iRing][iLayer][iStraw] = timeshift;
164 }
165
166 }
167
168 return timeshift;
169}
170
171//__________________________________________________________________________________________________________
172double TRTTimeCorrection::calculateTimeShift_Barrel( const unsigned int& iPhi,
173 const unsigned int& iRing,
174 const unsigned int& iLayer,
175 const unsigned int& iStraw,
176 const int strawID) {
177
178 const InDetDD::TRT_BarrelElement * barrel_element(m_detmgr->getBarrelElement(0/*positive*/,
179 iRing, iPhi, iLayer ));
180
181 //Sanity checks:
182 if (!barrel_element) {
183 ATH_MSG_ERROR("calculateTimeShift_Barrel: Could not get element for iRing = "
184 << iRing <<" and iLayer = "<<iLayer<<". Timeshift becomes 0.");
185 return 0.0;
186 }
187
188 if (iStraw >= barrel_element->nStraws()) {
189 ATH_MSG_ERROR("calculateTimeShift_Barrel: Trying to access iStraw "
190 << iStraw <<" in an element with "<<barrel_element->nStraws()<<" straws (iRing="
191 << iRing <<",iLayer="<<iLayer<<"). Timeshift becomes 0.");
192 return 0.0;
193 }
194
195 //Straw endpoints for the straw lying along the z-axis:
196 Amg::Vector3D strawend1(0,0, barrel_element->strawLength()*0.5 );
197 Amg::Vector3D strawend2(0,0, -(barrel_element->strawLength()*0.5) );
198
199 //And here put into their proper global place:
200 strawend1 = barrel_element->strawTransform(iStraw) * strawend1;
201 strawend2 = barrel_element->strawTransform(iStraw) * strawend2;
202
203 return calculateTimeShiftFromStrawEnds(strawend1,strawend2,strawID);
204
205}
206
207//__________________________________________________________________________________________________________
208double TRTTimeCorrection::calculateTimeShift_EndCap( const unsigned int& iPhi,
209 const unsigned int& iWheel,
210 const unsigned int& iLayer,
211 const int strawID) {
212
213 const InDetDD::TRT_EndcapElement * ec_element(m_detmgr->getEndcapElement(0/*positive*/,
214 iWheel, iLayer, iPhi ));
215
216 //Sanity check:
217 if (!ec_element) {
218 ATH_MSG_ERROR("calculateTimeShift_EndCap: Could not get element for iWheel = "
219 << iWheel <<" and iLayer = "<<iLayer<<". Timeshift becomes 0.");
220 return 0.0;
221 }
222
223 //Straw endpoints for the straw lying along the z-axis:
224 Amg::Vector3D strawend1(0,0, ec_element->strawLength() * 0.5 );
225 Amg::Vector3D strawend2(0,0, ec_element->strawLength() * (-0.5) );
226
227 //And here put into their proper global place:
228 strawend1 = ec_element->strawTransform(0) * strawend1;
229 strawend2 = ec_element->strawTransform(0) * strawend2;
230
231 return calculateTimeShiftFromStrawEnds(strawend1,strawend2,strawID); //,m_lvl
232
233}
234
235//__________________________________________________________________________________________________________
237 const Amg::Vector3D& strawend2_globalcoord,
238 const int strawID ) {
239
240 //The two (hopefully relevant) extreme points of the vertex region:
241 Amg::Vector3D vertexExtension1( m_settings->timeOffsetCalcVertexX(),
242 m_settings->timeOffsetCalcVertexY(),
243 m_settings->timeOffsetCalcVertexZ() + m_maxVertexDisplacement);
244 Amg::Vector3D vertexExtension2( m_settings->timeOffsetCalcVertexX(),
245 m_settings->timeOffsetCalcVertexY(),
246 m_settings->timeOffsetCalcVertexZ() - m_maxVertexDisplacement);
247
248 //Minimum distance between vertex region and the straw ends:
249 // const double mindisttoend1(std::min(strawend1_globalcoord.distance(vertexExtension1),
250 // strawend1_globalcoord.distance(vertexExtension2)));
251 const double mindisttoend1(std::min((strawend1_globalcoord-vertexExtension1).mag(),
252 (strawend1_globalcoord-vertexExtension2).mag()));
253 // const double mindisttoend2(std::min(strawend2_globalcoord.distance(vertexExtension1),
254 // strawend2_globalcoord.distance(vertexExtension2)));
255 const double mindisttoend2(std::min((strawend2_globalcoord-vertexExtension1).mag(),
256 (strawend2_globalcoord-vertexExtension2).mag()));
257
258 //Just a sanity check here:
259 if ( (mindisttoend2<mindisttoend1) == m_settings->electronicsAreAtFarEnd() ) {
260 ATH_MSG_WARNING("It would seem that the local z-coordinate of a test straw grows TOWARDS"
261 <<" the electronics ends. This will give trouble elsewhere!!");
262 }
263
264 double shift = 1.0; // 1 ns (negative) overall shift for the whole TRT detector. Now set in stone.
265 // Used to be set with overallT0Shift() & overallT0ShiftShortBarrel()
266 // Note: if you change this then you need to set ToolSvc.InDetTRT_DriftFunctionTool.MCTuningShift
267
268 if (m_settings->getT0FromData()) {
269 bool identifierOK;
270 const Identifier idStraw(getIdentifier(strawID, identifierOK));
271 if (identifierOK) {
272 shift = m_trtcaldbtool->getT0(idStraw);
273 } else {
274 ATH_MSG_ERROR("Attempt to use t0 from data failed: TRTCalDbSvc was not able to supply t0 for straw with identifier: "
275 << idStraw << ". Please set getT0FromData=false in jobOptions and run again");
276 }
277 }
278
279 if (m_settings->electronicsAreAtFarEnd())
280 return std::max(mindisttoend1,mindisttoend2) / (m_settings->distanceToTimeFactor() * CLHEP::c_light) - shift;
281 else
282 return std::min(mindisttoend1,mindisttoend2) / (m_settings->distanceToTimeFactor() * CLHEP::c_light) - shift;
283
284}
285
286//__________________________________________________________________________________________________________
287void TRTTimeCorrection::PropagationTime(const int& strawID, const double& meanZ,
288 double& propagationTime1, double& propagationTime2) {
289
290 double direct_distance, reflect_distance;
291
292 if (strawID & m_subdetectorMask) {
293
294 //===// EndCap //===//
295 const unsigned int iWheel((strawID >> m_shift15Bits) & m_right5Bits);
296 direct_distance = m_directDistsForEndCapWheels[iWheel];
297 reflect_distance = m_reflectedDistsForEndCapWheels[iWheel];
298
299 if (direct_distance==m_notInitVal) {
300 //We need to initialize
301 calculateSignalDists_EndCap(iWheel,direct_distance,reflect_distance);
302 m_directDistsForEndCapWheels[iWheel] = direct_distance;
303 m_reflectedDistsForEndCapWheels[iWheel] = reflect_distance;
304 };
305
306 //Z is counted positive AWAY from the electronics:
307 propagationTime1 = (direct_distance + meanZ) / m_signalPropagationSpeed;
308 propagationTime2 = (reflect_distance - meanZ) / m_signalPropagationSpeed;
309
310 } else {
311
312 //===// Barrel //===//
313 const unsigned int iRing((strawID >> m_shift15Bits) & m_right5Bits);
314 const unsigned int iLayer((strawID >> m_shift5Bits) & m_right5Bits);
315 direct_distance = m_directDistsForBarrelLayers[iRing][iLayer];
316 reflect_distance = m_reflectedDistsForBarrelLayers[iRing][iLayer];
317
318 if (direct_distance==m_notInitVal) {
319 //We need to initialize
320 calculateSignalDists_Barrel(iRing,iLayer,direct_distance,reflect_distance);
321 m_directDistsForBarrelLayers[iRing][iLayer] = direct_distance;
322 m_reflectedDistsForBarrelLayers[iRing][iLayer] = reflect_distance;
323 };
324
325 //Z is counted positive AWAY from the electronics:
326 propagationTime1 = (direct_distance + meanZ) / m_signalPropagationSpeed;
327 propagationTime2 = (reflect_distance - meanZ) / m_signalPropagationSpeed;
328
329 }
330
331 }
332
333//__________________________________________________________________________________________________________
334void TRTTimeCorrection::calculateSignalDists_Barrel(const unsigned int& iRing, const unsigned int& iLayer,
335 double& direct_dist, double& reflect_dist ) const {
336
337 //We need to calculate the distance along the wire that the signal
338 //has to travel before it reaches the electronics. Both if it goes
339 //directly to the electronics and if it goes via a reflection in the
340 //other end of the wire.
341 //
342 //The signal starts in the middle of the active region.
343 //
344 //In addition to the length of the active gas, the signal also has
345 //to go through the little dead region at the end.
346
347 const InDetDD::TRT_BarrelElement * barrel_element(m_detmgr->getBarrelElement(0,//positive,
348 iRing,//moduleIndex,
349 0,//int phiIndex,
350 iLayer));//strawLayerIndex
351
352 direct_dist = 0.5*barrel_element->strawLength() + m_lengthDeadRegion;
353 reflect_dist = 1.5*barrel_element->strawLength() + 3*m_lengthDeadRegion;
354}
355
356//__________________________________________________________________________________________________________
358 double& direct_dist,
359 double& reflect_dist ) const {
360
361 //For an explanation, please read the comment in calculateSignalDists_Barrel
362
363 const InDetDD::TRT_EndcapElement * ec_element(m_detmgr->getEndcapElement(0,//positive,
364 iWheel,//wheelIndex,
365 0,//strawLayerIndex,
366 0));//phiIndex
367
368 direct_dist = 0.5*ec_element->strawLength() + m_lengthDeadRegion;
369 reflect_dist = 1.5*ec_element->strawLength() + 3*m_lengthDeadRegion;
370}
371
372//_____________________________________________________________________________
374 bool & statusok)
375{
376 statusok = true;
377
378 Identifier IdStraw;
379 Identifier IdLayer;
380
381 const int mask(0x0000001F);
382 const int word_shift(5);
383 int trtID, ringID, moduleID, layerID, strawID;
384 int wheelID, planeID, sectorID;
385
386 const InDetDD::TRT_BarrelElement *barrelElement;
387 const InDetDD::TRT_EndcapElement *endcapElement;
388
389 if ( !(hitID & 0x00200000) ) { // barrel
390 strawID = hitID & mask;
391 hitID >>= word_shift;
392 layerID = hitID & mask;
393 hitID >>= word_shift;
394 moduleID = hitID & mask;
395 hitID >>= word_shift;
396 ringID = hitID & mask;
397 trtID = hitID >> word_shift;
398
399 barrelElement =
400 m_detmgr->getBarrelElement(trtID, ringID, moduleID, layerID);
401 if ( barrelElement ) {
402
403 IdLayer = barrelElement->identify();
404 IdStraw = m_trt_id->straw_id(IdLayer, strawID);
405 } else {
406 ATH_MSG_ERROR("Could not find detector element for barrel identifier with "
407 << "(ipos,iring,imod,ilayer,istraw) = ("
408 << trtID << ", " << ringID << ", " << moduleID << ", "
409 << layerID << ", " << strawID << ")");
410 statusok = false;
411 }
412 } else { // endcap
413 strawID = hitID & mask;
414 hitID >>= word_shift;
415 planeID = hitID & mask;
416 hitID >>= word_shift;
417 sectorID = hitID & mask;
418 hitID >>= word_shift;
419 wheelID = hitID & mask;
420 trtID = hitID >> word_shift;
421
422 // change trtID (which is 2/3 for endcaps) to use 0/1 in getEndcapElement
423 if (trtID == 3) trtID = 0;
424 else trtID = 1;
425
426 endcapElement =
427 m_detmgr->getEndcapElement(trtID, wheelID, planeID, sectorID);
428
429 if ( endcapElement ) {
430 IdLayer = endcapElement->identify();
431 IdStraw = m_trt_id->straw_id(IdLayer, strawID);
432 } else {
433 ATH_MSG_ERROR("Could not find detector element for endcap identifier with "
434 << "(ipos,iwheel,isector,iplane,istraw) = ("
435 << trtID << ", " << wheelID << ", " << sectorID << ", "
436 << planeID << ", " << strawID << ")");
437 ATH_MSG_ERROR("If this happens very rarely, don't be alarmed (it is a Geant4 'feature')");
438 ATH_MSG_ERROR("If it happens a lot, you probably have misconfigured geometry in the sim. job.");
439 statusok = false;
440 }
441
442 }
443
444 return IdStraw;
445}
Scalar mag() const
mag method
#define ATH_MSG_ERROR(x)
#define ATH_MSG_WARNING(x)
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
abstract interface to TRT calibration constants
Extended TRT_BaseElement to describe a TRT readout element, this is a planar layer with n ( order of ...
virtual const double & strawLength() const override final
Get the length of the straws (active length):
unsigned int nStraws() const
Number of straws in the element.
virtual Identifier identify() const override final
identifier of this detector element:
const Amg::Transform3D & strawTransform(unsigned int straw) const
Straw transform - fast access in array, in Tracking frame: Amg.
The Detector Manager for all TRT Detector elements, it acts as the interface to the detector elements...
Extended class of a TRT_BaseElement to describe a readout elment in the endcap.
virtual const double & strawLength() const override
Active straw length.
Helper class to organize the straw elements on TRT readout elements.
unsigned int getNEndcapWheels() const
unsigned int getNEndcapPhi() const
unsigned int getNBarrelPhi() const
unsigned int getNBarrelRings() const
unsigned int getNBarrelLayers(unsigned int iMod) const
unsigned int getNEndcapLayers(unsigned int iWheel) const
Class containing parameters and settings used by TRT digitization.
TRTTimeCorrection(const TRTDigSettings *digset, const InDetDD::TRT_DetectorManager *detmgr, const TRT_ID *, const ITRT_CalDbTool *)
std::vector< std::vector< double > > m_directDistsForBarrelLayers
Cached distances.
void calculateSignalDists_EndCap(const unsigned int &iWheel, double &direct_dist, double &reflect_dist) const
Calculate the distance along the wire the signal travels before reaching the electronics.
const unsigned int m_subdetectorMask
std::vector< std::vector< double > > m_reflectedDistsForBarrelLayers
Cached distances.
const TRTDigSettings * m_settings
std::vector< double > m_directDistsForEndCapWheels
Cached distances.
std::vector< std::vector< std::vector< double > > > m_timeShiftForEndCapPlanes
Cached timeshifts.
const TRT_ID * m_trt_id
const unsigned int m_shift10Bits
const double m_notInitVal
Value used to denote an uninitialized value.
const unsigned int m_right5Bits
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.
std::vector< double > m_reflectedDistsForEndCapWheels
Cached distances.
void calculateSignalDists_Barrel(const unsigned int &iRing, const unsigned int &iLayer, double &direct_dist, double &reflect_dist) const
Calculate the distance along the wire the signal travels before reaching the electronics.
const ITRT_CalDbTool * m_trtcaldbtool
Identifier getIdentifier(int hitID, bool &statusok)
double calculateTimeShift_EndCap(const unsigned int &iPhi, const unsigned int &iWheel, const unsigned int &iLayer, const int strawID)
Time shift for end cap straws.
double calculateTimeShift_Barrel(const unsigned int &iPhi, const unsigned int &iRing, const unsigned int &iLayer, const unsigned int &iStraw, const int strawID)
Time shift for barrel straws.
const unsigned int m_shift5Bits
double calculateTimeShiftFromStrawEnds(const Amg::Vector3D &strawend1_globalcoord, const Amg::Vector3D &strawend2_globalcoord, const int strawID)
Time shift from straw endpoints in global system.
const unsigned int m_shift15Bits
std::vector< std::vector< std::vector< std::vector< double > > > > m_timeShiftForBarrelStraws
Cached timeshifts.
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 ...
const InDetDD::TRT_DetectorManager * m_detmgr
This is an Identifier helper class for the TRT subdetector.
Definition TRT_ID.h:82
Eigen::Matrix< double, 3, 1 > Vector3D