ATLAS Offline Software
TRT_LayerBuilderImpl.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
7 //Trk
12 #include "TrkGeometry/DiscLayer.h"
17 // GeoPrimitives
19 // InDetDD
24 #include "InDetIdentifier/TRT_ID.h"
25 
26 namespace {
27  template<class T>
28  class PtrVectorWrapper
29  {
30  public:
31  PtrVectorWrapper()
32  : m_ptr(new std::vector<T*>)
33  {}
34 
35  ~PtrVectorWrapper()
36  {
37  if (m_ptr) {
38  for (const T* elm : *m_ptr) {
39  delete elm;
40  }
41  m_ptr->clear();
42  }
43  }
44  std::vector<T*>& operator*() { return *m_ptr; }
45  const std::vector<const T*>& operator*() const { return *m_ptr; }
46 
47  std::vector<T*>* operator->() { return m_ptr.get(); }
48  const std::vector<const T*>* operator->() const { return m_ptr.get(); }
49 
50  std::vector<T*>* release() { return m_ptr.release(); }
51 
52  private:
53  std::unique_ptr<std::vector<T*>> m_ptr;
54  };
55 
56 }
57 
58 // constructor
59 InDet::TRT_LayerBuilderImpl::TRT_LayerBuilderImpl(const std::string& t, const std::string& n, const IInterface* p) :
60  AthAlgTool(t,n,p)
61 {
62 }
63 
64 
65 std::unique_ptr<const std::vector<Trk::CylinderLayer*> >
67  ATH_MSG_DEBUG( "Building cylindrical layers for the TRT " );
68  PtrVectorWrapper<Trk::CylinderLayer> barrelLayers;
69 
70  // get Numerology and Id HElper
71  const InDetDD::TRT_Numerology* trtNums = trtContainer->getTRTNumerology();
72 
73  // get the TRT ID Helper
74  const TRT_ID* trtIdHelper = nullptr;
75  if (detStore()->retrieve(trtIdHelper, "TRT_ID").isFailure()) {
76  ATH_MSG_ERROR("Could not get TRT ID helper");
77  return nullptr;
78  }
79 
80  int nBarrelRings = trtNums->getNBarrelRings();
81  int nBarrelPhiSectors = trtNums->getNBarrelPhi();
82  double layerPhiStep = 2*M_PI/nBarrelPhiSectors;
83 
84  int nTotalBarrelLayers = 0;
85 
86  // get the overall dimensions
87  double rMin = 10e10;
88  double rMax = 0.;
89 
90  double layerZmax = 0.;
91  double layerZmin = 10e10;
92 
93  // pre-loop for overall layer numbers & some ordering ---------------------------------------
94  for (int ring=0; ring < nBarrelRings; ring++) {
95  // the number of barrel layers
96  int nBarrelLayers = trtNums->getNBarrelLayers(ring);
97  nTotalBarrelLayers += nBarrelLayers;
98  // loop over layers
99  for (int layer=0; layer < nBarrelLayers; layer++){
100  for (int phisec=0; phisec <nBarrelPhiSectors; ++phisec)
101  {
102  for (int iposneg=0; iposneg<2; ++iposneg){
103  // get the element
104  const InDetDD::TRT_BarrelElement* trtbar = trtContainer->getBarrelDetElement(iposneg, ring, phisec, layer); // TODO share this line
105 
106  // get overall dimensions only one time
107  const Trk::PlaneSurface* elementSurface = dynamic_cast<const Trk::PlaneSurface*>(&(trtbar->surface()));
108  if (!elementSurface) {
109  ATH_MSG_WARNING( "elementSurface: dynamic_cast to Trk::PlaneSurface failed - skipping ... ring/layer/phisec/iposneg = " << ring << "/" << layer << "/" << phisec << "/" << iposneg );
110  continue;
111  }
112  const Trk::RectangleBounds* elementBounds = dynamic_cast<const Trk::RectangleBounds*>(&(trtbar->bounds()));
113  if (!elementBounds) {
114  ATH_MSG_WARNING( "elementBounds: dynamic_cast to Trk::RectangleBounds failed - skipping ... ring/layer/phisec/iposneg = " << ring << "/" << layer << "/" << phisec << "/" << iposneg );
115  continue;
116  }
117  double elementZcenter = (elementSurface->center()).z();
118  double elementZmin = std::abs(elementZcenter - elementBounds->halflengthY());
119  double elementZmax = std::abs(elementZcenter + elementBounds->halflengthY());
120  // take what you need
121  takeSmaller(layerZmin, elementZmin); takeBigger(layerZmax, elementZmax);
122  // get the radial dimensions
123  double currentR = trtbar->center().perp();
124  takeSmallerBigger(rMin,rMax,currentR);
125  }
126  }
127  }
128  }
129 
130  if (nTotalBarrelLayers==0) {
131  ATH_MSG_WARNING( "nTotalBarrelLayers = 0 ... aborting and returning 0 !" );
132  return nullptr;
133  }
134 
135  // calculate delta(R) steps and delta(R)
136  double rDiff = std::abs(rMax-rMin);
137  double rStep = rDiff/(m_modelBarrelLayers+1);
138  double layerHalflength = layerZmax;
139 
140  // prepare the material
141  if ( std::abs(rDiff) <= 0.1 ) {
142  return nullptr;
143  }
144 
145  // fix the positions where the layers are - these are used for the model geometry and the complex geometry ---------------
146  std::vector<double> layerRadii;
147  layerRadii.reserve(m_modelBarrelLayers);
148  for (unsigned int ilay = 1; ilay <= m_modelBarrelLayers; ++ilay)
149  layerRadii.push_back(rMin+ilay*rStep-0.5*m_layerThickness);
150  // these are the layer iterators
151  auto layerRadiusIter = layerRadii.begin();
152  auto layerRadiusIterEnd = layerRadii.end();
153 
154  // (A) model geometry section
156 
157  ATH_MSG_VERBOSE( " -> " << layerRadii.size() << " cylindrical barrel layers between " << rMin << " and " << rMax << " ( at step "<< rStep << " )");
158 
159  // create the layers
160  for ( ; layerRadiusIter != layerRadiusIterEnd; ++layerRadiusIter ) {
161  // ----- prepare the BinnedLayerMaterial -----------------------------------------------------
162  Trk::BinnedLayerMaterial* layerMaterial = nullptr;
163  // -- material with 1D binning
164  Trk::BinUtility layerBinUtility1DZ(m_barrelLayerBinsZ,-layerHalflength, layerHalflength, Trk::open, Trk::binZ);
165  if (m_barrelLayerBinsPhi==1u){
166  // no binning in phi
167  layerMaterial =new Trk::BinnedLayerMaterial(layerBinUtility1DZ);
168  } else { // -- material with 2D binning : Rphi*Z optimized for cylinder layer
169  Trk::BinUtility layerBinUtility2DRPhiZ(m_barrelLayerBinsPhi,
170  -(*layerRadiusIter)*M_PI,
171  (*layerRadiusIter)*M_PI,
172  Trk::closed,
173  Trk::binRPhi);
174  layerBinUtility2DRPhiZ += layerBinUtility1DZ;
175  layerMaterial =new Trk::BinnedLayerMaterial(layerBinUtility2DRPhiZ);
176  }
177  // Barrel layers are centered around (0,0,0) by definition
178  barrelLayers->push_back(
179  new Trk::CylinderLayer(std::make_shared<Trk::CylinderBounds>(
180  *layerRadiusIter, layerHalflength),
181  *layerMaterial, m_layerThickness));
182  ATH_MSG_VERBOSE(" --> Creating a layer at radius : " << *layerRadiusIter);
183  delete layerMaterial;
184  }
185  } else {
186 
187  // (B) complex geometry section
188  float nMaterialLayerStep = 1.*nTotalBarrelLayers/m_modelBarrelLayers;
189  // complex geo should build same # of mat. layers as model geo; counter to check this:
190  unsigned int cMaterialLayerCount = 0;
191  // inclusive layer counter over all rings, used to determine mat. layer position
192  unsigned int cLayer=0;
193 
194  // loop over rings
195  ATH_MSG_VERBOSE("TRT Barrel has " << nBarrelRings << " rings.");
196 
197  for (int ring=0; ring < nBarrelRings; ring++){
198 
199  int nBarrelLayers = trtNums->getNBarrelLayers(ring);
200  ATH_MSG_VERBOSE("-> Ring " << ring << " has " << nBarrelLayers << " barrel layers.");
201  // loop over layers
202  for (int layer=0; layer < nBarrelLayers; layer++){
203 
204  // ----------------------------------------------------------------------------------
205  ATH_MSG_VERBOSE("--> Layer " << layer << " is being built with " << nBarrelPhiSectors << " secors in phi.");
206 
207  // increase inclusive layer counter for next material layer
208  ++cLayer;
209 
210  // set layer dimensions radius
211  double layerRadius = 0.;
212  double layerRadiusMin = 10e10;
213  double layerRadiusMax = 0.;
214  double layerPhiMin = 10.;
215  double layerPhiMax = -10;
216 
217  // per phi sector we make a 2D binnin in phi-z
218  std::vector< std::pair<Trk::BinnedArray2D<Trk::Surface>, Amg::Vector3D > > layerSectorArrays;
219  Amg::Vector3D layerSectorPosition(0.,0.,0.);
220 
221  // the sector approaching surfaces
222  std::vector< std::pair< std::shared_ptr<const Trk::ApproachSurfaces>, Amg::Vector3D > > layerApproachSurfaces;
223 
224  // layer sector arrays
225  for (int phisec=0; phisec < nBarrelPhiSectors; phisec++){
226  // ----------------------------------------------------------------------------------
227  ATH_MSG_VERBOSE("---> Sector " << phisec << " gahtering the details.");
228  // -------------- a phi sector (expands in +/- z) -----------------------------------
229 
230  // order the straws onto layers
231  std::vector< Trk::SurfaceOrderPosition > strawsPerPhiSecLayer;
232  // get the min an max phi, the min and max z
233  double phiMin = 10.;
234  double phiMax = -10.;
235  // sector stuff
236  int sectorStraws = 0;
237  // positive and negative sector
238  for (int posneg=0; posneg<2; ++posneg){
239  // sort the elements
240  const InDetDD::TRT_BarrelElement* currentElement = trtContainer->getBarrelDetElement(posneg, ring, phisec, layer); // TODO share this line
241  // get overall dimensions only one time
242  const Trk::PlaneSurface* elementSurface = dynamic_cast<const Trk::PlaneSurface*>(&(currentElement->surface()));
243  if (!elementSurface) {
244  ATH_MSG_WARNING( "elementSurface: dynamic_cast to Trk::PlaneSurface failed - skipping ... ring/layer/phisec/posneg = " << ring << "/" << layer << "/" << phisec << "/" << posneg );
245  continue;
246  }
247 
248  // create teh approach surfaces --------------------------------------------------------------------------------------------------
249  // getTransformFromRotTransl(Amg::RotationMatrix3D rot, Amg::Vector3D transl_vec )
251  const Amg::Transform3D& elementTransform = elementSurface->transform();
252  const Amg::Vector3D& elementCenter = elementSurface->center();
253  const Amg::Vector3D& elementNormal = elementSurface->normal();
254  Amg::RotationMatrix3D elementRotation = elementTransform.rotation();
255  // outer / inner
256  Amg::Vector3D outerCenter(elementCenter+(0.5*m_layerThickness+m_layerStrawRadius)*elementNormal);
257  Amg::Vector3D innerCenter(elementCenter-(0.5*m_layerThickness+m_layerStrawRadius)*elementNormal);
258 
259  // assign the layer sector position for the straw array ordering
260  layerSectorPosition = elementSurface->center();
261 
262  // now register the two surfaces
263  aSurfaces->push_back(new Trk::PlaneSurface(Amg::Transform3D(Amg::getTransformFromRotTransl(elementRotation, innerCenter))));
264  aSurfaces->push_back(new Trk::PlaneSurface(Amg::Transform3D(Amg::getTransformFromRotTransl(elementRotation, outerCenter))));
265 
266  // now register it to for building the array
267  layerApproachSurfaces.emplace_back( std::shared_ptr<const Trk::ApproachSurfaces>(aSurfaces),elementCenter);
268  // screen output
269  ATH_MSG_VERBOSE("---> Sector " << phisec << " - posneg - " << posneg << " - with central phi = " << elementSurface->center().phi() );
270  // sector phi centers
271  takeSmallerBigger(layerPhiMin,layerPhiMax,elementSurface->center().phi());
272 
273  // loop over straws, fill them and find the phi boundaries
274  for (unsigned int istraw=0; istraw<currentElement->nStraws(); ++istraw)
275  {
276  Identifier strawId = trtIdHelper->straw_id(currentElement->identify(), istraw);
277  const Trk::Surface* currentStraw = &(currentElement->surface(strawId));
278  // get the phi values
279  double currentPhi = currentStraw->center().phi();
280  if (phisec == m_barrelSectorAtPiBoundary && currentPhi < 0.){
281  currentPhi = M_PI + currentPhi;
282  currentPhi += M_PI;
283  }
284  // the layer radius
285  takeSmallerBigger(layerRadiusMin,layerRadiusMax,currentStraw->center().perp());
286  takeSmallerBigger(phiMin, phiMax, currentPhi);
287  // make the ordering position
288  Amg::Vector3D strawOrderPos(currentStraw->center());
289  /*
290  * The above line was using the nodel (not delete option for the old shared object
291  * now that SharedObject is a shared_ptr typedef do the same with empty deleter
292  */
293  // Something like
294  // std::shared_ptr<Trk::Surface> =
295  // std::make_shared<Trk::Surface>(.....)) could be fine
296  //
297  // As things are now
298  // 1) Notice that basically we couple the DetElement owned
299  // surface to the Tracking Geometry passing a no-op deleter
300  // (no delete happens) to the shared_ptr(SharedObject is
301  // typedef of shared_ptr)
302  // 2) The const_cast here make the
303  // code non MT safe. For now we handle this by being careful
304  // on lifetimes and non-re-entrant TG construction.
305  std::shared_ptr<Trk::Surface> sharedSurface(const_cast<Trk::Surface*>(currentStraw),
306  Trk::do_not_delete<Trk::Surface>);
307  strawsPerPhiSecLayer.emplace_back(sharedSurface, strawOrderPos);
308  // and record
309  ++sectorStraws;
310  } // loop over straws done
311  } // loop over posneg done
312  // show the phiMin/phiMax to the screen
313  // prepare the
314  // fix to CID 24918
315  if (!sectorStraws) {
316  return nullptr;
317  }
318  double deltaPhi = (phiMax-phiMin);
319  double phiStep = deltaPhi/(0.5*sectorStraws-1);
320  ATH_MSG_VERBOSE("---> Sector " << phisec << " - with " << 0.5*sectorStraws << " straws - straw phiMin/phiMax (step) = " << phiMin << " / " << phiMax << " (" << phiStep << ")");
321  // phi min / phi max
322  phiMin -= 0.5*phiStep;
323  phiMax += 0.5*phiStep;
324  // correct for the +pi/-pi module
325  // now create the BinUtility
326  auto layerStrawPhiZUtility = Trk::BinUtility(sectorStraws/2,phiMin,phiMax,Trk::open, Trk::binPhi);
327  layerStrawPhiZUtility += Trk::BinUtility(2,-layerZmax, layerZmax, Trk::open, Trk::binZ);
328  // create the 2D BinnedArray
329  Trk::BinnedArray2D<Trk::Surface> layerStrawPhiSector(strawsPerPhiSecLayer,layerStrawPhiZUtility);
330  ATH_MSG_VERBOSE("---> Sector " << phisec << " - BinnedArray for straws prepared for " << strawsPerPhiSecLayer.size() << " straws.");
331  // fill the array
332  layerSectorArrays.emplace_back(std::move(layerStrawPhiSector), layerSectorPosition);
333  // ---------------- enf of phi sector ----------------------------------------------------
334  } // loop over PhiSectors done
335 
336  // build the mean of the layer Radius
337  layerRadius = 0.5*(layerRadiusMin+layerRadiusMax)+0.5*m_layerStrawRadius;
338 
339  bool assignMaterial = false;
340  if (cLayer==(unsigned)int((cMaterialLayerCount+1)*nMaterialLayerStep)) {
341  assignMaterial = true;
342  ++cMaterialLayerCount;
343  ATH_MSG_VERBOSE( "--> Creating a material+straw layer at radius : " << layerRadius );
344  } else
345  ATH_MSG_VERBOSE( "--> Creating a straw layer at radius : " << layerRadius );
346 
347  // now order the plane layers to sit on cylindrical layers
348  auto barrelLayerBounds = std::make_shared<Trk::CylinderBounds>(layerRadius, layerHalflength);
349 
350  // ---- correct phi -------------------------------------------------------------------
351  ATH_MSG_VERBOSE(" prepare approach description with " << nBarrelPhiSectors << " barrel sectors.");
352  ATH_MSG_VERBOSE(" min phi / max phi detected : " << layerPhiMin << " / " << layerPhiMax );
353  double layerPhiMinCorrected = layerPhiMin-0.5*layerPhiStep;
354  double layerPhiMaxCorrected = layerPhiMax+0.5*layerPhiStep;
355  // catch if the minPhi falls below M_PI
356  if (layerPhiMinCorrected < -M_PI){
357  layerPhiMinCorrected += layerPhiStep;
358  layerPhiMaxCorrected += layerPhiStep;
359  }
360  ATH_MSG_VERBOSE(" min phi / max phi corrected : " << layerPhiMinCorrected << " / " << layerPhiMaxCorrected );
361 
362  // the sector surfaces
363  auto layerSectorBinUtility = Trk::BinUtility(nBarrelPhiSectors,layerPhiMinCorrected,layerPhiMaxCorrected,Trk::closed,Trk::binPhi);
364  auto strawArray = std::make_unique<Trk::BinnedArrayArray2D<Trk::Surface>>(std::move(layerSectorArrays), layerSectorBinUtility );
365 
366  ATH_MSG_VERBOSE("--> Layer " << layer << " has been built with " << strawArray->arrayObjects().size() << " straws.");
367 
368  // ApproachDescriptor
369  // build a BinUtility for the ApproachDescritptor
370  auto aDescriptorBinUtility = Trk::BinUtility(nBarrelPhiSectors,layerPhiMinCorrected,layerPhiMaxCorrected,Trk::closed,Trk::binPhi);
371  aDescriptorBinUtility += Trk::BinUtility(2,-layerHalflength,layerHalflength,Trk::open, Trk::binZ);
372 
373  auto aDescriptorBinnedArray = std::make_unique<Trk::BinnedArray2D<const Trk::ApproachSurfaces>> (layerApproachSurfaces, aDescriptorBinUtility);
374 
375  // build an approach surface
376  auto approachSurface = std::make_unique<Trk::CylinderSurface>(
377  std::make_shared<Trk::CylinderBounds>(*barrelLayerBounds));
379  std::move(aDescriptorBinnedArray), std::move(approachSurface));
380 
381  // do not give every layer material properties
382  if (assignMaterial) {
383  // ----- prepare the BinnedLayerMaterial -----------------------------------------------------
384  Trk::BinnedLayerMaterial* layerMaterial = nullptr;
385  // -- material with 1D binning
386  Trk::BinUtility layerBinUtilityZ(m_barrelLayerBinsZ, -layerHalflength, layerHalflength, Trk::open, Trk::binZ );
387  if (m_barrelLayerBinsPhi==1u){
388  layerMaterial =new Trk::BinnedLayerMaterial(layerBinUtilityZ);
389  } else { // -- material with 2D binning: RPhiZ binning
390  Trk::BinUtility layerBinUtilityRPhiZ(m_barrelLayerBinsPhi,
391  -layerRadius*M_PI, layerRadius*M_PI,
392  Trk::closed,
393  Trk::binRPhi);
394  layerBinUtilityRPhiZ += layerBinUtilityZ;
395  layerMaterial =new Trk::BinnedLayerMaterial(layerBinUtilityRPhiZ);
396  }
397 
398  barrelLayers->push_back(new Trk::CylinderLayer(barrelLayerBounds,
399  std::move(strawArray),
400  *layerMaterial,
402  std::make_unique<InDet::TRT_OverlapDescriptor>(trtIdHelper),
403  aDescritpor));
404  delete layerMaterial;
405 
406  } else
407  barrelLayers->push_back(new Trk::CylinderLayer(barrelLayerBounds,
408  std::move(strawArray),
410  std::make_unique<InDet::TRT_OverlapDescriptor>(trtIdHelper),
411  aDescritpor));
412  } // loop over layers
413  } // loop over rings
414 
415  ATH_MSG_VERBOSE(" Built number of TRT barrel material layers: " << cMaterialLayerCount);
416  // In Complex geo # of material layers should match the expected # of layers,
417  // else a mis-match in layer and material map index occurs.
418  // This mis-match will results layers getting incorrect material properties.
419  if (cMaterialLayerCount!=m_modelBarrelLayers) {
420  ATH_MSG_WARNING(" Complex geo built incorrect # of TRT barrel material layers: "
421  << cMaterialLayerCount << " / " << m_modelBarrelLayers);
422  }
423  }// complex geometry
424 
425  // return what you have
426  return std::unique_ptr<const std::vector<Trk::CylinderLayer*> > (barrelLayers.release());
427 }
428 
429 
430 std::unique_ptr<const std::vector<Trk::DiscLayer*> >
432 {
433  ATH_MSG_DEBUG( "Building disc-like layers for the TRT " );
434 
435  const InDetDD::TRT_Numerology* trtNums = trtContainer->getTRTNumerology();
436  // get the TRT ID Helper
437  const TRT_ID* trtIdHelper = nullptr;
438  if (detStore()->retrieve(trtIdHelper, "TRT_ID").isFailure()) {
439  ATH_MSG_ERROR("Could not get TRT ID helper");
440  return nullptr;
441  }
442  unsigned int nEndcapWheels = trtNums->getNEndcapWheels();
443  unsigned int nEndcapPhiSectors = trtNums->getNEndcapPhi();
444 
445  // total layer numbers
446  int numTotalLayers = 0;
447 
448  // zMin / zMax
449  double zMin = 10e10;
450  double zMax = 0.;
451 
452  const Trk::DiscBounds* sectorDiscBounds = nullptr;
453 
454  // preloop for overall numbers
455  for (unsigned int iwheel=0; iwheel<nEndcapWheels; ++iwheel)
456  {
457  unsigned int nEndcapLayers = trtNums->getNEndcapLayers(iwheel);
458  numTotalLayers += nEndcapLayers;
459  for (unsigned int ilayer = 0; ilayer<nEndcapLayers; ++ilayer){
460  const InDetDD::TRT_EndcapElement* sectorDiscElement = trtContainer->getEndcapDetElement(0, iwheel, ilayer, 0); // TODO share this line
461 
462  // get a reference element for dimensions
463  if (!sectorDiscBounds){
464  sectorDiscBounds = dynamic_cast<const Trk::DiscBounds*>(&(sectorDiscElement->bounds()));
465  }
466 
467  double currentZ = std::abs(sectorDiscElement->center().z());
468  takeSmallerBigger(zMin,zMax,currentZ);
469  }
470  }
471  if (numTotalLayers==0) {
472  ATH_MSG_WARNING( "numTotalLayers = 0 ... aborting and returning 0 !" );
473  return nullptr;
474  }
475 
476  if (!sectorDiscBounds) {
477  ATH_MSG_WARNING( "fullDiscBounds do not exist ... aborting and returning 0 !" );
478  return nullptr;
479  }
480  auto fullDiscBounds = std::make_unique<Trk::DiscBounds>(sectorDiscBounds->rMin(), sectorDiscBounds->rMax());
481 
482  PtrVectorWrapper<Trk::DiscLayer> endcapLayers;
483 
484  // the BinUtility for the material
485  std::unique_ptr<Trk::BinnedLayerMaterial> layerMaterial;
486  // -- material with 1D binning
487  Trk::BinUtility layerBinUtilityR(m_endcapLayerBinsR,
488  fullDiscBounds->rMin(),
489  fullDiscBounds->rMax(),
490  Trk::open,
491  Trk::binR);
492  if (m_barrelLayerBinsPhi==1u)
493  layerMaterial = std::make_unique<Trk::BinnedLayerMaterial>(layerBinUtilityR);
494  else { // -- material with 2D binning
495  Trk::BinUtility layerBinUtilityPhi(m_barrelLayerBinsPhi,
496  -M_PI, M_PI,
497  Trk::closed,
498  Trk::binPhi);
499  // make it rPhi now
500  layerBinUtilityR += layerBinUtilityPhi;
501  layerMaterial = std::make_unique<Trk::BinnedLayerMaterial>(layerBinUtilityR);
502  }
503 
504  // global geometry statistics
505  double zDiff = std::abs(zMax-zMin);
506  double zStep = zDiff/(m_modelEndcapLayers+1);
507 
508  // loop for surface ordering
509  int maxendcaps=2;
510  if (m_endcapConly) maxendcaps=1;
511 
512  for (int iposneg=0; iposneg<maxendcaps; ++iposneg){
513 
514  // fill the positions of the disc layers
515  std::vector<double> zPositions;
516  zPositions.reserve(m_modelEndcapLayers);
517 
518  double stepdir = iposneg ? 1. : -1.;
519  double zStart = stepdir*zMin;
520 
521  ATH_MSG_VERBOSE( " -> Creating " << m_modelEndcapLayers << " disc-layers on each side between "
522  << zMin << " and " << zMax << " ( at step "<< zStep << " )");
523 
524  // take a different modelling for the layers - use these layers for the model geometry and the real geometry
525  for (unsigned int izpos = 1; izpos <= m_modelEndcapLayers; ++izpos){
526  zPositions.push_back(zStart + stepdir * double(izpos) * zStep - 0.5 * m_layerThickness);
527  }
528 
529  std::vector<double>::const_iterator zPosIter = zPositions.begin();
530  std::vector<double>::const_iterator zPosIterEnd = zPositions.end();
531 
532  // (a) simplified geometry
533  if (m_modelGeometry){
534  // build the layers actually
535  for ( ; zPosIter != zPosIterEnd; ++zPosIter){
536  ATH_MSG_VERBOSE( " --> Creating a layer at z pos : " << (*zPosIter) );
537  Amg::Transform3D zPosTrans =
538  Amg::Transform3D(Amg::Translation3D(0., 0., (*zPosIter)));
539  endcapLayers->push_back(new Trk::DiscLayer(zPosTrans,
540  std::make_shared<Trk::DiscBounds>(*fullDiscBounds),
541  *layerMaterial,
543  }
544 
545  } else {
546  // (b) complex geometry
547  float nMaterialLayerStep = 1.*numTotalLayers/m_modelEndcapLayers;
548  // inclusive layer counter over all wheels
549  unsigned int cLayer = 0;
550  // complex geo should build same # of mat. layers as model geo; counter to check this:
551  unsigned int cMaterialLayerCount = 0;
552 
553  // complex geometry - needs a little bit of joggling
554  for (unsigned int iwheel=0; iwheel<nEndcapWheels; ++iwheel)
555  {
556  // do the loop per side
557  unsigned int nEndcapLayers = trtNums->getNEndcapLayers(iwheel);
558  for (unsigned int ilayer = 0; ilayer < nEndcapLayers; ++ilayer){
559 
560  // increase inclusive layer counter for next material layer
561  ++cLayer;
562 
563  // count the straws;
564  int numberOfStraws = 0;
565 
566  // check if dynamic cast worked
567  if (fullDiscBounds){
568  // get a reference element for dimensions
569  const InDetDD::TRT_EndcapElement* sectorDiscElement = trtContainer->getEndcapDetElement(iposneg, iwheel, ilayer, 0); // TODO share this line
570 
571  // take the position, but not the rotation (the rotation has to be standard)
572  Amg::Vector3D fullDiscPosition(sectorDiscElement->surface().transform().translation());
573  double discZ = fullDiscPosition.z();
574 
575  // check if we need to build a straw layer or not
576  bool assignMaterial = false;
577  if (cLayer == (unsigned)int((cMaterialLayerCount+1)*nMaterialLayerStep)) {
578  assignMaterial = true;
579  ++cMaterialLayerCount;
580  ATH_MSG_VERBOSE( "--> Creating a material+straw layer at z-pos : " << discZ );
581  } else {
582  ATH_MSG_VERBOSE( "--> Creating a straw layer at z-pos : " << discZ );
583  }
584 
585  // order the straws onto layers
586  std::vector< Trk::SurfaceOrderPosition > strawPerEndcapLayer;
587 
588  // the layer thickness - for approaching surfaces
589  double zMin = 10e10;
590  double zMax = -10e10;
591 
592  for (unsigned int iphisec=0; iphisec<nEndcapPhiSectors; ++iphisec){
593  ATH_MSG_VERBOSE("Building sector " << iphisec << " of endcap wheel " << iwheel );
594  const InDetDD::TRT_EndcapElement* currentElement = trtContainer->getEndcapDetElement(iposneg, iwheel, ilayer, iphisec); // TODO share this line
595  unsigned int nstraws = currentElement->nStraws();
596  for (unsigned int istraw=0; istraw<nstraws; istraw++){
597  Identifier strawId = trtIdHelper->straw_id(currentElement->identify(), istraw);
598  const Trk::Surface* currentStraw = &(currentElement->surface(strawId));
599  Amg::Vector3D strawOrderPos(currentStraw->center());
600  // get the z position
601  double zPos = currentStraw->center().z();
602  takeSmaller(zMin,zPos);
603  takeBigger(zMax,zPos);
604  // Something like
605  // std::shared_ptr<Trk::Surface> =
606  // std::make_shared<Trk::Surface>(currentElement)) could be fine
607  //
608  // As things are now
609  // 1) Notice that basically we couple the DetElement owned
610  // surface to the Tracking Geometry passing a no-op deleter
611  // (no delete happens) to the shared_ptr(SharedObject is
612  // typedef of shared_ptr)
613  // 2) The const_cast here make the
614  // code non MT safe. For now we handle this by being careful
615  // on lifetimes and non-re-entrant TG construction.
616  std::shared_ptr<Trk::Surface> sharedSurface(const_cast<Trk::Surface*>(currentStraw),
617  [](Trk::Surface*) {});
618  strawPerEndcapLayer.emplace_back(sharedSurface, strawOrderPos);
619  ++numberOfStraws;
620  }
621  }
622  // fix to CID 11326
623  if (!numberOfStraws){
624  return nullptr;
625  }
626  auto currentBinUtility = Trk::BinUtility(numberOfStraws, -M_PI, M_PI, Trk::closed, Trk::binPhi);
627  auto strawArray = std::make_unique<Trk::BinnedArray1D<Trk::Surface>>(strawPerEndcapLayer, currentBinUtility);
628  Trk::DiscLayer* currentLayer = nullptr;
629 
630  // redefine the discZ
631  discZ = 0.5*(zMin+zMax);
632  Amg::Transform3D fullDiscTransform = Amg::Transform3D(Amg::Translation3D(0.,0.,discZ));
633 
634  ATH_MSG_VERBOSE("TRT Disc being build at z Position " << discZ << " ( from " << zMin << " / " << zMax << " )");
635 
636  // create the approach offset
637  auto aSurfaces = std::make_unique<Trk::ApproachSurfaces>();
638  // get the position of the approach surfaces
639  const Amg::Vector3D aspPosition(0.,0.,zMin-m_layerStrawRadius);
640  const Amg::Vector3D asnPosition(0.,0.,zMax+m_layerStrawRadius);
641 
642  // create new surfaces
643  Amg::Transform3D asnTransform = Amg::Transform3D(Amg::Translation3D(asnPosition));
644  Amg::Transform3D aspTransform = Amg::Transform3D(Amg::Translation3D(aspPosition));
645  // order in an optimised way for collision direction
646  if (discZ > 0.){
647  aSurfaces->push_back( new Trk::DiscSurface(asnTransform, std::make_shared<Trk::DiscBounds>(*fullDiscBounds)));
648  aSurfaces->push_back( new Trk::DiscSurface(aspTransform, std::make_shared<Trk::DiscBounds>(*fullDiscBounds)) );
649  } else {
650  aSurfaces->push_back( new Trk::DiscSurface(aspTransform, std::make_shared<Trk::DiscBounds>(*fullDiscBounds)) );
651  aSurfaces->push_back( new Trk::DiscSurface(asnTransform, std::make_shared<Trk::DiscBounds>(*fullDiscBounds)) );
652  }
653  // approach descriptor
654  Trk::ApproachDescriptor* aDescriptor = new Trk::ApproachDescriptor(std::move(aSurfaces),false);
655 
656  // do not give every layer material properties
657  if (assignMaterial)
658  currentLayer = new Trk::DiscLayer(fullDiscTransform,
659  std::make_shared<Trk::DiscBounds>(*fullDiscBounds),
660  std::move(strawArray),
661  *layerMaterial,
663  std::make_unique<InDet::TRT_OverlapDescriptor>(trtIdHelper),
664  aDescriptor);
665  else if (!m_modelGeometry)
666  currentLayer = new Trk::DiscLayer(fullDiscTransform,
667  std::make_shared<Trk::DiscBounds>(*fullDiscBounds),
668  std::move(strawArray),
670  std::make_unique<InDet::TRT_OverlapDescriptor>(trtIdHelper),
671  aDescriptor);
672 
673  if (currentLayer) endcapLayers->push_back(currentLayer);
674  } // end of sectorDiscBounds if
675  } // end of layer loop
676  } // end of wheel loop
677 
678  ATH_MSG_VERBOSE(" Built # of TRT material layers: " << cMaterialLayerCount << "in ispos: " << iposneg << "ring");
679  // # of material layers should match the expected # of layers,
680  // else a mis-match in layer and material map index occurs.
681  // This mis-match will results layers getting incorrect material properties.
682  if (cMaterialLayerCount != m_modelEndcapLayers) {
683  ATH_MSG_WARNING(" Built incorrect # of TRT material layers: "
684  << cMaterialLayerCount << " / " << m_modelEndcapLayers << "in ispos" << iposneg << "ring" );
685  }
686 
687  } // model/real geometry
688  } // end of posneg loop
689 
690  return std::unique_ptr<const std::vector<Trk::DiscLayer*> > (endcapLayers.release());
691 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
Trk::RectangleBounds
Definition: RectangleBounds.h:38
InDet::TRT_LayerBuilderImpl::m_layerStrawRadius
double m_layerStrawRadius
straw radius
Definition: TRT_LayerBuilderImpl.h:71
InDet::TRT_LayerBuilderImpl::m_endcapLayerBinsR
UnsignedIntegerProperty m_endcapLayerBinsR
Bins for the Endcap material - in r.
Definition: TRT_LayerBuilderImpl.h:79
InDetDD::TRT_BarrelElement
Definition: TRT_BarrelElement.h:43
InDet::TRT_LayerBuilderImpl::m_barrelSectorAtPiBoundary
IntegerProperty m_barrelSectorAtPiBoundary
this is the barrel Sector where +pi/-pi is within
Definition: TRT_LayerBuilderImpl.h:84
DiscBounds.h
RectangleBounds.h
InDet::TRT_LayerBuilderImpl::m_barrelLayerBinsPhi
UnsignedIntegerProperty m_barrelLayerBinsPhi
Bins for the Barrel material - in phi.
Definition: TRT_LayerBuilderImpl.h:78
Trk::binZ
@ binZ
Definition: BinningType.h:49
InDetDD::TRT_DetElementContainer
Class to hold different TRT detector elements structures.
Definition: TRT_DetElementContainer.h:25
TRT_DetElementContainer.h
SharedDoNoDelete.h
xAOD::deltaPhi
setSAddress setEtaMS setDirPhiMS setDirZMS setBarrelRadius setEndcapAlpha setEndcapRadius setInterceptInner setEtaMap setEtaBin setIsTgcFailure setDeltaPt deltaPhi
Definition: L2StandAloneMuon_v1.cxx:161
BinnedArray2D.h
takeSmallerBigger
#define takeSmallerBigger(cSmallest, cBiggest, test)
Definition: RobustTrackingGeometryBuilderImpl.h:45
InDetDD::TRT_BaseElement::nStraws
unsigned int nStraws() const
Number of straws in the element.
CSV_InDetExporter.new
new
Definition: CSV_InDetExporter.py:145
TRT_ID.h
This is an Identifier helper class for the TRT subdetector. This class is a factory for creating comp...
DiscLayer.h
M_PI
#define M_PI
Definition: ActiveFraction.h:11
InDetDD::TRT_EndcapElement
Definition: TRT_EndcapElement.h:43
Trk::closed
@ closed
Definition: BinningType.h:41
InDet::TRT_LayerBuilderImpl::m_layerThickness
DoubleProperty m_layerThickness
modelled layer thickness
Definition: TRT_LayerBuilderImpl.h:72
Trk::DiscSurface
Definition: DiscSurface.h:54
Trk::ApproachDescriptor
Definition: ApproachDescriptor.h:25
InDet::TRT_LayerBuilderImpl::TRT_LayerBuilderImpl
TRT_LayerBuilderImpl(const std::string &, const std::string &, const IInterface *)
AlgTool style constructor.
Definition: TRT_LayerBuilderImpl.cxx:59
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
InDet::TRT_LayerBuilderImpl::m_modelBarrelLayers
UnsignedIntegerProperty m_modelBarrelLayers
model barrel layers with material
Definition: TRT_LayerBuilderImpl.h:74
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
Trk::Surface::center
const Amg::Vector3D & center() const
Returns the center position of the Surface.
Trk::ApproachSurfaces
Definition: IApproachDescriptor.h:25
Trk::DiscBounds::rMax
double rMax() const
This method returns outer radius.
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
InDet::TRT_LayerBuilderImpl::m_modelEndcapLayers
UnsignedIntegerProperty m_modelEndcapLayers
model endcap layers with material
Definition: TRT_LayerBuilderImpl.h:75
InDet::TRT_LayerBuilderImpl::cylindricalLayersImpl
std::unique_ptr< const std::vector< Trk::CylinderLayer * > > cylindricalLayersImpl(const InDetDD::TRT_DetElementContainer *trtContainer) const
Definition: TRT_LayerBuilderImpl.cxx:66
AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
takeBigger
#define takeBigger(current, test)
Definition: RobustTrackingGeometryBuilderImpl.h:44
Amg::getTransformFromRotTransl
Amg::Transform3D getTransformFromRotTransl(Amg::RotationMatrix3D rot, Amg::Vector3D transl_vec)
Definition: GeoPrimitivesHelpers.h:172
InDet::TRT_LayerBuilderImpl::m_modelGeometry
BooleanProperty m_modelGeometry
Build the geometry with model layers.
Definition: TRT_LayerBuilderImpl.h:73
InDetDD::TRT_Numerology::getNEndcapWheels
unsigned int getNEndcapWheels() const
BinnedArray1D.h
Trk::DiscBounds::rMin
double rMin() const
This method returns inner radius.
TRT_EndcapElement.h
InDetDD::operator*
SiLocalPosition operator*(const SiLocalPosition &position, const double factor)
Definition: SiLocalPosition.cxx:98
InDetDD::TRT_Numerology
Definition: TRT_Numerology.h:22
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
z
#define z
beamspotman.n
n
Definition: beamspotman.py:727
vector
Definition: MultiHisto.h:13
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
TRT_OverlapDescriptor.h
Trk::Surface::normal
virtual const Amg::Vector3D & normal() const
Returns the normal vector of the Surface (i.e.
InDetDD::TRT_Numerology::getNBarrelPhi
unsigned int getNBarrelPhi() const
InDetDD::TRT_BaseElement::identify
virtual Identifier identify() const override final
identifier of this detector element:
CylinderLayer.h
InDetDD::TRT_Numerology::getNBarrelLayers
unsigned int getNBarrelLayers(unsigned int iMod) const
Trk::DiscLayer
Definition: DiscLayer.h:45
BinnedLayerMaterial.h
Trk::BinnedLayerMaterial
Definition: BinnedLayerMaterial.h:33
TRT_BarrelElement.h
InDet::TRT_LayerBuilderImpl::m_endcapConly
BooleanProperty m_endcapConly
Only build the endcapC.
Definition: TRT_LayerBuilderImpl.h:81
Trk::BinnedArray2D
Definition: BinnedArray2D.h:37
InDet::TRT_LayerBuilderImpl::discLayersImpl
std::unique_ptr< const std::vector< Trk::DiscLayer * > > discLayersImpl(const InDetDD::TRT_DetElementContainer *trtContainer) const
Definition: TRT_LayerBuilderImpl.cxx:431
Trk::BinUtility
Definition: BinUtility.h:39
Trk::CylinderLayer
Definition: CylinderLayer.h:43
InDetDD::TRT_DetElementContainer::getBarrelDetElement
const TRT_BarrelElement * getBarrelDetElement(unsigned int positive, unsigned int moduleIndex, unsigned int phiIndex, unsigned int strawLayerIndex) const
Definition: TRT_DetElementContainer.cxx:44
python.EventInfoMgtInit.release
release
Definition: EventInfoMgtInit.py:23
Trk::RectangleBounds::halflengthY
double halflengthY() const
for consitant naming
TRT_LayerBuilderImpl.h
InDet::TRT_LayerBuilderImpl::m_registerStraws
BooleanProperty m_registerStraws
register the straws
Definition: TRT_LayerBuilderImpl.h:83
takeSmaller
#define takeSmaller(current, test)
Definition: RobustTrackingGeometryBuilderImpl.h:43
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
InDetDD::TRT_BaseElement::bounds
virtual const Trk::SurfaceBounds & bounds() const override final
Straw layer bounds.
Trk::open
@ open
Definition: BinningType.h:40
Trk::binR
@ binR
Definition: BinningType.h:50
TRT_ID
Definition: TRT_ID.h:82
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Trk::binRPhi
@ binRPhi
Definition: BinningType.h:52
Trk::PlaneSurface
Definition: PlaneSurface.h:64
Amg::RotationMatrix3D
Eigen::Matrix< double, 3, 3 > RotationMatrix3D
Definition: GeoPrimitives.h:49
GeoPrimitivesHelpers.h
Amg::Translation3D
Eigen::Translation< double, 3 > Translation3D
Definition: GeoPrimitives.h:44
InDetDD::TRT_BaseElement::center
virtual const Amg::Vector3D & center() const override final
Element Surface: center of a straw layer.
InDetDD::TRT_DetElementContainer::getTRTNumerology
const TRT_Numerology * getTRTNumerology() const
Definition: TRT_DetElementContainer.cxx:39
TRT_Numerology.h
InDetDD::TRT_Numerology::getNEndcapPhi
unsigned int getNEndcapPhi() const
InDetDD::TRT_Numerology::getNEndcapLayers
unsigned int getNEndcapLayers(unsigned int iWheel) const
InDetDD::TRT_Numerology::getNBarrelRings
unsigned int getNBarrelRings() const
AthAlgTool
Definition: AthAlgTool.h:26
InDet::TRT_LayerBuilderImpl::m_barrelLayerBinsZ
UnsignedIntegerProperty m_barrelLayerBinsZ
Bins for the Barrel material - in z.
Definition: TRT_LayerBuilderImpl.h:77
InDetDD::TRT_DetElementContainer::getEndcapDetElement
const TRT_EndcapElement * getEndcapDetElement(unsigned int positive, unsigned int wheelIndex, unsigned int strawLayerIndex, unsigned int phiIndex) const
Definition: TRT_DetElementContainer.cxx:67
Trk::Surface
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:79
BinnedArrayArray2D.h
Trk::Surface::transform
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
InDetDD::TRT_BaseElement::surface
virtual const Trk::Surface & surface() const override final
Element Surface: access to the Surface (straw layer)
TSU::T
unsigned long long T
Definition: L1TopoDataTypes.h:35
Trk::DiscBounds
Definition: DiscBounds.h:44
TRT_ID::straw_id
Identifier straw_id(int barrel_ec, int phi_module, int layer_or_wheel, int straw_layer, int straw) const
Three ways of getting id for a single straw:
Definition: TRT_ID.h:575
Trk::binPhi
@ binPhi
Definition: BinningType.h:51
Identifier
Definition: IdentifierFieldParser.cxx:14