ATLAS Offline Software
Loading...
Searching...
No Matches
ReFitTrackWithTruth.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 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 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 ATH_MSG_DEBUG ("Refitted parameters differences "
366 << (od0-d0)/od0 << " "
367 << (oz0-z0)/oz0 << " "
368 << (ophi0-phi0)/ophi0 << " "
369 << (otheta-theta)/otheta << " "
370 << (oqOverP-qOverP)/oqOverP );
371 } // aMeasPer exists
372 } // newtrack exists
373 } // if debug
374
375 if (newtrack) { newtracks.push_back(std::move(newtrack)); }
376 else { ATH_MSG_WARNING ("Refit Failed"); }
377
378 } // loop over tracks
379
380 ATH_MSG_VERBOSE ("Add PRDs to assoc tool.");
381
382 // recreate the summaries on the final track collection with correct PRD tool
383 for(const std::unique_ptr<Trk::Track> &new_track : newtracks ) {
384 if((m_assoTool->addPRDs(*prd_to_track_map, *new_track)).isFailure()) {ATH_MSG_WARNING("Failed to add PRDs to map");}
385 }
386
387 ATH_MSG_VERBOSE ("Recalculate the summary");
388 // and copy tracks from vector of non-const tracks to collection of const tracks
389 std::unique_ptr<TrackCollection> new_track_collection = std::make_unique<TrackCollection>();
390 new_track_collection->reserve(newtracks.size());
391 for(std::unique_ptr<Trk::Track> &new_track : newtracks ) {
392 m_trkSummaryTool->computeAndReplaceTrackSummary(ctx, *new_track, false /* DO NOT suppress hole search*/);
393 new_track_collection->push_back(std::move(new_track));
394 }
395
396 ATH_MSG_VERBOSE ("Save tracks");
397 ATH_CHECK(SG::WriteHandle<TrackCollection>(m_outputTrackCollectionName, ctx).record(std::move(new_track_collection)));
398
399 ATH_MSG_INFO ("ReFitTrackWithTruth::execute() completed");
400 return StatusCode::SUCCESS;
401}
402
403std::vector<SiHit> Trk::ReFitTrackWithTruth::matchSiHitsToCluster( const int uniqueIdToMatch,
404 const InDet::PixelCluster* pixClus,
405 SG::ReadHandle<AtlasHitsVector<SiHit>> &siHitCollection) const {
406
407 // passing a negative unique ID value skip this requirement - can get multiple SiHits upon return from different particles
408
409 ATH_MSG_VERBOSE( " Have " << (*siHitCollection).size() << " SiHits to look through" );
410 std::vector<SiHit> matchingHits;
411
412 // Check if we have detector element -- needed to find the local position of the SiHits
413 const InDetDD::SiDetectorElement* de = pixClus->detectorElement();
414 if(!de) {
415 ATH_MSG_WARNING("Do not have detector element to find the local position of SiHits!");
416 return matchingHits;
417 }
418
419 // To locate cluster module
420 Identifier clusterId = pixClus->identify();
421
422 std::vector<const SiHit* > multiMatchingHits;
423
424 // match SiHits to unique ID and make sure in same module as reco hit
425 for ( const auto& siHit : *siHitCollection) {
426
427 if ( uniqueIdToMatch > 0 ) { // negative uniqueIdToMatch will keep all
428 if ( HepMC::uniqueID(&(siHit.particleLink())) != uniqueIdToMatch ) { continue; }
429 }
430
431 // Check if it is a Pixel hit
432 if( !siHit.isPixel() ) { continue; }
433
434 // Match to the cluster module
435 if( m_pixelID->barrel_ec(clusterId) != siHit.getBarrelEndcap() ) { continue; }
436 if( m_pixelID->layer_disk(clusterId)!= siHit.getLayerDisk() ) { continue; }
437 if( m_pixelID->phi_module(clusterId)!= siHit.getPhiModule() ) { continue; }
438 if( m_pixelID->eta_module(clusterId)!= siHit.getEtaModule() ) { continue; }
439
440 // Have SiHits in the same module as the cluster at this point
441 ATH_MSG_DEBUG("Hit is on the same module");
442 multiMatchingHits.push_back(&siHit);
443
444 } // loop over SiHitCollection
445
446
447 //Now we will now make 1 SiHit for each true particle if the SiHits "touch" other
448 std::vector<const SiHit* >::iterator siHitIter = multiMatchingHits.begin();
449 std::vector<const SiHit* >::iterator siHitIter2 = multiMatchingHits.begin();
450 ATH_MSG_DEBUG( "Found " << multiMatchingHits.size() << " SiHit " );
451
452 // double loop - for each matching SiHit, consider all the SiHits _next_ in the collection
453 // to see if they overlap.
454 // if overlapping, combine and only consider new merged hits
455 for ( ; siHitIter != multiMatchingHits.end(); ++siHitIter) {
456 const SiHit* lowestXPos = *siHitIter;
457 const SiHit* highestXPos = *siHitIter;
458
459
460 // We will merge these hits
461 std::vector<const SiHit* > ajoiningHits;
462 ajoiningHits.push_back( *siHitIter );
463
464 siHitIter2 = siHitIter+1;
465 while ( siHitIter2 != multiMatchingHits.end() ) {
466 // Need to come from the same truth particle
467
468 // wasn't the unique ID match already done!?
469 if ( HepMC::uniqueID(&((*siHitIter)->particleLink())) != HepMC::uniqueID(&((*siHitIter2)->particleLink()))) {
470 ++siHitIter2;
471 continue;
472 }
473
474 // Check to see if the SiHits are compatible with each other.
475 if (std::abs((highestXPos->localEndPosition().x()-(*siHitIter2)->localStartPosition().x()))<0.00005 &&
476 std::abs((highestXPos->localEndPosition().y()-(*siHitIter2)->localStartPosition().y()))<0.00005 &&
477 std::abs((highestXPos->localEndPosition().z()-(*siHitIter2)->localStartPosition().z()))<0.00005 )
478 {
479 highestXPos = *siHitIter2;
480 ajoiningHits.push_back( *siHitIter2 );
481 // Dont use hit more than once
482 siHitIter2 = multiMatchingHits.erase( siHitIter2 );
483 //--siHitIter2; // maybe
484 }else if (std::abs((lowestXPos->localStartPosition().x()-(*siHitIter2)->localEndPosition().x()))<0.00005 &&
485 std::abs((lowestXPos->localStartPosition().y()-(*siHitIter2)->localEndPosition().y()))<0.00005 &&
486 std::abs((lowestXPos->localStartPosition().z()-(*siHitIter2)->localEndPosition().z()))<0.00005)
487 {
488 lowestXPos = *siHitIter2;
489 ajoiningHits.push_back( *siHitIter2 );
490 // Dont use hit more than once
491 siHitIter2 = multiMatchingHits.erase( siHitIter2 );
492 // --siHitIter2; // maybe
493 } else {
494 ++siHitIter2;
495 }
496 } // loop over matching SiHits to see if any overlap
497
498 if( ajoiningHits.empty()){
499 ATH_MSG_WARNING("This should really never happen");
500 continue;
501 }
502 if(ajoiningHits.size() == 1){
503 // Copy Si Hit ready to return
504 matchingHits.push_back( *ajoiningHits[0] );
505 continue;
506 }
507 // Build new SiHit and merge information together.
508 ATH_MSG_DEBUG("Merging " << ajoiningHits.size() << " SiHits together." );
509
510
511 float energyDep(0);
512 float time(0);
513 for( auto& siHit : ajoiningHits){
514 energyDep += siHit->energyLoss();
515 time += siHit->meanTime();
516 }
517 time /= (float)ajoiningHits.size();
518
519 matchingHits.emplace_back(lowestXPos->localStartPosition(),
520 highestXPos->localEndPosition(),
521 energyDep,
522 time,
523 HepMC::uniqueID(&((*siHitIter)->particleLink())),
524 0, // 0 for pixel 1 for Pixel
525 (*siHitIter)->getBarrelEndcap(),
526 (*siHitIter)->getLayerDisk(),
527 (*siHitIter)->getEtaModule(),
528 (*siHitIter)->getPhiModule(),
529 (*siHitIter)->getSide() );
530 ATH_MSG_DEBUG("Finished Merging " << ajoiningHits.size() << " SiHits together." );
531 } // loop over all matching SiHits
532
533 return matchingHits;
534}
535
537 const int uniqueIdToMatch,
538 const InDetSimDataCollection &sdoCollection) {
539
540 // Should be true for all pseudotracks
541 // Can be false for reco tracks - misassigned hits
542
543 bool match(false);
544
545 // loop over reconstructed energy depoists in the cluster
546 for( const auto &hitIdentifier : pixClus->rdoList() ) {
547
548 // find the rdo in the sdo collection
549 auto pos = sdoCollection.find(hitIdentifier);
550 if( pos == sdoCollection.end() ) { continue; }
551
552 // get the unique ID from each deposit
553 for( const auto& deposit : pos->second.getdeposits() ){
554 if( !deposit.first ){ continue; } // if truthparticle(?) link doesn't exists? Energy deposit is still known
555 if( HepMC::uniqueID(&(deposit.first)) != uniqueIdToMatch ) { continue; }
556 match = true;
557 break;
558 }
559 if(match) { break; }
560 }
561
562 return match;
563}
564
565HepGeom::Point3D<double> Trk::ReFitTrackWithTruth::smearTruthPosition( const HepGeom::Point3D<double>& orig,
566 const int bec,
567 const int layer_disk,
568 const InDetDD::SiDetectorDesign* design) const {
569
570 HepGeom::Point3D<double> smeared(0,0,0);
571
572 smeared.setX(orig.x());
573
574 if (bec == 0) {
575 double smearLocY = m_random->Gaus(0, getPhiPosResolution(layer_disk));
576 double smearLocZ = m_random->Gaus(0, getEtaPosResolution(layer_disk));
577 smeared.setY(orig.y() + smearLocY);
578 smeared.setZ(orig.z() + smearLocZ);
579
580 } else {
581
582 smeared.setY(orig.y());
583 smeared.setZ(orig.z());
584 }
585
586 //check for module boundaries
587 if (smeared.y()>design->width()/2) {
588 smeared.setY(design->width()/2-1e-6);
589 } else if (smeared.y()<-design->width()/2) {
590 smeared.setY(-design->width()/2+1e-6);
591 }
592 if (smeared.z()>design->length()/2) {
593 smeared.setZ(design->length()/2-1e-6);
594 } else if (smeared.z()<-design->length()/2) {
595 smeared.setZ(-design->width()/2+1e-6);
596 }
597
598
599 return smeared;
600}
601
602double Trk::ReFitTrackWithTruth::getPhiPosResolution(int layer) const { return m_resolutionRPhi[layer]; }
603double Trk::ReFitTrackWithTruth::getEtaPosResolution(int layer) const { return m_resolutionZ[layer]; }
604
605double Trk::ReFitTrackWithTruth::getPhiPosErrorFactor(int layer) const { return m_errorRPhi[layer]; }
606double 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