Skip to content
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
5 changes: 3 additions & 2 deletions app/tool/bias.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ static void bias(const std::string& cmd, pflib::HcalTarget* pft) {
double temp = bias.readTemp();
std::cout << "Board temperature: " << temp << " C" << std::endl;
for (int ch = 0; ch < 16; ch++) {
std::cout << "Channel " << std::setw(2) << ch << " SiPM DAC " << bias.readSiPM(ch)
<< " LED DAC " << bias.readLED(ch) << std::endl;
std::cout << "Channel " << std::setw(2) << ch << " SiPM DAC "
<< bias.readSiPM(ch) << " LED DAC " << bias.readLED(ch)
<< std::endl;
}
}
if (cmd == "READ_SIPM") {
Expand Down
48 changes: 48 additions & 0 deletions include/pflib/packing/DecompressAEBM.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#pragma once
#ifndef PFLIB_PACKING_DECODEAEBM_H
#define PFLIB_PACKING_DECODEAEBM_H

#include "pflib/packing/Mask.h"

namespace pflib::packing {

/**
* Generically decompress AE+BM encoding
*
* AE+BM stands for A bits of exponnent and B bits for a
* mantissa giving a total compressed size of A+B bits.
* At time of writing, we've seen two copies of this
* encoding: The ROC's Trigger Cells use 4E+3M and the
* ECON-T's Super Trigger Cells use 5E+4M.
*
* This decompression assembles the encoded value assigning
* the B least significant bits to be the mantissa value
* and the A most significant bits to be the exponent.
*
* `unsigned long` is used to manipulate the integers to avoid
* size issues, use `static_cast` to intentially cut the return
* value down to a smaller size if desired.
*
* @tparam A number of bits for the exponent
* @tparam B number of bits for the mantissa
* @param[in] encoded compressed value to decompress
* @return decompressed value
*/
template <unsigned short A, unsigned short B>
unsigned long decompressAEBM(unsigned long encoded) {
static_assert(A + B < 12); // arbitrary limit to avoid typos
unsigned long mantissa = (encoded & mask<B>);
unsigned long exponent = ((encoded >> B) & mask<A>);
if (exponent == 0) {
return mantissa;
}
unsigned long output = (((1 << B) | mantissa) << (exponent - 1));
if (exponent > 1) {
output |= (1 << (exponent - 2));
}
return output;
}

} // namespace pflib::packing

#endif
6 changes: 6 additions & 0 deletions include/pflib/packing/SingleECONTCaptureFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,13 @@ class SingleECONTCaptureFrame {

public:
void from(std::span<uint32_t> data);
/// bx counter for this sample of STC sums
int bx() const;
/// decode the 5E+4M encoding into a linearized sum value
int stc_sum(int i_stc) const;
/// the raw value trasmitted by the ECON-T
int encoded_stc_sum(int i_stc) const;
/// index of the TC within the STC that was the maximum
int max_tc(int i_stc) const;
};

Expand All @@ -71,6 +76,7 @@ class SingleECONTCaptureFrame {
const SingleECONTSample& sample(std::optional<int> i_sample = {}) const;
int bx(std::optional<int> i_sample = {}) const;
int stc_sum(int i_stc, std::optional<int> i_sample = {}) const;
int encoded_stc_sum(int i_stc, std::optional<int> i_sample = {}) const;
int max_tc(int i_stc, std::optional<int> i_sample = {}) const;
const ECONTCaptureHeader& header() const;
int length() const;
Expand Down
4 changes: 2 additions & 2 deletions include/pflib/packing/TriggerLinkFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ struct TriggerLinkFrame {
* Convert a compressed trigger sum into its linearized equivalent
*
* The chip lossy compresses its trigger sums into seven bits
* and this function decompresses the sum into our best estimate
* of what the on-chip trigger sum was.
* using the 4E+3M encoding and this function decompresses the
* sum into our best estimate of what the on-chip trigger sum was.
*
* @note This function undoes the wacky compression algorithm, but
* the scale of the linearized sum is not quite correct.
Expand Down
34 changes: 24 additions & 10 deletions src/pflib/packing/SingleECONTCaptureFrame.cxx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include "pflib/packing/SingleECONTCaptureFrame.h"

#include "pflib/packing/DecompressAEBM.h"
#include "pflib/packing/Mask.h"

namespace pflib::packing {
void SingleECONTCaptureFrame::SingleECONTSample::from(
std::span<uint32_t> data) {
Expand All @@ -9,27 +12,33 @@ void SingleECONTCaptureFrame::SingleECONTSample::from(
<< data.size();
return;
}
bx_ = ((data[0] >> 28) & 0xf);
bx_ = ((data[0] >> 28) & mask<4>);
for (int i{0}; i < N_STC; i++) {
// max is all within the first 32b word even if there
// are more eTx
max_tc_[i] = ((data[0] >> (26 - 2 * i)) & 0x3);
max_tc_[i] = ((data[0] >> (26 - 2 * i)) & mask<2>);
}

// just hardcoding 3 eTx for now
stc_sums_[0] = ((data[0] >> 2) & 0x1ff);
stc_sums_[1] = (((data[0] & 0x11) << 7) | ((data[1] >> 25) & 0x7f));
stc_sums_[2] = ((data[1] >> 16) & 0x1ff);
stc_sums_[3] = ((data[1] >> 7) & 0x1ff);
stc_sums_[4] = (((data[1] & 0x7f) << 2) | ((data[2] >> 30) & 0x3));
stc_sums_[5] = ((data[2] >> 21) & 0x1ff);
stc_sums_[6] = ((data[2] >> 12) & 0x1ff);
stc_sums_[7] = ((data[2] >> 3) & 0x1ff);
stc_sums_[0] = ((data[0] >> 3) & mask<9>);
stc_sums_[1] =
(((data[0] & mask<3>) << 6) | ((data[1] >> (32 - 6)) & mask<6>));
stc_sums_[2] = ((data[1] >> 17) & mask<9>);
stc_sums_[3] = ((data[1] >> 8) & mask<9>);
stc_sums_[4] = (((data[1] & mask<8>) << 1) | ((data[2] >> 31) & mask<1>));
stc_sums_[5] = ((data[2] >> 22) & mask<9>);
stc_sums_[6] = ((data[2] >> 13) & mask<9>);
stc_sums_[7] = ((data[2] >> 4) & mask<9>);
}

int SingleECONTCaptureFrame::SingleECONTSample::bx() const { return bx_; }

int SingleECONTCaptureFrame::SingleECONTSample::stc_sum(int i_stc) const {
return decompressAEBM<5, 4>(encoded_stc_sum(i_stc));
}

int SingleECONTCaptureFrame::SingleECONTSample::encoded_stc_sum(
int i_stc) const {
return stc_sums_.at(i_stc);
}

Expand Down Expand Up @@ -96,6 +105,11 @@ int SingleECONTCaptureFrame::bx(std::optional<int> i_sample) const {
return sample(i_sample).bx();
}

int SingleECONTCaptureFrame::encoded_stc_sum(
int i_stc, std::optional<int> i_sample) const {
return sample(i_sample).encoded_stc_sum(i_stc);
}

int SingleECONTCaptureFrame::stc_sum(int i_stc,
std::optional<int> i_sample) const {
return sample(i_sample).stc_sum(i_stc);
Expand Down
9 changes: 2 additions & 7 deletions src/pflib/packing/TriggerLinkFrame.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,13 @@
#include <iostream>

#include "pflib/Exception.h"
#include "pflib/packing/DecompressAEBM.h"
#include "pflib/packing/Mask.h"

namespace pflib::packing {

uint32_t TriggerLinkFrame::compressed_to_linearized(uint8_t cs) {
auto pos = (cs >> 3) & 0xf;
if (pos < 1) {
// no position stored (i.e. compressed value is < 8)
// linearized sum is sum stored as compressed
return cs;
}
return (((1 << 3) + (cs & 0b111)) << (pos + 2 - 3));
return static_cast<uint32_t>(decompressAEBM<4, 3>(cs));
}

void TriggerLinkFrame::from(std::span<uint32_t> data) {
Expand Down
42 changes: 40 additions & 2 deletions test/decoding.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@

#include "pflib/Exception.h"
#include "pflib/packing/DAQLinkFrame.h"
#include "pflib/packing/DecompressAEBM.h"
#include "pflib/packing/ECONDEventPacket.h"
#include "pflib/packing/ECONDFormatter.h"
#include "pflib/packing/Hex.h"
#include "pflib/packing/Mask.h"
#include "pflib/packing/Sample.h"
#include "pflib/packing/SingleECONTCaptureFrame.h"
#include "pflib/packing/TriggerLinkFrame.h"

int decode5E4M(int w) { return pflib::packing::decompressAEBM<5, 4>(w); }

std::vector<uint32_t> gen_test_daq_link_frame() {
std::vector<uint32_t> test_frame = {
0xf00c26a5, // daq header
Expand Down Expand Up @@ -230,7 +234,7 @@ BOOST_AUTO_TEST_SUITE(trigger)

BOOST_AUTO_TEST_CASE(example_decompression) {
uint8_t compressed = 0b0100111;
uint32_t decomp = 0b1111000;
uint32_t decomp = 0b1111100;
BOOST_CHECK_EQUAL(
decomp,
pflib::packing::TriggerLinkFrame::compressed_to_linearized(compressed));
Expand All @@ -248,7 +252,7 @@ BOOST_AUTO_TEST_CASE(decompress_small) {

BOOST_AUTO_TEST_CASE(decompress_large) {
uint8_t compressed = 0b1111011;
uint32_t decomp = 0b101100000000000000;
uint32_t decomp = 0b101110000000000000;
BOOST_CHECK_EQUAL(
decomp,
pflib::packing::TriggerLinkFrame::compressed_to_linearized(compressed));
Expand Down Expand Up @@ -570,4 +574,38 @@ BOOST_AUTO_TEST_CASE(roundtrip_with_formatter) {

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE(econt)

BOOST_AUTO_TEST_CASE(single_sample) {
using pflib::packing::SingleECONTCaptureFrame;
std::vector<uint32_t> words = {0x40005020, 0x10080444, 0xa2d148b0};
SingleECONTCaptureFrame::SingleECONTSample sample;
sample.from(words);
BOOST_CHECK_EQUAL(sample.bx(), 4);
BOOST_CHECK_EQUAL(sample.max_tc(0), 0);
BOOST_CHECK_EQUAL(sample.max_tc(1), 0);
BOOST_CHECK_EQUAL(sample.max_tc(2), 0);
BOOST_CHECK_EQUAL(sample.max_tc(3), 0);
BOOST_CHECK_EQUAL(sample.max_tc(4), 0);
BOOST_CHECK_EQUAL(sample.max_tc(5), 0);
BOOST_CHECK_EQUAL(sample.max_tc(6), 1);
BOOST_CHECK_EQUAL(sample.max_tc(7), 1);
BOOST_CHECK_EQUAL(sample.encoded_stc_sum(0), 0b000000100);
BOOST_CHECK_EQUAL(sample.encoded_stc_sum(1), 0b000000100);
BOOST_CHECK_EQUAL(sample.encoded_stc_sum(2), 0b000000100);
BOOST_CHECK_EQUAL(sample.encoded_stc_sum(3), 0b000000100);
BOOST_CHECK_EQUAL(sample.encoded_stc_sum(4), 0b010001001);
BOOST_CHECK_EQUAL(sample.encoded_stc_sum(5), 0b010001011);
BOOST_CHECK_EQUAL(sample.encoded_stc_sum(6), 0b010001010);
BOOST_CHECK_EQUAL(sample.encoded_stc_sum(7), 0b010001011);
}

BOOST_AUTO_TEST_CASE(decode_5E4M) {
BOOST_CHECK_EQUAL(decode5E4M(0), 0);
BOOST_CHECK_EQUAL(decode5E4M(7), 7);
BOOST_CHECK_EQUAL(decode5E4M(0b010001001), 0b110011000000);
}

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE_END()
Loading