Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // SPDX-License-Identifier: LGPL-3.0-or-later
0002 // Copyright (C) 2022 Whitney Armstrong
0003 
0004 #include "DD4hep/DetFactoryHelper.h"
0005 #include "XML/Layering.h"
0006 #include "XML/Utilities.h"
0007 #include <map>
0008 
0009 using namespace std;
0010 using namespace dd4hep;
0011 using namespace dd4hep::detail;
0012 
0013 /**  Forward off-momentum tracker.
0014  *
0015  *
0016  * \ingroup tracking
0017  *
0018  * @author Whitney Armstrong
0019  */
0020 static Ref_t create_OffMomentumTracker(Detector& description, xml_h e, SensitiveDetector sens) {
0021   typedef vector<PlacedVolume> Placements;
0022   xml_det_t x_det = e;
0023   Material vacuum = description.vacuum();
0024   int det_id      = x_det.id();
0025   string det_name = x_det.nameStr();
0026   DetElement sdet(det_name, det_id);
0027   Assembly assembly(det_name);
0028   xml::Component pos = x_det.position();
0029   xml::Component rot = x_det.rotation();
0030 
0031   // Material  air  = description.material("Air");
0032   //  Volume      assembly    (det_name,Box(10000,10000,10000),vacuum);
0033   Volume motherVol = description.pickMotherVolume(sdet);
0034   int m_id = 0, c_id = 0, n_sensor = 0;
0035   map<string, Volume> modules;
0036   map<string, Placements> sensitives;
0037   PlacedVolume pv;
0038 
0039   assembly.setVisAttributes(description.invisible());
0040   sens.setType("tracker");
0041 
0042   for (xml_coll_t su(x_det, _U(support)); su; ++su) {
0043     xml_comp_t x_support     = su;
0044     double support_thickness = getAttrOrDefault<double>(x_support, _U(thickness), 2.0 * mm);
0045     double support_length    = getAttrOrDefault<double>(x_support, _U(length), 2.0 * mm);
0046     double support_rmin      = getAttrOrDefault<double>(x_support, _U(rmin), 2.0 * mm);
0047     double support_zstart    = getAttrOrDefault<double>(x_support, _U(zstart), 2.0 * mm);
0048     std::string support_name =
0049         getAttrOrDefault<std::string>(x_support, _Unicode(name), "support_tube");
0050     std::string support_vis = getAttrOrDefault<std::string>(x_support, _Unicode(vis), "AnlRed");
0051     xml_dim_t support_pos(x_support.child(_U(position), false));
0052     xml_dim_t support_rot(x_support.child(_U(rotation), false));
0053     Solid support_solid;
0054     if (x_support.hasChild(_U(shape))) {
0055       xml_comp_t shape(x_support.child(_U(shape)));
0056       string shape_type = shape.typeStr();
0057       support_solid     = xml::createShape(description, shape_type, shape);
0058     } else {
0059       support_solid = Tube(support_rmin, support_rmin + support_thickness, support_length / 2);
0060     }
0061     Transform3D tr =
0062         Transform3D(Rotation3D(), Position(0, 0, (support_zstart + support_length / 2)));
0063     if (support_pos.ptr() && support_rot.ptr()) {
0064       Rotation3D rot3D(RotationZYX(support_rot.z(0), support_rot.y(0), support_rot.x(0)));
0065       Position pos3D(support_pos.x(0), support_pos.y(0), support_pos.z(0));
0066       tr = Transform3D(rot3D, pos3D);
0067     } else if (support_pos.ptr()) {
0068       tr =
0069           Transform3D(Rotation3D(), Position(support_pos.x(0), support_pos.y(0), support_pos.z(0)));
0070     } else if (support_rot.ptr()) {
0071       Rotation3D rot3D(RotationZYX(support_rot.z(0), support_rot.y(0), support_rot.x(0)));
0072       tr = Transform3D(rot3D, Position());
0073     }
0074     Material support_mat = description.material(x_support.materialStr());
0075     Volume support_vol(support_name, support_solid, support_mat);
0076     support_vol.setVisAttributes(description.visAttributes(support_vis));
0077     pv = assembly.placeVolume(support_vol, tr);
0078     // pv = assembly.placeVolume(support_vol, Position(0, 0, support_zstart + support_length / 2));
0079   }
0080 
0081   for (xml_coll_t mi(x_det, _U(module)); mi; ++mi, ++m_id) {
0082     xml_comp_t x_mod = mi;
0083     string m_nam     = x_mod.nameStr();
0084     xml_comp_t x_box = x_mod.shape();
0085 
0086     double x1 = x_box.x();
0087     double y1 = x_box.y();
0088     // double     z1              = x_box.z();
0089     double total_thickness = 0.;
0090 
0091     xml_coll_t ci(x_mod, _U(module_component));
0092     for (ci.reset(), total_thickness = 0.0; ci; ++ci) {
0093       total_thickness += xml_comp_t(ci).thickness();
0094     }
0095 
0096     Box m_solid(x1 / 2.0, y1 / 2.0, total_thickness / 2.0);
0097     Volume m_volume(m_nam, m_solid, vacuum);
0098     m_volume.setVisAttributes(description.visAttributes(x_mod.visStr()));
0099 
0100     // Solid  frame_s;
0101     if (x_mod.hasChild(_U(frame))) {
0102       // todo
0103       // build frame from trd (assumed to be smaller)
0104       // xml_comp_t m_frame         = x_mod.child(_U(frame));
0105       // xml_comp_t f_pos           = m_frame.child(_U(position));
0106       // xml_comp_t frame_trd       = m_frame.trd();
0107       // double     frame_thickness = getAttrOrDefault(m_frame, _U(thickness), total_thickness);
0108       // double     frame_x1        = frame_trd.x1();
0109       // double     frame_x2        = frame_trd.x2();
0110       // double     frame_z         = frame_trd.z();
0111       //// make the frame match the total thickness if thickness attribute is not given
0112       // Trapezoid        f_solid1(x1, x2,frame_thickness / 2.0, frame_thickness / 2.0, z);
0113       // Trapezoid        f_solid(frame_x1, frame_x2, frame_thickness / 2.0, frame_thickness / 2.0, frame_z) ;
0114       // SubtractionSolid frame_shape(f_solid1, f_solid);
0115       // frame_s = frame_shape;
0116 
0117       // Material f_mat  = description.material(m_frame.materialStr());
0118       // Volume f_vol(m_nam + "_frame", frame_shape, f_mat);
0119       // f_vol.setVisAttributes(description.visAttributes(m_frame.visStr()));
0120 
0121       //// figure out how to best place
0122       // pv = m_volume.placeVolume(f_vol, Position(f_pos.x(), f_pos.y(),  f_pos.z()));
0123     }
0124 
0125     double posZ = -total_thickness / 2.0;
0126     for (ci.reset(), n_sensor = 1, c_id = 0, posZ = -total_thickness / 2.0; ci; ++ci, ++c_id) {
0127       xml_comp_t c   = ci;
0128       double c_thick = c.thickness();
0129       auto comp_x    = getAttrOrDefault(c, _Unicode(x), x1);
0130       auto comp_y    = getAttrOrDefault(c, _Unicode(y), y1);
0131 
0132       Material c_mat = description.material(c.materialStr());
0133       string c_name  = _toString(c_id, "OMD_component%d");
0134 
0135       Box comp_s1(comp_x / 2.0, comp_y / 2.0, c_thick / 2e0);
0136       Solid comp_shape = comp_s1;
0137       // if(frame_s.isValid()) {
0138       //   comp_shape = SubtractionSolid( comp_s1, frame_s);
0139       // }
0140       Volume c_vol(c_name, comp_shape, c_mat);
0141 
0142       c_vol.setVisAttributes(description.visAttributes(c.visStr()));
0143       pv = m_volume.placeVolume(c_vol, Position(0, 0, posZ + c_thick / 2.0));
0144       if (c.isSensitive()) {
0145         // std::cout << " adding sensitive volume" << c_name << "\n";
0146         sdet.check(n_sensor > 2,
0147                    "SiTrackerEndcap2::fromCompact: " + c_name + " Max of 2 modules allowed!");
0148         pv.addPhysVolID("slice", n_sensor);
0149         sens.setType("tracker");
0150         c_vol.setSensitiveDetector(sens);
0151         sensitives[m_nam].push_back(pv);
0152         ++n_sensor;
0153       }
0154       posZ += c_thick;
0155     }
0156     modules[m_nam] = m_volume;
0157   }
0158 
0159   for (xml_coll_t li(x_det, _U(layer)); li; ++li) {
0160     xml_comp_t x_layer(li);
0161     int l_id    = x_layer.id();
0162     int mod_num = 1;
0163 
0164     xml_comp_t l_env  = x_layer.child(_U(envelope));
0165     string layer_name = det_name + std::string("_layer") + std::to_string(l_id);
0166 
0167     std::string layer_vis = l_env.attr<std::string>(_Unicode(vis));
0168     // double      layer_x  = l_env.attr<double>(_Unicode(x));
0169     // double      layer_y   = l_env.attr<double>(_Unicode(y));
0170     double layer_length   = l_env.attr<double>(_Unicode(length));
0171     double layer_zstart   = l_env.attr<double>(_Unicode(zstart));
0172     double layer_center_z = layer_zstart + layer_length / 2.0;
0173     // printout(INFO,"ROOTGDMLParse","+++ Read geometry from GDML file file:%s",input.c_str());
0174     // std::cout << "SiTracker Endcap layer " << l_id << " zstart = " << layer_zstart/dd4hep::mm << "mm ( " <<
0175     // layer_length/dd4hep::mm << " mm thick )\n";
0176 
0177     Assembly layer_vol(layer_name);
0178     // assembly.placeVolume(layer_assembly);
0179     // Tube       layer_tub(layer_rmin, layer_rmax, layer_length / 2);
0180     // Volume     layer_vol(layer_name, layer_tub, air); // Create the layer envelope volume.
0181     layer_vol.setVisAttributes(description.visAttributes(layer_vis));
0182 
0183     PlacedVolume layer_pv;
0184     // if (reflect) {
0185     //   layer_pv =
0186     //       assembly.placeVolume(layer_vol, Transform3D(RotationZYX(0.0, -M_PI, 0.0), Position(0, 0,
0187     //       -layer_center_z)));
0188     //   layer_pv.addPhysVolID("barrel", 3).addPhysVolID("layer", l_id);
0189     //   layer_name += "_N";
0190     // } else {
0191     layer_pv = assembly.placeVolume(layer_vol, Position(0, 0, layer_center_z));
0192     layer_pv.addPhysVolID("layer", l_id);
0193     //}
0194     DetElement layer_element(sdet, layer_name, l_id);
0195     layer_element.setPlacement(layer_pv);
0196 
0197     string m_nam         = x_layer.moduleStr();
0198     Volume m_vol         = modules[m_nam];
0199     Placements& sensVols = sensitives[m_nam];
0200 
0201     DetElement module(layer_element, "module_", l_id);
0202     pv = layer_vol.placeVolume(m_vol, Position(0, 0, 0));
0203     pv.addPhysVolID("layer", l_id).addPhysVolID("module", mod_num);
0204     module.setPlacement(pv);
0205     for (size_t ic = 0; ic < sensVols.size(); ++ic) {
0206       PlacedVolume sens_pv = sensVols[ic];
0207       DetElement comp_elt(module, sens_pv.volume().name(), mod_num);
0208       comp_elt.setPlacement(sens_pv);
0209     }
0210 
0211     // for (xml_coll_t ri(x_layer, _U(ring)); ri; ++ri) {
0212     //  xml_comp_t  x_ring   = ri;
0213     //  double      r        = x_ring.r();
0214     //  double      phi0     = x_ring.phi0(0);
0215     //  double      zstart   = x_ring.zstart();
0216     //  double      dz       = x_ring.dz(0);
0217     //  int         nmodules = x_ring.nmodules();
0218     //  string      m_nam    = x_ring.moduleStr();
0219     //  Volume      m_vol    = modules[m_nam];
0220     //  double      iphi     = 2 * M_PI / nmodules;
0221     //  double      dphi     = dd4hep::getAttrOrDefault(x_ring,_Unicode(dphi),iphi);
0222     //  double      phi      = phi0;
0223     //  Placements& sensVols = sensitives[m_nam];
0224 
0225     //  for (int k = 0; k < nmodules; ++k) {
0226     //    string     m_base = _toString(l_id, "layer%d") + _toString(mod_num, "_module%d");
0227     //    double     x      = -r * std::cos(phi);
0228     //    double     y      = -r * std::sin(phi);
0229 
0230     //    //if (!reflect) {
0231     //      DetElement module(layer_element, m_base + "_pos", det_id);
0232     //      pv = layer_vol.placeVolume(
0233     //          m_vol, Transform3D(RotationZYX(0, -M_PI / 2 - phi, -M_PI / 2), Position(x, y, zstart + dz)));
0234     //      pv.addPhysVolID("layer", l_id).addPhysVolID("module", mod_num);
0235     //      module.setPlacement(pv);
0236     //      for (size_t ic = 0; ic < sensVols.size(); ++ic) {
0237     //        PlacedVolume sens_pv = sensVols[ic];
0238     //        DetElement   comp_elt(module, sens_pv.volume().name(), mod_num);
0239     //        comp_elt.setPlacement(sens_pv);
0240     //    //std::cout << " adding ACTS extension" << "\n";
0241     //        Acts::ActsExtension* moduleExtension = new Acts::ActsExtension();
0242     //        comp_elt.addExtension<Acts::ActsExtension>(moduleExtension);
0243     //      }
0244     //    //} else {
0245     //    //  pv = layer_vol.placeVolume(
0246     //    //      m_vol, Transform3D(RotationZYX(0, -M_PI / 2 - phi, -M_PI / 2), Position(x, y, -zstart - dz)));
0247     //    //  pv.addPhysVolID("barrel", 2).addPhysVolID("layer", l_id).addPhysVolID("module", mod_num);
0248     //    //  DetElement r_module(layer_element, m_base + "_neg", det_id);
0249     //    //  r_module.setPlacement(pv);
0250     //    //  for (size_t ic = 0; ic < sensVols.size(); ++ic) {
0251     //    //    PlacedVolume sens_pv = sensVols[ic];
0252     //    //    DetElement   comp_elt(r_module, sens_pv.volume().name(), mod_num);
0253     //    //    comp_elt.setPlacement(sens_pv);
0254     //    ////std::cout << " adding ACTS extension" << "\n";
0255     //    //    Acts::ActsExtension* moduleExtension = new Acts::ActsExtension("XZY");
0256     //    //    comp_elt.addExtension<Acts::ActsExtension>(moduleExtension);
0257     //    //  }
0258     //    //}
0259     //    dz = -dz;
0260     //    phi += dphi;
0261     //    ++mod_num;
0262     //  }
0263     //}
0264     ++mod_num;
0265   }
0266   Transform3D posAndRot(RotationZYX(rot.z(), rot.y(), rot.x()),
0267                         Position(pos.x(), pos.y(), pos.z()));
0268   pv = motherVol.placeVolume(assembly, posAndRot);
0269   pv.addPhysVolID("system", det_id);
0270   sdet.setPlacement(pv);
0271   return sdet;
0272 }
0273 
0274 // clang-format off
0275 DECLARE_DETELEMENT(ip6_OffMomentumTracker, create_OffMomentumTracker)