ATLAS Offline Software
Loading...
Searching...
No Matches
ITkSiSpacePointsSeedMaker.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3 */
4
6// Implementation file for class ITk::SiSpacePointsSeedMaker
8// (c) ATLAS Detector software
10// AlgTool used for TRT_DriftCircleOnTrack object production
12// Version 1.0 21/04/2004 I.Gavrilenko
14
16
18
19
20//for validation
21#include "TrkTrack/Track.h"
24
25#include <cmath>
26
27#include <iomanip>
28#include <ostream>
29
30namespace ITk
31{
32
34// Constructor
36
37SiSpacePointsSeedMaker::SiSpacePointsSeedMaker(const std::string &t, const std::string &n, const IInterface *p)
38 : base_class(t, n, p),
39 m_thistSvc("THistSvc", n),
40 m_outputTree(nullptr),
41 m_treeName(""),
42 m_treeFolder("/valNtuples/")
43{
44 if (m_maxOneSize > 0)
45 {
48 }
49}
50
52// Initialisation
54
56{
57 StatusCode sc = AlgTool::initialize();
58
62
63 // Get beam geometry
64 //
65 ATH_CHECK(m_beamSpotKey.initialize());
66
68
69 // PRD-to-track association (optional)
70 ATH_CHECK(m_prdToTrackMap.initialize(!m_prdToTrackMap.key().empty()));
71
72 // Build framework
73 //
75
76 // Get output print level
77 //
78 m_outputlevel = msg().level() - MSG::DEBUG;
79
80 m_umax = 100. - std::abs(m_umax) * 300.;
81
82 if (m_writeNtuple) {
83 //coverity[MISSING_LOCK]
84 ATH_CHECK( m_thistSvc.retrieve() );
85
86 m_treeName = (std::string("SeedTree_")+name());
87 std::replace( m_treeName.begin(), m_treeName.end(), '.', '_' );
88
89 m_outputTree = new TTree( m_treeName.c_str() , "SeedMakerValTool");
90
91 m_outputTree->Branch("eventNumber", &m_eventNumber,"eventNumber/L");
92 m_outputTree->Branch("d0", &m_d0);
93 m_outputTree->Branch("z0", &m_z0);
94 m_outputTree->Branch("pt", &m_pt);
95 m_outputTree->Branch("eta", &m_eta);
96 m_outputTree->Branch("x1", &m_x1);
97 m_outputTree->Branch("x2", &m_x2);
98 m_outputTree->Branch("x3", &m_x3);
99 m_outputTree->Branch("y1", &m_y1);
100 m_outputTree->Branch("y2", &m_y2);
101 m_outputTree->Branch("y3", &m_y3);
102 m_outputTree->Branch("z1", &m_z1);
103 m_outputTree->Branch("z2", &m_z2);
104 m_outputTree->Branch("z3", &m_z3);
105 m_outputTree->Branch("r1", &m_r1);
106 m_outputTree->Branch("r2", &m_r2);
107 m_outputTree->Branch("r3", &m_r3);
108 m_outputTree->Branch("quality", &m_quality);
109 m_outputTree->Branch("seedType", &m_type);
110 m_outputTree->Branch("givesTrack", &m_givesTrack);
111 m_outputTree->Branch("dzdr_b", &m_dzdr_b);
112 m_outputTree->Branch("dzdr_t", &m_dzdr_t);
113 m_outputTree->Branch("track_pt", &m_trackPt);
114 m_outputTree->Branch("track_eta", &m_trackEta);
115
116 std::string fullTreeName = m_treeFolder + m_treeName;
117
118 ATH_CHECK( m_thistSvc->regTree( fullTreeName, m_outputTree ) );
119
120 }
121
122
123 return sc;
124}
125
127// Finalize
129
131{
132 return AlgTool::finalize();
133}
134
136// Initialize tool for new event
138
139void SiSpacePointsSeedMaker::newEvent(const EventContext &ctx, EventData &data, int iteration) const
140{
141 if (!m_pixel && !m_strip)
142 return;
143
145 if (not data.initialized)
146 initializeEventData(data, ctx);
147
149 erase(data);
150 data.trigger = false;
152 data.iteration = iteration;
153 if (iteration <= 0)
154 data.iteration = 0;
155 data.dzdrmin = m_dzdrmin0;
156 data.checketa = data.dzdrmin > 1.;
157 data.dzdrmax = m_dzdrmax0;
158 data.maxScore = m_maxScore;
159 data.r_first = 0;
160
162 float oneOverBinSizeR = 1. / m_binSizeR;
163 int maxBinR = m_nBinsR - 1;
164
166 data.i_ITkSpacePointForSeed = data.l_ITkSpacePointForSeed.begin();
167
168 bool isPixel = (m_fastTracking && m_pixel) || data.iteration == 1;
169
170 if (not isPixel)
171 {
172 // Now, we will populate the space point list in the event data object.
173
174 // Set the seed multiplicity strategy of the event data to the one configured
175 // by the user for strip seeds
176 data.maxSeedsPerSP = m_maxOneSizeSSS;
177 data.keepAllConfirmedSeeds = m_alwaysKeepConfirmedStripSeeds;
178
179 SG::ReadHandle<Trk::PRDtoTrackMap> prd_to_track_map;
180 const Trk::PRDtoTrackMap *prd_to_track_map_cptr = nullptr;
181 if (!m_prdToTrackMap.key().empty()) {
183 if (!prd_to_track_map.isValid()) {
184 ATH_MSG_ERROR("Failed to read PRD to track association map: " << m_prdToTrackMap.key());
185 }
186 prd_to_track_map_cptr = prd_to_track_map.cptr();
187 }
188
190 if (spacepointsStrip.isValid()) {
191 for (const SpacePointCollection *spc : *spacepointsStrip) {
192 for (const Trk::SpacePoint *sp : *spc) {
195 if ((prd_to_track_map_cptr && isUsed(sp, *prd_to_track_map_cptr)) || sp->r() > m_r_rmax || sp->r() < m_r_rmin)
196 continue;
199 if (!sps)
200 continue;
201
203 int radiusBin = static_cast<int>(sps->radius() * oneOverBinSizeR);
204 if (radiusBin > maxBinR)
205 radiusBin = maxBinR;
207 data.r_ITkSorted[radiusBin].push_back(sps);
209 ++data.r_map[radiusBin];
211 if (data.r_map[radiusBin] == 1)
212 data.r_index[data.nr++] = radiusBin;
214 ++data.ns;
215 }
216 }
217 }
219 if (m_useOverlap && !data.checketa) {
221 if (spacepointsOverlap.isValid()) {
222 for (const Trk::SpacePoint *sp : *spacepointsOverlap) {
224 if ((prd_to_track_map_cptr && isUsed(sp, *prd_to_track_map_cptr)) || sp->r() > m_r_rmax || sp->r() < m_r_rmin)
225 continue;
226
229 if (!sps)
230 continue;
231
233 int radiusBin = static_cast<int>(sps->radius() * oneOverBinSizeR);
234 if (radiusBin > maxBinR)
235 radiusBin = maxBinR;
237 data.r_ITkSorted[radiusBin].push_back(sps);
239 ++data.r_map[radiusBin];
241 if (data.r_map[radiusBin] == 1)
242 data.r_index[data.nr++] = radiusBin;
244 ++data.ns;
245 }
246 }
247 }
248 } else {
249
250 // Now, we will populate the space point list in the event data object.
251
252 // Set the seed multiplicity strategy of the event data to the one configured
253 // by the user for pixel seeds
254 data.maxSeedsPerSP = m_maxOneSizePPP;
255 data.keepAllConfirmedSeeds = m_alwaysKeepConfirmedPixelSeeds;
256
257 SG::ReadHandle<Trk::PRDtoTrackMap> prd_to_track_map;
258 const Trk::PRDtoTrackMap *prd_to_track_map_cptr = nullptr;
259 if (!m_prdToTrackMap.key().empty()) {
261 if (!prd_to_track_map.isValid()) {
262 ATH_MSG_ERROR("Failed to read PRD to track association map: " << m_prdToTrackMap.key());
263 }
264 prd_to_track_map_cptr = prd_to_track_map.cptr();
265 }
266
268 if (spacepointsPixel.isValid()) {
270 for (const SpacePointCollection *spc : *spacepointsPixel) {
271 for (const Trk::SpacePoint *sp : *spc) {
274 if ((prd_to_track_map_cptr && isUsed(sp, *prd_to_track_map_cptr)) || sp->r() > m_r_rmax || sp->r() < m_r_rmin)
275 continue;
276
283 if (!sps)
284 continue;
285
288 int radiusBin = static_cast<int>(sps->radius() * oneOverBinSizeR);
290 if (radiusBin > maxBinR)
291 radiusBin = maxBinR;
292
294 data.r_ITkSorted[radiusBin].push_back(sps);
296 ++data.r_map[radiusBin];
299 if (data.r_map[radiusBin] == 1)
300 data.r_index[data.nr++] = radiusBin;
302 ++data.ns;
303 }
304 }
305 }
306 }
307}
308
310// Initialize tool for new region
312
313void SiSpacePointsSeedMaker::newRegion(const EventContext &ctx, EventData &data,
314 const std::vector<IdentifierHash> &vPixel, const std::vector<IdentifierHash> &vStrip) const
315{
316 if (!m_pixel && !m_strip)
317 return;
318
319 if (not data.initialized)
320 initializeEventData(data, ctx);
321 erase(data);
322 data.iteration = 0;
323 data.trigger = false;
324 data.dzdrmin = m_dzdrmin0;
325 data.dzdrmax = m_dzdrmax0;
326 data.maxScore = m_maxScore;
327 data.r_first = 0;
328 data.checketa = false;
329
331 float oneOverBinSizeR = 1. / m_binSizeR; //was float irstep = 1.f/m_binSizeR;
332 int maxBinR = m_nBinsR - 1; //was int irmax = m_nBinsR-1;
333
335 data.i_ITkSpacePointForSeed = data.l_ITkSpacePointForSeed.begin();
336
337 SG::ReadHandle<Trk::PRDtoTrackMap> prd_to_track_map;
338 const Trk::PRDtoTrackMap *prd_to_track_map_cptr = nullptr;
339 if (!m_prdToTrackMap.key().empty())
340 {
342 if (!prd_to_track_map.isValid())
343 {
344 ATH_MSG_ERROR("Failed to read PRD to track association map: " << m_prdToTrackMap.key());
345 }
346 prd_to_track_map_cptr = prd_to_track_map.cptr();
347 }
348
349 // Get pixels space points containers from store gate
350 //
351 if (m_pixel && !vPixel.empty())
352 {
353
355 if (spacepointsPixel.isValid())
356 {
357 data.maxSeedsPerSP = m_maxOneSizePPP;
358
359 // Loop through all trigger collections
360 //
361 for (const IdentifierHash &l : vPixel)
362 {
363 const auto *w = spacepointsPixel->indexFindPtr(l);
364 if (w == nullptr)
365 continue;
366 for (const Trk::SpacePoint *sp : *w)
367 {
368 float r = sp->r();
369 if ((prd_to_track_map_cptr && isUsed(sp, *prd_to_track_map_cptr)) || r > m_r_rmax || r < m_r_rmin)
370 continue;
372 int ir = static_cast<int>(sps->radius() * oneOverBinSizeR);
373 if (ir > maxBinR)
374 ir = maxBinR;
375 data.r_ITkSorted[ir].push_back(sps);
376 ++data.r_map[ir];
377 if (data.r_map[ir] == 1)
378 data.r_index[data.nr++] = ir;
379 ++data.ns;
380 }
381 }
382 }
383 }
384
385 // Get strip space points containers from store gate
386 //
387 if (m_strip && !vStrip.empty())
388 {
389 data.maxSeedsPerSP = m_maxOneSizeSSS;
390
392 if (spacepointsStrip.isValid())
393 {
394
395 // Loop through all trigger collections
396 //
397 for (const IdentifierHash &l : vStrip)
398 {
399 const auto *w = spacepointsStrip->indexFindPtr(l);
400 if (w == nullptr)
401 continue;
402 for (const Trk::SpacePoint *sp : *w)
403 {
404 float r = sp->r();
405 if ((prd_to_track_map_cptr && isUsed(sp, *prd_to_track_map_cptr)) || r > m_r_rmax || r < m_r_rmin)
406 continue;
408 int ir = static_cast<int>(sps->radius() * oneOverBinSizeR);
409 if (ir > maxBinR)
410 ir = maxBinR;
411 data.r_ITkSorted[ir].push_back(sps);
412 ++data.r_map[ir];
413 if (data.r_map[ir] == 1)
414 data.r_index[data.nr++] = ir;
415 ++data.ns;
416 }
417 }
418 }
419 }
420}
421
422// Initialize tool for new region
424
425void SiSpacePointsSeedMaker::newRegion(const EventContext &ctx, EventData &data,
426 const std::vector<IdentifierHash> &vPixel, const std::vector<IdentifierHash> &vStrip, const IRoiDescriptor &IRD) const
427{
428 constexpr float twoPi = 2. * M_PI;
429
430 newRegion(ctx, data, vPixel, vStrip);
431 data.trigger = true;
432
433 double dzdrmin = 1. / std::tan(2. * std::atan(std::exp(-IRD.etaMinus())));
434 double dzdrmax = 1. / std::tan(2. * std::atan(std::exp(-IRD.etaPlus())));
435
436 data.zminB = IRD.zedMinus() - data.zbeam[0]; // min bottom Z
437 data.zmaxB = IRD.zedPlus() - data.zbeam[0]; // max bottom Z
438 data.zminU = data.zminB + 550. * dzdrmin;
439 data.zmaxU = data.zmaxB + 550. * dzdrmax;
440 double fmax = IRD.phiPlus();
441 double fmin = IRD.phiMinus();
442 if (fmin > fmax)
443 fmin -= twoPi;
444 data.ftrig = (fmin + fmax) * .5;
445 data.ftrigW = (fmax - fmin) * .5;
446}
447
448
450// Methods to initilize different strategies of seeds production
451// with two space points with or without vertex constraint
453
454void SiSpacePointsSeedMaker::find2Sp(EventData &/*data*/, const std::list<Trk::Vertex> &/*lv*/) const
455{
456 ATH_MSG_WARNING("ITk::SiSpacePointsSeedMaker::find2Sp not implemented!");
457}
458
460// Methods to initilize different strategies of seeds production
461// with three space points with or without vertex constraint
463
464void SiSpacePointsSeedMaker::find3Sp(const EventContext & ctx, EventData &data, const std::list<Trk::Vertex> &lv) const
465{
466 if (not data.initialized)
467 initializeEventData(data, ctx);
468
470 fillLists(data);
471
473 data.zminU = m_zmin;
474 data.zmaxU = m_zmax;
476 int mode = 2;
477 if (lv.begin() != lv.end())
478 mode = 3;
483 bool newv = newVertices(data, lv);
485 if (newv || !data.state || data.nspoint != 3 || data.mode != mode || data.nlist)
486 {
487 data.i_ITkSeedEnd = data.i_ITkSeeds.begin();
488 data.state = 1;
489 data.nspoint = 3;
490 data.nlist = 0;
491 data.mode = mode;
492 data.endlist = true;
493 data.fvNmin = 0;
494 data.fNmin = 0;
495 data.zMin = 0;
496 production3Sp(data);
497 }
498
501 data.i_ITkSeed = data.i_ITkSeeds.begin();
502
503 if (msgLvl(MSG::DEBUG))
504 {
505 data.nprint = 1;
506 dump(data, msg(MSG::DEBUG));
507 }
508}
509
511// Methods to initilize different strategies of seeds production
512// with three space points with or without vertex constraint
514
515void SiSpacePointsSeedMaker::find3Sp(const EventContext &ctx, EventData &data, const std::list<Trk::Vertex> &lv, const double *ZVertex) const
516{
517 if (not data.initialized)
518 initializeEventData(data, ctx);
519
521 fillLists(data);
522
525 data.zminU = ZVertex[0];
526 if (data.zminU < m_zmin)
527 data.zminU = m_zmin;
528 data.zmaxU = ZVertex[1];
529 if (data.zmaxU > m_zmax)
530 data.zmaxU = m_zmax;
531
533 int mode = 2;
534 if (lv.begin() != lv.end())
535 mode = 3;
540 bool newv = newVertices(data, lv);
542 if (newv || !data.state || data.nspoint != 3 || data.mode != mode || data.nlist)
543 {
544 data.i_ITkSeedEnd = data.i_ITkSeeds.begin();
545 data.state = 1;
546 data.nspoint = 3;
547 data.nlist = 0;
548 data.mode = mode;
549 data.endlist = true;
550 data.fvNmin = 0;
551 data.fNmin = 0;
552 data.zMin = 0;
553 production3Sp(data);
554 }
557 data.i_ITkSeed = data.i_ITkSeeds.begin();
558
559 if (msgLvl(MSG::DEBUG))
560 {
561 data.nprint = 1;
562 dump(data, msg(MSG::DEBUG));
563 }
564}
565
567// Methods to initilize different strategies of seeds production
568// with variable number space points with or without vertex constraint
569// Variable means (2,3,4,....) any number space points
571
572void SiSpacePointsSeedMaker::findVSp(const EventContext &ctx, EventData &data, const std::list<Trk::Vertex> &lv) const
573{
574
575 if (not data.initialized)
576 initializeEventData(data, ctx);
577
579 fillLists(data);
580
581 data.zminU = m_zmin;
582 data.zmaxU = m_zmax;
583
584 int mode = 5;
585 if (lv.begin() != lv.end())
586 mode = 6;
587 bool newv = newVertices(data, lv);
588
589 if (newv || !data.state || data.nspoint != 4 || data.mode != mode || data.nlist)
590 {
591 data.i_ITkSeedEnd = data.i_ITkSeeds.begin();
592 data.state = 1;
593 data.nspoint = 4;
594 data.nlist = 0;
595 data.mode = mode;
596 data.endlist = true;
597 data.fvNmin = 0;
598 data.fNmin = 0;
599 data.zMin = 0;
600 production3Sp(data);
601 }
602 data.i_ITkSeed = data.i_ITkSeeds.begin();
603
604 if (msgLvl(MSG::DEBUG))
605 {
606 data.nprint = 1;
607 dump(data, msg(MSG::DEBUG));
608 }
609}
610
612// Dumps relevant information into the MsgStream
614
615MsgStream &SiSpacePointsSeedMaker::dump(EventData &data, MsgStream &out) const
616{
617 if (data.nprint)
618 return dumpEvent(data, out);
619 return dumpConditions(data, out);
620}
621
623// Dumps conditions information into the MsgStream
625
626MsgStream &SiSpacePointsSeedMaker::dumpConditions(EventData &data, MsgStream &out) const
627{
628 int n = 42-m_spacepointsPixel.key().size();
629 std::string s2;
630 for (int i=0; i<n; ++i) s2.append(" ");
631 s2.append("|");
632 n = 42-m_spacepointsStrip.key().size();
633 std::string s3;
634 for (int i=0; i<n; ++i) s3.append(" ");
635 s3.append("|");
636 n = 42-m_spacepointsOverlap.key().size();
637 std::string s4;
638 for (int i=0; i<n; ++i) s4.append(" ");
639 s4.append("|");
640 n = 42-m_beamSpotKey.key().size();
641 std::string s5;
642 for (int i=0; i<n; ++i) s5.append(" ");
643 s5.append("|");
644
645 out<<"|---------------------------------------------------------------------|"
646 <<endmsg;
647 out<<"| Pixel space points | "<<m_spacepointsPixel.key() <<s2
648 <<endmsg;
649 out<<"| Strip space points | "<<m_spacepointsStrip.key()<<s3
650 <<endmsg;
651 out<<"| Overlap space points | "<<m_spacepointsOverlap.key()<<s4
652 <<endmsg;
653 out<<"| BeamConditionsService | "<<m_beamSpotKey.key()<<s5
654 <<endmsg;
655 out<<"| usePixel | "
656 <<std::setw(12)<<m_pixel
657 <<" |"<<endmsg;
658 out<<"| useStrip | "
659 <<std::setw(12)<<m_strip
660 <<" |"<<endmsg;
661 out<<"| maxSize | "
662 <<std::setw(12)<<m_maxsize
663 <<" |"<<endmsg;
664 out<<"| maxSizeSP | "
665 <<std::setw(12)<<m_maxsizeSP
666 <<" |"<<endmsg;
667 out<<"| pTmin (mev) | "
668 <<std::setw(12)<<std::setprecision(5)<<m_ptmin
669 <<" |"<<endmsg;
670 out<<"| max radius SP | "
671 <<std::setw(12)<<std::setprecision(5)<<m_r_rmax
672 <<" |"<<endmsg;
673 out<<"| radius step | "
674 <<std::setw(12)<<std::setprecision(5)<<m_binSizeR
675 <<" |"<<endmsg;
676 out<<"| min Z-vertex position | "
677 <<std::setw(12)<<std::setprecision(5)<<m_zmin
678 <<" |"<<endmsg;
679 out<<"| max Z-vertex position | "
680 <<std::setw(12)<<std::setprecision(5)<<m_zmax
681 <<" |"<<endmsg;
682 out<<"| min space points dR SSS | "
683 <<std::setw(12)<<std::setprecision(5)<<m_drminSSS
684 <<" |"<<std::endl;
685 out<<"| max space points dR SSS | "
686 <<std::setw(12)<<std::setprecision(5)<<m_drmaxSSS
687 <<" |"<<std::endl;
688 out<<"| min space points dR PPP | "
689 <<std::setw(12)<<std::setprecision(5)<<m_drminPPP
690 <<" |"<<std::endl;
691 out<<"| max space points dR PPP | "
692 <<std::setw(12)<<std::setprecision(5)<<m_drmaxPPP
693 <<" |"<<std::endl;
694 out<<"| max dZ impact | "
695 <<std::setw(12)<<std::setprecision(5)<<m_dzver
696 <<" |"<<endmsg;
697 out<<"| max dZ/dR impact | "
698 <<std::setw(12)<<std::setprecision(5)<<m_dzdrver
699 <<" |"<<endmsg;
700 out<<"| max impact | "
701 <<std::setw(12)<<std::setprecision(5)<<m_maxdImpact
702 <<" |"<<endmsg;
703 out<<"| max impact sss | "
704 <<std::setw(12)<<std::setprecision(5)<<m_maxdImpactSSS
705 <<" |"<<endmsg;
706 out<<"|---------------------------------------------------------------------|"
707 <<endmsg;
708 out<<"| Beam X center | "
709 <<std::setw(12)<<std::setprecision(5)<<data.xbeam[0]
710 <<" |"<<endmsg;
711 out<<"| Beam Y center | "
712 <<std::setw(12)<<std::setprecision(5)<<data.ybeam[0]
713 <<" |"<<endmsg;
714 out<<"| Beam Z center | "
715 <<std::setw(12)<<std::setprecision(5)<<data.zbeam[0]
716 <<" |"<<endmsg;
717 out<<"| Beam X-axis direction | "
718 <<std::setw(12)<<std::setprecision(5)<<data.xbeam[1]
719 <<std::setw(12)<<std::setprecision(5)<<data.xbeam[2]
720 <<std::setw(12)<<std::setprecision(5)<<data.xbeam[3]
721 <<" |"<<endmsg;
722 out<<"| Beam Y-axis direction | "
723 <<std::setw(12)<<std::setprecision(5)<<data.ybeam[1]
724 <<std::setw(12)<<std::setprecision(5)<<data.ybeam[2]
725 <<std::setw(12)<<std::setprecision(5)<<data.ybeam[3]
726 <<" |"<<endmsg;
727 out<<"| Beam Z-axis direction | "
728 <<std::setw(12)<<std::setprecision(5)<<data.zbeam[1]
729 <<std::setw(12)<<std::setprecision(5)<<data.zbeam[2]
730 <<std::setw(12)<<std::setprecision(5)<<data.zbeam[3]
731 <<" |"<<endmsg;
732 out<<"|---------------------------------------------------------------------|"
733 <<endmsg;
734 return out;
735
736
737}
738
740// Dumps event information into the MsgStream
742
743MsgStream &SiSpacePointsSeedMaker::dumpEvent(EventData &data, MsgStream &out)
744{
745 out<<"|---------------------------------------------------------------------|"
746 <<endmsg;
747 out<<"| ns | "
748 <<std::setw(12)<<data.ns
749 <<" |"<<endmsg;
750 out<<"| nsaz | "
751 <<std::setw(12)<<data.nsaz
752 <<" |"<<endmsg;
753 out<<"| nsazv | "
754 <<std::setw(12)<<data.nsazv
755 <<" |"<<endmsg;
756 out<<"| seeds | "
757 <<std::setw(12)<<data.i_ITkSeeds.size()
758 <<" |"<<endmsg;
759 out<<"|---------------------------------------------------------------------|"
760 <<endmsg;
761 return out;
762
763}
764
766// Find next set space points
768
770{
771 if (data.endlist)
772 return;
773
774 data.i_ITkSeedEnd = data.i_ITkSeeds.begin();
775
776 if (data.mode == 2 || data.mode == 3 || data.mode == 5 || data.mode == 6)
777 production3Sp(data);
778
779 data.i_ITkSeed = data.i_ITkSeeds.begin();
780 ++data.nlist;
781}
782
784// New and old list vertices comparison
786
787bool SiSpacePointsSeedMaker::newVertices(EventData &data, const std::list<Trk::Vertex> &lV) const
788{
789
790 unsigned int s1 = data.l_vertex.size();
791 unsigned int s2 = lV.size();
792
794 data.isvertex = false;
797 if (s1 == 0 && s2 == 0)
798 return false;
799
801 data.l_vertex.clear();
803 if (s2 == 0)
804 return false;
805
807 data.isvertex = true;
808 for (const Trk::Vertex &v : lV)
809 {
810 data.l_vertex.insert(static_cast<float>(v.position().z()));
811 }
812
815 data.zminU = (*data.l_vertex.begin()) - 20.;
816 if (data.zminU < m_zmin)
817 data.zminU = m_zmin;
818 data.zmaxU = (*data.l_vertex.rbegin()) + 20.;
819 if (data.zmaxU > m_zmax)
820 data.zmaxU = m_zmax;
821
822 return false;
823}
824
826// Initiate frame work for seed generator
828
830{
831 m_ptmin = std::abs(m_ptmin);
832
833 if (m_ptmin < 100.)
834 m_ptmin = 100.;
835
839
841 if (std::abs(m_etamin) < .1)
844 m_dzdrmax0 = 1. / std::tan(2. * std::atan(std::exp(-m_etamax)));
845 m_dzdrmin0 = 1. / std::tan(2. * std::atan(std::exp(-m_etamin)));
846
848 m_ipt = 1. / std::abs(m_ptmin);
849 m_ipt2 = m_ipt * m_ipt;
850
859
861 m_nBinsR = static_cast<int>((m_r_rmax + .1) / m_binSizeR);
862
867
869 constexpr float twoPi = 2. * M_PI;
870
872 const int nPhiBinsMax = arraySizePhi;
873 const float inverseSizePhiMax = static_cast<float>(nPhiBinsMax) / twoPi;
874 constexpr float inverseSizePhiMin = 10. / twoPi;
875
881
883 {
885 const float radiusPixelStart = m_fastTracking ? 50. : 40.;
886 const float radiusPixelEnd = m_fastTracking ? 250. : 320.;
887 const float binSizePhi_PPP = m_pixel ? azimuthalStep(m_ptmin, m_maxdImpact, radiusPixelStart, radiusPixelEnd) / 3.f : 1.f;
889 const float binSizePhi_SSS = m_strip ? azimuthalStep(m_ptmin, m_maxdImpactSSS, m_rminSSS, m_rmaxSSS) / 3.f : 1.f;
890 m_inverseBinSizePhiPPP = 1. / binSizePhi_PPP;
891 m_inverseBinSizePhiSSS = 1. / binSizePhi_SSS;
892 }
893 else
894 {
897 float ptm = 400.;
899 if (m_ptmin < ptm)
900 ptm = m_ptmin;
902 }
903
905 if (m_inverseBinSizePhiPPP > inverseSizePhiMax)
906 m_inverseBinSizePhiPPP = inverseSizePhiMax;
907 else if (m_inverseBinSizePhiPPP < inverseSizePhiMin)
908 m_inverseBinSizePhiPPP = inverseSizePhiMin;
909 if (m_inverseBinSizePhiSSS > inverseSizePhiMax)
910 m_inverseBinSizePhiSSS = inverseSizePhiMax;
911 else if (m_inverseBinSizePhiSSS < inverseSizePhiMin)
912 m_inverseBinSizePhiSSS = inverseSizePhiMin;
913
915 m_maxPhiBinPPP = static_cast<int>(twoPi * m_inverseBinSizePhiPPP);
917 if (m_maxPhiBinPPP >= nPhiBinsMax) m_maxPhiBinPPP = nPhiBinsMax - 1;
918 m_maxPhiBinSSS = static_cast<int>(twoPi * m_inverseBinSizePhiSSS);
919 if (m_maxPhiBinSSS >= nPhiBinsMax) m_maxPhiBinSSS = nPhiBinsMax - 1;
921 m_inverseBinSizePhiPPP = ( m_maxPhiBinPPP + 1 ) / twoPi;
922 m_inverseBinSizePhiSSS = ( m_maxPhiBinSSS + 1 ) / twoPi;
923
924 // Build radius-azimuthal-Z sorted containers for Z-vertices
926 const int nPhiBinsVertexMax = arraySizePhiV;
927 const float inverseBinSizePhiVertexMax = static_cast<float>(nPhiBinsVertexMax)/twoPi;
929 if (m_inverseBinSizePhiVertex > inverseBinSizePhiVertexMax) m_inverseBinSizePhiVertex = inverseBinSizePhiVertexMax;
930 m_maxBinPhiVertex = static_cast<int>(twoPi*m_inverseBinSizePhiVertex);
931 if (m_maxBinPhiVertex>=nPhiBinsVertexMax) m_maxBinPhiVertex = nPhiBinsVertexMax-1;
932
935 m_maxPhiBinPPP, false);
936
939 m_maxPhiBinSSS, true);
940
944
945}
946
947void SiSpacePointsSeedMaker::buildConnectionMaps(std::array<int, arraySizePhiZ> &nNeighbourCellsBottom,
948 std::array<int, arraySizePhiZ> &nNeighbourCellsTop,
949 std::array<std::array<int, arraySizeNeighbourBins>, arraySizePhiZ> &neighbourCellsBottom,
950 std::array<std::array<int, arraySizeNeighbourBins>, arraySizePhiZ> &neighbourCellsTop,
951 int maxPhiBin, bool isSSS)
952{
953
957
958 for (int phiBin = 0; phiBin <= maxPhiBin; ++phiBin)
959 {
960
961 int phiBelow = phiBin - 1;
962 if (phiBelow < 0) phiBelow = maxPhiBin;
963
964 int phiAbove = phiBin + 1;
965 if (phiAbove > maxPhiBin) phiAbove = 0;
966
968 for (int z = 0; z < arraySizeZ; ++z) {
969
972
973 int twoDbinSamePhi = phiBin * arraySizeZ + z;
974 int twoDbinLowerPhi = phiBelow * arraySizeZ + z;
975 int twoDbinHigherPhi = phiAbove * arraySizeZ + z;
976
977 nNeighbourCellsBottom[twoDbinSamePhi] = 3;
978 nNeighbourCellsTop[twoDbinSamePhi] = 3;
979
980 neighbourCellsBottom[twoDbinSamePhi][0] = twoDbinSamePhi;
981 neighbourCellsTop[twoDbinSamePhi][0] = twoDbinSamePhi;
982
983 neighbourCellsBottom[twoDbinSamePhi][1] = twoDbinLowerPhi;
984 neighbourCellsTop[twoDbinSamePhi][1] = twoDbinLowerPhi;
985
986 neighbourCellsBottom[twoDbinSamePhi][2] = twoDbinHigherPhi;
987 neighbourCellsTop[twoDbinSamePhi][2] = twoDbinHigherPhi;
988
997 if (z == 5)
998 {
999 nNeighbourCellsTop[twoDbinSamePhi] = 9;
1000 // in the central z region, we include the two neighbouring
1001 // z slices for the top neighbour search
1002
1003 neighbourCellsTop[twoDbinSamePhi][3] = twoDbinSamePhi + 1;
1004 neighbourCellsTop[twoDbinSamePhi][4] = twoDbinLowerPhi + 1;
1005 neighbourCellsTop[twoDbinSamePhi][5] = twoDbinHigherPhi + 1;
1006 neighbourCellsTop[twoDbinSamePhi][6] = twoDbinSamePhi - 1;
1007 neighbourCellsTop[twoDbinSamePhi][7] = twoDbinLowerPhi - 1;
1008 neighbourCellsTop[twoDbinSamePhi][8] = twoDbinHigherPhi - 1;
1009 }
1010 // z > 5: positive z values, |z| > 250mm
1011 else if (z > 5)
1012 {
1013 // for the bottom SP search in positive non-central z, we include the
1014 // neighbouring Z region on the left (towards the IP) in the bottom
1015 // neighbour search
1016 nNeighbourCellsBottom[twoDbinSamePhi] = 6;
1017 neighbourCellsBottom[twoDbinSamePhi][3] = twoDbinSamePhi - 1;
1018 neighbourCellsBottom[twoDbinSamePhi][4] = twoDbinLowerPhi - 1;
1019 neighbourCellsBottom[twoDbinSamePhi][5] = twoDbinHigherPhi - 1;
1020
1021 if (z < 10)
1022 {
1028 nNeighbourCellsTop[twoDbinSamePhi] = 6;
1029 neighbourCellsTop[twoDbinSamePhi][3] = twoDbinSamePhi + 1;
1030 neighbourCellsTop[twoDbinSamePhi][4] = twoDbinLowerPhi + 1;
1031 neighbourCellsTop[twoDbinSamePhi][5] = twoDbinHigherPhi + 1;
1032 }
1033 }
1034 // z < 5: negative z values, |z| > 250mm
1035 else
1036 {
1041 nNeighbourCellsBottom[twoDbinSamePhi] = 6;
1042 neighbourCellsBottom[twoDbinSamePhi][3] = twoDbinSamePhi + 1;
1043 neighbourCellsBottom[twoDbinSamePhi][4] = twoDbinLowerPhi + 1;
1044 neighbourCellsBottom[twoDbinSamePhi][5] = twoDbinHigherPhi + 1;
1045
1046 if (z > 0)
1047 {
1048 // if there is a z region on the left (away from the IP), we include it in the top
1049 // neighbour search
1050 nNeighbourCellsTop[twoDbinSamePhi] = 6;
1051 neighbourCellsTop[twoDbinSamePhi][3] = twoDbinSamePhi - 1;
1052 neighbourCellsTop[twoDbinSamePhi][4] = twoDbinLowerPhi - 1;
1053 neighbourCellsTop[twoDbinSamePhi][5] = twoDbinHigherPhi - 1;
1054 }
1055 }
1056
1063 if (isSSS)
1064 {
1065 if (z == 3)
1066 {
1067 nNeighbourCellsBottom[twoDbinSamePhi] = 9;
1068 neighbourCellsBottom[twoDbinSamePhi][6] = twoDbinSamePhi + 2;
1069 neighbourCellsBottom[twoDbinSamePhi][7] = twoDbinLowerPhi + 2;
1070 neighbourCellsBottom[twoDbinSamePhi][8] = twoDbinHigherPhi + 2;
1071 }
1072 else if (z == 7)
1073 {
1074 nNeighbourCellsBottom[twoDbinSamePhi] = 9;
1075 neighbourCellsBottom[twoDbinSamePhi][6] = twoDbinSamePhi - 2;
1076 neighbourCellsBottom[twoDbinSamePhi][7] = twoDbinLowerPhi - 2;
1077 neighbourCellsBottom[twoDbinSamePhi][8] = twoDbinHigherPhi - 2;
1078 }
1079 }
1080 }
1081 }
1082}
1083
1087
1088void SiSpacePointsSeedMaker::buildConnectionMapsVertex(std::array<int, arraySizePhiZV> &nNeighbourCells,
1089 std::array<std::array<int, arraySizeNeighbourBinsVertex>, arraySizePhiZV> &neighbourCells,
1090 int maxPhiBin)
1091{
1092 for (int phiBin=0; phiBin<=maxPhiBin; ++phiBin) {
1093
1094 int phiBinBelow = phiBin-1;
1095 if (phiBinBelow<0) phiBinBelow=maxPhiBin;
1096
1097 int phiBinTop = phiBin+1;
1098 if (phiBinTop>maxPhiBin) phiBinTop=0;
1099
1101 for (int zbin=0; zbin<arraySizeZV; ++zbin) {
1102
1103 int twoDbinSamePhi = phiBin*arraySizeZV+zbin;
1104 int twoDbinLowerPhi = phiBinBelow*arraySizeZV+zbin;
1105 int twoDbinHigherPhi = phiBinTop*arraySizeZV+zbin;
1106
1108 nNeighbourCells[twoDbinSamePhi] = 3;
1109 neighbourCells[twoDbinSamePhi][0] = twoDbinSamePhi;
1110 neighbourCells[twoDbinSamePhi][1] = twoDbinLowerPhi;
1111 neighbourCells[twoDbinSamePhi][2] = twoDbinHigherPhi;
1112
1114 if (zbin>1) {
1115 nNeighbourCells[twoDbinSamePhi] = 6;
1116 neighbourCells[twoDbinSamePhi][3] = twoDbinSamePhi-1;
1117 neighbourCells[twoDbinSamePhi][4] = twoDbinLowerPhi-1;
1118 neighbourCells[twoDbinSamePhi][5] = twoDbinHigherPhi-1;
1119 }
1121 else if (zbin<1) {
1122 nNeighbourCells[twoDbinSamePhi] = 6;
1123 neighbourCells[twoDbinSamePhi][3] = twoDbinSamePhi+1;
1124 neighbourCells[twoDbinSamePhi][4] = twoDbinLowerPhi+1;
1125 neighbourCells[twoDbinSamePhi][5] = twoDbinHigherPhi+1;
1126 }
1127 }
1128 }
1129}
1130
1131float SiSpacePointsSeedMaker::azimuthalStep(const float pTmin, const float maxd0, const float Rmin, const float Rmax)
1132{
1136 float Rm = pTmin / .6;
1137
1144 float worstCaseD0 = maxd0;
1145 if (maxd0 > Rmin)
1146 worstCaseD0 = Rmin;
1147
1148 float sI = std::abs(std::asin(worstCaseD0 / Rmin) - std::asin(worstCaseD0 / Rmax));
1149 float sF = std::abs(std::asin(std::min(1., Rmax / (2. * Rm))) -
1150 std::asin(std::min(1., Rmin / (2. * Rm))));
1151 return sI + sF;
1152}
1153
1155// Initiate beam frame work for seed generator
1157
1159{
1161
1162 const Amg::Vector3D &cb = beamSpotHandle->beamPos();
1163 double tx = std::tan(beamSpotHandle->beamTilt(0));
1164 double ty = std::tan(beamSpotHandle->beamTilt(1));
1165
1166 double phi = std::atan2(ty, tx);
1167 double theta = std::acos(1. / std::sqrt(1. + tx * tx + ty * ty));
1168 double sinTheta = std::sin(theta);
1169 double cosTheta = std::cos(theta);
1170 double sinPhi = std::sin(phi);
1171 double cosPhi = std::cos(phi);
1172
1173 data.xbeam[0] = static_cast<float>(cb.x());
1174 data.xbeam[1] = static_cast<float>(cosTheta * cosPhi * cosPhi + sinPhi * sinPhi);
1175 data.xbeam[2] = static_cast<float>(cosTheta * sinPhi * cosPhi - sinPhi * cosPhi);
1176 data.xbeam[3] = -static_cast<float>(sinTheta * cosPhi);
1177
1178 data.ybeam[0] = static_cast<float>(cb.y());
1179 data.ybeam[1] = static_cast<float>(cosTheta * cosPhi * sinPhi - sinPhi * cosPhi);
1180 data.ybeam[2] = static_cast<float>(cosTheta * sinPhi * sinPhi + cosPhi * cosPhi);
1181 data.ybeam[3] = -static_cast<float>(sinTheta * sinPhi);
1182
1183 data.zbeam[0] = static_cast<float>(cb.z());
1184 data.zbeam[1] = static_cast<float>(sinTheta * cosPhi);
1185 data.zbeam[2] = static_cast<float>(sinTheta * sinPhi);
1186 data.zbeam[3] = static_cast<float>(cosTheta);
1187}
1188
1190// Initiate beam frame work for seed generator
1193{
1194 r[0] = static_cast<float>(sp->globalPosition().x()) - data.xbeam[0];
1195 r[1] = static_cast<float>(sp->globalPosition().y()) - data.ybeam[0];
1196 r[2] = static_cast<float>(sp->globalPosition().z()) - data.zbeam[0];
1197}
1198
1200// Initiate space points seed maker
1202
1204{
1205 constexpr float twoPi = 2. * M_PI;
1206
1207 int firstRadialBin = 0;
1208 int lastRadialBin = 0;
1209 bool endcap = false;
1210
1223
1224 const std::map<float, int> ztoBin{
1225 {-2500., 0},
1226 {-1400., 1},
1227 {-925., 2},
1228 {-500., 3},
1229 {-250., 4},
1230 {250., 5},
1231 {500., 6},
1232 {925., 7},
1233 {1400, 8},
1234 {2500, 9},
1235 {100000, 10},
1236 };
1237
1238 bool isPixel = (m_fastTracking && m_pixel) || data.iteration == 1;
1239
1240 int nPhiBins = isPixel ? m_maxPhiBinPPP : m_maxPhiBinSSS;
1241 float inverseBinSizePhi = isPixel ? m_inverseBinSizePhiPPP : m_inverseBinSizePhiSSS;
1242
1243 for (int radialBin = data.r_first; radialBin < m_nBinsR; ++radialBin)
1244 {
1246 if (!data.r_map[radialBin])
1247 continue;
1248
1249 // Stop when we reach strip SP in PPP iteration #1
1250 std::vector<SiSpacePointForSeed *>::iterator SP_first = data.r_ITkSorted[radialBin].begin();
1251 if (isPixel && (*SP_first)->spacepoint->clusterList().second)
1252 break;
1253
1255 if (firstRadialBin == 0)
1256 firstRadialBin = radialBin;
1257 lastRadialBin = radialBin;
1258
1259 // loop over the space points in the r-bin and sort them into the 2d phi-z binning
1260 for (SiSpacePointForSeed *SP : data.r_ITkSorted[radialBin])
1261 {
1262
1265 float Phi = SP->phi();
1266 if (Phi < 0.)
1267 Phi += twoPi; // phi is defined in [0..2pi] for the binning
1268 int phiBin = static_cast<int>(Phi * inverseBinSizePhi);
1270 if (phiBin < 0)
1271 {
1272 phiBin = nPhiBins;
1273 }
1274 else if (phiBin > nPhiBins)
1275 {
1276 phiBin = 0;
1277 }
1278
1279 float Z = SP->z();
1280 endcap = (std::abs(Z) > 1490);
1287 int zBin{0};
1288 auto bound = ztoBin.lower_bound(Z);
1290 if (bound == ztoBin.end())
1291 {
1292 --bound;
1293 }
1294 zBin = bound->second;
1295
1297 int twoDbin = phiBin * arraySizeZ + zBin;
1300 ++data.nsaz;
1301 // push our space point into the 2D binned array
1302 data.rfz_ITkSorted[twoDbin].push_back(SP);
1303
1307 if (!data.rfz_map[twoDbin]++)
1308 data.rfz_index[data.nrfz++] = twoDbin;
1309 }
1310 }
1311
1312 data.state = 0;
1313
1314 if (m_fastTracking) {
1315 // Loop through all RZ collections and sort them in radius order
1316 //
1317 for (int twoDbin(0); twoDbin != arraySizePhiZ; ++twoDbin) {
1318 if (data.rfz_ITkSorted[twoDbin].size() > 1) {
1319 std::sort(data.rfz_ITkSorted[twoDbin].begin(), data.rfz_ITkSorted[twoDbin].end(), SiSpacePointsComparison_R());
1320 }
1321 }
1322
1323 if (m_strip) {
1324 data.RTmin = m_rminSSS ;
1325 data.RTmax = m_rmaxSSS ;
1326 }
1327
1328 } else {
1329 if (isPixel) { // PPP
1330 data.RTmin = m_binSizeR*firstRadialBin+10. ;
1331 data.RTmax = m_binSizeR*lastRadialBin-10.;
1332 } else { //SSS
1333 if (endcap and m_isLRT) {
1334 data.RTmin = m_binSizeR*firstRadialBin+10. ;
1335 data.RTmax = m_binSizeR*lastRadialBin-10.;
1336 } else {
1337 data.RTmin = m_binSizeR*firstRadialBin+30. ;
1338 data.RTmax = m_binSizeR*lastRadialBin-150.;
1339 }
1340 }
1341 }
1342
1343}
1344
1346// Pixels information
1348
1350{
1351 const InDet::SiCluster *cl = static_cast<const InDet::SiCluster *>(sp->clusterList().first);
1352 const InDetDD::SiDetectorElement *de = cl->detectorElement();
1353 const Amg::Transform3D &Tp = de->surface().transform();
1354 r[3] = float(Tp(0, 2));
1355 r[4] = float(Tp(1, 2));
1356 r[5] = float(Tp(2, 2));
1357}
1358
1360// Strip information
1362
1364{
1365 const InDet::SiCluster *c0 = static_cast<const InDet::SiCluster *>(sp->clusterList().first);
1366 const InDet::SiCluster *c1 = static_cast<const InDet::SiCluster *>(sp->clusterList().second);
1367 const InDetDD::SiDetectorElement *d0 = c0->detectorElement();
1368 const InDetDD::SiDetectorElement *d1 = c1->detectorElement();
1369
1370 Amg::Vector2D lc0 = c0->localPosition();
1371 Amg::Vector2D lc1 = c1->localPosition();
1372
1373 std::pair<Amg::Vector3D, Amg::Vector3D> e0 =
1374 (d0->endsOfStrip(InDetDD::SiLocalPosition(lc0.y(), lc0.x(), 0.)));
1375 std::pair<Amg::Vector3D, Amg::Vector3D> e1 =
1376 (d1->endsOfStrip(InDetDD::SiLocalPosition(lc1.y(), lc1.x(), 0.)));
1377
1378 Amg::Vector3D s0(.5 * (e0.first + e0.second));
1379 Amg::Vector3D s1(.5 * (e1.first + e1.second));
1380
1381 Amg::Vector3D b0(.5 * (e0.second - e0.first));
1382 Amg::Vector3D b1(.5 * (e1.second - e1.first));
1383 Amg::Vector3D d02(s0 - s1);
1384
1385 // b0
1386 r[3] = float(b0[0]);
1387 r[4] = float(b0[1]);
1388 r[5] = float(b0[2]);
1389
1390 // b1
1391 r[6] = float(b1[0]);
1392 r[7] = float(b1[1]);
1393 r[8] = float(b1[2]);
1394
1395 // r0-r2
1396 r[9] = float(d02[0]);
1397 r[10] = float(d02[1]);
1398 r[11] = float(d02[2]);
1399
1400 // r0
1401 r[12] = float(s0[0]) - data.xbeam[0];
1402 r[13] = float(s0[1]) - data.ybeam[0];
1403 r[14] = float(s0[2]) - data.zbeam[0];
1404}
1405
1407// Erase space point information
1409
1411{
1412 for (int i = 0; i < data.nrfz; ++i)
1413 {
1414 int n = data.rfz_index[i];
1415 data.rfz_map[n] = 0;
1416 data.rfz_ITkSorted[n].clear();
1417 }
1418
1419 for (int i = 0; i < data.nrfzv; ++i)
1420 {
1421 int n = data.rfzv_index[i];
1422 data.rfzv_map[n] = 0;
1423 data.rfzv_ITkSorted[n].clear();
1424 }
1425
1426 for (int i = 0; i < data.nr; ++i) {
1427 int n = data.r_index[i];
1428 data.r_map[n] = 0;
1429 data.r_ITkSorted[n].clear();
1430 }
1431
1432 data.state = 0;
1433 data.nsaz = 0;
1434 data.nsazv = 0;
1435 data.nrfz = 0;
1436 data.nrfzv = 0;
1437 data.ns = 0;
1438 data.nr = 0;
1439}
1440
1442// 2 space points seeds production
1444
1446{
1447 ATH_MSG_WARNING("ITk::SiSpacePointsSeedMaker::production2Sp not implemented!");
1448}
1449
1451// Production 3 space points seeds
1453
1455{
1457 if (data.nsaz < 3)
1458 return;
1459
1470
1478 const std::array<int, arraySizeZ> zBinIndex_SSS{5, 6, 4, 7, 3, 8, 2, 9, 1, 10, 0};
1479 const std::array<int, arraySizeZ> zBinIndex_PPP_fast{0, 10, 1, 9, 2, 8, 5, 3, 7, 4, 6};
1480 const std::array<int, arraySizeZ> zBinIndex_PPP_long{0, 1, 2, 3, 10, 9, 8, 7, 5, 4, 6};
1481 const auto zBinIndex_PPP = m_fastTracking ? zBinIndex_PPP_fast : zBinIndex_PPP_long;
1482 // Fast tracking runs a single iteration, either pixel or strip
1483 // Default tracking runs a 0-th iteration for strip then a 1-st for pixel
1484 bool isPixel = (m_fastTracking && m_pixel) || data.iteration == 1;
1485 const auto zBinIndex = isPixel ? zBinIndex_PPP : zBinIndex_SSS;
1486
1487 const float RTmax[11] = { 80., 200., 200., 200., 250., 250., 250., 200., 200., 200., 80.};
1488 const float RTmin[11] = { 40., 40., 70., 70., 70., 70., 70., 70., 70., 40., 40.};
1489
1492 std::array<std::vector<SiSpacePointForSeed *>::iterator, arraySizeNeighbourBins> iter_topCands;
1493 std::array<std::vector<SiSpacePointForSeed *>::iterator, arraySizeNeighbourBins> iter_endTopCands;
1494 std::array<std::vector<SiSpacePointForSeed *>::iterator, arraySizeNeighbourBins> iter_bottomCands;
1495 std::array<std::vector<SiSpacePointForSeed *>::iterator, arraySizeNeighbourBins> iter_endBottomCands;
1496
1497 int nPhiBins;
1498 std::array<int, arraySizePhiZ> nNeighbourCellsBottom{};
1499 std::array<int, arraySizePhiZ> nNeighbourCellsTop{};
1500 //coverity[STACK_USE]
1501 std::array<std::array<int, arraySizeNeighbourBins>, arraySizePhiZ> neighbourCellsBottom{};
1502 // Local variable neighbourCellsTop uses 79200 bytes of stack space,
1503 //coverity[STACK_USE]
1504 std::array<std::array<int, arraySizeNeighbourBins>, arraySizePhiZ> neighbourCellsTop{};
1505
1506 if (isPixel)
1507 {
1508 nPhiBins = m_maxPhiBinPPP;
1509 nNeighbourCellsBottom = m_nNeighbourCellsBottomPPP;
1510 nNeighbourCellsTop = m_nNeighbourCellsTopPPP;
1511 neighbourCellsBottom = m_neighbourCellsBottomPPP;
1512 neighbourCellsTop = m_neighbourCellsTopPPP;
1513 }
1514 else
1515 {
1516 nPhiBins = m_maxPhiBinSSS;
1517 nNeighbourCellsBottom = m_nNeighbourCellsBottomSSS;
1518 nNeighbourCellsTop = m_nNeighbourCellsTopSSS;
1519 neighbourCellsBottom = m_neighbourCellsBottomSSS;
1520 neighbourCellsTop = m_neighbourCellsTopSSS;
1521 }
1522
1524 int nseed = 0;
1526 data.endlist = true;
1527
1529 for (int phiBin = data.fNmin; phiBin <= nPhiBins; ++phiBin)
1530 {
1531
1533 int z = (m_fastTracking && m_pixel) ? 2 : 0;
1535 if (!data.endlist)
1536 z = data.zMin;
1537
1541 for (; z < arraySizeZ; ++z)
1542 {
1543
1544 if (m_fastTracking && m_pixel)
1545 {
1546 data.RTmax = RTmax[ zBinIndex[z] ];
1547 data.RTmin = RTmin[ zBinIndex[z] ];
1548 }
1549
1550 int phiZbin = phiBin * arraySizeZ + zBinIndex[z];
1551
1553 if (!data.rfz_map[phiZbin])
1554 continue;
1555
1558 int numberBottomCells = 0;
1559 int numberTopCells = 0;
1560
1565 for (int neighbourCellNumber = 0; neighbourCellNumber < nNeighbourCellsBottom[phiZbin]; ++neighbourCellNumber)
1566 {
1567
1568 int theNeighbourCell = neighbourCellsBottom[phiZbin][neighbourCellNumber];
1570 if (!data.rfz_map[theNeighbourCell])
1571 continue;
1573 //cppcheck-suppress objectIndex; false positive
1574 iter_bottomCands[numberBottomCells] = data.rfz_ITkSorted[theNeighbourCell].begin();
1575 //cppcheck-suppress objectIndex; false positive
1576 iter_endBottomCands[numberBottomCells++] = data.rfz_ITkSorted[theNeighbourCell].end();
1577 }
1578
1583 for (int neighbourCellNumber = 0; neighbourCellNumber < nNeighbourCellsTop[phiZbin]; ++neighbourCellNumber)
1584 {
1585
1586 int theNeighbourCell = neighbourCellsTop[phiZbin][neighbourCellNumber];
1588 if (!data.rfz_map[theNeighbourCell])
1589 continue;
1591 //cppcheck-suppress objectIndex; false positive
1592 iter_topCands[numberTopCells] = data.rfz_ITkSorted[theNeighbourCell].begin();
1593 //cppcheck-suppress objectIndex; false positive
1594 iter_endTopCands[numberTopCells++] = data.rfz_ITkSorted[theNeighbourCell].end();
1595 }
1596
1598 if (!data.trigger)
1599 {
1600 if (isPixel)
1601 production3SpPPP(data, iter_bottomCands, iter_endBottomCands, iter_topCands, iter_endTopCands, numberBottomCells, numberTopCells, nseed);
1602 else
1603 production3SpSSS(data, iter_bottomCands, iter_endBottomCands, iter_topCands, iter_endTopCands, numberBottomCells, numberTopCells, nseed);
1604 }
1605 else
1606 production3SpTrigger(data, iter_bottomCands, iter_endBottomCands, iter_topCands, iter_endTopCands, numberBottomCells, numberTopCells, nseed);
1607 }
1608
1615 if (nseed >= m_maxsize)
1616 {
1617 data.endlist = false;
1618 data.fNmin = phiBin + 1;
1619 return;
1620 }
1621 }
1622
1624 data.endlist = true;
1625}
1626
1628// Production 3 pixel space points seeds for full scan
1630
1632 std::array<std::vector<SiSpacePointForSeed *>::iterator, arraySizeNeighbourBins> &iter_bottomCands,
1633 std::array<std::vector<SiSpacePointForSeed *>::iterator, arraySizeNeighbourBins> &iter_endBottomCands,
1634 std::array<std::vector<SiSpacePointForSeed *>::iterator, arraySizeNeighbourBins> &iter_topCands,
1635 std::array<std::vector<SiSpacePointForSeed *>::iterator, arraySizeNeighbourBins> &iter_endTopCands,
1636 const int numberBottomCells, const int numberTopCells, int &nseed) const
1637{
1638
1644
1646 std::vector<SiSpacePointForSeed *>::iterator iter_centralSP = iter_bottomCands[0];
1647
1653
1655 for (; iter_centralSP != iter_endBottomCands[0]; ++iter_centralSP)
1656 {
1657 if((*iter_centralSP)->radius() > data.RTmin) break;
1658 }
1659
1662 iter_topCands[0] = iter_centralSP;
1663 ++iter_topCands[0];
1664
1666 const float &ipt2K = data.ipt2K;
1667 const float &ipt2C = data.ipt2C;
1668 const float &COFK = data.COFK;
1669 const float &maxd0cut = m_maxdImpact;
1670 const float &zmax = data.zmaxU;
1671 const float &dzdrmax = data.dzdrmax;
1672 data.ITkCmSp.clear();
1673
1676 size_t SPcapacity = data.ITkSP.size();
1677
1679 for (; iter_centralSP != iter_endBottomCands[0]; ++iter_centralSP)
1680 {
1681 const float &R = (*iter_centralSP)->radius();
1682
1683 if(R > data.RTmax)
1684 break;
1685
1687 const float &X = (*iter_centralSP)->x();
1688 const float &Y = (*iter_centralSP)->y();
1689 const float &Z = (*iter_centralSP)->z();
1690
1693 double absZ = std::abs(Z);
1694 if (!m_fastTracking && absZ > m_zmaxPPP)
1695 continue;
1696
1697 float covr0 = (*iter_centralSP)->covr();
1698 float covz0 = (*iter_centralSP)->covz();
1699 float Ri = 1. / R;
1700 float ax = X * Ri;
1701 float ay = Y * Ri;
1702 float VR = maxd0cut / (R * R);
1703 size_t Ntm = 2;
1704 if (R > m_rmaxPPP)
1705 Ntm = 1;
1706
1709 size_t Nt = 0;
1710
1713 for (int cell = 0; cell < numberTopCells; ++cell)
1714 {
1715 std::vector<SiSpacePointForSeed *>::iterator iter_otherSP = iter_topCands[cell], iter_otherSPend = iter_endTopCands[cell];
1716 if (iter_otherSP == iter_otherSPend) continue;
1717
1718 for(; iter_otherSP!=iter_otherSPend; ++iter_otherSP) {
1719 if(( (*iter_otherSP)->radius()- R ) >= m_drminPPP) break;
1720 }
1721 iter_topCands[cell]=iter_otherSP;
1722
1724 for (; iter_otherSP != iter_endTopCands[cell]; ++iter_otherSP)
1725 {
1727 float Rt = (*iter_otherSP)->radius();
1728 float dR = Rt - R;
1729
1730 const float dz = (*iter_otherSP)->z() - Z;
1731 const float dZdR = dz / dR;
1734 const float z0 = Z - R * dZdR;
1735 if (std::abs(z0) > zmax)
1736 continue;
1737
1738 float dx = (*iter_otherSP)->x() - X;
1739 float dy = (*iter_otherSP)->y() - Y;
1740 float x = dx * ax + dy * ay;
1741 float y = dy * ax - dx * ay;
1742 float dxy = x * x + y * y;
1743 float r2 = 1. / dxy;
1744 float u = x * r2;
1745 float v = y * r2;
1746
1747 if (std::abs(R * y) > maxd0cut * x)
1748 {
1749 float V0;
1750 y < 0. ? V0 = VR : V0 = -VR;
1751 float A = (v - V0) / (u + 1. / R);
1752 float B = V0 + A / R;
1753 if ((B * B) > (ipt2K * (1. + A * A)))
1754 continue;
1755 }
1756
1757 const float dr = std::sqrt(r2);
1758 const float tz = dz * dr;
1760 if (std::abs(tz) > dzdrmax)
1761 continue;
1762
1764 data.ITkSP[Nt] = (*iter_otherSP);
1765 data.R[Nt] = dr;
1766 data.U[Nt] = u;
1767 data.V[Nt] = v;
1768 data.Er[Nt] = ((covz0 + (*iter_otherSP)->covz()) + (tz * tz) * (covr0 + (*iter_otherSP)->covr())) * r2;
1769 data.ITkSP[Nt]->setDR(std::sqrt(dxy + dz * dz));
1770 data.ITkSP[Nt]->setDZDR(dZdR);
1771 data.Tn[Nt].Fl = tz;
1772 data.Tn[Nt].In = Nt;
1773
1777 if (++Nt == SPcapacity)
1778 {
1779 size_t increment = 50;
1780 data.resizeSPCont(increment, InDet::SiSpacePointsSeedMakerEventData::ToolType::ITk);
1781 SPcapacity = data.ITkSP.size();
1782 }
1783 }
1784 }
1785
1786 if (Nt < Ntm)
1787 continue;
1788
1792 size_t Nb = Nt;
1793
1796 for (int cell = 0; cell < numberBottomCells; ++cell)
1797 {
1798
1799 std::vector<SiSpacePointForSeed*>::iterator iter_otherSP = iter_bottomCands[cell];
1800
1801 for(; iter_otherSP!=iter_endBottomCands[cell]; ++iter_otherSP) {
1802 if( (R - (*iter_otherSP)->radius()) <= m_drmaxPPP) break;
1803 }
1804 iter_bottomCands[cell]=iter_otherSP;
1805
1807 for (; iter_otherSP != iter_endBottomCands[cell]; ++iter_otherSP)
1808 {
1810 const float &Rb = (*iter_otherSP)->radius();
1811 float dR = R - Rb;
1812
1814 if (dR < m_drminPPP)
1815 break;
1816
1817 const float dz = Z - (*iter_otherSP)->z();
1818 const float dZdR = dz / dR;
1821 const float z0 = Z - R * dZdR;
1822 if (std::abs(z0) > zmax)
1823 continue;
1824
1825 float dx = (*iter_otherSP)->x() - X;
1826 float dy = (*iter_otherSP)->y() - Y;
1827 float x = dx * ax + dy * ay;
1828 float y = dy * ax - dx * ay;
1829 float dxy = ( x * x + y * y );
1830 float r2 = 1. / dxy;
1831 float u = x * r2;
1832 float v = y * r2;
1833
1834 if (std::abs(R * y) > -maxd0cut * x)
1835 {
1836 float V0;
1837 y > 0. ? V0 = VR : V0 = -VR;
1838 float A = (v - V0) / (u + 1. / R);
1839 float B = V0 + A / R;
1840 if ((B * B) > (ipt2K * (1. + A * A)))
1841 continue;
1842 }
1843
1844 const float dr = std::sqrt(r2);
1845 const float tz = dz * dr;
1847 if (std::abs(tz) > dzdrmax)
1848 continue;
1849
1850 //Updated to 45mm for ITk layout 03-00-00
1851 if (m_fastTracking && (*iter_otherSP)->radius() < 45. && std::abs(tz) > 1.5)
1852 continue;
1853
1855 data.ITkSP[Nb] = (*iter_otherSP);
1856 data.R[Nb] = dr;
1857 data.U[Nb] = u;
1858 data.V[Nb] = v;
1859 data.Er[Nb] = ((covz0 + (*iter_otherSP)->covz()) + (tz * tz) * (covr0 + (*iter_otherSP)->covr())) * r2;
1860 data.ITkSP[Nb]->setDR(std::sqrt(dxy + dz * dz));
1861 data.ITkSP[Nb]->setDZDR(dZdR);
1862 data.Tn[Nb].Fl = tz;
1863 data.Tn[Nb].In = Nb;
1864
1868 if (++Nb == SPcapacity)
1869 {
1870 size_t increment = 50;
1871 data.resizeSPCont(increment, InDet::SiSpacePointsSeedMakerEventData::ToolType::ITk);
1872 SPcapacity = data.ITkSP.size();
1873 }
1874
1875 }
1876 }
1877
1879 if (!(Nb - Nt))
1880 continue;
1881
1882 sort(data.Tn,0,Nt);
1883 sort(data.Tn,Nt,Nb-Nt);
1884
1885 data.nOneSeeds = 0;
1886 data.nOneSeedsQ = 0;
1887 data.ITkMapOneSeeds.clear();
1888 data.ITkMapOneSeedsQ.clear();
1889
1892 size_t it0 = 0;
1893 for (size_t ib = Nt; ib < Nb; ++ib)
1894 {
1895
1896 if (it0 == Nt)
1897 break;
1898
1900 float Tzb = data.Tn[ib].Fl;
1901 int b = data.Tn[ib].In;
1902
1903 float Rb2r = data.R[b] * covr0;
1904 float Rb2z = data.R[b] * covz0;
1905 float Erb = data.Er[b];
1906 float Vb = data.V[b];
1907 float Ub = data.U[b];
1908 float Tzb2 = (1. + Tzb * Tzb);
1909 float sTzb2 = std::sqrt(Tzb2);
1910
1911 float sigmaSquaredScatteringPtDependent = Tzb2 * COFK;
1912 float sigmaSquaredScatteringMinPt = Tzb2 * ipt2C;
1915 float d0max = maxd0cut;
1916
1917 size_t Nc = 1;
1918 if (data.ITkSP[b]->radius() > m_rmaxPPP){
1919 Nc = 0;
1920 }
1921 if (data.nOneSeedsQ)
1922 ++Nc;
1923
1925 for (size_t it = it0; it < Nt; ++it)
1926 {
1927
1928 int t = data.Tn[it].In; // index of top seed after sorting
1929 float Tzt = data.Tn[it].Fl;
1930
1935
1937 float meanOneOverTanThetaSquare = Tzb * Tzt; // SSS uses arithmetic average, PPP geometric average
1938
1940 float sigmaSquaredSpacePointErrors = Erb + data.Er[t]
1941 + 2 * Rb2z * data.R[t]
1942 + 2 * Rb2r * data.R[t] * meanOneOverTanThetaSquare; // mixed term with r-uncertainy on central SP
1943
1945 float remainingSquaredDelta = (Tzb - Tzt) * (Tzb - Tzt) - sigmaSquaredSpacePointErrors;
1946
1949 if (remainingSquaredDelta - sigmaSquaredScatteringMinPt > 0)
1950 {
1951 if (Tzb - Tzt < 0.)
1952 break;
1953 it0 = it + 1 ;
1954 continue;
1955 }
1956
1978
1979 float dU = data.U[t] - Ub;
1980 if (dU == 0.)
1981 continue;
1982 float A = (data.V[t] - Vb) / dU;
1983 float onePlusAsquare = 1. + A * A;
1984 float B = Vb - A * Ub;
1985 float BSquare = B * B;
1986
1999 if (BSquare > ipt2K * onePlusAsquare)
2000 continue;
2001 if (remainingSquaredDelta * onePlusAsquare > BSquare * sigmaSquaredScatteringPtDependent)
2002 {
2003 if (Tzb - Tzt < 0.)
2004 break;
2005 it0 = it;
2006 continue;
2007 }
2008
2025 float d0 = std::abs((A - B * R) * R);
2026
2028 if (d0 <= d0max)
2029 {
2031 float dr = data.R[b];
2032 if (data.R[t] < data.R[b])
2033 dr = data.R[t];
2037 data.ITkSP[t]->setScorePenalty(std::abs((Tzb - Tzt) / (dr * sTzb2)));
2038 data.ITkSP[t]->setParam(d0);
2039
2041 data.ITkCmSp.emplace_back(B / std::sqrt(onePlusAsquare), data.ITkSP[t]);
2043 if (data.ITkCmSp.size() == 500)
2044 break;
2045 }
2046
2047 }
2049
2050 if (data.ITkCmSp.size() > Nc)
2051 {
2052 newOneSeedWithCurvaturesComparisonPPP(data, data.ITkSP[b], (*iter_centralSP), Z - R * Tzb);
2053 }
2054 data.ITkCmSp.clear();
2055 }
2057 fillSeeds(data);
2058 nseed += data.fillOneSeeds;
2059
2060 }
2061}
2062
2066
2068 std::array<std::vector<SiSpacePointForSeed *>::iterator, arraySizeNeighbourBins> &iter_bottomCands,
2069 std::array<std::vector<SiSpacePointForSeed *>::iterator, arraySizeNeighbourBins> &iter_endBottomCands,
2070 std::array<std::vector<SiSpacePointForSeed *>::iterator, arraySizeNeighbourBins> &iter_topCands,
2071 std::array<std::vector<SiSpacePointForSeed *>::iterator, arraySizeNeighbourBins> &iter_endTopCands,
2072 const int numberBottomCells, const int numberTopCells, int &nseed) const
2073{
2074
2080
2082 std::vector<SiSpacePointForSeed *>::iterator iter_centralSP = iter_bottomCands[0];
2083 std::vector<SiSpacePointForSeed *>::iterator iter_otherSP;
2084
2090
2092 for (; iter_centralSP != iter_endBottomCands[0]; ++iter_centralSP)
2093 {
2094 if((*iter_centralSP)->radius() > data.RTmin) break;
2095 }
2096
2099 iter_topCands[0] = iter_centralSP;
2100 ++iter_topCands[0];
2101
2103 const float ipt2K = data.ipt2K;
2104 const float ipt2C = data.ipt2C;
2105 const float COFK = data.COFK;
2106 const float maxd0cut = m_maxdImpactSSS;
2107 const float zmax = data.zmaxU;
2108 data.ITkCmSp.clear();
2109
2112 size_t SPcapacity = data.ITkSP.size();
2113
2115 for (; iter_centralSP != iter_endBottomCands[0]; ++iter_centralSP)
2116 {
2117
2118 const float &R = (*iter_centralSP)->radius();
2119
2120 if(R > data.RTmax) break;
2121
2123 const float &X = (*iter_centralSP)->x();
2124 const float &Y = (*iter_centralSP)->y();
2125 const float &Z = (*iter_centralSP)->z();
2126
2129 double absZ = std::abs(Z);
2131 if (absZ > m_zmaxSSS)
2132 continue;
2133
2136 size_t Nt = 0;
2137
2140 for (int cell = 0; cell < numberTopCells; ++cell)
2141 {
2142
2143 for (iter_otherSP = iter_topCands[cell]; iter_otherSP != iter_endTopCands[cell]; ++iter_otherSP)
2144 {
2146 float Rt = (*iter_otherSP)->radius();
2147 float dR = Rt - R;
2148 if (dR >= m_drminSSS)
2149 break;
2150 }
2151 iter_topCands[cell] = iter_otherSP;
2152
2154 for (iter_otherSP = iter_topCands[cell]; iter_otherSP != iter_endTopCands[cell]; ++iter_otherSP)
2155 {
2156
2158 float Rt = (*iter_otherSP)->radius();
2159 float dR = Rt - R;
2161 if (dR > m_drmaxSSS)
2162 break;
2163
2164 const float dz = (*iter_otherSP)->z() - Z;
2165 const float dZdR = dz / dR;
2166
2169 const float z0 = Z - R * dZdR;
2170 if (std::abs(dz) > m_dzmaxSSS || std::abs(z0) > zmax)
2171 continue;
2172
2174 if(m_isLRT){
2175 float Ri = 1./R;
2176 const float ax = X*Ri;
2177 const float ay = Y*Ri;
2178 float VR = m_maxdImpact*Ri*Ri ;
2179 float dx = (*iter_otherSP)->x() - X;
2180 float dy = (*iter_otherSP)->y() - Y;
2181 float x = dx * ax + dy * ay;
2182 float y = dy * ax - dx * ay;
2183
2184 if(std::abs(R*y) > maxd0cut * x) {
2185 float r2 = 1. / (x * x + y * y);
2186 float u = x*r2 ;
2187 float v = y*r2 ;
2188 const float V0 = (y < 0.) ? VR: -VR;
2189 float A = (v-V0)/(u+Ri) ;
2190 float B = V0+A*Ri ;
2191 if((B*B) > (ipt2K*(1.+A*A))) continue;
2192 }
2193 }
2194
2196 data.ITkSP[Nt] = (*iter_otherSP);
2197 data.ITkSP[Nt]->setDZDR(dZdR);
2201 if (++Nt == SPcapacity)
2202 {
2203 data.resizeSPCont();
2204 SPcapacity = data.ITkSP.size();
2205 }
2206 }
2207 }
2208
2210 if (!Nt)
2211 continue;
2212
2216 size_t Nb = Nt;
2217
2220 for (int cell = 0; cell < numberBottomCells; ++cell)
2221 {
2222
2223 for(iter_otherSP=iter_bottomCands[cell]; iter_otherSP!=iter_endBottomCands[cell]; ++iter_otherSP) {
2224 if((R-(*iter_otherSP)->radius()) <= m_drmaxSSS) break;
2225 }
2226 iter_bottomCands[cell]=iter_otherSP;
2227
2229 for (; iter_otherSP != iter_endBottomCands[cell]; ++iter_otherSP)
2230 {
2231
2233 const float &Rb = (*iter_otherSP)->radius();
2234 float dR = R - Rb;
2235
2237 if (dR < m_drminSSS)
2238 break;
2239
2240 const float dz = Z - (*iter_otherSP)->z();
2241 const float dZdR = dz / dR;
2242
2245 const float z0 = Z - R * dZdR;
2246 if (std::abs(dz) > m_dzmaxSSS || std::abs(z0) > zmax)
2247 continue;
2248
2250 if(m_isLRT){
2251 float Ri = 1./R;
2252 const float ax = X*Ri;
2253 const float ay = Y*Ri;
2254 float VR = m_maxdImpact*Ri*Ri ;
2255 float dx = (*iter_otherSP)->x() - X;
2256 float dy = (*iter_otherSP)->y() - Y;
2257 float x = dx * ax + dy * ay;
2258 float y = dy * ax - dx * ay;
2259
2260 if(std::abs(R*y) > -maxd0cut * x) {
2261 float r2 = 1. / (x * x + y * y);
2262 float u = x*r2 ;
2263 float v = y*r2 ;
2264 const float V0 = (y < 0.) ? VR: -VR;
2265 float A = (v-V0)/(u+Ri) ;
2266 float B = V0+A*Ri ;
2267 if((B*B) > (ipt2K*(1.+A*A))) continue;
2268 }
2269 }
2270
2272 data.ITkSP[Nb] = (*iter_otherSP);
2273 data.ITkSP[Nb]->setDZDR(dZdR);
2277 if (++Nb == SPcapacity)
2278 {
2279 data.resizeSPCont();
2280 SPcapacity = data.ITkSP.size();
2281 }
2282 }
2283 }
2284
2286 if (!(Nb - Nt))
2287 continue;
2288
2290 float covr0 = (*iter_centralSP)->covr();
2291 float covz0 = (*iter_centralSP)->covz();
2292
2294 float ax = X / R;
2295 float ay = Y / R;
2296
2299 for (size_t i = 0; i < Nb; ++i)
2300 {
2301
2302 SiSpacePointForSeed *sp = data.ITkSP[i];
2303
2306 float dx = sp->x() - X;
2307 float dy = sp->y() - Y;
2308 float dz = sp->z() - Z;
2309 float x = dx * ax + dy * ay;
2310 float y = dy * ax - dx * ay;
2311
2313 float r2 = 1. / (x * x + y * y);
2315 float dr = std::sqrt(r2);
2318 float tz = dz * dr;
2319
2322 if (i >= Nt)
2323 tz = -tz;
2324
2326 data.X[i] = x;
2327 data.Y[i] = y;
2328 data.Tz[i] = tz;
2329 data.Zo[i] = Z - R * tz;
2330 data.R[i] = dr;
2331 data.U[i] = x * r2;
2332 data.V[i] = y * r2;
2333 data.Er[i] = ((covz0 + sp->covz()) + (tz * tz) * (covr0 + sp->covr())) * r2;
2334 }
2335
2336 data.nOneSeeds = 0;
2337 data.nOneSeedsQ = 0;
2338 data.ITkMapOneSeeds.clear();
2339 data.ITkMapOneSeedsQ.clear();
2340
2343 for (size_t b = Nt; b < Nb; ++b)
2344 {
2345
2347 float Zob = data.Zo[b];
2348 float Tzb = data.Tz[b];
2349 float Rb2r = data.R[b] * covr0;
2350 float Rb2z = data.R[b] * covz0;
2351 float Erb = data.Er[b];
2352 float Vb = data.V[b];
2353 float Ub = data.U[b];
2354 float Tzb2 = (1. + Tzb * Tzb);
2355 float sTzb2 = std::sqrt(Tzb2);
2356 float Se = 1. / std::sqrt(Tzb2);
2357 float Ce = Se * Tzb;
2358 float Sx = Se * ax;
2359 float Sy = Se * ay;
2360
2361 float sigmaSquaredScatteringPtDependent = Tzb2 * COFK;
2362 float sigmaSquaredScatteringMinPt = Tzb2 * ipt2C;
2365 float d0max = maxd0cut;
2366
2368 for (size_t t = 0; t < Nt; ++t)
2369 {
2370
2392
2393 // Trigger point
2394 //
2395 float dU0 = data.U[t] - Ub;
2396 if (dU0 == 0.)
2397 continue;
2398 float A0 = (data.V[t] - Vb) / dU0;
2399
2400 float Cn = Ce * std::sqrt(1. + A0 * A0);
2401
2402 float dn[3] = {Sx - Sy * A0, Sx * A0 + Sy, Cn};
2403 float rn[3];
2404 if (!(*iter_centralSP)->coordinates(dn, rn))
2405 continue;
2406
2407 // Bottom point
2408 //
2409 float B0 = 2. * (Vb - A0 * Ub);
2410 float Cb = 1. - B0 * data.Y[b];
2411 float Sb = A0 + B0 * data.X[b];
2412 float db[3] = {Sx * Cb - Sy * Sb, Sx * Sb + Sy * Cb, Cn};
2413 float rb[3];
2414 if (!data.ITkSP[b]->coordinates(db, rb))
2415 continue;
2416
2417 // Top point
2418 //
2419 float Ct = 1. - B0 * data.Y[t];
2420 float St = A0 + B0 * data.X[t];
2421 float dt[3] = {Sx * Ct - Sy * St, Sx * St + Sy * Ct, Cn};
2422 float rt[3];
2423 if (!data.ITkSP[t]->coordinates(dt, rt))
2424 continue;
2425
2426 float xb = rb[0] - rn[0];
2427 float yb = rb[1] - rn[1];
2428 float zb = rb[2] - rn[2];
2429 float xt = rt[0] - rn[0];
2430 float yt = rt[1] - rn[1];
2431 float zt = rt[2] - rn[2];
2432
2433 float rb2 = 1. / (xb * xb + yb * yb);
2434 float rt2 = 1. / (xt * xt + yt * yt);
2435
2436 float tb = -zb * std::sqrt(rb2);
2437 float tz = zt * std::sqrt(rt2);
2438
2443
2445 float meanOneOverTanTheta = (tb + tz) / 2.;
2446
2448 float sigmaSquaredSpacePointErrors = Erb + data.Er[t]
2449 + 2 * Rb2z * data.R[t]
2450 + 2 * Rb2r * data.R[t] * meanOneOverTanTheta * meanOneOverTanTheta; // mixed term with r-uncertainy on central SP
2451
2453 float remainingSquaredDelta = (tb - tz) * (tb - tz) - sigmaSquaredSpacePointErrors;
2454
2457 if (remainingSquaredDelta - sigmaSquaredScatteringMinPt > 0)
2458 continue;
2459
2460 float Rn = std::sqrt(rn[0] * rn[0] + rn[1] * rn[1]);
2461 float Ax = rn[0] / Rn;
2462 float Ay = rn[1] / Rn;
2463
2464 float ub = (xb * Ax + yb * Ay) * rb2;
2465 float vb = (yb * Ax - xb * Ay) * rb2;
2466 float ut = (xt * Ax + yt * Ay) * rt2;
2467 float vt = (yt * Ax - xt * Ay) * rt2;
2468
2469 float dU = ut - ub;
2470 if (dU == 0.)
2471 continue;
2472 float A = (vt - vb) / dU;
2473 float onePlusAsquare = 1. + A * A;
2474 float B = vb - A * ub;
2475 float BSquare = B * B;
2476
2489 if (BSquare > ipt2K * onePlusAsquare || remainingSquaredDelta * onePlusAsquare > BSquare * sigmaSquaredScatteringPtDependent)
2490 continue;
2491
2508 float d0 = std::abs((A - B * Rn) * Rn);
2509
2511 if (d0 <= d0max)
2512 {
2514 float dr = std::sqrt(1 / rb2);
2515 if (data.R[t] < data.R[b])
2516 dr = std::sqrt(1 / rt2);
2520 data.ITkSP[t]->setScorePenalty(std::abs((tb - tz) / (dr * sTzb2)));
2521 data.ITkSP[t]->setParam(d0);
2522 float DR = std::sqrt( xt * xt + yt * yt + zt * zt ); // distance between top and central SP
2523 data.ITkSP[t]->setDR(DR);
2524
2526 data.ITkCmSp.emplace_back(B / std::sqrt(onePlusAsquare), data.ITkSP[t]);
2528 if (data.ITkCmSp.size() == 500)
2529 break;
2530 }
2531
2532 }
2534 if (!data.ITkCmSp.empty())
2535 {
2536 newOneSeedWithCurvaturesComparisonSSS(data, data.ITkSP[b], (*iter_centralSP), Zob);
2537 }
2538 }
2540 fillSeeds(data);
2541 nseed += data.fillOneSeeds;
2542
2543 }
2544}
2545
2547// Production 3 space points seeds in ROI
2549
2551 std::array<std::vector<SiSpacePointForSeed *>::iterator, arraySizeNeighbourBins> &/*rb*/,
2552 std::array<std::vector<SiSpacePointForSeed *>::iterator, arraySizeNeighbourBins> &/*rbe*/,
2553 std::array<std::vector<SiSpacePointForSeed *>::iterator, arraySizeNeighbourBins> &/*rt*/,
2554 std::array<std::vector<SiSpacePointForSeed *>::iterator, arraySizeNeighbourBins> &/*rte*/,
2555 const int /*numberBottomCells*/, const int /*numberTopCells*/, int &/*nseed*/) const
2556{
2557 ATH_MSG_WARNING("ITk::SiSpacePointsSeedMaker::production3SpTrigger not implemented!");
2558}
2559
2561// New 3 space points pro seeds
2563
2566 SiSpacePointForSeed *&p3, float z, float seedCandidateQuality) const
2567{
2569 float worstQualityInMap = std::numeric_limits<float>::min();
2570 SiSpacePointsProSeed *worstSeedSoFar = nullptr;
2571 if (!data.ITkMapOneSeeds.empty())
2572 {
2573 std::multimap<float, SiSpacePointsProSeed *>::reverse_iterator l = data.ITkMapOneSeeds.rbegin();
2574 worstQualityInMap = (*l).first;
2575 worstSeedSoFar = (*l).second;
2576 }
2579 if (data.nOneSeeds < data.maxSeedsPerSP
2582 || (m_useSeedConfirmation && data.keepAllConfirmedSeeds && worstQualityInMap <= seedCandidateQuality && isConfirmedSeed(p1, p3, seedCandidateQuality) && data.nOneSeeds < data.seedPerSpCapacity)
2585 || (m_useSeedConfirmation && data.keepAllConfirmedSeeds && worstQualityInMap > seedCandidateQuality && isConfirmedSeed(worstSeedSoFar->spacepoint0(), worstSeedSoFar->spacepoint2(), worstQualityInMap) && data.nOneSeeds < data.seedPerSpCapacity))
2586 {
2587 data.ITkOneSeeds[data.nOneSeeds].set(p1, p2, p3, z);
2588 data.ITkMapOneSeeds.insert(std::make_pair(seedCandidateQuality, &data.ITkOneSeeds[data.nOneSeeds]));
2589 ++data.nOneSeeds;
2590 }
2591
2593 else if (worstQualityInMap > seedCandidateQuality)
2594 {
2596 worstSeedSoFar->set(p1, p2, p3, z);
2598 std::multimap<float, SiSpacePointsProSeed *>::iterator
2599 i = data.ITkMapOneSeeds.insert(std::make_pair(seedCandidateQuality, worstSeedSoFar));
2601 for (++i; i != data.ITkMapOneSeeds.end(); ++i)
2602 {
2603 if ((*i).second == worstSeedSoFar)
2604 {
2605 data.ITkMapOneSeeds.erase(i);
2606 return;
2607 }
2608 }
2609 }
2610}
2611
2612
2615 SiSpacePointForSeed *&p3, float z, float seedCandidateQuality) const
2616{
2618 float worstQualityInMap = std::numeric_limits<float>::min();
2619 SiSpacePointsProSeed *worstSeedSoFar = nullptr;
2620 if (!data.ITkMapOneSeedsQ.empty())
2621 {
2622 std::multimap<float, SiSpacePointsProSeed *>::reverse_iterator l = data.ITkMapOneSeedsQ.rbegin();
2623 worstQualityInMap = (*l).first;
2624 worstSeedSoFar = (*l).second;
2625 }
2628 if (data.nOneSeedsQ < data.maxSeedsPerSP
2631 || (m_useSeedConfirmation && data.keepAllConfirmedSeeds && worstQualityInMap <= seedCandidateQuality && isConfirmedSeed(p1, p3, seedCandidateQuality) && data.nOneSeedsQ < data.seedPerSpCapacity)
2634 || (m_useSeedConfirmation && data.keepAllConfirmedSeeds && worstQualityInMap > seedCandidateQuality && isConfirmedSeed(worstSeedSoFar->spacepoint0(), worstSeedSoFar->spacepoint2(), worstQualityInMap) && data.nOneSeedsQ < data.seedPerSpCapacity))
2635 {
2636 data.ITkOneSeedsQ[data.nOneSeedsQ].set(p1, p2, p3, z);
2637 data.ITkMapOneSeedsQ.insert(std::make_pair(seedCandidateQuality, &data.ITkOneSeedsQ[data.nOneSeedsQ]));
2638 ++data.nOneSeedsQ;
2639 }
2640
2642 else if (worstQualityInMap > seedCandidateQuality)
2643 {
2645 worstSeedSoFar->set(p1, p2, p3, z);
2647 std::multimap<float, SiSpacePointsProSeed *>::iterator
2648 i = data.ITkMapOneSeedsQ.insert(std::make_pair(seedCandidateQuality, worstSeedSoFar));
2650 for (++i; i != data.ITkMapOneSeedsQ.end(); ++i)
2651 {
2652 if ((*i).second == worstSeedSoFar)
2653 {
2654 data.ITkMapOneSeedsQ.erase(i);
2655 return;
2656 }
2657 }
2658 }
2659}
2660
2661
2662
2664// New 3 space points pro seeds production
2666
2668{
2669 const float dC = .00003;
2670
2671 bool pixb = !SPb->spacepoint->clusterList().second;
2672
2673 std::sort(data.ITkCmSp.begin(), data.ITkCmSp.end(), comCurvature());
2674 std::vector<std::pair<float, SiSpacePointForSeed *>>::iterator j, jn, i = data.ITkCmSp.begin(), ie = data.ITkCmSp.end();
2675 jn = i;
2676
2677 for (; i != ie; ++i)
2678 {
2679 float u = (*i).second->param();
2680 bool pixt = !(*i).second->spacepoint->clusterList().second;
2681 if (pixt && std::abs(SPb->z() - (*i).second->z()) > m_dzmaxPPP)
2682 continue;
2683
2684 const Trk::Surface *Sui = (*i).second->sur();
2685 float Ri = (*i).second->radius();
2686 float Ci1 = (*i).first - dC;
2687 float Ci2 = (*i).first + dC;
2688 float Rmi = 0.;
2689 float Rma = 0.;
2690 bool in = false;
2691
2692 if (!pixb)
2693 u -= 400.;
2694 else if (pixt)
2695 u -= 200.;
2696
2697 for (j = jn; j != ie; ++j)
2698 {
2699 if (j == i)
2700 continue;
2701 if ((*j).first < Ci1)
2702 {
2703 jn = j;
2704 ++jn;
2705 continue;
2706 }
2707 if ((*j).first > Ci2)
2708 break;
2709 if ((*j).second->sur() == Sui)
2710 continue;
2711
2712 float Rj = (*j).second->radius();
2713 if (std::abs(Rj - Ri) < m_drmin)
2714 continue;
2715
2716 if (in)
2717 {
2718 if (Rj > Rma)
2719 Rma = Rj;
2720 else if (Rj < Rmi)
2721 Rmi = Rj;
2722 else
2723 continue;
2724 if ((Rma - Rmi) > 20.)
2725 {
2726 u -= 200.;
2727 break;
2728 }
2729 }
2730 else
2731 {
2732 in = true;
2733 Rma = Rmi = Rj;
2734 u -= 200.;
2735 }
2736 }
2737 if (u > m_umax)
2738 continue;
2739
2740 newOneSeed(data, SPb, SP0, (*i).second, Zob, u);
2741 }
2742 data.ITkCmSp.clear();
2743}
2744
2745
2746
2747
2748
2750// Fill seeds
2752
2754{
2755 data.fillOneSeeds = 0;
2756
2757 std::multimap<float, SiSpacePointsProSeed *>::iterator it_seedCandidate = data.ITkMapOneSeeds.begin();
2758 std::multimap<float, SiSpacePointsProSeed *>::iterator it_endSeedCandidates = data.ITkMapOneSeeds.end();
2759
2760 if (data.nOneSeedsQ){
2761 it_seedCandidate = data.ITkMapOneSeedsQ.begin();
2762 it_endSeedCandidates = data.ITkMapOneSeedsQ.end();
2763 }
2764
2766 if (it_seedCandidate == it_endSeedCandidates)
2767 return;
2768
2769 SiSpacePointsProSeed *theSeed{nullptr};
2770
2772 for (; it_seedCandidate != it_endSeedCandidates; ++it_seedCandidate)
2773 {
2774
2776 float quality = (*it_seedCandidate).first;
2777 theSeed = (*it_seedCandidate).second;
2778
2780 if (!theSeed->setQuality(quality))
2781 continue;
2782
2784 if (data.i_ITkSeedEnd != data.i_ITkSeeds.end())
2785 {
2786 theSeed = &(*data.i_ITkSeedEnd++);
2787 *theSeed = *(*it_seedCandidate).second;
2788 }
2789 else
2790 {
2792 data.i_ITkSeeds.emplace_back(*(*it_seedCandidate).second);
2793 //unused value, keep in comment to avoid repeating in future
2794 //theSeed = &(data.i_ITkSeeds.back());
2795 data.i_ITkSeedEnd = data.i_ITkSeeds.end();
2796 }
2797
2798 ++data.fillOneSeeds;
2799 }
2800}
2801
2802const InDet::SiSpacePointsSeed *SiSpacePointsSeedMaker::next(const EventContext& ctx, EventData &data) const
2803{
2805 if (not data.initialized)
2806 initializeEventData(data, ctx);
2807
2808 if (data.nspoint == 3)
2809 {
2810 do
2811 {
2813 if (data.i_ITkSeed == data.i_ITkSeedEnd)
2814 {
2819 findNext(data);
2821 //cppcheck-suppress identicalInnerCondition
2822 if (data.i_ITkSeed == data.i_ITkSeedEnd)
2823 return nullptr;
2824 }
2825
2827 } while (!(*data.i_ITkSeed++).set3(data.seedOutput, 1./(1000. * data.K)));
2829 return &data.seedOutput;
2830 }
2831 else
2832 {
2834 if (data.i_ITkSeed == data.i_ITkSeedEnd)
2835 {
2836 findNext(data);
2837 //cppcheck-suppress identicalInnerCondition
2838 if (data.i_ITkSeed == data.i_ITkSeedEnd)
2839 return nullptr;
2840 }
2841 (*data.i_ITkSeed++).set2(data.seedOutput);
2842 return &data.seedOutput;
2843 }
2844 return nullptr;
2845}
2846
2848 float Zv, float R, float T) const
2849{
2850 if (Zv < data.zminU || Zv > data.zmaxU)
2851 return false;
2852 if (!data.isvertex)
2853 return true;
2854
2855 float dZmin = std::numeric_limits<float>::max();
2856 for (const float &v : data.l_vertex)
2857 {
2858 float dZ = std::abs(v - Zv);
2859 if (dZ >= dZmin)
2860 break;
2861 dZmin = dZ;
2862 }
2863 return dZmin < (m_dzver + m_dzdrver * R) * sqrt(1. + T * T);
2864}
2865
2867// New space point for seeds
2869
2871{
2872 std::array<float, 15> r;
2873 return newSpacePoint(data, sp, r, true);
2874}
2875
2876SiSpacePointForSeed *SiSpacePointsSeedMaker::newSpacePoint(EventData &data, const Trk::SpacePoint *const &sp, std::span<float, 15> r, bool usePixStripInform) const
2877{
2878
2879 SiSpacePointForSeed *sps = nullptr;
2880
2883 convertToBeamFrameWork(data, sp, r.data());
2884
2886 if (data.checketa)
2887 {
2888 float z = (std::abs(r[2]) + m_zmax);
2889 float x = r[0] * data.dzdrmin;
2890 float y = r[1] * data.dzdrmin;
2891 if ((z * z) < (x * x + y * y))
2892 return sps;
2893 }
2894
2895 if (m_fastTracking)
2896 {
2897 float R2 = r[0] * r[0] + r[1] * r[1];
2898 // cotTheta=18.2855 corresponds to eta=3.6
2899 if (std::abs(r[2]) > m_dzMaxFast && R2 < m_R2MaxFast && std::abs(r[2]) < 18.2855 * std::sqrt(R2))
2900 return nullptr;
2901 if (std::abs(r[2]) - m_zmax > data.dzdrmax * std::sqrt(R2))
2902 return nullptr;
2903 }
2904
2905 if (usePixStripInform)
2906 {
2907 if (!sp->clusterList().second)
2908 pixInform(sp, r.data());
2909 else
2910 stripInform(data, sp, r.data());
2911 }
2912
2916 if (data.i_ITkSpacePointForSeed != data.l_ITkSpacePointForSeed.end())
2917 {
2919 sps = &(*data.i_ITkSpacePointForSeed++);
2922 sps->set(sp, r);
2923 }
2924 else
2925 {
2927 data.l_ITkSpacePointForSeed.emplace_back(sp, r);
2929 sps = &(data.l_ITkSpacePointForSeed.back());
2931 data.i_ITkSpacePointForSeed = data.l_ITkSpacePointForSeed.end();
2932 }
2933
2934 return sps;
2935}
2936
2938// New 2 space points seeds
2940
2942 SiSpacePointForSeed *&p1, SiSpacePointForSeed *&p2, float z)
2943{
2944 SiSpacePointForSeed *p3 = nullptr;
2945
2946 if (data.i_ITkSeedEnd != data.i_ITkSeeds.end())
2947 {
2948 SiSpacePointsProSeed *s = &(*data.i_ITkSeedEnd++);
2949 s->set(p1, p2, p3, z);
2950 }
2951 else
2952 {
2953 data.i_ITkSeeds.emplace_back(p1, p2, p3, z);
2954 data.i_ITkSeedEnd = data.i_ITkSeeds.end();
2955 }
2956}
2957
2958void SiSpacePointsSeedMaker::initializeEventData(EventData &data, const EventContext& ctx) const
2959{
2960 int seedArrayPerSPSize = (m_maxOneSizePPP > m_maxOneSizeSSS ? m_maxOneSizePPP : m_maxOneSizeSSS);
2962 seedArrayPerSPSize = 50;
2963 data.initialize(EventData::ToolType::ITk,
2965 seedArrayPerSPSize,
2966 0,
2967 m_nBinsR,
2968 0,
2971 m_checketa);
2972
2973 buildBeamFrameWork(data);
2974
2976 double magField[3]{0, 0, 0};
2977 double globalPos[3] = {10., 10., 0.};
2978
2979 MagField::AtlasFieldCache fieldCache;
2981 const AtlasFieldCacheCondObj *fieldCondObj{*readHandle};
2982 if (fieldCondObj == nullptr) {
2983 ATH_MSG_ERROR("ITk::SiSpacePointsSeedMaker: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
2984 return;
2985 }
2986
2987 fieldCondObj->getInitializedCache(fieldCache);
2988
2989 if (fieldCache.solenoidOn()) {
2991 fieldCache.getFieldZR(globalPos, magField);
3002 data.K = 2. / (300. * magField[2]);
3003 } else {
3004 data.K = 2. / (300. * 5.);
3005 }
3006
3011 data.ipt2K = m_ipt2 / (data.K * data.K);
3013 data.ipt2C = m_ipt2 * m_COF;
3014 data.COFK = m_COF * (data.K * data.K);
3016 data.bField[0] = magField[0];
3017 data.bField[1] = magField[1];
3018 data.bField[2] = magField[2];
3019
3020}
3021
3023// New 3 space points pro seeds production
3025
3027 SiSpacePointForSeed *&SPb, SiSpacePointForSeed *&SP0, float Zob) const
3028{
3029
3031 {
3033 }
3034
3035 else
3036 {
3037
3038 static const float curvatureInterval = .00003;
3039
3041 if (data.ITkCmSp.size() > 2)
3042 std::sort(data.ITkCmSp.begin(), data.ITkCmSp.end(), comCurvature());
3043
3044 std::vector<std::pair<float, SiSpacePointForSeed *>>::iterator it_otherSP;
3045 std::vector<std::pair<float, SiSpacePointForSeed *>>::iterator it_commonTopSP = data.ITkCmSp.begin(), ie = data.ITkCmSp.end();
3046 std::vector<std::pair<float, SiSpacePointForSeed *>>::iterator it_startInnerLoop = it_commonTopSP;
3047
3048 float Lt[4];
3049
3051 for (; it_commonTopSP != ie; ++it_commonTopSP)
3052 {
3053
3054 SiSpacePointForSeed *SPt = (*it_commonTopSP).second;
3055 int NT = 1;
3056 Lt[0] = SPt->dR();
3057 float seedIP = SPt->param();
3058
3060 float minCurvature = (*it_commonTopSP).first - curvatureInterval;
3061 float maxCurvature = (*it_commonTopSP).first + curvatureInterval;
3062
3068
3069 for (it_otherSP = it_startInnerLoop; it_otherSP != ie; ++it_otherSP)
3070 {
3072 if (it_otherSP == it_commonTopSP)
3073 continue;
3076 if ((*it_otherSP).first < minCurvature)
3077 {
3078 it_startInnerLoop = it_otherSP;
3079 ++it_startInnerLoop;
3080 continue;
3081 }
3083 if ((*it_otherSP).first > maxCurvature)
3084 break;
3085
3086 float L = (*it_otherSP).second->dR();
3087
3088 int k = 0;
3089 for (; k != NT; ++k)
3090 {
3091 if (std::abs(L - Lt[k]) < 20.)
3092 break;
3093 }
3094 if (k == NT)
3095 {
3096 Lt[NT] = L;
3097 if (++NT == 4)
3098 break;
3099 }
3100 }
3101
3102 // ITk seed quality used so far
3103 float Q = seedIP - float(NT) * 100.;
3104 if (NT > 2)
3105 Q -= 100000.;
3107 newOneSeed(data, SPb, SP0, SPt, Zob, Q);
3108 }
3109 data.ITkCmSp.clear();
3110 }
3111}
3112
3114 SiSpacePointForSeed *&SPb, SiSpacePointForSeed *&SP0, float Zob) const
3115{
3116
3118 {
3120 }
3121
3122 else
3123 {
3124
3125 static const float curvatureInterval = .00003;
3126
3128 if (data.ITkCmSp.size() > 2)
3129 std::sort(data.ITkCmSp.begin(), data.ITkCmSp.end(), comCurvature());
3130
3131 std::vector<std::pair<float, SiSpacePointForSeed *>>::iterator it_otherSP;
3132 std::vector<std::pair<float, SiSpacePointForSeed *>>::iterator it_commonTopSP = data.ITkCmSp.begin(), ie = data.ITkCmSp.end();
3133 std::vector<std::pair<float, SiSpacePointForSeed *>>::iterator it_startInnerLoop = it_commonTopSP;
3134
3135 float Lt[4];
3136
3137 float Qmin = 1.e20;
3138 float Rb = 2. * SPb->radius();
3139 int NTc(2);
3140 if (Rb > 280.) {
3141 NTc = 1;
3142 }
3143
3144 SiSpacePointForSeed *SPmin = nullptr;
3145 bool Qm = Rb < 120. || std::abs(Zob) > 150.;
3146
3148 for (; it_commonTopSP != ie; ++it_commonTopSP)
3149 {
3150
3151 SiSpacePointForSeed *SPt = (*it_commonTopSP).second;
3152 int NT = 1;
3153 Lt[0] = SPt->dR();
3154 float seedIP = SPt->param();
3155
3157 float minCurvature = (*it_commonTopSP).first - curvatureInterval;
3158 float maxCurvature = (*it_commonTopSP).first + curvatureInterval;
3159
3165
3166 for (it_otherSP = it_startInnerLoop; it_otherSP != ie; ++it_otherSP)
3167 {
3169 if (it_otherSP == it_commonTopSP)
3170 continue;
3173 if ((*it_otherSP).first < minCurvature)
3174 {
3175 it_startInnerLoop = it_otherSP;
3176 ++it_startInnerLoop;
3177 continue;
3178 }
3180 if ((*it_otherSP).first > maxCurvature)
3181 break;
3182
3183 float L = (*it_otherSP).second->dR();
3184
3185 int k = 0;
3186 for (; k != NT; ++k)
3187 {
3188 if (std::abs(L - Lt[k]) < 20.)
3189 break;
3190 }
3191 if (k == NT)
3192 {
3193 Lt[NT] = L;
3194 if (++NT == 4)
3195 break;
3196 }
3197 }
3198
3199 int dN = NT - NTc;
3200 if (dN < 0 || (data.nOneSeedsQ && !dN))
3201 continue;
3202 if (Qm && !dN && seedIP > 1.)
3203 continue;
3204
3205 // ITk seed quality used so far
3206 float Q = 100. * seedIP + (std::abs(Zob) - float(NT) * 100.);
3207 if (Q > SPb->quality() && Q > SP0->quality() && Q > SPt->quality())
3208 continue;
3209
3210 if (dN)
3211 newOneSeedQ(data, SPb, SP0, SPt, Zob, Q);
3212 else if (Q < Qmin)
3213 {
3214 Qmin = Q;
3215 SPmin = SPt;
3216 }
3217 }
3218 if (SPmin && !data.nOneSeedsQ)
3219 newOneSeed(data, SPb, SP0, SPmin, Zob, Qmin);
3220 data.ITkCmSp.clear();
3221 }
3222}
3223
3225 SiSpacePointForSeed *&SPb, SiSpacePointForSeed *&SP0, float Zob) const
3226{
3227 static const float curvatureInterval = .00003;
3228 bool bottomSPisPixel = !SPb->spacepoint->clusterList().second;
3229 float bottomSPQuality = SPb->quality();
3230 float centralSPQuality = SP0->quality();
3231
3233 if (data.ITkCmSp.size() > 2)
3234 std::sort(data.ITkCmSp.begin(), data.ITkCmSp.end(), comCurvature());
3235
3236 float bottomR = SPb->radius();
3237 float bottomZ = SPb->z();
3238
3239 std::vector<std::pair<float, SiSpacePointForSeed *>>::iterator it_otherSP;
3240 std::vector<std::pair<float, SiSpacePointForSeed *>>::iterator it_commonTopSP = data.ITkCmSp.begin(), ie = data.ITkCmSp.end();
3241 std::vector<std::pair<float, SiSpacePointForSeed *>>::iterator it_startInnerLoop = it_commonTopSP;
3242
3244 for (; it_commonTopSP != ie; ++it_commonTopSP)
3245 {
3246
3247 SiSpacePointForSeed *SPt = (*it_commonTopSP).second;
3249 float seedIP = SPt->param();
3250 float seedQuality = seedIP + SPt->scorePenalty();
3251 float originalSeedQuality = seedQuality;
3252
3253 if (m_maxdImpact > 50)
3254 { //This only applies to LRT
3255
3256 float topR = SPt->radius();
3257 float topZ = SPt->z();
3258
3259 float Zot = std::abs(topR - bottomR) > 10e-9 ? bottomZ - (bottomR - originalSeedQuality) * ((topZ - bottomZ) / (topR - bottomR)) : bottomZ;
3260
3261 float theta1 = std::abs(topR - bottomR) > 10e-9 ? std::atan2(topR - bottomR, topZ - bottomZ) : 0.;
3262 float eta1 = theta1 > 0 ? -std::log(std::tan(.5 * theta1)) : 0.;
3263
3264 float theta0 = seedIP > 0 ? std::atan2(seedIP, Zot) : 0;
3265 float eta0 = theta0 > 0 ? -std::log(std::tan(.5 * theta0)) : 0.;
3266
3267 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
3268 //calculate weighted average of d0 and deltaEta, normalized by their maximum values
3269 float f = std::min(0.5, originalSeedQuality / 200.); //0.5 and 200 are parameters chosen from a grid scan to optimize efficiency
3270 seedQuality *= (1 - f) / 300.;
3271 seedQuality += f * deltaEta / 2.5;
3272 }
3273
3274 bool topSPisPixel = !SPt->spacepoint->clusterList().second;
3275
3277 const Trk::Surface *surfaceTopSP = SPt->sur();
3278 float radiusTopSP = SPt->radius();
3280 float minCurvature = (*it_commonTopSP).first - curvatureInterval;
3281 float maxCurvature = (*it_commonTopSP).first + curvatureInterval;
3282
3289
3291 if (!bottomSPisPixel)
3292 seedQuality += m_seedScoreBonusSSS;
3294 else if (topSPisPixel)
3295 seedQuality += m_seedScoreBonusPPP;
3296
3302
3303 for (it_otherSP = it_startInnerLoop; it_otherSP != ie; ++it_otherSP)
3304 {
3306 if (it_otherSP == it_commonTopSP)
3307 continue;
3310 if ((*it_otherSP).first < minCurvature)
3311 {
3312 it_startInnerLoop = it_otherSP;
3313 ++it_startInnerLoop;
3314 continue;
3315 }
3317 if ((*it_otherSP).first > maxCurvature)
3318 break;
3320 if ((*it_otherSP).second->sur() == surfaceTopSP)
3321 continue;
3323 float radiusOtherSP = (*it_otherSP).second->radius();
3324 if (std::abs(radiusOtherSP - radiusTopSP) < m_drminSeedConf)
3325 continue;
3326 // if we have a confirmation seed, we improve the score of the seed.
3327 seedQuality += m_seedScoreBonusConfirmationSeed;
3328 // apply confirmation bonus only once
3329 break;
3330 }
3331
3333 if (seedQuality > data.maxScore)
3334 continue;
3335
3338 if (bottomSPisPixel != topSPisPixel)
3339 {
3340 if (seedQuality > 0. ||
3341 (seedQuality > bottomSPQuality && seedQuality > centralSPQuality && seedQuality > SPt->quality()))
3342 continue;
3343 }
3346 if (!isConfirmedSeed(SPb, SPt, seedQuality))
3347 {
3349 double maxdImpact = m_maxdImpact - (m_dImpactCutSlopeUnconfirmedPPP * SPt->scorePenalty());
3351 if (!bottomSPisPixel)
3353 if (seedIP > maxdImpact)
3354 continue;
3355 }
3357 newOneSeed(data, SPb, SP0, SPt, Zob, seedQuality);
3358 }
3359 data.ITkCmSp.clear();
3360}
3361
3363 const SiSpacePointForSeed *topSP, float quality) const
3364{
3365
3367 if (bottomSP->spacepoint->clusterList().second)
3368 {
3369 return (quality < m_seedScoreThresholdSSSConfirmationSeed);
3370 }
3372 else if (!topSP->spacepoint->clusterList().second)
3373 {
3374 return (quality < m_seedScoreThresholdPPPConfirmationSeed);
3375 }
3377 else
3378 return (quality < 0.);
3379}
3380
3381void SiSpacePointsSeedMaker::writeNtuple(const InDet::SiSpacePointsSeed* seed, const Trk::Track* track, int seedType, long eventNumber) const
3382{
3383 if(m_writeNtuple) {
3384 std::lock_guard<std::mutex> lock(m_mutex);
3385
3386 if(track != nullptr) {
3387 m_trackPt = (track->trackParameters()->front()->pT())/1000.f;
3388 m_trackEta = std::abs(track->trackParameters()->front()->eta());
3389 }
3390 else {
3391 m_trackPt = -1.;
3392 m_trackEta = -1.;
3393 }
3394 m_d0 = seed->d0();
3395 m_z0 = seed->zVertex();
3396 m_eta = seed->eta();
3397 m_x1 = seed->x1();
3398 m_x2 = seed->x2();
3399 m_x3 = seed->x3();
3400 m_y1 = seed->y1();
3401 m_y2 = seed->y2();
3402 m_y3 = seed->y3();
3403 m_z1 = seed->z1();
3404 m_z2 = seed->z2();
3405 m_z3 = seed->z3();
3406 m_r1 = seed->r1();
3407 m_r2 = seed->r2();
3408 m_r3 = seed->r3();
3409 m_type = seedType;
3410 m_dzdr_b = seed->dzdr_b();
3411 m_dzdr_t = seed->dzdr_t();
3412 m_pt = seed->pt();
3413 m_givesTrack = !(track == nullptr);
3414 m_eventNumber = eventNumber;
3415
3416 // Ok: protected by mutex.
3417 TTree* outputTree ATLAS_THREAD_SAFE = m_outputTree;
3418 outputTree->Fill();
3419
3420 }
3421
3422}
3423
3428
3429} // namespace ITk
#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,...)
#define ATH_MSG_WARNING(x,...)
static const int B0
Definition AtlasPID.h:130
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
static Double_t sp
static Double_t s0
static Double_t Tp(Double_t *t, Double_t *par)
static Double_t sc
#define X(x)
Definition SiHitPlots.h:102
#define y
#define xt
#define yt
#define x
#define zt
#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
const Trk::SpacePoint * spacepoint
const Trk::Surface * sur() const
distance between top and central SP
float dR() const
penalty term in the seed score
void set(const Trk::SpacePoint *, std::span< float const, 15 >)
SiSpacePointForSeed * spacepoint2()
SiSpacePointForSeed * spacepoint0()
void set(SiSpacePointForSeed *&, SiSpacePointForSeed *&, SiSpacePointForSeed *&, float)
SG::ReadHandleKey< SpacePointContainer > m_spacepointsPixel
float m_seedScoreThresholdSSSConfirmationSeed
max (score is assigned negative sign) score for SSS seeds with confirmation seed requirement.
static MsgStream & dumpEvent(EventData &data, MsgStream &out)
bool isZCompatible(EventData &data, float Zv, float R, float T) const
std::array< std::array< int, arraySizeNeighbourBins >, arraySizePhiZ > m_neighbourCellsBottomSSS
void newOneSeedWithCurvaturesComparisonPPP(EventData &data, SiSpacePointForSeed *&SPb, SiSpacePointForSeed *&SP0, float Zob) const
std::array< int, arraySizePhiZ > m_nNeighbourCellsTopSSS
static void pixInform(const Trk::SpacePoint *sp, float *r)
void fillLists(EventData &data) const
ServiceHandle< ITHistSvc > m_thistSvc
Flag to write validation ntuples. Turned off by default.
virtual MsgStream & dump(EventData &data, MsgStream &out) const override
virtual StatusCode finalize() override
SiSpacePointForSeed * newSpacePoint(EventData &data, const Trk::SpacePoint *const &sp) const
Create a SiSpacePointForSeed from the space point.
virtual const InDet::SiSpacePointsSeed * next(const EventContext &ctx, EventData &data) const override
void production3SpPPP(EventData &data, std::array< std::vector< SiSpacePointForSeed * >::iterator, arraySizeNeighbourBins > &iter_bottomCands, std::array< std::vector< SiSpacePointForSeed * >::iterator, arraySizeNeighbourBins > &iter_endBottomCands, std::array< std::vector< SiSpacePointForSeed * >::iterator, arraySizeNeighbourBins > &iter_topCands, std::array< std::vector< SiSpacePointForSeed * >::iterator, arraySizeNeighbourBins > &iter_endTopCands, const int numberBottomCells, const int numberTopCells, int &nseed) const
bool isConfirmedSeed(const SiSpacePointForSeed *bottomSP, const 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< InDet::BeamSpotData > m_beamSpotKey
void newOneSeed(EventData &data, SiSpacePointForSeed *&, SiSpacePointForSeed *&, SiSpacePointForSeed *&, float, float) const
static void buildConnectionMapsVertex(std::array< int, arraySizePhiZV > &nNeighbourCells, std::array< std::array< int, arraySizeNeighbourBinsVertex >, arraySizePhiZV > &neighbourCells, int maxPhiBin)
Build maps for radius-azimuthal-Z sorted collections for Z Similar logic to the above,...
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 StatusCode initialize() override
void newOneSeedWithCurvaturesComparison(EventData &data, SiSpacePointForSeed *&, SiSpacePointForSeed *&, float) const
void production3SpTrigger(EventData &, std::array< std::vector< SiSpacePointForSeed * >::iterator, arraySizeNeighbourBins > &, std::array< std::vector< SiSpacePointForSeed * >::iterator, arraySizeNeighbourBins > &, std::array< std::vector< SiSpacePointForSeed * >::iterator, arraySizeNeighbourBins > &, std::array< std::vector< SiSpacePointForSeed * >::iterator, arraySizeNeighbourBins > &, const int, const int, int &) const
as above, but for the trigger
std::array< int, arraySizePhiZ > m_nNeighbourCellsBottomSSS
void findNext(EventData &data) const
bool newVertices(EventData &data, const std::list< Trk::Vertex > &) const
@ arraySizeZ
capacity of the 1D z arrays
@ arraySizeNeighbourBins
array size to store neighbouring phi-z-regions in the seed finding
@ arraySizePhiV
array size in phi for vertexing
@ arraySizeZV
array size in z for vertexing
@ arraySizePhiZV
array size in phi-Z 2D for the vertexing
@ arraySizePhi
capacity of the 1D phi arrays
@ arraySizePhiZ
capacity for the 2D phi-z arrays
float m_inverseBinSizePhiPPP
cache the inverse bin size in phi which we use - needed to evaluate phi bin locations
virtual void writeNtuple(const InDet::SiSpacePointsSeed *seed, const Trk::Track *track, int seedType, long eventNumber) const override
void production3Sp(EventData &data) const
bool isUsed(const Trk::SpacePoint *, const Trk::PRDtoTrackMap &prd_to_track_map) const
std::array< std::array< int, arraySizeNeighbourBins >, arraySizePhiZ > m_neighbourCellsBottomPPP
mapping of neighbour cells in the 2D phi-z binning to consider for the "bottom SP" search for central...
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,...
static void newSeed(EventData &data, SiSpacePointForSeed *&, SiSpacePointForSeed *&, float)
void newOneSeedQ(EventData &data, SiSpacePointForSeed *&, SiSpacePointForSeed *&, SiSpacePointForSeed *&, float, float) const
SG::ReadHandleKey< Trk::PRDtoTrackMap > m_prdToTrackMap
int m_maxPhiBinPPP
number of bins in phi
void sort(std::vector< InDet::FloatInt > &s, int start, int size) const
static void fillSeeds(EventData &data)
std::array< int, arraySizePhiZ > m_nNeighbourCellsTopPPP
number of neighbouring phi-z bins to consider when looking for "top SP" candidates for each phi-z bin
void newOneSeedWithCurvaturesComparisonSSS(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...
std::array< std::array< int, arraySizeNeighbourBinsVertex >, arraySizePhiZV > m_neighboursVertexPhiZ
MsgStream & dumpConditions(EventData &data, MsgStream &out) const
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.
std::array< int, arraySizePhiZ > m_nNeighbourCellsBottomPPP
arrays associating bins to each other for SP formation
static void stripInform(EventData &data, const Trk::SpacePoint *sp, float *r)
std::array< std::array< int, arraySizeNeighbourBins >, arraySizePhiZ > m_neighbourCellsTopSSS
virtual bool getWriteNtupleBoolProperty() const override
std::array< int, arraySizePhiZV > m_nNeighboursVertexPhiZ
SG::ReadHandleKey< SpacePointOverlapCollection > m_spacepointsOverlap
virtual void newEvent(const EventContext &ctx, EventData &data, int iteration) const override
SG::ReadHandleKey< SpacePointContainer > m_spacepointsStrip
static void convertToBeamFrameWork(EventData &data, const Trk::SpacePoint *, float *)
void production3SpSSS(EventData &data, std::array< std::vector< SiSpacePointForSeed * >::iterator, arraySizeNeighbourBins > &iter_bottomCands, std::array< std::vector< SiSpacePointForSeed * >::iterator, arraySizeNeighbourBins > &iter_endBottomCands, std::array< std::vector< SiSpacePointForSeed * >::iterator, arraySizeNeighbourBins > &iter_topCands, std::array< std::vector< SiSpacePointForSeed * >::iterator, arraySizeNeighbourBins > &iter_endTopCands, const int numberBottomCells, const int numberTopCells, int &nseed) const
: Seed production from space points.
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCondObjInputKey
void initializeEventData(EventData &data, const EventContext &ctx) const
std::array< std::array< int, arraySizeNeighbourBins >, arraySizePhiZ > m_neighbourCellsTopPPP
mapping of neighbour cells in the 2D phi-z binning to consider for the "top SP" search for central SP...
virtual void newRegion(const EventContext &ctx, EventData &data, const std::vector< IdentifierHash > &vPixel, const std::vector< IdentifierHash > &vStrip) const override
void newOneSeedWithCurvaturesComparisonSeedConfirmation(EventData &data, SiSpacePointForSeed *&SPb, SiSpacePointForSeed *&SP0, float Zob) const
void buildBeamFrameWork(EventData &data) const
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
int m_nBinsR
number of bins in the radial coordinate
static void buildConnectionMaps(std::array< int, arraySizePhiZ > &nNeighbourCellsBottom, std::array< int, arraySizePhiZ > &nNeighbourCellsTop, std::array< std::array< int, arraySizeNeighbourBins >, arraySizePhiZ > &neighbourCellsBottom, std::array< std::array< int, arraySizeNeighbourBins >, arraySizePhiZ > &neighbourCellsTop, int maxPhiBin, bool isSSS)
void production2Sp(EventData &data) const
This is a "hash" representation of an Identifier.
Class to hold geometrical description of a silicon detector element.
Class to represent a position in the natural frame of a silicon sensor, for Pixel and SCT For Pixel: ...
Trk::Surface & surface()
Element Surface.
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.
Definition Surface.h:79
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
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::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
InDet::SiSpacePointsSeedMakerEventData EventData
-event-from-file
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
#define ATH_RESTRICT
Definition restrict.h:31
hold the test vectors and ease the comparison
MsgStream & msg
Definition testRead.cxx:32