From 1bb6957ca38bc4d82f5fa4f96448021b53cf8a22 Mon Sep 17 00:00:00 2001
From: Chengdong Fu <fucd@ihep.ac.cn>
Date: Fri, 22 Apr 2022 16:50:05 +0800
Subject: [PATCH] add AHcal module

---
 Detector/DetCEPCv4/CMakeLists.txt             |   8 +-
 .../src/calorimeter/SHcalSc04_Barrel_v04.cpp  | 723 ++++++++++++++++++
 .../src/calorimeter/SHcalSc04_Endcaps_v01.cpp | 498 ++++++++++++
 .../SHcalSc04_Barrel_v04_01.xml               |  71 ++
 .../SHcalSc04_Endcaps_v01_01.xml              |  90 +++
 .../Standalone/Standalone-SHcalSc04.xml       |  51 ++
 6 files changed, 1438 insertions(+), 3 deletions(-)
 create mode 100644 Detector/DetCEPCv4/src/calorimeter/SHcalSc04_Barrel_v04.cpp
 create mode 100644 Detector/DetCEPCv4/src/calorimeter/SHcalSc04_Endcaps_v01.cpp
 create mode 100644 Detector/DetCRD/compact/CRD_common_v01/SHcalSc04_Barrel_v04_01.xml
 create mode 100644 Detector/DetCRD/compact/CRD_common_v01/SHcalSc04_Endcaps_v01_01.xml
 create mode 100644 Detector/DetCRD/compact/Standalone/Standalone-SHcalSc04.xml

diff --git a/Detector/DetCEPCv4/CMakeLists.txt b/Detector/DetCEPCv4/CMakeLists.txt
index 19046a69..03b897ae 100644
--- a/Detector/DetCEPCv4/CMakeLists.txt
+++ b/Detector/DetCEPCv4/CMakeLists.txt
@@ -32,11 +32,13 @@ gaudi_add_module(DetCEPCv4
                          src/calorimeter/SHcalRpc02_Barrel.cpp
                          src/calorimeter/SHcalRpc01_Endcaps.cpp
                          src/calorimeter/SHcalRpc01_EndcapRing.cpp
-			 src/calorimeter/Yoke05_Barrel.cpp
-			 src/calorimeter/Yoke05_Endcaps.cpp
+                         src/calorimeter/SHcalSc04_Barrel_v04.cpp
+                         src/calorimeter/SHcalSc04_Endcaps_v01.cpp
+                         src/calorimeter/Yoke05_Barrel.cpp
+                         src/calorimeter/Yoke05_Endcaps.cpp
                          src/other/BoxSupport_o1_v01_geo.cpp
                          src/other/TubeSupport_o1_v01_geo.cpp
-			 src/other/SCoil02_geo.cpp
+                         src/other/SCoil02_geo.cpp
 
 		 LINK ${DD4hep_COMPONENT_LIBRARIES}
 )
