From f5e56c8c7d6613291cfcf348d59ff8e22d88a396 Mon Sep 17 00:00:00 2001 From: Steven Doran <78985334+S81D@users.noreply.github.com> Date: Tue, 4 Nov 2025 10:19:25 -0600 Subject: [PATCH 1/8] Remove skipping of events Instead, we can fill one of the dead PMTs with a "minimal" waveform to pass to the hit finding tool --- UserTools/PMTWaveformSim/PMTWaveformSim.cpp | 58 ++++++++++++++++----- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/UserTools/PMTWaveformSim/PMTWaveformSim.cpp b/UserTools/PMTWaveformSim/PMTWaveformSim.cpp index d5789e354..4cb3c7063 100644 --- a/UserTools/PMTWaveformSim/PMTWaveformSim.cpp +++ b/UserTools/PMTWaveformSim/PMTWaveformSim.cpp @@ -97,11 +97,51 @@ bool PMTWaveformSim::Execute() { int load_status = LoadFromStores(); - + if (load_status == 0) return false; + // The container for the data that we'll put into the ANNIEEvent std::map> > RawADCDataMC; std::map> > CalADCDataMC; + + // If MCHits is empty (load_status == 2), create one minimal baseline waveform so that the hit finder doesn't freak out + // while keeping the rest of the machinery the same + if (load_status == 2) { + logmessage = "PMTWaveformSim: Creating single minimal baseline waveform (No MCHits)..."; + Log(logmessage, v_message, verbosity); + + // we can use any valid PMT ID --> let's just use 332 + unsigned long dummy_chankey = 332; + + // create a short baseline waveform (~50ns) so that the hit finder will be satisfied + int num_samples = 25; // 50ns + double noiseSigma = fRandom.Gaus(1, 0.01); // set the noise to basically 0 + int baseline = fRandom.Uniform(300, 350); + + std::vector rawSamples; + std::vector calSamples; + + for (int i = 0; i < num_samples; i++) { + double noise = fRandom.Gaus(0, noiseSigma); + int sample = std::round(noise + baseline); + sample = (sample > 4095) ? 4095 : ((sample < 0) ? 0 : sample); // shouldn't matter + + rawSamples.push_back(sample); + calSamples.push_back((sample - baseline) * ADC_TO_VOLT); + } + + std::vector> rawWaveforms; + std::vector> calWaveforms; + + rawWaveforms.emplace_back(0, rawSamples); + calWaveforms.emplace_back(0, calSamples, baseline, noiseSigma); + + RawADCDataMC.emplace(dummy_chankey, rawWaveforms); + CalADCDataMC.emplace(dummy_chankey, calWaveforms); + + } + + // normal use case (no blank MCHits) for (auto mcHitsIt : *fMCHits) { // Loop over the hit PMTs int PMTID = mcHitsIt.first; @@ -177,22 +217,14 @@ bool PMTWaveformSim::Execute() CalADCDataMC.emplace(PMTID, calWaveforms); }// end loop over PMTs + // Publish the waveforms to the ANNIEEvent store if we have them - if (RawADCDataMC.size()) { - m_data->Stores.at("ANNIEEvent")->Set("RawADCDataMC", RawADCDataMC); - m_data->Stores.at("ANNIEEvent")->Set("CalibratedADCData", CalADCDataMC); - } else { - logmessage = "PMTWaveformSim: No waveforms produced. Skipping!"; - Log(logmessage, v_warning, verbosity); - m_data->Stores.at("ANNIEEvent")->Set("SkipExecute", true); - return true; - } - + m_data->Stores.at("ANNIEEvent")->Set("RawADCDataMC", RawADCDataMC); + m_data->Stores.at("ANNIEEvent")->Set("CalibratedADCData", CalADCDataMC); if (fDebug) FillDebugGraphs(RawADCDataMC); - m_data->Stores.at("ANNIEEvent")->Set("SkipExecute", false); return true; } @@ -460,7 +492,7 @@ int PMTWaveformSim::LoadFromStores() } if (fMCHits->empty()) { - logmessage = "PMTWaveformSim: The MCHits map is empty! Skipping!"; + logmessage = "PMTWaveformSim: The MCHits map is empty! Will fill a single PMT with a minimal waveform."; Log(logmessage, v_warning, verbosity); return 2; } From 8e59d607c8668998f81679ca7fdccba67aa2bda5 Mon Sep 17 00:00:00 2001 From: Steven Doran <78985334+S81D@users.noreply.github.com> Date: Tue, 4 Nov 2025 10:20:22 -0600 Subject: [PATCH 2/8] Remove event skipping for hit finder tool --- .../PhaseIIADCHitFinder.cpp | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.cpp b/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.cpp index 761e22ddf..f1a48b62d 100755 --- a/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.cpp +++ b/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.cpp @@ -140,20 +140,6 @@ bool PhaseIIADCHitFinder::Execute() { if (mc_waveforms) { got_raw_data = annie_event->Get("RawADCDataMC", raw_waveform_map); - - // Some executes are skipped if there are no MCHits or waveforms produced - // Put the cleared maps into the ANNIEEvent to ensure that a downstream - // tool doesn't grab a map from a previous event - bool skip = false; - bool got_skip_status = annie_event->Get("SkipExecute", skip); - if (got_skip_status && skip) { - Log("PhaseIIADCHitFinder: An upstream tool told me to skip this event.",v_warning,verbosity); - - m_data->Stores.at("ANNIEEvent")->Set("RecoADCHits", pulse_map); - m_data->Stores.at("ANNIEEvent")->Set("RecoADCAuxHits", aux_pulse_map); - - return true; - } }// end if mc_waveforms } @@ -168,7 +154,7 @@ bool PhaseIIADCHitFinder::Execute() { verbosity); return false; } - else if ( raw_waveform_map.empty() ) { + else if ( raw_waveform_map.empty() && !mc_waveforms ) { Log("Error: The PhaseIIADCHitFinder tool found an empty RawADCData entry", v_error, verbosity); return false; @@ -197,7 +183,7 @@ bool PhaseIIADCHitFinder::Execute() { " entry", v_error, verbosity); return false; } - else if ( calibrated_waveform_map.empty() ) { + else if ( calibrated_waveform_map.empty() && !mc_waveforms ) { Log("Error: The PhaseIIADCHitFinder tool found an empty CalibratedADCData entry", v_error, verbosity); return false; From 55d40c226db467e9a83c61ff29146e8e82d0edf6 Mon Sep 17 00:00:00 2001 From: Steven Doran <78985334+S81D@users.noreply.github.com> Date: Tue, 4 Nov 2025 10:23:30 -0600 Subject: [PATCH 3/8] Fix skip event --- UserTools/AssignBunchTimingMC/AssignBunchTimingMC.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/UserTools/AssignBunchTimingMC/AssignBunchTimingMC.cpp b/UserTools/AssignBunchTimingMC/AssignBunchTimingMC.cpp index a821d6685..c34aa7b75 100644 --- a/UserTools/AssignBunchTimingMC/AssignBunchTimingMC.cpp +++ b/UserTools/AssignBunchTimingMC/AssignBunchTimingMC.cpp @@ -99,16 +99,6 @@ bool AssignBunchTimingMC::Execute() std::cout << "AssignBunchTimingMC: Executing tool..." << std::endl; } - // An upstream tool may opt to skip this execution stage - // For example the PMTWaveformSim tool will skip events with no MCHits or if - // no waveforms are produced. - bool skip = false; - bool got_skip_status = m_data->Stores["ANNIEEvent"]->Get("SkipExecute", skip); - if (got_skip_status && skip) { - Log("AssignBunchTimingMC: An upstream tool told me to skip this event.",v_warning,verbosity); - return true; - } - if (!LoadStores()) // Load info from store return false; if (verbosity >= v_debug) { From 1b57293708b8cef4763e16d8b0a25dd5f552ff08 Mon Sep 17 00:00:00 2001 From: Steven Doran <78985334+S81D@users.noreply.github.com> Date: Tue, 4 Nov 2025 10:23:47 -0600 Subject: [PATCH 4/8] Add files via upload --- UserTools/ClusterFinder/ClusterFinder.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/UserTools/ClusterFinder/ClusterFinder.cpp b/UserTools/ClusterFinder/ClusterFinder.cpp index de16c4b23..3d90cf910 100644 --- a/UserTools/ClusterFinder/ClusterFinder.cpp +++ b/UserTools/ClusterFinder/ClusterFinder.cpp @@ -165,16 +165,6 @@ bool ClusterFinder::Execute(){ //---------------------------------------------------------------------------- //---------------get the members of the ANNIEEvent---------------------------- //---------------------------------------------------------------------------- - - // An upstream tool may opt to skip this execution stage - // For example the PMTWaveformSim tool will skip events with no MCHits or if - // no waveforms are produced. - bool skip = false; - bool got_skip_status = m_data->Stores["ANNIEEvent"]->Get("SkipExecute", skip); - if (got_skip_status && skip) { - Log("ClusterFinder: An upstream tool told me to skip this event.",v_warning,verbose); - return true; - } m_data->Stores["ANNIEEvent"]->Get("EventNumber", evnum); //m_data->Stores["ANNIEEvent"]->Get("BeamStatus", BeamStatus); From ad74c464e1e4b42aff13de3e70f9fbefe7017772 Mon Sep 17 00:00:00 2001 From: Steven Doran <78985334+S81D@users.noreply.github.com> Date: Tue, 4 Nov 2025 10:24:04 -0600 Subject: [PATCH 5/8] Add files via upload --- UserTools/ClusterClassifiers/ClusterClassifiers.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/UserTools/ClusterClassifiers/ClusterClassifiers.cpp b/UserTools/ClusterClassifiers/ClusterClassifiers.cpp index 3480e8cea..939d2dbef 100644 --- a/UserTools/ClusterClassifiers/ClusterClassifiers.cpp +++ b/UserTools/ClusterClassifiers/ClusterClassifiers.cpp @@ -35,15 +35,6 @@ bool ClusterClassifiers::Initialise(std::string configfile, DataModel &data){ bool ClusterClassifiers::Execute(){ - //We're gonna make ourselves a couple cluster classifier maps boyeeee - bool skip = false; - bool goodSkipStatus = m_data->Stores.at("ANNIEEvent")->Get("SkipExecute", skip); - if (goodSkipStatus && skip) { - logmessage = "ClusterClassifier: An upstream tool told me to skip this event."; - Log(logmessage, v_warning, verbosity); - return true; - } - if(verbosity>4) std::cout << "ClusterClassifiers tool: Accessing cluster map in CStore" << std::endl; bool get_clusters = false; m_data->CStore.Get("ClusterMap",m_all_clusters); From 5acb942b8cb5c1fcfbd3c091e90cd3141e975a99 Mon Sep 17 00:00:00 2001 From: Steven Doran <78985334+S81D@users.noreply.github.com> Date: Tue, 4 Nov 2025 10:24:30 -0600 Subject: [PATCH 6/8] Add files via upload --- UserTools/PhaseIITreeMaker/PhaseIITreeMaker.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.cpp b/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.cpp index 573b64c24..d952cd04f 100644 --- a/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.cpp +++ b/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.cpp @@ -526,16 +526,6 @@ bool PhaseIITreeMaker::Execute(){ // Reset variables this->ResetVariables(); // Get a pointer to the ANNIEEvent Store - - // An upstream tool may opt to skip this execution stage - // For example the PMTWaveformSim tool will skip events with no MCHits or if - // no waveforms are produced. - bool skip = false; - bool got_skip_status = m_data->Stores["ANNIEEvent"]->Get("SkipExecute", skip); - if (got_skip_status && skip) { - Log("PhaseIITreeMaker: An upstream tool told me to skip this event.",v_warning,verbosity); - return true; - } // If only clean events are built, return true for dirty events if(fillCleanEventsOnly){ From b275eae33f099cd7c76c87dfe3f2696f96088827 Mon Sep 17 00:00:00 2001 From: Steven Doran <78985334+S81D@users.noreply.github.com> Date: Tue, 4 Nov 2025 10:46:46 -0600 Subject: [PATCH 7/8] Update PMTWaveformSim.cpp forgot to set the channel ID to a dead PMT --- UserTools/PMTWaveformSim/PMTWaveformSim.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UserTools/PMTWaveformSim/PMTWaveformSim.cpp b/UserTools/PMTWaveformSim/PMTWaveformSim.cpp index 4cb3c7063..0f1a4f804 100644 --- a/UserTools/PMTWaveformSim/PMTWaveformSim.cpp +++ b/UserTools/PMTWaveformSim/PMTWaveformSim.cpp @@ -110,8 +110,8 @@ bool PMTWaveformSim::Execute() logmessage = "PMTWaveformSim: Creating single minimal baseline waveform (No MCHits)..."; Log(logmessage, v_message, verbosity); - // we can use any valid PMT ID --> let's just use 332 - unsigned long dummy_chankey = 332; + // we can put the dummy baseline in a dead PMT channel so it won't be integrated + unsigned long dummy_chankey = 333; // PMT ID 333 is dead // create a short baseline waveform (~50ns) so that the hit finder will be satisfied int num_samples = 25; // 50ns From 68d0b1c951eea5774e9e37ab49aefa5a800c50c5 Mon Sep 17 00:00:00 2001 From: Steven Doran <78985334+S81D@users.noreply.github.com> Date: Thu, 6 Nov 2025 09:39:12 -0600 Subject: [PATCH 8/8] Update README.md Quick disclaimer about the dummy channel --- UserTools/PMTWaveformSim/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/UserTools/PMTWaveformSim/README.md b/UserTools/PMTWaveformSim/README.md index a31230d80..09dd5b692 100644 --- a/UserTools/PMTWaveformSim/README.md +++ b/UserTools/PMTWaveformSim/README.md @@ -35,3 +35,6 @@ MakeDebugFile 0 # Produce a root file containing all the simulated waveforms ## Other notes #### CAUTION: In line 90, the RNG seed is set in Initialization based on the clock time. If any other downstream tools are also setting a random seed, there may be unexpected behavior as a result of this tool. + +For events with no MCHits (and hence no waveforms to simulate) a "dummy" waveform is simulated in one of the dead PMT channels (333). The dummy waveform is very short (50ns) and samples from a noise distribution lower than normal, as to not have any hits register in the hit finder (the hit finder will skip dead PMTs anyways). Passing at least one waveform to the hit finding tools prevents crashing. **IF** that PMT is ever repaired or comes back online, please move this dummy channel to a different offline channel. +