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