Skip to content

Commit 3f93ceb

Browse files
committed
Waveforms decoding function
1 parent 1e492fd commit 3f93ceb

2 files changed

Lines changed: 89 additions & 108 deletions

File tree

sbndcode/Decoders/XARAPUCA/SBNDXARAPUCADecoder_module.cc

Lines changed: 88 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -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 << "\tSample: " << sample << "\tg: " << g << "\tch: " << c << "\ts:" << s << "\tS: " << 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 << "\tSample: " << sample << "\tg: " << g << "\tch: " << c << "\ts:" << s << "\tS: " << 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
*

sbndcode/Decoders/XARAPUCA/xarapucadecoder.fcl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ xarapucadecoder:
3232
# - Output data product instance name.
3333
waveforms_instance_name: "XARAPUCAChannels" # Name for the instance product containing the raw decoded waveforms.
3434
timing_ref_instance_name: "" # Name for the instance product containing the timing reference information.
35-
store_debug_waveforms: -1 # Number of waveforms to store (0: none, -1: all, n: first n waveforms).
35+
store_debug_waveforms: 33 # Number of waveforms to store (0: none, -1: all, n: first n waveforms).
3636
# - Debug options.
3737
debug_tdc_handle: false # (De)activates SPEC-TDC art::Handle information printing.
3838
debug_ptb_handle: false # (De)activates PTB art::Handle information printing.

0 commit comments

Comments
 (0)