From fd3192cbf75ca3663233ca0222b2f9a52e4f101b Mon Sep 17 00:00:00 2001
From: Yee Chinn Yap <yee.chinn.yap@cern.ch>
Date: Tue, 17 Nov 2020 11:44:53 +0000
Subject: [PATCH] Beampipe optimisation

---
 .../src/BeamPipeDetectorFactory.cxx           | 88 ++++++++++++++-----
 .../src/BeamPipeDetectorFactory.h             |  6 +-
 .../src/BeamPipeDetectorTool.cxx              |  7 +-
 .../src/BeamPipeDetectorTool.h                |  1 +
 4 files changed, 76 insertions(+), 26 deletions(-)

diff --git a/AtlasGeometryCommon/BeamPipeGeoModel/src/BeamPipeDetectorFactory.cxx b/AtlasGeometryCommon/BeamPipeGeoModel/src/BeamPipeDetectorFactory.cxx
index 002ac41b950..03f4fd11868 100755
--- a/AtlasGeometryCommon/BeamPipeGeoModel/src/BeamPipeDetectorFactory.cxx
+++ b/AtlasGeometryCommon/BeamPipeGeoModel/src/BeamPipeDetectorFactory.cxx
@@ -66,6 +66,11 @@ void BeamPipeDetectorFactory::create(GeoPhysVol *world)
   m_centralRegionZMax = 1500 * Gaudi::Units::mm; // For backward compatibility in DB.
   if (bpipeGeneral->size() != 0) m_centralRegionZMax = (*bpipeGeneral)[0]->getDouble("CENTRALZMAX") * Gaudi::Units::mm;
 
+  const GeoMaterial* ether = m_materialManager->getMaterial("special::Ether");
+  GeoTube* dummytube= new GeoTube(0., 4711., 4711.);
+  GeoLogVol* dummyBeamPipe = new GeoLogVol("BeamPipe",dummytube,ether);
+  GeoPhysVol* theBeamPipe = new GeoPhysVol(dummyBeamPipe);
+
   EnvelopeShapes envelopes;
 
   if (bpipeEnvelope->size() != 0) {
@@ -103,26 +108,48 @@ void BeamPipeDetectorFactory::create(GeoPhysVol *world)
     beamz = (*bpipePosition)[0]->getDouble("POSZ") * Gaudi::Units::mm;
   }
 
-  // Only shift the central section
-
-  // Central
-  world->add(tag);
-  world->add(new GeoTransform(GeoTrf::Translate3D(beamx,beamy,beamz)));
-  world->add(pvMotherCentral);
-  m_detectorManager->addTreeTop(pvMotherCentral);                                                                  //
-
-  // FwdPlus
-  world->add(tag);
-  world->add(pvMotherFwdPlus);
-  m_detectorManager->addTreeTop(pvMotherFwdPlus);
-
-  // FwdMinus
-  world->add(tag);
-  world->add(new GeoTransform(GeoTrf::RotateY3D(180*Gaudi::Units::degree)));
-  world->add(pvMotherFwdMinus);
-  m_detectorManager->addTreeTop(pvMotherFwdMinus);
-
-
+  if (m_mode=="AssemblyBeamPipe"){
+    // Only shift the central section
+    // Central
+    theBeamPipe->add(tag);
+    theBeamPipe->add(new GeoTransform(GeoTrf::Translate3D(beamx,beamy,beamz)));
+    theBeamPipe->add(pvMotherCentral);
+
+    // FwdPlus
+    theBeamPipe->add(tag);
+    theBeamPipe->add(pvMotherFwdPlus);
+
+    // FwdMinus
+    theBeamPipe->add(tag);
+    theBeamPipe->add(new GeoTransform(GeoTrf::RotateY3D(180*Gaudi::Units::degree)));
+    theBeamPipe->add(pvMotherFwdMinus);
+
+    const GeoShape *shape = envelopes.bpShape;
+    GeoLogVol* lvMother = new GeoLogVol("BeamPipe",shape,air);
+    GeoPhysVol* pvMother = new GeoPhysVol(lvMother);
+    pvMother->add(tag);
+    pvMother->add(theBeamPipe);
+
+    world->add(tag);
+    world->add(pvMother);
+    m_detectorManager->addTreeTop(pvMother);
+  }
+  else{
+    // Default beam pipe, union of central and forward beampipes rather than assembly volume
+    // Central
+    world->add(tag);
+    world->add(new GeoTransform(GeoTrf::Translate3D(beamx,beamy,beamz)));
+    world->add(pvMotherCentral);
+    m_detectorManager->addTreeTop(pvMotherCentral);                                                                  //
+    // FwdPlus
+    world->add(tag);
+    world->add(pvMotherFwdPlus);
+    m_detectorManager->addTreeTop(pvMotherFwdPlus);
+    // FwdMinus
+    world->add(new GeoTransform(GeoTrf::RotateY3D(180*Gaudi::Units::degree)));
+    world->add(pvMotherFwdMinus);
+    m_detectorManager->addTreeTop(pvMotherFwdMinus);
+  }
 }
 
 void BeamPipeDetectorFactory::addSections(GeoPhysVol* parent, int region)
@@ -283,10 +310,11 @@ const BeamPipeDetectorManager * BeamPipeDetectorFactory::getDetectorManager() co
   return m_detectorManager;
 }
 
-void BeamPipeDetectorFactory::setTagNode(std::string tag, std::string node)
+void BeamPipeDetectorFactory::setTagNode(std::string tag, std::string node, std::string mode)
 {
   m_versionTag = tag;
   m_versionNode = node;
+  m_mode = mode;
 }
 
 
