Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:14:58

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 //
0014 // Specialized generic detector constructor
0015 // 
0016 //==========================================================================
0017 #include "DD4hep/DetFactoryHelper.h"
0018 #include "DD4hep/Printout.h"
0019 
0020 using namespace std;
0021 using namespace dd4hep;
0022 using namespace dd4hep::detail;
0023 
0024 static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens)  {
0025   typedef vector<PlacedVolume> Placements;
0026   xml_det_t   x_det     = e;
0027   Material    air       = description.air();
0028   int         det_id    = x_det.id();
0029   string      det_name  = x_det.nameStr();
0030   DetElement  sdet       (det_name,det_id);
0031   Assembly    assembly   (det_name);
0032   map<string, Volume>    volumes;
0033   map<string, Placements>  sensitives;
0034   PlacedVolume pv;
0035 
0036   sens.setType("tracker");
0037   for(xml_coll_t mi(x_det,_U(module)); mi; ++mi)  {
0038     xml_comp_t x_mod  = mi;
0039     xml_comp_t m_env  = x_mod.child(_U(module_envelope));
0040     string     m_nam  = x_mod.nameStr();
0041     Volume     m_vol(m_nam,Box(m_env.width()/2,m_env.length()/2,m_env.thickness()/2),air);
0042     int        ncomponents = 0, sensor_number = 1;
0043 
0044     if ( volumes.find(m_nam) != volumes.end() )   {
0045       printout(ERROR,"SiTrackerBarrel","Logics error in building modules.");
0046       throw runtime_error("Logics error in building modules.");
0047     }
0048     volumes[m_nam] = m_vol;
0049     m_vol.setVisAttributes(description.visAttributes(x_mod.visStr()));
0050     for(xml_coll_t ci(x_mod,_U(module_component)); ci; ++ci, ++ncomponents)  {
0051       xml_comp_t x_comp = ci;
0052       xml_comp_t x_pos  = x_comp.position(false);
0053       xml_comp_t x_rot  = x_comp.rotation(false);        
0054       string     c_nam  = _toString(ncomponents,"component%d");
0055       Box        c_box(x_comp.width()/2,x_comp.length()/2,x_comp.thickness()/2);
0056       Volume     c_vol(c_nam,c_box,description.material(x_comp.materialStr()));
0057 
0058       if ( x_pos && x_rot ) {
0059         Position    c_pos(x_pos.x(0),x_pos.y(0),x_pos.z(0));
0060         RotationZYX c_rot(x_rot.z(0),x_rot.y(0),x_rot.x(0));
0061         pv = m_vol.placeVolume(c_vol, Transform3D(c_rot,c_pos));
0062       }
0063       else if ( x_rot ) {
0064         pv = m_vol.placeVolume(c_vol,RotationZYX(x_rot.z(0),x_rot.y(0),x_rot.x(0)));
0065       }
0066       else if ( x_pos ) {
0067         pv = m_vol.placeVolume(c_vol,Position(x_pos.x(0),x_pos.y(0),x_pos.z(0)));
0068       }
0069       else {
0070         pv = m_vol.placeVolume(c_vol);
0071       }
0072       c_vol.setRegion(description, x_comp.regionStr());
0073       c_vol.setLimitSet(description, x_comp.limitsStr());
0074       c_vol.setVisAttributes(description, x_comp.visStr());
0075       if ( x_comp.isSensitive() ) {
0076         pv.addPhysVolID(_U(sensor),sensor_number++);
0077         c_vol.setSensitiveDetector(sens);
0078         sensitives[m_nam].push_back(pv);
0079       }
0080     }
0081   }
0082   for(xml_coll_t li(x_det,_U(layer)); li; ++li)  {
0083     xml_comp_t x_layer  = li;
0084     xml_comp_t x_barrel = x_layer.child(_U(barrel_envelope));
0085     xml_comp_t x_layout = x_layer.child(_U(rphi_layout));
0086     xml_comp_t z_layout = x_layer.child(_U(z_layout));      // Get the <z_layout> element.
0087     int        lay_id   = x_layer.id();
0088     string     m_nam    = x_layer.moduleStr();
0089     string     lay_nam  = _toString(x_layer.id(),"layer%d");
0090     Tube       lay_tub   (x_barrel.inner_r(),x_barrel.outer_r(),x_barrel.z_length()/2);
0091     Volume     lay_vol   (lay_nam,lay_tub,air);         // Create the layer envelope volume.
0092     double     phi0     = x_layout.phi0();              // Starting phi of first module.
0093     double     phi_tilt = x_layout.phi_tilt();          // Phi tilt of a module.
0094     double     rc       = x_layout.rc();                // Radius of the module center.
0095     int        nphi     = x_layout.nphi();              // Number of modules in phi.
0096     double     rphi_dr  = x_layout.dr();                // The delta radius of every other module.
0097     double     phi_incr = (M_PI * 2) / nphi;            // Phi increment for one module.
0098     double     phic     = phi0;                         // Phi of the module center.
0099     double     z0       = z_layout.z0();                // Z position of first module in phi.
0100     double     nz       = z_layout.nz();                // Number of modules to place in z.
0101     double     z_dr     = z_layout.dr();                // Radial displacement parameter, of every other module.
0102     Volume     m_env    = volumes[m_nam];
0103     DetElement lay_elt(sdet,_toString(x_layer.id(),"layer%d"),lay_id);
0104     Placements& sensVols = sensitives[m_nam];
0105 
0106     // Z increment for module placement along Z axis.
0107     // Adjust for z0 at center of module rather than
0108     // the end of cylindrical envelope.
0109     double z_incr   = nz > 1 ? (2.0 * z0) / (nz - 1) : 0.0;
0110     // Starting z for module placement along Z axis.
0111     double module_z = -z0;
0112     int module = 1;
0113       
0114     // Loop over the number of modules in phi.
0115     for (int ii = 0; ii < nphi; ii++)        {
0116       double dx = z_dr * std::cos(phic + phi_tilt);        // Delta x of module position.
0117       double dy = z_dr * std::sin(phic + phi_tilt);        // Delta y of module position.
0118       double  x = rc * std::cos(phic);                     // Basic x module position.
0119       double  y = rc * std::sin(phic);                     // Basic y module position.
0120 
0121       // Loop over the number of modules in z.
0122       for (int j = 0; j < nz; j++)          {
0123         string module_name = _toString(module,"module%d");
0124         DetElement mod_elt(lay_elt,module_name,module);
0125         // Module PhysicalVolume.
0126         //         Transform3D tr(RotationZYX(0,-((M_PI/2)-phic-phi_tilt),M_PI/2),Position(x,y,module_z));
0127         //NOTE (Nikiforos, 26/08 Rotations needed to be fixed so that component1 (silicon) is on the outside
0128         Transform3D tr(RotationZYX(0,((M_PI/2)-phic-phi_tilt),-M_PI/2),Position(x,y,module_z));
0129 
0130         pv = lay_vol.placeVolume(m_env,tr);
0131         pv.addPhysVolID("module", module);
0132         mod_elt.setPlacement(pv);
0133         for(size_t ic=0; ic<sensVols.size(); ++ic)  {
0134           PlacedVolume sens_pv = sensVols[ic];
0135           DetElement comp_elt(mod_elt,sens_pv.volume().name(),module);
0136           comp_elt.setPlacement(sens_pv);
0137         }
0138 
0139         /// Increase counters etc.
0140         module++;
0141         // Adjust the x and y coordinates of the module.
0142         x += dx;
0143         y += dy;
0144         // Flip sign of x and y adjustments.
0145         dx *= -1;
0146         dy *= -1;
0147         // Add z increment to get next z placement pos.
0148         module_z += z_incr;
0149       }
0150       phic     += phi_incr;      // Increment the phi placement of module.
0151       rc       += rphi_dr;       // Increment the center radius according to dr parameter.
0152       rphi_dr  *= -1;            // Flip sign of dr parameter.
0153       module_z  = -z0;           // Reset the Z placement parameter for module.
0154     }
0155     // Create the PhysicalVolume for the layer.
0156     pv = assembly.placeVolume(lay_vol); // Place layer in mother
0157     pv.addPhysVolID("layer", lay_id);       // Set the layer ID.
0158     lay_elt.setAttributes(description,lay_vol,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr());
0159     lay_elt.setPlacement(pv);
0160   }
0161   sdet.setAttributes(description,assembly,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
0162   assembly.setVisAttributes(description.invisible());
0163   pv = description.pickMotherVolume(sdet).placeVolume(assembly);
0164   pv.addPhysVolID("system", det_id);      // Set the subdetector system ID.
0165   pv.addPhysVolID("barrel", 0);           // Flag this as a barrel subdetector.
0166   sdet.setPlacement(pv);
0167   return sdet;
0168 }
0169 
0170 DECLARE_DETELEMENT(Lhe_SiTrackerBarrel,create_detector)