46 std::unique_ptr<const Logger>
logger)
60 std::unique_ptr<const Logger> newLogger) {
64 std::shared_ptr<Acts::TrackingVolume>
67 std::shared_ptr<const IVolumeMaterial> volumeMaterial,
68 std::shared_ptr<const VolumeBounds> volumeBounds,
74 std::unique_ptr<const LayerArray> layerArray =
nullptr;
84 bool idTrf = transform.isApprox(Transform3::Identity());
91 if (cylinderBounds ==
nullptr) {
93 "[!] Problem: given bounds are not cylindrical - return nullptr");
98 if (!layers.empty()) {
108 if (not estimateAndCheckDimension(gctx, layers, cylinderBounds, transform,
109 rMinRaw, rMaxRaw, zMinRaw, zMaxRaw,
112 "[!] Problem with given dimensions - return nullptr and "
113 "delete provided objects");
115 if (volumeBounds ==
nullptr) {
116 delete cylinderBounds;
122 (not idTrf ? transform.translation().z() : 0.) +
123 (cylinderBounds !=
nullptr
126 double zMax = (not idTrf ? transform.translation().z() : 0.) +
127 (cylinderBounds !=
nullptr
131 double rMin = cylinderBounds !=
nullptr
134 double rMax = cylinderBounds !=
nullptr
139 "Filling the layers into an appropriate layer array - with "
144 layerArray = (bValue ==
binR)
145 ?
m_cfg.layerArrayCreator->layerArray(gctx, layers, rMin,
147 :
m_cfg.layerArrayCreator->layerArray(gctx, layers, zMin,
148 zMax, bType, bValue);
152 std::shared_ptr<const VolumeBounds> volumeBoundsFinal =
153 volumeBounds.get() !=
nullptr
155 : std::shared_ptr<const VolumeBounds>(cylinderBounds);
158 std::move(layerArray),
nullptr, mtvVector,
162 "Created cylindrical volume at z-position :" << tVolume->center().z());
163 ACTS_VERBOSE(
" created bounds : " << tVolume->volumeBounds());
168 std::shared_ptr<Acts::TrackingVolume>
172 std::shared_ptr<const IVolumeMaterial> volumeMaterial,
double rMin,
173 double rMax,
double zMin,
double zMax,
const std::string& volumeName,
179 ACTS_VERBOSE(
"Create cylindrical TrackingVolume '" << volumeName <<
"'.");
180 ACTS_VERBOSE(
" -> with given dimensions of (rMin/rMax/zMin/Max) = "
181 << rMin <<
" / " << rMax <<
" / " << zMin <<
" / " << zMax);
184 if (zMin > zMax || rMin > rMax) {
186 << ((zMin > zMax) ?
" zMin > zMax (" :
" rMin > rMax (")
187 << ((zMin > zMax) ? zMin : rMin) <<
" > "
188 << ((zMin > zMax) ? zMax : rMax) <<
" ) - return 0");
193 double halflengthZ = 0.5 * (zMax - zMin);
194 double zPosition = 0.5 * (zMin + zMax);
195 zPosition = std::abs(zPosition) < 0.1 ? 0. : zPosition;
203 return createTrackingVolume(gctx, layers, volumeMaterial,
208 std::shared_ptr<Acts::TrackingVolume>
211 std::shared_ptr<const IVolumeMaterial> volumeMaterial,
double rMin,
212 double rMax,
double zMin,
double zMax,
unsigned int materialLayers,
213 bool cylinder,
const std::string& volumeName)
const {
216 << volumeName <<
"' with (rMin/rMax/zMin/Max) = ");
217 ACTS_VERBOSE(
'\t' << rMin <<
" / " << rMax <<
" / " << zMin <<
" / " << zMax);
220 double min = cylinder ? rMin : zMin;
221 double max = cylinder ? rMax : zMax;
224 std::vector<double> layerPositions;
225 if (materialLayers > 1) {
226 double step = cylinder ? (max -
min) / (materialLayers - 1)
227 : (max -
min) / (materialLayers - 1);
228 for (
unsigned int il = 0; il < materialLayers; ++il) {
229 layerPositions.push_back(min + il * step);
232 layerPositions.push_back(0.5 * (min + max));
236 return createGapTrackingVolume(gctx, mtvVector, volumeMaterial, rMin, rMax,
237 zMin, zMax, layerPositions, cylinder,
241 std::shared_ptr<Acts::TrackingVolume>
244 std::shared_ptr<const IVolumeMaterial> volumeMaterial,
double rMin,
245 double rMax,
double zMin,
double zMax,
246 const std::vector<double>& layerPositions,
bool cylinder,
250 << volumeName <<
"' with (rMin/rMax/zMin/Max) = ");
251 ACTS_VERBOSE(
'\t' << rMin <<
" / " << rMax <<
" / " << zMin <<
" / " << zMax);
255 layers.reserve(layerPositions.size());
257 std::vector<double>::const_iterator layerPropIter = layerPositions.begin();
258 std::vector<double>::const_iterator layerPropEnd = layerPositions.end();
259 for (; layerPropIter != layerPropEnd; ++layerPropIter) {
263 double zMinLayer = zMin;
264 double zMaxLayer = zMax;
266 layers.push_back(createCylinderLayer(
267 0.5 * (zMinLayer + zMaxLayer), (*layerPropIter),
268 std::abs(0.5 * (zMaxLayer - zMinLayer)),
m_cfg.passiveLayerThickness,
269 m_cfg.passiveLayerPhiBins,
m_cfg.passiveLayerRzBins));
273 double rMinLayer = rMin;
274 double rMaxLayer = rMax;
276 layers.push_back(createDiscLayer(
277 (*layerPropIter), rMinLayer, rMaxLayer,
m_cfg.passiveLayerThickness,
278 m_cfg.passiveLayerPhiBins,
m_cfg.passiveLayerRzBins));
282 return createTrackingVolume(gctx, layers, mtvVector, volumeMaterial, rMin,
283 rMax, zMin, zMax, volumeName, bType);
286 std::shared_ptr<Acts::TrackingVolume>
290 if (volumes.size() <= (size_t)1) {
292 "None (only one) TrackingVolume given to create container "
293 "volume (min required: 2) - returning 0 ");
298 ACTS_VERBOSE(
"[start] Creating a container volume with " << volumes.size()
302 auto firstVolume = volumes.begin();
303 auto lastVolume = volumes.end();
305 for (
size_t ivol = 0; firstVolume != lastVolume; ++firstVolume, ++ivol) {
307 <<
") is : " << (*firstVolume)->volumeName());
308 ACTS_VERBOSE(
" at position : " << (*firstVolume)->center().x() <<
", "
309 << (*firstVolume)->center().y() <<
", "
310 << (*firstVolume)->center().z());
312 ACTS_VERBOSE(
" with bounds : " << (*firstVolume)->volumeBounds());
314 volumeName += (*firstVolume)->volumeName();
315 if (ivol + 1 < volumes.size()) {
322 firstVolume = volumes.begin();
325 if (firstVolume == lastVolume) {
327 "Only one TrackingVolume given to create Top level volume "
328 "(min required: 2) - returning 0 ");
334 &((*firstVolume)->volumeBounds()));
337 &((*lastVolume)->volumeBounds()));
339 if ((firstVolumeBounds ==
nullptr) || (lastVolumeBounds ==
nullptr)) {
341 "VolumeBounds given are not of type: CylinderVolumeBounds "
342 "(required) - returning 0 ");
354 double rGlueMin = 0.;
359 zMin = (*firstVolume)->center().z() -
361 zMax = (*firstVolume)->center().z() +
369 zMin = (*firstVolume)->center().z() -
371 zMax = (*lastVolume)->center().z() +
373 zSep1 = (*firstVolume)->center().z() +
380 double zPos = 0.5 * (zMin + zMax);
388 ACTS_VERBOSE(
"Container volume bounds are " << (*topVolumeBounds));
391 std::shared_ptr<const TrackingVolumeArray> volumeArray =
392 (rCase) ?
m_cfg.trackingVolumeArrayCreator->trackingVolumeArray(
394 :
m_cfg.trackingVolumeArrayCreator->trackingVolumeArray(
395 gctx, volumes,
binZ);
396 if (volumeArray ==
nullptr) {
398 "Creation of TrackingVolume array did not succeed - returning 0 ");
399 delete topVolumeBounds;
408 if (not interGlueTrackingVolume(gctx, topVolume, rCase, rMin, rGlueMin, rMax,
411 "Problem with inter-glueing of TrackingVolumes (needed) - "
417 "[ end ] return newly created container : " << topVolume->volumeName());
427 const Transform3& transform,
double& rMinClean,
double& rMaxClean,
428 double& zMinClean,
double& zMaxClean,
BinningValue& bValue,
433 <<
" layers to gather overall dimensions");
434 if (cylinderVolumeBounds !=
nullptr) {
436 "Cylinder volume bounds are given: (rmin/rmax/dz) = "
444 double layerRmin = 10e10;
445 double layerRmax = 0.;
446 double layerZmin = 10e10;
447 double layerZmax = -10e10;
456 for (
auto& layerIter : layers) {
458 double currentRmin = 0.;
459 double currentRmax = 0.;
460 double currentZmin = 0.;
461 double currentZmax = 0.;
464 &(layerIter->surfaceRepresentation()).
bounds());
466 if (cylBounds !=
nullptr) {
470 double centerZ = (layerIter->surfaceRepresentation()).center(gctx).z();
472 currentRmin = currentR - (0.5 * (layerIter)->
thickness());
473 currentRmax = currentR + (0.5 * (layerIter)->
thickness());
479 &(layerIter->surfaceRepresentation()).
bounds());
480 if (discBounds !=
nullptr) {
482 double centerZ = (layerIter->surfaceRepresentation()).center(gctx).z();
483 currentRmin = discBounds->
rMin();
484 currentRmax = discBounds->
rMax();
485 currentZmin = centerZ - (0.5 * (layerIter)->
thickness());
486 currentZmax = centerZ + (0.5 * (layerIter)->
thickness());
489 rMinClean =
std::min(rMinClean, currentRmin);
490 rMaxClean = std::max(rMaxClean, currentRmax);
491 zMinClean =
std::min(zMinClean, currentZmin);
492 zMaxClean = std::max(zMaxClean, currentZmax);
494 layerRmin =
std::min(layerRmin, currentRmin);
495 layerRmax = std::max(layerRmax, currentRmax);
496 layerZmin =
std::min(layerZmin, currentZmin);
497 layerZmax = std::max(layerZmax, currentZmax);
504 "Estimate/check CylinderVolumeBounds from/w.r.t. enclosed "
505 "layers + envelope covers");
507 double zEstFromLayerEnv = 0.5 * (layerZmax + layerZmin);
508 double halflengthFromLayer = 0.5 * std::abs(layerZmax - layerZmin);
513 bool concentric = std::abs(zEstFromLayerEnv) < 0.031622777;
515 bool idTrf = transform.isApprox(Transform3::Identity());
517 Transform3 vtransform = Transform3::Identity();
519 if ((cylinderVolumeBounds ==
nullptr) && idTrf) {
521 cylinderVolumeBounds =
525 : Transform3::Identity();
526 }
else if ((cylinderVolumeBounds !=
nullptr) && idTrf && !concentric) {
528 }
else if (not idTrf && (cylinderVolumeBounds ==
nullptr)) {
530 cylinderVolumeBounds =
534 ACTS_VERBOSE(
" -> dimensions from layers (rMin/rMax/zMin/zMax) = "
535 << layerRmin <<
" / " << layerRmax <<
" / " << layerZmin <<
" / "
538 double zFromTransform = not idTrf ? transform.translation().z() : 0.;
540 " -> while created bounds are (rMin/rMax/zMin/zMax) = "
550 if (cylinderVolumeBounds !=
nullptr) {
563 "Provided layers are not contained by volume ! Bailing out. ");
566 << zFromTransform - cylinderVolumeBounds->
get(
568 <<
", layerZmin: " << layerZmin);
570 << zFromTransform + cylinderVolumeBounds->
get(
572 <<
", layerZmax: " << layerZmax);
575 <<
", layerRmin: " << layerRmin);
578 <<
", layerRmax: " << layerRmax);
583 ACTS_VERBOSE(
"Created/Checked " << *cylinderVolumeBounds);
588 const GeometryContext& gctx,
const std::shared_ptr<TrackingVolume>& tVolume,
589 bool rBinned,
double rMin,
double rGlueMin,
double rMax,
double zMin,
591 ACTS_VERBOSE(
"Glue contained TrackingVolumes of container '"
592 << tVolume->volumeName() <<
"'.");
595 if (tVolume->confinedVolumes()) {
601 auto&
volumes = tVolume->confinedVolumes()->arrayObjects();
607 ACTS_VERBOSE(
"[" << ivol++ <<
"] - volume : " << vol->volumeName());
611 auto tVolIter = volumes.begin();
612 auto tVolFirst = volumes.begin();
613 auto tVolLast = volumes.end();
615 auto tVolEnd = volumes.end();
627 for (; tVolIter != tVolEnd;) {
629 ACTS_VERBOSE(
"r-binning: Processing volume [" << ivol++ <<
"]");
631 std::shared_ptr<TrackingVolume> tVol =
633 if (tVolIter == tVolFirst) {
639 if (tVolIter == tVolLast) {
643 std::shared_ptr<TrackingVolume> tVol1 =
645 std::shared_ptr<TrackingVolume> tVol2 =
650 0.5 * (tVol1->volumeBounds()
651 .values()[CylinderVolumeBounds::BoundValues::eMaxR] +
652 tVol2->volumeBounds()
653 .values()[CylinderVolumeBounds::BoundValues::eMinR]);
662 for (; tVolIter != tVolEnd;) {
665 << (*tVolIter)->volumeName() <<
"'.");
666 std::shared_ptr<TrackingVolume> tVol =
668 if (tVolIter == tVolFirst) {
673 if (tVolIter == tVolLast) {
677 std::shared_ptr<TrackingVolume> tVol1 =
679 std::shared_ptr<TrackingVolume> tVol2 =
688 if (!glueVolumesNegativeFace.empty()) {
690 std::shared_ptr<const TrackingVolumeArray> glueVolumesNegativeFaceArray =
691 m_cfg.trackingVolumeArrayCreator->trackingVolumeArray(
692 gctx, glueVolumesNegativeFace,
binR);
695 glueVolumesNegativeFaceArray);
697 if (!glueVolumesPositiveFace.empty()) {
699 std::shared_ptr<const TrackingVolumeArray> glueVolumesPositiveFaceArray =
700 m_cfg.trackingVolumeArrayCreator->trackingVolumeArray(
701 gctx, glueVolumesPositiveFace,
binR);
704 glueVolumesPositiveFaceArray);
706 if (!glueVolumesInnerTube.empty()) {
708 std::shared_ptr<const TrackingVolumeArray> glueVolumesInnerTubeArray =
709 m_cfg.trackingVolumeArrayCreator->trackingVolumeArray(
710 gctx, glueVolumesInnerTube,
binZ);
714 if (!glueVolumesOuterTube.empty()) {
716 std::shared_ptr<const TrackingVolumeArray> glueVolumesOuterTubeArray =
717 m_cfg.trackingVolumeArrayCreator->trackingVolumeArray(
718 gctx, glueVolumesOuterTube,
binZ);
723 ACTS_VERBOSE(
"[GV] Register " << glueVolumesNegativeFace.size()
724 <<
" volumes at face negativeFaceXY:");
725 for (tVolIter = glueVolumesNegativeFace.begin();
726 tVolIter != glueVolumesNegativeFace.end(); ++tVolIter) {
727 ACTS_VERBOSE(
" -> volume '" << (*tVolIter)->volumeName() <<
"'");
729 ACTS_VERBOSE(
"[GV] Register " << glueVolumesPositiveFace.size()
730 <<
" volumes at face positiveFaceXY: ");
731 for (tVolIter = glueVolumesPositiveFace.begin();
732 tVolIter != glueVolumesPositiveFace.end(); ++tVolIter) {
733 ACTS_VERBOSE(
" -> volume '" << (*tVolIter)->volumeName() <<
"'");
735 ACTS_VERBOSE(
"[GV] Register " << glueVolumesInnerTube.size()
736 <<
" volumes at face tubeInnerCover: ");
737 for (tVolIter = glueVolumesInnerTube.begin();
738 tVolIter != glueVolumesInnerTube.end(); ++tVolIter) {
739 ACTS_VERBOSE(
" -> volume '" << (*tVolIter)->volumeName() <<
"'");
741 ACTS_VERBOSE(
"[GV] Register " << glueVolumesOuterTube.size()
742 <<
" volumes at face tubeOuterCover:");
743 for (tVolIter = glueVolumesOuterTube.begin();
744 tVolIter != glueVolumesOuterTube.end(); ++tVolIter) {
745 ACTS_VERBOSE(
" -> volume '" << (*tVolIter)->volumeName());
754 const GeometryContext& gctx,
const std::shared_ptr<TrackingVolume>& tvolOne,
757 double zMin,
double zMax)
const {
760 tvolOne->glueVolumesDescriptor();
762 tvolTwo->glueVolumesDescriptor();
764 size_t volOneGlueVols =
766 ? gvDescriptorOne.
glueVolumes(faceOne)->arrayObjects().size()
769 << tvolOne->volumeName() <<
"' has " << volOneGlueVols <<
" @ "
771 size_t volTwoGlueVols =
773 ? gvDescriptorTwo.
glueVolumes(faceTwo)->arrayObjects().size()
776 << tvolTwo->volumeName() <<
"' has " << volTwoGlueVols <<
" @ "
782 ? gvDescriptorOne.
glueVolumes(faceOne)->arrayObjects()[0]
786 ? gvDescriptorTwo.
glueVolumes(faceTwo)->arrayObjects()[0]
794 if (volOneGlueVols <= 1 && volTwoGlueVols <= 1) {
796 ACTS_VERBOSE(
" glue : one[ " << glueVolOne->volumeName() <<
" @ "
797 << faceOne <<
" ]-to-one[ "
798 << glueVolTwo->volumeName() <<
" @ "
801 mutableGlueVolOne->glueTrackingVolume(gctx, faceOne,
802 mutableGlueVolTwo.get(), faceTwo);
804 }
else if (volOneGlueVols <= 1) {
807 << glueVolOne->volumeName() <<
" @ " << faceOne
808 <<
" ]-to-many[ " << tvolTwo->volumeName() <<
" @ " << faceTwo
812 mutableGlueVolOne->glueTrackingVolumes(gctx, faceOne, mutableFaceTwoVolumes,
814 }
else if (volTwoGlueVols <= 1) {
817 << tvolOne->volumeName() <<
" @ " << faceOne <<
" ]-to-one[ "
818 << glueVolTwo->volumeName() <<
" @ " << faceTwo <<
" ]");
821 mutableGlueVolTwo->glueTrackingVolumes(gctx, faceTwo, mutableFaceOneVolumes,
826 << tvolOne->volumeName() <<
" @ " << faceOne <<
" ]-to-many[ "
827 << tvolTwo->volumeName() <<
" @ " << faceTwo <<
" ]");
830 std::shared_ptr<const BoundarySurfaceT<TrackingVolume>> boundarySurface =
834 Transform3 transform = Transform3::Identity();
835 if (std::abs(zMin + zMax) > 0.1) {
844 std::make_shared<CylinderBounds>(rGlueMin, 0.5 * (zMax - zMin));
845 std::shared_ptr<const Surface>
cSurface =
846 Surface::makeShared<CylinderSurface>(
transform, cBounds);
848 " creating a new cylindrical boundary surface "
850 << cSurface->bounds());
851 ACTS_VERBOSE(
" at " << cSurface->center(gctx).transpose());
853 std::make_shared<const BoundarySurfaceT<TrackingVolume>>(
861 &tvolOne->volumeBounds());
862 double zPos = tvolOne->center().z();
870 std::shared_ptr<const Surface> dSurface =
871 Surface::makeShared<DiscSurface>(
transform, rMin, rMax);
873 " creating a new disc-like boundary surface "
875 << dSurface->bounds());
876 ACTS_VERBOSE(
" at " << dSurface->center(gctx).transpose());
878 std::make_shared<const BoundarySurfaceT<TrackingVolume>>(
884 std::shared_ptr<const ISurfaceMaterial> boundaryMaterial =
nullptr;
886 ACTS_VERBOSE(
"New Boundary surface setting for containers");
887 ACTS_VERBOSE(
" - at first volume: " << tvolOne->volumeName());
890 for (
auto& oneVolume :
891 gvDescriptorOne.
glueVolumes(faceOne)->arrayObjects()) {
892 auto mutableOneVolume =
895 if (boundaryMaterial ==
nullptr) {
898 oneBSurface->surfaceRepresentation().surfaceMaterialSharedPtr();
900 mutableOneVolume->updateBoundarySurface(faceOne, boundarySurface);
902 << mutableOneVolume->volumeName());
904 ACTS_VERBOSE(
" - at second volume: " << tvolTwo->volumeName());
905 for (
auto& twoVolume :
906 gvDescriptorTwo.
glueVolumes(faceTwo)->arrayObjects()) {
907 auto mutableTwoVolume =
910 if (boundaryMaterial ==
nullptr) {
913 twoBSurface->surfaceRepresentation().surfaceMaterialSharedPtr();
915 mutableTwoVolume->updateBoundarySurface(faceTwo, boundarySurface);
917 << mutableTwoVolume->volumeName());
921 if (boundaryMaterial !=
nullptr) {
923 ACTS_VERBOSE(
"- the new boundary surface has boundary material: ");
926 const_cast<Surface*
>(&(boundarySurface->surfaceRepresentation()));
937 ACTS_VERBOSE(
"Adding face volumes of face " << glueFace <<
" for the volume '"
938 << tvol->volumeName() <<
"'.");
942 if (gvDescriptor.glueVolumes(glueFace)) {
944 auto volIter = gvDescriptor.
glueVolumes(glueFace)->arrayObjects().begin();
945 auto volEnd = gvDescriptor.glueVolumes(glueFace)->arrayObjects().end();
946 for (; volIter != volEnd; ++volIter) {
947 ACTS_VERBOSE(
" -> adding : " << (*volIter)->volumeName());
948 vols.push_back(*volIter);
952 <<
" navigation volumes registered as glue volumes.");
955 ACTS_VERBOSE(
" -> adding only volume itself (at navigation level).");
956 vols.push_back(tvol);
960 std::shared_ptr<const Acts::Layer>
965 ACTS_VERBOSE(
"Creating a CylinderLayer at position " << z <<
" and radius "
971 BinUtility layerBinUtility(binsZ, z - halflengthZ, z + halflengthZ,
open,
976 ACTS_VERBOSE(
" -> Preparing the binned material with " << binsZ
983 layerBinUtilityPhiZ += layerBinUtility;
986 << binsPhi <<
" / " << binsZ <<
" bins in phi / Z. ");
993 transform, std::shared_ptr<const CylinderBounds>(cylinderBounds),
nullptr,
998 double z,
double rMin,
double rMax,
double thickness,
int binsPhi,
1000 ACTS_VERBOSE(
"Creating a DiscLayer at position " << z <<
" and rMin/rMax "
1001 << rMin <<
" / " << rMax);
1009 ACTS_VERBOSE(
" -> Preparing the binned material with " << binsR
1015 << binsPhi <<
" / " << binsR <<
" bins in phi / R. ");
1023 std::shared_ptr<const DiscBounds>(discBounds),
1024 nullptr, thickness);