diff --git a/Detector/DetCEPCv4/src/calorimeter/SHcalSc04_Barrel_v04.cpp b/Detector/DetCEPCv4/src/calorimeter/SHcalSc04_Barrel_v04.cpp
new file mode 100644
index 00000000..334af303
--- /dev/null
+++ b/Detector/DetCEPCv4/src/calorimeter/SHcalSc04_Barrel_v04.cpp
@@ -0,0 +1,723 @@
+//====================================================================
+//  DD4hep Geometry driver for HcalBarrel
+//--------------------------------------------------------------------
+//  S.Lu, DESY
+//  F. Gaede, DESY :  v04 : prepare for multi segmentation
+//     18.04.2017            - copied from SHcalSc04_Barrel_v01.cpp
+//                           - add optional parameter <subsegmentation key="" value=""/>
+//                             defines the segmentation to be used in reconstruction
+//====================================================================
+#include "DD4hep/Printout.h"
+#include "DD4hep/DetFactoryHelper.h"
+#include "XML/Utilities.h"
+#include "DDRec/DetectorData.h"
+#include "DDSegmentation/BitField64.h"
+#include "DDSegmentation/TiledLayerGridXY.h"
+#include "DDSegmentation/Segmentation.h"
+#include "DDSegmentation/MultiSegmentation.h"
+#include "LcgeoExceptions.h"
+
+#include <iostream>
+#include <vector>
+
+using namespace std;
+
+using dd4hep::BUILD_ENVELOPE;
+using dd4hep::Box;
+using dd4hep::DetElement;
+using dd4hep::Detector;
+using dd4hep::IntersectionSolid;
+using dd4hep::Material;
+using dd4hep::PlacedVolume;
+using dd4hep::Position;
+using dd4hep::Readout;
+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;
+
+// After reading in all the necessary parameters.
+// To check the radius range and the space for placing the total layers
+static bool validateEnvelope(double rInner, double rOuter, double radiatorThickness, double layerThickness, int layerNumber){
+  
+  bool Error = false;
+  bool Warning = false;
+  double spaceAllowed = rOuter*cos(M_PI/16.) - rInner;
+  double spaceNeeded  = (radiatorThickness + layerThickness)* layerNumber;
+  double spaceToleranted  = (radiatorThickness + layerThickness)* (layerNumber+1);
+  double rOuterRecommaned = ( rInner + spaceNeeded )/cos(M_PI/16.);
+  int layerNumberRecommaned = floor( ( spaceAllowed ) / (radiatorThickness + layerThickness) );
+  
+  
+  if( spaceNeeded > spaceAllowed )
+    {
+      printout( dd4hep::ERROR,  "SHcalSc04_Barrel_v01", " Layer number is more than it can be built! "  ) ;
+      Error = true;
+    }
+  else if ( spaceToleranted < spaceAllowed )
+    {
+      printout( dd4hep::WARNING,  "SHcalSc04_Barrel_v01", " Layer number is less than it is able to build!" ) ;
+      Warning = true;
+    }
+  else
+    {
+      printout( dd4hep::DEBUG,  "SHcalSc04_Barrel_v01"," has been validated and start to build it." ) ;
+      Error = false;
+      Warning = false;
+    }
+
+  if( Error )
+    {
+      cout<<"\n ============> First Help Documentation <=============== \n"
+	  <<" When you see this message, that means you are crashing the module. \n"
+	  <<" Please take a cup of cafe, and think about what you want to do! \n"
+	  <<" Here are few FirstAid# for you. Please read them carefully. \n"
+	  <<" \n"
+	  <<" ###  FirstAid 1: ###\n"
+	  <<" If you want to build HCAL within the rInner and rOuter range, \n"
+	  <<" please reduce the layer number to " << layerNumberRecommaned <<" \n"
+	  <<" with the current layer thickness structure. \n"
+	  <<" \n"
+	  <<" You may redisgn the layer structure and thickness, too. \n"
+	  <<" \n"
+	  <<" ###  FirstAid 2: ###\n"
+	  <<" If you want to build HCAL with this layer number and the layer thickness, \n"
+	  <<" you have to update rOuter to "<< rOuterRecommaned*10. <<"*mm \n"
+	  <<" and to inform other subdetector, you need this space for building your design. \n"
+	  <<" \n"
+	  <<" ###  FirstAid 3: ###\n"
+	  <<" Do you think that you are looking for another type of HCAL driver? \n"
+	  <<" \n"
+	  <<endl; 
+      throw lcgeo::GeometryException(  "SHcalSc04_Barrel: Error: Layer number is more than it can be built!"   ) ;
+    } 
+  else if( Warning )
+    {
+      cout<<"\n ============> First Help Documentation <=============== \n"
+	  <<" When you see this warning message, that means you are changing the module. \n"
+	  <<" Please take a cup of cafe, and think about what you want to do! \n"
+	  <<" Here are few FirstAid# for you. Please read them carefully. \n"
+	  <<" \n"
+	  <<" ###  FirstAid 1: ###\n"
+	  <<" If you want to build HCAL within the rInner and rOuter range, \n"
+	  <<" You could build the layer number up to " << layerNumberRecommaned <<" \n"
+	  <<" with the current layer thickness structure. \n"
+	  <<" \n"
+	  <<" You may redisgn the layer structure and thickness, too. \n"
+	  <<" \n"
+	  <<" ###  FirstAid 2: ###\n"
+	  <<" If you want to build HCAL with this layer number and the layer thickness, \n"
+	  <<" you could reduce rOuter to "<< rOuterRecommaned*10. <<"*mm \n"
+	  <<" and to reduce the back plate thickness, which you may not need for placing layer. \n"
+	  <<" \n"
+	  <<" ###  FirstAid 3: ###\n"
+	  <<" Do you think that you are looking for another type of HCAL driver? \n"
+	  <<" \n"
+	  <<endl; 
+      return Warning;
+    }
+  else { return true; }
+
+}
+
+static Ref_t create_detector(Detector& theDetector, xml_h element, SensitiveDetector sens)  {
+
+  double boundarySafety = 0.0001;
+
+  xml_det_t   x_det       = element;
+  string      det_name    = x_det.nameStr();
+  int           det_id    = x_det.id();
+  DetElement  sdet( det_name, det_id );
+
+  // --- create an envelope volume and position it into the world ---------------------
+  
+  Volume envelope = dd4hep::xml::createPlacedEnvelope( theDetector,  element , sdet ) ;
+  
+  dd4hep::xml::setDetectorTypeFlag( element, sdet ) ;
+  
+  if( theDetector.buildType() == BUILD_ENVELOPE ) return sdet ;
+
+  //-----------------------------------------------------------------------------------
+
+  xml_comp_t    x_staves          = x_det.staves();
+  Material      stavesMaterial    = theDetector.material(x_staves.materialStr());
+  Material      air               = theDetector.air();
+
+  PlacedVolume pv;
+
+  sens.setType("calorimeter");
+
+//====================================================================
+//
+// Read all the constant from ILD_o1_v05.xml
+// Use them to build HcalBarrel
+//
+//====================================================================
+  double      Hcal_inner_radius   = theDetector.constant<double>("Hcal_inner_radius");
+  double      Hcal_outer_radius   = theDetector.constant<double>("Hcal_outer_radius");
+  double      Hcal_half_length    = theDetector.constant<double>("Hcal_half_length");
+  int         Hcal_inner_symmetry = theDetector.constant<int>("Hcal_inner_symmetry");
+  int         Hcal_outer_symmetry = 0; // Fixed shape for Tube, and not allow to modify from compact xml.
+
+  double      Hcal_radiator_thickness          = theDetector.constant<double>("Hcal_radiator_thickness");
+  double      Hcal_chamber_thickness           = theDetector.constant<double>("Hcal_chamber_thickness");
+  double      Hcal_back_plate_thickness        = theDetector.constant<double>("Hcal_back_plate_thickness");
+  double      Hcal_lateral_plate_thickness     = theDetector.constant<double>("Hcal_lateral_structure_thickness");
+  double      Hcal_stave_gaps                  = theDetector.constant<double>("Hcal_stave_gaps");
+  double      Hcal_modules_gap                 = theDetector.constant<double>("Hcal_modules_gap"); 
+  double      Hcal_middle_stave_gaps           = theDetector.constant<double>("Hcal_middle_stave_gaps");
+  double      Hcal_layer_air_gap               = theDetector.constant<double>("Hcal_layer_air_gap");
+  //double      Hcal_cells_size                  = theDetector.constant<double>("Hcal_cells_size");
+
+  int         Hcal_nlayers                     = theDetector.constant<int>("Hcal_nlayers");
+
+  double      TPC_outer_radius               = theDetector.constant<double>("TPC_outer_radius");
+
+  double      Ecal_outer_radius               = theDetector.constant<double>("Ecal_outer_radius");
+
+  printout( dd4hep::DEBUG,  "SHcalSc04_Barrel_v04", "TPC_outer_radius : %e   - Ecal_outer_radius: %e ", TPC_outer_radius , Ecal_outer_radius) ;
+
+  validateEnvelope(Hcal_inner_radius, Hcal_outer_radius, Hcal_radiator_thickness, Hcal_chamber_thickness, Hcal_nlayers);
+
+  Readout readout = sens.readout();
+  dd4hep::Segmentation seg = readout.segmentation();
+  
+  dd4hep::DDSegmentation::BitField64 encoder = seg.decoder();
+  encoder.setValue(0) ;
+  
+
+  //fg: this is a bit tricky: we first have to check whether a multi segmentation is used and then, if so, we
+  //    will check the <subsegmentation key="" value=""/> element, for which subsegmentation to use for filling the 
+  //    DDRec:LayeredCalorimeterData information.
+  //    Additionally, we need to figure out if there is a TiledLayerGridXY instance defined -
+  //    and in case, there is more than one defined, we need to pick the correct one specified via the
+  //    <subsegmentation key="" value=""/> element.
+  //    This involves a lot of casting:  review the API in DD4hep !!
+
+  // check if we have a multi segmentation :
+
+  dd4hep::DDSegmentation::MultiSegmentation* multiSeg = 
+    dynamic_cast< dd4hep::DDSegmentation::MultiSegmentation*>( seg.segmentation() ) ;
+  
+  dd4hep::DDSegmentation::TiledLayerGridXY* tileSeg = 0 ;
+    
+  int sensitive_slice_number = -1 ;
+
+  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 ;
+
+      // 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 == "slice" ){
+	sensitive_slice_number = keyVal ;
+      }
+
+
+    } catch(const std::runtime_error &) {
+      throw lcgeo::GeometryException(  "SHcalSc04_Barrel: Error: MultiSegmentation specified but no "
+                                       " <subsegmentation key="" value=""/> element defined for detector ! " ) ;
+    }
+    
+    // check if we have a TiledLayerGridXY segmentation :
+    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() ) ;
+  }
+  
+  
+
+  std::vector<double> cellSizeVector = seg.cellDimensions( encoder.getValue() ); //Assume uniform cell sizes, provide dummy cellID
+  double cell_sizeX      = cellSizeVector[0];
+  double cell_sizeY      = cellSizeVector[1];
+
+
+  //========== fill data for reconstruction ============================
+  LayeredCalorimeterData* caloData = new LayeredCalorimeterData ;
+  caloData->layoutType = LayeredCalorimeterData::BarrelLayout ;
+  caloData->inner_symmetry = Hcal_inner_symmetry  ;
+  caloData->outer_symmetry = Hcal_outer_symmetry  ;
+  caloData->phi0 = 0 ; // fg: also hardcoded below 
+
+  /// extent of the calorimeter in the r-z-plane [ rmin, rmax, zmin, zmax ] in mm.
+  caloData->extent[0] = Hcal_inner_radius ;
+  caloData->extent[1] = Hcal_outer_radius ;
+  caloData->extent[2] = 0. ; // Barrel zmin is "0" by default.
+  caloData->extent[3] = Hcal_half_length ;
+
+//====================================================================
+//
+// general calculated parameters
+//
+//====================================================================
+
+  double Hcal_total_dim_y   = Hcal_nlayers * (Hcal_radiator_thickness + Hcal_chamber_thickness) 
+                            + Hcal_back_plate_thickness;
+
+  double Hcal_y_dim1_for_x  = Hcal_outer_radius*cos(M_PI/Hcal_inner_symmetry) - Hcal_inner_radius;
+  double Hcal_bottom_dim_x  = 2.*Hcal_inner_radius*tan(M_PI/Hcal_inner_symmetry)- Hcal_stave_gaps;
+  double Hcal_normal_dim_z  = (2 * Hcal_half_length - Hcal_modules_gap)/2.;
+
+ //only the middle has the steel plate.
+  double Hcal_regular_chamber_dim_z = Hcal_normal_dim_z - Hcal_lateral_plate_thickness;
+
+  //double Hcal_cell_dim_x            = Hcal_cells_size;
+  //double Hcal_cell_dim_z            = Hcal_regular_chamber_dim_z / floor (Hcal_regular_chamber_dim_z/Hcal_cell_dim_x);
+
+ 
+// ========= Create Hcal Barrel stave   ====================================
+//  It will be the volume for palcing the Hcal Barrel Chamber(i.e. Layers).
+//  Itself will be placed into the world volume.
+// ==========================================================================
+ 
+  double chambers_y_off_correction = 0.;
+ 
+  // stave modules shaper parameters
+  double BHX  = (Hcal_bottom_dim_x + Hcal_stave_gaps)/2.;
+  double THX  = (Hcal_total_dim_y + Hcal_inner_radius)*tan(M_PI/Hcal_inner_symmetry);
+  double YXH  = Hcal_total_dim_y / 2.;
+  double DHZ  = (Hcal_normal_dim_z - Hcal_lateral_plate_thickness) / 2.;
+
+  Trapezoid stave_shaper(  THX, BHX, DHZ, DHZ, YXH);
+
+  Tube solidCaloTube(0, Hcal_outer_radius, DHZ+boundarySafety);
+  
+  RotationZYX mrot(0,0,M_PI/2.);
+
+  Rotation3D mrot3D(mrot);
+  Position mxyzVec(0,0,(Hcal_inner_radius + Hcal_total_dim_y / 2.));
+  Transform3D mtran3D(mrot3D,mxyzVec);
+
+  IntersectionSolid barrelModuleSolid(stave_shaper, solidCaloTube, mtran3D);
+
+  Volume  EnvLogHcalModuleBarrel(det_name+"_module",barrelModuleSolid,stavesMaterial);
+
+  EnvLogHcalModuleBarrel.setAttributes(theDetector,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
+
+
+
+
+
+  //stave modules lateral plate shaper parameters
+  double BHX_LP  = BHX;
+  double THX_LP  = THX;
+  double YXH_LP  = YXH;
+
+  //build lateral palte here to simulate lateral plate in the middle of barrel.
+  double DHZ_LP  = Hcal_lateral_plate_thickness/2.0; 
+
+  Trapezoid stave_shaper_LP(THX_LP, BHX_LP, DHZ_LP, DHZ_LP, YXH_LP);
+
+  Tube solidCaloTube_LP(0, Hcal_outer_radius, DHZ_LP+boundarySafety);
+
+  IntersectionSolid Module_lateral_plate(stave_shaper_LP, solidCaloTube_LP, mtran3D);
+
+  Volume  EnvLogHcalModuleBarrel_LP(det_name+"_Module_lateral_plate",Module_lateral_plate,stavesMaterial);
+
+  EnvLogHcalModuleBarrel_LP.setAttributes(theDetector,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
+
+
+
+#ifdef SHCALSC04_DEBUG
+  std::cout<< " ==> Hcal_outer_radius: "<<Hcal_outer_radius <<std::endl;
+#endif
+
+
+
+
+
+//====================================================================
+//
+// Chambers in the HCAL BARREL
+//
+//====================================================================
+  // Build Layer Chamber fill with air, which include the tolarance space at the two side
+  // place the slice into the Layer Chamber
+  // Place the Layer Chamber into the Stave module
+  // place the Stave module into the asembly Volume
+  // place the module middle lateral plate into asembly Volume
+
+  double x_length; //dimension of an Hcal barrel layer on the x-axis
+  double y_height; //dimension of an Hcal barrel layer on the y-axis
+  double z_width;  //dimension of an Hcal barrel layer on the z-axis
+  x_length = 0.; // Each Layer the x_length has new value.
+  y_height = Hcal_chamber_thickness / 2.;
+  z_width  = Hcal_regular_chamber_dim_z/2.;
+
+  double xOffset = 0.;//the x_length of a barrel layer is calculated as a
+  //barrel x-dimension plus (bottom barrel) or minus
+  //(top barrel) an x-offset, which depends on the angle M_PI/Hcal_inner_symmetry
+
+  double xShift = 0.;//Geant4 draws everything in the barrel related to the 
+  //center of the bottom barrel, so we need to shift the layers to
+  //the left (or to the right) with the quantity xShift
+
+
+  //-------------------- start loop over HCAL layers ----------------------
+
+  for (int layer_id = 1; layer_id <= (2*Hcal_nlayers); layer_id++)
+    {
+ 
+      double TanPiDiv8 = tan(M_PI/Hcal_inner_symmetry);
+      double x_total   = 0.;
+      double x_halfLength;
+      x_length  = 0.;
+
+      int logical_layer_id = 0;
+
+      if ( (layer_id < Hcal_nlayers)
+	   || (layer_id > Hcal_nlayers && layer_id < (2*Hcal_nlayers)) )
+	logical_layer_id = layer_id % Hcal_nlayers;
+      else if ( (layer_id == Hcal_nlayers) 
+		|| (layer_id == 2*Hcal_nlayers) ) logical_layer_id = Hcal_nlayers;
+
+      //---- bottom barrel------------------------------------------------------------
+      if( logical_layer_id *(Hcal_radiator_thickness + Hcal_chamber_thickness)
+	  < (Hcal_outer_radius * cos(M_PI/Hcal_inner_symmetry) - Hcal_inner_radius ) ) {
+	xOffset = (logical_layer_id * Hcal_radiator_thickness 
+		   + (logical_layer_id -1) * Hcal_chamber_thickness) * TanPiDiv8;
+
+	x_total  = Hcal_bottom_dim_x/2 - Hcal_middle_stave_gaps/2 + xOffset;
+	x_length = x_total - 2*Hcal_layer_air_gap;
+	x_halfLength = x_length/2.;
+
+      } else {//----- top barrel -------------------------------------------------
+	double y_layerID = logical_layer_id * (Hcal_radiator_thickness + Hcal_chamber_thickness) + Hcal_inner_radius;
+	double ro_layer = Hcal_outer_radius - Hcal_radiator_thickness;
+	
+	x_total = sqrt( ro_layer * ro_layer - y_layerID * y_layerID);
+	
+	x_length = x_total - Hcal_middle_stave_gaps;
+	
+	x_halfLength = x_length/2.;
+	
+	xOffset = (logical_layer_id * Hcal_radiator_thickness 
+		   + (logical_layer_id - 1) * Hcal_chamber_thickness - Hcal_y_dim1_for_x) / TanPiDiv8
+	  + Hcal_chamber_thickness / TanPiDiv8;
+	
+      }
+
+      double xAbsShift = (Hcal_middle_stave_gaps/2 + Hcal_layer_air_gap + x_halfLength);
+      
+      if (layer_id <= Hcal_nlayers)     xShift = - xAbsShift;
+      else if (layer_id > Hcal_nlayers) xShift = xAbsShift;
+
+      x_length = x_length/2.;
+
+      
+      //calculate the size of a fractional tile
+      //-> this sets fract_cell_dim_x
+      
+      //double fract_cell_dim_x = 0.;
+      //this->CalculateFractTileSize(2*x_length, Hcal_cell_dim_x, fract_cell_dim_x);
+      
+      //Vector newFractCellDim(fract_cell_dim_x, Hcal_chamber_thickness, Hcal_cell_dim_z);
+      //theBarrilRegSD->SetFractCellDimPerLayer(layer_id, newFractCellDim);
+
+      encoder["layer"] = logical_layer_id ;
+      cellSizeVector = seg.segmentation()->cellDimensions( encoder.getValue() ); 
+      cell_sizeX      = cellSizeVector[0];
+      cell_sizeY      = cellSizeVector[1];
+
+      LayeredCalorimeterData::Layer caloLayer ;
+      caloLayer.cellSize0 = cell_sizeX;
+      caloLayer.cellSize1 = cell_sizeY;
+
+
+      //--------------------------------------------------------------------------------
+      //  build chamber box, with the calculated dimensions 
+      //-------------------------------------------------------------------------------
+      printout( dd4hep::DEBUG,  "SHcalSc04_Barrel_v04", " \n Start to build layer chamber - layer_id: %d", layer_id ) ;
+      printout( dd4hep::DEBUG,  "SHcalSc04_Barrel_v04"," chamber x:y:z:  %e:%e:%e", x_length*2., z_width*2. , y_height*2. );
+
+      //check if x_length (scintillator length) is divisible with x_integerTileSize
+      if( layer_id <= Hcal_nlayers) {
+	double fracPart, intPart;
+	double temp = x_length*2./cell_sizeX;
+	fracPart = modf(temp, &intPart);
+	int noOfIntCells = int(temp);
+
+
+	if( tileSeg !=0 ){
+
+	  tileSeg->setBoundaryLayerX(x_length);
+	  
+	  if (fracPart == 0){ //divisible
+	    if ( noOfIntCells%2 ) {
+	      if( tileSeg !=0 ) tileSeg->setLayerOffsetX(0);
+	    }
+	    else {
+	      if( tileSeg !=0 ) tileSeg->setLayerOffsetX(1);
+	    }
+	    tileSeg->setFractCellSizeXPerLayer(0);
+	  }
+	  else if (fracPart>0){
+	    if ( noOfIntCells%2 ) {
+	      if( tileSeg !=0 ) tileSeg->setLayerOffsetX(1);
+	    }
+	    else {
+	      if( tileSeg !=0 ) tileSeg->setLayerOffsetX(0);
+	    }
+	    tileSeg->setFractCellSizeXPerLayer( (fracPart+1.0)/2.0*cell_sizeX );
+	  }
+	  
+	  if ( (int)( (z_width*2.) / cell_sizeX)%2 ){
+	    if( tileSeg !=0 ) tileSeg->setLayerOffsetY(0);
+	  }
+	  else {
+	    if( tileSeg !=0 ) tileSeg->setLayerOffsetY(1);
+	  }
+
+	}
+      }
+      Box ChamberSolid((x_length + Hcal_layer_air_gap),  //x + air gaps at two side, do not need to build air gaps individualy.
+			 z_width,   //z attention!
+			 y_height); //y attention!
+
+      string ChamberLogical_name      = det_name+_toString(layer_id,"_layer%d");
+
+      Volume ChamberLogical(ChamberLogical_name, ChamberSolid, air);   
+
+
+
+      double layer_thickness = y_height*2.;
+
+      double nRadiationLengths=0.;
+      double nInteractionLengths=0.;
+      double thickness_sum=0;
+
+      nRadiationLengths   = Hcal_radiator_thickness/(stavesMaterial.radLength());
+      nInteractionLengths = Hcal_radiator_thickness/(stavesMaterial.intLength());
+      thickness_sum       = Hcal_radiator_thickness;
+
+//====================================================================
+// Create Hcal Barrel Chamber without radiator
+// Place into the Hcal Barrel stave, after each radiator 
+//====================================================================
+      xml_coll_t c(x_det,_U(layer));
+      xml_comp_t   x_layer = c;
+      string layer_name      = det_name+_toString(layer_id,"_layer%d");
+      
+      // Create the slices (sublayers) within the Hcal Barrel Chamber.
+      double slice_pos_z = layer_thickness/2.;
+      int slice_number = 0;
+
+      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");
+	double   slice_thickness = x_slice.thickness();
+	Material slice_material  = theDetector.material(x_slice.materialStr());
+	DetElement slice(layer_name,_toString(slice_number,"slice%d"),x_det.id());
+	
+	slice_pos_z -= slice_thickness/2.;
+	
+	// Slice volume & box
+	Volume slice_vol(slice_name,Box(x_length,z_width,slice_thickness/2.),slice_material);
+
+	nRadiationLengths   += slice_thickness/(2.*slice_material.radLength());
+	nInteractionLengths += slice_thickness/(2.*slice_material.intLength());
+	thickness_sum       += slice_thickness/2;
+	
+	if ( x_slice.isSensitive() ) {
+
+	  slice_vol.setSensitiveDetector(sens);
+
+	  // if we have a multisegmentation based on slices, we need to use the correct slice here
+	  if ( sensitive_slice_number<0  || sensitive_slice_number == slice_number ) {
+	
+	    //Store "inner" quantities
+	    caloLayer.inner_nRadiationLengths   = nRadiationLengths;
+	    caloLayer.inner_nInteractionLengths = nInteractionLengths;
+	    caloLayer.inner_thickness = thickness_sum;
+	    //Store scintillator thickness
+	    caloLayer.sensitive_thickness = slice_thickness;
+	    
+	    //Reset counters to measure "outside" quantitites
+	    nRadiationLengths=0.;
+	    nInteractionLengths=0.;
+	    thickness_sum = 0.;
+	  }
+	}
+
+	nRadiationLengths   += slice_thickness/(2.*slice_material.radLength());
+	nInteractionLengths += slice_thickness/(2.*slice_material.intLength());
+	thickness_sum       += slice_thickness/2;
+
+
+	// Set region, limitset, and vis.
+	slice_vol.setAttributes(theDetector,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr());
+	// slice PlacedVolume
+	PlacedVolume slice_phv = ChamberLogical.placeVolume(slice_vol,Position(0.,0.,slice_pos_z));
+
+	slice_phv.addPhysVolID("layer",logical_layer_id).addPhysVolID("slice", slice_number );
+
+	
+	if ( x_slice.isSensitive() ) {
+	  int tower_id  = (layer_id > Hcal_nlayers)? 1:-1;
+	  slice_phv.addPhysVolID("tower",tower_id);
+	  printout( dd4hep::DEBUG,  "SHcalSc04_Barrel_v04", "  logical_layer_id:  %d  tower_id:  %d", logical_layer_id, tower_id  ) ;
+	}
+	
+	slice.setPlacement(slice_phv);
+	// Increment x position for next slice.
+	slice_pos_z -= slice_thickness/2.;
+	// Increment slice number.
+	++slice_number;             
+      }
+
+      //Store "outer" quantities
+      caloLayer.outer_nRadiationLengths = nRadiationLengths;
+      caloLayer.outer_nInteractionLengths = nInteractionLengths;
+      caloLayer.outer_thickness = thickness_sum;
+
+
+//---------------------------  Chamber Placements -----------------------------------------
+
+      double chamber_x_offset, chamber_y_offset, chamber_z_offset;
+      chamber_x_offset = xShift;
+
+      chamber_z_offset = 0;
+
+
+      chamber_y_offset = -(-Hcal_total_dim_y/2. 
+			   + (logical_layer_id-1) *(Hcal_chamber_thickness + Hcal_radiator_thickness)
+			   + Hcal_radiator_thickness + Hcal_chamber_thickness/2.);
+
+
+      pv =  EnvLogHcalModuleBarrel.placeVolume(ChamberLogical,
+					       Position(chamber_x_offset,
+							chamber_z_offset,
+							chamber_y_offset + chambers_y_off_correction));
+      
+
+
+      //-----------------------------------------------------------------------------------------
+      if( layer_id <= Hcal_nlayers ){ // add the first set of layers to the reconstruction data
+	
+	caloLayer.distance = Hcal_inner_radius + Hcal_total_dim_y/2.0 - (chamber_y_offset + chambers_y_off_correction)
+	  - caloLayer.inner_thickness ; // Will be added later at "DDMarlinPandora/DDGeometryCreator.cc:226" to get center of sensitive element
+
+	caloLayer.absorberThickness = Hcal_radiator_thickness ;
+	
+	caloData->layers.push_back( caloLayer ) ;
+      }
+      //-----------------------------------------------------------------------------------------
+
+      
+    }//end loop over HCAL nlayers;
+
+  if( tileSeg !=0 ){
+    // check the offsets directly in the TileSeg ...
+    std::vector<double> LOX = tileSeg->layerOffsetX();
+    std::vector<double> LOY = tileSeg->layerOffsetY();
+
+    std::stringstream sts ;
+    sts <<" layerOffsetX(): ";
+    for (std::vector<double>::const_iterator ix = LOX.begin(); ix != LOX.end(); ++ix)
+      sts << *ix << ' ';
+    printout( dd4hep::DEBUG,  "SHcalSc04_Barrel_v04", "%s" , sts.str().c_str() ) ;
+    sts.clear() ; sts.str("") ;
+    sts <<" layerOffsetY(): ";
+    for (std::vector<double>::const_iterator iy = LOY.begin(); iy != LOY.end(); ++iy)
+      sts << *iy << ' ';
+    printout( dd4hep::DEBUG,  "SHcalSc04_Barrel_v04", "%s" , sts.str().c_str() ) ;
+
+  }
+
+
+
+//====================================================================
+// Place HCAL Barrel stave module into the envelope
+//====================================================================
+  double stave_phi_offset,  module_z_offset,  lateral_plate_z_offset;
+
+  double Y = Hcal_inner_radius + Hcal_total_dim_y / 2.;
+
+  stave_phi_offset = M_PI/Hcal_inner_symmetry -M_PI/2.;
+
+
+  //-------- start loop over HCAL BARREL staves ----------------------------
+
+  for (int stave_id = 1;
+       stave_id <=Hcal_inner_symmetry;
+       stave_id++)
+    {
+      module_z_offset = - (Hcal_normal_dim_z + Hcal_modules_gap + Hcal_lateral_plate_thickness)/2.;
+      lateral_plate_z_offset = - (Hcal_lateral_plate_thickness + Hcal_modules_gap)/2.;
+
+      double phirot = stave_phi_offset;
+      RotationZYX srot(0,phirot,M_PI*0.5);
+      Rotation3D srot3D(srot);
+
+      for (int module_id = 1;
+         module_id <=2;
+         module_id++)
+	{
+	  Position sxyzVec(-Y*sin(phirot), Y*cos(phirot), module_z_offset);
+	  Transform3D stran3D(srot3D,sxyzVec);
+	  
+	  // Place Hcal Barrel volume into the envelope volume
+	  pv = envelope.placeVolume(EnvLogHcalModuleBarrel,stran3D);
+	  pv.addPhysVolID("stave",stave_id);
+	  pv.addPhysVolID("module",module_id);
+	  pv.addPhysVolID("system",det_id);
+
+	  const int staveCounter = (stave_id-1)*2+module_id-1;
+	  DetElement stave(sdet, _toString(staveCounter,"stave%d"), staveCounter );
+	  stave.setPlacement(pv);
+
+	  Position xyzVec_LP(-Y*sin(phirot), Y*cos(phirot),lateral_plate_z_offset);
+	  Transform3D tran3D_LP(srot3D,xyzVec_LP);
+	  pv = envelope.placeVolume(EnvLogHcalModuleBarrel_LP,tran3D_LP);
+
+	  module_z_offset = - module_z_offset;
+	  lateral_plate_z_offset = - lateral_plate_z_offset;
+	}
+
+
+      stave_phi_offset -=  M_PI*2.0/Hcal_inner_symmetry;
+    }  //-------- end loop over HCAL BARREL staves ----------------------------
+
+
+  sdet.addExtension< LayeredCalorimeterData >( caloData ) ;
+
+ 
+  return sdet;
+
+}
+
+DECLARE_DETELEMENT(SHcalSc04_Barrel_v04, create_detector)
diff --git a/Detector/DetCEPCv4/src/calorimeter/SHcalSc04_Endcaps_v01.cpp b/Detector/DetCEPCv4/src/calorimeter/SHcalSc04_Endcaps_v01.cpp
new file mode 100644
index 00000000..4b074089
--- /dev/null
+++ b/Detector/DetCEPCv4/src/calorimeter/SHcalSc04_Endcaps_v01.cpp
@@ -0,0 +1,498 @@
+//====================================================================
+//  AIDA Detector description implementation
+//  for LDC AHCAL Endcap
+//--------------------------------------------------------------------
+//
+//  Author     : S.Lu
+//  F. Gaede, DESY :  v01 : prepare for multi segmentation
+//     18.04.2017            - copied from SHcalSc04_Barrel_v01.cpp
+//                           - add optional parameter <subsegmentation key="" value=""/>
+//                             defines the segmentation to be used in reconstruction
+//
+// Basic idea:
+// 1. Create the Hcal Endcap module envelope (16 modules).
+//    Note: with default material Steel235.
+//    
+// 2. Create the Hcal Endcap Chamber(i.e. Layer) for each module.
+//    Create the Layer with slices (Polystyrene,Cu,FR4,air).
+//    Place each slice into the chamber with the right position,
+//    And registry the IDs for slice
+//
+// 3. Place the same Layer into the endcap module envelope.
+//    It will be repeated repeat 48 times.
+//    And registry the IDs for layer, and endcapID.
+//
+// 4. Place the endcap module into the world volume,
+//    with the right position and rotation.
+//    And registry the IDs for stave,module and endcapID.
+//
+// 5. Customer material FR4 and Steel235 defined in materials.xml
+//
+//====================================================================
+#include "DD4hep/DetFactoryHelper.h"
+#include "DD4hep/DetType.h"
+#include "XML/Layering.h"
+#include "XML/Utilities.h"
+#include "DDRec/DetectorData.h"
+#include "DDSegmentation/BitField64.h"
+#include "DDSegmentation/Segmentation.h"
+#include "DDSegmentation/MultiSegmentation.h"
+#include "LcgeoExceptions.h"
+
+using namespace std;
+
+using dd4hep::BUILD_ENVELOPE;
+using dd4hep::BitField64;
+using dd4hep::Box;
+using dd4hep::DetElement;
+using dd4hep::DetType;
+using dd4hep::Detector;
+using dd4hep::Layering;
+using dd4hep::Material;
+using dd4hep::PlacedVolume;
+using dd4hep::Position;
+using dd4hep::Readout;
+using dd4hep::Ref_t;
+using dd4hep::RotationX;
+using dd4hep::Segmentation;
+using dd4hep::SensitiveDetector;
+using dd4hep::Transform3D;
+using dd4hep::Translation3D;
+using dd4hep::Volume;
+using dd4hep::_toString;
+
+using dd4hep::rec::LayeredCalorimeterData;
+
+
+static Ref_t create_detector(Detector& theDetector, xml_h element, SensitiveDetector sens)  {
+  xml_det_t   x_det     = element;
+  Layering    layering(x_det);
+  xml_dim_t   dim         = x_det.dimensions();
+  string      det_name    = x_det.nameStr();
+
+  Material    air         = theDetector.air();
+  Material    stavesMaterial    = theDetector.material(x_det.materialStr());
+  int         numSides    = dim.numsides();
+
+  int           det_id    = x_det.id();
+
+  DetElement   sdet(det_name,det_id);
+
+  PlacedVolume pVol;
+
+  // --- create an envelope volume and position it into the world ---------------------
+
+  Volume envelope = dd4hep::xml::createPlacedEnvelope( theDetector,  element , sdet ) ;
+  
+  sdet.setTypeFlag( DetType::CALORIMETER |  DetType::ENDCAP  | DetType::HADRONIC ) ;
+
+  if( theDetector.buildType() == BUILD_ENVELOPE ) return sdet ;
+  //-----------------------------------------------------------------------------------
+
+  sens.setType("calorimeter");
+
+  DetElement    stave_det("module0stave0",det_id);
+ 
+  // The way to reaad constant from XML/Detector file.
+  double      Hcal_radiator_thickness          = theDetector.constant<double>("Hcal_radiator_thickness");
+  double      Hcal_endcap_lateral_structure_thickness = theDetector.constant<double>("Hcal_endcap_lateral_structure_thickness");
+  double      Hcal_endcap_layer_air_gap        = theDetector.constant<double>("Hcal_endcap_layer_air_gap");
+
+  //double      Hcal_cells_size                  = theDetector.constant<double>("Hcal_cells_size");
+  double      HcalEndcap_inner_radius          = theDetector.constant<double>("Hcal_endcap_inner_radius");
+  double      HcalEndcap_outer_radius          = theDetector.constant<double>("Hcal_endcap_outer_radius");
+  double      HcalEndcap_min_z                 = theDetector.constant<double>("Hcal_endcap_zmin");
+  double      HcalEndcap_max_z                 = theDetector.constant<double>("Hcal_endcap_zmax");
+
+  double   Hcal_steel_cassette_thickness       = theDetector.constant<double>("Hcal_steel_cassette_thickness");
+  double   HcalServices_outer_FR4_thickness    = theDetector.constant<double>("Hcal_services_outer_FR4_thickness");
+  double   HcalServices_outer_Cu_thickness     = theDetector.constant<double>("Hcal_services_outer_Cu_thickness");
+  double   Hcal_endcap_services_module_width   = theDetector.constant<double>("Hcal_endcap_services_module_width");
+
+  Material  stainless_steel =  theDetector.material("stainless_steel");
+  Material  PCB             =  theDetector.material("PCB");
+  Material  copper          =  theDetector.material("Cu");
+
+  std::cout <<"\n HcalEndcap_inner_radius = "
+	    <<HcalEndcap_inner_radius/dd4hep::mm <<" mm"
+	    <<"\n HcalEndcap_outer_radius = "
+	    <<HcalEndcap_outer_radius/dd4hep::mm <<" mm"
+	    <<"\n HcalEndcap_min_z = "
+	    <<HcalEndcap_min_z/dd4hep::mm <<" mm"
+	    <<"\n HcalEndcap_max_z = "
+	    <<HcalEndcap_max_z/dd4hep::mm <<" mm"
+	    <<std::endl;
+  
+  Readout readout = sens.readout();
+  Segmentation seg = readout.segmentation();
+  
+
+  BitField64 encoder = seg.decoder();
+  encoder.setValue(0) ;
+  
+  //    we first have to check whether a multi segmentation is used and then, if so, we
+  //    will check the <subsegmentation key="" value=""/> element, for which subsegmentation to use for filling the 
+  //    DDRec:LayeredCalorimeterData information.
+
+  // check if we have a multi segmentation :
+  dd4hep::DDSegmentation::MultiSegmentation* multiSeg = 
+    dynamic_cast< dd4hep::DDSegmentation::MultiSegmentation*>( seg.segmentation() ) ;
+  
+  int sensitive_slice_number = -1 ;
+
+  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 ;
+
+      // 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 == "slice" ){
+	sensitive_slice_number = keyVal ;
+      }
+
+    } catch(const std::runtime_error &) {
+      throw lcgeo::GeometryException(  "SHcalSc04_Endcaps_v01: Error: MultiSegmentation specified but no "
+				       " <subsegmentation key="" value=""/> element defined for detector ! " ) ;
+    }
+  }
+ 
+  //========== fill data for reconstruction ============================
+  LayeredCalorimeterData* caloData = new LayeredCalorimeterData ;
+  caloData->layoutType = LayeredCalorimeterData::EndcapLayout ;
+  caloData->inner_symmetry = 4  ; // hard code cernter box hole
+  caloData->outer_symmetry = 0  ; // outer tube, or 8 for Octagun
+  caloData->phi0 = 0 ;
+
+  /// extent of the calorimeter in the r-z-plane [ rmin, rmax, zmin, zmax ] in mm.
+  caloData->extent[0] = HcalEndcap_inner_radius ;
+  caloData->extent[1] = HcalEndcap_outer_radius ;
+  caloData->extent[2] = HcalEndcap_min_z ;
+  caloData->extent[3] = HcalEndcap_max_z ;
+  
+
+  int endcapID = 0;
+  for(xml_coll_t c(x_det.child(_U(dimensions)),_U(dimensions)); c; ++c) 
+    {
+      xml_comp_t l(c);
+      
+      double dim_x = l.attr<double>(_Unicode(dim_x));
+      double dim_y = l.attr<double>(_Unicode(dim_y));
+      double dim_z = l.attr<double>(_Unicode(dim_z));
+      double pos_y = l.attr<double>(_Unicode(y_offset));
+    
+      // Hcal Endcap module shape
+      double box_half_x= dim_x/2.0; // module width, all are same
+      double box_half_y= dim_y/2.0; // module length, changing 
+      double box_half_z= dim_z/2.0; // total thickness, all are same
+      
+      double x_offset = box_half_x*numSides-box_half_x*endcapID*2.0-box_half_x;
+      double y_offset = pos_y;
+      
+      Box    EndcapModule(box_half_x,box_half_y,box_half_z);
+      
+      // define the name of each endcap Module
+      string envelopeVol_name   = det_name+_toString(endcapID,"_EndcapModule%d");
+      
+      Volume envelopeVol(envelopeVol_name,EndcapModule,stavesMaterial);
+      
+      // Set envelope volume attributes.
+      envelopeVol.setAttributes(theDetector,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
+      
+      
+      double FEE_half_x = box_half_x-Hcal_endcap_services_module_width/2.0;
+      double FEE_half_y = Hcal_endcap_services_module_width/2.0;
+      double FEE_half_z = box_half_z;
+
+      Box    FEEBox(FEE_half_x,FEE_half_y,FEE_half_z);
+      Volume FEEModule("Hcal_endcap_FEE",FEEBox,air);
+
+      double FEELayer_thickness = Hcal_steel_cassette_thickness + HcalServices_outer_FR4_thickness + HcalServices_outer_Cu_thickness;
+      Box    FEELayerBox(FEE_half_x,FEE_half_y,FEELayer_thickness/2.0);
+      Volume FEELayer("FEELayer",FEELayerBox,air);
+
+      Box    FEELayerSteelBox(FEE_half_x,FEE_half_y,Hcal_steel_cassette_thickness/2.0);
+      Volume FEELayerSteel("FEELayerSteel",FEELayerSteelBox,stainless_steel);
+      pVol = FEELayer.placeVolume(FEELayerSteel,
+				  Position(0,
+                                           0,
+					   (-FEELayer_thickness/2.0
+					    +Hcal_steel_cassette_thickness/2.0)));
+
+      Box    FEELayerFR4Box(FEE_half_x,FEE_half_y,HcalServices_outer_FR4_thickness/2.0);
+      Volume FEELayerFR4("FEELayerFR4",FEELayerFR4Box,PCB);
+      pVol = FEELayer.placeVolume(FEELayerFR4,
+				  Position(0,
+                                           0,
+					   (-FEELayer_thickness/2.0+Hcal_steel_cassette_thickness
+					    +HcalServices_outer_FR4_thickness/2.0)));
+
+      Box    FEELayerCuBox(FEE_half_x,FEE_half_y,HcalServices_outer_Cu_thickness/2.0);
+      Volume FEELayerCu("FEELayerCu",FEELayerCuBox,copper);
+      pVol = FEELayer.placeVolume(FEELayerCu,
+				  Position(0,
+                                           0,
+					   (-FEELayer_thickness/2.0+Hcal_steel_cassette_thickness+HcalServices_outer_FR4_thickness +HcalServices_outer_Cu_thickness/2.0)));
+
+
+      // ========= Create Hcal Chamber (i.e. Layers) ==============================
+      // It will be the sub volume for placing the slices.
+      // Itself will be placed into the Hcal Endcap modules envelope.
+      // ==========================================================================
+      
+      // create Layer (air) and place the slices (Polystyrene,Cu,FR4,air) into it. 
+      // place the Layer into the Hcal Endcap Modules envelope (stavesMaterial).
+      
+      // First Hcal Chamber position, start after first radiator
+      double layer_pos_z     = - box_half_z + Hcal_radiator_thickness;                      
+      
+      // Create Hcal Endcap Chamber without radiator
+      // Place into the Hcal Encap module envelope, after each radiator 
+      int layer_num = 1;
+      for(xml_coll_t m(x_det,_U(layer)); m; ++m)  {
+	xml_comp_t   x_layer = m;
+	int          repeat = x_layer.repeat();          // Get number of layers.
+
+	double layer_thickness = layering.layer(layer_num)->thickness();
+	string layer_name      = envelopeVol_name+"_layer";
+	DetElement  layer(stave_det,layer_name,det_id);
+	
+	// Active Layer box & volume
+	double active_layer_dim_x = box_half_x - Hcal_endcap_lateral_structure_thickness - Hcal_endcap_layer_air_gap;
+	double active_layer_dim_y = box_half_y;
+	double active_layer_dim_z = layer_thickness/2.0;
+	
+	// Build chamber including air gap
+	// The Layer will be filled with slices, 
+	Volume layer_vol(layer_name, Box((active_layer_dim_x + Hcal_endcap_layer_air_gap),
+					 active_layer_dim_y,active_layer_dim_z), air);
+
+
+
+	encoder["layer"] = layer_num ;
+	std::vector<double> cellSizeVector = seg.segmentation()->cellDimensions( encoder.getValue() ); 
+
+	LayeredCalorimeterData::Layer caloLayer ;
+	caloLayer.cellSize0 = cellSizeVector[0];
+	caloLayer.cellSize1 = cellSizeVector[1];
+	
+	// ========= Create sublayer slices =========================================
+	// Create and place the slices into Layer
+	// ==========================================================================
+	
+	// Create the slices (sublayers) within the Hcal Chamber.
+	double slice_pos_z = -(layer_thickness / 2.0);
+	int slice_number = 0;
+
+	double nRadiationLengths=0.;
+	double nInteractionLengths=0.;
+	double thickness_sum=0;
+
+	nRadiationLengths   = Hcal_radiator_thickness/(stavesMaterial.radLength());
+	nInteractionLengths = Hcal_radiator_thickness/(stavesMaterial.intLength());
+	thickness_sum       = Hcal_radiator_thickness;
+
+	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");
+	  double   slice_thickness = x_slice.thickness();
+	  Material slice_material  = theDetector.material(x_slice.materialStr());
+	  DetElement slice(layer,_toString(slice_number,"slice%d"),det_id);
+	  
+	  slice_pos_z += slice_thickness / 2.0;
+	  
+	  // Slice volume & box
+	  Volume slice_vol(slice_name,Box(active_layer_dim_x,active_layer_dim_y,slice_thickness/2.0),slice_material);
+	  
+	  nRadiationLengths   += slice_thickness/(2.*slice_material.radLength());
+	  nInteractionLengths += slice_thickness/(2.*slice_material.intLength());
+	  thickness_sum       += slice_thickness/2;
+
+
+	  if ( x_slice.isSensitive() ) {
+
+	    slice_vol.setSensitiveDetector(sens);
+
+	    // if we have a multisegmentation based on slices, we need to use the correct slice here
+	    if ( sensitive_slice_number<0  || sensitive_slice_number == slice_number ) {
+
+	      //Store "inner" quantities
+	      caloLayer.inner_nRadiationLengths = nRadiationLengths;
+	      caloLayer.inner_nInteractionLengths = nInteractionLengths;
+	      caloLayer.inner_thickness = thickness_sum;
+	      //Store scintillator thickness
+	      caloLayer.sensitive_thickness = slice_thickness;
+	      
+	      //Reset counters to measure "outside" quantitites
+	      nRadiationLengths=0.;
+	      nInteractionLengths=0.;
+	      thickness_sum = 0.;
+	    }
+	  }
+
+	  nRadiationLengths += slice_thickness/(2.*slice_material.radLength());
+	  nInteractionLengths += slice_thickness/(2.*slice_material.intLength());
+	  thickness_sum += slice_thickness/2;
+
+	  // Set region, limitset, and vis.
+	  slice_vol.setAttributes(theDetector,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr());
+	  // slice PlacedVolume
+	  PlacedVolume slice_phv = layer_vol.placeVolume(slice_vol,Position(0,0,slice_pos_z));
+	  slice_phv.addPhysVolID("slice",slice_number);
+	  
+	  slice.setPlacement(slice_phv);
+	  // Increment Z position for next slice.
+	  slice_pos_z += slice_thickness / 2.0;
+	  // Increment slice number.
+	  ++slice_number;             
+	}
+	// Set region, limitset, and vis.
+	layer_vol.setAttributes(theDetector,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr());
+
+
+	//Store "outer" quantities
+	caloLayer.outer_nRadiationLengths = nRadiationLengths;
+	caloLayer.outer_nInteractionLengths = nInteractionLengths;
+	caloLayer.outer_thickness = thickness_sum;
+	
+	// ========= Place the Layer (i.e. Chamber) =================================
+	// Place the Layer into the Hcal Endcap module envelope.
+	// with the right position and rotation.
+	// Registry the IDs (layer, stave, module).
+	// Place the same layer 48 times into Endcap module
+	// ==========================================================================
+	
+	for (int j = 0; j < repeat; j++)    {
+	  
+	  // Layer position in y within the Endcap Modules.
+	  layer_pos_z += layer_thickness / 2.0;
+	  
+	  PlacedVolume layer_phv = envelopeVol.placeVolume(layer_vol,
+							   Position(0,0,layer_pos_z));
+	  // registry the ID of Layer, stave and module
+	  layer_phv.addPhysVolID("layer",layer_num);
+
+	  // then setPlacement for it.
+	  layer.setPlacement(layer_phv);
+
+	  pVol = FEEModule.placeVolume(FEELayer,
+				       Position(0,0,layer_pos_z));
+	  //-----------------------------------------------------------------------------------------
+	  if ( caloData->layers.size() < (unsigned int)repeat ) {
+
+	    caloLayer.distance = HcalEndcap_min_z + box_half_z + layer_pos_z
+	      - caloLayer.inner_thickness ; // Will be added later at "DDMarlinPandora/DDGeometryCreator.cc:226" to get center of sensitive element
+	    caloLayer.absorberThickness = Hcal_radiator_thickness ;
+	    
+	    caloData->layers.push_back( caloLayer ) ;
+	  }
+	  //-----------------------------------------------------------------------------------------
+	  
+	  
+	  // ===== Prepare for next layer (i.e. next Chamber) =========================
+	  // Prepare the chamber placement position and the chamber dimension
+	  // ==========================================================================
+	  
+	  // Increment the layer_pos_y
+	  // Place Hcal Chamber after each radiator 
+	  layer_pos_z += layer_thickness / 2.0;
+	  layer_pos_z += Hcal_radiator_thickness;
+	  ++layer_num;         
+	}
+	
+	
+      }
+      
+      
+      // =========== Place Hcal Endcap envelope ===================================
+      // Finally place the Hcal Endcap envelope into the world volume.
+      // Registry the stave(up/down), module(left/right) and endcapID.
+      // ==========================================================================
+      
+      // Acording to the number of staves and modules,
+      // Place the same Hcal Endcap module volume into the world volume
+      // with the right position and rotation.
+      for(int stave_num=0;stave_num<2;stave_num++){
+	
+	double EndcapModule_pos_x = 0;
+	double EndcapModule_pos_y = 0;
+	double EndcapModule_pos_z = 0;
+	double rot_EM = 0;
+
+	double EndcapModule_center_pos_z = HcalEndcap_min_z + box_half_z;
+	
+	double FEEModule_pos_x = 0;
+	double FEEModule_pos_y = 0;
+	double FEEModule_pos_z = 0;
+	double FEEModule_center_pos_z = HcalEndcap_min_z + box_half_z;
+
+	switch (stave_num)
+	  {
+	  case 0 : 
+	    EndcapModule_pos_x = x_offset;
+	    EndcapModule_pos_y = y_offset;
+	    FEEModule_pos_x = x_offset;
+	    FEEModule_pos_y = y_offset + box_half_y + Hcal_endcap_services_module_width/2.0;
+	    break;
+	  case 1 : 
+	    EndcapModule_pos_x = -x_offset;
+	    EndcapModule_pos_y = -y_offset;
+	    FEEModule_pos_x = -x_offset;
+	    FEEModule_pos_y = -y_offset - box_half_y - Hcal_endcap_services_module_width/2.0;
+	    break;
+	  }
+	
+	for(int module_num=0;module_num<2;module_num++) {
+
+	  int module_id = (module_num==0)? 0:6;
+	  
+	  rot_EM = (module_id==0)?M_PI:0;
+	  
+	  EndcapModule_pos_z = (module_id==0)? -EndcapModule_center_pos_z:EndcapModule_center_pos_z;
+
+	  PlacedVolume env_phv = envelope.placeVolume(envelopeVol,
+						      Transform3D(RotationX(rot_EM),
+								  Translation3D(EndcapModule_pos_x,
+										EndcapModule_pos_y,
+										EndcapModule_pos_z)));
+	  env_phv.addPhysVolID("tower",endcapID);	  
+	  env_phv.addPhysVolID("stave",stave_num);   // y: up /down
+	  env_phv.addPhysVolID("module",module_id); // z: -/+ 0/6
+	  env_phv.addPhysVolID("system",det_id);
+
+	  FEEModule_pos_z = (module_id==0)? -FEEModule_center_pos_z:FEEModule_center_pos_z;
+
+	  if (!(endcapID==0))
+	    env_phv = envelope.placeVolume(FEEModule,
+					   Transform3D(RotationX(rot_EM),
+						       Translation3D(FEEModule_pos_x,
+								     FEEModule_pos_y,
+								     FEEModule_pos_z)));
+
+
+	  DetElement sd = (module_num==0&&stave_num==0) ? stave_det : stave_det.clone(_toString(module_id,"module%d")+_toString(stave_num,"stave%d"));	  
+	  sd.setPlacement(env_phv);	  
+
+	}
+	
+      }
+
+    endcapID++;
+      
+    }
+  
+  sdet.addExtension< LayeredCalorimeterData >( caloData ) ;  
+  
+  return sdet;
+}
+
+
+
+
+DECLARE_DETELEMENT(SHcalSc04_Endcaps_v01, create_detector)
diff --git a/Detector/DetCRD/compact/CRD_common_v01/SHcalSc04_Barrel_v04_01.xml b/Detector/DetCRD/compact/CRD_common_v01/SHcalSc04_Barrel_v04_01.xml
new file mode 100644
index 00000000..32810ce1
--- /dev/null
+++ b/Detector/DetCRD/compact/CRD_common_v01/SHcalSc04_Barrel_v04_01.xml
@@ -0,0 +1,71 @@
+<!-- comment>Calorimeters</comment -->
+
+<lccdd>
+  <define>
+    <constant name="Hcal_cell_size" value="10*mm"/>
+    <constant name="Hcal_inner_radius" value="Hcal_barrel_inner_radius"/>
+    <constant name="Hcal_half_length" value="Hcal_barrel_half_length"/>
+    <constant name="Hcal_inner_symmetry" value="Hcal_barrel_symmetry"/>
+    <constant name="Hcal_nlayers" value="38"/>
+    <constant name="Hcal_radiator_thickness" value="20.0*mm"/>
+    <constant name="Hcal_chamber_thickness" value="6.5*mm"/>
+    <constant name="Hcal_back_plate_thickness" value="15*mm"/>
+    <constant name="Hcal_lateral_structure_thickness" value="10*mm"/>
+    <constant name="Hcal_stave_gaps" value="0*mm"/>
+    <constant name="Hcal_middle_stave_gaps" value="0*mm"/>
+    <constant name="Hcal_modules_gap" value="2*mm"/>
+    <constant name="Hcal_layer_air_gap" value="0*mm"/>
+    <constant name="HcalSD_glass_anode_thickness" value="0.7*mm"/>
+    <constant name="HcalSD_sensitive_gas_gap" value="1.2*mm"/>
+    <constant name="HcalSD_glass_cathode_thickness" value="1.1*mm"/>
+    <constant name="Hcal_scintillator_thickness" value="3.0*mm"/>
+    <constant name="Ecal_outer_radius" value="Ecal_barrel_outer_radius"/>
+    <constant name="Hcal_readout_segmentation_slice" value="3"/>
+  </define>
+  <detectors>
+    <detector name="HcalBarrel" type="SHcalSc04_Barrel_v04" id="DetID_HCAL" readout="HcalBarrelCollection" vis="GreenVis" insideTrackingVolume="false" >
+      <comment>Hadron Calorimeter Barrel</comment>
+
+      <envelope vis="ILD_HCALVis">
+        <shape type="BooleanShape" operation="Subtraction" material="Air" >
+          <shape type="Cone" rmin1="0.0" rmax1="Hcal_outer_radius + env_safety" rmin2="0.0" rmax2="Hcal_outer_radius + env_safety" z="Hcal_half_length + env_safety/2.0"/>
+          <shape type="PolyhedraRegular"  numsides="Hcal_inner_symmetry" rmin="0.0"
+                 rmax="Hcal_inner_radius - env_safety" dz="2*(Hcal_half_length + env_safety)"/>
+        </shape>
+        <rotation x="0" y="0" z="90*deg-180*deg/Hcal_inner_symmetry"/>
+      </envelope>
+
+      <type_flags type=" DetType_CALORIMETER + DetType_BARREL + DetType_HADRONIC " />
+
+      <staves  material = "Steel235"  vis="BlueVis"/>
+
+
+      <!--  select which subsegmentation will be used to fill the DDRec:LayeredCalorimeterData cell dimensions -->
+      <subsegmentation key="slice" value="Hcal_readout_segmentation_slice"/>
+
+      <layer repeat="Hcal_nlayers" vis="SeeThrough">
+        <slice material="FloatGlass" thickness="HcalSD_glass_anode_thickness" vis="Invisible"/>
+        <slice material="RPCGAS2"    thickness="HcalSD_sensitive_gas_gap" sensitive="yes" limits="cal_limits" vis="YellowVis"/>
+        <slice material="FloatGlass" thickness="HcalSD_glass_cathode_thickness" vis="Invisible"/>
+        <slice material="G4_POLYSTYRENE" thickness = "Hcal_scintillator_thickness" sensitive = "yes"   limits="cal_limits"  vis="CyanVis"   />
+        <slice material="Air"      thickness="Hcal_chamber_thickness - ( HcalSD_glass_anode_thickness + HcalSD_sensitive_gas_gap + HcalSD_glass_cathode_thickness + Hcal_scintillator_thickness)" vis="Invisible" />
+      </layer>
+    </detector>
+  </detectors>
+
+  <readouts>
+    <readout name="HcalBarrelCollection">
+      <segmentation   type="MultiSegmentation"  key="slice">
+        <segmentation name="RPCgrid" type="CartesianGridXY"   key_value="1"  grid_size_x="Hcal_cell_size" grid_size_y="Hcal_cell_size" />
+        <segmentation name="Scigrid" type="TiledLayerGridXY"  key_value="3"  grid_size_x="3" grid_size_y="3.03248"/>
+      </segmentation>
+      <hits_collections>
+        <hits_collection name="HCalBarrelRPCHits"  key="slice" key_value="1"/>
+        <hits_collection name="HcalBarrelRegCollection"  key="slice" key_value="3"/>
+      </hits_collections>
+      <id>system:5,module:3,stave:4,tower:5,layer:6,slice:4,x:32:-16,y:-16</id>
+    </readout>
+  </readouts>
+
+
+</lccdd>
diff --git a/Detector/DetCRD/compact/CRD_common_v01/SHcalSc04_Endcaps_v01_01.xml b/Detector/DetCRD/compact/CRD_common_v01/SHcalSc04_Endcaps_v01_01.xml
new file mode 100644
index 00000000..6b11b773
--- /dev/null
+++ b/Detector/DetCRD/compact/CRD_common_v01/SHcalSc04_Endcaps_v01_01.xml
@@ -0,0 +1,90 @@
+<lccdd>
+  <define>
+    <constant name="SDHCal_cell_size" value="10*mm"/>
+    <constant name="AHCal_cell_size" value="10*mm"/>
+    <constant name="Hcal_endcap_lateral_structure_thickness" value="5.0*mm"/>
+    <constant name="Hcal_endcap_layer_air_gap" value="2.5*mm"/>
+    <constant name="Hcal_steel_cassette_thickness" value="0.5*mm"/>
+    <constant name="Hcal_services_outer_FR4_thickness" value="2.8*mm"/>
+    <constant name="Hcal_services_outer_Cu_thickness" value="0.4*mm"/>
+    <constant name="Hcal_endcap_services_module_width" value="100.0*mm"/>
+    <constant name="Hcal_endcap_nlayers" value="40"/>
+    <constant name="Hcal_endcap_env_thickness" value="Hcal_endcap_zmax-Hcal_endcap_zmin"/>
+    <constant name="Hcal_x_modul" value="12"/>
+    <constant name="Hcal_x_width" value="Hcal_endcap_inner_radius*2/2"/><!--350-->
+    <constant name="Hcal_y_height" value="Hcal_x_width*Hcal_x_modul/2"/><!--2100-->
+    <constant name="Hcal_hole_height" value="Hcal_endcap_inner_radius"/>
+    <constant name="Hcal_r_max" value="Hcal_y_height/cos(pi/Hcal_endcap_symmetry)"/><!--2174.08-->
+    <constant name="Hcal_x_top" value="Hcal_y_height*tan(pi/Hcal_endcap_symmetry)"/> <!--562.69-->
+    <constant name="Hcal_x_point" value="(Hcal_y_height+Hcal_x_top*tan(2*pi/Hcal_endcap_symmetry))/(1+tan(2*pi/Hcal_endcap_symmetry))"/><!--1537.30-->
+    <constant name="Hcal_y5" value="Hcal_y_height-(Hcal_x_width*2-Hcal_x_top)*tan(2*pi/Hcal_endcap_symmetry)"/>
+    <constant name="Hcal_y4" value="Hcal_y5-Hcal_x_width*tan(2*pi/Hcal_endcap_symmetry)"/>
+    <constant name="Hcal_y3" value="Hcal_y4-Hcal_x_width*tan(2*pi/Hcal_endcap_symmetry)"/>
+    <constant name="Hcal_y2" value="Hcal_x_top+Hcal_x_width/tan(2*pi/Hcal_endcap_symmetry)"/>
+    
+  </define>
+  <detectors>
+    <detector id="DetID_HCAL_ENDCAP" name="HcalEndcap" type="SHcalSc04_Endcaps_v01" readout="HcalEndcapsReadout"  vis="GreenVis" calorimeterType="HAD_ENDCAP">
+      <comment>Hadron Calorimeter Endcap</comment>
+
+      <envelope vis="ILD_HCALVis">
+        <shape type="BooleanShape" operation="Subtraction" material="Air"><!--2. create center box hole -->
+          <shape type="BooleanShape" operation="Subtraction" material="Air"><!--1. create Endcaps envelope -->
+            <shape type="Tube" rmin="0.0" rmax="Solenoid_inner_radius" dz="Hcal_endcap_zmax + env_safety"/>
+            <shape type="Tube" rmin="0.0" rmax="Solenoid_inner_radius" dz="Hcal_endcap_zmin - env_safety"/>
+          </shape>
+          <shape type="Box" dx="Hcal_endcap_inner_radius - env_safety" dy="Hcal_endcap_inner_radius - env_safety"
+                 dz="Hcal_endcap_zmax + 2.0*env_safety"/>
+        </shape>
+        <rotation x="0" y="0" z="0"/>
+      </envelope>
+
+      <type_flags type=" DetType_CALORIMETER + DetType_ENDCAP + DetType_HADRONIC " />
+
+      <material name="Steel235"/><!-- radiator and the thickness has been defined in the main xml file-->
+
+      <dimensions numsides="Hcal_x_modul" >
+	<dimensions id="1"  y_offset="Hcal_x_top/2"                       dim_x="Hcal_hole_height" dim_y="Hcal_x_top"                     dim_z="Hcal_endcap_env_thickness"/>
+	<dimensions id="2"  y_offset="Hcal_y2/2"                          dim_x="Hcal_hole_height" dim_y="Hcal_y2"                        dim_z="Hcal_endcap_env_thickness"/>
+	<dimensions id="3"  y_offset="Hcal_y3/2"                          dim_x="Hcal_hole_height" dim_y="Hcal_y3"                        dim_z="Hcal_endcap_env_thickness"/>
+	<dimensions id="4"  y_offset="Hcal_y4/2"                          dim_x="Hcal_hole_height" dim_y="Hcal_y4"                        dim_z="Hcal_endcap_env_thickness"/>
+	<dimensions id="5"  y_offset="Hcal_y5/2"                          dim_x="Hcal_hole_height" dim_y="Hcal_y5"                        dim_z="Hcal_endcap_env_thickness"/>
+        <dimensions id="6"  y_offset="Hcal_y_height/2+Hcal_hole_height/2" dim_x="Hcal_hole_height" dim_y="Hcal_y_height-Hcal_hole_height" dim_z="Hcal_endcap_env_thickness"/>
+	<dimensions id="7"  y_offset="Hcal_y_height/2+Hcal_hole_height/2" dim_x="Hcal_hole_height" dim_y="Hcal_y_height-Hcal_hole_height" dim_z="Hcal_endcap_env_thickness"/>
+	<dimensions id="8"  y_offset="Hcal_y5/2"                          dim_x="Hcal_hole_height" dim_y="Hcal_y5"                        dim_z="Hcal_endcap_env_thickness"/>
+	<dimensions id="9"  y_offset="Hcal_y4/2"                          dim_x="Hcal_hole_height" dim_y="Hcal_y4"                        dim_z="Hcal_endcap_env_thickness"/>
+	<dimensions id="10" y_offset="Hcal_y3/2"                          dim_x="Hcal_hole_height" dim_y="Hcal_y3"                        dim_z="Hcal_endcap_env_thickness"/>
+	<dimensions id="11" y_offset="Hcal_y2/2"                          dim_x="Hcal_hole_height" dim_y="Hcal_y2"                        dim_z="Hcal_endcap_env_thickness"/>
+	<dimensions id="12" y_offset="Hcal_x_top/2"                     dim_x="Hcal_hole_height" dim_y="Hcal_x_top"                     dim_z="Hcal_endcap_env_thickness"/>
+      </dimensions>
+
+      <!--  select which subsegmentation will be used to fill the DDRec:LayeredCalorimeterData cell dimensions -->
+      <subsegmentation key="slice" value="Hcal_readout_segmentation_slice"/>
+
+      <layer repeat="Hcal_endcap_nlayers" vis="SeeThrough">
+        <slice material="FloatGlass" thickness="HcalSD_glass_anode_thickness" vis="Invisible"/>
+        <slice material="RPCGAS2"    thickness="HcalSD_sensitive_gas_gap" sensitive="yes" limits="cal_limits" vis="YellowVis"/>
+        <slice material="FloatGlass" thickness="HcalSD_glass_cathode_thickness" vis="Invisible"/>
+        <slice material="G4_POLYSTYRENE" thickness = "Hcal_scintillator_thickness" sensitive = "yes"   limits="cal_limits"  vis="CyanVis"   />
+        <slice material="Air"      thickness="Hcal_chamber_thickness - ( HcalSD_glass_anode_thickness + HcalSD_sensitive_gas_gap + HcalSD_glass_cathode_thickness + Hcal_scintillator_thickness)" vis="Invisible" />
+      </layer>
+    </detector>
+  </detectors>
+
+  <readouts>
+    <readout name="HcalEndcapsReadout">
+      <segmentation   type="MultiSegmentation"  key="slice">
+        <segmentation name="RPCgrid" type="CartesianGridXY"    key_value="1"    grid_size_x="SDHCal_cell_size" grid_size_y="SDHCal_cell_size" offset_x="SDHCal_cell_size/2.0" offset_y="SDHCal_cell_size/2.0" />
+        <segmentation name="Scigrid"  type="CartesianGridXY"  key_value="3"  grid_size_x="AHCal_cell_size" grid_size_y="AHCal_cell_size" offset_x="AHCal_cell_size/2.0" offset_y="AHCal_cell_size/2.0" />
+      </segmentation>
+      <hits_collections>
+        <hits_collection name="HCalEndcapRPCHits"  key="slice" key_value="1"/>
+        <hits_collection name="HcalEndcapsCollection"  key="slice" key_value="3"/>
+      </hits_collections>
+      <id>system:5,module:3,stave:3,tower:5,layer:6,slice:4,x:32:-16,y:-16</id>
+    </readout>
+  </readouts>
+
+
+</lccdd>
+
diff --git a/Detector/DetCRD/compact/Standalone/Standalone-SHcalSc04.xml b/Detector/DetCRD/compact/Standalone/Standalone-SHcalSc04.xml
new file mode 100644
index 00000000..42edeebe
--- /dev/null
+++ b/Detector/DetCRD/compact/Standalone/Standalone-SHcalSc04.xml
@@ -0,0 +1,51 @@
+<?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="StandaloneEcalRotCrystal"
+        title="CepC standalone calorimeter with rotated crystal"
+        author="C.D.Fu"
+        url="http://cepc.ihep.ac.cn"
+        status="developing"
+        version="v01">
+    <comment>CepC detector simulation models used for detector study </comment>
+  </info>
+  
+  <includes>
+    <gdmlFile  ref="${DD4hepINSTALL}/DDDetectors/compact/elements.xml"/>
+    <gdmlFile  ref="../CRD_common_v01/materials.xml"/>
+  </includes>
+  
+  <define>
+    <constant name="world_size" value="6*m"/>
+    <constant name="world_x" value="world_size"/>
+    <constant name="world_y" value="world_size"/>
+    <constant name="world_z" value="world_size"/>
+
+    <include ref="${DD4hepINSTALL}/DDDetectors/compact/detector_types.xml"/>
+  </define>
+
+  <include ref="./Dimensions_v01_01.xml"/>
+
+  <!--include ref="../CRD_common_v01/Coil_Simple_v01_01.xml"/-->
+  <include ref="../CRD_common_v01/SHcalSc04_Barrel_v04_01.xml"/>
+  <include ref="../CRD_common_v01/SHcalSc04_Endcaps_v01_01.xml"/>
+  
+  <fields>
+    <field name="InnerSolenoid" type="solenoid"
+           inner_field="Field_nominal_value"
+           outer_field="0"
+           zmax="SolenoidCoil_half_length"
+           inner_radius="SolenoidCoil_center_radius"
+           outer_radius="Solenoid_outer_radius">
+    </field>
+    <field name="OuterSolenoid" type="solenoid"
+           inner_field="0"
+           outer_field="Field_outer_nominal_value"
+           zmax="SolenoidCoil_half_length"
+           inner_radius="Solenoid_outer_radius"
+           outer_radius="Yoke_barrel_inner_radius">
+    </field>
+  </fields>
+
+</lccdd>
-- 
GitLab