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