File indexing completed on 2025-08-05 08:18:13
0001
0002
0003 #include "PHG4MvtxDigitizer.h"
0004
0005
0006 #include <trackbase/TrkrDefs.h>
0007 #include <trackbase/TrkrHit.h> // for TrkrHit
0008 #include <trackbase/TrkrHitSet.h>
0009 #include <trackbase/TrkrHitSetContainer.h>
0010 #include <trackbase/TrkrHitTruthAssoc.h>
0011
0012 #include <g4detectors/PHG4CylinderGeom.h>
0013 #include <g4detectors/PHG4CylinderGeomContainer.h>
0014
0015 #include <fun4all/Fun4AllReturnCodes.h>
0016 #include <fun4all/SubsysReco.h> // for SubsysReco
0017
0018 #include <phool/PHCompositeNode.h>
0019 #include <phool/PHNode.h> // for PHNode
0020 #include <phool/PHNodeIterator.h>
0021 #include <phool/PHRandomSeed.h>
0022 #include <phool/getClass.h>
0023 #include <phool/phool.h> // for PHWHERE
0024
0025 #include <gsl/gsl_rng.h> // for gsl_rng_alloc
0026
0027 #include <cstdlib> // for exit
0028 #include <iostream>
0029 #include <set>
0030
0031 PHG4MvtxDigitizer::PHG4MvtxDigitizer(const std::string &name)
0032 : SubsysReco(name)
0033 , _energy_threshold(0.95e-6)
0034 {
0035 unsigned int seed = PHRandomSeed();
0036 std::cout << Name() << " random seed: " << seed << std::endl;
0037 RandomGenerator = gsl_rng_alloc(gsl_rng_mt19937);
0038 gsl_rng_set(RandomGenerator, seed);
0039
0040 if (Verbosity() > 0)
0041 {
0042 std::cout << "Creating PHG4MvtxDigitizer with name = " << name << std::endl;
0043 }
0044 }
0045
0046 PHG4MvtxDigitizer::~PHG4MvtxDigitizer()
0047 {
0048 gsl_rng_free(RandomGenerator);
0049 }
0050
0051 int PHG4MvtxDigitizer::InitRun(PHCompositeNode *topNode)
0052 {
0053
0054
0055
0056 PHNodeIterator iter(topNode);
0057
0058
0059 PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
0060 if (!dstNode)
0061 {
0062 std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl;
0063 return Fun4AllReturnCodes::ABORTRUN;
0064 }
0065
0066 CalculateMvtxLadderCellADCScale(topNode);
0067
0068
0069
0070
0071
0072 if (Verbosity() > 0)
0073 {
0074 std::cout << "====================== PHG4MvtxDigitizer::InitRun() =====================" << std::endl;
0075 for (auto &miter : _max_adc)
0076 {
0077 std::cout << " Max ADC in Layer #" << miter.first << " = " << miter.second << std::endl;
0078 }
0079 for (auto &miter : _energy_scale)
0080 {
0081 std::cout << " Energy per ADC in Layer #" << miter.first << " = " << 1.0e6 * miter.second << " keV" << std::endl;
0082 }
0083 std::cout << "===========================================================================" << std::endl;
0084 }
0085
0086 return Fun4AllReturnCodes::EVENT_OK;
0087 }
0088
0089 int PHG4MvtxDigitizer::process_event(PHCompositeNode *topNode)
0090 {
0091
0092 DigitizeMvtxLadderCells(topNode);
0093
0094 return Fun4AllReturnCodes::EVENT_OK;
0095 }
0096
0097 void PHG4MvtxDigitizer::CalculateMvtxLadderCellADCScale(PHCompositeNode *topNode)
0098 {
0099
0100
0101 PHG4CylinderGeomContainer *geom_container = findNode::getClass<PHG4CylinderGeomContainer>(topNode, "CYLINDERGEOM_MVTX");
0102
0103 if (!geom_container)
0104 {
0105 return;
0106 }
0107
0108 if (Verbosity())
0109 {
0110 std::cout << "Found CYLINDERGEOM_MVTX node" << std::endl;
0111 }
0112
0113 PHG4CylinderGeomContainer::ConstRange layerrange = geom_container->get_begin_end();
0114 for (PHG4CylinderGeomContainer::ConstIterator layeriter = layerrange.first;
0115 layeriter != layerrange.second;
0116 ++layeriter)
0117 {
0118 int layer = layeriter->second->get_layer();
0119 float thickness = (layeriter->second)->get_pixel_thickness();
0120 float pitch = (layeriter->second)->get_pixel_x();
0121 float length = (layeriter->second)->get_pixel_z();
0122
0123 float minpath = pitch;
0124 if (length < minpath)
0125 {
0126 minpath = length;
0127 }
0128 if (thickness < minpath)
0129 {
0130 minpath = thickness;
0131 }
0132 float mip_e = 0.003876 * minpath;
0133
0134 if (Verbosity())
0135 {
0136 std::cout << "mip_e = " << mip_e << std::endl;
0137 }
0138
0139 if (_max_adc.find(layer) == _max_adc.end())
0140 {
0141
0142 _max_adc[layer] = 255;
0143 _energy_scale[layer] = mip_e / 64;
0144 }
0145 }
0146
0147 return;
0148 }
0149
0150 void PHG4MvtxDigitizer::DigitizeMvtxLadderCells(PHCompositeNode *topNode)
0151 {
0152
0153
0154
0155
0156
0157
0158
0159 TrkrHitSetContainer *trkrhitsetcontainer = findNode::getClass<TrkrHitSetContainer>(topNode, "TRKR_HITSET");
0160 if (!trkrhitsetcontainer)
0161 {
0162 std::cout << "Could not locate TRKR_HITSET node, quit! " << std::endl;
0163 exit(1);
0164 }
0165
0166
0167 auto hittruthassoc = findNode::getClass<TrkrHitTruthAssoc>(topNode, "TRKR_HITTRUTHASSOC");
0168
0169
0170
0171
0172 TrkrHitSetContainer::ConstRange hitset_range = trkrhitsetcontainer->getHitSets(TrkrDefs::TrkrId::mvtxId);
0173 for (TrkrHitSetContainer::ConstIterator hitset_iter = hitset_range.first;
0174 hitset_iter != hitset_range.second;
0175 ++hitset_iter)
0176 {
0177
0178
0179 TrkrDefs::hitsetkey hitsetkey = hitset_iter->first;
0180 int layer = TrkrDefs::getLayer(hitsetkey);
0181 if (Verbosity() > 1)
0182 {
0183 std::cout << "PHG4MvtxDigitizer: found hitset with key: " << hitsetkey << " in layer " << layer << std::endl;
0184 }
0185
0186
0187 TrkrHitSet *hitset = hitset_iter->second;
0188 TrkrHitSet::ConstRange hit_range = hitset->getHits();
0189 std::set<TrkrDefs::hitkey> hits_rm;
0190 for (TrkrHitSet::ConstIterator hit_iter = hit_range.first;
0191 hit_iter != hit_range.second;
0192 ++hit_iter)
0193 {
0194 TrkrHit *hit = hit_iter->second;
0195
0196
0197
0198 if (Verbosity() > 0)
0199 {
0200 std::cout << " PHG4MvtxDigitizer: found hit with key: " << hit_iter->first << " and signal " << hit->getEnergy() / TrkrDefs::MvtxEnergyScaleup << " in layer " << layer << std::endl;
0201 }
0202
0203 bool rm_hit = false;
0204 if ((hit->getEnergy() / TrkrDefs::MvtxEnergyScaleup) < _energy_threshold)
0205 {
0206 if (Verbosity() > 0)
0207 {
0208 std::cout << " remove hit, below energy threshold of " << _energy_threshold << std::endl;
0209 }
0210 rm_hit = true;
0211 }
0212 unsigned short adc = (unsigned short) (hit->getEnergy() / (TrkrDefs::MvtxEnergyScaleup * _energy_scale[layer]));
0213 if (adc > _max_adc[layer])
0214 {
0215 adc = _max_adc[layer];
0216 }
0217 hit->setAdc(adc);
0218
0219 if (rm_hit)
0220 {
0221 hits_rm.insert(hit_iter->first);
0222 }
0223 }
0224
0225 for (const auto &key : hits_rm)
0226 {
0227 if (Verbosity() > 0)
0228 {
0229 std::cout << " PHG4MvtxDigitizer: remove hit with key: " << key << std::endl;
0230 }
0231 hitset->removeHit(key);
0232 if (hittruthassoc)
0233 {
0234 hittruthassoc->removeAssoc(hitsetkey, key);
0235 }
0236 }
0237 }
0238
0239
0240
0241
0242 return;
0243 }