@@ -126,6 +126,7 @@ class sbndaq::SBNDXARAPUCADecoder : public art::EDProducer {
126126 int fstore_debug_waveforms; /* *< Number of waveforms to store in the ServiceHandle object for debugging purposes (0: none, -1: all, n: first n waveforms each event). */
127127
128128 bool fcombine_ext_frag; /* *< If `true` combines extended fragments into a single raw::OpDetWaveform object. */
129+ int32_t fallowed_jittering; /* *< Allowed jittering (in ns) between fragments to be combined. */
129130
130131 bool fdebug_tdc_handle; /* *< If `true` SPEC-TDC information is printed. */
131132 bool fdebug_ptb_handle; /* *< If `true` PTB information is printed. */
@@ -138,7 +139,7 @@ class sbndaq::SBNDXARAPUCADecoder : public art::EDProducer {
138139 bool fverbose; /* *< If `true` it increases verbosity of console output for detailed processing steps. */
139140
140141 // Main processing method.
141- void decode_fragment (uint64_t timestamp, uint64_t & nominal_frag_timestamp, int32_t & nominal_TTT , int32_t & prev_TTT, std::vector<size_t > & fragment_indices, const artdaq::Fragment& fragment, std::vector <raw::OpDetWaveform>& prod_wvfms, std::vector<std::vector<uint16_t >>& wvfms, bool last_one);
142+ void decode_fragment (uint64_t timestamp, uint64_t & first_frag_timestamp, size_t & first_frag_idx, int32_t & first_TTT , int32_t & prev_TTT, std::vector<size_t > & fragment_indices, const artdaq::Fragment& fragment, std::vector <raw::OpDetWaveform>& prod_wvfms, std::vector<std::vector<uint16_t >>& wvfms, bool last_one);
142143
143144 // Timing.
144145 void shift_time (uint64_t TTT_ticks, int64_t TTT_end_ns, uint64_t frag_timestamp, uint64_t timestamp, uint32_t num_samples_per_wvfm, double & ini_wvfm_timestamp, double & end_wvfm_timestamp);
@@ -152,10 +153,10 @@ class sbndaq::SBNDXARAPUCADecoder : public art::EDProducer {
152153 unsigned int get_channel_id (unsigned int board, unsigned int board_channel);
153154
154155 // Combines decoded waveforms.
155- void combine_waveforms (std::vector<std::vector<uint16_t >>& wvfms, const std::vector<std::vector<uint16_t >>& fragment_wvfms, uint32_t num_channels);
156+ void append_waveforms (std::vector<std::vector<uint16_t >>& wvfms, const std::vector<std::vector<uint16_t >>& fragment_wvfms, uint32_t num_channels);
156157
157158 // Dumps and saves waveforms.
158- void dump_waveforms (std::vector <raw::OpDetWaveform> & prod_wvfms, std::vector<std::vector<uint16_t >>& wvfms, std::vector< size_t > & fragment_indices , size_t board_index, uint32_t num_channels, double ini_wvfm_timestamp, double end_wvfm_timestamp);
159+ void dump_waveforms (std::vector <raw::OpDetWaveform> & prod_wvfms, std::vector<std::vector<uint16_t >>& wvfms, size_t first_frag_idx , size_t board_index, uint32_t num_channels, double ini_wvfm_timestamp, double end_wvfm_timestamp);
159160 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);
160161 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);
161162
@@ -217,6 +218,7 @@ sbndaq::SBNDXARAPUCADecoder::SBNDXARAPUCADecoder(fhicl::ParameterSet const& p)
217218
218219 // Gets the combination of extended fragments option.
219220 fcombine_ext_frag = p.get <bool > (" combine_ext_frag" , true );
221+ fallowed_jittering = p.get <int32_t > (" allowed_jittering" , 64 );
220222
221223 // Gets the debug and verbose options.
222224 fdebug_ptb_handle = p.get <bool > (" debug_ptb_handle" , false );
@@ -320,15 +322,16 @@ void sbndaq::SBNDXARAPUCADecoder::produce(art::Event& e) {
320322 // Flag to track if valid CAEN fragments are found.
321323 bool found_caen = false ;
322324
323- std::vector<size_t > fragment_indices (fnum_caen_boards, 0 );
325+ std::vector<size_t > fragment_indices (fnum_caen_boards, - 1 );
324326 std::vector<std::vector <uint16_t >> wvfms;
325327 if (fdebug_extended_fragments) {
326328 std::cout << " Waveforms size: " << wvfms.size () << std::endl;
327329 }
328330
329- int32_t nominal_TTT = TTT_DEFAULT;
331+ size_t first_frag_idx = 0 ;
332+ int32_t first_TTT = TTT_DEFAULT;
330333 int32_t prev_TTT = 0 ;
331- uint64_t nominal_frag_timestamp = TTT_DEFAULT;
334+ uint64_t first_frag_timestamp = TTT_DEFAULT;
332335 bool last_one = false ;
333336
334337 if (fverbose | fdebug_fragments_handle) std::cout << " \n > SBNDXARAPUCADecoder::produce: searching for V1740 fragments..." << std::endl;
@@ -368,7 +371,7 @@ void sbndaq::SBNDXARAPUCADecoder::produce(art::Event& e) {
368371 for (size_t f = 0 ; f < num_caen_fragments; f++) {
369372 const artdaq::Fragment fragment = *container_fragment[f].get ();
370373 last_one = f == (num_caen_fragments - 1 );
371- decode_fragment (timestamp, nominal_frag_timestamp, nominal_TTT , prev_TTT, fragment_indices, fragment, *prod_wvfms, wvfms, last_one);
374+ decode_fragment (timestamp, first_frag_timestamp, first_frag_idx, first_TTT , prev_TTT, fragment_indices, fragment, *prod_wvfms, wvfms, last_one);
372375 } // End CAEN V1740 fragments loop.
373376 }
374377 } // End Container fragments loop.
@@ -381,7 +384,7 @@ void sbndaq::SBNDXARAPUCADecoder::produce(art::Event& e) {
381384 for (size_t f = 0 ; f < frag_handle_size; f++) {
382385 const artdaq::Fragment fragment = fragment_handle->at (f);
383386 last_one = f == (frag_handle_size - 1 );
384- decode_fragment (timestamp, nominal_frag_timestamp, nominal_TTT , prev_TTT, fragment_indices, fragment, *prod_wvfms, wvfms, last_one);
387+ decode_fragment (timestamp, first_frag_timestamp, first_frag_idx, first_TTT , prev_TTT, fragment_indices, fragment, *prod_wvfms, wvfms, last_one);
385388 } // End CAEN V1740 fragments loop.
386389 }
387390 } // End extracting CAEN V1740 fragments.
@@ -407,8 +410,9 @@ void sbndaq::SBNDXARAPUCADecoder::produce(art::Event& e) {
407410/* *
408411 * @brief Decodes a CAEN V1740 fragment, extracts the waveforms and combines them into the output product.
409412 * @param[in] timestamp The valid timestamp used as reference for the event.
410- * @param[in,out] nominal_frag_timestamp The nominal timestamp calculated for the fragment being processed.
411- * @param[in,out] nominal_TTT The nominal Trigger Time Tag (TTT) calculated for the fragment being processed.
413+ * @param[in,out] first_frag_timestamp The nominal timestamp calculated for the fragment being processed.
414+ * @param[in, out] first_frag_idx The first index of the fragments being combined.
415+ * @param[in,out] first_TTT The nominal Trigger Time Tag (TTT) calculated for the fragment being processed.
412416 * @param[in,out] fragment_indices A vector containing the indices of the fragments already processed for each board.
413417 * @param[in] fragment The artdaq::Fragment object to be processed.
414418 * @param[in,out] prod_wvfms The vector of raw::OpDetWaveform objects to be filled with the decoded waveforms.
@@ -429,11 +433,11 @@ void sbndaq::SBNDXARAPUCADecoder::produce(art::Event& e) {
429433 * @post The vector of raw::OpDetWaveform objects is filled with the decoded waveforms from the fragment.
430434 * @see shift_time
431435 * @see decode_waveforms
432- * @see combine_waveforms
436+ * @see append_waveforms
433437 * @see dump_waveforms
434438 */
435439
436- void sbndaq::SBNDXARAPUCADecoder::decode_fragment (uint64_t timestamp, uint64_t & nominal_frag_timestamp, int32_t & nominal_TTT , int32_t & prev_TTT, std::vector<size_t > & fragment_indices, const artdaq::Fragment& fragment, std::vector <raw::OpDetWaveform>& prod_wvfms, std::vector<std::vector<uint16_t >>& wvfms, bool last_one) {
440+ void sbndaq::SBNDXARAPUCADecoder::decode_fragment (uint64_t timestamp, uint64_t & first_frag_timestamp, size_t & first_frag_idx, int32_t & first_TTT , int32_t & prev_TTT, std::vector<size_t > & fragment_indices, const artdaq::Fragment& fragment, std::vector <raw::OpDetWaveform>& prod_wvfms, std::vector<std::vector<uint16_t >>& wvfms, bool last_one) {
437441 auto fragment_id = fragment.fragmentID () - ffragment_id_offset;
438442 auto it = std::find (fboard_id_list.begin (), fboard_id_list.end (), fragment_id);
439443 size_t board_idx;
@@ -451,6 +455,7 @@ void sbndaq::SBNDXARAPUCADecoder::decode_fragment(uint64_t timestamp, uint64_t&
451455 }
452456
453457 if (valid_fragment) {
458+ fragment_indices[board_idx]++;
454459 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;
455460
456461 // =============== Accesses Event metadata and Event header for this fragment =============== //
@@ -518,71 +523,72 @@ void sbndaq::SBNDXARAPUCADecoder::decode_fragment(uint64_t timestamp, uint64_t&
518523 }
519524
520525 if (fcombine_ext_frag) {
521- bool is_nominal_length = (num_nominal_samples_per_wvfm == num_samples_per_wvfm);
526+
527+ // Combination variables and checks.
528+
529+ bool is_nominal = (num_nominal_samples_per_wvfm == num_samples_per_wvfm);
522530 bool is_first = (fragment_indices[board_idx] == 0 );
523531
532+ int32_t frag_length = num_samples_per_wvfm * fns_per_sample; // ns.
533+
534+ // - Computation of the difference w.r.t. previous TTT difference.
524535 int32_t TTT_dif = 0 ;
525- // If the fragment timestamp is greater than the TTT end timestamp, it means that rollover occurred.
526- if (nominal_TTT > TTT_end_ns) {
536+ if (prev_TTT > TTT_end_ns) {
527537 if (fverbose | fdebug_timing) std::cout << " > SBNDXARAPUCADecoder::decode_fragment: CAEN TTT rollover occurred." << std::endl;
528- TTT_dif = nominal_TTT - (NANOSEC_IN_SEC - TTT_end_ns);
538+ TTT_dif = prev_TTT - (NANOSEC_IN_SEC - TTT_end_ns);
529539 } else {
530- TTT_dif = TTT_end_ns - nominal_TTT ;
540+ TTT_dif = TTT_end_ns - prev_TTT ;
531541 }
532- bool is_in_time = TTT_dif <= static_cast <int >(num_nominal_samples_per_wvfm * fns_per_sample);
533-
534- int32_t TTT_ini_ns = TTT_end_ns - static_cast <int32_t >(num_nominal_samples_per_wvfm * fns_per_sample);
535-
536- if (is_nominal_length) {
537- if (fdebug_jittering) {
538- std::cout << " \t\t NOMINAL fragment (" << num_samples_per_wvfm << " ), [" << TTT_ini_ns << " , " << TTT_end_ns << " ] diff with prev: " << TTT_end_ns - prev_TTT << " ns, length: " << num_samples_per_wvfm * fns_per_sample << " ns, diff_with_length: " << (TTT_end_ns - prev_TTT) - (num_samples_per_wvfm * fns_per_sample) << std::endl;
539- }
540- if (!is_first) {
541- if (fdebug_extended_fragments) {
542- std::cout << " \t\t NOT FIRST NOMINAL fragment " << std::endl;
543- std::cout << " \t\t nominal_TTT: " << nominal_TTT << " TTT_end_ns: " << TTT_end_ns << std::endl;
544- std::cout << " \t\t nominal_frag_timestamp: " << nominal_frag_timestamp << " frag_timestamp : " << frag_timestamp << std::endl;
542+
543+ // - Computation of the difference between TTTs difference and the length of the fragment in ns (to detect jittering between fragments).
544+ // int32_t J = TTT_dif - frag_length;
545+
546+ // - Combination boolean variable.
547+ // bool dump_comb_wvfms = true;
548+ /* if (is_nominal) { // Nominal fragment
549+ if (!is_first && (TTT_dif <= (frag_length - fallowed_jittering))) {
550+ std::cout << "\t\t WARNING: NOMINAL fragment too close to previous one! TTT_dif: " << TTT_dif << " ns, fragment idx: " << fragment_indices[board_idx] << ", board idx: " << board_idx << " (slot " << fboard_id_list[board_idx] << "), " << num_samples_per_wvfm << " samples. Skipping this fragment..." << std::endl;
545551 }
546- shift_time (TTT_ticks, nominal_TTT, nominal_frag_timestamp, timestamp, num_nominal_samples_per_wvfm, ini_wvfm_timestamp, end_wvfm_timestamp);
547- dump_waveforms (prod_wvfms, wvfms, fragment_indices, board_idx, num_channels, ini_wvfm_timestamp, end_wvfm_timestamp);
548- } else {
549- if (fdebug_extended_fragments) std::cout << " \t\t FIRST NOMINAL fragment " << std::endl;
550- }
551- combine_waveforms (wvfms, fragment_wvfms, num_channels);
552- nominal_TTT = TTT_end_ns;
553- nominal_frag_timestamp = frag_timestamp;
554- } else if (is_in_time) {
555- if (fdebug_extended_fragments) {
556- std::cout << " \t\t EXTENDED fragment " << std::endl;
557- std::cout << " \t\t TTT_dif w.r.t. nominal TTT: " << TTT_dif << " ns, is_in_time: " << is_in_time << std::endl;
558- }
559- if (fdebug_jittering) {
560- std::cout << " \t\t EXTENDED fragment (" << num_samples_per_wvfm << " ), [" << TTT_ini_ns << " , " << TTT_end_ns << " ] diff with prev: " << TTT_end_ns - prev_TTT << " ns, length: " << num_samples_per_wvfm * fns_per_sample << " ns, diff_with_length: " << (TTT_end_ns - prev_TTT) - (num_samples_per_wvfm * fns_per_sample) << std::endl;
561- }
552+ } else { // Extended fragment
553+ if (std::abs(J) <= fallowed_jittering) {
554+ dump_comb_wvfms = false;
555+ } else if (TTT_dif <= (frag_length - fallowed_jittering)) {
556+ dump_comb_wvfms = false;
557+ std::cout << "\t\t WARNING: EXTENDED fragment too close to previous one! TTT_dif: " << TTT_dif << " ns, fragment idx: " << fragment_indices[board_idx] << ", board idx: " << board_idx << " (slot " << fboard_id_list[board_idx] << "), " << num_samples_per_wvfm << " samples. Skipping this fragment..." << std::endl;
558+ }
559+ }*/
562560
563- combine_waveforms (wvfms, fragment_wvfms, num_channels);
564- } else if (!is_in_time) {
565- // combine_waveforms(wvfms, fragment_wvfms, num_channels); //TEMP!!!!!
566- if (fdebug_jittering ) {
567- std::cout << " \t\t EXTENDED? fragment ( " << num_samples_per_wvfm << " ), [ " << TTT_ini_ns << " , " << TTT_end_ns << " ] diff with prev: " << TTT_end_ns - prev_TTT << " ns, length: " << num_samples_per_wvfm * fns_per_sample << " ns, diff_with_length: " << (TTT_end_ns - prev_TTT) - (num_samples_per_wvfm * fns_per_sample) << std::endl ;
568- }
569- std::cout << " \t\t WARNING: EXTENDED fragment out of time window! TTT_dif: " << TTT_dif << " ns, fragment idx: " << fragment_indices[board_idx] << " , board idx: " << board_idx << " (slot " << fboard_id_list[board_idx] << " ), " << num_samples_per_wvfm << " samples. Skipping this fragment... " << std::endl ;
561+
562+ bool dump_comb_wvfms = !is_first && (is_nominal || (!is_nominal && (TTT_dif > (frag_length + fallowed_jittering))));
563+
564+ if (is_first ) {
565+ first_frag_idx = fragment_indices[board_idx] ;
566+ first_TTT = TTT_end_ns;
567+ first_frag_timestamp = frag_timestamp ;
570568 }
571-
572- fragment_indices[board_idx]++;
573569
570+ if (dump_comb_wvfms) {
571+ shift_time (TTT_ticks, first_TTT, first_frag_timestamp, timestamp, num_nominal_samples_per_wvfm, ini_wvfm_timestamp, end_wvfm_timestamp);
572+ dump_waveforms (prod_wvfms, wvfms, first_frag_idx, board_idx, num_channels, ini_wvfm_timestamp, end_wvfm_timestamp);
573+ first_frag_idx = fragment_indices[board_idx];
574+ first_TTT = TTT_end_ns;
575+ first_frag_timestamp = frag_timestamp;
576+ }
577+ append_waveforms (wvfms, fragment_wvfms, num_channels);
578+
574579 if (last_one) {
575580 if (fdebug_extended_fragments) std::cout << " \t\t LAST fragment " << std::endl;
576- shift_time (TTT_ticks, nominal_TTT, nominal_frag_timestamp, timestamp, num_nominal_samples_per_wvfm, ini_wvfm_timestamp, end_wvfm_timestamp);
577- dump_waveforms (prod_wvfms, wvfms, fragment_indices, board_idx, num_channels, ini_wvfm_timestamp, end_wvfm_timestamp);
581+ fragment_indices[board_idx]++;
582+ shift_time (TTT_ticks, first_TTT, first_frag_timestamp, timestamp, num_nominal_samples_per_wvfm, ini_wvfm_timestamp, end_wvfm_timestamp);
583+ dump_waveforms (prod_wvfms, wvfms, first_frag_idx, board_idx, num_channels, ini_wvfm_timestamp, end_wvfm_timestamp);
578584 }
585+
579586 prev_TTT = TTT_end_ns;
580- } else {
587+
588+ } else { // Combination of extended fragments disabled.
581589 shift_time (TTT_ticks, TTT_end_ns, frag_timestamp, timestamp, num_samples_per_wvfm, ini_wvfm_timestamp, end_wvfm_timestamp);
582- dump_waveforms (prod_wvfms, fragment_wvfms, fragment_indices, board_idx, num_channels, ini_wvfm_timestamp, end_wvfm_timestamp);
583- fragment_indices[board_idx]++;
590+ dump_waveforms (prod_wvfms, fragment_wvfms, first_frag_idx, board_idx, num_channels, ini_wvfm_timestamp, end_wvfm_timestamp);
584591 }
585-
586592 }
587593
588594}
@@ -1008,8 +1014,8 @@ unsigned int sbndaq::SBNDXARAPUCADecoder::get_channel_id(unsigned int board, uns
10081014 * @pre The `fragment_wvfms` vector should contain waveforms for all channels of the board being processed.
10091015 * @pre The `wvfms` vector should be either empty or already contain waveforms for all channels of the board being processed.
10101016 */
1011- void sbndaq::SBNDXARAPUCADecoder::combine_waveforms (std::vector<std::vector<uint16_t >>& wvfms, const std::vector<std::vector<uint16_t >>& fragment_wvfms, uint32_t num_channels) {
1012- if (fdebug_extended_fragments) std::cout << " > SBNDXARAPUCADecoder::combine_waveforms : combining waveforms from extended fragments..." << std::endl;
1017+ void sbndaq::SBNDXARAPUCADecoder::append_waveforms (std::vector<std::vector<uint16_t >>& wvfms, const std::vector<std::vector<uint16_t >>& fragment_wvfms, uint32_t num_channels) {
1018+ if (fdebug_extended_fragments) std::cout << " > SBNDXARAPUCADecoder::append_waveforms : combining waveforms from extended fragments..." << std::endl;
10131019 if (wvfms.empty ()) {
10141020 if (fdebug_extended_fragments) {
10151021 std::cout << " \t\t Empty waveforms, resizing to " << num_channels << " channels." << std::endl;
@@ -1059,7 +1065,7 @@ void sbndaq::SBNDXARAPUCADecoder::combine_waveforms(std::vector<std::vector<uint
10591065 * @see save_prod_wvfm
10601066 * @see save_debug_wvfm
10611067 */
1062- void sbndaq::SBNDXARAPUCADecoder::dump_waveforms (std::vector <raw::OpDetWaveform> & prod_wvfms, std::vector<std::vector<uint16_t >>& wvfms, std::vector< size_t > & fragment_indices , size_t board_idx, uint32_t num_channels, double ini_wvfm_timestamp, double end_wvfm_timestamp) {
1068+ void sbndaq::SBNDXARAPUCADecoder::dump_waveforms (std::vector <raw::OpDetWaveform> & prod_wvfms, std::vector<std::vector<uint16_t >>& wvfms, size_t first_frag_idx , size_t board_idx, uint32_t num_channels, double ini_wvfm_timestamp, double end_wvfm_timestamp) {
10631069
10641070 // The decoded waveforms are dumped into two products:
10651071 // - A xarapucadecoder-art.root file with the OpDetWaveforms as the product of this producer for further analysis.
@@ -1078,14 +1084,15 @@ void sbndaq::SBNDXARAPUCADecoder::dump_waveforms(std::vector <raw::OpDetWaveform
10781084
10791085 for (ch = 0 ; ch < num_debug_wvfms; ch++) {
10801086 save_prod_wvfm (board_idx, ch, ini_wvfm_timestamp, wvfms, prod_wvfms);
1081- save_debug_wvfm (board_idx, fragment_indices[board_idx] , ch, ini_wvfm_timestamp, end_wvfm_timestamp, wvfms);
1087+ save_debug_wvfm (board_idx, first_frag_idx , ch, ini_wvfm_timestamp, end_wvfm_timestamp, wvfms);
10821088 }
10831089
10841090 for (;ch < num_channels; ch++) {
10851091 save_prod_wvfm (board_idx, ch, ini_wvfm_timestamp, wvfms, prod_wvfms);
10861092 }
10871093
10881094 wvfms.clear ();
1095+
10891096}
10901097
10911098/* *
0 commit comments