11 #include "art/Framework/Core/EDProducer.h"
12 #include "art/Framework/Core/ConsumesCollector.h"
13 #include "art/Framework/Core/ProducesCollector.h"
14 #include "art/Framework/Principal/Run.h"
15 #include "art/Framework/Principal/Event.h"
16 #include "art/Framework/Principal/Handle.h"
17 #include "art/Framework/Services/Registry/ServiceHandle.h"
18 #include "art/Persistency/Common/PtrMaker.h"
19 #include "art/Utilities/ToolMacros.h"
20 #include "cetlib/cpu_timer.h"
21 #include "fhiclcpp/ParameterSet.h"
22 #include "messagefacility/MessageLogger/MessageLogger.h"
31 #include "sbndaq-artdaq-core/Overlays/ICARUS/ICARUSTriggerV2Fragment.hh"
45 #include <string_view>
50 using namespace std::string_literals;
211 class TriggerDecoder :
public IDecoder
218 virtual void consumes(art::ConsumesCollector& collector)
override;
219 virtual void produces(art::ProducesCollector&)
override;
220 virtual void configure(
const fhicl::ParameterSet&)
override;
221 virtual void initializeDataProducts()
override;
222 virtual void setupRun(art::Run
const& run)
override;
223 virtual void process_fragment(
const artdaq::Fragment &fragment)
override;
224 virtual void outputDataProducts(art::Event &event)
override;
235 std::unique_ptr<RelativeTriggerCollection> fRelTrigger;
239 bool fDiagnosticOutput;
251 icarus::ICARUSTriggerV2Fragment makeTriggerFragment
252 (artdaq::Fragment
const& fragment)
const;
255 icarus::ICARUSTriggerInfo parseTriggerString(std::string_view data)
const;
259 (std::string
const& data)
const;
262 static std::string
const CurrentTriggerInstanceName;
265 static std::string
const PreviousTriggerInstanceName;
267 static constexpr
double UnknownBeamTime = std::numeric_limits<double>::max();
271 static constexpr
int BNB { 1 };
272 static constexpr
int NuMI { 2 };
273 static constexpr
int OffbeamBNB { 3 };
275 static constexpr
int Calib { 5 };
278 static constexpr
nanoseconds BNBgateDuration { 1600. };
279 static constexpr
nanoseconds NuMIgateDuration { 9500. };
281 static std::string_view firstLine
282 (std::string
const&
s, std::string
const& endl =
"\0\n\r"s);
286 {
return s * 1000000000ULL + ns; }
289 {
return static_cast<long long int>(
a) - static_cast<long long int>(b); }
293 static std::uint64_t encodeLVDSbits
294 (
short int cryostat,
short int connector, std::uint64_t connectorWord);
302 std::string
const TriggerDecoder::CurrentTriggerInstanceName {};
303 std::string
const TriggerDecoder::PreviousTriggerInstanceName {
"previous" };
306 TriggerDecoder::TriggerDecoder(fhicl::ParameterSet
const &pset)
308 { art::ServiceHandle<detinfo::DetectorClocksService>()->DataForJob() }
310 this->configure(pset);
333 fDebug = pset.get<
bool>(
"Debug",
false);
334 if (pset.has_key(
"TimeOffset")) {
335 if (
auto offset = pset.get<
long long int>(
"TimeOffset");
offset == 0) {
336 mf::LogWarning(
"TriggerDecoder")
337 <<
"Configuration parameter 'TimeOffset' has been dropped.\n";
340 throw art::Exception(art::errors::Configuration)
341 <<
"Adding offset (configuration parameter 'TimeOffset', here set to "
342 <<
offset <<
" seconds) is not supported any more.\n";
352 fTrigger = std::make_unique<TriggerCollection>();
354 fRelTrigger = std::make_unique<RelativeTriggerCollection>();
362 (artdaq::Fragment
const& fragment)
const
365 return icarus::ICARUSTriggerV2Fragment { fragment };
367 catch(std::exception
const&
e) {
368 mf::LogSystem(
"TriggerDecoder")
369 <<
"Error while creating trigger fragment from:\n"
371 <<
"\nError message: " << e.what();
375 mf::LogSystem(
"TriggerDecoder")
376 <<
"Unidentified exception while creating trigger fragment from:"
384 (std::string_view data)
const
387 return icarus::parse_ICARUSTriggerV2String(data.data());
389 catch(std::exception
const& e) {
390 mf::LogSystem(
"TriggerDecoder")
391 <<
"Error while running standard parser on " << data.length()
392 <<
"-char long trigger string:\n==>|" << data
393 <<
"|<==\nError message: " << e.what();
397 mf::LogSystem(
"TriggerDecoder")
398 <<
"Unidentified exception while running standard parser on "
399 << data.length() <<
"-char long trigger string:\n==>|" << data <<
"|.";
406 (std::string
const& data)
const
410 {
"Cryo. (EAST|WEST) Connector . and .", 1U }
411 , {
"Trigger Type", 1U }
413 std::string_view
const dataLine = firstLine(data);
418 mf::LogError(
"TriggerDecoder")
419 <<
"Error parsing " << dataLine.length()
420 <<
"-char long trigger string:\n==>|" << dataLine
421 <<
"|<==\nError message: " << e.what() << std::endl;
442 uint64_t
const artdaq_ts = fragment.timestamp();
444 std::string data = frag.GetDataString();
445 char *buffer =
const_cast<char*
>(data.c_str());
448 uint64_t
const raw_wr_ts
449 =
makeTimestamp(frag.getWRSeconds(), frag.getWRNanoSeconds());
452 int64_t
const WRtimeToTriggerTime
453 =
static_cast<int64_t
>(artdaq_ts) - raw_wr_ts;
454 auto const correctWRtime = [WRtimeToTriggerTime](uint64_t time)
455 {
return time + WRtimeToTriggerTime; };
456 assert(correctWRtime(raw_wr_ts) == artdaq_ts);
464 unsigned int beamgate_count { std::numeric_limits<unsigned int>::max() };
465 std::uint64_t beamgate_ts { artdaq_ts };
472 if (
auto pBeamGateInfo = parsedData.findItem(
"Beam_TS")) {
490 int64_t
const triggerVetoDurationNS
495 beamgate_count = pBeamGateInfo->getNumber<
unsigned int>(0U);
498 pBeamGateInfo->getNumber<
unsigned int>(1U),
499 pBeamGateInfo->getNumber<
unsigned int>(2U)
501 + triggerVetoDurationNS
506 beamgate_ts += raw_bg_ts - raw_wr_ts;
509 std::uint64_t enablegate_ts { artdaq_ts };
510 if (
auto pEnableGateInfo = parsedData.findItem(
"Enable_TS"))
516 pEnableGateInfo->getNumber<
unsigned int>(1U),
517 pEnableGateInfo->getNumber<
unsigned int>(2U)
523 enablegate_ts += raw_en_ts - raw_wr_ts;
528 if(fDiagnosticOutput || fDebug)
530 std::cout <<
"Full Timestamp = " << artdaq_ts
531 <<
"\nBeam gate " << beamgate_count <<
" at "
532 << (beamgate_ts/1
'000'000
'000) << "." << std::setfill('0
')
533 << std::setw(9) << (beamgate_ts%1'000
'000'000) << std::setfill(
' ')
535 <<
" ns relative to trigger)"
536 <<
"\nParsed data (from " << data.size() <<
" characters): "
537 << parsedData << std::endl;
540 std::cout <<
"Trigger packet content:\n" << data
541 <<
"\nFull trigger fragment dump:"
549 switch (datastream_info.gate_type) {
551 beamGateBit = sbn::triggerSource::BNB;
552 fTriggerExtra->gateCountFromPreviousTrigger = frag.getDeltaGatesBNB();
553 fTriggerExtra->previousTriggerTimestamp = frag.getLastTimestampBNB();
556 fTriggerExtra->anyTriggerCountFromPreviousTrigger = frag.getLastTriggerBNB();
560 beamGateBit = sbn::triggerSource::NuMI;
561 fTriggerExtra->gateCountFromPreviousTrigger = frag.getDeltaGatesNuMI();
562 fTriggerExtra->previousTriggerTimestamp = frag.getLastTimestampNuMI();
565 fTriggerExtra->anyTriggerCountFromPreviousTrigger = frag.getLastTriggerNuMI();
569 beamGateBit = sbn::triggerSource::OffbeamBNB;
570 fTriggerExtra->gateCountFromPreviousTrigger = frag.getDeltaGatesBNBOff();
571 fTriggerExtra->previousTriggerTimestamp= frag.getLastTimestampBNBOff();
574 fTriggerExtra->anyTriggerCountFromPreviousTrigger = frag.getLastTriggerBNBOff();
578 beamGateBit = sbn::triggerSource::OffbeamNuMI;
579 fTriggerExtra->gateCountFromPreviousTrigger = frag.getDeltaGatesNuMIOff();
580 fTriggerExtra->previousTriggerTimestamp= frag.getLastTimestampNuMIOff();
583 fTriggerExtra->anyTriggerCountFromPreviousTrigger = frag.getLastTriggerNuMIOff();
587 beamGateBit = sbn::triggerSource::Calib;
588 fTriggerExtra->gateCountFromPreviousTrigger = frag.getDeltaGatesCalib();
589 fTriggerExtra->previousTriggerTimestamp = frag.getLastTimestampCalib();
592 fTriggerExtra->anyTriggerCountFromPreviousTrigger = frag.getLastTriggerCalib();
595 default: beamGateBit = sbn::triggerSource::Unknown;
604 fTriggerExtra->anyGateCountFromAnyPreviousTrigger = frag.getDeltaGates();
605 fTriggerExtra->anyPreviousTriggerTimestamp = frag.getLastTimestamp();
607 if(frag.getLastTriggerType() == 1)
608 previousTriggerSourceBit = sbn::triggerSource::BNB;
609 else if(frag.getLastTriggerType() == 2)
610 previousTriggerSourceBit = sbn::triggerSource::NuMI;
611 else if(frag.getLastTriggerType() == 3)
612 previousTriggerSourceBit = sbn::triggerSource::OffbeamBNB;
613 else if(frag.getLastTriggerType() == 4)
614 previousTriggerSourceBit = sbn::triggerSource::OffbeamNuMI;
615 else if(frag.getLastTriggerType() == 5)
616 previousTriggerSourceBit = sbn::triggerSource::Calib;
618 previousTriggerSourceBit = sbn::triggerSource::Unknown;
619 fTriggerExtra->anyPreviousTriggerSourceType = previousTriggerSourceBit;
624 int const triggerLocation = parsedData.getItem(
"Trigger Source").getNumber<
int>(0);
625 if(triggerLocation == 1)
626 locationMask =
mask(sbn::triggerLocation::CryoEast);
627 else if(triggerLocation == 2)
628 locationMask =
mask(sbn::triggerLocation::CryoWest);
629 else if(triggerLocation == 7)
630 locationMask =
mask(sbn::triggerLocation::CryoEast, sbn::triggerLocation::CryoWest);
636 ? 0UL: parsedData.getItem(
"Cryo1 EAST counts").getNumber<
unsigned long int>(0),
639 (triggerLocation & 1)
642 parsedData.getItem(
"Cryo1 EAST Connector 2 and 3").getNumber<std::uint64_t>(0, 16)
645 (triggerLocation & 1)
648 parsedData.getItem(
"Cryo1 EAST Connector 0 and 1").getNumber<std::uint64_t>(0, 16)
657 ? 0UL: parsedData.getItem(
"Cryo2 WEST counts").getNumber<
unsigned long int>(0),
660 (triggerLocation & 2)
663 parsedData.getItem(
"Cryo2 WEST Connector 2 and 3").getNumber<std::uint64_t>(0, 16)
666 (triggerLocation & 2)
669 parsedData.getItem(
"Cryo2 WEST Connector 0 and 1").getNumber<std::uint64_t>(0, 16)
676 for (
auto const& cryoInfo [[maybe_unused]]:
fTriggerExtra->cryostats)
677 for (
auto LVDS [[maybe_unused]]: cryoInfo.LVDSstatus)
678 assert((LVDS & 0xFF000000FF000000) == 0);
689 uint64_t lastTrigger = 0;
720 (simGateStart.value(), gateWidth.value(),
simGateType(beamGateBit));
726 static_cast<unsigned int>(datastream_info.wr_event_no),
728 elecGateStart.value(),
748 (std::string
const&
s, std::string
const& endl )
750 return { s.data(), std::min(s.find_first_of(endl), s.size()) };
755 (
short int cryostat,
short int connector, std::uint64_t connectorWord)
768 std::uint64_t lsw = connectorWord & 0xFFFFFFFFULL;
769 std::uint64_t msw = connectorWord >> 32ULL;
770 assert(connectorWord == ((msw << 32ULL) | lsw));
772 return (msw << 32ULL) | lsw;
779 case sbn::triggerSource::BNB:
780 case sbn::triggerSource::OffbeamBNB:
782 case sbn::triggerSource::NuMI:
783 case sbn::triggerSource::OffbeamNuMI:
785 case sbn::triggerSource::Calib:
788 mf::LogWarning(
"TriggerDecoder") <<
"Unsupported trigger source " <<
name(source);
Definitions of the trigger bits for SBN.
virtual void produces(art::ProducesCollector &) override
The space point building should output the hit collection for those hits which combine to form space ...
Parser to fill a KeyValuesData structure out of a character buffer.
BEGIN_PROLOG TPC Trig offset(g4 rise time) ProjectToHeight
detinfo::DetectorTimings const fDetTimings
Detector clocks and timings.
bool fDiagnosticOutput
Produces large number of diagnostic messages, use with caution!
virtual void initializeDataProducts() override
Initialize any data products the tool will output.
microsecond_as<> microsecond
Type of time stored in microseconds, in double precision.
This provides an art tool interface definition for tools which "decode" artdaq fragments into LArSoft...
std::unique_ptr< TriggerCollection > TriggerPtr
static constexpr int OffbeamNuMI
std::unique_ptr< sbn::ExtraTriggerInfo > ExtraInfoPtr
icarus::TriggerConfiguration const * fTriggerConfiguration
Cached pointer to the trigger configuration of the current run, if any.
virtual void process_fragment(const artdaq::Fragment &fragment) override
Given a set of recob hits, run DBscan to form 3D clusters.
float getGateWidth(std::size_t source) const
returns the effective gate width corrected for the veto delay in us
static std::string const CurrentTriggerInstanceName
Name of the data product instance for the current trigger.
static constexpr int Calib
BeamGateInfoPtr fBeamGateInfo
std::vector< sim::BeamGateInfo > BeamGateInfoCollection
Simple parser for comma-separated text.
Information from the configuration of the ICARUS trigger readout.
triggerLocation
Location or locations generating a trigger.
std::unique_ptr< BeamGateInfoCollection > BeamGateInfoPtr
static std::string const PreviousTriggerInstanceName
Name of the data product instance for the previous trigger.
Interface to detinfo::DetectorClocks.
util::quantities::nanosecond nanoseconds
ExtraInfoPtr fTriggerExtra
Simple parsed data format.
virtual void configure(const fhicl::ParameterSet &) override
Interface for configuring the particular algorithm tool.
icarus::ICARUSTriggerUDPFragment makeTriggerFragment(artdaq::Fragment const &fragment) const
Creates a ICARUSTriggerInfo from a generic fragment.
constexpr mask_t< EnumType > mask(EnumType bit, OtherBits...otherBits)
Returns a mask with all specified bits set.
bool fDebug
Use this for debugging this tool.
static constexpr int NuMI
A value measured in the specified unit.
Collection of items with key/values structure.
simulation_time toSimulationTime(FromTime time) const
Converts a time point into simulation time scale.
art::InputTag fTriggerConfigTag
Data product with hardware trigger configuration.
virtual void outputDataProducts(art::Event &event) override
Output the data products to the event store.
KeyedCSVparser & addPatterns(std::initializer_list< std::pair< std::regex, unsigned int >> patterns)
Adds known patterns.
Utility to dump a artDAQ fragment on screen.
virtual void consumes(art::ConsumesCollector &collector) override
Declare to the framework what you expect to read.
electronics_time TriggerTime() const
static std::uint64_t encodeLVDSbits(short int cryostat, short int connector, std::uint64_t connectorWord)
std::unique_ptr< RelativeTriggerCollection > fRelTrigger
static long long int timestampDiff(std::uint64_t a, std::uint64_t b)
Returns the difference a - b.
icarus::KeyValuesData parseTriggerStringAsCSV(std::string const &data) const
Parses the trigger data packet with a CSV parser.
static std::uint64_t makeTimestamp(unsigned int s, unsigned int ns)
Combines second and nanosecond counts into a 64-bit timestamp.
details::DumpFragWrap dumpFragment(artdaq::Fragment const &frag)
Dump a artDAQ fragment into an output stream.
then echo File list $list not found else cat $list while read file do echo $file sed s
Dimensioned variables representing space or time quantities.
A class exposing an upgraded interface of detinfo::DetectorClocksData.
std::vector< raw::Trigger > RelativeTriggerCollection
nanosecond_as<> nanosecond
Type of time stored in nanoseconds, in double precision.
std::vector< raw::ExternalTrigger > TriggerCollection
Tool decoding the trigger information from DAQ.
Codes of gate types from the trigger hardware.
virtual void setupRun(art::Run const &run) override
Preparation to process a new run.
triggerSource
Type of beam or beam gate or other trigger source.
static constexpr int OffbeamBNB
static sim::BeamType_t simGateType(sbn::triggerSource source)
Returns the beam type corresponding to the specified trigger source.
static std::string_view firstLine(std::string const &s, std::string const &endl="\0\n\r"s)
unsigned int vetoDelay
Veto (this delay has to be subtracted to the gate width ). Value is in ns.
util::quantities::microsecond microseconds
BeamType_t
Defines category of beams to be stored in sim::BeamGateInfo.
BEGIN_PROLOG could also be cout
Functions to dump the content of binary data chunks to console.
icarus::ICARUSTriggerInfo parseTriggerString(std::string_view data) const
Parses the trigger data packet with the "standard" parser.
nanosecond nanoseconds
Alias for common language habits.