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