ATLAS Offline Software
Loading...
Searching...
No Matches
TRT_SeededSpacePointFinder_ATL.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6// Implementation file for class TRT_SeededSpacePointFinder_ATL
8// (c) ATLAS Detector software
10// Version 1.0 04/15/2006 T.Koffas
12
13
14#include "GaudiKernel/MsgStream.h"
15#include "GaudiKernel/ServiceHandle.h"
16#include "CLHEP/Vector/ThreeVector.h"
20
21//Cluster collections
22//
24//SCT Geometry
25//
27
28//Association tool
29//
30
32
33#include <ostream>
34#include <iomanip>
35#include <set>
36
37using namespace std;
38
40// Constructor
42
44(const std::string& t,const std::string& n,const IInterface* p)
45 : AthAlgTool(t,n,p)
46{
47 declareInterface<ITRT_SeededSpacePointFinder>(this);
48}
49
51// Destructor
53
55= default;
56
58// Initialisation
60
62{
64
65 // PRD-to-track association (optional)
66 ATH_CHECK( m_prdToTrackMap.initialize( !m_prdToTrackMap.key().empty()));
67 ATH_CHECK( m_fieldCondObjInputKey.initialize());
68 StatusCode sc = detStore()->retrieve(m_sctId, "SCT_ID");
69 if (sc.isFailure()){
70 msg(MSG::FATAL) << "Could not get SCT_ID helper !" << endmsg;
71 return StatusCode::FAILURE;
72 }
73
74 // Build framework
75 //
76
77 // Get output print level
78 //
79 if(msgLvl(MSG::DEBUG)){ dumpConditions(msg(MSG::DEBUG)); msg(MSG::DEBUG)<<endmsg; }
80
81 ATH_CHECK(m_spacepointsPixname.initialize());
82 ATH_CHECK(m_spacepointsSCTname.initialize());
84
85 return sc;
86}
87
89// Finalize
91
93{
94 StatusCode sc = AthAlgTool::finalize(); return sc;
95
96}
97
99// Initialize tool for new event
101
102std::unique_ptr<InDet::ITRT_SeededSpacePointFinder::IEventData>
104{
105 std::unique_ptr<InDet::TRT_SeededSpacePointFinder_ATL::EventData> event_data_p = std::make_unique<InDet::TRT_SeededSpacePointFinder_ATL::EventData>();
106 event_data_p->buildFrameWork(m_r_rmax, m_r_rstep, m_ptmin);
107 // @TODO remove m_r_Sorted and directly fill m_rf_Sorted ?
108
109 double irstep = 1./m_r_rstep;
110
111 std::vector< std::vector<const Trk::SpacePoint*> > r_Sorted;
112 r_Sorted.resize(event_data_p->m_r_size);
113
114 if(m_loadFull){
115 // Get pixel space points containers from store gate
116 //
118 if (spacepointsPix.isValid()) {
119 SpacePointContainer::const_iterator spc = spacepointsPix->begin ();
120 SpacePointContainer::const_iterator spce = spacepointsPix->end ();
121
122 for(; spc != spce; ++spc) {
123
125 SpacePointCollection::const_iterator spe = (*spc)->end ();
126 for(; sp != spe; ++sp) {
127
128 double r = (*sp)->r(); if(r<0. || r>=m_r_rmax) continue;
129 int ir = int(r*irstep);
130 const Trk::SpacePoint* sps = (*sp);
131 r_Sorted[ir].push_back(sps);
132 ++event_data_p->m_r_map[ir];
133 if(event_data_p->m_r_map[ir]==1) event_data_p->m_r_index[event_data_p->m_nr++] = ir;
134 ++event_data_p->m_ns;
135 }
136 }
137 }
138 }
139
140 SG::ReadHandle<Trk::PRDtoTrackMap> prd_to_track_map;
141 if (!m_prdToTrackMap.key().empty()) {
143 if (!prd_to_track_map.isValid()) {
144 ATH_MSG_ERROR("Failed to read PRD to track association map.");
145 }
146 }
147 // Get sct space points containers from store gate
148 //
150 if (spacepointsSCT.isValid()) {
151
152 SpacePointContainer::const_iterator spc = spacepointsSCT->begin();
153 SpacePointContainer::const_iterator spce = spacepointsSCT->end ();
154
155 double r_rmin = (!m_loadFull) ? m_r2min : m_r_rmin;
156 for(; spc != spce; ++spc) {
157
159 SpacePointCollection::const_iterator spe = (*spc)->end ();
160 for(; sp != spe; ++sp) {
161
162 if(prd_to_track_map.cptr()){
163 bool u1=false; bool u2=false;
164 const Trk::PrepRawData* p1=(*sp)->clusterList().first; u1=prd_to_track_map->isUsed(*p1);
165 const Trk::PrepRawData* p2=(*sp)->clusterList().second;u2=prd_to_track_map->isUsed(*p2);
166 if(u1 || u2){continue;}
167 }
168
169 double r = (*sp)->r(); if(r<r_rmin || r>=m_r_rmax) continue;
170 int ir = int(r*irstep);
171 const Trk::SpacePoint* sps = (*sp);
172 r_Sorted[ir].push_back(sps); ++event_data_p->m_r_map[ir];
173 if(event_data_p->m_r_map[ir]==1) event_data_p->m_r_index[event_data_p->m_nr++] = ir;
174 ++event_data_p->m_ns;
175 }
176 }
177 }
178
179 // Get sct overlap space points containers from store gate
180 //
182 if (spacepointsOverlap.isValid()) {
183 SpacePointOverlapCollection::const_iterator sp = spacepointsOverlap->begin();
184 SpacePointOverlapCollection::const_iterator spe = spacepointsOverlap->end ();
185
186 for (; sp!=spe; ++sp) {
187
188 if(prd_to_track_map.cptr()){
189 bool u1=false; bool u2=false;
190 const Trk::PrepRawData* p1=(*sp)->clusterList().first; u1=prd_to_track_map->isUsed(*p1);
191 const Trk::PrepRawData* p2=(*sp)->clusterList().second;u2=prd_to_track_map->isUsed(*p2);
192 if(u1 || u2){continue;}
193 }
194
195 double r = (*sp)->r(); if(r<0. || r>=m_r_rmax) continue;
196 int ir = int(r*irstep);
197 const Trk::SpacePoint* sps = (*sp);
198 r_Sorted[ir].push_back(sps); ++event_data_p->m_r_map[ir];
199 if(event_data_p->m_r_map[ir]==1) event_data_p->m_r_index[event_data_p->m_nr++] = ir;
200 ++event_data_p->m_ns;
201 }
202 }
203
204 fillLists(r_Sorted, *event_data_p); //Fill the R-phi sectors with the corresponding space points
205 return std::unique_ptr<InDet::ITRT_SeededSpacePointFinder::IEventData>(event_data_p.release());
206}
207
209// Initialize tool for new region
211
212std::unique_ptr<InDet::ITRT_SeededSpacePointFinder::IEventData> InDet::TRT_SeededSpacePointFinder_ATL::newRegion
213(const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT) const
214{
215 std::unique_ptr<InDet::TRT_SeededSpacePointFinder_ATL::EventData> event_data_p = std::make_unique<InDet::TRT_SeededSpacePointFinder_ATL::EventData>();
216 event_data_p->buildFrameWork(m_r_rmax, m_r_rstep, m_ptmin);
217
218 std::vector< std::vector<const Trk::SpacePoint*> > r_Sorted;
219 r_Sorted.resize(event_data_p->m_r_size);
220
221 double irstep = 1./m_r_rstep;
222
223 if(m_loadFull && !vPixel.empty()){
224 // Get pixel space points containers from store gate
225 //
227 if (spacepointsPix.isValid()) {
228 std::vector<IdentifierHash>::const_iterator l = vPixel.begin(), le = vPixel.end();
229
230 // Loop through all trigger collections
231 //
232 for(; l!=le; ++l) {
233
234 const SpacePointCollection *w = spacepointsPix->indexFindPtr(*l);
235 if(w==nullptr) continue;
238 for(; sp != spe; ++sp) {
239
240 double r = (*sp)->r(); if(r<0. || r>=m_r_rmax) continue;
241 int ir = int(r*irstep);
242 const Trk::SpacePoint* sps = (*sp);
243 r_Sorted[ir].push_back(sps); ++event_data_p->m_r_map[ir];
244 if(event_data_p->m_r_map[ir]==1) event_data_p->m_r_index[event_data_p->m_nr++] = ir;
245 ++event_data_p->m_ns;
246 }
247 }
248 }
249 }
250
251 // Get sct space points containers from store gate
252 //
253 if(!vSCT.empty()) {
254
256 if (spacepointsSCT.isValid()) {
257
258 SG::ReadHandle<Trk::PRDtoTrackMap> prd_to_track_map;
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.");
263 }
264 }
265 std::vector<IdentifierHash>::const_iterator l = vSCT.begin(), le = vSCT.end();
266
267 // Loop through all trigger collections
268 //
269 double r_rmin = (!m_loadFull) ? m_r2min : m_r_rmin;
270 for(; l!=le; ++l) {
271
272 const SpacePointCollection *w = spacepointsSCT->indexFindPtr(*l);
273 if(w==nullptr) continue;
276 for(; sp != spe; ++sp) {
277
278 if(prd_to_track_map.cptr()){
279 bool u1=false; bool u2=false;
280 const Trk::PrepRawData* p1=(*sp)->clusterList().first; u1=prd_to_track_map->isUsed(*p1);
281 const Trk::PrepRawData* p2=(*sp)->clusterList().second;u2=prd_to_track_map->isUsed(*p2);
282 if(u1 || u2){continue;}
283 }
284
285 double r = (*sp)->r(); if(r<r_rmin || r>=m_r_rmax) continue;
286 int ir = int(r*irstep);
287 const Trk::SpacePoint* sps = (*sp);
288 r_Sorted[ir].push_back(sps); ++event_data_p->m_r_map[ir];
289 if(event_data_p->m_r_map[ir]==1) event_data_p->m_r_index[event_data_p->m_nr++] = ir;
290 ++event_data_p->m_ns;
291 }
292 }
293 }
294 }
295
296 fillLists(r_Sorted,*event_data_p); //Fill the R-phi sectors with the corresponding space points
297 return std::unique_ptr<InDet::ITRT_SeededSpacePointFinder::IEventData>(event_data_p.release());
298}
299
301// Methods to initialize different strategies of seeds production
302// with two space points with or without vertex constraint
304
305std::list<std::pair<const Trk::SpacePoint*, const Trk::SpacePoint*> >
307 const Trk::TrackParameters& tP,
308 ITRT_SeededSpacePointFinder::IEventData &virt_event_data) const
309{
311
312 const double pi2 = 2.*M_PI;
313
315 std::list<std::pair<const Trk::SpacePoint*,const Trk::SpacePoint*> > outputListBuffer;
316
318 double F = 0.;
319 double GPx=tP.position().x(); double GPy=tP.position().y();
320 F=atan2(GPy,GPx); if(F<0.) F+=pi2;
321 int f = int(F*event_data.m_sF);
322 if (f < 0)
323 f += event_data.m_fNmax;
324 else if (f > event_data.m_fNmax)
325 f -= event_data.m_fNmax;
326
327
328 production2Spb (ctx, tP,f, outputListBuffer,event_data); //Get a list of SP pairs.
329
330 if(msgLvl(MSG::DEBUG)) {
331 dumpEvent( msg(MSG::DEBUG), event_data);
332 dumpConditions( msg(MSG::DEBUG));
333 msg(MSG::DEBUG) << endmsg;
334 }
335
336 if(outputListBuffer.size()>10000.) outputListBuffer.clear();
337
338 return outputListBuffer;
339}
340
341
343// Dumps conditions information into the MsgStream
345
347{
348 int n = 42-m_fieldCondObjInputKey.key().size();
349 std::string s1; for(int i=0; i<n; ++i) s1.append(" "); s1.append("|");
350 n = 42-m_spacepointsSCTname.key().size();
351 std::string s3; for(int i=0; i<n; ++i) s3.append(" "); s3.append("|");
352 n = 42-m_spacepointsOverlapname.key().size();
353 std::string s4; for(int i=0; i<n; ++i) s4.append(" "); s4.append("|");
354
355 std::string fieldmode[9] ={"NoField" ,"ConstantField","SolenoidalField",
356 "ToroidalField" ,"Grid3DField" ,"RealisticField" ,
357 "UndefinedField","AthenaField" , "?????" };
358
359 int mode = m_fieldprop.magneticFieldMode();
360 if(mode<0 || mode>8 ) mode = 8;
361
362 n = 62-fieldmode[mode].size();
363 std::string s5; for(int i=0; i<n; ++i) s5.append(" "); s5.append("|");
364
365 out<<"|---------------------------------------------------------------------|"
366 <<std::endl;
367 out<<"| Key of magentic field condition Object | "<<m_fieldCondObjInputKey.key()<<s1
368 <<std::endl;
369 out<<"| SCT space points | "<<m_spacepointsSCTname.key()<<s3
370 <<std::endl;
371 out<<"| Overlap space points | "<<m_spacepointsOverlapname.key()<<s4
372 <<std::endl;
373 out<<"| Magnetic field mode | "<<fieldmode[mode]<<s5
374 <<std::endl;
375 out<<"| pTmin (mev) | "
376 <<std::setw(12)<<std::setprecision(5)<<m_ptmin
377 <<" |"<<std::endl;
378 out<<"| max radius SP | "
379 <<std::setw(12)<<std::setprecision(5)<<m_r_rmax
380 <<" |"<<std::endl;
381 out<<"| radius step | "
382 <<std::setw(12)<<std::setprecision(5)<<m_r_rstep
383 <<" |"<<std::endl;
384 out<<"| min radius second SP(3) | "
385 <<std::setw(12)<<std::setprecision(5)<<m_r2min
386 <<" |"<<std::endl;
387 out<<"| min radius first SP(3) | "
388 <<std::setw(12)<<std::setprecision(5)<<m_r12min
389 <<" |"<<std::endl;
390 out<<"| max radius first SP(3) | "
391 <<std::setw(12)<<std::setprecision(4)<<m_r1max
392 <<" |"<<std::endl;
393 out<<"| min seeds dZ/dR | "
394 <<std::setw(12)<<std::setprecision(5)<<m_dzdrmin
395 <<" |"<<std::endl;
396 out<<"| max seeds dZ/dR | "
397 <<std::setw(12)<<std::setprecision(5)<<m_dzdrmax
398 <<" |"<<std::endl;
399 out<<"| momentum chi2 cut | "
400 <<std::setw(12)<<std::setprecision(5)<<m_xiC
401 <<" |"<<std::endl;
402 out<<"| polar angle chi2 cut | "
403 <<std::setw(12)<<std::setprecision(5)<<m_xiTC
404 <<" |"<<std::endl;
405 out<<"| azimuthal angle chi2 cut | "
406 <<std::setw(12)<<std::setprecision(5)<<m_xiFC
407 <<" |"<<std::endl;
408 out<<"|---------------------------------------------------------------------|"
409 <<std::endl;
410 return out;
411}
412
414// Dumps event information into the MsgStream
416namespace {
417 class StreamState
418 {
419 public:
420 explicit StreamState(std::ostream& out)
421 : m_out(out), m_prec(out.precision())
422 {
423 }
424
425 ~StreamState()
426 {
427 m_out.precision(m_prec);
428 }
429
430 private:
431 std::ostream& m_out;
432 std::streamsize m_prec;
433 };
434}
435
437{
438 const double pi2 = 2.*M_PI;
439 out<<"|---------------------------------------------------------------------|"
440 <<"\n";
441 out<<"| m_ns | "
442 <<std::setw(12)<<event_data.m_ns
443 <<" |"<<"\n";
444 out<<"|---------------------------------------------------------------------|"
445 <<"\n";
446
447 if(msgLvl(MSG::DEBUG)) return out;
448
449 out<<"|-------------|--------|-------|-------|-------|-------|-------|";
450 out<<"-------|-------|-------|-------|-------|-------|"
451 <<"\n";
452
453 out<<"| Azimuthal | n | z[ 0] | z[ 1] | z[ 2] | z[ 3] | z[4] |";
454 out<<" z[ 5] | z[ 6] | z[ 7] | z[ 8] | z[ 9] | z[10] |"
455 <<"\n";
456 out<<"|-------------|--------|-------|-------|-------|-------|-------|";
457 out<<"-------|-------|-------|-------|-------|-------|"
458 <<"\n";
459
460 double sF1 = pi2/double(event_data.m_fNmax+1);
461
462 //StreamState restore_precision(out);
463 auto prec(out.precision());
464 for(int f=0; f<=event_data.m_fNmax; ++f) {
465 out<<"| "
466 <<std::setw(10)<<std::setprecision(4)<<sF1*double(f)<<" | "
467 <<std::setw(6)<<event_data.m_rf_map[f]<<" |";
468 out<<"\n";
469 }
470 out<<"|-------------|--------|-------|-------|-------|-------|-------|";
471 out<<"-------|-------|-------|-------|-------|-------|"
472 <<"\n";
473 out<<endmsg;
474 out.precision(prec);
475 return out;
476}
477
479// Dumps relevant information into the ostream
481
482MsgStream& InDet::TRT_SeededSpacePointFinder_ATL::dump( MsgStream& out ) const
483{
484 return dumpConditions(out);
485}
486
487std::ostream& InDet::TRT_SeededSpacePointFinder_ATL::dump( std::ostream& out ) const
488{
489 return out;
490}
491
493// Initiate frame work for seed generator
495
496void InDet::TRT_SeededSpacePointFinder_ATL::EventData::buildFrameWork(double r_rmax, double r_rstep, double ptmin)
497{
498
499 m_ns = m_nr = m_nrf = 0;
500
501 // Build radius sorted containers
502 //
503 m_r_size = int((r_rmax+.1)/r_rstep);
504 m_r_index = new int[m_r_size];
505 m_r_map = new int[m_r_size];
506 m_nr = 0; for(int i=0; i!=m_r_size; ++i) {m_r_index[i]=0; m_r_map[i]=0;}
507
508 // Build radius-azimuthal sorted containers
509 //
510 const double pi2 = 2.*M_PI ;
511 const int NFmax = 530 ;
512 const double sFmax = double(NFmax )/pi2;
513 m_sF = ptmin /60. ; if(m_sF >sFmax ) m_sF = sFmax ;
514 m_fNmax = int(pi2*m_sF); if(m_fNmax >=NFmax) m_fNmax = NFmax-1;
515 m_nrf = 0; for(int i=0; i!= 530; ++i) {m_rf_index [i]=0; m_rf_map [i]=0;}
516
517}
518
520// Initiate space points seed maker
522
523void InDet::TRT_SeededSpacePointFinder_ATL::fillLists(std::vector< std::vector<const Trk::SpacePoint*> > &r_Sorted,
525{
526 assert( static_cast<size_t>(event_data.m_r_size) == r_Sorted.size());
527 const double pi2 = 2.*M_PI;
528
529 for(int i=0; i!= event_data.m_r_size; ++i) {
530 if(!event_data.m_r_map[i]) continue;
531 for(const Trk::SpacePoint *space_point : r_Sorted[i]) {
532
533 // Azimuthal angle sort
534 //
535 double F = space_point->phi(); if(F<0.) F+=pi2;
536 int f = int(F*event_data.m_sF);
537 if (f < 0)
538 f += event_data.m_fNmax;
539 else if (f > event_data.m_fNmax)
540 f -= event_data.m_fNmax;
541 int isBRL = 1000; int isLYR = 1000; int DD = 1000;
542
543 geoInfo(space_point,isBRL,isLYR);
544
545 // Use 4 lower bits (Mask == ((2^4 -1) == 15)) for isLYR
546 // the upper 28 bits for isBRL (including sign)
547 DD = ((isBRL+3) << 4) + (isLYR & 15);
548
549 event_data.m_rf_Sorted[f].emplace_back(space_point,DD);
550 if(!event_data.m_rf_map[f]++) event_data.m_rf_index[event_data.m_nrf++] = f;
551
552 }
553 event_data.m_r_map[i] = 0;
554 }
555
556 event_data.m_nr = 0;
557}
558
560// Erase space point information
562
564{
565
566 for(int i=0; i!=m_nrf; ++i) {
567 int n = m_rf_index[i]; m_rf_map[n] = 0;
568 m_rf_Sorted[n].erase(m_rf_Sorted[n].begin(),m_rf_Sorted[n].end());
569 }
570
571 m_ns = 0;
572 m_nr = 0;
573 m_nrf = 0;
574}
575
576// // // // // // // // // // // // // // // // // // // // // // // // // //
577
578// Monotonic function of the angle to map the comparison to replace atan2
579// Computation is not in the inner loop, so trigonometric functions are OK
580double
582 while (angle < 0) {
583 angle += 2*M_PI;
584 }
585 while (angle > 2*M_PI) {
586 angle -= 2*M_PI;
587 }
588 double rotations = angle/(2*M_PI);
589 double rquadrant = rotations*4.0;
590 long quadrant = (long)rquadrant & 3;
591 double twist;
592 if ((quadrant & 1) != 0) {
593 twist = cos(angle);
594 }
595 else {
596 twist = sin(angle);
597 }
598 twist *= twist;
599 quadrant -= ((quadrant & 2) << 1);
600 return quadrant + twist;
601}
602
603// Since the theta and phi cuts in cutTP are essentially
604// checks for the angle to be within a specified region,
605// only the upper and the lower boundaries have to calculated,
606// once again, not in the inner loop but just once
607// The logic is:
608// {lower <= angle <= upper_} necessary and sufficient for
609// {rollrating(lower) <= rollrating(angle) <= rollrating(upper)}
610void
611bracket_angle(double angle, double delta,
612 double *min, double *max) {
613 double amin = rollrating(angle - delta);
614 double amax = rollrating(angle + delta);
615 if (delta >= M_PI) {
616 amin = 0.0;
617 amax = 4.0;
618 }
619 *min = amin;
620 *max = amax;
621}
622
623
624// rotrating(sin(angle), cos(angle)) == rollrating(angle)
625// Called many times, for each pair still in consideration
626// Performance critical, so no SQRTs or transcendentals here
627inline double
628rotrating(double y, double x) {
629 long asign_x = (long)(x < 0.0);
630 long asign_y = (long)(y < 0.0);
631 long quadrant = -(asign_y << 1) + (asign_y ^ asign_x);
632 double x2 = x*x;
633 double y2 = y*y;
634 double denominator = x2 + y2;
635 double numerator = ((quadrant & 1) != 0) ? x2 : y2;
636 return (double)quadrant + numerator/denominator;
637}
638
639void
641 const Trk::TrackParameters& tP,
642 int phi,
643 std::list<std::pair<const Trk::SpacePoint*,const Trk::SpacePoint*> > &outputListBuffer,
645{
646 uint64_t spcount = 0;
647 // // // // // // <Fill the invar_bypass // // // // // // //
648
649 //const Trk::MeasuredAtaStraightLine &ntP =
650 //dynamic_cast<const Trk::MeasuredAtaStraightLine&>(tP);
651 const AmgVector(5)& pTS=tP.parameters();
652 const AmgSymMatrix(5)* vCM = tP.covariance();
653
654 double sPhi = (*vCM)(2,2) ; //Sigma on TRT segment azimuthal angle
655 double sTheta = (*vCM)(3,3); //Sigma on TRT segment polar angle
656 double sp = (*vCM)(4,4) ; //Sigma on TRT segment inverse momentum estimate
657
658 double ipdelta = sqrt(m_xiC*sp);
659
660 invar_bypass_struct tmp_invar_bypass{};
661 tmp_invar_bypass.invp_min = pTS[4] - ipdelta;
662 tmp_invar_bypass.invp_max = pTS[4] + ipdelta;
663
664 tmp_invar_bypass.invp_min2 = tmp_invar_bypass.invp_min*tmp_invar_bypass.invp_min;
665 tmp_invar_bypass.invp_max2 = tmp_invar_bypass.invp_max*tmp_invar_bypass.invp_max;
666
667 double theta_center = pTS[3];
668 double theta_delta = sqrt(m_xiTC*sTheta);
669
670 double phi_center = pTS[2];
671 double phi_delta = sqrt(m_xiFC*sPhi);
672
673 bracket_angle(theta_center, theta_delta,
674 &(tmp_invar_bypass.min_theta), &(tmp_invar_bypass.max_theta));
675 bracket_angle(phi_center, phi_delta,
676 &(tmp_invar_bypass.min_phi), &(tmp_invar_bypass.max_phi));
677
678 // // // // // // Fill the invar_bypass> // // // // // // //
679
681 double x0=tP.position().x() ;
682 double y0=tP.position().y() ;
683 double z0=tP.position().z() ;
684 double H[3]; double gP[3] = {x0,y0,z0};
685
686 // Get field cache object
688 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
689 if (fieldCondObj == nullptr) {
690 ATH_MSG_ERROR("TRT_SeededSpacePointFinder_ATL: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
691 return;
692 }
693 MagField::AtlasFieldCache fieldCache;
694 fieldCondObj->getInitializedCache (fieldCache);
695 fieldCache.getField (gP, H);
696
697 //need conversion kilotesla -> kilogauss - Previously used getMagneticFiledKiloGauss, whereas new function returns value in kiloTesla...
698 H[0] *= 10000;
699 H[1] *= 10000;
700 H[2] *= 10000;
701
702 std::list<std::pair<const Trk::SpacePoint*,int> >::iterator r0,r0e,r,re, rb;
703 const Trk::SpacePoint* SpToPair = nullptr;
704
705
707 //
708 int fmin=phi; int fmax=phi;
709 if(m_search){fmin = phi-1; fmax = phi+1;}
710 for(int f=fmin; f<=fmax; ++f) {
711 int j=0; f<0 ? j=f+event_data.m_fNmax+1 : f>event_data.m_fNmax ? j=f-event_data.m_fNmax-1 : j=f;
712 if(!event_data.m_rf_map[j]){
713 continue;
714 }
715 r0 = event_data.m_rf_Sorted[j].begin();
716 r0e = event_data.m_rf_Sorted[j].end();
717
719 for(; r0!=r0e; ++r0){
720 if((((*r0).first)->r() > m_r1max) ||
721 (((*r0).first)->r() < m_r2min)) {
722 continue; //Fill only the SCT SPs
723 }
724 event_data.m_newRfi_Sorted.push_back(*r0);
725 }
726 }
727
728 if(event_data.m_newRfi_Sorted.size()>5000 && event_data.m_newRfi_Sorted.size()<=10000) {
729 event_data.m_newRfi_Sorted.erase(event_data.m_newRfi_Sorted.begin(),event_data.m_newRfi_Sorted.end());
730 int fmin=phi; int fmax=phi;
731 for(int f=fmin; f<=fmax; ++f) {
732 int j=0; f<0 ? j=f+event_data.m_fNmax+1 : f>event_data.m_fNmax ? j=f-event_data.m_fNmax-1 : j=f;
733 if(!event_data.m_rf_map[j]){
734 continue;
735 }
736 r0 = event_data.m_rf_Sorted[j].begin();
737 r0e = event_data.m_rf_Sorted[j].end();
738
740 for(; r0!=r0e; ++r0){
741 if((((*r0).first)->r()>m_r1max) || (((*r0).first)->r()<m_r2min)) {
742 continue; //Fill only the SCT SPs
743 }
744 event_data.m_newRfi_Sorted.push_back(*r0);
745 }
746 }
747 }
748 if(event_data.m_newRfi_Sorted.size()>10000) {
749 event_data.m_newRfi_Sorted.erase(event_data.m_newRfi_Sorted.begin(),event_data.m_newRfi_Sorted.end());
750 return;
751 }
752
753 event_data.m_newRfi_Sorted.sort(MyNewDataSortPredicate());
754
755 spcount = event_data.m_newRfi_Sorted.size();
756
757 r = event_data.m_newRfi_Sorted.begin();
758 re = event_data.m_newRfi_Sorted.end();
759
760 std::vector<bypass_struct> tmp_prod_bypass;
761 std::vector<const Trk::SpacePoint *> vrp;
762 std::vector<double> rk;
763 std::vector<long> geo_info;
764 std::vector<double> zSP;
765 tmp_prod_bypass.reserve(spcount);
766 vrp.reserve(spcount);
767 rk.reserve(spcount);
768 geo_info.reserve(spcount);
769 zSP.reserve(spcount);
770
771 // // // // // // <Fill m_prod_bypass and the local array // // // //
772 for (; r != re; ++r) {
773 const Trk::SpacePoint *vrpi = (*r).first;
774
775 geo_info.push_back((*r).second);
776 vrp.push_back(vrpi);
777 rk.push_back(vrpi->r());
778
779 double X = vrpi->globalPosition().x() - x0;
780 double Y = vrpi->globalPosition().y() - y0;
781 double zSPi = vrpi->globalPosition().z();
782 zSP.push_back(zSPi);
783 double Z = zSPi - z0;
784
785 double RR = X*X + Y*Y;
786 double R = sqrt(RR);
787 double invR = 1.0/R;
788
789 double a = X*invR;
790 double b = Y*invR;
791
792 tmp_prod_bypass.emplace_back();
793 tmp_prod_bypass.back().X = X;
794 tmp_prod_bypass.back().Y = Y;
795 tmp_prod_bypass.back().Z = Z;
796
797 tmp_prod_bypass.back().R = R;
798 tmp_prod_bypass.back().invR = invR;
799
800 tmp_prod_bypass.back().a = a;
801 tmp_prod_bypass.back().b = b;
802 }
803
804 // // // // // // Fill m_prod_bypass and the local array> // // // //
805
807
808 if (m_doCosmics) { // no need to check this every time in the loop
809 for (long i = 0; i < (long)spcount; i++) {
810 SpToPair = nullptr;
811 const Trk::SpacePoint *up = vrp[i];
812 for (long j = i + 1; j < (long)spcount; j++) {
813 const Trk::SpacePoint *bp = vrp[j];
814 SpToPair = bp;
815 outputListBuffer.emplace_back(up, SpToPair);
816 }
817 if(!SpToPair) {
818 outputListBuffer.emplace_back(up, up);
819 }
820 }
821 }
822 else { // (!m_doCosmics)
823 for (long i = 0; i < (long)spcount; i++) {
824 SpToPair = nullptr;
825 const Trk::SpacePoint *up = vrp[i];
826 double R = rk[i];
827 if(R<m_r12min) {
828 continue;
829 }
830 double Z = zSP[i];
831 long geoi = geo_info[i];
832 int isBU = (geoi >> 4)-3;
833 int eleU = geoi & 15;
834
835 for (long j = i + 1; j < (long)spcount; j++) {
836 const Trk::SpacePoint *bp = vrp[j];
837 double Zb = zSP[j];
838 double Rb = rk[j];
839 long geoj = geo_info[j];
840 int isBB = (geoj >> 4)-3;
841 int eleB = geoj & 15;
842 // // // // // // // // // // // // // // // // // // // // // //
843
844 // Equivalent to {
845 // if ((isBU == 0) && (isBB != isBU)) continue;
846 // if((isBU == isBB) && (eleU <= eleB)) continue;
847 // }
848 // Rather cryptic but 2 to 3 times faster
849 // than the 4 branches above...
850
851 int Bd = (isBU - isBB) | (isBB - isBU);
852 int Ed = (eleB - eleU);
853 int BUzero = (isBU | -isBU);
854 if (((BUzero | ~Bd) & (Bd | Ed) & (((unsigned)(-1) >> 1) + 1))
855 == 0) {
856 continue;
857 }
858
859 // // // // // // // // // // // // // // // // // // // // // //
860 double dR = R - Rb;
861 double dZ = Z - Zb;
862 double dz_min = m_dzdrmin*dR;
863 double dz_max = m_dzdrmax*dR;
864 if (dZ < dz_min || dZ > dz_max) {
865 continue;//Should be within the +-2.5 pseudorapidity range
866 }
867 if(fieldCache.solenoidOn()) {
868 if(!cutTPb(tmp_invar_bypass, tmp_prod_bypass,i, j, H[2])) {
869 continue;
870 }
871 }
872 SpToPair = bp;
873 outputListBuffer.emplace_back(up, SpToPair);
874 }
875 if(!SpToPair) {
876 outputListBuffer.emplace_back(up, up);
877 }
878 }
879 }
880
881 event_data.m_newRfi_Sorted.erase(event_data.m_newRfi_Sorted.begin(),event_data.m_newRfi_Sorted.end());
882}
883
884// comment out to enable angle discontinuity correction
885// so that e.g. angles PI-epsilon and -Pi+epsilon are treated
886// as being 2*epsilon apart as they should, instead of 2*Pi-2*epsilon
887// as they would w/o this correction
888//#define ANGLE_DISCO_COMPAT
889
890bool
892 const std::vector<bypass_struct> &tmp_prod_bypass,
893 long bSP1, long bSP2, double H) const
894{
895
896 double inv_r2 = tmp_prod_bypass[bSP2].invR;
897 double inv_r1 = tmp_prod_bypass[bSP1].invR; // == u1 in original cutTP
898 double r1 = tmp_prod_bypass[bSP1].R;
899
900 double inv_rr2 = inv_r2*inv_r2;
901 double x2 = tmp_prod_bypass[bSP2].X;
902 double y2 = tmp_prod_bypass[bSP2].Y;
903 double a1 = tmp_prod_bypass[bSP1].a;
904 double b1 = tmp_prod_bypass[bSP1].b;
905
906 double u2 = (a1*x2 + b1*y2)*inv_rr2;
907 double v2 = (a1*y2 - b1*x2)*inv_rr2;
908
909 double A = v2/(u2 - inv_r1);
910 double B = 2.0*(v2 - A*u2);
911 double CC = B*B/(1.0 + A*A);
912 double rcrc = CC*r1*r1;
913 double z1 = tmp_prod_bypass[bSP1].Z;
914 double T = -z1/(r1*(1.0 + 0.04*rcrc));
915
916 if(H==0.) return false;
917
918 double invpSignature = B*H;
919
920 double invP2 = CC/(0.03*0.03*H*H*(1.0 + T*T));
921
922 if (invpSignature >= 0 && invP2*0.9*0.9*m_ptmin*m_ptmin > 1.0) {
923 return false;
924 }
925
926 double invp_min = tmp_invar_bypass.invp_min;
927 double invp_max = tmp_invar_bypass.invp_max;
928
929 double invp_min2 = tmp_invar_bypass.invp_min2;
930 double invp_max2 = tmp_invar_bypass.invp_max2;
931
932 if (invp_min >= 0) {
933 if (invpSignature < 0 || invP2 < invp_min2) {
934 return false;
935 }
936 }
937 else {
938 if (invpSignature < 0 && invP2 > invp_min2) {
939 return false;
940 }
941 }
942 if (invp_max >= 0) {
943 if (invpSignature >= 0 && invP2 > invp_max2) {
944 return false;
945 }
946 }
947 else {
948 if (invpSignature >= 0 || invP2 < invp_max2) {
949 return false;
950 }
951 }
952
953 //Estimate the seed polar angle. Make a chi2 cut based on that suggested by the TRT segment
954
955 double theta_rating = rotrating(1.0, T);
956 double tmin = tmp_invar_bypass.min_theta;
957 double tmax = tmp_invar_bypass.max_theta;
958
959 if (tmin > tmax) {
960#ifndef ANGLE_DISCO_COMPAT
961 // correct math but incompatible with old version
962 if (theta_rating >= 0) {
963 tmax += 4.0;
964 }
965 else {
966 tmin -= 4.0;
967 }
968#else
969 // compatibility mode
970 if (tmin + tmax <= 0) {
971 // center in "+" (YES, "+") range; any negative theta_rating => false
972 tmax = 2.0; // forcing range into all positive
973 }
974 else {
975 // center in "-" (YES, "-") range; any positive theta_rating => false
976 tmin = -2.0; // forcing range into all negative
977 }
978#endif
979 }
980
981 if (theta_rating < tmin || theta_rating > tmax) {
982 return false;
983 }
984
985 double phi_rating = rotrating(-(b1 + a1*A), -(a1 - b1*A));
986 double pmin = tmp_invar_bypass.min_phi;
987 double pmax = tmp_invar_bypass.max_phi;
988
989 if (pmin > pmax) {
990#ifndef ANGLE_DISCO_COMPAT
991 // correct math but incompatible with old version
992 if (phi_rating >= 0) {
993 pmax += 4.0;
994 }
995 else {
996 pmin -= 4.0;
997 }
998#else
999 // compatibility mode
1000 if (pmin + pmax <= 0) {
1001 // center in "+" (YES, "+") range; any negative phi_rating => false
1002 pmax = 2.0; // forcing range into all positive
1003 }
1004 else {
1005 // center in "-" (YES, "-") range; any positive phi_rating => false
1006 pmin = -2.0; // forcing range into all negative
1007 }
1008#endif
1009 }
1010
1011 return phi_rating >= pmin && phi_rating <= pmax;
1012}
1013
1014// // // // // // // // // // // // // // // // // // // // // // // // // //
1015
1016
1018// Check whether the SP belongs to a barrel or an endcap element
1020
1021void
1023{
1024 const Trk::PrepRawData* p1;
1025 const InDet::SCT_Cluster* c1;
1026 Identifier id;
1027
1028 p1 = SP->clusterList().first;
1029 if(p1){
1030 c1=dynamic_cast<const InDet::SCT_Cluster*>(p1);
1031 if(c1){
1032 id=c1->detectorElement()->identify();
1033 isB = m_sctId->barrel_ec(id);
1034 ld = m_sctId->layer_disk(id);
1035 }
1036 }
1037
1038}
1039
1041// MagneticFieldProperties production
1043
const boost::regex re(r_e)
#define M_PI
Scalar phi() const
phi method
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define AmgSymMatrix(dim)
#define AmgVector(rows)
static Double_t sp
static Double_t a
static Double_t sc
#define F(x, y, z)
Definition MD5.cxx:112
#define H(x, y, z)
Definition MD5.cxx:114
This is an Identifier helper class for the SCT subdetector.
Handle class for reading from StoreGate.
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
double rotrating(double y, double x)
void bracket_angle(double angle, double delta, double *min, double *max)
double rollrating(double angle)
#define y
#define x
#define min(a, b)
Definition cfImp.cxx:40
#define max(a, b)
Definition cfImp.cxx:41
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
const ServiceHandle< StoreGateSvc > & detStore() const
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
Sorting function according to space point radial position.
std::list< std::pair< const Trk::SpacePoint *, int > > m_newRfi_Sorted
std::list< std::pair< const Trk::SpacePoint *, int > > m_rf_Sorted[530]
void buildFrameWork(double r_rmax, double r_rstep, double ptmin)
std::unique_ptr< InDet::ITRT_SeededSpacePointFinder::IEventData > newEvent() const
Method to initialize tool for new event.
static constexpr double m_dzdrmax
Min R-z direction cut.
DoubleProperty m_ptmin
Seed selection criteria.
SG::ReadHandleKey< SpacePointOverlapCollection > m_spacepointsOverlapname
static constexpr double m_r_rmax
Minimum SCT radius to be searched.
static constexpr double m_r1max
Step size for space point storage.
std::list< std::pair< const Trk::SpacePoint *, const Trk::SpacePoint * > > find2Sp(const EventContext &ctx, const Trk::TrackParameters &, ITRT_SeededSpacePointFinder::IEventData &event_data) const
Main method of seed production.
static constexpr double m_dzdrmin
Min radius to search for SP pairs.
const SCT_ID * m_sctId
Magnetic field properties.
SG::ReadHandleKey< SpacePointContainer > m_spacepointsPixname
Space points containers.
TRT_SeededSpacePointFinder_ATL(const std::string &, const std::string &, const IInterface *)
Standard tool methods.
SG::ReadHandleKey< Trk::PRDtoTrackMap > m_prdToTrackMap
static constexpr double m_r2min
Min radius of last SCT layer.
void magneticFieldInit()
Get magnetic field properties.
SG::ReadHandleKey< SpacePointContainer > m_spacepointsSCTname
static constexpr double m_r12min
Max radius of last SCT layer.
void geoInfo(const Trk::SpacePoint *, int &, int &) const
Obtain geo model info for a specific space point.
MsgStream & dumpConditions(MsgStream &out) const
Protected methods.
void fillLists(std::vector< std::vector< const Trk::SpacePoint * > > &r_Sorted, InDet::TRT_SeededSpacePointFinder_ATL::EventData &event_data) const
Fill the space point container lists at beginning of each event.
void production2Spb(const EventContext &ctx, const Trk::TrackParameters &, int, std::list< std::pair< const Trk::SpacePoint *, const Trk::SpacePoint * > > &outputListBuffer, InDet::TRT_SeededSpacePointFinder_ATL::EventData &event_data) const
Form possible space point combinations within allowed radial and pseudorapidity ranges.
MsgStream & dumpEvent(MsgStream &out, InDet::TRT_SeededSpacePointFinder_ATL::EventData &event_data) const
bool cutTPb(const invar_bypass_struct &invar_bypass, const std::vector< bypass_struct > &prod_bypass, long, long, double) const
Cut on chi2 based on TRT segment qOverP, theta and phi track parameters.
static constexpr double m_r_rstep
Maximum STC radius to be searched.
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCondObjInputKey
std::unique_ptr< InDet::ITRT_SeededSpacePointFinder::IEventData > newRegion(const std::vector< IdentifierHash > &, const std::vector< IdentifierHash > &) const
StringProperty m_fieldmode
Protected data and methods.
MsgStream & dump(MsgStream &out) const
Print internal tool parameters and status.
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
bool solenoidOn() const
status of the magnets
void getField(const double *ATH_RESTRICT xyz, double *ATH_RESTRICT bxyz, double *ATH_RESTRICT deriv=nullptr)
get B field value at given position xyz[3] is in mm, bxyz[3] is in kT if deriv[9] is given,...
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
static EventData & getPrivateEventData(InDet::ITRT_SeededSpacePointFinder::IEventData &virt_event_data)
magnetic field properties to steer the behavior of the extrapolation
const Amg::Vector3D & position() const
Access method for the position.
virtual const Amg::Vector3D & globalPosition() const override final
Interface method to get the global Position.
double r() const
returns the r value of the SpacePoint's position (in cylindrical coordinates).
const std::pair< const PrepRawData *, const PrepRawData * > & clusterList() const
return the pair of cluster pointers by reference
int ir
counter of the current depth
Definition fastadd.cxx:49
int r
Definition globals.cxx:22
@ FastField
call the fast field access method of the FieldSvc
@ NoField
Field is set to 0., 0., 0.,.
@ FullField
Field is set to be realistic, but within a given Volume.
ParametersBase< TrackParametersDim, Charged > TrackParameters
STL namespace.
hold the test vectors and ease the comparison