Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:14: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 // Framework include files
0015 #include <DDDigi/noise/DigiSubdetectorSequence.h>
0016 #include <DDDigi/DigiSegmentation.h>
0017 #include <DDDigi/DigiKernel.h>
0018 #include <DDDigi/DigiContext.h>
0019 #include <DDDigi/DigiData.h>
0020 
0021 #include <DD4hep/InstanceCount.h>
0022 #include <DD4hep/Detector.h>
0023 #include <DD4hep/IDDescriptor.h>
0024 #include <DD4hep/detail/VolumeManagerInterna.h>
0025 #include <TClass.h>
0026 
0027 // C/C++ include files
0028 #include <stdexcept>
0029 
0030 using namespace dd4hep::digi;
0031 
0032 /// Standard constructor
0033 DigiSubdetectorSequence::DigiSubdetectorSequence(const DigiKernel& kernel, const std::string& nam)
0034   : DigiActionSequence(kernel, nam)
0035 {
0036   declareProperty("detector",m_detectorName);
0037   declareProperty("parallize_by",m_segmentName);
0038   m_cellHandler = [this](DigiContext& context, const DigiCellScanner& scanner, const DigiCellData& data)  {
0039     this->process_cell(context, scanner, data);
0040   };
0041   InstanceCount::increment(this);
0042 }
0043 
0044 /// Default destructor
0045 DigiSubdetectorSequence::~DigiSubdetectorSequence() {
0046   InstanceCount::decrement(this);
0047 }
0048 
0049 /// Initialize subdetector sequencer
0050 void DigiSubdetectorSequence::initialize()   {
0051   info("Initializing detector sequencer for detector: %s",m_detectorName.c_str());
0052   m_detector     = subdetector(m_detectorName);
0053   m_sensDet      = sensitiveDetector(m_detectorName);
0054   m_parallelVid.clear();
0055   m_parallelDet.clear();
0056   if ( m_detector.isValid() && m_sensDet.isValid() )   {
0057     m_idDesc       = m_sensDet.readout().idSpec();
0058     m_segmentation = m_sensDet.readout().segmentation();
0059     PlacedVolume  plc = m_detector.placement();
0060     const VolIDs& ids = plc.volIDs();
0061     VolumeID      vid = m_idDesc.encode(ids);
0062     VolumeID      msk = m_idDesc.get_mask(ids);
0063     scan_detector(m_detector, vid, msk);
0064   }
0065 }
0066 
0067 void DigiSubdetectorSequence::scan_sensitive(PlacedVolume pv, VolumeID vid, VolumeID mask)   {
0068   Volume vol = pv.volume();
0069   if ( vol.isSensitive() )    {
0070     Solid sol = vol.solid();
0071     auto  key = std::make_pair(sol->IsA(), m_segmentation);
0072     auto  is  = m_scanners.find(key);
0073     if ( is == m_scanners.end() )  {
0074       is = m_scanners.insert(std::make_pair(key, create_cell_scanner(sol, m_segmentation))).first;
0075     }
0076   }
0077   for ( int idau = 0, ndau = pv->GetNdaughters(); idau < ndau; ++idau ) {
0078     PlacedVolume  p(pv->GetDaughter(idau));
0079     const VolIDs& new_ids = p.volIDs();
0080     if ( !new_ids.empty() )   {
0081       VolumeID new_vid = vid  | m_idDesc.encode(new_ids);
0082       VolumeID new_msk = mask | m_idDesc.get_mask(new_ids);
0083       scan_sensitive(p, new_vid, new_msk);
0084       continue;
0085     }
0086     scan_sensitive(p, vid, mask);
0087   }
0088 }
0089 
0090 void DigiSubdetectorSequence::scan_detector(DetElement de, VolumeID vid, VolumeID mask)   {
0091   PlacedVolume  place   = m_detector.placement();
0092   const VolIDs& new_ids = place.volIDs();
0093   VolumeID      new_vid = vid;
0094   VolumeID      new_msk = mask;
0095   if ( !new_ids.empty() )   {
0096     new_vid |= m_idDesc.encode(new_ids);
0097     new_msk |= m_idDesc.get_mask(new_ids);
0098     for (const auto& id : new_ids)   {
0099       if ( id.first == m_segmentName )   {
0100         VolumeID rid = detail::reverseBits<VolumeID>(new_vid);
0101         m_parallelVid.emplace(std::make_pair(rid, Context(de, new_vid, rid, new_msk)));
0102         m_parallelDet.emplace(std::make_pair(de, new_vid));
0103         scan_sensitive(de.placement(), new_vid, new_msk);
0104         return;
0105       }
0106     }
0107   }
0108   for ( const auto& c : de.children() )
0109     scan_detector(c.second, new_vid, new_msk);
0110 }
0111 
0112 
0113 void DigiSubdetectorSequence::process_cell(DigiContext&, const DigiCellScanner& , const DigiCellData& /* data */)  const   {
0114 #if 0
0115   Segmentation seg  = m_sensDet.readout().segmentation();
0116   std::string       desc = m_idDesc.str(data.cell_id);
0117   info("Sensitive: [%s/%s]   vid:%s %s",
0118        data.solid->IsA()->GetName(),
0119        seg.type().c_str(),
0120        volumeID(data.cell_id).c_str(),
0121        desc.c_str());
0122   if ( data.cell_id )  {
0123   }
0124 #endif
0125 }
0126 
0127 void DigiSubdetectorSequence::process_context(DigiContext& context,
0128                                               const Context& c,
0129                                               PlacedVolume pv,
0130                                               VolumeID vid,
0131                                               VolumeID mask)   const
0132 {
0133   Volume vol = pv.volume();
0134   if ( vol.isSensitive() )    {
0135     auto key = std::make_pair(vol->GetShape()->IsA(), m_segmentation);
0136     auto is  = m_scanners.find(key);
0137     if ( is == m_scanners.end() )   {
0138       except("Fatal error in process_context: Invalid cell scanner. vid: %016X",vid);
0139     }
0140     (*(is->second))(context, pv, vid, m_cellHandler);
0141     return;
0142   }
0143   for (int idau = 0, ndau = pv->GetNdaughters(); idau < ndau; ++idau) {
0144     PlacedVolume p(pv->GetDaughter(idau));
0145     const VolIDs& new_ids = p.volIDs();
0146     if ( !new_ids.empty() )
0147       process_context(context, c, p, vid | m_idDesc.encode(new_ids), mask | m_idDesc.get_mask(new_ids));
0148     else
0149       process_context(context, c, p, vid, mask);
0150   }
0151 }
0152 
0153 /// Pre-track action callback
0154 void DigiSubdetectorSequence::execute(DigiContext& context)  const   {
0155   for( const auto& d : m_parallelVid )   {
0156     const Context& c = d.second;
0157     auto vid = c.detector_id;
0158     auto det = c.detector;
0159     std::string id_desc = m_idDesc.str(vid);
0160     info("  Order:%-64s    vid:%s %s %s",
0161          det.path().c_str(), volumeID(d.first).c_str(), volumeID(vid).c_str(), id_desc.c_str());
0162     process_context(context, c, c.detector.placement(), c.detector_id, c.detector_mask);
0163   }
0164   this->DigiSynchronize::execute(context);
0165   debug("+++ Event: %8d (DigiSubdetectorSequence) Parallel: %s Done.",
0166         context.event->eventNumber, yes_no(m_parallel));
0167 }
0168 
0169 /// Access subdetector from the detector description
0170 dd4hep::DetElement DigiSubdetectorSequence::subdetector(const std::string& nam)   const   {
0171   return m_kernel.detectorDescription().detector(nam);
0172 }
0173 
0174 /// Access sensitive detector from the detector description
0175 dd4hep::SensitiveDetector DigiSubdetectorSequence::sensitiveDetector(const std::string& nam)   const   {
0176   return m_kernel.detectorDescription().sensitiveDetector(nam);
0177 }