ATLAS Offline Software
LayerArrayCreator.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // LayerArrayCreator.cxx, (c) ATLAS Detector software
8 
9 // Trk include
14 #include "TrkGeometry/Layer.h"
18 #include "TrkSurfaces/DiscBounds.h"
23 // Amg
25 
26 
27 // constructor
28 Trk::LayerArrayCreator::LayerArrayCreator(const std::string& t, const std::string& n, const IInterface* p)
29 : AthAlgTool(t,n,p),
30  m_emptyLayerMode(0)
31 {
32  declareInterface<ILayerArrayCreator>(this);
33 
34  declareProperty("EmptyLayerMode", m_emptyLayerMode);
35 }
36 
37 
38 std::unique_ptr<Trk::BinnedArray1D<Trk::Layer>> Trk::LayerArrayCreator::cylinderLayerArray(
39  const std::vector<Trk::CylinderLayer*>& cylLayersInput,
40  double rmin, double rmax, Trk::BinningType btype) const
41 {
42  ATH_MSG_VERBOSE( " build LayerArray with " << cylLayersInput.size() << " cylindrical material layers." );
43  ATH_MSG_VERBOSE( " rmin/rmax provided : " << rmin << " / " << rmax );
44 
45  //copy so that you can sort
46  std::vector<Trk::CylinderLayer*> cylLayers(cylLayersInput);
47  // sort the vector
49  std::sort(cylLayers.begin(), cylLayers.end(), rSorter);
50 
51  // needed for all cases
52  Trk::Layer* cylinderLayer = nullptr;
53  std::unique_ptr<Trk::BinnedArray1D<Trk::Layer>> cylinderLayerArray = nullptr;
54  std::vector< std::pair<std::shared_ptr<Trk::Layer>, Amg::Vector3D> > layerOrderVector;
55 
56  switch (btype) {
57 
58  // equidistant binning - no navigation layers built
59  case Trk::equidistant :
60  {
61  // count the layers
62  unsigned int layers = cylLayers.size();
63  // loop over layers and put them in
64  for (auto& layIter : cylLayers ) {
65  // get the R
66  const Trk::CylinderSurface& layerSurface = layIter->surfaceRepresentation();
67  double currentR = layerSurface.bounds().r();
68  ATH_MSG_VERBOSE( "equidistant : registering cylindrical MaterialLayer at radius : " << currentR );
69  layerOrderVector.emplace_back(std::shared_ptr<Layer>(layIter),
70  Amg::Vector3D(currentR, 0.,0.));
71  }
72  // create the binUtility
73  auto binUtility = Trk::BinUtility(layers,rmin,rmax,Trk::open, Trk::binR);
74  ATH_MSG_VERBOSE( "equidistant : created a BinUtility as " << binUtility );
75 
76  // create the BinnedArray; BinnedArray now owns the binUtility pointer
77  cylinderLayerArray = std::make_unique<Trk::BinnedArray1D<Trk::Layer>>(layerOrderVector, binUtility);
78  } break;
79 
80  // bi-equidistant binning - take care the layers have to be binned equidistant + same thickness
81  case Trk::biequidistant :
82  {
83 
84  // count the layers
85  unsigned int layers = cylLayers.size();
86  // take a reference thinkness
87  double layerThickness = cylLayers[0]->thickness();
88  // the radialstep
89  double radialStep = (rmax-rmin)/(layers-1);
90  // the next step
91  double navigationR = 0.;
92  double navLayerHalflengthZ = 0.;
93  const Amg::Transform3D* layerTransform = nullptr;
94 
95  // loop over layers
96  for (auto& layIter : cylLayers ) {
97  // get the dimensions
98  const Trk::CylinderSurface& layerSurface = layIter->surfaceRepresentation();
99  layerTransform = layerSurface.transform().isApprox(Amg::Transform3D::Identity()) ? nullptr : &layerSurface.transform();
100 
101  double currentR = layerSurface.bounds().r();
102  navigationR = currentR - 0.5*radialStep;
103 
104  navLayerHalflengthZ = layerSurface.bounds().halflengthZ();
105  ATH_MSG_VERBOSE( "bi-equidistant : creating cylindrical NavigationLayer at radius : " << navigationR );
106  auto navLayerSurface =
107  layerTransform ? std::make_unique<Trk::CylinderSurface>(
108  Amg::Transform3D(*layerTransform),navigationR, navLayerHalflengthZ)
109  : std::make_unique<Trk::CylinderSurface>(
110  navigationR, navLayerHalflengthZ);
111  // the navigation layer
112  auto navLayer = std::make_shared<Trk::NavigationLayer>(std::move(navLayerSurface));
113  // push the navigation layer in
114  layerOrderVector.emplace_back(std::move(navLayer),
115  Amg::Vector3D(navigationR, 0., 0.));
116  ATH_MSG_VERBOSE( "bi-equidistant : registering cylindrical MaterialLayer at radius : " << currentR );
117  // push the original layer in
118  layerOrderVector.emplace_back(std::shared_ptr<Trk::Layer>(layIter),
119  Amg::Vector3D(currentR, 0., 0.));
120  }
121 
122  // special treatment for the last one
123  ATH_MSG_VERBOSE( "bi-equidistant : creating cylindrical NavigationLayer at radius : " << navigationR+radialStep);
124  auto navLayerSurfacFinal = layerTransform ?
125  std::make_unique<Trk::CylinderSurface>(
126  Amg::Transform3D(*layerTransform), navigationR+radialStep, navLayerHalflengthZ) :
127  std::make_unique<Trk::CylinderSurface>(navigationR+radialStep, navLayerHalflengthZ);
128  // the navigation layer
129  auto navLayer = std::make_shared<Trk::NavigationLayer>(std::move(navLayerSurfacFinal));
130  // push the navigation layer in
131  layerOrderVector.emplace_back(std::move(navLayer),
132  Amg::Vector3D(navigationR+radialStep, 0., 0.));
133 
134  ATH_MSG_VERBOSE( layerOrderVector.size() << " cylindrical Layers (material + navigation) built. " );
135 
136  // create the binUtility
137  double rMinBoundary = rmin-radialStep+0.5*layerThickness;
138  double rMaxBoundary = rmax+radialStep+0.5*layerThickness;
139  auto binUtility = Trk::BinUtility(layers, layerThickness, rMinBoundary, rMaxBoundary, Trk::open, Trk::binR);
140  ATH_MSG_VERBOSE( "bi-equidistant : created a BinUtility as " << binUtility );
141 
142  // create the BinnedArray; BinnedArray now owns the binUtility pointer
143  cylinderLayerArray = std::make_unique<Trk::BinnedArray1D<Trk::Layer>>(layerOrderVector, binUtility);
144 
145  } break;
146 
147  // arbitrary binning
148  case Trk::arbitrary :
149  {
150  std::vector<float> boundaries;
151  // maz z extension
152  double halfLengthZ = 0;
153  const Amg::Transform3D* layerTransform = nullptr;
154 
155  // initial step
156  boundaries.push_back(rmin);
157 
158  // loop over the provided layers and put Navigation layers in between
159  for (auto& layIter : cylLayers) {
160  // get the cylinder surface
161  const Trk::CylinderSurface& layerSurface = layIter->surfaceRepresentation();
162  layerTransform = layerSurface.transform().isApprox(Amg::Transform3D::Identity()) ? nullptr : &layerSurface.transform();
163  // and get the halflength
164  double currentHalfLengthZ = layerSurface.bounds().halflengthZ();
165  takeBigger(halfLengthZ, currentHalfLengthZ);
166  double layerRadius = layerSurface.bounds().r();
167  double layerThickness = layIter->thickness();
168  // navigation layer : previous bin
169  double navLayerRadius = 0.5*( (layerRadius-0.5*layerThickness) + boundaries[boundaries.size()-1] );
170  auto navLayerSurface = layerTransform ?
171  std::make_unique<Trk::CylinderSurface>(
172  Amg::Transform3D(*layerTransform), navLayerRadius, halfLengthZ) :
173  std::make_unique<Trk::CylinderSurface>(navLayerRadius, halfLengthZ);
174  // material layer : current bin
175  cylinderLayer = checkAndReplaceEmptyLayer(layIter);
176  if (cylinderLayer){
177  ATH_MSG_VERBOSE( "arbitrary : creating cylindrical NavigationLayer at radius : " << navLayerRadius );
178  layerOrderVector.emplace_back(
179  std::make_shared<Trk::NavigationLayer>(std::move(navLayerSurface)),
180  Amg::Vector3D(navLayerRadius, 0., 0.));
181  ATH_MSG_VERBOSE( "arbitrary : registering cylindrical MaterialLayer at radius :" << layerRadius );
182  layerOrderVector.emplace_back(
183  std::shared_ptr<Trk::Layer>(cylinderLayer),
184  Amg::Vector3D(layerRadius, 0.,0.));
185  boundaries.push_back(layerRadius-0.5*layerThickness);
186  boundaries.push_back(layerRadius+0.5*layerThickness);
187  } else {
188  ATH_MSG_VERBOSE( "arbitrary : empty layer configuration cancelled this building of navigation layer.");
189  }
190  }
191  // close up the array with last bin
192  double navLayerRadiusFinal = 0.5*(rmax+boundaries[boundaries.size()-1]);
193  auto navLayerSurfaceFinal = layerTransform ?
194  std::make_unique<Trk::CylinderSurface>(
195  Amg::Transform3D(*layerTransform), navLayerRadiusFinal, halfLengthZ) :
196  std::make_unique<Trk::CylinderSurface>(navLayerRadiusFinal, halfLengthZ);
197  boundaries.push_back(rmax);
198  ATH_MSG_VERBOSE( "arbitrary : creating cylindrical NavigationLayer at radius : " << navLayerRadiusFinal );
199  layerOrderVector.emplace_back(std::make_shared<Trk::NavigationLayer>(std::move(navLayerSurfaceFinal)),
200  Amg::Vector3D(navLayerRadiusFinal, 0., 0.));
201 
202  ATH_MSG_VERBOSE( layerOrderVector.size() << " cylindrical Layers (material + navigation) built. " );
203  // create the BinUtility
204  auto binUtility = Trk::BinUtility(boundaries, Trk::open, Trk::binR);
205  ATH_MSG_VERBOSE( "arbitrary : created a BinUtility as " << binUtility );
206 
207  // create the BinnedArray; BinnedArray now owns the binUtility pointer
208  cylinderLayerArray = std::make_unique<Trk::BinnedArray1D<Trk::Layer>>(layerOrderVector, binUtility);
209 
210  } break;
211 
212  // default return 0
213  default : { return nullptr; }
214  }
215 
216  return cylinderLayerArray;
217 }
218 
219 
220 std::unique_ptr<Trk::BinnedArray1D<Trk::Layer>> Trk::LayerArrayCreator::discLayerArray(
221  const std::vector<Trk::DiscLayer*>& discLayersInput,
222  double zmin,
223  double zmax,
224  Trk::BinningType btype) const
225 {
226 
227  ATH_MSG_VERBOSE( " build LayerArray with " << discLayersInput.size() << " disc-like material layers." );
228  ATH_MSG_VERBOSE( " zmin/zmax provided : " << zmin << " / " << zmax );
229 
230  // needed for all cases
231  std::unique_ptr<Trk::BinnedArray1D<Trk::Layer>> discLayerArray = nullptr;
232  std::vector<std::pair<std::shared_ptr<Trk::Layer>, Amg::Vector3D>> layerOrderVector;
233 
234  //copy so that you can sort
235  std::vector<Trk::DiscLayer*> discLayers(discLayersInput);
236  // sort the vector
237  Trk::DiscLayerSorterZ zSorter;
238  std::sort(discLayers.begin(), discLayers.end(), zSorter);
239  // the layer to be pushed back
240  Trk::Layer* discLayer = nullptr;
241 
242  switch (btype) {
243 
244  // equidistant binning
245  case Trk::equidistant :
246  {
247  // count the layers
248  size_t layers = discLayers.size();
249  // loop over layers and put them in
250  for (Trk::DiscLayer* layIter : discLayers ) {
251  discLayer = checkAndReplaceEmptyLayer(layIter);
252  // get the Z
253  const Trk::Surface& layerSurface = discLayer->surfaceRepresentation();
254  ATH_MSG_VERBOSE( "equidistant : registering disc-like MaterialLayer at z-Position : " << layerSurface.center().z() );
255  layerOrderVector.emplace_back(std::shared_ptr<Layer>(discLayer),
256  layerSurface.center());
257  }
258  // create the binUitlity
259  auto binUtility = Trk::BinUtility(layers,zmin,zmax,Trk::open,Trk::binZ);
260  ATH_MSG_VERBOSE( "equidistant : created a BinUtility as " << binUtility );
261 
262  // create the BinnedArray; BinnedArray now owns the binUtility pointer
263  discLayerArray = std::make_unique<Trk::BinnedArray1D<Trk::Layer>>(layerOrderVector, binUtility);
264 
265  } break;
266 
267  // bi-equidistant binning
268  case Trk::biequidistant :
269  {
270  // count the layers
271  unsigned int layers = discLayers.size();
272  // take a reference layer thickness
273  double layerThickness = discLayers[0]->thickness();
274  ATH_MSG_VERBOSE( "bi-equidistant : zmin / zmax re-evaluated as = " << zmin << " / " << zmax );
275  // the radialstep
276  double zStep = (zmax-zmin)/(layers-1);
277  double minR = 0.;
278  double maxR = 0.;
279 
280  Amg::Transform3D navLayerTransform;
281  double navigationZ = 0.;
282  // loop over layers
283  for (auto& layIter : discLayers) {
284  // get the dimensions
285  const Trk::DiscSurface& layerSurface = layIter->surfaceRepresentation();
286  double currentZ = layerSurface.center().z();
287  // create the navigation Z from current Z
288  navigationZ = currentZ - 0.5*(zStep);
289  navLayerTransform = Amg::Transform3D(Amg::Translation3D(0.,0.,navigationZ));
290  auto navLayerSurface = std::make_unique<Trk::DiscSurface>(navLayerTransform, minR, maxR);
291  // push that layer back
292  ATH_MSG_VERBOSE( "bi-equidistant : creating disc-like NavigationLayer at z-Position : " << navigationZ );
293  const Amg::Vector3D center = navLayerSurface->center();
294  layerOrderVector.emplace_back(
295  std::make_shared<Trk::NavigationLayer>(std::move(navLayerSurface)),
296  center);
297  // and get dimensions
298  const Trk::DiscBounds* dbounds = dynamic_cast<const Trk::DiscBounds*>(&(layerSurface.bounds()));
299  if (dbounds) {
300  minR = dbounds->rMin();
301  maxR = dbounds->rMax();
302  } else { // protection
303  minR = 0.;
304  maxR = 100000.;
305  }
306  // get the material layer first
307  ATH_MSG_VERBOSE( "bi-equidistant : registering disc-like MaterialLayer at z-Position : " << currentZ );
308  layerOrderVector.emplace_back(std::shared_ptr<Trk::Layer>(layIter),
309  layerSurface.center());
310  }
311  // special treatment for last bin
312  ATH_MSG_VERBOSE( "bi-equidistant : creating disc-like NavigationLayer at z-Position : " << navigationZ + zStep );
313  navLayerTransform = Amg::Transform3D(Amg::Translation3D(0.,0.,navigationZ+zStep));
314  auto navLayerSurface = std::make_unique<Trk::DiscSurface>(navLayerTransform, minR, maxR);
315  const Amg::Vector3D center = navLayerSurface->center();
316  layerOrderVector.emplace_back(std::make_shared<Trk::NavigationLayer>(std::move(navLayerSurface)),
317  center);
318  // verbose output
319  ATH_MSG_VERBOSE( layerOrderVector.size() << " disc Layers (material + navigation) built. " );
320 
321  // create the binUtility
322  double zminBoundary = zmin-zStep+0.5*layerThickness;
323  double zmaxBoundary = zmax+zStep+0.5*layerThickness;
324  auto binUtility = Trk::BinUtility(layers, layerThickness, zminBoundary, zmaxBoundary, Trk::open, Trk::binZ);
325  ATH_MSG_VERBOSE( "bi-equidistant : created a BinUtility as " << binUtility );
326 
327  // create the BinnedArray; BinnedArray now owns the binUtility pointer
328  discLayerArray = std::make_unique<Trk::BinnedArray1D<Trk::Layer>>(layerOrderVector, binUtility);
329 
330  } break;
331 
332  // arbitrary binning
333  case Trk::arbitrary :
334  {
335  std::vector<float> boundaries;
336 
337  // max disc dimension
338  double minR = 10e10;
339  double maxR = 0.;
340 
341  // initial boundary
342  boundaries.push_back(zmin);
343 
344  // loop over the provided layers and put NavigationLayers in between
345  for (auto& layIter : discLayers ) {
346  // get the cylinder surface
347  const Trk::DiscSurface& layerSurface = layIter->surfaceRepresentation();
348  // and get dimensions
349  const Trk::DiscBounds* dbounds = dynamic_cast<const Trk::DiscBounds*>(&(layerSurface.bounds()));
350  if (dbounds) {
351  double layInnerR = dbounds->rMin();
352  double layOuterR = dbounds->rMax();
353  minR = (layInnerR < minR) ? layInnerR : minR;
354  maxR = (layOuterR > maxR) ? layOuterR : maxR;
355  } else { // protection
356  minR = 0.;
357  maxR = 100000.;
358  }
359  // the radius & position
360  double layerPositionZ = layerSurface.center().z();
361  double layerThickness = layIter->thickness();
362  // navigation Layer
363  double navLayerPositionZ = 0.5*((layerPositionZ-0.5*layerThickness)+boundaries[boundaries.size()-1]);
364  // now fill the layer post slot after navigation layer has been determined
365  // the transform for this
366  Amg::Transform3D navLayerTransform = Amg::Transform3D(Amg::Translation3D(0.,0.,navLayerPositionZ));
367  auto navLayerSurface = std::make_unique<Trk::DiscSurface>(navLayerTransform, minR, maxR);
368 
369  // the material layer
370  discLayer = checkAndReplaceEmptyLayer(layIter);
371  if (discLayer) {
372  ATH_MSG_VERBOSE( "arbitrary : creating disc-like NavigationLayer at z-Position : " << navLayerPositionZ );
373  layerOrderVector.emplace_back(std::make_shared<Trk::NavigationLayer>(std::move(navLayerSurface)),
374  Amg::Vector3D(0., 0., navLayerPositionZ));
375  ATH_MSG_VERBOSE( "arbitrary : registering disc-like MaterialLayer at z-Position : " << layerPositionZ );
376  layerOrderVector.emplace_back(
377  std::shared_ptr<Trk::Layer>(discLayer),
378  Amg::Vector3D(0.,0., layerPositionZ));
379  boundaries.push_back(layerPositionZ-0.5*layerThickness);
380  boundaries.push_back(layerPositionZ+0.5*layerThickness);
381  } else {
382  ATH_MSG_VERBOSE( "arbitrary : empty layer configuration cancelled this building of navigation layer.");
383  }
384  }
385  // final material layer
386  double navLayerPositionZFinal = 0.5*(zmax+boundaries[boundaries.size()-1]);
387  Amg::Transform3D navLayerTransformFinal = Amg::Transform3D(
388  Amg::Translation3D(0., 0., navLayerPositionZFinal));
389  auto navLayerSurfaceFinal = std::make_unique<Trk::DiscSurface>(navLayerTransformFinal, minR, maxR);
390  ATH_MSG_VERBOSE( "arbitrary : creating disc-like NavigationLayer at z-Position : " << navLayerPositionZFinal );
391  layerOrderVector.emplace_back(std::make_shared<Trk::NavigationLayer>(std::move(navLayerSurfaceFinal)),
392  Amg::Vector3D(0., 0., navLayerPositionZFinal));
393  ATH_MSG_VERBOSE( layerOrderVector.size() << " disc Layers (material + navigation) built. " );
394  // register the last bounday
395  boundaries.push_back(zmax);
396  // create the BinUtility
397  auto binUtility = Trk::BinUtility(boundaries, Trk::open, Trk::binZ);
398  ATH_MSG_VERBOSE( "arbitrary : created a BinUtility as " << binUtility );
399 
400  // create the BinnedArray; BinnedArray now owns the binUtility pointer
401  // cppcheck-suppress memleak
402  discLayerArray = std::make_unique<Trk::BinnedArray1D<Trk::Layer>>(layerOrderVector, binUtility);
403 
404  } break;
405 
406  // default return 0
407  default : { return nullptr; }
408  }
409 
410  return discLayerArray;
411 }
412 
413 
414 std::unique_ptr<Trk::BinnedArray1D<Trk::Layer>> Trk::LayerArrayCreator::planeLayerArray(
415  const std::vector<Trk::PlaneLayer*>& planeLayersInput,
416  double posmin,
417  double posmax,
418  Trk::BinningType btype,
419  Trk::BinningValue bv) const
420 {
421  ATH_MSG_VERBOSE( " build LayerArray with " << planeLayersInput.size() << " plane-like material layers." );
422 
423  // needed for all cases
424  std::unique_ptr<Trk::BinnedArray1D<Trk::Layer>> planeLayerArray = nullptr;
425  std::vector< std::pair< std::shared_ptr<Trk::Layer>, Amg::Vector3D> > layerOrderVector;
426  Amg::Vector3D layerCenter(0.,0.,0.);
427 
428  //copy so that you can sort
429  std::vector<Trk::PlaneLayer*> planeLayers(planeLayersInput);
430 
431  auto sortBegin = planeLayers.begin();
432  auto sortEnd = planeLayers.end();
433  switch (bv) {
434  case Trk::binX : { std::sort(sortBegin, sortEnd, Trk::PlaneLayerSorterX()); } break;
435  case Trk::binY : { std::sort(sortBegin, sortEnd, Trk::PlaneLayerSorterY()); } break;
436  case Trk::binZ : { std::sort(sortBegin, sortEnd, Trk::PlaneLayerSorterZ()); } break;
437  default : {
438  ATH_MSG_WARNING("Plane Layers can only be sorted in x/y/z. Returning 0.");
439  return nullptr;
440  }
441  }
442 
443  // the iterator
444  auto layIter = planeLayers.begin();
445 
446  switch (btype) {
447 
448  // equidistant binning
449  case Trk::equidistant :
450  {
451  // count the layers
452  unsigned int layers = planeLayers.size();
453  // loop over layers and put them in
454  for ( ; layIter != planeLayers.end(); ++layIter) {
455  // get the X
456  const Trk::PlaneSurface& layerSurface = (*layIter)->surfaceRepresentation();
457  ATH_MSG_VERBOSE( "equidistant : registering plane-like MaterialLayer at position : " << layerSurface.center() );
458 
459  layerOrderVector.emplace_back(
460  std::shared_ptr<Layer>(*layIter),
461  layerSurface.center());
462  }
463  // create the binUitlity
464  auto binUtility = Trk::BinUtility(layers,posmin,posmax, Trk::open, bv);
465  // create the BinnedArray
466  planeLayerArray = std::make_unique<Trk::BinnedArray1D<Trk::Layer>>(layerOrderVector, binUtility);
467 
468  } break;
469 
470  // bi-equidistant binning
471  case Trk::biequidistant :
472  {
473  // count the layers
474  unsigned int layers = planeLayers.size();
475  // the x-step
476  double posStep = (posmax-posmin)/(layers+1);
477 
478  double currentPos = posmin + posStep;
479  double lastPos = posmin;
480 
481  double minHalfX = 0.;
482  double maxHalfX = 0.;
483  double halfY = 0.;
484 
485  double layerThickness = 0.;
486 
487  // loop over layers
488  for ( ; layIter != planeLayers.end() ; ++layIter) {
489 
490  // get the dimensions
491  const Trk::PlaneSurface& layerSurface = (*layIter)->surfaceRepresentation();
492  // get dimensions
493  const Trk::RectangleBounds* recbounds = dynamic_cast<const Trk::RectangleBounds*>(&(layerSurface.bounds()));
494  // try rectangular hypothesis
495  if (recbounds) {
496  maxHalfX = recbounds->halflengthX();
497  halfY = recbounds->halflengthY();
498  } else {
499  // try trapezoidal hypothesis
500  const Trk::TrapezoidBounds* trapbounds = dynamic_cast<const Trk::TrapezoidBounds*>(&(layerSurface.bounds()));
501  if (trapbounds) {
502  minHalfX = trapbounds->minHalflengthX();
503  maxHalfX = trapbounds->maxHalflengthX();
504  halfY = trapbounds->halflengthY();
505  } else {
506  // protection
507  minHalfX = 0.;
508  maxHalfX = 10e10;
509  halfY = 10e10;
510  }
511  }
512 
513  layerThickness = ((*layIter)->thickness() > layerThickness ) ? (*layIter)->thickness() : layerThickness;
514 
515  // the navigation Layer
516  double navigationPos = 0.5*(currentPos+lastPos);
517  double navigationX = (bv == Trk::binX) ? navigationPos : 0.;
518  double navigationY = (bv == Trk::binY) ? navigationPos : 0.;
519  double navigationZ = (bv == Trk::binZ) ? navigationPos : 0.;
520  Amg::Translation3D(navigationX,navigationY,navigationZ);
521 
522  std::unique_ptr<Trk::PlaneSurface> navLayerSurface = nullptr;
523  Amg::Transform3D navLayerTransform(Amg::Translation3D(navigationX,0.,0.));
524 
525  if (std::abs(minHalfX)<10e-5) {
526  navLayerSurface = std::make_unique<Trk::PlaneSurface>(navLayerTransform,
527  maxHalfX,
528  halfY);
529  } else {
530  navLayerSurface = std::make_unique<Trk::PlaneSurface>(navLayerTransform,
531  minHalfX,
532  maxHalfX,
533  halfY);
534  }
535 
536  ATH_MSG_VERBOSE( "bi-equidistant : creating plane-like NavigationLayer at position : " << navigationX );
537 
538  layerOrderVector.emplace_back(std::make_shared<Trk::NavigationLayer>(std::move(navLayerSurface)),
539  Amg::Vector3D(navigationX, 0.,0.));
540  // restore
541  lastPos = currentPos;
542  // the material Layer
543 
544  ATH_MSG_VERBOSE( "bi-equidistant : registering plane-like MaterialLayer at position : " << currentPos );
545  layerOrderVector.emplace_back(
546  std::shared_ptr<Trk::Layer>(*layIter),
547  layerSurface.center());
548 
549  // increase the Step
550  currentPos += posStep;
551  }
552 
553  // the final navigation layer
554  double navigationPosFinal = 0.5*(currentPos+lastPos);
555  double navigationXFinal = (bv == Trk::binX) ? navigationPosFinal : 0.;
556  double navigationYFinal = (bv == Trk::binY) ? navigationPosFinal : 0.;
557  double navigationZFinal = (bv == Trk::binZ) ? navigationPosFinal : 0.;
558 
559  Amg::Transform3D navLayerTransform(Amg::Translation3D(navigationXFinal,navigationYFinal,navigationZFinal));
560 
561  auto navLayerSurface = (std::abs(minHalfX)<10e-5) ?
562  std::make_unique<Trk::PlaneSurface>(navLayerTransform, maxHalfX,halfY) :
563  std::make_unique<Trk::PlaneSurface>(navLayerTransform, minHalfX, maxHalfX, halfY);
564 
565  ATH_MSG_VERBOSE( "bi-equidistant : creating plane-like NavigationLayer at position : " << navLayerSurface->center() );
566  const Amg::Vector3D center = navLayerSurface->center();
567  layerOrderVector.emplace_back(std::make_shared<Trk::NavigationLayer>(std::move(navLayerSurface)),
568  center);
569 
570  // create the binUtility
571  auto binUtility = Trk::BinUtility(layers, layerThickness, posmin, posmax, Trk::open, bv);
572 
573  // create the BinnedArray
574  planeLayerArray = std::make_unique<Trk::BinnedArray1D<Trk::Layer>>(layerOrderVector, binUtility);
575 
576  } break;
577 
578  // arbitrary binning
579  case Trk::arbitrary :
580  {
581 
582  std::vector<float> boundaries;
583  boundaries.push_back(posmin);
584  // max plane dimension
585  double minHalfX = 0.;
586  double maxHalfX = 0.;
587  double halfY = 0.;
588 
589  // loop over the layers and register navigation layers in between
590  for ( ; layIter != planeLayers.end(); ++layIter) {
591 
592  // get the cylinder surface
593  const Trk::PlaneSurface& layerSurface = (*layIter)->surfaceRepresentation();
594  // get dimensions
595  const Trk::RectangleBounds* recbounds = dynamic_cast<const Trk::RectangleBounds*>(&(layerSurface.bounds()));
596  // try rectangular hypothesis
597  if (recbounds) {
598  maxHalfX = recbounds->halflengthX();
599  halfY = recbounds->halflengthY();
600  } else {
601  // try trapezoidal hypothesis
602  const Trk::TrapezoidBounds* trapbounds = dynamic_cast<const Trk::TrapezoidBounds*>(&(layerSurface.bounds()));
603  if (trapbounds) {
604  minHalfX = trapbounds->minHalflengthX();
605  maxHalfX = trapbounds->maxHalflengthX();
606  halfY = trapbounds->halflengthY();
607  } else {
608  // protection
609  minHalfX = 0.;
610  maxHalfX = 10e10;
611  halfY = 10e10;
612  }
613  }
614  // the x position
615  // and get dimensions
616  layerCenter = layerSurface.center();
617  double layerPosition = layerCenter[bv];
618  // get the thickness
619  double layerThickness = (*layIter)->thickness();
620  // register
621  boundaries.push_back(layerPosition-0.5*layerThickness);
622  double navLayerPositionX = (bv == Trk::binX) ? 0.5*(layerPosition+boundaries[boundaries.size()-1]) : layerCenter.x();
623  double navLayerPositionY = (bv == Trk::binY) ? 0.5*(layerPosition+boundaries[boundaries.size()-1]) : layerCenter.y();
624  double navLayerPositionZ = (bv == Trk::binZ) ? 0.5*(layerPosition+boundaries[boundaries.size()-1]) : layerCenter.z();
625  Amg::Translation3D navLayerPosition(navLayerPositionX,navLayerPositionY,navLayerPositionZ);
626  Amg::Transform3D navLayerTransform(navLayerPosition);
627  // create the navigation plane layer
628  auto navLayerSurface = (std::abs(minHalfX)<10e-5) ?
629  std::make_unique<Trk::PlaneSurface>( navLayerTransform, maxHalfX, halfY ) :
630  std::make_unique<Trk::PlaneSurface>( navLayerTransform, minHalfX, maxHalfX, halfY );
631  ATH_MSG_VERBOSE( "arbitrary : creating plane-like NavigationLayer at position : " << navLayerPositionX );
632  layerOrderVector.emplace_back(
633  std::make_shared<Trk::NavigationLayer>(std::move(navLayerSurface)),
634  Amg::Vector3D(navLayerPositionX, navLayerPositionY, navLayerPositionZ));
635  // register the material layer
636  boundaries.push_back(layerPosition+0.5*layerThickness);
637  // material layer
638  layerOrderVector.emplace_back(
639  std::shared_ptr<Trk::Layer>(*layIter),
640  layerSurface.center());
641 
642  }
643  // last NavigationLayer
644  double navLayerPositionXFinal = (bv == Trk::binX) ? 0.5*(posmax+boundaries[boundaries.size()-1]) : layerCenter.x();
645  double navLayerPositionYFinal = (bv == Trk::binY) ? 0.5*(posmax+boundaries[boundaries.size()-1]) : layerCenter.y();
646  double navLayerPositionZFinal = (bv == Trk::binZ) ? 0.5*(posmax+boundaries[boundaries.size()-1]) : layerCenter.z();
647  Amg::Translation3D navLayerPositionFinal(navLayerPositionXFinal,navLayerPositionYFinal,navLayerPositionZFinal);
648  Amg::Transform3D navLayerTransformFinal(navLayerPositionFinal);
649  // create the navigation plane layer
650  auto navLayerSurfaceFinal = (std::abs(minHalfX)<10e-5) ?
651  std::make_unique<Trk::PlaneSurface>( navLayerTransformFinal, maxHalfX, halfY ) :
652  std::make_unique<Trk::PlaneSurface>( navLayerTransformFinal, minHalfX, maxHalfX, halfY );
653  ATH_MSG_VERBOSE( "arbitrary : creating plane-like NavigationLayer at position : " << 0.5*(posmax+boundaries[boundaries.size()-1]) );
654  layerOrderVector.emplace_back(std::make_shared<Trk::NavigationLayer>(std::move(navLayerSurfaceFinal)),
655  Amg::Vector3D(navLayerPositionXFinal, navLayerPositionYFinal, navLayerPositionZFinal));
656 
657  ATH_MSG_VERBOSE( layerOrderVector.size() << " plane Layers (material + navigation) built. " );
658 
659  // create the BinUtility
660  auto binUtility = Trk::BinUtility(boundaries, Trk::open, bv);
661  // and the BinnedArray
662  planeLayerArray = std::make_unique<Trk::BinnedArray1D<Trk::Layer>>(layerOrderVector, binUtility);
663 
664  } break;
665  // default return 0
666  default : { return nullptr; }
667  }
668 
669  return planeLayerArray;
670  //cppcheck-suppress memleak
671 }
672 
674  // empty layers will be replaced by navigation layers
675  if (m_emptyLayerMode){
676  if (lay->layerMaterialProperties() || lay->surfaceArray()) return lay;
678  " replacing dummyMaterial layer with "
679  << (m_emptyLayerMode > 1 ? " nothing" : " NavigationLayer."));
680  Trk::NavigationLayer* nLayer =
681  m_emptyLayerMode > 1
682  ? nullptr
683  : new Trk::NavigationLayer(
684  lay->surfaceRepresentation().uniqueClone(), 1.);
685  delete lay;
686  return nLayer;
687  }
688  // don't replace - just give back what you had
689  return lay;
690 }
691 
692 
693 
TrapezoidBounds.h
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
Trk::TrapezoidBounds::maxHalflengthX
double maxHalflengthX() const
This method returns the maximal halflength in X (first coordinate of local surface frame)
Trk::RectangleBounds
Definition: RectangleBounds.h:38
Trk::LayerArrayCreator::planeLayerArray
std::unique_ptr< Trk::BinnedArray1D< Layer > > planeLayerArray(const std::vector< PlaneLayer * > &layers, double min, double max, BinningType btype=arbitrary, Trk::BinningValue bv=Trk::binX) const
LayerArrayCreator interface method - for Planar-like layers.
Definition: LayerArrayCreator.cxx:414
Trk::PlaneLayerSorterX
Definition: PlaneLayer.h:116
DiscBounds.h
NavigationLayer.h
Trk::equidistant
@ equidistant
Definition: BinningType.h:32
RectangleBounds.h
Trk::binZ
@ binZ
Definition: BinningType.h:49
PixelAthClusterMonAlgCfg.zmin
zmin
Definition: PixelAthClusterMonAlgCfg.py:169
Trk::LayerArrayCreator::m_emptyLayerMode
int m_emptyLayerMode
0 - do nothing, 1 - replace with navigation layer, 2 - delete
Definition: LayerArrayCreator.h:85
Trk::TrapezoidBounds::halflengthY
double halflengthY() const
This method returns the halflength in Y (second coordinate of local surface frame)
BinUtility.h
module_driven_slicing.layers
layers
Definition: module_driven_slicing.py:113
Trk::NavigationLayer
Definition: NavigationLayer.h:41
Trk::biequidistant
@ biequidistant
Definition: BinningType.h:33
Trk::CylinderSurface::bounds
virtual const CylinderBounds & bounds() const override final
This method returns the CylinderBounds by reference (NoBounds is not possible for cylinder)
Layer.h
Trk::BinningType
BinningType
Definition: BinningType.h:31
Trk::DiscSurface
Definition: DiscSurface.h:54
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
Trk::TrapezoidBounds::minHalflengthX
double minHalflengthX() const
This method returns the minimal halflength in X (first coordinate of local surface frame)
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::DiscBounds::rMax
double rMax() const
This method returns outer radius.
takeBigger
#define takeBigger(current, test)
Definition: RobustTrackingGeometryBuilderImpl.h:44
Trk::Layer::surfaceArray
const SurfaceArray * surfaceArray() const
Return the entire SurfaceArray, returns nullptr if no SurfaceArray.
Trk::arbitrary
@ arbitrary
Definition: BinningType.h:34
BinnedArray1D.h
GeoPrimitives.h
GeometryStatics.h
Trk::binY
@ binY
Definition: BinningType.h:48
SurfaceBounds.h
Trk::DiscBounds::rMin
double rMin() const
This method returns inner radius.
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
Trk::Surface::uniqueClone
std::unique_ptr< Surface > uniqueClone() const
NVI method returning unique_ptr clone.
Trk::Layer::surfaceRepresentation
virtual const Surface & surfaceRepresentation() const =0
Transforms the layer into a Surface representation for extrapolation.
Trk::BinningValue
BinningValue
how to take the global / local position
Definition: BinningType.h:46
Trk::RectangleBounds::halflengthX
double halflengthX() const
for consistant naming
beamspotman.n
n
Definition: beamspotman.py:727
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
Definition: AthCommonDataStore.h:145
Trk::CylinderSurface
Definition: CylinderSurface.h:55
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
Trk::DiscSurface::bounds
const SurfaceBounds & bounds() const override final
This method returns the bounds by reference.
CylinderSurface.h
Trk::LayerArrayCreator::LayerArrayCreator
LayerArrayCreator(const std::string &, const std::string &, const IInterface *)
Constructor.
Definition: LayerArrayCreator.cxx:28
PixelAthClusterMonAlgCfg.zmax
zmax
Definition: PixelAthClusterMonAlgCfg.py:169
Trk::DiscLayer
Definition: DiscLayer.h:45
Trk::LayerArrayCreator::discLayerArray
std::unique_ptr< Trk::BinnedArray1D< Layer > > discLayerArray(const std::vector< DiscLayer * > &layers, double zmin, double zmax, BinningType btype=arbitrary) const
LayerArrayCreator interface method - for Endcap-like layers.
Definition: LayerArrayCreator.cxx:220
Trk::binX
@ binX
Definition: BinningType.h:47
Trk::BinUtility
Definition: BinUtility.h:39
Trk::LayerArrayCreator::checkAndReplaceEmptyLayer
Trk::Layer * checkAndReplaceEmptyLayer(Trk::Layer *lay) const
Definition: LayerArrayCreator.cxx:673
Trk::PlaneLayerSorterZ
Definition: PlaneLayer.h:142
Trk::RectangleBounds::halflengthY
double halflengthY() const
for consitant naming
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Trk::TrapezoidBounds
Definition: TrapezoidBounds.h:43
Trk::open
@ open
Definition: BinningType.h:40
Trk::LayerArrayCreator::cylinderLayerArray
std::unique_ptr< Trk::BinnedArray1D< Layer > > cylinderLayerArray(const std::vector< CylinderLayer * > &layers, double rmin, double rmax, BinningType btype=arbitrary) const
LayerArrayCreator interface method - for Barrel-like layers.
Definition: LayerArrayCreator.cxx:38
Trk::binR
@ binR
Definition: BinningType.h:50
python.CaloAddPedShiftConfig.default
default
Definition: CaloAddPedShiftConfig.py:43
Trk::CylinderLayerSorterR
Definition: CylinderLayer.h:180
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Trk::PlaneSurface
Definition: PlaneSurface.h:64
PlaneSurface.h
Trk::PlaneSurface::bounds
virtual const SurfaceBounds & bounds() const override final
This method returns the bounds by reference, static NoBounds in case of no boundaries.
Amg::Translation3D
Eigen::Translation< double, 3 > Translation3D
Definition: GeoPrimitives.h:44
Trk::Layer::layerMaterialProperties
const LayerMaterialProperties * layerMaterialProperties() const
getting the LayerMaterialProperties including full/pre/post update
LayerArrayCreator.h
DiscSurface.h
Trk::PlaneLayerSorterY
Definition: PlaneLayer.h:129
AthAlgTool
Definition: AthAlgTool.h:26
Trk::Surface
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:79
Trk::Surface::transform
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
Trk::DiscBounds
Definition: DiscBounds.h:44
Trk::CylinderBounds::halflengthZ
double halflengthZ() const
This method returns the halflengthZ.
Trk::CylinderBounds::r
virtual double r() const override final
This method returns the radius.
Trk::Layer
Definition: Layer.h:72
Trk::DiscLayerSorterZ
Definition: DiscLayer.h:152