103{
104
105 std::map<double, Trk::AssociatedMaterial> collectedMaterial;
106
107
109
111
113
115
117
118 for (auto& lCandidate : layerIntersections ) {
119
120 const Trk::Layer*
layer = lCandidate.object;
121 double pathLength = lCandidate.intersection.pathLength;
122
123 if (
layer->layerMaterialProperties()){
124
125 const Trk::MaterialProperties* mprop =
layer->layerMaterialProperties()->fullMaterial(lCandidate.intersection.position);
126 if (mprop){
127 double stepLength = mprop->
thickness()*fabs(
layer->surfaceRepresentation().pathCorrection(lCandidate.intersection.position,direction));
128 collectedMaterial[pathLength] = Trk::AssociatedMaterial(lCandidate.intersection.position, mprop, stepLength, &tvol, layer);
129 }
130 }
131 }
132
133 Amg::Vector3D lastPosition = !collectedMaterial.empty() ? collectedMaterial.rbegin()->second.materialPosition() : (position + direction.unit());
135
137 if (!boundaryIntersections.empty()){
138
139 lastPosition = boundaryIntersections.begin()->intersection.position;
140 const Trk::BoundarySurface<Trk::TrackingVolume>* bSurfaceTV = boundaryIntersections.begin()->object;
142
145 double pathLength = (lastPosition-position).
mag();
146 if (mprop){
148 collectedMaterial[pathLength] = Trk::AssociatedMaterial(lastPosition, mprop, stepLength, &tvol, bSurface.
materialLayer());
149 } else
150 collectedMaterial[pathLength] = Trk::AssociatedMaterial(lastPosition, &tvol, bSurface.
materialLayer());
151 }
152
155 } else
157 } else {
158 std::map<double, std::pair<const Trk::Layer*, Amg::Vector3D> > intersectedLayers;
159
160
162 if (layerArray) {
163
165 auto layIter =
layers.begin();
166 auto layIterE =
layers.end();
167 for ( ; layIter != layIterE; ++layIter){
168 if ( (*layIter)->layerMaterialProperties() ){
169 Trk::Intersection lsIntersection = (*layIter)->surfaceRepresentation().straightLineIntersection(position, direction, true, true);
170 if (lsIntersection.
valid){
171 intersectedLayers[lsIntersection.
pathLength] = std::pair<const Trk::Layer*, Amg::Vector3D>(*layIter,lsIntersection.
position);
172
173
174 Amg::Vector3D mposition = (*layIter)->surfaceRepresentation().transform().inverse()*lsIntersection.
position;
175 const Trk::MaterialProperties* mprop = (*layIter)->layerMaterialProperties()->fullMaterial(mposition);
176 if (mprop) {
177 double stepLength = mprop->
thickness()*fabs((*layIter)->surfaceRepresentation().pathCorrection(lsIntersection.
position,direction));
178 collectedMaterial[lsIntersection.
pathLength] = Trk::AssociatedMaterial(lsIntersection.
position, mprop, stepLength, &tvol, (*layIter));
179 } else
180 collectedMaterial[lsIntersection.
pathLength] = Trk::AssociatedMaterial(lsIntersection.
position, &tvol, (*layIter));
181
183 if (mprop)
185 else
187 }
188 }
189 }
190 }
191
192
193
194
195 Amg::Vector3D lastPosition = !intersectedLayers.empty() ? (*(--(intersectedLayers.end()))).second.second : position;
196
197 std::map<double, Trk::VolumeExit > volumeExits;
198
200 for (
size_t ib = 0;
ib < bSurfaces.size(); ++
ib){
201
202 if ( !bSurfaces[ib]->surfaceRepresentation().isOnSurface(lastPosition, true, 0.1, 0.1) ){
203 Trk::Intersection evIntersection = bSurfaces[
ib]->surfaceRepresentation().straightLineIntersection(lastPosition, direction,
true,
true);
206 if (evIntersection.
valid){
207
209
210 volumeExits[evIntersection.
pathLength] = Trk::VolumeExit(naVolume, &(bSurfaces[ib]->surfaceRepresentation()), evIntersection.
position);
211
213 }
214 } else
216 }
217
218 if (!volumeExits.empty()){
219
220 VolumeExit closestVolumeExit = (*volumeExits.begin()).second;
221
222 const Trk::Surface* bSurface = closestVolumeExit.bSurface;
224 ATH_MSG_VERBOSE(
"[>>>>] The boundary surface has an associated layer, collect material from there");
226 double pathToExit = (closestVolumeExit.vExit-lastPosition).
mag();
227 if (mprop){
229 collectedMaterial[pathToExit] = Trk::AssociatedMaterial(closestVolumeExit.vExit, mprop, stepLength, &tvol, bSurface->
materialLayer());
230 } else
231 collectedMaterial[pathToExit] = Trk::AssociatedMaterial(closestVolumeExit.vExit, &tvol, bSurface->
materialLayer());
232 }
233
234 if (closestVolumeExit.nVolume != &tvol && closestVolumeExit.nVolume) {
235 ATH_MSG_VERBOSE(
"[>>>>] Next Volume: " << closestVolumeExit.nVolume->volumeName() <<
" - at " <<
Amg::toString(closestVolumeExit.vExit) );
236
238 }
239 } else {
240 ATH_MSG_VERBOSE(
"[>>>>] No exit found from Volume '" << tvol.
volumeName() <<
"' - starting radius = " << lastPosition.perp() );
241 const Trk::CylinderVolumeBounds* cvb =
dynamic_cast<const Trk::CylinderVolumeBounds*
>(&(tvol.
volumeBounds()));
242 if (cvb)
244 }
245
246 }
247
248 ATH_MSG_DEBUG(
"[>>>] Collecting materials from "<< collectedMaterial.size() <<
" layers");
249
250 auto cmIter = collectedMaterial.begin();
251 auto cmIterE = collectedMaterial.end();
252 for ( ; cmIter != cmIterE; ++cmIter ){
253 m_materialMapper->recordMaterialHit(cmIter->second, cmIter->second.materialPosition());
254 m_accTinX0 += cmIter->second.steplengthInX0();
255 int layerIndex = cmIter->second.associatedLayer() ? cmIter->second.associatedLayer()->layerIndex().value() : 0;
256 ATH_MSG_DEBUG(
"[>>>] Accumulate pathLength/X0 on layer with index " << layerIndex <<
" - t/X0 (total so far) = " << cmIter->second.steplengthInX0() <<
" (" <<
m_accTinX0 <<
")");
257 if (layerIndex){
258 std::string surfaceType =
259 cmIter->second.associatedLayer()->surfaceRepresentation().type() ==
261 ? "Cylinder at radius = "
262 : "Disc at z-position = ";
263 std::string layerType =
264 cmIter->second.associatedLayer()->surfaceArray() ? "Active "
265 : "Passive ";
267 cmIter->second.associatedLayer()->surfaceRepresentation().type() ==
269 ? cmIter->second.associatedLayer()
270 ->surfaceRepresentation()
271 .bounds()
272 .r()
273 : cmIter->second.associatedLayer()
274 ->surfaceRepresentation()
275 .center()
276 .z();
278 }
279 ATH_MSG_DEBUG(
" Distance to origin is " << cmIter->second.materialPosition().mag() );
280 }
281
282
283 return pab;
284
285}
Scalar mag() const
mag method
#define ATH_MSG_VERBOSE(x)
virtual std::span< T *const > arrayObjects()=0
Return all objects of the Array non-const we can still modify the T.
virtual const Tvol * attachedVolume(const TrackParameters &parms, PropDirection dir) const =0
Get the next Volume depending on the TrackParameters and the requested direction.
virtual const Surface & surfaceRepresentation() const =0
The Surface Representation of this.
double outerRadius() const
This method returns the outer radius.
virtual const MaterialProperties * fullMaterial(const Amg::Vector3D &gp) const =0
Return method for full material description of the Layer.
const LayerMaterialProperties * layerMaterialProperties() const
getting the LayerMaterialProperties including full/pre/post update
float thickness() const
Return the thickness in mm.
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...
const Trk::MaterialLayer * materialLayer() const
return the material Layer
const LayerArray * confinedLayers() const
Return the subLayer array.
std::vector< LayerIntersection< T > > materialLayersOrdered(const Layer *sLayer, const Layer *eLayer, const T ¶meters, PropDirection pDir=alongMomentum, const BoundaryCheck &bchk=true, bool resolveSubSurfaces=false) const
Return the material layers ordered based on straight line intersections:
std::vector< std::shared_ptr< BoundarySurface< TrackingVolume > > > & boundarySurfaces()
Method to return the BoundarySurfaces.
const std::string & volumeName() const
Returns the VolumeName - for debug reason, might be depreciated later.
std::vector< BoundaryIntersection< T > > boundarySurfacesOrdered(const T ¶meters, PropDirection pDir=alongMomentum, bool startOffBoundary=false) const
Returns the boundary surfaces ordered in probability to hit them based on straight line intersection.
const VolumeBounds & volumeBounds() const
returns the volumeBounds()
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Matrix< double, 3, 1 > Vector3D
layers(flags, cells_name, *args, **kw)
Here we define wrapper functions to set up all of the standard corrections.
BinnedArray< Layer > LayerArray
simply for the eye
std::pair< Amg::Vector3D, const Trk::TrackingVolume * > PositionAtBoundary
CurvilinearParametersT< NeutralParametersDim, Neutral, PlaneSurface > NeutralCurvilinearParameters