File indexing completed on 2025-01-18 09:14:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include "DD4hep/DetFactoryHelper.h"
0018 #include "XML/Layering.h"
0019
0020 using namespace std;
0021 using namespace dd4hep;
0022 using namespace dd4hep::detail;
0023
0024 static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
0025 xml_det_t x_det = e;
0026 xml_dim_t dim = x_det.dimensions();
0027 int det_id = x_det.id();
0028 bool reflect = x_det.reflect(true);
0029 string det_name = x_det.nameStr();
0030 Material air = description.air();
0031 int numsides = dim.numsides();
0032 double rmin = dim.rmin();
0033 double rmax = dim.rmax()*std::cos(M_PI/numsides);
0034 double zmin = dim.zmin();
0035 Layering layering(x_det);
0036 double totalThickness = layering.totalThickness();
0037 Volume endcapVol("endcap",PolyhedraRegular(numsides,rmin,rmax,totalThickness),air);
0038 DetElement endcap("endcap",det_id);
0039
0040 int l_num = 1;
0041 int layerType = 0;
0042 double layerZ = -totalThickness/2;
0043
0044 endcapVol.setAttributes(description,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
0045
0046 for(xml_coll_t xc(x_det,_U(layer)); xc; ++xc) {
0047 xml_comp_t x_layer = xc;
0048 double l_thick = layering.layer(l_num-1)->thickness();
0049 string l_name = _toString(layerType,"layer%d");
0050 int l_repeat = x_layer.repeat();
0051 Volume l_vol(l_name,PolyhedraRegular(numsides,rmin,rmax,l_thick),air);
0052 vector<PlacedVolume> sensitives;
0053
0054 int s_num = 1;
0055 double sliceZ = -l_thick/2;
0056 for(xml_coll_t xs(x_layer,_U(slice)); xs; ++xs) {
0057 xml_comp_t x_slice = xs;
0058 string s_name = _toString(s_num,"slice%d");
0059 double s_thick = x_slice.thickness();
0060 Material s_mat = description.material(x_slice.materialStr());
0061 Volume s_vol(s_name,PolyhedraRegular(numsides,rmin,rmax,s_thick),s_mat);
0062
0063 s_vol.setVisAttributes(description.visAttributes(x_slice.visStr()));
0064 sliceZ += s_thick/2;
0065 PlacedVolume s_phv = l_vol.placeVolume(s_vol,Position(0,0,sliceZ));
0066 s_phv.addPhysVolID("slice",s_num);
0067 if ( x_slice.isSensitive() ) {
0068 sens.setType("calorimeter");
0069 s_vol.setSensitiveDetector(sens);
0070 sensitives.push_back(s_phv);
0071 }
0072 sliceZ += s_thick/2;
0073 s_num++;
0074 }
0075 l_vol.setVisAttributes(description.visAttributes(x_layer.visStr()));
0076 if ( l_repeat <= 0 ) throw std::runtime_error(x_det.nameStr()+"> Invalid repeat value");
0077 for(int j=0; j<l_repeat; ++j) {
0078 string phys_lay = _toString(l_num,"layer%d");
0079 layerZ += l_thick/2;
0080 DetElement layer_elt(endcap, phys_lay, l_num);
0081 PlacedVolume pv = endcapVol.placeVolume(l_vol,Position(0,0,layerZ));
0082 pv.addPhysVolID("layer", l_num);
0083 layer_elt.setPlacement(pv);
0084 for(size_t ic=0; ic<sensitives.size(); ++ic) {
0085 PlacedVolume sens_pv = sensitives[ic];
0086 DetElement comp_elt(layer_elt,sens_pv.volume().name(),l_num);
0087 comp_elt.setPlacement(sens_pv);
0088 }
0089 layerZ += l_thick/2;
0090 ++l_num;
0091 }
0092 ++layerType;
0093 }
0094
0095 double z_pos = zmin+totalThickness/2;
0096 PlacedVolume pv;
0097
0098 if ( reflect ) {
0099 Assembly assembly(det_name);
0100 DetElement both_endcaps(det_name,det_id);
0101 Volume motherVol = description.pickMotherVolume(both_endcaps);
0102 DetElement sdetA = endcap;
0103 Ref_t(sdetA)->SetName((det_name+"_A").c_str());
0104 DetElement sdetB = endcap.clone(det_name+"_B",x_det.id());
0105
0106 pv = assembly.placeVolume(endcapVol,Transform3D(RotationZYX(M_PI/numsides,0,0),
0107 Position(0,0,z_pos)));
0108 pv.addPhysVolID("barrel", 1);
0109 sdetA.setPlacement(pv);
0110
0111 pv = assembly.placeVolume(endcapVol,Transform3D(RotationZYX(M_PI/numsides,M_PI,0),
0112 Position(0,0,-z_pos)));
0113 pv.addPhysVolID("barrel", 2);
0114 sdetB.setPlacement(pv);
0115
0116 pv = motherVol.placeVolume(assembly);
0117 pv.addPhysVolID("system", det_id);
0118 both_endcaps.setPlacement(pv);
0119 both_endcaps.add(sdetA);
0120 both_endcaps.add(sdetB);
0121 return both_endcaps;
0122 }
0123 Volume motherVol = description.pickMotherVolume(endcap);
0124 pv = motherVol.placeVolume(endcapVol,Transform3D(RotationZYX(M_PI/numsides,0,0),
0125 Position(0,0,z_pos)));
0126 pv.addPhysVolID("system", det_id);
0127 pv.addPhysVolID("barrel", 1);
0128 endcap.setPlacement(pv);
0129 Ref_t(endcap)->SetName(det_name.c_str());
0130 return endcap;
0131 }
0132
0133 DECLARE_DETELEMENT(DD4hep_PolyhedraEndcapCalorimeter2,create_detector)
0134