11 #include "art_root_io/TFileService.h"
12 #include "art/Framework/Principal/Run.h"
13 #include "art/Framework/Principal/Event.h"
14 #include "art/Framework/Principal/Handle.h"
15 #include "art/Framework/Services/Registry/ServiceHandle.h"
16 #include "art/Framework/Core/ProducesCollector.h"
17 #include "art/Framework/Core/ConsumesCollector.h"
18 #include "art/Utilities/ToolConfigTable.h"
19 #include "art/Utilities/ToolMacros.h"
20 #include "canvas/Persistency/Provenance/EventID.h"
21 #include "canvas/Persistency/Provenance/Timestamp.h"
23 #include "cetlib_except/exception.h"
24 #include "fhiclcpp/types/TableAs.h"
25 #include "fhiclcpp/types/Atom.h"
26 #include "fhiclcpp/types/OptionalAtom.h"
27 #include "fhiclcpp/types/Sequence.h"
28 #include "messagefacility/MessageLogger/MessageLogger.h"
44 #include "sbndaq-artdaq-core/Overlays/Common/CAENV1730Fragment.hh"
69 using namespace util::quantities::time_literals;
74 namespace daq {
class PMTDecoder; }
280 static std::string listTreeNames(std::string
const& sep =
"\n");
288 static_assert(
sizeof(
int) >= 4U);
290 int seconds = std::numeric_limits<int>::min();
292 unsigned int nanoseconds = std::numeric_limits<unsigned int>::max();
296 long long int time = std::numeric_limits<long long int>::min();
311 fhicl::Atom<std::string>
Name {
313 fhicl::Comment(
"board name, as specified in the DAQ configuration")
316 fhicl::OptionalAtom<unsigned int> FragmentID {
318 fhicl::Comment(
"ID of the fragments associated with the board")
321 fhicl::Atom<nanoseconds> TriggerDelay {
324 (
"from delay from the trigger timestamp to the PMT trigger [ns]"),
337 fhicl::Atom<bool> DiagnosticOutput {
338 Name(
"DiagnosticOutput"),
339 Comment(
"enable additional console output"),
343 fhicl::Atom<bool> RequireKnownBoards {
344 Name(
"RequireKnownBoards"),
345 Comment(
"all readout boards in input must be known (setup+PMT configuration)"),
350 Name(
"RequireBoardConfig"),
351 Comment(
"all readout boards in setup must have a matching PMT configuration"),
355 fhicl::OptionalAtom<art::InputTag> PMTconfigTag {
356 Name(
"PMTconfigTag"),
357 Comment(
"input tag for the PMT readout board configuration information")
360 fhicl::Sequence<fhicl::TableAs<details::BoardSetup_t, BoardSetupConfig>> BoardSetup {
362 Comment(
"list of the setup settings for all relevant V1730 boards")
365 fhicl::Atom<art::InputTag> TriggerTag {
367 Comment(
"input tag for the global trigger object (raw::ExternalTrigger)")
372 fhicl::Comment(
"produces the specified ROOT trees (" + listTreeNames(
",") +
")"),
373 std::vector<std::string>{}
376 fhicl::Atom<std::string> LogCategory {
378 Comment(
"name of the category for message stream"),
397 virtual void consumes(art::ConsumesCollector& consumerColl)
override;
403 virtual void produces(art::ProducesCollector&)
override;
406 virtual void configure(
const fhicl::ParameterSet&)
override;
409 virtual void setupRun(art::Run
const& run)
override;
412 virtual void setupEvent(art::Event
const& event)
override;
418 virtual void initializeDataProducts()
override;
427 virtual void process_fragment(
const artdaq::Fragment &fragment)
override;
434 virtual void outputDataProducts(art::Event& event)
override;
525 NeededBoardInfo_t fetchNeededBoardInfo
549 template <std::
size_t NBits,
typename T>
550 constexpr std::pair<std::array<std::size_t, NBits>, std::size_t>
551 setBitIndices(T
value) noexcept;
569 unsigned long int TriggerTimeTag = 0;
578 TTree* tree =
nullptr;
590 void usesEventInfo();
593 void initTrees(std::vector<std::string>
const& treeNames);
599 void initFragmentsTree();
625 .value_or(details::BoardSetup_t::NoFragmentID)
635 : time {
static_cast<long long int>(sec) * 1
'000'000
'000LL + ns }
639 constexpr daq::PMTDecoder::SplitTimestamp_t::SplitTimestamp_t(long long int triggerTime)
640 : time { triggerTime }
642 static_cast<int>(time / 1'000
'000'000),
643 static_cast<unsigned int>(
time % 1
'000'000
'000) // nanoseconds
649 std::ostream& operator<< (std::ostream& out, PMTDecoder::SplitTimestamp_t const& time) {
650 out << time.split.seconds << '.
'
651 << std::setfill('0
') << std::setw(9) << time.split.nanoseconds;
653 } // operator<< (std::ostream&, PMTDecoder::SplitTimestamp_t)
657 //------------------------------------------------------------------------------------------------------------------------------------------
658 daq::PMTDecoder::TreeNameList_t const daq::PMTDecoder::TreeNames
659 = daq::PMTDecoder::initTreeNames();
661 auto daq::PMTDecoder::initTreeNames() -> TreeNameList_t {
662 TreeNameList_t names;
663 names[static_cast<std::size_t>(DataTrees::Fragments)] = "PMTfragments";
665 } // daq::PMTDecoder::initTreeNames()
667 std::string daq::PMTDecoder::listTreeNames(std::string const& sep /* = " " */) {
669 for (std::string const& name: TreeNames) {
670 if (!l.empty()) l += sep;
681 : fDiagnosticOutput{ params().DiagnosticOutput() }
682 , fRequireKnownBoards{ params().RequireKnownBoards() }
683 , fRequireBoardConfig{ params().RequireBoardConfig() }
685 , fTriggerTag{ params().TriggerTag() }
686 , fBoardSetup{ params().BoardSetup() }
688 , fGeometry{ *(lar::providerFrom<geo::Geometry const>()) }
690 { art::ServiceHandle<detinfo::DetectorClocksService const>()->DataForJob() }
691 , fChannelMap{ *(art::ServiceHandle<icarusDB::IICARUSChannelMap const>{}) }
693 , fNominalTriggerTime{ fDetTimings.TriggerTime() }
696 initTrees(params().DataTrees());
699 log <<
"Configuration:"
700 <<
"\n * boards with setup: " << fBoardSetup.size();
702 log <<
"\n * PMT configuration from '" << fPMTconfigTag->encode() <<
"'";
704 log <<
"\n * PMT configuration not used (and some corrections will be skipped)";
705 if (fRequireKnownBoards) {
706 log <<
"\n * all readout boards in input must be known (from `"
707 << params().BoardSetup.name() <<
"` or `"
708 << params().PMTconfigTag.name() <<
"`)"
712 log <<
"\n * readout boards with no information (from neither `"
713 << params().BoardSetup.name() <<
"` or `"
714 << params().PMTconfigTag.name()
715 <<
"`) are processed at the best we can (skipping corrections)"
718 if (fRequireBoardConfig) {
719 log <<
"\n * all readout boards in `"
720 << params().BoardSetup.name()
721 <<
"` must appear in the PMT configuration from `"
722 << params().PMTconfigTag.name() <<
"`"
726 log <<
"\n * all readout boards in `"
727 << params().BoardSetup.name()
728 <<
"` may lack a matching PMT configuration from `"
729 << params().PMTconfigTag.name() <<
"`"
741 consumerColl.consumes<std::vector<raw::ExternalTrigger>>(fTriggerTag);
747 collector.produces<OpDetWaveformCollection>();
753 throw cet::exception(
"PMTDecoder")
754 <<
"This tool does not support reconfiguration.\n";
764 UpdatePMTConfiguration(PMTconfig);
775 =
event.getProduct<std::vector<raw::ExternalTrigger>>(fTriggerTag);
776 if (triggers.size() != 1) {
779 throw cet::exception(
"PMTDecoder")
780 <<
"Found " << triggers.size() <<
" triggers from '"
781 << fTriggerTag.encode() <<
"', can deal only with 1.\n";
783 fTriggerTimestamp = { triggers.front().GetTrigTime() };
785 <<
"Trigger time ('" << fTriggerTag.encode() <<
"'): " << fTriggerTimestamp <<
" s";
792 if (fEventInfo) fillTreeEventID(event, *fEventInfo);
800 fOpDetWaveformCollection = OpDetWaveformCollectionPtr(
new OpDetWaveformCollection);
804 template <std::
size_t NBits,
typename T>
805 constexpr std::pair<std::array<std::size_t, NBits>, std::size_t>
808 std::pair<std::array<std::size_t, NBits>, std::size_t> res;
809 auto& [
indices, nSetBits ] = res;
810 for (std::size_t& index:
indices) {
811 index = (
value & 1)? nSetBits++: NBits;
820 size_t const fragment_id = artdaqFragment.fragmentID();
821 size_t const eff_fragment_id = artdaqFragment.fragmentID() & 0x0fff;
824 sbndaq::CAENV1730Fragment fragment(artdaqFragment);
825 sbndaq::CAENV1730FragmentMetadata metafrag = *fragment.Metadata();
826 sbndaq::CAENV1730Event
evt = *fragment.Event();
827 sbndaq::CAENV1730EventHeader header = evt.Header;
829 size_t nChannelsPerBoard = metafrag.nChannels;
833 uint32_t ev_size_quad_bytes = header.eventSize;
834 uint32_t evt_header_size_quad_bytes =
sizeof(sbndaq::CAENV1730EventHeader)/
sizeof(uint32_t);
835 uint32_t data_size_double_bytes = 2*(ev_size_quad_bytes - evt_header_size_quad_bytes);
836 uint32_t nSamplesPerChannel = data_size_double_bytes/nChannelsPerBoard;
837 uint16_t
const enabledChannels = header.ChannelMask();
839 artdaq::Fragment::timestamp_t
const fragmentTimestamp = artdaqFragment.timestamp();
841 unsigned int const time_tag = header.triggerTimeTag;
843 size_t boardId = nChannelsPerBoard * eff_fragment_id;
847 auto const [ chDataMap, nEnabledChannels ] = setBitIndices<16U>(enabledChannels);
849 if (fDiagnosticOutput)
852 <<
"----> PMT Fragment ID: " << std::hex << fragment_id << std::dec
853 <<
", boardID: " << boardId
854 <<
", nChannelsPerBoard: " << nChannelsPerBoard
855 <<
", nSamplesPerChannel: " << nSamplesPerChannel
857 <<
"\n size: " << ev_size_quad_bytes
858 <<
", data size: " << data_size_double_bytes
859 <<
", samples/channel: " << nSamplesPerChannel
860 <<
", trigger time tag: " << time_tag
861 <<
", time stamp: " << (fragmentTimestamp / 1
'000'000
'000UL)
862 << "." << (fragmentTimestamp % 1'000
'000'000UL) <<
" s"
866 const uint16_t* data_begin =
reinterpret_cast<const uint16_t*
>(artdaqFragment.dataBeginBytes() +
sizeof(sbndaq::CAENV1730EventHeader));
869 if (fChannelMap.hasPMTDigitizerID(eff_fragment_id))
871 assert(fBoardInfoLookup);
880 details::BoardInfoLookup::BoardInfo_t
const* boardInfo = fBoardInfoLookup->findBoardInfo(fragment_id);
882 if (fRequireKnownBoards) {
883 cet::exception
e(
"PMTDecoder");
884 e <<
"Input fragment has ID " << fragment_id
885 <<
" which has no associated board information (`BoardSetup`";
886 if (!hasPMTconfiguration())
e <<
" + `.FragmentID`";
891 assert(boardInfo->fragmentID == fragment_id);
892 assert(boardInfo->setup);
895 NeededBoardInfo_t
const info = fetchNeededBoardInfo(boardInfo, fragment_id);
897 nanoseconds const preTriggerTime = info.preTriggerTime;
898 nanoseconds const PMTtriggerDelay = info.PMTtriggerDelay;
900 = fNominalTriggerTime - PMTtriggerDelay - preTriggerTime;
901 mf::LogTrace(
fLogCategory) <<
"V1730 board '" << info.name
902 <<
"' has data starting at electronics time " << timeStamp
903 <<
" = " << fNominalTriggerTime
904 <<
" - " << PMTtriggerDelay <<
" - " << preTriggerTime
908 = fChannelMap.getChannelIDPairVec(eff_fragment_id);
910 std::optional<mf::LogVerbatim> diagOut;
911 if (fDiagnosticOutput) {
914 <<
" " << digitizerChannelVec.size() <<
" channels:";
917 std::vector<uint16_t> wvfm(nSamplesPerChannel);
920 uint16_t attemptedChannels = 0;
922 for(
auto const [ digitizerChannel, channelID ]: digitizerChannelVec)
925 (*diagOut) <<
" " << digitizerChannel <<
" [=> " << channelID <<
"];";
927 attemptedChannels |= (1 << digitizerChannel);
929 std::size_t
const channelPosInData = chDataMap[digitizerChannel];
930 if (channelPosInData >= nEnabledChannels) {
932 <<
"Digitizer channel " << digitizerChannel
933 <<
" [=> " << channelID <<
"] skipped because not enabled.";
937 std::size_t
const ch_offset = channelPosInData * nSamplesPerChannel;
939 std::copy_n(data_begin + ch_offset, nSamplesPerChannel, wvfm.begin());
942 <<
"PMT channel " << channelID <<
" has " << wvfm.size()
943 <<
" samples (read from entry #" << channelPosInData
944 <<
" in fragment data) starting at electronics time " << timeStamp;
945 fOpDetWaveformCollection->emplace_back(timeStamp.value(), channelID, wvfm);
947 if (diagOut) diagOut.reset();
948 if (attemptedChannels != enabledChannels) {
953 log <<
"Not all data read:";
955 uint16_t
const mask = (1 << bit);
956 bool const attempted =
bool(attemptedChannels & mask);
957 bool const enabled =
bool(enabledChannels & mask);
958 if (attempted == enabled)
continue;
960 log <<
"\n requested channel " << bit <<
" was not enabled";
962 log <<
"\n data for enabled channel " << bit <<
" was ignored";
969 <<
"*** PMT could not find channel information for fragment: "
973 if (fDiagnosticOutput) {
975 <<
" - size of output collection: " << fOpDetWaveformCollection->size();
979 fTreeFragment->data.fragmentID = fragment_id;
980 fTreeFragment->data.TriggerTimeTag = time_tag;
981 fTreeFragment->data.trigger = fTriggerTimestamp;
982 fTreeFragment->data.fragTime = {
static_cast<long long int>(fragmentTimestamp) };
983 assignEventInfo(fTreeFragment->data);
984 fTreeFragment->tree->Fill();
993 std::sort(fOpDetWaveformCollection->begin(),fOpDetWaveformCollection->end(),[](
const auto&
left,
const auto&
right){
return left.ChannelNumber() <
right.ChannelNumber();});
996 event.put(std::move(fOpDetWaveformCollection));
1003 fBoardInfoLookup.emplace(matchBoardConfigurationAndSetup(PMTconfig));
1005 mf::LogDebug(
fLogCategory) <<
"Board information as cached:\n" << *fBoardInfoLookup;
1040 std::vector<std::pair<std::string, sbn::V1730Configuration const*>> configByName;
1042 if (!PMTconfig->
boards.empty())
1043 configByName.reserve(PMTconfig->
boards.size());
1045 configByName.emplace_back(boardConfig.
boardName, &boardConfig);
1046 std::sort(configByName.begin(), configByName.end());
1050 auto findPMTconfig = [
this,&configByName]
1053 if (!hasPMTconfiguration())
return nullptr;
1055 if (!ppBoardConfig) {
1056 if (!fRequireBoardConfig)
return nullptr;
1057 throw cet::exception(
"PMTDecoder")
1058 <<
"No DAQ configuration found for PMT readout board '"
1060 <<
"If this is expected, you may skip this check by setting "
1061 <<
"PMTDecoder tool configuration `RequireBoardConfig` to `false`.\n";
1063 return ppBoardConfig->second;
1070 for (details::BoardSetup_t
const& boardSetup: fBoardSetup) {
1072 std::string
const& boardName = boardSetup.name;
1078 if (boardSetup.hasFragmentID() && (boardSetup.fragmentID != pBoardConfig->
fragmentID))
1080 throw cet::exception(
"PMTDecoder")
1081 <<
"Board '" << boardName <<
"' has fragment ID "
1082 << std::hex << pBoardConfig->
fragmentID << std::dec
1083 <<
" but it is set up as "
1084 << std::hex << boardSetup.fragmentID << std::dec
1089 if (boardSetup.hasFragmentID()) {
1091 <<
"Board '" << boardName
1092 <<
"' has no configuration information:"
1093 " some time stamp corrections will be skipped.";
1098 <<
"Board '" << boardName
1099 <<
"' can't be associated to a fragment ID: its time stamp corrections will be skipped.";
1106 unsigned int const fragmentID
1107 = pBoardConfig? pBoardConfig->
fragmentID: boardSetup.fragmentID;
1116 details::BoardFacts_t boardFacts {
1120 boardInfoByFragment.push_back({
1124 std::move(boardFacts)
1128 return details::BoardInfoLookup{ std::move(boardInfoByFragment) };
1135 (details::BoardInfoLookup::BoardInfo_t
const* boardInfo,
unsigned int fragmentID)
const
1136 -> NeededBoardInfo_t
1139 return NeededBoardInfo_t{
1141 ((boardInfo && boardInfo->config)? boardInfo->config->boardName: (
"<ID=" +
std::to_string(fragmentID)))
1143 , (boardInfo? boardInfo->facts.preTriggerTime:
nanoseconds{ 0.0 })
1145 , ((boardInfo && boardInfo->setup)? boardInfo->setup->triggerDelay:
nanoseconds{ 0.0 })
1170 auto findTree = [](std::string
const&
name)
1178 for (std::string
const&
name: treeNames) {
1179 switch (findTree(
name)) {
1180 case DataTrees::Fragments: initFragmentsTree();
break;
1183 throw cet::exception(
"PMTdecoder")
1184 <<
"initTrees(): no data tree supported with name '" <<
name <<
"'.\n";
1196 tree.Branch(
"run", &data.run);
1197 tree.Branch(
"subrun", &data.subrun);
1198 tree.Branch(
"event", &data.event);
1199 tree.Branch(
"timestamp", &data.timestamp.time,
"timestamp/L");
1206 if (fTreeFragment)
return;
1208 TTree* tree = art::ServiceHandle<art::TFileService>()
1209 ->make<TTree>(
"PMTfragments",
"PMT fragment data");
1211 fTreeFragment = std::make_unique<TreeFragment_t>();
1212 fTreeFragment->tree = tree;
1213 auto& data = fTreeFragment->data;
1215 initEventIDtree(*tree, data);
1217 tree->Branch(
"fragmentID", &data.fragmentID);
1218 tree->Branch(
"fragTime", &data.fragTime.time,
"fragTime/L");
1219 tree->Branch(
"fragTimeSec", &data.fragTime.split.seconds);
1220 tree->Branch(
"TTT", &data.TriggerTimeTag,
"TTT/l");
1221 tree->Branch(
"trigger", &data.trigger.time,
"trigger/L");
1222 tree->Branch(
"triggerSec", &data.trigger.split.seconds);
1223 tree->Branch(
"triggerNS", &data.trigger.split.nanoseconds);
1231 if (!fEventInfo) fEventInfo = std::make_unique<TreeData_EventID_t>();
1237 (TreeData_EventID_t& treeData)
const
1241 treeData = *fEventInfo;
1247 (art::Event
const& event, TreeData_EventID_t& treeData)
const
1249 art::EventID
const&
id =
event.id();
1250 treeData.run =
id.run();
1251 treeData.subrun =
id.subRun();
1252 treeData.event =
id.event();
1254 art::Timestamp
const& timestamp =
event.time();
1256 = {
static_cast<int>(timestamp.timeHigh()), timestamp.timeLow() };
detinfo::DetectorTimings const fDetTimings
Interface to LArSoft configuration for detector timing.
SplitTimestamp_t timestamp
Event timestamp (seconds from the epoch).
std::string boardName
Name (mnemonic) of the board.
virtual void setupEvent(art::Event const &event) override
Will read trigger information one day if needed.
virtual void initializeDataProducts() override
Initialize any data products the tool will output.
unsigned int run
Run number.
Structure collecting all data for a fragment ROOT tree.
std::vector< DigitizerChannelChannelIDPair > DigitizerChannelChannelIDPairVec
Utilities related to art service access.
PMTDecoder(Parameters const ¶ms)
Constructor.
icarusDB::IICARUSChannelMap const & fChannelMap
Fragment/channel mapping database.
std::vector< details::BoardSetup_t > const fBoardSetup
All board setup settings.
std::optional< typename Optional::value_type > getOptionalValue(Optional const ¶meter)
Returns the value of an optional parameter as std::optional.
IDecoder interface class definiton.
SplitTimestamp_t fTriggerTimestamp
Trigger timestamp for the current event.
Data structure for basic event information in simple ROOT trees.
Utility class for fast lookup of board data by fragment ID.
DataTrees
Enumerate the supported data trees.
Definition of util::enumerate().
std::array< std::string, static_cast< std::size_t >(DataTrees::N)> TreeNameList_t
bool const fRequireKnownBoards
Whether info on all input boards is required.
bool hasPMTconfiguration() const
Returns whether PMT configuration information is expected to be available.
This provides an art tool interface definition for tools which "decode" artdaq fragments into LArSoft...
void assignEventInfo(TreeData_EventID_t &treeData) const
Assigns the cached event information to the specified tree data.
fhicl::Atom< std::string > Name
virtual void setupRun(art::Run const &run) override
Reads the PMT configuration from the run.
bool UpdatePMTConfiguration(sbn::PMTconfiguration const *PMTconfig)
Updates the PMT configuration cache. How? Dunno. Placeholder.
Information used in decoding from a board.
Some helpers for PMT decoder tool.
geo::GeometryCore const & fGeometry
Geometry service provider.
virtual void produces(art::ProducesCollector &) override
Each algorithm may have different objects it wants "produced" so use this to let the top level produc...
std::vector< BoardInfo_t > Database_t
void fillTreeEventID(art::Event const &event, TreeData_EventID_t &treeData) const
Fills the base information of a tree data entry from an art event.
pure virtual base interface for detector clocks
nanoseconds PMTtriggerDelay
constexpr details::BinObj< T > bin(T value)
Returns a wrapper to print the specified data in binary format.
unsigned int fragmentID
DAQ fragment ID.
Interface to detinfo::DetectorClocks.
std::unique_ptr< TreeData_EventID_t > fEventInfo
Event ID for trees.
unsigned int bufferLength
Ticks in each buffer (recordLength).
void initEventIDtree(TTree &tree, TreeData_EventID_t &data)
Initializes the event ID part of a tree.
NeededBoardInfo_t fetchNeededBoardInfo(details::BoardInfoLookup::BoardInfo_t const *boardInfo, unsigned int fragmentID) const
Puts together all the needed information for a board.
Configuration of the V1730 readout board setup.
Access the description of detector geometry.
std::optional< art::InputTag > const fPMTconfigTag
Input tag of the PMT configuration.
virtual void process_fragment(const artdaq::Fragment &fragment) override
Given a set of recob hits, run DBscan to form 3D clusters.
long long int time
Trigger time in nanoseconds from The Epoch.
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
void usesEventInfo()
Declares the use of event information.
constexpr mask_t< EnumType > mask(EnumType bit, OtherBits...otherBits)
Returns a mask with all specified bits set.
second seconds
Alias for common language habits.
bool const fDiagnosticOutput
If true will spew endless messages to output.
void initFragmentsTree()
Initializes the fragment data tree (fTreeFragment).
SplitTimestamp_t trigger
Global trigger time.
constexpr std::array< std::size_t, geo::vect::dimension< Vector >)> indices()
Returns a sequence of indices valid for a vector of the specified type.
detinfo::timescales::electronics_time const fNominalTriggerTime
Trigger time as reported by DetectorClocks service.
unsigned int subrun
Subrun number.
auto end(FixedBins< T, C > const &) noexcept
std::unique_ptr< OpDetWaveformCollection > OpDetWaveformCollectionPtr
bool const fRequireBoardConfig
Whether setup info on all boards is required.
BEGIN_PROLOG vertical distance to the surface Name
nanoseconds preTriggerTime
Information from the configuration of PMT readout.
Test of util::counter and support utilities.
static constexpr unsigned int NoFragmentID
Special value to mark the absence of fragment ID information.
Description of geometry of one entire detector.
static TreeNameList_t const TreeNames
An interval (duration, length, distance) between two quantity points.
Coll::value_type const * binarySearch(Coll const &coll, Key const &key, KeyExtractor &&extractKey)
Record of information about a readout board.
nanoseconds_as<> nanoseconds
Type of time interval stored in nanoseconds, in double precision.
auto begin(FixedBins< T, C > const &) noexcept
constexpr SplitTimestamp_t()=default
Utilities to read interval and point quantity FHiCL configuration.
virtual void consumes(art::ConsumesCollector &consumerColl) override
I hereby declare I will consume trigger and PMT configuration products.
std::string const fLogCategory
Message facility category.
std::string to_string(WindowPattern const &pattern)
process_name sequence::icarus_stage0_EastHits_TPC physics sequence::icarus_stage0_EastHits_TPC physics pathNUMI physics streamNUMI outputs outBNB drop *_ *_ *_DAQ drop *_daqTPCROI_ *_ drop *_decon1droi_ *_ drop *_decon1DroiTPC *_ *_ *outputs outNUMI drop *_ *_ *_DAQ drop *_daqTPCROI_ *_ drop *_decon1droi_ *_ drop *_decon1DroiTPC *_ *_ *physics producers daqPMT DecoderTool RequireBoardConfig
Dimensioned variables representing space or time quantities.
Data structure for trigger time.
A class exposing an upgraded interface of detinfo::DetectorClocksData.
process_name largeant stream1 can override from command line with o or output physics producers generator N
std::optional< details::BoardInfoLookup > fBoardInfoLookup
Find the information on a readout boards by fragment ID.
details::BoardInfoLookup matchBoardConfigurationAndSetup(sbn::PMTconfiguration const *PMTconfig) const
Returns a lookup object with board setup and configuration info.
OpDetWaveformCollectionPtr fOpDetWaveformCollection
The output data collection pointer.
void initTrees(std::vector< std::string > const &treeNames)
Initializes all requested data trees.
art::ToolConfigTable< Config > Parameters
Simple helper functions to deal with FHiCL.
float postTriggerFrac
Fraction of the waveform after the trigger signal (postPercent).
Split_t split
Trigger time in nanoseconds from The Epoch (in components).
virtual void outputDataProducts(art::Event &event) override
Output the data products to the event store.
fhicl::Atom< nanoseconds > TriggerDelay
Information of the setup of a V1730 readout board.
virtual void configure(const fhicl::ParameterSet &) override
Reconfiguration is not supported: all configuration at construction time.
nanoseconds const fOpticalTick
Duration of the optical detector readout sampling tick (i.e. 2 ns; shh!).
Class containing configuration for PMT readout.
timescale_traits< ElectronicsTimeCategory >::time_point_t electronics_time
A point in time on the electronics time scale.
unsigned int event
Event number.
std::vector< raw::OpDetWaveform > OpDetWaveformCollection
SplitTimestamp_t fragTime
PMT fragment time stamp.
TimeTrackTreeStorage::TriggerInputSpec_t convert(TimeTrackTreeStorage::Config::TriggerSpecConfig const &config)
art framework interface to geometry description
Functions to dump the content of binary data chunks to console.
Turns PMT readout fragments from DAQ into LArSoft data products.
std::unique_ptr< TreeFragment_t > fTreeFragment
Tree with fragment information.
fhicl::OptionalAtom< unsigned int > FragmentID
art::InputTag const fTriggerTag
Input tag of the global trigger.
std::vector< sbn::V1730Configuration > boards
Configuration of all PMT readout boards.
nanosecond nanoseconds
Alias for common language habits.
constexpr std::pair< std::array< std::size_t, NBits >, std::size_t > setBitIndices(T value) noexcept
Returns the count of set bits for each set bit.
Class containing configuration for a V1730 board.