Back to home page

EIC code displayed by LXR

 
 

    


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

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