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 auto mLayer = std::make_shared<MaterialLayerNoOwnSurf>(&firstFaceSurface, std::move(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<MaterialLayer> mLayer{};
119 if (buildBoundaryLayer){
126 mLayer = std::make_shared<MaterialLayerNoOwnSurf>(&firstFaceSurface, std::move(lmps));
127 ATH_MSG_VERBOSE(
"Set MaterialLayer to the BoundarySurface of first volume (may be shared with second volume)." );
132 if (secondVolumes.size() == 1) {
137 std::unique_ptr<BinnedArray<TrackingVolume>> navArray =
nullptr;
153 if (boundaryFaceExchange){
155 ATH_MSG_VERBOSE(
"Creating a joint boundary surface for 1-to-n glueing case.");
157 std::shared_ptr<BoundarySurface<TrackingVolume> > bSurface = firstVol.
boundarySurfaces()[firstFace];
159 for (
const auto & volIter: secondVolumes )
164 for (
const auto & volIter: secondVolumes ) {
171 if (currentVolBounds && currentVolBounds->
innerRadius() < 10
e-3)
181 Surface& secondFaceSurface = volIter->boundarySurfaces()[secondFace]->surfaceRepresentation();
192 const std::vector<TrackingVolume*>& secondVolumes,
194 bool buildBoundaryLayer,
195 bool boundaryFaceExchange)
const
199 std::unique_ptr<BinnedArray<TrackingVolume>> navArrayOne =
nullptr;
200 std::unique_ptr<BinnedArray<TrackingVolume>> navArrayTwo =
nullptr;
202 std::unique_ptr<Surface> mLayerSurface;
203 std::shared_ptr<MaterialLayer> mLayer;
205 ATH_MSG_VERBOSE(
"Glue configuration firstFace | secondFace = " << firstFace <<
" | " << secondFace );
208 if (firstFace < 2 && secondFace < 2 ) {
213 if (buildBoundaryLayer || boundaryFaceExchange){
214 double rmin = 10e10;
double rmax = 0;
double boundaryz = 0.;
double centerzOne = 0.;
215 for (
const auto & volIter : firstVolumes ){
221 boundaryz = volIter->boundarySurfaces()[firstFace]->surfaceRepresentation().center().z();
223 centerzOne = volIter->center().z();
225 if (buildBoundaryLayer){
229 mLayerSurface = std::make_unique<DiscSurface>(mLayerTransform, rmin, rmax);
235 mLayer = std::make_shared<MaterialLayerOwnSurf>(std::move(mLayerSurface), std::move(lmps));
238 if (boundaryFaceExchange){
240 ATH_MSG_VERBOSE(
"Creating a joint boundary surface for n-to-n glueing case.");
242 double centerzTwo = secondVolumes[secondVolumes.size()-1]->center().z();
246 DiscSurface dSurface(boundaryTransform, rmin, rmax);
248 if (centerzTwo < centerzOne){
252 std::shared_ptr< BinnedArray<TrackingVolume> > navArrayInside(std::move(navArrayOne));
253 std::shared_ptr< BinnedArray<TrackingVolume> > navArrayOutside(std::move(navArrayTwo));
255 std::shared_ptr<BoundarySurface<TrackingVolume> > sharedBoundarySurface(boundarySurface);
258 ATH_MSG_VERBOSE(
"Set MaterialLayer to the BoundarySurface of volume from second array." );
262 for (
const auto & volIter : firstVolumes){
263 ATH_MSG_VERBOSE(
" -> first array : setting a newly created boundary surface to " << volIter->volumeName());
266 for (
const auto & volIter : secondVolumes){
267 ATH_MSG_VERBOSE(
" -> second array : setting a newly created boundary surface to " << volIter->volumeName());
279 if (buildBoundaryLayer || boundaryFaceExchange){
281 double zmin = 10e10;
double zmax = -10e10;
double boundaryr = 0.;
double volumerOne = 0.;
double volumerTwo = 10e10;
282 for (
const auto & volIter : firstVolumes ){
288 boundaryr = volIter->boundarySurfaces()[firstFace]->surfaceRepresentation().bounds().r();
294 if (buildBoundaryLayer){
295 std::unique_ptr<Amg::Transform3D> mLayerTransform =
298 : std::make_unique < Amg::Transform3D>();
306 if (lmps) mLayer = std::make_shared<MaterialLayerOwnSurf>(
307 std::move(mLayerSurface),
311 if (boundaryFaceExchange) {
313 ATH_MSG_VERBOSE(
"Creating a joint boundary surface for n-to-n glueing case.");
315 std::unique_ptr<Amg::Transform3D> boundaryTransform =
318 : std::make_unique<Amg::Transform3D>();
330 if (volumerTwo < volumerOne){
334 std::shared_ptr< BinnedArray<TrackingVolume> > navArrayInside(std::move(navArrayOne));
335 std::shared_ptr< BinnedArray<TrackingVolume> > navArrayOutside(std::move(navArrayTwo));
337 std::shared_ptr<BoundarySurface<TrackingVolume> > sharedBoundarySurface(boundarySurface);
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());
361 ATH_MSG_VERBOSE(
"Leaving individual boundary surfaces for n-to-n glueing case.");
364 std::shared_ptr< BinnedArray< TrackingVolume> > navArrayOneShared(std::move(navArrayOne));
365 std::shared_ptr< BinnedArray< TrackingVolume> > navArrayTwoShared(std::move(navArrayTwo));
368 for (
const auto & tVolIter: firstVolumes) {
372 ATH_MSG_VERBOSE(
"Set outsideTrackingVolumeArray at face " << firstFace <<
" to " << (*tVolIter).volumeName() );
375 ATH_MSG_VERBOSE(
"Set insideTrackingVolumeArray at face " << firstFace <<
" to " << (*tVolIter).volumeName() );
379 ATH_MSG_VERBOSE(
"Set MaterialLayer to the BoundarySurface of volume from first array." );
380 Surface& firstFaceSurface = tVolIter->boundarySurfaces()[firstFace]->surfaceRepresentation();
388 for (
const auto & tVolIter : secondVolumes) {
391 ATH_MSG_VERBOSE(
"Set outsideTrackingVolumeArray at face " << secondFace <<
" to " << (*tVolIter).volumeName() );
394 ATH_MSG_VERBOSE(
"Set insideTrackingVolumeArray at face " << secondFace <<
" to " << (*tVolIter).volumeName() );
398 ATH_MSG_VERBOSE(
"Set MaterialLayer to the BoundarySurface of volume from second array." );
399 Surface& secondFaceSurface = tVolIter->boundarySurfaces()[secondFace]->surfaceRepresentation();
410 std::shared_ptr<TrackingVolume> secondVol,
412 const std::string&
name)
const {
413 std::unique_ptr<TrackingVolume> enclosingVolume{};
418 if (!cyl1 || !cyl2) {
419 ATH_MSG_ERROR(
"TrackingVolumeHelper::glueTrackingVolumeArrays: input volumes not cylinders, return 0" );
420 return enclosingVolume;
422 if (cyl1->halfPhiSector()!=
M_PI || cyl2->halfPhiSector()!=
M_PI ) {
423 ATH_MSG_ERROR(
"TrackingVolumeHelper::glueTrackingVolumeArrays: not coded for cylinder Phi sectors yet, return 0" );
424 return enclosingVolume;
433 std::vector<std::shared_ptr<TrackingVolume>> vols;
434 std::shared_ptr<CylinderVolumeBounds> envBounds{};
435 std::unique_ptr<Amg::Transform3D> envTransf{};
436 std::unique_ptr<BinnedArray<TrackingVolume>> subVols{};
437 vols.push_back(firstVol);
438 vols.push_back(secondVol);
439 std::vector<std::shared_ptr<TrackingVolume>> envGlueNegXY{};
440 std::vector<std::shared_ptr<TrackingVolume>> envGluePosXY{};
441 std::vector<std::shared_ptr<TrackingVolume>> envGlueOuter;
442 std::vector<std::shared_ptr<TrackingVolume>> envGlueInner{};
445 envBounds = std::make_shared<CylinderVolumeBounds>(cyl1->innerRadius(),
447 cyl1->halflengthZ() + cyl2->halflengthZ());
452 center.z() + cyl2->halflengthZ()));
455 envGlueNegXY.push_back(firstVol);
456 envGluePosXY.push_back(secondVol);
460 envBounds = std::make_shared<CylinderVolumeBounds>(cyl1->innerRadius(),
462 cyl1->halflengthZ()+cyl2->halflengthZ());
466 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;
482 envBounds = std::make_shared<CylinderVolumeBounds>(cyl2->innerRadius(),
484 cyl1->halflengthZ());
486 envBounds = std::make_shared<CylinderVolumeBounds>(cyl1->outerRadius(),
487 cyl1->halflengthZ());
489 if (!firstVol->transform().isApprox(Amg::Transform3D::Identity())) {
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);
506 envBounds = std::make_shared<CylinderVolumeBounds>(cyl1->innerRadius(),
508 cyl1->halflengthZ());
509 if(!firstVol->transform().isApprox(Amg::Transform3D::Identity())){
515 envGlueOuter.push_back(secondVol);
516 envGlueInner.push_back(firstVol);
518 firstFaceCorr = secondFace;
519 secondFaceCorr = firstFace;
523 enclosingVolume = std::make_unique<TrackingVolume>(std::move(envTransf),
526 nullptr, std::move(subVols),
name);
533 std::vector<TrackingVolume*> glueNegXY{};
534 std::vector<TrackingVolume*> gluePosXY{};
535 std::vector<TrackingVolume*> glueInner{};
536 std::vector<TrackingVolume*> glueOuter{};
551 return enclosingVolume;
557 const std::vector<std::shared_ptr<TrackingVolume>>& envelopeFaceVolumes,
559 std::vector<TrackingVolume*>& glueVols){
560 std::vector<std::shared_ptr<TrackingVolume>> sharedTops{};
561 std::vector<std::shared_ptr<TrackingVolume>> sharedFaces{};
563 ::toRawVec(envelopeFaceVolumes),
568 const std::vector<TrackingVolume*>& envelopeFaceVolumes,
570 std::vector<TrackingVolume*>& glueVols) {
572 auto refVolIter = topLevelVolumes.begin();
573 for ( ; refVolIter != topLevelVolumes.end(); ++refVolIter ) {
575 for (
auto *envelopeFaceVolume : envelopeFaceVolumes){
577 if (envelopeFaceVolume==(*refVolIter)) {
581 if ( (glueVolDescriptor.
glueVolumes(glueFace)).empty()) {
582 glueVols.push_back(*refVolIter);
585 for (
auto *isubNavVol : glueVolDescriptor.
glueVolumes(glueFace))
586 glueVols.push_back( isubNavVol );
605 if (glueVols.size()<2) {
611 ATH_MSG_VERBOSE(
" glueTrackingVolumes() called with boundary faces " <<
static_cast<int>(firstFace)
612 <<
" and " <<
static_cast<int>(secondFace) <<
"." );
615 std::vector<TrackingVolume*>::const_iterator firstVol = glueVols.begin();
616 std::vector<TrackingVolume*>::const_iterator secondVol = firstVol + 1;
617 for ( ; secondVol != glueVols.end(); ++firstVol, ++secondVol) {
620 ATH_MSG_VERBOSE(
"Processing '" << (*firstVol)->volumeName() <<
"' and '" << (*secondVol)->volumeName() <<
"'." );
627 std::vector<TrackingVolume*> glueVols1{};
628 std::vector<TrackingVolume*> glueVols2{};
634 if (glueVols1.empty() && glueVols2.empty()) {
638 }
else if (glueVols1.empty() && !glueVols2.empty()) {
639 glueVols1.push_back(*firstVol);
641 }
else if (!glueVols1.empty() && glueVols2.empty()) {
642 glueVols2.push_back(*secondVol);
653 if (glueVols2.size()>1)
658 if (glueVols1.size()>1)
672 for (
auto & vol : glueVols1) {
675 if (glueVols2.size()>1)
680 if (glueVols2.size()>1){
690 for (
auto & vol : glueVols2) {
703 std::unique_ptr<LayerMaterialProperties>
706 std::unique_ptr<LayerMaterialProperties> layerMaterial{};
710 if (!cb)
throw std::logic_error(
"Not CylinderBounds");
717 layerMaterial = std::make_unique<BinnedLayerMaterial>(layerBinUtilityZ);
720 layerBinUtilityRPhiZ += layerBinUtilityZ;
721 layerMaterial = std::make_unique<BinnedLayerMaterial>(layerBinUtilityRPhiZ);
728 if (!
db)
throw std::logic_error(
"Not DiscBounds");
729 double rMin =
db->rMin();
730 double rMax =
db->rMax();
734 layerMaterial = std::make_unique<BinnedLayerMaterial>(layerBinUtilityR);
737 layerBinUtilityR += layerBinUtilityPhi;
738 layerMaterial = std::make_unique<BinnedLayerMaterial>(layerBinUtilityR);
743 return layerMaterial;
777 unsigned int numVols = outsidevolarray.get()->arrayObjects().size() ;