@@ -138,6 +138,7 @@ class sbndaq::SBNDXARAPUCADecoder : public art::EDProducer {
138138 bool get_ptb_hlt_timestamp (art::Event& e, uint64_t corr_raw_timestamp, uint64_t & timestamp, uint16_t & hlt_code);
139139 bool get_spec_tdc_etrig_timestamp (art::Event& e, uint64_t corr_raw_timestamp, uint64_t & timestamp);
140140 void shift_time (const artdaq::Fragment& fragment, uint64_t TTT_ticks, int64_t TTT_end_ns, uint64_t timestamp, uint32_t num_samples_per_wvfm, double & ini_wvfm_timestamp, double & end_wvfm_timestamp);
141+ void decode_waveforms (const artdaq::Fragment& fragment, std::vector<std::vector<uint16_t >>& wvfms, size_t header_size, uint32_t num_channels, uint32_t num_samples_per_wvfm, uint32_t num_words_per_wvfms, uint32_t num_samples_per_group);
141142
142143 void save_prod_wvfm (size_t board_idx, size_t ch, double ini_wvfm_timestamp, const std::vector <std::vector <uint16_t > > & wvfms, std::vector <raw::OpDetWaveform> & prod_wvfms);
143144 void save_debug_wvfm (size_t board_idx, size_t fragment_idx, int ch, double ini_wvfm_timestamp, double end_wvfm_timestamp, const std::vector <std::vector <uint16_t > > & wvfms);
@@ -634,7 +635,8 @@ void sbndaq::SBNDXARAPUCADecoder::decode_fragment(uint64_t timestamp, std::vecto
634635
635636 // Gets the number of words of the header and the waveforms.
636637 uint32_t num_words_per_event = header.eventSize ;
637- uint32_t num_words_per_header = sizeof (CAENV1740EventHeader) / sizeof (uint32_t );
638+ size_t header_size = sizeof (CAENV1740EventHeader);
639+ uint32_t num_words_per_header = header_size / sizeof (uint32_t );
638640 uint32_t num_words_per_wvfms = (num_words_per_event - num_words_per_header);
639641
640642 uint32_t num_bits_per_all_wvfms = num_words_per_wvfms * BITS_PER_WORD;
@@ -663,126 +665,60 @@ void sbndaq::SBNDXARAPUCADecoder::decode_fragment(uint64_t timestamp, std::vecto
663665
664666 // =============== Extracts timing information for this fragment =============== //
665667
666- // Gets the timing information of the CAEN fragment.
667- // int64_t pulse_duration_ns = num_samples_per_wvfm * fns_per_sample; // ns.
668- // uint64_t frag_timestamp = fragment.timestamp(); // ns.
669- // int64_t frag_timestamp_s = frag_timestamp / NANOSEC_IN_SEC; // s.
670- // int64_t frag_timestamp_ns = frag_timestamp % NANOSEC_IN_SEC; // ns.
671-
672668 uint32_t TTT_ticks = header.triggerTime ();
673669 int64_t TTT_end_ns = TTT_ticks * NANOSEC_PER_TICK; // ns.
674670
675671 if (fdebug_timing) {
676672 std::cout << " \t\t TTT header.extendedTriggerTime() [TTT_ticks] = " << header.extendedTriggerTime () << " ticks. \t TTT_end_ns = " << print_timestamp (header.extendedTriggerTime () * NANOSEC_PER_TICK) << " ." << std::endl;
677673 std::cout << " \t\t TTT header.triggerTimeRollOver(): " << header.triggerTimeRollOver () << std::endl;
678674 }
675+
676+ // // =============== Start decoding the waveforms =============== //
677+ std::vector <std::vector <uint16_t > > wvfms (num_channels, std::vector<uint16_t >(num_samples_per_wvfm, 0 ));
678+ decode_waveforms (fragment, wvfms, header_size, num_channels, num_samples_per_wvfm, num_words_per_wvfms, num_samples_per_group);
679+ // if (fverbose) std::cout << " > SBNDXARAPUCADecoder::decode_fragment: binary decoding of the waveforms starting... " << std::endl;
680+ //
681+ // std::vector <std::vector <uint16_t> > wvfms(num_channels, std::vector<uint16_t>(num_samples_per_wvfm, 0));
679682//
680- // // Gets the full TTT timestamp.
681- // uint64_t full_TTT = 0;
682- // // If the fragment timestamp is greater than the TTT end timestamp, it means that rollover occurred.
683- // if (frag_timestamp_ns > TTT_end_ns) {
684- // if (fverbose | fdebug_timing) std::cout << " > SBNDXARAPUCADecoder::decode_fragment: CAEN TTT rollover occurred w.r.t. the fragment timestamp (FTS)." << std::endl;
685- // full_TTT = (frag_timestamp_s + 1) * NANOSEC_IN_SEC + TTT_end_ns;
686- // } else {
687- // full_TTT = frag_timestamp_s * NANOSEC_IN_SEC + TTT_end_ns;
688- // }
689- //
690- // int64_t ref_timestamp = 0;
691- //
692- // double ini_wvfm_timestamp = 0;
693- // double end_wvfm_timestamp = 0;
694- //
695- // // If an ETRIG or HLT timestamp was found it restarts the time from it. Otherwise the CAEN time frame is assigned.
696- // if (factive_timing_frame != CAEN_ONLY_TIMING) {
697- // ref_timestamp = signed_difference(full_TTT, timestamp); // ns.
698- //
699- // ini_wvfm_timestamp = (ref_timestamp - pulse_duration_ns) * NANOSEC_TO_MICROSEC; // us.
700- // end_wvfm_timestamp = ref_timestamp * NANOSEC_TO_MICROSEC; // us.
701- // } else {
702- // ref_timestamp = full_TTT; // ns.
683+ // // Absolute sample number [0, TOTAL_NUM_SAMPLES] where TOTAL_NUM_SAMPLES is the total number of samples stored for an event.
684+ // uint32_t S = 0;
685+ // // Buffer variables.
686+ // uint64_t buffer = 0;
687+ // uint32_t bits_in_buffer = 0;
703688//
704- // ini_wvfm_timestamp = ((ref_timestamp - pulse_duration_ns) % NANOSEC_IN_SEC) * NANOSEC_TO_MICROSEC; // ns.
705- // end_wvfm_timestamp = (ref_timestamp % NANOSEC_IN_SEC) * NANOSEC_TO_MICROSEC; // us.
706- // }
689+ // // Data pointer to the beggining of the waveforms stores in the event.
690+ // const uint32_t* data_ptr = reinterpret_cast<const uint32_t*>(fragment.dataBeginBytes() + sizeof(CAENV1740EventHeader));
691+ // // Accesses each word, stores it in the buffer and then the samples are extracted from the buffer.
692+ // for (size_t j = 0; j < num_words_per_wvfms; j++) {
693+ // uint64_t word = read_word(data_ptr);
707694//
708- // if (fdebug_timing) {
709- // std::cout << std::fixed << std::setprecision(0);
710- // std::cout << "\t\t ns/tick = " << NANOSEC_PER_TICK << ", ns/sample = " << fns_per_sample << std::endl;
711- // std::cout << "\t\t TTT header.TriggerTime() [TTT_ticks] = " << TTT_ticks << " ticks. \t TTT_end_ns = " << print_timestamp(TTT_end_ns) << "." << std::endl;
712- // std::cout << "\t\t TTT header.extendedTriggerTime() [TTT_ticks] = " << header.extendedTriggerTime() << " ticks. \t TTT_end_ns = " << print_timestamp(header.extendedTriggerTime() * NANOSEC_PER_TICK) << "." << std::endl;
713- // std::cout << "\t\t TTT header.triggerTimeRollOver(): " << header.triggerTimeRollOver() << std::endl;
714- // std::cout << "\t\t Full Fragment timestamp: " << print_timestamp(frag_timestamp) << " = " << frag_timestamp_s << " s " << frag_timestamp_ns << " ns." << std::endl;
715- // std::cout << "\t\t Full TTT - fragment timestamp = "<< abs_difference(full_TTT, frag_timestamp) << " ns." << " Post-percent: " << (double(abs_difference(full_TTT, frag_timestamp)) / double(pulse_duration_ns)) * 100 << "%." << std::endl;
716- // if (factive_timing_frame == SPEC_TDC_TIMING) {
717- // std::cout << "\t ETRIG (SPEC-TDC) timestamp of the fragment: " << std::endl;
718- // std::cout << "\t\t Full UTC ETRIG timestamp: " << print_timestamp(timestamp) << "." << std::endl;
719- // std::cout << "\t\t ETRIG SPEC-TDC difference applied to the CAEN frame (full timestamps): " << print_timestamp(full_TTT) << " - " << print_timestamp(timestamp) << " = " << ref_timestamp << " ns." << std::endl;
720- // } else if (factive_timing_frame == PTB_TIMING) {
721- // std::cout << "\t HLT ETRIG (PTB) timestamp of the fragment: " << std::endl;
722- // std::cout << "\t\t Full UTC HLT ETRIG timestamp: " << print_timestamp(timestamp) << "." << std::endl;
723- // std::cout << "\t\t HLT ETRIG (PTB) difference applied to the CAEN frame (full timestamps): " << print_timestamp(full_TTT) << " - " << print_timestamp(timestamp) << " = " << ref_timestamp << " ns." << std::endl;
724- // } else if (factive_timing_frame == CAEN_ONLY_TIMING) {
725- // std::cout << "\t CAEN trigger timestamp (TTT) of the fragment: " << std::endl;
726- // std::cout << "\t\t Full UTC TTT timestamp: " << print_timestamp(full_TTT) << " = " << full_TTT / NANOSEC_IN_SEC << " s " << TTT_end_ns << " ns." << std::endl;
727- // }
728- // }
695+ // // Adds the new word to the buffer and increments the number of bits stored in it.
696+ // if (fdebug_buffer) std::cout << buffer << "[word: " << word << "]" << std::endl;
697+ // buffer |= word << bits_in_buffer;
698+ // bits_in_buffer += BITS_PER_WORD; // bytes * 8 bits/byte
699+ // if (fdebug_buffer) std::cout << " +" << buffer << " [bits in buffer: "<< bits_in_buffer << "]" << std::endl;
729700//
730- // if (fverbose | fdebug_timing) {
731- // std::cout << std::fixed << std::setprecision(3);
732- // if (factive_timing_frame == SPEC_TDC_TIMING) {
733- // std::cout << " > SBNDXARAPUCADecoder::decode_fragment: SPEC-TDC time window of " << end_wvfm_timestamp - ini_wvfm_timestamp << " us: [" << ini_wvfm_timestamp << ", " << end_wvfm_timestamp << "] us." << std::endl;
734- // } else if (factive_timing_frame == PTB_TIMING) {
735- // std::cout << " > SBNDXARAPUCADecoder::decode_fragment: PTB time window of " << end_wvfm_timestamp - ini_wvfm_timestamp << " us: [" << ini_wvfm_timestamp << ", " << end_wvfm_timestamp << "] us." << std::endl;
736- // } else { // CAEN_ONLY_TIMING
737- // std::cout << " > SBNDXARAPUCADecoder::decode_fragment: CAEN time window of " << end_wvfm_timestamp - ini_wvfm_timestamp << " us: [" << ini_wvfm_timestamp << ", " << end_wvfm_timestamp << "] us." << std::endl;
701+ // // Obtains 12-bit sequences from the buffer and assigns each sample to the channel and channel sample it belongs to.
702+ // while (bits_in_buffer >= BITS_PER_SAMPLE) {
703+ // // Computes board channel, channel sample and group channel and assigns the sample to those indices.
704+ // uint32_t g = (S / num_samples_per_group); // Group index.
705+ // uint32_t c = ((S / NUM_CONSECUTIVE_SAMPLES) % NUM_CHANNELS_PER_GROUP) + g * NUM_GROUPS; // Channel index.
706+ // uint32_t s = (S % NUM_CONSECUTIVE_SAMPLES) + ((S / NUM_SAMPLES_PER_ROUND) * NUM_CONSECUTIVE_SAMPLES) % num_samples_per_wvfm; // Sample/channel index.
707+ // uint16_t sample = get_sample(buffer, BITS_PER_SAMPLE - 1, 0);
708+ // wvfms[c][s] = sample;
709+ // if (fdebug_waveforms) std::cout << "\tSample: " << sample << "\tg: " << g << "\tch: " << c << "\ts:" << s << "\tS: " << S << std::endl;
710+ //
711+ // // Updates the buffer status removing the read bits and decreasing the number of bits stored in it.
712+ // buffer >>= BITS_PER_SAMPLE;
713+ // bits_in_buffer -= BITS_PER_SAMPLE;
714+ // if (fdebug_buffer) std::cout << " -" << buffer << " [bits in buffer: "<< bits_in_buffer << "]" << std::endl;
715+ //
716+ // // Increments the absolute sample step.
717+ // S++;
738718// }
739- // std::cout << " > SBNDXARAPUCADecoder::decode_fragment: TTT_end_ticks = " << TTT_ticks << " ticks. \t TTT_end_ns = " << print_timestamp(TTT_end_ns) << "." << std::endl;
740719// }
741- //
742- // =============== Start decoding the waveforms =============== //
743- if (fverbose) std::cout << " > SBNDXARAPUCADecoder::decode_fragment: binary decoding of the waveforms starting... " << std::endl;
744-
745- std::vector <std::vector <uint16_t > > wvfms (num_channels, std::vector<uint16_t >(num_samples_per_wvfm, 0 ));
746-
747- // Absolute sample number [0, TOTAL_NUM_SAMPLES] where TOTAL_NUM_SAMPLES is the total number of samples stored for an event.
748- uint32_t S = 0 ;
749- // Buffer variables.
750- uint64_t buffer = 0 ;
751- uint32_t bits_in_buffer = 0 ;
752-
753- // Data pointer to the beggining of the waveforms stores in the event.
754- const uint32_t * data_ptr = reinterpret_cast <const uint32_t *>(fragment.dataBeginBytes () + sizeof (CAENV1740EventHeader));
755- // Accesses each word, stores it in the buffer and then the samples are extracted from the buffer.
756- for (size_t j = 0 ; j < num_words_per_wvfms; j++) {
757- uint64_t word = read_word (data_ptr);
758-
759- // Adds the new word to the buffer and increments the number of bits stored in it.
760- if (fdebug_buffer) std::cout << buffer << " [word: " << word << " ]" << std::endl;
761- buffer |= word << bits_in_buffer;
762- bits_in_buffer += BITS_PER_WORD; // bytes * 8 bits/byte
763- if (fdebug_buffer) std::cout << " +" << buffer << " [bits in buffer: " << bits_in_buffer << " ]" << std::endl;
764-
765- // Obtains 12-bit sequences from the buffer and assigns each sample to the channel and channel sample it belongs to.
766- while (bits_in_buffer >= BITS_PER_SAMPLE) {
767- // Computes board channel, channel sample and group channel and assigns the sample to those indices.
768- uint32_t g = (S / num_samples_per_group); // Group index.
769- uint32_t c = ((S / NUM_CONSECUTIVE_SAMPLES) % NUM_CHANNELS_PER_GROUP) + g * NUM_GROUPS; // Channel index.
770- uint32_t s = (S % NUM_CONSECUTIVE_SAMPLES) + ((S / NUM_SAMPLES_PER_ROUND) * NUM_CONSECUTIVE_SAMPLES) % num_samples_per_wvfm; // Sample/channel index.
771- uint16_t sample = get_sample (buffer, BITS_PER_SAMPLE - 1 , 0 );
772- wvfms[c][s] = sample;
773- if (fdebug_waveforms) std::cout << " \t Sample: " << sample << " \t g: " << g << " \t ch: " << c << " \t s:" << s << " \t S: " << S << std::endl;
774-
775- // Updates the buffer status removing the read bits and decreasing the number of bits stored in it.
776- buffer >>= BITS_PER_SAMPLE;
777- bits_in_buffer -= BITS_PER_SAMPLE;
778- if (fdebug_buffer) std::cout << " -" << buffer << " [bits in buffer: " << bits_in_buffer << " ]" << std::endl;
779-
780- // Increments the absolute sample step.
781- S++;
782- }
783- }
784-
785720
721+ // =============== Shifts timing to the selected timing reference frame =============== //
786722 double ini_wvfm_timestamp = 0 ;
787723 double end_wvfm_timestamp = 0 ;
788724 shift_time (fragment, TTT_ticks, TTT_end_ns, timestamp, num_samples_per_wvfm, ini_wvfm_timestamp, end_wvfm_timestamp);
@@ -958,6 +894,51 @@ void sbndaq::SBNDXARAPUCADecoder::shift_time(const artdaq::Fragment& fragment, u
958894 }
959895}
960896
897+ void sbndaq::SBNDXARAPUCADecoder::decode_waveforms (const artdaq::Fragment& fragment, std::vector<std::vector<uint16_t >>& wvfms, size_t header_size, uint32_t num_channels, uint32_t num_samples_per_wvfm, uint32_t num_words_per_wvfms, uint32_t num_samples_per_group) {
898+ // =============== Start decoding the waveforms =============== //
899+ if (fverbose) std::cout << " > SBNDXARAPUCADecoder::decode_fragment: binary decoding of the waveforms starting... " << std::endl;
900+
901+ // std::vector <std::vector <uint16_t> > wvfms(num_channels, std::vector<uint16_t>(num_samples_per_wvfm, 0));
902+
903+ // Absolute sample number [0, TOTAL_NUM_SAMPLES] where TOTAL_NUM_SAMPLES is the total number of samples stored for an event.
904+ uint32_t S = 0 ;
905+ // Buffer variables.
906+ uint64_t buffer = 0 ;
907+ uint32_t bits_in_buffer = 0 ;
908+
909+ // Data pointer to the beggining of the waveforms stores in the event.
910+ const uint32_t * data_ptr = reinterpret_cast <const uint32_t *>(fragment.dataBeginBytes () + header_size);
911+ // Accesses each word, stores it in the buffer and then the samples are extracted from the buffer.
912+ for (size_t j = 0 ; j < num_words_per_wvfms; j++) {
913+ uint64_t word = read_word (data_ptr);
914+
915+ // Adds the new word to the buffer and increments the number of bits stored in it.
916+ if (fdebug_buffer) std::cout << buffer << " [word: " << word << " ]" << std::endl;
917+ buffer |= word << bits_in_buffer;
918+ bits_in_buffer += BITS_PER_WORD; // bytes * 8 bits/byte
919+ if (fdebug_buffer) std::cout << " +" << buffer << " [bits in buffer: " << bits_in_buffer << " ]" << std::endl;
920+
921+ // Obtains 12-bit sequences from the buffer and assigns each sample to the channel and channel sample it belongs to.
922+ while (bits_in_buffer >= BITS_PER_SAMPLE) {
923+ // Computes board channel, channel sample and group channel and assigns the sample to those indices.
924+ uint32_t g = (S / num_samples_per_group); // Group index.
925+ uint32_t c = ((S / NUM_CONSECUTIVE_SAMPLES) % NUM_CHANNELS_PER_GROUP) + g * NUM_GROUPS; // Channel index.
926+ uint32_t s = (S % NUM_CONSECUTIVE_SAMPLES) + ((S / NUM_SAMPLES_PER_ROUND) * NUM_CONSECUTIVE_SAMPLES) % num_samples_per_wvfm; // Sample/channel index.
927+ uint16_t sample = get_sample (buffer, BITS_PER_SAMPLE - 1 , 0 );
928+ wvfms[c][s] = sample;
929+ if (fdebug_waveforms) std::cout << " \t Sample: " << sample << " \t g: " << g << " \t ch: " << c << " \t s:" << s << " \t S: " << S << std::endl;
930+
931+ // Updates the buffer status removing the read bits and decreasing the number of bits stored in it.
932+ buffer >>= BITS_PER_SAMPLE;
933+ bits_in_buffer -= BITS_PER_SAMPLE;
934+ if (fdebug_buffer) std::cout << " -" << buffer << " [bits in buffer: " << bits_in_buffer << " ]" << std::endl;
935+
936+ // Increments the absolute sample step.
937+ S++;
938+ }
939+ }
940+ }
941+
961942/* *
962943 * @brief Extract a sample from a 64-bit buffer using the specified bit positions.
963944 *
0 commit comments