ATLAS Offline Software
Loading...
Searching...
No Matches
SiDetElementsRoadMaker_xk.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6// Implementation file for class InDet::SiDetElementsRoadMaker_xk
8// (c) ATLAS Detector software
11// Version 1.0 21/04/2004 I.Gavrilenko
13
16
18
19#include "GaudiKernel/ContextSpecificPtr.h"
25#include <cmath>
26
27#include <ostream>
28#include <iomanip>
29
31// Constructor
33
35(const std::string& t, const std::string& n, const IInterface* p)
36 : base_class(t, n, p)
37{
38}
39
41// Initialisation
43
45{
46 //Class optimization checks
47 static_assert(std::is_trivially_copyable<SiDetElementLink_xk::ElementWay>::value);
48 static_assert(std::is_trivially_destructible<SiDetElementLink_xk::ElementWay>::value);
49 static_assert(std::is_trivially_copyable<SiDetElementLink_xk>::value);
50 static_assert(std::is_trivially_destructible<SiDetElementLink_xk>::value);
51 static_assert(std::is_nothrow_move_constructible<SiDetElementsLayer_xk>::value);
52
53
54 if (!m_usePIX && !m_useSCT) {
55 ATH_MSG_FATAL("Please don't call this tool if usePixel and useSCT are false");
56 return StatusCode::FAILURE;
57 }
58
59 if (m_fieldmode == "NoField") m_fieldModeEnum = Trk::NoField;
60 else if (m_fieldmode == "MapSolenoid") m_fieldModeEnum = Trk::FastField;
62
63 // Get propagator tool
64 //
65 ATH_CHECK(m_proptool.retrieve());
66
67 // Get output print level
68 //
69 m_outputlevel = msg().level()-MSG::DEBUG;
70
72
73 ATH_CHECK(m_layerVecKey.initialize());
75
76 return StatusCode::SUCCESS;
77}
78
80// Finalize
82
84{
85 return StatusCode::SUCCESS;
86}
87
88
90// Dumps relevant information into the MsgStream
92
93MsgStream& InDet::SiDetElementsRoadMaker_xk::dump(MsgStream& out) const
94{
95 out<<"\n";
96 return dumpConditions(out);
97}
98
100// Dumps conditions information into the MsgStream
102
104{
105 int n = 62-m_proptool.type().size();
106 std::string s1;
107 for (int i=0; i<n; ++i) s1.append(" ");
108 s1.append("|");
109
110 std::string fieldmode[9] = {"NoField" , "ConstantField", "SolenoidalField",
111 "ToroidalField" , "Grid3DField" , "RealisticField" ,
112 "UndefinedField", "AthenaField" , "?????" };
113
115
117 const AtlasFieldCacheCondObj* fieldCondObj(*fieldHandle);
118 if (fieldCondObj) {
119 MagField::AtlasFieldCache fieldCache;
120 fieldCondObj->getInitializedCache(fieldCache);
121 if (!fieldCache.solenoidOn()) fieldModeEnum = Trk::NoField;
122 }
123
124 Trk::MagneticFieldProperties fieldprop(fieldModeEnum);
125
126 int mode = fieldprop.magneticFieldMode();
127 if (mode<0 || mode>8) mode = 8;
128
129 n = 62-fieldmode[mode].size();
130 std::string s3;
131 for (int i=0; i<n; ++i) s3.append(" ");
132 s3.append("|");
133
134 n = 62-m_sct.size();
135 std::string s5;
136 for (int i=0; i<n; ++i) s5.append(" ");
137 s5.append("|");
138
139 n = 62-m_pix.size();
140 std::string s6;
141 for (int i=0; i<n; ++i) s6.append(" ");
142 s6.append("|");
143
144 const EventContext& ctx = Gaudi::Hive::currentContext();
145
146 const SiDetElementsLayerVectors_xk &layer = *getLayers(ctx);
147
148 int maps = 0;
149 if (!layer[0].empty()) ++maps;
150 if (!layer[1].empty()) ++maps;
151 if (!layer[2].empty()) ++maps;
152 auto prec = out.precision();
153 out<<"|----------------------------------------------------------------------"
154 <<"-------------------|"
155 <<"\n";
156 if (m_useSCT) {
157 out<<"| SCT detector manager | "<<m_sct <<s5<<"\n";
158 }
159 if (m_usePIX) {
160 out<<"| Pixel detector manager | "<<m_pix <<s6<<"\n";
161 }
162 out<<"| Tool for propagation | "<<m_proptool.type() <<s1<<"\n";
163 out<<"| Magnetic field mode | "<<fieldmode[mode] <<s3<<"\n";
164 out<<"| Width of the road (mm) | "
165 <<std::setw(12)<<std::setprecision(5)<<m_width
166 <<" |"<<"\n";
167 out<<"|----------------------------------------------------------------------"
168 <<"-------------------|"
169 <<"\n";
170
171 if (!maps || m_outputlevel==0) return out;
172
173 if (!layer[1].empty()) {
174 int nl = layer[1].size();
175 int nc = 0;
176 for (const auto & i : layer[1]) nc+=i.nElements();
177 out<<"|----------------------------------------------------------------|"
178 <<"\n";
179 out<<"| Barrel map contains "
180 <<std::setw(3)<<nl<<" layers and"
181 <<std::setw(5)<<nc<<" elements |"
182 <<"\n";
183 out<<"|------|-----------|------------|------------|------------|------|"
184 <<"\n";
185 out<<"| n | R | Z min | Z max | max dF | nEl |"
186 <<"\n";
187 out<<"|------|-----------|------------|------------|------------|------|"
188 <<"\n";
189 for (unsigned int i=0; i!=layer[1].size(); ++i) {
190 double zmin = layer[1].at(i).z()-layer[1].at(i).dz();
191 double zmax = layer[1].at(i).z()+layer[1].at(i).dz();
192 out<<"| "
193 <<std::setw(4)<<i<<" |"
194 <<std::setw(10)<<std::setprecision(4)<< layer[1].at(i).r ()<<" | "
195 <<std::setw(10)<<std::setprecision(4)<< zmin<<" | "
196 <<std::setw(10)<<std::setprecision(4)<< zmax<<" | "
197 <<std::setw(10)<<std::setprecision(4)<< layer[1].at(i).dfe()<<" | "
198 <<std::setw(4)<<layer[1].at(i).nElements()<<" | "
199 <<"\n";
200 }
201 out<<"|------|-----------|------------|------------|------------|------|"
202 <<"\n";
203
204 }
205 if (!layer[0].empty()) {
206 int nl = layer[0].size();
207 int nc = 0;
208 for (const auto & i : layer[0]) nc+=i.nElements();
209 out<<"|----------------------------------------------------------------|"
210 <<"\n";
211 out<<"| L.Endcap map contains"
212 <<std::setw(3)<<nl<<" layers and"
213 <<std::setw(5)<<nc<<" elements |"
214 <<"\n";
215
216 out<<"|------|-----------|------------|------------|------------|------|"
217 <<"\n";
218 out<<"| n | Z | R min | R max | max dF | nEl |"
219 <<"\n";
220 out<<"|------|-----------|------------|------------|------------|------|"
221 <<"\n";
222 for (unsigned int i=0; i!=layer[0].size(); ++i) {
223 double rmin = layer[0].at(i).r()-layer[0].at(i).dr();
224 double rmax = layer[0].at(i).r()+layer[0].at(i).dr();
225 out<<"| "
226 <<std::setw(4)<<i<<" |"
227 <<std::setw(10)<<std::setprecision(4)<< layer[0].at(i).z()<<" | "
228 <<std::setw(10)<<std::setprecision(4)<< rmin<<" | "
229 <<std::setw(10)<<std::setprecision(4)<< rmax<<" | "
230 <<std::setw(10)<<std::setprecision(4)<<layer[0].at(i).dfe()<<" | "
231 <<std::setw(4)<<layer[0].at(i).nElements()<<" | "
232 <<"\n";
233 }
234 out<<"|------|-----------|------------|------------|------------|------|"
235 <<"\n";
236 }
237 if (!layer[2].empty()) {
238 int nl = layer[2].size();
239 int nc = 0;
240 for (const auto & i : layer[2]) nc+=i.nElements();
241 out<<"|----------------------------------------------------------------|"
242 <<"\n";
243 out<<"| R.Endcap map contains"
244 <<std::setw(3)<<nl<<" layers and"
245 <<std::setw(5)<<nc<<" elements |"
246 <<"\n";
247 out<<"|------|-----------|------------|------------|------------|------|"
248 <<"\n";
249 out<<"| n | Z | R min | R max | max dF | nEl |"
250 <<"\n";
251 out<<"|------|-----------|------------|------------|------------|------|"
252 <<"\n";
253 for (unsigned int i=0; i!=layer[2].size(); ++i) {
254 double rmin = layer[2].at(i).r()-layer[2].at(i).dr();
255 double rmax = layer[2].at(i).r()+layer[2].at(i).dr();
256 out<<"| "
257 <<std::setw(4)<<i<<" |"
258 <<std::setw(10)<<std::setprecision(4)<< layer[2].at(i).z()<<" | "
259 <<std::setw(10)<<std::setprecision(4)<< rmin<<" | "
260 <<std::setw(10)<<std::setprecision(4)<< rmax<<" | "
261 <<std::setw(10)<<std::setprecision(4)<<layer[2].at(i).dfe()<<" | "
262 <<std::setw(4)<<layer[2].at(i).nElements()<<" | "
263 <<"\n";
264 }
265 out<<"|------|-----------|------------|------------|------------|------|"
266 <<"\n";
267 }
268 out<<"\n";
269 out.precision(prec);
270 return out;
271}
272
274// Dumps relevant information into the ostream
276
277std::ostream& InDet::SiDetElementsRoadMaker_xk::dump(std::ostream& out) const
278{
279 return out;
280}
281
283// Overload of << operator MsgStream
285
286MsgStream& InDet::operator <<
287(MsgStream& sl, const InDet::SiDetElementsRoadMaker_xk& se)
288{
289 return se.dump(sl);
290}
291
293// Overload of << operator std::ostream
295
296std::ostream& InDet::operator <<
297(std::ostream& sl, const InDet::SiDetElementsRoadMaker_xk& se)
298{
299 return se.dump(sl);
300}
301
302
304// Main methods for road builder using input list global positions
306
308(std::deque<Amg::Vector3D>& globalPositions,
309 std::vector<const InDetDD::SiDetectorElement*>& Road,
310 bool testDirection,
311 SiDetElementRoadMakerData_xk & roadMakerData,
312 const EventContext& ctx) const
313{
314 if (!m_usePIX && !m_useSCT) return;
315
327 const SiDetElementsLayerVectors_xk &layer = *getLayers(ctx);
328
330 std::deque<Amg::Vector3D>::iterator currentPosition=globalPositions.begin(), endPositions=globalPositions.end();
331
334 std::array<float,6> par_startingPoint{static_cast<float>((*currentPosition).x()), // x of first position
335 static_cast<float>((*currentPosition).y()), // y of first position
336 static_cast<float>((*currentPosition).z()), // Z of first position
337 static_cast<float>(sqrt((*currentPosition).x()*(*currentPosition).x()+(*currentPosition).y()*(*currentPosition).y())), // r of first position
338 m_width, // road width
339 0.};
340
344 int n0 = 0;
345 for (; n0!=static_cast<int>(layer[0].size()); ++n0) {
346 if (par_startingPoint[2] > layer[0][n0].z()) break;
347 }
348
352 int n1 = 0;
353 for (; n1!=static_cast<int>(layer[1].size()); ++n1) {
354 if (par_startingPoint[3] < layer[1][n1].r()) break;
355 }
358 int n2 = 0;
359 for (; n2!=static_cast<int>(layer[2].size()); ++n2) {
360 if (par_startingPoint[2] < layer[2][n2].z()) break;
361 }
362
363
364
368 if (!roadMakerData.isInitialized){
369 bookUsageTracker(roadMakerData,layer);
370 }
371 else{
374 roadMakerData.resetUsageTracker();
375 }
376
377 std::vector<InDet::SiDetElementLink_xk::ElementWay> lDE;
378 lDE.reserve(8); //reasonable minimum guess
380 ++currentPosition;
381 while (currentPosition!=endPositions) {
383 std::array<float,4> par_targetPoint{static_cast<float>((*currentPosition).x()),
384 static_cast<float>((*currentPosition).y()),
385 static_cast<float>((*currentPosition).z()),
386 static_cast<float>(sqrt((*currentPosition).x()*(*currentPosition).x()+(*currentPosition).y()*(*currentPosition).y()))
387 };
388
390 float dx = par_targetPoint[0]-par_startingPoint[0];
391 float dy = par_targetPoint[1]-par_startingPoint[1];
392 float dz = par_targetPoint[2]-par_startingPoint[2];
393 float dist3D = std::sqrt(dx*dx+dy*dy+dz*dz);
394 if (dist3D <=0.) {
395 ++currentPosition;
396 continue;
397 }
398 float inverseDistance = 1./dist3D;
400 std::array<float,3> searchDirection{dx*inverseDistance, dy*inverseDistance, dz*inverseDistance};
401
405 float unitSepTransverseComp = searchDirection[0]*searchDirection[0]+searchDirection[1]*searchDirection[1];
406 float dr = 0. ;
407 if (unitSepTransverseComp!=0.) {
410 float sm = -( searchDirection[0]*par_startingPoint[0] +
411 searchDirection[1]*par_startingPoint[1])
412 /unitSepTransverseComp;
413
419 if (sm > 1. && sm < dist3D) {
420 par_targetPoint[0] = par_startingPoint[0]+searchDirection[0]*sm;
421 par_targetPoint[1] = par_startingPoint[1]+searchDirection[1]*sm;
422 par_targetPoint[2] = par_startingPoint[2]+searchDirection[2]*sm;
423 par_targetPoint[3] = std::sqrt(par_targetPoint[0]*par_targetPoint[0]+par_targetPoint[1]*par_targetPoint[1]);
426 dr = 20.;
427 } else {
428 ++currentPosition;
429 }
430 } else {
431 ++currentPosition;
432 }
433
435
437
439 if (par_targetPoint[3]>par_startingPoint[3]) {
441 for (; n1<static_cast<int>(layer[1].size()); ++n1) {
443 if (par_targetPoint[3] < layer[1][n1].r()) break;
444 assert( roadMakerData.elementUsageTracker[1].size() > static_cast<unsigned int>(n1) );
446 if(m_ITkGeometry) layer[1][n1].getITkBarrelDetElements(par_startingPoint, searchDirection, lDE, roadMakerData.elementUsageTracker[1][n1]);
447 else layer[1][n1].getBarrelDetElements(par_startingPoint, searchDirection, lDE, roadMakerData.elementUsageTracker[1][n1]);
448 }
450 } else {
451 for (--n1; n1>=0; --n1) {
453 if (par_targetPoint[3] > layer[1][n1].r()+dr) break;
454 assert( roadMakerData.elementUsageTracker[1].size() > static_cast<unsigned int>(n1) );
456 if(m_ITkGeometry) layer[1][n1].getITkBarrelDetElements(par_startingPoint, searchDirection, lDE, roadMakerData.elementUsageTracker[1][n1]);
457 else layer[1][n1].getBarrelDetElements(par_startingPoint, searchDirection, lDE, roadMakerData.elementUsageTracker[1][n1]);
458
459 }
460 ++n1;
461 }
462
465 if (par_targetPoint[2]>par_startingPoint[2]) {
466 for (; n2<static_cast<int>(layer[2].size()); ++n2) {
467 if (par_targetPoint[2] < layer[2][n2].z()) break;
468 assert( roadMakerData.elementUsageTracker[2].size() > static_cast<unsigned int>(n2) );
470 if(m_ITkGeometry) layer[2][n2].getITkEndcapDetElements(par_startingPoint, searchDirection, lDE,roadMakerData.elementUsageTracker[2][n2]);
471 else layer[2][n2].getEndcapDetElements(par_startingPoint, searchDirection, lDE,roadMakerData.elementUsageTracker[2][n2]);
472 }
473 } else {
474 for (--n2; n2>=0; --n2) {
475 if (par_targetPoint[2] > layer[2][n2].z()) break;
476 assert( roadMakerData.elementUsageTracker[2].size() > static_cast<unsigned int>(n2) );
478 if(m_ITkGeometry) layer[2][n2].getITkEndcapDetElements(par_startingPoint, searchDirection, lDE, roadMakerData.elementUsageTracker[2][n2]);
479 else layer[2][n2].getEndcapDetElements(par_startingPoint, searchDirection, lDE, roadMakerData.elementUsageTracker[2][n2]);
480 }
481 ++n2;
482 }
483
486 if (par_targetPoint[2]<par_startingPoint[2]) {
487 for (; n0<static_cast<int>(layer[0].size()); ++n0) {
488 if (par_targetPoint[2] > layer[0][n0].z()) break;
489 assert( roadMakerData.elementUsageTracker[0].size() > static_cast<unsigned int>(n0) );
491 if(m_ITkGeometry) layer[0][n0].getITkEndcapDetElements(par_startingPoint, searchDirection, lDE,roadMakerData.elementUsageTracker[0][n0]);
492 else layer[0][n0].getEndcapDetElements(par_startingPoint, searchDirection, lDE,roadMakerData.elementUsageTracker[0][n0]);
493 }
494 } else {
495 for (--n0; n0>=0; --n0) {
496 if (par_targetPoint[2] < layer[0][n0].z()) break;
497 assert( roadMakerData.elementUsageTracker[0].size() > static_cast<unsigned int>(n0) );
499 if(m_ITkGeometry) layer[0][n0].getITkEndcapDetElements(par_startingPoint, searchDirection, lDE,roadMakerData.elementUsageTracker[0][n0]);
500 else layer[0][n0].getEndcapDetElements(par_startingPoint, searchDirection, lDE,roadMakerData.elementUsageTracker[0][n0]);
501 }
502 ++n0;
503 }
505 par_startingPoint[0] = par_targetPoint[0];
506 par_startingPoint[1] = par_targetPoint[1];
507 par_startingPoint[2] = par_targetPoint[2];
508 par_startingPoint[3] = par_targetPoint[3];
510 par_startingPoint[5]+= dist3D;
511 }
512 auto vec2 = lDE;
513 std::sort(lDE.begin(),lDE.end(),InDet::compDetElementWays());
514 // Fill pointers to detector elements
515 Road.reserve(lDE.size());
516 for (auto & d : lDE){
517 if (testDirection && d.way() < 0) {continue;}
518 Road.push_back(d.link()->detElement());
519 }
520}
521
523void InDet::SiDetElementsRoadMaker_xk::bookUsageTracker(InDet::SiDetElementRoadMakerData_xk & data, const SiDetElementsLayerVectors_xk &layers) {
524
527 for ( unsigned int side_i=0; side_i<3; ++side_i) {
528 data.elementUsageTracker[side_i].resize( layers[side_i].size() );
529 for (unsigned int layer_i=0; layer_i < layers[side_i].size(); ++layer_i) {
531 data.elementUsageTracker[side_i][layer_i].resize( layers[side_i][layer_i].nElements() );
532 }
533 }
534 data.isInitialized=true;
535}
536
538// Main methods for road builder using track parameters and direction
540
542(const EventContext& ctx,
543 MagField::AtlasFieldCache& fieldCache,
545 Trk::PropDirection direction,
546 std::vector<const InDetDD::SiDetectorElement*>& Road,
547 SiDetElementRoadMakerData_xk & roadMakerData) const
548{
549 if (!m_usePIX && !m_useSCT) return;
551 double qp = fabs(500.*Tp.parameters()[4]);
553 if (qp < 1.e-10) qp = 1.e-10;
555 double S = m_step/qp;
557 if (S > 1000. ) S = 1000. ;
558
559 bool testDirection = true;
560 if (direction<0) {
561 testDirection = false;
562 S=-S;
563 }
564
566 if (!fieldCache.solenoidOn()) fieldModeEnum = Trk::NoField;
567 Trk::MagneticFieldProperties fieldprop(fieldModeEnum);
568
569 // Note: could also give fieldCache directly to propagator if it would be more efficient - would
570 // need to add interface RDS 2020/03
571 std::deque<Amg::Vector3D> G;
572
575 m_proptool->globalPositions(ctx, G, Tp, fieldprop,getBound(fieldCache, Tp), S, Trk::pion);
577 if (G.size()<2) return;
578
581 if (direction > 0) {
582 std::deque<Amg::Vector3D>::iterator currentPosition=G.begin(), nextPosition, endPositions=G.end();
583 float r0 = (*currentPosition).x()*(*currentPosition).x()+(*currentPosition).y()*(*currentPosition).y();
584
585 while (currentPosition!=endPositions) {
586 nextPosition = currentPosition;
587 if (++nextPosition == endPositions) break;
588
589 float r = (*nextPosition).x()*(*nextPosition).x()+(*nextPosition).y()*(*nextPosition).y();
591 if (r < r0) {
592 r0 = r;
593 currentPosition = G.erase(currentPosition);
594 } else {
595 break;
596 }
597 }
598 }
600 detElementsRoad(G, Road,testDirection, roadMakerData,ctx);
601}
602
603
605// Map of detector elements production
607
609{
610
611 StatusCode sc;
612
613 // Get Pixel Detector Manager
614 //
615 const InDetDD::PixelDetectorManager* pixmgr = nullptr;
616 if (m_usePIX) {
617 sc = detStore()->retrieve(pixmgr, m_pix);
618 if (sc.isFailure() || !pixmgr) {
619 ATH_MSG_FATAL("Could not get PixelDetectorManager !");
620 return;
621 }
622 }
623
624 // Get SCT Detector Manager
625 //
626 const InDetDD::SCT_DetectorManager* sctmgr = nullptr;
627 if (m_useSCT) {
628 sc = detStore()->retrieve(sctmgr, m_sct);
629 if (sc.isFailure() || !sctmgr) {
630 ATH_MSG_FATAL("Could not get SCT_DetectorManager !");
631 return;
632 }
633 }
634
635 const PixelID* IDp = nullptr;
636 const SCT_ID* IDs = nullptr;
637
638 if (m_usePIX && detStore()->retrieve(IDp, "PixelID").isFailure()) {
639 ATH_MSG_FATAL("Could not get Pixel ID helper");
640 }
641
642 if (m_useSCT && detStore()->retrieve(IDs, "SCT_ID").isFailure()) {
643 ATH_MSG_FATAL("Could not get SCT ID helper");
644 }
645
646
647 if (!IDs && !IDp) return;
648
650 std::vector<InDetDD::SiDetectorElement const*> pW[3];
651
652 if (IDp) {
653 // Loop over each wafer of pixels
654 //
655 s = pixmgr->getDetectorElementBegin();
656 se = pixmgr->getDetectorElementEnd ();
657
658 for (; s!=se; ++s) {
659 if ((*s)->isBarrel() ) pW[1].push_back((*s)); // Barrel
660 else if ((*s)->center().z() > 0.) pW[2].push_back((*s)); // Right endcap
661 else pW[0].push_back((*s)); // Left endcap
662 }
663 }
664
665 if (IDs) {
666 // Loop over each wafer of sct
667 //
668 s = sctmgr->getDetectorElementBegin();
669 se = sctmgr->getDetectorElementEnd ();
670
671 for (; s!=se; ++s) {
672 if ((*s)->isBarrel() ) pW[1].push_back((*s)); // Barrel
673 else if ((*s)->center().z() > 0.) pW[2].push_back((*s)); // Right endcap
674 else pW[0].push_back((*s)); // Left endcap
675 }
676 }
677
678 int nel = pW[0].size()+pW[1].size()+pW[2].size();
679 if (!nel) return;
680
681 std::sort(pW[1].begin(), pW[1].end(), InDet::compDetElements_RAZ());
682 std::sort(pW[0].begin(), pW[0].end(), InDet::compDetElements_ZRA());
683 std::sort(pW[2].begin(), pW[2].end(), InDet::compDetElements_ZRA());
684
685 double mzmin [3]; // min Z coordinate
686 double mzmax [3]; // max Z coordinate
687 double mrmin [3]; // min radius
688 double mrmax [3]; // max radius
689 bool has[3] {false,false,false};
690
691 for (int N=0; N!=3; ++N) {
692 double P[40];
693 int im = static_cast<int>(pW[N].size()-1);
694 int If = 0 ;
695 double z0 = 0. ;
696 double r0 = 0. ;
697 mrmin[N] = 100000.;
698 mrmax[N] =-100000.;
699 mzmin[N] = 100000.;
700 mzmax[N] =-100000.;
701
702 for (int i = 0; i<= im; ++i) {
704
705 if (P[ 9] < mrmin[N]) mrmin[N] = P[ 9];
706 if (P[10] > mrmax[N]) mrmax[N] = P[10];
707 if (P[11] < mzmin[N]) mzmin[N] = P[11];
708 if (P[12] > mzmax[N]) mzmax[N] = P[12];
709
710 double r = P[0];
711 double z = P[1];
712 bool newl = false;
713 if (N==1) {
714 if (fabs(r-r0) > 10.) {
715 newl=true;
716 r0=r;
717 }
718 } else {
719 if (fabs(z-z0) > 10.) {
720 newl=true;
721 r0=r;
722 z0=z;
723 }
724 }
725
726 if (newl || i==im) {
727 int Il = i-1;
728 if (i==im) ++Il;
729
730 if (If<=Il) {
731 has[N]=true;
732 }
733 If = i;
734 }
735 }
736 }
737
738 // CylinderBounds production
739 //
740 double zmi = +100000;
741 double zma = -100000;
742 double rma = -100000;
743 for (int i=0; i!=3; ++i) {
744 if (has[i]) {
745 if (mzmin[i]<zmi) zmi=mzmin[i];
746 if (mzmax[i]>zma) zma=mzmax[i];
747 if (mrmax[i]>rma) rma=mrmax[i];
748 }
749 }
750
751 double hz = fabs(zma);
752 if (hz<fabs(zmi)) hz = fabs(zmi);
753 const Trk::CylinderBounds CB(rma+20., hz+20.);
754 m_bounds = CB;
755}
756
757
759// Distance to detector element according stright line model
761
764{
765 Amg::Vector3D R = de->center();
766 Amg::Vector3D A = de->normal();
767 double D = a.x()*A.x()+a.y()*A.y()+a.z()*A.z();
768 if (D==0.) return static_cast<float>(D);
769 return static_cast<float>((A.x()*(R.x()-r.x())+A.y()*(R.y()-r.y())+A.z()*(R.z()-r.z()))/D);
770}
771
773// Cylinder bounds parameters estimation
775
777(MagField::AtlasFieldCache& fieldCache,
778 const Trk::TrackParameters& Tp) const
779{
780 const double cor = 1.;
781
782 double zfield = 0.;
783 if (m_fieldModeEnum!=Trk::NoField && fieldCache.solenoidOn()) {
784 const Amg::Vector3D& pos = Tp.position();
785 double f[3], p[3] = {pos[Amg::x], pos[Amg::y], pos[Amg::z]};
786
787 fieldCache.getFieldZR(p, f);
788
789 zfield = 299.7925*f[2];
790 }
791
792 if (fabs(zfield) < .0000001) return m_bounds;
793
794 const AmgVector(5)& Vp = Tp.parameters();
795
796 double cur = zfield*Vp[4]/sin(Vp[3]);
797
798 if (fabs(cur)*m_bounds.r() < cor) return m_bounds;
799
800 double rad = 1./cur;
801 if (cor*fabs(rad) > m_bounds.r() ) return m_bounds;
802
803 const Amg::Vector3D& Gp = Tp.position();
804
805 double S, C;
806 sincos(Vp[2], &S, &C);
807
808 double xc = Gp.x()+S*rad;
809 double yc = Gp.y()-C*rad;
810 double rm = (sqrt(xc*xc+yc*yc)+fabs(rad))*cor;
811 if (rm > m_bounds.r()) return m_bounds;
812 Trk::CylinderBounds CB(rm, m_bounds.halflengthZ());
813 return CB;
814}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define AmgVector(rows)
static Double_t a
static Double_t Tp(Double_t *t, Double_t *par)
static Double_t P(Double_t *tt, Double_t *par)
static Double_t sc
#define G(x, y, z)
Definition MD5.cxx:113
size_t size() const
Number of registered mappings.
#define z
static const Attributes_t empty
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
Dedicated detector manager extending the functionality of the SiDetectorManager with dedicated pixel ...
virtual SiDetectorElementCollection::const_iterator getDetectorElementBegin() const override
virtual SiDetectorElementCollection::const_iterator getDetectorElementEnd() const override
Dedicated detector manager extending the functionality of the SiDetectorManager with dedicated SCT in...
virtual SiDetectorElementCollection::const_iterator getDetectorElementBegin() const override
virtual SiDetectorElementCollection::const_iterator getDetectorElementEnd() const override
Class to hold geometrical description of a silicon detector element.
virtual const Amg::Vector3D & normal() const override final
Get reconstruction local normal axes in global frame.
virtual const Amg::Vector3D & center() const override final
Center in global coordinates.
InDet::SiDetElementRoadMakerData_xk holds event dependent data used by SiDetElementRoadMaker_xk.
void resetUsageTracker()
method to reset the flags stored in the elementUsageTracker (below) when building a new search road.
bool isInitialized
Flag to check if the event data was already initialized by the client tool.
const SiDetElementsLayerVectors_xk * getLayers(const EventContext &ctx) const
virtual StatusCode initialize() override
MsgStream & dump(MsgStream &out) const override
MsgStream & dumpConditions(MsgStream &out) const
virtual void detElementsRoad(std::deque< Amg::Vector3D > &globalPositions, std::vector< const InDetDD::SiDetectorElement * > &Road, bool testDirection, SiDetElementRoadMakerData_xk &roadMakerData, const EventContext &ctx) const override
This signature assumes you already have a list of positions along the trajectory.
PublicToolHandle< Trk::IPropagator > m_proptool
static float stepToDetElement(const InDetDD::SiDetectorElement *&, Amg::Vector3D &, Amg::Vector3D &)
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCondObjInputKey
Trk::CylinderBounds getBound(MagField::AtlasFieldCache &fieldCache, const Trk::TrackParameters &) const
static void bookUsageTracker(InDet::SiDetElementRoadMakerData_xk &data, const SiDetElementsLayerVectors_xk &layers)
this method is used to initialize the detector element usage tracker member of the event data struct ...
SG::ReadCondHandleKey< SiDetElementsLayerVectors_xk > m_layerVecKey
Created by SiDetElementsRoadCondAlg_xk.
SiDetElementsRoadMaker_xk(const std::string &, const std::string &, const IInterface *)
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.
This is an Identifier helper class for the Pixel subdetector.
Definition PixelID.h:69
This is an Identifier helper class for the SCT subdetector.
Definition SCT_ID.h:68
Bounds for a cylindrical Surface.
magnetic field properties to steer the behavior of the extrapolation
MagneticFieldMode magneticFieldMode() const
Returns the MagneticFieldMode as specified.
int r
Definition globals.cxx:22
struct color C
Eigen::Matrix< double, 3, 1 > Vector3D
void detElementInformation(const InDetDD::SiDetectorElement &Si, double *P)
PropDirection
PropDirection, enum for direction of the propagation.
MagneticFieldMode
MagneticFieldMode describing the field setup within a volume.
@ 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
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
hold the test vectors and ease the comparison
MsgStream & msg
Definition testRead.cxx:32