-
Notifications
You must be signed in to change notification settings - Fork 257
Expand file tree
/
Copy pathBinnedSurfaceMaterialAccumulator.cpp
More file actions
168 lines (152 loc) · 6.62 KB
/
Copy pathBinnedSurfaceMaterialAccumulator.cpp
File metadata and controls
168 lines (152 loc) · 6.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// This file is part of the ACTS project.
//
// Copyright (C) 2016 CERN for the benefit of the ACTS project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
#include "Acts/Material/BinnedSurfaceMaterialAccumulator.hpp"
#include "Acts/Geometry/GeometryContext.hpp"
#include "Acts/Material/BinnedSurfaceMaterial.hpp"
#include "Acts/Material/ProtoSurfaceMaterial.hpp"
#include "Acts/Surfaces/Surface.hpp"
#include "Acts/Utilities/BinAdjustment.hpp"
#include "Acts/Utilities/BinUtility.hpp"
Acts::BinnedSurfaceMaterialAccumulator::BinnedSurfaceMaterialAccumulator(
const Config& cfg, std::unique_ptr<const Logger> mlogger)
: m_cfg(cfg), m_logger(std::move(mlogger)) {}
std::unique_ptr<Acts::ISurfaceMaterialAccumulator::State>
Acts::BinnedSurfaceMaterialAccumulator::createState(
const GeometryContext& gctx) const {
auto state = std::make_unique<State>();
/// Create the surface accumulation
for (const auto& surface : m_cfg.materialSurfaces) {
GeometryIdentifier geoID = surface->geometryId();
// Get the Surface Material
const ISurfaceMaterial* surfaceMaterial = surface->surfaceMaterial();
if (surfaceMaterial == nullptr) {
throw std::invalid_argument(
"Surface material is not set, inconsistent configuration.");
}
// First attempt from ProtoSurfaceMaterial
auto psm = dynamic_cast<const ProtoSurfaceMaterial*>(surfaceMaterial);
if (psm != nullptr) {
auto binUtility = psm->binning();
// Screen output for Binned Surface material
ACTS_DEBUG(" - (proto) binning from ProtoSurfaceMateria is "
<< binUtility);
// Now adjust to surface type
binUtility = adjustBinUtility(binUtility, *surface, gctx);
// Screen output for Binned Surface material
ACTS_DEBUG(" - adjusted binning is " << binUtility);
state->accumulatedMaterial[geoID] =
AccumulatedSurfaceMaterial(binUtility);
// Material accumulation is created for this
continue;
}
// Second attempt from ProtoGridSurfaceMaterial
auto psgm = dynamic_cast<const ProtoGridSurfaceMaterial*>(surfaceMaterial);
if (psgm != nullptr) {
BinUtility binUtility(psgm->binning());
// Screen output for Binned Surface material
ACTS_DEBUG(" - (proto) binning from ProtoGridSurfaceMaterial is "
<< binUtility);
// Now adjust to surface type
binUtility = adjustBinUtility(binUtility, *surface, gctx);
// Screen output for Binned Surface material
ACTS_DEBUG(" - adjusted binning is " << binUtility);
state->accumulatedMaterial[geoID] =
AccumulatedSurfaceMaterial(binUtility);
// Material accumulation is created for this
continue;
}
// Third attempt: binned material
auto bmp = dynamic_cast<const BinnedSurfaceMaterial*>(surfaceMaterial);
if (bmp != nullptr) {
// Screen output for Binned Surface material
ACTS_DEBUG(" - binning from BinnedSurfaceMaterial is "
<< bmp->binUtility());
state->accumulatedMaterial[geoID] =
AccumulatedSurfaceMaterial(bmp->binUtility());
// Material accumulation is created for this
continue;
}
// Create a homogeneous type of material
ACTS_DEBUG(" - this is homogeneous material.");
state->accumulatedMaterial[geoID] = AccumulatedSurfaceMaterial();
}
return state;
}
void Acts::BinnedSurfaceMaterialAccumulator::accumulate(
ISurfaceMaterialAccumulator::State& state, const GeometryContext& /*gctx*/,
const std::vector<MaterialInteraction>& interactions,
const std::vector<IAssignmentFinder::SurfaceAssignment>&
surfacesWithoutAssignment) const {
// Cast into the right state object (guaranteed by upstream algorithm)
State* cState = static_cast<State*>(&state);
if (cState == nullptr) {
throw std::invalid_argument(
"Invalid state object provided, something is seriously wrong.");
}
using MapBin =
std::pair<AccumulatedSurfaceMaterial*, std::array<std::size_t, 3>>;
std::map<AccumulatedSurfaceMaterial*, std::array<std::size_t, 3>>
touchedMapBins;
// Assign the hits
for (const auto& mi : interactions) {
// Get the surface
const Surface* surface = mi.surface;
GeometryIdentifier geoID = surface->geometryId();
// Get the accumulated material
auto accMaterial = cState->accumulatedMaterial.find(geoID);
if (accMaterial == cState->accumulatedMaterial.end()) {
throw std::invalid_argument(
"Surface material is not found, inconsistent configuration.");
}
// Accumulate the material - remember the touched bin
auto tBin = accMaterial->second.accumulate(mi.intersection, mi.materialSlab,
mi.pathCorrection);
touchedMapBins.insert(MapBin(&(accMaterial->second), tBin));
}
// After mapping this track, average the touched bins
for (const auto& [key, value] : touchedMapBins) {
std::vector<std::array<std::size_t, 3>> trackBins = {value};
key->trackAverage(trackBins, true);
}
// Empty bin correction
if (m_cfg.emptyBinCorrection) {
for (const auto& [surface, position, direction] :
surfacesWithoutAssignment) {
// Get the accumulated material
auto missedMaterial =
cState->accumulatedMaterial.find(surface->geometryId());
if (missedMaterial == cState->accumulatedMaterial.end()) {
throw std::invalid_argument(
"Surface material is not found, inconsistent configuration.");
}
// Apply empty hit correction
missedMaterial->second.trackAverage(position, true);
}
}
}
std::map<Acts::GeometryIdentifier,
std::shared_ptr<const Acts::ISurfaceMaterial>>
Acts::BinnedSurfaceMaterialAccumulator::finalizeMaterial(
ISurfaceMaterialAccumulator::State& state,
const GeometryContext& /*gctx*/) const {
std::map<GeometryIdentifier, std::shared_ptr<const ISurfaceMaterial>>
sMaterials;
// Cast into the right state object (guaranteed by upstream algorithm)
State* cState = static_cast<State*>(&state);
if (cState == nullptr) {
throw std::invalid_argument(
"Invalid state object provided, something is seriously wrong.");
}
// iterate over the map to call the total average
for (auto& accMaterial : cState->accumulatedMaterial) {
ACTS_DEBUG("Finalizing map for Surface " << accMaterial.first);
auto sMaterial = accMaterial.second.totalAverage(m_cfg.recordBinCounts);
sMaterials[accMaterial.first] = std::move(sMaterial);
}
return sMaterials;
}