Back to home page

EIC code displayed by LXR

 
 

    


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

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