diff --git a/sbncode/BeamSpillInfoRetriever/POTTools.cpp b/sbncode/BeamSpillInfoRetriever/POTTools.cpp index 585fdba5b..d2b85dc0c 100644 --- a/sbncode/BeamSpillInfoRetriever/POTTools.cpp +++ b/sbncode/BeamSpillInfoRetriever/POTTools.cpp @@ -43,6 +43,36 @@ namespace sbn::pot{ } } + std::vector extractAllPTBInfo(art::Handle > cont_frags) { + std::vector PTBInfoVec; + for (auto const& cont : *cont_frags) + { + artdaq::ContainerFragment cont_frag(cont); + for (size_t fragi = 0; fragi < cont_frag.block_count(); ++fragi) + { + artdaq::Fragment frag = *cont_frag[fragi]; + sbndaq::CTBFragment ctb_frag(frag); + for(size_t word_i = 0; word_i < ctb_frag.NWords(); ++word_i) + { + if(ctb_frag.Trigger(word_i)){ + PTBInfo_t PTBInfo; + uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS; + uint64_t RawcurrPTBTimeStamp = ctb_frag.Trigger(word_i)->timestamp; + double currTS_candidate = std::bitset<64>(RawcurrPTBTimeStamp).to_ullong()/50e6; + PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp).to_ullong()/50e6; + PTBInfo.currPTBTimeStamp = currTS_candidate; + PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; + PTBInfo.isHLT = ctb_frag.Trigger(word_i)->IsHLT(); + PTBInfo.triggerWord = ctb_frag.Trigger(word_i)->trigger_word; + PTBInfoVec.push_back(PTBInfo); + } + } + } + } + + return PTBInfoVec; + } + double extractTDCTimeStamp(art::Handle > cont_frags) { double TDCTimeStamp = 0; diff --git a/sbncode/BeamSpillInfoRetriever/POTTools.h b/sbncode/BeamSpillInfoRetriever/POTTools.h index cb78fe686..3518f8d3a 100644 --- a/sbncode/BeamSpillInfoRetriever/POTTools.h +++ b/sbncode/BeamSpillInfoRetriever/POTTools.h @@ -13,6 +13,7 @@ #include "sbncode/BeamSpillInfoRetriever/MWRData.h" #include "larcorealg/CoreUtils/counter.h" +#include namespace sbn::pot{ @@ -20,6 +21,8 @@ namespace sbn::pot{ double currPTBTimeStamp = 1e20; double prevPTBTimeStamp = 0; unsigned int GateCounter = 0; + bool isHLT = false; + uint64_t triggerWord = 0; } PTBInfo_t; typedef struct TriggerInfo_t { @@ -36,13 +39,21 @@ namespace sbn::pot{ } MWRdata_t; /** - * @brief Extracts information from PTB for use in SBND POT accounting. + * @brief Extracts information from PTB for a single HLT for use in SBND POT accounting. * * @param cont_frags The PTB fragments to examine. * @param HLT The high level trigger we are searching for. */ PTBInfo_t extractPTBInfo(art::Handle > cont_frags, int HLT); + /** + * @brief Extracts ALL PTB information for using in SBND CAF files. + * + * @param cont_frags The PTB fragments to examine. + * @return Vector of PTBInfo_t containing all triggers found. + */ + std::vector extractAllPTBInfo(art::Handle > cont_frags); + /** * @brief Extracts information from TDC for use in SBND POT accounting. * diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 9f2c01590..04550ffaf 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -115,6 +115,8 @@ #include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" #include "sbnobj/Common/POTAccounting/EXTCountInfo.h" #include "sbnobj/Common/POTAccounting/NuMISpillInfo.h" +#include "sbncode/BeamSpillInfoRetriever/POTTools.h" +#include "artdaq-core/Data/ContainerFragment.hh" #include "sbnobj/Common/Trigger/ExtraTriggerInfo.h" #include "sbnobj/Common/Reco/CRUMBSResult.h" #include "sbnobj/Common/Reco/OpT0FinderResult.h" @@ -1711,6 +1713,23 @@ void CAFMaker::produce(art::Event& evt) noexcept { FillTriggerEmulation(monpulses_handle, monpulse_sizes_handle, pairs_handle, trigemu_handle, srtrigger); } + + // Fill PTB (Penn Trigger Board) information for SBND real data + if (isRealData && fDet == kSBND) { + art::InputTag PTB_itag("daq", "ContainerPTB"); + art::Handle ptb_frags_handle; + evt.getByLabel(PTB_itag, ptb_frags_handle); + if (ptb_frags_handle.isValid()) { + try { + std::vector ptb_triggers = sbn::pot::extractAllPTBInfo(ptb_frags_handle); + FillPTBTriggersSBND(ptb_triggers, srtrigger); + } + catch (...) { + std::cout << "CAFMaker: Failed to extract PTB triggers" << std::endl; + } + } + } + // If not real data, fill in enough of the SRTrigger to make (e.g.) the CRT // time referencing work. TODO: add more stuff to a "MC"-Trigger? // No longer needed with incorporation of trigger emulation in the MC. diff --git a/sbncode/CAFMaker/CMakeLists.txt b/sbncode/CAFMaker/CMakeLists.txt index 5dd4f2a8f..24228ba3f 100644 --- a/sbncode/CAFMaker/CMakeLists.txt +++ b/sbncode/CAFMaker/CMakeLists.txt @@ -50,6 +50,7 @@ art_make_library( LIBRARY_NAME sbncode_CAFMaker ${GENIE_LIB_LIST} nugen::EventGeneratorBase_GENIE sbndaq_artdaq_core::sbndaq-artdaq-core_Obj_SBND + sbn_POTTools ) cet_build_plugin ( CAFMaker art::module diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index fab6ae074..2fcf30914 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -73,4 +73,28 @@ namespace caf caf_softInfo.flash_peakpe = softInfo.peakPE; caf_softInfo.flash_peaktime = softInfo.peaktime + softInfo.trig_ts*1e-3; } + + void FillPTBTriggersSBND(const std::vector& ptb_triggers, caf::SRTrigger& triggerInfo) { + triggerInfo.ptb_hlt_timestamp.clear(); + triggerInfo.ptb_hlt_bit.clear(); + triggerInfo.ptb_llt_timestamp.clear(); + triggerInfo.ptb_llt_bit.clear(); + + // Decode trigger words: each set bit becomes a separate entry with the same timestamp + for(const auto& trig : ptb_triggers) { + std::uint64_t triggerWord = trig.triggerWord; + for(int bit = 0; bit < 64; ++bit) { + std::uint64_t bitMask = 1ULL << bit; + if(triggerWord & bitMask) { + if(trig.isHLT) { + triggerInfo.ptb_hlt_timestamp.push_back(trig.currPTBTimeStamp); + triggerInfo.ptb_hlt_bit.push_back(bit); + } else { + triggerInfo.ptb_llt_timestamp.push_back(trig.currPTBTimeStamp); + triggerInfo.ptb_llt_bit.push_back(bit); + } + } + } + } + } } diff --git a/sbncode/CAFMaker/FillTrigger.h b/sbncode/CAFMaker/FillTrigger.h index 2c2ada243..203fbe57c 100644 --- a/sbncode/CAFMaker/FillTrigger.h +++ b/sbncode/CAFMaker/FillTrigger.h @@ -9,6 +9,7 @@ #include "lardataobj/RawData/TriggerData.h" #include "art/Framework/Principal/Handle.h" #include "sbndaq-artdaq-core/Obj/SBND/pmtSoftwareTrigger.hh" +#include "sbncode/BeamSpillInfoRetriever/POTTools.h" namespace caf { @@ -30,6 +31,8 @@ namespace caf art::Handle const& passedTrig, caf::SRTrigger& triggerInfo); void FillSoftwareTriggerSBND(const sbnd::trigger::pmtSoftwareTrigger& softInfo, caf::SRSoftwareTrigger& caf_softInfo); + + void FillPTBTriggersSBND(const std::vector& ptb_triggers, caf::SRTrigger& triggerInfo); } #endif