File indexing completed on 2025-01-18 09:15:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include "DD4hep/DetFactoryHelper.h"
0017 #include "DD4hep/Printout.h"
0018 #include "DD4hep/Shapes.h"
0019 #include "DDRec/DetectorData.h"
0020 #include "DDRec/Surface.h"
0021 #include "XML/Layering.h"
0022 #include <array>
0023
0024 using namespace std;
0025 using namespace dd4hep;
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 static Ref_t create_BarrelBarDetectorWithSideFrame(Detector& description, xml_h e,
0036 SensitiveDetector sens) {
0037 typedef vector<PlacedVolume> Placements;
0038 xml_det_t x_det = e;
0039 Material air = description.air();
0040 int det_id = x_det.id();
0041 string det_name = x_det.nameStr();
0042 DetElement sdet(det_name, det_id);
0043 map<string, Volume> volumes;
0044 map<string, Placements> sensitives;
0045 map<string, std::vector<rec::VolPlane>> volplane_surfaces;
0046 PlacedVolume pv;
0047 dd4hep::xml::Dimension dimensions(x_det.dimensions());
0048 xml_dim_t dirc_pos = x_det.position();
0049
0050 map<string, std::array<double, 2>> module_thicknesses;
0051
0052 Tube topVolumeShape(dimensions.rmin(), dimensions.rmax(), dimensions.length() * 0.5);
0053 Volume assembly(det_name, topVolumeShape, air);
0054
0055 sens.setType("tracker");
0056
0057
0058 for (xml_coll_t mi(x_det, _U(module)); mi; ++mi) {
0059 xml_comp_t x_mod = mi;
0060 string m_nam = x_mod.nameStr();
0061
0062 if (volumes.find(m_nam) != volumes.end()) {
0063 printout(ERROR, "BarrelBarDetectorWithSideFrame",
0064 string((string("Module with named ") + m_nam + string(" already exists."))).c_str());
0065 throw runtime_error("Logics error in building modules.");
0066 }
0067
0068 int ncomponents = 0;
0069 double total_thickness = 0;
0070
0071
0072 xml_coll_t ci(x_mod, _U(module_component));
0073 for (ci.reset(), total_thickness = 0.0; ci; ++ci) {
0074 total_thickness += xml_comp_t(ci).thickness();
0075 }
0076
0077 Assembly m_vol(m_nam);
0078 volumes[m_nam] = m_vol;
0079 m_vol.setVisAttributes(description, x_mod.visStr());
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090 double frame_width = 0;
0091 if (x_mod.hasChild(_U(frame))) {
0092 xml_comp_t m_frame = x_mod.child(_U(frame));
0093 frame_width = m_frame.width();
0094 }
0095
0096 double thickness_so_far = 0.0;
0097 double thickness_sum = -total_thickness / 2.0;
0098 double max_component_width = 0;
0099 for (xml_coll_t mci(x_mod, _U(module_component)); mci; ++mci, ++ncomponents) {
0100 xml_comp_t x_comp = mci;
0101 string c_nam = _toString(ncomponents, "component%d");
0102
0103 double box_width = x_comp.width() - 2 * frame_width;
0104 max_component_width = fmax(max_component_width, box_width);
0105
0106 Box c_box{box_width / 2, x_comp.length() / 2, x_comp.thickness() / 2};
0107 Volume c_vol{c_nam, c_box, description.material(x_comp.materialStr())};
0108
0109 pv = m_vol.placeVolume(c_vol, Position(0, 0, thickness_sum + x_comp.thickness() / 2.0));
0110
0111 c_vol.setRegion(description, x_comp.regionStr());
0112 c_vol.setLimitSet(description, x_comp.limitsStr());
0113 c_vol.setVisAttributes(description, x_comp.visStr());
0114 if (x_comp.isSensitive()) {
0115 c_vol.setSensitiveDetector(sens);
0116 sensitives[m_nam].push_back(pv);
0117 module_thicknesses[m_nam] = {thickness_so_far + x_comp.thickness() / 2.0,
0118 total_thickness - thickness_so_far - x_comp.thickness() / 2.0};
0119
0120 rec::Vector3D u(0., 1., 0.);
0121 rec::Vector3D v(0., 0., 1.);
0122 rec::Vector3D n(1., 0., 0.);
0123
0124
0125
0126 double inner_thickness = module_thicknesses[m_nam][0];
0127 double outer_thickness = module_thicknesses[m_nam][1];
0128
0129 rec::SurfaceType type(rec::SurfaceType::Sensitive);
0130
0131 rec::VolPlane surf(c_vol, type, inner_thickness, outer_thickness, u, v, n);
0132 volplane_surfaces[m_nam].push_back(surf);
0133 }
0134 thickness_sum += x_comp.thickness();
0135 thickness_so_far += x_comp.thickness();
0136 }
0137
0138 if (x_mod.hasChild(_U(frame))) {
0139 xml_comp_t m_frame = x_mod.child(_U(frame));
0140 double frame_thickness = getAttrOrDefault<double>(m_frame, _U(thickness), total_thickness);
0141
0142 Box lframe_box{m_frame.width() / 2., m_frame.length() / 2., frame_thickness / 2.};
0143 Box rframe_box{m_frame.width() / 2., m_frame.length() / 2., frame_thickness / 2.};
0144
0145
0146
0147 Volume lframe_vol{"left_frame", lframe_box, description.material(m_frame.materialStr())};
0148 Volume rframe_vol{"right_frame", rframe_box, description.material(m_frame.materialStr())};
0149 lframe_vol.setVisAttributes(description, m_frame.visStr());
0150 rframe_vol.setVisAttributes(description, m_frame.visStr());
0151
0152 m_vol.placeVolume(lframe_vol, Position(frame_width / 2. + max_component_width / 2, 0.,
0153 frame_thickness / 2. - total_thickness / 2.0));
0154 m_vol.placeVolume(rframe_vol, Position(-frame_width / 2. - max_component_width / 2, 0.,
0155 frame_thickness / 2. - total_thickness / 2.0));
0156 }
0157 }
0158
0159
0160 for (xml_coll_t li(x_det, _U(layer)); li; ++li) {
0161 xml_comp_t x_layer = li;
0162 xml_comp_t x_barrel = x_layer.child(_U(barrel_envelope));
0163 xml_comp_t x_layout = x_layer.child(_U(rphi_layout));
0164 xml_comp_t z_layout = x_layer.child(_U(z_layout));
0165 int lay_id = x_layer.id();
0166 string m_nam = x_layer.moduleStr();
0167 string lay_nam = _toString(x_layer.id(), "layer%d");
0168 Tube lay_tub(x_barrel.inner_r(), x_barrel.outer_r(), x_barrel.z_length() / 2.0);
0169 Volume lay_vol(lay_nam, lay_tub, air);
0170 lay_vol.setVisAttributes(description, x_layer.visStr());
0171
0172 double phi0 = x_layout.phi0();
0173 double phi_tilt = x_layout.phi_tilt();
0174 double rc = x_layout.rc();
0175 int nphi = x_layout.nphi();
0176 double rphi_dr = x_layout.dr();
0177 double phi_incr = (M_PI * 2) / nphi;
0178 double phic = phi0;
0179 double z0 = z_layout.z0();
0180 double nz = z_layout.nz();
0181 double z_dr = z_layout.dr();
0182
0183 Volume module_env = volumes[m_nam];
0184 DetElement lay_elt(sdet, _toString(x_layer.id(), "layer%d"), lay_id);
0185 Placements& sensVols = sensitives[m_nam];
0186
0187
0188
0189
0190 double z_incr = nz > 1 ? (2.0 * z0) / (nz - 1) : 0.0;
0191
0192 double module_z = -z0;
0193 int module = 1;
0194
0195
0196 for (int ii = 0; ii < nphi; ii++) {
0197 double dx = z_dr * std::cos(phic + phi_tilt);
0198 double dy = z_dr * std::sin(phic + phi_tilt);
0199 double x = rc * std::cos(phic);
0200 double y = rc * std::sin(phic);
0201
0202
0203 for (int j = 0; j < nz; j++) {
0204 string module_name = _toString(module, "module%d");
0205 DetElement mod_elt(lay_elt, module_name, module);
0206
0207 Transform3D tr(RotationZYX(0, ((M_PI / 2) - phic - phi_tilt), -M_PI / 2),
0208 Position(x, y, module_z));
0209
0210 pv = lay_vol.placeVolume(module_env, tr);
0211 pv.addPhysVolID("module", module);
0212 pv.addPhysVolID("section", j);
0213 mod_elt.setPlacement(pv);
0214 for (size_t ic = 0; ic < sensVols.size(); ++ic) {
0215 PlacedVolume sens_pv = sensVols[ic];
0216 DetElement comp_de(mod_elt, std::string("de_") + sens_pv.volume().name(), module);
0217 comp_de.setPlacement(sens_pv);
0218 rec::volSurfaceList(comp_de)->push_back(volplane_surfaces[m_nam][ic]);
0219 }
0220
0221
0222 module++;
0223
0224 x += dx;
0225 y += dy;
0226
0227 dx *= -1;
0228 dy *= -1;
0229
0230 module_z += z_incr;
0231 }
0232 phic += phi_incr;
0233 rc += rphi_dr;
0234 rphi_dr *= -1;
0235 module_z = -z0;
0236 }
0237
0238 pv = assembly.placeVolume(lay_vol);
0239 pv.addPhysVolID("layer", lay_id);
0240 lay_elt.setAttributes(description, lay_vol, x_layer.regionStr(), x_layer.limitsStr(),
0241 x_layer.visStr());
0242 lay_elt.setPlacement(pv);
0243 }
0244 sdet.setAttributes(description, assembly, x_det.regionStr(), x_det.limitsStr(), x_det.visStr());
0245 assembly.setVisAttributes(description.invisible());
0246 pv = description.pickMotherVolume(sdet).placeVolume(assembly, Position(0, 0, dirc_pos.z()));
0247 pv.addPhysVolID("system", det_id);
0248 sdet.setPlacement(pv);
0249 return sdet;
0250 }
0251
0252
0253
0254 DECLARE_DETELEMENT(epic_BarrelBarDetectorWithSideFrame, create_BarrelBarDetectorWithSideFrame)
0255 DECLARE_DETELEMENT(epic_FakeDIRC, create_BarrelBarDetectorWithSideFrame)