Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:17:07

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 "XML/Layering.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   static double tolerance = 0e0;
0026   Layering      layering (e);
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   xml_comp_t    x_staves  = x_det.staves();
0032   xml_comp_t    x_dim     = x_det.dimensions();
0033   int           nsides    = x_dim.numsides();
0034   double        inner_r   = x_dim.rmin();
0035   double        dphi      = (2*M_PI/nsides);
0036   double        hphi      = dphi/2;
0037   double        mod_z     = layering.totalThickness();
0038   double        outer_r   = inner_r + mod_z;
0039   double        totThick  = mod_z;
0040   DetElement    sdet      (det_name,det_id);
0041   Volume        motherVol = description.pickMotherVolume(sdet);
0042   PolyhedraRegular hedra  (nsides,inner_r,inner_r+totThick+tolerance*2e0,x_dim.z());
0043   Volume        envelope  (det_name,hedra,air);
0044   PlacedVolume  env_phv   = motherVol.placeVolume(envelope,RotationZYX(0,0,M_PI/nsides));
0045 
0046   env_phv.addPhysVolID("system",det_id);
0047   env_phv.addPhysVolID("barrel",0);
0048   sdet.setPlacement(env_phv);
0049 
0050   DetElement    stave_det("stave0",det_id);
0051   double dx = 0.0; //mod_z / std::sin(dphi); // dx per layer
0052     
0053   // Compute the top and bottom face measurements.
0054   double trd_x2 = (2 * std::tan(hphi) * outer_r - dx)/2 - tolerance;
0055   double trd_x1 = (2 * std::tan(hphi) * inner_r + dx)/2 - tolerance;
0056   double trd_y1 = x_dim.z()/2 - tolerance;
0057   double trd_y2 = trd_y1;
0058   double trd_z  = mod_z/2 - tolerance;
0059         
0060   // Create the trapezoid for the stave.
0061   Trapezoid trd(trd_x1, // Outer side, i.e. the "short" X side.
0062                 trd_x2, // Inner side, i.e. the "long"  X side.
0063                 trd_y1, // Corresponds to subdetector (or module) Z.
0064                 trd_y2, //
0065                 trd_z); // Thickness, in Y for top stave, when rotated.
0066 
0067   Volume mod_vol("stave",trd,air);
0068 
0069   sens.setType("calorimeter");
0070   { // =====  buildBarrelStave(description, sens, module_volume) =====
0071     // Parameters for computing the layer X dimension:
0072     double stave_z  = trd_y1;
0073     double tan_hphi = std::tan(hphi);
0074     double l_dim_x  = trd_x1; // Starting X dimension for the layer.
0075     double l_pos_z  = -(layering.totalThickness() / 2);
0076 
0077     // Loop over the sets of layer elements in the detector.
0078     int l_num = 1;
0079     for(xml_coll_t li(x_det,_U(layer)); li; ++li)  {
0080       xml_comp_t x_layer = li;
0081       int repeat = x_layer.repeat();
0082       // Loop over number of repeats for this layer.
0083       for (int j=0; j<repeat; j++)    {
0084         string l_name = _toString(l_num,"layer%d");
0085         double l_thickness = layering.layer(l_num-1)->thickness();  // Layer's thickness.
0086 
0087         Position   l_pos(0,0,l_pos_z+l_thickness/2);      // Position of the layer.
0088         Box        l_box(l_dim_x-tolerance,stave_z-tolerance,l_thickness / 2-tolerance);
0089         Volume     l_vol(l_name,l_box,air);
0090         DetElement layer(stave_det, l_name, det_id);
0091 
0092         // Loop over the sublayers or slices for this layer.
0093         int s_num = 1;
0094         double s_pos_z = -(l_thickness / 2);
0095         for(xml_coll_t si(x_layer,_U(slice)); si; ++si)  {
0096           xml_comp_t x_slice = si;
0097           string     s_name  = _toString(s_num,"slice%d");
0098           double     s_thick = x_slice.thickness();
0099           Box        s_box(l_dim_x-tolerance,stave_z-tolerance,s_thick / 2-tolerance);
0100           Volume     s_vol(s_name,s_box,description.material(x_slice.materialStr()));
0101           DetElement slice(layer,s_name,det_id);
0102 
0103           if ( x_slice.isSensitive() ) {
0104             s_vol.setSensitiveDetector(sens);
0105           }
0106           slice.setAttributes(description,s_vol,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr());
0107 
0108           // Slice placement.
0109           PlacedVolume slice_phv = l_vol.placeVolume(s_vol,Position(0,0,s_pos_z+s_thick/2));
0110           slice_phv.addPhysVolID("slice", s_num);
0111           slice.setPlacement(slice_phv);
0112           // Increment Z position of slice.
0113           s_pos_z += s_thick;
0114                                         
0115           // Increment slice number.
0116           ++s_num;
0117         }        
0118 
0119         // Set region, limitset, and vis of layer.
0120         layer.setAttributes(description,l_vol,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr());
0121 
0122         PlacedVolume layer_phv = mod_vol.placeVolume(l_vol,l_pos);
0123         layer_phv.addPhysVolID("layer", l_num);
0124         layer.setPlacement(layer_phv);
0125         // Increment to next layer Z position.
0126         double xcut = l_thickness * tan_hphi;
0127         l_dim_x += xcut;
0128         l_pos_z += l_thickness;          
0129         ++l_num;
0130       }
0131     }
0132   }
0133 
0134   // Set stave visualization.
0135   if ( x_staves )   {
0136     mod_vol.setVisAttributes(description.visAttributes(x_staves.visStr()));
0137   }
0138   // Phi start for a stave.
0139   double phi = M_PI / nsides;
0140   double mod_x_off = dx / 2;             // Stave X offset, derived from the dx.
0141   double mod_y_off = inner_r + mod_z/2;  // Stave Y offset
0142 
0143   // Create nsides staves.
0144   for (int i = 0; i < nsides; i++, phi -= dphi)      { // i is module number
0145     // Compute the stave position
0146     double m_pos_x = mod_x_off * std::cos(phi) - mod_y_off * std::sin(phi);
0147     double m_pos_y = mod_x_off * std::sin(phi) + mod_y_off * std::cos(phi);
0148     Transform3D tr(RotationZYX(0,phi,M_PI*0.5),Translation3D(-m_pos_x,-m_pos_y,0));
0149     PlacedVolume pv = envelope.placeVolume(mod_vol,tr);
0150     pv.addPhysVolID("system",det_id);
0151     pv.addPhysVolID("barrel",0);
0152     pv.addPhysVolID("module",i+1);
0153     DetElement sd = i==0 ? stave_det : stave_det.clone(_toString(i,"stave%d"));
0154     sd.setPlacement(pv);
0155     sdet.add(sd);
0156   }
0157 
0158   // Set envelope volume attributes.
0159   envelope.setAttributes(description,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
0160   return sdet;
0161 }
0162 
0163 DECLARE_DETELEMENT(DD4hep_EcalBarrel,create_detector)