File indexing completed on 2025-08-06 08:17:53
0001
0002
0003
0004
0005
0006 #include "MicromegasCombinedDataDecoder.h"
0007 #include "MicromegasDefs.h"
0008
0009 #include <trackbase/TrkrHitSet.h>
0010 #include <trackbase/TrkrHitSetContainerv1.h>
0011 #include <trackbase/TrkrHitv2.h>
0012
0013 #include <ffarawobjects/MicromegasRawHit.h>
0014 #include <ffarawobjects/MicromegasRawHitContainer.h>
0015
0016 #include <fun4all/Fun4AllReturnCodes.h>
0017 #include <fun4all/Fun4AllServer.h>
0018
0019 #include <phool/PHCompositeNode.h>
0020 #include <phool/PHNodeIterator.h>
0021 #include <phool/getClass.h>
0022
0023 #include <algorithm>
0024 #include <cassert>
0025 #include <memory>
0026
0027 namespace
0028 {
0029
0030
0031
0032
0033 bool channel_is_permanently_masked( int fee_id, int channel )
0034 { return fee_id==8 && channel>=128; }
0035
0036 }
0037
0038
0039 MicromegasCombinedDataDecoder::MicromegasCombinedDataDecoder(const std::string& name)
0040 : SubsysReco(name)
0041 {
0042 }
0043
0044
0045 int MicromegasCombinedDataDecoder::Init(PHCompositeNode* )
0046 {
0047
0048 std::cout
0049 << "MicromegasCombinedDataDecoder::Init -"
0050 << " m_calibration_filename: "
0051 << (m_calibration_filename.empty() ? "unspecified" : m_calibration_filename)
0052 << std::endl;
0053
0054 std::cout
0055 << "MicromegasCombinedDataDecoder::Init -"
0056 << " m_hot_channel_map_filename: "
0057 << (m_hot_channel_map_filename.empty() ? "unspecified" : m_hot_channel_map_filename)
0058 << std::endl;
0059
0060 std::cout << "MicromegasCombinedDataDecoder::Init - m_n_sigma: " << m_n_sigma << std::endl;
0061 std::cout << "MicromegasCombinedDataDecoder::Init - m_min_adc: " << m_min_adc << std::endl;
0062 std::cout << "MicromegasCombinedDataDecoder::Init - m_sample_min: " << m_sample_min << std::endl;
0063 std::cout << "MicromegasCombinedDataDecoder::Init - m_sample_max: " << m_sample_max << std::endl;
0064
0065
0066 m_calibration_data.read(m_calibration_filename);
0067
0068
0069 if (!m_hot_channel_map_filename.empty())
0070 {
0071 m_hot_channels.read(m_hot_channel_map_filename);
0072 }
0073
0074 return Fun4AllReturnCodes::EVENT_OK;
0075 }
0076
0077
0078 int MicromegasCombinedDataDecoder::InitRun(PHCompositeNode* topNode)
0079 {
0080
0081 PHNodeIterator iter(topNode);
0082 auto dstNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "DST"));
0083 if (!dstNode)
0084 {
0085 std::cout << "MicromegasCombinedDataDecoder::InitRun - DST Node missing, doing nothing." << std::endl;
0086 exit(1);
0087 }
0088
0089
0090 auto hitsetcontainer = findNode::getClass<TrkrHitSetContainer>(topNode, "TRKR_HITSET");
0091 if (!hitsetcontainer)
0092 {
0093 std::cout << "MicromegasCombinedDataDecoder::InitRun - creating TRKR_HITSET." << std::endl;
0094
0095
0096 PHNodeIterator dstiter(dstNode);
0097 auto trkrnode = dynamic_cast<PHCompositeNode*>(dstiter.findFirst("PHCompositeNode", "TRKR"));
0098 if (!trkrnode)
0099 {
0100 trkrnode = new PHCompositeNode("TRKR");
0101 dstNode->addNode(trkrnode);
0102 }
0103
0104
0105 hitsetcontainer = new TrkrHitSetContainerv1;
0106 auto newNode = new PHIODataNode<PHObject>(hitsetcontainer, "TRKR_HITSET", "PHObject");
0107 trkrnode->addNode(newNode);
0108 }
0109 auto rawhitcontainer = findNode::getClass<MicromegasRawHitContainer>(topNode, m_rawhitnodename);
0110 if(!rawhitcontainer)
0111 {
0112 Fun4AllServer* se = Fun4AllServer::instance();
0113 se->unregisterSubsystem(this);
0114 std::cout << PHWHERE << "Removing TPOT unpacker, no raw hit container" << std::endl;
0115 }
0116
0117 return Fun4AllReturnCodes::EVENT_OK;
0118 }
0119
0120
0121 int MicromegasCombinedDataDecoder::process_event(PHCompositeNode* topNode)
0122 {
0123
0124
0125 auto trkrhitsetcontainer = findNode::getClass<TrkrHitSetContainer>(topNode, "TRKR_HITSET");
0126 assert(trkrhitsetcontainer);
0127
0128
0129 auto rawhitcontainer = findNode::getClass<MicromegasRawHitContainer>(topNode, m_rawhitnodename);
0130 assert(rawhitcontainer);
0131
0132
0133 if (Verbosity())
0134 {
0135 std::cout << "MicromegasCombinedDataDecoder::process_event - hits: " << rawhitcontainer->get_nhits() << std::endl;
0136 }
0137
0138 int n_signal_hits = 0;
0139
0140 bool first = true;
0141 uint64_t first_lvl1_bco = 0;
0142
0143 for (unsigned int ihit = 0; ihit < rawhitcontainer->get_nhits(); ++ihit)
0144 {
0145 const auto rawhit = rawhitcontainer->get_hit(ihit);
0146 const auto packet_id = rawhit->get_packetid();
0147
0148 if (first)
0149 {
0150 first = false;
0151 first_lvl1_bco = rawhit->get_gtm_bco();
0152 }
0153
0154
0155 if (std::find(std::begin(MicromegasDefs::m_packet_ids), std::end(MicromegasDefs::m_packet_ids), packet_id) == std::end(MicromegasDefs::m_packet_ids))
0156 {
0157 std::cout << "MicromegasCombinedDataDecoder::process_event - invalid packet: " << packet_id << std::endl;
0158 continue;
0159 }
0160
0161
0162 const int fee = m_mapping.get_new_fee_id(rawhit->get_fee());
0163 const auto channel = rawhit->get_channel();
0164
0165
0166 if( channel_is_permanently_masked(fee, channel ))
0167 {
0168 continue;
0169 }
0170
0171
0172
0173 const TrkrDefs::hitsetkey hitsetkey = m_mapping.get_hitsetkey(fee);
0174 if (!hitsetkey)
0175 {
0176 continue;
0177 }
0178
0179
0180 int layer = int(TrkrDefs::getLayer(hitsetkey));
0181 int tile = int(MicromegasDefs::getTileId(hitsetkey));
0182 int strip = m_mapping.get_physical_strip(fee, channel);
0183 if (strip < 0)
0184 {
0185 continue;
0186 }
0187
0188
0189 if (m_hot_channels.is_hot_channel(layer, tile, strip))
0190 {
0191 continue;
0192 }
0193
0194
0195 const double pedestal = m_calibration_data.get_pedestal(fee, channel);
0196 const double rms = m_calibration_data.get_rms(fee, channel);
0197
0198
0199 if (rms <= 0)
0200 {
0201 continue;
0202 }
0203
0204
0205 const auto sample_range = std::make_pair(rawhit->get_sample_begin(), rawhit->get_sample_end());
0206 std::vector<uint16_t> adc_list;
0207 for (auto is = std::max(m_sample_min, sample_range.first); is < std::min(m_sample_max, sample_range.second); ++is)
0208 {
0209 const uint16_t adc = rawhit->get_adc(is);
0210 if (adc != MicromegasDefs::m_adc_invalid)
0211 {
0212 adc_list.push_back(adc);
0213 }
0214 }
0215
0216 if (adc_list.empty())
0217 {
0218 continue;
0219 }
0220
0221
0222
0223 auto max_adc = *std::max_element(adc_list.begin(), adc_list.end());
0224
0225
0226 if (max_adc < m_min_adc)
0227 {
0228 continue;
0229 }
0230
0231
0232 if (max_adc < pedestal + m_n_sigma * rms)
0233 {
0234 continue;
0235 }
0236
0237 if (Verbosity())
0238 {
0239 const auto bco = rawhit->get_gtm_bco();
0240 std::cout << "MicromegasCombinedDataDecoder::process_event -"
0241 << " bco: " << bco
0242 << " layer: " << layer
0243 << " tile: " << tile
0244 << " channel: " << channel
0245 << " strip: " << strip
0246 << " adc: " << max_adc
0247 << std::endl;
0248 }
0249
0250
0251 const auto hitset_it = trkrhitsetcontainer->findOrAddHitSet(hitsetkey);
0252
0253
0254 const TrkrDefs::hitkey hitkey = MicromegasDefs::genHitKey(strip);
0255
0256
0257 auto hit = hitset_it->second->getHit(hitkey);
0258 if (hit)
0259 {
0260
0261 continue;
0262 }
0263
0264
0265 hit = new TrkrHitv2;
0266 hit->setAdc(max_adc);
0267 hitset_it->second->addHitSpecificKey(hitkey, hit);
0268
0269
0270 ++m_hitcounts[hitsetkey];
0271 ++n_signal_hits;
0272 }
0273
0274 if (Verbosity())
0275 {
0276 std::cout << "MicromegasCombinedDataDecoder::process_event - BCO: " << first_lvl1_bco << " n_signal_hits: " << n_signal_hits << std::endl;
0277 }
0278
0279 return Fun4AllReturnCodes::EVENT_OK;
0280 }
0281
0282
0283 int MicromegasCombinedDataDecoder::End(PHCompositeNode* )
0284 {
0285
0286 {
0287 for (const auto& [hitsetkey, count] : m_hitcounts)
0288 {
0289 std::cout << "MicromegasCombinedDataDecoder::End - hitsetkey: " << hitsetkey << ", hit count: " << count << std::endl;
0290 }
0291 }
0292
0293 return Fun4AllReturnCodes::EVENT_OK;
0294 }