44 #include <type_traits>
48 struct EndOfWorldReached;
53 std::unique_ptr<const Logger> slogger)
55 m_propagator(std::
move(propagator)),
65 State mState(gctx, mctx);
66 resolveMaterialVolume(mState, *world);
67 collectMaterialSurfaces(mState, *world);
74 <<
"' for material surfaces.")
77 checkAndInsert(mState, tVolume);
84 resolveMaterialVolume(mState, *sVolume);
90 resolveMaterialVolume(mState, *sVolume);
99 if (volumeMaterial !=
nullptr) {
101 size_t volumeID = geoID.
volume();
102 ACTS_DEBUG(
"Material volume found with volumeID " << volumeID);
109 const BinUtility* bu = (psm !=
nullptr) ? (&psm->binUtility()) :
nullptr;
116 ACTS_DEBUG(
" - adjusted binning is " << buAdjusted);
119 ACTS_DEBUG(
"Binning of dimension 0 create AccumulatedVolumeMaterial");
123 ACTS_DEBUG(
"Binning of dimension 2 create 2D Grid");
124 std::function<Acts::Vector2(Acts::Vector3)> transfoGlobalToLocal;
126 mState.
grid2D.insert(std::make_pair(geoID, Grid));
127 mState.
transform2D.insert(std::make_pair(geoID, transfoGlobalToLocal));
129 ACTS_DEBUG(
"Binning of dimension 3 create 3D Grid");
130 std::function<Acts::Vector3(Acts::Vector3)> transfoGlobalToLocal;
132 mState.
grid3D.insert(std::make_pair(geoID, Grid));
133 mState.
transform3D.insert(std::make_pair(geoID, transfoGlobalToLocal));
135 throw std::invalid_argument(
136 "Incorrect bin dimension, only 0, 2 and 3 are accepted");
141 auto bmp2 =
dynamic_cast<
144 bu = (bmp2 !=
nullptr) ? (&bmp2->binUtility()) :
nullptr;
147 ACTS_DEBUG(
" - (2D grid) binning is " << *bu);
149 std::function<Acts::Vector2(Acts::Vector3)> transfoGlobalToLocal;
151 mState.
grid2D.insert(std::make_pair(geoID, Grid));
152 mState.
transform2D.insert(std::make_pair(geoID, transfoGlobalToLocal));
156 auto bmp3 =
dynamic_cast<
159 bu = (bmp3 !=
nullptr) ? (&bmp3->binUtility()) :
nullptr;
162 ACTS_DEBUG(
" - (3D grid) binning is " << *bu);
164 std::function<Acts::Vector3(Acts::Vector3)> transfoGlobalToLocal;
166 mState.
grid3D.insert(std::make_pair(geoID, Grid));
167 mState.
transform3D.insert(std::make_pair(geoID, transfoGlobalToLocal));
171 ACTS_DEBUG(
" - this is homogeneous material.");
184 <<
"' for material surfaces.")
189 if (bSurface->surfaceRepresentation().surfaceMaterial() !=
nullptr) {
190 mState.
surfaceMaterial[bSurface->surfaceRepresentation().geometryId()] =
191 bSurface->surfaceRepresentation().surfaceMaterialSharedPtr();
202 if (cLayer->surfaceRepresentation().surfaceMaterial() !=
nullptr) {
204 cLayer->surfaceRepresentation().surfaceMaterialSharedPtr();
207 if (cLayer->approachDescriptor() !=
nullptr) {
208 for (
auto& aSurface :
209 cLayer->approachDescriptor()->containedSurfaces()) {
210 if (aSurface !=
nullptr) {
211 if (aSurface->surfaceMaterial() !=
nullptr) {
213 aSurface->surfaceMaterialSharedPtr();
219 if (cLayer->surfaceArray() !=
nullptr) {
221 for (
auto& sSurface : cLayer->surfaceArray()->surfaces()) {
222 if (sSurface !=
nullptr) {
223 if (sSurface->surfaceMaterial() !=
nullptr) {
225 sSurface->surfaceMaterialSharedPtr();
237 collectMaterialSurfaces(mState, *sVolume);
244 std::pair<const GeometryIdentifier, BinUtility>& currentBinning,
247 if (currentBinning.second.dimensions() == 0) {
256 static_cast<int>(std::floor(properties.
thickness() /
m_cfg.mappingStep));
257 float remainder = properties.
thickness() -
m_cfg.mappingStep * volumeStep;
259 direction = direction * (
m_cfg.mappingStep / direction.norm());
261 for (
int extraStep = 0; extraStep < volumeStep; extraStep++) {
262 Vector3 extraPosition = position + extraStep * direction;
265 if (currentBinning.second.dimensions() == 2) {
266 auto grid = mState.
grid2D.find(currentBinning.first);
270 mState.
transform2D[currentBinning.first](extraPosition));
271 grid->second.atLocalBins(index).accumulate(properties);
273 throw std::domain_error(
"No grid 2D was found");
275 }
else if (currentBinning.second.dimensions() == 3) {
276 auto grid = mState.
grid3D.find(currentBinning.first);
280 mState.
transform3D[currentBinning.first](extraPosition));
281 grid->second.atLocalBins(index).accumulate(properties);
283 throw std::domain_error(
"No grid 3D was found");
292 Vector3 extraPosition = position + volumeStep * direction;
293 if (currentBinning.second.dimensions() == 2) {
294 auto grid = mState.
grid2D.find(currentBinning.first);
298 mState.
transform2D[currentBinning.first](extraPosition));
299 grid->second.atLocalBins(index).accumulate(properties);
301 throw std::domain_error(
"No grid 2D was found");
303 }
else if (currentBinning.second.dimensions() == 3) {
304 auto grid = mState.
grid3D.find(currentBinning.first);
308 mState.
transform3D[currentBinning.first](extraPosition));
309 grid->second.atLocalBins(index).accumulate(properties);
311 throw std::domain_error(
"No grid 3D was found");
320 ACTS_DEBUG(
"Create the material for volume " << matBin.first);
321 if (matBin.second.dimensions() == 0) {
326 std::make_unique<HomogeneousVolumeMaterial>(mat);
327 }
else if (matBin.second.dimensions() == 2) {
340 throw std::domain_error(
"No grid 2D was found");
342 }
else if (matBin.second.dimensions() == 3) {
355 throw std::domain_error(
"No grid 3D was found");
358 throw std::invalid_argument(
359 "Incorrect bin dimension, only 0, 2 and 3 are accepted");
370 makeVector4(mTrack.first.first, 0), mTrack.first.second,
371 1 / mTrack.first.second.norm(), std::nullopt,
372 NeutralParticleHypothesis::geantino());
377 using ActionList = ActionList<BoundSurfaceCollector, MaterialVolumeCollector>;
378 using AbortList = AbortList<EndOfWorldReached>;
384 const auto& result = m_propagator.propagate(
start, options).value();
385 auto mcResult = result.get<BoundSurfaceCollector::result_type>();
386 auto mvcResult = result.get<MaterialVolumeCollector::result_type>();
388 auto mappingSurfaces = mcResult.collected;
389 auto mappingVolumes = mvcResult.collected;
392 auto& rMaterial = mTrack.second.materialInteractions;
394 <<
" recorded material steps to map.")
398 <<
" mapping volumes for this track.");
400 for (
auto& mVolumes : mappingVolumes) {
401 ACTS_VERBOSE(
" - Volume : " << mVolumes.volume->geometryId()
402 <<
" at position = (" << mVolumes.position.x()
403 <<
", " << mVolumes.position.y() <<
", "
404 << mVolumes.position.z() <<
")");
406 mappingVolumes.push_back(mVolumes);
410 auto rmIter = rMaterial.begin();
411 auto sfIter = mappingSurfaces.begin();
412 auto volIter = mappingVolumes.begin();
423 if (volIter != mappingVolumes.end()) {
424 lastPositionEnd = volIter->position;
429 while (rmIter != rMaterial.end() && volIter != mappingVolumes.end()) {
430 if (volIter != mappingVolumes.end() &&
431 !volIter->volume->inside(rmIter->position)) {
435 double distVol = (volIter->position - mTrack.first.first).
norm();
436 double distMat = (rmIter->position - mTrack.first.first).
norm();
443 if (volIter != mappingVolumes.end() &&
444 volIter->volume->inside(rmIter->position,
s_epsilon)) {
445 currentID = volIter->
volume->geometryId();
446 direction = rmIter->direction;
447 if (not(currentID == lastID)) {
450 lastPositionEnd = volIter->position;
451 currentBinning = mState.
materialBin.find(currentID);
456 rmIter->materialSlab.thickness() > 0) {
458 float vacuumThickness = (rmIter->position - lastPositionEnd).
norm();
462 createExtraHits(mState, *currentBinning, properties, lastPositionEnd,
468 direction * (rmIter->materialSlab.thickness() / direction.norm());
469 lastPositionEnd = rmIter->position + direction;
471 createExtraHits(mState, *currentBinning, rmIter->materialSlab,
472 rmIter->position, direction);
477 if ((rmIter + 1) == rMaterial.end() ||
480 while (sfIter != mappingSurfaces.end()) {
481 if (sfIter->surface->geometryId().volume() == lastID.
volume() ||
482 ((volIter + 1) != mappingVolumes.end() &&
483 sfIter->surface->geometryId().volume() ==
484 (volIter + 1)->volume->geometryId().volume())) {
485 double distVol = (volIter->position - mTrack.first.first).
norm();
486 double distSur = (sfIter->position - mTrack.first.first).
norm();
488 float vacuumThickness =
489 (sfIter->position - lastPositionEnd).
norm();
494 createExtraHits(mState, *currentBinning, properties,
495 lastPositionEnd, direction);
496 lastPositionEnd = sfIter->position;
504 rmIter->volume = volIter->volume;
505 rmIter->intersectionID = currentID;
506 rmIter->intersection = rmIter->position;