ATLAS Offline Software
Loading...
Searching...
No Matches
LayerMaterialRecord.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
6// LayerMaterialRecord.cxx, (c) ATLAS Detector software
8
10
11#include <climits>
12
17#include "TrkGeometry/Layer.h"
21#include "TrkSurfaces/Surface.h"
23
25 : m_layerThickness(0.),
26 m_binUtility(nullptr),
27 m_bins0(0),
28 m_bins1(0),
29 m_minFraction(0.),
30 m_steps(0),
31 m_pos(Amg::Vector3D(0., 0., 0.)),
32 m_emptyHitCase(false),
33 m_s(0.),
34 m_s_in_x0(0.),
35 m_s_in_l0(0.),
36 m_a(0.),
37 m_z(0.),
38 m_rho(0.),
40 // m_pos = Amg::Vector3D(0.,0.,0.);
41}
42
44 double thickness, const BinUtility* binutils, double minfraction,
46 : m_layerThickness(thickness),
47 m_binUtility(binutils ? binutils->clone() : nullptr),
48 m_bins0(binutils ? (binutils->max(0) + 1) : 1),
49 m_bins1(binutils && binutils->dimensions() > 1 ? (binutils->max(1) + 1)
50 : 1),
51 m_minFraction(minfraction),
52 m_steps(0),
53 m_pos(Amg::Vector3D(0., 0., 0.)),
54 m_emptyHitCase(false),
55 m_s(0.),
56 m_s_in_x0(0.),
57 m_s_in_l0(0.),
58 m_a(0.),
59 m_z(0.),
60 m_rho(0.),
61 m_assoc(assoc) {
62 // initialize for the run
63 const auto zeroedVectorDbl = std::vector<double>(m_bins0, 0.);
64 const auto zeroedVectorUInt = std::vector<unsigned int>(m_bins0, 0);
65 const auto zeroedVectorVector3D = std::vector<Amg::Vector3D>(m_bins0, m_pos);
66 using Element_t = std::map<unsigned int, double>;
67 const auto zeroedVectorElements =
68 std::vector<Element_t>(m_bins0, Element_t());
69 for (int ibin = 0; ibin < m_bins1; ++ibin) {
70 // run-related parameters
71 m_run_pos.push_back(zeroedVectorVector3D);
72 m_run_events.push_back(zeroedVectorUInt);
73 m_run_s.push_back(zeroedVectorDbl);
74 m_run_s_in_x0.push_back(zeroedVectorDbl);
75 m_run_s_in_l0.push_back(zeroedVectorDbl);
76 m_run_a.push_back(zeroedVectorDbl);
77 m_run_z.push_back(zeroedVectorDbl);
78 m_run_rho.push_back(zeroedVectorDbl);
79 m_run_elements.push_back(zeroedVectorElements);
80 }
81}
82
112
114 const Trk::LayerMaterialRecord& lmr) {
115 if (this != &lmr) {
117 delete m_binUtility;
118 m_binUtility = lmr.m_binUtility ? lmr.m_binUtility->clone() : nullptr;
119 m_bins0 = lmr.m_bins0;
120 m_bins1 = lmr.m_bins1;
122 m_assoc = lmr.m_assoc;
123 m_steps = lmr.m_steps;
124 m_pos = lmr.m_pos;
126 m_s = lmr.m_s;
127 m_s_in_x0 = lmr.m_s_in_x0;
128 m_s_in_l0 = lmr.m_s_in_l0;
129 m_a = lmr.m_a;
130 m_z = lmr.m_z;
131 m_rho = lmr.m_rho;
134 m_run_s = lmr.m_run_s;
137 m_run_pos = lmr.m_run_pos;
138 m_run_a = lmr.m_run_a;
139 m_run_z = lmr.m_run_z;
140 m_run_rho = lmr.m_run_rho;
142 // deal with the material
145 }
146 return (*this);
147}
148
150 // don't delete the material -> its given to the outside world
151 delete m_binUtility;
152}
153
155 double s,
156 const Trk::Material& mat) {
157 m_steps++;
158
159 m_s += s;
160 // path association method
161 m_pos += pos;
162 // path lenght updates
163 m_s_in_x0 += s / mat.X0;
164 m_s_in_l0 += s / mat.L0;
165 // effective rho, A, Z weithed by pathlength through it
166 m_rho += mat.rho * s;
167 m_a += mat.A * s * mat.rho;
168 m_z += mat.Z * s * mat.rho;
169
170 // record the composition - since this is mainly for hadronic interactions :
171 // weight by s/L0
172 MaterialComposition* mComposition = mat.composition;
173 if (mComposition) {
174 for (auto& it : (*mComposition)) {
175 // element identification
176 unsigned int Z = uchar2uint(it.first);
177 double fraction = uchar2dfrac(it.second);
178 // record the elements, let's weight the fractions in s/mat.L0
179 auto eIter = m_elements.find(Z);
180 if (eIter == m_elements.end())
181 m_elements[Z] = fraction * s / mat.L0;
182 else
183 m_elements[Z] += fraction * s / mat.L0;
184 }
185 }
186}
187
189 // just remember that you had an empty hit
190 m_emptyHitCase = true;
191 // take the position to increase the event counter by one
192 m_pos = pos;
193}
194
196 const Trk::Layer& lay, bool fullHit) {
197 Trk::AssociatedMaterial* fullHitMaterial = nullptr;
198 // empty hit scaling
199 if (m_emptyHitCase) {
200 // averge the hit positions
201 int rBin0 = m_binUtility ? m_binUtility->bin(m_pos, 0) : 0;
202 int rBin1 = (m_binUtility && m_binUtility->dimensions() > 1)
203 ? m_binUtility->bin(m_pos, 1)
204 : 0;
205 // simply increas the event counter
206 m_run_events[rBin1][rBin0]++;
207 // material hit collection
208 } else if (m_steps) {
209 // only if there was a single step in the event
210 Amg::Vector3D hitPosition(m_pos * 1. / (m_steps));
211 // get the correction factor depending on the layer type
212 double corrFactorInv = fabs(1. / lay.surfaceRepresentation().pathCorrection(
213 hitPosition, hitPosition));
214 // averge the hit positions
215 int rBin0 = m_binUtility ? m_binUtility->bin(hitPosition, 0) : 0;
216 int rBin1 = (m_binUtility && m_binUtility->dimensions() > 1)
217 ? m_binUtility->bin(hitPosition, 1)
218 : 0;
219
220 // event averaging
221 m_run_events[rBin1][rBin0]++;
222 m_run_s[rBin1][rBin0] += m_s;
223 m_run_pos[rBin1][rBin0] += hitPosition;
224 m_run_s_in_x0[rBin1][rBin0] += m_s_in_x0 * corrFactorInv;
225 m_run_s_in_l0[rBin1][rBin0] += m_s_in_l0 * corrFactorInv;
226 // a & z are normalised to rho
227 m_run_a[rBin1][rBin0] += m_a / m_rho;
228 m_run_z[rBin1][rBin0] += m_z / m_rho;
229 // rho is normalised to the layer thickness times corection factor
230 m_run_rho[rBin1][rBin0] += m_rho * corrFactorInv / m_layerThickness; // ST
231
232 // add to the run element table
233 for (auto& eIter : m_elements) {
234 // first normalize the element fraction
235 double nef = eIter.second * corrFactorInv / m_s_in_l0;
236 if (m_run_elements[rBin1][rBin0].find(eIter.first) ==
237 m_run_elements[rBin1][rBin0].end())
238 m_run_elements[rBin1][rBin0][eIter.first] = nef;
239 else
240 m_run_elements[rBin1][rBin0][eIter.first] += nef;
241 }
242
243 // just for validation purpose
244 if (fullHit) {
245 // average the material for the per event validation
246 double eventNorm = 1. / double(m_run_events[rBin1][rBin0]);
247
248 // normalize the value by number of recorded events - each event counts
249 // the same
250 double a = m_run_a[rBin1][rBin0] * eventNorm;
251 double z = m_run_z[rBin1][rBin0] * eventNorm;
252 double rho = m_run_rho[rBin1][rBin0] * eventNorm;
253
254 // the average s/X0 and s/L0 is the average over all events corrected by
255 // the incident angle
256 double s_in_x0 = m_run_s_in_x0[rBin1][rBin0] * eventNorm;
257 double s_in_l0 = m_run_s_in_l0[rBin1][rBin0] * eventNorm;
258
259 // condense to the layer thickness
260 double x0 = m_layerThickness / s_in_x0;
261 double l0 = m_layerThickness / s_in_l0;
262
264 fullHitMaterial = new Trk::AssociatedMaterial(
265 hitPosition, m_run_s[rBin1][rBin0] * eventNorm, x0, l0, a, z, rho,
266 corrFactorInv, lay.enclosingTrackingVolume(), &lay);
267 }
268 }
269
270 // reset event variables
271 m_emptyHitCase = false;
272 m_steps = 0;
273 m_pos = Amg::Vector3D(0., 0., 0.);
274 m_s = 0.;
275 m_s_in_x0 = 0.;
276 m_s_in_l0 = 0.;
277 m_a = 0.;
278 m_z = 0.;
279 m_rho = 0.;
280 m_elements.clear();
281
282 return fullHitMaterial;
283}
284
285void Trk::LayerMaterialRecord::finalizeRun(bool recordElements) {
287
288 for (int ibin1 = 0; ibin1 < m_bins1; ++ibin1) {
289 // create the vector first
291 matVector.reserve(m_bins0);
292 // loop over local 1 bins
293 for (int ibin0 = 0; ibin0 < m_bins0; ++ibin0) {
294 Trk::MaterialProperties* binMaterial = nullptr;
295 if (m_run_events[ibin1][ibin0]) {
296 // The event norm
297 double eventNorm = 1. / double(m_run_events[ibin1][ibin0]);
298
299 // normalize the value by number of recorded events - each event counts
300 // the same
301 m_run_a[ibin1][ibin0] *= eventNorm;
302 m_run_z[ibin1][ibin0] *= eventNorm;
303 m_run_rho[ibin1][ibin0] *= eventNorm;
304
305 // the average s/X0 and s/L0 is the average over all events corrected by
306 // the incident angle
307 m_run_s_in_x0[ibin1][ibin0] *= eventNorm;
308 m_run_s_in_l0[ibin1][ibin0] *= eventNorm;
309
310 // condense to the layer thickness
311 double x0 = m_layerThickness / m_run_s_in_x0[ibin1][ibin0];
312 double l0 = m_layerThickness / m_run_s_in_l0[ibin1][ibin0];
313
314 // prepare the material composition
315 Trk::MaterialComposition* matComposition = nullptr;
316 if (recordElements) {
317 // pre-loop to get a sample
318 double preTotalFraction = 0.;
319 std::map<unsigned int, double> binElements =
320 m_run_elements[ibin1][ibin0];
321 for (auto& peIter : binElements) {
322 // normalize the fraction to the number of events
323 peIter.second *= eventNorm;
324 preTotalFraction += peIter.second;
325 }
326 // first loop to sort rescale
327 std::map<double, unsigned int> probabilityOrdered;
328 double totalFraction = 0.;
329 for (auto& eIter : binElements) {
330 // get the fraction
331 double eFraction = eIter.second / preTotalFraction;
332 if (eFraction < m_minFraction) continue;
333 probabilityOrdered[eIter.second] = eIter.first;
334 totalFraction += eIter.second;
335 }
336 // second loop to fill the element fractions
337 std::vector<Trk::ElementFraction> elementFractions;
338 elementFractions.reserve(binElements.size());
339 for (auto& poEl : probabilityOrdered) {
340 double fracEl = poEl.first / totalFraction;
341 unsigned int fracEluChar = fracEl * UCHAR_MAX;
342 elementFractions.emplace_back(poEl.second, fracEluChar);
343 }
344 // reverse the order to have the one with the highest fraction first
345 std::reverse(elementFractions.begin(), elementFractions.end());
346 matComposition = new Trk::MaterialComposition(elementFractions);
347 }
348
349 Trk::Material material(x0, l0, m_run_a[ibin1][ibin0],
350 m_run_z[ibin1][ibin0], m_run_rho[ibin1][ibin0],
351 0., matComposition);
352
353 binMaterial = new Trk::MaterialProperties(material, m_layerThickness);
354 }
355 matVector.push_back(binMaterial);
356 }
357 m_associatedLayerMaterial.push_back(matVector);
358 }
359}
360
362 Trk::MaterialPropertiesMatrix::iterator matMatrixIter =
364 Trk::MaterialPropertiesMatrix::iterator matMatrixIterEnd =
366 for (; matMatrixIter != matMatrixIterEnd; ++matMatrixIter) {
367 // loop over the subsets
368 std::vector<const Trk::MaterialProperties*>::iterator matIter =
369 (*matMatrixIter).begin();
370 std::vector<const Trk::MaterialProperties*>::iterator matIterEnd =
371 (*matMatrixIter).end();
372 for (; matIter != matIterEnd; ++matIter) delete (*matIter);
373 }
375}
376
378 const MaterialPropertiesMatrix& materialMatrix) {
379 // clear the vector
381
382 Trk::MaterialPropertiesMatrix::const_iterator matMatrixIter =
383 materialMatrix.begin();
384 Trk::MaterialPropertiesMatrix::const_iterator matMatrixIterEnd =
385 materialMatrix.end();
386 for (; matMatrixIter != matMatrixIterEnd; ++matMatrixIter) {
388 // loop over the subsets
389 std::vector<const Trk::MaterialProperties*>::const_iterator matIter =
390 (*matMatrixIter).begin();
391 std::vector<const Trk::MaterialProperties*>::const_iterator matIterEnd =
392 (*matMatrixIter).end();
393 for (; matIter != matIterEnd; ++matIter) {
394 // test it
395 matProp.push_back(((*matIter) ? (*matIter)->clone() : nullptr));
396 }
397 // and now push back the vector
398 m_associatedLayerMaterial.push_back(matProp);
399 }
400}
static Double_t a
#define uchar2uint(uchar)
#define uchar2dfrac(uchar)
Eigen::Matrix< double, 3, 1 > Vector3D
#define max(a, b)
Definition cfImp.cxx:41
It is used in the Mapping process ( using MaterialSteps ), the validation and recostruction ( using M...
A generic symmetric BinUtility, for fully symmetric binning in terms of binning grid and binning type...
Definition BinUtility.h:39
BinUtility * clone() const
Implizit Constructor.
Definition BinUtility.h:120
Helper Class to record the material during the GeantinoNtupleMappingProcess.
int m_bins1
number of bins in coordinate 2
std::vector< std::vector< unsigned int > > m_run_events
LayerMaterialRecord()
Default Constructor.
std::vector< std::vector< double > > m_run_s_in_x0
double m_layerThickness
record the layerThickness
std::vector< std::vector< double > > m_run_s
LayerMaterialRecord & operator=(const LayerMaterialRecord &lmr)
Assignment operator.
std::map< unsigned int, double > m_elements
Amg::Vector3D m_pos
event related information
std::vector< std::vector< double > > m_run_a
MaterialAssociationType m_assoc
type of hit association
void finalizeRun(bool recordElements=true)
finalize the Run
AssociatedMaterial * finalizeEvent(const Trk::Layer &lay, bool fullHit=false)
finalize the Event
std::vector< std::vector< Amg::Vector3D > > m_run_pos
MaterialPropertiesMatrix m_associatedLayerMaterial
clear the material -> calls delete
BinUtility * m_binUtility
record the BinnedArray
std::vector< std::vector< std::map< unsigned int, double > > > m_run_elements
the final material properties
void clearMaterial()
copy from another vector
void associateGeantinoHit(const Amg::Vector3D &pos, double s, const Trk::Material &mat)
adding the information about the Geantino hit
void copyMaterial(const MaterialPropertiesMatrix &mat)
void associateEmptyHit(const Amg::Vector3D &pos)
adding the information about an empty hit scaling- particle crossed layer, but no mapping information
std::vector< std::vector< double > > m_run_s_in_l0
std::vector< std::vector< double > > m_run_z
double m_minFraction
minimum element fraction to be recorded
int m_bins0
number of bins in coordinate 1
std::vector< std::vector< double > > m_run_rho
Base Class for a Detector Layer in the Tracking realm.
Definition Layer.h:72
virtual const Surface & surfaceRepresentation() const =0
Transforms the layer into a Surface representation for extrapolation.
const TrackingVolume * enclosingTrackingVolume() const
get the confining TrackingVolume
Material with information about thickness of material.
A common object to be contained by.
Definition Material.h:117
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...
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138
Definition of ATLAS Math & Geometry primitives (Amg)
Eigen::Matrix< double, 3, 1 > Vector3D
Ensure that the ATLAS eigen extensions are properly loaded.
@ z
global position (cartesian)
Definition ParamDefs.h:57
std::vector< const MaterialProperties * > MaterialPropertiesVector
Useful typedefs.
std::vector< std::vector< const MaterialProperties * > > MaterialPropertiesMatrix
void reverse(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of reverse for DataVector/List.