File indexing completed on 2026-09-15 08:26:38
0001
0002
0003
0004 #include "DD4hep/DetFactoryHelper.h"
0005 #include "XML/Utilities.h"
0006 #include <map>
0007
0008 using namespace std;
0009 using namespace dd4hep;
0010 using namespace dd4hep::detail;
0011
0012
0013
0014
0015
0016
0017
0018 static Ref_t create_B0Preshower(Detector& description, xml_h e, SensitiveDetector sens) {
0019 typedef vector<PlacedVolume> Placements;
0020 xml_det_t x_det = e;
0021 Material vacuum = description.vacuum();
0022 int det_id = x_det.id();
0023 string det_name = x_det.nameStr();
0024 bool reflect = x_det.reflect(false);
0025 DetElement sdet(det_name, det_id);
0026 Assembly assembly(det_name);
0027 xml::Component pos = x_det.position();
0028 xml::Component rot = x_det.rotation();
0029
0030
0031 dd4hep::xml::setDetectorTypeFlag(x_det, sdet);
0032
0033
0034
0035 Volume motherVol = description.pickMotherVolume(sdet);
0036 int m_id = 0, c_id = 0, n_sensor = 0;
0037 map<string, Volume> modules;
0038 map<string, Placements> sensitives;
0039 PlacedVolume pv;
0040
0041 assembly.setVisAttributes(description.invisible());
0042 sens.setType("tracker");
0043
0044 for (xml_coll_t mi(x_det, _U(module)); mi; ++mi, ++m_id) {
0045 xml_comp_t x_mod = mi;
0046 string m_nam = x_mod.nameStr();
0047 xml_comp_t trd = x_mod.trd();
0048
0049 double posY;
0050 double x1 = trd.x1();
0051 double x2 = trd.x2();
0052 double z = trd.z();
0053 double y1, y2, total_thickness = 0.;
0054 xml_coll_t ci(x_mod, _U(module_component));
0055 for (ci.reset(), total_thickness = 0.0; ci; ++ci)
0056 total_thickness += xml_comp_t(ci).thickness();
0057
0058 y1 = y2 = total_thickness / 2;
0059 Trapezoid m_solid(x1, x2, y1, y2, z);
0060 Volume m_volume(m_nam, m_solid, vacuum);
0061 m_volume.setVisAttributes(description.visAttributes(x_mod.visStr()));
0062
0063 Solid frame_s;
0064 if (x_mod.hasChild(_U(frame))) {
0065
0066 xml_comp_t m_frame = x_mod.child(_U(frame));
0067 xml_comp_t f_pos = m_frame.child(_U(position));
0068 xml_comp_t frame_trd = m_frame.trd();
0069 double frame_thickness = getAttrOrDefault(m_frame, _U(thickness), total_thickness);
0070 double frame_x1 = frame_trd.x1();
0071 double frame_x2 = frame_trd.x2();
0072 double frame_z = frame_trd.z();
0073
0074 Trapezoid f_solid1(x1, x2, frame_thickness / 2.0, frame_thickness / 2.0, z);
0075 Trapezoid f_solid(frame_x1, frame_x2, frame_thickness / 2.0, frame_thickness / 2.0, frame_z);
0076 SubtractionSolid frame_shape(f_solid1, f_solid);
0077 frame_s = frame_shape;
0078
0079 Material f_mat = description.material(m_frame.materialStr());
0080 Volume f_vol(m_nam + "_frame", frame_shape, f_mat);
0081 f_vol.setVisAttributes(description.visAttributes(m_frame.visStr()));
0082
0083
0084 pv = m_volume.placeVolume(f_vol, Position(f_pos.x(), f_pos.y(), f_pos.z()));
0085 }
0086
0087 for (ci.reset(), n_sensor = 1, c_id = 0, posY = -y1; ci; ++ci, ++c_id) {
0088 xml_comp_t c = ci;
0089 double c_thick = c.thickness();
0090 auto comp_x1 = getAttrOrDefault(c, _Unicode(x1), x1);
0091 auto comp_x2 = getAttrOrDefault(c, _Unicode(x2), x2);
0092 auto comp_height = getAttrOrDefault(c, _Unicode(height), z);
0093
0094 Material c_mat = description.material(c.materialStr());
0095 string c_name = _toString(c_id, "component%d");
0096
0097 Trapezoid comp_s1(comp_x1, comp_x2, c_thick / 2e0, c_thick / 2e0, comp_height);
0098 Solid comp_shape = comp_s1;
0099 if (frame_s.isValid()) {
0100 comp_shape = SubtractionSolid(comp_s1, frame_s);
0101 }
0102 Volume c_vol(c_name, comp_shape, c_mat);
0103
0104 c_vol.setVisAttributes(description.visAttributes(c.visStr()));
0105 pv = m_volume.placeVolume(c_vol, Position(0, posY + c_thick / 2, 0));
0106 if (c.isSensitive()) {
0107
0108 sdet.check(n_sensor > 2,
0109 "SiTrackerEndcap2::fromCompact: " + c_name + " Max of 2 modules allowed!");
0110 pv.addPhysVolID("sensor", n_sensor);
0111 sens.setType("tracker");
0112 c_vol.setSensitiveDetector(sens);
0113 sensitives[m_nam].push_back(pv);
0114 ++n_sensor;
0115 }
0116 posY += c_thick;
0117 }
0118 modules[m_nam] = m_volume;
0119 }
0120
0121 for (xml_coll_t li(x_det, _U(layer)); li; ++li) {
0122 xml_comp_t x_layer(li);
0123 int l_id = x_layer.id();
0124 int mod_num = 1;
0125
0126 xml_comp_t l_env = x_layer.child(_U(envelope));
0127 string layer_name = det_name + std::string("_layer") + std::to_string(l_id);
0128
0129 std::string layer_vis = l_env.attr<std::string>(_Unicode(vis));
0130
0131
0132 double layer_length = l_env.attr<double>(_Unicode(length));
0133 double layer_zstart = l_env.attr<double>(_Unicode(zstart));
0134 double layer_center_z = layer_zstart + layer_length / 2.0;
0135
0136
0137
0138
0139 Assembly layer_vol(layer_name);
0140
0141
0142
0143 layer_vol.setVisAttributes(description.visAttributes(layer_vis));
0144
0145 PlacedVolume layer_pv;
0146 if (reflect) {
0147 layer_pv = assembly.placeVolume(
0148 layer_vol, Transform3D(RotationZYX(0.0, -M_PI, 0.0), Position(0, 0, -layer_center_z)));
0149 layer_pv.addPhysVolID("barrel", 3).addPhysVolID("layer", l_id);
0150 layer_name += "_N";
0151 } else {
0152 layer_pv = assembly.placeVolume(layer_vol, Position(0, 0, layer_center_z));
0153 layer_pv.addPhysVolID("barrel", 2).addPhysVolID("layer", l_id);
0154 layer_name += "_P";
0155 }
0156 DetElement layer_element(sdet, layer_name, l_id);
0157 layer_element.setPlacement(layer_pv);
0158 layer_element.setTypeFlag(sdet.typeFlag());
0159
0160 for (xml_coll_t ri(x_layer, _U(ring)); ri; ++ri) {
0161 xml_comp_t x_ring = ri;
0162 double r = x_ring.r();
0163 double phi0 = x_ring.phi0(0);
0164 double zstart = x_ring.zstart();
0165 double dz = x_ring.dz(0);
0166 int nmodules = x_ring.nmodules();
0167 string m_nam = x_ring.moduleStr();
0168 Volume m_vol = modules[m_nam];
0169 double iphi = 2 * M_PI / nmodules;
0170 double dphi = dd4hep::getAttrOrDefault(x_ring, _Unicode(dphi), iphi);
0171 double phi = phi0;
0172 Placements& sensVols = sensitives[m_nam];
0173
0174 for (int k = 0; k < nmodules; ++k) {
0175 string m_base = _toString(l_id, "layer%d") + _toString(mod_num, "_module%d");
0176 double x = -r * std::cos(phi);
0177 double y = -r * std::sin(phi);
0178
0179 if (!reflect) {
0180 DetElement module(layer_element, m_base + "_pos", det_id);
0181 pv = layer_vol.placeVolume(m_vol, Transform3D(RotationZYX(0, -M_PI / 2 - phi, -M_PI / 2),
0182 Position(x, y, zstart + dz)));
0183 pv.addPhysVolID("barrel", 1).addPhysVolID("layer", l_id).addPhysVolID("module", mod_num);
0184 module.setPlacement(pv);
0185 module.setTypeFlag(sdet.typeFlag());
0186 for (size_t ic = 0; ic < sensVols.size(); ++ic) {
0187 PlacedVolume sens_pv = sensVols[ic];
0188 DetElement comp_elt(module, sens_pv.volume().name(), mod_num);
0189 comp_elt.setPlacement(sens_pv);
0190 comp_elt.setTypeFlag(sdet.typeFlag());
0191 }
0192 } else {
0193 pv = layer_vol.placeVolume(m_vol, Transform3D(RotationZYX(0, -M_PI / 2 - phi, -M_PI / 2),
0194 Position(x, y, -zstart - dz)));
0195 pv.addPhysVolID("barrel", 2).addPhysVolID("layer", l_id).addPhysVolID("module", mod_num);
0196 DetElement r_module(layer_element, m_base + "_neg", det_id);
0197 r_module.setPlacement(pv);
0198 r_module.setTypeFlag(sdet.typeFlag());
0199 for (size_t ic = 0; ic < sensVols.size(); ++ic) {
0200 PlacedVolume sens_pv = sensVols[ic];
0201 DetElement comp_elt(r_module, sens_pv.volume().name(), mod_num);
0202 comp_elt.setPlacement(sens_pv);
0203 comp_elt.setTypeFlag(sdet.typeFlag());
0204 }
0205 }
0206 dz = -dz;
0207 phi += dphi;
0208 ++mod_num;
0209 }
0210 }
0211 }
0212 Transform3D posAndRot(RotationZYX(rot.z(), rot.y(), rot.x()),
0213 Position(pos.x(), pos.y(), pos.z()));
0214 pv = motherVol.placeVolume(assembly, posAndRot);
0215 pv.addPhysVolID("system", det_id);
0216 sdet.setPlacement(pv);
0217 return sdet;
0218 }
0219
0220
0221 DECLARE_DETELEMENT(ip6_B0Preshower, create_B0Preshower)