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