ATLAS Offline Software
Loading...
Searching...
No Matches
TRT_ToT_dEdx.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "TRT_ToT_dEdx.h"
7
8#include "GaudiKernel/MsgStream.h"
9#include "GaudiKernel/IToolSvc.h"
10
13
14#include "TrkSurfaces/Surface.h"
15
16#include "GaudiKernel/IChronoStatSvc.h"
17
18#include "TF1.h"
19
24#include <cmath>
25#include <limits>
26
27namespace{
28 bool
29 inRange(const double val, const double lo, const double hi){
30 return (val>lo) and (val<hi);
31 }
32}
33
34// constructor
35TRT_ToT_dEdx::TRT_ToT_dEdx(const std::string& t, const std::string& n, const IInterface* p) : AthAlgTool(t,n,p)
36{
37 declareInterface<ITRT_ToT_dEdx>(this);
38}
39
40
41// destructor
43
44
45
46// initialize
48{
49
50 MsgStream log(msgSvc(), name());
51
52 // retrieve TRT-ID helper
53
54 StatusCode sc = detStore()->retrieve(m_trtId, "TRT_ID");
55 if (sc.isFailure()){
56 ATH_MSG_ERROR ( "Could not get TRT_ID helper !" );
57 return StatusCode::FAILURE;
58 }
59
60 // Initialize ReadHandleKey and ReadCondHandleKey
61 ATH_CHECK(m_rdhkEvtInfo.initialize());
62 ATH_CHECK(m_ReadKey.initialize());
63 ATH_CHECK(m_assoTool.retrieve());
64 ATH_CHECK( m_localOccTool.retrieve() );
66
69 ATH_MSG_ERROR("Property TRT_dEdx_useTrackPartWithGasType has an invalid "
70 << "value: " << m_useTrackPartWithGasType);
71 return StatusCode::FAILURE;
72 }
73
74 return StatusCode::SUCCESS;
75}
76
77bool
78TRT_ToT_dEdx::isGoodHit(const EventContext& ctx,
79 const Trk::TrackStateOnSurface* trackState,
80 bool useHitsHT,
81 double& length) const
82{
83 const Trk::MeasurementBase* trkM = trackState->measurementOnTrack();
84 if (!trkM) {
85 return false;
86 }
87
88 // Check if this is RIO on track
89 // and if yes check if is TRT Drift Circle
90 // then set the ptr
91 const InDet::TRT_DriftCircleOnTrack* driftcircle = nullptr;
93 const Trk::RIO_OnTrack* tmpRio = static_cast<const Trk::RIO_OnTrack*>(trkM);
95 driftcircle = static_cast<const InDet::TRT_DriftCircleOnTrack*>(tmpRio);
96 }
97 }
98
99 if (!driftcircle) {
100 return false;
101 }
102
103 const Trk::TrackParameters* trkP = trackState->trackParameters();
104 if(trkP==nullptr)return false;
105
106 double Trt_Rtrack = std::abs(trkP->parameters()[Trk::locR]);
107 double Trt_RHit = std::abs(driftcircle->localParameters()[Trk::driftRadius]);
108 double error = std::sqrt(driftcircle->localCovariance()(Trk::driftRadius,Trk::driftRadius));
109
110 if (trackState->type(Trk::TrackStateOnSurface::Outlier)) return false; //Outliers
111 if (m_useZeroRHitCut && Trt_RHit==0 && error>1.) return false; //Select precision hits only
112 if ((Trt_Rtrack >= m_trackConfig_maxRtrack) || (Trt_Rtrack <= m_trackConfig_minRtrack)) return false; // drift radius close to wire or wall
113
115
116 if (m_divideByL and length < 1.7) return false; // Length in the straw
117
118 if (!useHitsHT) {
119 int TrtHl = driftcircle->highLevel();
120 if (TrtHl==1) return false;
121 }
122
123 if (m_useTrackPartWithGasType != kUnset) { // don't preselect hits
124 if(m_useTrackPartWithGasType != gasTypeInStraw(ctx,trackState)) return false;
125 }
126
127 if (driftcircle->prepRawData()->timeOverThreshold()==0.) return false; // If ToT for this hit equal 0, skip it.
128
129 return true;
130}
131
132double
133TRT_ToT_dEdx::dEdx(const EventContext& ctx,
134 const Trk::Track* track,
135 bool useHitsHT,
136 std::optional<float> localOccupancy) const
137{
138 ATH_MSG_DEBUG("dEdx()");
139
140 double nVtx=-1.;
141 // Event information
143 if(!eventInfoDecor.isPresent()) {
144 REPORT_MESSAGE(MSG::FATAL) << "EventInfo decoration not available!";
145 return 0;
146 }
147
148 // Average interactions per crossing for the current BCID
149 // TODO: we should really not hard-code a mu to nVtx conversion
150 double mu = eventInfoDecor(0);
151 if(m_isData) {
152 nVtx = 1.3129 + 0.716194*mu + (-0.00475074)*mu*mu;
153 }
154 else {
155 nVtx = 1.0897 + 0.748287*mu + (-0.00421788)*mu*mu;
156 }
157
158 if (!track) {
159 return 0;
160 }
161 const Trk::TrackStates* vtsos = track->trackStateOnSurfaces();
162 if (!vtsos) {
163 return 0;
164 }
165
166 EGasType gasType;
169 size_t vtos_size = vtsos->size();
170 double correctionFactor = 1.;
171
173 std::vector<double> vecToT;
174 vecToT.reserve(vtos_size);
175 double ToTsum = 0;
176
177 for ( ; itr!=itre ; ++itr) {
178 double length = 0;
179 if ( isGoodHit(ctx,(*itr), useHitsHT, length)) {
180 double ToT_correct = correctToT_corrRZ(ctx,*itr, length);
182 correctionFactor = hitOccupancyCorrection(ctx,*itr);
183 ToT_correct*=correctionFactor;
184 }
185 vecToT.push_back(ToT_correct);
186 }
187 }
188
189 sort(vecToT.begin(), vecToT.end());
190 size_t nhits = vecToT.size();
191
192 if (m_divideByL) {
193 nhits-=m_nTrunkateHits;
194 }
195
196 // Boost speed
197 if (nhits<1) return 0.0;
198
199 ToTsum = std::accumulate(vecToT.begin(), vecToT.end(), 0);
201 correctionFactor=trackOccupancyCorrection(ctx,track, useHitsHT,localOccupancy);
202 } else {
203 correctionFactor=correctNormalization(ctx,nVtx);
204 }
205 ToTsum*=correctionFactor;
206 return ToTsum/nhits;
207 }
208
210 std::vector<double> vecToT_Xe;
211 vecToT_Xe.reserve(vtos_size/2);
212 std::vector<double> vecToT_Ar;
213 vecToT_Ar.reserve(vtos_size/2);
214 std::vector<double> vecToT_Kr;
215
218 "dEdX_Estimator():: Using m_toolScenario="
219 << m_toolScenario << " scenario m_useTrackPartWithGasType is set to"
221 << ", but kUnset is requiered. Check you tool configuration.");
222 }
223
224 for ( ; itr!=itre ; ++itr) {
225 double length=0;
226 if (isGoodHit(ctx,(*itr), useHitsHT, length)) {
227 gasType=gasTypeInStraw(ctx,*itr);
228 double ToT_correct = correctToT_corrRZ(ctx,*itr, length);
230 correctionFactor = hitOccupancyCorrection(ctx,*itr);
231 }
232 ToT_correct*=correctionFactor;
233 if(gasType==kXenon) {
234 vecToT_Xe.push_back(ToT_correct);
235 } else if (gasType==kArgon) {
236 vecToT_Ar.push_back(ToT_correct);
237 } else if (gasType==kKrypton) {
238 vecToT_Kr.push_back(ToT_correct);
239 } else {
240 ATH_MSG_ERROR("dEdX_Estimator():: During scenario kAlgReweight variable gasTypeInStraw got value kUnset.");
241 }
242 }
243 }
244
245 sort(vecToT_Xe.begin(), vecToT_Xe.end());
246 sort(vecToT_Ar.begin(), vecToT_Ar.end());
247 sort(vecToT_Kr.begin(), vecToT_Kr.end());
248
249 size_t nhitsXe = vecToT_Xe.size();
250 size_t nhitsAr = vecToT_Ar.size();
251 size_t nhitsKr = vecToT_Kr.size();
252
253 if (m_divideByL) {
255 if (nhitsXe>=m_nTrunkateHits) nhitsXe-=m_nTrunkateHits;
256 if (nhitsAr>=m_nTrunkateHits) nhitsAr-=m_nTrunkateHits;
257 if (nhitsKr>=m_nTrunkateHits) nhitsKr-=m_nTrunkateHits;
258 } else {// kAlgReweightTrunkOne
259 int trunkGas = kUnset;
260 double maxToT = 0.;
261 if (nhitsXe>0 && vecToT_Xe.at(nhitsXe-1)>maxToT) {
262 trunkGas = kXenon;
263 maxToT = vecToT_Xe.at(nhitsXe-1);
264 }
265 if(nhitsAr>0 && vecToT_Ar.at(nhitsAr-1)>maxToT){
266 trunkGas = kArgon;
267 maxToT = vecToT_Ar.at(nhitsAr-1);
268 }
269 if (nhitsKr>0 && vecToT_Kr.at(nhitsKr-1)>maxToT) {
270 trunkGas = kKrypton;
271 }
272
273 if (trunkGas==kXenon) {
274 nhitsXe-=m_nTrunkateHits;
275 } else if (trunkGas==kArgon) {
276 nhitsAr-=m_nTrunkateHits;
277 } else if (trunkGas==kKrypton) {
278 nhitsKr-=m_nTrunkateHits;
279 }
280 }
281 }
282
283 size_t nhits = nhitsXe + nhitsAr + nhitsKr;
284 if(nhits<1) return 0.0;
285
286 double ToTsumXe = 0;
287 double ToTsumAr = 0;
288 double ToTsumKr = 0;
289 for (size_t i = 0; i < nhitsXe;i++) {
290 ToTsumXe+=vecToT_Xe[i];
291 }
292 for (size_t i = 0; i < nhitsAr;i++) {
293 ToTsumAr+=vecToT_Ar[i];
294 }
295 for (size_t i = 0; i < nhitsKr;i++) {
296 ToTsumKr+=vecToT_Kr[i];
297 }
298
299 ToTsumXe = (nhitsXe>0) ? ToTsumXe/nhitsXe : 0;
300 ToTsumAr = (nhitsAr>0) ? ToTsumAr/nhitsAr : 0;
301 ToTsumKr = (nhitsKr>0) ? ToTsumKr/nhitsKr : 0;
302 double ToTsum = ToTsumXe*nhitsXe + ToTsumAr*nhitsAr + ToTsumKr*nhitsKr;
303
305 correctionFactor =
306 trackOccupancyCorrection(ctx, track, true, localOccupancy);
307 } else {
308 correctionFactor = correctNormalization(ctx, nVtx);
309 }
310 ToTsum *= correctionFactor;
311
312 return ToTsum/nhits;
313 }
314
315 ATH_MSG_ERROR("dEdX_Estimator():: m_toolScenario has wrong value "<<m_toolScenario<<"");
316 return 0.;
317}
318
319double
320TRT_ToT_dEdx::usedHits(const EventContext& ctx,
321 const Trk::Track* track,
322 bool useHitsHT) const
323{
324 ATH_MSG_DEBUG("usedHits()");
325 EGasType gasType = kUnset;
326
327 if (!track) {
328 return 0;
329 }
330 const Trk::TrackStates* vtsos = track->trackStateOnSurfaces();
331 if (!vtsos) {
332 return 0;
333 }
334
337
339 int nhits =0;
340
341 for ( ; itr!=itre ; ++itr) {
342 double length=0;
343 if (isGoodHit(ctx,(*itr), useHitsHT, length)) {
344 nhits++;
345 }
346 }
347 if (m_divideByL) nhits -= m_nTrunkateHits;
348 return nhits;
350 int nhits = 0;
351 int nhitsXe = 0;
352 int nhitsAr = 0;
353 int nhitsKr = 0;
354
357 "usedHits_Estimator():: Using m_toolScenario="
358 << m_toolScenario << " scenario m_useTrackPartWithGasType is set to "
360 << ", but kUnset is required. Check you tool configuration.");
361 }
362
363 for ( ; itr!=itre ; ++itr) {
364 double length=0;
365 if ( isGoodHit(ctx,(*itr), useHitsHT, length)) {
366 gasType=gasTypeInStraw(ctx,*itr);
367 if (gasType==kXenon) {
368 nhitsXe++;
369 } else if (gasType==kArgon) {
370 nhitsAr++;
371 } else if (gasType==kKrypton) {
372 nhitsKr++;
373 } else {
374 ATH_MSG_ERROR("usedHits_Estimator():: During scenario kAlgReweight variable gasTypeInStraw got value kUnset.");
375 }
376 }
377 }
378
379 if (m_divideByL) {
381 if(nhitsXe>0) nhitsXe -= m_nTrunkateHits;
382 if(nhitsAr>0) nhitsAr -= m_nTrunkateHits;
383 if(nhitsKr>0) nhitsKr -= m_nTrunkateHits;
384 } else { // kAlgReweightTrunkOne
385 if(nhitsXe>0 || nhitsAr>0 || nhitsKr>0)
386 nhitsXe -= m_nTrunkateHits;
387 }
388 }
389
390 nhits = nhitsXe + nhitsAr + nhitsKr;
391 return nhits;
392 }
393
394 ATH_MSG_ERROR("usedHits_Estimator():: m_toolScenario has wrong value "<<m_toolScenario<<"");
395 return 0;
396}
397
398double
399TRT_ToT_dEdx::getProb(const EventContext& ctx,
400 const Trk::TrackStateOnSurface* itr,
401 const double dEdx_obs,
402 const double pTrk,
403 Trk::ParticleHypothesis hypothesis,
404 int nUsedHits) const
405{
406 EGasType gasType = gasTypeInStraw(ctx, itr);
407 return getProb(ctx,gasType, dEdx_obs, pTrk, hypothesis, nUsedHits);
408}
409
410double
411TRT_ToT_dEdx::getProb(const EventContext& ctx,
412 EGasType gasType,
413 const double dEdx_obs,
414 const double pTrk,
415 Trk::ParticleHypothesis hypothesis,
416 int nUsedHits) const
417{
418 ATH_MSG_DEBUG("getProb():: gasTypeInStraw = "<<gasType<<"");
419
421 const TRTDedxcorrection* dEdxCorrection{*readHandle};
422 if (dEdxCorrection==nullptr) {
423 ATH_MSG_ERROR(" getProb: Could not find any dEdxCorrection in CondStore. Return zero.");
424 return 0;
425 }
426
427 if(gasType==kUnset) {
428 ATH_MSG_DEBUG("getProb():: gasTypeInStraw set kUnset that is not allowed! Use gasTypeInStraw(*itr) to get gas type info for that hit first!");
429 ATH_MSG_DEBUG("getProb():: Now gasTypeInStraw sets to kXenon.");
430 gasType = kXenon;
431 }
432
433 double dEdx_pred = predictdEdx(ctx,gasType, pTrk, hypothesis);
434 if (dEdx_pred==0) return 0.0;
435 if (hypothesis==Trk::electron) {
436 // correction for pTrk in [MeV]
437 double factor = 1;
438 double correct = 1+factor*(0.045*log10(pTrk)+0.885-1);
439 dEdx_pred= dEdx_pred/correct;
440 }
441
442 double Resolution =
443 dEdxCorrection->resolution[gasType][0] +
444 dEdxCorrection->resolution[gasType][1] * (nUsedHits + 0.5) +
445 dEdxCorrection->resolution[gasType][2] * (nUsedHits + 0.5) *
446 (nUsedHits + 0.5) +
447 dEdxCorrection->resolution[gasType][3] * (nUsedHits + 0.5) *
448 (nUsedHits + 0.5) * (nUsedHits + 0.5);
449 if (hypothesis == Trk::electron) {
450 Resolution =
451 dEdxCorrection->resolutionElectron[gasType][0] +
452 dEdxCorrection->resolutionElectron[gasType][1] * (nUsedHits + 0.5) +
453 dEdxCorrection->resolutionElectron[gasType][2] * (nUsedHits + 0.5) *
454 (nUsedHits + 0.5) +
455 dEdxCorrection->resolutionElectron[gasType][3] * (nUsedHits + 0.5) *
456 (nUsedHits + 0.5) * (nUsedHits + 0.5);
457 }
458
459 double prob = std::exp( -0.5 * ( ( ( dEdx_obs - dEdx_pred ) / (Resolution*dEdx_pred) ) *
460 ( ( dEdx_obs - dEdx_pred ) / (Resolution*dEdx_pred) ) )) ;
461
462 ATH_MSG_DEBUG("getProb():: return "<<prob<<"");
463 return prob;
464}
465
466double
467TRT_ToT_dEdx::getTest(const EventContext& ctx,
468 const double dEdx_obs,
469 const double pTrk,
470 Trk::ParticleHypothesis hypothesis,
471 Trk::ParticleHypothesis antihypothesis,
472 int nUsedHits) const
473{
474 ATH_MSG_DEBUG("getTest()");
475
476 EGasType gasType = kUnset;
477 if ( dEdx_obs<=0. || pTrk<=0. || nUsedHits<=0 ) return 0.5;
478
479 double Pone = getProb(ctx,gasType, dEdx_obs,pTrk,hypothesis,nUsedHits);
480 double Ptwo = getProb(ctx,gasType, dEdx_obs,pTrk,antihypothesis,nUsedHits);
481 if ((Pone+Ptwo) != 0) {
482 ATH_MSG_DEBUG("getTest():: return "<<Pone/(Pone+Ptwo)<<"");
483 return Pone/(Pone+Ptwo);
484 } else {
485 return 0.5;
486 }
487}
488
489double
490TRT_ToT_dEdx::predictdEdx(const EventContext& ctx,
491 const Trk::TrackStateOnSurface* itr,
492 const double pTrk,
493 Trk::ParticleHypothesis hypothesis) const
494{
495 EGasType gasType = gasTypeInStraw(ctx, itr);
496 return predictdEdx(ctx,gasType, pTrk, hypothesis);
497}
498
499double
500TRT_ToT_dEdx::predictdEdx(const EventContext& ctx,
501 EGasType gasType,
502 const double pTrk,
503 Trk::ParticleHypothesis hypothesis) const
504{
505 ATH_MSG_DEBUG("predictdEdx(): gasTypeInStraw = " << gasType << "");
506
508 const TRTDedxcorrection* dEdxCorrection{ *readHandle };
509 if (dEdxCorrection == nullptr) {
510 ATH_MSG_ERROR(" predictdEdx: Could not find any dEdxCorrection in "
511 "CondStore. Return zero.");
512 return 0;
513 }
514
515 if (gasType == kUnset) {
517 "predictdEdx():: gasTypeInStraw set kUnset that is not allowed! Use "
518 "gasTypeInStraw(*itr) to get gas type info for that hit first!");
519 ATH_MSG_DEBUG("predictdEdx():: Now gasTypeInStraw sets to kXenon.");
520 gasType = kXenon;
521 }
522
523 double mass = Trk::ParticleMasses::mass[hypothesis];
524
525 double betaGamma = pTrk/mass;
527 // low momentum particle can create floating point error
528 // do we need the check in the log parameter in addition? will create CPU increase
529 // do we want to throw an assertion here?
530 if (pTrk < 100)
531 return 0;
532 if (m_divideByL) {
533 if (dEdxCorrection->paraDivideByLengthDedxP3[gasType] +
534 1. / (std::pow(betaGamma,
535 dEdxCorrection->paraDivideByLengthDedxP5[gasType])) <=
536 0)
537 return 0;
538 return dEdxCorrection->paraDivideByLengthDedxP1[gasType] /
539 std::pow(std::sqrt((betaGamma * betaGamma) /
540 (1. + (betaGamma * betaGamma))),
541 dEdxCorrection->paraDivideByLengthDedxP4[gasType]) *
542 (dEdxCorrection->paraDivideByLengthDedxP2[gasType] -
543 std::pow(std::sqrt((betaGamma * betaGamma) /
544 (1. + (betaGamma * betaGamma))),
545 dEdxCorrection->paraDivideByLengthDedxP4[gasType]) -
546 log(dEdxCorrection->paraDivideByLengthDedxP3[gasType] +
547 1. / (std::pow(
548 betaGamma,
549 dEdxCorrection->paraDivideByLengthDedxP5[gasType]))));
550 }
551 if (dEdxCorrection->paraDedxP3[gasType] +
552 1. / (std::pow(betaGamma, dEdxCorrection->paraDedxP5[gasType])) <=
553 0)
554 return 0;
555 return dEdxCorrection->paraDedxP1[gasType] /
556 std::pow(
557 std::sqrt((betaGamma * betaGamma) / (1. + (betaGamma * betaGamma))),
558 dEdxCorrection->paraDedxP4[gasType]) *
559 (dEdxCorrection->paraDedxP2[gasType] -
560 std::pow(
561 std::sqrt((betaGamma * betaGamma) / (1. + (betaGamma * betaGamma))),
562 dEdxCorrection->paraDedxP4[gasType]) -
563 log(dEdxCorrection->paraDedxP3[gasType] +
564 1. / (std::pow(betaGamma, dEdxCorrection->paraDedxP5[gasType]))));
565
566 //return 0;
567}
568
569double
570TRT_ToT_dEdx::mass(const EventContext& ctx,
571 const Trk::TrackStateOnSurface* itr,
572 const double pTrk,
573 double dEdx) const
574{
575 EGasType gasType = gasTypeInStraw(ctx,itr);
576
577 ATH_MSG_DEBUG("mass(): gasTypeInStraw = "<<gasType<<"");
578
580 const TRTDedxcorrection* dEdxCorrection{*readHandle};
581 if(dEdxCorrection==nullptr)
582 {
583 ATH_MSG_ERROR(" mass: Could not find any dEdxCorrection in CondStore. Return zero.");
584 return 0;
585 }
586
587 if(gasType==kUnset)
588 {
589 ATH_MSG_WARNING("mass():: gasTypeInStraw set kUnset that is not allowed! Use gasTypeInStraw(*itr) to get gas type info for that hit first!");
590 ATH_MSG_WARNING("mass():: Now gasTypeInStraw sets to kXenon.");
591 gasType = kXenon;
592 }
593 // only for testing purposes!!!!
594 // note that dE/dx has to be corrected on track level first before value can be transferred to mass
595 // this has to be tuned on user level
597 static const double bg_min = 0.001;
598 static const double bg_max = 3; // maximal allowed bg
599
600 static const std::string blumRolandiFunction =
601 "( [0]/sqrt( (x*x/([5]*[5]))/(1.+(x*x/([5]*[5]))) )^[3] ) * ([1] - sqrt( "
602 "(x*x/([5]*[5]))/(1.+(x*x/([5]*[5]))) )^[3] - log([2]+1./((x/[5])^[4]) ) )";
603
604 TF1 blumRolandi( "BR", blumRolandiFunction.c_str(), 0.7, 100000);
605
606 blumRolandi.SetParameters(dEdxCorrection->paraDedxP1[gasType],
607 dEdxCorrection->paraDedxP2[gasType],
608 dEdxCorrection->paraDedxP3[gasType],
609 dEdxCorrection->paraDedxP4[gasType],
610 dEdxCorrection->paraDedxP5[gasType],
611 1.);
612 //blumRolandi.SetParameters(&dEdxCorrection->para_dEdx_BB);
613 double betaGamma = blumRolandi.GetX(dEdx, bg_min, bg_max);
614
615 ATH_MSG_DEBUG("mass():: return "<<pTrk/betaGamma<<"");
616
617 return pTrk/betaGamma;
618}
619
620/* returns gas type for given straw */
621// TODO: move this functionality to TRT_StrawStatusSummaryTool.
623 const Trk::TrackStateOnSurface *itr) const
624{
625 const Trk::MeasurementBase* trkM = itr->measurementOnTrack();
626 if (!trkM) {
627 return kUnset;
628 }
629
630 // Check if this is RIO on track
631 //annd if yes check if is TRT Drift Circle
632 //then set the ptr
633 const InDet::TRT_DriftCircleOnTrack* driftcircle = nullptr;
635 const Trk::RIO_OnTrack* tmpRio = static_cast<const Trk::RIO_OnTrack*>(trkM);
637 driftcircle = static_cast<const InDet::TRT_DriftCircleOnTrack*>(tmpRio);
638 }
639 }
640
641 if (!driftcircle) {
642 return kUnset;
643 }
644
645 return gasTypeInStraw(ctx,driftcircle);
646}
647
650 const EventContext& ctx,
651 const InDet::TRT_DriftCircleOnTrack* driftcircle) const
652{
653 Identifier DCid = driftcircle->identify();
654
655 // getStatusHT returns enum {Undefined, Dead, Good, Xenon, Argon, Krypton, EmulatedArgon, EmulatedKrypton}.
656 // Our representation of 'GasType' is 0:Xenon, 1:Argon, 2:Krypton
657 EGasType GasType=kUnset; // kUnset is default
658 if (!m_TRTStrawSummaryTool.empty()) {
659 int stat = m_TRTStrawSummaryTool->getStatusHT(DCid,ctx);
660 if ( stat==2 || stat==3 ) { GasType = kXenon; } // Xe
661 else if ( stat==1 || stat==4 ) { GasType = kArgon; } // Ar
662 else if ( stat==5 ) { GasType = kKrypton; } // Kr
663 else if ( stat==6 ) { GasType = kArgon; } // Emulated Ar
664 else if ( stat==7 ) { GasType = kKrypton;
665 } // Emulated Kr
666 else {
668 "getStatusHT = "
669 << stat
670 << ", must be 'Good(2)||Xenon(3)' or 'Dead(1)||Argon(4)' or "
671 "'Krypton(5)' or 'EmulatedArgon(6)' or 'EmulatedKr(7)'!");
672 throw std::exception();
673 }
674 }
675
676 return GasType;
677}
678
680// Corrections
682
683double
684TRT_ToT_dEdx::correctNormalization(const EventContext& ctx, double nVtx) const
685{
687 const TRTDedxcorrection* dEdxCorrection{*readHandle};
688 if(dEdxCorrection==nullptr) {
689 ATH_MSG_ERROR(" correctNormalization: Could not find any dEdxCorrection in CondStore. Return zero.");
690 return 0;
691 }
692
693 EGasType gasType = static_cast<EGasType> (m_useTrackPartWithGasType.value());
695 if (nVtx<=0) nVtx=dEdxCorrection->normNzero[gasType];
696 double slope = dEdxCorrection->normSlopeTot[gasType];
697 double offset = dEdxCorrection->normOffsetTot[gasType];
698 if (m_divideByL){
699 slope = dEdxCorrection->normSlopeTotDivideByLength[gasType];
700 offset = dEdxCorrection->normOffsetTotDivideByLength[gasType];
701 }
702 double shift = dEdxCorrection->normOffsetData[gasType];
703 if(!m_isData)shift = 0;
704 return (slope*dEdxCorrection->normNzero[gasType]+offset)/(slope*nVtx+offset+shift);
705}
706
707double
708TRT_ToT_dEdx::correctToT_corrRZ(const EventContext& ctx,
709 const Trk::TrackStateOnSurface* itr,
710 double length) const
711{
712 const Trk::MeasurementBase* trkM = itr->measurementOnTrack();
713 const Trk::TrackParameters* trkP = itr->trackParameters();
714
715 // Check if this is RIO on track
716 // annd if yes check if is TRT Drift Circle
717 // then set the ptr
718 const InDet::TRT_DriftCircleOnTrack* driftcircle = nullptr;
719 if (trkM && trkM->type(Trk::MeasurementBaseType::RIO_OnTrack)) {
720 const Trk::RIO_OnTrack* tmpRio = static_cast<const Trk::RIO_OnTrack*>(trkM);
722 driftcircle = static_cast<const InDet::TRT_DriftCircleOnTrack*>(tmpRio);
723 }
724 }
725
726 if (!driftcircle) {
727 return 0;
728 }
729 if (driftcircle->prepRawData()==nullptr) {
730 return 0;
731 }
732
733 Identifier DCId = driftcircle->identify();
734 double timeOverThreshold = driftcircle->prepRawData()->timeOverThreshold();
735 if(timeOverThreshold==0) {
736 ATH_MSG_WARNING("correctToT_corrRZ(const Trk::TrackStateOnSurface *itr):: ToT="<<timeOverThreshold<<". We must cut that hit in isGoodHit() !");
737 return 0;
738 }
739 int hitPart = m_trtId->barrel_ec(DCId);
740 int StrawLayer = m_trtId->straw_layer(DCId);
741 int Layer = m_trtId->layer_or_wheel(DCId);
742 double hitRtrack = std::abs(trkP->parameters()[Trk::locR]);
743 EGasType gasType = gasTypeInStraw(ctx,itr);
744 if(gasType==kUnset) {
745 ATH_MSG_ERROR("correctToT_corrRZ(const Trk::TrackStateOnSurface *itr):: Gas type in straw is kUnset! Return ToT = 0");
746 return 0;
747 }
748
750 if(!m_corrected) return timeOverThreshold;
751 /* else correct */
752
753 double hitZ = driftcircle->globalPosition().z();
754 double trackx = driftcircle->globalPosition().x();
755 double tracky = driftcircle->globalPosition().y();
756 double hitPosR = std::sqrt(trackx*trackx+tracky*tracky);
757
760 double ToTmip = 1;
761 double valToT = 0;
762 if(m_divideByL){
763 if (abs(hitPart)==1) // Barrel
764 valToT = fitFuncBarrel_corrRZL(ctx,gasType, hitRtrack, hitZ, Layer, StrawLayer);
765 else // End-cap
766 valToT = fitFuncEndcap_corrRZL(ctx,gasType, hitRtrack, hitPosR, Layer, hitZ>0?1:(hitZ<0?-1:0));
767 }else{
768 if (abs(hitPart)==1) // Barrel
769 valToT = fitFuncBarrel_corrRZ(ctx,gasType, hitRtrack, hitZ, Layer, StrawLayer);
770 else // End-cap
771 valToT = fitFuncEndcap_corrRZ(ctx,gasType, hitRtrack, hitPosR, Layer, hitZ>0?1:(hitZ<0?-1:0));
772 }
773 if (std::isinf(valToT)) return 0.;
774 if (valToT!=0) return ToTmip*timeOverThreshold/valToT;
775 return 0.;
776}
777
778double
780 EGasType gasType,
781 double driftRadius,
782 double zPosition,
783 int Layer,
784 int StrawLayer) const
785{
786 if (Layer == 0 && StrawLayer < 9) {
787 return fitFuncBarrelShort_corrRZ(ctx,gasType, driftRadius, zPosition, StrawLayer);
788 }
789 return fitFuncBarrelLong_corrRZ(ctx,gasType, driftRadius, zPosition, Layer, StrawLayer);
790}
791
792double
794 EGasType gasType,
795 double driftRadius,
796 double radialPosition,
797 int Layer,
798 int sign) const
799{
803 double T0 = fitFuncPol_corrRZ(ctx,gasType, 0,driftRadius,Layer,0,sign,2);
804 double a = fitFuncPol_corrRZ(ctx,gasType, 1,driftRadius,Layer,0,sign,2);
805 return T0+a*radialPosition;
806}
807
808double
810 EGasType gasType,
811 double driftRadius,
812 double zPosition,
813 int Layer,
814 int StrawLayer) const
815{
821 double z = std::abs(zPosition);
822 int sign=1;
823 if(zPosition<0)sign=-1;
824 double l = 704.6;
825 // define set of parameters for negative and positive z positions
826 double T0 = fitFuncPol_corrRZ(ctx,gasType, 0,driftRadius,Layer,StrawLayer,sign,0);
827 double v = fitFuncPol_corrRZ(ctx,gasType, 1,driftRadius,Layer,StrawLayer,sign,0);
828 double s = fitFuncPol_corrRZ(ctx,gasType, 2,driftRadius,Layer,StrawLayer,sign,0);
829 //_in theory_ For IEEE-compatible type double, argument causes exp to overflow if outside [-708.4, 709.8]
830 //however, overflow still seen when argument is 702; so I restrict these to -600, 600
831 const double expArg=(z-l)/s;
832 if (not inRange(expArg, -600.0,600.0)){
833 return expArg>0 ? std::numeric_limits<double>::infinity():0.;
834 }
835 return T0+(z/v)*std::exp(expArg);
836}
837
838double
840 EGasType gasType,
841 double driftRadius,
842 double zPosition,
843 int StrawLayer) const
844{
848 double z = std::abs(zPosition);
849 int sign=1;
850 if(zPosition<0)sign=-1;
851 double T0 = fitFuncPol_corrRZ(ctx,gasType, 0,driftRadius,0,StrawLayer,sign,1);
852 double b = fitFuncPol_corrRZ(ctx,gasType, 1,driftRadius,0,StrawLayer,sign,1);
853 return T0+b*z;
854}
855
856double
857TRT_ToT_dEdx::fitFuncPol_corrRZ(const EventContext& ctx,
858 EGasType gasType,
859 int parameter,
860 double driftRadius,
861 int Layer,
862 int Strawlayer,
863 int sign,
864 int set) const
865{
867 const TRTDedxcorrection* dEdxCorrection{*readHandle};
868 if(dEdxCorrection==nullptr)
869 {
870 ATH_MSG_ERROR(" fitFuncPol_corrRZ: Could not find any dEdxCorrection in CondStore. Return zero.");
871 return 0;
872 }
873
874 double a = 0;
875 double b = 0;
876 double c = 0;
877 double d = 0;
878 double e = 0;
879 double f = 0;
880 double r = driftRadius;
881 int offset = 0;
882 if(m_isData){
883 if(set==0){ // long straws in barrel
884 a = dEdxCorrection->paraLongCorrRZ[gasType][(6*parameter+0)*30*3+Layer*30+Strawlayer+offset];
885 b = dEdxCorrection->paraLongCorrRZ[gasType][(6*parameter+1)*30*3+Layer*30+Strawlayer+offset];
886 c = dEdxCorrection->paraLongCorrRZ[gasType][(6*parameter+2)*30*3+Layer*30+Strawlayer+offset];
887 d = dEdxCorrection->paraLongCorrRZ[gasType][(6*parameter+3)*30*3+Layer*30+Strawlayer+offset];
888 e = dEdxCorrection->paraLongCorrRZ[gasType][(6*parameter+4)*30*3+Layer*30+Strawlayer+offset];
889 f = dEdxCorrection->paraLongCorrRZ[gasType][(6*parameter+5)*30*3+Layer*30+Strawlayer+offset];
890
891 }else if (set ==1) { // short straws in barrel
892 if(sign > 0) offset+=108;
893 a = dEdxCorrection->paraShortCorrRZ[gasType][(6*parameter+0)*9+Layer+offset];
894 b = dEdxCorrection->paraShortCorrRZ[gasType][(6*parameter+1)*9+Layer+offset];
895 c = dEdxCorrection->paraShortCorrRZ[gasType][(6*parameter+2)*9+Layer+offset];
896 d = dEdxCorrection->paraShortCorrRZ[gasType][(6*parameter+3)*9+Layer+offset];
897 e = dEdxCorrection->paraShortCorrRZ[gasType][(6*parameter+4)*9+Layer+offset];
898 f = dEdxCorrection->paraShortCorrRZ[gasType][(6*parameter+5)*9+Layer+offset];
899 }else{ // straws in endcap
900 if(sign >0) Layer+=14;
901 a = dEdxCorrection->paraEndCorrRZ[gasType][(6*parameter+0)*28+Layer];
902 b = dEdxCorrection->paraEndCorrRZ[gasType][(6*parameter+1)*28+Layer];
903 c = dEdxCorrection->paraEndCorrRZ[gasType][(6*parameter+2)*28+Layer];
904 d = dEdxCorrection->paraEndCorrRZ[gasType][(6*parameter+3)*28+Layer];
905 e = dEdxCorrection->paraEndCorrRZ[gasType][(6*parameter+4)*28+Layer];
906 f = dEdxCorrection->paraEndCorrRZ[gasType][(6*parameter+5)*28+Layer];
907 }
908 }else{
909 if(set==0){ // long straws in barrel
910 if(sign > 0) offset=1620;
911 a = dEdxCorrection->paraLongCorrRZMC[gasType][(6*parameter+0)*30*3+Layer*30+Strawlayer+offset];
912 b = dEdxCorrection->paraLongCorrRZMC[gasType][(6*parameter+1)*30*3+Layer*30+Strawlayer+offset];
913 c = dEdxCorrection->paraLongCorrRZMC[gasType][(6*parameter+2)*30*3+Layer*30+Strawlayer+offset];
914 d = dEdxCorrection->paraLongCorrRZMC[gasType][(6*parameter+3)*30*3+Layer*30+Strawlayer+offset];
915 e = dEdxCorrection->paraLongCorrRZMC[gasType][(6*parameter+4)*30*3+Layer*30+Strawlayer+offset];
916 f = dEdxCorrection->paraLongCorrRZMC[gasType][(6*parameter+5)*30*3+Layer*30+Strawlayer+offset];
917 }else if (set ==1) { // short straws in barrel
918 if(sign > 0) offset+=108;
919 a = dEdxCorrection->paraShortCorrRZMC[gasType][(6*parameter+0)*9+Layer+offset];
920 b = dEdxCorrection->paraShortCorrRZMC[gasType][(6*parameter+1)*9+Layer+offset];
921 c = dEdxCorrection->paraShortCorrRZMC[gasType][(6*parameter+2)*9+Layer+offset];
922 d = dEdxCorrection->paraShortCorrRZMC[gasType][(6*parameter+3)*9+Layer+offset];
923 e = dEdxCorrection->paraShortCorrRZMC[gasType][(6*parameter+4)*9+Layer+offset];
924 f = dEdxCorrection->paraShortCorrRZMC[gasType][(6*parameter+5)*9+Layer+offset];
925 }else{ // straws in endcap
926 if(sign >0) Layer+=14;
927 a = dEdxCorrection->paraEndCorrRZMC[gasType][(6*parameter+0)*28+Layer];
928 b = dEdxCorrection->paraEndCorrRZMC[gasType][(6*parameter+1)*28+Layer];
929 c = dEdxCorrection->paraEndCorrRZMC[gasType][(6*parameter+2)*28+Layer];
930 d = dEdxCorrection->paraEndCorrRZMC[gasType][(6*parameter+3)*28+Layer];
931 e = dEdxCorrection->paraEndCorrRZMC[gasType][(6*parameter+4)*28+Layer];
932 f = dEdxCorrection->paraEndCorrRZMC[gasType][(6*parameter+5)*28+Layer];
933 }
934 }
935 return a+b*r+c*r*r+d*r*r*r+e*r*r*r*r+f*r*r*r*r*r;
936}
937
938double
940 EGasType gasType,
941 double driftRadius,
942 double radialPosition,
943 int Layer,
944 int sign) const
945{
946 /*
947 * T(r,R) = T0(r)+ a(r)*R
948 */
949
951 const TRTDedxcorrection* dEdxCorrection{*readHandle};
952 if(dEdxCorrection==nullptr) {
953 ATH_MSG_ERROR(" fitFuncEndcap_corrRZL: Could not find any dEdxCorrection in CondStore. Return zero.");
954 return 0;
955 }
956
957 double r = std::abs(driftRadius);
958 double a,b,c,d,e,f,g,h,i;
959 if(sign >0) Layer+=14;
960 if(m_isData){
961 a = dEdxCorrection->paraEndCorrRZDivideByLengthDATA[gasType][(0)*28+Layer];
962 b = dEdxCorrection->paraEndCorrRZDivideByLengthDATA[gasType][(1)*28+Layer];
963 c = dEdxCorrection->paraEndCorrRZDivideByLengthDATA[gasType][(2)*28+Layer];
964 d = dEdxCorrection->paraEndCorrRZDivideByLengthDATA[gasType][(3)*28+Layer];
965 e = dEdxCorrection->paraEndCorrRZDivideByLengthDATA[gasType][(4)*28+Layer];
966 f = dEdxCorrection->paraEndCorrRZDivideByLengthDATA[gasType][(5)*28+Layer];
967 g = dEdxCorrection->paraEndCorrRZDivideByLengthDATA[gasType][(6)*28+Layer];
968 h = dEdxCorrection->paraEndCorrRZDivideByLengthDATA[gasType][(7)*28+Layer];
969 i = dEdxCorrection->paraEndCorrRZDivideByLengthDATA[gasType][(8)*28+Layer];
970 }else{
971 a = dEdxCorrection->paraEndCorrRZDivideByLengthMC[gasType][(0)*28+Layer];
972 b = dEdxCorrection->paraEndCorrRZDivideByLengthMC[gasType][(1)*28+Layer];
973 c = dEdxCorrection->paraEndCorrRZDivideByLengthMC[gasType][(2)*28+Layer];
974 d = dEdxCorrection->paraEndCorrRZDivideByLengthMC[gasType][(3)*28+Layer];
975 e = dEdxCorrection->paraEndCorrRZDivideByLengthMC[gasType][(4)*28+Layer];
976 f = dEdxCorrection->paraEndCorrRZDivideByLengthMC[gasType][(5)*28+Layer];
977 g = dEdxCorrection->paraEndCorrRZDivideByLengthMC[gasType][(6)*28+Layer];
978 h = dEdxCorrection->paraEndCorrRZDivideByLengthMC[gasType][(7)*28+Layer];
979 i = dEdxCorrection->paraEndCorrRZDivideByLengthMC[gasType][(8)*28+Layer];
980 }
981
982 double T1 = b*r+c*r*r+d*r*r*r+e*r*r*r*r+f*r*r*r*r*r;
983 double slope = g+h*r+i*r*r;
984 double T0 = a;
985
986 return T0+T1+slope*radialPosition;
987}
988
989double
991 EGasType gasType,
992 double driftRadius,
993 double zPosition,
994 int Layer,
995 int Strawlayer) const
996{
997 /*
998 * T(r,z) = T0(r)+ b(r)*z*z
999 */
1001 const TRTDedxcorrection* dEdxCorrection{*readHandle};
1002 if(dEdxCorrection==nullptr) {
1003 ATH_MSG_ERROR(" fitFuncBarrel_corrRZL: Could not find any dEdxCorrection in CondStore. Return zero.");
1004 return 0;
1005 }
1006
1007 double a,b,c,d,e,f,g;
1008 if (Layer==0 && Strawlayer<9) { // short straws
1009 if (m_isData){
1010 a = dEdxCorrection->paraShortCorrRZDivideByLengthDATA[gasType][(0)*9+Strawlayer];
1011 b = dEdxCorrection->paraShortCorrRZDivideByLengthDATA[gasType][(1)*9+Strawlayer];
1012 c = dEdxCorrection->paraShortCorrRZDivideByLengthDATA[gasType][(2)*9+Strawlayer];
1013 d = dEdxCorrection->paraShortCorrRZDivideByLengthDATA[gasType][(3)*9+Strawlayer];
1014 e = dEdxCorrection->paraShortCorrRZDivideByLengthDATA[gasType][(4)*9+Strawlayer];
1015 f = dEdxCorrection->paraShortCorrRZDivideByLengthDATA[gasType][(5)*9+Strawlayer];
1016 g = dEdxCorrection->paraShortCorrRZDivideByLengthDATA[gasType][(6)*9+Strawlayer];
1017 } else {
1018 a = dEdxCorrection->paraShortCorrRZDivideByLengthMC[gasType][(0)*9+Strawlayer];
1019 b = dEdxCorrection->paraShortCorrRZDivideByLengthMC[gasType][(1)*9+Strawlayer];
1020 c = dEdxCorrection->paraShortCorrRZDivideByLengthMC[gasType][(2)*9+Strawlayer];
1021 d = dEdxCorrection->paraShortCorrRZDivideByLengthMC[gasType][(3)*9+Strawlayer];
1022 e = dEdxCorrection->paraShortCorrRZDivideByLengthMC[gasType][(4)*9+Strawlayer];
1023 f = dEdxCorrection->paraShortCorrRZDivideByLengthMC[gasType][(5)*9+Strawlayer];
1024 g = dEdxCorrection->paraShortCorrRZDivideByLengthMC[gasType][(6)*9+Strawlayer];
1025 }
1026 } else {
1027 if (m_isData) {
1028 a = dEdxCorrection->paraLongCorrRZDivideByLengthDATA[gasType][(0)*30*3+Layer*30+Strawlayer];
1029 b = dEdxCorrection->paraLongCorrRZDivideByLengthDATA[gasType][(1)*30*3+Layer*30+Strawlayer];
1030 c = dEdxCorrection->paraLongCorrRZDivideByLengthDATA[gasType][(2)*30*3+Layer*30+Strawlayer];
1031 d = dEdxCorrection->paraLongCorrRZDivideByLengthDATA[gasType][(3)*30*3+Layer*30+Strawlayer];
1032 e = dEdxCorrection->paraLongCorrRZDivideByLengthDATA[gasType][(4)*30*3+Layer*30+Strawlayer];
1033 f = dEdxCorrection->paraLongCorrRZDivideByLengthDATA[gasType][(5)*30*3+Layer*30+Strawlayer];
1034 g = dEdxCorrection->paraLongCorrRZDivideByLengthDATA[gasType][(6)*30*3+Layer*30+Strawlayer];
1035 } else {
1036 a = dEdxCorrection->paraLongCorrRZDivideByLengthMC[gasType][(0)*30*3+Layer*30+Strawlayer];
1037 b = dEdxCorrection->paraLongCorrRZDivideByLengthMC[gasType][(1)*30*3+Layer*30+Strawlayer];
1038 c = dEdxCorrection->paraLongCorrRZDivideByLengthMC[gasType][(2)*30*3+Layer*30+Strawlayer];
1039 d = dEdxCorrection->paraLongCorrRZDivideByLengthMC[gasType][(3)*30*3+Layer*30+Strawlayer];
1040 e = dEdxCorrection->paraLongCorrRZDivideByLengthMC[gasType][(4)*30*3+Layer*30+Strawlayer];
1041 f = dEdxCorrection->paraLongCorrRZDivideByLengthMC[gasType][(5)*30*3+Layer*30+Strawlayer];
1042 g = dEdxCorrection->paraLongCorrRZDivideByLengthMC[gasType][(6)*30*3+Layer*30+Strawlayer];
1043 }
1044 }
1045 double z = std::abs(zPosition);
1046 double r = std::abs(driftRadius);
1047 double T0neg=a;
1048 double T0pos=b;
1049 double T1 = std::exp(-c*r*r)+d*r;
1050 double slope = e*r+f*r*r+g*r*r*r;
1051 double result;
1052 result = T0neg+T1+slope*z;
1053 if (zPosition>0) result = T0pos+T1+slope*z;
1054
1055 return result;
1056}
1057
1058double
1060 const Trk::TrackStateOnSurface* itr) const
1061{
1063 const TRTDedxcorrection* dEdxCorrection{*readHandle};
1064
1065 const Trk::MeasurementBase* trkM = itr->measurementOnTrack();
1066
1067 // Check if this is RIO on track
1068 // and if yes check if is TRT Drift Circle
1069 // then set the ptr
1070 const InDet::TRT_DriftCircleOnTrack* driftcircle = nullptr;
1071 if (trkM && trkM->type(Trk::MeasurementBaseType::RIO_OnTrack)) {
1072 const Trk::RIO_OnTrack* tmpRio = static_cast<const Trk::RIO_OnTrack*>(trkM);
1074 driftcircle = static_cast<const InDet::TRT_DriftCircleOnTrack*>(tmpRio);
1075 }
1076 }
1077
1078 if (!driftcircle) {
1079 return 0.;
1080 }
1081
1082 const Trk::TrackParameters* trkP = itr->trackParameters();
1083 Identifier DCId = driftcircle->identify();
1084 int isHT = driftcircle->highLevel();
1085 int isShared=0;
1086
1087 const Trk::RIO_OnTrack* hit_trt = nullptr;
1088 if (trkM && trkM->type(Trk::MeasurementBaseType::RIO_OnTrack)) {
1089 hit_trt = static_cast<const Trk::RIO_OnTrack*>(trkM);
1090 }
1091
1092 if (hit_trt) {
1093 if ( m_assoTool->isShared(*(hit_trt->prepRawData())) ) isShared=1;
1094 }
1095 int layer = m_trtId->layer_or_wheel(DCId);
1096 int phimodule = m_trtId->phi_module(DCId);
1097 int HitPart = m_trtId->barrel_ec(DCId);
1098 double Trt_HitTheta = trkP->parameters()[Trk::theta];
1099 double trackEta = -log(tan(Trt_HitTheta/2.0));
1100
1101 double localOccupancy = m_localOccTool->LocalOccupancy(ctx, trackEta, phimodule);
1102 double ToTmip = 1;
1103 double valToT = 1.;
1104
1105 double p0=0., p1=0., p2=0., p0_flat=0.;
1106
1107 //the calibration array is structured as follows (hence the non intuitive numbers)
1108 //the first 36 parameters are for barrel, the last 168 for the endcap
1109 //each of these subarrays is divided into smaller subarrays of length 12 (barrel has 3 and endcap 14 layers)
1110 int nBarrelLayers = 3, nEndcapLayers = 14;
1111 //each layer has 3 parameters (function 2nd order), so a subarray for each layer has 3 parameters
1112 int nParametersPerLayer = 3;
1113 //this subarray for every layer exits for HT/LT hits, so 6 parameters
1114 int nHTConfigurations = 2;
1115 //this subarray exists for shared/non-shared hits, so 12 parameters
1116 int nSharedConfigurations = 2;
1117 int num =
1118 layer * nParametersPerLayer +
1119 isHT * ((abs(HitPart) - 1) * (nEndcapLayers - nBarrelLayers) *
1120 nParametersPerLayer +
1121 nBarrelLayers * nParametersPerLayer) +
1122 isShared * ((abs(HitPart) - 1) * (nEndcapLayers - nBarrelLayers) *
1123 nParametersPerLayer * nHTConfigurations +
1124 nBarrelLayers * nParametersPerLayer * nHTConfigurations) +
1125 (abs(HitPart) - 1) * nParametersPerLayer * nBarrelLayers *
1126 nHTConfigurations * nSharedConfigurations;
1127 //number for that given hit for non-shared conditions
1128 int num_flat = layer * 3 +
1129 isHT * ((abs(HitPart) - 1) * (nEndcapLayers - nBarrelLayers) *
1130 nParametersPerLayer +
1131 nBarrelLayers * nParametersPerLayer) +
1132 (abs(HitPart) - 1) * nParametersPerLayer * nBarrelLayers *
1133 nHTConfigurations * nSharedConfigurations;
1134
1135 p0 = dEdxCorrection->hitOccPar[num];
1136 p1 = dEdxCorrection->hitOccPar[num+1];
1137 p2 = dEdxCorrection->hitOccPar[num+2];
1138 p0_flat = dEdxCorrection->hitOccPar[num_flat];
1139
1140 //fitting function is a polynomial 2nd order f(x)=a+b*x+x^2
1141 //Hence the tot value is divided by the value of the function
1142 //multiplied to the non-shared intercept
1143 valToT = p0_flat/(p0+p1*localOccupancy+p2*localOccupancy*localOccupancy);
1144
1145 return ToTmip*valToT;
1146}
1147
1148double
1150 const Trk::Track* track,
1151 bool useHitsHT,
1152 std::optional<float> localOccupancy) const
1153{
1155 const TRTDedxcorrection* dEdxCorrection{*readHandle};
1156
1157 double corr=-999.;
1158
1159 double trackOcc = localOccupancy != std::nullopt
1160 ? *localOccupancy
1161 : m_localOccTool->LocalOccupancy(ctx, *track);
1162 const Trk::TrackParameters* perigee = track->perigeeParameters();
1163 const AmgVector(Trk::TrackParameters::dim)& parameterVector = perigee->parameters();
1164 double theta = parameterVector[Trk::theta];
1165 double trackEta = -log(tan(theta/2.0));
1166
1167 // the correction constants were determined in 100 bins of 0.04 in the eta range between -2 and 2
1168 int index = int(25*(trackEta+2.)); // determine the bin of the corrections
1169 if (index < 0) index = 0; // lower bound corresponding to eta = -2
1170 else if (index > 99) index = 99; // upper bound corresponding to eta = +2
1171
1172 //Function of the from f(x)=a+b*x+c*x^2 was used as a fitting function, separately for tracks with and without excluding HT hits
1173 if (useHitsHT) {
1174 corr=dEdxCorrection->trackOccPar0[index]+dEdxCorrection->trackOccPar1[index]*trackOcc+dEdxCorrection->trackOccPar2[index]*pow(trackOcc,2);
1175 } else {
1176 corr=dEdxCorrection->trackOccPar0NoHt[index]+dEdxCorrection->trackOccPar1NoHt[index]*trackOcc+dEdxCorrection->trackOccPar2NoHt[index]*pow(trackOcc,2);
1177 }
1178
1179 if (corr != 0) {
1180 return 1./corr;
1181 }
1182 return 0.;
1183}
1184
1186 if (trackState->type(Trk::TrackStateOnSurface::Outlier)) return 0.; //Outliers
1187
1188 const Trk::MeasurementBase* trkM = trackState->measurementOnTrack();
1189 if (!trkM) {
1190 return 0.;
1191 }
1192
1193 // Check if this is RIO on track
1194 // and if yes check if is TRT Drift Circle
1195 // then set the ptr
1196 const InDet::TRT_DriftCircleOnTrack* driftcircle = nullptr;
1198 const Trk::RIO_OnTrack* tmpRio = static_cast<const Trk::RIO_OnTrack*>(trkM);
1200 driftcircle = static_cast<const InDet::TRT_DriftCircleOnTrack*>(tmpRio);
1201 }
1202 }
1203
1204 if (!driftcircle) {
1205 return 0.;
1206 }
1207
1208 const Trk::TrackParameters* trkP = trackState->trackParameters();
1209 if(trkP==nullptr) return 0.;
1210
1211 double Trt_Rtrack = std::abs(trkP->parameters()[Trk::locR]);
1212 double Trt_HitTheta = trkP->parameters()[Trk::theta];
1213 double Trt_HitPhi = trkP->parameters()[Trk::phi];
1214 Identifier DCId = driftcircle->identify();
1215 int HitPart = std::abs(identifier->barrel_ec(DCId));
1216 const InDetDD::TRT_BaseElement* element = driftcircle->detectorElement();
1217 double strawphi = element->center(DCId).phi();
1218
1219 // check if track is an outlier
1220 if (Trt_Rtrack >= 2.0) {
1221 return 0.;
1222 }
1223
1224 double length=0;
1225 if (HitPart == 1) { //Barrel
1226 length = 2*std::sqrt(4-Trt_Rtrack*Trt_Rtrack)*1./std::abs(std::sin(Trt_HitTheta));
1227 } else if (HitPart == 2) { //EndCap
1228 length = 2*std::sqrt(4-Trt_Rtrack*Trt_Rtrack)*1./std::sqrt(1-std::sin(Trt_HitTheta)*std::sin(Trt_HitTheta)*std::cos(Trt_HitPhi-strawphi)*std::cos(Trt_HitPhi-strawphi));
1229 } else {
1230 // This should never happen
1231 throw std::runtime_error("Unknown barrel/endcap identifier: " + std::to_string(HitPart) + ". Must be 1(Barrel) or 2(Endcap)");
1232 }
1233
1234 return length;
1235}
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define REPORT_MESSAGE(LVL)
Report a message.
defines an "iterator" over instances of a given type in StoreGateSvc
#define AmgVector(rows)
double length(const pvec &v)
static Double_t a
static Double_t sc
bool inRange(const double *boundaries, const double value, const double tolerance=0.02)
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
Handle class for reading a decoration on an object.
Handle class for reading from StoreGate.
This is an Identifier helper class for the TRT subdetector.
int sign(int a)
#define z
constexpr int pow(int base, int exp) noexcept
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
const ServiceHandle< StoreGateSvc > & detStore() const
Header file for AthHistogramAlgorithm.
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
Virtual base class of TRT readout elements.
virtual const Amg::Vector3D & center() const override final
Element Surface: center of a straw layer.
Represents 'corrected' measurements from the TRT (for example, corrected for wire sag).
bool highLevel() const
returns true if the high level threshold was passed
virtual const InDetDD::TRT_BaseElement * detectorElement() const override final
returns the detector element, assoicated with the PRD of this class
virtual const TRT_DriftCircle * prepRawData() const override final
returns the PrepRawData - is a TRT_DriftCircle in this scope
virtual const Amg::Vector3D & globalPosition() const override final
return the global position of this RIO_OnTrack
double timeOverThreshold() const
returns Time over threshold in ns
Handle class for reading a decoration on an object.
bool isPresent() const
Is the referenced container present in SG?
This is an Identifier helper class for the TRT subdetector.
Definition TRT_ID.h:82
double fitFuncEndcap_corrRZL(const EventContext &ctx, EGasType gasType, double driftRadius, double radialPosition, int Layer, int sign) const
function to compute correction factor in endcap region
virtual StatusCode initialize() override
AlgTool initailize method.
double fitFuncBarrel_corrRZ(const EventContext &ctx, EGasType gas, double driftRadius, double zPosition, int Layer, int StrawLayer) const
function to compute correction factor in barrel region
const TRT_ID * m_trtId
BooleanProperty m_corrected
virtual double dEdx(const EventContext &ctx, const Trk::Track *track, bool useHThits, std::optional< float > localOccupancy=std::nullopt) const override final
function to calculate sum ToT normalised to number of used hits
EGasType gasTypeInStraw(const EventContext &ctx, const Trk::TrackStateOnSurface *itr) const
return gas type for that hit
IntegerProperty m_correctionType
TRT_ToT_dEdx(const std::string &, const std::string &, const IInterface *)
AlgTool like constructor.
IntegerProperty m_useTrackPartWithGasType
SG::ReadCondHandleKey< TRTDedxcorrection > m_ReadKey
BooleanProperty m_useZeroRHitCut
double trackOccupancyCorrection(const EventContext &ctx, const Trk::Track *track, bool useHThits, std::optional< float > localOccupancy) const
double fitFuncBarrelShort_corrRZ(const EventContext &ctx, EGasType gasType, double driftRadius, double zPosition, int StrawLayer) const
function called by fitFuncBarrel_corrRZ for short straws
virtual ~TRT_ToT_dEdx()
Virtual destructor.
double mass(const EventContext &ctx, const Trk::TrackStateOnSurface *itr, const double pTrk, double dEdx) const
function to extract most likely mass in bg [0,3]
virtual double getTest(const EventContext &ctx, const double dEdx_obs, const double pTrk, Trk::ParticleHypothesis hypothesis, Trk::ParticleHypothesis antihypothesis, int nUsedHits) const override final
function to calculate likelihood ratio test
bool isGoodHit(const EventContext &ctx, const Trk::TrackStateOnSurface *trackState, bool useHitsHT, double &length) const
function to define what is a good hit to be used for dEdx calculation cuts on track level can be made...
virtual double usedHits(const EventContext &ctx, const Trk::Track *track, bool useHThits=true) const override final
function to calculate number of used hits
double fitFuncPol_corrRZ(const EventContext &ctx, EGasType gasType, int parameter, double driftRadius, int Layer, int Strawlayer, int sign, int set) const
function called by fitFuncBarrel_corrRZ and fitFuncEndcap_corrRZ
unsigned int m_nTrunkateHits
double predictdEdx(const EventContext &ctx, const Trk::TrackStateOnSurface *itr, const double pTrk, Trk::ParticleHypothesis hypothesis) const
function to calculate expectation value for dEdx using BB fit
BooleanProperty m_isData
ToolHandle< Trk::IPRD_AssociationTool > m_assoTool
double fitFuncBarrel_corrRZL(const EventContext &ctx, EGasType gasType, double driftRadius, double zPosition, int Layer, int StrawLayer) const
function to compute correction factor in barrel region
FloatProperty m_trackConfig_maxRtrack
double fitFuncEndcap_corrRZ(const EventContext &ctx, EGasType gas, double driftRadius, double rPosition, int Layer, int sign) const
function to compute correction factor in endcap region
double correctToT_corrRZ(const EventContext &ctx, const Trk::TrackStateOnSurface *itr, double length) const
main function to correct ToT values on hit level as a function of track radius and z-position
ToolHandle< ITRT_StrawStatusSummaryTool > m_TRTStrawSummaryTool
SG::ReadDecorHandleKey< xAOD::EventInfo > m_rdhkEvtInfo
FloatProperty m_trackConfig_minRtrack
double hitOccupancyCorrection(const EventContext &ctx, const Trk::TrackStateOnSurface *itr) const
static double calculateTrackLengthInStraw(const Trk::TrackStateOnSurface *trackState, const TRT_ID *identifier)
double getProb(const EventContext &ctx, const Trk::TrackStateOnSurface *itr, const double dEdx_obs, const double pTrk, Trk::ParticleHypothesis hypothesis, int nUsedHits) const
function to calculate likelihood from prediction and resolution
double fitFuncBarrelLong_corrRZ(const EventContext &ctx, EGasType gasType, double driftRadius, double zPosition, int Layer, int StrawLayer) const
function called by fitFuncBarrel_corrRZ for long straws
BooleanProperty m_divideByL
IntegerProperty m_toolScenario
double correctNormalization(const EventContext &ctx, double nVtx=-1) const
correct overall dEdx normalization on track level
ToolHandle< InDet::ITRT_LocalOccupancy > m_localOccTool
This class is the pure abstract base class for all fittable tracking measurements.
const LocalParameters & localParameters() const
Interface method to get the LocalParameters.
virtual bool type(MeasurementBaseType::Type type) const =0
Interface method checking the type.
const Amg::MatrixX & localCovariance() const
Interface method to get the localError.
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
Definition RIO_OnTrack.h:70
virtual const Trk::PrepRawData * prepRawData() const =0
returns the PrepRawData (also known as RIO) object to which this RIO_OnTrack is associated.
Identifier identify() const
return the identifier -extends MeasurementBase
virtual bool rioType(RIO_OnTrackType::Type type) const =0
Method checking the Rio On Track type.
represents the track state (measurement, material, fit parameters and quality) at a surface.
const MeasurementBase * measurementOnTrack() const
returns MeasurementBase const overload
const TrackParameters * trackParameters() const
return ptr to trackparameters const overload
bool type(const TrackStateOnSurfaceType type) const
Use this method to find out if the TSoS is of a certain type: i.e.
@ Outlier
This TSoS contains an outlier, that is, it contains a MeasurementBase/RIO_OnTrack which was not used ...
STL class.
double timeOverThreshold(unsigned int m_word)
int r
Definition globals.cxx:22
constexpr double mass[PARTICLEHYPOTHESES]
the array of masses
DataVector< const Trk::TrackStateOnSurface > TrackStates
@ driftRadius
trt, straws
Definition ParamDefs.h:53
@ locR
Definition ParamDefs.h:44
@ theta
Definition ParamDefs.h:66
@ phi
Definition ParamDefs.h:75
ParticleHypothesis
Enumeration for Particle hypothesis respecting the interaction with material.
ParametersBase< TrackParametersDim, Charged > TrackParameters
Definition index.py:1
double normOffsetData[nGasTypes]
double hitOccPar[nParametersHitBaseddEdx]
double paraShortCorrRZDivideByLengthMC[nGasTypes][nParametersShortStrawsRZDivideByLength]
double paraEndCorrRZMC[nGasTypes][nParametersEndcapRZ]
double paraDivideByLengthDedxP4[nGasTypes]
double trackOccPar0NoHt[nParametersTrackBaseddEdx]
double resolution[nGasTypes][nParametersResolution]
double paraDedxP5[nGasTypes]
double paraDedxP4[nGasTypes]
double paraShortCorrRZMC[nGasTypes][nParametersShortStrawsRZ]
double paraLongCorrRZDivideByLengthMC[nGasTypes][nParametersLongStrawsRZDivideByLength]
double trackOccPar2[nParametersTrackBaseddEdx]
double normSlopeTot[nGasTypes]
double paraDedxP3[nGasTypes]
double paraDivideByLengthDedxP1[nGasTypes]
double paraDedxP2[nGasTypes]
double trackOccPar1NoHt[nParametersTrackBaseddEdx]
double paraLongCorrRZ[nGasTypes][nParametersLongStrawsRZ]
double normSlopeTotDivideByLength[nGasTypes]
int normNzero[nGasTypes]
double paraEndCorrRZDivideByLengthDATA[nGasTypes][nParametersEndcapRZDivideByLength]
double paraDivideByLengthDedxP2[nGasTypes]
double paraShortCorrRZ[nGasTypes][nParametersShortStrawsRZ]
double trackOccPar2NoHt[nParametersTrackBaseddEdx]
double paraShortCorrRZDivideByLengthDATA[nGasTypes][nParametersShortStrawsRZDivideByLength]
double paraLongCorrRZDivideByLengthDATA[nGasTypes][nParametersLongStrawsRZDivideByLength]
double normOffsetTot[nGasTypes]
double paraEndCorrRZDivideByLengthMC[nGasTypes][nParametersEndcapRZDivideByLength]
double trackOccPar0[nParametersTrackBaseddEdx]
double trackOccPar1[nParametersTrackBaseddEdx]
double paraLongCorrRZMC[nGasTypes][nParametersLongStrawsRZ]
double paraDivideByLengthDedxP3[nGasTypes]
double paraDedxP1[nGasTypes]
double paraDivideByLengthDedxP5[nGasTypes]
double paraEndCorrRZ[nGasTypes][nParametersEndcapRZ]
double normOffsetTotDivideByLength[nGasTypes]
double resolutionElectron[nGasTypes][nParametersResolution]