From 5a8fe9f9fcf353c44d1b0a753a5b125f73518f54 Mon Sep 17 00:00:00 2001
From: "221840222@smail.nju.edu.cn" <221840222@smail.nju.edu.cn>
Date: Wed, 12 Jun 2024 03:57:50 +0000
Subject: [PATCH] Lumical Detector build

---
 Detector/DetCRD/CMakeLists.txt                |   2 +
 .../CRD_common_v01/Beampipe_v01_02.xml        |   5 +-
 .../CRD_common_v01/Lumical_Beampipe.xml       |  48 ++
 .../compact/CRD_common_v01/Lumical_o1_v01.xml | 121 +++++
 .../compact/CRD_common_v02/materials.xml      |   9 +
 .../Standalone/Lumical_o1_v01_standalone.xml  |  20 +
 .../TDR_o1_v01/TDR_Dimensions_v01_01.xml      |   2 +-
 .../DetCRD/compact/TDR_o1_v01/TDR_o1_v01.xml  |   2 +
 .../src/Calorimeter/Lumical_v01_geo.cpp       | 440 ++++++++++++++++++
 .../src/Other/Lumical_v01_geo_beampipe.cpp    | 184 ++++++++
 .../src/Edm4hepWriterAnaElemTool.cpp          |   6 +
 .../DetSimAna/src/Edm4hepWriterAnaElemTool.h  |   7 +-
 12 files changed, 842 insertions(+), 4 deletions(-)
 create mode 100644 Detector/DetCRD/compact/CRD_common_v01/Lumical_Beampipe.xml
 create mode 100644 Detector/DetCRD/compact/CRD_common_v01/Lumical_o1_v01.xml
 create mode 100644 Detector/DetCRD/compact/Standalone/Lumical_o1_v01_standalone.xml
 create mode 100644 Detector/DetCRD/src/Calorimeter/Lumical_v01_geo.cpp
 create mode 100644 Detector/DetCRD/src/Other/Lumical_v01_geo_beampipe.cpp

