From 2783009df569685ca26014440632156cf7d7ca22 Mon Sep 17 00:00:00 2001 From: lynnt20 Date: Mon, 13 Jan 2025 12:35:30 -0600 Subject: [PATCH 1/3] add feature to find PTB gate HLT and use as reference for the +light streams --- .../PMTMetricProducer_module.cc | 82 +++++++++++++++---- 1 file changed, 64 insertions(+), 18 deletions(-) diff --git a/sbndaq-artdaq/ArtModules/SBND/SoftwareTrigger/PMTMetricProducer_module.cc b/sbndaq-artdaq/ArtModules/SBND/SoftwareTrigger/PMTMetricProducer_module.cc index 93a2ec0c..869903f0 100644 --- a/sbndaq-artdaq/ArtModules/SBND/SoftwareTrigger/PMTMetricProducer_module.cc +++ b/sbndaq-artdaq/ArtModules/SBND/SoftwareTrigger/PMTMetricProducer_module.cc @@ -37,6 +37,7 @@ #include "sbndaq-artdaq-core/Overlays/Common/CAENV1730Fragment.hh" #include "sbndaq-artdaq-core/Overlays/FragmentType.hh" #include "sbndaq-artdaq-core/Overlays/SBND/TDCTimestampFragment.hh" +#include "sbndaq-artdaq-core/Overlays/SBND/PTBFragment.hh" #include "sbndaq-artdaq-core/Obj/SBND/pmtSoftwareTrigger.hh" // ROOT includes @@ -86,7 +87,7 @@ class sbnd::trigger::pmtSoftwareTriggerProducer : public art::EDProducer { uint16_t fWvfmLength; // expected waveform length in samples uint8_t fStreamType; // 0 is random, 1 is beam zero bias, 2 is 1+light, 3 is offbeam zero bias, 4 is 3+light, 5 is crt crossing muon - uint8_t fTimingType; // 0 for SPEC TDC, 1 for rawheader + uint8_t fTimingType; // 0 for SPEC TDC/PTB, 1 for rawheader bool fAllowNTB; // allow NTB to be used as a timing reference uint32_t fNTBDelay; // in ns, NTB offset @@ -95,6 +96,10 @@ class sbnd::trigger::pmtSoftwareTriggerProducer : public art::EDProducer { uint8_t fSPECTDCTimingChannel; // 1 is bes, 2 is rwm, and 4 is ett int32_t fSPECTDCDelay; // in ns, time difference between tdc ftrig and caen ftrig + std::string fPTBModuleLabel; + std::vector fPTBInstanceLabels; + int32_t fPTBDelay; // in ns + std::vector fFragIDs; // the bottom two vectors MUST be the same size! std::vector fignorePMT_board; // specify the board of a pmt to ignore @@ -130,6 +135,8 @@ class sbnd::trigger::pmtSoftwareTriggerProducer : public art::EDProducer { bool getTDCTime(artdaq::Fragment & frag, std::vector & tdcTime, uint8_t tdcChannel); + bool getGateTime(art::Handle > ptb_handle, + double & gateTime); int8_t getClosestFTrig(double refTime, std::vector & ftrig_v); void getWaveforms(const artdaq::Fragment &frag, std::vector> &wvfm_v); void insertWaveforms(const artdaq::Fragment &frag, std::vector> &wvfm_v); @@ -173,7 +180,7 @@ void sbnd::trigger::pmtSoftwareTriggerProducer::reconfigure(fhicl::ParameterSet // 0 is random, 1 is beam zero bias, 2 is 1+light, 3 is offbeam zero bias, 4 is 3+light, 5 is crt crossing muon fStreamType = p.get("StreamType", 1); - // SPEC TDC ETT [0] -> NTB (RawEventHeader) [1] + // SPEC TDC ETT (or PTB gate HLT) [0] -> NTB (RawEventHeader) [1] fTimingType = p.get("TimingType", 0); fAllowNTB = p.get("AllowNTB", true); fNTBDelay = p.get("NTBDelay", 365000); // units of ns @@ -182,7 +189,11 @@ void sbnd::trigger::pmtSoftwareTriggerProducer::reconfigure(fhicl::ParameterSet fSPECTDCInstanceLabels = p.get>("SPECTDCInstanceLabels", {"TDCTIMESTAMP", "ContainerTDCTIMESTAMP" }); // 1 is bes, 2 is rwm, 3 is ftrig, 4 is ett fSPECTDCTimingChannel = p.get("SPECTDCTimingChannel", 4); - fSPECTDCDelay = p.get("SPECTDCDelay", 120); // difference between caen ftrig and tdc ftrig in ns, factor in additional 20 for PTB + fSPECTDCDelay = p.get("SPECTDCDelay", 140); // difference between caen ftrig and tdc ftrig in ns, factor in additional 20 for PTB + + fPTBModuleLabel = p.get("PTBModuleLabel", "daq"); + fPTBInstanceLabels = p.get>("PTBInstance",{"ContainerPTB"}); + fPTBDelay = p.get("PTBDelay", -120); // in ns fFragIDs = p.get>("FragIDs", {40960,40961,40962,40963,40964,40965,40966,40967}); fignorePMT_board = p.get>("IgnorePMTBoard", {}); @@ -217,6 +228,8 @@ void sbnd::trigger::pmtSoftwareTriggerProducer::produce(art::Event& e) // the reference time stamp, usually the event trigger time, used to find the right FTRIG double refTimestamp=0; auto timing_type = fTimingType; + // if timing type is 2 or 4, +light streams need the gate hlt timestamp + bool islightstream = ((fStreamType==2) || (fStreamType==4))? true : false; // section to obtain global timing information art::Handle header_handle; @@ -227,7 +240,17 @@ void sbnd::trigger::pmtSoftwareTriggerProducer::produce(art::Event& e) raw_timestamp = rawheader.timestamp()%int(1e9) - fNTBDelay; } - if (timing_type==0){ + double gateTime = 1e9; + bool foundgate = false; + if (islightstream){ + for (const std::string &PTBInstanceLabel : fPTBInstanceLabels){ + art::Handle> ptbHandle; + e.getByLabel(fPTBModuleLabel, PTBInstanceLabel, ptbHandle); + foundgate = getGateTime(ptbHandle, gateTime); + } + } + + if ((timing_type==0) && (islightstream==false)){ std::vector tdc_etrig_v; tdc_etrig_v.reserve(2); for(const std::string &SPECTDCInstanceLabel : fSPECTDCInstanceLabels){ @@ -279,6 +302,13 @@ void sbnd::trigger::pmtSoftwareTriggerProducer::produce(art::Event& e) timing_type++; } } + if ((timing_type==0) && (islightstream)){ + if (foundgate) refTimestamp = gateTime; + else{ + if (fVerbose>=2) TLOG(TLVL_WARNING) << "No valid PTB gate HLT found. Using NTB..." ; + timing_type++; + } + } if (timing_type==1){ if ((header_handle.isValid()) && (raw_timestamp!=0) && (fAllowNTB)) refTimestamp = raw_timestamp; @@ -456,8 +486,10 @@ void sbnd::trigger::pmtSoftwareTriggerProducer::produce(art::Event& e) flash_prelimPE = (flash_baseline-(*std::min_element(wvfm_sum.begin()+prelimStart,wvfm_sum.begin()+windowStartBin)))/fADCtoPE; flash_promptPE = (flash_baseline-(*std::min_element(wvfm_sum.begin()+windowStartBin,wvfm_sum.begin()+promptEnd)))/fADCtoPE; flash_peakPE = (flash_baseline-(*std::min_element(wvfm_sum.begin(),wvfm_sum.end())))/fADCtoPE; - auto flash_peak_it = std::min_element(wvfm_sum.begin(),wvfm_sum.end()); - + // auto flash_peak_it = std::min_element(wvfm_sum.begin(),wvfm_sum.end()); + // look at only the last 5000 samples of the waveform + // important because our "chosen" ftrig may be an extended fragment + auto flash_peak_it = std::min_element(wvfm_sum.end()-fWvfmLength,wvfm_sum.end()); // time is referenced to the end of the waveform; this is correct assuming we grabbed the right fragment! flash_peaktime = (fWvfmLength*fWvfmPostPercent - (wvfm_sum.end() - flash_peak_it))*ticks_to_us; // us } @@ -524,6 +556,31 @@ bool sbnd::trigger::pmtSoftwareTriggerProducer::getTDCTime(artdaq::Fragment & fr return found_timing_ch; } +bool sbnd::trigger::pmtSoftwareTriggerProducer::getGateTime(art::Handle > ptb_handle, double & gateTime){ + bool foundgate = false; + for (auto const& cont : *ptb_handle){ + artdaq::ContainerFragment contf(cont); + for (size_t ifrag = 0; ifrag < contf.block_count(); ++ifrag){ + artdaq::Fragment frag = *contf[ifrag]; + sbndaq::CTBFragment ctb_frag(frag); // somehow the name CTBFragment stuck + for(size_t word_i = 0; word_i < ctb_frag.NWords(); ++word_i){ + if(ctb_frag.Trigger(word_i)){ + auto wt = ctb_frag.Word(word_i)->word_type; + if (wt == 2 && ( ctb_frag.Trigger(word_i)->IsTrigger(26) || ctb_frag.Trigger(word_i)->IsTrigger(27) )){ + foundgate = true; + gateTime = double((std::bitset<64>(ctb_frag.Trigger(word_i)->timestamp).to_ullong()*20)%(uint(1e9)) - fPTBDelay); + if (fVerbose>=3) TLOG(TLVL_INFO) << "PTB gated FTRIG HLT timestamp: " << uint(gateTime) << " ns"; + break; + } + } + } //End of loop over the number of trigger words + if (foundgate) break; + } //End of loop over the number of fragments per container + if (foundgate) break; + } //End of loop over the number of containers + return foundgate; +} + int8_t sbnd::trigger::pmtSoftwareTriggerProducer::getClosestFTrig(double refTime, std::vector & ftrig_v){ double min_diff = 1e9; int8_t min_idx = -1; @@ -534,23 +591,12 @@ int8_t sbnd::trigger::pmtSoftwareTriggerProducer::getClosestFTrig(double refTime auto iftrig = ftrig_v[i]; double diff = ftrig_v[i] - refTime; diff_v[i] = std::abs(diff); - if (std::abs(diff) < min_diff){ min_idx = int8_t(i); min_diff = std::abs(diff); } } - if ((fStreamType==1) || (fStreamType==3) || (fStreamType==5)) - // if beam or offbeam zero bias, the closest FTRIG will be the gate FTRIG - returned_idx = min_idx; - - if ( (fStreamType==2) || (fStreamType==4)){ - // if +light stream, the 2nd closest FTRIG will be the gate FTRIG, - // which can be immediately before or after the closest - if (min_idx > 0 && (min_idx < (int8_t)ftrig_v.size()-1)){ - returned_idx = (diff_v[min_idx-1] < diff_v[min_idx+1]) ? min_idx-1 : min_idx+1; - } - } + returned_idx = min_idx; return returned_idx; } From e5e4d5d03efd633052cee7e0002f5523871e45e9 Mon Sep 17 00:00:00 2001 From: lynnt20 Date: Thu, 23 Jan 2025 14:34:38 -0600 Subject: [PATCH 2/3] add protection for accessing ptb handle --- .../ArtModules/SBND/SoftwareTrigger/PMTMetricProducer_module.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sbndaq-artdaq/ArtModules/SBND/SoftwareTrigger/PMTMetricProducer_module.cc b/sbndaq-artdaq/ArtModules/SBND/SoftwareTrigger/PMTMetricProducer_module.cc index 869903f0..16e0d2e8 100644 --- a/sbndaq-artdaq/ArtModules/SBND/SoftwareTrigger/PMTMetricProducer_module.cc +++ b/sbndaq-artdaq/ArtModules/SBND/SoftwareTrigger/PMTMetricProducer_module.cc @@ -246,6 +246,8 @@ void sbnd::trigger::pmtSoftwareTriggerProducer::produce(art::Event& e) for (const std::string &PTBInstanceLabel : fPTBInstanceLabels){ art::Handle> ptbHandle; e.getByLabel(fPTBModuleLabel, PTBInstanceLabel, ptbHandle); + if(!ptbHandle.isValid() || ptbHandle->size() == 0) + continue; foundgate = getGateTime(ptbHandle, gateTime); } } From 2f7753cc80f85ab50d19494306cbc522082157cf Mon Sep 17 00:00:00 2001 From: lynnt20 Date: Thu, 30 Jan 2025 10:58:48 -0600 Subject: [PATCH 3/3] update some default fcl params based on current daq performance --- .../SBND/SoftwareTrigger/PMTMetricProducer_module.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbndaq-artdaq/ArtModules/SBND/SoftwareTrigger/PMTMetricProducer_module.cc b/sbndaq-artdaq/ArtModules/SBND/SoftwareTrigger/PMTMetricProducer_module.cc index 16e0d2e8..b7e07b5b 100644 --- a/sbndaq-artdaq/ArtModules/SBND/SoftwareTrigger/PMTMetricProducer_module.cc +++ b/sbndaq-artdaq/ArtModules/SBND/SoftwareTrigger/PMTMetricProducer_module.cc @@ -182,7 +182,7 @@ void sbnd::trigger::pmtSoftwareTriggerProducer::reconfigure(fhicl::ParameterSet fStreamType = p.get("StreamType", 1); // SPEC TDC ETT (or PTB gate HLT) [0] -> NTB (RawEventHeader) [1] fTimingType = p.get("TimingType", 0); - fAllowNTB = p.get("AllowNTB", true); + fAllowNTB = p.get("AllowNTB", false); fNTBDelay = p.get("NTBDelay", 365000); // units of ns fSPECTDCModuleLabel = p.get("SPECTDCModuleLabel", "daq"); @@ -204,7 +204,7 @@ void sbnd::trigger::pmtSoftwareTriggerProducer::reconfigure(fhicl::ParameterSet // most likely these will all be off... fIncludeExtensions = p.get("IncludeExtensions",false); - fCalculateBaseline = p.get("CalculateBaseline",false); + fCalculateBaseline = p.get("CalculateBaseline",true); fCountPMTs = p.get("CountPMTs",false); fCalculatePEMetrics = p.get("CalculatePEMetrics",false); fInputBaseline = p.get>("InputBaseline",{14250,2.0});