From 6d3e058b3533a5e04e68d13216f796c93a14acce Mon Sep 17 00:00:00 2001 From: Fangyi Guo <guofangyi@ihep.ac.cn> Date: Sat, 24 Apr 2021 21:47:52 +0800 Subject: [PATCH] Modify Ecal geometry --- .../Ecal_Crystal_Barrel_v01_01.xml | 2 +- .../DetCRD/src/Calorimeter/CRDEcal_v01.cpp | 162 ++++++++++++++++++ 2 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 Detector/DetCRD/src/Calorimeter/CRDEcal_v01.cpp diff --git a/Detector/DetCRD/compact/CRD_common_v01/Ecal_Crystal_Barrel_v01_01.xml b/Detector/DetCRD/compact/CRD_common_v01/Ecal_Crystal_Barrel_v01_01.xml index 6d3b3a7f..74451cb0 100644 --- a/Detector/DetCRD/compact/CRD_common_v01/Ecal_Crystal_Barrel_v01_01.xml +++ b/Detector/DetCRD/compact/CRD_common_v01/Ecal_Crystal_Barrel_v01_01.xml @@ -25,7 +25,7 @@ grid_size_x="1*cm" grid_size_y="1*cm" grid_size_z="1*cm"/--> - <id>system:4,layer:6,block:8,bar:10</id> + <id>system:5,module:3,stave:4,dlayer:5,part:3,slayer:32:2,bar:6</id> </readout> </readouts> diff --git a/Detector/DetCRD/src/Calorimeter/CRDEcal_v01.cpp b/Detector/DetCRD/src/Calorimeter/CRDEcal_v01.cpp new file mode 100644 index 00000000..254fc6b9 --- /dev/null +++ b/Detector/DetCRD/src/Calorimeter/CRDEcal_v01.cpp @@ -0,0 +1,162 @@ +//==================================================================== +// Detector description for CEPC Reference Detector ECal Barrel. +//-------------------------------------------------------------------- +// +// Author: Fangyi Guo email: guofangyi@ihep.ac.cn +// Ecal cosists of long crystal bar 1cm*1cm*~40cm +// 8 parts cover 2pi phi range. Inner radius, height, z-length can change from xml. +// In each part, crystal bar crosses in odd-even layer. +// +// v0r0: nothing but BGO crystal +// v01: use double-layer as basic block, for cross-location in reconstruction. +// layout: 8 module +// ->14 double-layer(dlayer) in R-direction +// ->10 part along Z-direction +// ->4 block along phi-direction (4*10*14 blocks in each module). +// ->2 sub-layer (bars in 0 sub-layer along phi direction, in 1 sub-layer along z direction). +// ->N bar. +//==================================================================== +#include "DD4hep/DetFactoryHelper.h" +#include "XML/Layering.h" +#include "XML/Utilities.h" +#include "DDRec/DetectorData.h" +#include "DDSegmentation/Segmentation.h" + +#define MYDEBUG(x) std::cout << __FILE__ << ":" << __LINE__ << ": " << x << std::endl; +#define MYDEBUGVAL(x) std::cout << __FILE__ << ":" << __LINE__ << ": " << #x << ": " << x << std::endl; + +using dd4hep::rec::LayeredCalorimeterData; +using namespace dd4hep; +using namespace std; +static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector, + xml_h e, + dd4hep::SensitiveDetector sens) { + + xml_det_t x_det = e; + + std::string det_name = x_det.nameStr(); + std::string det_type = x_det.typeStr(); + MYDEBUGVAL(det_name); + MYDEBUGVAL(det_type); + int detid = x_det.id(); + + //Global geometry + double R0 = theDetector.constant<double>("ecalbarrel_inner_radius"); + double h0 = theDetector.constant<double>("ecalbarrel_thickness"); + double Z0 = theDetector.constant<double>("ecalbarrel_zlength"); + double barx = theDetector.constant<double>("bar_x"); //Crystal size in R direction. + double bary = theDetector.constant<double>("bar_y"); //Crystal size in z/phi direction (z for odd layer, phi for even layer). + + double dim_x1 = R0*tan(22.5*degree) + sqrt(2)*h0/2.; + double dim_x2 = dim_x1 - h0; + double dim_y = Z0/2.; + double dim_z = h0/2.; + double dx = dim_x1 - R0*tan(22.5*degree); //transport distance in x-axis + double r0 = R0+h0/2.; //rotation radius + + //Crystal bar size + int Nlayers = (int)h0/(2*barx); //14 double-layers. + int Nblock_z = 11; //block number in z direction + int Nblock_phi = 4; //block number in phi direction + double barz_s0; //Crystal bar lenghth in sub-layer 0(phi direction). Depends on layer number. + double barz_s1 = Z0/Nblock_z; //Crystal bar lenghth in sub-layer 1(z direction, 46cm). + int Nbar_phi; //Crystal bar number in each block, in phi direction. + int Nbar_z = (int)barz_s1/bary; //Crystal bar number in each block, in z direction. + + //Define detector and motherVolume(world) + dd4hep::DetElement ECAL(det_name, detid); + dd4hep::Volume motherVol = theDetector.pickMotherVolume(ECAL); + + // Create a Tube-like envelope representing the whole detector volume + dd4hep::PolyhedraRegular envelope(8, 22.5*degree, R0, (R0+h0), Z0); + dd4hep::Material air(theDetector.material("Air")); + dd4hep::Volume envelopeVol(det_name, envelope, air); + dd4hep::PlacedVolume envelopePlv = motherVol.placeVolume(envelopeVol, Position(0,0,0)); + envelopePlv.addPhysVolID("system",x_det.id()); + envelopeVol.setVisAttributes(theDetector, "InvisibleWithChildren" ); + ECAL.setPlacement(envelopePlv); + + //Define specific material and volumen for detElement + dd4hep::Material mat_BGO(theDetector.material("G4_BGO")); + dd4hep::Trapezoid trap(dim_x1, dim_x2, dim_y, dim_y, dim_z); + dd4hep::Volume det_vol("trap_vol", trap, mat_BGO); + det_vol.setVisAttributes(theDetector, "InvisibleWithChildren"); + + dd4hep::Trapezoid subtrap(dim_x1, dim_x2, dim_y/Nblock_z, dim_y/Nblock_z, dim_z); + dd4hep::Volume det_stave("stave_vol", subtrap, mat_BGO); + det_stave.setVisAttributes(theDetector, "InvisibleWithChildren"); + + + + //Loop to place crystalls in one part + //Outer loop: layer (odd layer). + dd4hep::Volume bar_s1("bar_s1", dd4hep::Box(bary/2, barz_s1/2, barx/2), mat_BGO); + bar_s1.setVisAttributes(theDetector, "VisibleRed"); + bar_s1.setSensitiveDetector(sens); + + dd4hep::DetElement stavedet(ECAL, "trap",detid); + for(int ilayer=1; ilayer<=Nlayers; ilayer++){ + double lx = dim_x1 - ilayer*2*barx; + barz_s0 = floor(2*lx/Nblock_phi); + Nbar_phi = (int)barz_s0/bary; + dd4hep::Volume bar_s0("bar_s0", dd4hep::Box(barz_s0/2, bary/2, barx/2), mat_BGO); + bar_s0.setVisAttributes(theDetector, "VisibleGreen"); + bar_s0.setSensitiveDetector(sens); + for(int iphi=1; iphi<=Nblock_phi; iphi++){ + dd4hep::Volume block("block", dd4hep::Box(barz_s0/2, barz_s1/2, barx), mat_BGO); + block.setVisAttributes(theDetector, "VisibleGreen"); + //std::string blockname = "Block_"+std::to_string(ilayer)+"_"+std::to_string(iphi)+"_"+std::to_string(iz); + std::string blockname = "Block_"+std::to_string(ilayer)+"_"+std::to_string(iphi); + dd4hep::DetElement sd(stavedet, blockname, detid); + + //sub-layer 0: bars along phi. length=barz_s0. Bar num=Nbar_z +/* for(int ibar0=1;ibar0<=Nbar_z;ibar0++){ + dd4hep::PlacedVolume plv_bar0 = block.placeVolume(bar_s0, Position(0,(2*ibar0-1)*bary/2-barz_s1/2, -barx/2)); + plv_bar0.addPhysVolID("slayer",0).addPhysVolID("bar",ibar0); + std::string barname0 = "CrystalBar_s0_"+std::to_string(ibar0); + dd4hep::DetElement bardet0(sd, barname0, detid); + bardet0.setPlacement(plv_bar0); + } + + //sub-layer1 + for(int ibar1=1;ibar1<=Nbar_phi;ibar1++){ + dd4hep::PlacedVolume plv_bar1 = block.placeVolume(bar_s1, Position((2*ibar1-1)*bary/2-barz_s0/2, 0, barx/2)); + plv_bar1.addPhysVolID("slayer",1).addPhysVolID("bar",ibar1); + std::string barname1 = "CrystalBar_s1_"+std::to_string(ibar1); + dd4hep::DetElement bardet1(sd, barname1, detid); + bardet1.setPlacement(plv_bar1); + } +*/ + //dd4hep::PlacedVolume plv = det_vol.placeVolume(block, Position(lx-(2*iphi-1)*barz_s0/2, (2*iz-1)*barz_s1/2-dim_y, (2*ilayer-1)*bary-dim_z)); + dd4hep::PlacedVolume plv = det_stave.placeVolume(block, Position(lx-(2*iphi-1)*barz_s0/2, 0, (2*ilayer-1)*bary-dim_z)); + plv.addPhysVolID("dlayer", ilayer).addPhysVolID("part", iphi); + sd.setPlacement(plv); + + } + } + + for(int iz=1; iz<=Nblock_z; iz++){ + dd4hep::PlacedVolume plv = det_vol.placeVolume(det_stave, Position(0, (2*iz-1)*barz_s1/2-dim_y, 0) ); + plv.addPhysVolID("stave", iz); + DetElement sd(stavedet, _toString(iz,"stave%3d"), detid); + sd.setPlacement(plv); + } + + for(int i=0;i<8;i++){ + double rotAngle = 45*i*degree; + double posx = -r0*sin(rotAngle) - dx*cos(rotAngle); + double posy = r0*cos(rotAngle) - dx*sin(rotAngle); + dd4hep::Transform3D transform(dd4hep::RotationZ(rotAngle)*dd4hep::RotationX(-90*degree), dd4hep::Position(posx, posy, 0.)); + dd4hep::PlacedVolume plv = envelopeVol.placeVolume(det_vol, transform); + plv.addPhysVolID("module", i); + DetElement sd(ECAL, _toString(i,"trap%3d"), detid); + sd.setPlacement(plv); + } + + sens.setType("calorimeter"); + + MYDEBUG("create_detector DONE. "); + return ECAL; +} + +DECLARE_DETELEMENT(CRDEcalBarrel_v01, create_detector) -- GitLab