ATLAS Offline Software
Loading...
Searching...
No Matches
SiCombinatorialTrackFinder_xk.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// Implementation file for class InDet::SiCombinatorialTrackFinder_xk
8// (c) ATLAS Detector software
11// Version 1.0 12/04/2007 I.Gavrilenko
13
15
23#include "TrkTrack/TrackInfo.h"
24
25#include <iomanip>
26#include <iostream>
27#include <utility>
28#include <stdexcept>
29
31// Constructor
33
35(const std::string& t, const std::string& n, const IInterface* p)
36 : base_class(t, n, p)
37{
38}
39
41// Initialisation
43
45{
46 // Get RungeKutta propagator tool
47 //
48 if ( m_proptool.retrieve().isFailure() ) {
49 ATH_MSG_FATAL("Failed to retrieve tool " << m_proptool);
50 return StatusCode::FAILURE;
51 }
52 ATH_MSG_DEBUG("Retrieved tool " << m_proptool);
53
54 // Get updator tool
55 //
56 if ( m_updatortool.retrieve().isFailure() ) {
57 ATH_MSG_FATAL("Failed to retrieve tool " << m_updatortool);
58 return StatusCode::FAILURE;
59 }
60 ATH_MSG_DEBUG("Retrieved tool " << m_updatortool);
61
62 // Get RIO_OnTrack creator
63 //
64 if ( m_riocreator.retrieve().isFailure() ) {
65 ATH_MSG_FATAL("Failed to retrieve tool " << m_riocreator);
66 return StatusCode::FAILURE;
67 }
68 ATH_MSG_DEBUG("Retrieved tool " << m_riocreator);
69
70 // disable pixel/SCT conditions summary tool: pixel/SCT are not used, the status event data is used and not being validated
71 ATH_CHECK( m_pixelCondSummaryTool.retrieve( DisableTool{!m_usePIX || (!m_pixelDetElStatus.empty() && !VALIDATE_STATUS_ARRAY_ACTIVATED)} ) );
72 ATH_CHECK( m_sctCondSummaryTool.retrieve( DisableTool{!m_useSCT || (!m_sctDetElStatus.empty() && !VALIDATE_STATUS_ARRAY_ACTIVATED)} ) );
73 //
74 // Get InDetBoundaryCheckTool
75 if ( m_boundaryCheckTool.retrieve().isFailure() ) {
76 ATH_MSG_FATAL("Failed to retrieve tool " << m_boundaryCheckTool);
77 return StatusCode::FAILURE;
78 }
79 ATH_MSG_DEBUG("Retrieved tool " << m_boundaryCheckTool);
80
81
82
83 // Setup callback for magnetic field
84 //
86
87 // Get output print level
88 //
89 m_outputlevel = msg().level()-MSG::DEBUG;
90
91 ATH_CHECK( m_pixcontainerkey.initialize (m_usePIX) );
93
94 ATH_CHECK( m_sctcontainerkey.initialize (m_useSCT) );
95 ATH_CHECK( m_boundarySCTKey.initialize (m_useSCT) );
96
97 // initialize conditions object key for field cache
98 //
99 ATH_CHECK( m_fieldCondObjInputKey.initialize() );
100 ATH_CHECK( m_pixelDetElStatus.initialize( !m_pixelDetElStatus.empty() && m_usePIX) );
101 ATH_CHECK( m_sctDetElStatus.initialize( !m_sctDetElStatus.empty() && m_useSCT) );
102 m_minPt2Cut = std::pow(m_minPtCut.value(),2);
103 return StatusCode::SUCCESS;
104}
105
107// Finalize
109
111{
112 return AlgTool::finalize();
113}
114
116// Dumps relevant information into the MsgStream
118
120{
121 if (not data.isInitialized()) initializeCombinatorialData(Gaudi::Hive::currentContext(), data);
122
123 out<<std::endl;
124 if (data.nprint()) return dumpevent(data, out);
125 return dumpconditions(out);
126}
127
129// Dumps conditions information into the MsgStream
131
133{
134 int n = 62-m_proptool.type().size();
135 std::string s1;
136 for (int i=0; i<n; ++i) s1.append(" ");
137 s1.append("|");
138
139 std::string fieldmode[9] ={"NoField" , "ConstantField", "SolenoidalField",
140 "ToroidalField" , "Grid3DField" , "RealisticField" ,
141 "UndefinedField", "AthenaField" , "?????" };
142
143 int mode = m_fieldprop.magneticFieldMode();
144 if (mode<0 || mode>8 ) mode = 8;
145
146 n = 62-fieldmode[mode].size();
147 std::string s3;
148 for (int i=0; i<n; ++i) s3.append(" ");
149 s3.append("|");
150
151 n = 62-m_updatortool.type().size();
152 std::string s4;
153 for (int i=0; i<n; ++i) s4.append(" ");
154 s4.append("|");
155
156 n = 62-m_riocreator.type().size();
157 std::string s5;
158 for (int i=0; i<n; ++i) s5.append(" ");
159 s5.append("|");
160
161 n = 62-m_pixcontainerkey.key().size();
162 std::string s7;
163 for (int i=0; i<n; ++i) s7.append(" ");
164 s7.append("|");
165
166 n = 62-m_sctcontainerkey.key().size();
167 std::string s8;
168 for (int i=0; i<n; ++i) s8.append(" ");
169 s8.append("|");
170
171 out<<"|----------------------------------------------------------------------"
172 <<"-------------------|"
173 <<std::endl;
174 if (m_usePIX) {
175 out<<"| Pixel clusters location | "<<m_pixcontainerkey.key() <<s7<<std::endl;
176 }
177 if (m_useSCT) {
178 out<<"| SCT clusters location | "<<m_sctcontainerkey.key() <<s8<<std::endl;
179 }
180 out<<"| Tool for propagation | "<<m_proptool .type()<<s1<<std::endl;
181 out<<"| Tool for updator | "<<m_updatortool.type()<<s4<<std::endl;
182 out<<"| Tool for rio on track | "<<m_riocreator .type()<<s5<<std::endl;
183 out<<"| Magnetic field mode | "<<fieldmode[mode] <<s3<<std::endl;
184 out<<"|----------------------------------------------------------------------"
185 <<"-------------------|"
186 <<std::endl;
187 return out;
188}
189
191// Dumps event information into the MsgStream
193
195{
196 out<<"|---------------------------------------------------------------------|"
197 <<std::endl;
198 out<<"| Min pT of track (MeV) | "<<std::setw(12)<<std::setprecision(5)<<data.pTmin()
199 <<" |"<<std::endl;
200 out<<"| Max Xi2 for cluster | "<<std::setw(12)<<std::setprecision(5)<<data.xi2max()
201 <<" |"<<std::endl;
202 out<<"| Max Xi2 for outlayer | "<<std::setw(12)<<std::setprecision(5)<<data.xi2maxNoAdd()
203 <<" |"<<std::endl;
204 out<<"| Max Xi2 for link | "<<std::setw(12)<<std::setprecision(5)<<data.xi2maxlink()
205 <<" |"<<std::endl;
206 out<<"| Min number of clusters | "<<std::setw(12)<<data.nclusmin()
207 <<" |"<<std::endl;
208 out<<"| Min number of wclusters | "<<std::setw(12)<<data.nwclusmin()
209 <<" |"<<std::endl;
210 out<<"| Max number holes | "<<std::setw(12)<<data.nholesmax()
211 <<" |"<<std::endl;
212 out<<"| Max holes gap | "<<std::setw(12)<<data.dholesmax()
213 <<" |"<<std::endl;
214 out<<"| Use PRD to track assoc.?| "<<std::setw(12)<<(data.PRDtoTrackMap() ? "yes" : "no ")
215 <<" |"<<std::endl;
216 out<<"|---------------------------------------------------------------------|"
217 <<std::endl;
218 out<<"| Number input seeds | "<<std::setw(12)<<data.inputseeds()
219 <<" |"<<std::endl;
220 out<<"| Number accepted seeds | "<<std::setw(12)<<data.goodseeds()
221 <<" |"<<std::endl;
222 out<<"| Number initial tracks | "<<std::setw(12)<<data.inittracks()
223 <<" |"<<std::endl;
224 out<<"| Number wrong DE roads | "<<std::setw(12)<<data.roadbug()
225 <<" |"<<std::endl;
226 out<<"| Number output tracks | "<<std::setw(12)<<data.findtracks()
227 <<" |"<<std::endl;
228 out<<"|---------------------------------------------------------------------|"
229 <<std::endl;
230 return out;
231}
232
234// Initiate track finding tool
236
238{
239 if (not data.isInitialized()) initializeCombinatorialData(ctx, data);
240
241 // Erase statistic information
242 //
243 data.inputseeds() = 0;
244 data.goodseeds() = 0;
245 data.inittracks() = 0;
246 data.findtracks() = 0;
247 data.roadbug() = 0;
248
249 // Set track info
250 //
251 data.trackinfo().setPatternRecognitionInfo(Trk::TrackInfo::SiSPSeededFinder);
252 data.setCosmicTrack(0);
253
254 // Add conditions object to SiCombinatorialTrackFinderData to be able to access the field cache for each new event
255 // Get conditions object for field cache
257 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
258 if (fieldCondObj == nullptr) {
259 std::string msg = "InDet::SiCombinatorialTrackFinder_xk::newEvent: Failed to retrieve AtlasFieldCacheCondObj with key " + m_fieldCondObjInputKey.key();
260 throw(std::runtime_error(msg));
261 }
262 data.setFieldCondObj(fieldCondObj);
263}
264
266// Initiate track finding tool
268
270(const EventContext& ctx, SiCombinatorialTrackFinderData_xk& data, Trk::TrackInfo info, const TrackQualityCuts& Cuts) const
271{
272
273 if (not data.isInitialized()) {
274 //Check if to use PRDAssociation before initializing all the tools
275 int useasso;
276 if(!Cuts.getIntCut ("UseAssociationTool" ,useasso )) useasso = 0;
277 data.tools().setAssociation(useasso);
278
280 }
281
282 newEvent(ctx, data);
283 data.trackinfo() = info;
284
288
289 data.setHeavyIon(false);
290 data.setCosmicTrack(0);
292 if (info.patternRecoInfo(Trk::TrackInfo::SiSpacePointsSeedMaker_Cosmic))
293 data.setCosmicTrack(1);
294 else if (info.patternRecoInfo(Trk::TrackInfo::SiSpacePointsSeedMaker_HeavyIon))
295 data.setHeavyIon(true);
296
297}
298
300// Finalize track finding tool for given event
302
304{
305 if (not data.isInitialized()) initializeCombinatorialData(Gaudi::Hive::currentContext(), data);
306
307 // Print event information
308 //
309 if (m_outputlevel<=0) {
310 data.nprint() = 1;
311 dump(data, msg(MSG::DEBUG));
312 }
313}
314
316// Main method for track finding using space points
318
322 const std::vector<const Trk::SpacePoint*>& Sp,
323 const std::vector<Amg::Vector3D>& Gp,
324 std::vector<const InDetDD::SiDetectorElement*>& DE,
325 const TrackQualityCuts& Cuts,
326 const EventContext& ctx) const
327{
328
329 if (not data.isInitialized()) initializeCombinatorialData(ctx, data);
330
331 data.statistic().fill(false);
332
334 data.tools().setBremNoise(false, false);
336 data.tracks().erase(data.tracks().begin(), data.tracks().end());
337
338 ++data.inputseeds();
339 if (!m_usePIX && !m_useSCT) {
340 return data.tracks();
341 }
342
343 // Get track quality cuts information and write them into the event data... again?
345 std::multimap<const Trk::PrepRawData*, const Trk::Track*> PT;
346
348 EStat_t FT = findTrack(data, Tp, Sp, Gp, DE, PT, ctx);
349
351 if(FT!=Success) {
352 data.statistic()[FT] = true;
353 if( ! data.flagToReturnFailedTrack() ) return data.tracks();
354 }
355
357 data.trajectory().sortStep();
358
359
361 if (t) {
362 ++data.findtracks();
363 if (m_writeHolesFromPattern) data.addPatternHoleSearchOutcome(t,data.trajectory().getHoleSearchResult());
364 data.tracks().push_back(t);
365 }
366
367 if (!data.tools().multiTrack() ||
368 data.simpleTrack() ||
369 Sp.size()<=2 ||
370 data.cosmicTrack() ||
371 data.trajectory().pTfirst() < data.tools().pTmin()) return data.tracks();
372
373 while ((t=convertToNextTrack(data))) {
374 ++data.findtracks();
375 if (m_writeHolesFromPattern) data.addPatternHoleSearchOutcome(t,data.trajectory().getHoleSearchResult());
376 data.tracks().push_back(t);
377 }
378 return data.tracks();
379}
380
382// Main method for track finding using space points
384
388 const std::vector<const Trk::SpacePoint*>& Sp,
389 const std::vector<Amg::Vector3D>& Gp,
390 std::vector<const InDetDD::SiDetectorElement*>& DE,
391 std::multimap<const Trk::PrepRawData*, const Trk::Track*>& PT,
392 const EventContext& ctx) const
393{
394
395 if (not data.isInitialized()) initializeCombinatorialData(ctx, data);
396
397 data.tools().setBremNoise(false, false);
398 data.tracks().erase(data.tracks().begin(), data.tracks().end());
399
400 data.statistic().fill(false);
401 ++data.inputseeds();
402 if (!m_usePIX && !m_useSCT) {
403 return data.tracks();
404 }
405
406 EStat_t FT = findTrack(data, Tp, Sp, Gp, DE, PT,ctx);
407 if(FT!=Success) {
408 data.statistic()[FT] = true;
409 if( ! data.flagToReturnFailedTrack() || std::abs(data.resultCode()) < SiCombinatorialTrackFinderData_xk::ResultCodeThreshold::RecoverableForDisTrk ) return data.tracks();
410 }
411 if (!data.trajectory().isNewTrack(PT))
412 {
413 data.statistic()[NotNewTrk] = true;
414 return data.tracks();
415 }
416 data.trajectory().sortStep();
417
418 if(data.useFastTracking()) {
419 if(!data.trajectory().filterWithPreciseClustersError(ctx)) {
420 data.statistic()[CantFindTrk] = true;
421 return data.tracks();
422 }
423 }
424
425 // Trk::Track production
426 //
428 if (t==nullptr) return data.tracks(); // @TODO should one check if convertToNextTrack would yield anything ?
429 if (m_writeHolesFromPattern) data.addPatternHoleSearchOutcome(t,data.trajectory().getHoleSearchResult());
430
431 ++data.findtracks();
432 data.tracks().push_back(t);
433
434 if (!data.tools().multiTrack() ||
435 data.simpleTrack() ||
436 Sp.size()<=2 ||
437 data.cosmicTrack() ||
438 data.trajectory().pTfirst() < data.tools().pTmin()) return data.tracks();
439
440 while ((t=convertToNextTrack(data))) {
441 if (m_writeHolesFromPattern) data.addPatternHoleSearchOutcome(t,data.trajectory().getHoleSearchResult());
442 ++data.findtracks();
443 data.tracks().push_back(t);
444 }
445 return data.tracks();
446}
447
449// Main method for track finding using space points and
450// using electron noise model
452
456 const std::vector<const Trk::SpacePoint*>& Sp,
457 const std::vector<Amg::Vector3D>& Gp,
458 std::vector<const InDetDD::SiDetectorElement*>& DE,
459 std::multimap<const Trk::PrepRawData*, const Trk::Track*>& PT,
460 bool isCaloCompatible,
461 const EventContext& ctx) const
462{
463
464 if (not data.isInitialized()) initializeCombinatorialData(ctx, data);
465
466 data.statistic().fill(false);
467
468 // Old information
469 //
470 int mult = 0;
471 if (data.tools().multiTrack()) mult = 1;
472 double Xi2m = data.tools().xi2multi();
473
474 data.tools().setBremNoise(false, true);
475 data.tracks().erase(data.tracks().begin(), data.tracks().end());
476
477 ++data.inputseeds();
478 if (!m_usePIX && !m_useSCT) {
479 return data.tracks();
480 }
481
482 EStat_t FT = findTrack(data,Tp,Sp,Gp,DE,PT,ctx);
483
484 bool Q = (FT==Success);
485 if (Q){
486 Q = data.trajectory().isNewTrack(PT);
487 }
488
489 int na = 0;
490 if (Q) {
491 data.trajectory().sortStep();
492
493 // Trk::Track production
494 //
495 Trk::TrackInfo oldinfo = data.trackinfo();
496 if (isCaloCompatible) data.trackinfo().setPatternRecognitionInfo(Trk::TrackInfo::TrackInCaloROI);
497
498 data.tools().setMultiTracks(0, Xi2m);
500 data.trackinfo() = oldinfo;
501 data.tools().setMultiTracks(mult,Xi2m);
502
503 if (t==nullptr) return data.tracks(); // @TODO should one check whether the next findTrack call would yield something ?
504 if (m_writeHolesFromPattern) data.addPatternHoleSearchOutcome(t,data.trajectory().getHoleSearchResult());
505 ++data.findtracks();
506 data.tracks().push_back(t);
507 na = data.trajectory().nclusters();
508 if (na >=12 && !data.trajectory().nclustersNoAdd()) return data.tracks();
509
510 if (data.trajectory().pTfirst() < data.pTminBrem()) return data.tracks();
511 }
512 if ((*Sp.begin())->clusterList().second) return data.tracks();
513
514 // Repeat track finding using electron noise model
515 //
516 data.statistic()[BremAttempt] = true;
517
518 data.tools().setBremNoise(true,true);
519 FT = findTrack(data, Tp, Sp, Gp, DE, PT,ctx);
520
521 if (FT!=Success) {
522 data.statistic()[FT] = true;
523 return data.tracks();
524 }
525
526 if (!data.trajectory().isNewTrack(PT)) { data.statistic()[NotNewTrk] = true; return data.tracks(); }
527
528 int nb = data.trajectory().nclusters();
529 if (nb <= na) return data.tracks();
530
531 data.trajectory().sortStep();
532
533 if(data.useFastTracking()) {
534 if(!data.trajectory().filterWithPreciseClustersError(ctx)) {
535 data.statistic()[CantFindTrk] = true;
536 return data.tracks();
537 }
538 }
539
540 // Trk::Track production
541 //
542 Trk::TrackInfo oldinfo = data.trackinfo();
543 data.trackinfo().setTrackProperties(Trk::TrackInfo::BremFit );
544 data.trackinfo().setTrackProperties(Trk::TrackInfo::BremFitSuccessful);
545 if (isCaloCompatible) data.trackinfo().setPatternRecognitionInfo(Trk::TrackInfo::TrackInCaloROI);
546
547 data.tools().setMultiTracks(0, Xi2m);
548 Trk::Track* t = convertToTrack(data, ctx);
549 data.trackinfo() = oldinfo;
550 data.tools().setMultiTracks(mult, Xi2m);
551
552 if (t==nullptr) return data.tracks();
553 if (m_writeHolesFromPattern) data.addPatternHoleSearchOutcome(t,data.trajectory().getHoleSearchResult());
554
555 ++data.findtracks();
556 data.tracks().push_back(t);
557 return data.tracks();
558}
559
561// Initial pT of 3 space points seed estimation
563
567 const std::vector<const Trk::SpacePoint*>& Sp,
568 const EventContext& ctx) const
569{
570 std::vector<const InDet::SiCluster*> Cl;
571 std::vector<const InDetDD::SiDetectorElement*> DE;
572 if(!spacePointsToClusters(Sp,Cl,DE)) return 0.;
573
574 std::vector<const InDet::SiDetElementBoundaryLink_xk*> DEL;
575 detectorElementLinks(DE,DEL,ctx);
576 return data.trajectory().pTseed(Tp,Cl,DEL,ctx);
577}
578
580// Main method for track finding using space points
582
586 const std::vector<const Trk::SpacePoint*>& Sp,
587 const std::vector<Amg::Vector3D>& Gp,
588 std::vector<const InDetDD::SiDetectorElement*>& DE,
589 std::multimap<const Trk::PrepRawData*,const Trk::Track*>& PT,
590 const EventContext& ctx) const
591{
593 if (not data.isInitialized()) initializeCombinatorialData(ctx, data);
594
596 std::vector<const InDet::SiDetElementBoundaryLink_xk*> DEL;
597 detectorElementLinks(DE, DEL,ctx);
598
600 const InDet::PixelClusterContainer* p_pixcontainer = data.pixContainer();
601 if (m_usePIX && !p_pixcontainer) {
603 if(!pixcontainer.isValid()){
604 //the pixel container is not valid
605 //we are supposed to use pixel so stop here
606 REPORT_ERROR (StatusCode::FAILURE)<< "Unable to dereference pix container, handle not valid";
607 return WrongInit;
608 }
609
610 p_pixcontainer = pixcontainer.ptr();
611 data.setPixContainer(p_pixcontainer);
612 }
613 const InDet::SCT_ClusterContainer* p_sctcontainer = data.sctContainer();
614 if (m_useSCT && !p_sctcontainer) {
616
617 if(!sctcontainer.isValid()){
618 //the sct container is not valid
619 //we are supposed to use sct so stop here
620 REPORT_ERROR (StatusCode::FAILURE)<< "Unable to dereference sct container, handle not valid";
621 return WrongInit;
622 }
623
624 p_sctcontainer = sctcontainer.ptr();
625 data.setSctContainer(p_sctcontainer);
626 }
627
629 std::vector<const InDet::SiCluster*> Cl;
630 bool isTwoPointSeed = false;
631
635 if (Sp.size() > 1) {
636
638 if (!spacePointsToClusters(Sp,Cl)) {
639 return TwoCluster;
640 }
641 if (Sp.size()==2) isTwoPointSeed = true;
642 }
644 else if (Gp.size() > 2) {
645 if (!data.trajectory().globalPositionsToClusters(p_pixcontainer, p_sctcontainer, Gp, DEL, PT, Cl)) return TwoCluster;
646 } else {
648 if (!data.trajectory().trackParametersToClusters(p_pixcontainer, p_sctcontainer, Tp, DEL, PT, Cl, ctx)) return TwoCluster;
649 }
650 ++data.goodseeds();
651
653 bool Qr;
655 bool Q = data.trajectory().initialize(m_usePIX, m_useSCT, p_pixcontainer, p_sctcontainer, Tp, Cl, DEL, Qr,ctx);
656
659 if (!Q && Sp.size() < 2 && Gp.size() > 3) {
661 Cl.clear();
663 if (!data.trajectory().trackParametersToClusters(p_pixcontainer, p_sctcontainer, Tp, DEL, PT, Cl,ctx)) return TwoCluster;
664
665 if (!data.trajectory().initialize(m_usePIX, m_useSCT, p_pixcontainer, p_sctcontainer, Tp, Cl, DEL, Qr,ctx)) return TwoCluster;
667
668 Q = Qr = true;
669 }
670
672 if (!Qr){
673 ++data.roadbug();
674 return WrongRoad;
675 }
677 if (!Q) return WrongInit;
678
679 ++data.inittracks();
681 bool pixseed = data.trajectory().isLastPixel();
683 int itmax = 30;
684 if (!data.useFastTracking() and data.simpleTrack()) itmax = 10;
685 if (data.heavyIon()) itmax = 50;
686
687 //
688 bool toReturnFailedTrack = data.flagToReturnFailedTrack();
689 if( toReturnFailedTrack ) data.setResultCode(SiCombinatorialTrackFinderData_xk::ResultCode::Unrecoverable);
690
692 if (pixseed) {
693 if (!data.trajectory().forwardExtension (false,itmax,ctx)) return CantFindTrk;
694 if (!data.trajectory().backwardSmoother (false,ctx) ) return CantFindTrk;
695 if (!data.trajectory().backwardExtension(itmax,ctx) ) return CantFindTrk;
696 if (data.isITkGeometry() &&
697 (data.trajectory().nclusters() < data.nclusmin() ||
698 data.trajectory().ndf() < data.nwclusmin()) ) return CantFindTrk;
699
701 if(!data.useFastTracking() && data.trajectory().difference() > 0){
702 if (!data.trajectory().forwardFilter(ctx)) {
703 if( toReturnFailedTrack ) {
705 }
706 else {
707 return CantFindTrk;
708 }
709 }
710
711 if (!data.trajectory().backwardSmoother (false,ctx) ) {
712 if( toReturnFailedTrack ) {
714 }
715 else {
716 return CantFindTrk;
717 }
718 }
719 }
720
721 int na = data.trajectory().nclustersNoAdd();
723 if (data.trajectory().nclusters()+na < data.nclusmin() ||
724 data.trajectory().ndf() < data.nwclusmin()) {
725 if( toReturnFailedTrack ) {
727 }
728 else {
729 return CantFindTrk;
730 }
731 }
732 }
733
735 else { // Strategy for mixed seeds
736 if (!data.trajectory().backwardSmoother(isTwoPointSeed,ctx) ) return CantFindTrk;
737 if (!data.trajectory().backwardExtension(itmax,ctx) ) return CantFindTrk;
738 if (!data.trajectory().forwardExtension(true,itmax,ctx)) return CantFindTrk;
739
741 int na = data.trajectory().nclustersNoAdd();
742 if (data.trajectory().nclusters()+na < data.nclusmin() ||
743 data.trajectory().ndf() < data.nwclusmin()) return CantFindTrk;
745 if (!data.trajectory().backwardSmoother(false,ctx) ) return CantFindTrk;
746
748 na = data.trajectory().nclustersNoAdd();
749 if (data.trajectory().nclusters()+na < data.nclusmin() ||
750 data.trajectory().ndf() < data.nwclusmin()) {
751 if( toReturnFailedTrack ) {
753 }
754 else {
755 return CantFindTrk;
756 }
757 }
758
760 if (data.trajectory().difference() > 0) {
761 if (!data.trajectory().forwardFilter(ctx)) {
762 if( toReturnFailedTrack ) {
764 }
765 else {
766 return CantFindTrk;
767 }
768 }
769 if (!data.trajectory().backwardSmoother (false, ctx)) {
770 if( toReturnFailedTrack ) {
772 }
773 else {
774 return CantFindTrk;
775 }
776 }
777 }
778 }
779
781 if (data.trajectory().qualityOptimization() < (m_qualityCut*data.nclusmin())) {
782 if( toReturnFailedTrack ) {
784 }
785 else {
786 return CantFindTrk;
787 }
788 }
789
790 if (data.trajectory().pTfirst () < data.pTmin () &&
791 data.trajectory().nclusters() < data.nclusmin()) {
792 if( toReturnFailedTrack ) {
794 }
795 else {
796 return CantFindTrk;
797 }
798 }
799
800 if (data.trajectory().nclusters() < data.nclusminb() ||
801 data.trajectory().ndf () < data.nwclusmin()) {
802 if( toReturnFailedTrack ) {
804 }
805 else {
806 return CantFindTrk;
807 }
808 }
809
812 data.trajectory().updateHoleSearchResult();
813 if (!data.trajectory().getHoleSearchResult().passPatternHoleCut) {
814 if( toReturnFailedTrack ) {
816 }
817 else {
818 return CantFindTrk;
819 }
820 }
821 }
822
823 if( toReturnFailedTrack ) {
825 return CantFindTrk;
826 }
827 else {
829 }
830 }
831
832 return Success;
833}
834
836// Trk::Track production
838
840{
841 const Trk::PatternTrackParameters *param = data.trajectory().firstParameters();
842 if (param) {
843 double pt = param->transverseMomentum();
844 // reject tracks with small pT
845 // The cut should be large enough otherwise eta computation of such tracks may yield NANs.
846 if (pt < m_minPtCut.value()) {
847 ATH_MSG_DEBUG( "Reject low pT track (pT = " << pt << " < " << m_minPtCut.value() << ")");
848 return nullptr;
849 }
850 }
851 if (!data.simpleTrack()) {
852 return new Trk::Track(
853 data.trackinfo(),
854 std::make_unique<Trk::TrackStates>(
855 data.trajectory().convertToTrackStateOnSurface(
856 data.cosmicTrack())),
857 data.trajectory().convertToFitQuality());
858 }
859
860 Trk::TrackInfo info = data.trackinfo();
861 info.setPatternRecognitionInfo(Trk::TrackInfo::SiSPSeededFinderSimple);
862 info.setParticleHypothesis(Trk::pion);
863 if (!data.flagToReturnFailedTrack()) {
864 return new Trk::Track(
865 info,
866 std::make_unique<Trk::TrackStates>(
867 data.trajectory().convertToSimpleTrackStateOnSurface(
868 data.cosmicTrack(), ctx)),
869 data.trajectory().convertToFitQuality());
870 } else {
871 return new Trk::Track(
872 info,
873 std::make_unique<Trk::TrackStates>(
874 data.trajectory()
875 .convertToSimpleTrackStateOnSurfaceForDisTrackTrigger(
876 data.cosmicTrack(), ctx)),
877 data.trajectory().convertToFitQuality());
878 }
879}
880
882// Next Trk::Track production
884
886{
887 auto tsos = std::make_unique<Trk::TrackStates>(
888 data.trajectory().convertToNextTrackStateOnSurface());
889 if (tsos->empty()){
890 return nullptr;
891 }
892
893 // verify first track parameters
894 const Trk::TrackParameters *param = nullptr;
895 for (const Trk::TrackStateOnSurface *a_tsos : *tsos) {
896 const Trk::TrackParameters *param = a_tsos->trackParameters();
897 if (param) {
898 break;
899 }
900 }
901
902 if (param) {
903 auto momentum = param->momentum();
904 const auto pt2 = momentum.perp2();
905 // reject tracks with small pT
906 // The cut should be large enough otherwise eta computation of such tracks may yield NANs.
907 if (pt2 < m_minPt2Cut) {
908 ATH_MSG_WARNING( "Reject low pT track (pT = " << sqrt(pt2) << " < " << m_minPtCut.value() << ")");
909 return nullptr;
910 }
911 }
912 return new Trk::Track(data.trackinfo(),
913 std::move(tsos),
914 data.trajectory().convertToFitQuality());
915}
916
918// Callback function - get the magnetic field /
920
929
931// Convert space points to clusters and (for Run 4) detector elements
933
935(const std::vector<const Trk::SpacePoint*>& Sp, std::vector<const InDet::SiCluster*>& Sc, std::optional<std::reference_wrapper<std::vector<const InDetDD::SiDetectorElement*>>> DE)
936{
937 Sc.reserve(Sp.size());
939 for (const Trk::SpacePoint* s : Sp) {
941 const Trk::PrepRawData* p = s->clusterList().first;
942 if (p) {
944 const InDet::SiCluster* c = static_cast<const InDet::SiCluster*>(p);
945 if (c){
946 Sc.push_back(c);
947 }
948 }
950 p = s->clusterList().second;
951 if (p) {
952 const InDet::SiCluster* c = static_cast<const InDet::SiCluster*>(p);
953 if (c){
954 Sc.push_back(c);
955 }
956 }
957 }
958
960 std::vector<const InDet::SiCluster*>::iterator cluster = Sc.begin(), nextCluster, endClusters = Sc.end();
961
964 if (DE) {
965 DE->get().reserve(Sc.size());
966 }
967 for (; cluster != endClusters; ++cluster) {
968
969 const InDetDD::SiDetectorElement* de = (*cluster)->detectorElement();
970
971 nextCluster = cluster;
972 ++nextCluster;
973 for (; nextCluster != endClusters; ++nextCluster) {
974 if (de == (*nextCluster)->detectorElement()){
975 return false;
976 }
977 }
978 if (DE) {
979 DE->get().push_back(de);
980 }
981 }
982 return true;
983}
984
986// Convert detector elements to detector element links
988
990(std::vector<const InDetDD::SiDetectorElement*> & DE,
991 std::vector<const InDet::SiDetElementBoundaryLink_xk*>& DEL,
992 const EventContext& ctx) const
993{
994 const InDet::SiDetElementBoundaryLinks_xk* boundaryPixel{nullptr};
995 const InDet::SiDetElementBoundaryLinks_xk* boundarySCT{nullptr};
996 if (m_usePIX) {
998 boundaryPixel = *boundaryPixelHandle;
999 if (boundaryPixel==nullptr) {
1000 ATH_MSG_FATAL(m_boundaryPixelKey.fullKey() << " returns null pointer");
1001 }
1002 }
1003 if (m_useSCT) {
1005 boundarySCT = *boundarySCTHandle;
1006 if (boundarySCT==nullptr) {
1007 ATH_MSG_FATAL(m_boundarySCTKey.fullKey() << " returns null pointer");
1008 }
1009 }
1010
1011 DEL.reserve(DE.size());
1012 for (const InDetDD::SiDetectorElement* d: DE) {
1013 IdentifierHash id = d->identifyHash();
1014 if (d->isPixel() && boundaryPixel && id < boundaryPixel->size()) DEL.push_back(&(*boundaryPixel)[id]);
1015 else if (d->isSCT() && boundarySCT && id < boundarySCT->size()) DEL.push_back(&(*boundarySCT)[id]);
1016 }
1017}
1018
1020// Get track quality cuts
1022
1025{
1026 // Integer cuts
1027 //
1028 int intCut = 0;
1029
1030 if (!Cuts.getIntCut("CosmicTrack" , intCut)) intCut = 0;
1031 data.setCosmicTrack(intCut);
1032
1033 if (!Cuts.getIntCut("MinNumberOfClusters" , intCut)) intCut = 7;
1034 data.setNclusmin(intCut);
1035
1036 data.setNclusminb(std::max(3, data.nclusmin()-1));
1037
1038 if (!Cuts.getIntCut("MinNumberOfWClusters", intCut)) intCut = 7;
1039 data.setNwclusmin(intCut);
1040
1041 if (!Cuts.getIntCut("MaxNumberOfHoles" , intCut)) intCut = 2;
1042 if(!data.cosmicTrack() && intCut>2) intCut = 2;
1043 data.setNholesmax(intCut);
1044
1045 if (!Cuts.getIntCut("MaxHolesGap" , intCut)) intCut = 2;
1046 if(!data.cosmicTrack() && intCut>2) intCut = 2;
1047 if(intCut > data.nholesmax()) intCut = data.nholesmax();
1048 data.setDholesmax(intCut);
1049
1050 data.tools().setHolesClusters(data.nholesmax(), data.dholesmax(),
1051 data.nclusmin());
1052
1053 if (!Cuts.getIntCut("UseAssociationTool" , intCut)) intCut = 0;
1054 data.tools().setAssociation(intCut);
1055
1056 if (!Cuts.getIntCut("SimpleTrack" , intCut)) intCut = 0;
1057 data.setSimpleTrack(bool(intCut));
1058
1059 // Double cuts
1060 //
1061 double doubleCut = 0.;
1062
1063 if (!Cuts.getDoubleCut("pTmin" , doubleCut)) doubleCut = 500.;
1064 data.setPTmin(doubleCut);
1065
1066 if (!Cuts.getDoubleCut("pTminBrem" , doubleCut)) doubleCut = 1000.;
1067 data.setPTminBrem(doubleCut);
1068
1069 if (!Cuts.getDoubleCut("MaxXi2forCluster" , doubleCut)) doubleCut = 9.;
1070 data.setXi2max(doubleCut);
1071
1072 if (!Cuts.getDoubleCut("MaxXi2forOutlier" , doubleCut)) doubleCut = 25.;
1073 if (!data.cosmicTrack() && doubleCut > 25.) doubleCut = 25.;
1074 if (doubleCut <= data.xi2max()) doubleCut = data.xi2max()+5.;
1075 data.setXi2maxNoAdd(doubleCut);
1076
1077 if (!Cuts.getDoubleCut("MaxXi2forSearch" , doubleCut)) doubleCut = 100.;
1078 data.setXi2maxlink(doubleCut);
1079
1080 data.tools().setXi2pTmin(data.xi2max(), data.xi2maxNoAdd(),
1081 data.xi2maxlink(), data.pTmin());
1082
1083 if (!Cuts.getIntCut ("doMultiTracksProd", intCut)) intCut = 0;
1084 if (!Cuts.getDoubleCut("MaxXi2MultiTracks", doubleCut)) doubleCut = 7.;
1085 if (!data.cosmicTrack() && doubleCut > 7.) doubleCut = 7.;
1086 data.tools().setMultiTracks(intCut, doubleCut);
1087
1088 data.trajectory().setParameters();
1089}
1090
1092
1096 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
1097 if (fieldCondObj == nullptr) {
1098 std::string msg = "InDet::SiCombinatorialTrackFinder_xk::initializeCombinatorialData: Failed to retrieve AtlasFieldCacheCondObj with key " + m_fieldCondObjInputKey.key();
1099 throw(std::runtime_error(msg));
1100 }
1101 data.setFieldCondObj(fieldCondObj);
1102
1104 data.setTools(&*m_proptool,
1105 &*m_updatortool,
1106 &*m_riocreator,
1109 &m_fieldprop,
1111 if (!m_pixelDetElStatus.empty()) {
1113 data.setPixelDetectorElementStatus( pixelDetElStatus.cptr() );
1114 }
1115 if (!m_sctDetElStatus.empty()) {
1117 data.setSCTDetectorElementStatus( sctDetElStatus.cptr() );
1118 }
1119
1120 // Set the ITk Geometry setup
1121 data.setITkGeometry(m_ITkGeometry);
1122 // Set the ITk Fast Tracking setup
1123 data.setFastTracking(m_doFastTracking);
1124}
1125
1127{
1128 for(int i=0; i!=NumberOfStats; ++i) information[i] = data.statistic()[i];
1129}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define REPORT_ERROR(SC)
Report an error.
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
static Double_t Tp(Double_t *t, Double_t *par)
#define VALIDATE_STATUS_ARRAY_ACTIVATED
Handle class for reading from StoreGate.
This is a "hash" representation of an Identifier.
Class to hold geometrical description of a silicon detector element.
InDet::SiCombinatorialTrackFinderData_xk holds event dependent data used by SiCombinatorialTrackFinde...
PublicToolHandle< Trk::IPatternParametersPropagator > m_proptool
Trk::Track * convertToNextTrack(SiCombinatorialTrackFinderData_xk &data) const
ToolHandle< Trk::IBoundaryCheckTool > m_boundaryCheckTool
SG::ReadHandleKey< InDet::SCT_ClusterContainer > m_sctcontainerkey
static MsgStream & dumpevent(SiCombinatorialTrackFinderData_xk &data, MsgStream &out)
PublicToolHandle< Trk::IPatternParametersUpdator > m_updatortool
static void getTrackQualityCuts(SiCombinatorialTrackFinderData_xk &data, const TrackQualityCuts &)
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCondObjInputKey
ToolHandle< IInDetConditionsTool > m_pixelCondSummaryTool
Trk::Track * convertToTrack(SiCombinatorialTrackFinderData_xk &data, const EventContext &ctx) const
MsgStream & dump(SiCombinatorialTrackFinderData_xk &data, MsgStream &out) const override
EStat_t findTrack(SiCombinatorialTrackFinderData_xk &data, const Trk::TrackParameters &, const std::vector< const Trk::SpacePoint * > &, const std::vector< Amg::Vector3D > &, std::vector< const InDetDD::SiDetectorElement * > &, std::multimap< const Trk::PrepRawData *, const Trk::Track * > &, const EventContext &) const
virtual void endEvent(SiCombinatorialTrackFinderData_xk &data) const override
virtual const std::list< Trk::Track * > & getTracks(SiCombinatorialTrackFinderData_xk &data, const Trk::TrackParameters &, const std::vector< const Trk::SpacePoint * > &, const std::vector< Amg::Vector3D > &, std::vector< const InDetDD::SiDetectorElement * > &, const TrackQualityCuts &, const EventContext &ctx) const override
SG::ReadHandleKey< InDet::SiDetectorElementStatus > m_sctDetElStatus
Optional read handle to get status data to test whether a SCT detector element is good.
SG::ReadHandleKey< InDet::SiDetectorElementStatus > m_pixelDetElStatus
Optional read handle to get status data to test whether a pixel detector element is good.
Trk::MagneticFieldProperties m_fieldprop
Magnetic field properties.
SG::ReadCondHandleKey< InDet::SiDetElementBoundaryLinks_xk > m_boundaryPixelKey
SG::ReadHandleKey< InDet::PixelClusterContainer > m_pixcontainerkey
void initializeCombinatorialData(const EventContext &ctx, SiCombinatorialTrackFinderData_xk &data) const
static bool spacePointsToClusters(const std::vector< const Trk::SpacePoint * > &, std::vector< const InDet::SiCluster * > &, std::optional< std::reference_wrapper< std::vector< const InDetDD::SiDetectorElement * > > >=std::nullopt)
SiCombinatorialTrackFinder_xk(const std::string &, const std::string &, const IInterface *)
SG::ReadCondHandleKey< InDet::SiDetElementBoundaryLinks_xk > m_boundarySCTKey
PublicToolHandle< Trk::IRIO_OnTrackCreator > m_riocreator
virtual void newEvent(const EventContext &ctx, SiCombinatorialTrackFinderData_xk &data) const override
ToolHandle< IInDetConditionsTool > m_sctCondSummaryTool
virtual const std::list< Trk::Track * > & getTracksWithBrem(SiCombinatorialTrackFinderData_xk &data, const Trk::TrackParameters &, const std::vector< const Trk::SpacePoint * > &, const std::vector< Amg::Vector3D > &, std::vector< const InDetDD::SiDetectorElement * > &, std::multimap< const Trk::PrepRawData *, const Trk::Track * > &, bool, const EventContext &ctx) const override
EStat_t
Array entries for data.statistic counter.
void detectorElementLinks(std::vector< const InDetDD::SiDetectorElement * > &, std::vector< const InDet::SiDetElementBoundaryLink_xk * > &, const EventContext &ctx) const
virtual double pTseed(SiCombinatorialTrackFinderData_xk &data, const Trk::TrackParameters &, const std::vector< const Trk::SpacePoint * > &, const EventContext &) const override
virtual void fillStatistic(SiCombinatorialTrackFinderData_xk &data, std::array< bool, NumberOfStats > &information) const override
bool getIntCut(const std::string &, int &) const
bool getDoubleCut(const std::string &, double &) const
const_pointer_type ptr()
Dereference the pointer.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
magnetic field properties to steer the behavior of the extrapolation
const Amg::Vector3D & momentum() const
Access method for the momentum.
double transverseMomentum() const
Contains information about the 'fitter' of this track.
@ BremFit
A brem fit was performed on this track.
@ BremFitSuccessful
A brem fit was performed on this track and this fit was successful.
@ SiSpacePointsSeedMaker_Cosmic
Entries allowing to distinguish different seed makers.
@ SiSPSeededFinder
Tracks from SiSPSeedFinder.
@ SiSPSeededFinderSimple
for tracks processed by the trigger version of the SiSPSeededFinder
represents the track state (measurement, material, fit parameters and quality) at a surface.
@ 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.
ParametersBase< TrackParametersDim, Charged > TrackParameters
-event-from-file
MsgStream & msg
Definition testRead.cxx:32