37 std::vector<Obj*> toRawVec(
const std::vector<std::shared_ptr<Obj>>& in) {
39 std::vector<Obj*>
out{};
40 out.reserve(in.size());
41 for (
const std::shared_ptr<Obj>&
obj : in) {
42 out.emplace_back(
obj.get());
53 declareInterface<ITrackingVolumeHelper>(
this);
65 return StatusCode::SUCCESS;
74 bool buildBoundaryLayer)
const
80 if (buildBoundaryLayer){
84 Surface& firstFaceSurface = bSurfacesFirst[firstFace]->surfaceRepresentation();
85 Surface& secondFaceSurface = bSurfacesSecond[secondFace]->surfaceRepresentation();
92 std::shared_ptr<Layer> mLayer = std::make_shared<MaterialLayer>(firstFaceSurface, *lmps);
93 ATH_MSG_VERBOSE(
"Set MaterialLayer to the BoundarySurface of first volume." );
95 ATH_MSG_VERBOSE(
"Set MaterialLayer to the BoundarySurface of second volume.");
104 const std::vector<TrackingVolume*>& secondVolumes,
106 bool buildBoundaryLayer,
107 bool boundaryFaceExchange)
const
112 for (
const auto & volIter : secondVolumes)
116 std::shared_ptr<Layer> mLayer{};
119 if (buildBoundaryLayer){
126 mLayer = std::make_unique<MaterialLayer>(firstFaceSurface, *lmps);
127 ATH_MSG_VERBOSE(
"Set MaterialLayer to the BoundarySurface of first volume (may be shared with second volume)." );
132 if (secondVolumes.size() == 1) {
151 if (boundaryFaceExchange){
153 ATH_MSG_VERBOSE(
"Creating a joint boundary surface for 1-to-n glueing case.");
157 for (
const auto & volIter: secondVolumes )
162 for (
const auto & volIter: secondVolumes ) {
169 if (currentVolBounds && currentVolBounds->
innerRadius() < 10
e-3)
179 Surface& secondFaceSurface = volIter->boundarySurfaces()[secondFace]->surfaceRepresentation();
190 const std::vector<TrackingVolume*>& secondVolumes,
192 bool buildBoundaryLayer,
193 bool boundaryFaceExchange)
const
200 std::unique_ptr<Surface> mLayerSurface;
201 std::shared_ptr<Layer> mLayer;
203 ATH_MSG_VERBOSE(
"Glue configuration firstFace | secondFace = " << firstFace <<
" | " << secondFace );
206 if (firstFace < 2 && secondFace < 2 ) {
211 if (buildBoundaryLayer || boundaryFaceExchange){
212 double rmin = 10e10;
double rmax = 0;
double boundaryz = 0.;
double centerzOne = 0.;
213 for (
const auto & volIter : firstVolumes ){
219 boundaryz = volIter->boundarySurfaces()[firstFace]->surfaceRepresentation().center().z();
221 centerzOne = volIter->center().z();
223 if (buildBoundaryLayer){
227 mLayerSurface = std::make_unique<DiscSurface>(mLayerTransform, rmin, rmax);
233 mLayer = std::make_unique<MaterialLayer>(std::move(mLayerSurface), *lmps);
236 if (boundaryFaceExchange){
238 ATH_MSG_VERBOSE(
"Creating a joint boundary surface for n-to-n glueing case.");
240 double centerzTwo = secondVolumes[secondVolumes.size()-1]->center().z();
244 DiscSurface dSurface(boundaryTransform, rmin, rmax);
246 if (centerzTwo < centerzOne){
256 ATH_MSG_VERBOSE(
"Set MaterialLayer to the BoundarySurface of volume from second array." );
260 for (
const auto & volIter : firstVolumes){
261 ATH_MSG_VERBOSE(
" -> first array : setting a newly created boundary surface to " << volIter->volumeName());
264 for (
const auto & volIter : secondVolumes){
265 ATH_MSG_VERBOSE(
" -> second array : setting a newly created boundary surface to " << volIter->volumeName());
277 if (buildBoundaryLayer || boundaryFaceExchange){
279 double zmin = 10e10;
double zmax = -10e10;
double boundaryr = 0.;
double volumerOne = 0.;
double volumerTwo = 10e10;
280 for (
const auto & volIter : firstVolumes ){
286 boundaryr = volIter->boundarySurfaces()[firstFace]->surfaceRepresentation().bounds().r();
292 if (buildBoundaryLayer){
293 std::unique_ptr<Amg::Transform3D> mLayerTransform =
296 : std::make_unique < Amg::Transform3D>();
304 if (lmps) mLayer = std::make_unique<MaterialLayer>(
305 std::shared_ptr<Surface>(std::move(mLayerSurface)),
309 if (boundaryFaceExchange) {
311 ATH_MSG_VERBOSE(
"Creating a joint boundary surface for n-to-n glueing case.");
313 std::unique_ptr<Amg::Transform3D> boundaryTransform =
316 : std::make_unique<Amg::Transform3D>();
328 if (volumerTwo < volumerOne){
330 navArrayTwo = navArrayOne;
331 navArrayOne = navArraySwap;
340 ATH_MSG_VERBOSE(
"Set MaterialLayer to the BoundarySurface of volume from second array.");
345 for (
const auto & volIter : firstVolumes){
346 ATH_MSG_VERBOSE(
" -> first array : setting a newly created boundary surface to " << volIter->volumeName());
349 for (
const auto & volIter : secondVolumes){
350 ATH_MSG_VERBOSE(
" -> second array : setting a newly created boundary surface to " << volIter->volumeName());
362 ATH_MSG_VERBOSE(
"Leaving individual boundary surfaces for n-to-n glueing case.");
369 for (
const auto & tVolIter: firstVolumes) {
373 ATH_MSG_VERBOSE(
"Set outsideTrackingVolumeArray at face " << firstFace <<
" to " << (*tVolIter).volumeName() );
376 ATH_MSG_VERBOSE(
"Set insideTrackingVolumeArray at face " << firstFace <<
" to " << (*tVolIter).volumeName() );
380 ATH_MSG_VERBOSE(
"Set MaterialLayer to the BoundarySurface of volume from first array." );
381 Surface& firstFaceSurface = tVolIter->boundarySurfaces()[firstFace]->surfaceRepresentation();
389 for (
const auto & tVolIter : secondVolumes) {
392 ATH_MSG_VERBOSE(
"Set outsideTrackingVolumeArray at face " << secondFace <<
" to " << (*tVolIter).volumeName() );
395 ATH_MSG_VERBOSE(
"Set insideTrackingVolumeArray at face " << secondFace <<
" to " << (*tVolIter).volumeName() );
399 ATH_MSG_VERBOSE(
"Set MaterialLayer to the BoundarySurface of volume from second array." );
400 Surface& secondFaceSurface = tVolIter->boundarySurfaces()[secondFace]->surfaceRepresentation();
420 if (!cyl1 || !cyl2) {
421 ATH_MSG_ERROR(
"TrackingVolumeHelper::glueTrackingVolumeArrays: input volumes not cylinders, return 0" );
422 return enclosingVolume;
424 if (cyl1->halfPhiSector()!=
M_PI || cyl2->halfPhiSector()!=
M_PI ) {
425 ATH_MSG_ERROR(
"TrackingVolumeHelper::glueTrackingVolumeArrays: not coded for cylinder Phi sectors yet, return 0" );
426 return enclosingVolume;
435 std::vector<TrackingVolume*> vols;
439 vols.push_back(&firstVol);
440 vols.push_back(&secondVol);
441 std::vector<TrackingVolume*> envGlueNegXY;
442 std::vector<TrackingVolume*> envGluePosXY;
443 std::vector<TrackingVolume*> envGlueOuter;
444 std::vector<TrackingVolume*> envGlueInner;
449 cyl1->halflengthZ()+cyl2->halflengthZ());
453 firstVol.
center().z()+cyl2->halflengthZ());
455 envGlueNegXY.push_back(&firstVol);
456 envGluePosXY.push_back(&secondVol);
462 cyl1->halflengthZ()+cyl2->halflengthZ());
466 firstVol.
center().z()-cyl2->halflengthZ());
467 envGlueNegXY.push_back(&secondVol);
468 envGluePosXY.push_back(&firstVol);
471 vols.push_back(&secondVol);
472 vols.push_back(&firstVol);
474 firstFaceCorr = secondFace;
475 secondFaceCorr = firstFace;
484 cyl1->halflengthZ());
487 cyl1->halflengthZ());
494 vols.push_back(&secondVol);
495 vols.push_back(&firstVol);
497 firstFaceCorr = secondFace;
498 secondFaceCorr = firstFace;
503 envGlueOuter.push_back(&firstVol);
504 envGlueInner.push_back(&secondVol);
508 cyl1->halflengthZ());
515 envGlueOuter.push_back(&secondVol);
516 envGlueInner.push_back(&firstVol);
518 firstFaceCorr = secondFace;
519 secondFaceCorr = firstFace;
534 std::vector<TrackingVolume*> glueNegXY;
535 std::vector<TrackingVolume*> gluePosXY;
536 std::vector<TrackingVolume*> glueInner;
537 std::vector<TrackingVolume*> glueOuter;
552 return enclosingVolume;
557 std::shared_ptr<TrackingVolume> secondVol,
559 const std::string&
name)
const {
560 std::unique_ptr<TrackingVolume> enclosingVolume{};
565 if (!cyl1 || !cyl2) {
566 ATH_MSG_ERROR(
"TrackingVolumeHelper::glueTrackingVolumeArrays: input volumes not cylinders, return 0" );
567 return enclosingVolume;
569 if (cyl1->halfPhiSector()!=
M_PI || cyl2->halfPhiSector()!=
M_PI ) {
570 ATH_MSG_ERROR(
"TrackingVolumeHelper::glueTrackingVolumeArrays: not coded for cylinder Phi sectors yet, return 0" );
571 return enclosingVolume;
580 std::vector<std::shared_ptr<TrackingVolume>> vols;
581 std::unique_ptr<CylinderVolumeBounds> envBounds{};
582 std::unique_ptr<Amg::Transform3D> envTransf{};
583 std::unique_ptr<BinnedArray<TrackingVolume>> subVols{};
584 vols.push_back(firstVol);
585 vols.push_back(secondVol);
586 std::vector<std::shared_ptr<TrackingVolume>> envGlueNegXY{}, envGluePosXY{}, envGlueOuter, envGlueInner{};
589 envBounds = std::make_unique<CylinderVolumeBounds>(cyl1->innerRadius(),
591 cyl1->halflengthZ() + cyl2->halflengthZ());
596 center.z() + cyl2->halflengthZ()));
599 envGlueNegXY.push_back(firstVol);
600 envGluePosXY.push_back(secondVol);
604 envBounds = std::make_unique<CylinderVolumeBounds>(cyl1->innerRadius(),
606 cyl1->halflengthZ()+cyl2->halflengthZ());
610 center.z() - cyl2->halflengthZ()));
611 envGlueNegXY.push_back(secondVol);
612 envGluePosXY.push_back(firstVol);
615 vols.push_back(secondVol);
616 vols.push_back(firstVol);
618 firstFaceCorr = secondFace;
619 secondFaceCorr = firstFace;
626 envBounds = std::make_unique<CylinderVolumeBounds>(cyl2->innerRadius(),
628 cyl1->halflengthZ());
630 envBounds = std::make_unique<CylinderVolumeBounds>(cyl1->outerRadius(),
631 cyl1->halflengthZ());
633 if (!firstVol->transform().isApprox(Amg::Transform3D::Identity())) {
638 vols.push_back(secondVol);
639 vols.push_back(firstVol);
641 firstFaceCorr = secondFace;
642 secondFaceCorr = firstFace;
647 envGlueOuter.push_back(firstVol);
648 envGlueInner.push_back(secondVol);
650 envBounds = std::make_unique<CylinderVolumeBounds>(cyl1->innerRadius(),
652 cyl1->halflengthZ());
653 if(!firstVol->transform().isApprox(Amg::Transform3D::Identity())){
659 envGlueOuter.push_back(secondVol);
660 envGlueInner.push_back(firstVol);
662 firstFaceCorr = secondFace;
663 secondFaceCorr = firstFace;
667 enclosingVolume = std::make_unique<TrackingVolume>(envTransf.release(),
670 nullptr, subVols.release(),
name);
677 std::vector<TrackingVolume*> glueNegXY{}, gluePosXY{}, glueInner{},glueOuter{};
692 return enclosingVolume;
698 const std::vector<std::shared_ptr<TrackingVolume>>& envelopeFaceVolumes,
700 std::vector<TrackingVolume*>& glueVols){
701 std::vector<std::shared_ptr<TrackingVolume>> sharedTops{}, sharedFaces{};
703 ::toRawVec(envelopeFaceVolumes),
708 const std::vector<TrackingVolume*>& envelopeFaceVolumes,
710 std::vector<TrackingVolume*>& glueVols) {
712 auto refVolIter = topLevelVolumes.begin();
713 for ( ; refVolIter != topLevelVolumes.end(); ++refVolIter ) {
715 for (
auto *envelopeFaceVolume : envelopeFaceVolumes){
717 if (envelopeFaceVolume==(*refVolIter)) {
721 if ( (glueVolDescriptor.
glueVolumes(glueFace)).empty()) {
722 glueVols.push_back(*refVolIter);
725 for (
auto *isubNavVol : glueVolDescriptor.
glueVolumes(glueFace))
726 glueVols.push_back( isubNavVol );
745 if (glueVols.size()<2) {
751 ATH_MSG_VERBOSE(
" glueTrackingVolumes() called with boundary faces " <<
static_cast<int>(firstFace)
752 <<
" and " <<
static_cast<int>(secondFace) <<
"." );
755 std::vector<TrackingVolume*>::const_iterator firstVol = glueVols.begin();
756 std::vector<TrackingVolume*>::const_iterator secondVol = firstVol + 1;
757 for ( ; secondVol != glueVols.end(); ++firstVol, ++secondVol) {
760 ATH_MSG_VERBOSE(
"Processing '" << (*firstVol)->volumeName() <<
"' and '" << (*secondVol)->volumeName() <<
"'." );
767 std::vector<TrackingVolume*> glueVols1{}, glueVols2{};
773 if (glueVols1.empty() && glueVols2.empty()) {
777 }
else if (glueVols1.empty() && !glueVols2.empty()) {
778 glueVols1.push_back(*firstVol);
780 }
else if (!glueVols1.empty() && glueVols2.empty()) {
781 glueVols2.push_back(*secondVol);
792 if (glueVols2.size()>1)
797 if (glueVols1.size()>1)
811 for (
auto & vol : glueVols1) {
814 if (glueVols2.size()>1)
819 if (glueVols2.size()>1){
829 for (
auto & vol : glueVols2) {
842 std::unique_ptr<LayerMaterialProperties>
845 std::unique_ptr<LayerMaterialProperties> layerMaterial{};
849 if (!cb)
throw std::logic_error(
"Not CylinderBounds");
856 layerMaterial = std::make_unique<BinnedLayerMaterial>(layerBinUtilityZ);
859 layerBinUtilityRPhiZ += layerBinUtilityZ;
860 layerMaterial = std::make_unique<BinnedLayerMaterial>(layerBinUtilityRPhiZ);
867 if (!
db)
throw std::logic_error(
"Not DiscBounds");
868 double rMin =
db->rMin();
869 double rMax =
db->rMax();
873 layerMaterial = std::make_unique<BinnedLayerMaterial>(layerBinUtilityR);
876 layerBinUtilityR += layerBinUtilityPhi;
877 layerMaterial = std::make_unique<BinnedLayerMaterial>(layerBinUtilityR);
882 return layerMaterial;
924 unsigned int numVols = outsidevolarray->
arrayObjects().size() ;
934 unsigned int numVols = outsidevolarray.get()->arrayObjects().size() ;