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