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 // Specialized generic detector constructor
0015 //
0016 //  mod.:        P.Kostka LHeD (asymmetrical detector placement in z)
0017 // 
0018 //==========================================================================
0019 #include "DD4hep/DetFactoryHelper.h"
0020 #include "XML/Layering.h"
0021 
0022 using namespace std;
0023 using namespace dd4hep;
0024 using namespace dd4hep::detail;
0025 
0026 static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens)  {
0027   xml_det_t   x_det     = e;
0028   xml_dim_t   dim       = x_det.dimensions();
0029   int         det_id    = x_det.id();
0030   bool        reflect   = x_det.reflect(true);
0031   string      det_name  = x_det.nameStr();
0032   Material    air       = description.air();
0033   int         numsides  = dim.numsides();
0034   double      rmin      = dim.rmin();
0035   double      rmax      = dim.rmax()*std::cos(M_PI/numsides);
0036   double      zmin      = dim.zmin();
0037   double      z_offset  = dim.hasAttr(_U(z_offset)) ? dim.z_offset() : 0.0;
0038   Layering    layering(x_det);
0039   double      totalThickness = layering.totalThickness();
0040   Volume      endcapVol("endcap",PolyhedraRegular(numsides,rmin,rmax,totalThickness+z_offset),air);
0041   DetElement  endcap("endcap",det_id);
0042 
0043   int l_num = 1;
0044   int layerType   = 0;
0045   double layerZ   = -totalThickness/2;
0046 
0047   endcapVol.setAttributes(description,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
0048 
0049   for(xml_coll_t xc(x_det,_U(layer)); xc; ++xc)  {
0050     xml_comp_t       x_layer  = xc;
0051     double           l_thick  = layering.layer(l_num-1)->thickness();
0052     string           l_name   = _toString(layerType,"layer%d");
0053     int              l_repeat = x_layer.repeat();
0054     Volume           l_vol(l_name,PolyhedraRegular(numsides,rmin,rmax,l_thick),air);
0055     vector<PlacedVolume> sensitives;
0056 
0057     int s_num = 1;
0058     double sliceZ = -l_thick/2;
0059     for(xml_coll_t xs(x_layer,_U(slice)); xs; ++xs)  {
0060       xml_comp_t x_slice = xs;
0061       string     s_name  = _toString(s_num,"slice%d");
0062       double     s_thick = x_slice.thickness();
0063       Material   s_mat   = description.material(x_slice.materialStr());
0064       Volume     s_vol(s_name,PolyhedraRegular(numsides,rmin,rmax,s_thick),s_mat);
0065         
0066       s_vol.setVisAttributes(description.visAttributes(x_slice.visStr()));
0067       sliceZ += s_thick/2;
0068       PlacedVolume s_phv = l_vol.placeVolume(s_vol,Position(0,0,sliceZ));
0069       s_phv.addPhysVolID("slice",s_num);
0070       if ( x_slice.isSensitive() )  {
0071         sens.setType("calorimeter");
0072         s_vol.setSensitiveDetector(sens);
0073         sensitives.push_back(s_phv);
0074       }
0075       sliceZ += s_thick/2;
0076       s_num++;
0077     }
0078     l_vol.setVisAttributes(description.visAttributes(x_layer.visStr()));
0079     if ( l_repeat <= 0 ) throw std::runtime_error(x_det.nameStr()+"> Invalid repeat value");
0080     for(int j=0; j<l_repeat; ++j) {
0081       string phys_lay = _toString(l_num,"layer%d");
0082       layerZ += l_thick/2;
0083       DetElement    layer_elt(endcap, phys_lay, l_num);
0084       PlacedVolume  pv = endcapVol.placeVolume(l_vol,Position(0,0,layerZ));
0085       pv.addPhysVolID("layer", l_num);
0086       layer_elt.setPlacement(pv);
0087       for(size_t ic=0; ic<sensitives.size(); ++ic)  {
0088         PlacedVolume sens_pv = sensitives[ic];
0089         DetElement comp_elt(layer_elt,sens_pv.volume().name(),l_num);
0090         comp_elt.setPlacement(sens_pv);
0091       }
0092       layerZ += l_thick/2;
0093       ++l_num;
0094     }
0095     ++layerType;
0096   }
0097 
0098   double z_pos = zmin+totalThickness/2;
0099   PlacedVolume pv;
0100   // Reflect it.
0101   if ( reflect )  {
0102     Assembly    assembly(det_name);
0103     DetElement  both_endcaps(det_name,det_id);
0104     Volume      motherVol = description.pickMotherVolume(both_endcaps);
0105     DetElement  sdetA = endcap;
0106     Ref_t(sdetA)->SetName((det_name+"_A").c_str());
0107     DetElement  sdetB = endcap.clone(det_name+"_B",x_det.id());
0108 
0109     pv = assembly.placeVolume(endcapVol,Transform3D(RotationZYX(M_PI/numsides,0,0),
0110                                                     Position(0,0,z_pos)));
0111     pv.addPhysVolID("barrel", 1);
0112     sdetA.setPlacement(pv);
0113 
0114     pv = assembly.placeVolume(endcapVol,Transform3D(RotationZYX(M_PI/numsides,M_PI,0),
0115                                                     Position(0,0,-z_pos)));
0116     pv.addPhysVolID("barrel", 2);
0117     sdetB.setPlacement(pv);
0118 
0119     pv = motherVol.placeVolume(assembly);
0120     pv.addPhysVolID("system", det_id);
0121     both_endcaps.setPlacement(pv);
0122     both_endcaps.add(sdetA);
0123     both_endcaps.add(sdetB);
0124     return both_endcaps;
0125   }
0126   else  {
0127     Volume motherVol = description.pickMotherVolume(endcap);
0128          pv = motherVol.placeVolume(endcapVol,Transform3D(RotationZYX(M_PI/numsides,0,0),
0129                                                    Position(0,0,z_pos)));
0130   pv.addPhysVolID("system", det_id);
0131       if ( z_pos >= 0) { 
0132          pv.addPhysVolID("barrel", 1);
0133       }
0134        else {
0135          pv.addPhysVolID("barrel", 2);
0136       }
0137   endcap.setPlacement(pv);
0138   Ref_t(endcap)->SetName(det_name.c_str());
0139   return endcap;
0140   }
0141 }
0142 
0143 DECLARE_DETELEMENT(Lhe_PolyhedraEndcapCalorimeter2,create_detector)