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