25 #include "GaudiKernel/SystemOfUnits.h"
31 Trk::TrackingVolumeManipulator()
57 return StatusCode::SUCCESS;
65 return StatusCode::SUCCESS;
68 std::unique_ptr<Trk::TrackingGeometry>
70 std::vector<InDet::LayerSetup>& layerSetups,
71 double maximumLayerExtendZ,
72 double maximumLayerRadius,
73 double envelopeVolumeHalfZ,
74 double envelopeVolumeRadius)
const
78 std::vector<Trk::TrackingVolume*> idVolumes;
80 std::vector<InDet::LayerSetup> layerSetupCache;
83 double lastFlushRadius = 0.;
88 "[ STEP 2 ] : Looping through the layer setups and flush them into the "
89 "ID detector volume vector.");
90 for (
auto& lSetup : layerSetups) {
93 << lSetup.identification
94 <<
"' ] being processed, current cache size is "
95 << layerSetupCache.size());
97 " -> estimated dimensions for this layer setup are");
99 << lSetup.minRadiusCenter <<
" / "
100 << lSetup.maxRadiusCenter <<
" / "
101 << lSetup.zExtendCenter);
105 if (layerSetupCache.empty() ||
setupFitsCache(lSetup, layerSetupCache)) {
107 " -> cache is empty or new sector fits cache setup - add "
108 "this one to the cache.");
112 " -> new sector does not fit the current cache specs -> "
113 "flushing the cache.");
117 (layerSetupCache[layerSetupCache.size() - 1].rMax + lSetup.rMin);
120 layerSetupCache, lastFlushRadius, flushRadius, maximumLayerExtendZ);
122 idVolumes.push_back(fVolume);
124 lastFlushRadius = flushRadius;
127 layerSetupCache.push_back(lSetup);
131 if (!layerSetupCache.empty()) {
133 "[ STEP 3 ] : Flush the remaining cache into the ID detector volume "
136 double flushRadius = 0.5 * (maximumLayerRadius + envelopeVolumeRadius);
138 layerSetupCache, lastFlushRadius, flushRadius, maximumLayerExtendZ);
140 idVolumes.push_back(fVolume);
141 lastFlushRadius = flushRadius;
144 ATH_MSG_DEBUG(
"[ STEP 4 ] : Create the ID detector volumes");
149 -maximumLayerExtendZ, maximumLayerExtendZ, 1,
true,
151 idVolumes.push_back(centralEnclosure);
153 std::string volumeName =
m_namespace +
"Detectors::Container";
162 -envelopeVolumeHalfZ, -maximumLayerExtendZ, 1,
false,
169 maximumLayerExtendZ, envelopeVolumeHalfZ, 1,
false,
172 std::vector<Trk::TrackingVolume*> enclosedVolumes;
173 enclosedVolumes.push_back(negativeEnclosure);
174 enclosedVolumes.push_back(idContainer);
175 enclosedVolumes.push_back(positiveEnclosure);
184 auto trackingGeometry =
185 std::make_unique<Trk::TrackingGeometry>(enclosedDetector);
191 return trackingGeometry;
196 const std::vector<Trk::Layer*>&
layers,
205 double thickness =
layer->thickness();
224 double rMinD =dBounds->
rMin();
225 double rMaxD =dBounds->
rMax();
239 std::vector<std::pair<double,double>> radii;
241 for (
auto *
const ring :
layers) {
243 const Trk::Surface& ringSurface = ring->surfaceRepresentation();
247 double zpos = ringSurface.
center().z();
248 double rMin = ringBounds->
rMin();
249 double rMax = ringBounds->
rMax();
252 ATH_MSG_DEBUG(
" -> Ring at z-position " << zpos <<
" - with rMin/rMax = " << rMin <<
"/" << rMax );
257 std::vector<std::pair<double,double>> tmpradii;
259 for (
auto& rs: radii) {
261 for (
auto& tmprs: tmpradii) {
262 if ((rs.first<tmprs.second and rs.second>tmprs.first) ) {
263 tmprs.first =
std::min(tmprs.first ,rs.first );
264 tmprs.second =
std::max(tmprs.second,rs.second);
270 tmpradii.push_back(rs);
274 rmins.clear(); rmaxs.clear();
275 for (
auto&
r: tmpradii) {
276 rmins.push_back(
r.first);
277 rmaxs.push_back(
r.second);
281 return (rmins.size() > 1 );
286 const std::vector<Trk::Layer*>&
layers,
291 const std::string& volumeName,
293 bool doAdjustOuterRadius)
const
297 std::vector<double> ringRmins;
298 std::vector<double> ringRmaxa;
300 ATH_MSG_INFO(
"Ring layout is present for volume '" << volumeName <<
"' dealing with it.");
302 std::vector<Trk::TrackingVolume* > ringVolumes;
303 std::vector<Trk::TrackingVolume* > const_ringVolumes;
306 std::vector< std::vector<Trk::Layer*> > groupedDiscs(ringRmins.size(), std::vector<Trk::Layer*>() );
308 for (
auto *ring :
layers){
310 const Trk::Surface& ringSurface = ring->surfaceRepresentation();
314 double rMax = ringBounds->
rMax();
317 for (
auto& rm : ringRmaxa){
323 if (dring) groupedDiscs[rPos].push_back(dring);
327 std::vector< std::vector<Trk::Layer*> > mergedLayers;
328 std::vector< float > mergedRmax;
329 std::vector< std::vector< int > >
merge;
330 std::vector<int> laySet(1,0);
merge.push_back(laySet);
331 double rCurr = ringRmaxa[0];
332 mergedRmax.push_back(rCurr);
333 for (
int idset = 1; idset <
int(groupedDiscs.size()); idset++){
335 merge.back().push_back(idset);
336 if (ringRmaxa[idset]>mergedRmax.back()) mergedRmax.back()=ringRmaxa[idset];
338 merge.emplace_back(1,idset);
339 mergedRmax.push_back(ringRmaxa[idset]);
341 rCurr = ringRmaxa[idset];
343 for (
const auto& layset :
merge ) {
344 std::vector<Trk::Layer*> ringSet;
345 for (
const auto& lay : layset ) {
346 for (
auto *ring : groupedDiscs[lay]) {
347 float zPos = ring->surfaceRepresentation().center().z();
348 if (ringSet.empty() || zPos>ringSet.back()->surfaceRepresentation().center().z()) ringSet.push_back(ring);
351 while (lit!=ringSet.end() && zPos>(*lit)->surfaceRepresentation().center().z()) ++lit;
352 ringSet.insert(lit,ring);
360 for (
int idset = 0; idset <
int(mergedLayers.size()); idset++){
364 if(idset==
int(mergedLayers.size())-1 && !doAdjustOuterRadius) crmax = outerRadius;
366 std::string ringVolumeName = volumeName+
"Ring"+
std::to_string(idset);
377 ringVolumes.push_back(ringVolume);
378 const_ringVolumes.push_back(ringVolume);
383 ATH_MSG_INFO(
" -> adjusting the outer radius to the last ring at " << outerRadius );
384 ATH_MSG_INFO(
" -> created " << ringVolumes.size() <<
" ring volumes for Volume '" << volumeName <<
"'.");
386 if (ringVolumes.size()==1)
387 return ringVolumes.at(0);
397 innerRadius,outerRadius,
405 const std::vector<Trk::TrackingVolume*>& negVolumes,
406 const std::vector<Trk::TrackingVolume*>& centralVolumes,
407 const std::vector<Trk::TrackingVolume*>& posVolumes,
408 const std::string& baseName)
const
410 ATH_MSG_VERBOSE(
'\t' <<
'\t'<<
"Pack provided Volumes from '" << baseName <<
"' triple into a container volume. " );
412 unsigned int negVolSize = negVolumes.size();
413 unsigned int cenVolSize = centralVolumes.size();
414 unsigned int posVolSize = posVolumes.size();
419 std::string volumeBase =
m_namespace+
"Containers::"+baseName;
424 volumeBase+
"::NegativeSector",
427 (negVolSize ? negVolumes[0] :
nullptr);
431 volumeBase+
"::CentralSector",
434 (cenVolSize ? centralVolumes[0] :
nullptr) ;
439 volumeBase+
"::PositiveSector",
442 (posVolSize ? posVolumes[0] :
nullptr);
444 if (!negativeVolume && !positiveVolume){
445 ATH_MSG_DEBUG(
"No negative/positive sector given - no packing needed, returning central container!" );
446 return centralVolume;
449 std::vector<Trk::TrackingVolume*> tripleVolumes;
450 if (negativeVolume) tripleVolumes.push_back(negativeVolume);
451 if (centralVolume) tripleVolumes.push_back(centralVolume);
452 if (positiveVolume) tripleVolumes.push_back(positiveVolume);
460 return tripleContainer;
470 double zPosCentral)
const
484 volumeBase +
"::NegativeEndcap",
496 volumeBase +
"::Barrel",
505 volumeBase +
"::PositiveEndcap",
511 '\t' <<
'\t' <<
"Volumes have been created, now pack them into a triple.");
518 std::vector<Trk::TrackingVolume*> tripleVolumes;
519 tripleVolumes.push_back(negativeVolume);
520 tripleVolumes.push_back(centralVolume);
521 tripleVolumes.push_back(positiveVolume);
532 ATH_MSG_VERBOSE(
'\t' <<
'\t' <<
"Created container volume with bounds: "
535 return tripleContainer;
542 const std::string& idName,
544 const std::vector<Trk::Layer*>& negLayers,
545 const std::vector<Trk::Layer*>& cenLayers,
546 const std::vector<Trk::Layer*>& posLayers,
551 double cenMinR = 10e10;
553 double cenMinZ = 10e10;
555 double posMinR = 10e10;
557 double posMinZ = 10e10;
564 if (posMaxZ > maxZ) {
565 ATH_MSG_WARNING(
"Estimated z extended of central sector bigger than maximal z extened. Resetting - may lose layers though.");
567 }
else if (posMaxZ > maxZ) {
568 ATH_MSG_WARNING(
"Estimated z extended of endcap sector bigger than maximal z extened. Resetting - may lose layers though.");
572 if (cenMaxR > maxR) {
573 ATH_MSG_WARNING(
"Estimated r extended of central sector bigger than maximal r extened. Resetting - may lose layers though.");
576 if (posMaxR > maxR) {
577 ATH_MSG_WARNING(
"Estimated r extended of endcap sector bigger than maximal r extened. Resetting - may lose layers though.");
603 std::vector<InDet::LayerSetup>& layerSetupCache)
const
606 double maxCenterCacheZ = 0.;
608 double minEndcapCacheZ = 10e10;
610 bool fullSectorSetup =
false;
612 for (
const auto& lCacheSetup : layerSetupCache){
613 takeBigger(maxCenterCacheZ, lCacheSetup.zExtendCenter);
614 takeSmaller(minEndcapCacheZ, lCacheSetup.minZextendEndcap);
616 fullSectorSetup = lCacheSetup.buildEndcap ? true : fullSectorSetup;
620 if (!fullSectorSetup) {
621 ATH_MSG_VERBOSE(
" -> only central sector being built, flush the cache ... ");
626 ATH_MSG_VERBOSE(
" -> cache endcap extend reaches into new central sector, flush the cache ... ");
631 ATH_MSG_VERBOSE(
" -> sector fully fits into cache! Add it and start synchronising ...");
635 double newSectorZ = 0.5*(newCenterMaxZ+newEndcapMinZ);
637 for (
auto& lCacheSetup : layerSetupCache)
638 lCacheSetup.zSector = newSectorZ;
639 layerSetup.
zSector = newSectorZ;
650 (std::vector<InDet::LayerSetup>& layerSetupCache,
653 double extendZ)
const
658 if (layerSetupCache.size() == 1 ){
659 ATH_MSG_VERBOSE(
" -> single sector setup - synchronising from inner (" << innerRadius <<
") to outer (" << outerRadius <<
") radius.");
660 ATH_MSG_VERBOSE(
" -> setup identification : " << layerSetupCache[0].identification );
662 flushVolume = layerSetupCache[0].buildEndcap ?
664 innerRadius, outerRadius,
665 extendZ,layerSetupCache[0].zSector) :
668 innerRadius,outerRadius,
670 layerSetupCache[0].identification,
674 ATH_MSG_VERBOSE(
" -> setup with " << layerSetupCache.size() <<
" entries - synchronising from inner (" << innerRadius <<
") to outer (" << outerRadius <<
") radius.");
676 std::vector<Trk::TrackingVolume*> negVolumes;
677 std::vector<Trk::TrackingVolume*> centralVolumes;
678 std::vector<Trk::TrackingVolume*> posVolumes;
679 std::string combinedName;
680 for (
size_t ilS = 0; ilS < layerSetupCache.size(); ++ilS){
682 double irE = ilS ? 0.5*(layerSetupCache[ilS].minRadiusEndcap+layerSetupCache[ilS-1].maxRadiusEndcap) : innerRadius;
683 double irC = ilS ? 0.5*(layerSetupCache[ilS].minRadiusCenter+layerSetupCache[ilS-1].maxRadiusCenter) : innerRadius;
685 double orE = ((ilS+1)==layerSetupCache.size()) ? outerRadius : 0.5*(layerSetupCache[ilS+1].minRadiusEndcap+layerSetupCache[ilS].maxRadiusEndcap);
686 double orC = ((ilS+1)==layerSetupCache.size()) ? outerRadius : 0.5*(layerSetupCache[ilS+1].minRadiusCenter+layerSetupCache[ilS].maxRadiusCenter);
688 if(ilS==layerSetupCache.size()-1) {
690 ATH_MSG_VERBOSE(
" --> adjust volumes to same extends: orE=" << orE <<
" orC=" << orC);
691 if(orE>orC) orC=orE;
else orE=orC;
695 layerSetupCache[ilS].negativeLayers,
699 -layerSetupCache[ilS].zSector,
700 layerSetupCache[ilS].identification +
"::NegativeEndcap",
705 layerSetupCache[ilS].centralLayers,
709 -layerSetupCache[ilS].zSector,
710 layerSetupCache[ilS].zSector,
711 layerSetupCache[ilS].identification +
"::Barrel",
714 layerSetupCache[ilS].positiveLayers,
717 layerSetupCache[ilS].zSector,
719 layerSetupCache[ilS].identification +
"::PositiveEndcap",
727 negVolumes.push_back(nVolume);
728 centralVolumes.push_back(cVolume);
729 posVolumes.push_back(pVolume);
731 combinedName +=
"_"+layerSetupCache[ilS].identification;
734 flushVolume =
packVolumeTriple(negVolumes,centralVolumes,posVolumes,combinedName);
737 layerSetupCache.clear();
748 std::map < float , std::vector<Trk::Layer*> > locationAndLayers;
754 for (
auto *lay : lays) {
755 float zpos= lay->surfaceRepresentation().center().z();
756 float thick = 0.5*lay->thickness();
758 bool foundZoverlap =
false;
759 for (
auto& singlePosLayer : locationAndLayers) {
760 if (abs(zpos - singlePosLayer.first) < thick) {
761 singlePosLayer.second.push_back(lay);
762 foundZoverlap =
true;
769 if (not foundZoverlap) {
770 locationAndLayers[zpos] = std::vector<Trk::Layer*>();
771 locationAndLayers[zpos].push_back(lay);
778 if (lays.size()>locationAndLayers.size()) {
779 std::vector<Trk::Layer*> mergedDiscLayers;
780 for (
auto& singlePosLayer : locationAndLayers) {
782 if (nd) mergedDiscLayers.push_back(nd);
784 ATH_MSG_WARNING(
"radial merge of rings failed, return the input layer set");
788 return mergedDiscLayers;
798 if (inputDiscs.size()==1)
799 return inputDiscs.at(0);
802 std::pair<float,float> zb(1.e5,-1.e5);
804 std::vector< std::pair<float,float> > rbounds;
805 std::vector<size_t> discOrder;
807 for (
const auto * lay : inputDiscs ) {
808 zb.first = fmin( zb.first, lay->surfaceRepresentation().center().z()-0.5*lay->thickness());
809 zb.second = fmax( zb.second, lay->surfaceRepresentation().center().z()+0.5*lay->thickness());
815 float r =
db->rMin();
816 if (rbounds.empty() ||
r>rbounds.back().first) {
817 rbounds.emplace_back(
r,
db->rMax());
818 discOrder.push_back(
id);
820 int ir=rbounds.size()-1;
825 auto rboundsInsertionPt(rbounds.begin());
826 std::advance(rboundsInsertionPt,
ir+1);
827 rbounds.insert(rboundsInsertionPt,std::pair<float,float> (
r,
db->rMax()));
828 auto discOrderInsertionPt(discOrder.begin());
829 std::advance(discOrderInsertionPt,
ir+1);
830 discOrder.insert(discOrderInsertionPt,
id);
835 std::vector<float> rsteps;
836 std::vector<Trk::Surface*> surfs;
837 std::vector<Trk::BinUtility*>* binUtils=
new std::vector<Trk::BinUtility*>();
838 rsteps.push_back(rbounds[0].
first);
839 for (
unsigned int id=0;
id<discOrder.size();
id++) {
840 unsigned int index=discOrder[
id];
848 if (
id+1<discOrder.size()) rsteps.push_back( 0.5*(rbounds[
id].
second+rbounds[
id+1].
first));
850 surfs.insert(surfs.end(),ringSurf.begin(),ringSurf.end());
854 rsteps.push_back(rbounds.back().second);
856 std::vector< std::pair< Trk::SharedObject<Trk::Surface>,
Amg::Vector3D > > surfaces;
857 for (
auto *
sf : surfs ) {
859 std::pair< Trk::SharedObject<Trk::Surface>,
Amg::Vector3D > surfaceOrder(sharedSurface,
sf->center());
860 surfaces.push_back(surfaceOrder);
866 auto mergeBA = std::make_unique<Trk::BinnedArray1D1D<Trk::Surface>>(
872 std::vector<Trk::BinUtility*>* clonedBinUtils =
new std::vector<Trk::BinUtility*>();
873 for (
auto *bu : *binUtils) clonedBinUtils->push_back(bu->clone());
874 auto olDescriptor = std::make_unique<InDet::DiscOverlapDescriptor>(mergeBA.get(),clonedBinUtils,
true);
877 double disc_thickness = std::fabs(zb.second-zb.first);
878 double disc_pos = (zb.first+zb.second)*0.5;
890 *(inputDiscs[0]->layerMaterialProperties()),
892 std::move(olDescriptor));
895 for (
const auto *
sf : layerSurfaces) {
897 const std::vector<const Trk::Surface*>& allSurfacesVector = detElement->
surfaces();
898 for (
const auto *subsf : allSurfacesVector){
903 for (
const auto *disc : inputDiscs) {