File indexing completed on 2025-08-05 08:15:10
0001 #include "TpcTimeFrameChecker.h"
0002
0003 #include <Event/oncsSubConstants.h>
0004 #include <Event/packet.h>
0005 #include <Event/Event.h>
0006 #include <Event/EventTypes.h>
0007 #include <Event/packet.h>
0008
0009 #include <fun4all/Fun4AllHistoManager.h>
0010
0011 #include <fun4all/Fun4AllReturnCodes.h>
0012 #include <phool/PHCompositeNode.h>
0013 #include <phool/PHIODataNode.h> // for PHIODataNode
0014 #include <phool/PHNodeIterator.h> // for PHNodeIterator
0015 #include <phool/PHObject.h> // for PHObject
0016 #include <phool/getClass.h>
0017 #include <phool/phool.h>
0018 #include <qautils/QAHistManagerDef.h>
0019
0020 #include <TAxis.h>
0021 #include <TH1.h>
0022 #include <TH2.h>
0023 #include <TNamed.h>
0024 #include <TFile.h>
0025 #include <TTree.h>
0026 #include <TString.h>
0027 #include <TVector3.h>
0028
0029 #include <stdint.h>
0030 #include <cassert>
0031 #include <memory>
0032 #include <string>
0033
0034 using namespace std;
0035
0036 TpcTimeFrameChecker::TpcTimeFrameChecker(const int packet_id)
0037 : m_packet_id(packet_id)
0038 , m_HistoPrefix("TpcTimeFrameBuilder_Packet" + to_string(packet_id))
0039 {
0040 Fun4AllHistoManager *hm = QAHistManagerDef::getHistoManager();
0041 assert(hm);
0042
0043 TH1 *h = new TH1D(TString(m_HistoPrefix.c_str()) + "_Normalization",
0044 TString(m_HistoPrefix.c_str()) + " Normalization;Items;Count", 10, .5, 10.5);
0045 int i = 1;
0046 h->GetXaxis()->SetBinLabel(i++, "Packet");
0047 h->GetXaxis()->SetBinLabel(i++, "Lv1-Taggers");
0048 h->GetXaxis()->SetBinLabel(i++, "EnDat-Taggers");
0049 h->GetXaxis()->SetBinLabel(i++, "ChannelPackets");
0050 h->GetXaxis()->SetBinLabel(i++, "Waveforms");
0051
0052 h->GetXaxis()->SetBinLabel(i++, "DMA_WORD_GTM");
0053 h->GetXaxis()->SetBinLabel(i++, "DMA_WORD_FEE");
0054 h->GetXaxis()->SetBinLabel(i++, "DMA_WORD_FEE_INVALID");
0055 h->GetXaxis()->SetBinLabel(i++, "DMA_WORD_INVALID");
0056
0057 h->GetYaxis()->SetBinLabel(i++, "TimeFrameSizeLimitError");
0058 assert(i <= 10);
0059 h->GetXaxis()->LabelsOption("v");
0060 hm->registerHisto(h);
0061
0062 h = new TH1I(TString(m_HistoPrefix.c_str()) + "_PacketLength",
0063 TString(m_HistoPrefix.c_str()) + " PacketLength;PacketLength [16bit Words];Count", 1000, .5, 5e6);
0064 hm->registerHisto(h);
0065 }
0066
0067 TpcTimeFrameChecker::~TpcTimeFrameChecker()
0068 {
0069
0070 }
0071
0072
0073
0074 int TpcTimeFrameChecker::InitRun(PHCompositeNode *)
0075 {
0076
0077 if (m_debugTTreeFile.size())
0078 {
0079 m_file = TFile::Open(m_debugTTreeFile.c_str(), "recreate");
0080 assert(m_file->IsOpen());
0081
0082 m_TaggerTree = new TTree("TaggerTree", "Each entry is one tagger for level 1 trigger or endat tag");
0083
0084 m_TaggerTree->Branch("packet", &m_packet_id, "packet/I");
0085 m_TaggerTree->Branch("RCDAQEvent", &m_frame, "frame/I");
0086
0087 }
0088
0089
0090 return Fun4AllReturnCodes::EVENT_OK;
0091 }
0092
0093
0094 int TpcTimeFrameChecker::process_event(PHCompositeNode *topNode)
0095 {
0096 Event *_event = findNode::getClass<Event>(topNode, "PRDF");
0097 if (_event == nullptr)
0098 {
0099 std::cout << "TpcTimeFrameChecker::Process_Event - Event not found" << std::endl;
0100 return -1;
0101 }
0102 if (_event->getEvtType() >= 8)
0103 {
0104 return Fun4AllReturnCodes::DISCARDEVENT;
0105 }
0106
0107 m_frame = _event->getEvtSequence();
0108
0109 std::unique_ptr<Packet> p(_event->getPacket(m_packet_id));
0110 if (!p)
0111 {
0112 if (Verbosity())
0113 {
0114 std::cout << __PRETTY_FUNCTION__ << " : missing packet " << m_packet_id << std::endl;
0115 }
0116 }
0117
0118 ProcessPacket(p.get());
0119
0120 return Fun4AllReturnCodes::EVENT_OK;
0121 }
0122
0123
0124 int TpcTimeFrameChecker::End(PHCompositeNode * )
0125 {
0126
0127 if (m_file)
0128 {
0129 m_file->Write();
0130
0131 std::cout << __PRETTY_FUNCTION__ << " : completed saving to " << m_file->GetName() << std::endl;
0132 m_file->ls();
0133
0134 m_file->Close();
0135 }
0136
0137 return Fun4AllReturnCodes::EVENT_OK;
0138 }
0139
0140
0141
0142 int TpcTimeFrameChecker::ProcessPacket(Packet *packet)
0143 {
0144 if (!packet)
0145 {
0146 cout << __PRETTY_FUNCTION__ << " Error : Invalid packet, doing nothing" << endl;
0147 assert(packet);
0148 return 0;
0149 }
0150
0151 if (packet->getHitFormat() != IDTPCFEEV4)
0152 {
0153 cout << __PRETTY_FUNCTION__ << " Error : expect packet format " << IDTPCFEEV4
0154 << " but received packet format " << packet->getHitFormat() << ":" << endl;
0155 packet->identify();
0156 assert(packet->getHitFormat() == IDTPCFEEV4);
0157 return 0;
0158 }
0159
0160 if (m_packet_id != packet->getIdentifier())
0161 {
0162 cout << __PRETTY_FUNCTION__ << " Error : mismatched packet with packet ID expectation of " << m_packet_id << ", but received";
0163 packet->identify();
0164 assert(m_packet_id == packet->getIdentifier());
0165 return 0;
0166 }
0167
0168 if (m_verbosity)
0169 {
0170 cout << __PRETTY_FUNCTION__ << " : received packet ";
0171 packet->identify();
0172 }
0173
0174 Fun4AllHistoManager *hm = QAHistManagerDef::getHistoManager();
0175 assert(hm);
0176 TH1D *h_norm = dynamic_cast<TH1D *>(hm->getHisto(
0177 m_HistoPrefix + "_Normalization"));
0178 assert(h_norm);
0179 h_norm->Fill("Packet", 1);
0180
0181 int l = packet->getDataLength() + 16;
0182 l *= 2;
0183 vector<uint16_t> buffer(l);
0184
0185 int l2 = 0;
0186
0187 packet->fillIntArray(reinterpret_cast<int *>(buffer.data()), l, &l2, "DATA");
0188 l2 -= packet->getPadding();
0189 assert(l2 >= 0);
0190 unsigned int payload_length = 2 * (unsigned int) l2;
0191
0192 TH1D *h_PacketLength = dynamic_cast<TH1D *>(hm->getHisto(
0193 m_HistoPrefix + "_PacketLength"));
0194 assert(h_PacketLength);
0195 h_PacketLength->Fill(payload_length);
0196
0197
0198 unsigned int index = 0;
0199 while (index < payload_length)
0200 {
0201 if ((buffer[index] & 0xFF00) == FEE_MAGIC_KEY)
0202 {
0203 unsigned int fee_id = buffer[index] & 0xff;
0204 ++index;
0205 if (fee_id < MAX_FEECOUNT)
0206 {
0207 for (unsigned int i = 0; i < DAM_DMA_WORD_BYTE_LENGTH - 1; i++)
0208 {
0209
0210 if (index >= payload_length)
0211 {
0212 cout << __PRETTY_FUNCTION__ << " : Error : unexpected reach at payload length at position " << index << endl;
0213 break;
0214 }
0215 }
0216 h_norm->Fill("DMA_WORD_FEE", 1);
0217 }
0218 else
0219 {
0220 cout << __PRETTY_FUNCTION__ << " : Error : Invalid FEE ID " << fee_id << " at position " << index << endl;
0221 index += DAM_DMA_WORD_BYTE_LENGTH - 1;
0222 h_norm->Fill("DMA_WORD_FEE_INVALID", 1);
0223 }
0224 }
0225 else if ((buffer[index] & 0xFF00) == GTM_MAGIC_KEY)
0226 {
0227
0228 if (index + DAM_DMA_WORD_BYTE_LENGTH > payload_length)
0229 {
0230 cout << __PRETTY_FUNCTION__ << " : Error : unexpected reach at payload length at position " << index << endl;
0231 break;
0232 }
0233 decode_gtm_data(&buffer[index]);
0234 index += DAM_DMA_WORD_BYTE_LENGTH;
0235 h_norm->Fill("DMA_WORD_GTM", 1);
0236 }
0237 else
0238 {
0239 cout << __PRETTY_FUNCTION__ << " : Error : Unknown data type at position " << index << ": " << hex << buffer[index] << dec << endl;
0240
0241 index += DAM_DMA_WORD_BYTE_LENGTH;
0242 h_norm->Fill("DMA_WORD_INVALID", 1);
0243 }
0244 }
0245
0246
0247 return Fun4AllReturnCodes::EVENT_OK;
0248 }
0249
0250
0251 int TpcTimeFrameChecker::decode_gtm_data(uint16_t dat[16])
0252 {
0253 unsigned char *gtm = reinterpret_cast<unsigned char *>(dat);
0254
0255
0256 m_payload.pkt_type = gtm[0] | ((uint16_t)gtm[1] << 8);
0257
0258 if (m_payload.pkt_type != GTM_LVL1_ACCEPT_MAGIC_KEY && m_payload.pkt_type != GTM_ENDAT_MAGIC_KEY && m_payload.pkt_type != GTM_MODEBIT_MAGIC_KEY)
0259 {
0260 return -1;
0261 }
0262
0263 m_payload.is_lvl1 = m_payload.pkt_type == GTM_LVL1_ACCEPT_MAGIC_KEY;
0264 m_payload.is_endat = m_payload.pkt_type == GTM_ENDAT_MAGIC_KEY;
0265 m_payload.is_modebit = m_payload.pkt_type == GTM_MODEBIT_MAGIC_KEY;
0266
0267 m_payload.bco = ((unsigned long long)gtm[2] << 0)
0268 | ((unsigned long long)gtm[3] << 8)
0269 | ((unsigned long long)gtm[4] << 16)
0270 | ((unsigned long long)gtm[5] << 24)
0271 | ((unsigned long long)gtm[6] << 32)
0272 | (((unsigned long long)gtm[7]) << 40);
0273 m_payload.lvl1_count = ((unsigned int)gtm[8] << 0)
0274 | ((unsigned int)gtm[9] << 8)
0275 | ((unsigned int)gtm[10] << 16)
0276 | ((unsigned int)gtm[11] << 24);
0277 m_payload.endat_count = ((unsigned int)gtm[12] << 0)
0278 | ((unsigned int)gtm[13] << 8)
0279 | ((unsigned int)gtm[14] << 16)
0280 | ((unsigned int)gtm[15] << 24);
0281 m_payload.last_bco = ((unsigned long long)gtm[16] << 0)
0282 | ((unsigned long long)gtm[17] << 8)
0283 | ((unsigned long long)gtm[18] << 16)
0284 | ((unsigned long long)gtm[19] << 24)
0285 | ((unsigned long long)gtm[20] << 32)
0286 | (((unsigned long long)gtm[21]) << 40);
0287 m_payload.modebits = gtm[22];
0288 m_payload.userbits = gtm[23];
0289
0290
0291
0292 return 0;
0293 }
0294