Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:17:13

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/DigiPlugins.h>
0020 #include <DDDigi/DigiAttenuator.h>
0021 
0022 /// C/C++ include files
0023 #include <cmath>
0024 
0025 using namespace dd4hep::digi;
0026 
0027 /// Exponential decay depending on time offset(t0) and mean signal decay time
0028 double DigiAttenuationTool::exponential(double t0, double decay_time)  const   {
0029   return std::exp(-1e0 * std::abs(t0)/decay_time);
0030 }
0031 
0032 /// Standard constructor
0033 DigiAttenuator::DigiAttenuator(const DigiKernel& krnl, const std::string& nam)
0034   : DigiContainerProcessor(krnl, nam)
0035 {
0036   declareProperty("factor", m_factor);
0037   InstanceCount::increment(this);
0038 }
0039 
0040 /// Default destructor
0041 DigiAttenuator::~DigiAttenuator() {
0042   InstanceCount::decrement(this);
0043 }
0044 
0045 /// Attenuator callback for single container
0046 template <typename T> std::size_t
0047 DigiAttenuator::attenuate(T& cont, const predicate_t& predicate) const {
0048   for( auto& dep : cont )   {
0049     if ( predicate(dep) )   {
0050       dep.second.deposit *= m_factor;
0051       auto& e = dep.second.history;
0052       for( auto& h : e.hits ) h.weight *= m_factor;
0053       for( auto& h : e.particles ) h.weight *= m_factor;
0054     }
0055   }
0056   return cont.size();
0057 }
0058 
0059 /// Attenuator callback for single container
0060 template <> std::size_t
0061 DigiAttenuator::attenuate<DetectorHistory>(DetectorHistory& cont, const predicate_t& /* predicate */) const {
0062   for( auto& history : cont )   {
0063     auto& entry = history.second;
0064     for( auto& h : entry.hits ) h.weight *= m_factor;
0065     for( auto& h : entry.particles ) h.weight *= m_factor;
0066   }
0067   return cont.size();
0068 }
0069 
0070 /// Main functional callback adapter
0071 void DigiAttenuator::execute(DigiContext& context, work_t& work, const predicate_t& predicate)  const   {
0072   std::size_t count = 0;
0073   if ( auto* m = work.get_input<DepositMapping>() )
0074     count = this->attenuate(*m, predicate);
0075   else if ( auto* v = work.get_input<DepositVector>() )
0076     count = this->attenuate(*v, predicate);
0077   else if ( auto* h = work.get_input<DetectorHistory>() )
0078     count = this->attenuate(*h, predicate);
0079   Key key { work.input.key };
0080   std::string nam = Key::key_name(key)+":";
0081   info("%s+++ %-32s mask:%04X item: %08X Attenuated %6ld hits by %8.5f",
0082     context.event->id(), nam.c_str(), key.mask(), key.item(), count, m_factor); 
0083 }
0084 
0085 /// Standard constructor
0086 DigiAttenuatorSequence::DigiAttenuatorSequence(const DigiKernel& krnl, const std::string& nam)
0087   : DigiContainerSequenceAction(krnl, nam)
0088 {
0089   declareProperty("processor_type",    m_processor_type = "DigiAttenuator");
0090   declareProperty("containers",        m_container_attenuation);
0091   declareProperty("signal_decay",      m_signal_decay = "exponential");
0092   declareProperty("t0",                m_t0);
0093   InstanceCount::increment(this);
0094 }
0095 
0096 /// Default destructor
0097 DigiAttenuatorSequence::~DigiAttenuatorSequence() {
0098   InstanceCount::decrement(this);
0099 }
0100 
0101 /// Initialization callback
0102 void DigiAttenuatorSequence::initialize()   {
0103   DigiAttenuationTool tool;
0104   if ( m_container_attenuation.empty() )   {
0105     warning("+++ No input containers given for attenuation action -- no action taken");
0106     return;
0107   }
0108   for ( const auto& c : m_container_attenuation )   {
0109     double factor = 0e0;
0110     switch( ::toupper(m_signal_decay[0]) )   {
0111     case 'E':
0112       factor = tool.exponential(m_t0, c.second);
0113       break;
0114     default:
0115       except("+++ The attenuation function '%s' is not supported ---> STOP", 
0116          m_signal_decay.c_str());
0117       break;
0118     }
0119     // Attenuate the signal
0120     std::string nam = name() + ".D." + c.first;
0121     auto* att = createAction<DigiAttenuator>(m_processor_type, m_kernel, nam);
0122     if ( !att )   {
0123       except("+++ Failed to create signal attenuator: %s of type: %s",
0124          nam.c_str(), m_processor_type.c_str());
0125     }
0126     att->property("factor").set(factor);
0127     att->property("OutputLevel").set(int(outputLevel()));
0128     adopt_processor(att, c.first);
0129     att->release(); // Release processor **after** adoption.
0130   }
0131   this->DigiContainerSequenceAction::initialize();
0132 }
0133 
0134 /// Main functional callback
0135 void DigiAttenuatorSequence::execute(DigiContext& context)  const    {
0136   this->DigiContainerSequenceAction::execute(context);
0137 }