File indexing completed on 2025-01-18 09:14:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
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
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
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
0057 if ( std::any_cast<DepositMapping>(work[i]) )
0058 work[i]->reset();
0059
0060 else if ( std::any_cast<DepositVector>(work[i]) )
0061 work[i]->reset();
0062
0063 else if ( std::any_cast<ParticleMapping>(work[i]) )
0064 work[i]->reset();
0065
0066 else if ( std::any_cast<DetectorHistory>(work[i]) )
0067 work[i]->reset();
0068
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
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
0107 DigiContainerDrop::~DigiContainerDrop() {
0108 InstanceCount::decrement(this);
0109 }
0110
0111
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
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
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();
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 }