ATLAS Offline Software
Loading...
Searching...
No Matches
TrackStateOnSurfaceDecorator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 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
17
21
27
31
37
39
40
42
44#include "TrkTrack/Track.h"
45
48
51
59
60#include <vector>
61#include <string>
62
63namespace DerivationFramework {
64
66 {
67 ATH_MSG_DEBUG("Initialize");
68
69 if (m_sgName.value() == "notSet") {
70 ATH_MSG_ERROR("No decoration prefix name provided for the output of TrackStateOnSurfaceDecorator! Use the variable DecorationPrefix to properly set a prefix.");
71 return StatusCode::FAILURE;
72 }
73 ATH_MSG_DEBUG("Prefix for decoration: " << m_sgName);
74
76 if (m_containerName.key().empty()) {
77 ATH_MSG_ERROR("No TrackParticle collection provided for TrackStateOnSurfaceDecorator!");
78 return StatusCode::FAILURE;
79 }
80 ATH_MSG_DEBUG("Input TrackParticle container: " << m_containerName.key());
81 ATH_CHECK( m_containerName.initialize() );
82
83 if (!m_selectionString.empty()) {
84 ATH_CHECK(initializeParser(m_selectionString));
85 }
86
87 // need Atlas id-helpers to identify sub-detectors, take them from detStore
88 if (detStore()->retrieve(m_idHelper, "AtlasID").isFailure()) {
89 ATH_MSG_ERROR("Could not get AtlasDetectorID helper");
90 return StatusCode::FAILURE;
91 }
92
93 if( m_storePixel && detStore()->retrieve(m_pixId,"PixelID").isFailure() ){
94 ATH_MSG_ERROR("Unable to retrieve pixel ID helper");
95 return StatusCode::FAILURE;
96 }
97
98 if( m_storeSCT && detStore()->retrieve(m_sctId,"SCT_ID").isFailure() ){
99 ATH_MSG_ERROR("Could not retrieve SCT helper");
100 return StatusCode::FAILURE;
101 }
102
103 if( m_storeTRT && detStore()->retrieve(m_trtId,"TRT_ID").isFailure() ){
104 ATH_MSG_ERROR("Could not retrieve TRT helper");
105 return StatusCode::FAILURE;
106 }
107
108 ATH_CHECK( m_trtcaldbTool.retrieve(DisableTool{ !m_storeTRT }));
109 ATH_CHECK( m_prdToTrackMap.initialize( !m_prdToTrackMap.key().empty() && m_storeTRT) );
110
111 ATH_CHECK( m_updator.retrieve(DisableTool{ !m_addPulls }));
112 ATH_CHECK( m_residualPullCalculator.retrieve(DisableTool{ !m_addPulls }));
113
114 ATH_CHECK( m_holeSearchTool.retrieve( DisableTool{ !m_storeHoles}) );
115
116 ATH_CHECK( m_TRTdEdxTool.retrieve( DisableTool{!m_storeTRT || m_TRTdEdxTool.empty()}) );
117
118 ATH_CHECK(m_extrapolator.retrieve());
119
120
122
124 std::vector<std::string> decor_names{"TrtPhaseTime"};
125 std::vector<SG::WriteDecorHandleKey<xAOD::EventInfo> > decor_key_out;
127 assert(m_trtPhaseDecorKey.size() == 1);
128 }
129 if (m_storeTRT && m_TRTdEdxTool.isEnabled()) {
130 std::vector<std::string> names;
131 names.resize(kNTRTFloatDecor);
132 names[kTRTdEdxDecor]="ToT_dEdx";
133 names[kTRTusedHitsDecor]="ToT_usedHits";
134 names[kTRTdEdx_noHT_divByLDecor]="ToT_dEdx_noHT_divByL";
135 names[kTRTusedHits_noHT_divByLDecor]="ToT_usedHits_noHT_divByL";
137 }
140 ATH_CHECK( m_sctMapName.initialize(m_storeSCT && m_addPRD) );
141 ATH_CHECK( m_trtMapName.initialize(m_storeTRT && m_addPRD) );
142
145 ATH_CHECK( m_trtDCName.initialize(m_storeTRT && m_addPRD) );
146
148 ATH_CHECK( m_sctMsosName.initialize(m_storeSCT && m_addPRD) );
149 ATH_CHECK( m_trtMsosName.initialize(m_storeTRT && m_addPRD) );
150
151 if (m_storePixel){
152 std::vector<std::string> names;
153 names.resize(kNPixFloatDecor);
154 names[kTrkIBLXDecor]="TrkIBLX";
155 names[kTrkIBLYDecor]="TrkIBLY";
156 names[kTrkIBLZDecor]="TrkIBLZ";
157 names[kTrkBLXDecor]="TrkBLX";
158 names[kTrkBLYDecor]="TrkBLY";
159 names[kTrkBLZDecor]="TrkBLZ";
160 names[kTrkL1XDecor]="TrkL1X";
161 names[kTrkL1YDecor]="TrkL1Y";
162 names[kTrkL1ZDecor]="TrkL1Z";
163 names[kTrkL2XDecor]="TrkL2X";
164 names[kTrkL2YDecor]="TrkL2Y";
165 names[kTrkL2ZDecor]="TrkL2Z";
167 }
168
169 m_trackTSOSMOSLinkDecorKey = m_containerName.key() + "." + m_sgName + "msosLink";
171
172 ATH_MSG_DEBUG("Initialization finished.");
173
174 return StatusCode::SUCCESS;
175 }
176
178 {
179 ATH_MSG_DEBUG("Finalize");
180 return StatusCode::SUCCESS;
181 }
182
183 StatusCode TrackStateOnSurfaceDecorator::addBranches(const EventContext& ctx) const
184 {
185 ATH_MSG_DEBUG("Adding TSOS decorations the track particles");
186
188
189 // --- Retrieve track container (absolutely needed for decoration)
191 if( ! tracks.isValid() ) {
192 ATH_MSG_ERROR ("Couldn't retrieve TrackParticles with key: " << m_containerName.key() );
193 return StatusCode::FAILURE;
194 }
195 size_t nTracks = tracks->size();
196
197
198 SG::ReadHandle<std::vector<unsigned int> > pixelClusterOffsets;
201
205
206
207 // Create the xAOD container and its auxiliary store
211
212 int nPixelMSOS(0);
213 int nSCT_MSOS(0);
214 int nTRT_MSOS(0);
215
216 // --- Add event-level information
218 ATH_MSG_DEBUG("Adding EventInfo decorations");
220 if (!eventInfo.isValid()) {
221 ATH_MSG_ERROR(" Cannot access to event info.");
222 return StatusCode::FAILURE;
223 }
224
225 //Add TRT event phase
227 float trtPhase_time=0.;
228 if (!trtPhase.isValid()) {
229 ATH_MSG_DEBUG("Failed to retrieve TRT phase information.");
230 } else {
231 trtPhase_time = trtPhase->getTime();
232 } //TRT phase
234 decorTRTPhase(*eventInfo) = trtPhase_time;
235 } //extra event info
236
237 // --- Add track states containers
238 if(m_addPRD){
239 // Get clusters and the mapping between xAOD::PRD and Trk::PRD
240 // Store the MSOS's in a conatiner based on the type of the detector
241 if(m_storePixel){
242 ATH_MSG_DEBUG("Creating Pixel track state container");
245
247 if (msosPixel.record(std::make_unique<xAOD::TrackStateValidationContainer>(),
248 std::make_unique<xAOD::TrackStateValidationAuxContainer>()).isFailure()) {
249 ATH_MSG_ERROR("Failed to record " << m_pixelMsosName.key() );
250 return StatusCode::FAILURE;
251 }
252 }
253 if(m_storeSCT){
254 ATH_MSG_DEBUG("Creating SCT track state container");
257
259 if (msosSCT.record(std::make_unique<xAOD::TrackStateValidationContainer>(),
260 std::make_unique<xAOD::TrackStateValidationAuxContainer>()).isFailure()) {
261 ATH_MSG_ERROR("Failed to record " << m_sctMsosName.key() );
262 return StatusCode::FAILURE;
263 }
264 }
265 if(m_storeTRT){
266 ATH_MSG_DEBUG("Creating TRT track state container");
269
271 if (msosTRT.record(std::make_unique<xAOD::TrackStateValidationContainer>(),
272 std::make_unique<xAOD::TrackStateValidationAuxContainer>()).isFailure()) {
273 ATH_MSG_ERROR("Failed to record " << m_trtMsosName.key() );
274 return StatusCode::FAILURE;
275 }
276 }
277 }
278
279 SG::ReadHandle<Trk::PRDtoTrackMap> prd_to_track_map;
280 const Trk::PRDtoTrackMap *prd_to_track_map_cptr{};
281 if (!m_prdToTrackMap.key().empty()) {
283 if (!prd_to_track_map.isValid()) {
284 ATH_MSG_ERROR("Failed to read PRD to track association map: " << m_prdToTrackMap.key());
285 }
286 prd_to_track_map_cptr = prd_to_track_map.cptr();
287 }
288
289 // Set up a mask with the same entries as the full TrackParticle collection
290 std::vector<bool> mask;
291 mask.assign(nTracks,true); // default: keep all the tracks
292 if (m_parser) {
293 std::vector<int> entries = m_parser->evaluateAsVector();
294 unsigned int nEntries = entries.size();
295 // check the sizes are compatible
296 if (nTracks != nEntries ) {
297 ATH_MSG_ERROR("Sizes incompatible! Are you sure your selection string used ID TrackParticles?");
298 return StatusCode::FAILURE;
299 } else {
300 // set mask
301 for (unsigned int i=0; i<nTracks; ++i) if (entries[i]!=1) mask[i]=false;
302 }
303 }
304
305 std::vector<SG::WriteDecorHandle<xAOD::TrackParticleContainer,float> > trackTRTFloatDecorators;
306 if (m_storeTRT && m_TRTdEdxTool.isEnabled()) {
308 }
309 std::vector<SG::WriteDecorHandle<xAOD::TrackParticleContainer,float> >
311 // -- Run over each track and decorate it
312 unsigned i_track = 0;
313 for (const auto *const track : *tracks) {
314 //-- Start with things that do not need a Trk::Track object
315
316 // mask bit check
317 if(!mask[i_track]) {
318 ++i_track;
319 continue;
320 }
321
322 // -- Now things that require a Trk::Track object
323 if( !track->trackLink().isValid() || track->track() == nullptr ) {
324 ATH_MSG_WARNING("Track particle without Trk::Track");
325 continue;
326 }
327 ATH_MSG_DEBUG("We have a Trk::Track");
328
329 // We now have a valid Trk::Track
330 const Trk::Track* trkTrack = track->track();
331
332 // This is the vector in which we will store the element links to the MSOS's
333 std::vector< ElementLink< xAOD::TrackStateValidationContainer > > msosLink;
334
335 if ( m_storeTRT && m_TRTdEdxTool.isEnabled() ) {
336 // for dEdx studies
337 trackTRTFloatDecorators[kTRTdEdxDecor] (*track) = m_TRTdEdxTool->dEdx(trkTrack,true);
338 trackTRTFloatDecorators[kTRTusedHitsDecor] (*track) = m_TRTdEdxTool->usedHits(trkTrack);
339 trackTRTFloatDecorators[kTRTdEdx_noHT_divByLDecor] (*track) = m_TRTdEdxTool->dEdx(trkTrack, false);
340 trackTRTFloatDecorators[kTRTusedHits_noHT_divByLDecor] (*track) = m_TRTdEdxTool->usedHits(trkTrack, false);
341 }
342
343 if(m_storePixel){
344 if ( trkTrack->perigeeParameters() ){
345
346 if(m_pixelLayerRadii.size() < 4) ATH_MSG_WARNING("Too few layer radii set! Should be at least 4!");
347
348 Trk::CylinderSurface cylSurfIBL(m_pixelLayerRadii[0], 3000.0);
349 Trk::CylinderSurface cylSurfBL(m_pixelLayerRadii[1], 3000.0);
350 Trk::CylinderSurface cylSurfL1(m_pixelLayerRadii[2], 3000.0);
351 Trk::CylinderSurface cylSurfL2(m_pixelLayerRadii[3], 3000.0);
352
353 bool allExtrapolationsSucceded = true;
356 //check the radius of the start parameters, to see which direction we need to go to the target surface
357 float startRadius = trkTrack->perigeeParameters()->associatedSurface().center().perp();
358 ATH_MSG_VERBOSE("Start radius for extrapolating to layers: "<<startRadius);
359 //see if we go along or opposite momentum
360 if(startRadius>m_pixelLayerRadii[0]) {whichDir = Trk::oppositeMomentum; whichMode = Trk::addNoise;}
361 std::unique_ptr<const Trk::TrackParameters> outputParamsIBL
362 (m_extrapolator->extrapolate(ctx,
363 *(trkTrack->perigeeParameters()),
364 cylSurfIBL,
365 whichDir,
366 true,
367 Trk::pion,
368 whichMode));
369 if(startRadius>m_pixelLayerRadii[1]){
370 whichDir = Trk::oppositeMomentum;
371 whichMode = Trk::addNoise;
372 }
373 std::unique_ptr<const Trk::TrackParameters> outputParamsBL
374 (m_extrapolator->extrapolate(ctx,
375 *(trkTrack->perigeeParameters()),
376 cylSurfBL,
377 whichDir,
378 true,
379 Trk::pion,
380 whichMode));
381 if(startRadius>m_pixelLayerRadii[2]){
382 whichDir = Trk::oppositeMomentum;
383 whichMode = Trk::addNoise;
384 }
385 std::unique_ptr<const Trk::TrackParameters> outputParamsL1
386 (m_extrapolator->extrapolate(ctx,
387 *(trkTrack->perigeeParameters()),
388 cylSurfL1,
389 whichDir,
390 true,
391 Trk::pion,
392 whichMode));
393 if(startRadius>m_pixelLayerRadii[2]){
394 whichDir = Trk::oppositeMomentum;
395 whichMode = Trk::addNoise;
396 }
397 std::unique_ptr<const Trk::TrackParameters> outputParamsL2
398 (m_extrapolator->extrapolate(ctx,
399 *(trkTrack->perigeeParameters()),
400 cylSurfL2,
401 whichDir,
402 true,
403 Trk::pion,
404 whichMode));
405
406 if (outputParamsIBL.get()) {
407 trackPixFloatDecorators[kTrkIBLXDecor](*track) = outputParamsIBL->position().x();
408 trackPixFloatDecorators[kTrkIBLYDecor](*track) = outputParamsIBL->position().y();
409 trackPixFloatDecorators[kTrkIBLZDecor](*track) = outputParamsIBL->position().z();
410 }
411 else {
412 allExtrapolationsSucceded = false;
413 ATH_MSG_VERBOSE("Extrapolation to IBL failed...");
414 trackPixFloatDecorators[kTrkIBLXDecor](*track) = 0.0;
415 trackPixFloatDecorators[kTrkIBLYDecor](*track) = 0.0;
416 trackPixFloatDecorators[kTrkIBLZDecor](*track) = 0.0;
417 }
418
419 if (outputParamsBL.get()) {
420 trackPixFloatDecorators[kTrkBLXDecor](*track) = outputParamsBL->position().x();
421 trackPixFloatDecorators[kTrkBLYDecor](*track) = outputParamsBL->position().y();
422 trackPixFloatDecorators[kTrkBLZDecor](*track) = outputParamsBL->position().z();
423 }
424 else {
425 allExtrapolationsSucceded = false;
426 ATH_MSG_VERBOSE("Extrapolation to BLayer failed...");
427 trackPixFloatDecorators[kTrkBLXDecor](*track) = 0.0;
428 trackPixFloatDecorators[kTrkBLYDecor](*track) = 0.0;
429 trackPixFloatDecorators[kTrkBLZDecor](*track) = 0.0;
430 }
431
432 if (outputParamsL1.get()) {
433 trackPixFloatDecorators[kTrkL1XDecor](*track) = outputParamsL1->position().x();
434 trackPixFloatDecorators[kTrkL1YDecor](*track) = outputParamsL1->position().y();
435 trackPixFloatDecorators[kTrkL1ZDecor](*track) = outputParamsL1->position().z();
436 }
437 else {
438 allExtrapolationsSucceded = false;
439 ATH_MSG_VERBOSE("Extrapolation to L1 failed...");
440 trackPixFloatDecorators[kTrkL1XDecor](*track) = 0.0;
441 trackPixFloatDecorators[kTrkL1YDecor](*track) = 0.0;
442 trackPixFloatDecorators[kTrkL1ZDecor](*track) = 0.0;
443 }
444
445 if (outputParamsL2.get()) {
446 trackPixFloatDecorators[kTrkL2XDecor](*track) = outputParamsL2->position().x();
447 trackPixFloatDecorators[kTrkL2YDecor](*track) = outputParamsL2->position().y();
448 trackPixFloatDecorators[kTrkL2ZDecor](*track) = outputParamsL2->position().z();
449 }
450 else {
451 allExtrapolationsSucceded = false;
452 ATH_MSG_VERBOSE("Extrapolation to L2 failed...");
453 trackPixFloatDecorators[kTrkL2XDecor](*track) = 0.0;
454 trackPixFloatDecorators[kTrkL2YDecor](*track) = 0.0;
455 trackPixFloatDecorators[kTrkL2ZDecor](*track) = 0.0;
456 }
457 if(!allExtrapolationsSucceded) ATH_MSG_WARNING("At least one extrapolation to a Pixel layer failed!");
458 }
459 else{
460 ATH_MSG_WARNING("No perigee TrackParameters found - filling positions on layers to (0,0,0)!");
461 //should decorate nonetheless, to make sure decorations are consistent across events
462 trackPixFloatDecorators[kTrkIBLXDecor](*track) = 0.0;
463 trackPixFloatDecorators[kTrkIBLYDecor](*track) = 0.0;
464 trackPixFloatDecorators[kTrkIBLZDecor](*track) = 0.0;
465 trackPixFloatDecorators[kTrkBLXDecor](*track) = 0.0;
466 trackPixFloatDecorators[kTrkBLYDecor](*track) = 0.0;
467 trackPixFloatDecorators[kTrkBLZDecor](*track) = 0.0;
468 trackPixFloatDecorators[kTrkL1XDecor](*track) = 0.0;
469 trackPixFloatDecorators[kTrkL1YDecor](*track) = 0.0;
470 trackPixFloatDecorators[kTrkL1ZDecor](*track) = 0.0;
471 trackPixFloatDecorators[kTrkL2XDecor](*track) = 0.0;
472 trackPixFloatDecorators[kTrkL2YDecor](*track) = 0.0;
473 trackPixFloatDecorators[kTrkL2ZDecor](*track) = 0.0;
474 }
475 }
476
477 // -- Add Track states to the current track, filtering on their type
478 std::vector<const Trk::TrackStateOnSurface*> tsoss;
479 for (const auto *const trackState: *(trkTrack->trackStateOnSurfaces())){
480 //Get rid of any holes that already exist -- we are doing the search again
481 if( trackState->types()[Trk::TrackStateOnSurface::Hole] )
482 continue;
483 tsoss.push_back(trackState);
484 }
485
486 std::unique_ptr<const Trk::TrackStates> holes;
487 if(m_storeHoles){
488 holes = std::unique_ptr<const Trk::TrackStates>( m_holeSearchTool->getHolesOnTrack(*trkTrack, trkTrack->info().particleHypothesis()) );
489 for (const auto *hole: *holes){
490 tsoss.push_back(hole);
491 }
492 if(trkTrack->perigeeParameters()){
494 stable_sort( tsoss.begin(), tsoss.end(), CompFunc );
495 } else {
496 ATH_MSG_ERROR("Track has no perigee parameters");
497 }
498 }
499
500 //Loop over the TrkStateOnSurfaces
501 for (const auto& trackState: tsoss){
502
503 //Only store Holes, Measurement & Outliers
504 if( !trackState->types()[Trk::TrackStateOnSurface::Hole] &&
505 !trackState->types()[Trk::TrackStateOnSurface::Measurement] &&
506 !trackState->types()[Trk::TrackStateOnSurface::Outlier] ) {
507 continue;
508 }
509
510 // Check if we want to store this types of TSOS
511 if(!m_storeOutliers && trackState->types()[Trk::TrackStateOnSurface::Outlier] )
512 continue;
513
514
515 if(!m_storeHoles && trackState->types()[Trk::TrackStateOnSurface::Hole] )
516 continue;
517
518 // Check that the surface has detector element
519 if(!trackState->surface().associatedDetectorElement()){
520 continue;
521 }
522
523 // Check that the surface ID is valid
524 Identifier surfaceID = trackState->surface().associatedDetectorElement()->identify();
525 if( !surfaceID.is_valid() ){
526 ATH_MSG_WARNING("Invalid surface ID");
527 continue;
528 }
529
530 //Determine what detector the hit is in
531 bool isPixel(false);
532 bool isSCT(false);
533 bool isTRT(false);
534
535 if( m_idHelper->is_trt(surfaceID) ){
536 isTRT = true;
537 if(!m_storeTRT)
538 continue;
539 }else if( m_idHelper->is_sct(surfaceID) ){
540 isSCT = true;
541 if(!m_storeSCT)
542 continue;
543 }else if( m_idHelper->is_pixel(surfaceID) ){
544 isPixel = true;
545 if(!m_storePixel)
546 continue;
547 }
548
549 if( !isPixel && !isSCT && !isTRT ){
550 continue;
551 }
552
553 //Create new MSOS to fill with information
555
556 //Put it in the obeject in the correct conatiner - one for each detector type.
557 if(isTRT){
558 //Add the msos to the container
559 msosTRT->push_back( msos );
560 //Set the det id
562 //Build the element link to the MSOS
563 ElementLink< xAOD::TrackStateValidationContainer > elink( *msosTRT, nTRT_MSOS );
564 elink.toPersistent();
565 msosLink.push_back(elink);
566 ++nTRT_MSOS;
567 }else if(isSCT){
568 //Add the msos to the container
569 msosSCT->push_back( msos );
570 //Set the det id
572 //Build the element link to the MSOS
573 ElementLink< xAOD::TrackStateValidationContainer > elink( *msosSCT, nSCT_MSOS );
574 elink.toPersistent();
575 msosLink.push_back(elink);
576 ++nSCT_MSOS;
577 }else if(isPixel){
578 //Add the msos to the container
579 msosPixel->push_back( msos );
580 //Set the det id
582 //Build the element link to the MSOS
583 ElementLink< xAOD::TrackStateValidationContainer > elink( *msosPixel, nPixelMSOS );
584 elink.toPersistent();
585 msosLink.push_back(elink);
586 ++nPixelMSOS;
587 }
588 else {
589 ATH_MSG_WARNING("NOT a pixel, SCT or TRT track state on surface.");
590 delete msos;
591 continue;
592 }
593
594 //fill type
595 if( trackState->types()[Trk::TrackStateOnSurface::Hole] ){
597 } else if (trackState->types()[Trk::TrackStateOnSurface::Measurement]){
599 } else if ( trackState->types()[Trk::TrackStateOnSurface::Outlier] ) {
601 }
602
603 //Fill surface id
604 msos->setDetElementId( surfaceID.get_compact() );
605
606
607 const Trk::TrackParameters* tp = trackState->trackParameters();
608
609 // some more detailed hit info
610 double lTheta=-1000., lPhi=-1000.;
611 //Get the measurement base object
612 const Trk::MeasurementBase* measurement=trackState->measurementOnTrack();
613 static const SG::Accessor<float> errDCAcc("errDC");
614 errDCAcc(*msos) = -1 ;
615 const Trk::RIO_OnTrack* rotp = dynamic_cast<const Trk::RIO_OnTrack*>(measurement) ;
616 if (rotp) errDCAcc(*msos) = sqrt(rotp->localCovariance()(Trk::driftRadius, Trk::driftRadius)) ;
617
618 if (m_storeTRT) {
619 const InDet::TRT_DriftCircleOnTrack *driftcircle = dynamic_cast<const InDet::TRT_DriftCircleOnTrack*>(measurement);
620 static const SG::Accessor<float> HitZAcc("HitZ");
621 static const SG::Accessor<float> HitRAcc("HitR");
622 static const SG::Accessor<float> rTrkWireAcc("rTrkWire");
623 if (!measurement) {
624 HitZAcc(*msos)=-3000;
625 HitRAcc(*msos)=-1;
626 rTrkWireAcc(*msos)=-1;
627 }
628 else {
629 if (!driftcircle) {
630 HitZAcc(*msos)=-3000;
631 HitRAcc(*msos)=-1;
632 rTrkWireAcc(*msos)=-1;
633 }
634 else {
635 if (tp) {
636 const Amg::Vector3D& gp = driftcircle->globalPosition();
637 HitZAcc(*msos)=gp.z();
638 HitRAcc(*msos)=gp.perp();
639 rTrkWireAcc(*msos)= fabs(trackState->trackParameters()->parameters()[Trk::driftRadius]);
640 lTheta = trackState->trackParameters()->parameters()[Trk::theta];
641 lPhi = trackState->trackParameters()->parameters()[Trk::phi];
642 }
643 else {
644 HitZAcc(*msos) =driftcircle->associatedSurface().center().z();
645 HitRAcc(*msos) =driftcircle->associatedSurface().center().perp();
646 rTrkWireAcc(*msos)=0;
647 }
648 }
649 }
650 msos->setLocalAngles(lTheta, lPhi);
651
652 bool isShared=false;
653 if (prd_to_track_map_cptr) {
654 const Trk::RIO_OnTrack* hit_trt = measurement ? dynamic_cast<const Trk::RIO_OnTrack*>(measurement) : nullptr;
655 if (hit_trt) {
656 if (prd_to_track_map_cptr->isShared(*(hit_trt->prepRawData())) ) isShared=true;
657 static const SG::Accessor<bool> isSharedAcc("isShared");
658 isSharedAcc(*msos) = isShared;
659 }
660 }
661 }
662
663 // Track extrapolation
664 std::unique_ptr<const Trk::TrackParameters> extrap( m_extrapolator->extrapolateTrack(ctx,*trkTrack,trackState->surface()) );
665
666 // Set local positions on the surface
667 if (tp) {
668 msos->setLocalPosition( tp->parameters()[0], tp->parameters()[1] );
669
670 if (extrap.get()) {
671 ATH_MSG_DEBUG(" Original position " << tp->parameters()[0] << " " << tp->parameters()[1]);
672 ATH_MSG_DEBUG("Extrapolated position " << extrap->parameters()[0] << " " << extrap->parameters()[1]);
673 }
674
675 }
676 else {
677 if (extrap.get()) {
678 msos->setLocalPosition( extrap->parameters()[0], extrap->parameters()[1] );
679 }
680 else {
681 ATH_MSG_DEBUG("Track extrapolation failed.");
682 }
683 }
684
685 // Set calculate local incident angles
686 const Trk::TrkDetElementBase *de = trackState->surface().associatedDetectorElement();
687 const InDetDD::SiDetectorElement *side = dynamic_cast<const InDetDD::SiDetectorElement *>(de);
688 if (side && (isSCT || isPixel)) {
689 const Amg::Vector3D& mynormal = side->normal();
690 const Amg::Vector3D& myphiax = side->phiAxis();
691 const Amg::Vector3D& myetaax = side->etaAxis();
692 if (tp) {
693 Amg::Vector3D mytrack = tp->momentum();
694 float trketacomp = mytrack.dot(myetaax);
695 float trkphicomp = mytrack.dot(myphiax);
696 float trknormcomp = mytrack.dot(mynormal);
697
698 ATH_MSG_DEBUG(" Original incident angle " << trketacomp << " " << trkphicomp << " " << trknormcomp);
699 if (extrap.get()) {
700 Amg::Vector3D metrack = extrap->momentum();
701 float trketacompX = metrack.dot(myetaax);
702 float trkphicompX = metrack.dot(myphiax);
703 float trknormcompX = metrack.dot(mynormal);
704 ATH_MSG_DEBUG("Extrapolated incident angle " << trketacompX << " " << trkphicompX << " " << trknormcompX);
705 }
706 msos->setLocalAngles( atan2(trketacomp,trknormcomp), atan2(trkphicomp,trknormcomp) );
707 }
708 else {
709 if (extrap.get()) {
710 Amg::Vector3D metrack = extrap->momentum();
711 float trketacompX = metrack.dot(myetaax);
712 float trkphicompX = metrack.dot(myphiax);
713 float trknormcompX = metrack.dot(mynormal);
714 msos->setLocalAngles( atan2(trketacompX,trknormcompX), atan2(trkphicompX,trknormcompX) );
715 }
716 }
717 }
718
719 if(!measurement) { continue; }
720
721 if (isTRT && !trtDCOffsets.isValid() && !trtDCs.isValid()) { continue; }
722 if (isSCT && !sctClusterOffsets.isValid() && !sctClusters.isValid()) { continue; }
723 if (isPixel && !pixelClusterOffsets.isValid() && !pixelClusters.isValid()) { continue; }
724
725 const Trk::RIO_OnTrack* hit = measurement ? dynamic_cast<const Trk::RIO_OnTrack*>(measurement) : nullptr;
726
727 if(!hit){
728 const Trk::CompetingRIOsOnTrack *crot = dynamic_cast<const Trk::CompetingRIOsOnTrack*>(measurement);
729 if(crot){
730 hit = &crot->rioOnTrack( crot->indexOfMaxAssignProb() );
731 }
732 }
733
734 if(m_addPRD && hit){
735 // Build an element link to the xAOD PRD
736 const Trk::PrepRawData* prd = hit->prepRawData();
737 if(prd && prd->getHashAndIndex().isValid() ){
738 if(isTRT){
739 msos->setTrackMeasurementValidationLink( buildElementLink( prd, trtDCOffsets.cptr(), trtDCs.cptr()) );
740 }else if(isSCT){
741 msos->setTrackMeasurementValidationLink( buildElementLink( prd, sctClusterOffsets.cptr(), sctClusters.cptr()) );
742 }else if(isPixel){
743 msos->setTrackMeasurementValidationLink( buildElementLink( prd, pixelClusterOffsets.cptr(), pixelClusters.cptr()) );
744 }
745 }
746 }
747
748 if (m_storeSCT && isSCT) {
749 // We use accessors because the aux variable is added directly in the TrackMeasurementValidation cluster producer
750 // and we are decorating the MSOS in the TrackStateValidationContainer producer here
751 static const SG::Accessor<int> SiWidthAcc("SiWidth");
752 static const SG::Accessor<int> firstStripAcc("first_strip");
753 static const SG::Accessor<std::vector<int>> rdoStripAcc("rdo_strip");
754
755 if( msos->trackMeasurementValidationLink().isValid() && *(msos->trackMeasurementValidationLink()) ){
757 SiWidthAcc(*msos) = SiWidthAcc(*sctCluster);
758 firstStripAcc(*msos) = (rdoStripAcc(*sctCluster)).at(0);
759 } else {
760 SiWidthAcc(*msos) = -1;
761 firstStripAcc(*msos) = -1;
762 }
763 }
764
765 // Add the drift time for the tracks position -- note the position is biased
766 if (isTRT) {
767 TRTCond::RtRelation const *rtr = m_trtcaldbTool->getRtRelation(surfaceID);
768 if(rtr) {
769 static const SG::Accessor<float> driftTimeAcc("driftTime");
770 if (tp){
771 driftTimeAcc(*msos) = rtr->drifttime(fabs(tp->parameters()[0]));
772 }
773 else {
774 if (extrap.get()) {
775 driftTimeAcc(*msos) = rtr->drifttime(fabs(extrap->parameters()[0]));
776 }
777 }
778 }
779 }
780
781 static const SG::Accessor<float> TrackError_biasedAcc("TrackError_biased");
782 static const SG::Accessor<float> TrackError_unbiasedAcc("TrackError_unbiased");
783 if (m_addPulls) {
784
785 std::optional<Trk::ResidualPull> biased;
786 std::optional<Trk::ResidualPull> unbiased;
787 if (tp) {
788 biased= m_residualPullCalculator->residualPull(measurement, tp, Trk::ResidualPull::Biased);
789 if (m_storeTRT) TrackError_biasedAcc(*msos) = sqrt(fabs((*tp->covariance())(Trk::locX,Trk::locX)));
790
791 if (m_storeTRT) TrackError_biasedAcc(*msos) = sqrt(fabs((*tp->covariance())(Trk::locX,Trk::locX)));
792 std::unique_ptr<const Trk::TrackParameters> unbiasedTp( m_updator->removeFromState(*tp, measurement->localParameters(), measurement->localCovariance()) );
793 if(unbiasedTp.get()) {
794 if (m_storeTRT) TrackError_unbiasedAcc(*msos) = sqrt(fabs((*unbiasedTp.get()->covariance())(Trk::locX,Trk::locX)));
795 unbiased = m_residualPullCalculator->residualPull(measurement, unbiasedTp.get(), Trk::ResidualPull::Unbiased);
796 }
797 }
798 else {
799 if (extrap.get()) {
800 if (m_storeTRT) TrackError_unbiasedAcc(*msos) = sqrt(fabs((*extrap.get()->covariance())(Trk::locX,Trk::locX)));
801 biased = m_residualPullCalculator->residualPull(measurement, extrap.get(), Trk::ResidualPull::Biased);
802 unbiased = m_residualPullCalculator->residualPull(measurement, extrap.get(), Trk::ResidualPull::Unbiased);
803 }
804 }
805
806 if (biased) {
807 if(biased->dimension()>Trk::locY){
808 msos->setBiasedResidual( biased->residual()[Trk::locX], biased->residual()[Trk::locY] );
809 msos->setBiasedPull( biased->pull()[Trk::locX], biased->pull()[Trk::locY] );
810 } else {
811 msos->setBiasedResidual( biased->residual()[Trk::locX], 0 );
812 msos->setBiasedPull( biased->pull()[Trk::locX], 0 );
813 }
814 }
815
816 if (unbiased) {
817 if(unbiased->dimension()>Trk::locY){
818 msos->setUnbiasedResidual( unbiased->residual()[Trk::locX], unbiased->residual()[Trk::locY] );
819 msos->setUnbiasedPull( unbiased->pull()[Trk::locX], unbiased->pull()[Trk::locY] );
820 } else {
821 msos->setUnbiasedResidual( unbiased->residual()[Trk::locX], 0 );
822 msos->setUnbiasedPull( unbiased->pull()[Trk::locX], 0 );
823 }
824 }
825
826 }
827
828 } //end loop over TSOS's
829
830 ATH_MSG_DEBUG("The number of TSOS's " << msosLink.size() );
831
832 dectsos_msosLink( *track ) = msosLink;
833
834 ATH_MSG_DEBUG("Finished dressing TrackParticle");
835
836 ++i_track;
837 } // end of loop over tracks
838
839 return StatusCode::SUCCESS;
840 }
841
842
844 const std::vector<unsigned int>* offsets,
845 const xAOD::TrackMeasurementValidationContainer* xaodPrdCont) const
846 {
847
848 const IdentContIndex& contIndex = prd->getHashAndIndex();
849 if( contIndex.collHash() >= offsets->size() ){
850 ATH_MSG_ERROR(" Offsets are incorrect " << contIndex.collHash() << " " << offsets->size() <<" "<< contIndex.objIndex());
851 return {0,0};
852 }
853
854 unsigned int xaodIndex = offsets->at( contIndex.collHash() ) + contIndex.objIndex();
856 el.toPersistent();
857
858 return el;
859
860 }
861
862
863}
#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.
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.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
Handle class for adding a decoration to an object.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
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)
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:
TrackStateValidation_v1 TrackStateValidation
Reference the current persistent version:
TrackMeasurementValidationContainer_v1 TrackMeasurementValidationContainer
Definition of the current "TrackMeasurementValidation container version".