@@ -81,6 +81,8 @@ bool PhaseITreeMaker::Initialise(std::string config_filename, DataModel& data)
81
81
output_tree_->Branch (" subrun" , &subrun_number_, " subrun/i" );
82
82
output_tree_->Branch (" event" , &event_number_, " event/i" );
83
83
output_tree_->Branch (" minibuffer" , &minibuffer_number_, " minibuffer/I" );
84
+ output_tree_->Branch (" spill" , &spill_number_, " spill/I" );
85
+ output_tree_->Branch (" in_spill" , &in_spill_, " in_spill/O" );
84
86
output_tree_->Branch (" ncv_position" , &ncv_position_, " ncv_position/I" );
85
87
output_tree_->Branch (" event_time_ns" , &event_time_ns_, " event_time_ns/L" );
86
88
output_tree_->Branch (" label" , &event_label_, " label/b" );
@@ -119,7 +121,7 @@ bool PhaseITreeMaker::Initialise(std::string config_filename, DataModel& data)
119
121
output_pulse_tree_->Branch (" run" , &run_number_, " run/i" );
120
122
output_pulse_tree_->Branch (" subrun" , &subrun_number_, " subrun/i" );
121
123
output_pulse_tree_->Branch (" event" , &event_number_, " event/i" );
122
- output_pulse_tree_->Branch (" spill" , &spill_number_, " spill/i " );
124
+ output_pulse_tree_->Branch (" spill" , &spill_number_, " spill/I " );
123
125
output_pulse_tree_->Branch (" minibuffer_number" , &minibuffer_number_,
124
126
" minibuffer_number/I" );
125
127
output_pulse_tree_->Branch (" ncv_position" , &ncv_position_, " ncv_position/I" );
@@ -249,114 +251,121 @@ bool PhaseITreeMaker::Execute() {
249
251
get_object_from_store (" RecoADCHits" , adc_hits, *annie_event);
250
252
check_that_not_empty (" RecoADCHits" , adc_hits);
251
253
252
- int old_spill_number = spill_number_;
254
+ int old_spill_number = 0 ;
255
+ spill_number_ = 0 ;
253
256
254
- for (const auto & pair : adc_hits) {
257
+ bool make_pulse_tree = true ;
258
+ m_variables.Get (" MakePulseTree" , make_pulse_tree);
255
259
256
- const auto & channel_key = pair.first ;
257
- const auto & minibuffer_pulses = pair.second ;
260
+ // Skip making the pulse tree if it has been disabled
261
+ if ( make_pulse_tree ) {
262
+ for (const auto & pair : adc_hits) {
258
263
259
- // Use the same spill number for each channel by resetting it during
260
- // each channel loop iteration. The final loop will increment it in a
261
- // without resetting it for the next event.
262
- spill_number_ = old_spill_number;
264
+ const auto & channel_key = pair.first ;
265
+ const auto & minibuffer_pulses = pair.second ;
263
266
264
- pulse_pmt_id_ = channel_key.GetDetectorElementIndex ();
267
+ // Use the same spill number for each channel by resetting it during
268
+ // each channel loop iteration. The final loop will increment it in a
269
+ // without resetting it for the next event.
270
+ spill_number_ = old_spill_number;
265
271
266
- // Flag that vetos minibuffers because the last beam minibuffer failed
267
- // the quality cuts.
268
- bool beam_veto_active = false ;
272
+ pulse_pmt_id_ = channel_key.GetDetectorElementIndex ();
269
273
270
- for (size_t mb = 0 ; mb < num_minibuffers; ++mb) {
274
+ // Flag that vetos minibuffers because the last beam minibuffer failed
275
+ // the quality cuts.
276
+ bool beam_veto_active = false ;
271
277
272
- minibuffer_number_ = mb;
278
+ for ( size_t mb = 0 ; mb < num_minibuffers; ++mb) {
273
279
274
- // Determine the correct label for the events in this minibuffer
275
- MinibufferLabel event_mb_label = mb_labels.at (mb);
276
- event_label_ = static_cast <uint8_t >( event_mb_label );
280
+ minibuffer_number_ = mb;
277
281
278
- // If this is Hefty mode data, save the trigger mask for the
279
- // current minibuffer. This is distinct from the MinibufferLabel
280
- // assigned to the event_label_ variable above. The trigger
281
- // mask branch isn't used for non-Hefty data.
282
- if ( hefty_mode_ ) hefty_trigger_mask_ = hefty_info.label (mb);
283
- else hefty_trigger_mask_ = 0 ;
282
+ // Determine the correct label for the events in this minibuffer
283
+ MinibufferLabel event_mb_label = mb_labels.at (mb);
284
+ event_label_ = static_cast <uint8_t >( event_mb_label );
284
285
285
- // BEAM QUALITY CUT
286
- // Skip beam minibuffers with bad or missing beam status information
287
- // TODO: consider printing a warning message here
288
- const auto & beam_status = beam_statuses.at (mb);
289
- const auto & beam_condition = beam_status.condition ();
290
- if (beam_condition == BeamCondition::Missing
291
- || beam_condition == BeamCondition::Bad)
292
- {
293
- // Skip all beam and Hefty window minibuffers until a good-quality beam
294
- // spill is found again
295
- beam_veto_active = true ;
296
- }
297
- if ( beam_veto_active && beam_condition == BeamCondition::Ok ) {
298
- // We've found a new beam minibuffer that passed the quality check,
299
- // so disable the beam quality veto
300
- beam_veto_active = false ;
301
- }
302
- if (beam_veto_active && (event_mb_label == MinibufferLabel::Hefty
303
- || event_mb_label == MinibufferLabel::Beam))
304
- {
305
- // Bad beam minibuffers and Hefty window minibuffers belonging to the
306
- // bad beam spill need to be skipped. Since other minibuffers (e.g.,
307
- // cosmic trigger minibuffers) are not part of the beam "macroevent,"
308
- // they may still be processed normally.
309
- continue ;
310
- }
286
+ // If this is Hefty mode data, save the trigger mask for the
287
+ // current minibuffer. This is distinct from the MinibufferLabel
288
+ // assigned to the event_label_ variable above. The trigger
289
+ // mask branch isn't used for non-Hefty data.
290
+ if ( hefty_mode_ ) hefty_trigger_mask_ = hefty_info.label (mb);
291
+ else hefty_trigger_mask_ = 0 ;
311
292
312
- if (beam_condition == BeamCondition::Ok) ++spill_number_;
313
-
314
- for (const ADCPulse& pulse : minibuffer_pulses.at (mb) ) {
315
- // For non-Hefty mode, the neutron capture candidate event time
316
- // is simply its timestamp relative to the start of the single
317
- // minibuffer.
318
- pulse_start_time_ns_ = pulse.start_time ().GetNs ();
319
- pulse_amplitude_ = pulse.amplitude ();
320
- pulse_charge_ = pulse.charge ();
321
- pulse_raw_amplitude_ = pulse.raw_amplitude ();
322
-
323
- // For Hefty mode, the pulse time within the current minibuffer
324
- // needs to be added to the TSinceBeam value for Hefty window
325
- // minibuffers (labeled by the RawLoader tool with
326
- // MinibufferLabel::Hefty). This should be zero for all other
327
- // minibuffers (it defaults to that value in the heftydb TTree).
328
- //
329
- // NOTE: event times for minibuffer labels other than "Beam", "Source",
330
- // and "Hefty" are calculated relative to the start of the minibuffer,
331
- // not the beam, source trigger, etc. Only make timing plots using
332
- // those 3 labels unless you're interested in single-minibuffer timing!
333
- if ( hefty_mode_ && event_mb_label == MinibufferLabel::Hefty) {
334
- // The name "TSinceBeam" is used in the heftydb tree for the time
335
- // since a beam *or* a source trigger, since the two won't be used
336
- // simultaneously.
337
- pulse_start_time_ns_ += hefty_info.t_since_beam (mb);
293
+ // BEAM QUALITY CUT
294
+ // Skip beam minibuffers with bad or missing beam status information
295
+ // TODO: consider printing a warning message here
296
+ const auto & beam_status = beam_statuses.at (mb);
297
+ const auto & beam_condition = beam_status.condition ();
298
+ if (beam_condition == BeamCondition::Missing
299
+ || beam_condition == BeamCondition::Bad)
300
+ {
301
+ // Skip all beam and Hefty window minibuffers until a good-quality beam
302
+ // spill is found again
303
+ beam_veto_active = true ;
338
304
}
339
-
340
- // Minibuffers for which TSinceBeam has been
341
- // calculated are considered "in the spill" (i.e., the pulse time
342
- // is expressed relative to the beam time), while those for which
343
- // it is not are not "in the spill."
344
- if ( !hefty_mode_ || (event_mb_label == MinibufferLabel::Hefty
345
- || event_mb_label == MinibufferLabel::Beam
346
- || event_mb_label == MinibufferLabel::Source) )
305
+ if ( beam_veto_active && beam_condition == BeamCondition::Ok ) {
306
+ // We've found a new beam minibuffer that passed the quality check,
307
+ // so disable the beam quality veto
308
+ beam_veto_active = false ;
309
+ }
310
+ if (beam_veto_active && (event_mb_label == MinibufferLabel::Hefty
311
+ || event_mb_label == MinibufferLabel::Beam))
347
312
{
348
- in_spill_ = true ;
313
+ // Bad beam minibuffers and Hefty window minibuffers belonging to the
314
+ // bad beam spill need to be skipped. Since other minibuffers (e.g.,
315
+ // cosmic trigger minibuffers) are not part of the beam "macroevent,"
316
+ // they may still be processed normally.
317
+ continue ;
349
318
}
350
- else in_spill_ = false ;
351
-
352
- output_pulse_tree_->Fill ();
353
319
354
- Log (" Found pulse on channel " + std::to_string (pulse_pmt_id_)
355
- + " in run " + std::to_string (run_number_) + " subrun "
356
- + std::to_string (subrun_number_) + " event "
357
- + std::to_string (event_number_) + " in minibuffer "
358
- + std::to_string (minibuffer_number_) + " at "
359
- + std::to_string (pulse_start_time_ns_) + " ns" , 3 , verbosity_);
320
+ if (beam_condition == BeamCondition::Ok) ++spill_number_;
321
+
322
+ for (const ADCPulse& pulse : minibuffer_pulses.at (mb) ) {
323
+ // For non-Hefty mode, the neutron capture candidate event time
324
+ // is simply its timestamp relative to the start of the single
325
+ // minibuffer.
326
+ pulse_start_time_ns_ = pulse.start_time ().GetNs ();
327
+ pulse_amplitude_ = pulse.amplitude ();
328
+ pulse_charge_ = pulse.charge ();
329
+ pulse_raw_amplitude_ = pulse.raw_amplitude ();
330
+
331
+ // For Hefty mode, the pulse time within the current minibuffer
332
+ // needs to be added to the TSinceBeam value for Hefty window
333
+ // minibuffers (labeled by the RawLoader tool with
334
+ // MinibufferLabel::Hefty). This should be zero for all other
335
+ // minibuffers (it defaults to that value in the heftydb TTree).
336
+ //
337
+ // NOTE: event times for minibuffer labels other than "Beam", "Source",
338
+ // and "Hefty" are calculated relative to the start of the minibuffer,
339
+ // not the beam, source trigger, etc. Only make timing plots using
340
+ // those 3 labels unless you're interested in single-minibuffer timing!
341
+ if ( hefty_mode_ && event_mb_label == MinibufferLabel::Hefty) {
342
+ // The name "TSinceBeam" is used in the heftydb tree for the time
343
+ // since a beam *or* a source trigger, since the two won't be used
344
+ // simultaneously.
345
+ pulse_start_time_ns_ += hefty_info.t_since_beam (mb);
346
+ }
347
+
348
+ // Minibuffers for which TSinceBeam has been
349
+ // calculated are considered "in the spill" (i.e., the pulse time
350
+ // is expressed relative to the beam time), while those for which
351
+ // it is not are not "in the spill."
352
+ if ( !hefty_mode_ || (event_mb_label == MinibufferLabel::Hefty
353
+ || event_mb_label == MinibufferLabel::Beam
354
+ || event_mb_label == MinibufferLabel::Source) )
355
+ {
356
+ in_spill_ = true ;
357
+ }
358
+ else in_spill_ = false ;
359
+
360
+ output_pulse_tree_->Fill ();
361
+
362
+ Log (" Found pulse on channel " + std::to_string (pulse_pmt_id_)
363
+ + " in run " + std::to_string (run_number_) + " subrun "
364
+ + std::to_string (subrun_number_) + " event "
365
+ + std::to_string (event_number_) + " in minibuffer "
366
+ + std::to_string (minibuffer_number_) + " at "
367
+ + std::to_string (pulse_start_time_ns_) + " ns" , 3 , verbosity_);
368
+ }
360
369
}
361
370
}
362
371
}
@@ -447,6 +456,9 @@ bool PhaseITreeMaker::Execute() {
447
456
continue ;
448
457
}
449
458
459
+ // Increment the spill counter since this is a good spill
460
+ if (beam_condition == BeamCondition::Ok) ++spill_number_;
461
+
450
462
// Increment beam POT count, etc. based on the characteristics of the
451
463
// current minibuffer
452
464
if (beam_condition == BeamCondition::Ok) {
@@ -467,6 +479,18 @@ bool PhaseITreeMaker::Execute() {
467
479
++pos_info.num_led_triggers ;
468
480
}
469
481
482
+ // Minibuffers for which TSinceBeam has been
483
+ // calculated are considered "in the spill" (i.e., the pulse time
484
+ // is expressed relative to the beam time), while those for which
485
+ // it is not are not "in the spill."
486
+ if ( !hefty_mode_ || (event_mb_label == MinibufferLabel::Hefty
487
+ || event_mb_label == MinibufferLabel::Beam
488
+ || event_mb_label == MinibufferLabel::Source) )
489
+ {
490
+ in_spill_ = true ;
491
+ }
492
+ else in_spill_ = false ;
493
+
470
494
find_ncv_events (ncv_pmt1_pulses, NCV_PMT1_ID, old_time_ncv1, adc_hits,
471
495
hefty_info, event_mb_label, mb);
472
496
find_ncv_events (ncv_pmt2_pulses, NCV_PMT2_ID, old_time_ncv2, adc_hits,
@@ -686,6 +710,9 @@ void PhaseITreeMaker::find_ncv_events(const std::vector<
686
710
const std::map<ChannelKey, std::vector< std::vector<ADCPulse> > >& adc_hits,
687
711
const HeftyInfo& hefty_info, const MinibufferLabel& event_mb_label, int mb)
688
712
{
713
+ int64_t mb_start_ns_since_epoch = 0 ;
714
+ if ( hefty_mode_ ) mb_start_ns_since_epoch = hefty_info.time (mb);
715
+
689
716
for (const ADCPulse& pulse : pulses.at (mb) ) {
690
717
int64_t pulse_time = pulse.start_time ().GetNs ();
691
718
@@ -694,10 +721,7 @@ void PhaseITreeMaker::find_ncv_events(const std::vector<
694
721
// absolute time (pulse time within the current minibuffer
695
722
// plus ns since the Unix epoch for the start of the current minibuffer)
696
723
// while checking for afterpulsing in Hefty mode.
697
- if ( hefty_mode_ ) {
698
- int64_t mb_start_ns_since_epoch = hefty_info.time (mb);
699
- pulse_time += mb_start_ns_since_epoch;
700
- }
724
+ if ( hefty_mode_ ) pulse_time += mb_start_ns_since_epoch;
701
725
702
726
Log (" Found pulse on PMT with ID #" + std::to_string (pmt_id) + " at "
703
727
+ std::to_string ( pulse.start_time ().GetNs () ) + " ns after the"
@@ -715,6 +739,13 @@ void PhaseITreeMaker::find_ncv_events(const std::vector<
715
739
if ( matching_pulse ) event_time_ns_ = std::min ( event_time_ns_,
716
740
static_cast <int64_t >(matching_pulse->start_time ().GetNs ()) );
717
741
742
+ // Apply the afterpulsing veto using the time for the last NCV
743
+ // coincidence, regardless of whether it passed the neutron candidate
744
+ // cuts or not.
745
+ if ( ncv1_fired_ && ncv2_fired_ ) {
746
+ old_time = event_time_ns_ + mb_start_ns_since_epoch;
747
+ }
748
+
718
749
// For Hefty mode, however the event time within the current minibuffer
719
750
// needs to be added to the TSinceBeam value for Hefty window
720
751
// minibuffers (labeled by the RawLoader tool with
@@ -738,10 +769,5 @@ void PhaseITreeMaker::find_ncv_events(const std::vector<
738
769
+ std::to_string (mb) + " at " + std::to_string (event_time_ns_)
739
770
+ " ns" , 2 , verbosity_);
740
771
}
741
-
742
- // Apply the afterpulsing veto using the time for the last pulse on the
743
- // current PMT, regardless of whether it passed the neutron candidate cuts
744
- // or not.
745
- old_time = pulse_time;
746
772
}
747
773
}
0 commit comments