10 #include "GaudiKernel/SystemOfUnits.h"
35 m_layerArrayCreator(
"Trk::LayerArrayCreator/LayerArrayCreator"),
36 m_trackingVolumeArrayCreator(
"Trk::TrackingVolumeArrayCreator/TrackingVolumeArrayCreator"),
37 m_trackingVolumeHelper(
"Trk::TrackingVolumeHelper/TrackingVolumeHelper"),
39 m_passiveLayerPhiBins(1),
40 m_passiveLayerRzBins(100)
42 declareInterface<ITrackingVolumeCreator>(
this);
63 if (m_layerArrayCreator.retrieve().isFailure())
65 ATH_MSG_FATAL(
"Failed to retrieve tool " << m_layerArrayCreator );
66 return StatusCode::FAILURE;
72 if (m_trackingVolumeArrayCreator.retrieve().isFailure())
74 ATH_MSG_FATAL(
"Failed to retrieve tool " << m_trackingVolumeArrayCreator );
75 return StatusCode::FAILURE;
77 ATH_MSG_DEBUG(
"Retrieved tool " << m_trackingVolumeArrayCreator );
81 if (m_trackingVolumeHelper.retrieve().isFailure())
83 ATH_MSG_FATAL(
"Failed to retrieve tool " << m_trackingVolumeHelper );
84 return StatusCode::FAILURE;
90 return StatusCode::SUCCESS;
95 const std::vector<Trk::Layer*>&
layers,
99 const std::string& volumeName,
116 if (!cylinderBounds){
117 ATH_MSG_WARNING(
"[!] Problem: given bounds were not cylindrical - return 0" );
121 std::vector<Trk::CylinderLayer*> cylLayers;
122 cylLayers.reserve(
layers.size());
123 std::vector<Trk::DiscLayer*> discLayers;
124 discLayers.reserve(
layers.size());
127 double rMinRaw{0.}, rMaxRaw{0.}, zMinRaw{0.}, zMaxRaw{0.};
130 if (estimateAndCheckDimension(
layers,
137 btype).isFailure()) {
138 ATH_MSG_WARNING(
"[!] Problem with given dimensions - return 0 and delete provided objects" );
140 delete cylinderBounds;
146 ( cylinderBounds ? -cylinderBounds->
halflengthZ() : 0. );
148 ( cylinderBounds ? cylinderBounds->
halflengthZ() : 0. );
161 if (!cylinderBounds) {
172 m_layerArrayCreator->cylinderLayerArray(cylLayers,
176 m_layerArrayCreator->discLayerArray(discLayers,
197 const std::vector<Trk::Layer*>&
layers,
203 const std::string& volumeName,
211 ATH_MSG_VERBOSE(
"Create cylindrical TrackingVolume '" << volumeName <<
"'.");
213 << rMin <<
" / " << rMax <<
" / " << zMin <<
" / " << zMax);
216 if (zMin > zMax || rMin > rMax) {
218 << ((zMin > zMax) ?
" zMin > zMax (" :
" rMin > rMax (")
219 << ((zMin > zMax) ? zMin : rMin) <<
" > "
220 << ((zMin > zMax) ? zMax : rMax) <<
" ) - return 0");
225 double halflengthZ = 0.5 * (zMax - zMin);
226 double zPosition = 0.5 * (zMin + zMax);
227 zPosition = fabs(zPosition) < 0.1 ? 0. : zPosition;
239 return createTrackingVolume(
249 unsigned int materialLayers,
251 const std::string& volumeName)
const
255 ATH_MSG_VERBOSE(
"Create cylindrical gap TrackingVolume '" << volumeName <<
"' with (rMin/rMax/zMin/Max) = ");
256 ATH_MSG_VERBOSE(
'\t' << rMin <<
" / " << rMax <<
" / " << zMin <<
" / " << zMax );
259 double min = cylinder ? rMin : zMin;
260 double max = cylinder ? rMax : zMax;
263 std::vector<double> layerPositions;
264 layerPositions.reserve(materialLayers);
265 if (materialLayers > 1){
267 const double step=(
max-
min)/(materialLayers-1);
268 for (
unsigned int il = 0;
il < materialLayers; ++
il)
271 layerPositions.push_back(0.5*(
min+
max));
274 return createGapTrackingVolume(matprop,
293 const std::vector<double>& layerPositions,
295 const std::string& volumeName,
301 << volumeName <<
"' with (rMin/rMax/zMin/Max) = ");
302 ATH_MSG_VERBOSE(
'\t' << rMin <<
" / " << rMax <<
" / " << zMin <<
" / "
306 std::vector<Trk::Layer*>
layers;
307 layers.reserve(layerPositions.size());
309 std::vector<double>::const_iterator layerPropIter = layerPositions.begin();
310 std::vector<double>::const_iterator layerPropEnd = layerPositions.end();
311 for (; layerPropIter != layerPropEnd; ++layerPropIter) {
315 double zMinLayer = zMin;
316 double zMaxLayer = zMax;
318 layers.push_back(createCylinderLayer(0.5 * (zMinLayer + zMaxLayer),
320 fabs(0.5 * (zMaxLayer - zMinLayer)),
321 m_passiveLayerThickness,
322 m_passiveLayerPhiBins,
323 m_passiveLayerRzBins));
327 double rMinLayer = rMin;
328 double rMaxLayer = rMax;
330 layers.push_back(createDiscLayer((*layerPropIter),
333 m_passiveLayerThickness,
334 m_passiveLayerPhiBins,
335 m_passiveLayerRzBins));
339 return createTrackingVolume(
340 layers, matprop, rMin, rMax, zMin, zMax, volumeName, btype);
345 const std::vector<Trk::TrackingVolume*>& volumes,
347 const std::string& volumeName,
348 bool buildBoundaryLayers,
349 bool replaceBoundaryFace)
const
352 if (volumes.size() <= (
unsigned int)1) {
353 ATH_MSG_WARNING(
"None (only one) TrackingVolume given to create container "
354 "volume (min required: 2) - returning 0 ");
360 << volumeName <<
"' with " << volumes.size()
364 auto firstVolume = volumes.begin();
365 auto lastVolume = volumes.end();
367 for (
unsigned int ivol = 0; firstVolume != lastVolume;
368 ++firstVolume, ++ivol) {
370 << ivol <<
") is : " << (*firstVolume)->volumeName());
372 " at position : " <<
Amg::toString((*firstVolume)->center()));
377 firstVolume = volumes.begin();
380 if (firstVolume == lastVolume) {
381 ATH_MSG_WARNING(
"Only one TrackingVolume given to create Top level volume "
382 "(min required: 2) - returning 0 ");
389 &((*firstVolume)->volumeBounds()));
392 &((*lastVolume)->volumeBounds()));
394 if (!firstVolumeBounds || !lastVolumeBounds) {
396 "Trk::CylinderVolumeBounds (required) - returning 0 ");
401 bool rCase = fabs(firstVolumeBounds->
innerRadius() -
410 zMin = (*firstVolume)->center().z() - firstVolumeBounds->
halflengthZ();
411 zMax = (*firstVolume)->center().z() + firstVolumeBounds->
halflengthZ();
415 zMin = (*firstVolume)->center().z() - firstVolumeBounds->
halflengthZ();
416 zMax = (*lastVolume)->center().z() + lastVolumeBounds->
halflengthZ();
422 double zPos = 0.5 * (zMin + zMax);
426 if (topVolumeTransform)
435 (rCase) ? m_trackingVolumeArrayCreator->cylinderVolumesArrayInR(volumes)
436 : m_trackingVolumeArrayCreator->cylinderVolumesArrayInZ(volumes);
439 "Creation of TrackingVolume array did not succeed - returning 0 ");
440 delete topVolumeTransform;
441 delete topVolumeBounds;
455 if (interGlueTrackingVolume(
456 *topVolume, rCase, buildBoundaryLayers, replaceBoundaryFace)
459 "Problem with inter-glueing of TrackingVolumes (needed) - returning 0 ");
465 "[ end ] return newly created container : " << topVolume->
volumeName());
473 const std::vector<Trk::Layer*>&
layers,
476 std::vector<Trk::CylinderLayer*>& cylinderLayers,
477 std::vector<Trk::DiscLayer*>& discLayers,
488 return StatusCode::FAILURE;
493 if (cylinderVolumeBounds)
ATH_MSG_VERBOSE(
"Cylinder volume bounds are given." );
496 double layerRmin = 10e10;
497 double layerRmax = 0.;
498 double layerZmin = 10e10;
499 double layerZmax = -10e10;
508 for (
auto *
const layerIter :
layers) {
511 double currentRmin = 0.;
512 double currentRmax = 0.;
513 double currentZmin = 0.;
514 double currentZmax = 0.;
524 double currentR = cylBounds->
r();
525 double centerZ = (layerIter->surfaceRepresentation()).center().z();
528 currentRmin = currentR; currentRmax = currentR;
530 currentRmin = currentR-(0.5*(layerIter)->thickness());
531 currentRmax = currentR+(0.5*(layerIter)->thickness());
538 dynamic_cast<const Trk::DiscBounds*
>(&(layerIter->surfaceRepresentation()).bounds());
543 double centerZ = (layerIter->surfaceRepresentation()).center().z();
544 currentRmin = discBounds->
rMin();
545 currentRmax = discBounds->
rMax();
547 currentZmin = centerZ; currentZmax = centerZ;
549 currentZmin = centerZ - (0.5*(layerIter)->thickness());
550 currentZmax = centerZ + (0.5*(layerIter)->thickness());
554 rMinClean =
std::min(rMinClean, currentRmin);
555 rMaxClean =
std::max(rMaxClean, currentRmax);
556 zMinClean =
std::min(zMinClean, currentZmin);
557 zMaxClean =
std::max(zMaxClean, currentZmax);
560 layerRmin =
std::min(layerRmin,currentRmin);
561 layerRmax =
std::max(layerRmax, currentRmax);
562 layerZmin =
std::min(layerZmin,currentZmin);
563 layerZmax =
std::max(layerZmax, currentZmax);
569 double rStepHalf = 0.5*(layerRmax-layerRmin)/(
layers.size()-1);
570 layerRmin -= rStepHalf;
571 layerRmax += rStepHalf;
573 double zStepHalf = 0.5*(layerZmax-layerZmin)/(
layers.size()-1);
574 layerZmin -= zStepHalf;
575 layerZmax += zStepHalf;
579 ATH_MSG_VERBOSE(
"Estimate/check CylinderVolumeBounds from/w.r.t. enclosed layers + envelope covers" );
581 double zEstFromLayerEnv = 0.5*((layerZmax)+(layerZmin));
582 double halflengthFromLayer = 0.5*fabs((layerZmax)-(layerZmin));
584 bool concentric = (zEstFromLayerEnv*zEstFromLayerEnv < 0.001);
587 if (!cylinderVolumeBounds && !
transform) {
594 }
else if (cylinderVolumeBounds && !
transform &&!concentric){
598 else if (
transform && !cylinderVolumeBounds) {
600 double halflengthFromLayer = 0.5*fabs((layerZmax)-(layerZmin));
603 halflengthFromLayer);
607 << layerRmin <<
" / " << layerRmax <<
" / " << layerZmin <<
" / " << layerZmax );
609 ATH_MSG_VERBOSE(
" -> while created bounds are (rMin/rMax/zMin/zMax) = "
611 << zFromTransform-cylinderVolumeBounds->
halflengthZ() <<
" / " << zFromTransform+cylinderVolumeBounds->
halflengthZ() );
615 if (cylinderVolumeBounds) {
617 if (zFromTransform-cylinderVolumeBounds->
halflengthZ() <= layerZmin &&
618 zFromTransform+cylinderVolumeBounds->
halflengthZ() >= layerZmax &&
619 cylinderVolumeBounds->
innerRadius() <= layerRmin &&
621 return StatusCode::SUCCESS;
623 ATH_MSG_WARNING(
"Provided layers are not contained by volume ! Bailing out. " );
624 return StatusCode::FAILURE;
630 return StatusCode::SUCCESS;
636 bool createBoundaryLayers,
637 bool replaceBoundaryFace)
const
649 auto tVolIter = volumes.begin();
650 auto tVolFirst = volumes.begin();
651 auto tVolLast = volumes.end(); --tVolLast;
652 auto tVolEnd = volumes.end();
655 std::vector<Trk::TrackingVolume*> glueVolumesInnerTube;
656 std::vector<Trk::TrackingVolume*> glueVolumesOuterTube;
657 std::vector<Trk::TrackingVolume*> glueVolumesNegativeFace;
658 std::vector<Trk::TrackingVolume*> glueVolumesPositiveFace;
663 for ( ; tVolIter != tVolEnd; ) {
665 ATH_MSG_VERBOSE(
"r-binning: Processing volume '" << (*tVolIter)->volumeName() <<
"'.");
667 if (tVolIter == tVolFirst)
672 if (tVolIter == tVolLast) {
684 for ( ; tVolIter != tVolEnd; ) {
686 ATH_MSG_VERBOSE(
"z-binning: Processing volume '" << (*tVolIter)->volumeName() <<
"'.");
687 if (tVolIter == tVolFirst)
691 if (tVolIter == tVolLast) {
709 return StatusCode::SUCCESS;
716 std::vector<Trk::TrackingVolume*>& vols)
const
725 std::vector<Trk::TrackingVolume*>::const_iterator volIter = gvDescriptor.
glueVolumes(glueFace).begin();
726 std::vector<Trk::TrackingVolume*>::const_iterator volEnd = gvDescriptor.
glueVolumes(glueFace).end();
727 for ( ; volIter != volEnd; ++volIter){
728 ATH_MSG_VERBOSE(
" -> adding volumes : " << (*volIter)->volumeName() );
729 vols.push_back(*volIter);
732 ATH_MSG_VERBOSE( vols.size() <<
" navigation volumes registered as glue volumes." );
736 vols.push_back(&tvol);
746 bool createBoundaryLayers,
747 bool replaceBoundaryFace)
const
754 ATH_MSG_VERBOSE(
"Glue method called with " << (replaceBoundaryFace ?
"joint boundaries." :
"individual boundaries." ) );
756 size_t volOneGlueVols = gvDescriptorOne.
glueVolumes(faceOne).size();
758 << volOneGlueVols <<
" @ " << faceOne );
759 size_t volTwoGlueVols = gvDescriptorTwo.
glueVolumes(faceTwo).size();
761 << volTwoGlueVols <<
" @ " << faceTwo );
765 gvDescriptorOne.
glueVolumes(faceOne)[0] : &tvolOne;
768 gvDescriptorTwo.
glueVolumes(faceTwo)[0] : &tvolTwo;
772 if ( volOneGlueVols <= 1 && volTwoGlueVols <= 1) {
775 <<
" ]-to-one[ "<< glueVolTwo->
volumeName() <<
" @ " << faceTwo <<
" ]" );
776 m_trackingVolumeHelper->glueTrackingVolumes(*glueVolOne,
780 createBoundaryLayers);
781 }
else if (volOneGlueVols <= 1) {
783 <<
" ]-to-many[ "<< tvolTwo.
volumeName() <<
" @ " << faceTwo <<
" ]" );
784 m_trackingVolumeHelper->glueTrackingVolumes(*glueVolOne,
788 createBoundaryLayers,
789 replaceBoundaryFace);
790 }
else if (volTwoGlueVols <= 1 ) {
792 <<
" ]-to-one[ "<< glueVolTwo->
volumeName() <<
" @ " << faceTwo <<
" ]" );
793 m_trackingVolumeHelper->glueTrackingVolumes(*glueVolTwo,
797 createBoundaryLayers,
798 replaceBoundaryFace);
802 <<
" ]-to-many[ "<< tvolTwo.
volumeName() <<
" @ " << faceTwo <<
" ]" );
803 m_trackingVolumeHelper->glueTrackingVolumes(gvDescriptorOne.
glueVolumes(faceOne),
807 createBoundaryLayers,
808 replaceBoundaryFace);
819 ATH_MSG_VERBOSE(
"Creating a CylinderLayer at position " <<
z <<
" and radius " <<
r );
823 std::unique_ptr<Amg::Transform3D>
transform =
824 (fabs(
z) > 0.1) ? std::make_unique<Amg::Transform3D>() :
nullptr;
836 <<
binsZ <<
" bins in Z. ");
841 layerBinUtilityRPhiZ += layerBinUtility;
846 << binsPhi <<
" / " <<
binsZ <<
" bins in R*phi / Z. ");
861 delete cylinderMaterial;
863 return cylinderLayer;
875 ATH_MSG_VERBOSE(
"Creating a DiscLayer at position " <<
z <<
" and rMin/rMax " << rMin <<
" / " << rMax);
878 std::unique_ptr<Amg::Transform3D>
transform =
879 fabs(
z) > 0.1 ? std::make_unique<Amg::Transform3D>() :
nullptr;
888 << binsR <<
" bins in R. ");
893 << binsPhi <<
" / " << binsR <<
" bins in phi / R. ");