ATLAS Offline Software
MaterialValidation.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // MaterialValidation.cxx, (c) ATLAS Detector Software
8 
9 // Amg
11 // Trk
12 #include "MaterialValidation.h"
14 #include "TrkGeometry/Layer.h"
20 
21 // test
23 
24 // Gaudi Units
25 #include "GaudiKernel/SystemOfUnits.h"
26 
27 
28 Trk::MaterialValidation::MaterialValidation(const std::string& name, ISvcLocator* pSvcLocator)
29 : AthAlgorithm(name,pSvcLocator) ,
30  m_materialMapper("Trk::MaterialMapper/MappingMaterialMapper"),
31  m_maxMaterialValidationEvents(25000),
32  m_flatDist(nullptr),
33  m_etaMin(-3.),
34  m_etaMax(3.),
35  m_runNativeNavigation(true),
36  m_accTinX0(0)
37 {
38 
39  // ---------------------- The Material Mapping -------------------------- //
40  // the toolhandle of the MaterialMapper to be used
41  declareProperty("MaterialMapper" , m_materialMapper);
42  declareProperty("MaximumMappingEvents" , m_maxMaterialValidationEvents);
43  // ---------------------- Range setup ----------------------------------- //
44  declareProperty("MinEta" , m_etaMin);
45  declareProperty("MaxEta" , m_etaMax);
46  // ---------------------- Native navigation ----------------------------- //
47  declareProperty("NativeNavigation" , m_runNativeNavigation);
48 }
49 
51 {
52  delete m_flatDist;
53 }
54 
55 
57 {
58 
59  // Get the TrackingGeometry from StoreGate
60  ATH_CHECK( m_trackingGeometryReadKey.initialize(!m_trackingGeometryReadKey.key().empty()) );
61 
62  if ( (m_materialMapper.retrieve()).isFailure() )
63  ATH_MSG_WARNING("Could not retrieve MaterialMapper");
64 
65  // initialize the random generators
66  m_flatDist = new Rndm::Numbers(randSvc(), Rndm::Flat(0.,1.));
67  return StatusCode::SUCCESS;
68 }
69 
70 
72 {
73  ATH_MSG_VERBOSE( "MaterialValidation execute() start ================================================" );
74 
75  // create the random direction - flat in eta
76  double eta = m_etaMin + (m_etaMax-m_etaMin)*m_flatDist->shoot();
77  double theta = 2.*atan(exp(-eta));
78  double phi = M_PI * ( 2*m_flatDist->shoot() - 1.);
79  m_accTinX0 = 0;
80 
81  // get the position and riection from the random numbers
82  Amg::Vector3D position(0.,0.,0.);
83  Amg::Vector3D direction(sin(theta)*cos(phi),sin(theta)*sin(phi), cos(theta));
84 
85  ATH_MSG_DEBUG("[>] Start mapping event with phi | eta = " << phi << " | " << direction.eta());
86 
87  // find the start TrackingVolume
88  const Trk::TrackingVolume* sVolume = trackingGeometry().lowestTrackingVolume(position);
89  const Trk::TrackingVolume* nVolume = sVolume;
90  while (nVolume ) {
91  Trk::PositionAtBoundary paB = collectMaterialAndExit(*nVolume, position, direction);
92  position = paB.first;
93  nVolume = paB.second;
94  }
95  ATH_MSG_DEBUG("[<] Finishing event with collected path [X0] = " << m_accTinX0);
96  return StatusCode::SUCCESS;
97 }
98 
100  const Amg::Vector3D& position,
101  const Amg::Vector3D& direction)
102 {
103  // get the entry layers -----------------------------------------------------------
104  std::map<double, Trk::AssociatedMaterial> collectedMaterial;
105 
106  // all boundaries found --- proceed
107  Trk::PositionAtBoundary pab(position, 0);
108 
109  ATH_MSG_DEBUG("[>>] Entering Volume: " << tvol.volumeName() << "- at " << Amg::toString(position));
110 
111  Trk::NeutralCurvilinearParameters cvp(position,direction,0.);
112 
113  if (m_runNativeNavigation){
114  // A : collect all hit layers
115  auto layerIntersections = tvol.materialLayersOrdered<Trk::NeutralCurvilinearParameters>(nullptr,nullptr,cvp,Trk::alongMomentum);
116  // loop over the layers
117  for (auto& lCandidate : layerIntersections ) {
118  // get the layer
119  const Trk::Layer* layer = lCandidate.object;
120  double pathLength = lCandidate.intersection.pathLength;
121  // get the associate material
122  if (layer->layerMaterialProperties()){
123  // take it from the global position
124  const Trk::MaterialProperties* mprop = layer->layerMaterialProperties()->fullMaterial(lCandidate.intersection.position);
125  if (mprop){
126  double stepLength = mprop->thickness()*fabs(layer->surfaceRepresentation().pathCorrection(lCandidate.intersection.position,direction));
127  collectedMaterial[pathLength] = Trk::AssociatedMaterial(lCandidate.intersection.position, mprop, stepLength, &tvol, layer);
128  }
129  }
130  }
131  // B : collect all boundary layers, start from last hit layer
132  Amg::Vector3D lastPosition = !collectedMaterial.empty() ? collectedMaterial.rbegin()->second.materialPosition() : (position + direction.unit());
133  Trk::NeutralCurvilinearParameters lcp(lastPosition,direction,0.);
134  // boundary surfaces
135  auto boundaryIntersections = tvol.boundarySurfacesOrdered<Trk::NeutralCurvilinearParameters>(lcp,Trk::alongMomentum);
136  if (!boundaryIntersections.empty()){
137  // by definition is the first one
138  lastPosition = boundaryIntersections.begin()->intersection.position;
139  const Trk::BoundarySurface<Trk::TrackingVolume>* bSurfaceTV = boundaryIntersections.begin()->object;
140  const Trk::Surface& bSurface = bSurfaceTV->surfaceRepresentation();
141  // get the path lenght to it
142  if (bSurface.materialLayer() && bSurface.materialLayer()->layerMaterialProperties()){
143  const Trk::MaterialProperties* mprop = bSurface.materialLayer()->layerMaterialProperties()->fullMaterial(lastPosition);
144  double pathLength = (lastPosition-position).mag();
145  if (mprop){
146  double stepLength = mprop->thickness()*fabs(bSurface.pathCorrection(lastPosition,direction));
147  collectedMaterial[pathLength] = Trk::AssociatedMaterial(lastPosition, mprop, stepLength, &tvol, bSurface.materialLayer());
148  } else
149  collectedMaterial[pathLength] = Trk::AssociatedMaterial(lastPosition, &tvol, bSurface.materialLayer());
150  }
151  // set the new volume
152  const Trk::TrackingVolume* naVolume = bSurfaceTV->attachedVolume(lastPosition, direction, Trk::alongMomentum);
153  pab = Trk::PositionAtBoundary(lastPosition,naVolume);
154  } else
155  pab = Trk::PositionAtBoundary(lastPosition,0);
156  } else {
157  std::map<double, std::pair<const Trk::Layer*, Amg::Vector3D> > intersectedLayers;
158 
159  // Process the contained layers if they exist
160  const Trk::LayerArray* layerArray = tvol.confinedLayers();
161  if (layerArray) {
162  // display output
164  auto layIter = layers.begin();
165  auto layIterE = layers.end();
166  for ( ; layIter != layIterE; ++layIter){
167  if ( (*layIter)->layerMaterialProperties() ){
168  Trk::Intersection lsIntersection = (*layIter)->surfaceRepresentation().straightLineIntersection(position, direction, true, true);
169  if (lsIntersection.valid){
170  intersectedLayers[lsIntersection.pathLength] = std::pair<const Trk::Layer*, Amg::Vector3D>(*layIter,lsIntersection.position);
171  // get & record the material
172  // - the position on the surface
173  Amg::Vector3D mposition = (*layIter)->surfaceRepresentation().transform().inverse()*lsIntersection.position;
174  const Trk::MaterialProperties* mprop = (*layIter)->layerMaterialProperties()->fullMaterial(mposition);
175  if (mprop) {
176  double stepLength = mprop->thickness()*fabs((*layIter)->surfaceRepresentation().pathCorrection(lsIntersection.position,direction));
177  collectedMaterial[lsIntersection.pathLength] = Trk::AssociatedMaterial(lsIntersection.position, mprop, stepLength, &tvol, (*layIter));
178  } else
179  collectedMaterial[lsIntersection.pathLength] = Trk::AssociatedMaterial(lsIntersection.position, &tvol, (*layIter));
180 
181  ATH_MSG_VERBOSE("[>>>>] record material hit at layer with index " << (*layIter)->layerIndex().value() << " - at " << Amg::toString(lsIntersection.position) );
182  if (mprop)
183  ATH_MSG_VERBOSE("[>>>>] MaterialProperties are " << (*mprop) );
184  else
185  ATH_MSG_VERBOSE("[>>>>] No MaterialProperties found." );
186  }
187  }
188  }
189  }
190 
191  // material for confined layers collected, now go to boundary
192 
193  // update the position to the last one
194  Amg::Vector3D lastPosition = !intersectedLayers.empty() ? (*(--(intersectedLayers.end()))).second.second : position;
195 
196  std::map<double, Trk::VolumeExit > volumeExits;
197  // now find the exit point
198  const auto & bSurfaces = tvol.boundarySurfaces();
199  for (size_t ib = 0; ib < bSurfaces.size(); ++ib){
200  // omit positions on the surface
201  if ( !bSurfaces[ib]->surfaceRepresentation().isOnSurface(lastPosition, true, 0.1, 0.1) ){
202  Trk::Intersection evIntersection = bSurfaces[ib]->surfaceRepresentation().straightLineIntersection(lastPosition, direction, true, true);
203  ATH_MSG_VERBOSE("[>>>>] boundary surface intersection / validity :" << Amg::toString(evIntersection.position) << " / " << evIntersection.valid);
204  ATH_MSG_VERBOSE("[>>>>] with path length = " << evIntersection.pathLength );
205  if (evIntersection.valid){
206  // next attached Tracking Volume
207  const Trk::TrackingVolume* naVolume = bSurfaces[ib]->attachedVolume(evIntersection.position, direction, Trk::alongMomentum);
208  // put it into the map
209  volumeExits[evIntersection.pathLength] = Trk::VolumeExit(naVolume, &(bSurfaces[ib]->surfaceRepresentation()), evIntersection.position);
210  // volume exit
211  ATH_MSG_VERBOSE("[>>>>] found volume exit - at " << Amg::toString(evIntersection.position) );
212  }
213  } else
214  ATH_MSG_VERBOSE("[>>>>] starting position is on surface ! " );
215  }
216  // prepare the boundary
217  if (!volumeExits.empty()){
218  // get the first entry in the map: closest next volume
219  VolumeExit closestVolumeExit = (*volumeExits.begin()).second;
220  // check if the volume exit boundary has material attached
221  const Trk::Surface* bSurface = closestVolumeExit.bSurface;
222  if ( bSurface && bSurface->materialLayer() && bSurface->materialLayer()->layerMaterialProperties()){
223  ATH_MSG_VERBOSE("[>>>>] The boundary surface has an associated layer, collect material from there");
224  const Trk::MaterialProperties* mprop = bSurface->materialLayer()->layerMaterialProperties()->fullMaterial(closestVolumeExit.vExit);
225  double pathToExit = (closestVolumeExit.vExit-lastPosition).mag();
226  if (mprop){
227  double stepLength = mprop->thickness()*fabs(bSurface->pathCorrection(closestVolumeExit.vExit,direction));
228  collectedMaterial[pathToExit] = Trk::AssociatedMaterial(closestVolumeExit.vExit, mprop, stepLength, &tvol, bSurface->materialLayer());
229  } else
230  collectedMaterial[pathToExit] = Trk::AssociatedMaterial(closestVolumeExit.vExit, &tvol, bSurface->materialLayer());
231  }
232  //
233  if (closestVolumeExit.nVolume != &tvol && closestVolumeExit.nVolume) {
234  ATH_MSG_VERBOSE("[>>>>] Next Volume: " << closestVolumeExit.nVolume->volumeName() << " - at " << Amg::toString(closestVolumeExit.vExit) );
235  // return for further navigation
236  pab = Trk::PositionAtBoundary(closestVolumeExit.vExit,closestVolumeExit.nVolume);
237  }
238  } else {
239  ATH_MSG_VERBOSE( "[>>>>] No exit found from Volume '" << tvol.volumeName() << "' - starting radius = " << lastPosition.perp() );
240  const Trk::CylinderVolumeBounds* cvb = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(tvol.volumeBounds()));
241  if (cvb)
242  ATH_MSG_VERBOSE( "[>>>>] Volume outer radius = " << cvb->outerRadius() );
243  }
244 
245  }
246  // finally collect the material
247  ATH_MSG_DEBUG("[>>>] Collecting materials from "<< collectedMaterial.size() << " layers");
248  // provide the material to the material mapper
249  auto cmIter = collectedMaterial.begin();
250  auto cmIterE = collectedMaterial.end();
251  for ( ; cmIter != cmIterE; ++cmIter ){
252  m_materialMapper->recordMaterialHit(cmIter->second, cmIter->second.materialPosition());
253  m_accTinX0 += cmIter->second.steplengthInX0();
254  int layerIndex = cmIter->second.associatedLayer() ? cmIter->second.associatedLayer()->layerIndex().value() : 0;
255  ATH_MSG_DEBUG("[>>>] Accumulate pathLength/X0 on layer with index " << layerIndex << " - t/X0 (total so far) = " << cmIter->second.steplengthInX0() << " (" << m_accTinX0 << ")");
256  if (layerIndex){
257  std::string surfaceType =
258  cmIter->second.associatedLayer()->surfaceRepresentation().type() ==
260  ? "Cylinder at radius = "
261  : "Disc at z-position = ";
262  std::string layerType =
263  cmIter->second.associatedLayer()->surfaceArray() ? "Active "
264  : "Passive ";
265  double rz =
266  cmIter->second.associatedLayer()->surfaceRepresentation().type() ==
268  ? cmIter->second.associatedLayer()
269  ->surfaceRepresentation()
270  .bounds()
271  .r()
272  : cmIter->second.associatedLayer()
273  ->surfaceRepresentation()
274  .center()
275  .z();
276  ATH_MSG_DEBUG(" " << layerType << surfaceType << rz);
277  }
278  ATH_MSG_DEBUG(" Distance to origin is " << cmIter->second.materialPosition().mag() );
279  }
280 
281  // return what you have
282  return pab;
283 
284 }
285 
286 
287 
289 {
290  ATH_MSG_INFO( "MaterialValidation finalize()" );
291  return StatusCode::SUCCESS;
292 }
293 
295  std::stringstream msg;
296  msg << "Failed to get conditions data " << m_trackingGeometryReadKey.key() << ".";
297  throw std::runtime_error(msg.str());
298 }
299 
300 
Trk::MaterialValidation::m_maxMaterialValidationEvents
int m_maxMaterialValidationEvents
limit the number of validation records to avoid 2G files
Definition: MaterialValidation.h:96
python.SystemOfUnits.second
int second
Definition: SystemOfUnits.py:120
Trk::Surface::pathCorrection
virtual double pathCorrection(const Amg::Vector3D &pos, const Amg::Vector3D &mom) const
the pathCorrection for derived classes with thickness - it reflects if the direction projection is po...
Trk::VolumeExit
Definition: MaterialValidation.h:37
Trk::BoundarySurface
Definition: BoundarySurface.h:50
Trk::Intersection
Definition: Intersection.h:24
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
Trk::LayerMaterialProperties::fullMaterial
virtual const MaterialProperties * fullMaterial(const Amg::Vector3D &gp) const =0
Return method for full material description of the Layer.
Trk::MaterialValidation::m_runNativeNavigation
bool m_runNativeNavigation
validate the native TG navigation
Definition: MaterialValidation.h:102
MaterialProperties.h
Trk::VolumeExit::bSurface
const Trk::Surface * bSurface
Definition: MaterialValidation.h:40
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
Trk::ParametersBase::position
const Amg::Vector3D & position() const
Access method for the position.
AthCommonDataStore< AthCommonMsg< Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
Trk::TrackingVolume::boundarySurfaces
std::vector< SharedObject< BoundarySurface< TrackingVolume > > > & boundarySurfaces()
Method to return the BoundarySurfaces.
Definition: TrackingVolume.cxx:982
Trk::MaterialValidation::finalize
StatusCode finalize()
standard Athena-Algorithm method
Definition: MaterialValidation.cxx:288
Trk::Intersection::pathLength
double pathLength
Definition: Intersection.h:26
module_driven_slicing.layers
layers
Definition: module_driven_slicing.py:114
Trk::MaterialValidation::~MaterialValidation
~MaterialValidation()
Default Destructor.
Definition: MaterialValidation.cxx:50
M_PI
#define M_PI
Definition: ActiveFraction.h:11
PlotCalibFromCool.ib
ib
Definition: PlotCalibFromCool.py:419
Layer.h
Trk::BoundarySurface::attachedVolume
virtual const Tvol * attachedVolume(const TrackParameters &parms, PropDirection dir) const =0
Get the next Volume depending on the TrackParameters and the requested direction.
Trk::alongMomentum
@ alongMomentum
Definition: PropDirection.h:20
NeutralParameters.h
Trk::MaterialValidation::initialize
StatusCode initialize()
standard Athena-Algorithm method
Definition: MaterialValidation.cxx:56
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
Trk::MaterialValidation::m_etaMin
double m_etaMin
eta boundary
Definition: MaterialValidation.h:100
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
Trk::TrackingVolume::confinedLayers
const LayerArray * confinedLayers() const
Return the subLayer array.
Trk::MaterialProperties::thickness
float thickness() const
Return the thickness in mm.
Trk::TrackingVolume::materialLayersOrdered
std::vector< LayerIntersection< T > > materialLayersOrdered(const Layer *sLayer, const Layer *eLayer, const T &parameters, PropDirection pDir=alongMomentum, const BoundaryCheck &bchk=true, bool resolveSubSurfaces=false) const
Return the material layers ordered based on straight line intersections:
CylinderVolumeBounds.h
Trk::MaterialValidation::throwFailedToGetTrackingGeometry
void throwFailedToGetTrackingGeometry() const
Definition: MaterialValidation.cxx:294
Trk::VolumeExit::nVolume
const Trk::TrackingVolume * nVolume
Definition: MaterialValidation.h:39
Trk::MaterialValidation::m_materialMapper
ToolHandle< IMaterialMapper > m_materialMapper
Mapper and Inspector.
Definition: MaterialValidation.h:95
Trk::BoundarySurface::surfaceRepresentation
virtual const Surface & surfaceRepresentation() const =0
The Surface Representation of this.
Trk::MaterialValidation::execute
StatusCode execute()
standard Athena-Algorithm method
Definition: MaterialValidation.cxx:71
Amg::toString
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Definition: GeoPrimitivesToStringConverter.h:40
Trk::MaterialValidation::collectMaterialAndExit
PositionAtBoundary collectMaterialAndExit(const Trk::TrackingVolume &tvol, const Amg::Vector3D &position, const Amg::Vector3D &direction)
Definition: MaterialValidation.cxx:99
Trk::theta
@ theta
Definition: ParamDefs.h:72
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Trk::MaterialValidation::m_etaMax
double m_etaMax
eta boundary
Definition: MaterialValidation.h:101
Trk::Surface::materialLayer
const Trk::Layer * materialLayer() const
return the material Layer
Trk::CurvilinearParametersT
Definition: CurvilinearParametersT.h:48
IMaterialMapper.h
Trk::Intersection::position
Amg::Vector3D position
Definition: Intersection.h:25
AthAlgorithm
Definition: AthAlgorithm.h:47
Trk::AssociatedMaterial
Definition: AssociatedMaterial.h:33
Trk::CylinderVolumeBounds
Definition: CylinderVolumeBounds.h:70
Trk::TrackingVolume::volumeName
const std::string & volumeName() const
Returns the VolumeName - for debug reason, might be depreciated later.
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
Trk::CylinderVolumeBounds::outerRadius
double outerRadius() const
This method returns the outer radius.
Definition: CylinderVolumeBounds.h:191
Trk::BinnedArray::arrayObjects
virtual BinnedArraySpan< T *const > arrayObjects()=0
Return all objects of the Array non-const we can still modify the T.
Trk::TrackingVolume::boundarySurfacesOrdered
std::vector< BoundaryIntersection< T > > boundarySurfacesOrdered(const T &parameters, PropDirection pDir=alongMomentum, bool startOffBoundary=false) const
Returns the boundary surfaces ordered in probability to hit them based on straight line intersection.
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Trk::Intersection::valid
bool valid
Definition: Intersection.h:28
MaterialValidation.h
Trk::MaterialProperties
Definition: MaterialProperties.h:40
TrackingVolume.h
Trk::VolumeExit::vExit
Amg::Vector3D vExit
Definition: MaterialValidation.h:41
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Trk::Volume::volumeBounds
const VolumeBounds & volumeBounds() const
returns the volumeBounds()
Definition: Volume.h:97
Trk::SurfaceType::Cylinder
@ Cylinder
Trk::Layer::layerMaterialProperties
const LayerMaterialProperties * layerMaterialProperties() const
getting the LayerMaterialProperties including full/pre/post update
GeoPrimitivesToStringConverter.h
AssociatedMaterial.h
Trk::phi
@ phi
Definition: ParamDefs.h:81
Trk::BinnedArray
Definition: BinnedArray.h:38
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
Trk::Surface
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:75
Trk::TrackingVolume
Definition: TrackingVolume.h:121
Trk::BinnedArraySpan
std::span< T > BinnedArraySpan
Definition: BinnedArray.h:34
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
mag
Scalar mag() const
mag method
Definition: AmgMatrixBasePlugin.h:25
LayerMaterialProperties.h
Trk::Layer
Definition: Layer.h:73
Trk::PositionAtBoundary
std::pair< Amg::Vector3D, const Trk::TrackingVolume * > PositionAtBoundary
Definition: MaterialValidation.h:26
Trk::MaterialValidation::MaterialValidation
MaterialValidation(const std::string &name, ISvcLocator *pSvcLocator)
Standard Athena-Algorithm Constructor.
Definition: MaterialValidation.cxx:28