ATLAS Offline Software
Loading...
Searching...
No Matches
TRT_SeededTrackFinder_ATL.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6// Implementation file for class InDet::TRT_SeededTrackFinder_ATL
8// (c) ATLAS Detector software
11// Version 10 04/12/2006 Thomas Koffas
13
14
15#include "GaudiKernel/MsgStream.h"
16
17#include "CLHEP/Vector/ThreeVector.h"
18
19//Track
20//
24
25//The main Input file
26//
28
29//SCT Geometry
30//
34#include "TrkTrack/TrackInfo.h"
35
36// For SiCombinatorialTrackFinder_xk
38
39//Space point seed finding tool
40
43
44//ReadHandle
46
47#include <cmath>
48#include <iostream>
49#include <iomanip>
50#include <utility>
51#include <string_view>
52
53namespace{
54 double
55 getRadius(const Trk::SpacePoint* pPoint){
56 return pPoint->globalPosition().perp();
57 }
58 double
59 getZ(const Trk::SpacePoint* pPoint){
60 return pPoint->globalPosition().z();
61 }
62
63 double
64 thetaFromSpacePoints(const Trk::SpacePoint* pPoint0, const Trk::SpacePoint* pPoint1 ){
65 const double deltaR = getRadius(pPoint1) - getRadius(pPoint0);
66 const double deltaZ = getZ(pPoint1) - getZ(pPoint0);
67 return std::atan2(deltaR,deltaZ);
68 }
69
70}
71
73// Constructor
75
77(const std::string& t,const std::string& n,const IInterface* p)
78 : AthAlgTool(t,n,p)
79{
80 declareInterface<ITRT_SeededTrackFinder>(this);
81}
82
84
85
87// Initialisation
89
90StatusCode
92
93 ATH_MSG_DEBUG("Initializing TRT_SeededTrackFinder_ATL");
95 ATH_CHECK( m_fieldCondObjInputKey.initialize());
96
97 // Get propagator tool
98 ATH_CHECK(m_proptool.retrieve());
99
100 // Get updator tool
101 ATH_CHECK(m_updatorTool.retrieve());
102
103 // Get detector elements road maker tool
104 ATH_CHECK(m_roadmaker.retrieve());
105
106 // Get seeds maker tool
107 ATH_CHECK(m_seedmaker.retrieve());
108
109 // Get combinatorial track finder tool
110 ATH_CHECK( m_tracksfinder.retrieve());
111
112 // Set track quality cuts for track finding tool
114
115 ATH_CHECK( detStore()->retrieve(m_trtId, "TRT_ID"));
116
117 // Get output print level
118 if(msgLvl(MSG::DEBUG)){ dumpconditions(msg(MSG::DEBUG)); msg(MSG::DEBUG) << endmsg;}
119
120 //initlialize readhandlekey
122
123 return StatusCode::SUCCESS;
124
125}
126
128// Finalize
130
131StatusCode
133 return StatusCode::SUCCESS;
134}
135
137// Dumps relevant information into the MsgStream
139
140MsgStream&
142 out<<"\n";
143 return dumpconditions(out);
144}
145
147// Dumps conditions information into the MsgStream
149
150MsgStream&
152 auto paddedName=[](const auto & str)->std::string{
153 const auto n = 62-std::size(str);
154 std::string result(n,' '); //padding
155 result+='|';
156 result+='\n';
157 return std::string(str)+result;
158 };
159
160 auto format = [](MsgStream& m)->MsgStream&{
161 m<<std::setw(12)<<std::setprecision(5);
162 return m;
163 };
164
165 constexpr std::string_view fieldmode[9] ={"NoField" ,"ConstantField","SolenoidalField",
166 "ToroidalField" ,"Grid3DField" ,"RealisticField" ,
167 "UndefinedField","AthenaField" , "?????" };
168
169 int mode = m_fieldprop.magneticFieldMode();
170 if(mode<0 || mode>8 ) mode = 8;
171
172 constexpr auto horizontalRule{
173 "|-----------------------------------------------------------------------------------------|\n"
174 };
175
176 constexpr auto padding{" |\n"};
177 out<<horizontalRule;
178 out<<"| Tool for propagation | "<<paddedName(m_proptool.type());
179 out<<"| Tool for updator | "<<paddedName(m_updatorTool.type());
180 out<<"| Tool for road maker | "<<paddedName(m_roadmaker.type());
181 out<<"| Tool for seed maker | "<<paddedName(m_seedmaker.type());
182 out<<"| Tool for track finding | "<<paddedName(m_tracksfinder.type());
183 out<<"| Magnetic field mode | "<<paddedName(fieldmode[mode]);
184 out<<"| Min pT of track (MeV) | "<<format<<m_pTmin<<padding;
185 out<<"| Max Xi2 for cluster | "<<format<<m_xi2max<<padding;
186 out<<"| Max Xi2 for outlayer | "<<format<<m_xi2maxNoAdd<<padding;
187 out<<"| Max Xi2 for link | "<<format<<m_xi2maxlink<<padding;
188 out<<"| Min number of clusters | "<<std::setw(12)<<m_nclusmin<<padding;
189 out<<"| Max number holes | "<<std::setw(12)<<m_nholesmax<<padding;
190 out<<"| Max holes gap | "<<std::setw(12)<<m_dholesmax<<padding;
191 out<<horizontalRule;
192 return out;
193}
194
195
197// Dumps relevant information into the ostream
199
200std::ostream&
201InDet::TRT_SeededTrackFinder_ATL::dump( std::ostream& out ) const{
202 return out;
203}
204
206// Initiate track finding tool
208
209std::unique_ptr<InDet::ITRT_SeededTrackFinder::IEventData>
211{
212
214 auto event_data_p = std::make_unique<InDet::TRT_SeededTrackFinder_ATL::EventData>(combinatorialData,
215 m_seedmaker->newEvent());
216 // New event for track finder tool
217 m_tracksfinder->newEvent(ctx, event_data_p->combinatorialData());
218
219 // Print event information
220 if(msgLvl(MSG::DEBUG)) {
221 dumpconditions(msg(MSG::DEBUG));
222 msg(MSG::DEBUG) << endmsg;
223 }
224
225 // Get the calo ROI:
226 if(m_searchInCaloROI ) {
228 if (!calo_rois.isValid()) {
229 ATH_MSG_FATAL("Failed to get EM Calo cluster collection " << m_caloClusterROIKey );
230 }
231 event_data_p->setCaloClusterROIEM(*calo_rois);
232 }
233 return event_data_p;
234}
235
237std::unique_ptr<InDet::ITRT_SeededTrackFinder::IEventData>
239 const std::vector<IdentifierHash>& listOfPixIds,
240 const std::vector<IdentifierHash>& listOfSCTIds) const{
241 auto event_data_p = std::make_unique<InDet::TRT_SeededTrackFinder_ATL::EventData>(combinatorialData,
242 m_seedmaker->newRegion(listOfPixIds,listOfSCTIds));
243
244 // New event for track finder tool
245 m_tracksfinder->newEvent(ctx, event_data_p->combinatorialData());
246
247
248 // Print event information
249 if(msgLvl(MSG::DEBUG)) {
250 dumpconditions(msg(MSG::DEBUG));
251 msg(MSG::DEBUG) << endmsg;
252 }
253
254 return event_data_p;
255}
256
258// Finalize track finding tool for given event
260
261void
263 //event_data cannot be const if passed to m_tracksfinder->endEvent
265 // End event for track finder tool
266 m_tracksfinder->endEvent(event_data.combinatorialData());
267
268}
269
271// Main method for back tracking through the Si ID
272// starting from an intial track segment
274
275std::list<Trk::Track*>
277 InDet::ITRT_SeededTrackFinder::IEventData &virt_event_data, const Trk::TrackSegment& tS) const{
278 //non-const because findTrack alters event_data
280 // return list, will be copied by value (fix!)
281 std::list<Trk::Track*> aSiTrack;
282
283 // protection for having the expected type of segment parameters
284 if ( tS.localParameters().parameterKey() != 31 ){
285 ATH_MSG_WARNING("Wrong type of TRT segment, rejected !" );
286 return aSiTrack;
287 }
288
289 //Get the track segment information and build the initial track parameters
290 const Trk::LocalParameters& Vp = tS.localParameters();
292 throw std::logic_error("Unhandled surface.");
293 }
294
295 const AmgSymMatrix(5)& locCov = tS.localCovariance();
296 AmgSymMatrix(5) ie = locCov;
297
298 std::unique_ptr<Trk::TrackParameters> newPerPar =
300 Vp.get(Trk::loc2),
301 Vp.get(Trk::phi),
302 Vp.get(Trk::theta),
303 Vp.get(Trk::qOverP),
304 ie);
305
306 if(newPerPar){
307 ATH_MSG_DEBUG("Initial Track Parameters created from TRT segment, ");
308 ATH_MSG_VERBOSE(*newPerPar) ;
309 }else{
310 ATH_MSG_WARNING( "Could not get initial TRT track parameters, rejected! " );
311 return aSiTrack;
312 }
313 constexpr auto horizontalRule{"==============================================================\n"};
314 //Do the actual tracking and smoothing and get the Si track states on surface
315 ATH_MSG_DEBUG(horizontalRule << "Start initial search with 3-4 SCT layer combinations ");
316
317 if (m_searchInCaloROI && !isCaloCompatible( *newPerPar, event_data )) {
318 return aSiTrack;
319 }
320
321 // Get AtlasFieldCache
323 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
324 if (fieldCondObj == nullptr) {
325 ATH_MSG_ERROR("TRT_SeededTrackFinder_ATL::getTracks: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
326 return aSiTrack;
327 }
328 MagField::AtlasFieldCache fieldCache;
329 fieldCondObj->getInitializedCache (fieldCache);
330
331 aSiTrack = findTrack(ctx, fieldCache, event_data, *newPerPar, tS);
332 if((aSiTrack.empty())&&(m_bremCorrect)){
333 ATH_MSG_DEBUG(horizontalRule << "Could not create track states on surface for this track!Try to add brem correction.");
334
335 std::unique_ptr<const Trk::TrackParameters> modTP = modifyTrackParameters(*newPerPar,0);
336 ATH_MSG_VERBOSE("Modified TRT Track Parameters for brem. \n"<<(*modTP));
337 aSiTrack = findTrack(ctx, fieldCache, event_data, *modTP, tS);
338 if(aSiTrack.empty()){
339 ATH_MSG_DEBUG("Could not create track states on surface for this track after all!");
340 return aSiTrack;
341 }
342 ATH_MSG_DEBUG(horizontalRule);
343 }
344
345 //Return list of tracks (by value !?)
346 return aSiTrack;
347}
348
350// Main method for back tracking through the Si ID
351// starting from initial track parameters
353
354std::list<Trk::Track*>
357 const Trk::TrackSegment& tS) const{
358 SiCombinatorialTrackFinderData_xk& combinatorialData=event_data.combinatorialData();
359 //Return list copied by value (fix!!)
360 std::list<Trk::Track*> associatedSiTrack; // List of found tracks per TRT segment
361 constexpr double pi2 = 2.*M_PI;
362 constexpr double pi=M_PI;
363
364 //Get the seeds
365 std::list<std::pair<const Trk::SpacePoint*,const Trk::SpacePoint*> >
366 SpE = m_seedmaker->find2Sp(ctx, initTP,event_data.spacePointFinderEventData()); //Get a list of SP pairs
367
368 ATH_MSG_DEBUG("---------------> SP SEED LIST SIZE " << SpE.size() );
369 if(SpE.empty()){return associatedSiTrack;}
370
371 //
372 // --------------- loop over the found seeds
373 //
374
375 //Get the track states on surface that correspond to each SP pair that came from the seeding
376 std::vector<const Trk::SpacePoint*> SpVec{nullptr, nullptr};
377
378 std::list<std::pair<const Trk::SpacePoint*,const Trk::SpacePoint*> >::iterator r,re=SpE.end();
379 for(r=SpE.begin();r!=re; ++r){
380 std::list<Trk::Track*> aTracks ; // List of tracks found per seed
381 std::list<Trk::Track*> cTracks ; // List of cleaned tracks found per seed
382 event_data.noise().reset(); //Initiate the noise production tool at the beginning of each seed
383
384 //
385 // --------------- filter SP to improve prediction, scale errors
386 //
387
388 //Get the track parameters to use to get the detector elements for each SP pair
389 std::pair<const Trk::SpacePoint*, const Trk::SpacePoint*>& pSP = *r;
390 if (pSP.first != pSP.second){
391 ATH_MSG_DEBUG( "----> Seed Pair: SP 1 " << (pSP.first)->r() << " SP 2 " << (pSP.second)->r() );
392 } else {
393 if(msgLvl(MSG::DEBUG)) {
394 msg(MSG::DEBUG) << "----> Seed Single: SP 1 " << (pSP.first)->r() << "\n";
395 msg(MSG::DEBUG) << " Will not process for the time being ! A special module is needed\n" ;
396 msg(MSG::DEBUG) << " to deal with late conversion (no search and stablized input fit ).\n";
397 msg(MSG::DEBUG) << " Current version is unstable in the SP updates and gets unpredictable results." << endmsg;
398 }
399 continue;
400 }
401
403 SpVec[0]=(pSP.second);
404 SpVec[1]=(pSP.first);
405 if(!newClusters(SpVec,event_data)) {
406 ATH_MSG_DEBUG( "Seed SPs already used by a single track. Ignore..." );
407 continue;
408 }
409 if(!newSeed(SpVec,event_data)) {
410 ATH_MSG_DEBUG( "Seed SPs already used by other tracks. Ignore..." );
411 continue;
412 }
413
414 //
415 // ----------------Check the SP seed if field is ON
416 //
417 if(fieldCache.solenoidOn()){
418 bool seedGood = checkSeed(SpVec,tS,initTP);
419 if(!seedGood && m_propR) {
420 ATH_MSG_DEBUG( "Seed not consistent with TRT segment. Ignore..." );
421 continue;
422 }
423 }
424
425 //
426 // ----------------Get new better track parameters using the SP seed
427 //
428 ATH_MSG_DEBUG( "Get better track parameters using the seed" );
429 double newTheta = thetaFromSpacePoints(SpVec[0], SpVec[1]);
430 const AmgVector(5)& iv = initTP.parameters();
431 double newPhi = iv[2];
432 //Protect for theta and phi being out of range
433 if (newTheta > pi) newTheta = fmod(newTheta+pi,pi2)-pi;
434 else if(newTheta <-pi) newTheta = fmod(newTheta-pi,pi2)+pi;
435 if(newTheta<0.){ newTheta = -newTheta; newPhi+=pi; }
436 if (newPhi > pi) newPhi = fmod(newPhi+pi,pi2)-pi;
437 else if(newPhi <-pi) newPhi = fmod(newPhi-pi,pi2)+pi;
438 if(newTheta<0.27) {
439 ATH_MSG_DEBUG("Pseudorapidity greater than 2.Ignore" );
440 continue;
441 }
442
443 const AmgSymMatrix(5) * vCM = initTP.covariance();
444 AmgSymMatrix(5) nvCM;
445 nvCM<<
446 m_errorScale[0]*m_errorScale[0]*(*vCM)(0,0),0.,0.,0.,0.,
447 0.,m_errorScale[1]*m_errorScale[1]*(*vCM)(1,1),0.,0.,0.,
448 0.,0.,m_errorScale[2]*m_errorScale[2]*(*vCM)(2,2),0.,0.,
449 0.,0.,0.,m_errorScale[3]*m_errorScale[3]*(*vCM)(3,3),0.,
450 //cppcheck-suppress constStatement
451 0.,0.,0.,0.,m_errorScale[4]*m_errorScale[4]*(*vCM)(4,4);
452
453
454 //New intial track parameters saved as MeasuredAtaStraightLine
455 std::unique_ptr<const Trk::TrackParameters> niTP =
457 iv[0], iv[1], newPhi, newTheta, iv[4], nvCM);
458
459 if (niTP) {
460 ATH_MSG_DEBUG("Initial Track Parameters created and scaled from TRT segment, ");
461 ATH_MSG_VERBOSE(*niTP);
462 } else {
463 ATH_MSG_DEBUG("Could not get initial TRT track parameters! " );
464 continue;
465 }
466
467 //
468 // ----------------Propagate through the SP seed
469 //
470 ATH_MSG_DEBUG( "Propagating through the seed" );
471 bool outl = false;
472
473 //update with first SP
474 ATH_MSG_DEBUG( "Update with 1st SP from seed" );
475 std::unique_ptr<const Trk::TrackParameters> upTP = getTP(fieldCache, pSP.first,*niTP,outl,event_data);
476 //If no track parameters are found, go to the next seed
477 if(!upTP){
478 ATH_MSG_DEBUG( "Extrapolation through seed failed!Seed bogus.Move to next seed" );
479 continue;
480 }
481 //Not good if SP pair has outliers. Clean up the memory and move to next seed
482 if(outl){
483 ATH_MSG_DEBUG("Seed with outliers. Will not process!");
484 continue;
485 }
486
487 //update with second SP ?
488 if (pSP.first != pSP.second) {
489 //update with second SP
490 ATH_MSG_DEBUG( "Update with 2nd SP from seed" );
491 std::unique_ptr<const Trk::TrackParameters> newTP = getTP(fieldCache, pSP.second,*upTP,outl,event_data);
492 //If no track parameters are found, go to the next seed
493 if(!newTP){
494 ATH_MSG_DEBUG( "Extrapolation through seed failed!Seed bogus.Move to next seed" );
495 continue;
496 }
497 //Not good if SP pair has outliers. Clean up the memory and move to next seed
498 if(outl){
499 ATH_MSG_DEBUG("Seed with outliers.Will not process!");
500 continue;
501 }
502 // copy the newTP to upTP
503 upTP = std::move(newTP);
504 }
505
506 //Protect the road maker tool when the momentum is too low since the particle will spiral inside the tracker
507 if(upTP->momentum().perp()<m_pTmin){
508 ATH_MSG_DEBUG("Low pT.Stop! ");
509 continue;
510 }
511
512 //
513 // --------------- get Si detector element road
514 //
515 const Trk::PerigeeSurface persurf (Amg::Vector3D(0,0,0));
516
517 //Get track parameters at the end of SCT to start backwards propagation
518 auto per = m_proptool->propagate(ctx,*upTP,persurf,Trk::oppositeMomentum,false,
519 m_fieldprop,Trk::nonInteracting); //Propagate
520 if(!per){
521 ATH_MSG_DEBUG("No extrapolated track parameters!");
522 continue;
523 }
524
525 if(msgLvl(MSG::VERBOSE)) {
526 msg(MSG::VERBOSE) << "Perigee after SP updates at same surface" << endmsg;
527 msg(MSG::VERBOSE) << *per << endmsg;
528 }
529
530 //Get list of InDet Elements
531 std::vector<const InDetDD::SiDetectorElement*> DE;
532 m_roadmaker->detElementsRoad(ctx, fieldCache, *per,Trk::alongMomentum,DE,event_data.roadMakerData());
533 if( int(DE.size()) < m_nclusmin){ //Not enough detector elements to satisfy the minimum number of clusters requirement. Stop
534 ATH_MSG_DEBUG( "Too few detector elements, not expected" );
535 continue;
536 }
537
538 //
539 // --------------- Cast it to measured parameters at 2nd SP with diagonal error matrix
540 //
541 const AmgVector(5)& piv = upTP->parameters();
542
543 //Get the intial Error matrix, diagonalize it and scale the errors
544 std::unique_ptr<const Trk::TrackParameters> mesTP{};
545 const AmgSymMatrix(5)* pvCM = upTP->covariance();
546 if(pvCM){
547 AmgSymMatrix(5) pnvCM;
548 pnvCM<<
549 m_errorScale[0]*m_errorScale[0]*(*pvCM)(0,0),0.,0.,0.,0.,
550 0.,m_errorScale[1]*m_errorScale[1]*(*pvCM)(1,1),0.,0.,0.,
551 0.,0.,m_errorScale[2]*m_errorScale[2]*(*pvCM)(2,2),0.,0.,
552 0.,0.,0.,m_errorScale[3]*m_errorScale[3]*(*pvCM)(3,3),0.,
553 //cppcheck-suppress constStatement
554 0.,0.,0.,0.,m_errorScale[4]*m_errorScale[4]*(*pvCM)(4,4);
555
556 mesTP = upTP->associatedSurface().createUniqueTrackParameters(piv[0],piv[1],piv[2],piv[3],piv[4],pnvCM);
557 if(mesTP){
558 ATH_MSG_DEBUG( "Initial Track Parameters at 1st SP created and scaled from TRT segment, " );
559 ATH_MSG_VERBOSE( *mesTP );
560 }else{
561 continue;
562 }
563 }else{
564 continue;
565 }
566
567 //
568 // --------------- Get the Si extensions using the combinatorial track finding tool
569 //
570 std::vector<Amg::Vector3D> Gp;
571 aTracks = m_tracksfinder->getTracks(combinatorialData, *mesTP, SpVec, Gp, DE, m_trackquality, ctx);
572 if(aTracks.empty()) {
573 ATH_MSG_DEBUG("No tracks found by the combinatorial track finder!");
574 }
575
576 //
577 // --------------- Drop spurious pixel hits
578 //
579 cTracks=cleanTrack(aTracks);
580
581 //
582 // --------------- Add tracks in the track multimap and in the overall list of TRT segment associated tracks
583 //
584 std::list<Trk::Track*>::iterator t = cTracks.begin();
585 while(t!=cTracks.end()) {
586 if(!isNewTrack((*t),event_data)) {
587 delete (*t);
588 cTracks.erase(t++);
589 } else {
590 clusterTrackMap((*t),event_data);
591 associatedSiTrack.push_back((*t++));
592 }
593 }
594 }
595
596 return associatedSiTrack;
597}
598
600// update track parameters using SP
602
603std::unique_ptr<const Trk::TrackParameters>
605 const Trk::TrackParameters& startTP,
606 bool& outl,
608 std::unique_ptr<const Trk::TrackParameters> iTP{};
609 outl = false;
610 const Trk::Surface& surf = SP->associatedSurface();//Get the associated surface
611 Trk::PropDirection dir = Trk::oppositeMomentum; //Propagate backwards i.e. opposite momentum when filtering
612 Trk::ParticleHypothesis part = Trk::nonInteracting;//Choose a non interacting particle
613 auto eTP = m_proptool->propagate(Gaudi::Hive::currentContext(),
614 startTP,surf,dir,false,m_fieldprop,part); //Propagate
615
616 if(!eTP){
617 ATH_MSG_DEBUG( "Extrapolation to Si element failed");
618 ATH_MSG_VERBOSE( surf );
619 return nullptr;
620 }else{
621 //Based on the hit information update the track parameters and the error matrix
622 Trk::FitQualityOnSurface* sct_fitChi2 = nullptr;
623 std::unique_ptr<const Trk::TrackParameters> uTP = m_updatorTool->addToState(*eTP,SP->localParameters(),SP->localCovariance(),sct_fitChi2);
624 if(!uTP) { //The updator failed
625 if (sct_fitChi2) {
626 ATH_MSG_DEBUG( "Updator returned no update, but a DitQuality object, a leak !");
627 delete sct_fitChi2;
628 }
629 event_data.noise().production(-1,1,*eTP);
630
631 iTP = addNoise(event_data.noise(),*eTP,0);
632 ATH_MSG_DEBUG("The updator failed! Count an outlier ");
633 outl = true;
634 }else{
635 //Keep as a measurement only if fit chi2 less than 25.Otherwise outlier
636 float outlierCut = m_outlierCut;
637 if(!fieldCache.solenoidOn()) outlierCut = 1000000.; // Increase the outlier chi2 cut if solenoid field is OFF
638 if( sct_fitChi2->chiSquared() < outlierCut && std::abs(uTP->parameters()[Trk::theta]) > 0.17 ){
639 ATH_MSG_DEBUG("Update worked, will update return track parameters, chi2: "<<(sct_fitChi2->chiSquared()));
640 event_data.noise().production(-1,1,*uTP);
641 iTP = addNoise(event_data.noise(),*uTP,0);
642 }else{
643 ATH_MSG_DEBUG("Outlier, did not satisfy cuts, chi2: "<<(sct_fitChi2->chiSquared())<<" "<<std::abs(uTP->parameters()[Trk::theta]));
644 event_data.noise().production(-1,1,*eTP);
645 iTP = addNoise(event_data.noise(),*eTP,0);
646 outl = true;
647 }
648 // Clean up
649 delete sct_fitChi2;
650 }
651 }
652 return iTP;
653}
654
656// Add noise to track parameters
657// 0-Filtering, 1-Smoothing
659
660std::unique_ptr<const Trk::TrackParameters>
662 ATH_MSG_DEBUG( "Adding noise to track parameters... " );
663 const double covAzim=noise.covarianceAzim();
664 const double covPola=noise.covariancePola();
665 const double covIMom=noise.covarianceIMom();
666 const double corIMom=noise.correctionIMom();
667 //Get the noise augmented parameters and the 15 lower half covariance matrix elements from the first input track parameters
668 const AmgVector(5)& Vp1 = P1.parameters();
669 double M[5]={Vp1[0],Vp1[1],Vp1[2],Vp1[3],Vp1[4]};
670 if(!isSmooth){
671 M[4] *= corIMom;
672 }else{
673 M[4] /= corIMom;
674 }
675 const AmgSymMatrix(5)* C = P1.covariance();
676 if(C){
677 AmgSymMatrix(5) nC;
678 nC = (*C);
679 nC(2,2)+=covAzim;
680 nC(3,3)+=covPola;
681 nC(4,4)+=covIMom;
682 return P1.associatedSurface().createUniqueTrackParameters(M[0],M[1],M[2],M[3],M[4],nC);
683 }
684 return nullptr;
685}
686
687
688
690// Get new theta estimate using the SPs from the seed
692
693bool
695 (std::vector<const Trk::SpacePoint*>& vsp,const Trk::TrackSegment& tS,const Trk::TrackParameters & tP) const{
696 bool isGood = true;
697 int nEC = 0; double gz = 0.;
699 const AmgVector(5)& pTS=tP.parameters();
701 if(std::abs(std::log(std::tan(pTS[3]/2.)))>0.8){
703 for(int it=0; it<int(tS.numberOfMeasurementBases()); it++){
704 //Check if it is a pseudo measurement and move on
705 if ( dynamic_cast<const Trk::PseudoMeasurementOnTrack*>(tS.measurement(it)) ) continue;
706 const InDet::TRT_DriftCircleOnTrack* trtcircle = dynamic_cast<const InDet::TRT_DriftCircleOnTrack*>(tS.measurement(it));
707 if(trtcircle){
708 Identifier id=trtcircle->detectorElement()->identify();
709 int isB = m_trtId->barrel_ec(id);
710 if(isB==2 || isB==-2) nEC++;
711 if(nEC==1){
712 gz = trtcircle->globalPosition().z();
713 break;
714 }
715 }
716 }
717 double tanTheta = std::tan(thetaFromSpacePoints(vsp[0], vsp[1]));
719 double propR = getRadius(vsp[1]) + (gz-getZ(vsp[1]))*tanTheta;
720 if(propR<620. || propR>1010.) isGood=false;
721 double zIn = gz-propR/tanTheta;
722 if(zIn>300.) isGood = false;
723 }
724 return isGood;
725}
726
728// Calculate initial track parameters for back tracking
729// using TRT New Tracking segments
731
732std::unique_ptr<const Trk::TrackParameters>
736 const AmgVector(5)& pV = TP.parameters();
737 double ip[5] = {pV[0], pV[1], pV[2], pV[3], pV[4]};
738
740 const double & q = ip[4]; //no need to take std::abs, its squared next
741 const double covarianceIMom = 0.25*q*q;
742 ip[4] *= 0.5;
743
744 const AmgSymMatrix(5) * CM = TP.covariance();
745 AmgSymMatrix(5) nM = (*CM);
746
747 if(mode==0){ //Modification initiated before seed propagation
748 nM(4,4) = 10.*(0.1*((*CM)(4,4))+covarianceIMom);
749 }
750 if(mode==1){ //Modification initiated before pixel propagation
751 nM(4,4)+=covarianceIMom;
752 }
753 return TP.associatedSurface().createUniqueTrackParameters(ip[0], ip[1], ip[2], ip[3], ip[4], nM);
754}
755
757// Set track quality cuts
759
760void
762 // Integer cuts
763 //
764 m_trackquality.setIntCut ("MinNumberOfClusters", m_nclusmin );
765 m_trackquality.setIntCut ("MinNumberOfWClusters", m_nwclusmin );
766 m_trackquality.setIntCut ("MaxNumberOfHoles" , m_nholesmax );
767 m_trackquality.setIntCut ("MaxHolesGap" , m_dholesmax );
768 if( m_useassoTool ) m_trackquality.setIntCut ("UseAssociationTool",1);
769 else m_trackquality.setIntCut ("UseAssociationTool",0);
770
771 // Double cuts
772 //
773 m_trackquality.setDoubleCut("pTmin" ,m_pTmin );
774 m_trackquality.setDoubleCut("MaxXi2forCluster" ,m_xi2max );
775 m_trackquality.setDoubleCut("MaxXi2forOutlier" ,m_xi2maxNoAdd);
776 m_trackquality.setDoubleCut("MaxXi2forSearch" ,m_xi2maxlink );
777}
778
780// Clusters-track multimap production
782
785{
787 m = Tr->measurementsOnTrack()->begin(),
788 me = Tr->measurementsOnTrack()->end ();
789
790 for(; m!=me; ++m) {
791 const Trk::PrepRawData* prd = ((const Trk::RIO_OnTrack*)(*m))->prepRawData();
792 if(prd) event_data.clusterTrack().insert(std::make_pair(prd,Tr));
793 }
794}
795
797// New clusters comparison with clusters associated with track
798// Reject seeds that all SPs belong to one and the same track
800
801bool
802InDet::TRT_SeededTrackFinder_ATL::newClusters(const std::vector<const Trk::SpacePoint*>& Sp,
804 const Trk::PrepRawData* prd [ 40];
805 const Trk::Track* trk[2][200];
806 std::multimap<const Trk::PrepRawData*,const Trk::Track*>::const_iterator
807 t[40],te = event_data.clusterTrack().end();
808 std::vector<const Trk::SpacePoint*>::const_iterator s=Sp.begin(),se=Sp.end();
809 int n = 0;
810
811 //If at least one of the clusters in the seed is not used by a track the seed is good
812 for(; s!=se; ++s) {
813 if((*s)->clusterList().first ) {
814 prd[n] = (*s)->clusterList().first;
815 t [n] = event_data.clusterTrack().find(prd[n]);
816 if(t[n]==te) return true;
817 ++n;
818 }
819 if((*s)->clusterList().second) {
820 prd[n] = (*s)->clusterList().second;
821 t [n] = event_data.clusterTrack().find(prd[n]);
822 if(t[n]==te) return true;
823 ++n;
824 }
825 if(n==40) break;
826 }
827 if(!n) return false;
828
829 //Array of pointers to the different tracks that the first used cluster belongs to
830 int m = 0;
831 auto & pTracks=t[0];
832 for(; pTracks!=te; ++pTracks) {
833 if (m==30) return false;
834 if( (*pTracks).first != prd[0] ) break;
835 trk[0][m++] = (*pTracks).second;
836 if(m==200) break;
837 }
838
839 //For a seed to be declared bad, all other clusters should belong to the same track as that of the first used cluster
840 int in=0, ou=1;
841 for(int i=1; i!=n; ++i) {
842 int l = 0; //Number of tracks that share the same clusters
843 auto & pTheseTracks=t[i];
844 for(; pTheseTracks!=te; ++pTheseTracks) {
845 if( (*pTheseTracks).first != prd[i] ) break;
846 for(int j=0; j!=m; ++j) {
847 if((*pTheseTracks).second == trk[in][j]) {trk[ou][l++]= trk[in][j];
848 break;
849 }
850 }
851 }
852 if(l==0) return true; //At least one of the seed clusters belongs to a track different from that of the first used clusters
853 m=l;
854 if(in==0) {
855 in=1; ou=0;
856 } else {
857 in=0; ou=1;
858 }
859 }
860
861 return false;
862}
863
865// New clusters comparison with clusters associated with track
866// Reject seeds that all SPs have been already used by other tracks
868
869 bool
870 InDet::TRT_SeededTrackFinder_ATL::newSeed(const std::vector<const Trk::SpacePoint*>& Sp,
872 const Trk::PrepRawData* prd [ 40];
873 const Trk::Track* trk[2][200];
874 std::multimap<const Trk::PrepRawData*,const Trk::Track*>::const_iterator
875 tt,t[40],te = event_data.clusterTrack().end();
876
877 std::vector<const Trk::SpacePoint*>::const_iterator s=Sp.begin(),se=Sp.end();
878 int n = 0;
879 int nc = 0;
880 for(; s!=se; ++s) {
881 if((*s)->clusterList().first ) {
882 prd[n] = (*s)->clusterList().first;
883 t [n] = event_data.clusterTrack().find(prd[n]); if(t[n]!=te) ++nc; ++n;
884 }
885 if((*s)->clusterList().second) {
886 prd[n] = (*s)->clusterList().second;
887 t [n] = event_data.clusterTrack().find(prd[n]); if(t[n]!=te) ++nc; ++n;
888 }
889 if(n>=40) break;
890 }
891 if(!nc) return true;
892 if(n==nc) {
893 int m = 0;
894 for(tt=t[0]; tt!=te; ++tt) {
895 if( (*tt).first != prd[0] ) break;
896 trk[0][m++] = (*tt).second;
897 if(m==200) break;
898 }
899 int in=0, ou=1, i=1;
900 for(; i!=n; ++i) {
901 int l = 0;
902 for(tt=t[i]; t[i]!=te; ++tt) {
903 if( (*tt).first != prd[i] ) break;
904 for(int j=0; j!=m; ++j) {
905 if((*tt).second == trk[in][j]) {
906 trk[ou][l++]= trk[in][j];
907 break;
908 }
909 }
910 }
911 if(l==0) break;
912 m=l;
913 if(in==0) {
914 in=1;
915 ou=0;
916 } else {
917 in=0;
918 ou=1;
919 }
920 }
921 if(i==n) return false;
922 }
923
924 //if(!(*Sp.rbegin())->clusterList().second) return true;
925
926 int h = 0;
927 for(int i=0; i!=n; ++i) {
928 for(tt=t[i]; t[i]!=te; ++tt) {
929 if( (*tt).first != prd[i] ) break;
930 if((*tt).second->trackStateOnSurfaces()->size() >= 10) {
931 ++h;
932 break;
933 }
934 }
935 }
936 return h == 0;
937}
938
940// Test is it new track
942
943bool
946
947 const Trk::PrepRawData* prd [100];
948 std::multimap<const Trk::PrepRawData*,const Trk::Track*>::const_iterator
949 ti,t[100],te = event_data.clusterTrack().end();
950 int n = 0 ;
952 m = Tr->measurementsOnTrack()->begin(),
953 me = Tr->measurementsOnTrack()->end ();
954
955 for(; m!=me; ++m) {
956 const Trk::PrepRawData* pr = ((const Trk::RIO_OnTrack*)(*m))->prepRawData();
957 if(pr) {
958 prd[n] =pr;
959 t[n] = event_data.clusterTrack().find(prd[n]);
960 if(t[n]==te) return true;
961 ++n;
962 }
963 }
964
965 int nclt = n;
966
967 for(int i=0; i!=n; ++i) {
968 int nclmax = 0;
969 for(ti=t[i]; ti!=te; ++ti) {
970 if( (*ti).first != prd[i] ) break;
971 int ncl = (*ti).second->trackStateOnSurfaces()->size();
972 if(ncl > nclmax) nclmax = ncl;
973 }
974 if(nclt > nclmax) return true;
975 }
976 return false;
977}
978
980// Eliminate spurious pixel hits
982
983std::list<Trk::Track*>
984InDet::TRT_SeededTrackFinder_ATL::cleanTrack(std::list<Trk::Track*> lTrk) const{
985 std::list<Trk::Track*> cleanSiTrack; // List of clean Si tracks per TRT segment
986 std::list<Trk::Track*>::const_iterator it = lTrk.begin();
987 std::list<Trk::Track*>::const_iterator itEnd = lTrk.end();
988 for (; it != itEnd ; ++it){
989 int nPixHits = 0; //Number of Pixel PRDs
990 int nSctHits = 0; //Number of SCT PRDs
991 double pixR = 0.; //Radial position of last pixel PRD
992 double sctR = 0.; //Radial position of first SCT PRD
993
994 const Trk::TrackStates* newtsos = (*it)->trackStateOnSurfaces();
995 if(!newtsos) continue;
996 Trk::TrackStates::const_iterator itp, itpe=newtsos->end();
997 for(itp=newtsos->begin(); itp!=itpe; ++itp){
999 const InDet::SiClusterOnTrack* clus = dynamic_cast<const InDet::SiClusterOnTrack*>((*itp)->measurementOnTrack());
1000 if(clus && ((*itp)->type(Trk::TrackStateOnSurface::Measurement))){ //Count the number of hits used in the track
1001 const InDet::SiCluster* RawDataClus=dynamic_cast<const InDet::SiCluster*>(clus->prepRawData());
1002 if(RawDataClus==nullptr){
1003 ATH_MSG_DEBUG( "Si Cluster without PrepRawData!!!" );
1004 continue;
1005 }
1006 if(RawDataClus->detectorElement()->isPixel()){
1007 nPixHits++;
1008 pixR = RawDataClus->globalPosition().perp();
1009 }
1010 if((RawDataClus->detectorElement()->isSCT()) && (nSctHits==0)) {
1011 sctR = RawDataClus->globalPosition().perp();
1012 nSctHits++;
1013 break;
1014 }
1015 }
1016 }
1017
1019 if(nPixHits==1 && (sctR-pixR)>200.){
1020 auto cltsos = std::make_unique<Trk::TrackStates>();
1021 auto fq = (*it)->fitQuality()->uniqueClone();
1022 // copy track Si states into track
1024 for(p_tsos=newtsos->begin()+nPixHits;p_tsos!=newtsos->end();++p_tsos){
1025 cltsos->push_back( (*p_tsos)->clone() );
1026 }
1028 Trk::TrackInfo info;
1029 // info.setPatternRecognitionInfo(Trk::TrackInfo::TRTSeededTrackFinder);
1030 Trk::Track* nTrack = new Trk::Track(info, std::move(cltsos), std::move(fq));
1031 cleanSiTrack.push_back(nTrack);
1032 delete (*it);
1033 }else{
1034 cleanSiTrack.push_back((*it));
1035 }
1036 }
1037
1038 return cleanSiTrack;
1039}
1040
1041
1043// Test is it track with calo seed compatible
1045bool
1047 const InDet::TRT_SeededTrackFinder_ATL::EventData &event_data) const{
1048 if(!event_data.caloClusterROIEM()) return false;
1049 const AmgVector(5)& Vp = Tp.parameters();
1050 const double F = Vp[2];
1051 ROIPhiRZContainer::const_iterator roi_iter = event_data.caloClusterROIEM()->lowerPhiBound( F, m_phiWidth);
1052 return roi_iter != event_data.caloClusterROIEM()->end();
1053}
1054
1055
1057// MagneticFieldProperties production
1059void
const boost::regex re(r_e)
#define M_PI
Scalar deltaR(const MatrixBase< Derived > &vec) const
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define AmgSymMatrix(dim)
#define AmgVector(rows)
static Double_t Tp(Double_t *t, Double_t *par)
#define F(x, y, z)
Definition MD5.cxx:112
Handle class for reading from StoreGate.
This is an Identifier helper class for the TRT subdetector.
#define pi
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
const ServiceHandle< StoreGateSvc > & detStore() const
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
Header file for AthHistogramAlgorithm.
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
DataModel_detail::const_iterator< DataVector > const_iterator
Standard const_iterator.
Definition DataVector.h:838
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
virtual Identifier identify() const override final
identifier of this detector element:
RIO_OnTrack base class for Silicon detector in the InnerDetector.
const Amg::Vector3D & globalPosition() const
return global position reference
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...
InDet::SiCombinatorialTrackFinderData_xk holds event dependent data used by SiCombinatorialTrackFinde...
void production(int direction, int model, const Trk::TrackParameters &tp)
Represents 'corrected' measurements from the TRT (for example, corrected for wire sag).
virtual const InDetDD::TRT_BaseElement * detectorElement() const override final
returns the detector element, assoicated with the PRD of this class
virtual const Amg::Vector3D & globalPosition() const override final
return the global position of this RIO_OnTrack
virtual InDet::SiCombinatorialTrackFinderData_xk & combinatorialData() override
InDet::SiDetElementRoadMakerData_xk & roadMakerData()
InDet::ITRT_SeededSpacePointFinder::IEventData & spacePointFinderEventData()
std::multimap< const Trk::PrepRawData *, const Trk::Track * > & clusterTrack()
ToolHandle< InDet::ITRT_SeededSpacePointFinder > m_seedmaker
MsgStream & dumpconditions(MsgStream &out) const
ToolHandle< Trk::IUpdator > m_updatorTool
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCondObjInputKey
bool checkSeed(std::vector< const Trk::SpacePoint * > &, const Trk::TrackSegment &, const Trk::TrackParameters &) const
Check consistency of seed and TRT track segment.
std::unique_ptr< const Trk::TrackParameters > addNoise(const SiNoise_bt &, const Trk::TrackParameters &, int) const
Add material effects.
static void clusterTrackMap(Trk::Track *, InDet::TRT_SeededTrackFinder_ATL::EventData &event_data)
Map PRDs-tracks.
virtual StatusCode initialize() override
std::list< Trk::Track * > findTrack(const EventContext &ctx, MagField::AtlasFieldCache &fieldCache, InDet::TRT_SeededTrackFinder_ATL::EventData &event_data, const Trk::TrackParameters &, const Trk::TrackSegment &) const
Find the corresponding list of Si tracks.
ToolHandle< Trk::IPropagator > m_proptool
virtual std::unique_ptr< InDet::ITRT_SeededTrackFinder::IEventData > newRegion(const EventContext &ctx, SiCombinatorialTrackFinderData_xk &combinatorialData, const std::vector< IdentifierHash > &, const std::vector< IdentifierHash > &) const override
New region intialization.
MsgStream & dump(MsgStream &out) const override
Print internal tool parameters and status.
bool isCaloCompatible(const Trk::TrackParameters &, const InDet::TRT_SeededTrackFinder_ATL::EventData &event_data) const
Only propagate to the Si if the TRT segment is compatible with a calo measurement.
ToolHandle< InDet::ISiDetElementsRoadMaker > m_roadmaker
Magnetic field properties.
virtual std::list< Trk::Track * > getTrack(const EventContext &ctx, InDet::ITRT_SeededTrackFinder::IEventData &event_data, const Trk::TrackSegment &) const override
Main methods for local track finding.
virtual std::unique_ptr< InDet::ITRT_SeededTrackFinder::IEventData > newEvent(const EventContext &ctx, SiCombinatorialTrackFinderData_xk &combinatorialData) const override
New event initialization.
ToolHandle< InDet::ISiCombinatorialTrackFinder > m_tracksfinder
SG::ReadHandleKey< ROIPhiRZContainer > m_caloClusterROIKey
static bool newClusters(const std::vector< const Trk::SpacePoint * > &, InDet::TRT_SeededTrackFinder_ATL::EventData &event_data)
Seed used by another track?
TRT_SeededTrackFinder_ATL(const std::string &, const std::string &, const IInterface *)
Standard tool methods.
static std::unique_ptr< const Trk::TrackParameters > modifyTrackParameters(const Trk::TrackParameters &, int)
Modify track parameters if brem correction.
void setTrackQualityCuts()
Set the track quality cuts for combinatorial track finding.
Trk::MagneticFieldProperties m_fieldprop
static bool newSeed(const std::vector< const Trk::SpacePoint * > &, InDet::TRT_SeededTrackFinder_ATL::EventData &event_data)
Seed SPs used by other high quality tracks?
DoubleProperty m_xi2max
Track quality cuts to be passed to the combinatorial track finder.
StringProperty m_fieldmode
Protected Data.
virtual void endEvent(InDet::ITRT_SeededTrackFinder::IEventData &event_data) const override
End of event tasks.
static bool isNewTrack(Trk::Track *, InDet::TRT_SeededTrackFinder_ATL::EventData &event_data)
Clean-up duplicate tracks.
std::unique_ptr< const Trk::TrackParameters > getTP(MagField::AtlasFieldCache &fieldCache, const Trk::SpacePoint *, const Trk::TrackParameters &, bool &, InDet::TRT_SeededTrackFinder_ATL::EventData &event_data) const
Update track parameters through space point propagation.
std::list< Trk::Track * > cleanTrack(std::list< Trk::Track * >) const
Eliminate spurious Pixel clusters in track.
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
bool solenoidOn() const
status of the magnets
const_iterator lowerPhiBound(float phi, float roi_phi_width) const
virtual bool isValid() override final
Can the handle be successfully dereferenced?
static EventData & getPrivateEventData(InDet::ITRT_SeededTrackFinder::IEventData &virt_event_data)
double chiSquared() const
returns the of the overall track fit
Definition FitQuality.h:56
int parameterKey() const
Identifier key for matrix expansion/reduction.
double get(ParamDefs par) const
Retrieve specified parameter (const version).
magnetic field properties to steer the behavior of the extrapolation
const LocalParameters & localParameters() const
Interface method to get the LocalParameters.
const Amg::MatrixX & localCovariance() const
Interface method to get the localError.
virtual const Surface & associatedSurface() const override=0
Access to the Surface associated to the Parameters.
Class describing the Line to which the Perigee refers to.
Class to handle pseudo-measurements in fitters and on track objects.
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.
const MeasurementBase * measurement(unsigned int) const
returns the Trk::MeasurementBase objects depending on the integer
unsigned int numberOfMeasurementBases() const
Return the number of contained Trk::MeasurementBase (s)
virtual const Amg::Vector3D & globalPosition() const override final
Interface method to get the global Position.
virtual const Surface & associatedSurface() const override final
Interface method to get the associated Surface.
Abstract Base Class for tracking surfaces.
virtual ChargedTrackParametersUniquePtr createUniqueTrackParameters(double l1, double l2, double phi, double theat, double qop, std::optional< AmgSymMatrix(5)> cov=std::nullopt) const =0
Use the Surface as a ParametersBase constructor, from local parameters - charged.
virtual constexpr SurfaceType type() const =0
Returns the Surface type to avoid dynamic casts.
Contains information about the 'fitter' of this track.
Class for a generic track segment that holdes polymorphic Trk::MeasurementBase objects,...
const Surface & associatedSurface() const override final
returns the surface for the local to global transformation
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
const DataVector< const MeasurementBase > * measurementsOnTrack() const
return a pointer to a vector of MeasurementBase (NOT including any that come from outliers).
int r
Definition globals.cxx:22
struct color C
Eigen::Matrix< double, 3, 1 > Vector3D
PropDirection
PropDirection, enum for direction of the propagation.
@ oppositeMomentum
@ alongMomentum
DataVector< const Trk::TrackStateOnSurface > TrackStates
@ FastField
call the fast field access method of the FieldSvc
@ NoField
Field is set to 0., 0., 0.,.
@ FullField
Field is set to be realistic, but within a given Volume.
@ theta
Definition ParamDefs.h:66
@ qOverP
perigee
Definition ParamDefs.h:67
@ loc2
generic first and second local coordinate
Definition ParamDefs.h:35
@ phi
Definition ParamDefs.h:75
@ loc1
Definition ParamDefs.h:34
ParticleHypothesis
Enumeration for Particle hypothesis respecting the interaction with material.
ParametersBase< TrackParametersDim, Charged > TrackParameters