ATLAS Offline Software
Loading...
Searching...
No Matches
TRT_DetElementsRoadMaker_xk.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 InDet::TRT_DetElementsRoadMaker_xk
8// (c) ATLAS Detector software
11// Version 1.0 21/04/2004 I.Gavrilenko
13
14#include <iostream>
15#include <iomanip>
16
17#include <utility>
18
20
24
29
31
34#include <cmath>
35
36
38// Constructor
40
42(const std::string& t,const std::string& n,const IInterface* p)
43 : AthAlgTool(t,n,p)
44{
45 declareInterface<ITRT_DetElementsRoadMaker>(this);
46}
47
49// Destructor
51
53= default;
54
56// Initialisation
58
60{
61 StatusCode sc = AlgTool::initialize();
62 if(m_fieldmode == "NoField") m_fieldModeEnum = Trk::NoField;
63 else if(m_fieldmode == "MapSolenoid") m_fieldModeEnum = Trk::FastField;
65 // Get propagator tool
66 ATH_CHECK (m_proptool.retrieve());
67 ATH_MSG_DEBUG("Retrieved tool " << m_proptool);
68 ATH_CHECK(m_roadDataKey.initialize());
70
71 return sc;
72}
73
75// Finalize
77
79{
80 StatusCode sc = AlgTool::finalize(); return sc;
81}
82
84// Dumps relevant information into the MsgStream
86
87MsgStream& InDet::TRT_DetElementsRoadMaker_xk::dump( MsgStream& out ) const
88{
89 return dumpConditions(out);
90}
91
93// Dumps conditions information into the MsgStream
95
97{
98 int n = 62-m_proptool.type().size();
99 std::string s1; for(int i=0; i<n; ++i) s1.append(" "); s1.append("|");
100
101 std::string fieldmode[9] ={"NoField" ,"ConstantField","SolenoidalField",
102 "ToroidalField" ,"Grid3DField" ,"RealisticField" ,
103 "UndefinedField","AthenaField" , "?????" };
104
107 const AtlasFieldCacheCondObj* fieldCondObj{*fieldHandle};
108 if (fieldCondObj) {
109 MagField::AtlasFieldCache fieldCache;
110 fieldCondObj->getInitializedCache (fieldCache);
111 if(!fieldCache.solenoidOn()) fieldModeEnum = Trk::NoField;
112 }
113 Trk::MagneticFieldProperties fieldprop(fieldModeEnum);
114 int mode = fieldprop.magneticFieldMode();
115 if(mode<0 || mode>8 ) mode = 8;
116
117 n = 62-fieldmode[mode].size();
118 std::string s3; for(int i=0; i<n; ++i) s3.append(" "); s3.append("|");
119
120 const TRT_DetElementsLayerVectors_xk &layer = *getLayers(Gaudi::Hive::currentContext());
121
122 int maps = 0;
123 if(!layer[0].empty()) ++maps;
124 if(!layer[1].empty()) ++maps;
125 if(!layer[2].empty()) ++maps;
126
127 out<<"|----------------------------------------------------------------------"
128 <<"-------------------|"
129 <<std::endl;
130 out<<"| Tool for propagation | "<<m_proptool.type()<<s1<<std::endl;
131 out<<"| Magnetic field mode | "<<fieldmode[mode]<<s3<<std::endl;
132 out<<"| Width of the road (mm) | "
133 <<std::setw(12)<<std::setprecision(5)<<m_width
134 <<" |"<<std::endl;
135 out<<"|----------------------------------------------------------------------"
136 <<"-------------------|"
137 <<std::endl;
138
139 if(!maps || !msgLvl(MSG::VERBOSE)) return out;
140
141 if(!layer[1].empty()) {
142 int nl = layer[1].size();
143 int nc = 0;
144 for(const auto & i : layer[1]) nc+=i.nElements();
145 out<<"|----------------------------------------------------------------|"
146 <<std::endl;
147 out<<"| Barrel map containt "
148 <<std::setw(4)<<nl<<" layers and "
149 <<std::setw(6)<<nc<<" elements |"
150 <<std::endl;
151 out<<"|------|-----------|------------|------------|------------|------|"
152 <<std::endl;
153 out<<"| n | R | Z min | Z max | max dF | nEl |"
154 <<std::endl;
155 out<<"|------|-----------|------------|------------|------------|------|"
156 <<std::endl;
157 for(unsigned int i=0; i!=layer[1].size(); ++i) {
158 float zmin = layer[1][i].z()-layer[1][i].dz();
159 float zmax = layer[1][i].z()+layer[1][i].dz();
160 out<<"| "
161 <<std::setw(4)<<i<<" |"
162 <<std::setw(10)<<std::setprecision(4)<< layer[1][i].r ()<<" | "
163 <<std::setw(10)<<std::setprecision(4)<< zmin<<" | "
164 <<std::setw(10)<<std::setprecision(4)<< zmax<<" | "
165 <<std::setw(10)<<std::setprecision(4)<< layer[1][i].dfe()<<" | "
166 <<std::setw(4)<<layer[1][i].nElements()<<" | "
167 <<std::endl;
168 }
169 out<<"|------|-----------|------------|------------|------------|------|"
170 <<std::endl;
171
172 }
173 if(!layer[0].empty()) {
174
175 int nl = layer[0].size();
176 int nc = 0;
177 for(const auto & i : layer[0]) nc+=i.nElements();
178 out<<"|----------------------------------------------------------------|"
179 <<std::endl;
180 out<<"| L.Endcap map containt "
181 <<std::setw(4)<<nl<<" layers and "
182 <<std::setw(6)<<nc<<" elements |"
183 <<std::endl;
184
185 out<<"|------|-----------|------------|------------|------------|------|"
186 <<std::endl;
187 out<<"| n | Z | R min | R max | max dF | nEl |"
188 <<std::endl;
189 out<<"|------|-----------|------------|------------|------------|------|"
190 <<std::endl;
191 for(unsigned int i=0; i!=layer[0].size(); ++i) {
192 float rmin = layer[0][i].r()-layer[0][i].dr();
193 float rmax = layer[0][i].r()+layer[0][i].dr();
194 out<<"| "
195 <<std::setw(4)<<i<<" |"
196 <<std::setw(10)<<std::setprecision(4)<< layer[0][i].z()<<" | "
197 <<std::setw(10)<<std::setprecision(4)<< rmin<<" | "
198 <<std::setw(10)<<std::setprecision(4)<< rmax<<" | "
199 <<std::setw(10)<<std::setprecision(4)<<layer[0][i].dfe()<<" | "
200 <<std::setw(4)<<layer[0][i].nElements()<<" | "
201 <<std::endl;
202 }
203 out<<"|------|-----------|------------|------------|------------|------|"
204 <<std::endl;
205 }
206 if(!layer[2].empty()) {
207 int nl = layer[2].size();
208 int nc = 0;
209 for(const auto & i : layer[2]) nc+=i.nElements();
210 out<<"|----------------------------------------------------------------|"
211 <<std::endl;
212 out<<"| R.Endcap map containt "
213 <<std::setw(4)<<nl<<" layers and "
214 <<std::setw(6)<<nc<<" elements |"
215 <<std::endl;
216 out<<"|------|-----------|------------|------------|------------|------|"
217 <<std::endl;
218 out<<"| n | Z | R min | R max | max dF | nEl |"
219 <<std::endl;
220 out<<"|------|-----------|------------|------------|------------|------|"
221 <<std::endl;
222 for(unsigned int i=0; i!=layer[2].size(); ++i) {
223 float rmin = layer[2][i].r()-layer[0][i].dr();
224 float rmax = layer[2][i].r()+layer[0][i].dr();
225 out<<"| "
226 <<std::setw(4)<<i<<" |"
227 <<std::setw(10)<<std::setprecision(4)<< layer[2][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[2][i].dfe()<<" | "
231 <<std::setw(4)<<layer[2][i].nElements()<<" | "
232 <<std::endl;
233 }
234 out<<"|------|-----------|------------|------------|------------|------|"
235 <<std::endl;
236 }
237 return out;
238}
239
241// Dumps event information into the MsgStream
243
244MsgStream& InDet::TRT_DetElementsRoadMaker_xk::dumpEvent( MsgStream& out, int size_road)
245{
246 out<<"|--------------------------------------------------------------------|"
247 <<std::endl;
248 out<<"| Road size | "<<std::setw(12)<<size_road
249 <<" |"<<std::endl;
250 out<<"|--------------------------------------------------------------------|"
251 <<std::endl;
252 return out;
253}
254
256// Dumps relevant information into the ostream
258
259std::ostream& InDet::TRT_DetElementsRoadMaker_xk::dump( std::ostream& out ) const
260{
261 return out;
262}
263
265// Main methods for road builder
267
268std::vector<const InDetDD::TRT_BaseElement*>
270(const EventContext& ctx,
271 MagField::AtlasFieldCache& fieldCache,
274{
275 double qp = std::abs(500.*Tp.parameters()[4]) ;
276 if( qp < 1.e-10 ) qp = 1.e-10;
277 double S = m_step/qp ;
278 if( S > 200. ) S = 200. ;
279 if(D<0) S=-S;
280 Trk::CylinderBounds CB = getBound(fieldCache, Tp, ctx);
281 double rminTRT = getTRTMinR(ctx);
282 std::vector<const InDetDD::TRT_BaseElement*> result;
283 if( CB.r() > rminTRT) {
285 if(!fieldCache.solenoidOn()) fieldModeEnum = Trk::NoField;
286 Trk::MagneticFieldProperties fieldprop(fieldModeEnum);
287 std::deque<Amg::Vector3D> G;
288 m_proptool->globalPositions(ctx, G,Tp,fieldprop,CB,S,Trk::pion);
289 if(G.size() > 1 ) {
291 }
292 }
293 return result;
294}
295
296
298// Main methods for road builder using input list global positions
299// for Atlas geometry
301
303(std::deque<Amg::Vector3D>& GP,
304 std::vector<const InDetDD::TRT_BaseElement*>& Road,
306 const EventContext& ctx) const
307{
308 int n0 = 0;
309 int n1 = 0;
310 int n2 = 0;
311 std::deque<Amg::Vector3D>::iterator g=GP.begin(),ge=GP.end();
312
313 const TRT_DetElementsLayerVectors_xk &layer = *getLayers(ctx);
314
315 float Po[6] = {float((*g).x()),float((*g).y()),float((*g).z()),
316 float(std::sqrt((*g).x()*(*g).x()+(*g).y()*(*g).y())),m_width,0.};
317
318 for(; n0!=(int)layer[0].size(); ++n0) {if(Po[2] > layer[0][n0].z()) break;}
319 for(; n1!=(int)layer[1].size(); ++n1) {if(Po[3] < layer[1][n1].r()) break;}
320 for(; n2!=(int)layer[2].size(); ++n2) {if(Po[2] < layer[2][n2].z()) break;}
321
322 std::vector<std::pair<const InDet::TRT_DetElementLink_xk*,float> > lDE;
323 for (unsigned int module_i = 0; module_i < 3; ++module_i) {
324 size_t layersSize = layer[module_i].size();
325 //Add more vectors if we need more
326 used[module_i].resize(layersSize);
327 for (unsigned int layer_i = 0; layer_i < layersSize; ++layer_i) {
328 // Although we clear/resize , we retain capacity
329 // clear what was there before
330 used[module_i][layer_i].clear();
331 //default init to false
332 used[module_i][layer_i].resize(layer[module_i][layer_i].nElements());
333 }
334 }
335
336 for(++g; g!=ge; ++g) {
337
338 float Pn[4] = {float((*g).x()),float((*g).y()),float((*g).z()),
339 float(std::sqrt((*g).x()*(*g).x()+(*g).y()*(*g).y()))};
340
341 float dx = Pn[0]-Po[0];
342 float dy = Pn[1]-Po[1];
343 float dz = Pn[2]-Po[2];
344 float st = std::sqrt(dx*dx+dy*dy+dz*dz);
345 if(st <=0.) continue;
346 float ds = 1./st;
347 float A[3]= {dx*ds,dy*ds,dz*ds};
348
349 // Barrel
350 //
351 if (Pn[3] > Po[3]) {
352 for (; n1 < (int)layer[1].size(); ++n1) {
353
354 if (Pn[3] < layer[1][n1].r())
355 break;
356 assert(used.at(1).size() > static_cast<unsigned int>(n1));
357 layer[1][n1].getBarrelDetElementsATL(Po, A, lDE, used[1][n1]);
358 }
359 } else {
360 for (--n1; n1 >= 0; --n1) {
361 if (Pn[3] > layer[1][n1].r())
362 break;
363 assert(used.at(1).size() > static_cast<unsigned int>(n1));
364 layer[1][n1].getBarrelDetElementsATL(Po, A, lDE, used[1][n1]);
365 }
366 ++n1;
367 }
368
369 // Positive endcap
370 //
371 if(Pn[2]>Po[2]) {
372
373 for (; n2 < (int)layer[2].size(); ++n2) {
374 if (Pn[2] < layer[2][n2].z())
375 break;
376 assert(used.at(2).size() > static_cast<unsigned int>(n2));
377 layer[2][n2].getEndcapDetElements(Po, A, lDE, used[2][n2]);
378 }
379 } else {
380 for (--n2; n2 >= 0; --n2) {
381 if (Pn[2] > layer[2][n2].z())
382 break;
383 assert(used.at(2).size() > static_cast<unsigned int>(n2));
384 layer[2][n2].getEndcapDetElements(Po, A, lDE, used[2][n2]);
385 }
386 ++n2;
387 }
388
389 // Negative endcap
390 //
391 if(Pn[2]<Po[2]) {
392
393 for (; n0 < (int)layer[0].size(); ++n0) {
394 if (Pn[2] > layer[0][n0].z())
395 break;
396 assert(used.at(0).size() > static_cast<unsigned int>(n0));
397 layer[0][n0].getEndcapDetElements(Po, A, lDE, used[0][n0]);
398 }
399 } else {
400 for (--n0; n0 >= 0; --n0) {
401 if (Pn[2] < layer[0][n0].z())
402 break;
403 assert(used.at(0).size() > static_cast<unsigned int>(n0));
404 layer[0][n0].getEndcapDetElements(Po, A, lDE, used[0][n0]);
405 }
406 ++n0;
407 }
408 Po[0] = Pn[0];
409 Po[1] = Pn[1];
410 Po[2] = Pn[2];
411 Po[3] = Pn[3];
412 Po[5]+= st;
413 }
414
415 // Sort list in propogation order
416 //
417 std::vector<std::pair<const InDet::TRT_DetElementLink_xk*,float> >::iterator l=lDE.begin(),le=lDE.end(),n,m;
418 if(l==le) return;
419
420 bool nc =true;
421 while(nc) {
422
423 nc =false; m=l; n=l;
424 for(++n; n!=le; ++n) {
425
426 if( (*m).second > (*n).second ) {
427 std::pair<const InDet::TRT_DetElementLink_xk*,float> d=(*m); (*m)=(*n); (*n)=d; nc=true;
428 }
429 ++m;
430 }
431 }
432
433 // Fill list pointers to detector elements
434 //
435 for(l=lDE.begin(); l!=le; ++l) {
436 Road.push_back((*l).first->detElement());
437 }
438}
439
441// Main methods for road builder using input list global positions
442// for CTB geometry
444
446(std::deque<Amg::Vector3D>& GP,
447 std::vector<const InDetDD::TRT_BaseElement*>& Road,
449 const EventContext& ctx) const
450{
451 int n1 = 0;
452 std::deque<Amg::Vector3D>::iterator g=GP.begin(),ge=GP.end();
453
454 const TRT_DetElementsLayerVectors_xk &layer = *getLayers(ctx);
455
456 float Po[6] = {float((*g).x()),float((*g).y()),float((*g).z()),
457 float(std::sqrt((*g).x()*(*g).x()+(*g).y()*(*g).y())),m_width,0.};
458
459 for(; n1!=(int)layer[1].size(); ++n1) {if(Po[3] < layer[1][n1].r()) break;}
460
461 std::vector<std::pair<const InDet::TRT_DetElementLink_xk*,float> > lDE;
462 for (unsigned int module_i = 0; module_i < 3; ++module_i) {
463 size_t layersSize = layer[module_i].size();
464 //Add more vectors if we need more
465 used[module_i].resize(layersSize);
466 for (unsigned int layer_i = 0; layer_i < layersSize; ++layer_i) {
467 // Although we clear/resize , we retain capacity
468 // clear what was there before
469 used[module_i][layer_i].clear();
470 //default init to false
471 used[module_i][layer_i].resize(layer[module_i][layer_i].nElements());
472 }
473 }
474
475 for(++g; g!=ge; ++g) {
476
477 float Pn[4] = {float((*g).x()),float((*g).y()),float((*g).z()),
478 float(std::sqrt((*g).x()*(*g).x()+(*g).y()*(*g).y()))};
479
480 float dx = Pn[0]-Po[0];
481 float dy = Pn[1]-Po[1];
482 float dz = Pn[2]-Po[2];
483 float st = std::sqrt(dx*dx+dy*dy+dz*dz);
484 float ds = 1./st;
485 float A[3]= {dx*ds,dy*ds,dz*ds};
486
487 // Barrel
488 //
489 if(Pn[3]>Po[3]) {
490 for(; n1<(int)layer[1].size(); ++n1) {
491 if(Pn[3] < layer[1][n1].r()) break;
492 assert( used.at(1).size() > static_cast<unsigned int>(n1) );
493 layer[1][n1].getBarrelDetElementsCTB(Po,A,lDE,used[1][n1]);
494 }
495 }
496 else {
497 for(--n1; n1>=0; --n1) {
498 if(Pn[3] > layer[1][n1].r()) break;
499 layer[1][n1].getBarrelDetElementsCTB(Po,A,lDE,used[1][n1]);
500 }
501 ++n1;
502 }
503 }
504
505 // Sort list in propogation order
506 //
507 std::vector<std::pair<const InDet::TRT_DetElementLink_xk*, float> >::iterator l=lDE.begin(),le=lDE.end(),n;
508 if(l==le) return;
509
510 bool nc =true;
511 while(nc) {
512
513 nc =false; n=l;
514 for(++n; n!=le; ++n) {
515
516 if( (*l).second > (*n).second ) {
517 std::pair<const InDet::TRT_DetElementLink_xk*,float> d = (*l); (*l) = (*n); (*n) = d;
518 nc = true;
519 }
520 ++l;
521 }
522 }
523
524 // Fill list pointers to detector elements
525 //
526 for(l=lDE.begin(); l!=le; ++l) {
527 Road.push_back((*l).first->detElement());
528 }
529}
530
532// Distance to detector element according stright line model
534
537{
538 Amg::Vector3D R = de->center();
539 Amg::Vector3D A = de->normal();
540 double D = a.x()*A.x()+a.y()*A.y()+a.z()*A.z(); if(D==0.) return D;
541 return ((A.x()*(R.x()-r.x())+A.y()*(R.y()-r.y())+A.z()*(R.z()-r.z()))/D);
542}
543
545// Cylinder bounds parameters estimation
547
549(MagField::AtlasFieldCache& fieldCache, const Trk::TrackParameters& Tp, const EventContext& ctx) const
550{
551 const double cor = 0.8;
552
553 double zfield = 0.;
554 if(m_fieldModeEnum!=Trk::NoField && fieldCache.solenoidOn()) {
555 const Amg::Vector3D& pos = Tp.position();
556 double f[3], p[3] ={pos[Amg::x],pos[Amg::y],pos[Amg::z]};
557 fieldCache.getFieldZR (p, f);
558 zfield = 299.7925*f[2];
559 }
560
561 const Trk::CylinderBounds bounds = get_bounds(ctx);
562
563 if( std::abs(zfield) < .0000001 ) return bounds;
564
565 const AmgVector(5)& Vp = Tp.parameters();
566
567 double cur = zfield*Vp[4]/std::sin(Vp[3]);
568
569 if( std::abs(cur)*bounds.r() < cor ) return bounds;
570
571 double rad = 1./cur;
572 if(cor*std::abs(rad) > bounds.r() ) return bounds;
573
574 const Amg::Vector3D& Gp = Tp.position() ;
575 double sn,cs; sincos(Vp[2],&sn,&cs);
576 double xc = Gp.x()+sn*rad ;
577 double yc = Gp.y()-cs*rad ;
578 double rm = (std::sqrt(xc*xc+yc*yc)+std::abs(rad))*cor;
579 if( rm > bounds.r() ) return bounds;
580 Trk::CylinderBounds CB(rm,bounds.halflengthZ());
581 return CB;
582}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x)
#define AmgVector(rows)
static Double_t a
static Double_t Tp(Double_t *t, Double_t *par)
static Double_t sc
#define G(x, y, z)
Definition MD5.cxx:113
#define z
static const Attributes_t empty
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
bool msgLvl(const MSG::Level lvl) const
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
Virtual base class of TRT readout elements.
virtual const Amg::Vector3D & normal() const override final
Element Surface: normal of a straw layer.
virtual const Amg::Vector3D & center() const override final
Element Surface: center of a straw layer.
static double stepToDetElement(const InDetDD::TRT_BaseElement *&, Amg::Vector3D &, Amg::Vector3D &)
double getTRTMinR(const EventContext &ctx) const
static MsgStream & dumpEvent(MsgStream &out, int size_road)
void detElementsRoadATL(std::deque< Amg::Vector3D > &, std::vector< const InDetDD::TRT_BaseElement * > &, InDet::TRT_DetElementLink_xk::TRT_DetElemUsedMap &used, const EventContext &ctx) const
MsgStream & dumpConditions(MsgStream &out) const
TRT_DetElementsRoadMaker_xk(const std::string &, const std::string &, const IInterface *)
virtual MsgStream & dump(MsgStream &out) const override
SG::ReadCondHandleKey< TRT_DetElementsRoadData_xk > m_roadDataKey
Trk::CylinderBounds getBound(MagField::AtlasFieldCache &fieldCache, const Trk::TrackParameters &, const EventContext &ctx) const
void detElementsRoadCTB(std::deque< Amg::Vector3D > &, std::vector< const InDetDD::TRT_BaseElement * > &, InDet::TRT_DetElementLink_xk::TRT_DetElemUsedMap &used, const EventContext &ctx) const
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCacheCondObjInputKey
PublicToolHandle< Trk::IPropagator > m_proptool
const TRT_DetElementsLayerVectors_xk * getLayers(const EventContext &ctx) const
virtual std::vector< const InDetDD::TRT_BaseElement * > detElementsRoad(const EventContext &ctx, MagField::AtlasFieldCache &fieldCache, const Trk::TrackParameters &Tp, Trk::PropDirection D, InDet::TRT_DetElementLink_xk::TRT_DetElemUsedMap &used) const override
const Trk::CylinderBounds get_bounds(const EventContext &ctx) const
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.
Bounds for a cylindrical Surface.
virtual double r() const override final
This method returns the radius.
double halflengthZ() const
This method returns the halflengthZ.
magnetic field properties to steer the behavior of the extrapolation
MagneticFieldMode magneticFieldMode() const
Returns the MagneticFieldMode as specified.
holding In fact this class is here in order to allow STL container for all features This class is sho...
int r
Definition globals.cxx:22
Eigen::Matrix< double, 3, 1 > Vector3D
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
hold the test vectors and ease the comparison