@@ -78,10 +78,7 @@ SBNDPTBDecoder::SBNDPTBDecoder(fhicl::ParameterSet const & p)
7878
7979void SBNDPTBDecoder::produce (art::Event & evt)
8080{
81-
82-
8381 // look first for container fragments and then non-container fragments
84-
8582 std::vector<raw::ptb::sbndptb> sbndptbs;
8683
8784 art::InputTag itag1 (fInputLabel , fInputContainerInstance );
@@ -117,6 +114,61 @@ void SBNDPTBDecoder::produce(art::Event & evt)
117114 evt.put (std::make_unique<std::vector<raw::ptb::sbndptb>>(std::move (sbndptbs)),fOutputInstance );
118115}
119116
117+
118+ void print_fragment_words (const artdaq::Fragment& frag, size_t wordNum, size_t bitsPerWord ) {
119+
120+ const __uint8_t * data_ptr = reinterpret_cast <const __uint8_t *>(frag.dataBegin ());
121+ size_t wordCount = frag.dataSizeBytes () / (bitsPerWord / 8 );
122+ for (size_t w = 0 ; w < wordCount; w++) {
123+ // Check if the current word index matches the specified word index
124+ if (w == wordNum) {
125+ // Print the bits for the specified n-bit word
126+ for (int i = (bitsPerWord-1 ); i >= 0 ; --i) {
127+ // Calculate the byte index and bit index
128+ size_t byteIndex = w * (bitsPerWord / 8 ) + (i / 8 );
129+ int bitIndex = (i % 8 ); // Get the correct bit position in the byte
130+ // Print the bit
131+ std::cout << static_cast <int >((data_ptr[byteIndex] >> bitIndex) & 1 );
132+ if (i % 8 == 0 ) {
133+ std::cout << " " ;
134+ }
135+ }
136+ std::cout << std::endl; // New line after printing the word
137+ }
138+ }
139+ }
140+
141+
142+ // Copied from Lines 1382-1406 from sbndaq-artdaq/sbndaq-artdaq/ArtModules/SBND/EventAna_module.cc
143+
144+ /* ******************************************
145+ * Note: Below for the Timestamp conversion,
146+ * The PTB TS is in UTC seconds since the Unix epoch in 50MHz clock ticks.
147+ * This means to recover seconds since the Unix epoch use: sec_since_epoch = TS / 50e6
148+ * and of course nanosec_since_epoch = (TS / 50e6) * 1e9 = TS * 20
149+ *
150+ * Note: The `CTBFragment` constructor grabs the chunk of memory the artDAQ fragment occupies.
151+ * Since we know a priori the number of PTB words (from the TCP header) and the size (128b for all words)
152+ * we can loop over the memory addresses, casting each 128b into the correct word type given by each word's `type`.
153+ *
154+ * There are 5 word types with the following bit arrangement:
155+ * Feeback = | 3b Word Type | 61b Payload | 64b Timestamp | (here Payload is split into code, source, payload1, payload2)
156+ * LLT, HLT = | 3b Word Type | 61b Payload | 64b Timestamp |
157+ * Channel Status = | 3b Word Type | 64b Payload | 61b Timestamp | (Larger Payload to fit all input channels)
158+ *
159+ * Word Type:
160+ * - 0x0 = Feedback/Error Word -> Errors from the firmware, should abort the run
161+ * - 0x1 = Low Level Trigger (LLT) -> Holds a record of any asserted LLTs
162+ * - 0x2 = High Level Trigger (HLT) -> Holds a record of any asserted HLTs
163+ * - 0x3 = Channel status -> Holds a record of any asserted inputs
164+ * - 0x7 = Timestamp Word -> No payload just a timestamp, these are periodic
165+ *
166+ * Note: Payload AND'd with mask the size of the expected number of bits just
167+ * to make sure we don't get any unexpected garbage bits since we aren't using
168+ * the full bits of the variable type e.g. uint64_t, unint16_t..
169+ **************************************/
170+
171+
120172void SBNDPTBDecoder::_process_PTB_AUX (const artdaq::Fragment& frag, ptbsv_t &sout)
121173{
122174 sbndaq::CTBFragment ctbfrag (frag); // somehow the name CTBFragment stuck
@@ -145,8 +197,19 @@ void SBNDPTBDecoder::_process_PTB_AUX(const artdaq::Fragment& frag, ptbsv_t &sou
145197 tstruct.timestamp = ctbfrag.Trigger (iword)->timestamp ;
146198 if (ctbfrag.Trigger (iword)->IsHLT ())
147199 {
200+
201+ if (*(frag.metadata <int >()) == 2 ){ // If data is taken with 192b PTB words
202+ tstruct.prev_timestamp = ctbfrag.PTBWord (iword)->prevTS ;
203+ tstruct.gate_counter = ctbfrag.Trigger (iword)->gate_counter ;
204+ }
205+ else if (*(frag.metadata <int >()) != 2 ){ // If data is taken with 128b PTB words
206+ tstruct.prev_timestamp = 0 ;
207+ tstruct.gate_counter = 0 ;
208+ }
209+
148210 ix = sout.HLTrigs .size ();
149211 sout.HLTrigs .push_back (tstruct);
212+
150213 if (fDebugLevel > 0 )
151214 {
152215 std::cout << " SBNDPTBDecoder_module: found HLT: " << wt << " " << ix << std::endl;
0 commit comments