From cb74c41cdbc4d8795a77e9a16001b5d4c4b94f67 Mon Sep 17 00:00:00 2001
From: Markus FRANK <Markus.Frank@cern.ch>
Date: Mon, 23 Aug 2021 21:33:53 +0200
Subject: [PATCH] Allow for sensitive actions with multiple readout
 segmentation in the Geant4Sensitive action sequence

---
 DDCore/src/plugins/Compact2Objects.cpp        |   3 +-
 DDDetectors/compact/SiD.xml                   |  10 +-
 DDG4/include/DDG4/Geant4SensDetAction.h       |  29 ++-
 DDG4/include/DDG4/Geant4SensDetAction.inl     |  28 +-
 DDG4/plugins/Geant4SDActions.cpp              |   4 +-
 DDG4/src/Geant4SensDetAction.cpp              |  16 +-
 .../compact/SiD_ECAL_Parallel_Readout.xml     |  61 +++++
 .../FCCmachine/BeamInstrumentation.xml        |  38 +++
 .../compact/FCCmachine/Beampipe.xml           | 154 +++++++++++
 .../FCCmachine/FCCee_DectDimensions.xml       | 243 ++++++++++++++++++
 .../compact/FCCmachine/FCCee_DectMaster.xml   |  55 ++++
 .../compact/FCCmachine/HOMAbsorber.xml        |  62 +++++
 .../ClientTests/compact/VisAttr_Extend.xml    |  61 +++++
 .../ClientTests/src/FCC_Mask_o1_v01_geo.cpp   | 236 +++++++++++++++++
 .../src/FCC_Mask_o1_v01_noRot_geo.cpp         | 235 +++++++++++++++++
 .../src/FCC_MaterialEnvelope_o1_v01.cpp       |  35 +++
 .../src/FCC_OtherDetectorHelpers.h            | 110 ++++++++
 examples/DDCAD/compact/Import_FCC_Machine.xml |  50 ++++
 18 files changed, 1397 insertions(+), 33 deletions(-)
 create mode 100644 examples/CLICSiD/compact/SiD_ECAL_Parallel_Readout.xml
 create mode 100644 examples/ClientTests/compact/FCCmachine/BeamInstrumentation.xml
 create mode 100644 examples/ClientTests/compact/FCCmachine/Beampipe.xml
 create mode 100644 examples/ClientTests/compact/FCCmachine/FCCee_DectDimensions.xml
 create mode 100644 examples/ClientTests/compact/FCCmachine/FCCee_DectMaster.xml
 create mode 100644 examples/ClientTests/compact/FCCmachine/HOMAbsorber.xml
 create mode 100644 examples/ClientTests/compact/VisAttr_Extend.xml
 create mode 100644 examples/ClientTests/src/FCC_Mask_o1_v01_geo.cpp
 create mode 100644 examples/ClientTests/src/FCC_Mask_o1_v01_noRot_geo.cpp
 create mode 100644 examples/ClientTests/src/FCC_MaterialEnvelope_o1_v01.cpp
 create mode 100644 examples/ClientTests/src/FCC_OtherDetectorHelpers.h
 create mode 100644 examples/DDCAD/compact/Import_FCC_Machine.xml

diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp
index 581f535fe..abc3c8431 100644
--- a/DDCore/src/plugins/Compact2Objects.cpp
+++ b/DDCore/src/plugins/Compact2Objects.cpp
@@ -1462,7 +1462,7 @@ template <> void Converter<DetElementInclude>::operator()(xml_h element) const {
       xml_coll_t(node, _U(readout)).for_each(Converter<Readout>(this->description));
     else if ( tag == "regions" )
       xml_coll_t(node, _U(region)).for_each(Converter<Region>(this->description));
-    else if ( tag == "limitsets" )
+    else if ( tag == "limits" || tag == "limitsets" )
       xml_coll_t(node, _U(limitset)).for_each(Converter<LimitSet>(this->description));
     else if ( tag == "display" )
       xml_coll_t(node,_U(vis)).for_each(Converter<VisAttr>(this->description));
@@ -1569,6 +1569,7 @@ template <> void Converter<Compact>::operator()(xml_h element) const {
     (Converter<World>(description))(xml_h(compact.child(_U(world))));
 
   if ( open_geometry ) description.init();
+  xml_coll_t(compact, _U(limits)).for_each(_U(include),  Converter<DetElementInclude>(description));
   xml_coll_t(compact, _U(limits)).for_each(_U(limitset), Converter<LimitSet>(description));
 
   printout(DEBUG, "Compact", "++ Converting readout  structures...");
diff --git a/DDDetectors/compact/SiD.xml b/DDDetectors/compact/SiD.xml
index 2a9e297c2..9110610f1 100644
--- a/DDDetectors/compact/SiD.xml
+++ b/DDDetectors/compact/SiD.xml
@@ -39,15 +39,9 @@
 
 
   <limits>
-    <limitset name="cal_limits">
-      <limit name="step_length_max" particles="*" value="5.0" unit="mm" />
-    </limitset>
-    <limitset name="SiTrackerBarrelRegionLimitSet">
-      <limit name="step_length_max" particles="*" value="5.0" unit="mm" />
-      <limit name="ekin_min" particles="*" value="0.01" unit="MeV" />
-      <limit name="range_min" particles="*" value="5.0" unit="mm" />
-    </limitset>
+    <include ref="SiD_Limits.xml"/>
   </limits>
+
   <regions>
     <region name="SiTrackerBarrelRegion" eunit="MeV" lunit="mm" cut="0.001" threshold="0.001">
       <limitsetref name="SiTrackerBarrelRegionLimitSet"/>
diff --git a/DDG4/include/DDG4/Geant4SensDetAction.h b/DDG4/include/DDG4/Geant4SensDetAction.h
index 9ed4d1f76..200ab98f1 100644
--- a/DDG4/include/DDG4/Geant4SensDetAction.h
+++ b/DDG4/include/DDG4/Geant4SensDetAction.h
@@ -123,28 +123,28 @@ namespace dd4hep {
 
     private:
       /// Reference to G4 sensitive detector
-      Geant4ActionSD* m_sensitiveDetector = 0;
+      Geant4ActionSD* m_sensitiveDetector     { nullptr };
       /// Reference to the containing action sequence
-      Geant4SensDetActionSequence* m_sequence = 0;
+      Geant4SensDetActionSequence* m_sequence { nullptr };
 
     protected:
       /// Property: Hit creation mode. Maybe one of the enum HitCreationFlags
       int  m_hitCreationMode = 0;
 #if defined(G__ROOT) || defined(__CLING__) || defined(__ROOTCLING__)
       /// Reference to the detector description object
-      Detector*            m_detDesc {0};
+      Detector*            m_detDesc          { nullptr };
 #else
       /// Reference to the detector description object
       Detector&            m_detDesc;
 #endif
       /// Reference to the detector element describing this sensitive element
-      DetElement           m_detector;
+      DetElement           m_detector         {  };
       /// Reference to the sensitive detector element
-      SensitiveDetector    m_sensitive;
+      SensitiveDetector    m_sensitive        {  };
       /// Reference to the readout structure
-      Readout              m_readout;
+      Readout              m_readout          {  };
       /// Reference to segmentation
-      Segmentation         m_segmentation;
+      Segmentation         m_segmentation     {  };
       /// The list of sensitive detector filter objects
       Actors<Geant4Filter> m_filters;
 
@@ -199,6 +199,9 @@ namespace dd4hep {
         return detector().readoutGeometry();
       }
 
+      /// Access the detector desciption object
+      Detector& detectorDescription()   const;
+
       /// Mark the track to be kept for MC truth propagation during hit processing
       void mark(const G4Track* track) const;
 
@@ -508,11 +511,14 @@ namespace dd4hep {
       typedef T UserData;
     protected:
       /// Property: collection name. If not set default is readout name!
-      std::string m_collectionName;
+      std::string m_collectionName    { };
+      /// Property: segmentation name for parallel readouts. If not set readout segmentation is used!
+      std::string m_readoutName       { };
+
       /// Collection identifier
-      size_t      m_collectionID = -1;
+      size_t      m_collectionID    { 0 };
       /// User data block
-      UserData    m_userData;
+      UserData    m_userData          { };
 
     protected:
       /// Define standard assignments and constructors
@@ -531,6 +537,9 @@ namespace dd4hep {
       /// Define collections created by this sensitivie action object
       virtual void defineCollections();
 
+      /// Access the readout object. Note: if m_readoutName is set, the m_readout != m_sensitive.readout()
+      Readout readout();
+      
       /// Define readout specific hit collection with volume ID filtering
       /** 
        *  Convenience function. To be called by specialized sensitive actions inheriting this class.
diff --git a/DDG4/include/DDG4/Geant4SensDetAction.inl b/DDG4/include/DDG4/Geant4SensDetAction.inl
index 79ee69084..69d852f3f 100644
--- a/DDG4/include/DDG4/Geant4SensDetAction.inl
+++ b/DDG4/include/DDG4/Geant4SensDetAction.inl
@@ -11,10 +11,11 @@
 //
 //==========================================================================
 
-// Framework include files
+/// Framework include files
 #include "DDG4/Geant4SensDetAction.h"
-#include "DD4hep/detail/ObjectsInterna.h"
+#include "DD4hep/Detector.h"
 #include "DD4hep/InstanceCount.h"
+#include "DD4hep/detail/ObjectsInterna.h"
 
 #include "DDG4/Geant4ReadoutVolumeFilter.h"
 #include "DDG4/Geant4Data.h"
@@ -33,6 +34,7 @@ namespace dd4hep {
 						    Detector& description_ref)
       : Geant4Sensitive(ctxt,nam,det,description_ref), m_collectionName(), m_collectionID(0)
     {
+      declareProperty("ReadoutName",    m_readoutName);
       declareProperty("CollectionName", m_collectionName);
       initialize();
       InstanceCount::increment(this);
@@ -52,6 +54,21 @@ namespace dd4hep {
     template <typename T> void Geant4SensitiveAction<T>::finalize()    {
     }
 
+    /// Access the readout object. Note: if m_readoutName is set, the m_readout != m_sensitive.readout()
+    template <typename T> Readout Geant4SensitiveAction<T>::readout()     {
+      if ( !m_readoutName.empty() && m_sensitive.readout() == m_readout )   {
+        m_readout = detectorDescription().readout(m_readoutName);
+        if ( !m_readout.isValid() )   {
+          except("+++ Failed to access parallel readout '%s'",m_sensitive.name());
+        }
+        m_segmentation = m_readout.segmentation();
+        if ( !m_segmentation.isValid() )   {
+          except("+++ Failed to access segmentation for readout '%s'",m_readout.name());
+        }
+      }
+      return m_readout;
+    }
+
     /// G4VSensitiveDetector interface: Method invoked at the begining of each event.
     template <typename T> void Geant4SensitiveAction<T>::begin(G4HCofThisEvent* hce)  {
       Geant4Sensitive::begin(hce);
@@ -84,7 +101,7 @@ namespace dd4hep {
     /// Define readout specific hit collection. matching name must be present in readout structure
     template <typename T> template <typename HIT> 
     size_t Geant4SensitiveAction<T>::defineReadoutCollection(const std::string match_name)  {
-      Readout ro = m_sensitive.readout();
+      auto ro = readout();
       for(const auto& c : ro->hits )  {
         if ( c.name == match_name )   {
           size_t coll_id = defineCollection<HIT>(match_name);
@@ -94,7 +111,7 @@ namespace dd4hep {
         }
       }
       except("+++ Custom collection name '%s' not defined in the Readout object: %s.",
-             m_collectionName.c_str(), ro.name());      
+             m_collectionName.c_str(), ro.name());
       return 0; // Anyhow not reachable. Exception thrown before
     }
 
@@ -103,8 +120,7 @@ namespace dd4hep {
     size_t Geant4SensitiveAction<T>::declareReadoutFilteredCollection()
     {
       if ( m_collectionName.empty() )  {
-        Readout ro = m_sensitive.readout();
-        return defineCollection<HIT>(ro.name());
+        return defineCollection<HIT>(readout().name());
       }
       return defineReadoutCollection<HIT>(m_collectionName);
     }
diff --git a/DDG4/plugins/Geant4SDActions.cpp b/DDG4/plugins/Geant4SDActions.cpp
index f624521f6..8aff2daca 100644
--- a/DDG4/plugins/Geant4SDActions.cpp
+++ b/DDG4/plugins/Geant4SDActions.cpp
@@ -104,7 +104,7 @@ namespace dd4hep {
       collection(m_collectionID)->add(hit);
       mark(h.track);
       if ( 0 == hit->cellID )  {
-        hit->cellID        = volumeID( step ) ;
+        hit->cellID      = volumeID( step ) ;
         except("+++ Invalid CELL ID for hit!");
       }
       print("Hit with deposit:%f  Pos:%f %f %f ID=%016X",
@@ -131,7 +131,7 @@ namespace dd4hep {
       collection(m_collectionID)->add(hit);
       mark(h.track);
       if ( 0 == hit->cellID )  {
-        hit->cellID = volumeID( spot ) ;
+        hit->cellID      = volumeID( spot ) ;
         except("+++ Invalid CELL ID for hit!");
       }
       print("Hit with deposit:%f  Pos:%f %f %f ID=%016X",
diff --git a/DDG4/src/Geant4SensDetAction.cpp b/DDG4/src/Geant4SensDetAction.cpp
index 0899d601c..634cd266f 100644
--- a/DDG4/src/Geant4SensDetAction.cpp
+++ b/DDG4/src/Geant4SensDetAction.cpp
@@ -98,18 +98,17 @@ bool Geant4Filter::operator()(const G4GFlashSpot*) const {
 }
 
 /// Constructor. The detector element is identified by the name
-Geant4Sensitive::Geant4Sensitive(Geant4Context* ctxt, const string& nam, DetElement det, Detector& description_ref)
-  : Geant4Action(ctxt, nam), m_sensitiveDetector(0), m_sequence(0),
-    m_detDesc(description_ref), m_detector(det), m_sensitive(), m_readout(), m_segmentation()
+Geant4Sensitive::Geant4Sensitive(Geant4Context* ctxt, const string& nam, DetElement det, Detector& det_ref)
+  : Geant4Action(ctxt, nam), m_detDesc(det_ref), m_detector(det)
 {
   InstanceCount::increment(this);
   if (!det.isValid()) {
     throw runtime_error(format("Geant4Sensitive", "DDG4: Detector elemnt for %s is invalid.", nam.c_str()));
   }
   declareProperty("HitCreationMode", m_hitCreationMode = SIMPLE_MODE);
-  m_sequence  = context()->kernel().sensitiveAction(m_detector.name());
-  m_sensitive = description_ref.sensitiveDetector(det.name());
-  m_readout   = m_sensitive.readout();
+  m_sequence     = context()->kernel().sensitiveAction(m_detector.name());
+  m_sensitive    = m_detDesc.sensitiveDetector(det.name());
+  m_readout      = m_sensitive.readout();
   m_segmentation = m_readout.segmentation();
 }
 
@@ -186,6 +185,11 @@ Geant4SensDetActionSequence& Geant4Sensitive::sequence() const {
   return *m_sequence;
 }
 
+/// Access the detector desciption object
+Detector& Geant4Sensitive::detectorDescription() const {
+  return m_detDesc;
+}
+
 /// Access HitCollection container names
 const string& Geant4Sensitive::hitCollectionName(size_t which) const {
   return sequence().hitCollectionName(which);
diff --git a/examples/CLICSiD/compact/SiD_ECAL_Parallel_Readout.xml b/examples/CLICSiD/compact/SiD_ECAL_Parallel_Readout.xml
new file mode 100644
index 000000000..b34032b6f
--- /dev/null
+++ b/examples/CLICSiD/compact/SiD_ECAL_Parallel_Readout.xml
@@ -0,0 +1,61 @@
+<lccdd>
+<!-- #==========================================================================
+     #  AIDA Detector description implementation 
+     #==========================================================================
+     # Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+     # All rights reserved.
+     #
+     # For the licensing terms see $DD4hepINSTALL/LICENSE.
+     # For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+     #
+     #==========================================================================
+-->
+  <info name="clic_sid_cdr"
+        title="CLIC Silicon Detector CDR"
+        author="Christian Grefe"
+        url="https://twiki.cern.ch/twiki/bin/view/CLIC/ClicSidCdr"
+        status="development"
+        version="$Id: compact.xml 1374 2014-11-05 10:49:55Z markus.frank@cern.ch $">
+    <comment>The compact format for the CLIC Silicon Detector used for the conceptual design report</comment>        
+  </info>
+
+  <includes>
+    <gdmlFile  ref="${DD4hepINSTALL}/DDDetectors/compact/elements.xml"/>
+    <gdmlFile  ref="${DD4hepINSTALL}/DDDetectors/compact/materials.xml"/>
+  </includes>
+  <include ref="${DD4hepINSTALL}/DDDetectors/compact/SiD/SiD_Materials.xml"/>
+
+  <define>
+    <include ref="${DD4hepINSTALL}/DDDetectors/compact/SiDConstants.xml"/>
+  </define>
+
+  <limits>
+    <include ref="${DD4hepINSTALL}/DDDetectors/compact/SiD_Limits.xml"/>
+  </limits>
+
+  <include ref="${DD4hepINSTALL}/DDDetectors/compact/SiD/SiD_EcalBarrel.xml"/>
+
+  <readouts>
+    <readout name="EcalBarrelHits">
+      <segmentation type="CartesianGridXY" grid_size_x="3.5" grid_size_y="3.5" />
+      <id>system:8,barrel:3,module:4,layer:6,slice:5,x:32:-16,y:-16</id>
+    </readout>        
+
+    <readout name="EcalBarrelHits_0">
+      <segmentation type="CartesianGridXY" grid_size_x="1" grid_size_y="1" />
+      <id>system:8,barrel:3,module:4,layer:6,slice:5,x:32:-16,y:-16</id>
+    </readout>        
+
+    <readout name="EcalBarrelHits_1">
+      <segmentation type="CartesianGridXY" grid_size_x="5" grid_size_y="5" />
+      <id>system:8,barrel:3,module:4,layer:6,slice:5,x:32:-16,y:-16</id>
+    </readout>        
+
+    <readout name="EcalBarrelHits_2">
+      <segmentation type="CartesianGridXY" grid_size_x="10" grid_size_y="10" />
+      <id>system:8,barrel:3,module:4,layer:6,slice:5,x:32:-16,y:-16</id>
+    </readout>        
+
+  </readouts>
+
+</lccdd>
diff --git a/examples/ClientTests/compact/FCCmachine/BeamInstrumentation.xml b/examples/ClientTests/compact/FCCmachine/BeamInstrumentation.xml
new file mode 100644
index 000000000..99c4aa72c
--- /dev/null
+++ b/examples/ClientTests/compact/FCCmachine/BeamInstrumentation.xml
@@ -0,0 +1,38 @@
+<lccdd>    
+
+  <info name="FCCee"
+        title="FCCee Beam instrumentation: taken correspoding to CLD: BeamInstrumentation_o3_v02_fitShield.xml"
+        author="nalipour taken from lcgeo"
+        url="no"
+        status="development"
+        version="1.0">
+    <comment>A beam instrumentation for FCCee detector based on CLD</comment>
+  </info>
+    
+    <detectors>
+        <comment>Beampipe Instrumentation</comment>
+        
+
+        <detector name="CompSol" type="DD4hep_FCC_Mask_o1_v01" insideTrackingVolume="true" vis="CompSolVis">
+            <parameter crossingangle="CrossingAngle" />
+            <envelope vis="CoilVis">
+                <shape type="Assembly"/>
+            </envelope>
+            <section type="Center"               start="CompSol_min_z"    end="QD0_min_z" rMin1="103*mm"  rMin2="180*mm"  rMax1="123*mm" rMax2="200*mm"    material="SolenoidMixture"  name="CompSol" />
+        </detector>
+
+
+        <detector name="ScreenSol" type="DD4hep_FCC_Mask_o1_v01" insideTrackingVolume="true" vis="ScreenSolVis">
+            <parameter crossingangle="CrossingAngle" />
+            <envelope vis="CoilVis">
+                <shape type="Assembly"/>
+            </envelope>
+
+           <section type="Center"  start="QD0_min_z" end="QD0_min_z+5*cm" rMin1="SeparatedBeamPipe_rmax+1*mm+5*cm" rMin2="SeparatedBeamPipe_rmax+1*mm+5*cm" rMax1="200*mm" rMax2="200*mm" material="SolenoidMixture"  name="CompSol" />
+
+            <section type="Center"    start="QD0_min_z+5*cm"    end="QD0_max_z" rMin1="180*mm"  rMin2="180*mm"  rMax1="200*mm" rMax2="200*mm"    material="SolenoidMixture"  name="CompSol" />
+        </detector>
+
+
+    </detectors>
+</lccdd>
diff --git a/examples/ClientTests/compact/FCCmachine/Beampipe.xml b/examples/ClientTests/compact/FCCmachine/Beampipe.xml
new file mode 100644
index 000000000..2f047a8fd
--- /dev/null
+++ b/examples/ClientTests/compact/FCCmachine/Beampipe.xml
@@ -0,0 +1,154 @@
+<lccdd>
+
+  <info name="FCCee"
+        title="FCCee Beam pipe: taken corresponding to CLD: Beampipe_o4_v04_noNotch_W_n02.xml"
+        author="nalipour taken from lcgeo"
+        url="no"
+        status="development"
+        version="1.0">
+    <comment>A beampipe for FCCee detector based on CLD</comment>
+  </info>
+    
+    <!--  Definition of global dictionary constants          -->
+    <define>
+      <constant name="beampipegoldwidth" value="BeamPipeGoldWidth"/>
+      <constant name="beampipegoldtolerance" value="BeamPipeGoldTolerance"/>
+    </define>
+    
+    <!--  Definition of the used visualization attributes    -->
+    <display>
+        <vis name="BeamPipeVis" alpha="0.0" r="0.0" g="1.0" b="0.0" showDaughters="true" visible="false"/>
+        <vis name="GoldCoatingVis" alpha="0.0" r="0.0" g="1.0" b="1.0" showDaughters="true" visible="true"/>
+        <vis name="TubeVis"  alpha="1.0" r="1.0" g="0.7"  b="0.5"   showDaughters="true"  visible="true"/>
+        <vis name="VacVis"   alpha="1.0" r="1.0" g="1.0"  b="1.0"   showDaughters="true"  visible="false"/>
+    </display>
+    
+    
+    <detectors>
+
+        <comment>Part of beampipe made of Beryllium</comment>
+        
+        <detector name="BeBeampipe" type="DD4hep_Beampipe_o1_v01" insideTrackingVolume="true" nocore="true" vis="BeamPipeVis">
+            <parameter crossingangle="CrossingAngle" />
+            <envelope vis="BlueVis">
+                <shape type="Assembly"/>
+            </envelope>
+
+            <section type="Center"               start="0*mm"    end="CentralBeamPipe_zmax" rMin1="CentralBeamPipe_rmax"  rMin2="CentralBeamPipe_rmax"    rMax1="CentralBeamPipe_rmax+BeamPipeWidth"  rMax2="CentralBeamPipe_rmax+BeamPipeWidth"                material="Beryllium" name="VertexInnerBe" />
+
+            <section type="Center" start="CentralBeamPipe_zmax"  end="BePartEnd_z"  rMin1="CentralBeamPipe_rmax"  rMin2="CentralBeamPipe_rmax+(BePartEnd_z-CentralBeamPipe_zmax)*0.017"      rMax1="CentralBeamPipe_rmax+BeamPipeWidthFirstCone"  rMax2="CentralBeamPipe_rmax+BeamPipeWidthFirstCone+(BePartEnd_z-CentralBeamPipe_zmax)*0.017" material="Beryllium" name="FirstConeBe" />
+
+        </detector>
+
+	<detector name="BeamPipe" type="DD4hep_Beampipe_o1_v01" insideTrackingVolume="true" vis="BeamPipeVis" >
+            <envelope vis="BlueVis">
+                <shape type="Assembly"/>
+            </envelope>
+            <parameter crossingangle="CrossingAngle" />
+
+
+            <comment>Golden foil in the inner part of the Be beampipe</comment>
+
+            <section type="Center"               start="0*mm"    end="CentralBeamPipe_zmax" rMin1="CentralBeamPipe_rmax-(beampipegoldwidth+beampipegoldtolerance)"  rMin2="CentralBeamPipe_rmax-(beampipegoldwidth+beampipegoldtolerance)"    rMax1="CentralBeamPipe_rmax-beampipegoldtolerance"  rMax2="CentralBeamPipe_rmax-beampipegoldtolerance"                material="Gold" name="VertexInnerGold"  />
+
+            <section type="Center" start="CentralBeamPipe_zmax"  end="BePartEnd_z"  rMin1="CentralBeamPipe_rmax-(beampipegoldwidth+beampipegoldtolerance)"  rMin2="CentralBeamPipe_rmax-(beampipegoldwidth+beampipegoldtolerance)+(BePartEnd_z-CentralBeamPipe_zmax)*0.017"      rMax1="CentralBeamPipe_rmax-beampipegoldtolerance"  rMax2="CentralBeamPipe_rmax-beampipegoldtolerance+(BePartEnd_z-CentralBeamPipe_zmax)*0.017" material="Gold" name="FirstConeGold" />
+
+        <comment>Part of beampipe made of Copper</comment>
+        
+            <section type="Center" start="BePartEnd_z"  end="SeparatedBeamPipe_z"  rMin1="CentralBeamPipe_rmax+(BePartEnd_z-CentralBeamPipe_zmax)*0.017"  rMin2="CentralBeamPipe_rmax+(BePartEnd_z-CentralBeamPipe_zmax)*0.017+(SeparatedBeamPipe_z-BePartEnd_z)*0.017"      rMax1="CentralBeamPipe_rmax+BeamPipeWidthFirstCone+(BePartEnd_z-CentralBeamPipe_zmax)*0.017"  rMax2="CentralBeamPipe_rmax+BeamPipeWidthFirstCone+(BePartEnd_z-CentralBeamPipe_zmax)*0.017+(SeparatedBeamPipe_z-BePartEnd_z)*0.017" material="Copper" name="CopperCone" />
+
+
+
+	    <section type="PunchedCenter"        start="SeparatedBeamPipe_z" end="SeparatedBeamPipe_z+3*mm"    rMin1="SeparatedBeamPipe_rmax"      rMin2="SeparatedBeamPipe_rmax"       rMax1="CentralBeamPipe_rmax+BeamPipeWidthFirstCone+(BePartEnd_z-CentralBeamPipe_zmax)*0.015+(SeparatedBeamPipe_z-BePartEnd_z)*0.015"     rMax2="CentralBeamPipe_rmax+BeamPipeWidthFirstCone+(BePartEnd_z-CentralBeamPipe_zmax)*0.017+(SeparatedBeamPipe_z-BePartEnd_z)*0.017 + 3*mm*0.017" material="Copper"     name="SplitVacChambers"/>
+
+
+             <section type="DnstreamClippedFront" start="SeparatedBeamPipe_z+3.01*mm" end="6000*mm"  rMin1="SeparatedBeamPipe_rmax"  rMin2="SeparatedBeamPipe_rmax" rMax1="SeparatedBeamPipe_rmax+1*mm"  rMax2="SeparatedBeamPipe_rmax+1*mm"  material="Copper"      name="DownStreamBeamPipe_1"/>
+
+          
+	   <section type="UpstreamClippedFront"  start="SeparatedBeamPipe_z+3.01*mm" end="6000*mm"  rMin1="SeparatedBeamPipe_rmax"  rMin2="SeparatedBeamPipe_rmax" rMax1="SeparatedBeamPipe_rmax+1*mm"  rMax2="SeparatedBeamPipe_rmax+1*mm"  material="Copper"      name="UpStreamBeamPipe_1"/>
+
+
+</detector>
+<comment>Full Cone Tungsten Shield</comment>
+<detector name="BeamPipeShield" type="DD4hep_FCC_Mask_o1_v01" insideTrackingVolume="true" vis="TantalumVis" >
+        <parameter crossingangle="CrossingAngle" />
+
+        <comment>Before HOM space</comment>
+        <section type="PunchedCenter"        
+        start="LumiCal_max_z + 5*mm" end="1197.5*mm" 
+        rMin1="SeparatedBeamPipe_rmax + BeamPipeWidth + 0.1*mm" 
+        rMin2="SeparatedBeamPipe_rmax + BeamPipeWidth + 0.1*mm "
+        rMax1="SeparatedBeamPipe_rmax + (LumiCal_max_z + 5*mm )*0.015 + BeamPipeWidth + 0.1*mm + BeamPipeTantalShieldWidth"
+        rMax2="SeparatedBeamPipe_rmax + (1197.5*mm) * 0.015 + BeamPipeWidth + 0.1*mm + BeamPipeTantalShieldWidth"
+        material="Tungsten" name="TaShield_BH2" />
+
+
+
+        <comment>After HOM space (1197.5*m - 1298.7*mm) +18 cm as solenoid is now closer to IP </comment>
+        <section type="PunchedCenter"        
+        start="1298.7*mm" end="QD0_min_z + 18*cm" 
+        rMin1="SeparatedBeamPipe_rmax + BeamPipeWidth + 0.1*mm" 
+        rMin2="SeparatedBeamPipe_rmax + BeamPipeWidth + 0.1*mm "
+        rMax1="SeparatedBeamPipe_rmax + (1298.7*mm )*0.015 + BeamPipeWidth + 0.1*mm + BeamPipeTantalShieldWidth"
+        rMax2="SeparatedBeamPipe_rmax + (QD0_min_z + 18*cm) * 0.015 + BeamPipeWidth + 0.1*mm + BeamPipeTantalShieldWidth"
+        material="Tungsten" name="TaShield_AH" />
+
+        </detector>
+<comment>Asymmetric Tungsten Shield no Rotation</comment>
+
+<detector name="BeamPipeShield_noRot" type="DD4hep_FCC_Mask_o1_v01_noRot" insideTrackingVolume="true" vis="TantalumVis"  >
+        <parameter crossingangle="CrossingAngle" />
+
+        <section type="Center"        
+        start="500*mm" end="LumiCal_max_z + 4.9*mm" 
+        rMin1="CentralBeamPipe_rmax + (500.0*mm-CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm"  
+        rMin2="CentralBeamPipe_rmax + (LumiCal_max_z + 4.9*mm-CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm"           
+        rMax1="CentralBeamPipe_rmax + (500.0*mm-CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm + TopFillerShieldWidth"  
+        rMax2="CentralBeamPipe_rmax + (LumiCal_max_z + 4.9*mm-CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm + BeamPipeTantalShieldWidth"
+        Phi1="326*degree"
+        Phi2="34*degree"      
+      
+        material="Tungsten" name="TaShieldTopPart" />
+
+	<comment>was 370</comment>
+        <section type="Center"        
+        start="330*mm" end="500*mm" 
+        rMin1="CentralBeamPipe_rmax + (330*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm"  
+        rMin2="CentralBeamPipe_rmax + (500*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm"           
+        rMax1="CentralBeamPipe_rmax + (330*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm"  
+        rMax2="CentralBeamPipe_rmax + (500*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm + TopFillerShieldWidth"
+        Phi1="326*degree"
+        Phi2="34*degree"      
+      
+        material="Tungsten" name="TaShieldTopPart2" />
+
+
+	<comment>one degree less, to fit lumical window</comment>
+        <section type="Center"        
+        start="600*mm" end="LumiCal_max_z + 4.9*mm" 
+        rMin1="CentralBeamPipe_rmax + (600*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm"  
+        rMin2="CentralBeamPipe_rmax + (LumiCal_max_z + 4.9*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm"           
+        rMax1="CentralBeamPipe_rmax + (600*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm + SideFillerShieldWidth"  
+        rMax2="CentralBeamPipe_rmax + (LumiCal_max_z + 4.9*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm + BeamPipeTantalShieldWidth"
+        Phi1="34*degree"
+        Phi2="70*degree"      
+      
+        material="Tungsten" name="TaShieldFiller1" />
+
+        <section type="Center"        
+        start="600*mm" end="LumiCal_max_z + 4.9*mm" 
+        rMin1="CentralBeamPipe_rmax + (600*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm"  
+        rMin2="CentralBeamPipe_rmax + (LumiCal_max_z + 4.9*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm"           
+        rMax1="CentralBeamPipe_rmax + (600*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm + SideFillerShieldWidth"  
+        rMax2="CentralBeamPipe_rmax + (LumiCal_max_z + 4.9*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm + BeamPipeTantalShieldWidth"
+        Phi1="291*degree"
+        Phi2="326*degree" 
+
+      
+        material="Tungsten" name="TaShieldFiller2" />
+
+
+      </detector>
+
+    </detectors>
+</lccdd>
diff --git a/examples/ClientTests/compact/FCCmachine/FCCee_DectDimensions.xml b/examples/ClientTests/compact/FCCmachine/FCCee_DectDimensions.xml
new file mode 100644
index 000000000..2c4ccc181
--- /dev/null
+++ b/examples/ClientTests/compact/FCCmachine/FCCee_DectDimensions.xml
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lccdd xmlns:compact="http://www.lcsim.org/schemas/compact/1.0"
+       xmlns:xs="http://www.w3.org/2001/XMLSchema"
+       xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/compact/1.0/compact.xsd">
+
+  <info name="FCCDectDimensions"
+	title="master file with includes and world dimension"
+	author="nalipour"
+	url="no"
+	status="development"
+	version="1.0">
+    <comment>
+    </comment>
+  </info>
+
+
+  <define>
+    <constant name="world_side" value="6100*mm"/>
+    <constant name="CrossingAngle" value="0.030*rad"/>  
+
+    <constant name="GlobalTrackerReadoutID_DCH" type="string" value="system:1,layer:16,phi:16"/>
+    <constant name="GlobalTrackerReadoutID" type="string" value="system:5,side:-2,layer:6,module:11,sensor:8"/>
+
+    <constant name="SolenoidField" value="2*tesla"/>
+    
+    
+    <constant name="DetID_NOTUSED"          value=" 0"/>
+    
+    <constant name="DetID_VXD_Barrel"       value=" 1"/>
+    <constant name="DetID_VXD_Endcap"       value=" 2"/>
+    <constant name="DetID_DCH"       value=" 3"/>
+    <constant name="DetID_Calo_Barrel"       value=" 4"/>
+    <constant name="DetID_Calo_Endcap"       value=" 5"/>
+    <constant name="DetID_Calo_Endcap_2"       value=" 6"/>
+
+    <constant name="DetID_HCAL_Barrel"      value=" 10"/>
+    <constant name="DetID_HCAL_Endcap"      value=" 11"/>
+    <constant name="DetID_HCAL_Ring"        value=" 12"/>
+    
+    <constant name="DetID_Yoke_Barrel"      value=" 13"/>
+    <constant name="DetID_Yoke_Endcap"      value=" 14"/>
+    
+    <constant name="DetID_LumiCal"          value=" 15"/>
+    <constant name="DetID_LumiCalInstrumentation"          value=" 16"/>
+    <constant name="DetID_LumiCalCooling"          value=" 17"/>
+    <constant name="DetID_LumiCalBackShield"          value=" 18"/>
+    <constant name="DetID_HOMAbsorber"          value=" 19"/>
+    <constant name="DetID_LumiCalNoseShield"          value=" 22"/>
+    
+    <constant name="BeamPipeWidth"   	value="1.2*mm" />
+    <constant name="BeamPipeWidthFirstCone"   	value="1.0*mm" />
+    <constant name="CentralBeamPipe_zmax" value="12.5*cm"/>
+    <constant name="BePartEnd_z" value="90.0*cm"/>
+    <constant name="SeparatedBeamPipe_z" value="1159.97*mm"/>
+    <constant name="CentralBeamPipe_rmax" value="15.0*mm"/>
+    <constant name="BeamPipeGoldWidth" value="0.005*mm" /> 
+    <constant name="BeamPipeGoldTolerance" value="0.001*mm" />  <!-- dummy tolerance, some small non zero value -->
+    
+    <constant name="InnerTracker_half_length" value="2300*mm" />
+    
+    <constant name="ConeBeamPipe_zmax" value="InnerTracker_half_length" />
+    <constant name="ConeBeamPipe_rmax_1"  value="InnerTracker_half_length * 0.1 + 1*mm" />
+    
+    <constant name="BigBeamPipe_zmax" value="1120*mm"/>
+    <constant name="SeparatedBeamPipe_rmax"  value="15*mm"/>
+    <constant name="BeamPipeTantalShieldWidth"  value="15*mm"/>
+    <constant name="SideFillerShieldWidth"  value="7*mm"/>
+    <constant name="TopFillerShieldWidth"  value="8*mm"/>
+    <constant name="BeamPipe_end" value="12500*mm"/>
+    
+    
+    <constant name="size_x" value="60*mm"/>       
+    <constant name="size_y" value="12*mm"/>         
+    <constant name="size_z" value="50*mm"/>   
+    
+    <constant name="env_safety" value="0.1*mm"/>
+    
+    <constant name="Vertex_inner_radius" value="17*mm"/>
+    <constant name="Vertex_outer_radius" value="111*mm"/>
+    <constant name="Vertex_half_length" value="302*mm"/>
+    
+    <constant name="InnerTracker_inner_radius" value="61*mm"/>
+    <constant name="InnerTracker_outer_radius" value="696*mm"/>
+    
+    <constant name="OuterTracker_inner_radius" value="696*mm"/>
+    <constant name="OuterTracker_outer_radius" value="2145*mm"/>  <!-- to avoid overlap with CaloFace, but it has to be large enough to accommodate OT-->
+    <constant name="OuterTracker_half_length" value="2300*mm"/>
+    
+    <constant name="ECalBarrel_inner_radius" value="2150*mm"/>
+    <constant name="ECalBarrel_outer_radius" value="2352*mm"/>
+    <constant name="ECalBarrel_half_length" value="2210*mm"/>
+    <constant name="ECalBarrel_symmetry" value="12"/>
+    
+    <constant name="ECalEndcap_inner_radius" value="340*mm"/>
+    <constant name="ECalEndcap_outer_radius" value="2350*mm"/>
+    <constant name="ECalEndcap_min_z" value="2307*mm"/>
+    <constant name="ECalEndcap_max_z" value="2509*mm"/>
+    <constant name="ECalEndcap_outer_symmetry" value="12"/>
+    <constant name="ECalEndcap_inner_symmetry" value="12"/>
+    
+    <!-- ECal plug not used -->
+    <constant name="ECalPlug_inner_radius" value="260*mm"/>
+    <constant name="ECalPlug_outer_radius" value="380*mm"/>
+    <constant name="ECalPlug_min_z" value="2307*mm"/>
+    <constant name="ECalPlug_max_z" value="2509*mm"/>
+    <constant name="ECalPlug_outer_symmetry" value="12"/>
+    <constant name="ECalPlug_inner_symmetry" value="12"/>
+    
+    <constant name="HCalBarrel_inner_radius" value="2400*mm"/>
+    <constant name="HCalBarrel_outer_radius" value="3566*mm"/>
+    <constant name="HCalBarrel_half_length" value="2210*mm"/>
+    <constant name="HCalBarrel_symmetry" value="12"/>
+    
+    <constant name="HCalEndcap_inner_radius" value="340*mm"/>
+    <constant name="HCalEndcap_outer_radius" value="3566*mm"/>
+    <constant name="HCalEndcap_min_z" value="2539*mm"/>
+    <constant name="HCalEndcap_max_z" value="3705*mm"/>
+    <constant name="HCalEndcap_symmetry" value="12"/>
+    <constant name="HCalEndcap_zcutout" value="200*mm"/>
+    <constant name="HCalEndcap_rcutout" value="0*mm"/>
+    
+    <constant name="HCalRing_inner_radius" value="2370*mm"/>
+    <constant name="HCalRing_outer_radius" value="HCalEndcap_outer_radius"/>
+    <constant name="HCalRing_min_z" value="2353.5*mm"/>
+    <constant name="HCalRing_max_z" value="HCalEndcap_min_z"/>
+    <constant name="HCalRing_symmetry" value="12"/>
+    
+    <constant name="Solenoid_inner_radius" value="3719*mm"/>
+    <constant name="Solenoid_outer_radius" value="4272*mm"/>
+    <constant name="Solenoid_half_length" value="3705*mm"/>
+    <constant name="Solenoid_Coil_half_length" value="3476*mm"/>
+    <constant name="Solenoid_Coil_radius" value="3930*mm"/>
+    
+    <constant name="YokeBarrel_inner_radius" value="4479*mm"/>
+    <constant name="YokeBarrel_outer_radius" value="6000*mm"/>
+    <constant name="YokeBarrel_half_length" value="3755*mm"/>
+    <constant name="YokeBarrel_symmetry" value="12"/>
+    
+    <constant name="YokeEndcap_inner_radius" value="400*mm"/>
+    <constant name="YokeEndcap_outer_radius" value="6000*mm"/>
+    <constant name="YokeEndcap_min_z" value="3755*mm"/>
+    <constant name="YokeEndcap_max_z" value="5300*mm"/>
+    <constant name="YokeEndcap_outer_symmetry" value="12"/>
+    <constant name="YokeEndcap_inner_symmetry" value="0"/>
+    
+    <constant name="CompSol_min_z" value="1230*mm"/>
+
+    <constant name="LumiCal_max_z" value="1186.5*mm" />
+    <constant name="LumiCal_min_z" value="1074*mm"/>
+    
+    <constant name="LumiCal_dz" value="(LumiCal_max_z-LumiCal_min_z)/2.0"/>
+    
+    <constant name="LumiCal_inner_radius" value="55.0*mm"/>
+    <constant name="LumiCal_outer_radius" value="112.0*mm- env_safety"/>
+    
+    <constant name="LumiCal_Instr_thickness" value="20*mm"/>
+    <constant name="LumiCal_Instr_inner_radius" value="LumiCal_outer_radius"/>
+    <constant name="LumiCal_Instr_outer_radius" value="LumiCal_outer_radius+LumiCal_Instr_thickness - env_safety"/>
+    
+    <constant name="LumiCal_Cool_thickness" value="9.75*mm"/>
+    <constant name="LumiCal_Cool_inner_radius" value="LumiCal_Instr_outer_radius"/>
+    <constant name="LumiCal_Cool_outer_radius" value="LumiCal_Instr_outer_radius+LumiCal_Cool_thickness"/>
+    
+    <constant name="Lcal_services_rmax" value="LumiCal_outer_radius+30*mm"/>
+    <constant name="Lcal_offset_phi" value=" 0."/>
+    <!--preliminary LumiCal shielding-->
+    <!--back shielding-->
+    <constant name="LumiCal_Shield_inner_radius" value="LumiCal_inner_radius"/>
+    <constant name="LumiCal_Shield_outer_radius" value="LumiCal_outer_radius+LumiCal_Instr_thickness+LumiCal_Cool_thickness"/>
+    <constant name="LumiCal_shield_dz" value="1.75*mm"/> 
+    <!--nose-->
+    <constant name="LumiCal_NoseShield_inner_radius" value="LumiCal_inner_radius-5*mm"/>
+    <constant name="LumiCal_NoseShield_outer_radius" value="LumiCal_inner_radius+10*mm"/>
+    <constant name="LumiCal_nose_shield_dz" value="12*mm"/>
+    
+    <constant name="BeamCal_inner_radius" value="32*mm"/>
+    <constant name="BeamCal_outer_radius" value="150*mm"/>
+    <constant name="BeamCal_min_z" value="3181*mm"/>
+    <constant name="BeamCal_max_z" value="3441*mm"/>
+    <constant name="BeamCal_dz" value="(BeamCal_max_z-BeamCal_min_z)/2.0"/>
+    
+    <constant name="Kicker_inner_radius" value="4*mm"/>
+    <constant name="Kicker_outer_radius" value="25*mm"/>
+    <constant name="Kicker_min_z" value="3480*mm"/>
+    <constant name="Kicker_max_z" value="3780*mm"/>
+    
+    <constant name="BPM_inner_radius" value="36*mm"/>
+    <constant name="BPM_outer_radius" value="55*mm"/>
+    <constant name="BPM_min_z" value="3790*mm"/>
+    <constant name="BPM_max_z" value="3880*mm"/>        
+
+    <constant name="QD0_min_z" value="2000*mm"/>
+    <constant name="QD0_max_z" value="5200*mm"/>
+    <constant name="QD0Coil_outer_radius" value="30*mm"/>
+    <constant name="CollimatorInFrontOfQD0_dz" value="20*cm"/>   
+    <constant name="CollimatorInFrontOfQD0_radius" value="10*mm"/>
+    <constant name="CollimatorInFrontOfQD0_dr" value="16*mm"/>
+    
+    <constant name="tracker_region_zmax" value="OuterTracker_half_length"/>
+    <constant name="tracker_region_rmax" value="OuterTracker_outer_radius"/>
+
+    <constant name="GlobalTrackerReadoutID" type="string" value="system:5,side:-2,layer:6,module:11,sensor:8"/>
+  </define>
+  
+  
+  <limits>
+    <limitset name="cal_limits">
+      <limit name="step_length_max" particles="*" value="5.0" unit="mm" />
+    </limitset>
+  </limits>
+  <regions>
+    <region name="BeampipeRegion"/>
+    <region name="VertexBarrelRegion"/>
+    <region name="VertexEndcapRegion"/>
+  </regions>
+
+
+  <display>
+    <vis name="VXDVis"        alpha="0.1" r="0.1" 	g=".5"      b=".5"    showDaughters="true"  visible="false"/>
+    <vis name="VXDLayerVis"   alpha="1.0" r="0.1" 	g=".5"      b=".5"    showDaughters="true"  visible="true"/>
+    <vis name="VXDSupportVis" alpha="1.0" r="0.0" 	g="1.0"     b="0.0"   showDaughters="true"  visible="true"/>
+    <vis name="ITVis"       	alpha="1.0" r="0.54"  	g="0.43"    b="0.04"  showDaughters="true"  visible="true"/>
+    <vis name="OTVis"       	alpha="1.0" r="0.8"   	g="0.8"     b="0.4"   showDaughters="true"  visible="false"/>
+    <vis name="ECALVis"     	alpha="1.0" r="0.2"   	g="0.6"     b="0"     showDaughters="true"  visible="true"/>
+    <vis name="HCALVis"     	alpha="1.0" r="0.078" 	g="0.01176" b="0.588" showDaughters="true"  visible="true"/>
+    <vis name="SOLVis"      	alpha="1.0" r="0.4"   	g="0.4"     b="0.4"   showDaughters="true"  visible="true"/>
+    <vis name="YOKEVis"     	alpha="1.0" r="0.6"   	g="0.0"     b="0.0"   showDaughters="true"  visible="true"/>
+    <vis name="LCALInstrVis"  alpha="1.0" r="0.35"  	g="0.0"     b="0.47"  showDaughters="true"  visible="true"/>
+    <vis name="LCALVis"    	alpha="1.0" r="0.25"  	g="0.88"    b="0.81"  showDaughters="true"  visible="true"/>
+    <vis name="LCALCoolVis"   alpha="1.0" r="0.2"   	g="0.6"     b="0"     showDaughters="true"  visible="true"/>
+    <vis name="BCALVis"     	alpha="1.0" r="0.0"   	g="0.4"     b="0.4"   showDaughters="true"  visible="true"/>
+    <vis name="KICKVis"     	alpha="1.0" r="1.0"   	g="0.498"   b="0.0"   showDaughters="true"  visible="true"/>
+    <vis name="QD0CoilIVis"   alpha="1.0" r="1.0"   	g="0.498"   b="0.0"   showDaughters="true"  visible="true"/>
+    <vis name="QD0CoilOVis"   alpha="1.0" r="1.0"   	g="0.25"    b="0.0"   showDaughters="true"  visible="true"/>
+    <vis name="CompSolVis"    alpha="1.0" r="0.5"   	g="0.5"     b="0.0"   showDaughters="true"  visible="true"/>
+    <vis name="ScreenSolVis"  alpha="1.0" r="1"   	g="1"       b="0"     showDaughters="true"  visible="true"/>
+    <vis name="ColliVis"      alpha="1.0" r="0.7"   	g="0.5"     b="1"     showDaughters="true"  visible="true"/>
+    <vis name="TantalumVis"   alpha="1.0" r="1"   	g="0.5"     b="0.5"   showDaughters="true"  visible="true"/>
+    <vis name="BPMVis"      	alpha="1.0" r="0.25"  	g="0.88"    b="0.81"  showDaughters="true"  visible="true"/>
+    <vis name="SupportVis"  	alpha="1"   r="0.2"   	g="0.2"     b="0.2"   showDaughters="true" visible="true"/>
+  </display>
+
+</lccdd>
diff --git a/examples/ClientTests/compact/FCCmachine/FCCee_DectMaster.xml b/examples/ClientTests/compact/FCCmachine/FCCee_DectMaster.xml
new file mode 100644
index 000000000..a3164bd96
--- /dev/null
+++ b/examples/ClientTests/compact/FCCmachine/FCCee_DectMaster.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lccdd xmlns:compact="http://www.lcsim.org/schemas/compact/1.0"
+  xmlns:xs="http://www.w3.org/2001/XMLSchema"
+  xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/compact/1.0/compact.xsd">
+
+
+
+  <info name="FCCDectMaster"
+    title="FCCee Machine Elements geometry master file"
+    author="Niloufar Alipour Tehrani (adapted: G Ganis)"
+    url="no"
+    status="development"
+    version="1.0">
+    <comment>
+      Machine-releated elements for the FCCee Detector concept.
+    </comment>
+  </info>
+
+  <includes>
+    <gdmlFile  ref="${DD4hepINSTALL}/DDDetectors/compact/elements.xml"/>
+    <gdmlFile  ref="${DD4hepINSTALL}/DDDetectors/compact/materials.xml"/>
+  </includes>
+  <materials>
+    <material name="beam" state="gas">
+      <P unit="pascal" value="6.25e-06"/>
+      <MEE unit="eV" value="38.5760755714278"/>
+      <D unit="g/cm3" value="1.7e-14"/>
+      <fraction n="0.36264" ref="H"/>
+      <fraction n="0.36276" ref="N"/>
+      <fraction n="0.117748421296248" ref="C"/>
+      <fraction n="0.156851578703752" ref="O"/>
+    </material>
+    <material formula="SolenoidMixture" name="SolenoidMixture" state="solid" >
+      <RL type="X0" unit="cm" value="1.75749" />
+      <NIL type="lambda" unit="cm" value="16.959" />
+      <D type="density" unit="g/cm3" value="7.874" />
+      <composite n="1" ref="Fe" />
+    </material>
+   
+  </materials>
+
+  <define>
+    <constant name="world_size" value="25*m"/>
+    <constant name="world_x" value="world_size"/>
+    <constant name="world_y" value="world_size"/>
+    <constant name="world_z" value="world_size"/>
+  </define>
+
+  <include ref="./FCCee_DectDimensions.xml" />
+
+  <include ref="Beampipe.xml"/>
+  <include ref="BeamInstrumentation.xml"/>
+  <include ref="HOMAbsorber.xml"/>
+
+</lccdd>
diff --git a/examples/ClientTests/compact/FCCmachine/HOMAbsorber.xml b/examples/ClientTests/compact/FCCmachine/HOMAbsorber.xml
new file mode 100644
index 000000000..dd4688f48
--- /dev/null
+++ b/examples/ClientTests/compact/FCCmachine/HOMAbsorber.xml
@@ -0,0 +1,62 @@
+<lccdd>
+
+  <info name="FCCee"
+        title="FCCee Beam instrumentation: taken correspoding to CLD: HOMAbsorber_v00.xml"
+        author="nalipour taken from lcgeo"
+        url="no"
+        status="development"
+        version="1.0">
+    <comment> Higher mode absorber for FCCee detector based on CLD</comment>
+  </info>
+
+  <detectors>
+
+    <detector name="HOMAbsorber" type="MaterialEnvelope_o1_v01" vis="SeeThrough" id="DetID_HOMAbsorber" insideTrackingVolume="false" >
+
+      <envelope vis="ITVis">
+
+        <shape type="BooleanShape" operation="Union"  material="Iron">
+
+          <shape type="BooleanShape" operation="Intersection">
+            <shape type="Box"  dx="world_side" dy="world_side" dz="world_side"/>
+            <shape type="BooleanShape" operation="Subtraction">
+	      <shape type="Box"  dx="42.5*mm" dy="37.5*mm" dz="(100.67/2.)*mm" material="Iron" />
+              <shape type="Cone" rmin1="0" rmax1="(1198*mm )*0.015+ SeparatedBeamPipe_rmax +BeamPipeWidth+0.2*mm" rmin2="0" rmax2="(1298.665*mm)*0.015+SeparatedBeamPipe_rmax +BeamPipeWidth+0.2*mm" z="(100.665/2.)*mm+0.1*mm"/>
+              <position x="0" y="0" z="0"/>
+            </shape>
+            <position x="0" y="0" z="1198*mm+(100.665/2.)*mm"/>
+          </shape>
+
+          <shape type="BooleanShape" operation="Intersection">
+            <shape type="Box"  dx="world_side" dy="world_side" dz="world_side"/>
+            <shape type="BooleanShape" operation="Subtraction">
+	      <shape type="Box"  dx="42.5*mm" dy="37.5*mm" dz="(100.67/2.)*mm" material="Iron" />
+              <shape type="Cone" rmin1="0" rmax1="(1298.665*mm+0.2*mm)*0.015+SeparatedBeamPipe_rmax +BeamPipeWidth+0.2*mm" rmin2="0" rmax2="(1198*mm )*0.015+ SeparatedBeamPipe_rmax +BeamPipeWidth+0.2*mm" z="(100.665/2.)*mm+0.1*mm" />
+              <position x="0" y="0" z="0"/>
+            </shape>
+	    <position x="0" y="0" z="-(1198*mm+(100.665/2.)*mm)"/>
+          </shape>
+
+        </shape>
+
+      </envelope>
+
+    </detector>
+
+    <detector name="HOMAbsorbers_PunchThrough" type="DD4hep_FCC_Mask_o1_v01" insideTrackingVolume="true" vis="ITVis" >
+      <parameter crossingangle="CrossingAngle" />
+      
+      <section type="PunchedCenter"        
+	       start="1198*mm" 
+	       end="1298.665*mm" 
+	       rMin1="SeparatedBeamPipe_rmax +BeamPipeWidth+0.1*mm" 
+	       rMin2="SeparatedBeamPipe_rmax +BeamPipeWidth+0.1*mm "
+	       rMax1="(1198*mm )*0.015+ SeparatedBeamPipe_rmax +BeamPipeWidth+0.1*mm "
+               rMax2="(1298.665*mm)*0.015+SeparatedBeamPipe_rmax +BeamPipeWidth+0.1*mm "
+	       material="Iron" name="HOM1" />
+      
+    </detector>
+
+  </detectors>
+  
+</lccdd>
diff --git a/examples/ClientTests/compact/VisAttr_Extend.xml b/examples/ClientTests/compact/VisAttr_Extend.xml
new file mode 100644
index 000000000..bf6fac329
--- /dev/null
+++ b/examples/ClientTests/compact/VisAttr_Extend.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lccdd>
+  
+<!-- #==========================================================================
+     #  AIDA Detector description implementation 
+     #==========================================================================
+     # Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+     # All rights reserved.
+     #
+     # For the licensing terms see $DD4hepINSTALL/LICENSE.
+     # For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+     #
+     #==========================================================================
+-->
+
+  <info name="alignment_boxes"
+	title="Alignment test with 2 simple boxes"
+	author="Markus Frank"
+	url="http://www.cern.ch/lhcb"
+	status="development"
+	version="$Id: compact.xml 513 2013-04-05 14:31:53Z gaede $">
+    <comment>Alignment test with 2 simple boxes</comment>        
+  </info>
+  
+  <includes>
+    <gdmlFile  ref="${DD4hepINSTALL}/DDDetectors/compact/elements.xml"/>
+    <gdmlFile  ref="${DD4hepINSTALL}/DDDetectors/compact/materials.xml"/>
+  </includes>
+  
+  <define>
+    <constant name="world_side" value="30000"/>
+    <constant name="world_x" value="world_side"/>
+    <constant name="world_y" value="world_side"/>
+    <constant name="world_z" value="world_side"/>
+  </define>
+
+  <display>
+    <vis name="InvisibleNoDaughters"      showDaughters="false" visible="false"/>
+    <vis name="InvisibleWithDaughters"    showDaughters="true" visible="false"/>
+    <vis name="B1_vis" alpha="1.0" r="1" g="0" b="0" showDaughters="true" visible="true"/>
+    <vis name="B2_vis" extend="B1_vis" r="0" g="1"/>
+  </display>
+
+  <detectors>
+    <comment>Boxes</comment>
+    <detector id="3" name="B3" type="DD4hep_BoxSegment" vis="B2_vis">
+      <comment>Vertical box</comment>
+      <material name="Steel235"/>
+      <box      x="10"  y="20"   z="30"/>
+      <position x="-10" y="30"   z="10"/>
+      <rotation x="0"   y="0"    z="0"/>
+    </detector>
+    <detector id="3" name="B4" type="DD4hep_BoxSegment" vis="B1_vis">
+      <comment>Vertical box</comment>
+      <material name="Steel235"/>
+      <box      x="10"  y="20"   z="30"/>
+      <position x="0"   y="0"    z="0"/>
+      <rotation x="0"   y="0"    z="0"/>
+    </detector>
+  </detectors>
+</lccdd>
diff --git a/examples/ClientTests/src/FCC_Mask_o1_v01_geo.cpp b/examples/ClientTests/src/FCC_Mask_o1_v01_geo.cpp
new file mode 100644
index 000000000..5a6590be5
--- /dev/null
+++ b/examples/ClientTests/src/FCC_Mask_o1_v01_geo.cpp
@@ -0,0 +1,236 @@
+//====================================================================
+//  LCGeo - LC detector models in DD4hep
+//--------------------------------------------------------------------
+// Mask based on the Beampipe driver (based on TubeX from Mokka), but not
+// filling the centre with Beam vaccum, just places cylinders in arbitrary
+// places with different alignments
+//  A.Sailer, CERN
+//  $Id$
+//====================================================================
+#include "FCC_OtherDetectorHelpers.h"
+
+
+// todo: remove gaudi logging and properly capture output
+#define endmsg std::endl
+#define lLog std::cout
+namespace MSG {
+const std::string ERROR = " Error: ";
+const std::string DEBUG = " Debug: ";
+const std::string INFO  = " Info: ";
+}
+
+#include "DD4hep/DD4hepUnits.h"
+#include "DD4hep/DetFactoryHelper.h"
+#include <cmath>
+#include <string>
+
+using dd4hep::Assembly;
+using dd4hep::ConeSegment;
+using dd4hep::DetElement;
+using dd4hep::Detector;
+using dd4hep::Material;
+using dd4hep::PlacedVolume;
+using dd4hep::Position;
+using dd4hep::Ref_t;
+using dd4hep::RotateY;
+using dd4hep::RotationY;
+using dd4hep::SensitiveDetector;
+using dd4hep::Solid;
+using dd4hep::SubtractionSolid;
+using dd4hep::Transform3D;
+using dd4hep::Tube;
+using dd4hep::Volume;
+
+static Ref_t create_element(Detector& theDetector, xml_h xmlHandle, SensitiveDetector /*sens*/) {
+  //------------------------------------------
+  //  See comments starting with '//**' for
+  //     hints on porting issues
+  //------------------------------------------
+
+  // Access to the XML File
+  xml_det_t xmlMask = xmlHandle;
+  const std::string name = xmlMask.nameStr();
+
+  //--------------------------------
+  Assembly envelope(name + "_assembly");
+  //--------------------------------
+
+  DetElement tube(name, xmlMask.id());
+
+  const double phi1 = 0;
+  const double phi2 = 360.0 * dd4hep::degree;
+
+  // Parameters we have to know about
+  dd4hep::xml::Component xmlParameter = xmlMask.child(_Unicode(parameter));
+  const double crossingAngle = xmlParameter.attr<double>(_Unicode(crossingangle)) * 0.5;  //  only half the angle
+
+  for (xml_coll_t c(xmlMask, Unicode("section")); c; ++c) {
+
+    xml_comp_t xmlSection(c);
+
+    ODH::ECrossType crossType = ODH::getCrossType(xmlSection.attr<std::string>(_Unicode(type)));
+    const double zStart = xmlSection.attr<double>(_Unicode(start));
+    const double zEnd = xmlSection.attr<double>(_Unicode(end));
+    const double rInnerStart = xmlSection.attr<double>(_Unicode(rMin1));
+    const double rInnerEnd = xmlSection.attr<double>(_Unicode(rMin2));
+    const double rOuterStart = xmlSection.attr<double>(_Unicode(rMax1));
+    const double rOuterEnd = xmlSection.attr<double>(_Unicode(rMax2));
+    const double thickness = rOuterStart - rInnerStart;
+    Material sectionMat = theDetector.material(xmlSection.materialStr());
+    const std::string volName = "tube_" + xmlSection.nameStr();
+
+    lLog << MSG::DEBUG << std::setw(8) << zStart << std::setw(8) << zEnd << std::setw(8) << rInnerStart << std::setw(8)
+              << rInnerEnd << std::setw(8) << rOuterStart << std::setw(8) << rOuterEnd << std::setw(8) << thickness
+              << std::setw(8) << crossType << std::setw(15) << volName << std::setw(15) << sectionMat.name()
+              << endmsg;
+
+    // things which can be calculated immediately
+    const double zHalf = fabs(zEnd - zStart) * 0.5;      // half z length of the cone
+    const double zPosition = fabs(zEnd + zStart) * 0.5;  // middle z position
+    Material material = sectionMat;
+
+    // this could mess up your geometry, so better check it
+    if (not ODH::checkForSensibleGeometry(crossingAngle, crossType)) {
+      throw std::runtime_error(" Mask_o1_v01_geo.cpp : checkForSensibleGeometry() failed ");
+    }
+
+    const double rotateAngle =
+        getCurrentAngle(crossingAngle, crossType);  // for the placement at +z (better make it const now)
+    const double mirrorAngle = M_PI - rotateAngle;  // for the "mirrored" placement at -z
+    // the "mirroring" in fact is done by a rotation of (almost) 180 degrees around the y-axis
+
+    switch (crossType) {
+    case ODH::kCenter:
+    case ODH::kUpstream:
+    case ODH::kDnstream: {
+      // a volume on the z-axis, on the upstream branch, or on the downstream branch
+
+      // absolute transformations for the placement in the world
+      Transform3D transformer(RotationY(rotateAngle), RotateY(Position(0, 0, zPosition), rotateAngle));
+      Transform3D transmirror(RotationY(mirrorAngle), RotateY(Position(0, 0, zPosition), mirrorAngle));
+
+      // solid for the tube (including vacuum and wall): a solid cone
+      ConeSegment tubeSolid(zHalf, rInnerStart, rOuterStart, rInnerEnd, rOuterEnd, phi1, phi2);
+
+      // tube consists of vacuum
+      Volume tubeLog(volName, tubeSolid, material);
+      tubeLog.setVisAttributes(theDetector, xmlMask.visStr());
+
+      // placement of the tube in the world, both at +z and -z
+      envelope.placeVolume(tubeLog, transformer);
+      envelope.placeVolume(tubeLog, transmirror);
+
+    } break;
+
+    case ODH::kPunchedCenter: {
+      // a cone with one or two inner holes (two tubes are punched out)
+
+      const double rUpstreamPunch = rInnerStart;  // just alias names denoting what is meant here
+      const double rDnstreamPunch = rInnerEnd;    // (the database entries are "abused" in this case)
+
+      // relative transformations for the composition of the SubtractionVolumes
+      Transform3D upstreamTransformer(RotationY(-crossingAngle), Position(zPosition * tan(-crossingAngle), 0, 0));
+      Transform3D dnstreamTransformer(RotationY(+crossingAngle), Position(zPosition * tan(+crossingAngle), 0, 0));
+
+      // absolute transformations for the final placement in the world (angles always equal zero and 180 deg)
+      Transform3D placementTransformer(RotationY(rotateAngle), RotateY(Position(0, 0, zPosition), rotateAngle));
+      Transform3D placementTransmirror(RotationY(mirrorAngle), RotateY(Position(0, 0, zPosition), mirrorAngle));
+
+      // the main solid and the two pieces (only tubes, for the moment) which will be punched out
+      ConeSegment wholeSolid(zHalf, 0, rOuterStart, 0, rOuterEnd, phi1, phi2);
+      Solid tmpSolid0, tmpSolid1, finalSolid0, finalSolid1;
+
+      // the punched subtraction solids can be asymmetric and therefore have to be created twice:
+      // one time in the "right" way, another time in the "reverse" way, because the "mirroring"
+      // rotation around the y-axis will not only exchange +z and -z, but also +x and -x
+
+      if (rUpstreamPunch > 1e-6) {                                     // do we need a hole on the upstream branch?
+        Tube upstreamPunch(0, rUpstreamPunch, 5 * zHalf, phi1, phi2);  // a bit longer
+        tmpSolid0 = SubtractionSolid(wholeSolid, upstreamPunch, upstreamTransformer);
+        tmpSolid1 = SubtractionSolid(wholeSolid, upstreamPunch, dnstreamTransformer);  // [sic]
+      } else {  // dont't do anything, just pass on the unmodified shape
+        tmpSolid0 = wholeSolid;
+        tmpSolid1 = wholeSolid;
+      }
+
+      if (rDnstreamPunch > 1e-6) {                                     // do we need a hole on the downstream branch?
+        Tube dnstreamPunch(0, rDnstreamPunch, 5 * zHalf, phi1, phi2);  // a bit longer
+        finalSolid0 = SubtractionSolid(tmpSolid0, dnstreamPunch, dnstreamTransformer);
+        finalSolid1 = SubtractionSolid(tmpSolid1, dnstreamPunch, upstreamTransformer);  // [sic]
+      } else {  // dont't do anything, just pass on the unmodified shape
+        finalSolid0 = tmpSolid0;
+        finalSolid1 = tmpSolid1;
+      }
+
+      // tube consists of vacuum (will later have two different daughters)
+      Volume tubeLog0(volName + "_0", finalSolid0, material);
+      Volume tubeLog1(volName + "_1", finalSolid1, material);
+      tubeLog0.setVisAttributes(theDetector, xmlMask.visStr());
+      tubeLog1.setVisAttributes(theDetector, xmlMask.visStr());
+
+      // placement of the tube in the world, both at +z and -z
+      envelope.placeVolume(tubeLog0, placementTransformer);
+      envelope.placeVolume(tubeLog1, placementTransmirror);
+
+      break;
+    }
+
+    case ODH::kPunchedUpstream:
+    case ODH::kPunchedDnstream: {
+      // a volume on the upstream or downstream branch with two inner holes
+      // (implemented as a cone from which another tube is punched out)
+
+      const double rCenterPunch = (crossType == ODH::kPunchedUpstream)
+          ? (rInnerStart)
+          : (rInnerEnd);  // just alias names denoting what is meant here
+      const double rOffsetPunch = (crossType == ODH::kPunchedDnstream)
+          ? (rInnerStart)
+          : (rInnerEnd);  // (the database entries are "abused" in this case)
+
+      // relative transformations for the composition of the SubtractionVolumes
+      Transform3D punchTransformer(RotationY(-2 * rotateAngle), Position(zPosition * tan(-2 * rotateAngle), 0, 0));
+      Transform3D punchTransmirror(RotationY(+2 * rotateAngle), Position(zPosition * tan(+2 * rotateAngle), 0, 0));
+
+      // absolute transformations for the final placement in the world
+      Transform3D placementTransformer(RotationY(rotateAngle), RotateY(Position(0, 0, zPosition), rotateAngle));
+      Transform3D placementTransmirror(RotationY(mirrorAngle), RotateY(Position(0, 0, zPosition), mirrorAngle));
+
+      // the main solid and the piece (only a tube, for the moment) which will be punched out
+      ConeSegment wholeSolid(zHalf, rCenterPunch, rOuterStart, rCenterPunch, rOuterEnd, phi1, phi2);
+      Tube punchSolid(0, rOffsetPunch, 5 * zHalf, phi1, phi2);  // a bit longer
+
+      // the punched subtraction solids can be asymmetric and therefore have to be created twice:
+      // one time in the "right" way, another time in the "reverse" way, because the "mirroring"
+      // rotation around the y-axis will not only exchange +z and -z, but also +x and -x
+      SubtractionSolid finalSolid0(wholeSolid, punchSolid, punchTransformer);
+      SubtractionSolid finalSolid1(wholeSolid, punchSolid, punchTransmirror);
+
+      // tube consists of vacuum (will later have two different daughters)
+      Volume tubeLog0(volName + "_0", finalSolid0, material);
+      Volume tubeLog1(volName + "_1", finalSolid1, material);
+      tubeLog0.setVisAttributes(theDetector, xmlMask.visStr());
+      tubeLog1.setVisAttributes(theDetector, xmlMask.visStr());
+
+      // placement of the tube in the world, both at +z and -z
+      envelope.placeVolume(tubeLog0, placementTransformer);
+      envelope.placeVolume(tubeLog1, placementTransmirror);
+
+      break;
+    }
+    default: { throw std::runtime_error(" Mask_o1_v01_geo.cpp : fatal failure !! ??  "); }
+
+    }  // end switch
+  }    // for all xmlSections
+
+  //--------------------------------------
+  Volume mother = theDetector.pickMotherVolume(tube);
+  PlacedVolume pv(mother.placeVolume(envelope));
+  pv.addPhysVolID("system", xmlMask.id());  //.addPhysVolID("side", 0 ) ;
+
+  tube.setVisAttributes(theDetector, xmlMask.visStr(), envelope);
+
+  tube.setPlacement(pv);
+
+  return tube;
+}
+DECLARE_DETELEMENT(DD4hep_FCC_Mask_o1_v01, create_element)
diff --git a/examples/ClientTests/src/FCC_Mask_o1_v01_noRot_geo.cpp b/examples/ClientTests/src/FCC_Mask_o1_v01_noRot_geo.cpp
new file mode 100644
index 000000000..8f50fa40c
--- /dev/null
+++ b/examples/ClientTests/src/FCC_Mask_o1_v01_noRot_geo.cpp
@@ -0,0 +1,235 @@
+//====================================================================
+//  LCGeo - LC detector models in DD4hep
+//--------------------------------------------------------------------
+// Mask based on the Beampipe driver (based on TubeX from Mokka), but not
+// filling the centre with Beam vaccum, just places cylinders in arbitrary
+// places with different alignments
+//  A.Sailer, CERN
+//  $Id$
+//====================================================================
+#include "FCC_OtherDetectorHelpers.h"
+
+#include "DD4hep/DD4hepUnits.h"
+#include "DD4hep/DetFactoryHelper.h"
+#include <cmath>
+#include <string>
+
+using dd4hep::Assembly;
+using dd4hep::ConeSegment;
+using dd4hep::DetElement;
+using dd4hep::Detector;
+using dd4hep::Material;
+using dd4hep::PlacedVolume;
+using dd4hep::Position;
+using dd4hep::Ref_t;
+using dd4hep::RotateY;
+using dd4hep::RotationY;
+using dd4hep::RotateX;
+using dd4hep::RotationX;
+using dd4hep::SensitiveDetector;
+using dd4hep::Solid;
+using dd4hep::SubtractionSolid;
+using dd4hep::Transform3D;
+using dd4hep::Tube;
+using dd4hep::Volume;
+
+static Ref_t create_element(Detector& theDetector, xml_h xmlHandle, SensitiveDetector /*sens*/) {
+
+  //------------------------------------------
+  //  See comments starting with '//**' for
+  //     hints on porting issues
+  //------------------------------------------
+
+  std::cout << "This is the Mask:" << std::endl;
+
+  // Access to the XML File
+  xml_det_t xmlMask = xmlHandle;
+  const std::string name = xmlMask.nameStr();
+
+  //--------------------------------
+  Assembly envelope(name + "_assembly");
+  //--------------------------------
+
+  DetElement tube(name, xmlMask.id());
+
+  //  const double phi1 = 0 ;
+  //  const double phi2 = 360.0*dd4hep::degree;
+
+  // Parameters we have to know about
+  dd4hep::xml::Component xmlParameter = xmlMask.child(_Unicode(parameter));
+  const double crossingAngle = xmlParameter.attr<double>(_Unicode(crossingangle)) * 0.5;  //  only half the angle
+
+  for (xml_coll_t c(xmlMask, Unicode("section")); c; ++c) {
+
+    xml_comp_t xmlSection(c);
+
+    ODH::ECrossType crossType = ODH::getCrossType(xmlSection.attr<std::string>(_Unicode(type)));
+    const double zStart = xmlSection.attr<double>(_Unicode(start));
+    const double zEnd = xmlSection.attr<double>(_Unicode(end));
+    const double rInnerStart = xmlSection.attr<double>(_Unicode(rMin1));
+    const double rInnerEnd = xmlSection.attr<double>(_Unicode(rMin2));
+    const double rOuterStart = xmlSection.attr<double>(_Unicode(rMax1));
+    const double rOuterEnd = xmlSection.attr<double>(_Unicode(rMax2));
+    const double phi1 = xmlSection.attr<double>(_Unicode(Phi1));
+    const double phi2 = xmlSection.attr<double>(_Unicode(Phi2));
+    const double thickness = rOuterStart - rInnerStart;
+    Material sectionMat = theDetector.material(xmlSection.materialStr());
+    const std::string volName = "tube_" + xmlSection.nameStr();
+
+    std::cout << std::setw(8) << zStart << std::setw(8) << zEnd << std::setw(8) << rInnerStart << std::setw(8)
+              << rInnerEnd << std::setw(8) << rOuterStart << std::setw(8) << rOuterEnd << std::setw(8) << thickness
+              << std::setw(8) << crossType << std::setw(8) << phi1 << std::setw(8) << phi2 << std::setw(15) << volName
+              << std::setw(15) << sectionMat.name() << std::endl;
+
+    // things which can be calculated immediately
+    const double zHalf = fabs(zEnd - zStart) * 0.5;      // half z length of the cone
+    const double zPosition = fabs(zEnd + zStart) * 0.5;  // middle z position
+    Material material = sectionMat;
+
+    // this could mess up your geometry, so better check it
+    if (not ODH::checkForSensibleGeometry(crossingAngle, crossType)) {
+      throw std::runtime_error(" Mask_o1_v01_noRot_geo.cpp : checkForSensibleGeometry() failed ");
+    }
+
+    const double rotateAngle =
+        getCurrentAngle(crossingAngle, crossType);  // for the placement at +z (better make it const now)
+    const double mirrorAngle = M_PI - rotateAngle;  // for the "mirrored" placement at -z
+    // the "mirroring" in fact is done by a rotation of (almost) 180 degrees around the y-axis
+
+    switch (crossType) {
+    case ODH::kCenter:
+    case ODH::kUpstream:
+    case ODH::kDnstream: {
+      // a volume on the z-axis, on the upstream branch, or on the downstream branch
+
+      // absolute transformations for the placement in the world, rotate over X
+      Transform3D transformer(RotationX(rotateAngle), RotateX(Position(0, 0, zPosition), rotateAngle));
+      Transform3D transmirror(RotationX(mirrorAngle), RotateX(Position(0, 0, zPosition), mirrorAngle));
+
+      // solid for the tube (including vacuum and wall): a solid cone
+      ConeSegment tubeSolid(zHalf, rInnerStart, rOuterStart, rInnerEnd, rOuterEnd, phi1, phi2);
+
+      // tube consists of vacuum
+      Volume tubeLog(volName, tubeSolid, material);
+      tubeLog.setVisAttributes(theDetector, xmlMask.visStr());
+
+      // placement of the tube in the world, both at +z and -z
+      envelope.placeVolume(tubeLog, transformer);
+      envelope.placeVolume(tubeLog, transmirror);
+
+    } break;
+
+    case ODH::kPunchedCenter: {
+      // a cone with one or two inner holes (two tubes are punched out)
+
+      const double rUpstreamPunch = rInnerStart;  // just alias names denoting what is meant here
+      const double rDnstreamPunch = rInnerEnd;    // (the database entries are "abused" in this case)
+
+      // relative transformations for the composition of the SubtractionVolumes
+      Transform3D upstreamTransformer(RotationY(-crossingAngle), Position(zPosition * tan(-crossingAngle), 0, 0));
+      Transform3D dnstreamTransformer(RotationY(+crossingAngle), Position(zPosition * tan(+crossingAngle), 0, 0));
+
+      // absolute transformations for the final placement in the world (angles always equal zero and 180 deg)
+      Transform3D placementTransformer(RotationY(rotateAngle), RotateY(Position(0, 0, zPosition), rotateAngle));
+      Transform3D placementTransmirror(RotationY(mirrorAngle), RotateY(Position(0, 0, zPosition), mirrorAngle));
+
+      // the main solid and the two pieces (only tubes, for the moment) which will be punched out
+      ConeSegment wholeSolid(zHalf, 0, rOuterStart, 0, rOuterEnd, phi1, phi2);
+      Solid tmpSolid0, tmpSolid1, finalSolid0, finalSolid1;
+
+      // the punched subtraction solids can be asymmetric and therefore have to be created twice:
+      // one time in the "right" way, another time in the "reverse" way, because the "mirroring"
+      // rotation around the y-axis will not only exchange +z and -z, but also +x and -x
+
+      if (rUpstreamPunch > 1e-6) {                                     // do we need a hole on the upstream branch?
+        Tube upstreamPunch(0, rUpstreamPunch, 5 * zHalf, phi1, phi2);  // a bit longer
+        tmpSolid0 = SubtractionSolid(wholeSolid, upstreamPunch, upstreamTransformer);
+        tmpSolid1 = SubtractionSolid(wholeSolid, upstreamPunch, dnstreamTransformer);  // [sic]
+      } else {  // dont't do anything, just pass on the unmodified shape
+        tmpSolid0 = wholeSolid;
+        tmpSolid1 = wholeSolid;
+      }
+
+      if (rDnstreamPunch > 1e-6) {                                     // do we need a hole on the downstream branch?
+        Tube dnstreamPunch(0, rDnstreamPunch, 5 * zHalf, phi1, phi2);  // a bit longer
+        finalSolid0 = SubtractionSolid(tmpSolid0, dnstreamPunch, dnstreamTransformer);
+        finalSolid1 = SubtractionSolid(tmpSolid1, dnstreamPunch, upstreamTransformer);  // [sic]
+      } else {  // dont't do anything, just pass on the unmodified shape
+        finalSolid0 = tmpSolid0;
+        finalSolid1 = tmpSolid1;
+      }
+
+      // tube consists of vacuum (will later have two different daughters)
+      Volume tubeLog0(volName + "_0", finalSolid0, material);
+      Volume tubeLog1(volName + "_1", finalSolid1, material);
+      tubeLog0.setVisAttributes(theDetector, xmlMask.visStr());
+      tubeLog1.setVisAttributes(theDetector, xmlMask.visStr());
+
+      // placement of the tube in the world, both at +z and -z
+      envelope.placeVolume(tubeLog0, placementTransformer);
+      envelope.placeVolume(tubeLog1, placementTransmirror);
+
+      break;
+    }
+
+    case ODH::kPunchedUpstream:
+    case ODH::kPunchedDnstream: {
+      // a volume on the upstream or downstream branch with two inner holes
+      // (implemented as a cone from which another tube is punched out)
+
+      const double rCenterPunch = (crossType == ODH::kPunchedUpstream)
+          ? (rInnerStart)
+          : (rInnerEnd);  // just alias names denoting what is meant here
+      const double rOffsetPunch = (crossType == ODH::kPunchedDnstream)
+          ? (rInnerStart)
+          : (rInnerEnd);  // (the database entries are "abused" in this case)
+
+      // relative transformations for the composition of the SubtractionVolumes
+      Transform3D punchTransformer(RotationY(-2 * rotateAngle), Position(zPosition * tan(-2 * rotateAngle), 0, 0));
+      Transform3D punchTransmirror(RotationY(+2 * rotateAngle), Position(zPosition * tan(+2 * rotateAngle), 0, 0));
+
+      // absolute transformations for the final placement in the world
+      Transform3D placementTransformer(RotationY(rotateAngle), RotateY(Position(0, 0, zPosition), rotateAngle));
+      Transform3D placementTransmirror(RotationY(mirrorAngle), RotateY(Position(0, 0, zPosition), mirrorAngle));
+
+      // the main solid and the piece (only a tube, for the moment) which will be punched out
+      ConeSegment wholeSolid(zHalf, rCenterPunch, rOuterStart, rCenterPunch, rOuterEnd, phi1, phi2);
+      Tube punchSolid(0, rOffsetPunch, 5 * zHalf, phi1, phi2);  // a bit longer
+
+      // the punched subtraction solids can be asymmetric and therefore have to be created twice:
+      // one time in the "right" way, another time in the "reverse" way, because the "mirroring"
+      // rotation around the y-axis will not only exchange +z and -z, but also +x and -x
+      SubtractionSolid finalSolid0(wholeSolid, punchSolid, punchTransformer);
+      SubtractionSolid finalSolid1(wholeSolid, punchSolid, punchTransmirror);
+
+      // tube consists of vacuum (will later have two different daughters)
+      Volume tubeLog0(volName + "_0", finalSolid0, material);
+      Volume tubeLog1(volName + "_1", finalSolid1, material);
+      tubeLog0.setVisAttributes(theDetector, xmlMask.visStr());
+      tubeLog1.setVisAttributes(theDetector, xmlMask.visStr());
+
+      // placement of the tube in the world, both at +z and -z
+      envelope.placeVolume(tubeLog0, placementTransformer);
+      envelope.placeVolume(tubeLog1, placementTransmirror);
+
+      break;
+    }
+    default: { throw std::runtime_error(" Mask_o1_v01_geo.cpp : fatal failure !! ??  "); }
+
+    }  // end switch
+  }    // for all xmlSections
+
+  //--------------------------------------
+  Volume mother = theDetector.pickMotherVolume(tube);
+  PlacedVolume pv(mother.placeVolume(envelope));
+  pv.addPhysVolID("system", xmlMask.id());  //.addPhysVolID("side", 0 ) ;
+
+  tube.setVisAttributes(theDetector, xmlMask.visStr(), envelope);
+
+  tube.setPlacement(pv);
+
+  return tube;
+}
+
+DECLARE_DEPRECATED_DETELEMENT(DD4hep_FCC_Mask_o1_v01_noRot, create_element)
+
diff --git a/examples/ClientTests/src/FCC_MaterialEnvelope_o1_v01.cpp b/examples/ClientTests/src/FCC_MaterialEnvelope_o1_v01.cpp
new file mode 100644
index 000000000..8a8a66589
--- /dev/null
+++ b/examples/ClientTests/src/FCC_MaterialEnvelope_o1_v01.cpp
@@ -0,0 +1,35 @@
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M. Petric
+//               A driver just to place a envelope, to placement of dead material
+//
+//====================================================================
+#include "DD4hep/DetFactoryHelper.h"
+#include "XML/Layering.h"
+#include "XML/Utilities.h"
+
+using namespace std;
+
+using dd4hep::DetElement;
+using dd4hep::Detector;
+using dd4hep::Ref_t;
+using dd4hep::SensitiveDetector;
+
+// workaround for DD4hep v00-14 (and older)
+#ifndef DD4HEP_VERSION_GE
+#define DD4HEP_VERSION_GE(a, b) 0
+#endif
+
+static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector) {
+  xml_det_t x_det = e;
+  string det_name = x_det.nameStr();
+  DetElement sdet(det_name, x_det.id());
+
+  dd4hep::xml::createPlacedEnvelope(theDetector, e, sdet);
+
+  return sdet;
+}
+
+DECLARE_DETELEMENT(MaterialEnvelope_o1_v01, create_detector)
diff --git a/examples/ClientTests/src/FCC_OtherDetectorHelpers.h b/examples/ClientTests/src/FCC_OtherDetectorHelpers.h
new file mode 100644
index 000000000..70cc47297
--- /dev/null
+++ b/examples/ClientTests/src/FCC_OtherDetectorHelpers.h
@@ -0,0 +1,110 @@
+#ifndef Other_Helpers_hh
+#define Other_Helpers_hh 1
+//====================================================================
+//  LCGeo - LC detector models in DD4hep
+//--------------------------------------------------------------------
+//  Helper functions used by detector constructers
+//  A.Sailer, CERN
+//  $Id$
+//====================================================================
+
+#include <iostream>
+#include <map>
+#include <stdexcept>
+
+namespace ODH {  // OtherDetectorHelpers
+
+typedef enum {                // These constants are also used in the MySQL database:
+  kCenter = 0,                // centered on the z-axis
+  kUpstream = 1,              // on the upstream branch, rotated by half the crossing angle
+  kDnstream = 2,              // on the downstream branch, rotated by half the crossing angle
+  kPunchedCenter = 3,         // centered, with one or two inner holes
+  kPunchedUpstream = 4,       // on the upstream branch, with two inner holes
+  kPunchedDnstream = 5,       // on the downstrem branch, with two inner holes
+  kUpstreamClippedFront = 6,  // upstream, with the front face parallel to the xy-plane
+  kDnstreamClippedFront = 7,  // downstream, with the front face parallel to the xy-plane
+  kUpstreamClippedRear = 8,   // upstream, with the rear face parallel to the xy-plane
+  kDnstreamClippedRear = 9,   // downstream, with the rear face parallel to the xy-plane
+  kUpstreamClippedBoth = 10,  // upstream, with both faces parallel to the xy-plane
+  kDnstreamClippedBoth = 11,  // downstream, with both faces parallel to the xy-plane
+  kUpstreamSlicedFront = 12,  // upstream, with the front face parallel to a tilted piece
+  kDnstreamSlicedFront = 13,  // downstream, with the front face parallel to a tilted piece
+  kUpstreamSlicedRear = 14,   // upstream, with the rear face parallel to a tilted piece
+  kDnstreamSlicedRear = 15,   // downstream, with the rear face parallel to a tilted piece
+  kUpstreamSlicedBoth = 16,   // upstream, with both faces parallel to a tilted piece
+  kDnstreamSlicedBoth = 17    // downstream, with both faces parallel to a tilted piece
+} ECrossType;
+
+inline ECrossType getCrossType(std::string const& type) {
+
+  std::map<std::string, ODH::ECrossType> CrossTypes;
+  CrossTypes["Center"] = ODH::kCenter;
+  CrossTypes["Upstream"] = ODH::kUpstream;
+  CrossTypes["Dnstream"] = ODH::kDnstream;
+  CrossTypes["PunchedCenter"] = ODH::kPunchedCenter;
+  CrossTypes["PunchedUpstream"] = ODH::kPunchedUpstream;
+  CrossTypes["PunchedDnstream"] = ODH::kPunchedDnstream;
+  CrossTypes["UpstreamClippedFront"] = ODH::kUpstreamClippedFront;
+  CrossTypes["DnstreamClippedFront"] = ODH::kDnstreamClippedFront;
+  CrossTypes["UpstreamClippedRear"] = ODH::kUpstreamClippedRear;
+  CrossTypes["DnstreamClippedRear"] = ODH::kDnstreamClippedRear;
+  CrossTypes["UpstreamClippedBoth"] = ODH::kUpstreamClippedBoth;
+  CrossTypes["DnstreamClippedBoth"] = ODH::kDnstreamClippedBoth;
+  CrossTypes["UpstreamSlicedFront"] = ODH::kUpstreamSlicedFront;
+  CrossTypes["DnstreamSlicedFront"] = ODH::kDnstreamSlicedFront;
+  CrossTypes["UpstreamSlicedRear"] = ODH::kUpstreamSlicedRear;
+  CrossTypes["DnstreamSlicedRear"] = ODH::kDnstreamSlicedRear;
+  CrossTypes["UpstreamSlicedBoth"] = ODH::kUpstreamSlicedBoth;
+  CrossTypes["DnstreamSlicedBoth"] = ODH::kDnstreamSlicedBoth;
+
+  std::map<std::string, ODH::ECrossType>::const_iterator ct = CrossTypes.find(type);
+  if (ct == CrossTypes.end()) {
+    throw std::runtime_error("Unknown Crossing Type for this geometry");
+  }
+  return ct->second;
+}
+
+inline bool checkForSensibleGeometry(double crossingAngle, ECrossType crossType) {
+  if (crossingAngle == 0 && crossType != kCenter) {
+    std::cout << "Mask: You are trying to build a crossing geometry without a crossing angle.\n"
+                 "This is probably not what you want - better check your geometry data!"
+              << std::endl;
+    return false;  // premature exit, dd4hep will abort now
+  }
+  return true;
+}
+
+inline double getCurrentAngle(double crossingAngle, ECrossType crossType) {
+  double tmpAngle;
+  switch (crossType) {
+  case kUpstream:
+  case kPunchedUpstream:
+  case kUpstreamClippedFront:
+  case kUpstreamClippedRear:
+  case kUpstreamClippedBoth:
+  case kUpstreamSlicedFront:
+  case kUpstreamSlicedRear:
+  case kUpstreamSlicedBoth:
+    tmpAngle = -crossingAngle;
+    break;
+  case kDnstream:
+  case kPunchedDnstream:
+  case kDnstreamClippedFront:
+  case kDnstreamClippedRear:
+  case kDnstreamClippedBoth:
+  case kDnstreamSlicedFront:
+  case kDnstreamSlicedRear:
+  case kDnstreamSlicedBoth:
+    tmpAngle = +crossingAngle;
+    break;
+  default:
+    tmpAngle = 0;
+    break;
+  }
+
+  return tmpAngle;
+}
+
+}  // namespace
+
+#endif  // Other_Helpers_hh
diff --git a/examples/DDCAD/compact/Import_FCC_Machine.xml b/examples/DDCAD/compact/Import_FCC_Machine.xml
new file mode 100644
index 000000000..c63a2fa3f
--- /dev/null
+++ b/examples/DDCAD/compact/Import_FCC_Machine.xml
@@ -0,0 +1,50 @@
+<lccdd>
+<!--
+    #==========================================================================
+    #  AIDA Detector description implementation 
+    #==========================================================================
+    # Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+    # All rights reserved.
+    #
+    # For the licensing terms see $DD4hepINSTALL/LICENSE.
+    # For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+    #
+    #==========================================================================
+-->
+
+  <includes>
+    <gdmlFile  ref="${DD4hepINSTALL}/DDDetectors/compact/elements.xml"/>
+    <gdmlFile  ref="${DD4hepINSTALL}/DDDetectors/compact/materials.xml"/>
+  </includes>
+  <materials>
+    <material name="beam" state="gas">
+      <P unit="pascal" value="6.25e-06"/>
+      <MEE unit="eV" value="38.5760755714278"/>
+      <D unit="g/cm3" value="1.7e-14"/>
+      <fraction n="0.36264" ref="H"/>
+      <fraction n="0.36276" ref="N"/>
+      <fraction n="0.117748421296248" ref="C"/>
+      <fraction n="0.156851578703752" ref="O"/>
+    </material>
+    <material formula="SolenoidMixture" name="SolenoidMixture" state="solid" >
+      <RL type="X0" unit="cm" value="1.75749" />
+      <NIL type="lambda" unit="cm" value="16.959" />
+      <D type="density" unit="g/cm3" value="7.874" />
+      <composite n="1" ref="Fe" />
+    </material>
+  </materials>
+  <define>
+    <constant name="world_size" value="25*m"/>
+    <constant name="world_x" value="world_size"/>
+    <constant name="world_y" value="world_size"/>
+    <constant name="world_z" value="world_size"/>
+  </define>
+
+  <detectors>
+    <detector id="1" name="Shape_Collada" type="DD4hep_TestShape_Creator">
+      <check>
+        <shape type="CAD_MultiVolume" ref="./Machine.collada" unit="cm"/>
+      </check>
+    </detector>
+  </detectors>
+</lccdd>
-- 
GitLab