Back to home page

EIC code displayed by LXR

 
 

    


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

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/InstanceCount.h>
0016 #include <DDDigi/DigiData.h>
0017 #include <DDDigi/DigiKernel.h>
0018 #include <DDDigi/DigiContext.h>
0019 #include <DDDigi/DigiContainerDrop.h>
0020 
0021 /// C/C++ include files
0022 #include <set>
0023 
0024 using namespace dd4hep::digi;
0025 
0026 class DigiContainerDrop::work_definition_t  {
0027 public:
0028   const DigiContainerDrop* drop;
0029   std::vector<Key>            keys;
0030   std::vector<std::any*>      work;
0031   std::set<Key::itemkey_type> items;
0032 
0033   DigiEvent&                  event;
0034   DataSegment&                inputs;
0035 
0036   /// Initializing constructor
0037   work_definition_t(const DigiContainerDrop* c, DigiEvent& ev, DataSegment& in)
0038     : drop(c), event(ev), inputs(in)
0039   {
0040     keys.reserve(inputs.size());
0041     work.reserve(inputs.size());
0042     for( auto& i : inputs )   {
0043       Key  key(i.first);
0044       if ( drop->use_key(key) )   {
0045     keys.emplace_back(key);
0046     work.emplace_back(&i.second);
0047     items.insert(key.item());
0048       }
0049     }
0050   }
0051 
0052   void drop_one(Key::itemkey_type itm)   {
0053     for( std::size_t i=0; i < keys.size(); ++i )   {
0054       if ( keys[i].item() != itm )
0055     continue;
0056       /// Drop deposit mapping
0057       if (      std::any_cast<DepositMapping>(work[i]) )
0058     work[i]->reset();
0059       /// Drop deposit vector
0060       else if ( std::any_cast<DepositVector>(work[i]) )
0061     work[i]->reset();
0062       /// Drop particle container
0063       else if ( std::any_cast<ParticleMapping>(work[i]) )
0064     work[i]->reset();
0065       /// Drop deposit history
0066       else if ( std::any_cast<DetectorHistory>(work[i]) )
0067     work[i]->reset();
0068       /// Drop detector response
0069       else if ( std::any_cast<DetectorResponse>(work[i]) )
0070     work[i]->reset();
0071       break;
0072     }
0073   }
0074 
0075   void drop_all()   {
0076     for( auto itm : items )
0077       drop_one(itm);
0078   }
0079 };
0080 
0081 template <> void DigiParallelWorker<DigiContainerDrop,
0082                     DigiContainerDrop::work_definition_t,
0083                     std::size_t>::execute(void* data) const  {
0084   calldata_t* args = reinterpret_cast<calldata_t*>(data);
0085   std::size_t cnt = 0;
0086   for( auto itm : args->items )  {
0087     if ( cnt == this->options )   {
0088       args->drop_one(itm);
0089       return;
0090     }
0091     ++cnt;
0092   }
0093 }
0094 
0095 /// Standard constructor
0096 DigiContainerDrop::DigiContainerDrop(const DigiKernel& krnl, const std::string& nam)
0097   : DigiEventAction(krnl, nam)
0098 {
0099   declareProperty("containers",       m_containers);
0100   declareProperty("input_masks",      m_input_masks);
0101   declareProperty("input_segment",    m_input_segment = "inputs");
0102   m_kernel.register_initialize(std::bind(&DigiContainerDrop::initialize,this));
0103   InstanceCount::increment(this);
0104 }
0105 
0106 /// Default destructor
0107 DigiContainerDrop::~DigiContainerDrop() {
0108   InstanceCount::decrement(this);
0109 }
0110 
0111 /// Initializing function: compute values which depend on properties
0112 void DigiContainerDrop::initialize()    {
0113   for ( const auto& cont : m_containers )   {
0114     Key key(cont, 0x0);
0115     m_cont_keys.emplace(key.item());
0116     if ( m_input_masks.empty() )   {
0117       m_keys.emplace(key.item());
0118       continue;
0119     }
0120     for ( int m : m_input_masks )    {
0121       key.set_mask(m);
0122       m_keys.emplace(key.value());
0123     }
0124   }
0125 }
0126 
0127 /// Decide if a continer is to dropd based on the properties
0128 bool DigiContainerDrop::use_key(Key key)  const   {
0129   const auto& m = m_input_masks;
0130   bool use = m.empty() || m_keys.empty();
0131   if ( !use )  {
0132     if ( m_cont_keys.empty() )   {
0133       return m.empty() || std::find(m.begin(), m.end(), key.mask()) != m.end();
0134     }
0135     use = m_cont_keys.find(key.item()) != m_cont_keys.end();
0136     if ( use )   {
0137       return m.empty() || std::find(m.begin(), m.end(), key.mask()) != m.end();
0138     }
0139     return false;
0140   }
0141   return true;
0142 }
0143 
0144 /// Main functional callback
0145 void DigiContainerDrop::execute(DigiContext& context)  const    {
0146   auto& event    = *context.event;
0147   auto& inputs   = event.get_segment(m_input_segment);
0148   work_definition_t def(this, event, inputs);
0149   if ( m_parallel )  {
0150     size_t count = def.items.size();
0151     if ( m_workers.size() < count )   {
0152       auto group = m_workers.get_group(); // Lock worker group
0153       for(size_t i=m_workers.size(); i <= count; ++i)
0154     m_workers.insert(new worker_t(nullptr, i));
0155     }
0156     m_kernel.submit(context, m_workers.get_group(), def.items.size(), &def);
0157   }
0158   else  {
0159     def.drop_all();
0160   }
0161   for( std::size_t i=0; i != def.work.size(); ++i )   {
0162     if ( def.work[i]->type() == typeid(void) )
0163       inputs.erase(def.keys[i]);
0164   }
0165 }