Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:15:52

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