readoutspeed in rx master file and other master file inconsistencies (#1245)

readout speed added to json and h5 master files.
Also fixed master file inconsistencies

Sserver binaries
- update server binaries because readoutspeed needs to be sent to receiver with rx_hostname command

API
- added const to Detector class set/getburstmode

Python
- updated python bindings (burstmode const and roi arguments)

Cmd generation
- added pragma once in Caller.in.h as Caller is included in test files

m3: num channels due to #counters < 3
* workaround for m3 for messed up num channels (client always assumes all counters enabled and adds them to num channels), fix for hdf5

g2: exptime master file inconsistency
- exptime didnt match because of round of when setting burst mode (sets to a different clk divider)
- so updating actual time for all timers (exptime, period, subexptime etc, )  in Module class, get timer values from detector when setting it and then send to receiver to write in master file

ctb image size incorrect:
-  write actual size into master file and not the reserved size (digital reduces depending on dbit list and dbit offset)
- added a calculate ctb image size free function in generalData.h that is used there as well as for the tests.


master file inconsistencies
- refactored master attributes writing using templates
-    names changed to keep it consistent between json and hdf5 master file (Version, Pixels, Exposure Times, GateDelays, Acquisition Period, etc.)
-  datatypes changed to keep it simple where possible: imageSize, dynamicRange, tengiga, quad, readnrows, analog, analogsamples, digital, digitalsamples, dbitreorder, dbitoffset, transceivermask, transeiver, transceiversamples, countermask, gates =>int
- replacing "toString" with arrays, objects etc for eg for scan, rois, etc.
- json header always written (empty dataset or empty brackets)
- hdf5 needs const char* so have to convert strings to it, but taking care that strings exist prior to push_back
- master attributes (redundant string literals->error prone

tests for master file
- suppressed deprecated functions in rapidjson warnings just for the tests
- added slsREceiverSoftware/src to allow access to receiver_defs.h to test binary/hdf5 version
- refactored acquire tests by moving all the acquire tests from individual detector type files to a single one=test-Caller-acquire.cpp
- set some default settings (loadBasicSettings) for a basic acquire at load config part for the test_simulator python scripts. so minimum number of settings for detector to be set for any acquire tests.
- added tests to test master files for json and hdf5= test-Caller-master-attributes.cpp
- added option to add '-m' markers for tests using test_simulator python script
This commit is contained in:
2025-07-25 11:45:26 +02:00
committed by GitHub
parent 047793766a
commit ee27f0bc1b
43 changed files with 3016 additions and 1518 deletions

View File

@@ -221,7 +221,7 @@ int ClientInterface::functionTable(){
flist[F_GET_RECEIVER_DBIT_REORDER] = &ClientInterface::get_dbit_reorder;
flist[F_SET_RECEIVER_DBIT_REORDER] = &ClientInterface::set_dbit_reorder;
flist[F_RECEIVER_GET_ROI_METADATA] = &ClientInterface::get_roi_metadata;
flist[F_SET_RECEIVER_READOUT_SPEED] = &ClientInterface::set_readout_speed;
for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) {
LOG(logDEBUG1) << "function fnum: " << i << " (" <<
@@ -411,6 +411,8 @@ int ClientInterface::setup_receiver(Interface &socket) {
impl()->setReadoutMode(arg.roMode);
impl()->setTenGigaADCEnableMask(arg.adc10gMask);
impl()->setTransceiverEnableMask(arg.transceiverMask);
} else {
impl()->setReadoutSpeed(arg.readoutSpeed);
}
if (detType == CHIPTESTBOARD) {
impl()->setADCEnableMask(arg.adcMask);
@@ -1851,4 +1853,33 @@ int ClientInterface::get_roi_metadata(Interface &socket) {
return OK;
}
int ClientInterface::set_readout_speed(Interface &socket) {
auto value = socket.Receive<int>();
verifyIdle(socket);
switch (detType) {
case GOTTHARD2:
if (value != G2_108MHZ && value != G2_144MHZ)
throw RuntimeError("Invalid readout speed for GOTTHARD2: " +
std::to_string(value));
break;
case EIGER:
case JUNGFRAU:
case MYTHEN3:
case MOENCH:
if (value < 0 || value > QUARTER_SPEED) {
throw RuntimeError("Invalid readout speed: " +
std::to_string(value));
}
break;
default:
functionNotImplemented();
}
LOG(logDEBUG1) << "Setting readout speed to " << value;
impl()->setReadoutSpeed(static_cast<speedLevel>(value));
return socket.Send(OK);
}
} // namespace sls

View File

@@ -167,6 +167,7 @@ class ClientInterface : private virtual slsDetectorDefs {
int get_dbit_reorder(ServerInterface &socket);
int set_dbit_reorder(ServerInterface &socket);
int get_roi_metadata(ServerInterface &socket);
int set_readout_speed(ServerInterface &socket);
Implementation *impl() {
if (receiver != nullptr) {

View File

@@ -18,6 +18,110 @@
namespace sls {
struct CtbImageInputs {
slsDetectorDefs::readoutMode mode{slsDetectorDefs::ANALOG_ONLY};
int nAnalogSamples{};
uint32_t adcMask{};
int nTransceiverSamples{};
uint32_t transceiverMask{};
int nDigitalSamples{};
int dbitOffset{};
bool dbitReorder{};
std::vector<int> dbitList{};
};
struct CtbImageOutputs {
int nAnalogBytes{};
int nDigitalBytes{};
int nDigitalBytesReserved{}; // including dbit offset and for 64 bits
int nTransceiverBytes{};
int nPixelsX{};
};
inline CtbImageOutputs computeCtbImageSize(const CtbImageInputs &in) {
CtbImageOutputs out{};
constexpr int num_bytes_per_analog_channel = 2;
constexpr int num_bytes_per_transceiver_channel = 8;
constexpr int max_digital_channels = 64;
// analog channels (normal, analog/digital readout)
if (in.mode == slsDetectorDefs::ANALOG_ONLY ||
in.mode == slsDetectorDefs::ANALOG_AND_DIGITAL) {
int nAnalogChans = __builtin_popcount(in.adcMask);
out.nPixelsX += nAnalogChans;
out.nAnalogBytes =
nAnalogChans * num_bytes_per_analog_channel * in.nAnalogSamples;
LOG(logDEBUG1) << " Number of Analog Channels:" << nAnalogChans
<< " Databytes: " << out.nAnalogBytes;
}
// digital channels
if (in.mode == slsDetectorDefs::DIGITAL_ONLY ||
in.mode == slsDetectorDefs::ANALOG_AND_DIGITAL ||
in.mode == slsDetectorDefs::DIGITAL_AND_TRANSCEIVER) {
int nSamples = in.nDigitalSamples;
{
// allocate enought for 64 bits and dbit offset for now
// TODO: to be replaced in the future with the actual reserved and
// used
int32_t num_bytes_per_bit =
(nSamples % 8 == 0) ? (nSamples / 8) : (nSamples / 8 + 1);
out.nDigitalBytesReserved =
max_digital_channels * num_bytes_per_bit;
LOG(logDEBUG1) << "Number of Digital Channels:"
<< max_digital_channels << " Databytes reserved: "
<< out.nDigitalBytesReserved;
}
// remove offset
if (in.dbitOffset > 0) {
int nBytesReserved = out.nDigitalBytesReserved - in.dbitOffset;
nSamples = nBytesReserved / sizeof(uint64_t);
}
// calculate channels
int nChans = in.dbitList.size();
if (nChans == 0) {
nChans = max_digital_channels;
}
out.nPixelsX += nChans;
// calculate actual bytes
if (!in.dbitReorder) {
uint32_t nBitsPerSample = nChans;
if (nBitsPerSample % 8 != 0) {
nBitsPerSample += (8 - (nBitsPerSample % 8));
}
out.nDigitalBytes = (nBitsPerSample / 8) * nSamples;
} else {
uint32_t nBitsPerSignal = nSamples;
if (nBitsPerSignal % 8 != 0) {
nBitsPerSignal += (8 - (nBitsPerSignal % 8));
}
out.nDigitalBytes = nChans * (nBitsPerSignal / 8);
}
LOG(logDEBUG1) << "Number of Actual Digital Channels:" << nChans
<< " Databytes: " << out.nDigitalBytes;
}
// transceiver channels
if (in.mode == slsDetectorDefs::TRANSCEIVER_ONLY ||
in.mode == slsDetectorDefs::DIGITAL_AND_TRANSCEIVER) {
int nTransceiverChans = __builtin_popcount(in.transceiverMask);
out.nPixelsX += nTransceiverChans;
out.nTransceiverBytes = nTransceiverChans *
num_bytes_per_transceiver_channel *
in.nTransceiverSamples;
LOG(logDEBUG1) << "Number of Transceiver Channels:" << nTransceiverChans
<< " Databytes: " << out.nTransceiverBytes;
}
return out;
}
class GeneralData {
public:
@@ -62,7 +166,8 @@ class GeneralData {
uint32_t transceiverMask{0};
slsDetectorDefs::frameDiscardPolicy frameDiscardMode{
slsDetectorDefs::NO_DISCARD};
/* actual image size after ctboffset and ctbreorder */
uint32_t actualImageSize{0};
GeneralData(){};
virtual ~GeneralData(){};
@@ -196,6 +301,7 @@ class EigerData : public GeneralData {
dataSize = (tengigaEnable ? 4096 : 1024);
packetSize = headerSizeinPacket + dataSize;
imageSize = int(nPixelsX * nPixelsY * GetPixelDepth());
actualImageSize = imageSize;
packetsPerFrame = imageSize / dataSize;
fifoDepth = (dynamicRange == 32 ? 100 : 1000);
};
@@ -226,6 +332,7 @@ class JungfrauData : public GeneralData {
nPixelsX = (256 * 4);
nPixelsY = (256 * 2) / numUDPInterfaces;
imageSize = int(nPixelsX * nPixelsY * GetPixelDepth());
actualImageSize = imageSize;
packetsPerFrame = imageSize / dataSize;
udpSocketBufferSize = (1000 * 1024 * 1024) / numUDPInterfaces;
};
@@ -257,6 +364,7 @@ class MoenchData : public GeneralData {
nPixelsX = (400);
nPixelsY = (400) / numUDPInterfaces;
imageSize = int(nPixelsX * nPixelsY * GetPixelDepth());
actualImageSize = imageSize;
packetsPerFrame = imageSize / dataSize;
udpSocketBufferSize = (1000 * 1024 * 1024) / numUDPInterfaces;
};
@@ -308,6 +416,7 @@ class Mythen3Data : public GeneralData {
nPixelsX = (NCHAN * ncounters); // max 1280 channels x 3 counters
LOG(logINFO) << "nPixelsX: " << nPixelsX;
imageSize = nPixelsX * nPixelsY * GetPixelDepth();
actualImageSize = imageSize;
// 10g
if (tengigaEnable) {
@@ -374,6 +483,7 @@ class Gotthard2Data : public GeneralData {
void UpdateImageSize() {
packetSize = headerSizeinPacket + dataSize;
imageSize = int(nPixelsX * nPixelsY * GetPixelDepth());
actualImageSize = imageSize;
packetsPerFrame = imageSize / dataSize;
vetoPacketSize = vetoHsize + vetoDataSize;
vetoImageSize = vetoDataSize * packetsPerFrame;
@@ -384,8 +494,6 @@ class Gotthard2Data : public GeneralData {
class ChipTestBoardData : public GeneralData {
private:
const int NCHAN_DIGITAL = 64;
const int NUM_BYTES_PER_ANALOG_CHANNEL = 2;
const int NUM_BYTES_PER_TRANSCEIVER_CHANNEL = 8;
int nAnalogBytes = 0;
int nDigitalBytes = 0;
int nTransceiverBytes = 0;
@@ -394,7 +502,7 @@ class ChipTestBoardData : public GeneralData {
/** Constructor */
ChipTestBoardData() {
detType = slsDetectorDefs::CHIPTESTBOARD;
nPixelsY = 1; // number of samples
nPixelsY = 1;
headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header);
frameIndexMask = 0xFFFFFF; // 10g
frameIndexOffset = 8; // 10g
@@ -404,29 +512,29 @@ class ChipTestBoardData : public GeneralData {
standardheader = true;
ctbDbitReorder = true;
UpdateImageSize();
};
}
public:
int GetNumberOfAnalogDatabytes() { return nAnalogBytes; };
int GetNumberOfAnalogDatabytes() { return nAnalogBytes; }
int GetNumberOfDigitalDatabytes() { return nDigitalBytes; };
int GetNumberOfDigitalDatabytes() { return nDigitalBytes; }
int GetNumberOfTransceiverDatabytes() { return nTransceiverBytes; };
int GetNumberOfTransceiverDatabytes() { return nTransceiverBytes; }
void SetNumberOfAnalogSamples(int n) {
nAnalogSamples = n;
UpdateImageSize();
};
}
void SetNumberOfDigitalSamples(int n) {
nDigitalSamples = n;
UpdateImageSize();
};
}
void SetNumberOfTransceiverSamples(int n) {
nTransceiverSamples = n;
UpdateImageSize();
};
}
void SetctbDbitOffset(const int value) { ctbDbitOffset = value; }
@@ -437,83 +545,60 @@ class ChipTestBoardData : public GeneralData {
void SetOneGigaAdcEnableMask(int n) {
adcEnableMaskOneGiga = n;
UpdateImageSize();
};
}
void SetTenGigaAdcEnableMask(int n) {
adcEnableMaskTenGiga = n;
UpdateImageSize();
};
}
void SetTransceiverEnableMask(int n) {
transceiverMask = n;
UpdateImageSize();
};
}
void SetReadoutMode(slsDetectorDefs::readoutMode r) {
readoutType = r;
UpdateImageSize();
};
}
void SetTenGigaEnable(bool tg) {
tengigaEnable = tg;
UpdateImageSize();
};
}
private:
void UpdateImageSize() {
nAnalogBytes = 0;
nDigitalBytes = 0;
nTransceiverBytes = 0;
int nAnalogChans = 0, nDigitalChans = 0, nTransceiverChans = 0;
uint64_t digital_bytes_reserved = 0;
// used in calculations so cant remove now - TODO: remove later
nDigitalBytes = sizeof(uint64_t) * nDigitalSamples;
// analog channels (normal, analog/digital readout)
if (readoutType == slsDetectorDefs::ANALOG_ONLY ||
readoutType == slsDetectorDefs::ANALOG_AND_DIGITAL) {
uint32_t adcEnableMask =
(tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga);
nAnalogChans = __builtin_popcount(adcEnableMask);
// calculate image size
CtbImageInputs inputs{};
inputs.nAnalogSamples = nAnalogSamples;
inputs.adcMask =
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga;
inputs.nTransceiverSamples = nTransceiverSamples;
inputs.transceiverMask = transceiverMask;
inputs.nDigitalSamples = nDigitalSamples;
inputs.dbitOffset = ctbDbitOffset;
inputs.dbitList = ctbDbitList;
inputs.dbitReorder = ctbDbitReorder;
auto out = computeCtbImageSize(inputs);
nPixelsX = out.nPixelsX;
imageSize = out.nAnalogBytes + out.nDigitalBytesReserved +
out.nTransceiverBytes;
// to write to file: after ctb offset and reorder
actualImageSize =
out.nAnalogBytes + out.nDigitalBytes + out.nTransceiverBytes;
LOG(logDEBUG1) << "Actual image size: " << actualImageSize;
nAnalogBytes =
nAnalogChans * NUM_BYTES_PER_ANALOG_CHANNEL * nAnalogSamples;
LOG(logDEBUG1) << " Number of Analog Channels:" << nAnalogChans
<< " Databytes: " << nAnalogBytes;
}
// digital channels
if (readoutType == slsDetectorDefs::DIGITAL_ONLY ||
readoutType == slsDetectorDefs::ANALOG_AND_DIGITAL ||
readoutType == slsDetectorDefs::DIGITAL_AND_TRANSCEIVER) {
nDigitalChans = NCHAN_DIGITAL;
// allocate enough memory to support reordering of digital bits
uint32_t num_bytes_per_bit = (nDigitalSamples % 8 == 0)
? nDigitalSamples / 8
: nDigitalSamples / 8 + 1;
digital_bytes_reserved = 64 * num_bytes_per_bit;
nDigitalBytes = sizeof(uint64_t) * nDigitalSamples;
LOG(logDEBUG1) << "Number of Digital Channels:" << nDigitalChans
<< " Databytes: " << nDigitalBytes;
}
// transceiver channels
if (readoutType == slsDetectorDefs::TRANSCEIVER_ONLY ||
readoutType == slsDetectorDefs::DIGITAL_AND_TRANSCEIVER) {
nTransceiverChans = __builtin_popcount(transceiverMask);
;
nTransceiverBytes = nTransceiverChans *
NUM_BYTES_PER_TRANSCEIVER_CHANNEL *
nTransceiverSamples;
LOG(logDEBUG1) << "Number of Transceiver Channels:"
<< nTransceiverChans
<< " Databytes: " << nTransceiverBytes;
}
nPixelsX = nAnalogChans + nDigitalChans + nTransceiverChans;
// calculate network parameters
dataSize = tengigaEnable ? 8144 : UDP_PACKET_DATA_BYTES;
packetSize = headerSizeinPacket + dataSize;
imageSize = nAnalogBytes + digital_bytes_reserved + nTransceiverBytes;
packetsPerFrame = ceil((double)imageSize / (double)dataSize);
LOG(logDEBUG1) << "Total Number of Channels:" << nPixelsX
<< " Databytes: " << imageSize;
};
}
};
class XilinxChipTestBoardData : public GeneralData {
@@ -572,11 +657,6 @@ class XilinxChipTestBoardData : public GeneralData {
void SetctbDbitReorder(const bool value) { ctbDbitReorder = value; }
void SetOneGigaAdcEnableMask(int n) {
adcEnableMaskOneGiga = n;
UpdateImageSize();
};
void SetTenGigaAdcEnableMask(int n) {
adcEnableMaskTenGiga = n;
UpdateImageSize();
@@ -594,53 +674,30 @@ class XilinxChipTestBoardData : public GeneralData {
private:
void UpdateImageSize() {
nAnalogBytes = 0;
nDigitalBytes = 0;
nTransceiverBytes = 0;
int nAnalogChans = 0, nDigitalChans = 0, nTransceiverChans = 0;
uint64_t digital_bytes_reserved = 0;
// used in calculations so cant remove now - TODO: remove later
nDigitalBytes = sizeof(uint64_t) * nDigitalSamples;
// analog channels (normal, analog/digital readout)
if (readoutType == slsDetectorDefs::ANALOG_ONLY ||
readoutType == slsDetectorDefs::ANALOG_AND_DIGITAL) {
uint32_t adcEnableMask = adcEnableMaskTenGiga;
nAnalogChans = __builtin_popcount(adcEnableMask);
// calculate image size
CtbImageInputs inputs{};
inputs.nAnalogSamples = nAnalogSamples;
inputs.adcMask = adcEnableMaskTenGiga;
inputs.nTransceiverSamples = nTransceiverSamples;
inputs.transceiverMask = transceiverMask;
inputs.nDigitalSamples = nDigitalSamples;
inputs.dbitOffset = ctbDbitOffset;
inputs.dbitList = ctbDbitList;
inputs.dbitReorder = ctbDbitReorder;
auto out = computeCtbImageSize(inputs);
nPixelsX = out.nPixelsX;
imageSize = out.nAnalogBytes + out.nDigitalBytesReserved +
out.nTransceiverBytes;
// to write to file: after ctb offset and reorder
actualImageSize =
out.nAnalogBytes + out.nDigitalBytes + out.nTransceiverBytes;
LOG(logDEBUG1) << "Actual image size: " << actualImageSize;
nAnalogBytes =
nAnalogChans * NUM_BYTES_PER_ANALOG_CHANNEL * nAnalogSamples;
LOG(logDEBUG1) << " Number of Analog Channels:" << nAnalogChans
<< " Databytes: " << nAnalogBytes;
}
// digital channels
if (readoutType == slsDetectorDefs::DIGITAL_ONLY ||
readoutType == slsDetectorDefs::ANALOG_AND_DIGITAL ||
readoutType == slsDetectorDefs::DIGITAL_AND_TRANSCEIVER) {
nDigitalChans = NCHAN_DIGITAL;
uint32_t num_bytes_per_bit = (nDigitalSamples % 8 == 0)
? nDigitalSamples / 8
: nDigitalSamples / 8 + 1;
digital_bytes_reserved = 64 * num_bytes_per_bit;
nDigitalBytes = sizeof(uint64_t) * nDigitalSamples;
LOG(logDEBUG1) << "Number of Digital Channels:" << nDigitalChans
<< " Databytes: " << nDigitalBytes;
}
// transceiver channels
if (readoutType == slsDetectorDefs::TRANSCEIVER_ONLY ||
readoutType == slsDetectorDefs::DIGITAL_AND_TRANSCEIVER) {
nTransceiverChans = __builtin_popcount(transceiverMask);
;
nTransceiverBytes = nTransceiverChans *
NUM_BYTES_PER_TRANSCEIVER_CHANNEL *
nTransceiverSamples;
LOG(logDEBUG1) << "Number of Transceiver Channels:"
<< nTransceiverChans
<< " Databytes: " << nTransceiverBytes;
}
nPixelsX = nAnalogChans + nDigitalChans + nTransceiverChans;
imageSize = nAnalogBytes + digital_bytes_reserved + nTransceiverBytes;
// calculate network parameters
packetsPerFrame = ceil((double)imageSize / (double)dataSize);
LOG(logDEBUG1) << "Total Number of Channels:" << nPixelsX
<< " Databytes: " << imageSize;
};

View File

@@ -908,7 +908,7 @@ void Implementation::StartMasterWriter() {
masterAttributes.detType = generalData->detType;
masterAttributes.timingMode = timingMode;
masterAttributes.geometry = numPorts;
masterAttributes.imageSize = generalData->imageSize;
masterAttributes.imageSize = generalData->actualImageSize;
masterAttributes.nPixels =
xy(generalData->nPixelsX, generalData->nPixelsY);
masterAttributes.maxFramesPerFile = generalData->framesPerFile;
@@ -943,7 +943,7 @@ void Implementation::StartMasterWriter() {
masterAttributes.quad = quadEnable;
masterAttributes.readNRows = readNRows;
masterAttributes.ratecorr = rateCorrections;
masterAttributes.adcmask = generalData->tengigaEnable
masterAttributes.adcMask = generalData->tengigaEnable
? generalData->adcEnableMaskTenGiga
: generalData->adcEnableMaskOneGiga;
masterAttributes.analog =
@@ -959,12 +959,12 @@ void Implementation::StartMasterWriter() {
? 1
: 0;
masterAttributes.digitalSamples = generalData->nDigitalSamples;
masterAttributes.dbitoffset = generalData->ctbDbitOffset;
masterAttributes.dbitreorder = generalData->ctbDbitReorder;
masterAttributes.dbitlist = 0;
masterAttributes.dbitOffset = generalData->ctbDbitOffset;
masterAttributes.dbitReorder = generalData->ctbDbitReorder;
masterAttributes.dbitList = 0;
for (auto &i : generalData->ctbDbitList) {
masterAttributes.dbitlist |= (static_cast<uint64_t>(1) << i);
masterAttributes.dbitList |= (static_cast<uint64_t>(1) << i);
}
masterAttributes.transceiverSamples =
generalData->nTransceiverSamples;
@@ -983,6 +983,7 @@ void Implementation::StartMasterWriter() {
masterAttributes.gateDelayArray[2] = gateDelay3;
masterAttributes.gates = numberOfGates;
masterAttributes.additionalJsonHeader = additionalJsonHeader;
masterAttributes.readoutSpeed = readoutSpeed;
// create master file
masterFileName = dataProcessor[0]->CreateMasterFile(
@@ -1781,6 +1782,15 @@ void Implementation::setTransceiverEnableMask(uint32_t mask) {
LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame);
}
slsDetectorDefs::speedLevel Implementation::getReadoutSpeed() const {
return readoutSpeed;
}
void Implementation::setReadoutSpeed(const slsDetectorDefs::speedLevel i) {
readoutSpeed = i;
LOG(logINFO) << "Readout Speed: " << ToString(readoutSpeed);
}
/**************************************************
* *
* Callbacks *

View File

@@ -256,10 +256,12 @@ class Implementation : private virtual slsDetectorDefs {
bool getDbitReorder() const;
/* [Ctb] */
void setDbitReorder(const bool reorder);
uint32_t getTransceiverEnableMask() const;
/* [Ctb] */
void setTransceiverEnableMask(const uint32_t mask);
speedLevel getReadoutSpeed() const;
/* [Eiger][Jungfrau][Moench][Mythen3][Gotthard2]*/
void setReadoutSpeed(const speedLevel i);
/**************************************************
* *
@@ -369,6 +371,7 @@ class Implementation : private virtual slsDetectorDefs {
int thresholdEnergyeV{-1};
std::array<int, 3> thresholdAllEnergyeV = {{-1, -1, -1}};
std::vector<int64_t> rateCorrections;
speedLevel readoutSpeed{FULL_SPEED};
// callbacks
void (*startAcquisitionCallBack)(const startCallbackHeader,

File diff suppressed because it is too large Load Diff

View File

@@ -4,12 +4,14 @@
#include "receiver_defs.h"
#include "sls/ToString.h"
#include "sls/TypeTraits.h"
#include "sls/logger.h"
#include "sls/sls_detector_defs.h"
#include <chrono>
#include <rapidjson/prettywriter.h>
#include <rapidjson/stringbuffer.h>
#include <string_view>
#ifdef HDF5C
#include "H5Cpp.h"
@@ -18,6 +20,7 @@
namespace sls {
using ns = std::chrono::nanoseconds;
using writer = rapidjson::PrettyWriter<rapidjson::StringBuffer>;
class MasterAttributes {
public:
@@ -25,7 +28,7 @@ class MasterAttributes {
slsDetectorDefs::detectorType detType{slsDetectorDefs::GENERIC};
slsDetectorDefs::timingMode timingMode{slsDetectorDefs::AUTO_TIMING};
slsDetectorDefs::xy geometry{};
uint32_t imageSize{0};
int imageSize{0};
slsDetectorDefs::xy nPixels{};
uint32_t maxFramesPerFile{0};
slsDetectorDefs::frameDiscardPolicy frameDiscardMode{
@@ -37,123 +40,413 @@ class MasterAttributes {
ns period{0};
slsDetectorDefs::burstMode burstMode{slsDetectorDefs::BURST_INTERNAL};
int numUDPInterfaces{0};
uint32_t dynamicRange{0};
uint32_t tenGiga{0};
int dynamicRange{0};
int tenGiga{0};
int thresholdEnergyeV{0};
std::array<int, 3> thresholdAllEnergyeV = {{0, 0, 0}};
ns subExptime{0};
ns subPeriod{0};
uint32_t quad{0};
uint32_t readNRows;
int quad{0};
int readNRows;
std::vector<int64_t> ratecorr;
uint32_t adcmask{0};
uint32_t analog{0};
uint32_t analogSamples{0};
uint32_t digital{0};
uint32_t digitalSamples{0};
uint32_t dbitreorder{1};
uint32_t dbitoffset{0};
uint64_t dbitlist{0};
uint32_t transceiverMask{0};
uint32_t transceiver{0};
uint32_t transceiverSamples{0};
uint32_t adcMask{0};
int analog{0};
int analogSamples{0};
int digital{0};
int digitalSamples{0};
int dbitReorder{1};
int dbitOffset{0};
uint64_t dbitList{0};
int transceiverMask{0};
int transceiver{0};
int transceiverSamples{0};
std::vector<slsDetectorDefs::ROI> rois{};
uint32_t counterMask{0};
int counterMask{0};
std::array<ns, 3> exptimeArray{};
std::array<ns, 3> gateDelayArray{};
uint32_t gates;
int gates;
std::map<std::string, std::string> additionalJsonHeader;
uint64_t framesInFile{0};
slsDetectorDefs::speedLevel readoutSpeed{slsDetectorDefs::FULL_SPEED};
inline static const std::string_view N_DETECTOR_TYPE = "Detector Type";
inline static const std::string_view N_TIMING_MODE = "Timing Mode";
inline static const std::string_view N_GEOMETRY = "Geometry";
inline static const std::string_view N_IMAGE_SIZE = "Image Size";
inline static const std::string_view N_PIXELS = "Pixels";
inline static const std::string_view N_MAX_FRAMES_PER_FILE =
"Max Frames Per File";
inline static const std::string_view N_FRAME_DISCARD_POLICY =
"Frame Discard Policy";
inline static const std::string_view N_FRAME_PADDING = "Frame Padding";
inline static const std::string_view N_TOTAL_FRAMES = "Total Frames";
inline static const std::string_view N_FRAMES_IN_FILE = "Frames in File";
inline static const std::string_view N_EXPOSURE_TIME = "Exposure Time";
inline static const std::string_view N_ACQUISITION_PERIOD =
"Acquisition Period";
inline static const std::string_view N_NUM_UDP_INTERFACES =
"Number of UDP Interfaces";
inline static const std::string_view N_NUMBER_OF_ROWS = "Number of Rows";
inline static const std::string_view N_READOUT_SPEED = "Readout Speed";
inline static const std::string_view N_DYNAMIC_RANGE = "Dynamic Range";
inline static const std::string_view N_TEN_GIGA = "Ten Giga";
inline static const std::string_view N_THRESHOLD_ENERGY =
"Threshold Energy";
inline static const std::string_view N_SUB_EXPOSURE_TIME =
"Sub Exposure Time";
inline static const std::string_view N_SUB_ACQUISITION_PERIOD =
"Sub Acquisition Period";
inline static const std::string_view N_QUAD = "Quad";
inline static const std::string_view N_RATE_CORRECTIONS =
"Rate Corrections";
inline static const std::string_view N_COUNTER_MASK = "Counter Mask";
inline static const std::string_view N_EXPOSURE_TIMES = "Exposure Times";
inline static const std::string_view N_GATE_DELAYS = "Gate Delays";
inline static const std::string_view N_GATES = "Gates";
inline static const std::string_view N_THRESHOLD_ENERGIES =
"Threshold Energies";
inline static const std::string_view N_BURST_MODE = "Burst Mode";
inline static const std::string_view N_ADC_MASK = "ADC Mask";
inline static const std::string_view N_ANALOG = "Analog Flag";
inline static const std::string_view N_ANALOG_SAMPLES = "Analog Samples";
inline static const std::string_view N_DIGITAL = "Digital Flag";
inline static const std::string_view N_DIGITAL_SAMPLES = "Digital Samples";
inline static const std::string_view N_DBIT_REORDER = "Dbit Reorder";
inline static const std::string_view N_DBIT_OFFSET = "Dbit Offset";
inline static const std::string_view N_DBIT_BITSET = "Dbit Bitset";
inline static const std::string_view N_TRANSCEIVER_MASK =
"Transceiver Mask";
inline static const std::string_view N_TRANSCEIVER = "Transceiver Flag";
inline static const std::string_view N_TRANSCEIVER_SAMPLES =
"Transceiver Samples";
inline static const std::string_view N_VERSION = "Version";
inline static const std::string_view N_TIMESTAMP = "Timestamp";
inline static const std::string_view N_RECEIVER_ROIS = "Receiver Rois";
inline static const std::string_view N_SCAN_PARAMETERS = "Scan Parameters";
inline static const std::string_view N_ADDITIONAL_JSON_HEADER =
"Additional JSON Header";
MasterAttributes() = default;
~MasterAttributes() = default;
void
GetBinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void GetBinaryAttributes(writer *w);
#ifdef HDF5C
void WriteHDF5Attributes(H5::H5File *fd, H5::Group *group);
#endif
void GetCommonBinaryAttributes(
rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void GetFinalBinaryAttributes(
rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void GetBinaryRois(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void GetCommonBinaryAttributes(writer *w);
void GetFinalBinaryAttributes(writer *w);
#ifdef HDF5C
void WriteCommonHDF5Attributes(H5::H5File *fd, H5::Group *group);
void WriteFinalHDF5Attributes(H5::Group *group);
void WriteHDF5ROIs(H5::Group *group);
void WriteHDF5Exptime(H5::Group *group);
void WriteHDF5Period(H5::Group *group);
void WriteHDF5DynamicRange(H5::Group *group);
void WriteHDF5TenGiga(H5::Group *group);
void WriteHDF5NumUDPInterfaces(H5::Group *group);
void WriteHDF5ReadNRows(H5::Group *group);
void WriteHDF5ThresholdEnergy(H5::Group *group);
void WriteHDF5ThresholdEnergies(H5::Group *group);
void WriteHDF5SubExpTime(H5::Group *group);
void WriteHDF5SubPeriod(H5::Group *group);
void WriteHDF5SubQuad(H5::Group *group);
void WriteHDF5RateCorrections(H5::Group *group);
void WriteHDF5CounterMask(H5::Group *group);
void WriteHDF5ExptimeArray(H5::Group *group);
void WriteHDF5GateDelayArray(H5::Group *group);
void WriteHDF5Gates(H5::Group *group);
void WriteHDF5BurstMode(H5::Group *group);
void WriteHDF5AdcMask(H5::Group *group);
void WriteHDF5AnalogFlag(H5::Group *group);
void WriteHDF5AnalogSamples(H5::Group *group);
void WriteHDF5DigitalFlag(H5::Group *group);
void WriteHDF5DigitalSamples(H5::Group *group);
void WriteHDF5DbitOffset(H5::Group *group);
void WriteHDF5DbitList(H5::Group *group);
void WriteHDF5DbitReorder(H5::Group *group);
void WriteHDF5TransceiverMask(H5::Group *group);
void WriteHDF5TransceiverFlag(H5::Group *group);
void WriteHDF5TransceiverSamples(H5::Group *group);
#endif
void GetJungfrauBinaryAttributes(
rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void GetJungfrauBinaryAttributes(writer *w);
#ifdef HDF5C
void WriteJungfrauHDF5Attributes(H5::Group *group);
#endif
void GetEigerBinaryAttributes(
rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void GetEigerBinaryAttributes(writer *w);
#ifdef HDF5C
void WriteEigerHDF5Attributes(H5::Group *group);
#endif
void GetMythen3BinaryAttributes(
rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void GetMythen3BinaryAttributes(writer *w);
#ifdef HDF5C
void WriteMythen3HDF5Attributes(H5::Group *group);
#endif
void GetGotthard2BinaryAttributes(
rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void GetGotthard2BinaryAttributes(writer *w);
#ifdef HDF5C
void WriteGotthard2HDF5Attributes(H5::Group *group);
#endif
void GetMoenchBinaryAttributes(
rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void GetMoenchBinaryAttributes(writer *w);
#ifdef HDF5C
void WriteMoenchHDF5Attributes(H5::Group *group);
#endif
void
GetCtbBinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void GetCtbBinaryAttributes(writer *w);
#ifdef HDF5C
void WriteCtbHDF5Attributes(H5::Group *group);
#endif
void GetXilinxCtbBinaryAttributes(
rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void GetXilinxCtbBinaryAttributes(writer *w);
#ifdef HDF5C
void WriteXilinxCtbHDF5Attributes(H5::Group *group);
#endif
void WriteBinaryDetectorType(writer *w);
#ifdef HDF5C
void WriteHDF5DetectorType(H5::Group *group);
#endif
void WriteBinaryTimingMode(writer *w);
#ifdef HDF5C
void WriteHDF5TimingMode(H5::Group *group);
#endif
void WriteBinaryGeometry(writer *w);
#ifdef HDF5C
void WriteHDF5Geometry(H5::Group *group);
#endif
void WriteBinaryImageSize(writer *w);
#ifdef HDF5C
void WriteHDF5ImageSize(H5::Group *group);
#endif
void WriteBinaryPixels(writer *w);
#ifdef HDF5C
void WriteHDF5Pixels(H5::Group *group);
#endif
void WriteBinaryMaxFramesPerFile(writer *w);
#ifdef HDF5C
void WriteHDF5MaxFramesPerFile(H5::Group *group);
#endif
void WriteBinaryFrameDiscardPolicy(writer *w);
#ifdef HDF5C
void WriteHDF5FrameDiscardPolicy(H5::Group *group);
#endif
void WriteBinaryFramePadding(writer *w);
#ifdef HDF5C
void WriteHDF5FramePadding(H5::Group *group);
#endif
void WriteBinaryTotalFrames(writer *w);
#ifdef HDF5C
void WriteHDF5TotalFrames(H5::Group *group);
#endif
void WriteBinaryFramesInFile(writer *w);
#ifdef HDF5C
void WriteHDF5FramesInFile(H5::Group *group);
#endif
void WriteBinaryExposureTme(writer *w);
#ifdef HDF5C
void WriteHDF5ExposureTime(H5::Group *group);
#endif
void WriteBinaryAcquisitionPeriod(writer *w);
#ifdef HDF5C
void WriteHDF5AcquisitionPeriod(H5::Group *group);
#endif
void WriteBinaryNumberOfUDPInterfaces(writer *w);
#ifdef HDF5C
void WriteHDF5NumberOfUDPInterfaces(H5::Group *group);
#endif
void WriteBinaryNumberOfRows(writer *w);
#ifdef HDF5C
void WriteHDF5NumberOfRows(H5::Group *group);
#endif
void WriteBinaryReadoutSpeed(writer *w);
#ifdef HDF5C
void WriteHDF5ReadoutSpeed(H5::Group *group);
#endif
void WriteBinaryDynamicRange(writer *w);
#ifdef HDF5C
void WriteHDF5DynamicRange(H5::Group *group);
#endif
void WriteBinaryTenGiga(writer *w);
#ifdef HDF5C
void WriteHDF5TenGiga(H5::Group *group);
#endif
void WriteBinaryThresholdEnergy(writer *w);
#ifdef HDF5C
void WriteHDF5ThresholdEnergy(H5::Group *group);
#endif
void WriteBinarySubExposureTime(writer *w);
#ifdef HDF5C
void WriteHDF5SubExposureTime(H5::Group *group);
#endif
void WriteBinarySubAcquisitionPeriod(writer *w);
#ifdef HDF5C
void WriteHDF5SubAcquisitionPeriod(H5::Group *group);
#endif
void WriteBinaryQuad(writer *w);
#ifdef HDF5C
void WriteHDF5Quad(H5::Group *group);
#endif
void WriteBinaryRateCorrections(writer *w);
#ifdef HDF5C
void WriteHDF5RateCorrections(H5::Group *group);
#endif
void WriteBinaryCounterMask(writer *w);
#ifdef HDF5C
void WriteHDF5CounterMask(H5::Group *group);
#endif
void WriteBinaryExptimeArray(writer *w);
#ifdef HDF5C
void WriteHDF5ExptimeArray(H5::Group *group);
#endif
void WriteBinaryGateDelayArray(writer *w);
#ifdef HDF5C
void WriteHDF5GateDelayArray(H5::Group *group);
#endif
void WriteBinaryGates(writer *w);
#ifdef HDF5C
void WriteHDF5Gates(H5::Group *group);
#endif
void WriteBinaryThresholdAllEnergy(writer *w);
#ifdef HDF5C
void WriteHDF5ThresholdAllEnergy(H5::Group *group);
#endif
void WriteBinaryBurstMode(writer *w);
#ifdef HDF5C
void WriteHDF5BurstMode(H5::Group *group);
#endif
void WriteBinaryAdcMask(writer *w);
#ifdef HDF5C
void WriteHDF5AdcMask(H5::Group *group);
#endif
void WriteBinaryAnalogFlag(writer *w);
#ifdef HDF5C
void WriteHDF5AnalogFlag(H5::Group *group);
#endif
void WriteBinaryAnalogSamples(writer *w);
#ifdef HDF5C
void WriteHDF5AnalogSamples(H5::Group *group);
#endif
void WriteBinaryDigitalFlag(writer *w);
#ifdef HDF5C
void WriteHDF5DigitalFlag(H5::Group *group);
#endif
void WriteBinaryDigitalSamples(writer *w);
#ifdef HDF5C
void WriteHDF5DigitalSamples(H5::Group *group);
#endif
void WriteBinaryDBitReorder(writer *w);
#ifdef HDF5C
void WriteHDF5DBitReorder(H5::Group *group);
#endif
void WriteBinaryDBitOffset(writer *w);
#ifdef HDF5C
void WriteHDF5DBitOffset(H5::Group *group);
#endif
void WriteBinaryDBitBitset(writer *w);
#ifdef HDF5C
void WriteHDF5DBitBitset(H5::Group *group);
#endif
void WriteBinaryTransceiverMask(writer *w);
#ifdef HDF5C
void WriteHDF5TransceiverMask(H5::Group *group);
#endif
void WriteBinaryTransceiverFlag(writer *w);
#ifdef HDF5C
void WriteHDF5TransceiverFlag(H5::Group *group);
#endif
void WriteBinaryTransceiverSamples(writer *w);
#ifdef HDF5C
void WriteHDF5TransceiverSamples(H5::Group *group);
#endif
/** writes according to type */
template <typename T> void WriteBinaryValue(writer *w, const T &value) {
if constexpr (std::is_same_v<T, int>) {
w->Int(value);
} else if constexpr (std::is_same_v<T, uint64_t>) {
w->Uint64(value);
} else if constexpr (std::is_same_v<T, int64_t>) {
w->Int64(value);
} else if constexpr (std::is_same_v<T, uint32_t>) {
w->Uint(value);
} else if constexpr (std::is_same_v<T, std::string>) {
w->String(value.c_str());
} else if constexpr (is_duration<T>::value) {
w->String(ToString(value).c_str());
} else {
throw RuntimeError("Unsupported type for Binary write: " +
std::string(typeid(T).name()));
}
}
/** For non-arrays */
template <typename T>
std::enable_if_t<(!std::is_class_v<T> || std::is_same_v<T, std::string>),
void>
WriteBinary(writer *w, const std::string &name, const T &value) {
w->Key(name.c_str());
WriteBinaryValue(w, value);
}
/** For arrays */
template <typename T>
std::enable_if_t<(std::is_class_v<T> && !std::is_same_v<T, std::string>),
void>
WriteBinary(writer *w, const std::string &name, const T &value) {
w->Key(name.c_str());
w->StartArray();
for (const auto &v : value) {
WriteBinaryValue(w, v);
}
w->EndArray();
}
#ifdef HDF5C
void WriteHDF5String(H5::Group *group, const std::string &name,
const std::string &value);
void WriteHDF5StringArray(H5::Group *group, const std::string &name,
const std::vector<std::string> &value);
/** get type */
template <typename T> H5::PredType const *GetHDF5Type() {
if constexpr (std::is_same_v<T, int>) {
return &H5::PredType::NATIVE_INT;
} else if constexpr (std::is_same_v<T, uint64_t>) {
return &H5::PredType::STD_U64LE;
} else if constexpr (std::is_same_v<T, int64_t>) {
return &H5::PredType::STD_I64LE;
} else if constexpr (std::is_same_v<T, uint32_t>) {
return &H5::PredType::STD_U32LE;
} else {
throw RuntimeError("Unsupported type for HDF5");
}
}
/** For non-arrays */
template <typename T>
typename std::enable_if<!std::is_class<T>::value, void>::type
WriteHDF5Int(H5::Group *group, const std::string &name, const T &value) {
H5::DataSpace dataspace(H5S_SCALAR);
auto h5type = GetHDF5Type<T>();
H5::DataSet dataset = group->createDataSet(name, *h5type, dataspace);
dataset.write(&value, *h5type);
}
/** For arrays */
template <typename T>
typename std::enable_if<std::is_class<T>::value, void>::type
WriteHDF5Int(H5::Group *group, const std::string &name, const T &value) {
using ElemT = typename T::value_type;
auto h5type = GetHDF5Type<ElemT>();
hsize_t dims[1] = {value.size()};
H5::DataSpace dataspace(1, dims);
H5::DataSet dataset = group->createDataSet(name, *h5type, dataspace);
dataset.write(value.data(), *h5type);
}
#endif
void WriteBinaryXY(writer *w, const std::string &name, const defs::xy &xy);
#ifdef HDF5C
void WriteHDF5XY(H5::Group *group, const std::string &name,
const defs::xy &xy);
#endif
void WriteBinaryVersion(writer *w);
#ifdef HDF5C
void WriteHDF5Version(H5::H5File *fd);
#endif
void WriteBinaryTimestamp(writer *w);
#ifdef HDF5C
void WriteHDF5Timestamp(H5::Group *group);
#endif
void WriteBinaryRois(writer *w);
#ifdef HDF5C
void WriteHDF5ROIs(H5::Group *group);
#endif
void WriteBinaryScanParameters(writer *w);
#ifdef HDF5C
void WriteHDF5ScanParameters(H5::Group *group);
#endif
void WriteBinaryJsonHeader(writer *w);
#ifdef HDF5C
void WriteHDF5JsonHeader(H5::Group *group);
#endif
void WriteBinaryFrameHeaderFormat(writer *w);
};
} // namespace sls

View File

@@ -140,13 +140,6 @@ std::string CreateMasterHDF5File(const std::string &filePath,
fd = make_unique<H5::H5File>(fileName.c_str(), createFlags,
H5::FileCreatPropList::DEFAULT, flist);
// attributes - version
double dValue = HDF5_WRITER_VERSION;
H5::DataSpace dataspace_attr = H5::DataSpace(H5S_SCALAR);
H5::Attribute attribute = fd->createAttribute(
"version", H5::PredType::NATIVE_DOUBLE, dataspace_attr);
attribute.write(H5::PredType::NATIVE_DOUBLE, &dValue);
// Create a group in the file
H5::Group group1(fd->createGroup("entry"));
H5::Group group2(group1.createGroup("data"));
@@ -230,13 +223,6 @@ std::string CreateVirtualHDF5File(
fd = make_unique<H5::H5File>(fileName.c_str(), H5F_ACC_TRUNC,
H5::FileCreatPropList::DEFAULT, fapl);
// attributes - version
double dValue = HDF5_WRITER_VERSION;
H5::DataSpace dataspace_attr = H5::DataSpace(H5S_SCALAR);
H5::Attribute attribute = fd->createAttribute(
"version", H5::PredType::NATIVE_DOUBLE, dataspace_attr);
attribute.write(H5::PredType::NATIVE_DOUBLE, &dValue);
for (size_t iRoi = 0; iRoi != multiRoi.size(); ++iRoi) {
auto currentRoi = multiRoi[iRoi];