diff --git a/Detector/DetCRD/CMakeLists.txt b/Detector/DetCRD/CMakeLists.txt
index e99d0789..d1bf4f67 100644
--- a/Detector/DetCRD/CMakeLists.txt
+++ b/Detector/DetCRD/CMakeLists.txt
@@ -20,6 +20,8 @@ gaudi_add_module(DetCRD
                          src/Calorimeter/LongCrystalBarBarrelCalorimeter32Polygon_v01.cpp
                          src/Calorimeter/RotatedPolyhedraBarrelCalorimeter_v01_geo.cpp
                          src/Calorimeter/RotatedCrystalCalorimeter_v01_geo.cpp
+                         src/Calorimeter/Lumical_v01_geo.cpp
+                         src/Other/Lumical_v01_geo_beampipe.cpp
                          src/Other/CRDBeamPipe_v01_geo.cpp
                          src/Muon/Muon_Barrel_v01.cpp
                          src/Muon/Muon_Endcap_v01.cpp
diff --git a/Detector/DetCRD/compact/CRD_common_v01/Beampipe_v01_02.xml b/Detector/DetCRD/compact/CRD_common_v01/Beampipe_v01_02.xml
index 24f79c29..54e4e2c1 100644
--- a/Detector/DetCRD/compact/CRD_common_v01/Beampipe_v01_02.xml
+++ b/Detector/DetCRD/compact/CRD_common_v01/Beampipe_v01_02.xml
@@ -101,9 +101,10 @@
       <section type="CenterSide" name="Magnet_3" zStart="3970*mm" zEnd="7000*mm" rStart="185*mm">
         <layer material="superconductor" thickness="10*mm" vis="MagentaVis"/>
       </section>
-      <section type="CenterSide" name="MagnetShell_1" zStart="970*mm" zEnd="1110*mm" rStart="33*mm">
+      <!--TO DO: overlap with Lumical-->
+      <!--section type="CenterSide" name="MagnetShell_1" zStart="970*mm" zEnd="1110*mm" rStart="33*mm">
         <layer material="stainless_steel" thickness="1.5*mm" vis="ShellVis"/>
-      </section>
+      </section-->
       <section type="CenterSide" name="MagnetShell_2" zStart="1110*mm" zEnd="1115*mm" rStart="50.0*mm">
         <layer material="stainless_steel" thickness="91.25*mm" vis="ShellVis"/>
       </section>
diff --git a/Detector/DetCRD/compact/CRD_common_v01/Lumical_Beampipe.xml b/Detector/DetCRD/compact/CRD_common_v01/Lumical_Beampipe.xml
new file mode 100644
index 00000000..203ee19f
--- /dev/null
+++ b/Detector/DetCRD/compact/CRD_common_v01/Lumical_Beampipe.xml
@@ -0,0 +1,48 @@
+<lccdd>
+
+    <define>
+        <include ref="${DD4hepINSTALL}/DDDetectors/compact/detector_types.xml"/>
+    </define>
+
+
+    <detectors>
+        <detector name="Lumical_Beampipe" type="Lumical_v01_standalone"  vis="SeeThroughit" insideTrackingVolume="false">
+            <envelope>
+                <shape type="Assembly"/>
+            </envelope>       
+            <type_flags type=" DetType_CALORIMETER + DetType_BARREL + DetType_HADRONIC " />
+            <beampipe_Be_inner type="Tubs" rmin="10*mm" rmax="10.5*mm" z="85*mm" phi1="0*deg" phi2="360*deg" material="G4_Be" vis="SeeThroughit">
+                <position x="0*mm" y="0*mm" z="42.5*mm"/>
+                <rotation x="0" y="0" z="0"/>
+            </beampipe_Be_inner>
+            <beampipe_Be_outter type="Tubs" rmin="11*mm" rmax="11.35*mm" z="85*mm" phi1="0*deg" phi2="360*deg" material="G4_Be" vis="SeeThroughit">
+                <position x="0*mm" y="0*mm" z="42.5*mm"/>
+                <rotation x="0" y="0" z="0"/>
+            </beampipe_Be_outter>
+            <beampipe_Al_inner type="Tubs" rmin="10*mm" rmax="10.5*mm" z="95*mm" phi1="0*deg" phi2="360*deg" material="G4_Al" vis="SeeThroughit">
+                <position x="0*mm" y="0*mm" z="132.5*mm"/>
+                <rotation x="0" y="0" z="0"/>
+            </beampipe_Al_inner>
+            <beampipe_Al_outter type="Tubs" rmin="11*mm" rmax="11.35*mm" z="95*mm" phi1="0*deg" phi2="360*deg" material="G4_Al" vis="SeeThroughit">
+                <position x="0*mm" y="0*mm" z="132.5*mm"/>
+                <rotation x="0" y="0" z="0"/>
+            </beampipe_Al_outter>
+            <runway type="Tubs" rmin="10*mm" rmax="11*mm" z="474.8*mm" phi1="0*deg" phi2="180*deg" material="G4_Al" vis="SeeThroughit">
+                <position x="3.75*mm" y="0*mm" z="417.58*mm"/>
+                <rotation x="0" y="0" z="0"/>
+            </runway>
+            <beampipe>
+                <slice type="Tubs" rmin="10*mm" rmax="11*mm" z="125*mm" phi1="0*deg" phi2="180*deg" material="G4_Cu" vis="SeeThroughit">
+                    <position x="3.75*mm" y="0*mm" z="717.5*mm"/>
+                </slice>
+                <slice type="Cone" rmin1="10*mm" rmax1="11*mm" rmin2="20*mm" rmax2="21*mm" z="75*mm" phi1="0*deg" phi2="180*deg" material="G4_Cu" vis="SeeThroughit">
+                    <position x="3.75*mm" y="0*mm" z="817.5*mm"/>
+                </slice>
+                <slice type="Tubs" rmin="10*mm" rmax="11*mm" z="345*mm" phi1="0*deg" phi2="360*deg" material="G4_Al" vis="SeeThroughit">
+                    <position x="11*mm" y="0*mm" z="1027.5*mm"/>
+                </slice>
+            </beampipe>
+        </detector>
+    </detectors>
+            
+</lccdd>
\ No newline at end of file
diff --git a/Detector/DetCRD/compact/CRD_common_v01/Lumical_o1_v01.xml b/Detector/DetCRD/compact/CRD_common_v01/Lumical_o1_v01.xml
new file mode 100644
index 00000000..cd5109cb
--- /dev/null
+++ b/Detector/DetCRD/compact/CRD_common_v01/Lumical_o1_v01.xml
@@ -0,0 +1,121 @@
+<lccdd>
+    
+    <define>
+        <constant name="Lumical_cell_size" value="3*mm"/>
+        <include ref="${DD4hepINSTALL}/DDDetectors/compact/detector_types.xml"/>
+        
+    </define>
+
+  <display>
+    <vis name="SeeThroughit"       alpha="0.0" r="0.0" g="0.0"  b="0.0"   showDaughters="true"  visible="false"/>
+    <vis name="Gray_Vis"          alpha="1.0" r="0.5" g="0.5"  b="0.5"   showDaughters="true"  visible="true"/>
+    <vis name="DiskVis"          alpha="1.0" r="0" g="0.5"  b="0.5"   showDaughters="true"  visible="true"/>
+    <vis name="beamVis_Al"          alpha="1.0" r="1.0" g="1"  b="1.0"   showDaughters="true"  visible="true"/>
+    <vis name="beamVis_Be"          alpha="1.0" r="0" g="1"  b="0"   showDaughters="true"  visible="true"/>
+    <vis name="FlangeVis"           alpha="1.0" r="1.0" g="1.0" b="1.0" showDaughters="true" visible="true"/>
+    <vis name="CuVis"               alpha="1.0" r="1.0" g="1.0" b="0" showDaughters="true" visible="true"/>
+  </display>
+
+
+    <detectors>
+        <detector name="Lumical" id="DetID_LCAL" type="Lumical_v01" readout="LumicalCollection" vis="SeeThroughit" insideTrackingVolume="false">
+            <envelope> 
+                <shape type = "Assembly"/>
+            </envelope>
+            <type_flags type=" DetType_CALORIMETER + DetType_BARREL + DetType_HADRONIC " />
+
+            <sensitive type="calorimeter"/>
+            
+            <subsegmentation key="module" value="1"/>
+            <subsegmentation key="module" value="2"/>
+            <subsegmentation key="module" value="3"/>
+            <subsegmentation key="module" value="5"/>
+            
+            <layer name = "Disk_Si_1st">
+                <slice type = "Box" dx = "12*mm" dy="29.5*mm" dz = "6*mm" material = "G4_Si" vis="DiskVis" sensitive="yes" limits="5*mm">
+                    <position x="0" y="26.75*mm" z="560*mm"/>
+                </slice>
+                <slice type="Tubs" rmin="0" rmax="29.5*mm" z="6*mm" phi1="0*deg" phi2="90*deg" material="G4_Si" vis="DiskVis" sensitive="yes" limits="5*mm">
+                    <position x="6*mm" y="12*mm" z="560*mm"/>
+                </slice>
+            </layer>
+            <layer name = "Disk_Si_2nd">
+                <slice type ="Box" dx = "24*mm" dy="39*mm" dz = "7.263*mm" material = "G4_Si" vis="DiskVis" sensitive="yes" limits="5*mm">
+                    <position x="0" y="31.5*mm" z="640*mm"/>
+                </slice>
+                <slice type="Tubs" rmin="0" rmax="39*mm" z="6*mm" phi1="0*deg" phi2="90*deg" material="G4_Si" vis="DiskVis" sensitive="yes" limits="5*mm">
+                    <position x="12*mm" y="12*mm" z="640*mm"/>
+                </slice>
+            </layer>
+            <layer name = "Flange">
+                <slice type="Tubs" rmin="17.5*mm" rmax="100*mm" z="30*mm" phi1="0*deg" phi2="360*deg" material="stainless_steel" vis="FlangeVis">
+                    <position x="0" y="0*mm" z="685*mm"/>
+                </slice>
+                <slice type="Tubs" rmin="17.5*mm" rmax="95*mm" z="20*mm" phi1="0*deg" phi2="360*deg" material="stainless_steel" vis="FlangeVis">
+                    <position x="0" y="0*mm" z="710*mm"/>
+                </slice>
+                <slice type="Tubs" rmin="17.5*mm" rmax="98*mm" z="20*mm" phi1="0*deg" phi2="360*deg" material="stainless_steel" vis="FlangeVis">
+                    <position x="0" y="0*mm" z="730*mm"/>
+                </slice>
+                <slice type="Tubs" rmin="17.5*mm" rmax="95*mm" z="1*mm" phi1="0*deg" phi2="360*deg" material="stainless_steel" vis="FlangeVis">
+                    <position x="0" y="0*mm" z="750*mm"/>
+                </slice>
+                <slice type="Tubs" rmin="17.5*mm" rmax="95*mm" z="1*mm" phi1="0*deg" phi2="360*deg" material="stainless_steel" vis="FlangeVis">
+                    <position x="0" y="0*mm" z="755*mm"/>
+                </slice>
+                <slice type="Tubs" rmin="17.5*mm" rmax="95*mm" z="1*mm" phi1="0*deg" phi2="360*deg" material="stainless_steel" vis="FlangeVis">
+                    <position x="0" y="0*mm" z="760*mm"/>
+                </slice>
+                <slice type="Tubs" rmin="17.5*mm" rmax="95*mm" z="1*mm" phi1="0*deg" phi2="360*deg" material="stainless_steel" vis="FlangeVis">
+                    <position x="0" y="0*mm" z="765*mm"/>
+                </slice>
+                <slice type="Tubs" rmin="17.5*mm" rmax="95*mm" z="1*mm" phi1="0*deg" phi2="360*deg" material="stainless_steel" vis="FlangeVis">
+                    <position x="0" y="0*mm" z="770*mm"/>
+                </slice>
+                <slice type="Tubs" rmin="17.5*mm" rmax="95*mm" z="1*mm" phi1="0*deg" phi2="360*deg" material="stainless_steel" vis="FlangeVis">
+                    <position x="0" y="0*mm" z="775*mm"/>
+                </slice>
+            </layer>
+            <layer name = "LYSO_1st">
+                <slice  dx="3*mm" dy="3*mm" dz="23*mm" material="LYSO" vis="Gray_Vis" sensitive="yes" limits="5*mm">
+	            <position x="0" y="-12*mm" z="658.5*mm"/>
+	            <rotation x="0" y="0" z="0" />
+                </slice>
+            </layer>
+            <layer name = "LYSO_2nd">
+                <slice  dx="10*mm" dy="10*mm" dz="200*mm" material="LYSO" vis="Gray_Vis" sensitive="yes" limits="5*mm">
+	            <position x="0" y="-12*mm" z="1000*mm"/>
+	            <rotation x="0" y="0" z="0" />
+                </slice>
+            </layer>
+            
+        
+            
+        </detector>
+    </detectors>
+
+  <readouts>
+    <readout name="LumicalCollection">
+        
+        <segmentation   type="MultiSegmentation"  key="module">
+             <segmentation name="RPCgrid_Si_1st" type="CartesianGridXY"   key_value="1"  grid_size_x="0.1*mm" grid_size_y="0.1*mm"  />
+            <segmentation name="RPCgrid_Si_2nd" type="CartesianGridXY"   key_value="2"  grid_size_x="0.1*mm" grid_size_y="0.1*mm"  />
+            <segmentation name="RPCgrid_LYSO_1st" type="CartesianGridXY"   key_value="3"  grid_size_x="3*mm" grid_size_y="3*mm"  />
+            <segmentation name="RPCgrid_LYSO_2nd" type="CartesianGridXY"   key_value="5"  grid_size_x="10*mm" grid_size_y="10*mm"  />
+            
+        </segmentation>
+            
+      
+        <hits_collections>
+            <hits_collection name="LumicalCollection"  key="module" key_value="1"/>
+            <hits_collection name="LumicalCollection"  key="module" key_value="2"/>
+            <hits_collection name="LumicalCollection"  key="module" key_value="3"/>
+            <hits_collection name="LumicalCollection"  key="module" key_value="5"/>
+            
+        </hits_collections>
+
+        <id>system:5,side:-2,stave:-2,module:6,layer:8,slice:8,x:32:-16,y:-16</id>
+    </readout>
+  </readouts>
+
+</lccdd>
\ No newline at end of file
diff --git a/Detector/DetCRD/compact/CRD_common_v02/materials.xml b/Detector/DetCRD/compact/CRD_common_v02/materials.xml
index 57b8871e..6c3d605e 100644
--- a/Detector/DetCRD/compact/CRD_common_v02/materials.xml
+++ b/Detector/DetCRD/compact/CRD_common_v02/materials.xml
@@ -671,4 +671,13 @@
      <composite n="2" ref="H" />
      <composite n="1"  ref="O" />
    </material>
+
+   <material name="LYSO" state="solid">
+      <MEE unit="eV" value="9.5"/>
+      <D value="7.15" unit="g/cm3" />
+      <fraction n="0.714" ref="Lu"/>
+      <fraction n="0.056" ref="Y" />
+      <fraction n="0.56" ref="Si" />
+      <fraction n="1.428" ref="O" />
+    </material>
   </materials>
diff --git a/Detector/DetCRD/compact/Standalone/Lumical_o1_v01_standalone.xml b/Detector/DetCRD/compact/Standalone/Lumical_o1_v01_standalone.xml
new file mode 100644
index 00000000..97988441
--- /dev/null
+++ b/Detector/DetCRD/compact/Standalone/Lumical_o1_v01_standalone.xml
@@ -0,0 +1,20 @@
+<lccdd>
+    <includes>
+        <gdmlFile  ref="${DD4hepINSTALL}/DDDetectors/compact/elements.xml"/>
+        <gdmlFile  ref="../CRD_common_v02/materials.xml"/>
+    </includes>
+
+    <define>
+        <include ref="${DD4hepINSTALL}/DDDetectors/compact/detector_types.xml"/>
+        <constant name="world_x" value="1*m"/>
+        <constant name="world_y" value="1*m"/>
+        <constant name="world_z" value="1.5*m"/>
+        <constant name="tracker_region_zmax" value="1500*mm"/>
+        <constant name="tracker_region_rmax" value="1100*mm"/>
+    </define>
+
+    <include ref="../TDR_o1_v01/TDR_Dimensions_v01_01.xml"/>
+    <include ref="../CRD_common_v01/Lumical_o1_v01.xml"/>
+    <include ref="../CRD_common_v01/Lumical_Beampipe.xml"/>
+
+</lccdd>
\ No newline at end of file
diff --git a/Detector/DetCRD/compact/TDR_o1_v01/TDR_Dimensions_v01_01.xml b/Detector/DetCRD/compact/TDR_o1_v01/TDR_Dimensions_v01_01.xml
index 011b215f..edb0c7c1 100644
--- a/Detector/DetCRD/compact/TDR_o1_v01/TDR_Dimensions_v01_01.xml
+++ b/Detector/DetCRD/compact/TDR_o1_v01/TDR_Dimensions_v01_01.xml
@@ -58,7 +58,7 @@
     <constant name="BeamPipe_Be_outer_thickness"   value="0.15*mm"/>
     <constant name="BeamPipe_Be_total_thickness"   value="BeamPipe_Be_inner_thickness+BeamPipe_Cooling_thickness+BeamPipe_Be_outer_thickness"/>
     <constant name="BeamPipe_Al_thickness"         value="BeamPipe_Be_total_thickness"/>
-    <constant name="BeamPipe_Cu_thickness"         value="4.0*mm"/>
+    <constant name="BeamPipe_Cu_thickness"         value="1.0*mm"/>
 
     <constant name="BeamPipe_CentralBe_zmax"       value="85*mm"/>
     <constant name="BeamPipe_CentralAl_zmax"       value="180*mm"/>
diff --git a/Detector/DetCRD/compact/TDR_o1_v01/TDR_o1_v01.xml b/Detector/DetCRD/compact/TDR_o1_v01/TDR_o1_v01.xml
index 71f251c6..d0c1c151 100644
--- a/Detector/DetCRD/compact/TDR_o1_v01/TDR_o1_v01.xml
+++ b/Detector/DetCRD/compact/TDR_o1_v01/TDR_o1_v01.xml
@@ -41,6 +41,8 @@
   <!--include ref="../CRD_common_v01/SHcalGlass_Barrel_v04_01.xml"/-->
   <!--include ref="../CRD_common_v02/HcalEndcaps_Polyhedra_v01_01.xml"/-->
 
+  <!--Lumical锛宼o update-->
+  <include ref="../CRD_common_v01/Lumical_o1_v01.xml"/>
   <!--preliminary Magnet, to update/-->
   <include ref="../CRD_common_v02/Coil_Simple_v01_02.xml"/>
   <!--preliminary Muon, to update/-->
diff --git a/Detector/DetCRD/src/Calorimeter/Lumical_v01_geo.cpp b/Detector/DetCRD/src/Calorimeter/Lumical_v01_geo.cpp
new file mode 100644
index 00000000..7c5a851c
--- /dev/null
+++ b/Detector/DetCRD/src/Calorimeter/Lumical_v01_geo.cpp
@@ -0,0 +1,440 @@
+//==========================================================================
+//Lumical Detector Construction
+//--------------------------------------------------------------------------
+// 
+// Author: Sun Xingyang , NJU
+//==========================================================================
+#include "DD4hep/DetFactoryHelper.h"
+#include "DDRec/DetectorData.h"
+#include "XML/Utilities.h"
+#include "cmath"
+#include "DDSegmentation/BitField64.h"
+#include "DDSegmentation/TiledLayerGridXY.h"
+#include "DDSegmentation/Segmentation.h"
+#include "DDSegmentation/MultiSegmentation.h"
+#include <vector>
+#include <iostream>
+#include "XML/Layering.h"
+
+
+using namespace std;
+using namespace dd4hep;
+using namespace dd4hep::detail;
+using dd4hep::Readout;
+using dd4hep::Position;
+using dd4hep::BUILD_ENVELOPE;
+using dd4hep::Box;
+using dd4hep::DetElement;
+using dd4hep::Detector;
+using dd4hep::IntersectionSolid;
+using dd4hep::Material;
+using dd4hep::PlacedVolume;
+using dd4hep::Ref_t;
+using dd4hep::Rotation3D;
+using dd4hep::RotationZ;
+using dd4hep::RotationZYX;
+using dd4hep::SensitiveDetector;
+using dd4hep::Transform3D;
+using dd4hep::Trapezoid;
+using dd4hep::Tube;
+using dd4hep::Volume;
+using dd4hep::_toString;
+
+using dd4hep::rec::LayeredCalorimeterData;
+
+
+static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
+    std::cout << "This is the Lumical_v01:"  << std::endl;
+//get the define of LYSO cyrstals in xml
+    xml_det_t x_det = e;
+    string det_name = x_det.nameStr();
+    int loop = 0;
+    xml_coll_t LYSO_layer(x_det,_U(layer));
+    xml_coll_t second_LYSO_layer(x_det,_U(layer));
+    for(xml_coll_t c(x_det,_U(layer));c;c++){
+        if(loop == 3){LYSO_layer = c;}
+        else if(loop == 4){second_LYSO_layer=c;
+            break;}
+        loop++;
+    }
+//get the define information of the first LYSO crystal
+    xml_coll_t k_0(LYSO_layer,_U(slice));
+    xml_comp_t component = k_0;
+    double dx = component.dx();
+    double dy = component.dy();
+    double dz = component.dz();
+    Material mat = description.material(component.materialStr());
+    int crystal_id,crystal_num = 0;
+    xml_dim_t pos = component.position();
+    double x  = pos.x();
+    double y  = pos.y();
+    double z  = pos.z();
+
+    xml_dim_t rot = component.rotation();
+    double rotx = rot.x();
+    double roty = rot.y();
+    double rotz = rot.z();
+  
+    DetElement cal(det_name, x_det.id());
+
+// --- create an envelope volume and position it into the world ---------------------
+    
+    Volume envelope = dd4hep::xml::createPlacedEnvelope( description, e, cal );
+    dd4hep::xml::setDetectorTypeFlag( e, cal ) ;
+    if( description.buildType() == BUILD_ENVELOPE ) return cal;
+    envelope.setVisAttributes(description, x_det.visStr());
+  
+
+
+    xml_dim_t sd_typ = x_det.child(_U(sensitive));
+    sens.setType(sd_typ.typeStr());
+    Readout readout = sens.readout();
+
+    dd4hep::Segmentation seg = readout.segmentation();
+  
+    dd4hep::DDSegmentation::BitField64 encoder = seg.decoder();
+    encoder.setValue(0) ;
+
+    dd4hep::DDSegmentation::MultiSegmentation* multiSeg = 
+    dynamic_cast< dd4hep::DDSegmentation::MultiSegmentation*>( seg.segmentation() ) ;
+  
+    dd4hep::DDSegmentation::TiledLayerGridXY* tileSeg = 0 ;
+    int sensitive_slice_number = -1 ;
+    try{
+        if( multiSeg ){
+            try{ 
+    // check if we have an entry for the subsegmentation to be used 
+                xml_comp_t segxml = x_det.child( _Unicode( subsegmentation ) ) ;
+
+                std::string keyStr = segxml.attr<std::string>( _Unicode(key) ) ;
+                int keyVal = segxml.attr<int>( _Unicode(value) )  ;
+
+                encoder[ keyStr ] =  keyVal ;
+                std::cout<<"keyStr:"<<keyStr<<"_keyVal:"<<keyVal<<"\n";
+    // if we have a multisegmentation that uses the slice as key, we need to know for the
+    // computation of the layer parameters in LayeredCalorimeterData::Layer below
+            if( keyStr == "layer"){sensitive_slice_number = keyVal;}
+            }
+            catch(const std::runtime_error &) {std::cerr << "Error: "  << std::endl;}
+    
+    // check if we have a TiledLayerGridXY segmentation :s
+            const dd4hep::DDSegmentation::TiledLayerGridXY* ts0 =
+            dynamic_cast<const dd4hep::DDSegmentation::TiledLayerGridXY*>(  &multiSeg->subsegmentation( encoder.getValue() ) ) ;
+    
+            tileSeg = const_cast<dd4hep::DDSegmentation::TiledLayerGridXY*>( ts0 ) ;
+    
+            if( ! tileSeg ){ // if the current segmentation is not a tileSeg, we see if there is another one
+      
+            for( auto s : multiSeg->subSegmentations() ){
+	            const dd4hep::DDSegmentation::TiledLayerGridXY* ts =
+	            dynamic_cast<const dd4hep::DDSegmentation::TiledLayerGridXY*>( s.segmentation ) ;
+	
+	            if( ts ) {
+	                tileSeg = const_cast<dd4hep::DDSegmentation::TiledLayerGridXY*>( ts ) ;
+	                break ;
+	            }
+            }
+            }
+    
+        } else {
+            tileSeg = dynamic_cast< dd4hep::DDSegmentation::TiledLayerGridXY*>( seg.segmentation() ) ;
+        }
+    }   
+    catch (const std::exception& ex) {
+        std::cerr << "Exception caught: " << std::endl;
+        // Handle the exception gracefully, possibly by logging the error or providing fallback behavior
+    }
+
+    LayeredCalorimeterData* caloData = new LayeredCalorimeterData ;
+    for(int il=0;il<2; il++){
+    //used for reconstruction, so write a 1*1*2 layer cell size. No absorber or dead-meaterial.
+        dd4hep::rec::LayeredCalorimeterData::Layer _caloLayer;
+        _caloLayer.distance                        = 560+il*80*mm;
+        _caloLayer.phi0                               = 0;
+        _caloLayer.absorberThickness            = 0;
+        _caloLayer.inner_nRadiationLengths   = 0.01;
+        _caloLayer.inner_nInteractionLengths = 0.01;
+        _caloLayer.outer_nRadiationLengths   = 0.01;
+        _caloLayer.outer_nInteractionLengths = 0.01;
+        _caloLayer.inner_thickness              = 3*mm;    //1cm
+        _caloLayer.outer_thickness              = 3*mm;    //1cm
+        _caloLayer.sensitive_thickness       = 2*3*mm; //2cm
+        _caloLayer.cellSize0                         = 3*mm;    //1cm
+        _caloLayer.cellSize1                         = 3*mm;    //1cm
+        caloData->layers.push_back(_caloLayer);
+    }
+
+    caloData->layoutType = LayeredCalorimeterData::BarrelLayout ;
+    caloData->inner_symmetry = 8  ;
+    caloData->outer_symmetry = 8  ;
+    caloData->phi0 = 0 ; // hardcoded
+
+  // extent of the calorimeter in the r-z-plane [ rmin, rmax, zmin, zmax ] in mm.
+    caloData->extent[0] = 10*mm ;
+    caloData->extent[1] = 50*mm;
+    caloData->extent[2] = 0. ;
+    caloData->extent[3] = 700*mm ;
+
+
+//loop in order to build symmetry geo
+    for(int kz=1;kz>=-1;kz-=2){
+/////////////////////////////////////////////////////////////////
+//build Disk and flange
+    std::vector<double> cellSizeVector = seg.cellDimensions( encoder.getValue() ); //Assume uniform cell sizes, provide dummy cellID
+    int layer_num=1;// count the number of layers in order to define the ID of objects
+    for(int ky = 1;ky>=-1;ky-=2){
+            int logical_disk_id = 1; //count the number of disks
+            int l=0;//stand for the ID number of module
+            for(xml_coll_t c(x_det,_U(layer));c;c++){
+                string module_name = _toString(l+1,"_module%d")+_toString(0,"_stave%d");
+                int slice_number = 0;//used to count the number of slices we have placed
+                xml_comp_t   x_layer = c;
+                string layer_name      = det_name+module_name+_toString(layer_num,"_layer%d");
+            
+                encoder["layer"] = logical_disk_id ;
+                cellSizeVector = seg.segmentation()->cellDimensions( encoder.getValue() ); 
+                int slice_num = 0;//used to distinguish which slice we are building
+                if(l>=2){
+                    //build flange
+                    if(ky==-1)
+                    {
+                        break;
+                    }
+                    slice_number=1;
+                    for(xml_coll_t k(x_layer,_U(slice)); k; k++){
+                        xml_comp_t x_slice = k;
+                        string slice_name      = layer_name+_toString(slice_num,"_slice%d");
+                        DetElement slice(slice_name,_toString(slice_num,"_slice%d"),x_det.id());
+                        Material slice_material  = description.material(x_slice.materialStr());
+                        Volume slice_vol(slice_name,Tube(x_slice.rmin(),x_slice.rmax(),x_slice.z()/2,x_slice.phi1(),x_slice.phi2()),slice_material);
+                        slice_vol.setVisAttributes(description,x_slice.visStr());
+                        PlacedVolume slice_phv = envelope.placeVolume(slice_vol,Position(0*mm,0*mm,kz*x_slice.position().z()));
+                        slice_phv.addPhysVolID("side",kz).addPhysVolID("module",4).addPhysVolID("layer",0  ).addPhysVolID("slice",layer_num);
+                        if(ky==1 && kz==1){
+                            std::cout<<"Flange"<<layer_num<<":"<<"zStart = "<<x_slice.position().z()-x_slice.z()/2 << "    zEnd = "<<x_slice.position().z()+x_slice.z()/2 <<"   rmin ="<<x_slice.rmin()<<"  rmax = "<<x_slice.rmax()<<"position of circle center = "<<x_slice.position().x()<<" "<<x_slice.position().y()<<"   material = "<<x_slice.materialStr()<<"\n";
+                        }
+                        slice.setPlacement(slice_phv);
+                    
+                        logical_disk_id++;
+                        slice_number++;
+                    }
+                    break;
+                }
+            for(xml_coll_t k(x_layer,_U(slice)); k; k++)  {
+                
+                xml_comp_t x_slice = k;
+	            string   slice_name      = layer_name + _toString(slice_number,"_slice%d");
+	            Material slice_material  = description.material(x_slice.materialStr());
+	            DetElement slice(layer_name,_toString(slice_number,"slice%d"),x_det.id());
+                if(slice_num%2==0){
+                    Volume slice_vol(slice_name,Box(x_slice.dx()/2,x_slice.dy()/2,x_slice.dz()/2),slice_material);
+                    slice_vol.setSensitiveDetector(sens);
+                    slice_vol.setVisAttributes(description,x_slice.visStr());
+                    PlacedVolume slice_phv = envelope.placeVolume(slice_vol,Position(x_slice.position().x(),ky*x_slice.position().y(),kz*x_slice.position().z()));
+	                slice_phv.addPhysVolID("side",kz).addPhysVolID("stave",ky).addPhysVolID("module",l+1).addPhysVolID("layer",layer_num  ).addPhysVolID("slice",slice_number);
+    
+                    if(ky==1 && kz==1){
+                            std::cout<<"Disk_Box:"<<"zStart = "<<x_slice.position().z()-x_slice.dz()/2 << "    zEnd = "<<x_slice.position().z()+x_slice.dz()/2 <<"  dy = "<<x_slice.dy()<<"   dx = "<<x_slice.dx()<<" position of mass center = "<<x_slice.position().x()<<" "<<x_slice.position().y()<<"   material = "<<x_slice.materialStr()<<"\n";
+                        }
+                    slice.setPlacement(slice_phv);
+                    
+                    slice_num++;
+                    
+                    slice_number++;
+                }
+                else{
+                    for (int kx=1;kx>=-1;kx-=2){
+                        double phi1 = 0*deg;
+                        if(kx==1){phi1 =0*deg;}
+                        else{phi1 = 90*deg;}
+                        if(ky==-1){phi1+=90*deg;
+                        if(kx==1)phi1+=180*deg;}//invert the geometry
+                        Volume slice_vol(slice_name,Tube(x_slice.rmin(),x_slice.rmax(),x_slice.z()/2,phi1,phi1+90*deg),slice_material);
+                        slice_vol.setSensitiveDetector(sens);
+                        slice_vol.setVisAttributes(description,x_slice.visStr());
+                        PlacedVolume slice_phv = envelope.placeVolume(slice_vol,Position(kx*x_slice.position().x(),ky*x_slice.position().y(),kz*x_slice.position().z()));
+	                    slice_phv.addPhysVolID("side",kz).addPhysVolID("stave",ky).addPhysVolID("module",l+1).addPhysVolID("layer",layer_num  ).addPhysVolID("slice",slice_number);
+                        slice.setPlacement(slice_phv);
+                        if(ky==1 && kz==1){
+                            std::cout<<"Disk_tube:"<<"zStart = "<<x_slice.position().z()-x_slice.z()/2 << "    zEnd = "<<x_slice.position().z()+x_slice.z()/2 <<"  r = "<<x_slice.rmax()<<"position of circle center = "<<x_slice.position().x()<<" "<<x_slice.position().y()<<"   material = "<<x_slice.materialStr()<<"\n";
+                        }
+                        
+                        slice_number++;
+                    }
+                    slice_num++;
+                    
+                }
+                    
+                  
+            }
+            l=l+1;
+            logical_disk_id++;  
+            }
+        
+            
+        
+    layer_num++;
+    }
+//////////////////////////////////////////////////////////////////
+//build 1st LYSO
+  
+    cellSizeVector = seg.cellDimensions( encoder.getValue() ); 
+
+    for(int ky=-1;ky<=1;ky=ky+2) {
+        string module_name = _toString(3,"_module%d")+_toString(ky,"_stave%d");
+    
+        for (int i = 0; i < 14; i++) {
+            encoder["layer"] = 4 ;
+            cellSizeVector = seg.segmentation()->cellDimensions( encoder.getValue() ); 
+            int num = 0;//calculate the number of crystals allowed to be placed in each line
+            crystal_id=0;//stand for the id of LYSO crystals
+            double yc = 12.0 + dy * (i + 1);
+            double xc = dx / mm;
+            num = (int) 2 * ((std::sqrt(56 * 56 - yc * yc) / xc) - 1);
+          
+            string layer_name      = det_name+ module_name+_toString(kz*(i+1),"_layer%d");
+            int j = 0;
+            int half = 0;
+            if (num % 2 == 1) {
+                half = (num - 1) / 2; // half amount of total number each line
+                j = -half;
+                while (j <= half) {
+                    string crystal_name = layer_name +_toString(crystal_id,"_slice%d");
+                    DetElement crystalDE(layer_name, _toString(crystal_num,"_slice%d"), x_det.id());
+                    Box crystalBox(0.5*dx, 0.5*dy, 0.5*dz);
+                    Volume crystalVol(crystal_name, crystalBox, mat);
+
+                    crystalVol.setVisAttributes(description, component.visStr());
+
+                    crystalVol.setSensitiveDetector(sens);
+                    Transform3D transform(RotationZYX(rotz, roty, rotx), Translation3D(x + j * dx, ky*(y - 0.5*dy-i * dy), kz*z));
+                    PlacedVolume LYSO_phv =envelope.placeVolume(crystalVol, transform);
+
+                    if (x_det.hasAttr(_U(id))) LYSO_phv.addPhysVolID("system", x_det.id());
+                    LYSO_phv.addPhysVolID("side",kz).addPhysVolID("stave",ky).addPhysVolID("module",3).addPhysVolID("layer",i+1  ).addPhysVolID("slice",crystal_id);
+                    if(ky==1 && kz==1){
+                            std::cout << "LYSO_pixel:" << "zStart = " << z - dz / 2 << "    zEnd = "<< z + dz / 2 <<"  dy = "<< dy << "   dx = "<< dx << " position of mass center = "<< x + j * dx <<" "<< ky * (y - 0.5*dy-i * dy)<<"\n";
+                        }
+                    crystalDE.setPlacement(LYSO_phv);
+                    j++;
+                    crystal_id++;
+                    crystal_num++;
+                }
+            } else {
+                half = num / 2;
+                j = -half;
+                while (j < half) {
+                    string crystal_name = layer_name+_toString(crystal_id,"_slice%d");
+                    DetElement crystalDE(layer_name, _toString(crystal_num,"_slice%d"), x_det.id());
+
+                    Box crystalBox(0.5*dx, 0.5*dy, 0.5*dz);
+                    Volume crystalVol(crystal_name, crystalBox, mat);
+
+                    crystalVol.setVisAttributes(description, component.visStr());
+                    crystalVol.setSensitiveDetector(sens);
+                    Transform3D transform(RotationZYX(rotz, roty, rotx),
+                                            Translation3D(x + (j + 0.5) * dx, ky*(y -0.5*dy- i * dy), kz*z));
+                    PlacedVolume LYSO_phv = envelope.placeVolume(crystalVol, transform);
+
+                    if (x_det.hasAttr(_U(id))) LYSO_phv.addPhysVolID("system", x_det.id());
+                    LYSO_phv.addPhysVolID("side",kz).addPhysVolID("stave",ky).addPhysVolID("module",3).addPhysVolID("layer",i+1  ).addPhysVolID("slice",crystal_id);
+                    if(ky==1 && kz==1){
+                            std::cout<<"LYSO_pixel:"<<"zStart = "<<z-dz/2<< "    zEnd = "<<z+dz/2 <<"  dy = "<< dy <<"   dx = "<<dx<<" position of mass center = "<<x + j * dx<<" "<<ky*(y - 0.5*dy-i * dy)<<"\n";
+                        }
+                    crystalDE.setPlacement(LYSO_phv);
+                    j++;
+                    crystal_id++;
+                    crystal_num++;
+                }
+            }
+        }
+      
+    }
+//////////////////////////////////////////////////////////////////////
+// build 2nd LYSO
+    xml_coll_t k_second(second_LYSO_layer,_U(slice));
+    xml_comp_t component_second = k_second;
+    double dx2 = component_second.dx();
+    double dy2 = component_second.dy();
+    double dz2 = component_second.dz();
+    Material mat2 = description.material(component_second.materialStr());
+    xml_dim_t pos_second = component_second.position();
+    double x2  = pos_second.x();
+    double y2  = pos_second.y();
+    double z2  = pos_second.z();
+
+    for(int ky=-1;ky<=1;ky=ky+2) {
+        string module_name = _toString(5,"_module%d")+_toString(ky,"_stave%d");
+    
+        for (int i = 0; i < 10; i++) {
+            encoder["layer"] = 4 ;
+            cellSizeVector = seg.segmentation()->cellDimensions( encoder.getValue() ); 
+            int num = 0;//calculate the number of crystals allowed to be placed in each line
+            crystal_id=0;//stand for the id of LYSO crystals
+            double yc =12.0+ dy2/mm * (i+1);
+            double xc = dx2 / mm;
+            num = (int) 2 * ((std::sqrt(100.0*100.0 - yc * yc) / xc) - 1);
+          
+            string layer_name      = det_name+ module_name+_toString(kz*(i+1),"_layer%d");
+            int j = 0;
+            int half = 0;
+            if (num % 2 == 1) {
+                half = (num - 1) / 2;
+                j = -half;
+                while (j <= half) {
+                    string crystal_name = layer_name +_toString(crystal_id,"_slice%d");
+                    DetElement crystalDE(layer_name, _toString(crystal_num,"_slice%d"), x_det.id());
+                    Box crystalBox(0.5*dx2, 0.5*dy2, 0.5*dz2);
+                    Volume crystalVol(crystal_name, crystalBox, mat2);
+                
+                    crystalVol.setVisAttributes(description, component_second.visStr());
+
+                    crystalVol.setSensitiveDetector(sens);
+                    Transform3D transform(RotationZYX(0, 0, 0), Translation3D(x2 + j * dx2, ky*(y2 -0.5*dy2- i * dy2), kz*z2));
+                    PlacedVolume LYSO_phv =envelope.placeVolume(crystalVol, transform);
+
+                    if (x_det.hasAttr(_U(id))) LYSO_phv.addPhysVolID("system", x_det.id());
+                    LYSO_phv.addPhysVolID("side",kz).addPhysVolID("stave",ky).addPhysVolID("module",5).addPhysVolID("layer",i+1  ).addPhysVolID("slice",crystal_id);
+                    if(ky==1 && kz==1){
+                            std::cout<<"LYSO_pixel:"<<"zStart = "<<z2-dz2/2<< "    zEnd = "<<z2+dz2/2 <<"  dy = "<< dy2 <<"   dx = "<<dx2<<" position of mass center = "<<x2 + j * dx2<<" "<<ky*(y2 - 0.5*dy2-i * dy2)<<"\n";
+                        }
+                    crystalDE.setPlacement(LYSO_phv);
+                    j++;
+                    crystal_id++;
+                    crystal_num++;
+                }
+            } else {
+                half = num / 2;
+                j = -half;
+                while (j < half) {
+                    string crystal_name = layer_name+_toString(crystal_id,"_slice%d");
+                    DetElement crystalDE(layer_name, _toString(crystal_num,"_slice%d"), x_det.id());
+                  
+                    Box crystalBox(0.5*dx2, 0.5*dy2, 0.5*dz2);
+                    Volume crystalVol(crystal_name, crystalBox, mat2);
+                  
+                    crystalVol.setVisAttributes(description, component_second.visStr());
+                    crystalVol.setSensitiveDetector(sens);
+                    Transform3D transform(RotationZYX(0, 0, 0),
+                                        Translation3D(x2 + (j + 0.5) * dx2, ky*(y2 -0.5*dy2- i * dy2), kz*z2));
+                    PlacedVolume LYSO_phv = envelope.placeVolume(crystalVol, transform);
+
+                    if (x_det.hasAttr(_U(id))) LYSO_phv.addPhysVolID("system", x_det.id());
+                    LYSO_phv.addPhysVolID("side",kz).addPhysVolID("stave",ky).addPhysVolID("module",5).addPhysVolID("layer",i+1  ).addPhysVolID("slice",crystal_id);
+                    if(ky==1 && kz==1){
+                            std::cout<<"LYSO_pixel:"<<"zStart = "<<z2-dz2/2<< "    zEnd = "<<z2+dz2/2 <<"  dy = "<< dy2 <<"   dx = "<<dx2<<" position of mass center = "<<x2 + j * dx2<<" "<<ky*(y2 - 0.5*dy2-i * dy2)<<"\n";
+                        }
+                    crystalDE.setPlacement(LYSO_phv);
+                    j++;
+                    crystal_id++;
+                    crystal_num++;
+                }
+            }
+        }
+    }
+}
+    cal.addExtension< LayeredCalorimeterData >( caloData ) ; 
+    return cal;
+}
+
+DECLARE_DETELEMENT(Lumical_v01, create_detector)
diff --git a/Detector/DetCRD/src/Other/Lumical_v01_geo_beampipe.cpp b/Detector/DetCRD/src/Other/Lumical_v01_geo_beampipe.cpp
new file mode 100644
index 00000000..d3c07fbe
--- /dev/null
+++ b/Detector/DetCRD/src/Other/Lumical_v01_geo_beampipe.cpp
@@ -0,0 +1,184 @@
+//==========================================================================
+//Lumical Detector Construction
+//--------------------------------------------------------------------------
+// 
+// Author: Sun Xingyang , NJU
+//==========================================================================
+#include "DD4hep/DetFactoryHelper.h"
+#include "DDRec/DetectorData.h"
+#include "XML/Utilities.h"
+#include "cmath"
+#include "DDSegmentation/BitField64.h"
+#include "DDSegmentation/TiledLayerGridXY.h"
+#include "DDSegmentation/Segmentation.h"
+#include "DDSegmentation/MultiSegmentation.h"
+#include <vector>
+#include <iostream>
+#include "XML/Layering.h"
+
+
+using namespace std;
+using namespace dd4hep;
+using namespace dd4hep::detail;
+using dd4hep::Readout;
+using dd4hep::Position;
+using dd4hep::BUILD_ENVELOPE;
+using dd4hep::Box;
+using dd4hep::DetElement;
+using dd4hep::Detector;
+using dd4hep::IntersectionSolid;
+using dd4hep::Material;
+using dd4hep::PlacedVolume;
+using dd4hep::Ref_t;
+using dd4hep::Rotation3D;
+using dd4hep::RotationZ;
+using dd4hep::RotationZYX;
+using dd4hep::SensitiveDetector;
+using dd4hep::Transform3D;
+using dd4hep::Trapezoid;
+using dd4hep::Tube;
+using dd4hep::Volume;
+using dd4hep::_toString;
+
+using dd4hep::rec::LayeredCalorimeterData;
+
+
+static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
+    std::cout << "This is the Lumical_v02:"  << std::endl;
+
+    xml_det_t x_det = e;
+    string det_name = x_det.nameStr();
+    DetElement cal(det_name, x_det.id());
+
+// --- create an envelope volume and position it into the world ---------------------
+    Volume envelope = dd4hep::xml::createPlacedEnvelope( description, e, cal );
+    dd4hep::xml::setDetectorTypeFlag( e, cal ) ;
+    if( description.buildType() == BUILD_ENVELOPE ) return cal;
+    envelope.setVisAttributes(description, x_det.visStr());
+    PlacedVolume pv;
+
+    DetElement beampipe1_inner_DE(cal,"beampipe_Be_inner",x_det.id());
+    DetElement beampipe1_outter_DE(cal,"beampipe_Be_outter",x_det.id());
+    DetElement beampipe2_inner_DE(cal,"beampipe_Al_inner",x_det.id());
+    DetElement beampipe2_outter_DE(cal,"beampipe_Al_outter",x_det.id());
+    DetElement runway_DE(cal,"runway",x_det.id());
+
+    for(int kz=1;kz>=-1;kz-=2){
+/////////////////////////////////////////////////////////////////
+//build Be beampipe
+        xml_comp_t component_beampipe1_inner = x_det.child(_Unicode(beampipe_Be_inner));
+        Material fBe = description.material(component_beampipe1_inner.materialStr());
+        xml_dim_t pos_beampipe_Be = component_beampipe1_inner.position();
+
+        xml_comp_t component_beampipe1_outter = x_det.child(_Unicode(beampipe_Be_outter));
+    
+        Tube beampipe_Be_inner(component_beampipe1_inner.rmin(),component_beampipe1_inner.rmax(),component_beampipe1_inner.z()*0.5,component_beampipe1_inner.phi1(),component_beampipe1_inner.phi2());
+    
+        Volume beampipe_Be_inner_Vol("beampipe_Be_inner", beampipe_Be_inner,fBe);
+        beampipe_Be_inner_Vol.setVisAttributes(description, component_beampipe1_inner.visStr());
+        Transform3D transform_beampipe_Be(RotationZYX(0,0,0), Translation3D(pos_beampipe_Be.x(), pos_beampipe_Be.y() , kz*pos_beampipe_Be.z()));
+        envelope.placeVolume(beampipe_Be_inner_Vol, transform_beampipe_Be);
+
+        Tube beampipe_Be_outter(component_beampipe1_outter.rmin(),component_beampipe1_outter.rmax(),component_beampipe1_outter.z()*0.5,component_beampipe1_outter.phi1(),component_beampipe1_outter.phi2());
+        Volume beampipe_Be_outter_Vol("beampipe_Be_outter", beampipe_Be_outter,fBe);
+        beampipe_Be_outter_Vol.setVisAttributes(description, component_beampipe1_outter.visStr());
+        envelope.placeVolume(beampipe_Be_outter_Vol, transform_beampipe_Be);
+    
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//build Al beampipe
+        xml_comp_t component_beampipe2_inner = x_det.child(_Unicode(beampipe_Al_inner));
+        Material fAl = description.material(component_beampipe2_inner.materialStr());
+        xml_dim_t pos_beampipe_Al = component_beampipe2_inner.position();
+
+        xml_comp_t component_beampipe2_outter = x_det.child(_Unicode(beampipe_Al_outter));
+    
+
+        Tube beampipe_Al_inner(component_beampipe2_inner.rmin(),component_beampipe2_inner.rmax(),component_beampipe2_inner.z()*0.5,component_beampipe2_inner.phi1(),component_beampipe2_inner.phi2());
+        Volume beampipe_Al_inner_Vol("beampipe_Al_inner", beampipe_Al_inner,fAl);
+        beampipe_Al_inner_Vol.setVisAttributes(description, component_beampipe2_inner.visStr());
+        Transform3D transform_beampipe_Al(RotationZYX(0,0,0), Translation3D(pos_beampipe_Al.x(), pos_beampipe_Al.y() , kz*pos_beampipe_Al.z()));
+        envelope.placeVolume(beampipe_Al_inner_Vol, transform_beampipe_Al);
+
+        Tube beampipe_Al_outter(component_beampipe2_outter.rmin(),component_beampipe2_outter.rmax(),component_beampipe2_outter.z()*0.5,component_beampipe2_outter.phi1(),component_beampipe2_outter.phi2());
+        Volume beampipe_Al_outter_Vol("beampipe_Al_outter", beampipe_Al_outter,fAl);
+        beampipe_Al_outter_Vol.setVisAttributes(description, component_beampipe2_outter.visStr());
+        envelope.placeVolume(beampipe_Al_outter_Vol, transform_beampipe_Al);
+//////////////////////////////////////////////////////////////////////
+//build runway
+
+        xml_comp_t component_runway = x_det.child(_Unicode(runway));
+    
+        xml_dim_t pos_runway = component_runway.position();
+        for(int kx = -1;kx<=1;kx+=2){
+            double phi0=90*deg-kx*90*deg;
+            Transform3D transform_runway(RotationZYX(90*deg,0,0), Translation3D(-kx*pos_runway.x(), pos_runway.y() , kz*pos_runway.z()));
+
+            Tube runway(component_runway.rmin(),component_runway.rmax(),component_runway.z()*0.5,phi0,phi0+180*deg);
+            Volume runway_Vol("runway", runway,fAl);
+            runway_Vol.setVisAttributes(description, component_runway.visStr());
+            envelope.placeVolume(runway_Vol, transform_runway);                                                                                                                                 
+        }
+///////////////////////////////////////////////////////////////////////////////////////
+//build beampipe between flange
+    
+    for(xml_coll_t c(x_det,_U(beampipe));c;c++){
+        int layer_num=1;
+        xml_comp_t   x_layer = c;
+        int count = 0;
+        for(xml_coll_t k(x_layer,_U(slice)); k; k++)  {
+            string module_name = _toString(0,"_module%d")+_toString(0,"_stave%d");
+            int slice_number = 0;
+            xml_comp_t x_slice = k;
+            string layer_name      = det_name+module_name+_toString(layer_num,"_layer%d");
+            for(int kx = -1;kx<=1;kx+=2){
+                double phi0=90*deg-kx*90*deg;
+                
+                string slice_name      = layer_name+_toString(slice_number,"_slice%d");
+
+                DetElement slice(slice_name,_toString(slice_number,"_slice%d"),x_det.id());
+                Material slice_material  = description.material(x_slice.materialStr());
+
+                if(count==0||count==2){
+                    Volume slice_vol(slice_name,Tube(x_slice.rmin(),x_slice.rmax(),x_slice.z()/2,phi0,phi0+90*deg*(count+2)),slice_material);
+                    slice_vol.setVisAttributes(description,x_slice.visStr());
+                    Transform3D transform_beampipe(RotationZYX(90*deg,0,0), Translation3D(-kx*x_slice.position().x(),x_slice.position().y() , kz*x_slice.position().z()));
+                    PlacedVolume slice_phv = envelope.placeVolume(slice_vol,transform_beampipe);
+                    slice_phv.addPhysVolID("side",kz).addPhysVolID("module",0).addPhysVolID("layer",0  ).addPhysVolID("slice",layer_num);
+                    std::cout<<"side:"<<kz<<"module:"<<0<<"layer:"<<layer_num<<"slice:"<<layer_num<<"\n";
+                    slice.setPlacement(slice_phv);
+                    slice_number++;
+                }
+                else if (count==1){
+                    
+                    double rmin1 = x_slice.rmin1();
+                    double rmax1 = x_slice.rmax1();
+                    double rmin2 = x_slice.rmin2();
+                    double rmax2 = x_slice.rmax2();
+                    if(kz==-1){
+                        double r1 = rmin1;
+                        rmin1 = rmin2;
+                        rmin2 = r1;
+                        double r2 = rmax1;
+                        rmax1 = rmax2;
+                        rmax2 = r2;
+                    }
+                    Volume slice_vol(slice_name,ConeSegment(x_slice.z()/2,rmin1,rmax1,rmin2,rmax2,phi0,phi0+180*deg),slice_material);
+                    slice_vol.setVisAttributes(description,x_slice.visStr());
+                    Transform3D transform_beampipe(RotationZYX(90*deg,0,0), Translation3D(-kx*x_slice.position().x(),x_slice.position().y() , kz*x_slice.position().z()));
+                    PlacedVolume slice_phv = envelope.placeVolume(slice_vol,transform_beampipe);
+                    slice_phv.addPhysVolID("side",kz).addPhysVolID("module",0).addPhysVolID("layer",0  ).addPhysVolID("slice",layer_num);
+                    std::cout<<"side:"<<kz<<"module:"<<0<<"layer:"<<layer_num<<"slice:"<<layer_num<<"\n";
+                    slice.setPlacement(slice_phv);
+                    slice_number++;
+                }
+                
+            }
+            count++;
+        }
+        layer_num++;
+    }
+    }
+    return cal;
+}
+
+DECLARE_DETELEMENT(Lumical_v01_standalone, create_detector)
diff --git a/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.cpp b/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.cpp
index 12628068..7ac6e5bd 100644
--- a/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.cpp
+++ b/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.cpp
@@ -121,6 +121,9 @@ Edm4hepWriterAnaElemTool::EndOfEventAction(const G4Event* anEvent) {
     auto ecalendcapringcol        = m_EcalEndcapRingCol.createAndPut();
     auto ecalendcapringcontribcol = m_EcalEndcapRingContributionCol.createAndPut();
 
+    auto lumicalcol               = m_LumicalCol.createAndPut();
+    auto lumicalconribcols        = m_LumicalContributionCol.createAndPut();
+
     auto hcalbarrelcol            = m_HcalBarrelCol.createAndPut();
     auto hcalbarrelcontribcols    = m_HcalBarrelContributionCol.createAndPut();
     auto hcalendcapscol           = m_HcalEndcapsCol.createAndPut();
@@ -197,6 +200,9 @@ Edm4hepWriterAnaElemTool::EndOfEventAction(const G4Event* anEvent) {
         } else if (collect->GetName() == "EcalEndcapRingCollection") {
             calo_col_ptr = ecalendcapringcol;
             calo_contrib_col_ptr = ecalendcapringcontribcol;
+        } else if (collect->GetName() == "LumicalCollection"){
+            calo_col_ptr = lumicalcol;
+            calo_contrib_col_ptr = lumicalconribcols;
         } else if (collect->GetName() == "HcalBarrelCollection") {
             calo_col_ptr = hcalbarrelcol;
             calo_contrib_col_ptr = hcalbarrelcontribcols;
diff --git a/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.h b/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.h
index e4415b17..13b43c9d 100644
--- a/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.h
+++ b/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.h
@@ -89,7 +89,12 @@ private:
     DataHandle<edm4hep::CaloHitContributionCollection> m_EcalEndcapRingContributionCol{
             "EcalEndcapRingContributionCollection", 
             Gaudi::DataHandle::Writer, this};
-
+    // Lumical
+    DataHandle<edm4hep::SimCalorimeterHitCollection> m_LumicalCol{"LumicalCollection",
+            Gaudi::DataHandle::Writer, this};
+    DataHandle<edm4hep::CaloHitContributionCollection> m_LumicalContributionCol{
+            "LumicalContributionCollection",
+            Gaudi::DataHandle::Writer, this};
     // Hcal
     DataHandle<edm4hep::SimCalorimeterHitCollection> m_HcalBarrelCol{"HcalBarrelCollection", 
             Gaudi::DataHandle::Writer, this};
-- 
GitLab