10 #include "GaudiKernel/SystemOfUnits.h"
34 m_layerArrayCreator(
"Trk::LayerArrayCreator/LayerArrayCreator"),
35 m_trackingVolumeArrayCreator(
"Trk::TrackingVolumeArrayCreator/TrackingVolumeArrayCreator"),
36 m_trackingVolumeHelper(
"Trk::TrackingVolumeHelper/TrackingVolumeHelper"),
38 m_passiveLayerPhiBins(1),
39 m_passiveLayerRzBins(100)
41 declareInterface<ITrackingVolumeCreator>(
this);
62 if (m_layerArrayCreator.retrieve().isFailure())
64 ATH_MSG_FATAL(
"Failed to retrieve tool " << m_layerArrayCreator );
65 return StatusCode::FAILURE;
71 if (m_trackingVolumeArrayCreator.retrieve().isFailure())
73 ATH_MSG_FATAL(
"Failed to retrieve tool " << m_trackingVolumeArrayCreator );
74 return StatusCode::FAILURE;
76 ATH_MSG_DEBUG(
"Retrieved tool " << m_trackingVolumeArrayCreator );
80 if (m_trackingVolumeHelper.retrieve().isFailure())
82 ATH_MSG_FATAL(
"Failed to retrieve tool " << m_trackingVolumeHelper );
83 return StatusCode::FAILURE;
89 return StatusCode::SUCCESS;
94 const std::vector<Trk::Layer*>&
layers,
98 const std::string& volumeName,
115 if (!cylinderBounds){
116 ATH_MSG_WARNING(
"[!] Problem: given bounds were not cylindrical - return 0" );
120 std::vector<Trk::CylinderLayer*> cylLayers;
121 cylLayers.reserve(
layers.size());
122 std::vector<Trk::DiscLayer*> discLayers;
123 discLayers.reserve(
layers.size());
132 if (estimateAndCheckDimension(
layers,
139 btype).isFailure()) {
140 ATH_MSG_WARNING(
"[!] Problem with given dimensions - return 0 and delete provided objects" );
142 delete cylinderBounds;
148 ( cylinderBounds ? -cylinderBounds->
halflengthZ() : 0. );
150 ( cylinderBounds ? cylinderBounds->
halflengthZ() : 0. );
163 if (!cylinderBounds) {
173 std::unique_ptr<Trk::BinnedArray1D<Trk::Layer>> layerArray =
174 !cylLayers.empty() ? m_layerArrayCreator->cylinderLayerArray(
175 cylLayers, rMin, rMax, btype)
176 : m_layerArrayCreator->discLayerArray(
177 discLayers, zMin, zMax, btype);
181 std::shared_ptr<Trk::CylinderVolumeBounds>(cylinderBounds),
183 std::move(layerArray),
196 const std::vector<Trk::Layer*>&
layers,
202 const std::string& volumeName,
210 ATH_MSG_VERBOSE(
"Create cylindrical TrackingVolume '" << volumeName <<
"'.");
212 << rMin <<
" / " << rMax <<
" / " << zMin <<
" / " << zMax);
215 if (zMin > zMax || rMin > rMax) {
217 << ((zMin > zMax) ?
" zMin > zMax (" :
" rMin > rMax (")
218 << ((zMin > zMax) ? zMin : rMin) <<
" > "
219 << ((zMin > zMax) ? zMax : rMax) <<
" ) - return 0");
224 double halflengthZ = 0.5 * (zMax - zMin);
225 double zPosition = 0.5 * (zMin + zMax);
226 zPosition = fabs(zPosition) < 0.1 ? 0. : zPosition;
238 return createTrackingVolume(
248 unsigned int materialLayers,
250 const std::string& volumeName)
const
254 ATH_MSG_VERBOSE(
"Create cylindrical gap TrackingVolume '" << volumeName <<
"' with (rMin/rMax/zMin/Max) = ");
255 ATH_MSG_VERBOSE(
'\t' << rMin <<
" / " << rMax <<
" / " << zMin <<
" / " << zMax );
258 double min = cylinder ? rMin : zMin;
259 double max = cylinder ? rMax : zMax;
262 std::vector<double> layerPositions;
263 layerPositions.reserve(materialLayers);
264 if (materialLayers > 1){
266 const double step=(
max-
min)/(materialLayers-1);
267 for (
unsigned int il = 0;
il < materialLayers; ++
il)
270 layerPositions.push_back(0.5*(
min+
max));
273 return createGapTrackingVolume(matprop,
292 const std::vector<double>& layerPositions,
294 const std::string& volumeName,
300 << volumeName <<
"' with (rMin/rMax/zMin/Max) = ");
301 ATH_MSG_VERBOSE(
'\t' << rMin <<
" / " << rMax <<
" / " << zMin <<
" / "
305 std::vector<Trk::Layer*>
layers;
306 layers.reserve(layerPositions.size());
308 std::vector<double>::const_iterator layerPropIter = layerPositions.begin();
309 std::vector<double>::const_iterator layerPropEnd = layerPositions.end();
310 for (; layerPropIter != layerPropEnd; ++layerPropIter) {
314 double zMinLayer = zMin;
315 double zMaxLayer = zMax;
317 layers.push_back(createCylinderLayer(0.5 * (zMinLayer + zMaxLayer),
319 fabs(0.5 * (zMaxLayer - zMinLayer)),
320 m_passiveLayerThickness,
321 m_passiveLayerPhiBins,
322 m_passiveLayerRzBins));
326 double rMinLayer = rMin;
327 double rMaxLayer = rMax;
329 layers.push_back(createDiscLayer((*layerPropIter),
332 m_passiveLayerThickness,
333 m_passiveLayerPhiBins,
334 m_passiveLayerRzBins));
338 return createTrackingVolume(
339 layers, matprop, rMin, rMax, zMin, zMax, volumeName, btype);
344 const std::vector<Trk::TrackingVolume*>& volumes,
346 const std::string& volumeName,
347 bool buildBoundaryLayers,
348 bool replaceBoundaryFace)
const
351 if (volumes.size() <= (
unsigned int)1) {
352 ATH_MSG_WARNING(
"None (only one) TrackingVolume given to create container "
353 "volume (min required: 2) - returning 0 ");
359 << volumeName <<
"' with " << volumes.size()
363 auto firstVolume = volumes.begin();
364 auto lastVolume = volumes.end();
366 for (
unsigned int ivol = 0; firstVolume != lastVolume;
367 ++firstVolume, ++ivol) {
369 << ivol <<
") is : " << (*firstVolume)->volumeName());
371 " at position : " <<
Amg::toString((*firstVolume)->center()));
376 firstVolume = volumes.begin();
379 if (firstVolume == lastVolume) {
380 ATH_MSG_WARNING(
"Only one TrackingVolume given to create Top level volume "
381 "(min required: 2) - returning 0 ");
388 &((*firstVolume)->volumeBounds()));
391 &((*lastVolume)->volumeBounds()));
393 if (!firstVolumeBounds || !lastVolumeBounds) {
395 "Trk::CylinderVolumeBounds (required) - returning 0 ");
400 bool rCase = fabs(firstVolumeBounds->
innerRadius() -
409 zMin = (*firstVolume)->center().z() - firstVolumeBounds->
halflengthZ();
410 zMax = (*firstVolume)->center().z() + firstVolumeBounds->
halflengthZ();
414 zMin = (*firstVolume)->center().z() - firstVolumeBounds->
halflengthZ();
415 zMax = (*lastVolume)->center().z() + lastVolumeBounds->
halflengthZ();
421 double zPos = 0.5 * (zMin + zMax);
423 std::unique_ptr<Amg::Transform3D> topVolumeTransform =
424 fabs(zPos) > 0.1 ? std::make_unique<Amg::Transform3D>(
Amg::Translation3D(0., 0., zPos)) :
nullptr;
426 auto topVolumeBounds =
428 ? std::make_shared<Trk::CylinderVolumeBounds>(rMin, rMax, 0.5 * fabs(zMax - zMin))
429 : std::make_shared<Trk::CylinderVolumeBounds>(rMax, 0.5 * fabs(zMax - zMin));
431 std::unique_ptr<Trk::BinnedArray<Trk::TrackingVolume>> volumeArray =
432 (rCase) ? m_trackingVolumeArrayCreator->cylinderVolumesArrayInR(volumes)
433 : m_trackingVolumeArrayCreator->cylinderVolumesArrayInZ(volumes);
436 "Creation of TrackingVolume array did not succeed - returning 0 ");
442 std::move(topVolumeTransform),
443 std::move(topVolumeBounds),
446 std::move(volumeArray),
451 if (interGlueTrackingVolume(
452 *topVolume, rCase, buildBoundaryLayers, replaceBoundaryFace)
455 "Problem with inter-glueing of TrackingVolumes (needed) - returning 0 ");
461 "[ end ] return newly created container : " << topVolume->
volumeName());
469 const std::vector<Trk::Layer*>&
layers,
472 std::vector<Trk::CylinderLayer*>& cylinderLayers,
473 std::vector<Trk::DiscLayer*>& discLayers,
484 return StatusCode::FAILURE;
489 if (cylinderVolumeBounds)
ATH_MSG_VERBOSE(
"Cylinder volume bounds are given." );
492 double layerRmin = 10e10;
493 double layerRmax = 0.;
494 double layerZmin = 10e10;
495 double layerZmax = -10e10;
504 for (
auto *
const layerIter :
layers) {
507 double currentRmin = 0.;
508 double currentRmax = 0.;
509 double currentZmin = 0.;
510 double currentZmax = 0.;
520 double currentR = cylBounds->
r();
521 double centerZ = (layerIter->surfaceRepresentation()).center().z();
524 currentRmin = currentR; currentRmax = currentR;
526 currentRmin = currentR-(0.5*(layerIter)->thickness());
527 currentRmax = currentR+(0.5*(layerIter)->thickness());
534 dynamic_cast<const Trk::DiscBounds*
>(&(layerIter->surfaceRepresentation()).bounds());
539 double centerZ = (layerIter->surfaceRepresentation()).center().z();
540 currentRmin = discBounds->
rMin();
541 currentRmax = discBounds->
rMax();
543 currentZmin = centerZ; currentZmax = centerZ;
545 currentZmin = centerZ - (0.5*(layerIter)->thickness());
546 currentZmax = centerZ + (0.5*(layerIter)->thickness());
550 rMinClean =
std::min(rMinClean, currentRmin);
551 rMaxClean =
std::max(rMaxClean, currentRmax);
552 zMinClean =
std::min(zMinClean, currentZmin);
553 zMaxClean =
std::max(zMaxClean, currentZmax);
556 layerRmin =
std::min(layerRmin,currentRmin);
557 layerRmax =
std::max(layerRmax, currentRmax);
558 layerZmin =
std::min(layerZmin,currentZmin);
559 layerZmax =
std::max(layerZmax, currentZmax);
565 double rStepHalf = 0.5*(layerRmax-layerRmin)/(
layers.size()-1);
566 layerRmin -= rStepHalf;
567 layerRmax += rStepHalf;
569 double zStepHalf = 0.5*(layerZmax-layerZmin)/(
layers.size()-1);
570 layerZmin -= zStepHalf;
571 layerZmax += zStepHalf;
575 ATH_MSG_VERBOSE(
"Estimate/check CylinderVolumeBounds from/w.r.t. enclosed layers + envelope covers" );
577 double zEstFromLayerEnv = 0.5*((layerZmax)+(layerZmin));
578 double halflengthFromLayer = 0.5*fabs((layerZmax)-(layerZmin));
580 bool concentric = (zEstFromLayerEnv*zEstFromLayerEnv < 0.001);
583 if (!cylinderVolumeBounds && !
transform) {
590 }
else if (cylinderVolumeBounds && !
transform &&!concentric){
594 else if (
transform && !cylinderVolumeBounds) {
596 double halflengthFromLayer = 0.5*fabs((layerZmax)-(layerZmin));
599 halflengthFromLayer);
603 << layerRmin <<
" / " << layerRmax <<
" / " << layerZmin <<
" / " << layerZmax );
605 ATH_MSG_VERBOSE(
" -> while created bounds are (rMin/rMax/zMin/zMax) = "
607 << zFromTransform-cylinderVolumeBounds->
halflengthZ() <<
" / " << zFromTransform+cylinderVolumeBounds->
halflengthZ() );
611 if (cylinderVolumeBounds) {
613 if (zFromTransform-cylinderVolumeBounds->
halflengthZ() <= layerZmin &&
614 zFromTransform+cylinderVolumeBounds->
halflengthZ() >= layerZmax &&
615 cylinderVolumeBounds->
innerRadius() <= layerRmin &&
617 return StatusCode::SUCCESS;
619 ATH_MSG_WARNING(
"Provided layers are not contained by volume ! Bailing out. " );
620 return StatusCode::FAILURE;
626 return StatusCode::SUCCESS;
632 bool createBoundaryLayers,
633 bool replaceBoundaryFace)
const
645 auto tVolIter = volumes.begin();
646 auto tVolFirst = volumes.begin();
647 auto tVolLast = volumes.end(); --tVolLast;
648 auto tVolEnd = volumes.end();
651 std::vector<Trk::TrackingVolume*> glueVolumesInnerTube;
652 std::vector<Trk::TrackingVolume*> glueVolumesOuterTube;
653 std::vector<Trk::TrackingVolume*> glueVolumesNegativeFace;
654 std::vector<Trk::TrackingVolume*> glueVolumesPositiveFace;
659 for ( ; tVolIter != tVolEnd; ) {
661 ATH_MSG_VERBOSE(
"r-binning: Processing volume '" << (*tVolIter)->volumeName() <<
"'.");
663 if (tVolIter == tVolFirst)
668 if (tVolIter == tVolLast) {
680 for ( ; tVolIter != tVolEnd; ) {
682 ATH_MSG_VERBOSE(
"z-binning: Processing volume '" << (*tVolIter)->volumeName() <<
"'.");
683 if (tVolIter == tVolFirst)
687 if (tVolIter == tVolLast) {
705 return StatusCode::SUCCESS;
712 std::vector<Trk::TrackingVolume*>& vols)
const
721 std::vector<Trk::TrackingVolume*>::const_iterator volIter = gvDescriptor.
glueVolumes(glueFace).begin();
722 std::vector<Trk::TrackingVolume*>::const_iterator volEnd = gvDescriptor.
glueVolumes(glueFace).end();
723 for ( ; volIter != volEnd; ++volIter){
724 ATH_MSG_VERBOSE(
" -> adding volumes : " << (*volIter)->volumeName() );
725 vols.push_back(*volIter);
728 ATH_MSG_VERBOSE( vols.size() <<
" navigation volumes registered as glue volumes." );
732 vols.push_back(&tvol);
742 bool createBoundaryLayers,
743 bool replaceBoundaryFace)
const
750 ATH_MSG_VERBOSE(
"Glue method called with " << (replaceBoundaryFace ?
"joint boundaries." :
"individual boundaries." ) );
752 size_t volOneGlueVols = gvDescriptorOne.
glueVolumes(faceOne).size();
754 << volOneGlueVols <<
" @ " << faceOne );
755 size_t volTwoGlueVols = gvDescriptorTwo.
glueVolumes(faceTwo).size();
757 << volTwoGlueVols <<
" @ " << faceTwo );
761 gvDescriptorOne.
glueVolumes(faceOne)[0] : &tvolOne;
764 gvDescriptorTwo.
glueVolumes(faceTwo)[0] : &tvolTwo;
768 if ( volOneGlueVols <= 1 && volTwoGlueVols <= 1) {
771 <<
" ]-to-one[ "<< glueVolTwo->
volumeName() <<
" @ " << faceTwo <<
" ]" );
772 m_trackingVolumeHelper->glueTrackingVolumes(*glueVolOne,
776 createBoundaryLayers);
777 }
else if (volOneGlueVols <= 1) {
779 <<
" ]-to-many[ "<< tvolTwo.
volumeName() <<
" @ " << faceTwo <<
" ]" );
780 m_trackingVolumeHelper->glueTrackingVolumes(*glueVolOne,
784 createBoundaryLayers,
785 replaceBoundaryFace);
786 }
else if (volTwoGlueVols <= 1 ) {
788 <<
" ]-to-one[ "<< glueVolTwo->
volumeName() <<
" @ " << faceTwo <<
" ]" );
789 m_trackingVolumeHelper->glueTrackingVolumes(*glueVolTwo,
793 createBoundaryLayers,
794 replaceBoundaryFace);
798 <<
" ]-to-many[ "<< tvolTwo.
volumeName() <<
" @ " << faceTwo <<
" ]" );
799 m_trackingVolumeHelper->glueTrackingVolumes(gvDescriptorOne.
glueVolumes(faceOne),
803 createBoundaryLayers,
804 replaceBoundaryFace);
815 ATH_MSG_VERBOSE(
"Creating a CylinderLayer at position " <<
z <<
" and radius " <<
r );
819 std::unique_ptr<Amg::Transform3D>
transform =
829 <<
binsZ <<
" bins in Z. ");
834 layerBinUtilityRPhiZ += layerBinUtility;
839 << binsPhi <<
" / " <<
binsZ <<
" bins in R*phi / Z. ");
842 auto cylinderBounds = std::make_shared<Trk::CylinderBounds>(
r,halflengthZ);
847 cylinderMaterial, thickness,
nullptr,
852 return cylinderLayer;
864 ATH_MSG_VERBOSE(
"Creating a DiscLayer at position " <<
z <<
" and rMin/rMax " << rMin <<
" / " << rMax);
874 << binsR <<
" bins in R. ");
879 << binsPhi <<
" / " << binsR <<
" bins in phi / R. ");
884 auto discBounds = std::make_shared<Trk::DiscBounds>(rMin,rMax);