File indexing completed on 2025-08-05 08:16:19
0001 #ifndef Fun4All_TpcTimeFrameBuilder_H
0002 #define Fun4All_TpcTimeFrameBuilder_H
0003
0004 #include <algorithm>
0005 #include <cstdint>
0006 #include <deque>
0007 #include <functional>
0008 #include <iostream>
0009 #include <limits>
0010 #include <list>
0011 #include <map>
0012 #include <optional>
0013 #include <queue>
0014 #include <set>
0015 #include <string>
0016 #include <utility>
0017 #include <vector>
0018
0019 class Packet;
0020 class TpcRawHit;
0021 class PHTimer;
0022 class TH1;
0023 class TH2;
0024 class TTree;
0025
0026
0027 class TpcTimeFrameBuilder
0028 {
0029 public:
0030 explicit TpcTimeFrameBuilder(const int packet_id);
0031 virtual ~TpcTimeFrameBuilder();
0032
0033 int ProcessPacket(Packet *);
0034 bool isMoreDataRequired(const uint64_t >m_bco) const;
0035 void CleanupUsedPackets(const uint64_t &bclk);
0036 std::vector<TpcRawHit *> &getTimeFrame(const uint64_t >m_bco);
0037
0038 void setVerbosity(const int i);
0039 void setFastBCOSkip(bool fastBCOSkip = true)
0040 {
0041 m_fastBCOSkip = fastBCOSkip;
0042 }
0043
0044
0045 void SaveDigitalCurrentDebugTTree(const std::string &name);
0046
0047 protected:
0048
0049 static const size_t DAM_DMA_WORD_LENGTH = 16;
0050
0051 static const uint16_t FEE_PACKET_MAGIC_KEY_1 = 0xfe;
0052 static const uint16_t FEE_PACKET_MAGIC_KEY_2 = 0xed;
0053 static const uint16_t FEE_PACKET_MAGIC_KEY_3_DC = 0xdcdc;
0054
0055 static const uint16_t FEE_MAGIC_KEY = 0xba00;
0056 static const uint16_t GTM_MAGIC_KEY = 0xbb00;
0057 static const uint16_t GTM_LVL1_ACCEPT_MAGIC_KEY = 0xbbf0;
0058 static const uint16_t GTM_ENDAT_MAGIC_KEY = 0xbbf1;
0059 static const uint16_t GTM_MODEBIT_MAGIC_KEY = 0xbbf2;
0060
0061 static const uint16_t MAX_FEECOUNT = 26;
0062 static const uint16_t MAX_SAMPA = 8;
0063 static const uint16_t MAX_CHANNELS = MAX_SAMPA * 32;
0064
0065 static const uint16_t HEADER_LENGTH = 7;
0066 static const uint16_t MAX_PACKET_LENGTH = 1025;
0067
0068 static const uint16_t GL1_BCO_MATCH_WINDOW = 256;
0069
0070 int m_hitFormat = -1;
0071
0072 uint16_t reverseBits(const uint16_t x) const;
0073 std::pair<uint16_t, uint16_t> crc16_parity(const uint32_t fee, const uint16_t l) const;
0074
0075
0076 struct dma_word
0077 {
0078 uint16_t dma_header = 0;
0079 uint16_t data[DAM_DMA_WORD_LENGTH - 1] = {0};
0080 };
0081
0082 int decode_gtm_data(const dma_word >m_word);
0083 int process_fee_data(unsigned int fee_id);
0084 void process_fee_data_waveform(const unsigned int & fee_id, std::deque<uint16_t>& data_buffer);
0085 void process_fee_data_digital_current(const unsigned int & fee_id, std::deque<uint16_t>& data_buffer);
0086
0087 struct gtm_payload
0088 {
0089 uint16_t pkt_type = 0;
0090 bool is_endat = false;
0091 bool is_lvl1 = false;
0092 bool is_modebit = false;
0093 uint64_t bco = 0;
0094 uint32_t lvl1_count = 0;
0095 uint32_t endat_count = 0;
0096 uint64_t last_bco = 0;
0097 uint8_t modebits = 0;
0098 uint8_t userbits = 0;
0099 };
0100
0101 struct fee_payload
0102 {
0103 uint16_t fee_id = 0;
0104 uint16_t adc_length = 0;
0105 uint16_t sampa_address = 0;
0106 uint16_t sampa_channel = 0;
0107 uint16_t channel = 0;
0108 uint16_t type = 0;
0109 uint16_t user_word = 0;
0110 uint32_t bx_timestamp = 0;
0111 uint64_t gtm_bco = 0;
0112
0113 uint16_t data_crc = 0;
0114 uint16_t calc_crc = 0;
0115
0116 uint16_t data_parity = 0;
0117 uint16_t calc_parity = 0;
0118
0119 std::vector<std::pair<uint16_t, std::vector<uint16_t>>> waveforms;
0120 };
0121
0122 struct digital_current_payload
0123 {
0124 static const int MAX_CHANNELS = 8;
0125
0126 uint64_t gtm_bco {std::numeric_limits<uint64_t>::max()};
0127 uint32_t bx_timestamp_predicted {std::numeric_limits<uint32_t>::max()};
0128
0129 uint16_t fee {std::numeric_limits<uint16_t>::max()};
0130 uint16_t pkt_length {std::numeric_limits<uint16_t>::max()};
0131 uint16_t channel {std::numeric_limits<uint16_t>::max()};
0132
0133 uint16_t sampa_address {std::numeric_limits<uint16_t>::max()};
0134 uint32_t bx_timestamp {0};
0135 uint32_t current[MAX_CHANNELS] {0};
0136 uint32_t nsamples[MAX_CHANNELS] {0};
0137 uint16_t data_crc {std::numeric_limits<uint16_t>::max()};
0138 uint16_t calc_crc = {std::numeric_limits<uint16_t>::max()};
0139
0140 };
0141
0142 class DigitalCurrentDebugTTree
0143 {
0144 public:
0145 explicit DigitalCurrentDebugTTree(const std::string &name);
0146 virtual ~DigitalCurrentDebugTTree();
0147
0148 void fill(const digital_current_payload &payload);
0149
0150 private:
0151 digital_current_payload m_payload;
0152
0153 std::string m_name;
0154 TTree *m_tDigitalCurrent = nullptr;
0155 };
0156 DigitalCurrentDebugTTree * m_digitalCurrentDebugTTree = nullptr;
0157
0158
0159
0160
0161
0162 class BcoMatchingInformation
0163 {
0164 public:
0165
0166 explicit BcoMatchingInformation(const std::string &name);
0167
0168
0169
0170
0171
0172 int verbosity() const
0173 {
0174 return m_verbosity;
0175 }
0176
0177
0178
0179
0180
0181
0182 bool is_verified() const
0183 {
0184 return m_verified_from_modebits || m_verified_from_data;
0185 }
0186
0187
0188 using m_gtm_fee_bco_matching_pair_t = std::pair<uint64_t, uint32_t>;
0189 using m_fee_gtm_bco_matching_pair_t = std::pair<uint32_t, uint64_t>;
0190
0191
0192 const std::optional<m_gtm_fee_bco_matching_pair_t> &get_reference_bco() const
0193 {
0194 return m_bco_reference;
0195 }
0196
0197
0198 bool isMoreDataRequired(const uint64_t >m_bco) const;
0199
0200
0201 std::optional<uint32_t> get_predicted_fee_bco(uint64_t) const;
0202
0203
0204 double get_gtm_clock_multiplier()
0205 {
0206 return m_multiplier;
0207 }
0208
0209
0210 void print_gtm_bco_information() const;
0211
0212
0213
0214
0215
0216
0217
0218 void set_verbosity(int value)
0219 {
0220 m_verbosity = value;
0221 }
0222
0223
0224 void set_gtm_clock_multiplier(double value)
0225 {
0226 m_multiplier = value;
0227 }
0228
0229
0230 uint64_t get_gtm_rollover_correction(const uint64_t >m_bco) const;
0231
0232
0233 std::optional<uint64_t> find_reference_heartbeat(const fee_payload &HeartBeatPacket);
0234
0235
0236 void save_gtm_bco_information(const gtm_payload >m_tagger);
0237
0238
0239 std::optional<uint64_t> find_gtm_bco(uint32_t );
0240
0241
0242 void cleanup();
0243
0244
0245 void cleanup(uint64_t );
0246
0247 m_gtm_fee_bco_matching_pair_t find_dc_read_bco() const
0248 {
0249 return m_gtm_bco_dc_read;
0250 }
0251
0252
0253
0254 enum SampaDataType
0255 {
0256 HEARTBEAT_T = 0b000,
0257 TRUNCATED_DATA_T = 0b001,
0258 TRUNCATED_TRIG_EARLY_DATA_T = 0b011,
0259 NORMAL_DATA_T = 0b100,
0260 LARGE_DATA_T = 0b101,
0261 TRIG_EARLY_DATA_T = 0b110,
0262 TRIG_EARLY_LARGE_DATA_T = 0b111,
0263 };
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275 enum ModeBitType
0276 {
0277 BX_COUNTER_SYNC_T = 0x1,
0278 ELINK_HEARTBEAT_T = 0x2,
0279 DC_STOP_SEND_T = 0x7
0280
0281
0282
0283 };
0284
0285
0286 template <class T>
0287 inline static constexpr T get_bco_diff(
0288 const T &first, const T &second)
0289 {
0290 return first < second ? (second - first) : (first - second);
0291 }
0292
0293
0294 inline static constexpr uint32_t get_fee_bco_diff(
0295 const uint32_t &first, const uint32_t &second)
0296 {
0297 const uint32_t diff_raw = get_bco_diff(first, second);
0298
0299 return (diff_raw < (1U << (m_FEE_CLOCK_BITS / 2))) ? diff_raw : (1U << m_FEE_CLOCK_BITS) - diff_raw;
0300 }
0301
0302 private:
0303 std::string m_name;
0304
0305
0306 unsigned int m_verbosity = 0;
0307
0308
0309 bool m_verified_from_modebits = false;
0310
0311 bool m_verified_from_data = false;
0312
0313
0314 std::list<uint64_t> m_gtm_bco_trig_list;
0315
0316
0317 m_gtm_fee_bco_matching_pair_t m_gtm_bco_dc_read = {0, 0};
0318
0319
0320 std::optional<m_gtm_fee_bco_matching_pair_t> m_bco_reference = std::nullopt;
0321
0322
0323
0324 std::list<m_gtm_fee_bco_matching_pair_t> m_bco_reference_candidate_list;
0325 static constexpr unsigned int m_max_bco_reference_candidate_list_size = 16;
0326
0327
0328
0329
0330
0331
0332 std::map<uint64_t, uint32_t> m_gtm_bco_trigger_map;
0333
0334 std::list<m_fee_gtm_bco_matching_pair_t> m_bco_matching_list;
0335
0336
0337 std::set<uint32_t> m_orphans;
0338
0339
0340 static constexpr int m_max_lv1_endat_bco_diff = 16;
0341
0342
0343 static constexpr unsigned int m_max_fee_bco_diff = 64;
0344
0345
0346
0347
0348 static constexpr unsigned int m_max_gtm_bco_diff = 256;
0349
0350
0351 static constexpr unsigned int m_max_matching_data_size = 10;
0352
0353
0354 static constexpr unsigned int m_max_fee_sync_time = 1024 * 8;
0355
0356 static constexpr unsigned int m_FEE_CLOCK_BITS = 20;
0357 static constexpr unsigned int m_GTM_CLOCK_BITS = 40;
0358
0359 double m_multiplier = 0;
0360
0361 TH1 *m_hNorm = nullptr;
0362 TH1 *m_hFEEClockAdjustment_MatchedReference = nullptr;
0363 TH1 *m_hFEEClockAdjustment_MatchedNew = nullptr;
0364 TH1 *m_hFEEClockAdjustment_Unmatched = nullptr;
0365 TH1 *m_hGTMNewEventSpacing = nullptr;
0366 TH1 *m_hFindGTMBCO_MatchedExisting_BCODiff = nullptr;
0367 TH1 *m_hFindGTMBCO_MatchedNew_BCODiff = nullptr;
0368
0369 };
0370
0371 private:
0372 std::vector<std::deque<uint16_t>> m_feeData;
0373
0374 int m_verbosity = 0;
0375 int m_packet_id = 0;
0376
0377
0378 std::string m_HistoPrefix;
0379
0380
0381
0382
0383 std::map<uint64_t, std::vector<TpcRawHit *>> m_timeFrameMap;
0384 static const size_t kMaxRawHitLimit = 10000;
0385 std::queue<uint64_t> m_UsedTimeFrameSet;
0386
0387
0388 bool m_fastBCOSkip = false;
0389
0390
0391 std::vector<BcoMatchingInformation> m_bcoMatchingInformation_vec;
0392
0393
0394
0395 PHTimer *m_packetTimer = nullptr;
0396
0397 TH1 *m_hNorm = nullptr;
0398 TH2 *m_hFEEDataStream = nullptr;
0399 TH1 *m_hFEEChannelPacketCount = nullptr;
0400 TH2 *m_hFEESAMPAADC = nullptr;
0401 TH1 *m_hFEESAMPAHeartBeatSync = nullptr;
0402
0403 TH1 *h_PacketLength = nullptr;
0404 TH1 *h_PacketLength_Padding = nullptr;
0405 TH1 *h_PacketLength_Residual = nullptr;
0406
0407 TH1 *h_GTMClockDiff_Matched = nullptr;
0408 TH1 *h_GTMClockDiff_Unmatched = nullptr;
0409 TH1 *h_GTMClockDiff_Dropped = nullptr;
0410 TH1 *h_TimeFrame_Matched_Size = nullptr;
0411
0412 TH2 *h_ProcessPacket_Time = nullptr;
0413 };
0414
0415 #endif