@@ -358,6 +386,24 @@ BeamPipeDetectorFactory::makeEnvelope(IRDBRecordset_ptr bpipeEnvelope)
     envelopes.fwdShape = pcone;
   }
 
+  //central+fwd
+  {
+    GeoPcon* Pcone = new GeoPcon(0, 360*Gaudi::Units::deg);
+    for (int i=fwdEntry.size()-1; i>=0; i--) {
+      double z = fwdEntry[i].z();
+      double r = fwdEntry[i].r();
+      Pcone->addPlane(-z,0,r);
+    }
+    Pcone->addPlane(-m_centralRegionZMax,0,rFwd);
+    Pcone->addPlane(m_centralRegionZMax,0,rFwd);
+    for (unsigned int i=0; i<fwdEntry.size(); i++) {
+      double z = fwdEntry[i].z();
+      double r = fwdEntry[i].r();
+      Pcone->addPlane(z,0,r);
+    }
+    envelopes.bpShape = Pcone;
+  }
+
   return envelopes;
 
 }
diff --git a/AtlasGeometryCommon/BeamPipeGeoModel/src/BeamPipeDetectorFactory.h b/AtlasGeometryCommon/BeamPipeGeoModel/src/BeamPipeDetectorFactory.h
index fcf1233e7b8..a66ed70cc3d 100755
--- a/AtlasGeometryCommon/BeamPipeGeoModel/src/BeamPipeDetectorFactory.h
+++ b/AtlasGeometryCommon/BeamPipeGeoModel/src/BeamPipeDetectorFactory.h
@@ -32,7 +32,7 @@ class BeamPipeDetectorFactory final : public GeoVDetectorFactory
   virtual const BeamPipeDetectorManager * getDetectorManager() const override;
   
   // Set version Tag and Node
-  void setTagNode(std::string tag, std::string node);
+  void setTagNode(std::string tag, std::string node, std::string mode);
 
   void addSections(GeoPhysVol* parent, int region);
 
@@ -52,9 +52,10 @@ class BeamPipeDetectorFactory final : public GeoVDetectorFactory
 
   class EnvelopeShapes {
   public:
-    EnvelopeShapes() : centralShape(0), fwdShape(0) {} 
+    EnvelopeShapes() : centralShape(0), fwdShape(0), bpShape(0) {} 
     GeoShape * centralShape;
     GeoShape * fwdShape;
+    GeoShape * bpShape;
   };
 
 
@@ -75,6 +76,7 @@ class BeamPipeDetectorFactory final : public GeoVDetectorFactory
   IRDBAccessSvc            * m_access;
   std::string              m_versionTag;
   std::string              m_versionNode;
+  std::string              m_mode;
 
   double m_centralRegionZMax;
 };
diff --git a/AtlasGeometryCommon/BeamPipeGeoModel/src/BeamPipeDetectorTool.cxx b/AtlasGeometryCommon/BeamPipeGeoModel/src/BeamPipeDetectorTool.cxx
index dff061d40e5..4d20c191e2d 100755
--- a/AtlasGeometryCommon/BeamPipeGeoModel/src/BeamPipeDetectorTool.cxx
+++ b/AtlasGeometryCommon/BeamPipeGeoModel/src/BeamPipeDetectorTool.cxx
@@ -22,8 +22,10 @@ BeamPipeDetectorTool::BeamPipeDetectorTool( const std::string& type,
 					    const std::string& name, 
 					    const IInterface* parent ): 
   GeoModelTool(type,name,parent),
-  m_manager(0)
+  m_manager(0),
+  m_mode("BeamPipe")
 {
+    declareProperty("BeamPipeMode",            m_mode); //m_mode="BeamPipe" by default, setting m_mode="AssemblyBeamPipe" will trigger optimised implementation using assembly volume
 }
 
 BeamPipeDetectorTool::~BeamPipeDetectorTool()
@@ -75,14 +77,13 @@ StatusCode BeamPipeDetectorTool::create()
     beampipeVersionTag = raccess->getChildTag("BeamPipe", atlasVersion,versionNode);
     log << MSG::DEBUG << "Beampipe Version: " << beampipeVersionTag << endmsg;
 
-
     if (beampipeVersionTag.empty()) { 
       log << MSG::INFO << "No BeamPipe Version. Beam pipe will not be built." << endmsg;
       
     } else {
       
       BeamPipeDetectorFactory theBeamPipeFactory(detStore().operator->(),raccess);
-      theBeamPipeFactory.setTagNode(atlasVersion,versionNode);
+      theBeamPipeFactory.setTagNode(atlasVersion,versionNode,m_mode);
       theBeamPipeFactory.create(world);
 
       m_manager = theBeamPipeFactory.getDetectorManager();
diff --git a/AtlasGeometryCommon/BeamPipeGeoModel/src/BeamPipeDetectorTool.h b/AtlasGeometryCommon/BeamPipeGeoModel/src/BeamPipeDetectorTool.h
index bfcc548967c..6baa5a2f2f7 100755
--- a/AtlasGeometryCommon/BeamPipeGeoModel/src/BeamPipeDetectorTool.h
+++ b/AtlasGeometryCommon/BeamPipeGeoModel/src/BeamPipeDetectorTool.h
@@ -22,6 +22,7 @@ class BeamPipeDetectorTool final : public GeoModelTool
   virtual StatusCode clear() override final;
  private:
   const BeamPipeDetectorManager* m_manager;
+  std::string m_mode;
 };
 
 #endif 
-- 
GitLab