Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-09-27 07:02:33

0001 //==========================================================================
0002 // Specialized generic detector constructor
0003 //==========================================================================
0004 
0005 #include "DD4hep/DetFactoryHelper.h"
0006 #include "DD4hep/Printout.h"
0007 
0008 #if defined(USE_ACTSDD4HEP)
0009 #include "ActsDD4hep/ActsExtension.hpp"
0010 #include "ActsDD4hep/ConvertMaterial.hpp"
0011 #else
0012 #include "Acts/Plugins/DD4hep/ActsExtension.hpp"
0013 #include "Acts/Plugins/DD4hep/ConvertDD4hepMaterial.hpp"
0014 #endif
0015 
0016 using namespace std;
0017 using namespace dd4hep;
0018 using namespace dd4hep::detail;
0019 
0020 /** A barrel tracker with a module that is curved (not flat).
0021  *
0022  * \ingroup tracking
0023  */
0024 static Ref_t CylinderTrackerBarrel_create_detector(Detector& description, xml_h e, SensitiveDetector sens)
0025 {
0026   typedef vector<PlacedVolume> Placements;
0027   xml_det_t                    x_det = e;
0028   Material                     air   = description.air();
0029 
0030   int        det_id   = x_det.id();
0031   string     det_name = x_det.nameStr();
0032   DetElement sdet(det_name, det_id);
0033 
0034   //Acts::ActsExtension* barrelExtension = new Acts::ActsExtension();
0035   //barrelExtension->addType("barrel", "detector");
0036   //sdet.addExtension<Acts::ActsExtension>(barrelExtension);
0037 
0038   Assembly                assembly(det_name);
0039   map<string, Volume>     mod_volumes;
0040   map<string, Placements> sensitives;
0041   PlacedVolume            pv;
0042 
0043   sens.setType("tracker");
0044   int n_modules = 0;
0045   for (xml_coll_t mi(x_det, _U(module)); mi; ++mi) {
0046     n_modules++;
0047     xml_comp_t x_mod = mi;
0048     xml_comp_t m_env = x_mod.child(_U(module_envelope));
0049     string     m_nam = x_mod.nameStr();
0050 
0051     Assembly module_assembly(_toString(n_modules, "mod_assembly_%d"));
0052     auto     module_rmin      = m_env.rmin();
0053     auto     module_thickness = m_env.thickness();
0054     auto     module_length    = m_env.length();
0055     auto     module_phi       = getAttrOrDefault(m_env, _Unicode(phi), 90.0);
0056 
0057     Volume m_vol(
0058         m_nam,
0059         Tube(module_rmin, module_rmin + module_thickness, module_length / 2, -module_phi / 2.0, module_phi / 2.0), air);
0060     int    ncomponents = 0, sensor_number = 1;
0061     module_assembly.placeVolume(m_vol, Position(-module_rmin, 0, 0));
0062     mod_volumes[m_nam] = module_assembly;
0063     m_vol.setVisAttributes(description.visAttributes(x_mod.visStr()));
0064 
0065     auto comp_rmin = module_rmin;
0066     for (xml_coll_t ci(x_mod, _U(module_component)); ci; ++ci, ++ncomponents) {
0067       xml_comp_t x_comp = ci;
0068       xml_comp_t x_pos  = x_comp.position(false);
0069       xml_comp_t x_rot  = x_comp.rotation(false);
0070       string     c_nam  = _toString(ncomponents, "component%d");
0071 
0072       auto comp_thickness = x_comp.thickness();
0073       comp_rmin           = getAttrOrDefault(x_comp, _Unicode(rmin), comp_rmin);
0074       auto comp_phi       = getAttrOrDefault(x_comp, _Unicode(phi), module_phi);
0075       auto comp_phi0      = getAttrOrDefault(x_comp, _Unicode(phi0), 0.0);
0076       auto comp_length    = getAttrOrDefault(x_comp, _Unicode(length), module_length);
0077 
0078       Tube         c_tube(comp_rmin, comp_rmin + comp_thickness, comp_length / 2, -comp_phi / 2.0 + comp_phi0,
0079                   comp_phi / 2.0 + comp_phi0);
0080       Volume       c_vol(c_nam, c_tube, description.material(x_comp.materialStr()));
0081       PlacedVolume c_pv;
0082 
0083       if (x_pos && x_rot) {
0084         Position    c_pos(x_pos.x(0), x_pos.y(0), x_pos.z(0));
0085         RotationZYX c_rot(x_rot.z(0), x_rot.y(0), x_rot.x(0));
0086         c_pv = m_vol.placeVolume(c_vol, Transform3D(c_rot, c_pos));
0087       } else if (x_rot) {
0088         c_pv = m_vol.placeVolume(c_vol, RotationZYX(x_rot.z(0), x_rot.y(0), x_rot.x(0)));
0089       } else if (x_pos) {
0090         c_pv = m_vol.placeVolume(c_vol, Position(x_pos.x(0), x_pos.y(0), x_pos.z(0)));
0091       } else {
0092         c_pv = m_vol.placeVolume(c_vol);
0093       }
0094       c_vol.setRegion(description, x_comp.regionStr());
0095       c_vol.setLimitSet(description, x_comp.limitsStr());
0096       c_vol.setVisAttributes(description, x_comp.visStr());
0097       if (x_comp.isSensitive()) {
0098         c_pv.addPhysVolID(_U(sensor), sensor_number++);
0099         c_vol.setSensitiveDetector(sens);
0100         sensitives[m_nam].push_back(c_pv);
0101       }
0102       comp_rmin = comp_rmin + comp_thickness;
0103     }
0104   }
0105   for (xml_coll_t li(x_det, _U(layer)); li; ++li) {
0106     xml_comp_t x_layer  = li;
0107     xml_comp_t x_barrel = x_layer.child(_U(barrel_envelope));
0108     xml_comp_t x_layout = x_layer.child(_U(rphi_layout));
0109     xml_comp_t z_layout = x_layer.child(_U(z_layout)); // Get the <z_layout> element.
0110     int        lay_id   = x_layer.id();
0111     string     m_nam    = x_layer.moduleStr();
0112     string     lay_nam  = _toString(x_layer.id(), "layer%d");
0113     Tube       lay_tub(x_barrel.inner_r(), x_barrel.outer_r(), x_barrel.z_length() / 2);
0114     Volume     lay_vol(lay_nam, lay_tub, air); // Create the layer envelope volume.
0115     lay_vol.setVisAttributes(description.visAttributes(x_layer.visStr()));
0116     double     phi0     = x_layout.phi0();     // Starting phi of first module.
0117     double     phi_tilt = x_layout.phi_tilt(); // Phi tilt of a module.
0118     double     rc       = x_layout.rc();       // Radius of the module center.
0119     int        nphi     = x_layout.nphi();     // Number of modules in phi.
0120     double     rphi_dr  = x_layout.dr();       // The delta radius of every other module.
0121     double     phi_incr = (M_PI * 2) / nphi;   // Phi increment for one module.
0122     double     phic     = phi0;                // Phi of the module center.
0123     double     z0       = z_layout.z0();       // Z position of first module in phi.
0124     double     nz       = z_layout.nz();       // Number of modules to place in z.
0125     double     z_dr     = z_layout.dr();       // Radial displacement parameter, of every other module.
0126     Volume     m_env    = mod_volumes[m_nam];
0127     DetElement lay_elt(sdet, _toString(x_layer.id(), "layer%d"), lay_id);
0128 
0129     ///Acts::ActsExtension* layerExtension = new Acts::ActsExtension();
0130     ///layerExtension->addType("sensitive cylinder", "layer");
0131     /////// layerExtension->addValue(10. * Acts::UnitConstants::mm, "r", "envelope");
0132     ///lay_elt.addExtension<Acts::ActsExtension>(layerExtension);
0133 
0134     Placements& sensVols = sensitives[m_nam];
0135 
0136     // Z increment for module placement along Z axis.
0137     // Adjust for z0 at center of module rather than
0138     // the end of cylindrical envelope.
0139     double z_incr = nz > 1 ? (2.0 * z0) / (nz - 1) : 0.0;
0140     // Starting z for module placement along Z axis.
0141     double module_z = -z0;
0142     int    module   = 1;
0143 
0144     // Loop over the number of modules in phi.
0145     for (int ii = 0; ii < nphi; ii++) {
0146       double dx = z_dr * std::cos(phic + phi_tilt); // Delta x of module position.
0147       double dy = z_dr * std::sin(phic + phi_tilt); // Delta y of module position.
0148       double x  = rc * std::cos(phic);              // Basic x module position.
0149       double y  = rc * std::sin(phic);              // Basic y module position.
0150 
0151       // Loop over the number of modules in z.
0152       for (int j = 0; j < nz; j++) {
0153         string     module_name = _toString(module, "module%d");
0154         DetElement mod_elt(lay_elt, module_name, module);
0155         // Module PhysicalVolume.
0156         //         Transform3D
0157         //         tr(RotationZYX(0,-((M_PI/2)-phic-phi_tilt),M_PI/2),Position(x,y,module_z));
0158         // NOTE (Nikiforos, 26/08 Rotations needed to be fixed so that component1 (silicon) is on the
0159         // outside
0160         Transform3D tr(RotationZYX(phic - phi_tilt, 0, 0), Position(x, y, module_z));
0161 
0162         pv = lay_vol.placeVolume(m_env, tr);
0163         pv.addPhysVolID("module", module);
0164         mod_elt.setPlacement(pv);
0165         for (size_t ic = 0; ic < sensVols.size(); ++ic) {
0166           PlacedVolume sens_pv = sensVols[ic];
0167           DetElement   comp_elt(mod_elt, sens_pv.volume().name(), module);
0168           comp_elt.setPlacement(sens_pv);
0169           //Acts::ActsExtension* moduleExtension = new Acts::ActsExtension();
0170           //comp_elt.addExtension<Acts::ActsExtension>(moduleExtension);
0171         }
0172 
0173         /// Increase counters etc.
0174         module++;
0175         // Adjust the x and y coordinates of the module.
0176         x += dx;
0177         y += dy;
0178         // Flip sign of x and y adjustments.
0179         dx *= -1;
0180         dy *= -1;
0181         // Add z increment to get next z placement pos.
0182         module_z += z_incr;
0183       }
0184       phic += phi_incr; // Increment the phi placement of module.
0185       rc += rphi_dr;    // Increment the center radius according to dr parameter.
0186       rphi_dr *= -1;    // Flip sign of dr parameter.
0187       module_z = -z0;   // Reset the Z placement parameter for module.
0188     }
0189     // Create the PhysicalVolume for the layer.
0190     pv = assembly.placeVolume(lay_vol); // Place layer in mother
0191     pv.addPhysVolID("layer", lay_id);   // Set the layer ID.
0192     lay_elt.setAttributes(description, lay_vol, x_layer.regionStr(), x_layer.limitsStr(), x_layer.visStr());
0193     lay_elt.setPlacement(pv);
0194   }
0195   sdet.setAttributes(description, assembly, x_det.regionStr(), x_det.limitsStr(), x_det.visStr());
0196   // assembly.setVisAttributes(description.invisible());
0197   pv = description.pickMotherVolume(sdet).placeVolume(assembly);
0198   pv.addPhysVolID("system", det_id); // Set the subdetector system ID.
0199   pv.addPhysVolID("barrel", 1);      // Flag this as a barrel subdetector.
0200   sdet.setPlacement(pv);
0201   return sdet;
0202 }
0203 
0204 // clang-format off
0205 DECLARE_DETELEMENT(athena_CylinderTrackerBarrel, CylinderTrackerBarrel_create_detector)
0206 DECLARE_DETELEMENT(athena_MMTrackerBarrel,       CylinderTrackerBarrel_create_detector)
0207 DECLARE_DETELEMENT(athena_RWellTrackerBarrel,    CylinderTrackerBarrel_create_detector)
0208 DECLARE_DETELEMENT(athena_CylinderVertexBarrel,  CylinderTrackerBarrel_create_detector)
0209