ATLAS Offline Software
Loading...
Searching...
No Matches
TrackStateOnSurfaceDecorator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6// TrackStateOnSurfaceDecorator.cxx, (c) ATLAS Detector software
8// Author:Anthony Morley
9//
10
13
16
18
22
28
32
38
40
41
43
45#include "TrkTrack/Track.h"
46
49
52
60
61#include <vector>
62#include <string>
63
64namespace {
67}
68
69namespace DerivationFramework {
70
72 {
73 ATH_MSG_DEBUG("Initialize");
74
75 if (m_sgName.value() == "notSet") {
76 ATH_MSG_ERROR("No decoration prefix name provided for the output of TrackStateOnSurfaceDecorator! Use the variable DecorationPrefix to properly set a prefix.");
77 return StatusCode::FAILURE;
78 }
79 ATH_MSG_DEBUG("Prefix for decoration: " << m_sgName);
80
82 if (m_containerName.key().empty()) {
83 ATH_MSG_ERROR("No TrackParticle collection provided for TrackStateOnSurfaceDecorator!");
84 return StatusCode::FAILURE;
85 }
86 ATH_MSG_DEBUG("Input TrackParticle container: " << m_containerName.key());
87 ATH_CHECK( m_containerName.initialize() );
88
89 if (!m_selectionString.empty()) {
90 ATH_CHECK(initializeParser(m_selectionString));
91 }
92
93 // need Atlas id-helpers to identify sub-detectors, take them from detStore
94 if (detStore()->retrieve(m_idHelper, "AtlasID").isFailure()) {
95 ATH_MSG_ERROR("Could not get AtlasDetectorID helper");
96 return StatusCode::FAILURE;
97 }
98
99 if( m_storePixel && detStore()->retrieve(m_pixId,"PixelID").isFailure() ){
100 ATH_MSG_ERROR("Unable to retrieve pixel ID helper");
101 return StatusCode::FAILURE;
102 }
103
104 if( m_storeSCT && detStore()->retrieve(m_sctId,"SCT_ID").isFailure() ){
105 ATH_MSG_ERROR("Could not retrieve SCT helper");
106 return StatusCode::FAILURE;
107 }
108
109 if( m_storeTRT && detStore()->retrieve(m_trtId,"TRT_ID").isFailure() ){
110 ATH_MSG_ERROR("Could not retrieve TRT helper");
111 return StatusCode::FAILURE;
112 }
113
114 ATH_CHECK( m_trtcaldbTool.retrieve(DisableTool{ !m_storeTRT }));
115 ATH_CHECK( m_prdToTrackMap.initialize( !m_prdToTrackMap.key().empty() && m_storeTRT) );
116
117 ATH_CHECK( m_updator.retrieve(DisableTool{ !m_addPulls }));
118 ATH_CHECK( m_residualPullCalculator.retrieve(DisableTool{ !m_addPulls }));
119
120 ATH_CHECK( m_holeSearchTool.retrieve( DisableTool{ !m_storeHoles}) );
121
122 ATH_CHECK( m_TRTdEdxTool.retrieve( DisableTool{!m_storeTRT || m_TRTdEdxTool.empty()}) );
123
124 ATH_CHECK(m_extrapolator.retrieve());
125
126
128
130 std::vector<std::string> decor_names{"TrtPhaseTime"};
131 std::vector<SG::WriteDecorHandleKey<xAOD::EventInfo> > decor_key_out;
133 assert(m_trtPhaseDecorKey.size() == 1);
134 }
135 if (m_storeTRT && m_TRTdEdxTool.isEnabled()) {
136 std::vector<std::string> names;
137 names.resize(kNTRTFloatDecor);
138 names[kTRTdEdxDecor]="ToT_dEdx";
139 names[kTRTusedHitsDecor]="ToT_usedHits";
140 names[kTRTdEdx_noHT_divByLDecor]="ToT_dEdx_noHT_divByL";
141 names[kTRTusedHits_noHT_divByLDecor]="ToT_usedHits_noHT_divByL";
143 }
146 ATH_CHECK( m_sctMapName.initialize(m_storeSCT && m_addPRD) );
147 ATH_CHECK( m_trtMapName.initialize(m_storeTRT && m_addPRD) );
148
151 ATH_CHECK( m_trtDCName.initialize(m_storeTRT && m_addPRD) );
152
154 ATH_CHECK( m_sctMsosName.initialize(m_storeSCT && m_addPRD) );
155 ATH_CHECK( m_trtMsosName.initialize(m_storeTRT && m_addPRD) );
156
157 if (m_storePixel){
158 std::vector<std::string> names;
159 names.resize(kNPixFloatDecor);
160 names[kTrkIBLXDecor]="TrkIBLX";
161 names[kTrkIBLYDecor]="TrkIBLY";
162 names[kTrkIBLZDecor]="TrkIBLZ";
163 names[kTrkBLXDecor]="TrkBLX";
164 names[kTrkBLYDecor]="TrkBLY";
165 names[kTrkBLZDecor]="TrkBLZ";
166 names[kTrkL1XDecor]="TrkL1X";
167 names[kTrkL1YDecor]="TrkL1Y";
168 names[kTrkL1ZDecor]="TrkL1Z";
169 names[kTrkL2XDecor]="TrkL2X";
170 names[kTrkL2YDecor]="TrkL2Y";
171 names[kTrkL2ZDecor]="TrkL2Z";
173 }
174
175 m_trackTSOSMOSLinkDecorKey = m_containerName.key() + "." + m_sgName + "msosLink";
177
178 ATH_MSG_DEBUG("Initialization finished.");
179
180 return StatusCode::SUCCESS;
181 }
182
184 {
185 ATH_MSG_DEBUG("Finalize");
186 return StatusCode::SUCCESS;
187 }
188
189 StatusCode TrackStateOnSurfaceDecorator::addBranches(const EventContext& ctx) const
190 {
191 ATH_MSG_DEBUG("Adding TSOS decorations the track particles");
192
193
194 // --- Retrieve track container (absolutely needed for decoration)
195 const xAOD::TrackParticleContainer* tracks{};
196 ATH_CHECK(SG::get(tracks, m_containerName, ctx));
197
198 size_t nTracks = tracks->size();
200
201
202 const std::vector<unsigned int>* pixelClusterOffsets{};
203 const std::vector<unsigned int>* sctClusterOffsets{};
204 const std::vector<unsigned int>* trtDCOffsets{};
205
206 ATH_CHECK(SG::get(pixelClusterOffsets, m_pixelMapName, ctx));
207 ATH_CHECK(SG::get(sctClusterOffsets, m_sctMapName, ctx));
208 ATH_CHECK(SG::get(trtDCOffsets, m_trtMapName, ctx));
209
210 const xAOD::TrackMeasurementValidationContainer* pixelClusters{};
213
214 ATH_CHECK(SG::get(pixelClusters, m_pixelClustersName, ctx));
215 ATH_CHECK(SG::get(sctClusters, m_sctClustersName, ctx));
216 ATH_CHECK(SG::get(trtDCs, m_trtDCName, ctx));
217
218 const xAOD::EventInfo* eventInfo{};
219 ATH_CHECK(SG::get(eventInfo, m_eventInfoKey,ctx));
220
221 // Create the xAOD container and its auxiliary store
222 StateContainer_t msosPixel{};
223 StateContainer_t msosSCT{};
224 StateContainer_t msosTRT{};
225
226 ATH_CHECK(msosPixel.record(m_pixelMsosName,ctx));
227 ATH_CHECK(msosSCT.record(m_sctMsosName,ctx));
228 ATH_CHECK(msosTRT.record(m_trtMsosName,ctx));
229
230 int nPixelMSOS(0);
231 int nSCT_MSOS(0);
232 int nTRT_MSOS(0);
233
234 // --- Add event-level information
236 ATH_MSG_DEBUG("Adding EventInfo decorations");
237
238 //Add TRT event phase
240 float trtPhase_time=0.;
241 if (!trtPhase.isValid()) {
242 ATH_MSG_DEBUG("Failed to retrieve TRT phase information.");
243 } else {
244 trtPhase_time = trtPhase->getTime();
245 } //TRT phase
247 decorTRTPhase(*eventInfo) = trtPhase_time;
248 } //extra event info
249
250 // --- Add track states containers
251 const Trk::PRDtoTrackMap *prd_to_track_map_cptr{};
252 ATH_CHECK(SG::get(prd_to_track_map_cptr, m_prdToTrackMap, ctx));
253
254 // Set up a mask with the same entries as the full TrackParticle collection
255 std::vector<bool> mask;
256 mask.assign(nTracks,true); // default: keep all the tracks
257 if (m_parser) {
258 std::vector<int> entries = m_parser->evaluateAsVector();
259 unsigned int nEntries = entries.size();
260 // check the sizes are compatible
261 if (nTracks != nEntries ) {
262 ATH_MSG_ERROR("Sizes incompatible! Are you sure your selection string used ID TrackParticles?");
263 return StatusCode::FAILURE;
264 } else {
265 // set mask
266 for (unsigned int i=0; i<nTracks; ++i) if (entries[i]!=1) mask[i]=false;
267 }
268 }
269
270 std::vector<SG::WriteDecorHandle<xAOD::TrackParticleContainer,float> > trackTRTFloatDecorators;
271 if (m_storeTRT && m_TRTdEdxTool.isEnabled()) {
273 }
274 std::vector<SG::WriteDecorHandle<xAOD::TrackParticleContainer,float> >
276 // -- Run over each track and decorate it
277 unsigned i_track = 0;
278 for (const auto *const track : *tracks) {
279 //-- Start with things that do not need a Trk::Track object
280
281 // mask bit check
282 if(!mask[i_track]) {
283 ++i_track;
284 continue;
285 }
286
287 // -- Now things that require a Trk::Track object
288 if( !track->trackLink().isValid() || track->track() == nullptr ) {
289 ATH_MSG_WARNING("Track particle without Trk::Track");
290 continue;
291 }
292 ATH_MSG_DEBUG("We have a Trk::Track");
293
294 // We now have a valid Trk::Track
295 const Trk::Track* trkTrack = track->track();
296
297 // This is the vector in which we will store the element links to the MSOS's
298 std::vector< ElementLink< xAOD::TrackStateValidationContainer > > msosLink;
299
300 if ( m_storeTRT && m_TRTdEdxTool.isEnabled() ) {
301 // for dEdx studies
302 trackTRTFloatDecorators[kTRTdEdxDecor] (*track) = m_TRTdEdxTool->dEdx(trkTrack,true);
303 trackTRTFloatDecorators[kTRTusedHitsDecor] (*track) = m_TRTdEdxTool->usedHits(trkTrack);
304 trackTRTFloatDecorators[kTRTdEdx_noHT_divByLDecor] (*track) = m_TRTdEdxTool->dEdx(trkTrack, false);
305 trackTRTFloatDecorators[kTRTusedHits_noHT_divByLDecor] (*track) = m_TRTdEdxTool->usedHits(trkTrack, false);
306 }
307
308 if(m_storePixel){
309 if ( trkTrack->perigeeParameters() ){
310
311 if(m_pixelLayerRadii.size() < 4) ATH_MSG_WARNING("Too few layer radii set! Should be at least 4!");
312
313 Trk::CylinderSurface cylSurfIBL(m_pixelLayerRadii[0], 3000.0);
314 Trk::CylinderSurface cylSurfBL(m_pixelLayerRadii[1], 3000.0);
315 Trk::CylinderSurface cylSurfL1(m_pixelLayerRadii[2], 3000.0);
316 Trk::CylinderSurface cylSurfL2(m_pixelLayerRadii[3], 3000.0);
317
318 bool allExtrapolationsSucceded = true;
321 //check the radius of the start parameters, to see which direction we need to go to the target surface
322 float startRadius = trkTrack->perigeeParameters()->associatedSurface().center().perp();
323 ATH_MSG_VERBOSE("Start radius for extrapolating to layers: "<<startRadius);
324 //see if we go along or opposite momentum
325 if(startRadius>m_pixelLayerRadii[0]) {whichDir = Trk::oppositeMomentum; whichMode = Trk::addNoise;}
326 std::unique_ptr<const Trk::TrackParameters> outputParamsIBL
327 (m_extrapolator->extrapolate(ctx,
328 *(trkTrack->perigeeParameters()),
329 cylSurfIBL,
330 whichDir,
331 true,
332 Trk::pion,
333 whichMode));
334 if(startRadius>m_pixelLayerRadii[1]){
335 whichDir = Trk::oppositeMomentum;
336 whichMode = Trk::addNoise;
337 }
338 std::unique_ptr<const Trk::TrackParameters> outputParamsBL
339 (m_extrapolator->extrapolate(ctx,
340 *(trkTrack->perigeeParameters()),
341 cylSurfBL,
342 whichDir,
343 true,
344 Trk::pion,
345 whichMode));
346 if(startRadius>m_pixelLayerRadii[2]){
347 whichDir = Trk::oppositeMomentum;
348 whichMode = Trk::addNoise;
349 }
350 std::unique_ptr<const Trk::TrackParameters> outputParamsL1
351 (m_extrapolator->extrapolate(ctx,
352 *(trkTrack->perigeeParameters()),
353 cylSurfL1,
354 whichDir,
355 true,
356 Trk::pion,
357 whichMode));
358 if(startRadius>m_pixelLayerRadii[2]){
359 whichDir = Trk::oppositeMomentum;
360 whichMode = Trk::addNoise;
361 }
362 std::unique_ptr<const Trk::TrackParameters> outputParamsL2
363 (m_extrapolator->extrapolate(ctx,
364 *(trkTrack->perigeeParameters()),
365 cylSurfL2,
366 whichDir,
367 true,
368 Trk::pion,
369 whichMode));
370
371 if (outputParamsIBL.get()) {
372 trackPixFloatDecorators[kTrkIBLXDecor](*track) = outputParamsIBL->position().x();
373 trackPixFloatDecorators[kTrkIBLYDecor](*track) = outputParamsIBL->position().y();
374 trackPixFloatDecorators[kTrkIBLZDecor](*track) = outputParamsIBL->position().z();
375 }
376 else {
377 allExtrapolationsSucceded = false;
378 ATH_MSG_VERBOSE("Extrapolation to IBL failed...");
379 trackPixFloatDecorators[kTrkIBLXDecor](*track) = 0.0;
380 trackPixFloatDecorators[kTrkIBLYDecor](*track) = 0.0;
381 trackPixFloatDecorators[kTrkIBLZDecor](*track) = 0.0;
382 }
383
384 if (outputParamsBL.get()) {
385 trackPixFloatDecorators[kTrkBLXDecor](*track) = outputParamsBL->position().x();
386 trackPixFloatDecorators[kTrkBLYDecor](*track) = outputParamsBL->position().y();
387 trackPixFloatDecorators[kTrkBLZDecor](*track) = outputParamsBL->position().z();
388 }
389 else {
390 allExtrapolationsSucceded = false;
391 ATH_MSG_VERBOSE("Extrapolation to BLayer failed...");
392 trackPixFloatDecorators[kTrkBLXDecor](*track) = 0.0;
393 trackPixFloatDecorators[kTrkBLYDecor](*track) = 0.0;
394 trackPixFloatDecorators[kTrkBLZDecor](*track) = 0.0;
395 }
396
397 if (outputParamsL1.get()) {
398 trackPixFloatDecorators[kTrkL1XDecor](*track) = outputParamsL1->position().x();
399 trackPixFloatDecorators[kTrkL1YDecor](*track) = outputParamsL1->position().y();
400 trackPixFloatDecorators[kTrkL1ZDecor](*track) = outputParamsL1->position().z();
401 }
402 else {
403 allExtrapolationsSucceded = false;
404 ATH_MSG_VERBOSE("Extrapolation to L1 failed...");
405 trackPixFloatDecorators[kTrkL1XDecor](*track) = 0.0;
406 trackPixFloatDecorators[kTrkL1YDecor](*track) = 0.0;
407 trackPixFloatDecorators[kTrkL1ZDecor](*track) = 0.0;
408 }
409
410 if (outputParamsL2.get()) {
411 trackPixFloatDecorators[kTrkL2XDecor](*track) = outputParamsL2->position().x();
412 trackPixFloatDecorators[kTrkL2YDecor](*track) = outputParamsL2->position().y();
413 trackPixFloatDecorators[kTrkL2ZDecor](*track) = outputParamsL2->position().z();
414 }
415 else {
416 allExtrapolationsSucceded = false;
417 ATH_MSG_VERBOSE("Extrapolation to L2 failed...");
418 trackPixFloatDecorators[kTrkL2XDecor](*track) = 0.0;
419 trackPixFloatDecorators[kTrkL2YDecor](*track) = 0.0;
420 trackPixFloatDecorators[kTrkL2ZDecor](*track) = 0.0;
421 }
422 if(!allExtrapolationsSucceded) ATH_MSG_WARNING("At least one extrapolation to a Pixel layer failed!");
423 }
424 else{
425 ATH_MSG_WARNING("No perigee TrackParameters found - filling positions on layers to (0,0,0)!");
426 //should decorate nonetheless, to make sure decorations are consistent across events
427 trackPixFloatDecorators[kTrkIBLXDecor](*track) = 0.0;
428 trackPixFloatDecorators[kTrkIBLYDecor](*track) = 0.0;
429 trackPixFloatDecorators[kTrkIBLZDecor](*track) = 0.0;
430 trackPixFloatDecorators[kTrkBLXDecor](*track) = 0.0;
431 trackPixFloatDecorators[kTrkBLYDecor](*track) = 0.0;
432 trackPixFloatDecorators[kTrkBLZDecor](*track) = 0.0;
433 trackPixFloatDecorators[kTrkL1XDecor](*track) = 0.0;
434 trackPixFloatDecorators[kTrkL1YDecor](*track) = 0.0;
435 trackPixFloatDecorators[kTrkL1ZDecor](*track) = 0.0;
436 trackPixFloatDecorators[kTrkL2XDecor](*track) = 0.0;
437 trackPixFloatDecorators[kTrkL2YDecor](*track) = 0.0;
438 trackPixFloatDecorators[kTrkL2ZDecor](*track) = 0.0;
439 }
440 }
441
442 // -- Add Track states to the current track, filtering on their type
443 std::vector<const Trk::TrackStateOnSurface*> tsoss;
444 for (const auto *const trackState: *(trkTrack->trackStateOnSurfaces())){
445 //Get rid of any holes that already exist -- we are doing the search again
446 if( trackState->types()[Trk::TrackStateOnSurface::Hole] )
447 continue;
448 tsoss.push_back(trackState);
449 }
450
451 std::unique_ptr<const Trk::TrackStates> holes;
452 if(m_storeHoles){
453 holes = std::unique_ptr<const Trk::TrackStates>( m_holeSearchTool->getHolesOnTrack(*trkTrack, trkTrack->info().particleHypothesis()) );
454 for (const auto *hole: *holes){
455 tsoss.push_back(hole);
456 }
457 if(trkTrack->perigeeParameters()){
459 stable_sort( tsoss.begin(), tsoss.end(), CompFunc );
460 } else {
461 ATH_MSG_ERROR("Track has no perigee parameters");
462 }
463 }
464
465 //Loop over the TrkStateOnSurfaces
466 for (const auto& trackState: tsoss){
467
468 //Only store Holes, Measurement & Outliers
469 if( !trackState->types()[Trk::TrackStateOnSurface::Hole] &&
470 !trackState->types()[Trk::TrackStateOnSurface::Measurement] &&
471 !trackState->types()[Trk::TrackStateOnSurface::Outlier] ) {
472 continue;
473 }
474
475 // Check if we want to store this types of TSOS
476 if(!m_storeOutliers && trackState->types()[Trk::TrackStateOnSurface::Outlier] )
477 continue;
478
479
480 if(!m_storeHoles && trackState->types()[Trk::TrackStateOnSurface::Hole] )
481 continue;
482
483 // Check that the surface has detector element
484 if(!trackState->surface().associatedDetectorElement()){
485 continue;
486 }
487
488 // Check that the surface ID is valid
489 Identifier surfaceID = trackState->surface().associatedDetectorElement()->identify();
490 if( !surfaceID.is_valid() ){
491 ATH_MSG_WARNING("Invalid surface ID");
492 continue;
493 }
494
495 //Determine what detector the hit is in
496 bool isPixel(false);
497 bool isSCT(false);
498 bool isTRT(false);
499
500 if( m_idHelper->is_trt(surfaceID) ){
501 isTRT = true;
502 if(!m_storeTRT)
503 continue;
504 }else if( m_idHelper->is_sct(surfaceID) ){
505 isSCT = true;
506 if(!m_storeSCT)
507 continue;
508 }else if( m_idHelper->is_pixel(surfaceID) ){
509 isPixel = true;
510 if(!m_storePixel)
511 continue;
512 }
513
514 if( !isPixel && !isSCT && !isTRT ){
515 continue;
516 }
517
518 //Create new MSOS to fill with information
520
521 //Put it in the obeject in the correct conatiner - one for each detector type.
522 if(isTRT){
523 //Add the msos to the container
524 msosTRT->push_back( msos );
525 //Set the det id
527 //Build the element link to the MSOS
528 ElementLink< xAOD::TrackStateValidationContainer > elink( *msosTRT, nTRT_MSOS );
529 elink.toPersistent();
530 msosLink.push_back(elink);
531 ++nTRT_MSOS;
532 }else if(isSCT){
533 //Add the msos to the container
534 msosSCT->push_back( msos );
535 //Set the det id
537 //Build the element link to the MSOS
538 ElementLink< xAOD::TrackStateValidationContainer > elink( *msosSCT, nSCT_MSOS );
539 elink.toPersistent();
540 msosLink.push_back(elink);
541 ++nSCT_MSOS;
542 }else if(isPixel){
543 //Add the msos to the container
544 msosPixel->push_back( msos );
545 //Set the det id
547 //Build the element link to the MSOS
548 ElementLink< xAOD::TrackStateValidationContainer > elink( *msosPixel, nPixelMSOS );
549 elink.toPersistent();
550 msosLink.push_back(elink);
551 ++nPixelMSOS;
552 }
553 else {
554 ATH_MSG_WARNING("NOT a pixel, SCT or TRT track state on surface.");
555 delete msos;
556 continue;
557 }
558
559 //fill type
560 if( trackState->types()[Trk::TrackStateOnSurface::Hole] ){
562 } else if (trackState->types()[Trk::TrackStateOnSurface::Measurement]){
564 } else if ( trackState->types()[Trk::TrackStateOnSurface::Outlier] ) {
566 }
567
568 //Fill surface id
569 msos->setDetElementId( surfaceID.get_compact() );
570
571
572 const Trk::TrackParameters* tp = trackState->trackParameters();
573
574 // some more detailed hit info
575 double lTheta=-1000., lPhi=-1000.;
576 //Get the measurement base object
577 const Trk::MeasurementBase* measurement=trackState->measurementOnTrack();
578 static const SG::Accessor<float> errDCAcc("errDC");
579 errDCAcc(*msos) = -1 ;
580 const Trk::RIO_OnTrack* rotp = dynamic_cast<const Trk::RIO_OnTrack*>(measurement) ;
581 if (rotp) errDCAcc(*msos) = sqrt(rotp->localCovariance()(Trk::driftRadius, Trk::driftRadius)) ;
582
583 if (m_storeTRT) {
584 const InDet::TRT_DriftCircleOnTrack *driftcircle = dynamic_cast<const InDet::TRT_DriftCircleOnTrack*>(measurement);
585 static const SG::Accessor<float> HitZAcc("HitZ");
586 static const SG::Accessor<float> HitRAcc("HitR");
587 static const SG::Accessor<float> rTrkWireAcc("rTrkWire");
588 if (!measurement) {
589 HitZAcc(*msos)=-3000;
590 HitRAcc(*msos)=-1;
591 rTrkWireAcc(*msos)=-1;
592 }
593 else {
594 if (!driftcircle) {
595 HitZAcc(*msos)=-3000;
596 HitRAcc(*msos)=-1;
597 rTrkWireAcc(*msos)=-1;
598 }
599 else {
600 if (tp) {
601 const Amg::Vector3D& gp = driftcircle->globalPosition();
602 HitZAcc(*msos)=gp.z();
603 HitRAcc(*msos)=gp.perp();
604 rTrkWireAcc(*msos)= fabs(trackState->trackParameters()->parameters()[Trk::driftRadius]);
605 lTheta = trackState->trackParameters()->parameters()[Trk::theta];
606 lPhi = trackState->trackParameters()->parameters()[Trk::phi];
607 }
608 else {
609 HitZAcc(*msos) =driftcircle->associatedSurface().center().z();
610 HitRAcc(*msos) =driftcircle->associatedSurface().center().perp();
611 rTrkWireAcc(*msos)=0;
612 }
613 }
614 }
615 msos->setLocalAngles(lTheta, lPhi);
616
617 bool isShared=false;
618 if (prd_to_track_map_cptr) {
619 const Trk::RIO_OnTrack* hit_trt = measurement ? dynamic_cast<const Trk::RIO_OnTrack*>(measurement) : nullptr;
620 if (hit_trt) {
621 if (prd_to_track_map_cptr->isShared(*(hit_trt->prepRawData())) ) isShared=true;
622 static const SG::Accessor<bool> isSharedAcc("isShared");
623 isSharedAcc(*msos) = isShared;
624 }
625 }
626 }
627
628 // Track extrapolation
629 std::unique_ptr<const Trk::TrackParameters> extrap( m_extrapolator->extrapolateTrack(ctx,*trkTrack,trackState->surface()) );
630
631 // Set local positions on the surface
632 if (tp) {
633 msos->setLocalPosition( tp->parameters()[0], tp->parameters()[1] );
634
635 if (extrap.get()) {
636 ATH_MSG_DEBUG(" Original position " << tp->parameters()[0] << " " << tp->parameters()[1]);
637 ATH_MSG_DEBUG("Extrapolated position " << extrap->parameters()[0] << " " << extrap->parameters()[1]);
638 }
639
640 }
641 else {
642 if (extrap.get()) {
643 msos->setLocalPosition( extrap->parameters()[0], extrap->parameters()[1] );
644 }
645 else {
646 ATH_MSG_DEBUG("Track extrapolation failed.");
647 }
648 }
649
650 // Set calculate local incident angles
651 const Trk::TrkDetElementBase *de = trackState->surface().associatedDetectorElement();
652 const InDetDD::SiDetectorElement *side = dynamic_cast<const InDetDD::SiDetectorElement *>(de);
653 if (side && (isSCT || isPixel)) {
654 const Amg::Vector3D& mynormal = side->normal();
655 const Amg::Vector3D& myphiax = side->phiAxis();
656 const Amg::Vector3D& myetaax = side->etaAxis();
657 if (tp) {
658 Amg::Vector3D mytrack = tp->momentum();
659 float trketacomp = mytrack.dot(myetaax);
660 float trkphicomp = mytrack.dot(myphiax);
661 float trknormcomp = mytrack.dot(mynormal);
662
663 ATH_MSG_DEBUG(" Original incident angle " << trketacomp << " " << trkphicomp << " " << trknormcomp);
664 if (extrap.get()) {
665 Amg::Vector3D metrack = extrap->momentum();
666 float trketacompX = metrack.dot(myetaax);
667 float trkphicompX = metrack.dot(myphiax);
668 float trknormcompX = metrack.dot(mynormal);
669 ATH_MSG_DEBUG("Extrapolated incident angle " << trketacompX << " " << trkphicompX << " " << trknormcompX);
670 }
671 msos->setLocalAngles( atan2(trketacomp,trknormcomp), atan2(trkphicomp,trknormcomp) );
672 }
673 else {
674 if (extrap.get()) {
675 Amg::Vector3D metrack = extrap->momentum();
676 float trketacompX = metrack.dot(myetaax);
677 float trkphicompX = metrack.dot(myphiax);
678 float trknormcompX = metrack.dot(mynormal);
679 msos->setLocalAngles( atan2(trketacompX,trknormcompX), atan2(trkphicompX,trknormcompX) );
680 }
681 }
682 }
683
684 if(!measurement) { continue; }
685
686 if (isTRT && ( !trtDCOffsets || !trtDCs)) { continue; }
687 if (isSCT && ( !sctClusterOffsets || !sctClusters)) { continue; }
688 if (isPixel && (!pixelClusterOffsets || !pixelClusters)) { continue; }
689
690 const Trk::RIO_OnTrack* hit = measurement ? dynamic_cast<const Trk::RIO_OnTrack*>(measurement) : nullptr;
691
692 if(!hit){
693 const Trk::CompetingRIOsOnTrack *crot = dynamic_cast<const Trk::CompetingRIOsOnTrack*>(measurement);
694 if(crot){
695 hit = &crot->rioOnTrack( crot->indexOfMaxAssignProb() );
696 }
697 }
698
699 if(m_addPRD && hit){
700 // Build an element link to the xAOD PRD
701 const Trk::PrepRawData* prd = hit->prepRawData();
702 if(prd && prd->getHashAndIndex().isValid() ){
703 if(isTRT){
704 msos->setTrackMeasurementValidationLink( buildElementLink( prd, trtDCOffsets, trtDCs));
705 }else if(isSCT){
706 msos->setTrackMeasurementValidationLink( buildElementLink( prd, sctClusterOffsets, sctClusters));
707 }else if(isPixel){
708 msos->setTrackMeasurementValidationLink( buildElementLink( prd, pixelClusterOffsets, pixelClusters) );
709 }
710 }
711 }
712
713 if (m_storeSCT && isSCT) {
714 // We use accessors because the aux variable is added directly in the TrackMeasurementValidation cluster producer
715 // and we are decorating the MSOS in the TrackStateValidationContainer producer here
716 static const SG::Accessor<int> SiWidthAcc("SiWidth");
717 static const SG::Accessor<int> firstStripAcc("first_strip");
718 static const SG::Accessor<std::vector<int>> rdoStripAcc("rdo_strip");
719
720 if( msos->trackMeasurementValidationLink().isValid() && *(msos->trackMeasurementValidationLink())
721 && rdoStripAcc.isAvailable(**msos->trackMeasurementValidationLink())){
723 SiWidthAcc(*msos) = SiWidthAcc(*sctCluster);
724 firstStripAcc(*msos) = (rdoStripAcc(*sctCluster)).at(0);
725 } else {
726 SiWidthAcc(*msos) = -1;
727 firstStripAcc(*msos) = -1;
728 }
729 }
730
731 // Add the drift time for the tracks position -- note the position is biased
732 if (isTRT) {
733 TRTCond::RtRelation const *rtr = m_trtcaldbTool->getRtRelation(surfaceID);
734 if(rtr) {
735 static const SG::Accessor<float> driftTimeAcc("driftTime");
736 if (tp){
737 driftTimeAcc(*msos) = rtr->drifttime(fabs(tp->parameters()[0]));
738 }
739 else {
740 if (extrap.get()) {
741 driftTimeAcc(*msos) = rtr->drifttime(fabs(extrap->parameters()[0]));
742 }
743 }
744 }
745 }
746
747 static const SG::Accessor<float> TrackError_biasedAcc("TrackError_biased");
748 static const SG::Accessor<float> TrackError_unbiasedAcc("TrackError_unbiased");
749 if (m_addPulls) {
750
751 std::optional<Trk::ResidualPull> biased;
752 std::optional<Trk::ResidualPull> unbiased;
753 if (tp) {
754 biased= m_residualPullCalculator->residualPull(measurement, tp, Trk::ResidualPull::Biased);
755 if (m_storeTRT) TrackError_biasedAcc(*msos) = sqrt(fabs((*tp->covariance())(Trk::locX,Trk::locX)));
756
757 if (m_storeTRT) TrackError_biasedAcc(*msos) = sqrt(fabs((*tp->covariance())(Trk::locX,Trk::locX)));
758 std::unique_ptr<const Trk::TrackParameters> unbiasedTp( m_updator->removeFromState(*tp, measurement->localParameters(), measurement->localCovariance()) );
759 if(unbiasedTp.get()) {
760 if (m_storeTRT) TrackError_unbiasedAcc(*msos) = sqrt(fabs((*unbiasedTp.get()->covariance())(Trk::locX,Trk::locX)));
761 unbiased = m_residualPullCalculator->residualPull(measurement, unbiasedTp.get(), Trk::ResidualPull::Unbiased);
762 }
763 }
764 else {
765 if (extrap.get()) {
766 if (m_storeTRT) TrackError_unbiasedAcc(*msos) = sqrt(fabs((*extrap.get()->covariance())(Trk::locX,Trk::locX)));
767 biased = m_residualPullCalculator->residualPull(measurement, extrap.get(), Trk::ResidualPull::Biased);
768 unbiased = m_residualPullCalculator->residualPull(measurement, extrap.get(), Trk::ResidualPull::Unbiased);
769 }
770 }
771
772 if (biased) {
773 if(biased->dimension()>Trk::locY){
774 msos->setBiasedResidual( biased->residual()[Trk::locX], biased->residual()[Trk::locY] );
775 msos->setBiasedPull( biased->pull()[Trk::locX], biased->pull()[Trk::locY] );
776 } else {
777 msos->setBiasedResidual( biased->residual()[Trk::locX], 0 );
778 msos->setBiasedPull( biased->pull()[Trk::locX], 0 );
779 }
780 }
781
782 if (unbiased) {
783 if(unbiased->dimension()>Trk::locY){
784 msos->setUnbiasedResidual( unbiased->residual()[Trk::locX], unbiased->residual()[Trk::locY] );
785 msos->setUnbiasedPull( unbiased->pull()[Trk::locX], unbiased->pull()[Trk::locY] );
786 } else {
787 msos->setUnbiasedResidual( unbiased->residual()[Trk::locX], 0 );
788 msos->setUnbiasedPull( unbiased->pull()[Trk::locX], 0 );
789 }
790 }
791
792 }
793
794 } //end loop over TSOS's
795
796 ATH_MSG_DEBUG("The number of TSOS's " << msosLink.size() );
797
798 dectsos_msosLink( *track ) = msosLink;
799
800 ATH_MSG_DEBUG("Finished dressing TrackParticle");
801
802 ++i_track;
803 } // end of loop over tracks
804 return StatusCode::SUCCESS;
805 }
806
807
809 const std::vector<unsigned int>* offsets,
810 const xAOD::TrackMeasurementValidationContainer* xaodPrdCont) const
811 {
812
813 const IdentContIndex& contIndex = prd->getHashAndIndex();
814
815 if( contIndex.collHash() >= offsets->size() ){
816 ATH_MSG_ERROR(" Offsets are incorrect " << contIndex.collHash() << " " << offsets->size() <<" "<< contIndex.objIndex());
817 return {0,0};
818 }
819
820 unsigned int xaodIndex = offsets->at( contIndex.collHash() ) + contIndex.objIndex();
822 el.toPersistent();
823
824 return el;
825
826 }
827
828
829}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
This class provides an interface to generate or decode an identifier for the upper levels of the dete...
Helper class to provide constant type-safe access to aux data.
Helper class to provide type-safe access to aux data.
abstract interface to TRT calibration constants
This is an Identifier helper class for the Pixel subdetector.
This is an Identifier helper class for the SCT subdetector.
Handle class for reading a decoration on an object.
Handle class for reading from StoreGate.
Property holding a SG store/key/clid/attr name from which a WriteDecorHandle is made.
Handle class for adding a decoration to an object.
This is an Identifier helper class for the TRT subdetector.
size_type size() const noexcept
Returns the number of elements in the collection.
SG::WriteHandleKey< xAOD::TrackStateValidationContainer > m_pixelMsosName
std::vector< SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > > m_trackPixFloatDecorKeys
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_containerName
SG::ReadHandleKey< xAOD::TrackMeasurementValidationContainer > m_trtDCName
std::vector< SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > > m_trackTRTFloatDecorKeys
std::vector< SG::WriteDecorHandleKey< xAOD::EventInfo > > m_trtPhaseDecorKey
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_trackTSOSMOSLinkDecorKey
virtual StatusCode addBranches(const EventContext &ctx) const
ElementLink< xAOD::TrackMeasurementValidationContainer > buildElementLink(const Trk::PrepRawData *, const std::vector< unsigned int > *, const xAOD::TrackMeasurementValidationContainer *) const
SG::ReadHandleKey< std::vector< unsigned int > > m_pixelMapName
SG::ReadHandleKey< xAOD::TrackMeasurementValidationContainer > m_sctClustersName
SG::WriteHandleKey< xAOD::TrackStateValidationContainer > m_sctMsosName
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_SCTDetEleCollKey
SG::ReadHandleKey< xAOD::TrackMeasurementValidationContainer > m_pixelClustersName
ToolHandle< Trk::IResidualPullCalculator > m_residualPullCalculator
SG::ReadHandleKey< std::vector< unsigned int > > m_trtMapName
Gaudi::Property< std::vector< float > > m_pixelLayerRadii
SG::ReadHandleKey< std::vector< unsigned int > > m_sctMapName
SG::WriteHandleKey< xAOD::TrackStateValidationContainer > m_trtMsosName
Identifiable container index to a contained object.
unsigned short objIndex() const
object index in collection
unsigned short collHash() const
Accessor to hash, obj index and combined index.
bool isValid() const
check that both fields are set
bool is_valid() const
Check if id is in a valid state.
value_type get_compact() const
Get the compact id.
Class to hold geometrical description of a silicon detector element.
Represents 'corrected' measurements from the TRT (for example, corrected for wire sag).
virtual const Amg::Vector3D & globalPosition() const override final
return the global position of this RIO_OnTrack
virtual const Trk::Surface & associatedSurface() const override final
returns the surface for the local to global transformation
Helper class to provide type-safe access to aux data.
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Handle class for adding a decoration to an object.
Base class for rt-relations in the TRT.
Definition RtRelation.h:27
virtual float drifttime(float radius) const =0
drifttime for given radius
Base class for all CompetingRIOsOnTack implementations, extends the common MeasurementBase.
unsigned int indexOfMaxAssignProb() const
Index of the ROT with the highest assignment probability.
virtual const RIO_OnTrack & rioOnTrack(unsigned int) const =0
returns the RIO_OnTrack (also known as ROT) objects depending on the integer.
Class for a CylinderSurface in the ATLAS detector.
This class is the pure abstract base class for all fittable tracking measurements.
const LocalParameters & localParameters() const
Interface method to get the LocalParameters.
const Amg::MatrixX & localCovariance() const
Interface method to get the localError.
bool isShared(const PrepRawData &prd) const
does this PRD belong to more than one track?
const Amg::Vector3D & momentum() const
Access method for the momentum.
virtual const S & associatedSurface() const override final
Access to the Surface method.
const IdentContIndex & getHashAndIndex() const
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.
@ Biased
RP with track state including the hit.
@ Unbiased
RP with track state that has measurement not included.
const TrkDetElementBase * associatedDetectorElement() const
return associated Detector Element
const Amg::Vector3D & center() const
Returns the center position of the Surface.
ParticleHypothesis particleHypothesis() const
Returns the particle hypothesis used for Track fitting.
Class providing comparison function, or relational definition, for sorting MeasurementBase objects.
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
@ Outlier
This TSoS contains an outlier, that is, it contains a MeasurementBase/RIO_OnTrack which was not used ...
@ Hole
A hole on the track - this is defined in the following way.
const Trk::TrackStates * trackStateOnSurfaces() const
return a pointer to a const DataVector of const TrackStateOnSurfaces.
const TrackInfo & info() const
Returns a const ref to info of a const tracks.
const Perigee * perigeeParameters() const
return Perigee.
This is the base class for all tracking detector elements with read-out relevant information.
virtual const Surface & surface() const =0
Return surface associated with this detector element.
void setBiasedPull(float biasedPullX, float biasedPullY)
Sets the biased pull.
void setLocalPosition(float localX, float localY)
Sets the local position.
void setUnbiasedResidual(float unbiasedResidualX, float unbiasedResidualY)
Sets the unbiased residual.
void setDetType(char detType)
Sets the detector type.
void setBiasedResidual(float biasedResidualX, float biasedResidualY)
Sets the biased residual.
void setDetElementId(uint64_t detElementId)
Sets the detector element identifier.
void setType(int type)
Sets the type (measurement, outlier, hole).
void setLocalAngles(float localTheta, float localPhi)
Sets the local angles.
void setTrackMeasurementValidationLink(ElementLink< xAOD::TrackMeasurementValidationContainer > trackMeasurementValidationLink)
sets the link to the TrackMeasurementValidationContainer
ElementLink< xAOD::TrackMeasurementValidationContainer > trackMeasurementValidationLink() const
void setUnbiasedPull(float unbiasedPullX, float unbiasedPullY)
Sets the unbiased pull.
double entries
Definition listroot.cxx:49
Eigen::Matrix< double, 3, 1 > Vector3D
THE reconstruction tool.
std::vector< SG::WriteDecorHandle< T_Cont, T > > createDecorators(const std::vector< SG::WriteDecorHandleKey< T_Cont > > &keys, const EventContext &ctx)
void createDecoratorKeys(T_Parent &parent, const SG::ReadHandleKey< T_Cont > &container_key, const std::string &prefix, const std::vector< std::string > &decor_names, std::vector< SG::WriteDecorHandleKey< T_Cont > > &decor_out)
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
PropDirection
PropDirection, enum for direction of the propagation.
@ oppositeMomentum
@ alongMomentum
@ driftRadius
trt, straws
Definition ParamDefs.h:53
@ locY
local cartesian
Definition ParamDefs.h:38
@ locX
Definition ParamDefs.h:37
@ theta
Definition ParamDefs.h:66
@ phi
Definition ParamDefs.h:75
MaterialUpdateMode
This is a steering enum to force the material update it can be: (1) addNoise (-1) removeNoise Second ...
ParametersBase< TrackParametersDim, Charged > TrackParameters
TrackMeasurementValidation_v1 TrackMeasurementValidation
Reference the current persistent version:
TrackStateValidationContainer_v1 TrackStateValidationContainer
Definition of the current "TrackStateValidation container version".
EventInfo_v1 EventInfo
Definition of the latest event info version.
TrackStateValidation_v1 TrackStateValidation
Reference the current persistent version:
TrackStateValidationAuxContainer_v1 TrackStateValidationAuxContainer
Definition of the current TrackStateValidation auxiliary container.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
TrackMeasurementValidationContainer_v1 TrackMeasurementValidationContainer
Definition of the current "TrackMeasurementValidation container version".