Skip to content

Commit 33ffbef

Browse files
committed
Add spill number and in_spill boolean flag to the phaseI tree. Add a flag
in the configuration file that allows the pulse output tree to be disabled.
1 parent c28a7c2 commit 33ffbef

File tree

2 files changed

+131
-105
lines changed

2 files changed

+131
-105
lines changed

UserTools/PhaseITreeMaker/PhaseITreeMaker.cpp

+129-103
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ bool PhaseITreeMaker::Initialise(std::string config_filename, DataModel& data)
8181
output_tree_->Branch("subrun", &subrun_number_, "subrun/i");
8282
output_tree_->Branch("event", &event_number_, "event/i");
8383
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");
8486
output_tree_->Branch("ncv_position", &ncv_position_, "ncv_position/I");
8587
output_tree_->Branch("event_time_ns", &event_time_ns_, "event_time_ns/L");
8688
output_tree_->Branch("label", &event_label_, "label/b");
@@ -119,7 +121,7 @@ bool PhaseITreeMaker::Initialise(std::string config_filename, DataModel& data)
119121
output_pulse_tree_->Branch("run", &run_number_, "run/i");
120122
output_pulse_tree_->Branch("subrun", &subrun_number_, "subrun/i");
121123
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");
123125
output_pulse_tree_->Branch("minibuffer_number", &minibuffer_number_,
124126
"minibuffer_number/I");
125127
output_pulse_tree_->Branch("ncv_position", &ncv_position_, "ncv_position/I");
@@ -249,114 +251,121 @@ bool PhaseITreeMaker::Execute() {
249251
get_object_from_store("RecoADCHits", adc_hits, *annie_event);
250252
check_that_not_empty("RecoADCHits", adc_hits);
251253

252-
int old_spill_number = spill_number_;
254+
int old_spill_number = 0;
255+
spill_number_ = 0;
253256

254-
for (const auto& pair : adc_hits) {
257+
bool make_pulse_tree = true;
258+
m_variables.Get("MakePulseTree", make_pulse_tree);
255259

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) {
258263

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;
263266

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;
265271

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();
269273

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;
271277

272-
minibuffer_number_ = mb;
278+
for (size_t mb = 0; mb < num_minibuffers; ++mb) {
273279

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;
277281

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 );
284285

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;
311292

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;
338304
}
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))
347312
{
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;
349318
}
350-
else in_spill_ = false;
351-
352-
output_pulse_tree_->Fill();
353319

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+
}
360369
}
361370
}
362371
}
@@ -447,6 +456,9 @@ bool PhaseITreeMaker::Execute() {
447456
continue;
448457
}
449458

459+
// Increment the spill counter since this is a good spill
460+
if (beam_condition == BeamCondition::Ok) ++spill_number_;
461+
450462
// Increment beam POT count, etc. based on the characteristics of the
451463
// current minibuffer
452464
if (beam_condition == BeamCondition::Ok) {
@@ -467,6 +479,18 @@ bool PhaseITreeMaker::Execute() {
467479
++pos_info.num_led_triggers;
468480
}
469481

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+
470494
find_ncv_events(ncv_pmt1_pulses, NCV_PMT1_ID, old_time_ncv1, adc_hits,
471495
hefty_info, event_mb_label, mb);
472496
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<
686710
const std::map<ChannelKey, std::vector< std::vector<ADCPulse> > >& adc_hits,
687711
const HeftyInfo& hefty_info, const MinibufferLabel& event_mb_label, int mb)
688712
{
713+
int64_t mb_start_ns_since_epoch = 0;
714+
if ( hefty_mode_ ) mb_start_ns_since_epoch = hefty_info.time(mb);
715+
689716
for (const ADCPulse& pulse : pulses.at(mb) ) {
690717
int64_t pulse_time = pulse.start_time().GetNs();
691718

@@ -694,10 +721,7 @@ void PhaseITreeMaker::find_ncv_events(const std::vector<
694721
// absolute time (pulse time within the current minibuffer
695722
// plus ns since the Unix epoch for the start of the current minibuffer)
696723
// 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;
701725

702726
Log("Found pulse on PMT with ID #" + std::to_string(pmt_id) + " at "
703727
+ std::to_string( pulse.start_time().GetNs() ) + " ns after the"
@@ -715,6 +739,13 @@ void PhaseITreeMaker::find_ncv_events(const std::vector<
715739
if ( matching_pulse ) event_time_ns_ = std::min( event_time_ns_,
716740
static_cast<int64_t>(matching_pulse->start_time().GetNs()) );
717741

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+
718749
// For Hefty mode, however the event time within the current minibuffer
719750
// needs to be added to the TSinceBeam value for Hefty window
720751
// minibuffers (labeled by the RawLoader tool with
@@ -738,10 +769,5 @@ void PhaseITreeMaker::find_ncv_events(const std::vector<
738769
+ std::to_string(mb) + " at " + std::to_string(event_time_ns_)
739770
+ " ns", 2, verbosity_);
740771
}
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;
746772
}
747773
}

UserTools/PhaseITreeMaker/PhaseITreeMaker.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ class PhaseITreeMaker : public Tool {
122122
uint32_t subrun_number_ = 0u;
123123
uint32_t event_number_ = 0u;
124124
int minibuffer_number_ = 0;
125+
int spill_number_ = 0;
126+
bool in_spill_ = false;
125127
int ncv_position_ = 0;
126128
int64_t event_time_ns_ = 0; // ns
127129
uint8_t event_label_ = 0u;
@@ -163,8 +165,6 @@ class PhaseITreeMaker : public Tool {
163165
double pulse_charge_ = 0.; // nC
164166
int pulse_pmt_id_ = 0.; // nC
165167
unsigned short pulse_raw_amplitude_ = 0u; // ADC counts
166-
uint32_t spill_number_ = 0u;
167-
bool in_spill_ = false;
168168

169169
// Tree that stores information about the beam quality cuts
170170
TTree* output_beam_tree_ = nullptr;

0 commit comments

Comments
 (0)