Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PTB decoder module and data product #397

Merged
merged 9 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sbndcode/Decoders/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
add_subdirectory(TPC)
add_subdirectory(PTB)
add_subdirectory(SPECTDC)
30 changes: 30 additions & 0 deletions sbndcode/Decoders/PTB/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

# this is borrowed from sbndaq-artdaq-core to make the c7 compiler happy
# remove if not needed by the trigger decoder
# add_definitions(-Wno-nested-anon-types)

cet_build_plugin( SBNDPTBDecoder art::module
SOURCE SBNDPTBDecoder_module.cc
LIBRARIES
sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_SBND
lardataobj::RawData
artdaq_core::artdaq-core_Utilities
art::Utilities
fhiclcpp::fhiclcpp
messagefacility::MF_MessageLogger
art::Framework_Core
ROOT::Core
)

cet_make_library(SOURCE
SBNDPTBRawUtils.cxx
LIBRARIES
sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_SBND
ROOT::Core
)

install_headers()
install_fhicl()
install_source()
art_dictionary()

13 changes: 13 additions & 0 deletions sbndcode/Decoders/PTB/SBNDPTBDecoderDefaults.fcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
BEGIN_PROLOG

SBNDPTBDecoderDefaults: {
module_type: SBNDPTBDecoder
InputLabel: "daq"
InputContainerInstance: "ContainerPTB"
InputNonContainerInstance: "PTB"
OutputInstance: ""
DebugLevel: 0
}

END_PROLOG

227 changes: 227 additions & 0 deletions sbndcode/Decoders/PTB/SBNDPTBDecoder_module.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
////////////////////////////////////////////////////////////////////////
// Class: SBNDPTBDecoder
// Plugin Type: producer
// File: SBNDPTBDecoder_module.cc
//
////////////////////////////////////////////////////////////////////////

#include "art/Framework/Core/EDProducer.h"
#include "art/Framework/Core/ModuleMacros.h"
#include "art/Framework/Principal/Event.h"
#include "art/Framework/Principal/Handle.h"
#include "art/Framework/Principal/Run.h"
#include "art/Framework/Principal/SubRun.h"
#include "canvas/Utilities/InputTag.h"
#include "fhiclcpp/ParameterSet.h"
#include "messagefacility/MessageLogger/MessageLogger.h"

#include <memory>

#include "sbndaq-artdaq-core/Overlays/SBND/PTBFragment.hh"
#include "artdaq-core/Data/ContainerFragment.hh"
#include "sbndcode/Decoders/PTB/sbndptb.h"

class SBNDPTBDecoder;


class SBNDPTBDecoder : public art::EDProducer {
public:
explicit SBNDPTBDecoder(fhicl::ParameterSet const & p);
// The compiler-generated destructor is fine for non-base
// classes without bare pointers or other resource use.

// Plugins should not be copied or assigned.
SBNDPTBDecoder(SBNDPTBDecoder const &) = delete;
SBNDPTBDecoder(SBNDPTBDecoder &&) = delete;
SBNDPTBDecoder & operator = (SBNDPTBDecoder const &) = delete;
SBNDPTBDecoder & operator = (SBNDPTBDecoder &&) = delete;

// Required functions.
void produce(art::Event & e) override;

private:

// Declare member data here.

std::string fInputLabel;
std::string fInputContainerInstance;
std::string fInputNonContainerInstance;
std::string fOutputInstance;
int fDebugLevel;

typedef struct ptbsv
{
std::vector<raw::ptb::Trigger> HLTrigs;
std::vector<raw::ptb::Trigger> LLTrigs;
std::vector<raw::ptb::ChStatus> ChStats;
std::vector<raw::ptb::Feedback> Feedbacks;
std::vector<raw::ptb::Misc> Miscs;
std::vector<raw::ptb::WordIndex> WordIndexes;
} ptbsv_t;

void _process_PTB_AUX(const artdaq::Fragment& frag, ptbsv_t &sout);
};


SBNDPTBDecoder::SBNDPTBDecoder(fhicl::ParameterSet const & p)
: EDProducer{p}
// Initialize member data here.
{
fInputLabel = p.get<std::string>("InputLabel");
fInputContainerInstance = p.get<std::string>("InputContainerInstance");
fInputNonContainerInstance = p.get<std::string>("InputNonContainerInstance");
fOutputInstance = p.get<std::string>("OutputInstance");
fDebugLevel = p.get<int>("DebugLevel",0);

produces<std::vector<raw::ptb::sbndptb> >(fOutputInstance);
}

