File indexing completed on 2025-08-06 08:19:25
0001
0002
0003
0004
0005
0006 #include "PHG4MicromegasDigitizer.h"
0007
0008
0009 #include <trackbase/TrkrDefs.h>
0010 #include <trackbase/TrkrHit.h>
0011 #include <trackbase/TrkrHitSet.h>
0012 #include <trackbase/TrkrHitSetContainer.h>
0013 #include <trackbase/TrkrHitTruthAssoc.h>
0014
0015 #include <phparameter/PHParameterInterface.h> // for PHParameterInterface
0016
0017 #include <fun4all/Fun4AllReturnCodes.h>
0018 #include <fun4all/SubsysReco.h>
0019
0020 #include <phool/PHRandomSeed.h>
0021 #include <phool/getClass.h>
0022
0023 #include <gsl/gsl_randist.h>
0024 #include <gsl/gsl_rng.h> // for gsl_rng_alloc, gsl_rng...
0025
0026 #include <cassert>
0027 #include <iostream> // for operator<<, basic_ostream
0028 #include <set>
0029 #include <utility> // for pair
0030
0031 namespace
0032 {
0033
0034
0035 template <class T>
0036 constexpr const T& clamp(const T& v, const T& lo, const T& hi)
0037 {
0038 return (v < lo) ? lo : (hi < v) ? hi
0039 : v;
0040 }
0041
0042 }
0043
0044 PHG4MicromegasDigitizer::PHG4MicromegasDigitizer(const std::string& name)
0045 : SubsysReco(name)
0046 , PHParameterInterface(name)
0047 {
0048
0049 const unsigned int seed = PHRandomSeed();
0050 m_rng.reset(gsl_rng_alloc(gsl_rng_mt19937));
0051 gsl_rng_set(m_rng.get(), seed);
0052
0053 InitializeParameters();
0054 }
0055
0056
0057 int PHG4MicromegasDigitizer::InitRun(PHCompositeNode* )
0058 {
0059 UpdateParametersWithMacro();
0060
0061
0062 m_adc_threshold = get_double_param("micromegas_adc_threshold");
0063 m_enc = get_double_param("micromegas_enc");
0064 m_pedestal = get_double_param("micromegas_pedestal");
0065 m_volts_per_charge = get_double_param("micromegas_volts_per_charge");
0066
0067
0068 std::cout
0069 << "PHG4MicromegasDigitizer::InitRun\n"
0070 << " m_adc_threshold: " << m_adc_threshold << " electrons\n"
0071 << " m_enc: " << m_enc << " electrons\n"
0072 << " m_pedestal: " << m_pedestal << " electrons\n"
0073 << " m_volts_per_charge: " << m_volts_per_charge << " mV/fC\n"
0074 << std::endl;
0075
0076
0077 m_adc_threshold += m_pedestal;
0078
0079
0080
0081
0082
0083
0084
0085 m_volt_per_electron_signal = m_volts_per_charge * 1.602e-4 * 2.4;
0086 m_volt_per_electron_noise = m_volts_per_charge * 1.602e-4;
0087
0088 return Fun4AllReturnCodes::EVENT_OK;
0089 }
0090
0091
0092 int PHG4MicromegasDigitizer::process_event(PHCompositeNode* topNode)
0093 {
0094
0095
0096 auto trkrhitsetcontainer = findNode::getClass<TrkrHitSetContainer>(topNode, "TRKR_HITSET");
0097 assert(trkrhitsetcontainer);
0098
0099
0100 auto hittruthassoc = findNode::getClass<TrkrHitTruthAssoc>(topNode, "TRKR_HITTRUTHASSOC");
0101
0102
0103 const auto hitset_range = trkrhitsetcontainer->getHitSets(TrkrDefs::TrkrId::micromegasId);
0104 for (auto hitset_it = hitset_range.first; hitset_it != hitset_range.second; ++hitset_it)
0105 {
0106
0107 const TrkrDefs::hitsetkey hitsetkey = hitset_it->first;
0108
0109
0110 TrkrHitSet* hitset = hitset_it->second;
0111 TrkrHitSet::ConstRange hit_range = hitset->getHits();
0112
0113
0114 std::set<TrkrDefs::hitkey> removed_keys;
0115
0116
0117 for (auto hit_it = hit_range.first; hit_it != hit_range.second; ++hit_it)
0118 {
0119
0120 const TrkrDefs::hitkey& key = hit_it->first;
0121 TrkrHit* hit = hit_it->second;
0122
0123
0124 const double signal = hit->getEnergy();
0125 const double noise = add_noise();
0126
0127
0128 const double voltage = (m_pedestal + noise) * m_volt_per_electron_noise + signal * m_volt_per_electron_signal;
0129
0130
0131 if (voltage > m_adc_threshold * m_volt_per_electron_noise)
0132 {
0133
0134 hit->setAdc(clamp<uint>(voltage * m_adc_per_volt, 0, 1023));
0135 }
0136 else
0137 {
0138
0139 removed_keys.insert(key);
0140 }
0141 }
0142
0143
0144 for (const auto& key : removed_keys)
0145 {
0146 hitset->removeHit(key);
0147 if (hittruthassoc)
0148 {
0149 hittruthassoc->removeAssoc(hitsetkey, key);
0150 }
0151 }
0152 }
0153 return Fun4AllReturnCodes::EVENT_OK;
0154 }
0155
0156
0157 void PHG4MicromegasDigitizer::SetDefaultParameters()
0158 {
0159
0160 set_default_double_param("micromegas_enc", 670);
0161 set_default_double_param("micromegas_adc_threshold", 2680);
0162 set_default_double_param("micromegas_pedestal", 50000);
0163 set_default_double_param("micromegas_volts_per_charge", 20);
0164 }
0165
0166
0167 double PHG4MicromegasDigitizer::add_noise() const
0168 {
0169 return gsl_ran_gaussian(m_rng.get(), m_enc);
0170 }