@@ -137,6 +137,7 @@ class sbndaq::SBNDXARAPUCADecoder : public art::EDProducer {
137137
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);
140+ 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);
140141
141142 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);
142143 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);
@@ -616,6 +617,10 @@ void sbndaq::SBNDXARAPUCADecoder::decode_fragment(uint64_t timestamp, std::vecto
616617 if (valid_fragment) {
617618 if (fverbose) std::cout << " \n > SBNDXARAPUCADecoder::decode_fragment: decoding V1740 CAEN fragment " << fragment_indices[board_idx] << " from the board " << board_idx << " (slot " << fboard_id_list[board_idx] << " ):" << std::endl;
618619
620+ // bool is_nominal_length = false;
621+ // bool is_within_nominal_length = false;
622+ // bool is_first = false;
623+
619624 // =============== Accesses Event metadata and Event header for this fragment =============== //
620625
621626 CAENV1740Fragment caen_fragment (fragment);
@@ -659,76 +664,81 @@ void sbndaq::SBNDXARAPUCADecoder::decode_fragment(uint64_t timestamp, std::vecto
659664 // =============== Extracts timing information for this fragment =============== //
660665
661666 // Gets the timing information of the CAEN fragment.
662- int64_t pulse_duration_ns = num_samples_per_wvfm * fns_per_sample; // ns.
663- uint64_t frag_timestamp = fragment.timestamp (); // ns.
664- int64_t frag_timestamp_s = frag_timestamp / NANOSEC_IN_SEC; // s.
665- int64_t frag_timestamp_ns = frag_timestamp % NANOSEC_IN_SEC; // ns.
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.
666671
667672 uint32_t TTT_ticks = header.triggerTime ();
668673 int64_t TTT_end_ns = TTT_ticks * NANOSEC_PER_TICK; // ns.
669674
670- // Gets the full TTT timestamp.
671- uint64_t full_TTT = 0 ;
672- // If the fragment timestamp is greater than the TTT end timestamp, it means that rollover occurred.
673- if (frag_timestamp_ns > TTT_end_ns) {
674- if (fverbose | fdebug_timing) std::cout << " > SBNDXARAPUCADecoder::decode_fragment: CAEN TTT rollover occurred w.r.t. the fragment timestamp (FTS)." << std::endl;
675- full_TTT = (frag_timestamp_s + 1 ) * NANOSEC_IN_SEC + TTT_end_ns;
676- } else {
677- full_TTT = frag_timestamp_s * NANOSEC_IN_SEC + TTT_end_ns;
678- }
679-
680- int64_t ref_timestamp = 0 ;
681-
682- double ini_wvfm_timestamp = 0 ;
683- double end_wvfm_timestamp = 0 ;
684-
685- // If an ETRIG or HLT timestamp was found it restarts the time from it. Otherwise the CAEN time frame is assigned.
686- if (factive_timing_frame != CAEN_ONLY_TIMING) {
687- ref_timestamp = signed_difference (full_TTT, timestamp); // ns.
688-
689- ini_wvfm_timestamp = (ref_timestamp - pulse_duration_ns) * NANOSEC_TO_MICROSEC; // us.
690- end_wvfm_timestamp = ref_timestamp * NANOSEC_TO_MICROSEC; // us.
691- } else {
692- ref_timestamp = full_TTT; // ns.
693-
694- ini_wvfm_timestamp = ((ref_timestamp - pulse_duration_ns) % NANOSEC_IN_SEC) * NANOSEC_TO_MICROSEC; // ns.
695- end_wvfm_timestamp = (ref_timestamp % NANOSEC_IN_SEC) * NANOSEC_TO_MICROSEC; // us.
696- }
697-
698675 if (fdebug_timing) {
699- std::cout << std::fixed << std::setprecision (0 );
700- std::cout << " \t\t ns/tick = " << NANOSEC_PER_TICK << " , ns/sample = " << fns_per_sample << std::endl;
701- std::cout << " \t\t TTT header.TriggerTime() [TTT_ticks] = " << TTT_ticks << " ticks. \t TTT_end_ns = " << print_timestamp (TTT_end_ns) << " ." << std::endl;
702676 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;
703677 std::cout << " \t\t TTT header.triggerTimeRollOver(): " << header.triggerTimeRollOver () << std::endl;
704- std::cout << " \t\t Full Fragment timestamp: " << print_timestamp (frag_timestamp) << " = " << frag_timestamp_s << " s " << frag_timestamp_ns << " ns." << std::endl;
705- 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;
706- if (factive_timing_frame == SPEC_TDC_TIMING) {
707- std::cout << " \t ETRIG (SPEC-TDC) timestamp of the fragment: " << std::endl;
708- std::cout << " \t\t Full UTC ETRIG timestamp: " << print_timestamp (timestamp) << " ." << std::endl;
709- 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;
710- } else if (factive_timing_frame == PTB_TIMING) {
711- std::cout << " \t HLT ETRIG (PTB) timestamp of the fragment: " << std::endl;
712- std::cout << " \t\t Full UTC HLT ETRIG timestamp: " << print_timestamp (timestamp) << " ." << std::endl;
713- 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;
714- } else if (factive_timing_frame == CAEN_ONLY_TIMING) {
715- std::cout << " \t CAEN trigger timestamp (TTT) of the fragment: " << std::endl;
716- std::cout << " \t\t Full UTC TTT timestamp: " << print_timestamp (full_TTT) << " = " << full_TTT / NANOSEC_IN_SEC << " s " << TTT_end_ns << " ns." << std::endl;
717- }
718- }
719-
720- if (fverbose | fdebug_timing) {
721- std::cout << std::fixed << std::setprecision (3 );
722- if (factive_timing_frame == SPEC_TDC_TIMING) {
723- 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;
724- } else if (factive_timing_frame == PTB_TIMING) {
725- 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;
726- } else { // CAEN_ONLY_TIMING
727- 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;
728- }
729- std::cout << " > SBNDXARAPUCADecoder::decode_fragment: TTT_end_ticks = " << TTT_ticks << " ticks. \t TTT_end_ns = " << print_timestamp (TTT_end_ns) << " ." << std::endl;
730678 }
731-
679+ //
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.
703+ //
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+ // }
707+ //
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+ // }
729+ //
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;
738+ // }
739+ // std::cout << " > SBNDXARAPUCADecoder::decode_fragment: TTT_end_ticks = " << TTT_ticks << " ticks. \t TTT_end_ns = " << print_timestamp(TTT_end_ns) << "." << std::endl;
740+ // }
741+ //
732742 // =============== Start decoding the waveforms =============== //
733743 if (fverbose) std::cout << " > SBNDXARAPUCADecoder::decode_fragment: binary decoding of the waveforms starting... " << std::endl;
734744
@@ -771,6 +781,11 @@ void sbndaq::SBNDXARAPUCADecoder::decode_fragment(uint64_t timestamp, std::vecto
771781 S++;
772782 }
773783 }
784+
785+
786+ double ini_wvfm_timestamp = 0 ;
787+ double end_wvfm_timestamp = 0 ;
788+ shift_time (fragment, TTT_ticks, TTT_end_ns, timestamp, num_samples_per_wvfm, ini_wvfm_timestamp, end_wvfm_timestamp);
774789
775790 // The decoded waveforms are dumped into two products:
776791 // - A xarapucadecoder-art.root file with the OpDetWaveforms as the product of this producer for further analysis.
@@ -878,6 +893,71 @@ void sbndaq::SBNDXARAPUCADecoder::save_debug_wvfm(size_t board_idx, size_t fragm
878893
879894}
880895
896+ void sbndaq::SBNDXARAPUCADecoder::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) {
897+
898+ int64_t pulse_duration_ns = num_samples_per_wvfm * fns_per_sample; // ns.
899+ uint64_t frag_timestamp = fragment.timestamp (); // ns.
900+ int64_t frag_timestamp_s = frag_timestamp / NANOSEC_IN_SEC; // s.
901+ int64_t frag_timestamp_ns = frag_timestamp % NANOSEC_IN_SEC; // ns.
902+
903+ // Gets the full TTT timestamp.
904+ uint64_t full_TTT = 0 ;
905+ // If the fragment timestamp is greater than the TTT end timestamp, it means that rollover occurred.
906+ if (frag_timestamp_ns > TTT_end_ns) {
907+ if (fverbose | fdebug_timing) std::cout << " > SBNDXARAPUCADecoder::decode_fragment: CAEN TTT rollover occurred w.r.t. the fragment timestamp (FTS)." << std::endl;
908+ full_TTT = (frag_timestamp_s + 1 ) * NANOSEC_IN_SEC + TTT_end_ns;
909+ } else {
910+ full_TTT = frag_timestamp_s * NANOSEC_IN_SEC + TTT_end_ns;
911+ }
912+
913+ int64_t ref_timestamp = 0 ;
914+
915+ // If an ETRIG or HLT timestamp was found it restarts the time from it. Otherwise the CAEN time frame is assigned.
916+ if (factive_timing_frame != CAEN_ONLY_TIMING) {
917+ ref_timestamp = signed_difference (full_TTT, timestamp); // ns.
918+
919+ ini_wvfm_timestamp = (ref_timestamp - pulse_duration_ns) * NANOSEC_TO_MICROSEC; // us.
920+ end_wvfm_timestamp = ref_timestamp * NANOSEC_TO_MICROSEC; // us.
921+ } else {
922+ ref_timestamp = full_TTT; // ns.
923+
924+ ini_wvfm_timestamp = ((ref_timestamp - pulse_duration_ns) % NANOSEC_IN_SEC) * NANOSEC_TO_MICROSEC; // ns.
925+ end_wvfm_timestamp = (ref_timestamp % NANOSEC_IN_SEC) * NANOSEC_TO_MICROSEC; // us.
926+ }
927+
928+ if (fdebug_timing) {
929+ std::cout << std::fixed << std::setprecision (0 );
930+ std::cout << " \t\t ns/tick = " << NANOSEC_PER_TICK << " , ns/sample = " << fns_per_sample << std::endl;
931+ std::cout << " \t\t TTT header.TriggerTime() [TTT_ticks] = " << TTT_ticks << " ticks. \t TTT_end_ns = " << print_timestamp (TTT_end_ns) << " ." << std::endl;
932+ std::cout << " \t\t Full Fragment timestamp: " << print_timestamp (frag_timestamp) << " = " << frag_timestamp_s << " s " << frag_timestamp_ns << " ns." << std::endl;
933+ 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;
934+ if (factive_timing_frame == SPEC_TDC_TIMING) {
935+ std::cout << " \t ETRIG (SPEC-TDC) timestamp of the fragment: " << std::endl;
936+ std::cout << " \t\t Full UTC ETRIG timestamp: " << print_timestamp (timestamp) << " ." << std::endl;
937+ 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;
938+ } else if (factive_timing_frame == PTB_TIMING) {
939+ std::cout << " \t HLT ETRIG (PTB) timestamp of the fragment: " << std::endl;
940+ std::cout << " \t\t Full UTC HLT ETRIG timestamp: " << print_timestamp (timestamp) << " ." << std::endl;
941+ 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;
942+ } else if (factive_timing_frame == CAEN_ONLY_TIMING) {
943+ std::cout << " \t CAEN trigger timestamp (TTT) of the fragment: " << std::endl;
944+ std::cout << " \t\t Full UTC TTT timestamp: " << print_timestamp (full_TTT) << " = " << full_TTT / NANOSEC_IN_SEC << " s " << TTT_end_ns << " ns." << std::endl;
945+ }
946+ }
947+
948+ if (fverbose | fdebug_timing) {
949+ std::cout << std::fixed << std::setprecision (3 );
950+ if (factive_timing_frame == SPEC_TDC_TIMING) {
951+ 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;
952+ } else if (factive_timing_frame == PTB_TIMING) {
953+ 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;
954+ } else { // CAEN_ONLY_TIMING
955+ 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;
956+ }
957+ std::cout << " > SBNDXARAPUCADecoder::decode_fragment: TTT_end_ticks = " << TTT_ticks << " ticks. \t TTT_end_ns = " << print_timestamp (TTT_end_ns) << " ." << std::endl;
958+ }
959+ }
960+
881961/* *
882962 * @brief Extract a sample from a 64-bit buffer using the specified bit positions.
883963 *
@@ -975,11 +1055,11 @@ uint64_t sbndaq::SBNDXARAPUCADecoder::abs_difference(uint64_t t1, uint64_t t2) {
9751055}
9761056
9771057/* *
978- * @brief Formats a timestamp in nanoseconds into a easily readable string format.
979- * @param[in] timestamp The timestamp in nanoseconds to be formatted.
980- * @return A string representation of the timestamp in the format "(seconds)nanoseconds ns".
981- * @details The function divides the input timestamp by 1,000,000,000 to obtain the seconds component and uses the modulus operator to get the remaining nanoseconds.
982- */
1058+ * @brief Formats a timestamp in nanoseconds into a easily readable string format.
1059+ * @param[in] timestamp The timestamp in nanoseconds to be formatted.
1060+ * @return A string representation of the timestamp in the format "(seconds)nanoseconds ns".
1061+ * @details The function divides the input timestamp by 1,000,000,000 to obtain the seconds component and uses the modulus operator to get the remaining nanoseconds.
1062+ */
9831063std::string sbndaq::SBNDXARAPUCADecoder::print_timestamp (uint64_t timestamp) {
9841064 return " (" + std::to_string (timestamp / NANOSEC_IN_SEC) + " )" + std::to_string (timestamp % NANOSEC_IN_SEC) + " ns" ;
9851065}
0 commit comments