Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-15 08:26:38

0001 // SPDX-License-Identifier: LGPL-3.0-or-later
0002 // Copyright (C) 2022 Whitney Armstrong
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 /*! B0 Preshower
0013  *
0014  * @author Whitney Armstrong
0015  *
0016  * This geometric element has been deprecated. ACTS tracking interface has also been removed. - Sakib Rahman (Dec 20, 2022)
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   // apply any detector type flags set in XML
0031   dd4hep::xml::setDetectorTypeFlag(x_det, sdet);
0032 
0033   // Material  air  = description.material("Air");
0034   //  Volume      assembly    (det_name,Box(10000,10000,10000),vacuum);
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       // build frame from trd (assumed to be smaller)
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       // make the frame match the total thickness if thickness attribute is not given
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       // figure out how to best place
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         // std::cout << " adding sensitive volume" << c_name << "\n";
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     // double      layer_rmin   = l_env.attr<double>(_Unicode(rmin));
0131     // double      layer_rmax   = l_env.attr<double>(_Unicode(rmax));
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     // printout(INFO,"ROOTGDMLParse","+++ Read geometry from GDML file file:%s",input.c_str());
0136     // std::cout << "SiTracker Endcap layer " << l_id << " zstart = " << layer_zstart/dd4hep::mm << "mm ( " <<
0137     // layer_length/dd4hep::mm << " mm thick )\n";
0138 
0139     Assembly layer_vol(layer_name);
0140     // assembly.placeVolume(layer_assembly);
0141     // Tube       layer_tub(layer_rmin, layer_rmax, layer_length / 2);
0142     // Volume     layer_vol(layer_name, layer_tub, air); // Create the layer envelope volume.
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()); // make sure type flags are propagated
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()); // make sure type flags are propagated
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 // clang-format off
0221 DECLARE_DETELEMENT(ip6_B0Preshower, create_B0Preshower)