Skip to content

Commit 43f7614

Browse files
committed
Update combination condition with timing features integrating the expected jittering of the extended fragments.
1 parent 3f44697 commit 43f7614

2 files changed

Lines changed: 78 additions & 70 deletions

File tree

sbndcode/Decoders/XARAPUCA/SBNDXARAPUCADecoder_module.cc

Lines changed: 72 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)