void SBNDPTBDecoder::produce(art::Event & evt)
{


// look first for container fragments and then non-container fragments

std::vector<raw::ptb::sbndptb> sbndptbs;

art::InputTag itag1(fInputLabel, fInputContainerInstance);
auto cont_frags = evt.getHandle<artdaq::Fragments>(itag1);
if (cont_frags)
{
for (auto const& cont : *cont_frags)
{
artdaq::ContainerFragment cont_frag(cont);
for (size_t ii = 0; ii < cont_frag.block_count(); ++ii)
{
ptbsv_t sout; // output structures
_process_PTB_AUX(*cont_frag[ii], sout);
raw::ptb::sbndptb ptbdp(sout.HLTrigs,sout.LLTrigs,sout.ChStats,sout.Feedbacks,sout.Miscs,sout.WordIndexes);
sbndptbs.push_back(ptbdp);
}
}
}

art::InputTag itag2(fInputLabel, fInputNonContainerInstance);
auto frags = evt.getHandle<artdaq::Fragments>(itag2);
if (frags)
{
for(auto const& frag: *frags)
{
ptbsv_t sout; // output structures
_process_PTB_AUX(frag, sout);
raw::ptb::sbndptb ptbdp(sout.HLTrigs,sout.LLTrigs,sout.ChStats,sout.Feedbacks,sout.Miscs,sout.WordIndexes);
sbndptbs.push_back(ptbdp);
}
}

evt.put(std::make_unique<std::vector<raw::ptb::sbndptb>>(std::move(sbndptbs)),fOutputInstance);
}

void SBNDPTBDecoder::_process_PTB_AUX(const artdaq::Fragment& frag, ptbsv_t &sout)
{
sbndaq::CTBFragment ctbfrag(frag); // somehow the name CTBFragment stuck

// use the same logic in sbndaq-artdaq-core/Overlays/SBND/PTBFragment.cc: operator<<
// but separate out the HLTs and LLTs
if (fDebugLevel > 0)
{
std::cout << "SBNDPTBDecoder_module: got into aux" << std::endl;
}

for (size_t iword = 0; iword < ctbfrag.NWords(); ++iword)
{
if (fDebugLevel > 0)
{
std::cout << "SBNDPTBDecoder_module: start processing word: " << iword << std::endl;
}
size_t ix=0;
uint32_t wt = 0;
if (ctbfrag.Trigger(iword))
{
raw::ptb::Trigger tstruct;
tstruct.word_type = ctbfrag.Trigger(iword)->word_type;
wt = tstruct.word_type;
tstruct.trigger_word = ctbfrag.Trigger(iword)->trigger_word;
tstruct.timestamp = ctbfrag.Trigger(iword)->timestamp;
if (ctbfrag.Trigger(iword)->IsHLT())
{
ix = sout.HLTrigs.size();
sout.HLTrigs.push_back(tstruct);
if (fDebugLevel > 0)
{
std::cout << "SBNDPTBDecoder_module: found HLT: " << wt << " " << ix << std::endl;
}
}
else if (ctbfrag.Trigger(iword)->IsLLT())
{
ix = sout.LLTrigs.size();
sout.LLTrigs.push_back(tstruct);
if (fDebugLevel > 0)
{
std::cout << "SBNDPTBDecoder_module: found LLT: " << wt << " " << ix << std::endl;
}
}
}
else if (ctbfrag.ChStatus(iword))
{
raw::ptb::ChStatus cstruct;
cstruct.timestamp = ctbfrag.ChStatus(iword)->timestamp;
cstruct.beam = ctbfrag.ChStatus(iword)->beam;
cstruct.crt = ctbfrag.ChStatus(iword)->crt;
cstruct.pds = ctbfrag.ChStatus(iword)->pds;
cstruct.mtca = ctbfrag.ChStatus(iword)->mtca;
cstruct.nim = ctbfrag.ChStatus(iword)->nim;
cstruct.auxpds = ctbfrag.ChStatus(iword)->auxpds;
cstruct.word_type = ctbfrag.ChStatus(iword)->word_type;
wt = cstruct.word_type;
ix = sout.ChStats.size();
sout.ChStats.push_back(cstruct);
if (fDebugLevel > 0)
{
std::cout << "SBNDPTBDecoder_module: found CHStat: " << wt << " " << ix << std::endl;
}
}
else if (ctbfrag.Feedback(iword))
{
raw::ptb::Feedback fstruct;
fstruct.timestamp = ctbfrag.Feedback(iword)->timestamp;
fstruct.code = ctbfrag.Feedback(iword)->code;
fstruct.source = ctbfrag.Feedback(iword)->source;
fstruct.payload = ctbfrag.Feedback(iword)->payload; // broken in two in Tereza's version
fstruct.word_type = ctbfrag.Feedback(iword)->word_type;
wt = fstruct.word_type;
ix = sout.Feedbacks.size();
sout.Feedbacks.push_back(fstruct);
if (fDebugLevel > 0)
{
std::cout << "SBNDPTBDecoder_module: found Feedback: " << wt << " " << ix << std::endl;
}
}
else
{
raw::ptb::Misc mstruct;
mstruct.timestamp = ctbfrag.Word(iword)->timestamp;
mstruct.payload = ctbfrag.Word(iword)->payload;
mstruct.word_type = ctbfrag.Word(iword)->word_type;
wt = mstruct.word_type;
ix = sout.Miscs.size();
sout.Miscs.push_back(mstruct);
if (fDebugLevel > 0)
{
std::cout << "SBNDPTBDecoder_module: found Misc: " << wt << " " << ix << std::endl;
}
}

raw::ptb::WordIndex wstruct;
wstruct.word_type = wt;
wstruct.index = ix;
sout.WordIndexes.push_back(wstruct);
if (fDebugLevel > 0)
{
std::cout << "SBNDPTBDecoder_module: index calc: " << wt << " " << ix << std::endl;
}
}
}


