Skip to content
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ add_library(packing SHARED
src/pflib/packing/SingleROCEventPacket.cxx
src/pflib/packing/ECONDEventPacket.cxx
src/pflib/packing/MultiSampleECONDEventPacket.cxx
src/pflib/packing/SoftWrappedECONDEventPacket.cxx
)
target_include_directories(packing PUBLIC
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
Expand Down
2 changes: 1 addition & 1 deletion ana/pedestal/violinplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

if args.output is None:
if len(args.pedestals) == 1:
args.output = args.pedestals.parent / (args.pedestals.stem + '-violinplot.png')
args.output = args.pedestals[0].parent / (args.pedestals[0].stem + '-violinplot.png')
else:
args.output = 'violinplot.png'

Expand Down
8 changes: 3 additions & 5 deletions app/econd_decoder.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include "pflib/Logging.h"
#include "pflib/packing/FileReader.h"
#include "pflib/packing/Hex.h"
#include "pflib/packing/MultiSampleECONDEventPacket.h"
#include "pflib/packing/SoftWrappedECONDEventPacket.h"
#include "pflib/version/Version.h"

static void usage() {
Expand Down Expand Up @@ -145,7 +145,7 @@ int main(int argc, char* argv[]) {
o << std::boolalpha;
o << pflib::packing::ECONDEventPacket::to_csv_header << '\n';

pflib::packing::MultiSampleECONDEventPacket ep(n_links);
pflib::packing::SoftWrappedECONDEventPacket ep(n_links);
// count is NOT written into output file,
// we use the event number from the links
// this is just to allow users to limit the number of entries in
Expand All @@ -157,9 +157,7 @@ int main(int argc, char* argv[]) {
r >> ep;
pflib_log(debug) << "r.eof(): " << std::boolalpha << r.eof()
<< " and bool(r): " << bool(r);
for (const auto& sample : ep.samples) {
sample.to_csv(o);
}
ep.data.to_csv(o);
count++;
if (nevents > 0 and count >= nevents) {
break;
Expand Down
8 changes: 7 additions & 1 deletion app/tool/algorithm/level_pedestals.cxx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "level_pedestals.h"

#include "../daq_run.h"
#include "../tasks/level_pedestals.h"
#include "pflib/utility/median.h"
#include "pflib/utility/string_format.h"

Expand Down Expand Up @@ -42,7 +43,12 @@ std::map<std::string, std::map<std::string, uint64_t>> level_pedestals(
/// do three runs of 100 samples each to have well defined pedestals
static const std::size_t n_events = 100;

tgt->setup_run(1, Target::DaqFormat::SIMPLEROC, 1);
// tgt->setup_run(1, Target::DaqFormat::SIMPLEROC, 1);
// Use the DAQ format selected in the pftool DAQ->FORMAT menu so the
// format mode can be chosen interactively by the user.
tgt->setup_run(1, pftool::state.daq_format_mode, 1);
pflib_log(info) << "Using DAQ format mode: "
<< static_cast<int>(pftool::state.daq_format_mode);

std::array<int, 2> target;
std::array<int, 72> baseline, highend, lowend;
Expand Down
38 changes: 36 additions & 2 deletions app/tool/daq.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,42 @@ static void daq(const std::string& cmd, Target* pft) {
pftool::readline_bool("Should we decode the packet into CSV?", true);

if (decoding) {
DecodeAndWriteToCSV writer{all_channels_to_csv(fname + ".csv")};
daq_run(pft, cmd, writer, nevents, pftool::state.daq_rate);
std::unique_ptr<DaqRunConsumer> consumer;
switch (pftool::state.daq_format_mode) {
case Target::DaqFormat::ECOND_SW_HEADERS:
consumer = std::make_unique<
DecodeAndWriteToCSV<pflib::packing::SoftWrappedECONDEventPacket>>(
fname + ".csv",
[](std::ofstream& f) {
f << std::boolalpha;
f << pflib::packing::SoftWrappedECONDEventPacket::to_csv_header
<< '\n';
},
[](std::ofstream& f,
const pflib::packing::SoftWrappedECONDEventPacket& ep) {
ep.to_csv(f);
});
break;
case Target::DaqFormat::SIMPLEROC:
consumer = std::make_unique<
DecodeAndWriteToCSV<pflib::packing::SingleROCEventPacket>>(
fname + ".csv",
[](std::ofstream& f) {
f << std::boolalpha;
f << pflib::packing::SingleROCEventPacket::to_csv_header
<< '\n';
},
[](std::ofstream& f,
const pflib::packing::SingleROCEventPacket& ep) {
ep.to_csv(f);
});
break;
default:
PFEXCEPTION_RAISE("BadConf",
"Unable to do live decoding for the currently "
"configured format.");
}
daq_run(pft, cmd, *consumer, nevents, pftool::state.daq_rate);
} else {
WriteToBinaryFile writer{fname + ".raw"};
daq_run(pft, cmd, writer, nevents, pftool::state.daq_rate);
Expand Down
51 changes: 30 additions & 21 deletions app/tool/daq_run.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ void WriteToBinaryFile::consume(std::vector<uint32_t>& event) {
fwrite(&(event[0]), sizeof(uint32_t), event.size(), fp_);
}

void DecodeAndWrite::consume(std::vector<uint32_t>& event) {
template <class EventPacket>
void DecodeAndWrite<EventPacket>::consume(std::vector<uint32_t>& event) {
// we have to manually check the size so that we can do the reinterpret_cast
if (event.size() == 0) {
pflib_log(warn) << "event with zero words passed in, skipping";
Expand All @@ -91,43 +92,46 @@ void DecodeAndWrite::consume(std::vector<uint32_t>& event) {
write_event(ep_);
}

DecodeAndWriteToCSV::DecodeAndWriteToCSV(
template <class EventPacket>
DecodeAndWriteToCSV<EventPacket>::DecodeAndWriteToCSV<EventPacket>(
const std::string& file_name,
std::function<void(std::ofstream&)> write_header,
std::function<void(std::ofstream& f,
const pflib::packing::SingleROCEventPacket&)>
write_event)
: DecodeAndWrite(), file_{file_name}, write_event_{write_event} {
std::function<void(std::ofstream& f, const EventPacket&)> write_event)
: DecodeAndWrite<EventPacket>(),
file_{file_name},
write_event_{write_event} {
if (not file_) {
PFEXCEPTION_RAISE("FileOpen",
"unable to open " + file_name + " for writing");
}
write_header(file_);
}

void DecodeAndWriteToCSV::write_event(
const pflib::packing::SingleROCEventPacket& ep) {
template <class EventPacket>
void DecodeAndWriteToCSV<EventPacket>::write_event(const EventPacket& ep) {
write_event_(file_, ep);
}

DecodeAndWriteToCSV all_channels_to_csv(const std::string& file_name) {
return DecodeAndWriteToCSV(
template <class EventPacket>
DecodeAndWriteToCSV<EventPacket> all_channels_to_csv(
const std::string& file_name) {
return DecodeAndWriteToCSV<EventPacket>(
file_name,
[](std::ofstream& f) {
f << std::boolalpha;
f << pflib::packing::SingleROCEventPacket::to_csv_header << '\n';
f << EventPacket::to_csv_header << '\n';
},
[](std::ofstream& f, const pflib::packing::SingleROCEventPacket& ep) {
ep.to_csv(f);
});
[](std::ofstream& f, const EventPacket& ep) { ep.to_csv(f); });
}

DecodeAndBuffer::DecodeAndBuffer(int nevents) : DecodeAndWrite() {
template <class EventPacket>
DecodeAndBuffer<EventPacket>::DecodeAndBuffer<EventPacket>(int nevents)
: DecodeAndWrite<EventPacket>() {
set_buffer_size(nevents);
}

void DecodeAndBuffer::write_event(
const pflib::packing::SingleROCEventPacket& ep) {
template <class EventPacket>
void DecodeAndBuffer<EventPacket>::write_event(const EventPacket& ep) {
if (ep_buffer_.size() > ep_buffer_.capacity()) {
pflib_log(warn) << "Trying to push more elements to buffer than allocated "
"capacity. Skipping!";
Expand All @@ -136,13 +140,18 @@ void DecodeAndBuffer::write_event(
ep_buffer_.push_back(ep);
}

void DecodeAndBuffer::start_run() { ep_buffer_.clear(); }
template <class EventPacket>
void DecodeAndBuffer<EventPacket>::start_run() {
ep_buffer_.clear();
}

const std::vector<pflib::packing::SingleROCEventPacket>&
DecodeAndBuffer::get_buffer() const {
template <class EventPacket>
const std::vector<EventPacket>& DecodeAndBuffer<EventPacket>::get_buffer()
const {
return ep_buffer_;
}

void DecodeAndBuffer::set_buffer_size(int nevents) {
template <class EventPacket>
void DecodeAndBuffer<EventPacket>::set_buffer_size(int nevents) {
ep_buffer_.reserve(nevents);
}
33 changes: 16 additions & 17 deletions app/tool/daq_run.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class WriteToBinaryFile : public DAQRunConsumer {
* other code just needs to write functions that define how the
* decoded data should be written out.
*/
template <class EventPacket>
class DecodeAndWrite : public DAQRunConsumer {
public:
virtual ~DecodeAndWrite() = default;
Expand All @@ -65,43 +66,41 @@ class DecodeAndWrite : public DAQRunConsumer {
virtual void consume(std::vector<uint32_t>& event) final;

/// pure virtual function for writing out decoded event
virtual void write_event(const pflib::packing::SingleROCEventPacket& ep) = 0;
virtual void write_event(const EventPacket& ep) = 0;

protected:
/// logging for warning messages on empty events
mutable ::pflib::logging::logger the_log_;

private:
/// event packet for decoding
pflib::packing::SingleROCEventPacket ep_;
EventPacket ep_;
};

/**
* specializatin of DecodeAndWrite that holds a std::ofstream
* for the user with functions for writing the header and events
*/
class DecodeAndWriteToCSV : public DecodeAndWrite {
template <class EventPacket>
class DecodeAndWriteToCSV : public DecodeAndWrite<EventPacket> {
/// output file writing to
std::ofstream file_;
/// function that writes row(s) to csv given an event
std::function<void(std::ofstream&,
const pflib::packing::SingleROCEventPacket&)>
write_event_;
std::function<void(std::ofstream&, const EventPacket&)> write_event_;

public:
DecodeAndWriteToCSV(
const std::string& file_name,
std::function<void(std::ofstream&)> write_header,
std::function<void(std::ofstream&,
const pflib::packing::SingleROCEventPacket&)>
write_event);
std::function<void(std::ofstream&, EventPacket&)> write_event);
virtual ~DecodeAndWriteToCSV() = default;
/// call write_event with our file handle
virtual void write_event(
const pflib::packing::SingleROCEventPacket& ep) final;
virtual void write_event(const EventPacket& ep) final;
};

DecodeAndWriteToCSV all_channels_to_csv(const std::string& file_name);
template <class EventPacket>
DecodeAndWriteToCSV<EventPacket> all_channels_to_csv(
const std::string& file_name);

/**
* Consume an event packet, decode it, and save to buffer.
Expand All @@ -119,21 +118,21 @@ DecodeAndWriteToCSV all_channels_to_csv(const std::string& file_name);
* const auto& events{buffer.get_buffer()};
* ```
*/
class DecodeAndBuffer : public DecodeAndWrite {
template <typename EventPacket>
class DecodeAndBuffer : public DecodeAndWrite<EventPacket> {
public:
DecodeAndBuffer(int nevents);
virtual ~DecodeAndBuffer() = default;
/// get buffer
const std::vector<pflib::packing::SingleROCEventPacket>& get_buffer() const;
const std::vector<EventPacket>& get_buffer() const;
/// Set the buffer size
void set_buffer_size(int nevents);
/// Save to buffer
virtual void write_event(
const pflib::packing::SingleROCEventPacket& ep) override;
virtual void write_event(const EventPacket& ep) override;
/// Check that the buffer was read and flushed since last run
virtual void start_run() override;

private:
/// Buffer for event packets
std::vector<pflib::packing::SingleROCEventPacket> ep_buffer_;
std::vector<EventPacket> ep_buffer_;
};
44 changes: 44 additions & 0 deletions include/pflib/packing/SoftWrappedECONDEventPacket.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#pragma once

#include "pflib/packing/ECONDEventPacket.h"
#include "pflib/packing/Reader.h"

namespace pflib::packing {

/**
* Unpack an event packet that includes an extra header inserted by
* the software
*
* @see ECONDEventPacket for how a single sample from a single ECOND
* is unpacked.
*/
class SoftWrappedECONDEventPacket {
/// handle to logging source
mutable ::pflib::logging::logger the_log_{::pflib::logging::get("decoding")};

public:
/// provide number of links (eRx) on the ECOND
SoftWrappedECONDEventPacket(std::size_t n_links);
/**
* Corruption bits
*
* Index | Description
* ------|------------
* 0 | sw header version mismatch
*/
std::array<bool, 1> corruption;
/// L1A index for this packet
int il1a;
/// ID specifying ECOND we are reading
int econ_id;
/// whether this packet is the sample-of-interest
bool is_soi;
/// actual data packet from ECOND
ECONDEventPacket data;
/// unpack the given data into this structure
void from(std::span<uint32_t> frame);
/// read into this structure from the input Reader
Reader& read(Reader& r);
};

} // namespace pflib::packing
6 changes: 5 additions & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,13 @@ hexdump *args:
hexdump -v -e '1/4 "%08x" "\n"' {{ args }}

# run the decoder
decode *args:
pfdecoder *args:
denv ./build/pfdecoder {{ args }}

# run the econd-decoder
econd-decoder *args:
denv ./build/econd-decoder {{ args }}

# open the test menu
test-menu:
denv ./build/test-menu
Loading