ATLAS Offline Software
Loading...
Searching...
No Matches
SiSpacePointsSeedMaker_ATLxk.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5
7// Implementation file for class SiSpacePointsSeedMaker_ATLxk
9// AlgTool used for TRT_DriftCircleOnTrack object production
11// Version 1.0 21/04/2004 I.Gavrilenko
13
15
18
19#include "TrkTrack/Track.h"
21
25#include <iomanip>
26#include <ostream>
27
31
33(const std::string& t,const std::string& n,const IInterface* p)
34 : base_class(t, n, p),
35 m_thistSvc("THistSvc", n),
36 m_outputTree(nullptr),
37 m_treeName(""),
38 m_treeFolder("/valNtuples/")
39{
40}
41
45
47{
48 StatusCode sc = AlgTool::initialize();
49
51 ATH_CHECK(m_spacepointsSCT.initialize(m_sct));
53
55 if (not m_beamSpotKey.empty()) {
56 ATH_CHECK(m_beamSpotKey.initialize());
57 }
58
59 ATH_CHECK( m_fieldCondObjInputKey.initialize() );
60
62 ATH_CHECK( m_prdToTrackMap.initialize( !m_prdToTrackMap.key().empty()));
63
67
68 if (msgLvl(MSG::DEBUG)) {
71 data.nprint=0;
72 dump(data, msg(MSG::DEBUG));
73 }
74
75 if (m_writeNtuple) {
76
77 ATH_CHECK( m_thistSvc.retrieve() );
78
79 m_treeName = (std::string("SeedTree_")+name());
80 std::replace( m_treeName.begin(), m_treeName.end(), '.', '_' );
81
82 m_outputTree = new TTree( m_treeName.c_str() , "SeedMakerValTool");
83
84 m_outputTree->Branch("eventNumber", &m_eventNumber);
85 m_outputTree->Branch("d0", &m_d0);
86 m_outputTree->Branch("z0", &m_z0);
87 m_outputTree->Branch("pt", &m_pt);
88 m_outputTree->Branch("eta", &m_eta);
89 m_outputTree->Branch("x1", &m_x1);
90 m_outputTree->Branch("x2", &m_x2);
91 m_outputTree->Branch("x3", &m_x3);
92 m_outputTree->Branch("y1", &m_y1);
93 m_outputTree->Branch("y2", &m_y2);
94 m_outputTree->Branch("y3", &m_y3);
95 m_outputTree->Branch("z1", &m_z1);
96 m_outputTree->Branch("z2", &m_z2);
97 m_outputTree->Branch("z3", &m_z3);
98 m_outputTree->Branch("r1", &m_r1);
99 m_outputTree->Branch("r2", &m_r2);
100 m_outputTree->Branch("r3", &m_r3);
101 m_outputTree->Branch("quality", &m_quality);
102 m_outputTree->Branch("seedType", &m_type);
103 m_outputTree->Branch("givesTrack", &m_givesTrack);
104 m_outputTree->Branch("dzdr_b", &m_dzdr_b);
105 m_outputTree->Branch("dzdr_t", &m_dzdr_t);
106 m_outputTree->Branch("track_pt", &m_trackPt);
107 m_outputTree->Branch("track_eta", &m_trackEta);
108
109 TString fullTreeName = m_treeFolder + m_treeName;
110
111 ATH_CHECK( m_thistSvc->regTree( fullTreeName.Data(), m_outputTree ) );
112
113 }
114
115 return sc;
116}
117
121
123{
124 return AlgTool::finalize();
125}
126
130
131void InDet::SiSpacePointsSeedMaker_ATLxk::newEvent(const EventContext& ctx, EventData& data, int iteration) const
132{
134 if (not data.initialized) initializeEventData(data);
135
136 data.trigger = false;
137 if (!m_pixel && !m_sct) return;
138
140 data.iteration = iteration;
141 if (iteration <=0) data.iteration = 0;
143 erase(data);
144 data.dzdrmin = m_dzdrmin0;
145 data.dzdrmax = m_dzdrmax0;
146 data.maxScore = m_maxScore;
147
149 if (data.iteration == 0) {
150 if (not m_beamSpotKey.empty()) {
152 }
153
155 double magField[3]{0,0,0};
156 double globalPos[3] ={10.,10.,0.};
157
158 MagField::AtlasFieldCache fieldCache;
161 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
162 if (fieldCondObj == nullptr) {
163 ATH_MSG_ERROR("SiSpacePointsSeedMaker_ATLxk: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
164 return;
165 }
166 fieldCondObj->getInitializedCache (fieldCache);
167
168 if (fieldCache.solenoidOn()) {
170 fieldCache.getFieldZR(globalPos,magField);
181 data.K = 2.f/(300.f*float(magField[2]));
182 } else {
183 data.K = 2.f/(300.f* 5.f );
184 }
189 data.ipt2K = m_ipt2/(data.K*data.K);
191 data.ipt2C = m_ipt2*m_COF;
192 data.COFK = m_COF*(data.K*data.K);
193
195 data.i_spforseed = data.l_spforseed.begin();
196 // Set the seed multiplicity strategy of the event data to the one configured
197 // by the user for strip seeds
198 data.maxSeedsPerSP = m_maxOneSizeSSS;
199 data.keepAllConfirmedSeeds = m_alwaysKeepConfirmedStripSeeds;
200
201 }
202 else {
203 data.r_first = 0;
204 // Set the seed multiplicity strategy of the event data to the one configured
205 // by the user for pixel seeds
206 data.maxSeedsPerSP = m_maxOneSizePPP;
207 data.keepAllConfirmedSeeds = m_alwaysKeepConfirmedPixelSeeds;
208
211 return;
212 }
213
215
216 data.checketa = data.dzdrmin > 1.;
217
219 float oneOverBinSizeR = 1.f/m_binSizeR;
220 int maxBinR = m_nBinsR-1;
221
228 for (int i=0; i<data.nr; ++i) {
229 int n = data.r_index[i];
230 data.r_map[n] = 0;
231 data.r_Sorted[n].clear();
232 }
233 data.ns = data.nr = 0;
234
236 SG::ReadHandle<Trk::PRDtoTrackMap> prd_to_track_map;
237 const Trk::PRDtoTrackMap *prd_to_track_map_cptr = nullptr;
238 if (!m_prdToTrackMap.key().empty()) {
240 if (!prd_to_track_map.isValid()) {
241 ATH_MSG_ERROR("Failed to read PRD to track association map: " << m_prdToTrackMap.key());
242 }
243 prd_to_track_map_cptr = prd_to_track_map.cptr();
244 }
245
249
251 data.r_first = 0;
252
254 if (m_pixel) {
255
257 if (spacepointsPixel.isValid()) {
259 for (const SpacePointCollection* spc: *spacepointsPixel) {
260 for (const Trk::SpacePoint* sp: *spc) {
261
264 if ((prd_to_track_map_cptr && isUsed(sp,*prd_to_track_map_cptr)) || sp->r() > m_r_rmax) continue;
265
269 static_cast<const InDetDD::SiDetectorElement*>(sp->clusterList().first->detectorElement());
270 if (!de || de->isDBM()) continue;
271
278 if (!sps) continue;
279
282 int radiusBin = static_cast<int>(sps->radius()*oneOverBinSizeR);
284 if (radiusBin>maxBinR) radiusBin = maxBinR;
285
287 data.r_Sorted[radiusBin].push_back(sps);
289 ++data.r_map[radiusBin];
292 if (data.r_map[radiusBin]==1) data.r_index[data.nr++] = radiusBin;
294 if (radiusBin > data.r_first) data.r_first = radiusBin;
296 ++data.ns;
297 }
298 }
299 }
300 ++data.r_first;
301 }
302
304 if (m_sct) {
305
307 if (spacepointsSCT.isValid()) {
308
309 for (const SpacePointCollection* spc: *spacepointsSCT) {
310 for (const Trk::SpacePoint* sp: *spc) {
313 if ((prd_to_track_map_cptr && isUsed(sp,*prd_to_track_map_cptr)) || sp->r() > m_r_rmax) continue;
314
317 if (!sps) continue;
318
321 int radiusBin = static_cast<int>(sps->radius()*oneOverBinSizeR);
322 if (radiusBin>maxBinR) radiusBin = maxBinR;
324 data.r_Sorted[radiusBin].push_back(sps);
326 ++data.r_map[radiusBin];
328 if (data.r_map[radiusBin]==1) data.r_index[data.nr++] = radiusBin;
330 ++data.ns;
331 }
332 }
333 }
334
336 if (m_useOverlap && !data.checketa) {
337
339 if (spacepointsOverlap.isValid()) {
340
341 for (const Trk::SpacePoint* sp: *spacepointsOverlap) {
343 if ((prd_to_track_map_cptr && isUsed(sp, *prd_to_track_map_cptr)) || sp->r() > m_r_rmax) continue;
344
347 if (!sps) continue;
348
350 int radiusBin = static_cast<int>(sps->radius()*oneOverBinSizeR);
351 if (radiusBin>maxBinR) radiusBin = maxBinR;
353 data.r_Sorted[radiusBin].push_back(sps);
355 ++data.r_map[radiusBin];
357 if (data.r_map[radiusBin]==1) data.r_index[data.nr++] = radiusBin;
359 ++data.ns;
360 }
361 }
362 }
363 }
364
366 if (iteration < 0) data.r_first = 0;
367
371}
372
376
379(const EventContext& ctx, EventData& data,
380 const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT) const
381{
382 if (not data.initialized) initializeEventData(data);
383
384 data.iteration = 0;
385 data.trigger = false;
386 erase(data);
387 if (!m_pixel && !m_sct) return;
388
389 data.dzdrmin = m_dzdrmin0;
390 data.dzdrmax = m_dzdrmax0;
391 data.maxScore = m_maxScore;
392
393 if (not m_beamSpotKey.empty()) {
395 }
396
397 double magField[3]{0,0,0};
398 double globalPos[3] ={10.,10.,0.};
399
400 MagField::AtlasFieldCache fieldCache;
401 // Get field cache object
403 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
404
405 if (fieldCondObj == nullptr) {
406 ATH_MSG_ERROR("SiSpacePointsSeedMaker_ATLxk: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
407 return;
408 }
409 fieldCondObj->getInitializedCache (fieldCache);
410
411 // initialise pt cuts and conversion factors
412 if (fieldCache.solenoidOn()) {
413 fieldCache.getFieldZR(globalPos,magField);
414
415 data.K = 2.f/(300.f*float(magField[2]));
416 } else {
417 data.K = 2.f/(300.f* 5.f );
418 }
419
420 data.ipt2K = m_ipt2/(data.K*data.K);
421 data.ipt2C = m_ipt2*m_COF;
422 data.COFK = m_COF*(data.K*data.K);
423
424 data.i_spforseed = data.l_spforseed.begin();
425
426 float oneOverBinSizeR = 1.f/m_binSizeR;
427 int maxBinR = m_nBinsR-1;
428
429 data.r_first = 0;
430 data.checketa = false;
431
432 for (int i=0; i<data.nr; ++i) {
433 int n = data.r_index[i];
434 data.r_map[n] = 0;
435 data.r_Sorted[n].clear();
436 }
437 data.ns = data.nr = 0;
438
439 // Get pixels space points containers from store gate
440 //
441 if (m_pixel && !vPixel.empty()) {
442
444 if ( spacepointsPixel.isValid() ) {
445
446 // Loop through all trigger collections
447 //
448 for (const IdentifierHash& l: vPixel) {
449 const auto *w = spacepointsPixel->indexFindPtr(l);
450 if (w==nullptr) continue;
451 for (const Trk::SpacePoint* sp: *w) {
452 float r = sp->r();
453 if (r > m_r_rmax) continue;
455 int ir = static_cast<int>(sps->radius()*oneOverBinSizeR);
456 if (ir>maxBinR) ir = maxBinR;
457 data.r_Sorted[ir].push_back(sps);
458 ++data.r_map[ir];
459 if (data.r_map[ir]==1) data.r_index[data.nr++] = ir;
460 ++data.ns;
461 }
462 }
463 }
464 }
465
466 // Get sct space points containers from store gate
467 //
468 if (m_sct && !vSCT.empty()) {
469
471 if (spacepointsSCT.isValid()) {
472
473 // Loop through all trigger collections
474 //
475 for (const IdentifierHash& l: vSCT) {
476 const auto *w = spacepointsSCT->indexFindPtr(l);
477 if (w==nullptr) continue;
478 for (const Trk::SpacePoint* sp: *w) {
479 float r = sp->r();
480 if (r > m_r_rmax) continue;
482 int ir = static_cast<int>(sps->radius()*oneOverBinSizeR);
483 if (ir>maxBinR) ir = maxBinR;
484 data.r_Sorted[ir].push_back(sps);
485 ++data.r_map[ir];
486 if (data.r_map[ir]==1) data.r_index[data.nr++] = ir;
487 ++data.ns;
488 }
489 }
490 }
491 }
493}
494
498
500(const EventContext& ctx, EventData& data,
501 const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT,
502 const IRoiDescriptor& IRD) const
503{
504 constexpr float twoPi = 2.*M_PI;
505
506 if (not data.initialized) initializeEventData(data);
507
508 newRegion(ctx, data, vPixel, vSCT);
509 data.trigger = true;
510
511 double dzdrmin = 1./std::tan(2.*std::atan(std::exp(-IRD.etaMinus())));
512 double dzdrmax = 1./std::tan(2.*std::atan(std::exp(-IRD.etaPlus ())));
513
514 data.zminB = IRD.zedMinus()-data.zbeam[0]; // min bottom Z
515 data.zmaxB = IRD.zedPlus ()-data.zbeam[0]; // max bottom Z
516 data.zminU = data.zminB+550.f*float(dzdrmin);
517 data.zmaxU = data.zmaxB+550.f*float(dzdrmax);
518 float fmax = IRD.phiPlus ();
519 float fmin = IRD.phiMinus();
520 if (fmin > fmax) fmin -= twoPi;
521 data.ftrig = (fmin+fmax)*.5f;
522 data.ftrigW = (fmax-fmin)*.5f;
523}
524
529
530void InDet::SiSpacePointsSeedMaker_ATLxk::find2Sp(EventData& data, const std::list<Trk::Vertex>& lv) const
531{
532 if (not data.initialized) initializeEventData(data);
533
534 data.zminU = m_zmin;
535 data.zmaxU = m_zmax;
536
537 int mode = 0;
538 if (lv.begin()!=lv.end()) mode = 1;
539 bool newv = newVertices(data, lv);
540
541 if (newv || !data.state || data.nspoint!=2 || data.mode!=mode || data.nlist) {
542 data.i_seede_Pro = data.l_seeds_Pro.begin();
543 data.state = 1;
544 data.nspoint = 2;
545 data.nlist = 0;
546 data.mode = mode;
547 data.endlist = true;
548 data.fvNmin = 0;
549 data.fNmin = 0;
550 data.zMin = 0;
552 }
553 data.i_seed_Pro = data.l_seeds_Pro.begin();
554
555
556 if (msgLvl(MSG::DEBUG)) {
557 data.nprint=1;
558 dump(data, msg(MSG::DEBUG));
559 }
560}
561
566
567void InDet::SiSpacePointsSeedMaker_ATLxk::find3Sp(const EventContext&, EventData& data, const std::list<Trk::Vertex>& lv) const
568{
569 if (not data.initialized) initializeEventData(data);
570
572 data.zminU = m_zmin;
573 data.zmaxU = m_zmax;
575 int mode = 2;
576 if (lv.begin()!=lv.end()) mode = 3;
581 bool newv = newVertices(data, lv);
583 if (newv || !data.state || data.nspoint!=3 || data.mode!=mode || data.nlist) {
584 data.i_seede_Pro = data.l_seeds_Pro.begin();
585 data.state = 1;
586 data.nspoint = 3;
587 data.nlist = 0;
588 data.mode = mode;
589 data.endlist = true;
590 data.fvNmin = 0;
591 data.fNmin = 0;
592 data.zMin = 0;
594 }
597 data.i_seed_Pro = data.l_seeds_Pro.begin();
598
599
600 if (msgLvl(MSG::DEBUG)) {
601 data.nprint=1;
602 dump(data, msg(MSG::DEBUG));
603 }
604}
605
610
611void InDet::SiSpacePointsSeedMaker_ATLxk::find3Sp(const EventContext&, EventData& data, const std::list<Trk::Vertex>& lv, const double* ZVertex) const
612{
613 if (not data.initialized) initializeEventData(data);
614
617 data.zminU = ZVertex[0];
618 if (data.zminU < m_zmin) data.zminU = m_zmin;
619 data.zmaxU = ZVertex[1];
620 if (data.zmaxU > m_zmax) data.zmaxU = m_zmax;
621
623 int mode = 2;
624 if (lv.begin()!=lv.end()) mode = 3;
629 bool newv = newVertices(data, lv);
631 if (newv || !data.state || data.nspoint!=3 || data.mode!=mode || data.nlist) {
632 data.i_seede_Pro = data.l_seeds_Pro.begin();
633 data.state = 1;
634 data.nspoint = 3;
635 data.nlist = 0;
636 data.mode = mode;
637 data.endlist = true;
638 data.fvNmin = 0;
639 data.fNmin = 0;
640 data.zMin = 0;
642 }
645 data.i_seed_Pro = data.l_seeds_Pro.begin();
646
647 if (msgLvl(MSG::DEBUG)) {
648 data.nprint=1;
649 dump(data, msg(MSG::DEBUG));
650 }
651}
652
658
659void InDet::SiSpacePointsSeedMaker_ATLxk::findVSp(const EventContext&, EventData& data, const std::list<Trk::Vertex>& lv) const
660{
661 if (not data.initialized) initializeEventData(data);
662
663 data.zminU = m_zmin;
664 data.zmaxU = m_zmax;
665
666 int mode = 5;
667 if (lv.begin()!=lv.end()) mode = 6;
668 bool newv = newVertices(data, lv);
669
670 if (newv || !data.state || data.nspoint!=4 || data.mode!=mode || data.nlist) {
671 data.i_seede_Pro = data.l_seeds_Pro.begin();
672 data.state = 1;
673 data.nspoint = 4;
674 data.nlist = 0;
675 data.mode = mode;
676 data.endlist = true;
677 data.fvNmin = 0;
678 data.fNmin = 0;
679 data.zMin = 0;
681 }
682 data.i_seed_Pro = data.l_seeds_Pro.begin();
683
684 if (msgLvl(MSG::DEBUG)) {
685 data.nprint=1;
686 dump(data, msg(MSG::DEBUG));
687 }
688}
689
693
695{
696 if (not data.initialized) initializeEventData(data);
697
698 if (data.nprint) return dumpEvent(data, out);
699 return dumpConditions(data, out);
700}
701
705
707{
708 int n = 42-m_spacepointsPixel.key().size();
709 std::string s2;
710 for (int i=0; i<n; ++i) s2.append(" ");
711 s2.append("|");
712 n = 42-m_spacepointsSCT.key().size();
713 std::string s3;
714 for (int i=0; i<n; ++i) s3.append(" ");
715 s3.append("|");
716 n = 42-m_spacepointsOverlap.key().size();
717 std::string s4;
718 for (int i=0; i<n; ++i) s4.append(" ");
719 s4.append("|");
720 n = 42-m_beamSpotKey.key().size();
721 std::string s5;
722 for (int i=0; i<n; ++i) s5.append(" ");
723 s5.append("|");
724
725 out<<"|---------------------------------------------------------------------|"
726 <<endmsg;
727 out<<"| Pixel space points | "<<m_spacepointsPixel.key() <<s2
728 <<endmsg;
729 out<<"| SCT space points | "<<m_spacepointsSCT.key()<<s3
730 <<endmsg;
731 out<<"| Overlap space points | "<<m_spacepointsOverlap.key()<<s4
732 <<endmsg;
733 out<<"| BeamConditionsService | "<<m_beamSpotKey.key()<<s5
734 <<endmsg;
735 out<<"| usePixel | "
736 <<std::setw(12)<<m_pixel
737 <<" |"<<endmsg;
738 out<<"| useSCT | "
739 <<std::setw(12)<<m_sct
740 <<" |"<<endmsg;
741 out<<"| maxSize | "
742 <<std::setw(12)<<m_maxsize
743 <<" |"<<endmsg;
744 out<<"| maxSizeSP | "
745 <<std::setw(12)<<m_maxsizeSP
746 <<" |"<<endmsg;
747 out<<"| pTmin (mev) | "
748 <<std::setw(12)<<std::setprecision(5)<<m_ptmin
749 <<" |"<<endmsg;
750 out<<"| max radius SP | "
751 <<std::setw(12)<<std::setprecision(5)<<m_r_rmax
752 <<" |"<<endmsg;
753 out<<"| radius step | "
754 <<std::setw(12)<<std::setprecision(5)<<m_binSizeR
755 <<" |"<<endmsg;
756 out<<"| min Z-vertex position | "
757 <<std::setw(12)<<std::setprecision(5)<<m_zmin
758 <<" |"<<endmsg;
759 out<<"| max Z-vertex position | "
760 <<std::setw(12)<<std::setprecision(5)<<m_zmax
761 <<" |"<<endmsg;
762 out<<"| min radius first SP(2) | "
763 <<std::setw(12)<<std::setprecision(5)<<m_r1minv
764 <<" |"<<endmsg;
765 out<<"| min radius second SP(2) | "
766 <<std::setw(12)<<std::setprecision(5)<<m_r2minv
767 <<" |"<<endmsg;
768 out<<"| max radius first SP(2) | "
769 <<std::setw(12)<<std::setprecision(5)<<m_r1maxv
770 <<" |"<<endmsg;
771 out<<"| max radius second SP(2) | "
772 <<std::setw(12)<<std::setprecision(5)<<m_r2maxv
773 <<" |"<<endmsg;
774 out<<"| min space points dR | "
775 <<std::setw(12)<<std::setprecision(5)<<m_drmin
776 <<" |"<<endmsg;
777 out<<"| max space points dR | "
778 <<std::setw(12)<<std::setprecision(5)<<m_drmax
779 <<" |"<<endmsg;
780 out<<"| max dZ impact | "
781 <<std::setw(12)<<std::setprecision(5)<<m_dzver
782 <<" |"<<endmsg;
783 out<<"| max dZ/dR impact | "
784 <<std::setw(12)<<std::setprecision(5)<<m_dzdrver
785 <<" |"<<endmsg;
786 out<<"| max impact | "
787 <<std::setw(12)<<std::setprecision(5)<<m_maxdImpact
788 <<" |"<<endmsg;
789 out<<"| max impact sss | "
790 <<std::setw(12)<<std::setprecision(5)<<m_maxdImpactSSS
791 <<" |"<<endmsg;
792 out<<"|---------------------------------------------------------------------|"
793 <<endmsg;
794 out<<"| Beam X center | "
795 <<std::setw(12)<<std::setprecision(5)<<data.xbeam[0]
796 <<" |"<<endmsg;
797 out<<"| Beam Y center | "
798 <<std::setw(12)<<std::setprecision(5)<<data.ybeam[0]
799 <<" |"<<endmsg;
800 out<<"| Beam Z center | "
801 <<std::setw(12)<<std::setprecision(5)<<data.zbeam[0]
802 <<" |"<<endmsg;
803 out<<"| Beam X-axis direction | "
804 <<std::setw(12)<<std::setprecision(5)<<data.xbeam[1]
805 <<std::setw(12)<<std::setprecision(5)<<data.xbeam[2]
806 <<std::setw(12)<<std::setprecision(5)<<data.xbeam[3]
807 <<" |"<<endmsg;
808 out<<"| Beam Y-axis direction | "
809 <<std::setw(12)<<std::setprecision(5)<<data.ybeam[1]
810 <<std::setw(12)<<std::setprecision(5)<<data.ybeam[2]
811 <<std::setw(12)<<std::setprecision(5)<<data.ybeam[3]
812 <<" |"<<endmsg;
813 out<<"| Beam Z-axis direction | "
814 <<std::setw(12)<<std::setprecision(5)<<data.zbeam[1]
815 <<std::setw(12)<<std::setprecision(5)<<data.zbeam[2]
816 <<std::setw(12)<<std::setprecision(5)<<data.zbeam[3]
817 <<" |"<<endmsg;
818 out<<"|---------------------------------------------------------------------|"
819 <<endmsg;
820 return out;
821}
822
826
828{
829 out<<"|---------------------------------------------------------------------|"
830 <<endmsg;
831 out<<"| ns | "
832 <<std::setw(12)<<data.ns
833 <<" |"<<endmsg;
834 out<<"| nsaz | "
835 <<std::setw(12)<<data.nsaz
836 <<" |"<<endmsg;
837 out<<"| nsazv | "
838 <<std::setw(12)<<data.nsazv
839 <<" |"<<endmsg;
840 out<<"| seeds | "
841 <<std::setw(12)<<data.l_seeds_Pro.size()
842 <<" |"<<endmsg;
843 out<<"|---------------------------------------------------------------------|"
844 <<endmsg;
845 return out;
846}
847
851
853{
854 if (data.endlist) return;
855
856 data.i_seede_Pro = data.l_seeds_Pro.begin();
857
858 if (data.mode==0 or data.mode==1) production2Sp(data);
859 else if (data.mode==2 or data.mode==3) production3Sp(data);
860 else if (data.mode==5 or data.mode==6) production3Sp(data);
861
862 data.i_seed_Pro = data.l_seeds_Pro.begin();
863 ++data.nlist;
864}
865
869
870bool InDet::SiSpacePointsSeedMaker_ATLxk::newVertices(EventData& data, const std::list<Trk::Vertex>& lV) const
871{
872 unsigned int s1 = data.l_vertex.size();
873 unsigned int s2 = lV.size();
874
876 data.isvertex = false;
879 if (s1==0 && s2==0) return false;
880
882 data.l_vertex.clear();
884 if (s2 == 0) return false;
885
887 data.isvertex = true;
888 for (const Trk::Vertex& v: lV) {
889 data.l_vertex.insert(static_cast<float>(v.position().z()));
890 }
891
894 data.zminU = (*data.l_vertex. begin())-20.f;
895 if (data.zminU < m_zmin) data.zminU = m_zmin;
896 data.zmaxU = (*data.l_vertex.rbegin())+20.f;
897 if (data.zmaxU > m_zmax) data.zmaxU = m_zmax;
898
901 return false;
902}
903
905// Initiate frame work for seed generator
907
909{
910 m_ptmin = std::max( std::abs(m_ptmin), float(100.*m_fieldScale));
914
916 if (std::abs(m_etamin) < .1) m_etamin = -m_etamax;
918 m_dzdrmax0 = 1.f/std::tan(2.f*std::atan(std::exp(-m_etamax)));
919 m_dzdrmin0 = 1.f/std::tan(2.f*std::atan(std::exp(-m_etamin)));
920
922 m_ipt = 1.f/std::abs(.9f*m_ptmin);
924
933
935 m_nBinsR = static_cast<int>((m_r_rmax+.1f)/m_binSizeR);
936
941
943 constexpr float twoPi = 2.f*M_PI;
944
946 const int nPhiBinsMax = arraySizePhi;
947 const float inverseSizePhiMax = static_cast<float>(nPhiBinsMax)/twoPi;
948
956 constexpr float inverseSizePhiMin = 100./60.;
957
963
966 constexpr float radiusPixelStart = 33.;
967 constexpr float radiusPixelEnd = 150.;
971 const float binSizePhi_PPP = m_pixel ? azimuthalStep(m_ptmin/m_fieldScale,m_maxdImpact,radiusPixelStart,radiusPixelEnd)/3.f : 0.f;
973 constexpr float radiusSctStart = 295.; ;
974 constexpr float radiusSctEnd = 560.;
975 const float binSizePhi_SSS = m_sct ? azimuthalStep(m_ptmin/m_fieldScale,m_maxdImpactSSS,radiusSctStart,radiusSctEnd)/3.f : 0.f;
977 m_inverseBinSizePhi = 1.f/std::max(binSizePhi_PPP, binSizePhi_SSS);
978 }
979 else {
982 float ptm = 400.;
984 if (m_ptmin/m_fieldScale < ptm) ptm = m_ptmin/m_fieldScale;
985 m_inverseBinSizePhi = ptm /60.f;
986 }
987
989 if (m_inverseBinSizePhi > inverseSizePhiMax) m_inverseBinSizePhi = inverseSizePhiMax;
990 else if (m_inverseBinSizePhi < inverseSizePhiMin) m_inverseBinSizePhi = inverseSizePhiMin;
991
993 m_maxPhiBin = static_cast<int>(twoPi*m_inverseBinSizePhi);
995 if (m_maxPhiBin >=nPhiBinsMax) m_maxPhiBin = nPhiBinsMax-1;
996
999 const int nPhiBinsVertexMax = arraySizePhiV;
1000 const float inverseBinSizePhiVertexMax = static_cast<float>(nPhiBinsVertexMax)/twoPi;
1002 if (m_inverseBinSizePhiVertex > inverseBinSizePhiVertexMax) m_inverseBinSizePhiVertex = inverseBinSizePhiVertexMax;
1003 m_maxBinPhiVertex = static_cast<int>(twoPi*m_inverseBinSizePhiVertex);
1004 if (m_maxBinPhiVertex>=nPhiBinsVertexMax) m_maxBinPhiVertex = nPhiBinsVertexMax-1;
1005
1006
1010
1011 for (int phiBin=0; phiBin<=m_maxPhiBin; ++phiBin) {
1012
1013 int phiBelow = phiBin-1;
1014 if (phiBelow<0) phiBelow=m_maxPhiBin;
1015
1016 int phiAbove = phiBin+1;
1017 if (phiAbove>m_maxPhiBin) phiAbove=0;
1018
1020 for (int z=0; z<arraySizeZ; ++z) {
1021
1024
1025 int twoDbinSamePhi = phiBin * arraySizeZ+z;
1026 int twoDbinLowerPhi = phiBelow*arraySizeZ+z;
1027 int twoDbinHigherPhi = phiAbove* arraySizeZ+z;
1028
1029 m_nNeighbourCellsBottom [twoDbinSamePhi] = 3;
1030 m_nNeighbourCellsTop [twoDbinSamePhi] = 3;
1031
1032 m_neighbourCellsBottom[twoDbinSamePhi][0] = twoDbinSamePhi;
1033 m_neighbourCellsTop[twoDbinSamePhi][0] = twoDbinSamePhi;
1034
1035 m_neighbourCellsBottom[twoDbinSamePhi][1] = twoDbinLowerPhi;
1036 m_neighbourCellsTop[twoDbinSamePhi][1] = twoDbinLowerPhi;
1037
1038 m_neighbourCellsBottom[twoDbinSamePhi][2] = twoDbinHigherPhi;
1039 m_neighbourCellsTop[twoDbinSamePhi][2] = twoDbinHigherPhi;
1040
1049 if (z==5) {
1050 m_nNeighbourCellsTop [twoDbinSamePhi] = 9;
1051 // in the central z region, we include the two neighbouring
1052 // z slices for the top neighbour search
1053
1054 m_neighbourCellsTop[twoDbinSamePhi][3] = twoDbinSamePhi+1;
1055 m_neighbourCellsTop[twoDbinSamePhi][4] = twoDbinLowerPhi+1;
1056 m_neighbourCellsTop[twoDbinSamePhi][5] = twoDbinHigherPhi+1;
1057 m_neighbourCellsTop[twoDbinSamePhi][6] = twoDbinSamePhi-1;
1058 m_neighbourCellsTop[twoDbinSamePhi][7] = twoDbinLowerPhi-1;
1059 m_neighbourCellsTop[twoDbinSamePhi][8] = twoDbinHigherPhi-1;
1060 }
1061 // z > 5: positive z values, |z| > 250mm
1062 else if (z> 5) {
1063 // for the bottom SP search in positive non-central z, we include the
1064 // neighbouring Z region on the left (towards the IP) in the bottom
1065 // neighbour search
1066 m_nNeighbourCellsBottom [twoDbinSamePhi] = 6;
1067 m_neighbourCellsBottom[twoDbinSamePhi][3] = twoDbinSamePhi-1;
1068 m_neighbourCellsBottom[twoDbinSamePhi][4] = twoDbinLowerPhi-1;
1069 m_neighbourCellsBottom[twoDbinSamePhi][5] = twoDbinHigherPhi-1;
1070
1071 if (z<10) {
1077 m_nNeighbourCellsTop [twoDbinSamePhi] = 6;
1078 m_neighbourCellsTop[twoDbinSamePhi][3] = twoDbinSamePhi+1;
1079 m_neighbourCellsTop[twoDbinSamePhi][4] = twoDbinLowerPhi+1;
1080 m_neighbourCellsTop[twoDbinSamePhi][5] = twoDbinHigherPhi+1;
1081 }
1082 }
1083 // z < 5: negative z values, |z| > 250mm
1084 else {
1089 m_nNeighbourCellsBottom [twoDbinSamePhi] = 6;
1090 m_neighbourCellsBottom[twoDbinSamePhi][3] = twoDbinSamePhi+1;
1091 m_neighbourCellsBottom[twoDbinSamePhi][4] = twoDbinLowerPhi+1;
1092 m_neighbourCellsBottom[twoDbinSamePhi][5] = twoDbinHigherPhi+1;
1093
1094 if (z>0) {
1095 // if there is a z region on the left (away from the IP), we include it in the top
1096 // neighbour search
1097 m_nNeighbourCellsTop [twoDbinSamePhi] = 6;
1098 m_neighbourCellsTop[twoDbinSamePhi][3] = twoDbinSamePhi-1;
1099 m_neighbourCellsTop[twoDbinSamePhi][4] = twoDbinLowerPhi-1;
1100 m_neighbourCellsTop[twoDbinSamePhi][5] = twoDbinHigherPhi-1;
1101 }
1102 }
1103
1109 if (z==3) {
1110 m_nNeighbourCellsBottom[twoDbinSamePhi] = 9;
1111 m_neighbourCellsBottom[twoDbinSamePhi][6] = twoDbinSamePhi+2;
1112 m_neighbourCellsBottom[twoDbinSamePhi][7] = twoDbinLowerPhi+2;
1113 m_neighbourCellsBottom[twoDbinSamePhi][8] = twoDbinHigherPhi+2;
1114 } else if (z==7) {
1115 m_nNeighbourCellsBottom[twoDbinSamePhi] = 9;
1116 m_neighbourCellsBottom[twoDbinSamePhi][6] = twoDbinSamePhi-2;
1117 m_neighbourCellsBottom[twoDbinSamePhi][7] = twoDbinLowerPhi-2;
1118 m_neighbourCellsBottom[twoDbinSamePhi][8] = twoDbinHigherPhi-2;
1119 }
1120 }
1121 }
1122
1126 for (int phiBin=0; phiBin<=m_maxBinPhiVertex; ++phiBin) {
1127
1128 int phiBinBelow = phiBin-1;
1129 if (phiBinBelow<0) phiBinBelow=m_maxBinPhiVertex;
1130
1131 int phiBinTop = phiBin+1;
1132 if (phiBinTop>m_maxBinPhiVertex) phiBinTop=0;
1133
1135 for (int zbin=0; zbin<arraySizeZV; ++zbin) {
1136
1137 int twoDbinSamePhi = phiBin *arraySizeZV+zbin;
1138 int twoDbinLowerPhi = phiBinBelow*arraySizeZV+zbin;
1139 int twoDbinHigherPhi = phiBinTop*arraySizeZV+zbin;
1140
1142 m_nNeighboursVertexPhiZ[twoDbinSamePhi] = 3;
1143 m_neighboursVertexPhiZ[twoDbinSamePhi][0] = twoDbinSamePhi;
1144 m_neighboursVertexPhiZ[twoDbinSamePhi][1] = twoDbinLowerPhi;
1145 m_neighboursVertexPhiZ[twoDbinSamePhi][2] = twoDbinHigherPhi;
1146
1148 if (zbin>1) {
1149 m_nNeighboursVertexPhiZ[twoDbinSamePhi] = 6;
1150 m_neighboursVertexPhiZ[twoDbinSamePhi][3] = twoDbinSamePhi-1;
1151 m_neighboursVertexPhiZ[twoDbinSamePhi][4] = twoDbinLowerPhi-1;
1152 m_neighboursVertexPhiZ[twoDbinSamePhi][5] = twoDbinHigherPhi-1;
1153 }
1155 else if (zbin<1) {
1156 m_nNeighboursVertexPhiZ[twoDbinSamePhi] = 6;
1157 m_neighboursVertexPhiZ[twoDbinSamePhi][3] = twoDbinSamePhi+1;
1158 m_neighboursVertexPhiZ[twoDbinSamePhi][4] = twoDbinLowerPhi+1;
1159 m_neighboursVertexPhiZ[twoDbinSamePhi][5] = twoDbinHigherPhi+1;
1160 }
1161 }
1162 }
1163}
1164
1168
1170{
1172
1173 const Amg::Vector3D &bsCentre = beamSpotHandle->beamPos();
1174 double tx = std::tan(beamSpotHandle->beamTilt(0));
1175 double ty = std::tan(beamSpotHandle->beamTilt(1));
1176
1177 double phi = std::atan2(ty,tx);
1178 double theta = std::acos(1./std::sqrt(1.+tx*tx+ty*ty));
1179 double sinTheta = std::sin(theta);
1180 double cosTheta = std::cos(theta);
1181 double sinPhi = std::sin(phi);
1182 double cosPhi = std::cos(phi);
1183
1184 data.xbeam[0] = static_cast<float>(bsCentre.x());
1185 data.xbeam[1] = static_cast<float>(cosTheta*cosPhi*cosPhi+sinPhi*sinPhi);
1186 data.xbeam[2] = static_cast<float>(cosTheta*sinPhi*cosPhi-sinPhi*cosPhi);
1187 data.xbeam[3] =-static_cast<float>(sinTheta*cosPhi );
1188
1189 data.ybeam[0] = static_cast<float>(bsCentre.y());
1190 data.ybeam[1] = static_cast<float>(cosTheta*cosPhi*sinPhi-sinPhi*cosPhi);
1191 data.ybeam[2] = static_cast<float>(cosTheta*sinPhi*sinPhi+cosPhi*cosPhi);
1192 data.ybeam[3] =-static_cast<float>(sinTheta*sinPhi );
1193
1194 data.zbeam[0] = static_cast<float>(bsCentre.z());
1195 data.zbeam[1] = static_cast<float>(sinTheta*cosPhi);
1196 data.zbeam[2] = static_cast<float>(sinTheta*sinPhi);
1197 data.zbeam[3] = static_cast<float>(cosTheta);
1198}
1199
1203
1205(EventData& data, const Trk::SpacePoint*const& sp, std::array<float,3> & r)
1206{
1207 r[0] = static_cast<float>(sp->globalPosition().x())-data.xbeam[0];
1208 r[1] = static_cast<float>(sp->globalPosition().y())-data.ybeam[0];
1209 r[2] = static_cast<float>(sp->globalPosition().z())-data.zbeam[0];
1210}
1211
1215
1217{
1218 constexpr float twoPi = 2.*M_PI;
1219
1220 int firstRadialBin = 0;
1221 bool ibl = false;
1222
1235
1236 const std::map<float, int> ztoBin{
1237 {-2500. ,0},
1238 {-1400. ,1},
1239 {-925. ,2},
1240 {-450. ,3},
1241 {-250 ,4},
1242 { 250 ,5},
1243 { 450 ,6},
1244 { 925 ,7},
1245 { 1400 ,8},
1246 { 2500 ,9},
1247 { 100000 ,10},
1248 };
1249
1250 for (int radialBin=data.r_first; radialBin<m_nBinsR; ++radialBin) {
1251
1253 if (!data.r_map[radialBin]) continue;
1255 if (firstRadialBin == 0) firstRadialBin = radialBin;
1256
1258 if (data.iteration) {
1265 if (!data.r_Sorted[radialBin].front()->spacepoint->clusterList().second) {
1266 if (radialBin * m_binSizeR < m_radiusCutIBL) ibl = true;
1267 }
1268
1270
1272 else if (ibl) {
1273 break;
1274 }
1280 else if (radialBin > 175) {
1281 break;
1282 }
1283 }
1284 // loop over the space points in the r-bin and sort them into the 2d phi-z binning
1285 for (InDet::SiSpacePointForSeed* SP : data.r_Sorted[radialBin]) {
1286
1289 float Phi = SP->phi();
1290 if (Phi<0.) Phi+=twoPi; // phi is defined in [0..2pi] for the binning
1291 int phiBin = static_cast<int>(Phi*m_inverseBinSizePhi);
1293 if (phiBin < 0) {
1294 phiBin = m_maxPhiBin;
1295 } else if (phiBin > m_maxPhiBin) {
1296 phiBin = 0;
1297 }
1298
1299 float Z = SP->z();
1306 int zBin{0};
1307 auto bound = ztoBin.lower_bound(Z);
1309 if (bound == ztoBin.end()){
1310 --bound;
1311 }
1312 zBin=bound->second;
1313
1315 int twoDbin = phiBin*arraySizeZ+zBin;
1318 ++data.nsaz;
1319 // push our space point into the 2D binned array
1320 data.rfz_Sorted[twoDbin].push_back(SP);
1324 if (!data.rfz_map[twoDbin]++) data.rfz_index[data.nrfz++] = twoDbin;
1325 }
1326 }
1329 if (!m_sct && firstRadialBin && static_cast<float>(firstRadialBin)*m_binSizeR < m_radiusCutIBL) {
1331 }
1332
1333 data.state = 0;
1334}
1335
1336
1337
1338float InDet::SiSpacePointsSeedMaker_ATLxk::azimuthalStep(const float pTmin,const float maxd0,const float Rmin,const float Rmax)
1339{
1340 // Tell clang to optimize assuming that FP exceptions can trap.
1341 // Otherwise, it can vectorize the division, which can lead to
1342 // spurious division-by-zero traps from unused vector lanes.
1344
1348 float Rm = pTmin/.6f;
1349
1356 float worstCaseD0 = maxd0;
1357 if (maxd0 > Rmin) worstCaseD0 = Rmin;
1358
1359 float sI = std::abs(std::asin(worstCaseD0/Rmin) - std::asin(worstCaseD0/Rmax));
1360 float sF = std::abs(std::asin(std::min(1.f,Rmax/(2.f*Rm))) -
1361 std::asin(std::min(1.f,Rmin/(2.f*Rm))));
1362 return sI+sF;
1363}
1364
1365
1366
1368// Erase space point information
1370
1372{
1373 for (int i=0; i<data.nrfz; ++i) {
1374 int n = data.rfz_index[i];
1375 data.rfz_map[n] = 0;
1376 data.rfz_Sorted[n].clear();
1377 }
1378
1379 for (int i=0; i<data.nrfzv; ++i) {
1380 int n = data.rfzv_index[i];
1381 data.rfzv_map[n] = 0;
1382 data.rfzv_Sorted[n].clear();
1383 }
1384 data.state = 0;
1385 data.nsaz = 0;
1386 data.nsazv = 0;
1387 data.nrfz = 0;
1388 data.nrfzv = 0;
1389}
1390
1392// Test is space point used
1394
1395
1396
1398// 2 space points seeds production
1400
1402{
1403 if (data.nsazv<2) return;
1404
1405 std::vector<InDet::SiSpacePointForSeed*>::iterator r0,r0e,r,re;
1406 int nseed = 0;
1407
1408 // Loop thorugh all azimuthal regions
1409 //
1410 for (int f=data.fvNmin; f<=m_maxBinPhiVertex; ++f) {
1411
1412 // For each azimuthal region loop through Z regions
1413 //
1414 int z = 0;
1415 if (!data.endlist) z = data.zMin;
1416 for (; z<arraySizeZV; ++z) {
1417
1418 int a = f*arraySizeZV+z;
1419 if (!data.rfzv_map[a]) continue;
1420 r0 = data.rfzv_Sorted[a].begin();
1421 r0e = data.rfzv_Sorted[a].end ();
1422
1423 if (!data.endlist) {
1424 r0 = data.rMin;
1425 data.endlist = true;
1426 }
1427
1428 // Loop through trigger space points
1429 //
1430 for (; r0!=r0e; ++r0) {
1431
1432 float X = (*r0)->x();
1433 float Y = (*r0)->y();
1434 float R = (*r0)->radius();
1435 if (R<m_r2minv) continue;
1436 if (R>m_r2maxv) break;
1437 float Z = (*r0)->z();
1438 float ax = X/R;
1439 float ay = Y/R;
1440
1441 // Bottom links production
1442 //
1443 int numberBottomCells = m_nNeighboursVertexPhiZ[a];
1444 for (int i=0; i<numberBottomCells; ++i) {
1445
1446 int an = m_neighboursVertexPhiZ[a][i];
1447 if (!data.rfzv_map[an]) continue;
1448
1449 r = data.rfzv_Sorted[an].begin();
1450 re = data.rfzv_Sorted[an].end();
1451
1452 for (; r!=re; ++r) {
1453
1454 float Rb =(*r)->radius();
1455 if (Rb<m_r1minv) continue;
1456 if (Rb>m_r1maxv) break;
1457 float dR = R-Rb;
1458 if (dR<m_drminv) break;
1459 if (dR>m_drmax) continue;
1460 float dZ = Z-(*r)->z();
1461 float Tz = dZ/dR;
1462 if (Tz<data.dzdrmin || Tz>data.dzdrmax) continue;
1463 float Zo = Z-R*Tz;
1464
1465 // Comparison with vertices Z coordinates
1466 //
1467 if (!isZCompatible(data, Zo, Rb, Tz)) continue;
1468
1469 // Momentum cut
1470 //
1471 float dx =(*r)->x()-X;
1472 float dy =(*r)->y()-Y;
1473 float x = dx*ax+dy*ay;
1474 float y =-dx*ay+dy*ax;
1475 float xy = x*x+y*y;
1476 if (xy == 0.) continue;
1477 float r2 = 1.f/xy;
1478 float Ut = x*r2;
1479 float Vt = y*r2;
1480 float UR = Ut*R+1.f;
1481 if (UR == 0.) continue;
1482 float A = Vt*R/UR;
1483 float B = Vt-A*Ut;
1484 if (std::abs(B*data.K) > m_ipt*std::sqrt(1.f+A*A)) continue;
1485 ++nseed;
1486 newSeed(data, (*r), (*r0), Zo);
1487 }
1488 }
1489 if (nseed < m_maxsize) continue;
1490 data.endlist=false;
1491 data.rMin = (++r0);
1492 data.fvNmin=f;
1493 data.zMin=z;
1494 return;
1495 }
1496 }
1497 }
1498 data.endlist = true;
1499}
1500
1502// Production 3 space points seeds
1504
1506{
1507
1509 if (data.nsaz<3) return;
1510
1521
1522
1532 const std::array<int,arraySizeZ> zBinIndex {5,6,7,8,9,10,4,3,2,1,0};
1533
1536 std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator,arraySizeNeighbourBins> iter_topCands;
1537 std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator,arraySizeNeighbourBins> iter_endTopCands;
1538 std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator,arraySizeNeighbourBins> iter_bottomCands;
1539 std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator,arraySizeNeighbourBins> iter_endBottomCands;
1540
1542 int nseed = 0;
1544 data.endlist = true;
1545
1547 for (int phiBin=data.fNmin; phiBin<=m_maxPhiBin; ++phiBin) {
1548
1550 int z = 0;
1552 if (!data.endlist) z = data.zMin;
1553
1557 for (; z<arraySizeZ; ++z) {
1558
1559 int phiZbin = phiBin *arraySizeZ+zBinIndex[z];
1560
1562 if (!data.rfz_map[phiZbin]) continue;
1563
1566 int numberBottomCells = 0;
1567 int numberTopCells = 0;
1568
1573 for (int neighbourCellNumber=0; neighbourCellNumber<m_nNeighbourCellsBottom[phiZbin]; ++neighbourCellNumber) {
1574
1575 int theNeighbourCell = m_neighbourCellsBottom[phiZbin][neighbourCellNumber];
1577 if (!data.rfz_map[theNeighbourCell]) continue;
1579 iter_bottomCands [numberBottomCells] = data.rfz_Sorted[theNeighbourCell].begin();
1580 iter_endBottomCands[numberBottomCells++] = data.rfz_Sorted[theNeighbourCell].end();
1581 }
1582
1587 for (int neighbourCellNumber=0; neighbourCellNumber<m_nNeighbourCellsTop[phiZbin]; ++neighbourCellNumber) {
1588
1589 int theNeighbourCell = m_neighbourCellsTop[phiZbin][neighbourCellNumber];
1591 if (!data.rfz_map[theNeighbourCell]) continue;
1593 iter_topCands [numberTopCells] = data.rfz_Sorted[theNeighbourCell].begin();
1594 iter_endTopCands[numberTopCells++] = data.rfz_Sorted[theNeighbourCell].end();
1595 }
1596
1598 if (!data.trigger) production3Sp (data, iter_bottomCands, iter_endBottomCands, iter_topCands, iter_endTopCands, numberBottomCells, numberTopCells, nseed,zBinIndex[z]);
1599 else production3SpTrigger(data, iter_bottomCands, iter_endBottomCands, iter_topCands, iter_endTopCands, numberBottomCells, numberTopCells, nseed);
1600 }
1601
1608 if (nseed>=m_maxsize) {
1609 data.endlist=false;
1610 data.fNmin = phiBin+1;
1611 return;
1612 }
1613 }
1615 data.endlist = true;
1616}
1617
1621
1623(EventData& data,
1624 std::array <std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & iter_bottomCands ,
1625 std::array <std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & iter_endBottomCands,
1626 std::array <std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & iter_topCands ,
1627 std::array <std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & iter_endTopCands,
1628 const int numberBottomCells, const int numberTopCells, int& nseed, const int zbin) const
1629{
1635
1637 std::vector<InDet::SiSpacePointForSeed*>::iterator iter_centralSP=iter_bottomCands[0];
1638 std::vector<InDet::SiSpacePointForSeed*>::iterator iter_otherSP;
1639
1645
1647 bool isStrip = ((*iter_centralSP)->spacepoint->clusterList().second);
1648
1651 bool isBarrelRegion = (zbin >=4 && zbin <= 6);
1652 bool isTransitionRegion = (zbin == 3 || zbin == 7); // region in z = 450 - 925mm
1653 float rmin = 40.;
1654 float rmax = 140.;
1655
1656 if (isBarrelRegion){
1657 rmax = 100;
1658 }
1660 if(isStrip) {
1662 rmin = 285.;
1663 rmax = 450.;
1664 if (isBarrelRegion){
1665 rmin = 335;
1666 rmax = 450.;
1667 }
1668 else if (isTransitionRegion){
1669 rmin = 335;
1670 rmax = 550;
1672 }
1673 }
1674
1676 for(; iter_centralSP!=iter_endBottomCands[0]; ++iter_centralSP) {
1677 if((*iter_centralSP)->radius() > rmin) break;
1678 }
1679
1682 iter_topCands[0] = iter_centralSP;
1683 ++iter_topCands[0];
1684
1686 const float ipt2K = data.ipt2K;
1687 const float ipt2C = data.ipt2C;
1688 const float COFK = data.COFK;
1689 const float maxd0cut = m_maxdImpact;
1690 const float maxd0cutstrips = m_maxdImpactDecays;
1691 const float zmin = data.zminU;
1692 const float zmax = data.zmaxU;
1693 const float dzdrmax = data.dzdrmax;
1694 const float dzdrmin = data.dzdrmin;
1695 data.CmSp.clear();
1696
1699 size_t SPcapacity = data.SP.size();
1700
1702 for (; iter_centralSP!=iter_endBottomCands[0]; ++iter_centralSP) {
1703
1704 const float& R = (*iter_centralSP)->radius();
1705 if(R > rmax) break;
1706
1708 const float& X = (*iter_centralSP)->x();
1709 const float& Y = (*iter_centralSP)->y();
1710 const float& Z = (*iter_centralSP)->z();
1711
1714 double absZ = std::abs(Z);
1716 if (isStrip && absZ > 2650. ) continue;
1718 if (!isStrip && absZ > 600.) continue;
1720 if (isStrip && isTransitionRegion && absZ < 750. && R > 450.) continue;
1721
1724 size_t Nb = 0;
1725
1728 for (int cell=0; cell<numberBottomCells; ++cell) {
1730 for (iter_otherSP=iter_bottomCands[cell]; iter_otherSP!=iter_endBottomCands[cell]; ++iter_otherSP) {
1731
1733 const float& Rb =(*iter_otherSP)->radius();
1734 float dR = R-Rb;
1735
1738 if (dR > m_drmax) {
1739 iter_bottomCands[cell]=iter_otherSP;
1740 continue;
1741 }
1744 if (dR < m_drmin || (data.iteration && (*iter_otherSP)->spacepoint->clusterList().second)) break;
1745
1747 const float dZdR = (Z-(*iter_otherSP)->z())/dR;
1749 const float absdZdR = std::abs(dZdR);
1751 if (absdZdR < dzdrmin or absdZdR > dzdrmax) continue;
1752
1755 const float z0 = Z-R*dZdR;
1756 if(z0 > zmax || z0 < zmin) continue;
1758 data.SP[Nb] = (*iter_otherSP);
1759 if(m_writeNtuple) data.SP[Nb]->setDZDR(dZdR);
1763 if (++Nb==SPcapacity){
1764 data.resizeSPCont();
1765 SPcapacity=data.SP.size();
1766 }
1767 }
1768 }
1769
1771 if (!Nb) continue;
1772
1776 size_t Nt = Nb;
1777
1779
1781 for (int cell=0; cell<numberTopCells; ++cell) {
1783 for (iter_otherSP=iter_topCands[cell];iter_otherSP!=iter_endTopCands[cell]; ++iter_otherSP) {
1784
1786 float Rt =(*iter_otherSP)->radius();
1787 float dR = Rt-R;
1788
1790 if (dR<m_drmin) {
1791 iter_topCands[cell]=iter_otherSP;
1792 continue;
1793 }
1795 if (dR>m_drmax) break;
1796
1798 float dZdR = ((*iter_otherSP)->z()-Z)/dR;
1799 float absdZdR = std::abs(dZdR);
1800 if (absdZdR < dzdrmin or absdZdR > dzdrmax) continue;
1801
1804 float z0 = Z-R*dZdR;
1805 if(z0 > zmax || z0 < zmin) continue;
1807 data.SP[Nt] = (*iter_otherSP);
1808 if (m_writeNtuple) data.SP[Nt]->setDZDR(dZdR);
1812 if (++Nt==SPcapacity) {
1813 data.resizeSPCont();
1814 SPcapacity=data.SP.size();
1815 }
1816 }
1817 }
1818
1820 if (!(Nt-Nb)) continue;
1821
1823 float covr0 = (*iter_centralSP)->covr ();
1824 float covz0 = (*iter_centralSP)->covz ();
1825
1827 float ax = X/R;
1828 float ay = Y/R;
1829
1832 for (size_t i=0; i<Nt; ++i) {
1833
1835
1838 float dx = sp->x()-X;
1839 float dy = sp->y()-Y;
1840 float dz = sp->z()-Z;
1841 float x = dx*ax+dy*ay;
1842 float y = dy*ax-dx*ay;
1843
1845 float r2 = 1.f/(x*x+y*y);
1847 float dr = std::sqrt(r2);
1850 float tz = dz*dr;
1851
1854 if (i < Nb) tz = -tz;
1855
1857 data.Tz[i] = tz;
1858 data.Zo[i] = Z-R*tz;
1859 data.R [i] = dr;
1860 data.U [i] = x*r2;
1861 data.V [i] = y*r2;
1862 data.Er[i] = ((covz0+sp->covz())+(tz*tz)*(covr0+sp->covr()))*r2;
1863 }
1864
1865 data.nOneSeeds = 0;
1866 data.mapOneSeeds_Pro.clear();
1867
1870 for (size_t b=0; b<Nb; ++b) {
1871
1873 float Zob = data.Zo[b];
1874 float Tzb = data.Tz[b];
1875 float Erb = data.Er[b];
1876 float Vb = data.V [b];
1877 float Ub = data.U [b];
1878 float Tzb2 = (1.f+Tzb*Tzb);
1879 float sTzb2 = std::sqrt(Tzb2);
1880 float sigmaSquaredScatteringPtDependent = Tzb2*COFK;
1881 float sigmaSquaredScatteringMinPt = Tzb2*ipt2C;
1884 float d0max = maxd0cut;
1886 if (data.SP[b]->spacepoint->clusterList().second) d0max = maxd0cutstrips;
1887
1889 for (size_t t=Nb; t<Nt; ++t) {
1890
1895
1897 float meanOneOverTanTheta = (Tzb+data.Tz[t])/2.f;
1898 float theta = 0.;
1899 if(m_writeNtuple){
1901 theta = std::atan(1.f/meanOneOverTanTheta);
1902 }
1904 float sigmaSquaredSpacePointErrors = Erb+data.Er[t]
1905 + 2.f * covz0 * data.R[t]*data.R[b]
1906 + 2.f * covr0 * data.R[t]*data.R[b] * meanOneOverTanTheta * meanOneOverTanTheta; // mixed term with r-uncertainy on central SP
1908 float remainingSquaredDelta = (Tzb-data.Tz[t])*(Tzb-data.Tz[t]) - sigmaSquaredSpacePointErrors;
1909
1912 if (remainingSquaredDelta - sigmaSquaredScatteringMinPt > 0 ) continue;
1913
1935 float deltaU = data.U[t]-Ub;
1936 if (deltaU == 0.) continue;
1937 float A = (data.V[t]-Vb)/deltaU;
1938 float B = Vb-A*Ub;
1939 float onePlusAsquare = 1.f+A*A;
1940 float BSquare = B*B;
1941
1954 if (BSquare > ipt2K*onePlusAsquare || remainingSquaredDelta*onePlusAsquare > BSquare*sigmaSquaredScatteringPtDependent) continue;
1971 float d0 = 0;
1972 if(std::abs(B) < 1e-10) d0 = std::abs((A-B*R)*R);
1974 else{
1975 float x0 = -A/(2.f*B);
1976 float rTrack = std::sqrt(onePlusAsquare/BSquare)*.5f;
1977 d0 = std::abs(-rTrack + std::sqrt(rTrack*rTrack +2.f*x0*R +R*R));
1978 }
1979
1981 if (d0 <= d0max) {
1983 float dr = data.R[b];
1984 if (data.R[t] < data.R[b]) dr = data.R[t];
1988 data.SP[t]->setScorePenalty(std::abs((Tzb-data.Tz[t])/(dr*sTzb2)));
1989 data.SP[t]->setParam(d0);
1990
1991 if(m_writeNtuple){
1993 data.SP[t]->setEta(-std::log(std::tan(0.5f*theta)));
1994 data.SP[t]->setPt(std::sqrt(onePlusAsquare/BSquare)/(1000.f*data.K));
1995 }
1997 data.CmSp.emplace_back(B/std::sqrt(onePlusAsquare), data.SP[t]);
1999
2000 }
2001
2002 }
2004 if (!data.CmSp.empty()) {
2005 newOneSeedWithCurvaturesComparison(data, data.SP[b], (*iter_centralSP), Zob);
2006 }
2007 }
2009 fillSeeds(data);
2010 nseed += data.fillOneSeeds;
2011
2012 }
2013}
2014
2016// Production 3 space points seeds in ROI
2018
2020(EventData& data,
2021 std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & rb ,
2022 std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & rbe,
2023 std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & rt ,
2024 std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & rte,
2025 const int numberBottomCells, const int numberTopCells, int& nseed) const
2026{
2027 constexpr float twoPi = 2.*M_PI;
2028
2029 std::vector<InDet::SiSpacePointForSeed*>::iterator r0=rb[0],r;
2030
2031 float rmin = 40.;
2032 float rmax = 140.;
2033 if((*r0)->spacepoint->clusterList().second) {
2034 rmin = 280.;
2035 rmax = 540.;
2036 }
2037
2038 for(; r0!=rbe[0]; ++r0) {if((*r0)->radius() > rmin) break;}
2039 rt[0] = r0; ++rt[0];
2040
2041 float ipt2K = data.ipt2K;
2042 float ipt2C = data.ipt2C;
2043 float COFK = data.COFK;
2044 float maxd0cut = m_maxdImpact;
2045 float maxd0cutstrips = m_maxdImpactSSS;
2046
2047 data.CmSp.clear();
2048
2049 // Loop through all trigger space points
2050 //
2051 for (; r0!=rbe[0]; ++r0) {
2052
2053 data.nOneSeeds = 0;
2054 data.mapOneSeeds_Pro.clear();
2055
2056 float R = (*r0)->radius();
2057 if(R>rmax) break;
2058
2059 const Trk::Surface* sur0 = (*r0)->sur();
2060 float X = (*r0)->x();
2061 float Y = (*r0)->y();
2062 float Z = (*r0)->z();
2063 int Nb = 0;
2064
2065 // Bottom links production
2066 //
2067 for (int i=0; i<numberBottomCells; ++i) {
2068
2069 for (r=rb[i]; r!=rbe[i]; ++r) {
2070
2071 float Rb =(*r)->radius();
2072
2073 float dR = R-Rb;
2074 if (dR > m_drmax) {
2075 rb[i]=r;
2076 continue;
2077 }
2078 if ((*r)->sur()==sur0) continue;
2079
2080 if (dR < m_drmin || (data.iteration && (*r)->spacepoint->clusterList().second)) break;
2081
2082 // Comparison with bottom and top Z
2083 //
2084 float Tz = (Z-(*r)->z())/dR;
2085 float Zo = Z-R*Tz;
2086 if (Zo < data.zminB || Zo > data.zmaxB) continue;
2087 float Zu = Z+(550.f-R)*Tz;
2088 if (Zu < data.zminU || Zu > data.zmaxU) continue;
2089 data.SP[Nb] = (*r);
2090 if (++Nb==m_maxsizeSP) goto breakb;
2091 }
2092 }
2093 breakb:
2094 if (!Nb || Nb==m_maxsizeSP) continue;
2095 int Nt = Nb;
2096
2097 // Top links production
2098 //
2099 for (int i=0; i<numberTopCells; ++i) {
2100
2101 for (r=rt[i]; r!=rte[i]; ++r) {
2102
2103 float Rt =(*r)->radius();
2104 float dR = Rt-R;
2105
2106 if (dR<m_drmin) {
2107 rt[i]=r;
2108 continue;
2109 }
2110 if (dR>m_drmax) break;
2111 if ((*r)->sur()==sur0) continue;
2112
2113 // Comparison with bottom and top Z
2114 //
2115 float Tz = ((*r)->z()-Z)/dR;
2116 float Zo = Z-R*Tz;
2117 if (Zo < data.zminB || Zo > data.zmaxB) continue;
2118 float Zu = Z+(550.f-R)*Tz;
2119 if (Zu < data.zminU || Zu > data.zmaxU) continue;
2120 data.SP[Nt] = (*r);
2121 if (++Nt==m_maxsizeSP) goto breakt;
2122 }
2123 }
2124
2125 breakt:
2126 if (!(Nt-Nb)) continue;
2127 float covr0 = (*r0)->covr ();
2128 float covz0 = (*r0)->covz ();
2129
2130 float ax = X/R;
2131 float ay = Y/R;
2132
2133 for (int i=0; i<Nt; ++i) {
2134
2136
2137 float dx = sp->x()-X;
2138 float dy = sp->y()-Y;
2139 float dz = sp->z()-Z;
2140 float x = dx*ax+dy*ay;
2141 float y = dy*ax-dx*ay;
2142 float r2 = 1.f/(x*x+y*y);
2143 float dr = std::sqrt(r2);
2144 float tz = dz*dr;
2145 if (i < Nb) tz = -tz;
2146
2147 data.Tz[i] = tz;
2148 data.Zo[i] = Z-R*tz;
2149 data.R [i] = dr;
2150 data.U [i] = x*r2;
2151 data.V [i] = y*r2;
2152 data.Er[i] = ((covz0+sp->covz())+(tz*tz)*(covr0+sp->covr()))*r2;
2153 }
2154 covr0 *= .5f;
2155 covz0 *= 2.f;
2156
2157 // Three space points comparison
2158 //
2159 for (int b=0; b<Nb; ++b) {
2160
2161 float Zob = data.Zo[b];
2162 float Tzb = data.Tz[b];
2163 float Rb2r = data.R [b]*covr0;
2164 float Rb2z = data.R [b]*covz0;
2165 float Erb = data.Er[b];
2166 float Vb = data.V [b];
2167 float Ub = data.U [b];
2168 float Tzb2 = (1.f+Tzb*Tzb);
2169 float CSA = Tzb2*COFK;
2170 float ICSA = Tzb2*ipt2C;
2171 float d0max = maxd0cut;
2172 if (data.SP[b]->spacepoint->clusterList().second) d0max = maxd0cutstrips;
2173
2174 for (int t=Nb; t<Nt; ++t) {
2175
2176 float dT = ((Tzb-data.Tz[t])*(Tzb-data.Tz[t])-data.R[t]*Rb2z-(Erb+data.Er[t]))-(data.R[t]*Rb2r)*((Tzb+data.Tz[t])*(Tzb+data.Tz[t]));
2177 if ( dT > ICSA) continue;
2178
2179 float deltaU = data.U[t]-Ub;
2180 if (deltaU == 0.) continue;
2181 float A = (data.V[t]-Vb)/deltaU;
2182 float onePlusAsquare = 1.f+A*A;
2183 float B = Vb-A*Ub;
2184 float BSquare = B*B;
2185 if (BSquare > ipt2K*onePlusAsquare || dT*onePlusAsquare > BSquare*CSA) continue;
2186
2187 float Im = std::abs((A-B*R)*R);
2188 if (Im > d0max) continue;
2189
2190 // Azimuthal angle test
2191 //
2192 float y = 1.;
2193 float x = 2.f*B*R-A;
2194 float df = std::abs(std::atan2(ay*y-ax*x,ax*y+ay*x)-data.ftrig);
2195 if (df > M_PI) df = twoPi-df;
2196 if (df > data.ftrigW) continue;
2197 data.CmSp.emplace_back(B/std::sqrt(onePlusAsquare), data.SP[t]);
2198 data.SP[t]->setParam(Im);
2199 }
2200 if (!data.CmSp.empty()) {
2201 newOneSeedWithCurvaturesComparison(data, data.SP[b], (*r0), Zob);
2202 }
2203 }
2204 fillSeeds(data);
2205 nseed += data.fillOneSeeds;
2206 }
2207}
2208
2210// New 3 space points pro seeds
2212
2214(EventData& data,
2216 InDet::SiSpacePointForSeed*& p3, float z, float seedCandidateQuality) const
2217{
2219 float worstQualityInMap = std::numeric_limits<float>::min();
2220 InDet::SiSpacePointsProSeed* worstSeedSoFar = nullptr;
2221 if (!data.mapOneSeeds_Pro.empty()) {
2222 std::multimap<float,InDet::SiSpacePointsProSeed*>::reverse_iterator l = data.mapOneSeeds_Pro.rbegin();
2223 worstQualityInMap = (*l).first;
2224 worstSeedSoFar = (*l).second;
2225 }
2228 if (data.nOneSeeds < data.maxSeedsPerSP
2231 || (data.keepAllConfirmedSeeds && worstQualityInMap <= seedCandidateQuality && isConfirmedSeed(p1,p3,seedCandidateQuality) && data.nOneSeeds < data.seedPerSpCapacity)
2234 || (data.keepAllConfirmedSeeds && worstQualityInMap > seedCandidateQuality && isConfirmedSeed(worstSeedSoFar->spacepoint0(),worstSeedSoFar->spacepoint2(),worstQualityInMap) && data.nOneSeeds < data.seedPerSpCapacity)
2235 ){
2236 data.OneSeeds_Pro[data.nOneSeeds].set(p1,p2,p3,z);
2237 data.mapOneSeeds_Pro.insert(std::make_pair(seedCandidateQuality, &data.OneSeeds_Pro[data.nOneSeeds]));
2238 ++data.nOneSeeds;
2239 }
2241 else if (worstQualityInMap > seedCandidateQuality){
2243 worstSeedSoFar->set(p1,p2,p3,z);
2245 std::multimap<float,InDet::SiSpacePointsProSeed*>::iterator
2246 i = data.mapOneSeeds_Pro.insert(std::make_pair(seedCandidateQuality,worstSeedSoFar));
2248 for (++i; i!=data.mapOneSeeds_Pro.end(); ++i) {
2249 if ((*i).second==worstSeedSoFar) {
2250 data.mapOneSeeds_Pro.erase(i);
2251 return;
2252 }
2253 }
2254 }
2255}
2256
2258// New 3 space points pro seeds production
2260namespace {
2261 inline
2262 float computeEta( float r, float z) {
2263 if (r <= 10e-9) return 0;
2264 auto asinh = [] (double x) { return std::log (std::sqrt (x*x+1) + x); };
2265 return asinh (z / r);
2266 }
2267}
2268
2270(EventData& data, SiSpacePointForSeed*& SPb, SiSpacePointForSeed*& SP0, float Zob) const
2271{
2272 constexpr float curvatureInterval = .00003;
2273
2274 bool bottomSPisPixel = !SPb->spacepoint->clusterList().second;
2275 float bottomSPQuality = SPb->quality();
2276 float centralSPQuality = SP0->quality();
2277
2279 if(data.CmSp.size() > 2) std::sort(data.CmSp.begin(), data.CmSp.end(), comCurvature());
2280
2281 float bottomR=SPb->radius();
2282 float bottomZ=SPb->z();
2283
2284 std::vector<std::pair<float,InDet::SiSpacePointForSeed*>>::iterator it_otherSP;
2285 std::vector<std::pair<float,InDet::SiSpacePointForSeed*>>::iterator it_commonTopSP = data.CmSp.begin(), ie = data.CmSp.end();
2286 std::vector<std::pair<float,InDet::SiSpacePointForSeed*>>::iterator it_startInnerLoop=it_commonTopSP;
2287
2289 for (; it_commonTopSP!=ie; ++it_commonTopSP) {
2290
2292 float seedIP = (*it_commonTopSP).second->param();
2293 float seedQuality = seedIP + (*it_commonTopSP).second->scorePenalty();
2294 float originalSeedQuality = seedQuality;
2295
2296 if(m_maxdImpact > 50){ //This only applies to LRT
2297 // Tell clang to optimize assuming that FP exceptions can trap.
2298 // Otherwise, it can vectorize the division, which can lead to
2299 // spurious division-by-zero traps from unused vector lanes.
2301
2302 float topR=(*it_commonTopSP).second->radius();
2303 float topZ=(*it_commonTopSP).second->z();
2304
2305 float Zot = std::abs(topR - bottomR) > 10e-9 ?
2306 bottomZ - (bottomR - originalSeedQuality) * ((topZ - bottomZ) / (topR - bottomR)) : bottomZ;
2307
2308 float eta1 = computeEta(topR - bottomR, topZ - bottomZ);
2309 float eta0 = computeEta(seedIP, Zot);
2310
2311 float deltaEta=std::abs(eta1-eta0); //For LLP daughters, the direction of the track is correlated with the direction of the LLP (which is correlated with the direction of the point of closest approach
2312 //calculate weighted average of d0 and deltaEta, normalized by their maximum values
2313 float f=std::min(0.5f,originalSeedQuality/200.f); //0.5 and 200 are parameters chosen from a grid scan to optimize efficiency
2314 seedQuality*=(1.f-f)/300.f;
2315 seedQuality+=f*deltaEta/2.5f;
2316 }
2317
2318 bool topSPisPixel = !(*it_commonTopSP).second->spacepoint->clusterList().second;
2319
2321 const Trk::Surface* surfaceTopSP = (*it_commonTopSP).second->sur ();
2322 float radiusTopSP = (*it_commonTopSP).second->radius();
2324 float minCurvature =(*it_commonTopSP).first-curvatureInterval;
2325 float maxCurvature =(*it_commonTopSP).first+curvatureInterval;
2326
2333
2335 if (!bottomSPisPixel) seedQuality+=m_seedScoreBonusSSS;
2337 else if ( topSPisPixel) seedQuality+=m_seedScoreBonusPPP;
2338
2339
2345
2346 for (it_otherSP=it_startInnerLoop; it_otherSP!=ie; ++it_otherSP) {
2348 if ( it_otherSP == it_commonTopSP ) continue;
2351 if ( (*it_otherSP).first < minCurvature ) {
2352 it_startInnerLoop=it_otherSP;
2353 ++it_startInnerLoop;
2354 continue;
2355 }
2357 if ( (*it_otherSP).first > maxCurvature ) break;
2359 if ( (*it_otherSP).second->sur()==surfaceTopSP) continue;
2361 float radiusOtherSP = (*it_otherSP).second->radius();
2362 if (std::abs(radiusOtherSP-radiusTopSP) < m_drmin) continue;
2363 // if we have a confirmation seed, we improve the score of the seed.
2364 seedQuality += m_seedScoreBonusConfirmationSeed;
2365 // apply confirmation bonus only once
2366 break;
2367 }
2368
2370 if (seedQuality > data.maxScore) continue;
2371
2374 if (bottomSPisPixel!=topSPisPixel) {
2375 if (seedQuality > 0. ||
2376 (seedQuality > bottomSPQuality && seedQuality > centralSPQuality && seedQuality > (*it_commonTopSP).second->quality())
2377 ) continue;
2378 }
2381 if (!isConfirmedSeed(SPb,it_commonTopSP->second,seedQuality)){
2383 double maxdImpact = m_maxdImpact - (m_dImpactCutSlopeUnconfirmedPPP * (*it_commonTopSP).second->scorePenalty());
2385 if (!bottomSPisPixel) maxdImpact = m_maxdImpactSSS - (m_dImpactCutSlopeUnconfirmedSSS * (*it_commonTopSP).second->scorePenalty());
2386 if (seedIP > maxdImpact) continue;
2387 }
2389 newOneSeed(data, SPb, SP0, (*it_commonTopSP).second, Zob, seedQuality);
2390 }
2391 data.CmSp.clear();
2392}
2393
2397
2399{
2400
2401 data.fillOneSeeds = 0;
2402
2403 std::multimap<float,InDet::SiSpacePointsProSeed*>::iterator it_firstSeedCandidate = data.mapOneSeeds_Pro.begin();
2404 std::multimap<float,InDet::SiSpacePointsProSeed*>::iterator it_seedCandidate = data.mapOneSeeds_Pro.begin();
2405 std::multimap<float,InDet::SiSpacePointsProSeed*>::iterator it_endSeedCandidates = data.mapOneSeeds_Pro.end();
2406
2408 if (it_seedCandidate==it_endSeedCandidates) return;
2409
2410 SiSpacePointsProSeed* theSeed{nullptr};
2411
2413 for (; it_seedCandidate!=it_endSeedCandidates; ++it_seedCandidate) {
2414
2416 float quality = (*it_seedCandidate).first;
2417 theSeed = (*it_seedCandidate).second;
2419 if (it_seedCandidate!=it_firstSeedCandidate && theSeed->spacepoint0()->radius() < m_radiusCutIBL && quality > m_seedScoreThresholdPPPConfirmationSeed) continue;
2421 if (!theSeed->setQuality(quality)) continue;
2422
2424 if (data.i_seede_Pro!=data.l_seeds_Pro.end()) {
2425 theSeed = &(*data.i_seede_Pro++);
2426 *theSeed = *(*it_seedCandidate).second;
2427 } else {
2429 data.l_seeds_Pro.emplace_back(*(*it_seedCandidate).second);
2430 theSeed = &(data.l_seeds_Pro.back());
2431 data.i_seede_Pro = data.l_seeds_Pro.end();
2432 }
2433
2434 ++data.fillOneSeeds;
2435 }
2436}
2437
2439{
2441 if (not data.initialized) initializeEventData(data);
2442
2443 if (data.nspoint==3) {
2444 do {
2446 if (data.i_seed_Pro==data.i_seede_Pro) {
2451 findNext(data);
2453 //cppcheck-suppress identicalInnerCondition
2454 if (data.i_seed_Pro==data.i_seede_Pro) return nullptr;
2455 }
2457 } while (!(*data.i_seed_Pro++).set3(data.seedOutput));
2458
2460 return &data.seedOutput;
2461 } else {
2463 if (data.i_seed_Pro==data.i_seede_Pro) {
2464 findNext(data);
2465 //cppcheck-suppress identicalInnerCondition
2466 if (data.i_seed_Pro==data.i_seede_Pro) return nullptr;
2467 }
2468 (*data.i_seed_Pro++).set2(data.seedOutput);
2469 return &data.seedOutput;
2470 }
2471 return nullptr;
2472}
2473
2477void InDet::SiSpacePointsSeedMaker_ATLxk::writeNtuple(const SiSpacePointsSeed* seed, const Trk::Track* track, int seedType, long eventNumber) const{
2478
2479 if(m_writeNtuple) {
2480 std::lock_guard<std::mutex> lock(m_mutex);
2481
2482 if(track != nullptr) {
2483 m_trackPt = (track->trackParameters()->front()->pT())/1000.f;
2484 m_trackEta = std::abs(track->trackParameters()->front()->eta());
2485 }
2486 else {
2487 m_trackPt = -1.;
2488 m_trackEta = -1.;
2489 }
2490 m_d0 = seed->d0();
2491 m_z0 = seed->zVertex();
2492 m_eta = seed->eta();
2493 m_x1 = seed->x1();
2494 m_x2 = seed->x2();
2495 m_x3 = seed->x3();
2496 m_y1 = seed->y1();
2497 m_y2 = seed->y2();
2498 m_y3 = seed->y3();
2499 m_z1 = seed->z1();
2500 m_z2 = seed->z2();
2501 m_z3 = seed->z3();
2502 m_r1 = seed->r1();
2503 m_r2 = seed->r2();
2504 m_r3 = seed->r3();
2505 m_type = seedType;
2506 m_dzdr_b = seed->dzdr_b();
2507 m_dzdr_t = seed->dzdr_t();
2508 m_pt = seed->pt();
2509 m_givesTrack = !(track == nullptr);
2510 m_eventNumber = eventNumber;
2511
2512 // Ok: protected by mutex.
2513 TTree* outputTree ATLAS_THREAD_SAFE = m_outputTree;
2514 outputTree->Fill();
2515
2516 }
2517
2518}
2519
2521(EventData& data, const float Zv, const float R, const float T) const
2522{
2523 if (Zv < data.zminU or Zv > data.zmaxU) return false;
2524 if (not data.isvertex) return true;
2525 if (data.l_vertex.empty()) return false;
2526
2527 float dZmin = std::numeric_limits<float>::max();
2528 for (const float& v: data.l_vertex) {
2529 float dZ = std::abs(v-Zv);
2530 if (dZ >= dZmin) break;
2531 dZmin = dZ;
2532 }
2533
2534 //return dZmin < (m_dzver+m_dzdrver*R)*sqrt(1.+T*T);
2535 //(Minor) speed-up: Avoid calculation of sqrt, compare squares
2536 return dZmin*dZmin < (m_dzver+m_dzdrver*R)*(m_dzver+m_dzdrver*R)*(1.f+T*T);
2537}
2538
2542
2544(EventData& data, const Trk::SpacePoint*const& sp) const
2545{
2546 InDet::SiSpacePointForSeed* sps = nullptr;
2547
2550 std::array<float,3> r{0,0,0};
2552
2554 if (data.checketa) {
2555 float z = (std::abs(r[2])+m_zmax);
2556 float x = r[0]*data.dzdrmin;
2557 float y = r[1]*data.dzdrmin;
2558 if ((z*z )<(x*x+y*y)) return sps;
2559 }
2563 if (data.i_spforseed!=data.l_spforseed.end()) {
2565 sps = &(*data.i_spforseed++);
2568 sps->set(sp,r);
2569 } else {
2571 data.l_spforseed.emplace_back(sp, r);
2573 sps = &(data.l_spforseed.back());
2575 data.i_spforseed = data.l_spforseed.end();
2576 }
2577
2578 return sps;
2579}
2580
2582// New 2 space points seeds
2584
2587{
2588 InDet::SiSpacePointForSeed* p3 = nullptr;
2589
2590 if (data.i_seede_Pro!=data.l_seeds_Pro.end()) {
2591 SiSpacePointsProSeed* s = &(*data.i_seede_Pro++);
2592 s->set(p1, p2, p3, z);
2593 } else {
2594 data.l_seeds_Pro.emplace_back(p1, p2, p3, z);
2595 data.i_seede_Pro = data.l_seeds_Pro.end();
2596 }
2597}
2598
2600 int seedArrayPerSPSize = (m_maxOneSizePPP>m_maxOneSizeSSS ? m_maxOneSizePPP : m_maxOneSizeSSS);
2602 data.initialize(EventData::ToolType::ATLxk,
2604 seedArrayPerSPSize,
2605 0,
2606 m_nBinsR,
2607 0,
2610 m_checketa);
2611}
2612
2614
2616 if (bottomSP->spacepoint->clusterList().second){
2617 return (quality < m_seedScoreThresholdSSSConfirmationSeed);
2618 }
2620 else if (!topSP->spacepoint->clusterList().second){
2621 return (quality < m_seedScoreThresholdPPPConfirmationSeed);
2622 }
2624 else return (quality < 0.);
2625}
2626
const boost::regex re(r_e)
#define M_PI
Scalar phi() const
phi method
Scalar theta() const
theta method
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
static Double_t sp
static Double_t a
static Double_t sc
#define y
#define x
#define z
Define macros for attributes used to control the static checker.
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
Describes the API of the Region of Ineterest geometry.
virtual double phiPlus() const =0
extreme phi values
virtual double zedPlus() const =0
the zed and eta values at the most forward and most rear ends of the RoI
virtual double phiMinus() const =0
virtual double zedMinus() const =0
virtual double etaMinus() const =0
virtual double etaPlus() const =0
This is a "hash" representation of an Identifier.
Class to hold geometrical description of a silicon detector element.
const Trk::SpacePoint * spacepoint
float quality() const
penalty term in the seed score
void set(const Trk::SpacePoint *, std::span< float const, 3 >)
SiSpacePointForSeed * spacepoint0()
void set(SiSpacePointForSeed *&, SiSpacePointForSeed *&, SiSpacePointForSeed *&, float)
SiSpacePointForSeed * spacepoint2()
FloatProperty m_maxScore
Maximum score to accept.
virtual bool getWriteNtupleBoolProperty() const override
static void newSeed(EventData &data, SiSpacePointForSeed *&p1, SiSpacePointForSeed *&p2, float z)
SG::ReadHandleKey< SpacePointContainer > m_spacepointsSCT
virtual void find3Sp(const EventContext &ctx, EventData &data, const std::list< Trk::Vertex > &lv) const override
with three space points with or without vertex constraint
void newOneSeed(EventData &data, SiSpacePointForSeed *&p1, SiSpacePointForSeed *&p2, SiSpacePointForSeed *&p3, float z, float quality) const
This inserts a seed into the set of saved seeds.
std::array< std::array< int, arraySizeNeighbourBinsVertex >, arraySizePhiZV > m_neighboursVertexPhiZ
virtual void newRegion(const EventContext &ctx, EventData &data, const std::vector< IdentifierHash > &vPixel, const std::vector< IdentifierHash > &vSCT) const override
Initialize tool for new region.
void fillSeeds(EventData &data) const
fills the seeds from the mapOneSeeds_Pro member into the l_seeds_Pro member of the data object,...
virtual void find2Sp(EventData &data, const std::list< Trk::Vertex > &lv) const override
With two space points with or without vertex constraint.
float m_seedScoreThresholdPPPConfirmationSeed
Seed score thresholds defined based on the modifiers defined as configurables above.
SG::ReadHandleKey< SpacePointContainer > m_spacepointsPixel
int m_maxBinPhiVertex
number of bins in phi for vertices
void buildFrameWork()
prepare several data members with cached cut values, conversion factors, binnings,...
BooleanProperty m_optimisePhiBinning
This flag will make the buildFrameWork method determine an optimal phi binning of the search regions ...
bool newVertices(EventData &data, const std::list< Trk::Vertex > &lV) const
This method updates the EventData based on the passed list of vertices.
SG::ReadCondHandleKey< InDet::BeamSpotData > m_beamSpotKey
std::array< int, arraySizePhiZ > m_nNeighbourCellsBottom
arrays associating bins to each other for SP formation
FloatProperty m_dImpactCutSlopeUnconfirmedSSS
these flags allow to dynamically tighten the d0 cut on non-confirmed seeds based on the penalty score...
void fillLists(EventData &data) const
this method populates the data object's "histograms" (implemented as nested vectors).
MsgStream & dumpConditions(EventData &data, MsgStream &out) const
Dumps conditions information into the MsgStream.
void production3SpTrigger(EventData &data, std::array< std::vector< InDet::SiSpacePointForSeed * >::iterator, arraySizeNeighbourBins > &rb, std::array< std::vector< InDet::SiSpacePointForSeed * >::iterator, arraySizeNeighbourBins > &rbe, std::array< std::vector< InDet::SiSpacePointForSeed * >::iterator, arraySizeNeighbourBins > &rt, std::array< std::vector< InDet::SiSpacePointForSeed * >::iterator, arraySizeNeighbourBins > &rte, const int numberBottomCells, const int numberTopCells, int &nseed) const
as above, but for the trigger
void findNext(EventData &data) const
This method is called within next() when we are out of vertices.
static void convertToBeamFrameWork(EventData &data, const Trk::SpacePoint *const &sp, std::array< float, 3 > &r)
This method popualtes the r array with the space point's coordinates relative to the beam spot.
SiSpacePointForSeed * newSpacePoint(EventData &data, const Trk::SpacePoint *const &sp) const
Create a SiSpacePointForSeed from the space point.
static constexpr float m_radiusCutIBL
We detect IBL hits via the seed radial location.
virtual void findVSp(const EventContext &ctx, EventData &data, const std::list< Trk::Vertex > &lv) const override
with variable number space points with or without vertex constraint Variable means (2,...
float m_seedScoreThresholdSSSConfirmationSeed
max (score is assigned negative sign) score for SSS seeds with confirmation seed requirement.
FloatProperty m_seedScoreBonusPPP
Scoring modifiers applied when ranking seeds.
bool isConfirmedSeed(const InDet::SiSpacePointForSeed *bottomSP, const InDet::SiSpacePointForSeed *topSP, float quality) const
Helper method to determine if a seed is 'confirmed' - this means that a second seed exists with compa...
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCondObjInputKey
Read handle for conditions object to get the field cache.
float m_inverseBinSizePhiVertex
as above but for vertex
std::array< int, arraySizePhiZV > m_nNeighboursVertexPhiZ
SG::ReadHandleKey< SpacePointOverlapCollection > m_spacepointsOverlap
virtual void newEvent(const EventContext &ctx, EventData &data, int iteration) const override
Initialize tool for new event.
float m_inverseBinSizePhi
cache the inverse bin size in phi which we use - needed to evaluate phi bin locations
BooleanProperty m_alwaysKeepConfirmedPixelSeeds
This flag will lead to all confirmed seeds (seeds where a second compatible seed with a different top...
std::array< std::array< int, arraySizeNeighbourBins >, arraySizePhiZ > m_neighbourCellsBottom
mapping of neighbour cells in the 2D phi-z binning to consider for the "bottom SP" search for central...
bool isUsed(const Trk::SpacePoint *sp, const Trk::PRDtoTrackMap &prd_to_track_map) const
int m_nBinsR
number of bins in the radial coordinate
virtual StatusCode initialize() override
Initialisation.
IntegerProperty m_maxOneSizeSSS
maximum number of seeds to keep per central space point.
void buildBeamFrameWork(EventData &data) const
Initiate beam frame work for seed generator.
float m_ipt2
inverse square of 90% of the pt min cut
SG::ReadHandleKey< Trk::PRDtoTrackMap > m_prdToTrackMap
virtual StatusCode finalize() override
Finalize.
static constexpr float m_COF
appears to be an approximated term related to multiple-scattering of particles traversing the ID duri...
void newOneSeedWithCurvaturesComparison(EventData &data, SiSpacePointForSeed *&SPb, SiSpacePointForSeed *&SP0, float Zob) const
This creates all possible seeds with the passed central and bottom SP, using all top SP candidates wh...
virtual const SiSpacePointsSeed * next(const EventContext &ctx, EventData &data) const override
This method will update the data.seedOutput member to be the next seed pointed at by the data....
virtual MsgStream & dump(EventData &data, MsgStream &out) const override
Dumps relevant information into the MsgStream.
std::array< int, arraySizePhiZ > m_nNeighbourCellsTop
number of neighbouring phi-z bins to consider when looking for "top SP" candidates for each phi-z bin
bool isZCompatible(EventData &data, const float Zv, const float R, const float T) const
std::array< std::array< int, arraySizeNeighbourBins >, arraySizePhiZ > m_neighbourCellsTop
mapping of neighbour cells in the 2D phi-z binning to consider for the "top SP" search for central SP...
Gaudi::Property< bool > m_writeNtuple
Flag to write validation ntuples. Turned off by default.
float m_ipt
inverse of 90% of the ptmin cut
@ arraySizePhiZ
capacity for the 2D phi-z arrays
@ arraySizeNeighbourBins
array size to store neighbouring phi-z-regions in the seed finding
@ arraySizePhiZV
array size in phi-Z 2D for the vertexing
@ arraySizePhiV
array size in phi for vertexing
void production3Sp(EventData &data) const
Top-level method for 3-SP seed production.
static MsgStream & dumpEvent(EventData &data, MsgStream &out)
Dumps event information into the MsgStream.
float m_dzdrmin0
conversion factors and cached cut values
static float azimuthalStep(const float pTmin, const float maxd0, const float Rmin, const float Rmax)
Determine the expected azimuthal trajectory displacement in phi in presence of the magnetic field for...
virtual void writeNtuple(const SiSpacePointsSeed *seed, const Trk::Track *track, int seedType, long eventNumber) const override
This method is called by the SiSPSeededTrackFinder algorithm to fill ntuples for seeds seen by the al...
SiSpacePointsSeedMakerEventData EventData
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
bool solenoidOn() const
status of the magnets
void getFieldZR(const double *ATH_RESTRICT xyz, double *ATH_RESTRICT bxyz, double *ATH_RESTRICT deriv=nullptr)
get B field valaue on the z-r plane at given position works only inside the solenoid.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
const std::pair< const PrepRawData *, const PrepRawData * > & clusterList() const
return the pair of cluster pointers by reference
Abstract Base Class for tracking surfaces.
This class is a simplest representation of a vertex candidate.
int ir
counter of the current depth
Definition fastadd.cxx:49
int r
Definition globals.cxx:22
Eigen::Matrix< double, 3, 1 > Vector3D
-event-from-file
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
hold the test vectors and ease the comparison
MsgStream & msg
Definition testRead.cxx:32
Tell the compiler to optimize assuming that FP may trap.
#define CXXUTILS_TRAPPING_FP
Definition trapping_fp.h:24