DEFINE_ART_MODULE(SBNDPTBDecoder)
67 changes: 67 additions & 0 deletions sbndcode/Decoders/PTB/SBNDPTBRawUtils.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/// \file SBNDPTBRawUtils.cxx
/// \brief SBND PTB raw data utilities
/// \author [email protected]

#include "SBNDPTBRawUtils.h"
#include "sbndaq-artdaq-core/Overlays/SBND/PTB_content.h"

namespace raw {
namespace ptb {
const std::vector<raw::ptb::ChStatus> GetChStatusBeforeHLTs(const raw::ptb::sbndptb &pdata)
{
std::vector<raw::ptb::ChStatus> chs;
raw::ptb::ChStatus emptychstat;
emptychstat.timestamp = 0;
emptychstat.beam = 0;
emptychstat.crt = 0;
emptychstat.pds = 0;
emptychstat.mtca = 0;
emptychstat.nim = 0;
emptychstat.auxpds = 0;
emptychstat.word_type = 0;

// Find the last CHStatus before each HLT

const auto &hlts = pdata.GetHLTriggers();
const auto &idxs = pdata.GetIndexes();
const auto &chst = pdata.GetChStatuses();

for (size_t i=0; i<hlts.size(); ++i)
{
for (size_t j=0; j<idxs.size(); ++j)
{
if (idxs.at(j).word_type == (uint32_t) ::ptb::content::word::t_gt && idxs.at(j).index == i)
{
size_t kstatindex = j;
if (kstatindex > 0)
{
kstatindex --; // it's the word before the HLT that has the chstat
if (idxs.at(kstatindex).word_type == (uint32_t) ::ptb::content::word::t_ch)
{
size_t kstat = idxs.at(kstatindex).index;

if (kstat < chst.size())
{
chs.push_back(chst.at(kstat));
}
else
{
chs.push_back(emptychstat);
}
}
else
{
chs.push_back(emptychstat);
}
}
else
{
chs.push_back(emptychstat);
}
}
}
}
return chs;
}
}
}
18 changes: 18 additions & 0 deletions sbndcode/Decoders/PTB/SBNDPTBRawUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/// \file SBNDPTBRawUtils.h
/// \brief Standalone C++ methods to interact with the sbndptb data product, separated from
/// the data product defintion itself so ROOT can persist it
/// \author [email protected]

#ifndef SBNDPTBRawUtils_H
#define SBNDPTBRawUtils_H

#include "sbndcode/Decoders/PTB/sbndptb.h"
#include "sbndaq-artdaq-core/Overlays/SBND/PTB_content.h"

namespace raw {
namespace ptb {
const std::vector<raw::ptb::ChStatus> GetChStatusBeforeHLTs(const raw::ptb::sbndptb &pdata);
}
}

#endif
10 changes: 10 additions & 0 deletions sbndcode/Decoders/PTB/classes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//File: classes.h
//Brief: Include directives needed to generate header(s) for the raw::ptb::sbndptb data product.
//Author: Tom Junk

//ART includes
#include "canvas/Persistency/Common/Wrapper.h"
#include "canvas/Persistency/Common/Assns.h"

//local includes
#include "sbndcode/Decoders/PTB/sbndptb.h"
Loading