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