File indexing completed on 2024-06-17 07:06:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include "DD4hep/DetFactoryHelper.h"
0013 #include "DD4hep/Printout.h"
0014 #include "DD4hep/Shapes.h"
0015 #include "DD4hepDetectorHelper.h"
0016 #include "DDRec/DetectorData.h"
0017 #include "DDRec/Surface.h"
0018 #include "XML/Layering.h"
0019 #include "XML/Utilities.h"
0020 #include <array>
0021 #include <map>
0022
0023 using namespace std;
0024 using namespace dd4hep;
0025 using namespace dd4hep::rec;
0026 using namespace dd4hep::detail;
0027
0028 static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
0029 xml_det_t x_det = e;
0030 int det_id = x_det.id();
0031 std::string det_name = x_det.nameStr();
0032 DetElement sdet(det_name, det_id);
0033 Material air = description.material("Air");
0034 Material carbon = description.material("CarbonFiber");
0035 PlacedVolume pv;
0036
0037 map<string, std::array<double, 2>> module_thicknesses;
0038
0039
0040 dd4hep::xml::setDetectorTypeFlag(x_det, sdet);
0041 auto& params = DD4hepDetectorHelper::ensureExtension<dd4hep::rec::VariantParameters>(sdet);
0042
0043 for (xml_coll_t bmat(x_det, _Unicode(boundary_material)); bmat; ++bmat) {
0044 xml_comp_t x_boundary_material = bmat;
0045 DD4hepDetectorHelper::xmlToProtoSurfaceMaterial(x_boundary_material, params,
0046 "boundary_material");
0047 }
0048
0049 Assembly assembly(det_name);
0050 assembly.setVisAttributes(description.invisible());
0051 sens.setType("tracker");
0052
0053 float zPos = 0;
0054
0055 xml_comp_t x_layer = x_det.child(_Unicode(layer));
0056 xml_comp_t envelope = x_layer.child(_Unicode(envelope), false);
0057 int lay_id = x_layer.id();
0058 string l_nam = x_layer.moduleStr();
0059 string lay_nam = det_name + _toString(x_layer.id(), "_layer%d");
0060 Tube lay_tub(envelope.rmin(), envelope.rmax(), envelope.length() / 2.0);
0061 Volume lay_vol(lay_nam, lay_tub, air);
0062 zPos = envelope.zstart();
0063 Position lay_pos(0, 0, 0);
0064 lay_vol.setVisAttributes(description.visAttributes(x_layer.visStr()));
0065
0066 DetElement lay_elt(sdet, lay_nam, lay_id);
0067
0068
0069
0070 auto& layerParams =
0071 DD4hepDetectorHelper::ensureExtension<dd4hep::rec::VariantParameters>(lay_elt);
0072
0073 for (xml_coll_t lmat(x_layer, _Unicode(layer_material)); lmat; ++lmat) {
0074 xml_comp_t x_layer_material = lmat;
0075 DD4hepDetectorHelper::xmlToProtoSurfaceMaterial(x_layer_material, layerParams,
0076 "layer_material");
0077 }
0078
0079
0080 xml_comp_t x_modsz = x_det.child(_Unicode(modsize));
0081
0082 double module_x = x_modsz.length();
0083 double module_y = x_modsz.width();
0084 double module_overlap = getAttrOrDefault(x_modsz, _Unicode(overlap), 0.);
0085 double module_spacing = getAttrOrDefault(x_modsz, _Unicode(spacing), 0.);
0086
0087
0088 xml_comp_t x_supp = x_det.child(_Unicode(support));
0089 xml_comp_t x_supp_envelope = x_supp.child(_Unicode(envelope), false);
0090
0091 double total_thickness = 0;
0092 xml_comp_t x_modFront = x_det.child(_Unicode(moduleFront));
0093 xml_comp_t x_modBack = x_det.child(_Unicode(moduleBack));
0094
0095
0096 xml_coll_t ci(x_modFront, _U(module_component));
0097 for (ci.reset(), total_thickness = 0.0; ci; ++ci) {
0098 total_thickness += xml_comp_t(ci).thickness();
0099 }
0100
0101 int module = 0;
0102 int nx = 25;
0103 int ny = 15;
0104 for (int ix = 0; ix < 2 * nx; ix++) {
0105 float xcoord = (ix - nx) * (module_x + module_spacing);
0106 for (int iy = 0; iy < 2 * ny; iy++) {
0107 float ycoord = (iy - ny) * (module_y - module_overlap);
0108
0109 xml_comp_t x_modCurr = iy % 2 == 0 ? x_modFront : x_modBack;
0110
0111 double module_z = x_supp_envelope.length() / 2.0 + total_thickness / 2;
0112 if (iy % 2 == 0) {
0113 module_z *= -1;
0114 }
0115 float corner_x1 = xcoord + module_x / 2;
0116 float corner_x2 = xcoord - module_x / 2;
0117 float corner_y1 = ycoord + module_y / 2;
0118 float corner_y2 = ycoord - module_y / 2;
0119 float maxRadius =
0120 std::max(std::max(std::hypot(corner_x1, corner_y1), std::hypot(corner_x2, corner_y2)),
0121 std::max(std::hypot(corner_x1, corner_y2), std::hypot(corner_x2, corner_y1)));
0122 float minRadius =
0123 std::min(std::min(std::hypot(corner_x1, corner_y1), std::hypot(corner_x2, corner_y2)),
0124 std::min(std::hypot(corner_x1, corner_y2), std::hypot(corner_x2, corner_y1)));
0125 if (maxRadius > envelope.rmax() || minRadius < envelope.rmin()) {
0126 continue;
0127 }
0128
0129 string module_name = Form("module%d_%d_%d", module, ix, iy);
0130 DetElement mod_elt(lay_elt, module_name, module);
0131
0132
0133 string m_nam = Form("EndcapTOF_Module1_%d_%d", ix, iy);
0134
0135 int ncomponents = 0;
0136
0137 Assembly m_vol(m_nam);
0138 m_vol.setVisAttributes(description.visAttributes(x_modCurr.visStr()));
0139
0140 double thickness_so_far = 0.0;
0141 double thickness_sum = -total_thickness / 2.0;
0142 double thickness_carbonsupp = 0.0;
0143 for (xml_coll_t mci(x_modCurr, _U(module_component)); mci; ++mci, ++ncomponents) {
0144 xml_comp_t x_comp = mci;
0145 xml_comp_t x_pos = x_comp.position(false);
0146 xml_comp_t x_rot = x_comp.rotation(false);
0147 const string c_nam = Form("component_%d_%d", ix, iy);
0148 Box c_box(x_comp.width() / 2, x_comp.length() / 2, x_comp.thickness() / 2);
0149 Volume c_vol(c_nam, c_box, description.material(x_comp.materialStr()));
0150 if (x_comp.materialStr() == "CarbonFiber") {
0151 thickness_carbonsupp = x_comp.thickness();
0152 }
0153
0154 const double zoff = thickness_sum + x_comp.thickness() / 2.0;
0155 if (x_pos && x_rot) {
0156 Position c_pos(x_pos.x(0), x_pos.y(0), x_pos.z(0) + zoff);
0157 RotationZYX c_rot(x_rot.z(0), x_rot.y(0), x_rot.x(0));
0158 pv = m_vol.placeVolume(c_vol, Transform3D(c_rot, c_pos));
0159 } else if (x_rot) {
0160 Position c_pos(0, 0, zoff);
0161 pv = m_vol.placeVolume(
0162 c_vol, Transform3D(RotationZYX(x_rot.z(0), x_rot.y(0), x_rot.x(0)), c_pos));
0163 } else if (x_pos) {
0164 pv = m_vol.placeVolume(c_vol, Position(x_pos.x(0), x_pos.y(0), x_pos.z(0) + zoff));
0165 } else {
0166 pv = m_vol.placeVolume(c_vol, Position(0, 0, zoff));
0167 }
0168 c_vol.setRegion(description, x_comp.regionStr());
0169 c_vol.setLimitSet(description, x_comp.limitsStr());
0170 c_vol.setVisAttributes(description, x_comp.visStr());
0171 if (x_comp.isSensitive()) {
0172 pv.addPhysVolID("idx", ix);
0173 pv.addPhysVolID("idy", iy);
0174 c_vol.setSensitiveDetector(sens);
0175 module_thicknesses[m_nam] = {thickness_so_far + x_comp.thickness() / 2.0,
0176 total_thickness - thickness_so_far -
0177 x_comp.thickness() / 2.0};
0178
0179
0180 Vector3D u(-1., 0., 0.);
0181 Vector3D v(0., -1., 0.);
0182 Vector3D n(0., 0., 1.);
0183
0184
0185
0186 double inner_thickness = module_thicknesses[m_nam][0];
0187 double outer_thickness = module_thicknesses[m_nam][1];
0188
0189 SurfaceType type(SurfaceType::Sensitive);
0190
0191 VolPlane surf(c_vol, type, inner_thickness, outer_thickness, u, v, n);
0192
0193 DetElement comp_de(mod_elt, std::string("de_") + pv.volume().name(), module);
0194 comp_de.setPlacement(pv);
0195
0196 auto& comp_de_params =
0197 DD4hepDetectorHelper::ensureExtension<dd4hep::rec::VariantParameters>(comp_de);
0198 comp_de_params.set<string>("axis_definitions", "XYZ");
0199 volSurfaceList(comp_de)->push_back(surf);
0200
0201
0202 }
0203 thickness_sum += x_comp.thickness();
0204 thickness_so_far += x_comp.thickness();
0205
0206 if (x_pos) {
0207 thickness_sum += x_pos.z(0);
0208 thickness_so_far += x_pos.z(0);
0209 }
0210 }
0211
0212 const string suppb_nam =
0213 Form("suppbar_%d_%d", ix, iy);
0214 Box suppb_box((module_x + module_spacing) / 2, thickness_carbonsupp / 2,
0215 x_supp_envelope.length() / 2);
0216 Volume suppb_vol(suppb_nam, suppb_box, carbon);
0217 Transform3D trsupp(RotationZYX(0, 0, 0),
0218 Position(xcoord, ycoord + module_y / 2 - module_overlap / 2, 0));
0219 suppb_vol.setVisAttributes(description, "AnlGray");
0220
0221 pv = lay_vol.placeVolume(suppb_vol, trsupp);
0222
0223
0224 Transform3D tr(RotationZYX(M_PI / 2, 0, 0), Position(xcoord, ycoord, module_z));
0225
0226 pv = lay_vol.placeVolume(m_vol, tr);
0227 pv.addPhysVolID("module", module);
0228 mod_elt.setPlacement(pv);
0229 }
0230 }
0231
0232
0233 pv = assembly.placeVolume(lay_vol, lay_pos);
0234 pv.addPhysVolID("layer", lay_id);
0235 lay_elt.setAttributes(description, lay_vol, x_layer.regionStr(), x_layer.limitsStr(),
0236 x_layer.visStr());
0237 lay_elt.setPlacement(pv);
0238
0239 pv = description.pickMotherVolume(sdet).placeVolume(assembly, Position(0, 0, zPos));
0240 pv.addPhysVolID("system", det_id);
0241 sdet.setPlacement(pv);
0242
0243 return sdet;
0244 }
0245
0246
0247
0248 DECLARE_DETELEMENT(epic_TOFEndcap, create_detector)