Back to home page

EIC code displayed by LXR

 
 

    


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

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; BP shape adoption)
0017 // 
0018 //==========================================================================
0019 #include "DD4hep/DetFactoryHelper.h"
0020 #include <map>
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   typedef vector<PlacedVolume> Placements;
0028   xml_det_t   x_det     = e;
0029   Material    vacuum    = description.vacuum();
0030   int         det_id    = x_det.id();
0031   string      det_name  = x_det.nameStr();
0032   bool        reflect   = x_det.reflect(false);
0033   DetElement  sdet        (det_name,det_id);
0034   Assembly    assembly    (det_name);
0035   // MSF: unused! double      ra        = x_det.rmax();  // ellipse long radius - y
0036   // MSF: unused! double      rb        = x_det.r();     // ellipse short radius - x   
0037   //Volume      assembly    (det_name,Box(10000,10000,10000),vacuum);
0038   Volume      motherVol = description.pickMotherVolume(sdet);
0039   int         m_id=0, c_id=0, n_sensor=0;
0040   map<string,Volume> modules;
0041   map<string, Placements>  sensitives;
0042   PlacedVolume pv;
0043 
0044   assembly.setVisAttributes(description.invisible());
0045   sens.setType("tracker");
0046   double   total_thickness_max=0.;
0047 
0048   for(xml_coll_t mi(x_det,_U(module)); mi; ++mi, ++m_id)  {
0049     xml_comp_t x_mod   = mi;
0050     string     m_nam   = x_mod.nameStr();
0051     xml_comp_t trd     = x_mod.trd();
0052     double     posY;
0053     double     x1      = trd.x1();
0054     double     x2      = trd.x2();
0055     double     z       = trd.z();
0056     double     y1, y2, total_thickness=0.;
0057     xml_coll_t ci(x_mod,_U(module_component));
0058     for(ci.reset(), total_thickness=0.0; ci; ++ci)
0059       total_thickness += xml_comp_t(ci).thickness();
0060     if ( total_thickness >  total_thickness_max) total_thickness_max=total_thickness;
0061     
0062     y1 = y2 = total_thickness / 2;
0063     Volume  m_volume(m_nam, Trapezoid(x1, x2, y1, y2, z), vacuum);      
0064     m_volume.setVisAttributes(description.visAttributes(x_mod.visStr()));
0065 
0066     for(ci.reset(), n_sensor=1, c_id=0, posY=-y1; ci; ++ci, ++c_id)  {
0067       xml_comp_t c       = ci;
0068       double     c_thick = c.thickness();
0069       Material   c_mat   = description.material(c.materialStr());
0070       string     c_name  = _toString(c_id,"component%d");
0071       Volume     c_vol(c_name, Trapezoid(x1,x2,c_thick/2e0,c_thick/2e0,z), c_mat);
0072 
0073       c_vol.setVisAttributes(description.visAttributes(c.visStr()));
0074       pv = m_volume.placeVolume(c_vol,Position(0,posY+c_thick/2,0));
0075       if ( c.isSensitive() ) {
0076         sdet.check(n_sensor > 2,"SiTrackerEndcap2::fromCompact: "+c_name+" Max of 2 modules allowed!");
0077         pv.addPhysVolID("sensor",n_sensor);
0078         c_vol.setSensitiveDetector(sens);
0079         sensitives[m_nam].push_back(pv);
0080         ++n_sensor;
0081       }
0082       posY += c_thick;
0083     }
0084     modules[m_nam] = m_volume;
0085   }
0086   
0087   for(xml_coll_t li(x_det,_U(layer)); li; ++li)  {
0088     xml_comp_t  x_layer(li);
0089     int l_id    = x_layer.id();
0090     int mod_num = 1;
0091     for(xml_coll_t ri(x_layer,_U(ring)); ri; ++ri)  {
0092       xml_comp_t x_ring = ri;
0093       double r        = x_ring.r();
0094       double phi0     = x_ring.phi0(0);
0095       double zstart   = x_ring.zstart();
0096       double dz       = x_ring.dz(0);
0097       int    nmodules = x_ring.nmodules();
0098       string m_nam    = x_ring.moduleStr();
0099       Volume m_vol    = modules[m_nam];
0100       double iphi     = 2*M_PI/nmodules;
0101       double phi      = phi0;
0102       Placements& sensVols = sensitives[m_nam];
0103 
0104       for(int k=0; k<nmodules; ++k) {
0105         string m_base = _toString(l_id,"layer%d") + _toString(mod_num,"_module%d");
0106         double x = -r*std::cos(phi);
0107         double y = -r*std::sin(phi);
0108 /*       
0109         EllipticalTube bpElTube(rb, ra, zstart-total_thickness_max/2); 
0110         SubtractionSolid tr1(m_vol,bpElTube);
0111         Volume  m_vol(m_nam, tr1, c_mat);       
0112         material of the module ? how to change a module shape?
0113         m_vol.setVisAttributes(description.visAttributes(x_ring.visStr()));
0114 */      
0115       
0116     if ( zstart >= 0 ) {
0117         DetElement module(sdet,m_base+"_pos",det_id);
0118         pv = assembly.placeVolume(m_vol,Transform3D(RotationZYX(0,-M_PI/2-phi,-M_PI/2),Position(x,y,zstart+dz)));
0119         pv.addPhysVolID("barrel",1).addPhysVolID("layer", l_id).addPhysVolID("module",mod_num);
0120         module.setPlacement(pv);
0121         for(size_t ic=0; ic<sensVols.size(); ++ic)  {
0122           PlacedVolume sens_pv = sensVols[ic];
0123           DetElement comp_elt(module,sens_pv.volume().name(),mod_num);
0124           comp_elt.setPlacement(sens_pv);
0125         }
0126 
0127         if ( reflect ) {
0128           pv = assembly.placeVolume(m_vol,Transform3D(RotationZYX(M_PI,-M_PI/2-phi,-M_PI/2),Position(x,y,-zstart-dz)));
0129           pv.addPhysVolID("barrel",2).addPhysVolID("layer",l_id).addPhysVolID("module",mod_num);
0130           DetElement r_module(sdet,m_base+"_neg",det_id);
0131           r_module.setPlacement(pv);
0132           for(size_t ic=0; ic<sensVols.size(); ++ic)  {
0133             PlacedVolume sens_pv = sensVols[ic];
0134             DetElement comp_elt(r_module,sens_pv.volume().name(),mod_num);
0135             comp_elt.setPlacement(sens_pv);
0136           }
0137         }
0138     } else
0139     {
0140        pv = assembly.placeVolume(m_vol,Transform3D(RotationZYX(0,-M_PI/2-phi,-M_PI/2),Position(x,y,zstart-dz)));
0141        pv.addPhysVolID("barrel",3).addPhysVolID("layer", l_id).addPhysVolID("module",mod_num);
0142        DetElement r_module(sdet,m_base+"_neg-z",det_id);
0143        r_module.setPlacement(pv);
0144        for(size_t ic=0; ic<sensVols.size(); ++ic)  {
0145         PlacedVolume sens_pv = sensVols[ic];
0146         DetElement comp_elt(r_module,sens_pv.volume().name(),mod_num);
0147         comp_elt.setPlacement(sens_pv);
0148       }
0149         }
0150         dz   = -dz;
0151         phi += iphi;
0152         ++mod_num;
0153       }
0154     }
0155   }
0156   pv = motherVol.placeVolume(assembly);
0157   pv.addPhysVolID("system",det_id);
0158   sdet.setPlacement(pv);
0159   return sdet;
0160 }
0161 
0162 DECLARE_DETELEMENT(Lhe_BP_SiTrackerEndcap2,create_detector)