File indexing completed on 2025-01-18 09:14:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <DDDigi/DigiContainerProcessor.h>
0016 #include <DDDigi/DigiKernel.h>
0017
0018 #include <DD4hep/DD4hepUnits.h>
0019 #include <DD4hep/Detector.h>
0020 #include <DD4hep/VolumeManager.h>
0021
0022
0023 #include <limits>
0024
0025
0026 namespace dd4hep {
0027
0028
0029 namespace digi {
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 class DigiDepositSmearPositionTrack : public DigiDepositsProcessor {
0040 protected:
0041
0042 double m_resolution_u { 0e0 * dd4hep::mm };
0043
0044 double m_resolution_v { 0e0 * dd4hep::mm };
0045
0046
0047 DigiDepositMonitor* m_local_monitor { nullptr };
0048
0049 public:
0050
0051 DigiDepositSmearPositionTrack(const DigiKernel& krnl, const std::string& nam)
0052 : DigiDepositsProcessor(krnl, nam)
0053 {
0054 declareProperty("resolution_u", m_resolution_u);
0055 declareProperty("resolution_v", m_resolution_v);
0056 m_kernel.register_initialize(std::bind(&DigiDepositSmearPositionTrack::initialize,this));
0057 DEPOSIT_PROCESSOR_BIND_HANDLERS(DigiDepositSmearPositionTrack::smear);
0058 }
0059
0060
0061 void initialize() {
0062 }
0063
0064
0065 template <typename T> void
0066 smear(DigiContext& context, T& cont, work_t& , const predicate_t& predicate) const {
0067 constexpr double eps = detail::numeric_epsilon;
0068 auto& random = context.randomGenerator();
0069 const auto& ev = *(context.event);
0070 std::size_t updated = 0UL;
0071
0072 VolumeManager volMgr = m_kernel.detectorDescription().volumeManager();
0073 for( auto& dep : cont ) {
0074 if ( predicate(dep) ) {
0075 CellID cell = dep.first;
0076 EnergyDeposit& depo = dep.second;
0077 auto* ctxt = volMgr.lookupContext(cell);
0078 Direction part_momentum = depo.history.average_particle_momentum(ev);
0079 Position local_pos = ctxt->worldToLocal(depo.position);
0080 Position local_dir = ctxt->worldToLocal(part_momentum).unit();
0081 double cos_u = local_dir.Dot(Position(1,0,0));
0082 double sin_u = std::sqrt(1e0 - cos_u*cos_u);
0083 double tan_u = sin_u/(std::abs(cos_u)>eps ? cos_u : eps);
0084 double delta_u = tan_u * m_resolution_u * random.gaussian();
0085
0086 double cos_v = local_dir.Dot(Position(0,1,0));
0087 double sin_v = std::sqrt(1e0 - cos_v*cos_v);
0088 double tan_v = sin_v/(std::abs(cos_v)>eps ? cos_v : eps);
0089 double delta_v = tan_v * m_resolution_v * random.gaussian();
0090
0091 Position delta_pos(delta_u, delta_v, 0e0);
0092 Position oldpos = depo.position;
0093 Position newpos = ctxt->localToWorld(local_pos + delta_pos);
0094
0095 if ( m_local_monitor ) m_local_monitor->position_shift(dep, local_pos, delta_pos);
0096 delta_pos = newpos - oldpos;
0097 if ( m_monitor ) m_monitor->position_shift(dep, oldpos, delta_pos);
0098
0099 info("%s+++ %016lX Smeared position [%9.2e %9.2e %9.2e] by [%9.2e %9.2e %9.2e] to [%9.2e %9.2e %9.2e] [mm]",
0100 ev.id(), oldpos.X(), oldpos.Y(), oldpos.Z(), delta_pos.X(), delta_pos.Y(), delta_pos.Z(),
0101 newpos.X(), newpos.Y(), newpos.Z());
0102
0103 depo.position = newpos;
0104 depo.flag |= EnergyDeposit::POSITION_SMEARED;
0105 ++updated;
0106 }
0107 }
0108 info("%s+++ %-32s Smear position(track): updated %6ld out of %6ld entries from mask: %04X",
0109 context.event->id(), cont.name.c_str(), updated, cont.size(), cont.key.mask());
0110 }
0111 };
0112 }
0113 }
0114
0115 #include <DDDigi/DigiFactories.h>
0116 DECLARE_DIGIACTION_NS(dd4hep::digi,DigiDepositSmearPositionTrack)