44 struct EndOfWorldReached;
49 std::unique_ptr<const Logger> slogger)
51 m_propagator(std::
move(propagator)),
61 State mState(gctx, mctx);
62 resolveMaterialSurfaces(mState, *world);
63 collectMaterialVolumes(mState, *world);
66 <<
" Surfaces with PROXIES collected ... ");
76 <<
"' for material surfaces.")
81 checkAndInsert(mState, bSurface->surfaceRepresentation());
91 checkAndInsert(mState, cLayer->surfaceRepresentation());
93 if (cLayer->approachDescriptor() !=
nullptr) {
95 cLayer->approachDescriptor()->containedSurfaces()) {
96 if (aSurface !=
nullptr) {
97 checkAndInsert(mState, *aSurface);
102 if (cLayer->surfaceArray() !=
nullptr) {
104 for (
auto& sSurface : cLayer->surfaceArray()->surfaces()) {
105 if (sSurface !=
nullptr) {
106 checkAndInsert(mState, *sSurface);
117 resolveMaterialSurfaces(mState, *sVolume);
126 if (surfaceMaterial !=
nullptr) {
127 if (
m_cfg.computeVariance) {
132 size_t volumeID = geoID.
volume();
133 ACTS_DEBUG(
"Material surface found with volumeID " << volumeID);
141 const BinUtility* bu = (psm !=
nullptr) ? (&psm->binUtility()) :
nullptr;
148 ACTS_DEBUG(
" - adjusted binning is " << buAdjusted);
156 bu = (bmp !=
nullptr) ? (&bmp->binUtility()) :
nullptr;
164 ACTS_DEBUG(
" - this is homogeneous material.");
173 <<
"' for material surfaces.")
185 collectMaterialVolumes(mState, *sVolume);
191 collectMaterialVolumes(mState, *sVolume);
199 ACTS_DEBUG(
"Finalizing map for Surface " << accMaterial.first);
201 accMaterial.second.totalAverage();
208 auto& rMaterial = mTrack.second.materialInteractions;
210 <<
" recorded material steps to map.")
216 "Material surfaces are associated with the material interaction. The "
217 "association interaction/surfaces won't be performed again.");
218 mapSurfaceInteraction(mState, rMaterial);
222 "Material interactions need to be associated with surfaces. Collecting "
223 "all surfaces on the trajectory.");
224 mapInteraction(mState, mTrack);
231 auto& rMaterial = mTrack.second.materialInteractions;
232 std::map<GeometryIdentifier, unsigned int> assignedMaterial;
236 makeVector4(mTrack.first.first, 0), mTrack.first.second,
237 1 / mTrack.first.second.norm(), std::nullopt,
238 NeutralParticleHypothesis::geantino());
244 ActionList<MaterialSurfaceCollector, MaterialVolumeCollector>;
245 using AbortList = AbortList<EndOfWorldReached>;
251 const auto& result = m_propagator.propagate(
start, options).value();
252 auto mcResult = result.get<MaterialSurfaceCollector::result_type>();
253 auto mvcResult = result.get<MaterialVolumeCollector::result_type>();
255 auto mappingSurfaces = mcResult.collected;
256 auto mappingVolumes = mvcResult.collected;
260 <<
" mapping surfaces for this track.");
262 for (
auto&
mSurface : mappingSurfaces) {
264 <<
" at position = (" <<
mSurface.position.x()
265 <<
", " <<
mSurface.position.y() <<
", "
267 assignedMaterial[
mSurface.surface->geometryId()] = 0;
275 auto rmIter = rMaterial.begin();
276 auto sfIter = mappingSurfaces.begin();
277 auto volIter = mappingVolumes.begin();
283 float currentPathCorrection = 1.;
287 using MapBin = std::pair<AccumulatedSurfaceMaterial*, std::array<size_t, 3>>;
289 std::shared_ptr<const ISurfaceMaterial>>;
290 std::map<AccumulatedSurfaceMaterial*, std::array<size_t, 3>> touchedMapBins;
291 std::map<AccumulatedSurfaceMaterial*, std::shared_ptr<const ISurfaceMaterial>>
293 if (sfIter != mappingSurfaces.end() &&
294 sfIter->surface->surfaceMaterial()->mappingType() ==
297 "The first mapping surface is a PostMapping one. Some material from "
298 "before the PostMapping surface will be mapped onto it ");
302 while (rmIter != rMaterial.end() && sfIter != mappingSurfaces.end()) {
304 if (volIter != mappingVolumes.end() &&
305 !volIter->volume->inside(rmIter->position)) {
306 double distVol = (volIter->position - mTrack.first.first).
norm();
307 double distMat = (rmIter->position - mTrack.first.first).
norm();
316 if (volIter != mappingVolumes.end() &&
317 volIter->volume->inside(rmIter->position)) {
322 if (sfIter != mappingSurfaces.end() - 1) {
323 int mappingType = sfIter->surface->surfaceMaterial()->mappingType();
324 int nextMappingType =
325 (sfIter + 1)->
surface->surfaceMaterial()->mappingType();
330 if ((rmIter->position - mTrack.first.first).norm() >
331 (sfIter->position - mTrack.first.first).
norm()) {
334 "PreMapping or Sensor surface followed by PostMapping. Some "
336 "from before the PostMapping surface will be mapped onto it");
343 switch (nextMappingType) {
347 if ((rmIter->position - sfIter->position).norm() >
348 (rmIter->position - (sfIter + 1)->
position).norm()) {
356 if ((rmIter->position - sfIter->position).norm() >
357 ((sfIter + 1)->
position - sfIter->position).norm()) {
365 if ((rmIter == rMaterial.end() - 1) ||
366 ((rmIter + 1)->position - sfIter->position).
norm() >
367 ((sfIter + 1)->
position - sfIter->position).norm()) {
374 ACTS_ERROR(
"Incorrect mapping type for the next surface : "
375 << (sfIter + 1)->
surface->geometryId());
379 ACTS_ERROR(
"Incorrect mapping type for surface : "
380 << sfIter->surface->geometryId());
385 currentID = sfIter->surface->geometryId();
387 if (not(currentID == lastID)) {
391 currentPathCorrection = sfIter->surface->pathCorrection(
392 mState.
geoContext, currentPos, sfIter->direction);
396 auto tBin = currentAccMaterial->second.accumulate(
397 currentPos, rmIter->materialSlab, currentPathCorrection);
398 if (touchedMapBins.find(&(currentAccMaterial->second)) ==
399 touchedMapBins.end()) {
400 touchedMapBins.insert(MapBin(&(currentAccMaterial->second), tBin));
402 if (
m_cfg.computeVariance) {
403 touchedMaterialBin[&(currentAccMaterial->second)] =
406 ++assignedMaterial[currentID];
409 rmIter->surface = sfIter->surface;
410 rmIter->intersection = sfIter->position;
411 rmIter->intersectionID = currentID;
412 rmIter->pathCorrection = currentPathCorrection;
417 ACTS_VERBOSE(
"Surfaces have following number of assigned hits :")
418 for (
auto& [key,
value] : assignedMaterial) {
423 for (
auto tmapBin : touchedMapBins) {
424 std::vector<std::array<size_t, 3>> trackBins = {tmapBin.second};
425 if (
m_cfg.computeVariance) {
426 tmapBin.first->trackVariance(
427 trackBins, touchedMaterialBin[tmapBin.first]->materialSlab(
428 trackBins[0][0], trackBins[0][1]));
430 tmapBin.first->trackAverage(trackBins);
434 if (
m_cfg.emptyBinCorrection) {
438 for (
auto&
mSurface : mappingSurfaces) {
439 auto mgID =
mSurface.surface->geometryId();
442 if (assignedMaterial[mgID] == 0) {
444 if (
m_cfg.computeVariance) {
445 missedMaterial->second.trackVariance(
451 missedMaterial->second.trackAverage(
mSurface.position,
true);
458 rMaterial.push_back(noMaterial);
465 State& mState, std::vector<MaterialInteraction>& rMaterial)
const {
466 using MapBin = std::pair<AccumulatedSurfaceMaterial*, std::array<size_t, 3>>;
467 std::map<AccumulatedSurfaceMaterial*, std::array<size_t, 3>> touchedMapBins;
468 std::map<AccumulatedSurfaceMaterial*, std::shared_ptr<const ISurfaceMaterial>>
472 auto rmIter = rMaterial.begin();
473 while (rmIter != rMaterial.end()) {
476 Vector3 currentPos = rmIter->intersection;
480 auto tBin = currentAccMaterial->second.accumulate(
481 currentPos, rmIter->materialSlab, rmIter->pathCorrection);
482 if (touchedMapBins.find(&(currentAccMaterial->second)) ==
483 touchedMapBins.end()) {
484 touchedMapBins.insert(MapBin(&(currentAccMaterial->second), tBin));
486 if (
m_cfg.computeVariance) {
487 touchedMaterialBin[&(currentAccMaterial->second)] =
494 for (
auto tmapBin : touchedMapBins) {
495 std::vector<std::array<size_t, 3>> trackBins = {tmapBin.second};
496 if (
m_cfg.computeVariance) {
497 tmapBin.first->trackVariance(
499 touchedMaterialBin[tmapBin.first]->materialSlab(trackBins[0][0],
505 tmapBin.first->trackAverage(trackBins,
true);