Skip to content
Snippets Groups Projects
SiliconTrackerEndcap_geo.cpp 6.32 KiB
Newer Older
  • Learn to ignore specific revisions
  • //==========================================================================
    //  AIDA Detector description implementation 
    //--------------------------------------------------------------------------
    // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
    // All rights reserved.
    //
    // For the licensing terms see $DD4hepINSTALL/LICENSE.
    // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
    //
    // Author     : M.Frank
    //
    //==========================================================================
    //
    // Specialized generic detector constructor
    // 
    //==========================================================================
    #include "DD4hep/DetFactoryHelper.h"
    #include <map>
    
    
    #include "Acts/Plugins/DD4hep/ActsExtension.hpp"
    #include "Acts/Surfaces/PlanarBounds.hpp"
    #include "Acts/Surfaces/RectangleBounds.hpp"
    #include "Acts/Surfaces/TrapezoidBounds.hpp"
    #include "Acts/Utilities/Units.hpp"
    
    using namespace std;
    using namespace dd4hep;
    using namespace dd4hep::detail;
    
    static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens)  {
      typedef vector<PlacedVolume> Placements;
      xml_det_t   x_det     = e;
      Material    vacuum    = description.vacuum();
      int         det_id    = x_det.id();
      string      det_name  = x_det.nameStr();
      bool        reflect   = x_det.reflect(false);
      DetElement  sdet        (det_name,det_id);
      Assembly    assembly    (det_name);
      //Volume      assembly    (det_name,Box(10000,10000,10000),vacuum);
      Volume      motherVol = description.pickMotherVolume(sdet);
      int         m_id=0, c_id=0, n_sensor=0;
      map<string,Volume> modules;
      map<string, Placements>  sensitives;
      PlacedVolume pv;
    
    
    
      Acts::ActsExtension* detWorldExt = new Acts::ActsExtension();
      detWorldExt->addType("endcap", "detector");
      sdet.addExtension<Acts::ActsExtension>(detWorldExt);
    
    
      assembly.setVisAttributes(description.invisible());
      sens.setType("tracker");
    
      for(xml_coll_t mi(x_det,_U(module)); mi; ++mi, ++m_id)  {
        xml_comp_t x_mod   = mi;
        string     m_nam   = x_mod.nameStr();
        xml_comp_t trd     = x_mod.trd();
        double     posY;
        double     x1      = trd.x1();
        double     x2      = trd.x2();
        double     z       = trd.z();
        double     y1, y2, total_thickness=0.;
        xml_coll_t ci(x_mod,_U(module_component));
        for(ci.reset(), total_thickness=0.0; ci; ++ci)
          total_thickness += xml_comp_t(ci).thickness();
          
        y1 = y2 = total_thickness / 2;
        Volume  m_volume(m_nam, Trapezoid(x1, x2, y1, y2, z), vacuum);      
        m_volume.setVisAttributes(description.visAttributes(x_mod.visStr()));
    
        for(ci.reset(), n_sensor=1, c_id=0, posY=-y1; ci; ++ci, ++c_id)  {
          xml_comp_t c       = ci;
          double     c_thick = c.thickness();
          Material   c_mat   = description.material(c.materialStr());
          string     c_name  = _toString(c_id,"component%d");
          Volume     c_vol(c_name, Trapezoid(x1,x2,c_thick/2e0,c_thick/2e0,z), c_mat);
    
          c_vol.setVisAttributes(description.visAttributes(c.visStr()));
          pv = m_volume.placeVolume(c_vol,Position(0,posY+c_thick/2,0));
          if ( c.isSensitive() ) {
            sdet.check(n_sensor > 2,"SiTrackerEndcap2::fromCompact: "+c_name+" Max of 2 modules allowed!");
            pv.addPhysVolID("sensor",n_sensor);
            c_vol.setSensitiveDetector(sens);
            sensitives[m_nam].push_back(pv);
            ++n_sensor;
          }
          posY += c_thick;
        }
        modules[m_nam] = m_volume;
      }
      
      for(xml_coll_t li(x_det,_U(layer)); li; ++li)  {
        xml_comp_t  x_layer(li);
        int l_id    = x_layer.id();
        int mod_num = 1;
        for(xml_coll_t ri(x_layer,_U(ring)); ri; ++ri)  {
          xml_comp_t x_ring = ri;
          double r        = x_ring.r();
          double phi0     = x_ring.phi0(0);
          double alpha     = x_ring.alpha(0);
          double zstart   = x_ring.zstart();
          double dz       = x_ring.dz();
          int    nmodules = x_ring.nmodules();
          string m_nam    = x_ring.moduleStr();
    
          string m_vis    = x_ring.visStr();
    
          Volume m_vol    = modules[m_nam];
          double iphi     = 2*M_PI/nmodules;
          double phi      = phi0;
          Placements& sensVols = sensitives[m_nam];
    
          if(std::size(m_vis) > 0 ) {
            // The vis attributes are set by the last setVisAttribute for the shared module's Volume
            //using TGeoSolidType = typename decltype(m_vol.solid())::Object;
            //Solid solidcopy(m_vol.solid()->Clone()); 
            //auto newvol = new TGeoSolidType(*(m_vol.solid()));
            //m_vol.setSolid(solidcopy);
            m_vol.setVisAttributes(description.visAttributes(m_vis));
          }
    
    
          for(int k=0; k<nmodules; ++k) {
            string m_base = _toString(l_id,"layer%d") + _toString(mod_num,"_module%d");
            double x = -r*std::cos(phi);
            double sign = 1.0;//(k%2==0?-1.0:1.0);
            //std::cout << "dz = " << zstart+sign*dz <<"\n";
            double y = -r*std::sin(phi);
            DetElement module(sdet,m_base+"_pos",det_id);
            pv = assembly.placeVolume(m_vol,Transform3D(RotationZYX(0,-M_PI/2-phi,-M_PI/2)*RotationZYX(0,0,-alpha),Position(x,y,zstart+sign*dz)));
            pv.addPhysVolID("barrel",1).addPhysVolID("layer", l_id).addPhysVolID("module",mod_num);
            module.setPlacement(pv);
            for(size_t ic=0; ic<sensVols.size(); ++ic)  {
              PlacedVolume sens_pv = sensVols[ic];
              DetElement comp_elt(module,sens_pv.volume().name(),mod_num);
              comp_elt.setPlacement(sens_pv);
            }
    
            if ( reflect ) {
    
              pv = assembly.placeVolume(m_vol,Transform3D(RotationZYX(M_PI,-M_PI/2-phi,-M_PI/2)*RotationZYX(0,0,-alpha),Position(x,y,-zstart-sign*dz)));
    
              pv.addPhysVolID("barrel",2).addPhysVolID("layer",l_id).addPhysVolID("module",mod_num);
              DetElement r_module(sdet,m_base+"_neg",det_id);
              r_module.setPlacement(pv);
              for(size_t ic=0; ic<sensVols.size(); ++ic)  {
                PlacedVolume sens_pv = sensVols[ic];
                DetElement comp_elt(r_module,sens_pv.volume().name(),mod_num);
                comp_elt.setPlacement(sens_pv);
    
                Acts::ActsExtension* moduleExtension = new Acts::ActsExtension();
                comp_elt.addExtension<Acts::ActsExtension>(moduleExtension);
    
              }
            }
            dz   = -dz;
            phi += iphi;
            ++mod_num;
          }
        }
      }
      pv = motherVol.placeVolume(assembly);
      pv.addPhysVolID("system",det_id);
      sdet.setPlacement(pv);
      return sdet;
    }
    
    DECLARE_DETELEMENT(SiliconTrackerEndcap_topside,create_detector)