ATLAS Offline Software
Loading...
Searching...
No Matches
ReFitTrackWithTruth.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// ReFitTrackWithTruth.cxx
7// Implementation file for class ReFitTrackWithTruth
9// version 1.0 03/10/19 Gabriel Facini (Rel21)
10// version 2.0 22/03/23 Andrea Sciandra (Rel22/Rel23)
12
13//SiTBLineFitter includes
15
16// Gaudi includes
17#include "GaudiKernel/TypeNameString.h"
18
30#include "TRandom3.h"
31
32#include <vector>
33
34// Constructor with parameters:
35Trk::ReFitTrackWithTruth::ReFitTrackWithTruth(const std::string &name, ISvcLocator *pSvcLocator) :
36 AthAlgorithm(name,pSvcLocator)
37{
38
39}
40
41// Initialize method:
43{
44 ATH_MSG_INFO ("ReFitTrackWithTruth::initialize()");
45
46 ATH_CHECK (m_siHitCollectionName.initialize());
47 ATH_CHECK (m_SDOContainerName.initialize());
48 ATH_CHECK (m_truthMapName.initialize());
49
50 // get tracks
51 ATH_CHECK( m_inputTrackColName.initialize() );
52
53 if (m_ITrackFitter.retrieve().isFailure()) {
54 ATH_MSG_FATAL ("Failed to retrieve tool "<<m_ITrackFitter.typeAndName());
55 return StatusCode::FAILURE;
56 } else {
57 ATH_MSG_INFO ("Retrieved general fitter " << m_ITrackFitter.typeAndName());
58 }
59
60 if (m_trkSummaryTool.retrieve().isFailure()) {
61 ATH_MSG_FATAL ("Failed to retrieve tool " << m_trkSummaryTool);
62 return StatusCode::FAILURE;
63 } else {
64 ATH_MSG_INFO ("Retrieved tool " << m_trkSummaryTool.typeAndName());
65 }
66
67 // needed if want to check on shared clusters
68 if ( m_assoTool.retrieve().isFailure() ) {
69 ATH_MSG_FATAL ("Failed to retrieve tool " << m_assoTool);
70 return StatusCode::FAILURE;
71 } else ATH_MSG_INFO("Retrieved tool " << m_assoTool);
72
73
74 // Configuration of the material effects
76
77 // Get ID Helper
78 ATH_CHECK(detStore()->retrieve(m_idHelper, "AtlasID"));
79
80 // Get Pixel Helper
81 if (detStore()->retrieve(m_pixelID, "PixelID").isFailure()) {
82 ATH_MSG_FATAL ("Could not get Pixel ID helper");
83 return StatusCode::FAILURE;
84 }
85
86 //set seed for random-number generator
87 m_random->SetSeed();
88
89 // ensure the vector is the correct size in case the user does not want to smear
90 if( m_resolutionRPhi.size() < 4 ) { m_resolutionRPhi={0.,0.,0.,0.}; }
91 if( m_resolutionZ.size() < 4 ) { m_resolutionZ={0.,0.,0.,0.}; }
92
93 if( m_errorRPhi.size() < 4 ) { m_errorRPhi={1.,1.,1.,1.}; }
94 if( m_errorZ.size() < 4 ) { m_errorZ={1.,1.,1.,1.}; }
95
96 ATH_MSG_INFO (" Resolutions " << m_resolutionRPhi.size() << " " << m_resolutionZ.size());
97 for( unsigned int i=0; i<m_resolutionRPhi.size(); i++) {
98 ATH_MSG_INFO (" " << i << " " << m_resolutionRPhi[i] << "\t" << m_resolutionZ[i]);
99 }
100 ATH_MSG_INFO (" Error SR " << m_errorRPhi.size() << " " << m_errorZ.size());
101 for( unsigned int i=0; i<m_errorRPhi.size(); i++) {
102 ATH_MSG_INFO (" " << i << " " << m_errorRPhi[i] << "\t" << m_errorZ[i]);
103 }
104
106 ATH_MSG_DEBUG("m_outputTrackCollectionName: " << m_outputTrackCollectionName);
107
108 return StatusCode::SUCCESS;
109}
110
111// Execute method:
112StatusCode Trk::ReFitTrackWithTruth::execute(const EventContext& ctx)
113{
114 ATH_MSG_DEBUG ("ReFitTrackWithTruth::execute()");
115 std::unique_ptr<Trk::PRDtoTrackMap> prd_to_track_map(m_assoTool->createPRDtoTrackMap());
116
118 if (!tracks.isValid()) {
119 ATH_MSG_ERROR(m_inputTrackColName.key() << " not found");
120 return StatusCode::FAILURE;
121 }
122
123 //retrieve truth information needed (SiHitCollection)
125 if (!siHits.isValid()) {
126 ATH_MSG_WARNING( "Error retrieving SiHitCollection " << m_siHitCollectionName);
127 return StatusCode::FAILURE;
128 }
129
130 //retrieve truth information needed (SDOCollection)
132 if (!sdoCollection.isValid()) {
133 ATH_MSG_WARNING( "Error retrieving SDOCollection " << m_SDOContainerName );
134 return StatusCode::FAILURE;
135 }
136
137 //retrieve truth map
139 if (!truthMap.isValid()) {
140 ATH_MSG_WARNING( "Error retrieving truth map " << m_truthMapName );
141 return StatusCode::FAILURE;
142 }
143
144 // create new collection of tracks to write in storegate
145 std::vector<std::unique_ptr<Trk::Track> > newtracks;
146
147 // loop over tracks
148 for (TrackCollection::const_iterator itr = tracks->begin(); itr != tracks->end(); ++itr) {
149 ATH_MSG_DEBUG("input track");
150
151 // Get original parameters
152 const TrackParameters* origPerigee = (*itr)->perigeeParameters();
153 double od0(0);
154 double oz0(0);
155 double ophi0(0);
156 double otheta(0);
157 double oqOverP(0);
158 if (!origPerigee){
159 ATH_MSG_WARNING("Cannot get original parameters");
160 }
161 else if (msgLvl(MSG::DEBUG)) {
162 od0 = origPerigee->parameters()[Trk::d0];
163 oz0 = origPerigee->parameters()[Trk::z0];
164 ophi0 = origPerigee->parameters()[Trk::phi0];
165 otheta = origPerigee->parameters()[Trk::theta];
166 oqOverP = origPerigee->parameters()[Trk::qOverP];
167 ATH_MSG_DEBUG ("Original parameters " << od0 << " " << oz0 << " " << ophi0 << " " << otheta << " " << oqOverP);
168 }
169
170 // get the unique ID of truth particle matched to the track
171 float minProb(0);
172
173 // copy from DenseEnvironmentsAmbiguityProcessorTool.cxx
175 tracklink.setElement(const_cast<Trk::Track*>(*itr));
176 tracklink.setStorableObject(*tracks);
177 const ElementLink<TrackCollection> tracklink2=tracklink;
178
179 TrackTruthCollection::const_iterator found = truthMap->find(tracklink2);
180 if ( found == truthMap->end() ) { continue; }
181 if ( !found->second.particleLink().isValid() ) { continue; }
182 if ( found->second.probability() < minProb ) { continue; }
183 int uniqueIdToMatch = HepMC::uniqueID(&(found->second.particleLink()));
184 ATH_MSG_DEBUG ("Unique ID to match " << uniqueIdToMatch);
185
186 // now that have the track, loop through and build a new set of measurements for a track fit
187 std::vector<const Trk::MeasurementBase*> measurementSet;
188 std::vector<const Trk::MeasurementBase*> trash;
189
190 ATH_MSG_DEBUG ("Loop over measurementsOnTrack " << (*itr)->measurementsOnTrack()->size() );
191 for (const auto *measurement : *((*itr)->measurementsOnTrack())) {
192 ATH_MSG_DEBUG ("Next Measurement: " << *measurement);
193
194 // Get measurement as RIO_OnTrack
195 const Trk::RIO_OnTrack* rio = dynamic_cast <const Trk::RIO_OnTrack*>( measurement );
196 if (rio == nullptr) {
197 ATH_MSG_WARNING("Cannot get RIO_OnTrack from measurement. Hit will NOT be included in track fit.");
198 continue;
199 }
200
201 // if not a pixel cluster, keep the measurement as is and press on
202 const Identifier& surfaceID = (rio->identify()) ;
203 if( !m_idHelper->is_pixel(surfaceID) ) {
204 measurementSet.push_back( measurement );
205 continue;
206 }
207
208 // only PIXEL CLUSTERS from here on
209 const InDet::PixelCluster* pix = dynamic_cast<const InDet::PixelCluster*>(rio->prepRawData());
210 if (pix == nullptr) {
211 ATH_MSG_WARNING("Cannot get PixelCluster from RIO_OnTrack");
212 continue;
213 }
214
215 const InDetDD::SiDetectorElement* element = pix->detectorElement();
216 const InDetDD::SiDetectorDesign* design = static_cast<const InDetDD::SiDetectorDesign*>(&element->design());
217 // To locate cluster module
218 Identifier clusterId = pix->identify();
219 int bec = m_pixelID->barrel_ec(clusterId);
220 int layer_disk = m_pixelID->layer_disk(clusterId);
221
222 // Do any SDOs in reconstructed cluster match uniqueIdToMatch
223 // Should always return true for pseudotracks. For reco tracks could differ
224 bool hasSDOMatch = IsClusterFromTruth( pix, uniqueIdToMatch, *sdoCollection );
225
226 // --- hit flags' logic
227 // m_saveWrongHits - only has impact on reco track, where hit might be from wrong particle
228 // m_fixWrongHits - fix will only work on hits that are not noise, noise hits behavior unchanged by this flag
229 // m_rejNoiseHits - if saving but don't want to save these
230
231 // could be used already here to correct wrong hits
232 double maxEnergyDeposit(-1);
233 SiHit maxEDepSiHit;
234
235 if ( !hasSDOMatch ) {
236 ATH_MSG_DEBUG ("No SDO matching cluster");
237 // save wrong hits
238 if (not m_saveWrongHits) continue;
239 const std::vector<SiHit> matchedSiHits = matchSiHitsToCluster( -999 , pix, siHits );
240 if( matchedSiHits.empty() ) { // then noise, and go to next hit
241 if( !m_rejNoiseHits ) { measurementSet.push_back( measurement ); }
242 continue;
243 } // is a real hit, just not from the particle in question -- will NOT go to next hit just yet
244 if( m_fixWrongHits ) { // if fix, use highest energy truth hit
245 for( const auto& siHit : matchedSiHits ) {
246 if (siHit.energyLoss() > maxEnergyDeposit) {
247 maxEnergyDeposit = siHit.energyLoss();
248 maxEDepSiHit = siHit;
249 }
250 }
251 } else { // save the wrong hit as is and go to next cluster
252 measurementSet.push_back( measurement );
253 continue;
254 }
255 } else { // hasSDOMatch
256 // Get All SiHits truth matched to the reconstruction cluster for the particle associated with the track
257 const std::vector<SiHit> matchedSiHits = matchSiHitsToCluster( uniqueIdToMatch, pix, siHits );
258 if( matchedSiHits.empty() ) {
259 ATH_MSG_WARNING ("No SiHit matching cluster");
260 continue; // should NOT HAPPEN for pseudotracks
261 }
262 ATH_MSG_DEBUG ("N SiHit matching cluster: " << matchedSiHits.size());
263
264 // If multiple SiHits / cluster FOR THE SAME TRUTH PARTICLE,
265 // Take position of SiHit giving the most energy
266 for( const auto& siHit : matchedSiHits ) {
267 if (siHit.energyLoss() > maxEnergyDeposit) {
268 maxEnergyDeposit = siHit.energyLoss();
269 maxEDepSiHit = siHit;
270 }
271 }
272 } // if else hasSDOMatch
273
274 // - Retrieve true position of cluster from entry/exit point of truth particle
275 //get average position of entry/exit point
276 HepGeom::Point3D<double> averagePosition = (maxEDepSiHit.localStartPosition() + maxEDepSiHit.localEndPosition()) * 0.5;
277 ATH_MSG_DEBUG (" Average position : " << averagePosition);
278
279 // SiHit coordinate system i.e. localStartPosition
280 // z = eta -> this is y in ATLAS sensor local frame
281 // y = phi -> this is x in ATLAS sensor local frame
282 // USE hitLocalToLocal from SiDetectorElement
283
284 HepGeom::Point3D<double> smearedPosition = smearTruthPosition( averagePosition, bec, layer_disk, design );
285 ATH_MSG_DEBUG (" Smeared position : " << smearedPosition );
286
287 const auto & locparOrig = rio->localParameters();
288 ATH_MSG_DEBUG(" Original locpar " << locparOrig);
289
290 Trk::LocalParameters locpar = element->hitLocalToLocal(smearedPosition.z(), smearedPosition.y()); // eta, phi
291 ATH_MSG_DEBUG(" locpar " << locpar);
292
293 InDetDD::SiLocalPosition centroid(locpar.get(Trk::loc2), locpar.get(Trk::loc1), 0); // eta, phi, depth
294 const Amg::Vector3D& globPos = element->globalPosition(centroid);
295
296 InDet::SiWidth pixWidth = pix->width();
297 Amg::MatrixX cov = pix->localCovariance();
298 // Original code took width / nrows (or columns)* 1/sqrt(12) to check if > 0...
299 // only need to check width to test against 0...
300 // disk one is layer 0
301 if(bec!=0) layer_disk++;
302 if(pixWidth.phiR()>0) {
303 float error(1.0);
304 error = getPhiPosResolution(layer_disk)*getPhiPosErrorFactor(layer_disk);
305 cov(0,0) = error*error;
306 } else {
307 ATH_MSG_WARNING("pixWidth.phiR not > 0");
308 }
309
310 if(pixWidth.z()>0) {
311 float error(1.0);
312 error = getEtaPosResolution(layer_disk)*getEtaPosErrorFactor(layer_disk);
313 cov(1,1) = error*error;
314 } else {
315 ATH_MSG_WARNING("pixWidth.z not > 0");
316 }
317
318 auto iH = element->identifyHash();
319
320 InDet::PixelClusterOnTrack* pcot = new InDet::PixelClusterOnTrack(pix,std::move(locpar),std::move(cov),iH,globPos,
321 pix->gangedPixel(),
322 false);
323
324 if(pcot) {
325 measurementSet.push_back( pcot);
326 trash.push_back(pcot);
327 } else {
328 ATH_MSG_WARNING("Could not make new PixelClusterOnTrack");
329 }
330
331 } // loop over measurements on track
332
333
334
335 ATH_MSG_DEBUG ("Fit new tracks with measurementSet : " << measurementSet.size());
336 std::unique_ptr<Trk::Track> newtrack;
337 try {
338 newtrack = m_ITrackFitter->fit(ctx,
339 measurementSet,
340 *origPerigee,
343 }
344 catch(const std::exception& e) {
345 ATH_MSG_ERROR ("Refit Logic Error. No new track. Message: " << e.what());
346 newtrack = nullptr;
347 }
348
349 ATH_MSG_DEBUG ("Track fit is done!");
350
351 if (msgLvl(MSG::DEBUG)) {
352 if (!newtrack) { ATH_MSG_DEBUG ("Refit Failed"); }
353 else {
354
355 ATH_MSG_VERBOSE ("re-fitted track:" << *newtrack);
356 const Trk::Perigee* aMeasPer = newtrack->perigeeParameters();
357 if (aMeasPer==nullptr){
358 ATH_MSG_ERROR ("Could not get Trk::MeasuredPerigee");
359 } else {
360 double d0 = aMeasPer->parameters()[Trk::d0];
361 double z0 = aMeasPer->parameters()[Trk::z0];
362 double phi0 = aMeasPer->parameters()[Trk::phi0];
363 double theta = aMeasPer->parameters()[Trk::theta];
364 double qOverP = aMeasPer->parameters()[Trk::qOverP];
365 if ((od0 == 0) or (oz0 == 0) or (ophi0 == 0) or (otheta == 0) or (oqOverP == 0)){
366 ATH_MSG_WARNING("A divisor is zero.");
367 } else {
368 ATH_MSG_DEBUG ("Refitted parameters differences "
369 << (od0-d0)/od0 << " "
370 << (oz0-z0)/oz0 << " "
371 << (ophi0-phi0)/ophi0 << " "
372 << (otheta-theta)/otheta << " "
373 << (oqOverP-qOverP)/oqOverP );
374 }
375 } // aMeasPer exists
376 } // newtrack exists
377 } // if debug
378
379 if (newtrack) { newtracks.push_back(std::move(newtrack)); }
380 else { ATH_MSG_WARNING ("Refit Failed"); }
381
382 } // loop over tracks
383
384 ATH_MSG_VERBOSE ("Add PRDs to assoc tool.");
385
386 // recreate the summaries on the final track collection with correct PRD tool
387 for(const std::unique_ptr<Trk::Track> &new_track : newtracks ) {
388 if((m_assoTool->addPRDs(*prd_to_track_map, *new_track)).isFailure()) {ATH_MSG_WARNING("Failed to add PRDs to map");}
389 }
390
391 ATH_MSG_VERBOSE ("Recalculate the summary");
392 // and copy tracks from vector of non-const tracks to collection of const tracks
393 std::unique_ptr<TrackCollection> new_track_collection = std::make_unique<TrackCollection>();
394 new_track_collection->reserve(newtracks.size());
395 for(std::unique_ptr<Trk::Track> &new_track : newtracks ) {
396 m_trkSummaryTool->computeAndReplaceTrackSummary(ctx, *new_track, false /* DO NOT suppress hole search*/);
397 new_track_collection->push_back(std::move(new_track));
398 }
399
400 ATH_MSG_VERBOSE ("Save tracks");
401 ATH_CHECK(SG::WriteHandle<TrackCollection>(m_outputTrackCollectionName, ctx).record(std::move(new_track_collection)));
402
403 ATH_MSG_INFO ("ReFitTrackWithTruth::execute() completed");
404 return StatusCode::SUCCESS;
405}
406
407std::vector<SiHit> Trk::ReFitTrackWithTruth::matchSiHitsToCluster( const int uniqueIdToMatch,
408 const InDet::PixelCluster* pixClus,
409 SG::ReadHandle<AtlasHitsVector<SiHit>> &siHitCollection) const {
410
411 // passing a negative unique ID value skip this requirement - can get multiple SiHits upon return from different particles
412
413 ATH_MSG_VERBOSE( " Have " << (*siHitCollection).size() << " SiHits to look through" );
414 std::vector<SiHit> matchingHits;
415
416 // Check if we have detector element -- needed to find the local position of the SiHits
417 const InDetDD::SiDetectorElement* de = pixClus->detectorElement();
418 if(!de) {
419 ATH_MSG_WARNING("Do not have detector element to find the local position of SiHits!");
420 return matchingHits;
421 }
422
423 // To locate cluster module
424 Identifier clusterId = pixClus->identify();
425
426 std::vector<const SiHit* > multiMatchingHits;
427
428 // match SiHits to unique ID and make sure in same module as reco hit
429 for ( const auto& siHit : *siHitCollection) {
430
431 if ( uniqueIdToMatch > 0 ) { // negative uniqueIdToMatch will keep all
432 if ( HepMC::uniqueID(&(siHit.particleLink())) != uniqueIdToMatch ) { continue; }
433 }
434
435 // Check if it is a Pixel hit
436 if( !siHit.isPixel() ) { continue; }
437
438 // Match to the cluster module
439 if( m_pixelID->barrel_ec(clusterId) != siHit.getBarrelEndcap() ) { continue; }
440 if( m_pixelID->layer_disk(clusterId)!= siHit.getLayerDisk() ) { continue; }
441 if( m_pixelID->phi_module(clusterId)!= siHit.getPhiModule() ) { continue; }
442 if( m_pixelID->eta_module(clusterId)!= siHit.getEtaModule() ) { continue; }
443
444 // Have SiHits in the same module as the cluster at this point
445 ATH_MSG_DEBUG("Hit is on the same module");
446 multiMatchingHits.push_back(&siHit);
447
448 } // loop over SiHitCollection
449
450
451 //Now we will now make 1 SiHit for each true particle if the SiHits "touch" other
452 std::vector<const SiHit* >::iterator siHitIter = multiMatchingHits.begin();
453 std::vector<const SiHit* >::iterator siHitIter2 = multiMatchingHits.begin();
454 ATH_MSG_DEBUG( "Found " << multiMatchingHits.size() << " SiHit " );
455
456 // double loop - for each matching SiHit, consider all the SiHits _next_ in the collection
457 // to see if they overlap.
458 // if overlapping, combine and only consider new merged hits
459 for ( ; siHitIter != multiMatchingHits.end(); ++siHitIter) {
460 const SiHit* lowestXPos = *siHitIter;
461 const SiHit* highestXPos = *siHitIter;
462
463
464 // We will merge these hits
465 std::vector<const SiHit* > ajoiningHits;
466 ajoiningHits.push_back( *siHitIter );
467
468 siHitIter2 = siHitIter+1;
469 while ( siHitIter2 != multiMatchingHits.end() ) {
470 // Need to come from the same truth particle
471
472 // wasn't the unique ID match already done!?
473 if ( HepMC::uniqueID(&((*siHitIter)->particleLink())) != HepMC::uniqueID(&((*siHitIter2)->particleLink()))) {
474 ++siHitIter2;
475 continue;
476 }
477
478 // Check to see if the SiHits are compatible with each other.
479 if (std::abs((highestXPos->localEndPosition().x()-(*siHitIter2)->localStartPosition().x()))<0.00005 &&
480 std::abs((highestXPos->localEndPosition().y()-(*siHitIter2)->localStartPosition().y()))<0.00005 &&
481 std::abs((highestXPos->localEndPosition().z()-(*siHitIter2)->localStartPosition().z()))<0.00005 )
482 {
483 highestXPos = *siHitIter2;
484 ajoiningHits.push_back( *siHitIter2 );
485 // Dont use hit more than once
486 siHitIter2 = multiMatchingHits.erase( siHitIter2 );
487 //--siHitIter2; // maybe
488 }else if (std::abs((lowestXPos->localStartPosition().x()-(*siHitIter2)->localEndPosition().x()))<0.00005 &&
489 std::abs((lowestXPos->localStartPosition().y()-(*siHitIter2)->localEndPosition().y()))<0.00005 &&
490 std::abs((lowestXPos->localStartPosition().z()-(*siHitIter2)->localEndPosition().z()))<0.00005)
491 {
492 lowestXPos = *siHitIter2;
493 ajoiningHits.push_back( *siHitIter2 );
494 // Dont use hit more than once
495 siHitIter2 = multiMatchingHits.erase( siHitIter2 );
496 // --siHitIter2; // maybe
497 } else {
498 ++siHitIter2;
499 }
500 } // loop over matching SiHits to see if any overlap
501
502 if( ajoiningHits.empty()){
503 ATH_MSG_WARNING("This should really never happen");
504 continue;
505 }
506 if(ajoiningHits.size() == 1){
507 // Copy Si Hit ready to return
508 matchingHits.push_back( *ajoiningHits[0] );
509 continue;
510 }
511 // Build new SiHit and merge information together.
512 ATH_MSG_DEBUG("Merging " << ajoiningHits.size() << " SiHits together." );
513
514
515 float energyDep(0);
516 float time(0);
517 for( auto& siHit : ajoiningHits){
518 energyDep += siHit->energyLoss();
519 time += siHit->meanTime();
520 }
521 time /= (float)ajoiningHits.size();
522
523 matchingHits.emplace_back(lowestXPos->localStartPosition(),
524 highestXPos->localEndPosition(),
525 energyDep,
526 time,
527 HepMC::uniqueID(&((*siHitIter)->particleLink())),
528 0, // 0 for pixel 1 for Pixel
529 (*siHitIter)->getBarrelEndcap(),
530 (*siHitIter)->getLayerDisk(),
531 (*siHitIter)->getEtaModule(),
532 (*siHitIter)->getPhiModule(),
533 (*siHitIter)->getSide() );
534 ATH_MSG_DEBUG("Finished Merging " << ajoiningHits.size() << " SiHits together." );
535 } // loop over all matching SiHits
536
537 return matchingHits;
538}
539
541 const int uniqueIdToMatch,
542 const InDetSimDataCollection &sdoCollection) {
543
544 // Should be true for all pseudotracks
545 // Can be false for reco tracks - misassigned hits
546
547 bool match(false);
548
549 // loop over reconstructed energy depoists in the cluster
550 for( const auto &hitIdentifier : pixClus->rdoList() ) {
551
552 // find the rdo in the sdo collection
553 auto pos = sdoCollection.find(hitIdentifier);
554 if( pos == sdoCollection.end() ) { continue; }
555
556 // get the unique ID from each deposit
557 for( const auto& deposit : pos->second.getdeposits() ){
558 if( !deposit.first ){ continue; } // if truthparticle(?) link doesn't exists? Energy deposit is still known
559 if( HepMC::uniqueID(&(deposit.first)) != uniqueIdToMatch ) { continue; }
560 match = true;
561 break;
562 }
563 if(match) { break; }
564 }
565
566 return match;
567}
568
569HepGeom::Point3D<double> Trk::ReFitTrackWithTruth::smearTruthPosition( const HepGeom::Point3D<double>& orig,
570 const int bec,
571 const int layer_disk,
572 const InDetDD::SiDetectorDesign* design) const {
573
574 HepGeom::Point3D<double> smeared(0,0,0);
575
576 smeared.setX(orig.x());
577
578 if (bec == 0) {
579 double smearLocY = m_random->Gaus(0, getPhiPosResolution(layer_disk));
580 double smearLocZ = m_random->Gaus(0, getEtaPosResolution(layer_disk));
581 smeared.setY(orig.y() + smearLocY);
582 smeared.setZ(orig.z() + smearLocZ);
583
584 } else {
585
586 smeared.setY(orig.y());
587 smeared.setZ(orig.z());
588 }
589
590 //check for module boundaries
591 if (smeared.y()>design->width()/2) {
592 smeared.setY(design->width()/2-1e-6);
593 } else if (smeared.y()<-design->width()/2) {
594 smeared.setY(-design->width()/2+1e-6);
595 }
596 if (smeared.z()>design->length()/2) {
597 smeared.setZ(design->length()/2-1e-6);
598 } else if (smeared.z()<-design->length()/2) {
599 smeared.setZ(-design->length()/2+1e-6);
600 }
601
602
603 return smeared;
604}
605
606double Trk::ReFitTrackWithTruth::getPhiPosResolution(int layer) const { return m_resolutionRPhi[layer]; }
607double Trk::ReFitTrackWithTruth::getEtaPosResolution(int layer) const { return m_resolutionZ[layer]; }
608
609double Trk::ReFitTrackWithTruth::getPhiPosErrorFactor(int layer) const { return m_errorRPhi[layer]; }
610double Trk::ReFitTrackWithTruth::getEtaPosErrorFactor(int layer) const { return m_errorZ[layer]; }
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(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...
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
const ServiceHandle< StoreGateSvc > & detStore() const
bool msgLvl(const MSG::Level lvl) const
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
virtual double length() const =0
Method to calculate length of a module.
virtual double width() const =0
Method to calculate average width of a module.
Base class for the detector design classes for Pixel and SCT.
Class to hold geometrical description of a silicon detector element.
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
Class to represent a position in the natural frame of a silicon sensor, for Pixel and SCT For Pixel: ...
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
HepGeom::Point3D< double > globalPosition(const HepGeom::Point3D< double > &localPos) const
transform a reconstruction local position into a global position (inline):
Amg::Vector2D hitLocalToLocal(double xEta, double xPhi) const
Simulation/Hit local frame to reconstruction local frame.
Specific class to represent the pixel measurements.
virtual const InDetDD::SiDetectorElement * detectorElement() const override final
return the detector element corresponding to this PRD The pointer will be zero if the det el is not d...
double z() const
Definition SiWidth.h:131
double phiR() const
Definition SiWidth.h:126
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Definition SiHit.h:19
HepGeom::Point3D< double > localStartPosition() const
Definition SiHit.cxx:146
HepGeom::Point3D< double > localEndPosition() const
Definition SiHit.cxx:153
double get(ParamDefs par) const
Retrieve specified parameter (const version).
const LocalParameters & localParameters() const
Interface method to get the LocalParameters.
Identifier identify() const
return the identifier
const std::vector< Identifier > & rdoList() const
return the List of rdo identifiers (pointers)
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
Gaudi::Property< bool > m_rejNoiseHits
SG::ReadHandleKey< InDetSimDataCollection > m_SDOContainerName
Trk::RunOutlierRemoval m_runOutlier
double getEtaPosErrorFactor(int layer) const
static bool IsClusterFromTruth(const InDet::PixelCluster *pixClus, const int uniqueIdToMatch, const InDetSimDataCollection &sdoCollection)
Gaudi::Property< bool > m_fixWrongHits
Gaudi::Property< std::vector< float > > m_resolutionRPhi
Gaudi::Property< std::vector< float > > m_resolutionZ
SG::ReadHandleKey< TrackTruthCollection > m_truthMapName
const PixelID * m_pixelID
Pixel ID.
std::vector< SiHit > matchSiHitsToCluster(const int uniqueIdToMatch, const InDet::PixelCluster *pixClus, SG::ReadHandle< AtlasHitsVector< SiHit > > &siHitCollection) const
boost::thread_specific_ptr< TRandom3 > m_random
smear away!
virtual StatusCode initialize() override
ReFitTrackWithTruth(const std::string &name, ISvcLocator *pSvcLocator)
standard Algorithm constructor
Trk::ParticleHypothesis m_ParticleHypothesis
Gaudi::Property< std::vector< float > > m_errorZ
ToolHandle< Trk::IExtendedTrackSummaryTool > m_trkSummaryTool
the track summary tool
SG::ReadHandleKey< SiHitCollection > m_siHitCollectionName
SG::ReadHandleKey< TrackCollection > m_inputTrackColName
Gaudi::Property< std::vector< float > > m_errorRPhi
const AtlasDetectorID * m_idHelper
Detector ID helper.
ToolHandle< Trk::IPRDtoTrackMapTool > m_assoTool
Tool to create and populate PRD to track.
double getEtaPosResolution(int layer) const
Gaudi::Property< bool > m_saveWrongHits
double getPhiPosResolution(int layer) const
virtual StatusCode execute(const EventContext &ctx) override
Execute method.
SG::WriteHandleKey< TrackCollection > m_outputTrackCollectionName
double getPhiPosErrorFactor(int layer) const
HepGeom::Point3D< double > smearTruthPosition(const HepGeom::Point3D< double > &orig, const int bec, const int layer_disk, const InDetDD::SiDetectorDesign *design) const
ToolHandle< Trk::ITrackFitter > m_ITrackFitter
the refit tool
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition hcg.cxx:359
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, 3, 1 > Vector3D
int uniqueID(const T &p)
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ phi0
Definition ParamDefs.h:65
@ theta
Definition ParamDefs.h:66
@ qOverP
perigee
Definition ParamDefs.h:67
@ loc2
generic first and second local coordinate
Definition ParamDefs.h:35
@ loc1
Definition ParamDefs.h:34
@ d0
Definition ParamDefs.h:63
@ z0
Definition ParamDefs.h:64
ParametersBase< TrackParametersDim, Charged > TrackParameters