Back to home page

EIC code displayed by LXR

 
 

    


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

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 <DD4hep/Plugins.h>
0016 #include <DD4hep/InstanceCount.h>
0017 #include <DDDigi/DigiKernel.h>
0018 #include <DDDigi/DigiContext.h>
0019 #include <DDDigi/DigiPlugins.h>
0020 #include <DDDigi/DigiSegmentSplitter.h>
0021 
0022 using namespace dd4hep::digi;
0023 
0024 /// Default copy constructor
0025 DigiSegmentProcessContext::DigiSegmentProcessContext(const DigiSegmentContext& copy)
0026   : DigiSegmentContext(copy)
0027 {
0028 }
0029 
0030 /// Full identifier (field + id)
0031 std::string DigiSegmentProcessContext::identifier()  const   {
0032   return this->DigiSegmentContext::identifier(this->predicate.id);
0033 }
0034 
0035 /// Default move assignment
0036 DigiSegmentProcessContext&
0037 DigiSegmentProcessContext::operator=(const DigiSegmentContext& copy)   {
0038   this->DigiSegmentContext::operator=(copy);
0039   return *this;
0040 }
0041 
0042 void DigiSegmentProcessContext::enable(uint32_t split_id)  {
0043   this->predicate.id = split_id;
0044   this->predicate.segmentation = this;
0045   this->predicate.callback = std::bind(&DigiSegmentProcessContext::use_depo, this, std::placeholders::_1);
0046 }
0047 
0048 /// Worker adaptor for caller DigiContainerSequence
0049 template <> void DigiParallelWorker<DigiContainerProcessor,
0050                     DigiContainerProcessor::work_t,
0051                     DigiSegmentProcessContext>::execute(void* ptr) const  {
0052   calldata_t* args  = reinterpret_cast<calldata_t*>(ptr);
0053   action->execute(args->environ.context, *args, this->options.predicate);
0054 }
0055 
0056 /// Standard constructor
0057 DigiSegmentSplitter::DigiSegmentSplitter(const kernel_t& kernel, const std::string& nam)
0058   : DigiContainerProcessor(kernel, nam),
0059     m_split_tool(kernel.detectorDescription())
0060 {
0061   declareProperty("parallel",        m_parallel = false);
0062   declareProperty("detector",        m_detector_name);
0063   declareProperty("split_by",        m_split_by);
0064   declareProperty("processor_type",  m_processor_type);
0065   declareProperty("share_processor", m_share_processor = false);
0066   m_kernel.register_initialize(std::bind(&DigiSegmentSplitter::initialize,this));
0067   InstanceCount::increment(this);
0068 }
0069 
0070 /// Default destructor
0071 DigiSegmentSplitter::~DigiSegmentSplitter() {
0072   InstanceCount::decrement(this);
0073 }
0074 
0075 /// Retrieve the names of all collection to be accessed
0076 std::vector<std::string> DigiSegmentSplitter::collection_names()  const   {
0077   if ( !m_detector_name.empty() )   {
0078     if ( m_splits.empty() )  {
0079       m_split_tool.set_detector(m_detector_name);
0080     }
0081     return m_split_tool.collection_names();
0082   }
0083   except("+++ collection_names: The detector name is not set. Unable to access readout properties.");
0084   return {};
0085 }
0086 
0087 /// Initialization function
0088 void DigiSegmentSplitter::initialize()   {
0089   char text[256];
0090 
0091   m_split_tool.set_detector(m_detector_name);
0092   m_keys          = m_split_tool.collection_keys();
0093   m_split_context = m_split_tool.split_context(m_split_by);
0094   m_splits        = m_split_tool.split_segmentation(m_split_by);
0095 
0096   /// 1) Check if the workers were pre-configured
0097   if ( !m_workers.empty() )    {
0098     bool bad = false;
0099     auto group = m_workers.get_group();
0100     const auto& workers = group.actors();
0101     /// Create the processors:
0102     for( auto split_id : m_splits )   {
0103       bool ok = false;
0104       for( auto* w : workers )   {
0105     if ( w->options.predicate.id == split_id )  {
0106       w->options = m_split_context;
0107       w->options.enable(split_id);
0108       ok = true;
0109       break;
0110     }
0111       }
0112       if ( !ok )   {
0113     error("+++ Missing processor for split ID: %08ld", split_id);
0114     bad = true;
0115       }
0116     }
0117     if ( bad )   {
0118       except("+++ If you add processors by hand, do it properly! "
0119          "Otherwise use the property 'processor_type'. "
0120          "This setup is invalid.");
0121     }
0122     return;
0123   }
0124   /// IF NOT:
0125   /// 2) Create the processors using the 'processor_type' option
0126   for( auto id : m_splits )   {
0127     ::snprintf(text, sizeof(text), "_%05X", id);
0128     std::string nam = this->name() + text;
0129     auto* proc = createAction<DigiContainerProcessor>(m_processor_type, m_kernel, nam);
0130     if ( !proc )   {
0131       except("+++ Failed to create split worker: %s/%s", m_processor_type.c_str(), nam.c_str());
0132     }
0133     info("+++ Created worker: %s layer: %d", nam.c_str(), id);
0134     auto* w = new worker_t(proc, m_split_context);
0135     w->options.enable(id);
0136     m_workers.insert(w);
0137   }
0138   info("+++ Detector splitter is now fully initialized!");
0139 }
0140 
0141 /// Adopt new parallel worker handling a single split identifier
0142 void DigiSegmentSplitter::adopt_segment_processor(DigiContainerProcessor* action, int split_id)   {
0143   if ( !action )  {
0144     except("+++ adopt_segment_processor: FAILED attempt to add invalid processor!");
0145   }
0146   auto* w = new worker_t(action, m_split_context);
0147   w->options.enable(split_id);
0148   m_workers.insert(w);
0149 }
0150 
0151 /// Adopt new parallel worker handling multiple split-identifiers
0152 void DigiSegmentSplitter::adopt_segment_processor(DigiContainerProcessor* action, const std::vector<int>&  ids)   {
0153   for( int split_id : ids )
0154     adopt_segment_processor(action, split_id);
0155 }
0156 
0157 /// Main functional callback
0158 void DigiSegmentSplitter::execute(context_t& context, work_t& work, const predicate_t& /* predicate */)  const    {
0159   Key key = work.input_key();
0160   Key unmasked_key;
0161   unmasked_key.set_item(key.item());
0162   if ( std::find(m_keys.begin(), m_keys.end(), unmasked_key) != m_keys.end() )   {
0163     if ( work.has_input() )   {
0164       info("%s+++ Got hit collection %04X %08X. Prepare processors for %sparallel execution.",
0165        context.event->id(), key.mask(), key.item(), m_parallel ? "" : "NON-");
0166       m_kernel.submit(context, m_workers.get_group(), m_workers.size(), &work, m_parallel);
0167     }
0168   }
0169 }