mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-06 01:50:40 +02:00
commit
fd6e44c396
@ -8,6 +8,8 @@ speedLevel = slsDetectorDefs.speedLevel
|
||||
dacIndex = slsDetectorDefs.dacIndex
|
||||
detectorType = slsDetectorDefs.detectorType
|
||||
|
||||
defs = slsDetectorDefs
|
||||
|
||||
from .utils import element_if_equal, all_equal, get_set_bits, list_to_bitmask
|
||||
from .utils import Geometry, to_geo, element, reduce_time, is_iterable
|
||||
from _slsdet import xy
|
||||
@ -1787,10 +1789,25 @@ class Detector(CppDetectorApi):
|
||||
|
||||
"""
|
||||
|
||||
<<<-----------------------Eiger specific----------------------->>>
|
||||
<<<Eiger>>>
|
||||
|
||||
"""
|
||||
|
||||
@property
|
||||
def datastream(self):
|
||||
"""
|
||||
datastream [left|right] [0, 1]
|
||||
[Eiger] Enables or disables data streaming from left or/and right side of detector. 1 (enabled) by default.
|
||||
"""
|
||||
result = {}
|
||||
for port in [defs.LEFT, defs.RIGHT]:
|
||||
result[port] = element_if_equal(self.getDataStream(port))
|
||||
return result
|
||||
|
||||
@datastream.setter
|
||||
def datastream(self, value):
|
||||
ut.set_using_dict(self.setDataStream, *value)
|
||||
|
||||
@property
|
||||
@element
|
||||
def quad(self):
|
||||
|
@ -401,7 +401,9 @@ void init_det(py::module &m) {
|
||||
.def("startDetector", (void (Detector::*)()) & Detector::startDetector)
|
||||
.def("startDetectorReadout",
|
||||
(void (Detector::*)()) & Detector::startDetectorReadout)
|
||||
.def("stopDetector", (void (Detector::*)()) & Detector::stopDetector)
|
||||
.def("stopDetector",
|
||||
(void (Detector::*)(sls::Positions)) & Detector::stopDetector,
|
||||
py::arg() = Positions{})
|
||||
.def("getDetectorStatus",
|
||||
(Result<defs::runStatus>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getDetectorStatus,
|
||||
@ -430,7 +432,7 @@ void init_det(py::module &m) {
|
||||
.def("sendSoftwareTrigger",
|
||||
(void (Detector::*)(const bool, sls::Positions)) &
|
||||
Detector::sendSoftwareTrigger,
|
||||
py::arg(), py::arg() = Positions{})
|
||||
py::arg() = false, py::arg() = Positions{})
|
||||
.def("getScan",
|
||||
(Result<defs::scanParameters>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getScan,
|
||||
@ -911,6 +913,16 @@ void init_det(py::module &m) {
|
||||
py::arg() = Positions{})
|
||||
.def("setQuad", (void (Detector::*)(const bool)) & Detector::setQuad,
|
||||
py::arg())
|
||||
.def("getDataStream",
|
||||
(Result<bool>(Detector::*)(const defs::portPosition,
|
||||
sls::Positions) const) &
|
||||
Detector::getDataStream,
|
||||
py::arg(), py::arg() = Positions{})
|
||||
.def("setDataStream",
|
||||
(void (Detector::*)(const defs::portPosition, const bool,
|
||||
sls::Positions)) &
|
||||
Detector::setDataStream,
|
||||
py::arg(), py::arg(), py::arg() = Positions{})
|
||||
.def("getThresholdTemperature",
|
||||
(Result<int>(Detector::*)(sls::Positions) const) &
|
||||
Detector::getThresholdTemperature,
|
||||
|
@ -281,4 +281,11 @@ void init_enums(py::module &m) {
|
||||
.value("M3_C225ACsh", slsDetectorDefs::M3_GainCaps::M3_C225ACsh)
|
||||
.value("M3_C15pre", slsDetectorDefs::M3_GainCaps::M3_C15pre)
|
||||
.export_values();
|
||||
|
||||
py::enum_<slsDetectorDefs::portPosition>(Defs, "portPosition")
|
||||
.value("LEFT", slsDetectorDefs::portPosition::LEFT)
|
||||
.value("RIGHT", slsDetectorDefs::portPosition::RIGHT)
|
||||
.value("TOP", slsDetectorDefs::portPosition::TOP)
|
||||
.value("BOTTOM", slsDetectorDefs::portPosition::BOTTOM)
|
||||
.export_values();
|
||||
}
|
||||
|
@ -43,6 +43,8 @@ int Beb_deactivated_transmission_flowcontrol_10g = 0;
|
||||
int Beb_deactivated_transmission_delay_frame = 0;
|
||||
int Beb_deactivated_transmission_delay_left = 0;
|
||||
int Beb_deactivated_transmission_delay_right = 0;
|
||||
int Beb_deactivated_left_datastream = 1;
|
||||
int Beb_deactivated_right_datastream = 1;
|
||||
|
||||
void BebInfo_BebInfo(struct BebInfo *bebInfo, unsigned int beb_num) {
|
||||
bebInfo->beb_number = beb_num;
|
||||
@ -449,6 +451,74 @@ int Beb_GetActivate(int *retval) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Beb_SetDataStream(enum portPosition port, int enable) {
|
||||
if (!Beb_activated) {
|
||||
if (port == LEFT) {
|
||||
Beb_deactivated_left_datastream = enable;
|
||||
} else {
|
||||
Beb_deactivated_right_datastream = enable;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (enable < 0) {
|
||||
LOG(logERROR, ("Invalid enable value\n"));
|
||||
return 0;
|
||||
}
|
||||
u_int32_t *csp0base = 0;
|
||||
int fd = Beb_open(&csp0base, XPAR_PLB_GPIO_SYS_BASEADDR);
|
||||
if (fd < 0) {
|
||||
LOG(logERROR, ("Activate FAIL, could not open fd\n"));
|
||||
return 0;
|
||||
} else {
|
||||
u_int32_t reg = XPAR_GPIO_P15_STREAMING_REG;
|
||||
u_int32_t mask = (port == LEFT ? XPAR_GPIO_LFT_STRM_DSBL_MSK
|
||||
: XPAR_GPIO_RGHT_STRM_DSBL_MSK);
|
||||
|
||||
u_int32_t value = Beb_Read32(csp0base, reg);
|
||||
// disabling in firmware
|
||||
if (!enable)
|
||||
value |= mask;
|
||||
else
|
||||
value &= ~mask;
|
||||
u_int32_t retval = Beb_Write32(csp0base, reg, value);
|
||||
if (retval != value) {
|
||||
LOG(logERROR,
|
||||
("Could not %s %s fpga datastream. Wrote 0x%x, read 0x%x\n",
|
||||
(enable ? "enable" : "disable"),
|
||||
(port == LEFT ? "left" : "right"), value, retval));
|
||||
Beb_close(fd, csp0base);
|
||||
}
|
||||
}
|
||||
Beb_close(fd, csp0base);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Beb_GetDataStream(enum portPosition port, int *retval) {
|
||||
if (!Beb_activated) {
|
||||
if (port == LEFT) {
|
||||
return Beb_deactivated_left_datastream;
|
||||
} else {
|
||||
return Beb_deactivated_right_datastream;
|
||||
}
|
||||
}
|
||||
u_int32_t *csp0base = 0;
|
||||
int fd = Beb_open(&csp0base, XPAR_PLB_GPIO_SYS_BASEADDR);
|
||||
if (fd < 0) {
|
||||
LOG(logERROR, ("Activate FAIL, could not open fd\n"));
|
||||
return 0;
|
||||
} else {
|
||||
u_int32_t reg = XPAR_GPIO_P15_STREAMING_REG;
|
||||
u_int32_t mask = (port == LEFT ? XPAR_GPIO_LFT_STRM_DSBL_MSK
|
||||
: XPAR_GPIO_RGHT_STRM_DSBL_MSK);
|
||||
|
||||
u_int32_t value = Beb_Read32(csp0base, reg);
|
||||
// disabling in firmware
|
||||
*retval = (value & mask) ? 0 : 1;
|
||||
}
|
||||
Beb_close(fd, csp0base);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Beb_Set32bitOverflow(int val) {
|
||||
if (!Beb_activated)
|
||||
return val;
|
||||
|
@ -41,6 +41,8 @@ int Beb_SetTop(enum TOPINDEX ind);
|
||||
int Beb_SetMaster(enum MASTERINDEX ind);
|
||||
int Beb_SetActivate(int enable);
|
||||
int Beb_GetActivate(int *retval);
|
||||
int Beb_SetDataStream(enum portPosition port, int enable);
|
||||
int Beb_GetDataStream(enum portPosition port, int *retval);
|
||||
int Beb_Set32bitOverflow(int val);
|
||||
|
||||
int Beb_GetTenGigaFlowControl();
|
||||
|
@ -23,26 +23,26 @@ int Feb_Control_activated = 1;
|
||||
int Feb_Control_hv_fd = -1;
|
||||
unsigned int Feb_Control_idelay[4]; // ll,lr,rl,ll
|
||||
int Feb_Control_counter_bit = 1;
|
||||
unsigned int Feb_Control_staticBits;
|
||||
unsigned int Feb_Control_acquireNReadoutMode;
|
||||
unsigned int Feb_Control_triggerMode;
|
||||
unsigned int Feb_Control_externalEnableMode;
|
||||
unsigned int Feb_Control_subFrameMode;
|
||||
unsigned int Feb_Control_softwareTrigger;
|
||||
unsigned int Feb_Control_staticBits = 0;
|
||||
unsigned int Feb_Control_acquireNReadoutMode = 0;
|
||||
unsigned int Feb_Control_triggerMode = 0;
|
||||
unsigned int Feb_Control_externalEnableMode = 0;
|
||||
unsigned int Feb_Control_subFrameMode = 0;
|
||||
unsigned int Feb_Control_quadMode = 0;
|
||||
|
||||
unsigned int Feb_Control_nimages;
|
||||
double Feb_Control_exposure_time_in_sec;
|
||||
int64_t Feb_Control_subframe_exposure_time_in_10nsec;
|
||||
int64_t Feb_Control_subframe_period_in_10nsec;
|
||||
double Feb_Control_exposure_period_in_sec;
|
||||
unsigned int Feb_Control_nimages = 0;
|
||||
double Feb_Control_exposure_time_in_sec = 0;
|
||||
int64_t Feb_Control_subframe_exposure_time_in_10nsec = 0;
|
||||
int64_t Feb_Control_subframe_period_in_10nsec = 0;
|
||||
double Feb_Control_exposure_period_in_sec = 0;
|
||||
|
||||
unsigned int Feb_Control_trimbit_size;
|
||||
unsigned int *Feb_Control_last_downloaded_trimbits;
|
||||
unsigned int Feb_Control_trimbit_size = 0;
|
||||
unsigned int *Feb_Control_last_downloaded_trimbits = 0;
|
||||
|
||||
int64_t Feb_Control_RateTable_Tau_in_nsec = -1;
|
||||
int64_t Feb_Control_RateTable_Period_in_nsec = -1;
|
||||
unsigned int Feb_Control_rate_correction_table[1024];
|
||||
double Feb_Control_rate_meas[16384];
|
||||
unsigned int Feb_Control_rate_correction_table[1024] = {};
|
||||
double Feb_Control_rate_meas[16384] = {};
|
||||
double ratemax = -1;
|
||||
|
||||
// setup
|
||||
@ -1518,10 +1518,31 @@ int Feb_Control_SetMaster(enum MASTERINDEX ind) {
|
||||
|
||||
int Feb_Control_SetQuad(int val) {
|
||||
LOG(logINFO, ("Setting Quad to %d in Feb\n", val));
|
||||
Feb_Control_quadMode = val;
|
||||
// only setting on the right feb if quad
|
||||
return Feb_Control_SetTop(val == 0 ? TOP_HARDWARE : OW_BOTTOM, 0, 1);
|
||||
}
|
||||
|
||||
int Feb_Control_SetChipSignalsToTrimQuad(int enable) {
|
||||
if (Feb_Control_quadMode) {
|
||||
LOG(logINFO, ("%s chip signals to trim quad\n",
|
||||
enable ? "Enabling" : "Disabling"));
|
||||
unsigned int regval = 0;
|
||||
if (!Feb_Control_ReadRegister(DAQ_REG_HRDWRE, ®val)) {
|
||||
LOG(logERROR, ("Could not set chip signals to trim quad\n"));
|
||||
return 0;
|
||||
}
|
||||
if (enable) {
|
||||
regval |= (DAQ_REG_HRDWRE_PROGRAM_MSK | DAQ_REG_HRDWRE_M8_MSK);
|
||||
} else {
|
||||
regval &= ~(DAQ_REG_HRDWRE_PROGRAM_MSK | DAQ_REG_HRDWRE_M8_MSK);
|
||||
}
|
||||
|
||||
return Feb_Control_WriteRegister(DAQ_REG_HRDWRE, regval);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Feb_Control_SetReadNLines(int value) {
|
||||
LOG(logINFO, ("Setting Read N Lines to %d\n", value));
|
||||
if (!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),
|
||||
|
@ -87,6 +87,7 @@ int Feb_Control_SetTop(enum TOPINDEX ind, int left, int right);
|
||||
void Feb_Control_SetMasterVariable(int val);
|
||||
int Feb_Control_SetMaster(enum MASTERINDEX ind);
|
||||
int Feb_Control_SetQuad(int val);
|
||||
int Feb_Control_SetChipSignalsToTrimQuad(int enable);
|
||||
int Feb_Control_SetReadNLines(int value);
|
||||
int Feb_Control_GetReadNLines();
|
||||
int Feb_Control_WriteRegister(uint32_t offset, uint32_t data);
|
||||
|
@ -27,6 +27,11 @@
|
||||
#define DAQ_REG_HRDWRE_OW_MASTER_MSK (0x00000001 << DAQ_REG_HRDWRE_OW_MASTER_OFST)
|
||||
#define DAQ_REG_HRDWRE_MASTER_OFST (4)
|
||||
#define DAQ_REG_HRDWRE_MASTER_MSK (0x00000001 << DAQ_REG_HRDWRE_MASTER_OFST)
|
||||
#define DAQ_REG_HRDWRE_PROGRAM_OFST (30)
|
||||
#define DAQ_REG_HRDWRE_PROGRAM_MSK (0x00000001 << DAQ_REG_HRDWRE_PROGRAM_OFST)
|
||||
#define DAQ_REG_HRDWRE_M8_OFST (31)
|
||||
#define DAQ_REG_HRDWRE_M8_MSK (0x00000001 << DAQ_REG_HRDWRE_M8_OFST)
|
||||
|
||||
|
||||
#define DAQ_REG_RO_OFFSET 20
|
||||
#define DAQ_REG_STATUS (DAQ_REG_RO_OFFSET + 0) // also pg and fifo status register
|
||||
|
Binary file not shown.
@ -90,6 +90,8 @@ int eiger_virtual_test_mode = 0;
|
||||
int eiger_virtual_quad_mode = 0;
|
||||
int eiger_virtual_read_nlines = 256;
|
||||
int eiger_virtual_interrupt_subframe = 0;
|
||||
int eiger_virtual_left_datastream = 1;
|
||||
int eiger_virtual_right_datastream = 1;
|
||||
#endif
|
||||
|
||||
int isInitCheckDone() { return initCheckDone; }
|
||||
@ -1135,15 +1137,33 @@ int setModule(sls_detector_module myMod, char *mess) {
|
||||
|
||||
// set trimbits
|
||||
sharedMemory_lockLocalLink();
|
||||
|
||||
// if quad, set M8 and PROGRAM manually
|
||||
if (!Feb_Control_SetChipSignalsToTrimQuad(1)) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (!Feb_Control_SetTrimbits(tt, top)) {
|
||||
sprintf(mess, "Could not set module. Could not set trimbits\n");
|
||||
LOG(logERROR, (mess));
|
||||
setSettings(UNDEFINED);
|
||||
LOG(logERROR, ("Settings has been changed to undefined (random "
|
||||
"trim file)\n"));
|
||||
|
||||
// if quad, reset M8 and PROGRAM manually
|
||||
if (!Feb_Control_SetChipSignalsToTrimQuad(0)) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
sharedMemory_unlockLocalLink();
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// if quad, reset M8 and PROGRAM manually
|
||||
if (!Feb_Control_SetChipSignalsToTrimQuad(0)) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
sharedMemory_unlockLocalLink();
|
||||
}
|
||||
#endif
|
||||
@ -2049,6 +2069,40 @@ int getActivate(int *retval) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
int setDataStream(enum portPosition port, int enable) {
|
||||
if (enable < 0) {
|
||||
LOG(logERROR, ("Invalid setDataStream enable argument: %d\n", enable));
|
||||
return FAIL;
|
||||
}
|
||||
#ifdef VIRTUAL
|
||||
if (port == LEFT) {
|
||||
eiger_virtual_left_datastream = enable;
|
||||
} else {
|
||||
eiger_virtual_right_datastream = enable;
|
||||
}
|
||||
#else
|
||||
if (!Beb_SetDataStream(port, enable)) {
|
||||
return FAIL;
|
||||
}
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
|
||||
int getDataStream(enum portPosition port, int *retval) {
|
||||
#ifdef VIRTUAL
|
||||
if (port == LEFT) {
|
||||
*retval = eiger_virtual_left_datastream;
|
||||
} else {
|
||||
*retval = eiger_virtual_right_datastream;
|
||||
}
|
||||
#else
|
||||
if (!Beb_GetDataStream(port, retval)) {
|
||||
return FAIL;
|
||||
}
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
|
||||
int getTenGigaFlowControl() {
|
||||
#ifdef VIRTUAL
|
||||
return eiger_virtual_transmission_flowcontrol_10g;
|
||||
@ -2196,6 +2250,19 @@ void *start_timer(void *arg) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int skipData = 0;
|
||||
if (!eiger_virtual_activate ||
|
||||
(!eiger_virtual_left_datastream && !eiger_virtual_right_datastream)) {
|
||||
skipData = 1;
|
||||
LOG(logWARNING, ("Not sending Left and Right datastream\n"));
|
||||
}
|
||||
if (!eiger_virtual_left_datastream) {
|
||||
LOG(logWARNING, ("Not sending Left datastream\n"));
|
||||
}
|
||||
if (!eiger_virtual_right_datastream) {
|
||||
LOG(logWARNING, ("Not sending Right datastream\n"));
|
||||
}
|
||||
|
||||
int64_t periodNs = eiger_virtual_period;
|
||||
int numFrames = nimages_per_request;
|
||||
int64_t expUs = eiger_virtual_exptime / 1000;
|
||||
@ -2257,7 +2324,7 @@ void *start_timer(void *arg) {
|
||||
}
|
||||
|
||||
// Send data
|
||||
{
|
||||
if (!skipData) {
|
||||
uint64_t frameNr = 0;
|
||||
getNextFrameNumber(&frameNr);
|
||||
// loop over number of frames
|
||||
@ -2342,10 +2409,14 @@ void *start_timer(void *arg) {
|
||||
}
|
||||
}
|
||||
}
|
||||
usleep(eiger_virtual_transmission_delay_left);
|
||||
sendUDPPacket(0, packetData, packetsize);
|
||||
usleep(eiger_virtual_transmission_delay_right);
|
||||
sendUDPPacket(1, packetData2, packetsize);
|
||||
if (eiger_virtual_left_datastream) {
|
||||
usleep(eiger_virtual_transmission_delay_left);
|
||||
sendUDPPacket(0, packetData, packetsize);
|
||||
}
|
||||
if (eiger_virtual_right_datastream) {
|
||||
usleep(eiger_virtual_transmission_delay_right);
|
||||
sendUDPPacket(1, packetData2, packetsize);
|
||||
}
|
||||
}
|
||||
LOG(logINFO, ("Sent frame: %d[%lld]\n", iframes,
|
||||
(long long unsigned int)(frameNr + iframes)));
|
||||
|
@ -35,7 +35,7 @@ XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_LEFT_BASEADDR
|
||||
|
||||
/* Definitions for peripheral PLB_BRAM_10G */
|
||||
#define XPAR_PLB_BRAM_10G_MEM0_BASEADDR 0xD4100000
|
||||
#define XPAR_PLB_BRAM_10G_MEM0_HIGHADDR 0xD410FFFF
|
||||
#define XPAR_PLB_BRAM_10G_MEM0_HIGHADDR
|
||||
|
||||
/* Definitions for peripheral PLB_BRAM_TEMAC */
|
||||
#define XPAR_PLB_BRAM_TEMAC_MEM0_BASEADDR 0xD4000000
|
||||
@ -45,6 +45,18 @@ XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_LEFT_BASEADDR
|
||||
#define XPAR_PLB_GPIO_SYS_BASEADDR 0xD1000000
|
||||
#define XPAR_PLB_GPIO_SYS_HIGHADDR 0xD100FFFF
|
||||
|
||||
// data streaming register
|
||||
// clang-format off
|
||||
#define XPAR_GPIO_P15_STREAMING_REG 0x01e0
|
||||
#define XPAR_GPIO_FRAME_PKT_ENBL_OFST (0)
|
||||
#define XPAR_GPIO_FRAME_PKT_ENBL_MSK (0x00000001 << XPAR_GPIO_FRAME_PKT_ENBL_OFST)
|
||||
#define XPAR_GPIO_RGHT_STRM_DSBL_OFST (1)
|
||||
#define XPAR_GPIO_RGHT_STRM_DSBL_MSK (0x00000001 << XPAR_GPIO_RGHT_STRM_DSBL_OFST)
|
||||
#define XPAR_GPIO_LFT_STRM_DSBL_OFST (2)
|
||||
#define XPAR_GPIO_LFT_STRM_DSBL_MSK (0x00000001 << XPAR_GPIO_LFT_STRM_DSBL_OFST)
|
||||
|
||||
// clang-format on
|
||||
|
||||
/** Command Generator */
|
||||
#define XPAR_CMD_GENERATOR 0xC5000000
|
||||
|
||||
|
@ -474,6 +474,8 @@ int getAllTrimbits();
|
||||
int getBebFPGATemp();
|
||||
int setActivate(int enable);
|
||||
int getActivate(int *retval);
|
||||
int getDataStream(enum portPosition port, int *retval);
|
||||
int setDataStream(enum portPosition port, int enable);
|
||||
|
||||
// gotthard specific - adc phase
|
||||
#elif GOTTHARDD
|
||||
|
@ -246,4 +246,6 @@ int get_all_threshold_energy(int);
|
||||
int get_master(int);
|
||||
int get_csr();
|
||||
int set_gain_caps(int);
|
||||
int get_gain_caps(int);
|
||||
int get_gain_caps(int);
|
||||
int get_datastream(int);
|
||||
int set_datastream(int);
|
||||
|
@ -373,6 +373,8 @@ void function_table() {
|
||||
flist[F_GET_CSR] = &get_csr;
|
||||
flist[F_SET_GAIN_CAPS] = &set_gain_caps;
|
||||
flist[F_GET_GAIN_CAPS] = &get_gain_caps;
|
||||
flist[F_GET_DATASTREAM] = &get_datastream;
|
||||
flist[F_SET_DATASTREAM] = &set_datastream;
|
||||
|
||||
// check
|
||||
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
|
||||
@ -3038,13 +3040,13 @@ int set_pattern_loop_addresses(int file_des) {
|
||||
else {
|
||||
// set
|
||||
if (startAddr >= 0 && stopAddr >= 0) {
|
||||
ret = validate_setPatternLoopAddresses(mess, loopLevel, startAddr,
|
||||
stopAddr);
|
||||
ret = validate_setPatternLoopAddresses(mess, loopLevel,
|
||||
startAddr, stopAddr);
|
||||
}
|
||||
// get
|
||||
if (ret == OK) {
|
||||
ret = validate_getPatternLoopAddresses(mess, loopLevel, &retvals[0],
|
||||
&retvals[1]);
|
||||
ret = validate_getPatternLoopAddresses(
|
||||
mess, loopLevel, &retvals[0], &retvals[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7053,6 +7055,28 @@ int get_receiver_parameters(int file_des) {
|
||||
if (n < 0)
|
||||
return printSocketReadError();
|
||||
|
||||
// data stream left
|
||||
#ifdef EIGERD
|
||||
i32 = 0;
|
||||
getDataStream(LEFT, &i32);
|
||||
#else
|
||||
i32 = 0;
|
||||
#endif
|
||||
n += sendData(file_des, &i32, sizeof(i32), INT32);
|
||||
if (n < 0)
|
||||
return printSocketReadError();
|
||||
|
||||
// data stream right
|
||||
#ifdef EIGERD
|
||||
i32 = 0;
|
||||
getDataStream(RIGHT, &i32);
|
||||
#else
|
||||
i32 = 0;
|
||||
#endif
|
||||
n += sendData(file_des, &i32, sizeof(i32), INT32);
|
||||
if (n < 0)
|
||||
return printSocketReadError();
|
||||
|
||||
// quad
|
||||
#ifdef EIGERD
|
||||
i32 = getQuad();
|
||||
@ -8223,3 +8247,91 @@ int get_gain_caps(int file_des) {
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
|
||||
}
|
||||
|
||||
int get_datastream(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
enum portPosition arg = LEFT;
|
||||
int retval = -1;
|
||||
|
||||
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
|
||||
return printSocketReadError();
|
||||
LOG(logDEBUG1, ("Getting data stream enable [port:%d]\n", arg));
|
||||
|
||||
#ifndef EIGERD
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// get only
|
||||
if (arg != LEFT && arg != RIGHT) {
|
||||
ret = FAIL;
|
||||
sprintf(
|
||||
mess,
|
||||
"Could not get data stream enable. Invalid port position %d. Only left and right allowed\n",
|
||||
arg);
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
ret = getDataStream(arg, &retval);
|
||||
LOG(logDEBUG1, ("datastream (%s) retval: %u\n",
|
||||
(arg == LEFT? "left" : "right"), retval));
|
||||
if (ret == FAIL) {
|
||||
sprintf(mess, "Could not get %s data stream enable.\n",
|
||||
(arg == LEFT ? "left" : "right"));
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
|
||||
}
|
||||
|
||||
int set_datastream(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
int args[2] = {-1, -1};
|
||||
|
||||
if (receiveData(file_des, args, sizeof(args), INT32) < 0)
|
||||
return printSocketReadError();
|
||||
LOG(logDEBUG1, ("Setting data stream enable [left:%d, enable:%d]\n",
|
||||
args[0], args[1]));
|
||||
|
||||
#ifndef EIGERD
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// only set
|
||||
if (Server_VerifyLock() == OK) {
|
||||
enum portPosition port = args[0];
|
||||
int enable = args[1];
|
||||
char msg[256];
|
||||
memset(msg, 0, sizeof(msg));
|
||||
sprintf(msg, "%s %s fpga datastream", (enable ? "enable" : "disable"),
|
||||
(port == LEFT ? "left" : "right"));
|
||||
if (port != LEFT && port != RIGHT) {
|
||||
ret = FAIL;
|
||||
sprintf(mess,
|
||||
"Could not %s. Invalid port position %d. Only left and right allowed\n",
|
||||
msg, port);
|
||||
LOG(logERROR, (mess));
|
||||
} else if (enable != 0 && enable != 1) {
|
||||
ret = FAIL;
|
||||
sprintf(mess, "Could not %s. Invalid enable %d. \n", msg, enable);
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
ret = setDataStream(port, enable);
|
||||
if (ret == FAIL) {
|
||||
sprintf(mess, "Could not %s\n", msg);
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
int retval = -1;
|
||||
ret = getDataStream(port, &retval);
|
||||
LOG(logDEBUG1, ("%s retval: %u\n", msg, retval));
|
||||
if (ret == FAIL) {
|
||||
sprintf(mess, "Could not get %s data stream enable.\n",
|
||||
(port == LEFT ? "left" : "right"));
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
validate(&ret, mess, enable, retval, msg, DEC);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, NULL, 0);
|
||||
}
|
@ -1060,6 +1060,17 @@ class Detector {
|
||||
/** [Eiger] Sets detector size to a quad. 0 (disabled) is default. (Specific
|
||||
* hardware required). */
|
||||
void setQuad(const bool enable);
|
||||
|
||||
/** [Eiger] */
|
||||
Result<bool> getDataStream(const defs::portPosition port,
|
||||
Positions pos = {}) const;
|
||||
|
||||
/** [Eiger] enable or disable data streaming from left or right of detector.
|
||||
* Default: enabled
|
||||
*/
|
||||
void setDataStream(const defs::portPosition port, const bool enable,
|
||||
Positions pos = {});
|
||||
|
||||
///@{
|
||||
|
||||
/** @name Jungfrau Specific */
|
||||
|
@ -1590,6 +1590,34 @@ std::string CmdProxy::Quad(int action) {
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string CmdProxy::DataStream(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "[left|right] [0, 1]\n\t[Eiger] Enables or disables data "
|
||||
"streaming from left or/and right side of detector. 1 (enabled) "
|
||||
"by default."
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
if (args.size() != 1) {
|
||||
WrongNumberOfParameters(1);
|
||||
}
|
||||
auto t = det->getDataStream(StringTo<defs::portPosition>(args[0]),
|
||||
std::vector<int>{det_id});
|
||||
os << OutString(t) << '\n';
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
if (args.size() != 2) {
|
||||
WrongNumberOfParameters(2);
|
||||
}
|
||||
det->setDataStream(StringTo<defs::portPosition>(args[0]),
|
||||
StringTo<bool>(args[1]), std::vector<int>{det_id});
|
||||
os << args << '\n';
|
||||
} else {
|
||||
throw sls::RuntimeError("Unknown action");
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
/* Jungfrau Specific */
|
||||
|
||||
std::string CmdProxy::TemperatureEvent(int action) {
|
||||
|
@ -915,6 +915,7 @@ class CmdProxy {
|
||||
{"pulsenmove", &CmdProxy::PulsePixelAndMove},
|
||||
{"pulsechip", &CmdProxy::PulseChip},
|
||||
{"quad", &CmdProxy::Quad},
|
||||
{"datastream", &CmdProxy::DataStream},
|
||||
|
||||
/* Jungfrau Specific */
|
||||
{"temp_threshold", &CmdProxy::temp_threshold},
|
||||
@ -1110,6 +1111,7 @@ class CmdProxy {
|
||||
std::string PulsePixelAndMove(int action);
|
||||
std::string PulseChip(int action);
|
||||
std::string Quad(int action);
|
||||
std::string DataStream(int action);
|
||||
/* Jungfrau Specific */
|
||||
std::string TemperatureEvent(int action);
|
||||
/* Gotthard Specific */
|
||||
|
@ -1369,6 +1369,16 @@ void Detector::setQuad(const bool enable) {
|
||||
pimpl->Parallel(&Module::setQuad, {}, enable);
|
||||
}
|
||||
|
||||
Result<bool> Detector::getDataStream(const defs::portPosition port,
|
||||
Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getDataStream, pos, port);
|
||||
}
|
||||
|
||||
void Detector::setDataStream(const defs::portPosition port, const bool enable,
|
||||
Positions pos) {
|
||||
pimpl->Parallel(&Module::setDataStream, pos, port, enable);
|
||||
}
|
||||
|
||||
// Jungfrau Specific
|
||||
|
||||
Result<int> Detector::getThresholdTemperature(Positions pos) const {
|
||||
|
@ -1509,6 +1509,18 @@ void Module::setQuad(const bool enable) {
|
||||
}
|
||||
}
|
||||
|
||||
bool Module::getDataStream(const portPosition port) const {
|
||||
return sendToDetector<int>(F_GET_DATASTREAM, static_cast<int>(port));
|
||||
}
|
||||
|
||||
void Module::setDataStream(const portPosition port, const bool enable) {
|
||||
int args[]{static_cast<int>(port), static_cast<int>(enable)};
|
||||
sendToDetector(F_SET_DATASTREAM, args, nullptr);
|
||||
if (shm()->useReceiverFlag) {
|
||||
sendToReceiver(F_RECEIVER_SET_DATASTREAM, args, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// Jungfrau Specific
|
||||
|
||||
int Module::getThresholdTemperature() const {
|
||||
|
@ -343,6 +343,8 @@ class Module : public virtual slsDetectorDefs {
|
||||
void pulseChip(int n_pulses = 0);
|
||||
bool getQuad() const;
|
||||
void setQuad(const bool enable);
|
||||
bool getDataStream(const portPosition port) const;
|
||||
void setDataStream(const portPosition port, const bool enable);
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
|
@ -649,3 +649,43 @@ TEST_CASE("quad", "[.cmd]") {
|
||||
REQUIRE_THROWS(proxy.Call("quad", {}, -1, GET));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("datastream", "[.cmd]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
if (det_type == defs::EIGER) {
|
||||
auto prev_val_left = det.getDataStream(defs::LEFT);
|
||||
auto prev_val_right = det.getDataStream(defs::RIGHT);
|
||||
// no "left" or "right"
|
||||
REQUIRE_THROWS(proxy.Call("datastream", {"1"}, -1, PUT));
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("datastream", {"left", "0"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "datastream left 0\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("datastream", {"right", "0"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "datastream right 0\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("datastream", {"left", "1"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "datastream left 1\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("datastream", {"right", "1"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "datastream right 1\n");
|
||||
}
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setDataStream(defs::LEFT, prev_val_left[i], {i});
|
||||
det.setDataStream(defs::RIGHT, prev_val_right[i], {i});
|
||||
}
|
||||
} else {
|
||||
REQUIRE_THROWS(proxy.Call("datastream", {}, -1, GET));
|
||||
REQUIRE_THROWS(proxy.Call("datastream", {"1"}, -1, PUT));
|
||||
REQUIRE_THROWS(proxy.Call("datastream", {"left", "1"}, -1, PUT));
|
||||
}
|
||||
}
|
@ -3,7 +3,8 @@ set(SOURCES
|
||||
src/ClientInterface.cpp
|
||||
src/Receiver.cpp
|
||||
src/File.cpp
|
||||
src/BinaryFile.cpp
|
||||
src/BinaryDataFile.cpp
|
||||
src/BinaryMasterFile.cpp
|
||||
src/ThreadObject.cpp
|
||||
src/Listener.cpp
|
||||
src/DataProcessor.cpp
|
||||
@ -22,7 +23,9 @@ if (SLS_USE_HDF5)
|
||||
-DHDF5C ${HDF5_DEFINITIONS}
|
||||
)
|
||||
list (APPEND SOURCES
|
||||
src/HDF5File.cpp
|
||||
src/HDF5DataFile.cpp
|
||||
src/HDF5MasterFile.cpp
|
||||
src/HDF5VirtualFile.cpp
|
||||
)
|
||||
endif (SLS_USE_HDF5)
|
||||
|
||||
|
108
slsReceiverSoftware/src/BinaryDataFile.cpp
Normal file
108
slsReceiverSoftware/src/BinaryDataFile.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
#include "BinaryDataFile.h"
|
||||
|
||||
BinaryDataFile::BinaryDataFile(const int index) : File(BINARY), index_(index) {}
|
||||
|
||||
BinaryDataFile::~BinaryDataFile() { CloseFile(); }
|
||||
|
||||
void BinaryDataFile::CloseFile() {
|
||||
if (fd_) {
|
||||
fclose(fd_);
|
||||
}
|
||||
fd_ = nullptr;
|
||||
}
|
||||
|
||||
void BinaryDataFile::CreateFirstBinaryDataFile(
|
||||
const std::string filePath, const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode,
|
||||
const int modulePos, const int numUnitsPerReadout,
|
||||
const uint32_t udpPortNumber, const uint32_t maxFramesPerFile) {
|
||||
|
||||
subFileIndex_ = 0;
|
||||
numFramesInFile_ = 0;
|
||||
|
||||
filePath_ = filePath;
|
||||
fileNamePrefix_ = fileNamePrefix;
|
||||
fileIndex_ = fileIndex;
|
||||
overWriteEnable_ = overWriteEnable;
|
||||
silentMode_ = silentMode;
|
||||
detIndex_ = modulePos;
|
||||
numUnitsPerReadout_ = numUnitsPerReadout;
|
||||
udpPortNumber_ = udpPortNumber;
|
||||
maxFramesPerFile_ = maxFramesPerFile;
|
||||
|
||||
CreateFile();
|
||||
}
|
||||
|
||||
void BinaryDataFile::CreateFile() {
|
||||
numFramesInFile_ = 0;
|
||||
|
||||
std::ostringstream os;
|
||||
os << filePath_ << "/" << fileNamePrefix_ << "_d"
|
||||
<< (detIndex_ * numUnitsPerReadout_ + index_) << "_f" << subFileIndex_
|
||||
<< '_' << fileIndex_ << ".raw";
|
||||
fileName_ = os.str();
|
||||
|
||||
if (!overWriteEnable_) {
|
||||
if (nullptr == (fd_ = fopen((const char *)fileName_.c_str(), "wx"))) {
|
||||
fd_ = nullptr;
|
||||
throw sls::RuntimeError("Could not create/overwrite file " +
|
||||
fileName_);
|
||||
}
|
||||
} else if (nullptr == (fd_ = fopen((const char *)fileName_.c_str(), "w"))) {
|
||||
fd_ = nullptr;
|
||||
throw sls::RuntimeError("Could not create file " + fileName_);
|
||||
}
|
||||
// setting to no file buffering
|
||||
setvbuf(fd_, nullptr, _IONBF, 0);
|
||||
|
||||
if (!silentMode_) {
|
||||
LOG(logINFO) << "[" << udpPortNumber_
|
||||
<< "]: Binary File created: " << fileName_;
|
||||
}
|
||||
}
|
||||
|
||||
void BinaryDataFile::WriteToFile(char *buffer, const int buffersize,
|
||||
const uint64_t currentFrameNumber,
|
||||
const uint32_t numPacketsCaught) {
|
||||
// check if maxframesperfile = 0 for infinite
|
||||
if (maxFramesPerFile_ && (numFramesInFile_ >= maxFramesPerFile_)) {
|
||||
CloseFile();
|
||||
++subFileIndex_;
|
||||
CreateFile();
|
||||
}
|
||||
numFramesInFile_++;
|
||||
|
||||
// write to file
|
||||
int ret = 0;
|
||||
|
||||
// contiguous bitset
|
||||
if (sizeof(sls_bitset) == sizeof(bitset_storage)) {
|
||||
ret = fwrite(buffer, 1, buffersize, fd_);
|
||||
}
|
||||
|
||||
// not contiguous bitset
|
||||
else {
|
||||
// write detector header
|
||||
ret = fwrite(buffer, 1, sizeof(sls_detector_header), fd_);
|
||||
|
||||
// get contiguous representation of bit mask
|
||||
bitset_storage storage;
|
||||
memset(storage, 0, sizeof(bitset_storage));
|
||||
sls_bitset bits = *(sls_bitset *)(buffer + sizeof(sls_detector_header));
|
||||
for (int i = 0; i < MAX_NUM_PACKETS; ++i)
|
||||
storage[i >> 3] |= (bits[i] << (i & 7));
|
||||
// write bitmask
|
||||
ret += fwrite((char *)storage, 1, sizeof(bitset_storage), fd_);
|
||||
|
||||
// write data
|
||||
ret += fwrite(buffer + sizeof(sls_detector_header), 1,
|
||||
buffersize - sizeof(sls_receiver_header), fd_);
|
||||
}
|
||||
|
||||
// if write error
|
||||
if (ret != buffersize) {
|
||||
throw sls::RuntimeError(std::to_string(index_) +
|
||||
" : Write to file failed for image number " +
|
||||
std::to_string(currentFrameNumber));
|
||||
}
|
||||
}
|
43
slsReceiverSoftware/src/BinaryDataFile.h
Normal file
43
slsReceiverSoftware/src/BinaryDataFile.h
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include "File.h"
|
||||
|
||||
class BinaryDataFile : private virtual slsDetectorDefs, public File {
|
||||
|
||||
public:
|
||||
BinaryDataFile(const int index);
|
||||
~BinaryDataFile();
|
||||
|
||||
void CloseFile() override;
|
||||
void CreateFirstBinaryDataFile(const std::string filePath,
|
||||
const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex,
|
||||
const bool overWriteEnable,
|
||||
const bool silentMode, const int modulePos,
|
||||
const int numUnitsPerReadout,
|
||||
const uint32_t udpPortNumber,
|
||||
const uint32_t maxFramesPerFile) override;
|
||||
|
||||
void WriteToFile(char *buffer, const int buffersize,
|
||||
const uint64_t currentFrameNumber,
|
||||
const uint32_t numPacketsCaught) override;
|
||||
|
||||
private:
|
||||
void CreateFile();
|
||||
|
||||
uint32_t index_;
|
||||
FILE *fd_{nullptr};
|
||||
std::string fileName_;
|
||||
uint32_t numFramesInFile_{0};
|
||||
uint32_t subFileIndex_{0};
|
||||
|
||||
std::string filePath_;
|
||||
std::string fileNamePrefix_;
|
||||
uint64_t fileIndex_{0};
|
||||
bool overWriteEnable_{false};
|
||||
bool silentMode_{false};
|
||||
int detIndex_{0};
|
||||
int numUnitsPerReadout_{0};
|
||||
uint32_t udpPortNumber_{0};
|
||||
uint32_t maxFramesPerFile_{0};
|
||||
};
|
@ -1,175 +0,0 @@
|
||||
/************************************************
|
||||
* @file BinaryFile.cpp
|
||||
* @short sets/gets properties for the binary file,
|
||||
* creates/closes the file and writes data to it
|
||||
***********************************************/
|
||||
|
||||
#include "BinaryFile.h"
|
||||
#include "Fifo.h"
|
||||
#include "MasterAttributes.h"
|
||||
#include "receiver_defs.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
|
||||
FILE *BinaryFile::masterfd = nullptr;
|
||||
|
||||
BinaryFile::BinaryFile(int ind, uint32_t *maxf, int *nd, std::string *fname,
|
||||
std::string *fpath, uint64_t *findex, bool *owenable,
|
||||
int *dindex, int *nunits, uint64_t *nf, uint32_t *dr,
|
||||
uint32_t *portno, bool *smode)
|
||||
: File(ind, BINARY, maxf, nd, fname, fpath, findex, owenable, dindex,
|
||||
nunits, nf, dr, portno, smode) {
|
||||
#ifdef VERBOSE
|
||||
PrintMembers();
|
||||
#endif
|
||||
}
|
||||
|
||||
BinaryFile::~BinaryFile() { CloseAllFiles(); }
|
||||
|
||||
void BinaryFile::PrintMembers(TLogLevel level) {
|
||||
File::PrintMembers(level);
|
||||
LOG(logINFO) << "Max Frames Per File: " << *maxFramesPerFile;
|
||||
LOG(logINFO) << "Number of Frames in File: " << numFramesInFile;
|
||||
}
|
||||
|
||||
void BinaryFile::CreateFile() {
|
||||
numFramesInFile = 0;
|
||||
numActualPacketsInFile = 0;
|
||||
|
||||
std::ostringstream os;
|
||||
os << *filePath << "/" << *fileNamePrefix << "_d"
|
||||
<< (*detIndex * (*numUnitsPerDetector) + index) << "_f" << subFileIndex
|
||||
<< '_' << *fileIndex << ".raw";
|
||||
currentFileName = os.str();
|
||||
|
||||
if (!(*overWriteEnable)) {
|
||||
if (nullptr ==
|
||||
(filefd = fopen((const char *)currentFileName.c_str(), "wx"))) {
|
||||
filefd = nullptr;
|
||||
throw sls::RuntimeError("Could not create/overwrite file " +
|
||||
currentFileName);
|
||||
}
|
||||
} else if (nullptr ==
|
||||
(filefd = fopen((const char *)currentFileName.c_str(), "w"))) {
|
||||
filefd = nullptr;
|
||||
throw sls::RuntimeError("Could not create file " + currentFileName);
|
||||
}
|
||||
// setting to no file buffering
|
||||
setvbuf(filefd, nullptr, _IONBF, 0);
|
||||
|
||||
if (!(*silentMode)) {
|
||||
LOG(logINFO) << "[" << *udpPortNumber
|
||||
<< "]: Binary File created: " << currentFileName;
|
||||
}
|
||||
}
|
||||
|
||||
void BinaryFile::CloseCurrentFile() {
|
||||
if (filefd)
|
||||
fclose(filefd);
|
||||
filefd = nullptr;
|
||||
}
|
||||
|
||||
void BinaryFile::CloseAllFiles() {
|
||||
CloseCurrentFile();
|
||||
if (master) {
|
||||
if (masterfd)
|
||||
fclose(masterfd);
|
||||
masterfd = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int BinaryFile::WriteData(char *buf, int bsize) {
|
||||
if (!filefd)
|
||||
return 0;
|
||||
return fwrite(buf, 1, bsize, filefd);
|
||||
}
|
||||
|
||||
void BinaryFile::WriteToFile(char *buffer, int buffersize,
|
||||
uint64_t currentFrameNumber,
|
||||
uint32_t numPacketsCaught) {
|
||||
// check if maxframesperfile = 0 for infinite
|
||||
if ((*maxFramesPerFile) && (numFramesInFile >= (*maxFramesPerFile))) {
|
||||
CloseCurrentFile();
|
||||
++subFileIndex;
|
||||
CreateFile();
|
||||
}
|
||||
numFramesInFile++;
|
||||
numActualPacketsInFile += numPacketsCaught;
|
||||
|
||||
// write to file
|
||||
int ret = 0;
|
||||
|
||||
// contiguous bitset
|
||||
if (sizeof(sls_bitset) == sizeof(bitset_storage)) {
|
||||
ret = WriteData(buffer, buffersize);
|
||||
}
|
||||
|
||||
// not contiguous bitset
|
||||
else {
|
||||
// write detector header
|
||||
ret = WriteData(buffer, sizeof(sls_detector_header));
|
||||
|
||||
// get contiguous representation of bit mask
|
||||
bitset_storage storage;
|
||||
memset(storage, 0, sizeof(bitset_storage));
|
||||
sls_bitset bits = *(sls_bitset *)(buffer + sizeof(sls_detector_header));
|
||||
for (int i = 0; i < MAX_NUM_PACKETS; ++i)
|
||||
storage[i >> 3] |= (bits[i] << (i & 7));
|
||||
// write bitmask
|
||||
ret += WriteData((char *)storage, sizeof(bitset_storage));
|
||||
|
||||
// write data
|
||||
ret += WriteData(buffer + sizeof(sls_detector_header),
|
||||
buffersize - sizeof(sls_receiver_header));
|
||||
}
|
||||
|
||||
// if write error
|
||||
if (ret != buffersize) {
|
||||
throw sls::RuntimeError(std::to_string(index) +
|
||||
" : Write to file failed for image number " +
|
||||
std::to_string(currentFrameNumber));
|
||||
}
|
||||
}
|
||||
|
||||
void BinaryFile::CreateMasterFile(bool masterFileWriteEnable,
|
||||
MasterAttributes *attr) {
|
||||
// beginning of every acquisition
|
||||
numFramesInFile = 0;
|
||||
numActualPacketsInFile = 0;
|
||||
|
||||
if (masterFileWriteEnable && master) {
|
||||
|
||||
std::ostringstream os;
|
||||
os << *filePath << "/" << *fileNamePrefix << "_master"
|
||||
<< "_" << *fileIndex << ".raw";
|
||||
masterFileName = os.str();
|
||||
if (!(*silentMode)) {
|
||||
LOG(logINFO) << "Master File: " << masterFileName;
|
||||
}
|
||||
|
||||
// create master file
|
||||
if (!(*overWriteEnable)) {
|
||||
if (nullptr == (masterfd = fopen(
|
||||
(const char *)masterFileName.c_str(), "wx"))) {
|
||||
masterfd = nullptr;
|
||||
throw sls::RuntimeError("Could not create binary master file "
|
||||
"(without overwrite enable) " +
|
||||
masterFileName);
|
||||
}
|
||||
} else if (nullptr ==
|
||||
(masterfd =
|
||||
fopen((const char *)masterFileName.c_str(), "w"))) {
|
||||
masterfd = nullptr;
|
||||
throw sls::RuntimeError("Could not create binary master file "
|
||||
"(with overwrite enable) " +
|
||||
masterFileName);
|
||||
}
|
||||
|
||||
attr->WriteMasterBinaryAttributes(masterfd);
|
||||
if (masterfd)
|
||||
fclose(masterfd);
|
||||
masterfd = nullptr;
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
#pragma once
|
||||
/************************************************
|
||||
* @file BinaryFile.h
|
||||
* @short sets/gets properties for the binary file,
|
||||
* creates/closes the file and writes data to it
|
||||
***********************************************/
|
||||
/**
|
||||
*@short sets/gets properties for the binary file, creates/closes the file and
|
||||
*writes data to it
|
||||
*/
|
||||
|
||||
#include "File.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
class BinaryFile : private virtual slsDetectorDefs, public File {
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* creates the File Writer
|
||||
* @param ind self index
|
||||
* @param maxf pointer to max frames per file
|
||||
* @param nd pointer to number of detectors in each dimension
|
||||
* @param fname pointer to file name prefix
|
||||
* @param fpath pointer to file path
|
||||
* @param findex pointer to file index
|
||||
* @param owenable pointer to over write enable
|
||||
* @param dindex pointer to detector index
|
||||
* @param nunits pointer to number of theads/ units per detector
|
||||
* @param nf pointer to number of images in acquisition
|
||||
* @param dr pointer to dynamic range
|
||||
* @param portno pointer to udp port number for logging
|
||||
* @param smode pointer to silent mode
|
||||
*/
|
||||
BinaryFile(int ind, uint32_t *maxf, int *nd, std::string *fname,
|
||||
std::string *fpath, uint64_t *findex, bool *owenable,
|
||||
int *dindex, int *nunits, uint64_t *nf, uint32_t *dr,
|
||||
uint32_t *portno, bool *smode);
|
||||
~BinaryFile();
|
||||
|
||||
void PrintMembers(TLogLevel level = logDEBUG1) override;
|
||||
void CreateFile() override;
|
||||
void CreateMasterFile(bool masterFileWriteEnable,
|
||||
MasterAttributes *attr) override;
|
||||
void CloseCurrentFile() override;
|
||||
void CloseAllFiles() override;
|
||||
void WriteToFile(char *buffer, int buffersize, uint64_t currentFrameNumber,
|
||||
uint32_t numPacketsCaught) override;
|
||||
|
||||
private:
|
||||
int WriteData(char *buf, int bsize);
|
||||
|
||||
FILE *filefd = nullptr;
|
||||
static FILE *masterfd;
|
||||
uint32_t numFramesInFile = 0;
|
||||
uint64_t numActualPacketsInFile = 0;
|
||||
};
|
44
slsReceiverSoftware/src/BinaryMasterFile.cpp
Normal file
44
slsReceiverSoftware/src/BinaryMasterFile.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
#include "BinaryMasterFile.h"
|
||||
#include "MasterAttributes.h"
|
||||
|
||||
BinaryMasterFile::BinaryMasterFile() : File(BINARY) {}
|
||||
|
||||
BinaryMasterFile::~BinaryMasterFile() { CloseFile(); }
|
||||
|
||||
void BinaryMasterFile::CloseFile() {
|
||||
if (fd_) {
|
||||
fclose(fd_);
|
||||
}
|
||||
fd_ = nullptr;
|
||||
}
|
||||
|
||||
void BinaryMasterFile::CreateMasterFile(const std::string filePath,
|
||||
const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex,
|
||||
const bool overWriteEnable,
|
||||
const bool silentMode,
|
||||
MasterAttributes *attr) {
|
||||
// create file name
|
||||
std::ostringstream os;
|
||||
os << filePath << "/" << fileNamePrefix << "_master"
|
||||
<< "_" << fileIndex << ".raw";
|
||||
fileName_ = os.str();
|
||||
|
||||
// create file
|
||||
if (!overWriteEnable) {
|
||||
if (nullptr == (fd_ = fopen((const char *)fileName_.c_str(), "wx"))) {
|
||||
fd_ = nullptr;
|
||||
throw sls::RuntimeError("Could not create binary master file " +
|
||||
fileName_);
|
||||
}
|
||||
} else if (nullptr == (fd_ = fopen((const char *)fileName_.c_str(), "w"))) {
|
||||
fd_ = nullptr;
|
||||
throw sls::RuntimeError(
|
||||
"Could not create/overwrite binary master file " + fileName_);
|
||||
}
|
||||
if (!silentMode) {
|
||||
LOG(logINFO) << "Master File: " << fileName_;
|
||||
}
|
||||
attr->WriteMasterBinaryAttributes(fd_);
|
||||
CloseFile();
|
||||
}
|
22
slsReceiverSoftware/src/BinaryMasterFile.h
Normal file
22
slsReceiverSoftware/src/BinaryMasterFile.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "File.h"
|
||||
#include "MasterAttributes.h"
|
||||
|
||||
class BinaryMasterFile : private virtual slsDetectorDefs, public File {
|
||||
|
||||
public:
|
||||
BinaryMasterFile();
|
||||
~BinaryMasterFile();
|
||||
|
||||
void CloseFile() override;
|
||||
void CreateMasterFile(const std::string filePath,
|
||||
const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable,
|
||||
const bool silentMode,
|
||||
MasterAttributes *attr) override;
|
||||
|
||||
private:
|
||||
FILE *fd_{nullptr};
|
||||
std::string fileName_;
|
||||
};
|
@ -209,6 +209,8 @@ int ClientInterface::functionTable(){
|
||||
flist[F_GET_RECEIVER_STREAMING_HWM] = &ClientInterface::get_streaming_hwm;
|
||||
flist[F_SET_RECEIVER_STREAMING_HWM] = &ClientInterface::set_streaming_hwm;
|
||||
flist[F_RECEIVER_SET_ALL_THRESHOLD] = &ClientInterface::set_all_threshold;
|
||||
flist[F_RECEIVER_SET_DATASTREAM] = &ClientInterface::set_detector_datastream;
|
||||
|
||||
|
||||
for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) {
|
||||
LOG(logDEBUG1) << "function fnum: " << i << " (" <<
|
||||
@ -401,6 +403,8 @@ int ClientInterface::setup_receiver(Interface &socket) {
|
||||
impl()->setSubPeriod(std::chrono::nanoseconds(arg.subExpTimeNs) +
|
||||
std::chrono::nanoseconds(arg.subDeadTimeNs));
|
||||
impl()->setActivate(static_cast<bool>(arg.activate));
|
||||
impl()->setDetectorDataStream(LEFT, arg.dataStreamLeft);
|
||||
impl()->setDetectorDataStream(RIGHT, arg.dataStreamRight);
|
||||
try {
|
||||
impl()->setQuad(arg.quad == 0 ? false : true);
|
||||
} catch (const RuntimeError &e) {
|
||||
@ -1695,3 +1699,25 @@ int ClientInterface::set_all_threshold(Interface &socket) {
|
||||
impl()->setThresholdEnergy(eVs);
|
||||
return socket.Send(OK);
|
||||
}
|
||||
|
||||
int ClientInterface::set_detector_datastream(Interface &socket) {
|
||||
int args[2]{-1, -1};
|
||||
socket.Receive(args);
|
||||
portPosition port = static_cast<portPosition>(args[0]);
|
||||
switch (port) {
|
||||
case LEFT:
|
||||
case RIGHT:
|
||||
break;
|
||||
default:
|
||||
throw RuntimeError("Invalid port type");
|
||||
}
|
||||
bool enable = static_cast<int>(args[1]);
|
||||
LOG(logDEBUG1) << "Setting datastream (" << sls::ToString(port) << ") to "
|
||||
<< sls::ToString(enable);
|
||||
if (myDetectorType != EIGER)
|
||||
functionNotImplemented();
|
||||
verifyIdle(socket);
|
||||
impl()->setDetectorDataStream(port, enable);
|
||||
return socket.Send(OK);
|
||||
}
|
||||
|
||||
|
@ -162,6 +162,8 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
int get_streaming_hwm(sls::ServerInterface &socket);
|
||||
int set_streaming_hwm(sls::ServerInterface &socket);
|
||||
int set_all_threshold(sls::ServerInterface &socket);
|
||||
int set_detector_datastream(sls::ServerInterface &socket);
|
||||
|
||||
|
||||
Implementation *impl() {
|
||||
if (receiver != nullptr) {
|
||||
|
@ -6,12 +6,15 @@
|
||||
***********************************************/
|
||||
|
||||
#include "DataProcessor.h"
|
||||
#include "BinaryFile.h"
|
||||
#include "BinaryDataFile.h"
|
||||
#include "BinaryMasterFile.h"
|
||||
#include "Fifo.h"
|
||||
#include "GeneralData.h"
|
||||
#include "MasterAttributes.h"
|
||||
#ifdef HDF5C
|
||||
#include "HDF5File.h"
|
||||
#include "HDF5DataFile.h"
|
||||
#include "HDF5MasterFile.h"
|
||||
#include "HDF5VirtualFile.h"
|
||||
#endif
|
||||
#include "DataStreamer.h"
|
||||
#include "sls/sls_detector_exceptions.h"
|
||||
@ -20,158 +23,234 @@
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
const std::string DataProcessor::TypeName = "DataProcessor";
|
||||
const std::string DataProcessor::typeName_ = "DataProcessor";
|
||||
|
||||
DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo *f,
|
||||
fileFormat *ftype, bool fwenable, bool *mfwenable,
|
||||
bool *dsEnable, uint32_t *freq, uint32_t *timer,
|
||||
uint32_t *sfnum, bool *fp, bool *act,
|
||||
bool *depaden, bool *sm, std::vector<int> *cdl,
|
||||
int *cdo, int *cad)
|
||||
: ThreadObject(ind, TypeName), fifo(f), myDetectorType(dtype),
|
||||
dataStreamEnable(dsEnable), fileFormatType(ftype),
|
||||
fileWriteEnable(fwenable), masterFileWriteEnable(mfwenable),
|
||||
streamingFrequency(freq), streamingTimerInMs(timer),
|
||||
streamingStartFnum(sfnum), activated(act),
|
||||
deactivatedPaddingEnable(depaden), silentMode(sm), framePadding(fp),
|
||||
ctbDbitList(cdl), ctbDbitOffset(cdo), ctbAnalogDataBytes(cad),
|
||||
firstStreamerFrame(false) {
|
||||
LOG(logDEBUG) << "DataProcessor " << ind << " created";
|
||||
memset((void *)&timerBegin, 0, sizeof(timespec));
|
||||
DataProcessor::DataProcessor(int index, detectorType detectorType, Fifo *fifo,
|
||||
bool *activated, bool *deactivatedPaddingEnable,
|
||||
bool *dataStreamEnable,
|
||||
uint32_t *streamingFrequency,
|
||||
uint32_t *streamingTimerInMs,
|
||||
uint32_t *streamingStartFnum, bool *framePadding,
|
||||
std::vector<int> *ctbDbitList, int *ctbDbitOffset,
|
||||
int *ctbAnalogDataBytes, std::mutex *hdf5Lib)
|
||||
: ThreadObject(index, typeName_), fifo_(fifo), detectorType_(detectorType),
|
||||
dataStreamEnable_(dataStreamEnable), activated_(activated),
|
||||
deactivatedPaddingEnable_(deactivatedPaddingEnable),
|
||||
streamingFrequency_(streamingFrequency),
|
||||
streamingTimerInMs_(streamingTimerInMs),
|
||||
streamingStartFnum_(streamingStartFnum), framePadding_(framePadding),
|
||||
ctbDbitList_(ctbDbitList), ctbDbitOffset_(ctbDbitOffset),
|
||||
ctbAnalogDataBytes_(ctbAnalogDataBytes), firstStreamerFrame_(false),
|
||||
hdf5Lib_(hdf5Lib) {
|
||||
|
||||
LOG(logDEBUG) << "DataProcessor " << index << " created";
|
||||
|
||||
memset((void *)&timerbegin_, 0, sizeof(timespec));
|
||||
}
|
||||
|
||||
DataProcessor::~DataProcessor() { delete file; }
|
||||
DataProcessor::~DataProcessor() { DeleteFiles(); }
|
||||
|
||||
/** getters */
|
||||
|
||||
bool DataProcessor::GetStartedFlag() { return startedFlag; }
|
||||
bool DataProcessor::GetStartedFlag() { return startedFlag_; }
|
||||
|
||||
uint64_t DataProcessor::GetNumFramesCaught() { return numFramesCaught; }
|
||||
uint64_t DataProcessor::GetNumFramesCaught() { return numFramesCaught_; }
|
||||
|
||||
uint64_t DataProcessor::GetCurrentFrameIndex() { return currentFrameIndex; }
|
||||
uint64_t DataProcessor::GetCurrentFrameIndex() { return currentFrameIndex_; }
|
||||
|
||||
uint64_t DataProcessor::GetProcessedIndex() {
|
||||
return currentFrameIndex - firstIndex;
|
||||
return currentFrameIndex_ - firstIndex_;
|
||||
}
|
||||
|
||||
void DataProcessor::SetFifo(Fifo *f) { fifo = f; }
|
||||
void DataProcessor::SetFifo(Fifo *fifo) { fifo_ = fifo; }
|
||||
|
||||
void DataProcessor::ResetParametersforNewAcquisition() {
|
||||
StopRunning();
|
||||
startedFlag = false;
|
||||
numFramesCaught = 0;
|
||||
firstIndex = 0;
|
||||
currentFrameIndex = 0;
|
||||
firstStreamerFrame = true;
|
||||
startedFlag_ = false;
|
||||
numFramesCaught_ = 0;
|
||||
firstIndex_ = 0;
|
||||
currentFrameIndex_ = 0;
|
||||
firstStreamerFrame_ = true;
|
||||
}
|
||||
|
||||
void DataProcessor::RecordFirstIndex(uint64_t fnum) {
|
||||
// listen to this fnum, later +1
|
||||
currentFrameIndex = fnum;
|
||||
currentFrameIndex_ = fnum;
|
||||
|
||||
startedFlag = true;
|
||||
firstIndex = fnum;
|
||||
startedFlag_ = true;
|
||||
firstIndex_ = fnum;
|
||||
|
||||
LOG(logDEBUG1) << index << " First Index:" << firstIndex;
|
||||
LOG(logDEBUG1) << index << " First Index:" << firstIndex_;
|
||||
}
|
||||
|
||||
void DataProcessor::SetGeneralData(GeneralData *g) {
|
||||
generalData = g;
|
||||
if (file != nullptr) {
|
||||
if (file->GetFileType() == HDF5) {
|
||||
file->SetNumberofPixels(generalData->nPixelsX,
|
||||
generalData->nPixelsY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DataProcessor::SetFileFormat(const fileFormat f) {
|
||||
if ((file != nullptr) && file->GetFileType() != f) {
|
||||
// remember the pointer values before they are destroyed
|
||||
int nd[MAX_DIMENSIONS];
|
||||
nd[0] = 0;
|
||||
nd[1] = 0;
|
||||
uint32_t *maxf = nullptr;
|
||||
std::string *fname = nullptr;
|
||||
std::string *fpath = nullptr;
|
||||
uint64_t *findex = nullptr;
|
||||
bool *owenable = nullptr;
|
||||
int *dindex = nullptr;
|
||||
int *nunits = nullptr;
|
||||
uint64_t *nf = nullptr;
|
||||
uint32_t *dr = nullptr;
|
||||
uint32_t *port = nullptr;
|
||||
file->GetMemberPointerValues(nd, maxf, fname, fpath, findex, owenable,
|
||||
dindex, nunits, nf, dr, port);
|
||||
// create file writer with same pointers
|
||||
SetupFileWriter(fileWriteEnable, nd, maxf, fname, fpath, findex,
|
||||
owenable, dindex, nunits, nf, dr, port);
|
||||
}
|
||||
}
|
||||
|
||||
void DataProcessor::SetupFileWriter(bool fwe, int *nd, uint32_t *maxf,
|
||||
std::string *fname, std::string *fpath,
|
||||
uint64_t *findex, bool *owenable,
|
||||
int *dindex, int *nunits, uint64_t *nf,
|
||||
uint32_t *dr, uint32_t *portno,
|
||||
GeneralData *g) {
|
||||
fileWriteEnable = fwe;
|
||||
if (g != nullptr)
|
||||
generalData = g;
|
||||
|
||||
if (file != nullptr) {
|
||||
delete file;
|
||||
file = nullptr;
|
||||
}
|
||||
|
||||
if (fileWriteEnable) {
|
||||
switch (*fileFormatType) {
|
||||
#ifdef HDF5C
|
||||
case HDF5:
|
||||
file = new HDF5File(index, maxf, nd, fname, fpath, findex, owenable,
|
||||
dindex, nunits, nf, dr, portno,
|
||||
generalData->nPixelsX, generalData->nPixelsY,
|
||||
silentMode);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
file =
|
||||
new BinaryFile(index, maxf, nd, fname, fpath, findex, owenable,
|
||||
dindex, nunits, nf, dr, portno, silentMode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// only the first file
|
||||
void DataProcessor::CreateNewFile(MasterAttributes *attr) {
|
||||
if (file == nullptr) {
|
||||
throw sls::RuntimeError("file object not contstructed");
|
||||
}
|
||||
file->CloseAllFiles();
|
||||
file->resetSubFileIndex();
|
||||
file->CreateMasterFile(*masterFileWriteEnable, attr);
|
||||
file->CreateFile();
|
||||
void DataProcessor::SetGeneralData(GeneralData *generalData) {
|
||||
generalData_ = generalData;
|
||||
}
|
||||
|
||||
void DataProcessor::CloseFiles() {
|
||||
if (file != nullptr)
|
||||
file->CloseAllFiles();
|
||||
if (dataFile_)
|
||||
dataFile_->CloseFile();
|
||||
if (masterFile_)
|
||||
masterFile_->CloseFile();
|
||||
#ifdef HDF5C
|
||||
if (virtualFile_)
|
||||
virtualFile_->CloseFile();
|
||||
#endif
|
||||
}
|
||||
|
||||
void DataProcessor::EndofAcquisition(bool anyPacketsCaught, uint64_t numf) {
|
||||
if ((file != nullptr) && file->GetFileType() == HDF5) {
|
||||
try {
|
||||
file->EndofAcquisition(anyPacketsCaught, numf);
|
||||
} catch (const sls::RuntimeError &e) {
|
||||
; // ignore for now //TODO: send error to client via stop receiver
|
||||
void DataProcessor::DeleteFiles() {
|
||||
CloseFiles();
|
||||
if (dataFile_) {
|
||||
delete dataFile_;
|
||||
dataFile_ = nullptr;
|
||||
}
|
||||
if (masterFile_) {
|
||||
delete masterFile_;
|
||||
masterFile_ = nullptr;
|
||||
}
|
||||
#ifdef HDF5C
|
||||
if (virtualFile_) {
|
||||
delete virtualFile_;
|
||||
virtualFile_ = nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void DataProcessor::SetupFileWriter(const bool filewriteEnable,
|
||||
const bool masterFilewriteEnable,
|
||||
const fileFormat fileFormatType,
|
||||
const int modulePos) {
|
||||
DeleteFiles();
|
||||
if (filewriteEnable) {
|
||||
switch (fileFormatType) {
|
||||
#ifdef HDF5C
|
||||
case HDF5:
|
||||
dataFile_ = new HDF5DataFile(index, hdf5Lib_);
|
||||
if (modulePos == 0 && index == 0) {
|
||||
if (masterFilewriteEnable) {
|
||||
masterFile_ = new HDF5MasterFile(hdf5Lib_);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case BINARY:
|
||||
dataFile_ = new BinaryDataFile(index);
|
||||
if (modulePos == 0 && index == 0 && masterFilewriteEnable) {
|
||||
masterFile_ = new BinaryMasterFile();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw sls::RuntimeError(
|
||||
"Unknown file format (compile with hdf5 flags");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DataProcessor::CreateFirstFiles(
|
||||
MasterAttributes *attr, const std::string filePath,
|
||||
const std::string fileNamePrefix, const uint64_t fileIndex,
|
||||
const bool overWriteEnable, const bool silentMode, const int modulePos,
|
||||
const int numUnitsPerReadout, const uint32_t udpPortNumber,
|
||||
const uint32_t maxFramesPerFile, const uint64_t numImages,
|
||||
const uint32_t dynamicRange, const bool detectorDataStream) {
|
||||
if (dataFile_ == nullptr) {
|
||||
throw sls::RuntimeError("file object not contstructed");
|
||||
}
|
||||
CloseFiles();
|
||||
|
||||
// master file write enabled
|
||||
if (masterFile_) {
|
||||
masterFile_->CreateMasterFile(filePath, fileNamePrefix, fileIndex,
|
||||
overWriteEnable, silentMode, attr);
|
||||
}
|
||||
|
||||
// deactivated with padding enabled, dont write file
|
||||
if (!*activated_ && !*deactivatedPaddingEnable_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// deactivated port, dont write file
|
||||
if (!detectorDataStream) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (dataFile_->GetFileFormat()) {
|
||||
#ifdef HDF5C
|
||||
case HDF5:
|
||||
dataFile_->CreateFirstHDF5DataFile(
|
||||
filePath, fileNamePrefix, fileIndex, overWriteEnable, silentMode,
|
||||
modulePos, numUnitsPerReadout, udpPortNumber, maxFramesPerFile,
|
||||
numImages, generalData_->nPixelsX, generalData_->nPixelsY,
|
||||
dynamicRange);
|
||||
break;
|
||||
#endif
|
||||
case BINARY:
|
||||
dataFile_->CreateFirstBinaryDataFile(
|
||||
filePath, fileNamePrefix, fileIndex, overWriteEnable, silentMode,
|
||||
modulePos, numUnitsPerReadout, udpPortNumber, maxFramesPerFile);
|
||||
break;
|
||||
default:
|
||||
throw sls::RuntimeError("Unknown file format (compile with hdf5 flags");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HDF5C
|
||||
uint32_t DataProcessor::GetFilesInAcquisition() const {
|
||||
if (dataFile_ == nullptr) {
|
||||
throw sls::RuntimeError("No data file object created to get number of "
|
||||
"files in acquiistion");
|
||||
}
|
||||
return dataFile_->GetFilesInAcquisition();
|
||||
}
|
||||
|
||||
void DataProcessor::CreateVirtualFile(
|
||||
const std::string filePath, const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode,
|
||||
const int modulePos, const int numUnitsPerReadout,
|
||||
const uint32_t maxFramesPerFile, const uint64_t numImages,
|
||||
const uint32_t dynamicRange, const int numModX, const int numModY) {
|
||||
|
||||
if (virtualFile_) {
|
||||
delete virtualFile_;
|
||||
}
|
||||
virtualFile_ = new HDF5VirtualFile(hdf5Lib_);
|
||||
|
||||
uint64_t numImagesProcessed = GetProcessedIndex() + 1;
|
||||
// maxframesperfile = 0 for infinite files
|
||||
uint32_t framesPerFile =
|
||||
((maxFramesPerFile == 0) ? numImagesProcessed + 1 : maxFramesPerFile);
|
||||
|
||||
// TODO: assumption 1: create virtual file even if no data in other
|
||||
// files (they exist anyway) assumption2: virtual file max frame index
|
||||
// is from R0 P0 (difference from others when missing frames or for a
|
||||
// stop acquisition)
|
||||
virtualFile_->CreateVirtualFile(
|
||||
filePath, fileNamePrefix, fileIndex, overWriteEnable, silentMode,
|
||||
modulePos, numUnitsPerReadout, framesPerFile, numImages,
|
||||
generalData_->nPixelsX, generalData_->nPixelsY, dynamicRange,
|
||||
numImagesProcessed, numModX, numModY, dataFile_->GetPDataType(),
|
||||
dataFile_->GetParameterNames(), dataFile_->GetParameterDataTypes());
|
||||
}
|
||||
|
||||
void DataProcessor::LinkDataInMasterFile(const bool silentMode) {
|
||||
std::string fname, datasetName;
|
||||
if (virtualFile_) {
|
||||
auto res = virtualFile_->GetFileAndDatasetName();
|
||||
fname = res[0];
|
||||
datasetName = res[1];
|
||||
} else {
|
||||
auto res = dataFile_->GetFileAndDatasetName();
|
||||
fname = res[0];
|
||||
datasetName = res[1];
|
||||
}
|
||||
// link in master
|
||||
masterFile_->LinkDataFile(fname, datasetName,
|
||||
dataFile_->GetParameterNames(), silentMode);
|
||||
}
|
||||
#endif
|
||||
|
||||
void DataProcessor::ThreadExecution() {
|
||||
char *buffer = nullptr;
|
||||
fifo->PopAddress(buffer);
|
||||
fifo_->PopAddress(buffer);
|
||||
LOG(logDEBUG5) << "DataProcessor " << index
|
||||
<< ", "
|
||||
"pop 0x"
|
||||
@ -189,21 +268,21 @@ void DataProcessor::ThreadExecution() {
|
||||
try {
|
||||
fnum = ProcessAnImage(buffer);
|
||||
} catch (const std::exception &e) {
|
||||
fifo->FreeAddress(buffer);
|
||||
fifo_->FreeAddress(buffer);
|
||||
return;
|
||||
}
|
||||
// stream (if time/freq to stream) or free
|
||||
if (*dataStreamEnable && SendToStreamer()) {
|
||||
if (*dataStreamEnable_ && SendToStreamer()) {
|
||||
// if first frame to stream, add frame index to fifo header (might
|
||||
// not be the first)
|
||||
if (firstStreamerFrame) {
|
||||
firstStreamerFrame = false;
|
||||
if (firstStreamerFrame_) {
|
||||
firstStreamerFrame_ = false;
|
||||
(*((uint32_t *)(buffer + FIFO_DATASIZE_NUMBYTES))) =
|
||||
(uint32_t)(fnum - firstIndex);
|
||||
(uint32_t)(fnum - firstIndex_);
|
||||
}
|
||||
fifo->PushAddressToStream(buffer);
|
||||
fifo_->PushAddressToStream(buffer);
|
||||
} else {
|
||||
fifo->FreeAddress(buffer);
|
||||
fifo_->FreeAddress(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,13 +290,12 @@ void DataProcessor::StopProcessing(char *buf) {
|
||||
LOG(logDEBUG1) << "DataProcessing " << index << ": Dummy";
|
||||
|
||||
// stream or free
|
||||
if (*dataStreamEnable)
|
||||
fifo->PushAddressToStream(buf);
|
||||
if (*dataStreamEnable_)
|
||||
fifo_->PushAddressToStream(buf);
|
||||
else
|
||||
fifo->FreeAddress(buf);
|
||||
fifo_->FreeAddress(buf);
|
||||
|
||||
if (file != nullptr)
|
||||
file->CloseCurrentFile();
|
||||
CloseFiles();
|
||||
StopRunning();
|
||||
LOG(logDEBUG1) << index << ": Processing Completed";
|
||||
}
|
||||
@ -227,37 +305,37 @@ uint64_t DataProcessor::ProcessAnImage(char *buf) {
|
||||
auto *rheader = (sls_receiver_header *)(buf + FIFO_HEADER_NUMBYTES);
|
||||
sls_detector_header header = rheader->detHeader;
|
||||
uint64_t fnum = header.frameNumber;
|
||||
currentFrameIndex = fnum;
|
||||
currentFrameIndex_ = fnum;
|
||||
uint32_t nump = header.packetNumber;
|
||||
if (nump == generalData->packetsPerFrame) {
|
||||
numFramesCaught++;
|
||||
if (nump == generalData_->packetsPerFrame) {
|
||||
numFramesCaught_++;
|
||||
}
|
||||
|
||||
LOG(logDEBUG1) << "DataProcessing " << index << ": fnum:" << fnum;
|
||||
|
||||
if (!startedFlag) {
|
||||
if (!startedFlag_) {
|
||||
RecordFirstIndex(fnum);
|
||||
if (*dataStreamEnable) {
|
||||
if (*dataStreamEnable_) {
|
||||
// restart timer
|
||||
clock_gettime(CLOCK_REALTIME, &timerBegin);
|
||||
timerBegin.tv_sec -= (*streamingTimerInMs) / 1000;
|
||||
timerBegin.tv_nsec -= ((*streamingTimerInMs) % 1000) * 1000000;
|
||||
clock_gettime(CLOCK_REALTIME, &timerbegin_);
|
||||
timerbegin_.tv_sec -= (*streamingTimerInMs_) / 1000;
|
||||
timerbegin_.tv_nsec -= ((*streamingTimerInMs_) % 1000) * 1000000;
|
||||
|
||||
// to send first image
|
||||
currentFreqCount = *streamingFrequency - *streamingStartFnum;
|
||||
currentFreqCount_ = *streamingFrequency_ - *streamingStartFnum_;
|
||||
}
|
||||
}
|
||||
|
||||
// frame padding
|
||||
if (*activated && *framePadding && nump < generalData->packetsPerFrame)
|
||||
if (*activated_ && *framePadding_ && nump < generalData_->packetsPerFrame)
|
||||
PadMissingPackets(buf);
|
||||
|
||||
// deactivated and padding enabled
|
||||
else if (!(*activated) && *deactivatedPaddingEnable)
|
||||
else if (!*activated_ && *deactivatedPaddingEnable_)
|
||||
PadMissingPackets(buf);
|
||||
|
||||
// rearrange ctb digital bits (if ctbDbitlist is not empty)
|
||||
if (!(*ctbDbitList).empty()) {
|
||||
if (!(*ctbDbitList_).empty()) {
|
||||
RearrangeDbitData(buf);
|
||||
}
|
||||
|
||||
@ -285,14 +363,14 @@ uint64_t DataProcessor::ProcessAnImage(char *buf) {
|
||||
}
|
||||
|
||||
// write to file
|
||||
if (file != nullptr) {
|
||||
if (dataFile_) {
|
||||
try {
|
||||
file->WriteToFile(
|
||||
dataFile_->WriteToFile(
|
||||
buf + FIFO_HEADER_NUMBYTES,
|
||||
sizeof(sls_receiver_header) +
|
||||
(uint32_t)(*((uint32_t *)buf)), //+ size of data (resizable
|
||||
// from previous call back
|
||||
fnum - firstIndex, nump);
|
||||
fnum - firstIndex_, nump);
|
||||
} catch (const sls::RuntimeError &e) {
|
||||
; // ignore write exception for now (TODO: send error message
|
||||
// via stopReceiver tcp)
|
||||
@ -303,7 +381,7 @@ uint64_t DataProcessor::ProcessAnImage(char *buf) {
|
||||
|
||||
bool DataProcessor::SendToStreamer() {
|
||||
// skip
|
||||
if ((*streamingFrequency) == 0u) {
|
||||
if ((*streamingFrequency_) == 0u) {
|
||||
if (!CheckTimer())
|
||||
return false;
|
||||
} else {
|
||||
@ -318,38 +396,29 @@ bool DataProcessor::CheckTimer() {
|
||||
clock_gettime(CLOCK_REALTIME, &end);
|
||||
|
||||
LOG(logDEBUG1) << index << " Timer elapsed time:"
|
||||
<< ((end.tv_sec - timerBegin.tv_sec) +
|
||||
(end.tv_nsec - timerBegin.tv_nsec) / 1000000000.0)
|
||||
<< ((end.tv_sec - timerbegin_.tv_sec) +
|
||||
(end.tv_nsec - timerbegin_.tv_nsec) / 1000000000.0)
|
||||
<< " seconds";
|
||||
// still less than streaming timer, keep waiting
|
||||
if (((end.tv_sec - timerBegin.tv_sec) +
|
||||
(end.tv_nsec - timerBegin.tv_nsec) / 1000000000.0) <
|
||||
((double)*streamingTimerInMs / 1000.00))
|
||||
if (((end.tv_sec - timerbegin_.tv_sec) +
|
||||
(end.tv_nsec - timerbegin_.tv_nsec) / 1000000000.0) <
|
||||
((double)*streamingTimerInMs_ / 1000.00))
|
||||
return false;
|
||||
|
||||
// restart timer
|
||||
clock_gettime(CLOCK_REALTIME, &timerBegin);
|
||||
clock_gettime(CLOCK_REALTIME, &timerbegin_);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DataProcessor::CheckCount() {
|
||||
if (currentFreqCount == *streamingFrequency) {
|
||||
currentFreqCount = 1;
|
||||
if (currentFreqCount_ == *streamingFrequency_) {
|
||||
currentFreqCount_ = 1;
|
||||
return true;
|
||||
}
|
||||
currentFreqCount++;
|
||||
currentFreqCount_++;
|
||||
return false;
|
||||
}
|
||||
|
||||
void DataProcessor::SetPixelDimension() {
|
||||
if (file != nullptr) {
|
||||
if (file->GetFileType() == HDF5) {
|
||||
file->SetNumberofPixels(generalData->nPixelsX,
|
||||
generalData->nPixelsY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DataProcessor::registerCallBackRawDataReady(void (*func)(char *, char *,
|
||||
uint32_t, void *),
|
||||
void *arg) {
|
||||
@ -366,18 +435,18 @@ void DataProcessor::registerCallBackRawDataModifyReady(
|
||||
void DataProcessor::PadMissingPackets(char *buf) {
|
||||
LOG(logDEBUG) << index << ": Padding Missing Packets";
|
||||
|
||||
uint32_t pperFrame = generalData->packetsPerFrame;
|
||||
uint32_t pperFrame = generalData_->packetsPerFrame;
|
||||
auto *header = (sls_receiver_header *)(buf + FIFO_HEADER_NUMBYTES);
|
||||
uint32_t nmissing = pperFrame - header->detHeader.packetNumber;
|
||||
sls_bitset pmask = header->packetsMask;
|
||||
|
||||
uint32_t dsize = generalData->dataSize;
|
||||
if (myDetectorType == GOTTHARD2 && index != 0) {
|
||||
dsize = generalData->vetoDataSize;
|
||||
uint32_t dsize = generalData_->dataSize;
|
||||
if (detectorType_ == GOTTHARD2 && index != 0) {
|
||||
dsize = generalData_->vetoDataSize;
|
||||
}
|
||||
uint32_t fifohsize = generalData->fifoBufferHeaderSize;
|
||||
uint32_t fifohsize = generalData_->fifoBufferHeaderSize;
|
||||
uint32_t corrected_dsize =
|
||||
dsize - ((pperFrame * dsize) - generalData->imageSize);
|
||||
dsize - ((pperFrame * dsize) - generalData_->imageSize);
|
||||
LOG(logDEBUG1) << "bitmask: " << pmask.to_string();
|
||||
|
||||
for (unsigned int pnum = 0; pnum < pperFrame; ++pnum) {
|
||||
@ -394,7 +463,7 @@ void DataProcessor::PadMissingPackets(char *buf) {
|
||||
<< std::endl;
|
||||
|
||||
// missing packet
|
||||
switch (myDetectorType) {
|
||||
switch (detectorType_) {
|
||||
// for gotthard, 1st packet: 4 bytes fnum, CACA + CACA, 639*2 bytes
|
||||
// data
|
||||
// 2nd packet: 4 bytes fnum, previous 1*2 bytes data +
|
||||
@ -425,7 +494,7 @@ void DataProcessor::RearrangeDbitData(char *buf) {
|
||||
// TODO! (Erik) Refactor and add tests
|
||||
int totalSize = (int)(*((uint32_t *)buf));
|
||||
int ctbDigitalDataBytes =
|
||||
totalSize - (*ctbAnalogDataBytes) - (*ctbDbitOffset);
|
||||
totalSize - (*ctbAnalogDataBytes_) - (*ctbDbitOffset_);
|
||||
|
||||
// no digital data
|
||||
if (ctbDigitalDataBytes == 0) {
|
||||
@ -436,19 +505,19 @@ void DataProcessor::RearrangeDbitData(char *buf) {
|
||||
|
||||
const int numSamples = (ctbDigitalDataBytes / sizeof(uint64_t));
|
||||
const int digOffset = FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header) +
|
||||
(*ctbAnalogDataBytes);
|
||||
(*ctbAnalogDataBytes_);
|
||||
|
||||
// ceil as numResult8Bits could be decimal
|
||||
const int numResult8Bits =
|
||||
ceil((double)(numSamples * (*ctbDbitList).size()) / 8.00);
|
||||
ceil((double)(numSamples * (*ctbDbitList_).size()) / 8.00);
|
||||
std::vector<uint8_t> result(numResult8Bits);
|
||||
uint8_t *dest = &result[0];
|
||||
|
||||
auto *source = (uint64_t *)(buf + digOffset + (*ctbDbitOffset));
|
||||
auto *source = (uint64_t *)(buf + digOffset + (*ctbDbitOffset_));
|
||||
|
||||
// loop through digital bit enable vector
|
||||
int bitoffset = 0;
|
||||
for (auto bi : (*ctbDbitList)) {
|
||||
for (auto bi : (*ctbDbitList_)) {
|
||||
// where numbits * numsamples is not a multiple of 8
|
||||
if (bitoffset != 0) {
|
||||
bitoffset = 0;
|
||||
|
@ -19,141 +19,63 @@ class DataStreamer;
|
||||
struct MasterAttributes;
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* Calls Base Class CreateThread(), sets ErrorMask if error and increments
|
||||
* NumberofDataProcessors
|
||||
* @param ind self index
|
||||
* @param dtype detector type
|
||||
* @param f address of Fifo pointer
|
||||
* @param ftype pointer to file format type
|
||||
* @param fwenable file writer enable
|
||||
* @param mfwenable pointer to master file write enable
|
||||
* @param dsEnable pointer to data stream enable
|
||||
* @param dr pointer to dynamic range
|
||||
* @param freq pointer to streaming frequency
|
||||
* @param timer pointer to timer if streaming frequency is random
|
||||
* @param sfnum pointer to streaming starting fnum
|
||||
* @param fp pointer to frame padding enable
|
||||
* @param act pointer to activated
|
||||
* @param depaden pointer to deactivated padding enable
|
||||
* @param sm pointer to silent mode
|
||||
* @param qe pointer to quad Enable
|
||||
* @param cdl pointer to vector or ctb digital bits enable
|
||||
* @param cdo pointer to digital bits offset
|
||||
* @param cad pointer to ctb analog databytes
|
||||
*/
|
||||
DataProcessor(int ind, detectorType dtype, Fifo *f, fileFormat *ftype,
|
||||
bool fwenable, bool *mfwenable, bool *dsEnable,
|
||||
uint32_t *freq, uint32_t *timer, uint32_t *sfnum, bool *fp,
|
||||
bool *act, bool *depaden, bool *sm, std::vector<int> *cdl,
|
||||
int *cdo, int *cad);
|
||||
DataProcessor(int index, detectorType detectorType, Fifo *fifo,
|
||||
bool *activated, bool *deactivatedPaddingEnable,
|
||||
bool *dataStreamEnable, uint32_t *streamingFrequency,
|
||||
uint32_t *streamingTimerInMs, uint32_t *streamingStartFnum,
|
||||
bool *framePadding, std::vector<int> *ctbDbitList,
|
||||
int *ctbDbitOffset, int *ctbAnalogDataBytes,
|
||||
std::mutex *hdf5Lib);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
* Calls Base Class DestroyThread() and decrements NumberofDataProcessors
|
||||
*/
|
||||
~DataProcessor() override;
|
||||
|
||||
//*** getters ***
|
||||
|
||||
/**
|
||||
* Get acquisition started flag
|
||||
* @return acquisition started flag
|
||||
*/
|
||||
bool GetStartedFlag();
|
||||
|
||||
/**
|
||||
* Get Frames Complete Caught
|
||||
* @return number of frames
|
||||
*/
|
||||
uint64_t GetNumFramesCaught();
|
||||
|
||||
/**
|
||||
* Gets Actual Current Frame Index (that has not been subtracted from
|
||||
* firstIndex) thats been processed
|
||||
* @return -1 if no frames have been caught, else current frame index
|
||||
*/
|
||||
/** (-1 if no frames have been caught */
|
||||
uint64_t GetCurrentFrameIndex();
|
||||
|
||||
/**
|
||||
* Get Current Frame Index thats been processed
|
||||
* @return -1 if no frames have been caught, else current frame index
|
||||
*/
|
||||
/** (-1 if no frames have been caught) */
|
||||
uint64_t GetProcessedIndex();
|
||||
|
||||
/**
|
||||
* Set Fifo pointer to the one given
|
||||
* @param f address of Fifo pointer
|
||||
*/
|
||||
void SetFifo(Fifo *f);
|
||||
|
||||
/**
|
||||
* Reset parameters for new acquisition
|
||||
*/
|
||||
void ResetParametersforNewAcquisition();
|
||||
void SetGeneralData(GeneralData *generalData);
|
||||
|
||||
/**
|
||||
* Set GeneralData pointer to the one given
|
||||
* @param g address of GeneralData (Detector Data) pointer
|
||||
*/
|
||||
void SetGeneralData(GeneralData *g);
|
||||
|
||||
/**
|
||||
* Set File Format
|
||||
* @param fs file format
|
||||
*/
|
||||
void SetFileFormat(const fileFormat fs);
|
||||
|
||||
/**
|
||||
* Set up file writer object and call backs
|
||||
* @param fwe file write enable
|
||||
* @param nd pointer to number of detectors in each dimension
|
||||
* @param maxf pointer to max frames per file
|
||||
* @param fname pointer to file name prefix
|
||||
* @param fpath pointer to file path
|
||||
* @param findex pointer to file index
|
||||
* @param owenable pointer to over write enable
|
||||
* @param dindex pointer to detector index
|
||||
* @param nunits pointer to number of threads/ units per detector
|
||||
* @param nf pointer to number of images in acquisition
|
||||
* @param dr pointer to dynamic range
|
||||
* @param portno pointer to udp port number
|
||||
* @param g address of GeneralData (Detector Data) pointer
|
||||
*/
|
||||
void SetupFileWriter(bool fwe, int *nd, uint32_t *maxf, std::string *fname,
|
||||
std::string *fpath, uint64_t *findex, bool *owenable,
|
||||
int *dindex, int *nunits, uint64_t *nf, uint32_t *dr,
|
||||
uint32_t *portno, GeneralData *g = nullptr);
|
||||
|
||||
/**
|
||||
* Create New File
|
||||
* @param attr master file attributes
|
||||
*/
|
||||
void CreateNewFile(MasterAttributes *attr);
|
||||
|
||||
/**
|
||||
* Closes files
|
||||
*/
|
||||
void CloseFiles();
|
||||
void DeleteFiles();
|
||||
void SetupFileWriter(const bool filewriteEnable,
|
||||
const bool masterFilewriteEnable,
|
||||
const fileFormat fileFormatType, const int modulePos);
|
||||
|
||||
/**
|
||||
* End of Acquisition
|
||||
* @param anyPacketsCaught true if any packets are caught, else false
|
||||
* @param numf number of images caught
|
||||
*/
|
||||
void EndofAcquisition(bool anyPacketsCaught, uint64_t numf);
|
||||
|
||||
/**
|
||||
* Update pixel dimensions in file writer
|
||||
*/
|
||||
void SetPixelDimension();
|
||||
|
||||
void CreateFirstFiles(MasterAttributes *attr, const std::string filePath,
|
||||
const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable,
|
||||
const bool silentMode, const int modulePos,
|
||||
const int numUnitsPerReadout,
|
||||
const uint32_t udpPortNumber,
|
||||
const uint32_t maxFramesPerFile,
|
||||
const uint64_t numImages,
|
||||
const uint32_t dynamicRange,
|
||||
const bool detectorDataStream
|
||||
);
|
||||
#ifdef HDF5C
|
||||
uint32_t GetFilesInAcquisition() const;
|
||||
void CreateVirtualFile(const std::string filePath,
|
||||
const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable,
|
||||
const bool silentMode, const int modulePos,
|
||||
const int numUnitsPerReadout,
|
||||
const uint32_t maxFramesPerFile,
|
||||
const uint64_t numImages,
|
||||
const uint32_t dynamicRange, const int numModX,
|
||||
const int numModY);
|
||||
void LinkDataInMasterFile(const bool silentMode);
|
||||
#endif
|
||||
/**
|
||||
* Call back for raw data
|
||||
* args to raw data ready callback are
|
||||
@ -179,10 +101,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
void *arg);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Record First Index
|
||||
* @param fnum frame index to record
|
||||
*/
|
||||
void RecordFirstIndex(uint64_t fnum);
|
||||
|
||||
/**
|
||||
@ -195,14 +113,12 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
/**
|
||||
* Frees dummy buffer,
|
||||
* reset running mask by calling StopRunning()
|
||||
* @param buf address of pointer
|
||||
*/
|
||||
void StopProcessing(char *buf);
|
||||
|
||||
/**
|
||||
* Process an image popped from fifo,
|
||||
* write to file if fw enabled & update parameters
|
||||
* @param buf address of pointer
|
||||
* @returns frame number
|
||||
*/
|
||||
uint64_t ProcessAnImage(char *buf);
|
||||
@ -228,10 +144,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
*/
|
||||
bool CheckCount();
|
||||
|
||||
/**
|
||||
* Pad Missing Packets from the bit mask
|
||||
* @param buf buffer
|
||||
*/
|
||||
void PadMissingPackets(char *buf);
|
||||
|
||||
/**
|
||||
@ -240,87 +152,43 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
*/
|
||||
void RearrangeDbitData(char *buf);
|
||||
|
||||
/** type of thread */
|
||||
static const std::string TypeName;
|
||||
static const std::string typeName_;
|
||||
|
||||
/** GeneralData (Detector Data) object */
|
||||
const GeneralData *generalData{nullptr};
|
||||
|
||||
/** Fifo structure */
|
||||
Fifo *fifo;
|
||||
|
||||
// individual members
|
||||
/** Detector Type */
|
||||
detectorType myDetectorType;
|
||||
|
||||
/** File writer implemented as binary or hdf5 File */
|
||||
File *file{nullptr};
|
||||
|
||||
/** Data Stream Enable */
|
||||
bool *dataStreamEnable;
|
||||
|
||||
/** File Format Type */
|
||||
fileFormat *fileFormatType;
|
||||
|
||||
/** File Write Enable */
|
||||
bool fileWriteEnable;
|
||||
|
||||
/** Master File Write Enable */
|
||||
bool *masterFileWriteEnable;
|
||||
|
||||
/** Pointer to Streaming frequency, if 0, sending random images with a timer
|
||||
*/
|
||||
uint32_t *streamingFrequency;
|
||||
|
||||
/** Pointer to the timer if Streaming frequency is random */
|
||||
uint32_t *streamingTimerInMs;
|
||||
|
||||
/** Pointer to streaming starting fnum */
|
||||
uint32_t *streamingStartFnum;
|
||||
|
||||
/** Current frequency count */
|
||||
uint32_t currentFreqCount{0};
|
||||
|
||||
/** timer beginning stamp for random streaming */
|
||||
struct timespec timerBegin;
|
||||
|
||||
/** Activated/Deactivated */
|
||||
bool *activated;
|
||||
|
||||
/** Deactivated padding enable */
|
||||
bool *deactivatedPaddingEnable;
|
||||
|
||||
/** Silent Mode */
|
||||
bool *silentMode;
|
||||
|
||||
/** frame padding */
|
||||
bool *framePadding;
|
||||
|
||||
/** ctb digital bits enable list */
|
||||
std::vector<int> *ctbDbitList;
|
||||
|
||||
/** ctb digital bits offset */
|
||||
int *ctbDbitOffset;
|
||||
|
||||
/** ctb analog databytes */
|
||||
int *ctbAnalogDataBytes;
|
||||
|
||||
// acquisition start
|
||||
/** Aquisition Started flag */
|
||||
std::atomic<bool> startedFlag{false};
|
||||
|
||||
/** Frame Number of First Frame */
|
||||
std::atomic<uint64_t> firstIndex{0};
|
||||
const GeneralData *generalData_{nullptr};
|
||||
Fifo *fifo_;
|
||||
detectorType detectorType_;
|
||||
bool *dataStreamEnable_;
|
||||
bool *activated_;
|
||||
bool *deactivatedPaddingEnable_;
|
||||
/** if 0, sending random images with a timer */
|
||||
uint32_t *streamingFrequency_;
|
||||
uint32_t *streamingTimerInMs_;
|
||||
uint32_t *streamingStartFnum_;
|
||||
uint32_t currentFreqCount_{0};
|
||||
struct timespec timerbegin_;
|
||||
bool *framePadding_;
|
||||
std::vector<int> *ctbDbitList_;
|
||||
int *ctbDbitOffset_;
|
||||
int *ctbAnalogDataBytes_;
|
||||
std::atomic<bool> startedFlag_{false};
|
||||
std::atomic<uint64_t> firstIndex_{0};
|
||||
|
||||
// for statistics
|
||||
/** Number of complete frames caught */
|
||||
uint64_t numFramesCaught{0};
|
||||
uint64_t numFramesCaught_{0};
|
||||
|
||||
/** Frame Number of latest processed frame number */
|
||||
std::atomic<uint64_t> currentFrameIndex{0};
|
||||
std::atomic<uint64_t> currentFrameIndex_{0};
|
||||
|
||||
/** first streamer frame to add frame index in fifo header */
|
||||
bool firstStreamerFrame{false};
|
||||
bool firstStreamerFrame_{false};
|
||||
|
||||
File *dataFile_{nullptr};
|
||||
File *masterFile_{nullptr};
|
||||
std::mutex *hdf5Lib_;
|
||||
#ifdef HDF5C
|
||||
File *virtualFile_{nullptr};
|
||||
#endif
|
||||
|
||||
// call back
|
||||
/**
|
||||
|
@ -15,11 +15,11 @@
|
||||
const std::string DataStreamer::TypeName = "DataStreamer";
|
||||
|
||||
DataStreamer::DataStreamer(int ind, Fifo *f, uint32_t *dr, ROI *r, uint64_t *fi,
|
||||
int fd, int *nd, bool *qe, uint64_t *tot)
|
||||
int fd, int *nm, bool *qe, uint64_t *tot)
|
||||
: ThreadObject(ind, TypeName), fifo(f), dynamicRange(dr), roi(r),
|
||||
fileIndex(fi), flippedDataX(fd), quadEnable(qe), totalNumFrames(tot) {
|
||||
numDet[0] = nd[0];
|
||||
numDet[1] = nd[1];
|
||||
numMods[0] = nm[0];
|
||||
numMods[1] = nm[1];
|
||||
|
||||
LOG(logDEBUG) << "DataStreamer " << ind << " created";
|
||||
}
|
||||
@ -60,9 +60,9 @@ void DataStreamer::RecordFirstIndex(uint64_t fnum, char *buf) {
|
||||
|
||||
void DataStreamer::SetGeneralData(GeneralData *g) { generalData = g; }
|
||||
|
||||
void DataStreamer::SetNumberofDetectors(int *nd) {
|
||||
numDet[0] = nd[0];
|
||||
numDet[1] = nd[1];
|
||||
void DataStreamer::SetNumberofModules(int *nm) {
|
||||
numMods[0] = nm[0];
|
||||
numMods[1] = nm[1];
|
||||
}
|
||||
|
||||
void DataStreamer::SetFlippedDataX(int fd) { flippedDataX = fd; }
|
||||
@ -217,8 +217,8 @@ int DataStreamer::SendHeader(sls_receiver_header *rheader, uint32_t size,
|
||||
|
||||
zHeader.dynamicRange = *dynamicRange;
|
||||
zHeader.fileIndex = *fileIndex;
|
||||
zHeader.ndetx = numDet[0];
|
||||
zHeader.ndety = numDet[1];
|
||||
zHeader.ndetx = numMods[0];
|
||||
zHeader.ndety = numMods[1];
|
||||
zHeader.npixelsx = nx;
|
||||
zHeader.npixelsy = ny;
|
||||
zHeader.imageSize = size;
|
||||
|
@ -31,12 +31,12 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
||||
* @param r roi
|
||||
* @param fi pointer to file index
|
||||
* @param fd flipped data enable for x dimension
|
||||
* @param nd pointer to number of detectors in each dimension
|
||||
* @param nm pointer to number of modules in each dimension
|
||||
* @param qe pointer to quad Enable
|
||||
* @param tot pointer to total number of frames
|
||||
*/
|
||||
DataStreamer(int ind, Fifo *f, uint32_t *dr, ROI *r, uint64_t *fi, int fd,
|
||||
int *nd, bool *qe, uint64_t *tot);
|
||||
int *nm, bool *qe, uint64_t *tot);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
@ -63,9 +63,9 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
||||
|
||||
/**
|
||||
* Set number of detectors
|
||||
* @param nd number of detectors in both dimensions
|
||||
* @param nm number of modules in both dimensions
|
||||
*/
|
||||
void SetNumberofDetectors(int *nd);
|
||||
void SetNumberofModules(int *nm);
|
||||
|
||||
/**
|
||||
* Set Flipped data enable across x dimension
|
||||
@ -193,8 +193,8 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
||||
/** Complete buffer used for roi, eg. shortGotthard */
|
||||
char *completeBuffer{nullptr};
|
||||
|
||||
/** Number of Detectors in X and Y dimension */
|
||||
int numDet[2];
|
||||
/** Number of Modules in X and Y dimension */
|
||||
int numMods[2];
|
||||
|
||||
/** Quad Enable */
|
||||
bool *quadEnable;
|
||||
|
@ -1,71 +1,9 @@
|
||||
/************************************************
|
||||
* @file File.cpp
|
||||
* @short sets/gets properties for the file,
|
||||
* creates/closes the file and writes data to it
|
||||
***********************************************/
|
||||
|
||||
#include "File.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
File::File(int ind, slsDetectorDefs::fileFormat type, uint32_t *maxf, int *nd,
|
||||
std::string *fname, std::string *fpath, uint64_t *findex,
|
||||
bool *owenable, int *dindex, int *nunits, uint64_t *nf, uint32_t *dr,
|
||||
uint32_t *portno, bool *smode)
|
||||
: index(ind), formatType(type), maxFramesPerFile(maxf), numDetX(nd[0]),
|
||||
numDetY(nd[1]), fileNamePrefix(fname), filePath(fpath), fileIndex(findex),
|
||||
overWriteEnable(owenable), detIndex(dindex), numUnitsPerDetector(nunits),
|
||||
numImages(nf), dynamicRange(dr), udpPortNumber(portno), silentMode(smode)
|
||||
|
||||
{
|
||||
master = ((index == 0) && (*detIndex == 0)) ? true : false;
|
||||
}
|
||||
File::File(const slsDetectorDefs::fileFormat format) : format_(format) {}
|
||||
|
||||
File::~File() {}
|
||||
|
||||
slsDetectorDefs::fileFormat File::GetFileType() { return formatType; }
|
||||
|
||||
std::string File::GetCurrentFileName() { return currentFileName; }
|
||||
|
||||
void File::resetSubFileIndex() { subFileIndex = 0u; }
|
||||
|
||||
void File::PrintMembers(TLogLevel level) {
|
||||
LOG(level) << "\nGeneral Writer Variables:" << std::endl
|
||||
<< "Index: " << index << std::endl
|
||||
<< "Max Frames Per File: " << *maxFramesPerFile << std::endl
|
||||
<< "Number of Detectors in x dir: " << numDetX << std::endl
|
||||
<< "Number of Detectors in y dir: " << numDetY << std::endl
|
||||
<< "File Name Prefix: " << fileNamePrefix << std::endl
|
||||
<< "File Path: " << filePath << std::endl
|
||||
<< "File Index: " << *fileIndex << std::endl
|
||||
<< "Over Write Enable: " << *overWriteEnable << std::endl
|
||||
|
||||
<< "Detector Index: " << *detIndex << std::endl
|
||||
<< "Number of Units Per Detector: " << *numUnitsPerDetector
|
||||
<< std::endl
|
||||
<< "Number of Images in Acquisition: " << *numImages << std::endl
|
||||
<< "Dynamic Range: " << *dynamicRange << std::endl
|
||||
<< "UDP Port number: " << *udpPortNumber << std::endl
|
||||
<< "Master File Name: " << masterFileName << std::endl
|
||||
<< "Current File Name: " << currentFileName << std::endl
|
||||
<< "Silent Mode: " << *silentMode;
|
||||
}
|
||||
|
||||
void File::GetMemberPointerValues(int *nd, uint32_t *&maxf, std::string *&fname,
|
||||
std::string *&fpath, uint64_t *&findex,
|
||||
bool *&owenable, int *&dindex, int *&nunits,
|
||||
uint64_t *&nf, uint32_t *&dr,
|
||||
uint32_t *&portno) {
|
||||
nd[0] = numDetX;
|
||||
nd[1] = numDetY;
|
||||
maxf = maxFramesPerFile;
|
||||
fname = fileNamePrefix;
|
||||
fpath = filePath;
|
||||
findex = fileIndex;
|
||||
owenable = overWriteEnable;
|
||||
dindex = detIndex;
|
||||
nunits = numUnitsPerDetector;
|
||||
nf = numImages;
|
||||
dr = dynamicRange;
|
||||
portno = udpPortNumber;
|
||||
}
|
||||
slsDetectorDefs::fileFormat File::GetFileFormat() const { return format_; }
|
||||
|
@ -1,134 +1,123 @@
|
||||
#pragma once
|
||||
/************************************************
|
||||
* @file File.h
|
||||
* @short sets/gets properties for the file,
|
||||
* creates/closes the file and writes data to it
|
||||
***********************************************/
|
||||
/**
|
||||
*@short sets/gets properties for the file, creates/closes the file and writes
|
||||
*data to it
|
||||
*/
|
||||
|
||||
#include "receiver_defs.h"
|
||||
#include "sls/logger.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
struct MasterAttributes;
|
||||
|
||||
#ifdef HDF5C
|
||||
#include "H5Cpp.h"
|
||||
#ifndef H5_NO_NAMESPACE
|
||||
using namespace H5;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <array>
|
||||
|
||||
class File : private virtual slsDetectorDefs {
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* creates the File Writer
|
||||
* @param ind self index
|
||||
* @param type file format type
|
||||
* @param maxf pointer to max frames per file
|
||||
* @param nd pointer to number of detectors in each dimension
|
||||
* @param fname pointer to file name prefix
|
||||
* @param fpath pointer to file path
|
||||
* @param findex pointer to file index
|
||||
* @param owenable pointer to over write enable
|
||||
* @param dindex pointer to detector index
|
||||
* @param nunits pointer to number of theads/ units per detector
|
||||
* @param nf pointer to number of images in acquisition
|
||||
* @param dr pointer to dynamic range
|
||||
* @param portno pointer to udp port number for logging
|
||||
* @param smode pointer to silent mode
|
||||
*/
|
||||
File(int ind, slsDetectorDefs::fileFormat type, uint32_t *maxf, int *nd,
|
||||
std::string *fname, std::string *fpath, uint64_t *findex,
|
||||
bool *owenable, int *dindex, int *nunits, uint64_t *nf, uint32_t *dr,
|
||||
uint32_t *portno, bool *smode);
|
||||
|
||||
File(const slsDetectorDefs::fileFormat format);
|
||||
virtual ~File();
|
||||
fileFormat GetFileType();
|
||||
std::string GetCurrentFileName();
|
||||
void resetSubFileIndex();
|
||||
virtual void PrintMembers(TLogLevel level = logDEBUG1);
|
||||
|
||||
/**
|
||||
* Get Member Pointer Values before the object is destroyed
|
||||
* @param nd pointer to number of detectors in each dimension
|
||||
* @param maxf pointer to max frames per file
|
||||
* @param fname pointer to file name prefix
|
||||
* @param fpath pointer to file path
|
||||
* @param findex pointer to file index
|
||||
* @param owenable pointer to over write enable
|
||||
* @param dindex pointer to detector index
|
||||
* @param nunits pointer to number of theads/ units per detector
|
||||
* @param nf pointer to number of images in acquisition
|
||||
* @param dr pointer to dynamic range
|
||||
* @param portno pointer to dynamic range
|
||||
*/
|
||||
void GetMemberPointerValues(int *nd, uint32_t *&maxf, std::string *&fname,
|
||||
std::string *&fpath, uint64_t *&findex,
|
||||
bool *&owenable, int *&dindex, int *&nunits,
|
||||
uint64_t *&nf, uint32_t *&dr,
|
||||
uint32_t *&portno);
|
||||
fileFormat GetFileFormat() const;
|
||||
virtual void CloseFile() = 0;
|
||||
|
||||
virtual void CreateFile() = 0;
|
||||
virtual void CloseCurrentFile() = 0;
|
||||
virtual void CloseAllFiles() = 0;
|
||||
#ifdef HDF5C
|
||||
virtual std::array<std::string, 2> GetFileAndDatasetName() const {
|
||||
LOG(logERROR)
|
||||
<< "This is a generic function GetFilesInAcquisition that "
|
||||
"should be overloaded by a derived class";
|
||||
return std::array<std::string, 2>{};
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data to file
|
||||
* @param buffer buffer to write from
|
||||
* @param buffersize size of buffer
|
||||
* @param fnum current image number
|
||||
* @param nump number of packets caught
|
||||
*/
|
||||
virtual void WriteToFile(char *buffer, int buffersize, uint64_t fnum,
|
||||
uint32_t nump) = 0;
|
||||
virtual uint32_t GetFilesInAcquisition() const {
|
||||
LOG(logERROR)
|
||||
<< "This is a generic function GetFilesInAcquisition that "
|
||||
"should be overloaded by a derived class";
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create master file
|
||||
* @param mfwenable master file write enable
|
||||
* @param attr master file attributes
|
||||
*/
|
||||
virtual void CreateMasterFile(bool mfwenable, MasterAttributes *attr) = 0;
|
||||
virtual DataType GetPDataType() const {
|
||||
LOG(logERROR) << "This is a generic function GetPDataType that "
|
||||
"should be overloaded by a derived class";
|
||||
return PredType::STD_U16LE;
|
||||
}
|
||||
|
||||
// HDf5 specific
|
||||
/**
|
||||
* Set Number of pixels
|
||||
* @param nx number of pixels in x direction
|
||||
* @param ny number of pixels in y direction
|
||||
*/
|
||||
virtual void SetNumberofPixels(uint32_t nx, uint32_t ny) {
|
||||
LOG(logERROR) << "This is a generic function SetNumberofPixels that "
|
||||
virtual std::vector<std::string> GetParameterNames() const {
|
||||
LOG(logERROR)
|
||||
<< "This is a generic function GetFilesInAcquisition that "
|
||||
"should be overloaded by a derived class";
|
||||
return std::vector<std::string>{};
|
||||
};
|
||||
|
||||
virtual std::vector<DataType> GetParameterDataTypes() const {
|
||||
LOG(logERROR)
|
||||
<< "This is a generic function GetFilesInAcquisition that "
|
||||
"should be overloaded by a derived class";
|
||||
return std::vector<DataType>{};
|
||||
};
|
||||
|
||||
virtual void CreateVirtualFile(
|
||||
const std::string filePath, const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable,
|
||||
const bool silentMode, const int modulePos,
|
||||
const int numUnitsPerReadout, const uint32_t maxFramesPerFile,
|
||||
const uint64_t numImages, const uint32_t nPixelsX,
|
||||
const uint32_t nPixelsY, const uint32_t dynamicRange,
|
||||
const uint64_t numImagesCaught, const int numModX, const int numModY,
|
||||
const DataType dataType, const std::vector<std::string> parameterNames,
|
||||
const std::vector<DataType> parameterDataTypes) {
|
||||
LOG(logERROR) << "This is a generic function CreateVirtualFile that "
|
||||
"should be overloaded by a derived class";
|
||||
}
|
||||
|
||||
/**
|
||||
* End of Acquisition
|
||||
* @param anyPacketsCaught true if any packets are caught, else false
|
||||
* @param numf number of images caught
|
||||
*/
|
||||
virtual void EndofAcquisition(bool anyPacketsCaught, uint64_t numf) {
|
||||
LOG(logERROR) << "This is a generic function EndofAcquisition that "
|
||||
virtual void CreateFirstHDF5DataFile(
|
||||
const std::string filePath, const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable,
|
||||
const bool silentMode, const int modulePos,
|
||||
const int numUnitsPerReadout, const uint32_t udpPortNumber,
|
||||
const uint32_t maxFramesPerFile, const uint64_t numImages,
|
||||
const uint32_t nPixelsX, const uint32_t nPixelsY,
|
||||
const uint32_t dynamicRange) {
|
||||
LOG(logERROR) << "This is a generic function CreateFirstDataFile that "
|
||||
"should be overloaded by a derived class";
|
||||
}
|
||||
};
|
||||
|
||||
virtual void LinkDataFile(std::string dataFilename, std::string dataSetname,
|
||||
const std::vector<std::string> parameterNames,
|
||||
const bool silentMode) {
|
||||
LOG(logERROR) << "This is a generic function LinkDataFile that "
|
||||
"should be overloaded by a derived class";
|
||||
};
|
||||
#endif
|
||||
virtual void CreateFirstBinaryDataFile(
|
||||
const std::string filePath, const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable,
|
||||
const bool silentMode, const int modulePos,
|
||||
const int numUnitsPerReadout, const uint32_t udpPortNumber,
|
||||
const uint32_t maxFramesPerFile) {
|
||||
LOG(logERROR) << "This is a generic function CreateFirstDataFile that "
|
||||
"should be overloaded by a derived class";
|
||||
};
|
||||
|
||||
virtual void CreateMasterFile(const std::string filePath,
|
||||
const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex,
|
||||
const bool overWriteEnable,
|
||||
const bool silentMode,
|
||||
MasterAttributes *attr) {
|
||||
LOG(logERROR) << "This is a generic function CreateMasterFile that "
|
||||
"should be overloaded by a derived class";
|
||||
};
|
||||
|
||||
virtual void WriteToFile(char *buffer, const int buffersize,
|
||||
const uint64_t currentFrameNumber,
|
||||
const uint32_t numPacketsCaught) {
|
||||
LOG(logERROR) << "This is a generic function WriteToFile that "
|
||||
"should be overloaded by a derived class";
|
||||
};
|
||||
|
||||
protected:
|
||||
bool master;
|
||||
int index;
|
||||
slsDetectorDefs::fileFormat formatType;
|
||||
uint32_t *maxFramesPerFile;
|
||||
std::string masterFileName;
|
||||
std::string currentFileName;
|
||||
int numDetX;
|
||||
int numDetY;
|
||||
std::string *fileNamePrefix;
|
||||
std::string *filePath;
|
||||
uint64_t *fileIndex;
|
||||
uint64_t subFileIndex{0};
|
||||
bool *overWriteEnable;
|
||||
int *detIndex;
|
||||
int *numUnitsPerDetector;
|
||||
uint64_t *numImages;
|
||||
uint32_t *dynamicRange;
|
||||
uint32_t *udpPortNumber;
|
||||
bool *silentMode;
|
||||
slsDetectorDefs::fileFormat format_;
|
||||
};
|
||||
|
393
slsReceiverSoftware/src/HDF5DataFile.cpp
Normal file
393
slsReceiverSoftware/src/HDF5DataFile.cpp
Normal file
@ -0,0 +1,393 @@
|
||||
#include "HDF5DataFile.h"
|
||||
#include "receiver_defs.h"
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
HDF5DataFile::HDF5DataFile(int index, std::mutex *hdf5Lib)
|
||||
: File(HDF5), index_(index), hdf5Lib_(hdf5Lib) {
|
||||
|
||||
parameterNames_ = std::vector<std::string>{
|
||||
"frame number",
|
||||
"exp length or sub exposure time",
|
||||
"packets caught",
|
||||
"bunch id",
|
||||
"timestamp",
|
||||
"mod id",
|
||||
"row",
|
||||
"column",
|
||||
"reserved",
|
||||
"debug",
|
||||
"round robin number",
|
||||
"detector type",
|
||||
"detector header version",
|
||||
"packets caught bit mask",
|
||||
};
|
||||
StrType strdatatype(PredType::C_S1, sizeof(bitset_storage));
|
||||
parameterDataTypes_ = std::vector<DataType>{
|
||||
PredType::STD_U64LE, PredType::STD_U32LE, PredType::STD_U32LE,
|
||||
PredType::STD_U64LE, PredType::STD_U64LE, PredType::STD_U16LE,
|
||||
PredType::STD_U16LE, PredType::STD_U16LE, PredType::STD_U16LE,
|
||||
PredType::STD_U32LE, PredType::STD_U16LE, PredType::STD_U8LE,
|
||||
PredType::STD_U8LE, strdatatype};
|
||||
}
|
||||
|
||||
HDF5DataFile::~HDF5DataFile() { CloseFile(); }
|
||||
|
||||
std::array<std::string, 2> HDF5DataFile::GetFileAndDatasetName() const {
|
||||
return std::array<std::string, 2>{fileName_, dataSetName_};
|
||||
}
|
||||
|
||||
uint32_t HDF5DataFile::GetFilesInAcquisition() const {
|
||||
return numFilesInAcquisition_;
|
||||
}
|
||||
|
||||
DataType HDF5DataFile::GetPDataType() const { return dataType_; }
|
||||
|
||||
std::vector<std::string> HDF5DataFile::GetParameterNames() const {
|
||||
return parameterNames_;
|
||||
}
|
||||
std::vector<DataType> HDF5DataFile::GetParameterDataTypes() const {
|
||||
return parameterDataTypes_;
|
||||
}
|
||||
|
||||
void HDF5DataFile::CloseFile() {
|
||||
std::lock_guard<std::mutex> lock(*hdf5Lib_);
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
if (fd_) {
|
||||
fd_->close();
|
||||
delete fd_;
|
||||
fd_ = nullptr;
|
||||
}
|
||||
} catch (const Exception &error) {
|
||||
LOG(logERROR) << "Could not close data HDF5 handles of index "
|
||||
<< index_;
|
||||
error.printErrorStack();
|
||||
}
|
||||
if (dataSpace_) {
|
||||
delete dataSpace_;
|
||||
dataSpace_ = nullptr;
|
||||
}
|
||||
if (dataSet_) {
|
||||
delete dataSet_;
|
||||
dataSet_ = nullptr;
|
||||
}
|
||||
if (dataSpacePara_) {
|
||||
delete dataSpacePara_;
|
||||
dataSpacePara_ = nullptr;
|
||||
}
|
||||
for (auto it : dataSetPara_)
|
||||
delete it;
|
||||
dataSetPara_.clear();
|
||||
}
|
||||
|
||||
void HDF5DataFile::CreateFirstHDF5DataFile(
|
||||
const std::string filePath, const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode,
|
||||
const int modulePos, const int numUnitsPerReadout,
|
||||
const uint32_t udpPortNumber, const uint32_t maxFramesPerFile,
|
||||
const uint64_t numImages, const uint32_t nPixelsX, const uint32_t nPixelsY,
|
||||
const uint32_t dynamicRange) {
|
||||
|
||||
subFileIndex_ = 0;
|
||||
numFramesInFile_ = 0;
|
||||
extNumImages_ = numImages;
|
||||
numFilesInAcquisition_ = 0;
|
||||
|
||||
maxFramesPerFile_ = maxFramesPerFile;
|
||||
numImages_ = numImages;
|
||||
nPixelsX_ = nPixelsX;
|
||||
nPixelsY_ = nPixelsY;
|
||||
dynamicRange_ = dynamicRange;
|
||||
|
||||
filePath_ = filePath;
|
||||
fileNamePrefix_ = fileNamePrefix;
|
||||
fileIndex_ = fileIndex;
|
||||
overWriteEnable_ = overWriteEnable;
|
||||
silentMode_ = silentMode;
|
||||
detIndex_ = modulePos;
|
||||
numUnitsPerReadout_ = numUnitsPerReadout;
|
||||
udpPortNumber_ = udpPortNumber;
|
||||
|
||||
switch (dynamicRange_) {
|
||||
case 16:
|
||||
dataType_ = PredType::STD_U16LE;
|
||||
break;
|
||||
case 32:
|
||||
dataType_ = PredType::STD_U32LE;
|
||||
break;
|
||||
default:
|
||||
dataType_ = PredType::STD_U8LE;
|
||||
break;
|
||||
}
|
||||
|
||||
CreateFile();
|
||||
}
|
||||
|
||||
void HDF5DataFile::CreateFile() {
|
||||
|
||||
numFilesInAcquisition_++;
|
||||
|
||||
std::ostringstream os;
|
||||
os << filePath_ << "/" << fileNamePrefix_ << "_d"
|
||||
<< (detIndex_ * numUnitsPerReadout_ + index_) << "_f" << subFileIndex_
|
||||
<< '_' << fileIndex_ << ".h5";
|
||||
fileName_ = os.str();
|
||||
|
||||
std::lock_guard<std::mutex> lock(*hdf5Lib_);
|
||||
|
||||
uint64_t framestosave =
|
||||
((maxFramesPerFile_ == 0) ? numImages_ : // infinite images
|
||||
(((extNumImages_ - subFileIndex_) > maxFramesPerFile_)
|
||||
? // save up to maximum at a time
|
||||
maxFramesPerFile_
|
||||
: (extNumImages_ - subFileIndex_)));
|
||||
|
||||
uint64_t nDimx = framestosave;
|
||||
uint32_t nDimy = nPixelsY_;
|
||||
uint32_t nDimz = ((dynamicRange_ == 4) ? (nPixelsX_ / 2) : nPixelsX_);
|
||||
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
|
||||
// file
|
||||
FileAccPropList fapl;
|
||||
fapl.setFcloseDegree(H5F_CLOSE_STRONG);
|
||||
fd_ = nullptr;
|
||||
if (!overWriteEnable_)
|
||||
fd_ = new H5File(fileName_.c_str(), H5F_ACC_EXCL,
|
||||
FileCreatPropList::DEFAULT, fapl);
|
||||
else
|
||||
fd_ = new H5File(fileName_.c_str(), H5F_ACC_TRUNC,
|
||||
FileCreatPropList::DEFAULT, fapl);
|
||||
|
||||
// attributes - version
|
||||
double dValue = HDF5_WRITER_VERSION;
|
||||
DataSpace dataspace_attr = DataSpace(H5S_SCALAR);
|
||||
Attribute attribute = fd_->createAttribute(
|
||||
"version", PredType::NATIVE_DOUBLE, dataspace_attr);
|
||||
attribute.write(PredType::NATIVE_DOUBLE, &dValue);
|
||||
|
||||
// dataspace
|
||||
hsize_t srcdims[3] = {nDimx, nDimy, nDimz};
|
||||
hsize_t srcdimsmax[3] = {H5S_UNLIMITED, nDimy, nDimz};
|
||||
dataSpace_ = nullptr;
|
||||
dataSpace_ = new DataSpace(3, srcdims, srcdimsmax);
|
||||
|
||||
// dataset name
|
||||
std::ostringstream osfn;
|
||||
osfn << "/data";
|
||||
if (numImages_ > 1)
|
||||
osfn << "_f" << std::setfill('0') << std::setw(12) << subFileIndex_;
|
||||
dataSetName_ = osfn.str();
|
||||
|
||||
// dataset
|
||||
// fill value
|
||||
DSetCreatPropList plist;
|
||||
int fill_value = -1;
|
||||
plist.setFillValue(dataType_, &fill_value);
|
||||
// always create chunked dataset as unlimited is only
|
||||
// supported with chunked layout
|
||||
hsize_t chunk_dims[3] = {MAX_CHUNKED_IMAGES, nDimy, nDimz};
|
||||
plist.setChunk(3, chunk_dims);
|
||||
dataSet_ = nullptr;
|
||||
dataSet_ = new DataSet(fd_->createDataSet(
|
||||
dataSetName_.c_str(), dataType_, *dataSpace_, plist));
|
||||
|
||||
// create parameter datasets
|
||||
hsize_t dims[1] = {nDimx};
|
||||
hsize_t dimsmax[1] = {H5S_UNLIMITED};
|
||||
dataSpacePara_ = nullptr;
|
||||
dataSpacePara_ = new DataSpace(1, dims, dimsmax);
|
||||
|
||||
// always create chunked dataset as unlimited is only
|
||||
// supported with chunked layout
|
||||
DSetCreatPropList paralist;
|
||||
hsize_t chunkpara_dims[3] = {MAX_CHUNKED_IMAGES};
|
||||
paralist.setChunk(1, chunkpara_dims);
|
||||
|
||||
for (unsigned int i = 0; i < parameterNames_.size(); ++i) {
|
||||
DataSet *ds = new DataSet(fd_->createDataSet(
|
||||
parameterNames_[i].c_str(), parameterDataTypes_[i],
|
||||
*dataSpacePara_, paralist));
|
||||
dataSetPara_.push_back(ds);
|
||||
}
|
||||
} catch (const Exception &error) {
|
||||
error.printErrorStack();
|
||||
CloseFile();
|
||||
throw sls::RuntimeError("Could not create HDF5 handles in object " +
|
||||
index_);
|
||||
}
|
||||
if (!silentMode_) {
|
||||
LOG(logINFO) << "[" << udpPortNumber_
|
||||
<< "]: HDF5 File created: " << fileName_;
|
||||
}
|
||||
}
|
||||
|
||||
void HDF5DataFile::WriteToFile(char *buffer, const int buffersize,
|
||||
const uint64_t currentFrameNumber,
|
||||
const uint32_t numPacketsCaught) {
|
||||
|
||||
// check if maxframesperfile = 0 for infinite
|
||||
if (maxFramesPerFile_ && (numFramesInFile_ >= maxFramesPerFile_)) {
|
||||
CloseFile();
|
||||
++subFileIndex_;
|
||||
CreateFile();
|
||||
}
|
||||
numFramesInFile_++;
|
||||
|
||||
// extend dataset (when receiver start followed by many status starts
|
||||
// (jungfrau)))
|
||||
if (currentFrameNumber >= extNumImages_) {
|
||||
ExtendDataset();
|
||||
}
|
||||
|
||||
WriteDataFile(currentFrameNumber, buffer + sizeof(sls_receiver_header));
|
||||
WriteParameterDatasets(currentFrameNumber, (sls_receiver_header *)(buffer));
|
||||
}
|
||||
|
||||
void HDF5DataFile::WriteDataFile(const uint64_t currentFrameNumber,
|
||||
char *buffer) {
|
||||
std::lock_guard<std::mutex> lock(*hdf5Lib_);
|
||||
|
||||
uint64_t nDimx =
|
||||
((maxFramesPerFile_ == 0) ? currentFrameNumber
|
||||
: currentFrameNumber % maxFramesPerFile_);
|
||||
uint32_t nDimy = nPixelsY_;
|
||||
uint32_t nDimz = ((dynamicRange_ == 4) ? (nPixelsX_ / 2) : nPixelsX_);
|
||||
|
||||
hsize_t count[3] = {1, nDimy, nDimz};
|
||||
hsize_t start[3] = {nDimx, 0, 0};
|
||||
hsize_t dims2[2] = {nDimy, nDimz};
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
|
||||
dataSpace_->selectHyperslab(H5S_SELECT_SET, count, start);
|
||||
DataSpace memspace(2, dims2);
|
||||
dataSet_->write(buffer, dataType_, memspace, *dataSpace_);
|
||||
memspace.close();
|
||||
} catch (const Exception &error) {
|
||||
LOG(logERROR) << "Could not write to file in object " << index_;
|
||||
error.printErrorStack();
|
||||
throw sls::RuntimeError("Could not write to file in object " +
|
||||
std::to_string(index_));
|
||||
}
|
||||
}
|
||||
|
||||
void HDF5DataFile::WriteParameterDatasets(const uint64_t currentFrameNumber,
|
||||
sls_receiver_header *rheader) {
|
||||
std::lock_guard<std::mutex> lock(*hdf5Lib_);
|
||||
|
||||
uint64_t fnum =
|
||||
((maxFramesPerFile_ == 0) ? currentFrameNumber
|
||||
: currentFrameNumber % maxFramesPerFile_);
|
||||
|
||||
sls_detector_header header = rheader->detHeader;
|
||||
hsize_t count[1] = {1};
|
||||
hsize_t start[1] = {fnum};
|
||||
int i = 0;
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
dataSpacePara_->selectHyperslab(H5S_SELECT_SET, count, start);
|
||||
DataSpace memspace(H5S_SCALAR);
|
||||
dataSetPara_[0]->write(&header.frameNumber, parameterDataTypes_[0],
|
||||
memspace, *dataSpacePara_);
|
||||
i = 1;
|
||||
dataSetPara_[1]->write(&header.expLength, parameterDataTypes_[1],
|
||||
memspace, *dataSpacePara_);
|
||||
i = 2;
|
||||
dataSetPara_[2]->write(&header.packetNumber, parameterDataTypes_[2],
|
||||
memspace, *dataSpacePara_);
|
||||
i = 3;
|
||||
dataSetPara_[3]->write(&header.bunchId, parameterDataTypes_[3],
|
||||
memspace, *dataSpacePara_);
|
||||
i = 4;
|
||||
dataSetPara_[4]->write(&header.timestamp, parameterDataTypes_[4],
|
||||
memspace, *dataSpacePara_);
|
||||
i = 5;
|
||||
dataSetPara_[5]->write(&header.modId, parameterDataTypes_[5], memspace,
|
||||
*dataSpacePara_);
|
||||
i = 6;
|
||||
dataSetPara_[6]->write(&header.row, parameterDataTypes_[6], memspace,
|
||||
*dataSpacePara_);
|
||||
i = 7;
|
||||
dataSetPara_[7]->write(&header.column, parameterDataTypes_[7], memspace,
|
||||
*dataSpacePara_);
|
||||
i = 8;
|
||||
dataSetPara_[8]->write(&header.reserved, parameterDataTypes_[8],
|
||||
memspace, *dataSpacePara_);
|
||||
i = 9;
|
||||
dataSetPara_[9]->write(&header.debug, parameterDataTypes_[9], memspace,
|
||||
*dataSpacePara_);
|
||||
i = 10;
|
||||
dataSetPara_[10]->write(&header.roundRNumber, parameterDataTypes_[10],
|
||||
memspace, *dataSpacePara_);
|
||||
i = 11;
|
||||
dataSetPara_[11]->write(&header.detType, parameterDataTypes_[11],
|
||||
memspace, *dataSpacePara_);
|
||||
i = 12;
|
||||
dataSetPara_[12]->write(&header.version, parameterDataTypes_[12],
|
||||
memspace, *dataSpacePara_);
|
||||
i = 13;
|
||||
|
||||
// contiguous bitset
|
||||
if (sizeof(sls_bitset) == sizeof(bitset_storage)) {
|
||||
dataSetPara_[13]->write((char *)&(rheader->packetsMask),
|
||||
parameterDataTypes_[13], memspace,
|
||||
*dataSpacePara_);
|
||||
}
|
||||
|
||||
// not contiguous bitset
|
||||
else {
|
||||
// get contiguous representation of bit mask
|
||||
bitset_storage storage;
|
||||
memset(storage, 0, sizeof(bitset_storage));
|
||||
sls_bitset bits = rheader->packetsMask;
|
||||
for (int i = 0; i < MAX_NUM_PACKETS; ++i)
|
||||
storage[i >> 3] |= (bits[i] << (i & 7));
|
||||
// write bitmask
|
||||
dataSetPara_[13]->write((char *)storage, parameterDataTypes_[13],
|
||||
memspace, *dataSpacePara_);
|
||||
}
|
||||
i = 14;
|
||||
} catch (const Exception &error) {
|
||||
error.printErrorStack();
|
||||
throw sls::RuntimeError(
|
||||
"Could not write parameters (index:" + std::to_string(i) +
|
||||
") to file in object " + std::to_string(index_));
|
||||
}
|
||||
}
|
||||
|
||||
void HDF5DataFile::ExtendDataset() {
|
||||
std::lock_guard<std::mutex> lock(*hdf5Lib_);
|
||||
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
|
||||
hsize_t dims[3];
|
||||
dataSpace_->getSimpleExtentDims(dims);
|
||||
dims[0] += numImages_;
|
||||
|
||||
dataSet_->extend(dims);
|
||||
delete dataSpace_;
|
||||
dataSpace_ = nullptr;
|
||||
dataSpace_ = new DataSpace(dataSet_->getSpace());
|
||||
|
||||
hsize_t dims_para[1] = {dims[0]};
|
||||
for (unsigned int i = 0; i < dataSetPara_.size(); ++i)
|
||||
dataSetPara_[i]->extend(dims_para);
|
||||
delete dataSpacePara_;
|
||||
dataSpacePara_ = nullptr;
|
||||
dataSpacePara_ = new DataSpace(dataSetPara_[0]->getSpace());
|
||||
|
||||
} catch (const Exception &error) {
|
||||
error.printErrorStack();
|
||||
throw sls::RuntimeError("Could not extend dataset in object " +
|
||||
std::to_string(index_));
|
||||
}
|
||||
if (!silentMode_) {
|
||||
LOG(logINFO) << index_ << " Extending HDF5 dataset by " << extNumImages_
|
||||
<< ", Total x Dimension: " << (extNumImages_ + numImages_);
|
||||
}
|
||||
extNumImages_ += numImages_;
|
||||
}
|
73
slsReceiverSoftware/src/HDF5DataFile.h
Normal file
73
slsReceiverSoftware/src/HDF5DataFile.h
Normal file
@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include "File.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
class HDF5DataFile : private virtual slsDetectorDefs, public File {
|
||||
|
||||
public:
|
||||
HDF5DataFile(const int index, std::mutex *hdf5Lib);
|
||||
~HDF5DataFile();
|
||||
|
||||
std::array<std::string, 2> GetFileAndDatasetName() const override;
|
||||
uint32_t GetFilesInAcquisition() const override;
|
||||
DataType GetPDataType() const override;
|
||||
std::vector<std::string> GetParameterNames() const override;
|
||||
std::vector<DataType> GetParameterDataTypes() const override;
|
||||
|
||||
void CloseFile() override;
|
||||
|
||||
void CreateFirstHDF5DataFile(
|
||||
const std::string filePath, const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable,
|
||||
const bool silentMode, const int modulePos,
|
||||
const int numUnitsPerReadout, const uint32_t udpPortNumber,
|
||||
const uint32_t maxFramesPerFile, const uint64_t numImages,
|
||||
const uint32_t nPixelsX, const uint32_t nPixelsY,
|
||||
const uint32_t dynamicRange) override;
|
||||
|
||||
void WriteToFile(char *buffer, const int buffersize,
|
||||
const uint64_t currentFrameNumber,
|
||||
const uint32_t numPacketsCaught) override;
|
||||
|
||||
private:
|
||||
void CreateFile();
|
||||
void WriteDataFile(const uint64_t currentFrameNumber, char *buffer);
|
||||
void WriteParameterDatasets(const uint64_t currentFrameNumber,
|
||||
sls_receiver_header *rheader);
|
||||
void ExtendDataset();
|
||||
|
||||
int index_;
|
||||
std::mutex *hdf5Lib_;
|
||||
H5File *fd_{nullptr};
|
||||
std::string fileName_;
|
||||
std::string dataSetName_;
|
||||
DataSpace *dataSpace_{nullptr};
|
||||
DataSet *dataSet_{nullptr};
|
||||
DataType dataType_{PredType::STD_U16LE};
|
||||
|
||||
DataSpace *dataSpacePara_{nullptr};
|
||||
std::vector<DataSet *> dataSetPara_{nullptr};
|
||||
std::vector<std::string> parameterNames_;
|
||||
std::vector<DataType> parameterDataTypes_;
|
||||
|
||||
uint32_t subFileIndex_{0};
|
||||
uint32_t numFramesInFile_{0};
|
||||
uint32_t numFilesInAcquisition_{0};
|
||||
uint32_t maxFramesPerFile_{0};
|
||||
uint64_t numImages_{0};
|
||||
uint64_t extNumImages_{0};
|
||||
uint32_t nPixelsX_{0};
|
||||
uint32_t nPixelsY_{0};
|
||||
uint32_t dynamicRange_{0};
|
||||
|
||||
std::string filePath_;
|
||||
std::string fileNamePrefix_;
|
||||
uint64_t fileIndex_{0};
|
||||
bool overWriteEnable_{false};
|
||||
bool silentMode_{false};
|
||||
int detIndex_{0};
|
||||
int numUnitsPerReadout_{0};
|
||||
uint32_t udpPortNumber_{0};
|
||||
};
|
@ -1,838 +0,0 @@
|
||||
/************************************************
|
||||
* @file HDF5File.cpp
|
||||
* @short sets/gets properties for the HDF5 file,
|
||||
* creates/closes the file and writes data to it
|
||||
***********************************************/
|
||||
#include "HDF5File.h"
|
||||
#include "Fifo.h"
|
||||
#include "MasterAttributes.h"
|
||||
#include "receiver_defs.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <libgen.h> //basename
|
||||
#include <string.h>
|
||||
|
||||
std::mutex HDF5File::hdf5Lib;
|
||||
|
||||
HDF5File::HDF5File(int ind, uint32_t *maxf, int *nd, std::string *fname,
|
||||
std::string *fpath, uint64_t *findex, bool *owenable,
|
||||
int *dindex, int *nunits, uint64_t *nf, uint32_t *dr,
|
||||
uint32_t *portno, uint32_t nx, uint32_t ny, bool *smode)
|
||||
:
|
||||
|
||||
File(ind, HDF5, maxf, nd, fname, fpath, findex, owenable, dindex, nunits,
|
||||
nf, dr, portno, smode),
|
||||
masterfd(nullptr), virtualfd(0), filefd(nullptr), dataspace(nullptr),
|
||||
dataset(nullptr), datatype(PredType::STD_U16LE), nPixelsX(nx),
|
||||
nPixelsY(ny), numFramesInFile(0), numActualPacketsInFile(0),
|
||||
numFilesinAcquisition(0), dataspace_para(nullptr), extNumImages(0) {
|
||||
PrintMembers();
|
||||
dataset_para.clear();
|
||||
parameterNames.clear();
|
||||
parameterDataTypes.clear();
|
||||
|
||||
parameterNames = std::vector<std::string>{
|
||||
"frame number",
|
||||
"exp length or sub exposure time",
|
||||
"packets caught",
|
||||
"bunch id",
|
||||
"timestamp",
|
||||
"mod id",
|
||||
"row",
|
||||
"column",
|
||||
"reserved",
|
||||
"debug",
|
||||
"round robin number",
|
||||
"detector type",
|
||||
"detector header version",
|
||||
"packets caught bit mask",
|
||||
};
|
||||
StrType strdatatype(PredType::C_S1, sizeof(bitset_storage));
|
||||
parameterDataTypes = std::vector<DataType>{
|
||||
PredType::STD_U64LE, PredType::STD_U32LE, PredType::STD_U32LE,
|
||||
PredType::STD_U64LE, PredType::STD_U64LE, PredType::STD_U16LE,
|
||||
PredType::STD_U16LE, PredType::STD_U16LE, PredType::STD_U16LE,
|
||||
PredType::STD_U32LE, PredType::STD_U16LE, PredType::STD_U8LE,
|
||||
PredType::STD_U8LE, strdatatype};
|
||||
}
|
||||
|
||||
HDF5File::~HDF5File() { CloseAllFiles(); }
|
||||
|
||||
void HDF5File::SetNumberofPixels(uint32_t nx, uint32_t ny) {
|
||||
nPixelsX = nx;
|
||||
nPixelsY = ny;
|
||||
}
|
||||
|
||||
void HDF5File::CreateFile() {
|
||||
numFilesinAcquisition++;
|
||||
numFramesInFile = 0;
|
||||
numActualPacketsInFile = 0;
|
||||
|
||||
// first time
|
||||
if (subFileIndex == 0u) {
|
||||
switch (*dynamicRange) {
|
||||
case 16:
|
||||
datatype = PredType::STD_U16LE;
|
||||
break;
|
||||
case 32:
|
||||
datatype = PredType::STD_U32LE;
|
||||
break;
|
||||
default:
|
||||
datatype = PredType::STD_U8LE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CreateDataFile();
|
||||
}
|
||||
|
||||
void HDF5File::CloseCurrentFile() {
|
||||
CloseFile(filefd, false);
|
||||
for (unsigned int i = 0; i < dataset_para.size(); ++i)
|
||||
delete dataset_para[i];
|
||||
dataset_para.clear();
|
||||
if (dataspace_para) {
|
||||
delete dataspace_para;
|
||||
dataspace_para = nullptr;
|
||||
}
|
||||
if (dataset) {
|
||||
delete dataset;
|
||||
dataset = nullptr;
|
||||
}
|
||||
if (dataspace) {
|
||||
delete dataspace;
|
||||
dataspace = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void HDF5File::CloseAllFiles() {
|
||||
numFilesinAcquisition = 0;
|
||||
{
|
||||
CloseFile(filefd, false);
|
||||
if (master) {
|
||||
CloseFile(masterfd, true);
|
||||
// close virtual file
|
||||
// c code due to only c implementation of H5Pset_virtual available
|
||||
if (virtualfd != 0) {
|
||||
if (H5Fclose(virtualfd) < 0) {
|
||||
LOG(logERROR) << "Could not close virtual HDF5 handles";
|
||||
}
|
||||
virtualfd = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (unsigned int i = 0; i < dataset_para.size(); ++i)
|
||||
delete dataset_para[i];
|
||||
dataset_para.clear();
|
||||
delete dataspace_para;
|
||||
delete dataset;
|
||||
delete dataspace;
|
||||
}
|
||||
|
||||
void HDF5File::WriteToFile(char *buffer, int bufferSize,
|
||||
uint64_t currentFrameNumber,
|
||||
uint32_t numPacketsCaught) {
|
||||
|
||||
// check if maxframesperfile = 0 for infinite
|
||||
if ((*maxFramesPerFile) && (numFramesInFile >= (*maxFramesPerFile))) {
|
||||
CloseCurrentFile();
|
||||
++subFileIndex;
|
||||
CreateFile();
|
||||
}
|
||||
numFramesInFile++;
|
||||
numActualPacketsInFile += numPacketsCaught;
|
||||
|
||||
// extend dataset (when receiver start followed by many status starts
|
||||
// (jungfrau)))
|
||||
if (currentFrameNumber >= extNumImages) {
|
||||
ExtendDataset();
|
||||
}
|
||||
|
||||
WriteDataFile(currentFrameNumber, buffer + sizeof(sls_receiver_header));
|
||||
WriteParameterDatasets(currentFrameNumber, (sls_receiver_header *)(buffer));
|
||||
}
|
||||
|
||||
void HDF5File::CreateMasterFile(bool masterFileWriteEnable,
|
||||
MasterAttributes *attr) {
|
||||
|
||||
// beginning of every acquisition
|
||||
numFramesInFile = 0;
|
||||
numActualPacketsInFile = 0;
|
||||
extNumImages = *numImages;
|
||||
|
||||
if (masterFileWriteEnable && master) {
|
||||
virtualfd = 0;
|
||||
CreateMasterDataFile(attr);
|
||||
}
|
||||
}
|
||||
|
||||
void HDF5File::EndofAcquisition(bool anyPacketsCaught,
|
||||
uint64_t numImagesCaught) {
|
||||
// not created before
|
||||
if (!virtualfd && anyPacketsCaught) {
|
||||
// called only by the one maser receiver
|
||||
if (master && masterfd != nullptr) {
|
||||
// only one file and one sub image (link current file in master)
|
||||
if (((numFilesinAcquisition == 1) && (numDetY * numDetX) == 1)) {
|
||||
// dataset name
|
||||
std::ostringstream oss;
|
||||
oss << "/data";
|
||||
if ((*numImages > 1)) {
|
||||
oss << "_f" << std::setfill('0') << std::setw(12) << 0;
|
||||
}
|
||||
std::string dsetname = oss.str();
|
||||
|
||||
LinkVirtualInMaster(currentFileName, dsetname);
|
||||
}
|
||||
// create virutal file
|
||||
else {
|
||||
CreateVirtualDataFile(
|
||||
// infinite images in 1 file, then maxfrperfile =
|
||||
// numImagesCaught
|
||||
((*maxFramesPerFile == 0) ? numImagesCaught + 1
|
||||
: *maxFramesPerFile),
|
||||
numImagesCaught + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
numFilesinAcquisition = 0;
|
||||
}
|
||||
|
||||
void HDF5File::CloseFile(H5File *&fd, bool masterFile) {
|
||||
std::lock_guard<std::mutex> lock(HDF5File::hdf5Lib);
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
if (fd) {
|
||||
fd->close();
|
||||
delete fd;
|
||||
fd = nullptr;
|
||||
}
|
||||
} catch (const Exception &error) {
|
||||
LOG(logERROR) << "Could not close " << (masterFile ? "master" : "data")
|
||||
<< " HDF5 handles of index " << index;
|
||||
error.printErrorStack();
|
||||
}
|
||||
}
|
||||
|
||||
void HDF5File::WriteDataFile(uint64_t currentFrameNumber, char *buffer) {
|
||||
std::lock_guard<std::mutex> lock(HDF5File::hdf5Lib);
|
||||
|
||||
uint64_t nDimx =
|
||||
((*maxFramesPerFile == 0) ? currentFrameNumber
|
||||
: currentFrameNumber % (*maxFramesPerFile));
|
||||
uint32_t nDimy = nPixelsY;
|
||||
uint32_t nDimz = ((*dynamicRange == 4) ? (nPixelsX / 2) : nPixelsX);
|
||||
|
||||
hsize_t count[3] = {1, nDimy, nDimz};
|
||||
hsize_t start[3] = {nDimx, 0, 0};
|
||||
hsize_t dims2[2] = {nDimy, nDimz};
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
|
||||
dataspace->selectHyperslab(H5S_SELECT_SET, count, start);
|
||||
DataSpace memspace(2, dims2);
|
||||
dataset->write(buffer, datatype, memspace, *dataspace);
|
||||
memspace.close();
|
||||
} catch (const Exception &error) {
|
||||
LOG(logERROR) << "Could not write to file in object " << index;
|
||||
error.printErrorStack();
|
||||
throw sls::RuntimeError("Could not write to file in object " +
|
||||
std::to_string(index));
|
||||
}
|
||||
}
|
||||
|
||||
void HDF5File::WriteParameterDatasets(uint64_t currentFrameNumber,
|
||||
sls_receiver_header *rheader) {
|
||||
std::lock_guard<std::mutex> lock(HDF5File::hdf5Lib);
|
||||
|
||||
uint64_t fnum =
|
||||
((*maxFramesPerFile == 0) ? currentFrameNumber
|
||||
: currentFrameNumber % (*maxFramesPerFile));
|
||||
|
||||
sls_detector_header header = rheader->detHeader;
|
||||
hsize_t count[1] = {1};
|
||||
hsize_t start[1] = {fnum};
|
||||
int i = 0;
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
dataspace_para->selectHyperslab(H5S_SELECT_SET, count, start);
|
||||
DataSpace memspace(H5S_SCALAR);
|
||||
dataset_para[0]->write(&header.frameNumber, parameterDataTypes[0],
|
||||
memspace, *dataspace_para);
|
||||
i = 1;
|
||||
dataset_para[1]->write(&header.expLength, parameterDataTypes[1],
|
||||
memspace, *dataspace_para);
|
||||
i = 2;
|
||||
dataset_para[2]->write(&header.packetNumber, parameterDataTypes[2],
|
||||
memspace, *dataspace_para);
|
||||
i = 3;
|
||||
dataset_para[3]->write(&header.bunchId, parameterDataTypes[3], memspace,
|
||||
*dataspace_para);
|
||||
i = 4;
|
||||
dataset_para[4]->write(&header.timestamp, parameterDataTypes[4],
|
||||
memspace, *dataspace_para);
|
||||
i = 5;
|
||||
dataset_para[5]->write(&header.modId, parameterDataTypes[5], memspace,
|
||||
*dataspace_para);
|
||||
i = 6;
|
||||
dataset_para[6]->write(&header.row, parameterDataTypes[6], memspace,
|
||||
*dataspace_para);
|
||||
i = 7;
|
||||
dataset_para[7]->write(&header.column, parameterDataTypes[7], memspace,
|
||||
*dataspace_para);
|
||||
i = 8;
|
||||
dataset_para[8]->write(&header.reserved, parameterDataTypes[8],
|
||||
memspace, *dataspace_para);
|
||||
i = 9;
|
||||
dataset_para[9]->write(&header.debug, parameterDataTypes[9], memspace,
|
||||
*dataspace_para);
|
||||
i = 10;
|
||||
dataset_para[10]->write(&header.roundRNumber, parameterDataTypes[10],
|
||||
memspace, *dataspace_para);
|
||||
i = 11;
|
||||
dataset_para[11]->write(&header.detType, parameterDataTypes[11],
|
||||
memspace, *dataspace_para);
|
||||
i = 12;
|
||||
dataset_para[12]->write(&header.version, parameterDataTypes[12],
|
||||
memspace, *dataspace_para);
|
||||
i = 13;
|
||||
|
||||
// contiguous bitset
|
||||
if (sizeof(sls_bitset) == sizeof(bitset_storage)) {
|
||||
dataset_para[13]->write((char *)&(rheader->packetsMask),
|
||||
parameterDataTypes[13], memspace,
|
||||
*dataspace_para);
|
||||
}
|
||||
|
||||
// not contiguous bitset
|
||||
else {
|
||||
// get contiguous representation of bit mask
|
||||
bitset_storage storage;
|
||||
memset(storage, 0, sizeof(bitset_storage));
|
||||
sls_bitset bits = rheader->packetsMask;
|
||||
for (int i = 0; i < MAX_NUM_PACKETS; ++i)
|
||||
storage[i >> 3] |= (bits[i] << (i & 7));
|
||||
// write bitmask
|
||||
dataset_para[13]->write((char *)storage, parameterDataTypes[13],
|
||||
memspace, *dataspace_para);
|
||||
}
|
||||
i = 14;
|
||||
} catch (const Exception &error) {
|
||||
error.printErrorStack();
|
||||
throw sls::RuntimeError(
|
||||
"Could not write parameters (index:" + std::to_string(i) +
|
||||
") to file in object " + std::to_string(index));
|
||||
}
|
||||
}
|
||||
|
||||
void HDF5File::ExtendDataset() {
|
||||
std::lock_guard<std::mutex> lock(HDF5File::hdf5Lib);
|
||||
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
|
||||
hsize_t dims[3];
|
||||
dataspace->getSimpleExtentDims(dims);
|
||||
dims[0] += *numImages;
|
||||
|
||||
dataset->extend(dims);
|
||||
delete dataspace;
|
||||
dataspace = nullptr;
|
||||
dataspace = new DataSpace(dataset->getSpace());
|
||||
|
||||
hsize_t dims_para[1] = {dims[0]};
|
||||
for (unsigned int i = 0; i < dataset_para.size(); ++i)
|
||||
dataset_para[i]->extend(dims_para);
|
||||
delete dataspace_para;
|
||||
dataspace_para = nullptr;
|
||||
dataspace_para = new DataSpace(dataset_para[0]->getSpace());
|
||||
|
||||
} catch (const Exception &error) {
|
||||
error.printErrorStack();
|
||||
throw sls::RuntimeError("Could not extend dataset in object " +
|
||||
std::to_string(index));
|
||||
}
|
||||
if (!(*silentMode)) {
|
||||
LOG(logINFO) << index << " Extending HDF5 dataset by " << extNumImages
|
||||
<< ", Total x Dimension: " << (extNumImages + *numImages);
|
||||
}
|
||||
extNumImages += *numImages;
|
||||
}
|
||||
|
||||
void HDF5File::CreateDataFile() {
|
||||
|
||||
std::ostringstream os;
|
||||
os << *filePath << "/" << *fileNamePrefix << "_d"
|
||||
<< (*detIndex * (*numUnitsPerDetector) + index) << "_f" << subFileIndex
|
||||
<< '_' << *fileIndex << ".h5";
|
||||
currentFileName = os.str();
|
||||
|
||||
std::lock_guard<std::mutex> lock(HDF5File::hdf5Lib);
|
||||
|
||||
uint64_t framestosave =
|
||||
((*maxFramesPerFile == 0) ? *numImages : // infinite images
|
||||
(((extNumImages - subFileIndex) > (*maxFramesPerFile))
|
||||
? // save up to maximum at a time
|
||||
(*maxFramesPerFile)
|
||||
: (extNumImages - subFileIndex)));
|
||||
|
||||
uint64_t nDimx = framestosave;
|
||||
uint32_t nDimy = nPixelsY;
|
||||
uint32_t nDimz = ((*dynamicRange == 4) ? (nPixelsX / 2) : nPixelsX);
|
||||
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
|
||||
// file
|
||||
FileAccPropList fapl;
|
||||
fapl.setFcloseDegree(H5F_CLOSE_STRONG);
|
||||
filefd = nullptr;
|
||||
if (!(*overWriteEnable))
|
||||
filefd = new H5File(currentFileName.c_str(), H5F_ACC_EXCL,
|
||||
FileCreatPropList::DEFAULT, fapl);
|
||||
else
|
||||
filefd = new H5File(currentFileName.c_str(), H5F_ACC_TRUNC,
|
||||
FileCreatPropList::DEFAULT, fapl);
|
||||
|
||||
// attributes - version
|
||||
double dValue = HDF5_WRITER_VERSION;
|
||||
DataSpace dataspace_attr = DataSpace(H5S_SCALAR);
|
||||
Attribute attribute = filefd->createAttribute(
|
||||
"version", PredType::NATIVE_DOUBLE, dataspace_attr);
|
||||
attribute.write(PredType::NATIVE_DOUBLE, &dValue);
|
||||
|
||||
// dataspace
|
||||
hsize_t srcdims[3] = {nDimx, nDimy, nDimz};
|
||||
hsize_t srcdimsmax[3] = {H5S_UNLIMITED, nDimy, nDimz};
|
||||
dataspace = nullptr;
|
||||
dataspace = new DataSpace(3, srcdims, srcdimsmax);
|
||||
|
||||
// dataset name
|
||||
std::ostringstream osfn;
|
||||
osfn << "/data";
|
||||
if (*numImages > 1)
|
||||
osfn << "_f" << std::setfill('0') << std::setw(12) << subFileIndex;
|
||||
std::string dsetname = osfn.str();
|
||||
|
||||
// dataset
|
||||
// fill value
|
||||
DSetCreatPropList plist;
|
||||
int fill_value = -1;
|
||||
plist.setFillValue(datatype, &fill_value);
|
||||
// always create chunked dataset as unlimited is only
|
||||
// supported with chunked layout
|
||||
hsize_t chunk_dims[3] = {MAX_CHUNKED_IMAGES, nDimy, nDimz};
|
||||
plist.setChunk(3, chunk_dims);
|
||||
dataset = nullptr;
|
||||
dataset = new DataSet(filefd->createDataSet(dsetname.c_str(), datatype,
|
||||
*dataspace, plist));
|
||||
|
||||
// create parameter datasets
|
||||
hsize_t dims[1] = {nDimx};
|
||||
hsize_t dimsmax[1] = {H5S_UNLIMITED};
|
||||
dataspace_para = nullptr;
|
||||
dataspace_para = new DataSpace(1, dims, dimsmax);
|
||||
|
||||
// always create chunked dataset as unlimited is only
|
||||
// supported with chunked layout
|
||||
DSetCreatPropList paralist;
|
||||
hsize_t chunkpara_dims[3] = {MAX_CHUNKED_IMAGES};
|
||||
paralist.setChunk(1, chunkpara_dims);
|
||||
|
||||
for (unsigned int i = 0; i < parameterNames.size(); ++i) {
|
||||
DataSet *ds = new DataSet(filefd->createDataSet(
|
||||
parameterNames[i].c_str(), parameterDataTypes[i],
|
||||
*dataspace_para, paralist));
|
||||
dataset_para.push_back(ds);
|
||||
}
|
||||
} catch (const Exception &error) {
|
||||
error.printErrorStack();
|
||||
if (filefd) {
|
||||
filefd->close();
|
||||
}
|
||||
throw sls::RuntimeError("Could not create HDF5 handles in object " +
|
||||
index);
|
||||
}
|
||||
if (!(*silentMode)) {
|
||||
LOG(logINFO) << *udpPortNumber
|
||||
<< ": HDF5 File created: " << currentFileName;
|
||||
}
|
||||
}
|
||||
|
||||
void HDF5File::CreateMasterDataFile(MasterAttributes *attr) {
|
||||
|
||||
std::ostringstream os;
|
||||
os << *filePath << "/" << *fileNamePrefix << "_master"
|
||||
<< "_" << *fileIndex << ".h5";
|
||||
masterFileName = os.str();
|
||||
|
||||
if (!(*silentMode)) {
|
||||
LOG(logINFO) << "Master File: " << masterFileName;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(HDF5File::hdf5Lib);
|
||||
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
|
||||
FileAccPropList flist;
|
||||
flist.setFcloseDegree(H5F_CLOSE_STRONG);
|
||||
masterfd = nullptr;
|
||||
if (!(*overWriteEnable))
|
||||
masterfd = new H5File(masterFileName.c_str(), H5F_ACC_EXCL,
|
||||
FileCreatPropList::DEFAULT, flist);
|
||||
else
|
||||
masterfd = new H5File(masterFileName.c_str(), H5F_ACC_TRUNC,
|
||||
FileCreatPropList::DEFAULT, flist);
|
||||
|
||||
// Create a group in the file
|
||||
Group group1(masterfd->createGroup("entry"));
|
||||
Group group2(group1.createGroup("data"));
|
||||
Group group3(group1.createGroup("instrument"));
|
||||
Group group4(group3.createGroup("beam"));
|
||||
Group group5(group3.createGroup("detector"));
|
||||
Group group6(group1.createGroup("sample"));
|
||||
|
||||
attr->WriteMasterHDF5Attributes(masterfd, &group5);
|
||||
masterfd->close();
|
||||
|
||||
} catch (const Exception &error) {
|
||||
error.printErrorStack();
|
||||
if (masterfd) {
|
||||
masterfd->close();
|
||||
}
|
||||
throw sls::RuntimeError("Could not create master HDF5 handles");
|
||||
}
|
||||
}
|
||||
|
||||
void HDF5File::CreateVirtualDataFile(uint32_t maxFramesPerFile, uint64_t numf) {
|
||||
|
||||
std::ostringstream osfn;
|
||||
osfn << *filePath << "/" << *fileNamePrefix;
|
||||
osfn << "_virtual";
|
||||
osfn << "_" << *fileIndex;
|
||||
osfn << ".h5";
|
||||
std::string vname = osfn.str();
|
||||
|
||||
if (!(*silentMode)) {
|
||||
LOG(logINFO) << "Virtual File: " << vname;
|
||||
}
|
||||
|
||||
int numDetz = numDetX;
|
||||
uint32_t nDimy = nPixelsY;
|
||||
uint32_t nDimz = ((*dynamicRange == 4) ? (nPixelsX / 2) : nPixelsX);
|
||||
|
||||
std::lock_guard<std::mutex> lock(HDF5File::hdf5Lib);
|
||||
|
||||
try {
|
||||
// file
|
||||
hid_t dfal = H5Pcreate(H5P_FILE_ACCESS);
|
||||
if (dfal < 0)
|
||||
throw sls::RuntimeError(
|
||||
"Could not create file access property for virtual file " +
|
||||
vname);
|
||||
if (H5Pset_fclose_degree(dfal, H5F_CLOSE_STRONG) < 0)
|
||||
throw sls::RuntimeError(
|
||||
"Could not set strong file close degree for virtual file " +
|
||||
vname);
|
||||
virtualfd = H5Fcreate(vname.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, dfal);
|
||||
if (virtualfd < 0)
|
||||
throw sls::RuntimeError("Could not create virtual file " + vname);
|
||||
|
||||
// attributes - version
|
||||
hid_t dataspace_attr = H5Screate(H5S_SCALAR);
|
||||
if (dataspace_attr < 0)
|
||||
throw sls::RuntimeError(
|
||||
"Could not create dataspace for attribute in virtual file " +
|
||||
vname);
|
||||
hid_t attrid = H5Acreate2(virtualfd, "version", H5T_NATIVE_DOUBLE,
|
||||
dataspace_attr, H5P_DEFAULT, H5P_DEFAULT);
|
||||
if (attrid < 0)
|
||||
throw sls::RuntimeError(
|
||||
"Could not create attribute in virtual file " + vname);
|
||||
double attr_data = HDF5_WRITER_VERSION;
|
||||
if (H5Awrite(attrid, H5T_NATIVE_DOUBLE, &attr_data) < 0)
|
||||
throw sls::RuntimeError(
|
||||
"Could not write attribute in virtual file " + vname);
|
||||
if (H5Aclose(attrid) < 0)
|
||||
throw sls::RuntimeError(
|
||||
"Could not close attribute in virtual file " + vname);
|
||||
|
||||
// virtual dataspace
|
||||
hsize_t vdsdims[3] = {numf, numDetY * nDimy, numDetz * nDimz};
|
||||
hid_t vdsDataspace = H5Screate_simple(3, vdsdims, nullptr);
|
||||
if (vdsDataspace < 0)
|
||||
throw sls::RuntimeError(
|
||||
"Could not create virtual dataspace in virtual file " + vname);
|
||||
hsize_t vdsdims_para[2] = {numf, (unsigned int)numDetY * numDetz};
|
||||
hid_t vdsDataspace_para = H5Screate_simple(2, vdsdims_para, nullptr);
|
||||
if (vdsDataspace_para < 0)
|
||||
throw sls::RuntimeError("Could not create virtual dataspace "
|
||||
"(parameters) in virtual file " +
|
||||
vname);
|
||||
|
||||
// fill values
|
||||
hid_t dcpl = H5Pcreate(H5P_DATASET_CREATE);
|
||||
if (dcpl < 0)
|
||||
throw sls::RuntimeError(
|
||||
"Could not create file creation properties in virtual file " +
|
||||
vname);
|
||||
int fill_value = -1;
|
||||
if (H5Pset_fill_value(dcpl, GetDataTypeinC(datatype), &fill_value) < 0)
|
||||
throw sls::RuntimeError(
|
||||
"Could not create fill value in virtual file " + vname);
|
||||
std::vector<hid_t> dcpl_para(parameterNames.size());
|
||||
for (unsigned int i = 0; i < parameterNames.size(); ++i) {
|
||||
dcpl_para[i] = H5Pcreate(H5P_DATASET_CREATE);
|
||||
if (dcpl_para[i] < 0)
|
||||
throw sls::RuntimeError(
|
||||
"Could not create file creation properties (parameters) in "
|
||||
"virtual file " +
|
||||
vname);
|
||||
if (H5Pset_fill_value(dcpl_para[i],
|
||||
GetDataTypeinC(parameterDataTypes[i]),
|
||||
&fill_value) < 0)
|
||||
throw sls::RuntimeError("Could not create fill value "
|
||||
"(parameters) in virtual file " +
|
||||
vname);
|
||||
}
|
||||
|
||||
// hyperslab
|
||||
int numMajorHyperslab = numf / maxFramesPerFile;
|
||||
if (numf % maxFramesPerFile)
|
||||
numMajorHyperslab++;
|
||||
uint64_t framesSaved = 0;
|
||||
for (int j = 0; j < numMajorHyperslab; j++) {
|
||||
|
||||
uint64_t nDimx = ((numf - framesSaved) > maxFramesPerFile)
|
||||
? maxFramesPerFile
|
||||
: (numf - framesSaved);
|
||||
hsize_t offset[3] = {framesSaved, 0, 0};
|
||||
hsize_t count[3] = {nDimx, nDimy, nDimz};
|
||||
hsize_t offset_para[2] = {framesSaved, 0};
|
||||
hsize_t count_para[2] = {nDimx, 1};
|
||||
|
||||
for (int i = 0; i < numDetY * numDetz; ++i) {
|
||||
|
||||
// setect hyperslabs
|
||||
if (H5Sselect_hyperslab(vdsDataspace, H5S_SELECT_SET, offset,
|
||||
nullptr, count, nullptr) < 0) {
|
||||
throw sls::RuntimeError("Could not select hyperslab");
|
||||
}
|
||||
if (H5Sselect_hyperslab(vdsDataspace_para, H5S_SELECT_SET,
|
||||
offset_para, nullptr, count_para,
|
||||
nullptr) < 0) {
|
||||
throw sls::RuntimeError(
|
||||
"Could not select hyperslab for parameters");
|
||||
}
|
||||
|
||||
// source file name
|
||||
std::ostringstream os;
|
||||
os << *filePath << "/" << *fileNamePrefix << "_d"
|
||||
<< (*detIndex * (*numUnitsPerDetector) + i) << "_f" << j
|
||||
<< '_' << *fileIndex << ".h5";
|
||||
std::string srcFileName = os.str();
|
||||
|
||||
LOG(logDEBUG1) << srcFileName;
|
||||
// find relative path
|
||||
std::string relative_srcFileName = srcFileName;
|
||||
{
|
||||
size_t i = srcFileName.rfind('/', srcFileName.length());
|
||||
if (i != std::string::npos)
|
||||
relative_srcFileName = (srcFileName.substr(
|
||||
i + 1, srcFileName.length() - i));
|
||||
}
|
||||
|
||||
// source dataset name
|
||||
std::ostringstream osfn;
|
||||
osfn << "/data";
|
||||
if (*numImages > 1)
|
||||
osfn << "_f" << std::setfill('0') << std::setw(12) << j;
|
||||
std::string srcDatasetName = osfn.str();
|
||||
|
||||
// source dataspace
|
||||
hsize_t srcdims[3] = {nDimx, nDimy, nDimz};
|
||||
hsize_t srcdimsmax[3] = {H5S_UNLIMITED, nDimy, nDimz};
|
||||
hid_t srcDataspace = H5Screate_simple(3, srcdims, srcdimsmax);
|
||||
if (srcDataspace < 0)
|
||||
throw sls::RuntimeError(
|
||||
"Could not create source dataspace in virtual file " +
|
||||
vname);
|
||||
hsize_t srcdims_para[1] = {nDimx};
|
||||
hsize_t srcdimsmax_para[1] = {H5S_UNLIMITED};
|
||||
hid_t srcDataspace_para =
|
||||
H5Screate_simple(1, srcdims_para, srcdimsmax_para);
|
||||
if (srcDataspace_para < 0)
|
||||
throw sls::RuntimeError("Could not create source dataspace "
|
||||
"(parameters) in virtual file " +
|
||||
vname);
|
||||
|
||||
// mapping
|
||||
if (H5Pset_virtual(dcpl, vdsDataspace,
|
||||
relative_srcFileName.c_str(),
|
||||
srcDatasetName.c_str(), srcDataspace) < 0) {
|
||||
throw sls::RuntimeError(
|
||||
"Could not set mapping for paramter 1");
|
||||
}
|
||||
|
||||
for (unsigned int k = 0; k < parameterNames.size(); ++k) {
|
||||
if (H5Pset_virtual(dcpl_para[k], vdsDataspace_para,
|
||||
relative_srcFileName.c_str(),
|
||||
parameterNames[k].c_str(),
|
||||
srcDataspace_para) < 0) {
|
||||
throw sls::RuntimeError(
|
||||
"Could not set mapping for paramter " +
|
||||
std::to_string(k));
|
||||
}
|
||||
}
|
||||
|
||||
// H5Sclose(srcDataspace);
|
||||
// H5Sclose(srcDataspace_para);
|
||||
offset[2] += nDimz;
|
||||
if (offset[2] >= (numDetz * nDimz)) {
|
||||
offset[2] = 0;
|
||||
offset[1] += nDimy;
|
||||
}
|
||||
offset_para[1]++;
|
||||
}
|
||||
framesSaved += nDimx;
|
||||
}
|
||||
|
||||
// dataset
|
||||
std::string virtualDatasetName = "data";
|
||||
hid_t vdsdataset = H5Dcreate2(virtualfd, virtualDatasetName.c_str(),
|
||||
GetDataTypeinC(datatype), vdsDataspace,
|
||||
H5P_DEFAULT, dcpl, H5P_DEFAULT);
|
||||
if (vdsdataset < 0)
|
||||
throw sls::RuntimeError(
|
||||
"Could not create virutal dataset in virtual file " + vname);
|
||||
|
||||
// virtual parameter dataset
|
||||
for (unsigned int i = 0; i < parameterNames.size(); ++i) {
|
||||
hid_t vdsdataset_para = H5Dcreate2(
|
||||
virtualfd, parameterNames[i].c_str(),
|
||||
GetDataTypeinC(parameterDataTypes[i]), vdsDataspace_para,
|
||||
H5P_DEFAULT, dcpl_para[i], H5P_DEFAULT);
|
||||
if (vdsdataset_para < 0)
|
||||
throw sls::RuntimeError("Could not create virutal dataset "
|
||||
"(parameters) in virtual file " +
|
||||
vname);
|
||||
}
|
||||
|
||||
// close
|
||||
H5Fclose(virtualfd);
|
||||
virtualfd = 0;
|
||||
|
||||
// link
|
||||
LinkVirtualInMaster(vname, virtualDatasetName);
|
||||
} catch (const sls::RuntimeError &e) {
|
||||
if (virtualfd > 0)
|
||||
H5Fclose(virtualfd);
|
||||
virtualfd = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void HDF5File::LinkVirtualInMaster(std::string fname, std::string dsetname) {
|
||||
|
||||
if (fname == currentFileName) {
|
||||
std::lock_guard<std::mutex> lock(HDF5File::hdf5Lib);
|
||||
}
|
||||
|
||||
char linkname[100];
|
||||
hid_t vfd = 0;
|
||||
|
||||
try {
|
||||
hid_t dfal = H5Pcreate(H5P_FILE_ACCESS);
|
||||
if (dfal < 0)
|
||||
throw sls::RuntimeError(
|
||||
"Could not create file access property for link");
|
||||
if (H5Pset_fclose_degree(dfal, H5F_CLOSE_STRONG) < 0)
|
||||
throw sls::RuntimeError(
|
||||
"Could not set strong file close degree for link");
|
||||
|
||||
// open master file
|
||||
hid_t mfd = H5Fopen(masterFileName.c_str(), H5F_ACC_RDWR, dfal);
|
||||
if (mfd < 0)
|
||||
throw sls::RuntimeError("Could not open master file");
|
||||
|
||||
// open virtual file
|
||||
vfd = H5Fopen(fname.c_str(), H5F_ACC_RDWR, dfal);
|
||||
if (vfd < 0) {
|
||||
H5Fclose(mfd);
|
||||
mfd = 0;
|
||||
throw sls::RuntimeError("Could not open virtual file");
|
||||
}
|
||||
|
||||
// find relative path
|
||||
std::string relative_virtualfname = fname;
|
||||
{
|
||||
size_t i = fname.rfind('/', fname.length());
|
||||
if (i != std::string::npos)
|
||||
relative_virtualfname =
|
||||
(fname.substr(i + 1, fname.length() - i));
|
||||
}
|
||||
|
||||
//**data dataset**
|
||||
hid_t vdset = H5Dopen2(vfd, dsetname.c_str(), H5P_DEFAULT);
|
||||
if (vdset < 0) {
|
||||
H5Fclose(mfd);
|
||||
throw sls::RuntimeError("Could not open virtual data dataset");
|
||||
}
|
||||
sprintf(linkname, "/entry/data/%s", dsetname.c_str());
|
||||
if (H5Lcreate_external(relative_virtualfname.c_str(), dsetname.c_str(),
|
||||
mfd, linkname, H5P_DEFAULT, H5P_DEFAULT) < 0) {
|
||||
H5Fclose(mfd);
|
||||
mfd = 0;
|
||||
throw sls::RuntimeError("Could not create link to data dataset");
|
||||
}
|
||||
H5Dclose(vdset);
|
||||
|
||||
//**paramter datasets**
|
||||
for (unsigned int i = 0; i < parameterNames.size(); ++i) {
|
||||
hid_t vdset_para = H5Dopen2(
|
||||
vfd, (std::string(parameterNames[i])).c_str(), H5P_DEFAULT);
|
||||
if (vdset_para < 0) {
|
||||
H5Fclose(mfd);
|
||||
mfd = 0;
|
||||
throw sls::RuntimeError(
|
||||
"Could not open virtual parameter dataset to create link");
|
||||
}
|
||||
sprintf(linkname, "/entry/data/%s",
|
||||
(std::string(parameterNames[i])).c_str());
|
||||
|
||||
if (H5Lcreate_external(relative_virtualfname.c_str(),
|
||||
parameterNames[i].c_str(), mfd, linkname,
|
||||
H5P_DEFAULT, H5P_DEFAULT) < 0) {
|
||||
H5Fclose(mfd);
|
||||
mfd = 0;
|
||||
throw sls::RuntimeError(
|
||||
"Could not create link to virtual parameter dataset");
|
||||
}
|
||||
}
|
||||
|
||||
H5Fclose(mfd);
|
||||
mfd = 0;
|
||||
H5Fclose(vfd);
|
||||
vfd = 0;
|
||||
} catch (...) {
|
||||
if (vfd > 0)
|
||||
H5Fclose(vfd);
|
||||
vfd = 0;
|
||||
}
|
||||
}
|
||||
|
||||
hid_t HDF5File::GetDataTypeinC(DataType dtype) {
|
||||
if (dtype == PredType::STD_U8LE)
|
||||
return H5T_STD_U8LE;
|
||||
else if (dtype == PredType::STD_U16LE)
|
||||
return H5T_STD_U16LE;
|
||||
else if (dtype == PredType::STD_U32LE)
|
||||
return H5T_STD_U32LE;
|
||||
else if (dtype == PredType::STD_U64LE)
|
||||
return H5T_STD_U64LE;
|
||||
else {
|
||||
hid_t s = H5Tcopy(H5T_C_S1);
|
||||
H5Tset_size(s, MAX_NUM_PACKETS);
|
||||
return s;
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
#pragma once
|
||||
/************************************************
|
||||
* @file HDF5File.h
|
||||
* @short sets/gets properties for the HDF5 file,
|
||||
* creates/closes the file and writes data to it
|
||||
***********************************************/
|
||||
/**
|
||||
*@short sets/gets properties for the HDF5 file, creates/closes the file and
|
||||
*writes data to it
|
||||
*/
|
||||
|
||||
#include "File.h"
|
||||
|
||||
#include "H5Cpp.h"
|
||||
#ifndef H5_NO_NAMESPACE
|
||||
using namespace H5;
|
||||
#endif
|
||||
#include <mutex>
|
||||
|
||||
class HDF5File : private virtual slsDetectorDefs, public File {
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* creates the File Writer
|
||||
* @param ind self index
|
||||
* @param maxf pointer to max frames per file
|
||||
* @param nd pointer to number of detectors in each dimension
|
||||
* @param fname pointer to file name prefix
|
||||
* @param fpath pointer to file path
|
||||
* @param findex pointer to file index
|
||||
* @param owenable pointer to over write enable
|
||||
* @param dindex pointer to detector index
|
||||
* @param nunits pointer to number of theads/ units per detector
|
||||
* @param nf pointer to number of images in acquisition
|
||||
* @param dr pointer to dynamic range
|
||||
* @param portno pointer to udp port number for logging
|
||||
* @param nx number of pixels in x direction
|
||||
* @param ny number of pixels in y direction
|
||||
* @param smode pointer to silent mode
|
||||
*/
|
||||
HDF5File(int ind, uint32_t *maxf, int *nd, std::string *fname,
|
||||
std::string *fpath, uint64_t *findex, bool *owenable, int *dindex,
|
||||
int *nunits, uint64_t *nf, uint32_t *dr, uint32_t *portno,
|
||||
uint32_t nx, uint32_t ny, bool *smode);
|
||||
~HDF5File();
|
||||
void SetNumberofPixels(uint32_t nx, uint32_t ny);
|
||||
void CreateFile();
|
||||
void CloseCurrentFile();
|
||||
void CloseAllFiles();
|
||||
void WriteToFile(char *buffer, int bufferSize, uint64_t currentFrameNumber,
|
||||
uint32_t numPacketsCaught);
|
||||
void CreateMasterFile(bool masterFileWriteEnable,
|
||||
MasterAttributes *attr) override;
|
||||
void EndofAcquisition(bool anyPacketsCaught, uint64_t numImagesCaught);
|
||||
|
||||
private:
|
||||
void CloseFile(H5File *&fd, bool masterFile);
|
||||
void WriteDataFile(uint64_t currentFrameNumber, char *buffer);
|
||||
void WriteParameterDatasets(uint64_t currentFrameNumber,
|
||||
sls_receiver_header *rheader);
|
||||
void ExtendDataset();
|
||||
void CreateDataFile();
|
||||
void CreateMasterDataFile(MasterAttributes *attr);
|
||||
void CreateVirtualDataFile(uint32_t maxFramesPerFile, uint64_t numf);
|
||||
void LinkVirtualInMaster(std::string fname, std::string dsetname);
|
||||
hid_t GetDataTypeinC(DataType dtype);
|
||||
|
||||
static std::mutex hdf5Lib;
|
||||
|
||||
H5File *masterfd;
|
||||
/** Virtual File handle ( only file name because
|
||||
code in C as H5Pset_virtual doesnt exist yet in C++) */
|
||||
hid_t virtualfd;
|
||||
H5File *filefd;
|
||||
DataSpace *dataspace;
|
||||
DataSet *dataset;
|
||||
DataType datatype;
|
||||
|
||||
uint32_t nPixelsX;
|
||||
uint32_t nPixelsY;
|
||||
uint32_t numFramesInFile;
|
||||
uint64_t numActualPacketsInFile;
|
||||
int numFilesinAcquisition;
|
||||
|
||||
std::vector<std::string> parameterNames;
|
||||
std::vector<DataType> parameterDataTypes;
|
||||
DataSpace *dataspace_para;
|
||||
std::vector<DataSet *> dataset_para;
|
||||
|
||||
uint64_t extNumImages;
|
||||
};
|
132
slsReceiverSoftware/src/HDF5MasterFile.cpp
Normal file
132
slsReceiverSoftware/src/HDF5MasterFile.cpp
Normal file
@ -0,0 +1,132 @@
|
||||
#include "HDF5MasterFile.h"
|
||||
#include "MasterAttributes.h"
|
||||
|
||||
HDF5MasterFile::HDF5MasterFile(std::mutex *hdf5Lib)
|
||||
: File(HDF5), hdf5Lib_(hdf5Lib) {}
|
||||
|
||||
HDF5MasterFile::~HDF5MasterFile() { CloseFile(); }
|
||||
|
||||
void HDF5MasterFile::CloseFile() {
|
||||
std::lock_guard<std::mutex> lock(*hdf5Lib_);
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
if (fd_) {
|
||||
fd_->close();
|
||||
delete fd_;
|
||||
fd_ = nullptr;
|
||||
}
|
||||
} catch (const Exception &error) {
|
||||
LOG(logERROR) << "Could not close master HDF5 handles";
|
||||
error.printErrorStack();
|
||||
}
|
||||
}
|
||||
|
||||
void HDF5MasterFile::LinkDataFile(std::string dataFilename,
|
||||
std::string dataSetname,
|
||||
const std::vector<std::string> parameterNames,
|
||||
const bool silentMode) {
|
||||
|
||||
std::lock_guard<std::mutex> lock(*hdf5Lib_);
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
|
||||
FileAccPropList flist;
|
||||
flist.setFcloseDegree(H5F_CLOSE_STRONG);
|
||||
|
||||
// open master file
|
||||
H5File masterfd(fileName_.c_str(), H5F_ACC_RDWR,
|
||||
FileCreatPropList::DEFAULT, flist);
|
||||
|
||||
// open data file
|
||||
H5File fd(dataFilename.c_str(), H5F_ACC_RDONLY,
|
||||
FileCreatPropList::DEFAULT, flist);
|
||||
|
||||
// create link for data dataset
|
||||
DataSet dset = fd.openDataSet(dataSetname.c_str());
|
||||
std::string linkname = std::string("/entry/data/") + dataSetname;
|
||||
if (H5Lcreate_external(dataFilename.c_str(), dataSetname.c_str(),
|
||||
masterfd.getLocId(), linkname.c_str(),
|
||||
H5P_DEFAULT, H5P_DEFAULT) < 0) {
|
||||
throw sls::RuntimeError(
|
||||
"Could not create link to data dataset in master");
|
||||
}
|
||||
|
||||
// create link for parameter datasets
|
||||
for (unsigned int i = 0; i < parameterNames.size(); ++i) {
|
||||
DataSet pDset = fd.openDataSet(parameterNames[i].c_str());
|
||||
linkname = std::string("/entry/data/") + parameterNames[i];
|
||||
if (H5Lcreate_external(dataFilename.c_str(),
|
||||
parameterNames[i].c_str(),
|
||||
masterfd.getLocId(), linkname.c_str(),
|
||||
H5P_DEFAULT, H5P_DEFAULT) < 0) {
|
||||
throw sls::RuntimeError(
|
||||
"Could not create link to parameter dataset in master");
|
||||
}
|
||||
}
|
||||
fd.close();
|
||||
masterfd.close();
|
||||
} catch (const Exception &error) {
|
||||
error.printErrorStack();
|
||||
CloseFile();
|
||||
throw sls::RuntimeError("Could not link in master hdf5 file");
|
||||
}
|
||||
if (!silentMode) {
|
||||
LOG(logINFO) << "Linked in Master File: " << dataFilename;
|
||||
}
|
||||
}
|
||||
|
||||
void HDF5MasterFile::CreateMasterFile(const std::string filePath,
|
||||
const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex,
|
||||
const bool overWriteEnable,
|
||||
const bool silentMode,
|
||||
MasterAttributes *attr) {
|
||||
|
||||
std::ostringstream os;
|
||||
os << filePath << "/" << fileNamePrefix << "_master"
|
||||
<< "_" << fileIndex << ".h5";
|
||||
fileName_ = os.str();
|
||||
|
||||
std::lock_guard<std::mutex> lock(*hdf5Lib_);
|
||||
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
|
||||
FileAccPropList flist;
|
||||
flist.setFcloseDegree(H5F_CLOSE_STRONG);
|
||||
fd_ = nullptr;
|
||||
if (!(overWriteEnable))
|
||||
fd_ = new H5File(fileName_.c_str(), H5F_ACC_EXCL,
|
||||
FileCreatPropList::DEFAULT, flist);
|
||||
else
|
||||
fd_ = new H5File(fileName_.c_str(), H5F_ACC_TRUNC,
|
||||
FileCreatPropList::DEFAULT, flist);
|
||||
|
||||
// attributes - version
|
||||
double dValue = HDF5_WRITER_VERSION;
|
||||
DataSpace dataspace_attr = DataSpace(H5S_SCALAR);
|
||||
Attribute attribute = fd_->createAttribute(
|
||||
"version", PredType::NATIVE_DOUBLE, dataspace_attr);
|
||||
attribute.write(PredType::NATIVE_DOUBLE, &dValue);
|
||||
|
||||
// Create a group in the file
|
||||
Group group1(fd_->createGroup("entry"));
|
||||
Group group2(group1.createGroup("data"));
|
||||
Group group3(group1.createGroup("instrument"));
|
||||
Group group4(group3.createGroup("beam"));
|
||||
Group group5(group3.createGroup("detector"));
|
||||
Group group6(group1.createGroup("sample"));
|
||||
|
||||
attr->WriteMasterHDF5Attributes(fd_, &group5);
|
||||
fd_->close();
|
||||
|
||||
} catch (const Exception &error) {
|
||||
error.printErrorStack();
|
||||
CloseFile();
|
||||
throw sls::RuntimeError(
|
||||
"Could not create/overwrite master HDF5 handles");
|
||||
}
|
||||
if (!silentMode) {
|
||||
LOG(logINFO) << "Master File: " << fileName_;
|
||||
}
|
||||
}
|
27
slsReceiverSoftware/src/HDF5MasterFile.h
Normal file
27
slsReceiverSoftware/src/HDF5MasterFile.h
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "File.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
class HDF5MasterFile : private virtual slsDetectorDefs, public File {
|
||||
|
||||
public:
|
||||
HDF5MasterFile(std::mutex *hdf5Lib);
|
||||
~HDF5MasterFile();
|
||||
|
||||
void CloseFile() override;
|
||||
void LinkDataFile(std::string dataFilename, std::string dataSetname,
|
||||
const std::vector<std::string> parameterNames,
|
||||
const bool silentMode) override;
|
||||
void CreateMasterFile(const std::string filePath,
|
||||
const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable,
|
||||
const bool silentMode,
|
||||
MasterAttributes *attr) override;
|
||||
|
||||
private:
|
||||
std::mutex *hdf5Lib_;
|
||||
H5File *fd_{nullptr};
|
||||
std::string fileName_;
|
||||
};
|
197
slsReceiverSoftware/src/HDF5VirtualFile.cpp
Normal file
197
slsReceiverSoftware/src/HDF5VirtualFile.cpp
Normal file
@ -0,0 +1,197 @@
|
||||
#include "HDF5VirtualFile.h"
|
||||
#include "receiver_defs.h"
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
HDF5VirtualFile::HDF5VirtualFile(std::mutex *hdf5Lib)
|
||||
: File(HDF5), hdf5Lib_(hdf5Lib) {}
|
||||
|
||||
HDF5VirtualFile::~HDF5VirtualFile() { CloseFile(); }
|
||||
|
||||
std::array<std::string, 2> HDF5VirtualFile::GetFileAndDatasetName() const {
|
||||
return std::array<std::string, 2>{fileName_, dataSetName_};
|
||||
}
|
||||
|
||||
void HDF5VirtualFile::CloseFile() {
|
||||
std::lock_guard<std::mutex> lock(*hdf5Lib_);
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
if (fd_) {
|
||||
fd_->close();
|
||||
delete fd_;
|
||||
fd_ = nullptr;
|
||||
}
|
||||
} catch (const Exception &error) {
|
||||
LOG(logERROR) << "Could not close virtual HDF5 handles of index";
|
||||
error.printErrorStack();
|
||||
}
|
||||
}
|
||||
|
||||
void HDF5VirtualFile::CreateVirtualFile(
|
||||
const std::string filePath, const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode,
|
||||
const int modulePos, const int numUnitsPerReadout,
|
||||
const uint32_t maxFramesPerFile, const uint64_t numImages,
|
||||
const uint32_t nPixelsX, const uint32_t nPixelsY,
|
||||
const uint32_t dynamicRange, const uint64_t numImagesCaught,
|
||||
const int numModX, const int numModY, const DataType dataType,
|
||||
const std::vector<std::string> parameterNames,
|
||||
const std::vector<DataType> parameterDataTypes) {
|
||||
// virtual file name
|
||||
std::ostringstream osfn;
|
||||
osfn << filePath << "/" << fileNamePrefix << "_virtual"
|
||||
<< "_" << fileIndex << ".h5";
|
||||
fileName_ = osfn.str();
|
||||
|
||||
unsigned int paraSize = parameterNames.size();
|
||||
uint64_t numModZ = numModX;
|
||||
uint32_t nDimy = nPixelsY;
|
||||
uint32_t nDimz = ((dynamicRange == 4) ? (nPixelsX / 2) : nPixelsX);
|
||||
|
||||
std::lock_guard<std::mutex> lock(*hdf5Lib_);
|
||||
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
|
||||
// file
|
||||
FileAccPropList fapl;
|
||||
fapl.setFcloseDegree(H5F_CLOSE_STRONG);
|
||||
fd_ = nullptr;
|
||||
if (!overWriteEnable)
|
||||
fd_ = new H5File(fileName_.c_str(), H5F_ACC_EXCL,
|
||||
FileCreatPropList::DEFAULT, fapl);
|
||||
else
|
||||
fd_ = new H5File(fileName_.c_str(), H5F_ACC_TRUNC,
|
||||
FileCreatPropList::DEFAULT, fapl);
|
||||
|
||||
// attributes - version
|
||||
double dValue = HDF5_WRITER_VERSION;
|
||||
DataSpace dataspace_attr = DataSpace(H5S_SCALAR);
|
||||
Attribute attribute = fd_->createAttribute(
|
||||
"version", PredType::NATIVE_DOUBLE, dataspace_attr);
|
||||
attribute.write(PredType::NATIVE_DOUBLE, &dValue);
|
||||
|
||||
// virtual data dataspace
|
||||
hsize_t vdsDims[3] = {numImagesCaught, numModY * nDimy,
|
||||
numModZ * nDimz};
|
||||
DataSpace vdsDataSpace(3, vdsDims, nullptr);
|
||||
|
||||
// virtual parameter dataspace
|
||||
hsize_t vdsDimsPara[2] = {numImagesCaught,
|
||||
(unsigned int)numModY * numModZ};
|
||||
DataSpace vdsDataSpacePara(2, vdsDimsPara, nullptr);
|
||||
|
||||
// property list (fill value and datatype)
|
||||
int fill_value = -1;
|
||||
DSetCreatPropList plist;
|
||||
plist.setFillValue(dataType, &fill_value);
|
||||
|
||||
// property list for parameters (datatype)
|
||||
std::vector<DSetCreatPropList> plistPara(paraSize);
|
||||
|
||||
// hyperslab
|
||||
int numMajorHyperslab = numImagesCaught / maxFramesPerFile;
|
||||
if (numImagesCaught % maxFramesPerFile)
|
||||
++numMajorHyperslab;
|
||||
uint64_t framesSaved = 0;
|
||||
// loop through files
|
||||
for (int hyperSlab = 0; hyperSlab < numMajorHyperslab; ++hyperSlab) {
|
||||
|
||||
uint64_t nDimx =
|
||||
((numImagesCaught - framesSaved) > maxFramesPerFile)
|
||||
? maxFramesPerFile
|
||||
: (numImagesCaught - framesSaved);
|
||||
hsize_t start[3] = {framesSaved, 0, 0};
|
||||
hsize_t count[3] = {nDimx, nDimy, nDimz};
|
||||
hsize_t startPara[2] = {framesSaved, 0};
|
||||
hsize_t countPara[2] = {nDimx, 1};
|
||||
// loop through readouts
|
||||
for (unsigned int i = 0; i < numModY * numModZ; ++i) {
|
||||
|
||||
// setect data hyperslabs
|
||||
vdsDataSpace.selectHyperslab(H5S_SELECT_SET, count, start);
|
||||
|
||||
// select parameter hyperslabs
|
||||
vdsDataSpacePara.selectHyperslab(H5S_SELECT_SET, countPara,
|
||||
startPara);
|
||||
|
||||
// source file name
|
||||
std::ostringstream os;
|
||||
os << filePath << "/" << fileNamePrefix << "_d"
|
||||
<< (modulePos * numUnitsPerReadout + i) << "_f" << hyperSlab
|
||||
<< '_' << fileIndex << ".h5";
|
||||
std::string srcFileName = os.str();
|
||||
LOG(logDEBUG1) << srcFileName;
|
||||
|
||||
// find relative path
|
||||
std::string relative_srcFileName = srcFileName;
|
||||
{
|
||||
size_t p = srcFileName.rfind('/', srcFileName.length());
|
||||
if (p != std::string::npos)
|
||||
relative_srcFileName = (srcFileName.substr(
|
||||
p + 1, srcFileName.length() - p));
|
||||
}
|
||||
|
||||
// source dataset name
|
||||
std::ostringstream osfn;
|
||||
osfn << "/data";
|
||||
if (numImages > 1)
|
||||
osfn << "_f" << std::setfill('0') << std::setw(12)
|
||||
<< hyperSlab;
|
||||
std::string srcDatasetName = osfn.str();
|
||||
|
||||
// source data dataspace
|
||||
hsize_t srcDims[3] = {nDimx, nDimy, nDimz};
|
||||
hsize_t srcDimsMax[3] = {H5S_UNLIMITED, nDimy, nDimz};
|
||||
DataSpace srcDataSpace(3, srcDims, srcDimsMax);
|
||||
|
||||
// source parameter dataspace
|
||||
hsize_t srcDimsPara[1] = {nDimx};
|
||||
hsize_t srcDimsMaxPara[1] = {H5S_UNLIMITED};
|
||||
DataSpace srcDataSpacePara(1, srcDimsPara, srcDimsMaxPara);
|
||||
|
||||
// mapping of data property list
|
||||
plist.setVirtual(vdsDataSpace, relative_srcFileName.c_str(),
|
||||
srcDatasetName.c_str(), srcDataSpace);
|
||||
|
||||
// mapping of parameter property list
|
||||
for (unsigned int p = 0; p < paraSize; ++p) {
|
||||
plistPara[p].setVirtual(
|
||||
vdsDataSpacePara, relative_srcFileName.c_str(),
|
||||
parameterNames[p].c_str(), srcDataSpacePara);
|
||||
}
|
||||
|
||||
// H5Sclose(srcDataspace);
|
||||
// H5Sclose(srcDataspace_para);
|
||||
start[2] += nDimz;
|
||||
if (start[2] >= (numModZ * nDimz)) {
|
||||
start[2] = 0;
|
||||
start[1] += nDimy;
|
||||
}
|
||||
startPara[1]++;
|
||||
}
|
||||
framesSaved += nDimx;
|
||||
}
|
||||
// data dataset
|
||||
dataSetName_ = "data";
|
||||
DataSet vdsDataSet(fd_->createDataSet(dataSetName_.c_str(), dataType,
|
||||
vdsDataSpace, plist));
|
||||
|
||||
// parameter dataset
|
||||
for (unsigned int p = 0; p < paraSize; ++p) {
|
||||
DataSet vdsDataSetPara(fd_->createDataSet(
|
||||
parameterNames[p].c_str(), parameterDataTypes[p],
|
||||
vdsDataSpacePara, plistPara[p]));
|
||||
}
|
||||
|
||||
fd_->close();
|
||||
} catch (const Exception &error) {
|
||||
error.printErrorStack();
|
||||
CloseFile();
|
||||
throw sls::RuntimeError(
|
||||
"Could not create/overwrite virtual HDF5 handles");
|
||||
}
|
||||
if (!silentMode) {
|
||||
LOG(logINFO) << "Virtual File: " << fileName_;
|
||||
}
|
||||
}
|
31
slsReceiverSoftware/src/HDF5VirtualFile.h
Normal file
31
slsReceiverSoftware/src/HDF5VirtualFile.h
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "File.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
class HDF5VirtualFile : private virtual slsDetectorDefs, public File {
|
||||
|
||||
public:
|
||||
HDF5VirtualFile(std::mutex *hdf5Lib);
|
||||
~HDF5VirtualFile();
|
||||
|
||||
std::array<std::string, 2> GetFileAndDatasetName() const override;
|
||||
void CloseFile() override;
|
||||
void CreateVirtualFile(
|
||||
const std::string filePath, const std::string fileNamePrefix,
|
||||
const uint64_t fileIndex, const bool overWriteEnable,
|
||||
const bool silentMode, const int modulePos,
|
||||
const int numUnitsPerReadout, const uint32_t maxFramesPerFile,
|
||||
const uint64_t numImages, const uint32_t nPixelsX,
|
||||
const uint32_t nPixelsY, const uint32_t dynamicRange,
|
||||
const uint64_t numImagesCaught, const int numModX, const int numModY,
|
||||
const DataType dataType, const std::vector<std::string> parameterNames,
|
||||
const std::vector<DataType> parameterDataTypes) override;
|
||||
|
||||
private:
|
||||
std::mutex *hdf5Lib_;
|
||||
H5File *fd_{nullptr};
|
||||
std::string fileName_;
|
||||
std::string dataSetName_;
|
||||
};
|
@ -65,7 +65,7 @@ void Implementation::SetupFifoStructure() {
|
||||
for (int i = 0; i < numThreads; ++i) {
|
||||
uint32_t datasize = generalData->imageSize;
|
||||
// veto data size
|
||||
if (myDetectorType == GOTTHARD2 && i != 0) {
|
||||
if (detType == GOTTHARD2 && i != 0) {
|
||||
datasize = generalData->vetoImageSize;
|
||||
}
|
||||
|
||||
@ -105,8 +105,8 @@ void Implementation::SetupFifoStructure() {
|
||||
* ************************************************/
|
||||
|
||||
void Implementation::setDetectorType(const detectorType d) {
|
||||
myDetectorType = d;
|
||||
switch (myDetectorType) {
|
||||
detType = d;
|
||||
switch (detType) {
|
||||
case GOTTHARD:
|
||||
case EIGER:
|
||||
case JUNGFRAU:
|
||||
@ -125,7 +125,7 @@ void Implementation::setDetectorType(const detectorType d) {
|
||||
generalData = nullptr;
|
||||
|
||||
// set detector specific variables
|
||||
switch (myDetectorType) {
|
||||
switch (detType) {
|
||||
case GOTTHARD:
|
||||
generalData = new GotthardData();
|
||||
break;
|
||||
@ -164,16 +164,15 @@ void Implementation::setDetectorType(const detectorType d) {
|
||||
try {
|
||||
auto fifo_ptr = fifo[i].get();
|
||||
listener.push_back(sls::make_unique<Listener>(
|
||||
i, myDetectorType, fifo_ptr, &status, &udpPortNum[i], ð[i],
|
||||
i, detType, fifo_ptr, &status, &udpPortNum[i], ð[i],
|
||||
&numberOfTotalFrames, &udpSocketBufferSize,
|
||||
&actualUDPSocketBufferSize, &framesPerFile, &frameDiscardMode,
|
||||
&activated, &deactivatedPaddingEnable, &silentMode));
|
||||
&activated, &detectorDataStream[i], &deactivatedPaddingEnable, &silentMode));
|
||||
dataProcessor.push_back(sls::make_unique<DataProcessor>(
|
||||
i, myDetectorType, fifo_ptr, &fileFormatType, fileWriteEnable,
|
||||
&masterFileWriteEnable, &dataStreamEnable, &streamingFrequency,
|
||||
&streamingTimerInMs, &streamingStartFnum, &framePadding,
|
||||
&activated, &deactivatedPaddingEnable, &silentMode,
|
||||
&ctbDbitList, &ctbDbitOffset, &ctbAnalogDataBytes));
|
||||
i, detType, fifo_ptr, &activated, &deactivatedPaddingEnable,
|
||||
&dataStreamEnable, &streamingFrequency, &streamingTimerInMs,
|
||||
&streamingStartFnum, &framePadding, &ctbDbitList,
|
||||
&ctbDbitOffset, &ctbAnalogDataBytes, &hdf5Lib));
|
||||
} catch (...) {
|
||||
listener.clear();
|
||||
dataProcessor.clear();
|
||||
@ -193,32 +192,32 @@ void Implementation::setDetectorType(const detectorType d) {
|
||||
LOG(logDEBUG) << " Detector type set to " << sls::ToString(d);
|
||||
}
|
||||
|
||||
int *Implementation::getDetectorSize() const { return (int *)numDet; }
|
||||
int *Implementation::getDetectorSize() const { return (int *)numMods; }
|
||||
|
||||
void Implementation::setDetectorSize(const int *size) {
|
||||
std::string log_message = "Detector Size (ports): (";
|
||||
for (int i = 0; i < MAX_DIMENSIONS; ++i) {
|
||||
// x dir (colums) each udp port
|
||||
if (myDetectorType == EIGER && i == X)
|
||||
numDet[i] = size[i] * 2;
|
||||
if (detType == EIGER && i == X)
|
||||
numMods[i] = size[i] * 2;
|
||||
// y dir (rows) each udp port
|
||||
else if (numUDPInterfaces == 2 && i == Y)
|
||||
numDet[i] = size[i] * 2;
|
||||
numMods[i] = size[i] * 2;
|
||||
else
|
||||
numDet[i] = size[i];
|
||||
log_message += std::to_string(numDet[i]);
|
||||
numMods[i] = size[i];
|
||||
log_message += std::to_string(numMods[i]);
|
||||
if (i < MAX_DIMENSIONS - 1)
|
||||
log_message += ", ";
|
||||
}
|
||||
log_message += ")";
|
||||
|
||||
int nd[2] = {numDet[0], numDet[1]};
|
||||
int nm[2] = {numMods[0], numMods[1]};
|
||||
if (quadEnable) {
|
||||
nd[0] = 1;
|
||||
nd[1] = 2;
|
||||
nm[0] = 1;
|
||||
nm[1] = 2;
|
||||
}
|
||||
for (const auto &it : dataStreamer) {
|
||||
it->SetNumberofDetectors(nd);
|
||||
it->SetNumberofModules(nm);
|
||||
}
|
||||
|
||||
LOG(logINFO) << log_message;
|
||||
@ -232,20 +231,17 @@ void Implementation::setModulePositionId(const int id) {
|
||||
|
||||
// update zmq port
|
||||
streamingPort =
|
||||
DEFAULT_ZMQ_RX_PORTNO + (modulePos * (myDetectorType == EIGER ? 2 : 1));
|
||||
DEFAULT_ZMQ_RX_PORTNO + (modulePos * (detType == EIGER ? 2 : 1));
|
||||
|
||||
for (unsigned int i = 0; i < dataProcessor.size(); ++i) {
|
||||
dataProcessor[i]->SetupFileWriter(
|
||||
fileWriteEnable, (int *)numDet, &framesPerFile, &fileName,
|
||||
&filePath, &fileIndex, &overwriteEnable, &modulePos, &numThreads,
|
||||
&numberOfTotalFrames, &dynamicRange, &udpPortNum[i], generalData);
|
||||
}
|
||||
assert(numDet[1] != 0);
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetupFileWriter(fileWriteEnable, masterFileWriteEnable,
|
||||
fileFormatType, modulePos);
|
||||
assert(numMods[1] != 0);
|
||||
for (unsigned int i = 0; i < listener.size(); ++i) {
|
||||
uint16_t row = 0, col = 0;
|
||||
row =
|
||||
(modulePos % numDet[1]) * ((numUDPInterfaces == 2) ? 2 : 1); // row
|
||||
col = (modulePos / numDet[1]) * ((myDetectorType == EIGER) ? 2 : 1) +
|
||||
(modulePos % numMods[1]) * ((numUDPInterfaces == 2) ? 2 : 1); // row
|
||||
col = (modulePos / numMods[1]) * ((detType == EIGER) ? 2 : 1) +
|
||||
i; // col for horiz. udp ports
|
||||
listener[i]->SetHardCodedPosition(row, col);
|
||||
}
|
||||
@ -332,20 +328,24 @@ slsDetectorDefs::fileFormat Implementation::getFileFormat() const {
|
||||
}
|
||||
|
||||
void Implementation::setFileFormat(const fileFormat f) {
|
||||
switch (f) {
|
||||
if (f != fileFormatType) {
|
||||
switch (f) {
|
||||
#ifdef HDF5C
|
||||
case HDF5:
|
||||
fileFormatType = HDF5;
|
||||
break;
|
||||
case HDF5:
|
||||
fileFormatType = HDF5;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
fileFormatType = BINARY;
|
||||
break;
|
||||
case BINARY:
|
||||
fileFormatType = BINARY;
|
||||
break;
|
||||
default:
|
||||
throw sls::RuntimeError("Unknown file format");
|
||||
}
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetupFileWriter(fileWriteEnable, masterFileWriteEnable,
|
||||
fileFormatType, modulePos);
|
||||
}
|
||||
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetFileFormat(f);
|
||||
|
||||
LOG(logINFO) << "File Format: " << sls::ToString(fileFormatType);
|
||||
}
|
||||
|
||||
@ -378,13 +378,9 @@ bool Implementation::getFileWriteEnable() const { return fileWriteEnable; }
|
||||
void Implementation::setFileWriteEnable(const bool b) {
|
||||
if (fileWriteEnable != b) {
|
||||
fileWriteEnable = b;
|
||||
for (unsigned int i = 0; i < dataProcessor.size(); ++i) {
|
||||
dataProcessor[i]->SetupFileWriter(
|
||||
fileWriteEnable, (int *)numDet, &framesPerFile, &fileName,
|
||||
&filePath, &fileIndex, &overwriteEnable, &modulePos,
|
||||
&numThreads, &numberOfTotalFrames, &dynamicRange,
|
||||
&udpPortNum[i], generalData);
|
||||
}
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetupFileWriter(fileWriteEnable, masterFileWriteEnable,
|
||||
fileFormatType, modulePos);
|
||||
}
|
||||
LOG(logINFO) << "File Write Enable: "
|
||||
<< (fileWriteEnable ? "enabled" : "disabled");
|
||||
@ -395,7 +391,12 @@ bool Implementation::getMasterFileWriteEnable() const {
|
||||
}
|
||||
|
||||
void Implementation::setMasterFileWriteEnable(const bool b) {
|
||||
masterFileWriteEnable = b;
|
||||
if (masterFileWriteEnable != b) {
|
||||
masterFileWriteEnable = b;
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetupFileWriter(fileWriteEnable, masterFileWriteEnable,
|
||||
fileFormatType, modulePos);
|
||||
}
|
||||
LOG(logINFO) << "Master File Write Enable: "
|
||||
<< (masterFileWriteEnable ? "enabled" : "disabled");
|
||||
}
|
||||
@ -554,19 +555,22 @@ void Implementation::stopReceiver() {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||
}
|
||||
|
||||
// create virtual file
|
||||
#ifdef HDF5C
|
||||
if (fileWriteEnable && fileFormatType == HDF5) {
|
||||
uint64_t maxIndexCaught = 0;
|
||||
bool anycaught = false;
|
||||
for (const auto &it : dataProcessor) {
|
||||
maxIndexCaught = std::max(maxIndexCaught, it->GetProcessedIndex());
|
||||
if (it->GetStartedFlag())
|
||||
anycaught = true;
|
||||
if (modulePos == 0) {
|
||||
// more than 1 file, create virtual file
|
||||
if (dataProcessor[0]->GetFilesInAcquisition() > 1 ||
|
||||
(numMods[X] * numMods[Y]) > 1) {
|
||||
dataProcessor[0]->CreateVirtualFile(
|
||||
filePath, fileName, fileIndex, overwriteEnable, silentMode,
|
||||
modulePos, numThreads, framesPerFile, numberOfTotalFrames,
|
||||
dynamicRange, numMods[X], numMods[Y]);
|
||||
}
|
||||
// link file in master
|
||||
dataProcessor[0]->LinkDataInMasterFile(silentMode);
|
||||
}
|
||||
// to create virtual file & set files/acquisition to 0 (only hdf5 at the
|
||||
// moment)
|
||||
dataProcessor[0]->EndofAcquisition(anycaught, maxIndexCaught);
|
||||
}
|
||||
#endif
|
||||
|
||||
// wait for the processes (dataStreamer) to be done
|
||||
running = true;
|
||||
@ -606,6 +610,12 @@ void Implementation::stopReceiver() {
|
||||
if (!activated) {
|
||||
LOG(logINFORED) << "Deactivated Receiver";
|
||||
}
|
||||
if (!detectorDataStream[0]) {
|
||||
LOG(logINFORED) << "Deactivated Left Port";
|
||||
}
|
||||
if (!detectorDataStream[1]) {
|
||||
LOG(logINFORED) << "Deactivated Right Port";
|
||||
}
|
||||
// callback
|
||||
if (acquisitionFinishedCallBack) {
|
||||
try {
|
||||
@ -671,20 +681,6 @@ void Implementation::shutDownUDPSockets() {
|
||||
it->ShutDownUDPSocket();
|
||||
}
|
||||
|
||||
void Implementation::closeFiles() {
|
||||
uint64_t maxIndexCaught = 0;
|
||||
bool anycaught = false;
|
||||
for (const auto &it : dataProcessor) {
|
||||
it->CloseFiles();
|
||||
maxIndexCaught = std::max(maxIndexCaught, it->GetProcessedIndex());
|
||||
if (it->GetStartedFlag())
|
||||
anycaught = true;
|
||||
}
|
||||
// to create virtual file & set files/acquisition to 0 (only hdf5 at the
|
||||
// moment)
|
||||
dataProcessor[0]->EndofAcquisition(anycaught, maxIndexCaught);
|
||||
}
|
||||
|
||||
void Implementation::restreamStop() {
|
||||
for (const auto &it : dataStreamer)
|
||||
it->RestreamStop();
|
||||
@ -719,90 +715,100 @@ void Implementation::CreateUDPSockets() {
|
||||
}
|
||||
|
||||
void Implementation::SetupWriter() {
|
||||
// master file
|
||||
std::unique_ptr<MasterAttributes> masterAttributes;
|
||||
switch (myDetectorType) {
|
||||
case GOTTHARD:
|
||||
masterAttributes = sls::make_unique<GotthardMasterAttributes>();
|
||||
break;
|
||||
case JUNGFRAU:
|
||||
masterAttributes = sls::make_unique<JungfrauMasterAttributes>();
|
||||
break;
|
||||
case EIGER:
|
||||
masterAttributes = sls::make_unique<EigerMasterAttributes>();
|
||||
break;
|
||||
case MYTHEN3:
|
||||
masterAttributes = sls::make_unique<Mythen3MasterAttributes>();
|
||||
break;
|
||||
case GOTTHARD2:
|
||||
masterAttributes = sls::make_unique<Gotthard2MasterAttributes>();
|
||||
break;
|
||||
case MOENCH:
|
||||
masterAttributes = sls::make_unique<MoenchMasterAttributes>();
|
||||
break;
|
||||
case CHIPTESTBOARD:
|
||||
masterAttributes = sls::make_unique<CtbMasterAttributes>();
|
||||
break;
|
||||
default:
|
||||
throw sls::RuntimeError(
|
||||
"Unknown detector type to set up master file attributes");
|
||||
if (masterFileWriteEnable && modulePos == 0) {
|
||||
switch (detType) {
|
||||
case GOTTHARD:
|
||||
masterAttributes = sls::make_unique<GotthardMasterAttributes>();
|
||||
break;
|
||||
case JUNGFRAU:
|
||||
masterAttributes = sls::make_unique<JungfrauMasterAttributes>();
|
||||
break;
|
||||
case EIGER:
|
||||
masterAttributes = sls::make_unique<EigerMasterAttributes>();
|
||||
break;
|
||||
case MYTHEN3:
|
||||
masterAttributes = sls::make_unique<Mythen3MasterAttributes>();
|
||||
break;
|
||||
case GOTTHARD2:
|
||||
masterAttributes = sls::make_unique<Gotthard2MasterAttributes>();
|
||||
break;
|
||||
case MOENCH:
|
||||
masterAttributes = sls::make_unique<MoenchMasterAttributes>();
|
||||
break;
|
||||
case CHIPTESTBOARD:
|
||||
masterAttributes = sls::make_unique<CtbMasterAttributes>();
|
||||
break;
|
||||
default:
|
||||
throw sls::RuntimeError(
|
||||
"Unknown detector type to set up master file attributes");
|
||||
}
|
||||
masterAttributes->detType = detType;
|
||||
masterAttributes->timingMode = timingMode;
|
||||
masterAttributes->imageSize = generalData->imageSize;
|
||||
masterAttributes->nPixels =
|
||||
xy(generalData->nPixelsX, generalData->nPixelsY);
|
||||
masterAttributes->maxFramesPerFile = framesPerFile;
|
||||
masterAttributes->frameDiscardMode = frameDiscardMode;
|
||||
masterAttributes->framePadding = framePadding;
|
||||
masterAttributes->scanParams = scanParams;
|
||||
masterAttributes->totalFrames = numberOfTotalFrames;
|
||||
masterAttributes->exptime = acquisitionTime;
|
||||
masterAttributes->period = acquisitionPeriod;
|
||||
masterAttributes->burstMode = burstMode;
|
||||
masterAttributes->numUDPInterfaces = numUDPInterfaces;
|
||||
masterAttributes->dynamicRange = dynamicRange;
|
||||
masterAttributes->tenGiga = tengigaEnable;
|
||||
masterAttributes->thresholdEnergyeV = thresholdEnergyeV;
|
||||
masterAttributes->thresholdAllEnergyeV = thresholdAllEnergyeV;
|
||||
masterAttributes->subExptime = subExpTime;
|
||||
masterAttributes->subPeriod = subPeriod;
|
||||
masterAttributes->quad = quadEnable;
|
||||
masterAttributes->numLinesReadout = numLinesReadout;
|
||||
masterAttributes->ratecorr = rateCorrections;
|
||||
masterAttributes->adcmask =
|
||||
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga;
|
||||
masterAttributes->analog =
|
||||
(readoutType == ANALOG_ONLY || readoutType == ANALOG_AND_DIGITAL)
|
||||
? 1
|
||||
: 0;
|
||||
masterAttributes->analogSamples = numberOfAnalogSamples;
|
||||
masterAttributes->digital =
|
||||
(readoutType == DIGITAL_ONLY || readoutType == ANALOG_AND_DIGITAL)
|
||||
? 1
|
||||
: 0;
|
||||
masterAttributes->digitalSamples = numberOfDigitalSamples;
|
||||
masterAttributes->dbitoffset = ctbDbitOffset;
|
||||
masterAttributes->dbitlist = 0;
|
||||
for (auto &i : ctbDbitList) {
|
||||
masterAttributes->dbitlist |= (1 << i);
|
||||
}
|
||||
masterAttributes->roi = roi;
|
||||
masterAttributes->counterMask = counterMask;
|
||||
masterAttributes->exptime1 = acquisitionTime1;
|
||||
masterAttributes->exptime2 = acquisitionTime2;
|
||||
masterAttributes->exptime3 = acquisitionTime3;
|
||||
masterAttributes->gateDelay1 = gateDelay1;
|
||||
masterAttributes->gateDelay2 = gateDelay2;
|
||||
masterAttributes->gateDelay3 = gateDelay3;
|
||||
masterAttributes->gates = numberOfGates;
|
||||
masterAttributes->additionalJsonHeader = additionalJsonHeader;
|
||||
}
|
||||
masterAttributes->detType = myDetectorType;
|
||||
masterAttributes->timingMode = timingMode;
|
||||
masterAttributes->imageSize = generalData->imageSize;
|
||||
masterAttributes->nPixels =
|
||||
xy(generalData->nPixelsX, generalData->nPixelsY);
|
||||
masterAttributes->maxFramesPerFile = framesPerFile;
|
||||
masterAttributes->frameDiscardMode = frameDiscardMode;
|
||||
masterAttributes->framePadding = framePadding;
|
||||
masterAttributes->scanParams = scanParams;
|
||||
masterAttributes->totalFrames = numberOfTotalFrames;
|
||||
masterAttributes->exptime = acquisitionTime;
|
||||
masterAttributes->period = acquisitionPeriod;
|
||||
masterAttributes->burstMode = burstMode;
|
||||
masterAttributes->numUDPInterfaces = numUDPInterfaces;
|
||||
masterAttributes->dynamicRange = dynamicRange;
|
||||
masterAttributes->tenGiga = tengigaEnable;
|
||||
masterAttributes->thresholdEnergyeV = thresholdEnergyeV;
|
||||
masterAttributes->thresholdAllEnergyeV = thresholdAllEnergyeV;
|
||||
masterAttributes->subExptime = subExpTime;
|
||||
masterAttributes->subPeriod = subPeriod;
|
||||
masterAttributes->quad = quadEnable;
|
||||
masterAttributes->numLinesReadout = numLinesReadout;
|
||||
masterAttributes->ratecorr = rateCorrections;
|
||||
masterAttributes->adcmask =
|
||||
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga;
|
||||
masterAttributes->analog =
|
||||
(readoutType == ANALOG_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1
|
||||
: 0;
|
||||
masterAttributes->analogSamples = numberOfAnalogSamples;
|
||||
masterAttributes->digital =
|
||||
(readoutType == DIGITAL_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1
|
||||
: 0;
|
||||
masterAttributes->digitalSamples = numberOfDigitalSamples;
|
||||
masterAttributes->dbitoffset = ctbDbitOffset;
|
||||
masterAttributes->dbitlist = 0;
|
||||
for (auto &i : ctbDbitList) {
|
||||
masterAttributes->dbitlist |= (1 << i);
|
||||
}
|
||||
masterAttributes->roi = roi;
|
||||
masterAttributes->counterMask = counterMask;
|
||||
masterAttributes->exptime1 = acquisitionTime1;
|
||||
masterAttributes->exptime2 = acquisitionTime2;
|
||||
masterAttributes->exptime3 = acquisitionTime3;
|
||||
masterAttributes->gateDelay1 = gateDelay1;
|
||||
masterAttributes->gateDelay2 = gateDelay2;
|
||||
masterAttributes->gateDelay3 = gateDelay3;
|
||||
masterAttributes->gates = numberOfGates;
|
||||
masterAttributes->additionalJsonHeader = additionalJsonHeader;
|
||||
|
||||
try {
|
||||
for (unsigned int i = 0; i < dataProcessor.size(); ++i) {
|
||||
dataProcessor[i]->CreateNewFile(masterAttributes.get());
|
||||
dataProcessor[i]->CreateFirstFiles(
|
||||
masterAttributes.get(), filePath, fileName, fileIndex,
|
||||
overwriteEnable, silentMode, modulePos, numThreads,
|
||||
udpPortNum[i], framesPerFile, numberOfTotalFrames,
|
||||
dynamicRange, detectorDataStream[i]);
|
||||
}
|
||||
} catch (const sls::RuntimeError &e) {
|
||||
shutDownUDPSockets();
|
||||
closeFiles();
|
||||
throw sls::RuntimeError("Could not create file.");
|
||||
for (const auto &it : dataProcessor)
|
||||
it->CloseFiles();
|
||||
throw sls::RuntimeError("Could not create first data file.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -840,7 +846,7 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
|
||||
// reduce number of detectors in y dir (rows) if it had 2 interfaces
|
||||
// before
|
||||
if (numUDPInterfaces == 2)
|
||||
numDet[Y] /= 2;
|
||||
numMods[Y] /= 2;
|
||||
|
||||
numUDPInterfaces = n;
|
||||
|
||||
@ -864,20 +870,18 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
|
||||
try {
|
||||
auto fifo_ptr = fifo[i].get();
|
||||
listener.push_back(sls::make_unique<Listener>(
|
||||
i, myDetectorType, fifo_ptr, &status, &udpPortNum[i],
|
||||
ð[i], &numberOfTotalFrames, &udpSocketBufferSize,
|
||||
i, detType, fifo_ptr, &status, &udpPortNum[i], ð[i],
|
||||
&numberOfTotalFrames, &udpSocketBufferSize,
|
||||
&actualUDPSocketBufferSize, &framesPerFile,
|
||||
&frameDiscardMode, &activated, &deactivatedPaddingEnable,
|
||||
&frameDiscardMode, &activated, &detectorDataStream[i], &deactivatedPaddingEnable,
|
||||
&silentMode));
|
||||
listener[i]->SetGeneralData(generalData);
|
||||
|
||||
dataProcessor.push_back(sls::make_unique<DataProcessor>(
|
||||
i, myDetectorType, fifo_ptr, &fileFormatType,
|
||||
fileWriteEnable, &masterFileWriteEnable, &dataStreamEnable,
|
||||
&streamingFrequency, &streamingTimerInMs,
|
||||
&streamingStartFnum, &framePadding, &activated,
|
||||
&deactivatedPaddingEnable, &silentMode, &ctbDbitList,
|
||||
&ctbDbitOffset, &ctbAnalogDataBytes));
|
||||
i, detType, fifo_ptr, &activated, &deactivatedPaddingEnable,
|
||||
&dataStreamEnable, &streamingFrequency, &streamingTimerInMs,
|
||||
&streamingStartFnum, &framePadding, &ctbDbitList,
|
||||
&ctbDbitOffset, &ctbAnalogDataBytes, &hdf5Lib));
|
||||
dataProcessor[i]->SetGeneralData(generalData);
|
||||
} catch (...) {
|
||||
listener.clear();
|
||||
@ -890,15 +894,15 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
|
||||
if (dataStreamEnable) {
|
||||
try {
|
||||
int fd = flippedDataX;
|
||||
int nd[2] = {numDet[0], numDet[1]};
|
||||
int nm[2] = {numMods[0], numMods[1]};
|
||||
if (quadEnable) {
|
||||
fd = i;
|
||||
nd[0] = 1;
|
||||
nd[1] = 2;
|
||||
nm[0] = 1;
|
||||
nm[1] = 2;
|
||||
}
|
||||
dataStreamer.push_back(sls::make_unique<DataStreamer>(
|
||||
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, fd,
|
||||
(int *)nd, &quadEnable, &numberOfTotalFrames));
|
||||
(int *)nm, &quadEnable, &numberOfTotalFrames));
|
||||
dataStreamer[i]->SetGeneralData(generalData);
|
||||
dataStreamer[i]->CreateZmqSockets(
|
||||
&numThreads, streamingPort, streamingSrcIP,
|
||||
@ -921,7 +925,7 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
|
||||
SetThreadPriorities();
|
||||
|
||||
// update (from 1 to 2 interface) & also for printout
|
||||
setDetectorSize(numDet);
|
||||
setDetectorSize(numMods);
|
||||
// update row and column in dataprocessor
|
||||
setModulePositionId(modulePos);
|
||||
|
||||
@ -981,7 +985,7 @@ void Implementation::setUDPSocketBufferSize(const int s) {
|
||||
// testing default setup at startup, argument is 0 to use default values
|
||||
int size = (s == 0) ? udpSocketBufferSize : s;
|
||||
size_t listSize = listener.size();
|
||||
if (myDetectorType == JUNGFRAU && (int)listSize != numUDPInterfaces) {
|
||||
if (detType == JUNGFRAU && (int)listSize != numUDPInterfaces) {
|
||||
throw sls::RuntimeError(
|
||||
"Number of Interfaces " + std::to_string(numUDPInterfaces) +
|
||||
" do not match listener size " + std::to_string(listSize));
|
||||
@ -1019,15 +1023,15 @@ void Implementation::setDataStreamEnable(const bool enable) {
|
||||
for (int i = 0; i < numThreads; ++i) {
|
||||
try {
|
||||
int fd = flippedDataX;
|
||||
int nd[2] = {numDet[0], numDet[1]};
|
||||
int nm[2] = {numMods[0], numMods[1]};
|
||||
if (quadEnable) {
|
||||
fd = i;
|
||||
nd[0] = 1;
|
||||
nd[1] = 2;
|
||||
nm[0] = 1;
|
||||
nm[1] = 2;
|
||||
}
|
||||
dataStreamer.push_back(sls::make_unique<DataStreamer>(
|
||||
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, fd,
|
||||
(int *)nd, &quadEnable, &numberOfTotalFrames));
|
||||
(int *)nm, &quadEnable, &numberOfTotalFrames));
|
||||
dataStreamer[i]->SetGeneralData(generalData);
|
||||
dataStreamer[i]->CreateZmqSockets(
|
||||
&numThreads, streamingPort, streamingSrcIP,
|
||||
@ -1166,7 +1170,7 @@ void Implementation::updateTotalNumberOfFrames() {
|
||||
int64_t repeats = numberOfTriggers;
|
||||
int64_t numFrames = numberOfFrames;
|
||||
// gotthard2
|
||||
if (myDetectorType == GOTTHARD2) {
|
||||
if (detType == GOTTHARD2) {
|
||||
// auto
|
||||
if (timingMode == AUTO_TIMING) {
|
||||
// burst mode, repeats = #bursts
|
||||
@ -1340,8 +1344,6 @@ void Implementation::setNumberofAnalogSamples(const uint32_t i) {
|
||||
numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable,
|
||||
readoutType);
|
||||
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetPixelDimension();
|
||||
SetupFifoStructure();
|
||||
}
|
||||
LOG(logINFO) << "Number of Analog Samples: " << numberOfAnalogSamples;
|
||||
@ -1361,8 +1363,6 @@ void Implementation::setNumberofDigitalSamples(const uint32_t i) {
|
||||
numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable,
|
||||
readoutType);
|
||||
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetPixelDimension();
|
||||
SetupFifoStructure();
|
||||
}
|
||||
LOG(logINFO) << "Number of Digital Samples: " << numberOfDigitalSamples;
|
||||
@ -1382,9 +1382,6 @@ void Implementation::setCounterMask(const uint32_t i) {
|
||||
counterMask = i;
|
||||
generalData->SetNumberofCounters(ncounters, dynamicRange,
|
||||
tengigaEnable);
|
||||
// to update npixelsx, npixelsy in file writer
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetPixelDimension();
|
||||
SetupFifoStructure();
|
||||
}
|
||||
LOG(logINFO) << "Counter mask: " << sls::ToStringHex(counterMask);
|
||||
@ -1398,18 +1395,15 @@ void Implementation::setDynamicRange(const uint32_t i) {
|
||||
if (dynamicRange != i) {
|
||||
dynamicRange = i;
|
||||
|
||||
if (myDetectorType == EIGER || myDetectorType == MYTHEN3) {
|
||||
if (detType == EIGER || detType == MYTHEN3) {
|
||||
|
||||
if (myDetectorType == EIGER) {
|
||||
if (detType == EIGER) {
|
||||
generalData->SetDynamicRange(i, tengigaEnable);
|
||||
} else {
|
||||
int ncounters = __builtin_popcount(counterMask);
|
||||
generalData->SetNumberofCounters(ncounters, i, tengigaEnable);
|
||||
}
|
||||
|
||||
// to update npixelsx, npixelsy in file writer
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetPixelDimension();
|
||||
fifoDepth = generalData->defaultFifoDepth;
|
||||
SetupFifoStructure();
|
||||
}
|
||||
@ -1427,8 +1421,6 @@ void Implementation::setROI(slsDetectorDefs::ROI arg) {
|
||||
// only for gotthard
|
||||
generalData->SetROI(arg);
|
||||
framesPerFile = generalData->maxFramesPerFile;
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetPixelDimension();
|
||||
SetupFifoStructure();
|
||||
}
|
||||
|
||||
@ -1443,7 +1435,7 @@ void Implementation::setTenGigaEnable(const bool b) {
|
||||
tengigaEnable = b;
|
||||
int ncounters = __builtin_popcount(counterMask);
|
||||
// side effects
|
||||
switch (myDetectorType) {
|
||||
switch (detType) {
|
||||
case EIGER:
|
||||
generalData->SetTenGigaEnable(b, dynamicRange);
|
||||
break;
|
||||
@ -1492,13 +1484,13 @@ void Implementation::setQuad(const bool b) {
|
||||
|
||||
if (!quadEnable) {
|
||||
for (const auto &it : dataStreamer) {
|
||||
it->SetNumberofDetectors(numDet);
|
||||
it->SetNumberofModules(numMods);
|
||||
it->SetFlippedDataX(flippedDataX);
|
||||
}
|
||||
} else {
|
||||
int size[2] = {1, 2};
|
||||
for (const auto &it : dataStreamer) {
|
||||
it->SetNumberofDetectors(size);
|
||||
it->SetNumberofModules(size);
|
||||
}
|
||||
if (dataStreamer.size() == 2) {
|
||||
dataStreamer[0]->SetFlippedDataX(0);
|
||||
@ -1511,10 +1503,22 @@ void Implementation::setQuad(const bool b) {
|
||||
|
||||
bool Implementation::getActivate() const { return activated; }
|
||||
|
||||
bool Implementation::setActivate(bool enable) {
|
||||
void Implementation::setActivate(bool enable) {
|
||||
activated = enable;
|
||||
LOG(logINFO) << "Activation: " << (activated ? "enabled" : "disabled");
|
||||
return activated;
|
||||
}
|
||||
|
||||
bool Implementation::getDetectorDataStream(const portPosition port) const {
|
||||
int index = (port == LEFT ? 0 : 1);
|
||||
return detectorDataStream[index];
|
||||
}
|
||||
|
||||
void Implementation::setDetectorDataStream(const portPosition port,
|
||||
const bool enable) {
|
||||
int index = (port == LEFT ? 0 : 1);
|
||||
detectorDataStream[index] = enable;
|
||||
LOG(logINFO) << "Detector datastream (" << sls::ToString(port)
|
||||
<< " Port): " << sls::ToString(detectorDataStream[index]);
|
||||
}
|
||||
|
||||
bool Implementation::getDeactivatedPadding() const {
|
||||
@ -1563,8 +1567,6 @@ void Implementation::setReadoutMode(const readoutMode f) {
|
||||
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga,
|
||||
numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable,
|
||||
readoutType);
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetPixelDimension();
|
||||
SetupFifoStructure();
|
||||
}
|
||||
LOG(logINFO) << "Readout Mode: " << sls::ToString(f);
|
||||
@ -1583,8 +1585,6 @@ void Implementation::setADCEnableMask(uint32_t mask) {
|
||||
numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable,
|
||||
readoutType);
|
||||
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetPixelDimension();
|
||||
SetupFifoStructure();
|
||||
}
|
||||
LOG(logINFO) << "ADC Enable Mask for 1Gb mode: 0x" << std::hex
|
||||
@ -1605,8 +1605,6 @@ void Implementation::setTenGigaADCEnableMask(uint32_t mask) {
|
||||
numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable,
|
||||
readoutType);
|
||||
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetPixelDimension();
|
||||
SetupFifoStructure();
|
||||
}
|
||||
LOG(logINFO) << "ADC Enable Mask for 10Gb mode: 0x" << std::hex
|
||||
|
@ -15,6 +15,7 @@ class slsDetectorDefs;
|
||||
#include <exception>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
using ns = std::chrono::nanoseconds;
|
||||
|
||||
@ -87,7 +88,6 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
void stopReceiver();
|
||||
void startReadout();
|
||||
void shutDownUDPSockets();
|
||||
void closeFiles();
|
||||
void restreamStop();
|
||||
|
||||
/**************************************************
|
||||
@ -210,7 +210,11 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
bool getActivate() const;
|
||||
/** [Eiger] If deactivated, receiver will create dummy data if deactivated
|
||||
* padding is enabled (as it will receive nothing from detector) */
|
||||
bool setActivate(const bool enable);
|
||||
void setActivate(const bool enable);
|
||||
bool getDetectorDataStream(const portPosition port) const;
|
||||
/** [Eiger] If datastream is disabled, receiver will create dummy data if deactivated
|
||||
* padding for that port is enabled (as it will receive nothing from detector) */
|
||||
void setDetectorDataStream(const portPosition port, const bool enable);
|
||||
bool getDeactivatedPadding() const;
|
||||
/* [Eiger] */
|
||||
void setDeactivatedPadding(const bool enable);
|
||||
@ -274,8 +278,8 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
|
||||
// config parameters
|
||||
int numThreads{1};
|
||||
detectorType myDetectorType{GENERIC};
|
||||
int numDet[MAX_DIMENSIONS] = {0, 0};
|
||||
detectorType detType{GENERIC};
|
||||
int numMods[MAX_DIMENSIONS] = {0, 0};
|
||||
int modulePos{0};
|
||||
std::string detHostname;
|
||||
bool silentMode{false};
|
||||
@ -346,10 +350,11 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
int flippedDataX{0};
|
||||
bool quadEnable{false};
|
||||
bool activated{true};
|
||||
std::array<bool, 2> detectorDataStream = {{true, true}};
|
||||
bool deactivatedPaddingEnable{true};
|
||||
int numLinesReadout{MAX_EIGER_ROWS_PER_READOUT};
|
||||
int thresholdEnergyeV{-1};
|
||||
std::array<int, 3> thresholdAllEnergyeV={{-1, -1, -1}};
|
||||
std::array<int, 3> thresholdAllEnergyeV = {{-1, -1, -1}};
|
||||
std::vector<int64_t> rateCorrections;
|
||||
readoutMode readoutType{ANALOG_ONLY};
|
||||
uint32_t adcEnableMaskOneGiga{BIT32_MASK};
|
||||
@ -375,4 +380,6 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
std::vector<std::unique_ptr<DataProcessor>> dataProcessor;
|
||||
std::vector<std::unique_ptr<DataStreamer>> dataStreamer;
|
||||
std::vector<std::unique_ptr<Fifo>> fifo;
|
||||
|
||||
std::mutex hdf5Lib;
|
||||
};
|
||||
|
@ -22,11 +22,11 @@ const std::string Listener::TypeName = "Listener";
|
||||
Listener::Listener(int ind, detectorType dtype, Fifo *f,
|
||||
std::atomic<runStatus> *s, uint32_t *portno, std::string *e,
|
||||
uint64_t *nf, int *us, int *as, uint32_t *fpf,
|
||||
frameDiscardPolicy *fdp, bool *act, bool *depaden, bool *sm)
|
||||
frameDiscardPolicy *fdp, bool *act, bool* detds, bool *depaden, bool *sm)
|
||||
: ThreadObject(ind, TypeName), fifo(f), myDetectorType(dtype), status(s),
|
||||
udpPortNumber(portno), eth(e), numImages(nf), udpSocketBufferSize(us),
|
||||
actualUDPSocketBufferSize(as), framesPerFile(fpf), frameDiscardMode(fdp),
|
||||
activated(act), deactivatedPaddingEnable(depaden), silentMode(sm) {
|
||||
activated(act), detectorDataStream(detds), deactivatedPaddingEnable(depaden), silentMode(sm) {
|
||||
LOG(logDEBUG) << "Listener " << ind << " created";
|
||||
}
|
||||
|
||||
@ -94,7 +94,7 @@ void Listener::RecordFirstIndex(uint64_t fnum) {
|
||||
void Listener::SetGeneralData(GeneralData *g) { generalData = g; }
|
||||
|
||||
void Listener::CreateUDPSockets() {
|
||||
if (!(*activated)) {
|
||||
if (!(*activated) || !(*detectorDataStream)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@ void Listener::CreateDummySocketForUDPSocketBufferSize(int s) {
|
||||
LOG(logINFO) << "Testing UDP Socket Buffer size " << s << " with test port "
|
||||
<< *udpPortNumber;
|
||||
|
||||
if (!(*activated)) {
|
||||
if (!(*activated) || !(*detectorDataStream)) {
|
||||
*actualUDPSocketBufferSize = (s * 2);
|
||||
return;
|
||||
}
|
||||
@ -201,7 +201,7 @@ void Listener::ThreadExecution() {
|
||||
<< std::hex << (void *)(buffer) << std::dec << ":" << buffer;
|
||||
|
||||
// udpsocket doesnt exist
|
||||
if (*activated && !udpSocketAlive && !carryOverFlag) {
|
||||
if (*activated && *detectorDataStream && !udpSocketAlive && !carryOverFlag) {
|
||||
// LOG(logERROR) << "Listening_Thread " << index << ": UDP Socket not
|
||||
// created or shut down earlier";
|
||||
(*((uint32_t *)buffer)) = 0;
|
||||
@ -210,7 +210,7 @@ void Listener::ThreadExecution() {
|
||||
}
|
||||
|
||||
// get data
|
||||
if ((*status != TRANSMITTING && (!(*activated) || udpSocketAlive)) ||
|
||||
if ((*status != TRANSMITTING && (!(*activated) || !(*detectorDataStream) || udpSocketAlive)) ||
|
||||
carryOverFlag) {
|
||||
rc = ListenToAnImage(buffer);
|
||||
}
|
||||
@ -293,6 +293,10 @@ uint32_t Listener::ListenToAnImage(char *buf) {
|
||||
memset(buf, 0, fifohsize);
|
||||
new_header = (sls_receiver_header *)(buf + FIFO_HEADER_NUMBYTES);
|
||||
|
||||
// deactivated port (eiger)
|
||||
if (!(*detectorDataStream)) {
|
||||
return 0;
|
||||
}
|
||||
// deactivated (eiger)
|
||||
if (!(*activated)) {
|
||||
// no padding
|
||||
|
@ -37,12 +37,13 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
|
||||
* @param fpf pointer to frames per file
|
||||
* @param fdp frame discard policy
|
||||
* @param act pointer to activated
|
||||
* @param detds pointer to detector data stream
|
||||
* @param depaden pointer to deactivated padding enable
|
||||
* @param sm pointer to silent mode
|
||||
*/
|
||||
Listener(int ind, detectorType dtype, Fifo *f, std::atomic<runStatus> *s,
|
||||
uint32_t *portno, std::string *e, uint64_t *nf, int *us, int *as,
|
||||
uint32_t *fpf, frameDiscardPolicy *fdp, bool *act, bool *depaden,
|
||||
uint32_t *fpf, frameDiscardPolicy *fdp, bool *act, bool* detds, bool *depaden,
|
||||
bool *sm);
|
||||
|
||||
/**
|
||||
@ -187,6 +188,9 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
|
||||
/** Activated/Deactivated */
|
||||
bool *activated;
|
||||
|
||||
/** detector data stream */
|
||||
bool* detectorDataStream;
|
||||
|
||||
/** Deactivated padding enable */
|
||||
bool *deactivatedPaddingEnable;
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "receiver_defs.h"
|
||||
#include "sls/ToString.h"
|
||||
#include "sls/logger.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
@ -14,10 +15,6 @@ using namespace H5;
|
||||
#include <chrono>
|
||||
using ns = std::chrono::nanoseconds;
|
||||
|
||||
// versions
|
||||
#define HDF5_WRITER_VERSION (6.2) // 1 decimal places
|
||||
#define BINARY_WRITER_VERSION (6.2) // 1 decimal places
|
||||
|
||||
struct MasterAttributes {
|
||||
slsDetectorDefs::detectorType detType{slsDetectorDefs::GENERIC};
|
||||
slsDetectorDefs::timingMode timingMode{slsDetectorDefs::AUTO_TIMING};
|
||||
@ -36,7 +33,7 @@ struct MasterAttributes {
|
||||
uint32_t dynamicRange{0};
|
||||
uint32_t tenGiga{0};
|
||||
int thresholdEnergyeV{0};
|
||||
std::array<int, 3> thresholdAllEnergyeV={{0, 0, 0}};
|
||||
std::array<int, 3> thresholdAllEnergyeV = {{0, 0, 0}};
|
||||
ns subExptime{0};
|
||||
ns subPeriod{0};
|
||||
uint32_t quad{0};
|
||||
@ -130,6 +127,8 @@ struct MasterAttributes {
|
||||
};
|
||||
|
||||
void WriteHDF5Attributes(H5File *fd, Group *group) {
|
||||
char c[1024];
|
||||
memset(c, 0, sizeof(c));
|
||||
// clang-format off
|
||||
// version
|
||||
{
|
||||
@ -145,24 +144,27 @@ struct MasterAttributes {
|
||||
StrType strdatatype(PredType::C_S1, 256);
|
||||
DataSpace dataspace = DataSpace(H5S_SCALAR);
|
||||
DataSet dataset =
|
||||
group->createDataSet("Timestamp", strdatatype, dataspace);
|
||||
dataset.write(std::string(ctime(&t)), strdatatype);
|
||||
group->createDataSet("Timestamp", strdatatype, dataspace);
|
||||
sls::strcpy_safe(c, std::string(ctime(&t)));
|
||||
dataset.write(c, strdatatype);
|
||||
}
|
||||
// detector type
|
||||
{
|
||||
DataSpace dataspace = DataSpace(H5S_SCALAR);
|
||||
StrType strdatatype(PredType::C_S1, 256);
|
||||
DataSet dataset =
|
||||
group->createDataSet("Detector Type", strdatatype, dataspace);
|
||||
dataset.write(sls::ToString(detType), strdatatype);
|
||||
group->createDataSet("Detector Type", strdatatype, dataspace);
|
||||
sls::strcpy_safe(c, sls::ToString(detType));
|
||||
dataset.write(c, strdatatype);
|
||||
}
|
||||
// timing mode
|
||||
{
|
||||
DataSpace dataspace = DataSpace(H5S_SCALAR);
|
||||
StrType strdatatype(PredType::C_S1, 256);
|
||||
DataSet dataset =
|
||||
group->createDataSet("Timing Mode", strdatatype, dataspace);
|
||||
dataset.write(sls::ToString(timingMode), strdatatype);
|
||||
group->createDataSet("Timing Mode", strdatatype, dataspace);
|
||||
sls::strcpy_safe(c, sls::ToString(timingMode));
|
||||
dataset.write(c, strdatatype);
|
||||
}
|
||||
// Image Size
|
||||
{
|
||||
@ -173,8 +175,9 @@ struct MasterAttributes {
|
||||
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
|
||||
StrType strdatatype(PredType::C_S1, 256);
|
||||
Attribute attribute =
|
||||
dataset.createAttribute("Unit", strdatatype, dataspaceAttr);
|
||||
attribute.write(strdatatype, std::string("bytes"));
|
||||
dataset.createAttribute("Unit", strdatatype, dataspaceAttr);
|
||||
sls::strcpy_safe(c, "bytes");
|
||||
attribute.write(strdatatype, c);
|
||||
}
|
||||
//TODO: make this into an array?
|
||||
// x
|
||||
@ -203,8 +206,9 @@ struct MasterAttributes {
|
||||
DataSpace dataspace = DataSpace(H5S_SCALAR);
|
||||
StrType strdatatype(PredType::C_S1, 256);
|
||||
DataSet dataset =
|
||||
group->createDataSet("Frame Discard Policy", strdatatype, dataspace);
|
||||
dataset.write(sls::ToString(frameDiscardMode), strdatatype);
|
||||
group->createDataSet("Frame Discard Policy", strdatatype, dataspace);
|
||||
sls::strcpy_safe(c, sls::ToString(frameDiscardMode));
|
||||
dataset.write(c, strdatatype);
|
||||
}
|
||||
// Frame Padding
|
||||
{
|
||||
@ -218,8 +222,9 @@ struct MasterAttributes {
|
||||
DataSpace dataspace = DataSpace(H5S_SCALAR);
|
||||
StrType strdatatype(PredType::C_S1, 256);
|
||||
DataSet dataset =
|
||||
group->createDataSet("Scan Parameters", strdatatype, dataspace);
|
||||
dataset.write(sls::ToString(scanParams), strdatatype);
|
||||
group->createDataSet("Scan Parameters", strdatatype, dataspace);
|
||||
sls::strcpy_safe(c, sls::ToString(scanParams));
|
||||
dataset.write(c, strdatatype);
|
||||
}
|
||||
// Total Frames
|
||||
{
|
||||
@ -234,8 +239,9 @@ struct MasterAttributes {
|
||||
StrType strdatatype(PredType::C_S1, json.length());
|
||||
DataSpace dataspace = DataSpace(H5S_SCALAR);
|
||||
DataSet dataset =
|
||||
group->createDataSet("Additional JSON Header", strdatatype, dataspace);
|
||||
dataset.write(sls::ToString(additionalJsonHeader), strdatatype);
|
||||
group->createDataSet("Additional JSON Header", strdatatype, dataspace);
|
||||
sls::strcpy_safe(c, sls::ToString(additionalJsonHeader));
|
||||
dataset.write(c, strdatatype);
|
||||
}
|
||||
};
|
||||
|
||||
@ -243,16 +249,22 @@ struct MasterAttributes {
|
||||
DataSpace dataspace = DataSpace(H5S_SCALAR);
|
||||
StrType strdatatype(PredType::C_S1, 256);
|
||||
DataSet dataset =
|
||||
group->createDataSet("Exposure Time", strdatatype, dataspace);
|
||||
dataset.write(sls::ToString(exptime), strdatatype);
|
||||
group->createDataSet("Exposure Time", strdatatype, dataspace);
|
||||
char c[1024];
|
||||
memset(c, 0, sizeof(c));
|
||||
sls::strcpy_safe(c, sls::ToString(exptime));
|
||||
dataset.write(c, strdatatype);
|
||||
};
|
||||
|
||||
void WriteHDF5Period(H5File *fd, Group *group) {
|
||||
DataSpace dataspace = DataSpace(H5S_SCALAR);
|
||||
StrType strdatatype(PredType::C_S1, 256);
|
||||
DataSet dataset =
|
||||
group->createDataSet("Acquisition Period", strdatatype, dataspace);
|
||||
dataset.write(sls::ToString(period), strdatatype);
|
||||
group->createDataSet("Acquisition Period", strdatatype, dataspace);
|
||||
char c[1024];
|
||||
memset(c, 0, sizeof(c));
|
||||
sls::strcpy_safe(c, sls::ToString(period));
|
||||
dataset.write(c, strdatatype);
|
||||
};
|
||||
|
||||
void WriteHDF5DynamicRange(H5File *fd, Group *group) {
|
||||
@ -263,8 +275,9 @@ struct MasterAttributes {
|
||||
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
|
||||
StrType strdatatype(PredType::C_S1, 256);
|
||||
Attribute attribute =
|
||||
dataset.createAttribute("Unit", strdatatype, dataspaceAttr);
|
||||
attribute.write(strdatatype, std::string("bits"));
|
||||
dataset.createAttribute("Unit", strdatatype, dataspaceAttr);
|
||||
char c[1024] = "bits";
|
||||
attribute.write( strdatatype, c);
|
||||
};
|
||||
|
||||
void WriteHDF5TenGiga(H5File *fd, Group *group) {
|
||||
@ -374,6 +387,8 @@ class EigerMasterAttributes : public MasterAttributes {
|
||||
MasterAttributes::WriteHDF5TenGiga(fd, group);
|
||||
MasterAttributes::WriteHDF5Exptime(fd, group);
|
||||
MasterAttributes::WriteHDF5Period(fd, group);
|
||||
char c[1024];
|
||||
memset(c, 0, sizeof(c));
|
||||
// threshold
|
||||
{
|
||||
DataSpace dataspace = DataSpace(H5S_SCALAR);
|
||||
@ -383,8 +398,9 @@ class EigerMasterAttributes : public MasterAttributes {
|
||||
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
|
||||
StrType strdatatype(PredType::C_S1, 256);
|
||||
Attribute attribute =
|
||||
dataset.createAttribute("Unit", strdatatype, dataspaceAttr);
|
||||
attribute.write(strdatatype, std::string("eV"));
|
||||
dataset.createAttribute("Unit", strdatatype, dataspaceAttr);
|
||||
sls::strcpy_safe(c, "eV");
|
||||
attribute.write(strdatatype, c);
|
||||
}
|
||||
// SubExptime
|
||||
{
|
||||
@ -392,21 +408,23 @@ class EigerMasterAttributes : public MasterAttributes {
|
||||
StrType strdatatype(PredType::C_S1, 256);
|
||||
DataSet dataset = group->createDataSet("Sub Exposure Time",
|
||||
strdatatype, dataspace);
|
||||
dataset.write(sls::ToString(subExptime), strdatatype);
|
||||
sls::strcpy_safe(c, sls::ToString(subExptime));
|
||||
dataset.write(c, strdatatype);
|
||||
}
|
||||
// SubPeriod
|
||||
{
|
||||
DataSpace dataspace = DataSpace(H5S_SCALAR);
|
||||
StrType strdatatype(PredType::C_S1, 256);
|
||||
DataSet dataset =
|
||||
group->createDataSet("Sub Period", strdatatype, dataspace);
|
||||
dataset.write(sls::ToString(subPeriod), strdatatype);
|
||||
group->createDataSet("Sub Period", strdatatype, dataspace);
|
||||
sls::strcpy_safe(c, sls::ToString(subPeriod));
|
||||
dataset.write(c, strdatatype);
|
||||
}
|
||||
// Quad
|
||||
{
|
||||
DataSpace dataspace = DataSpace(H5S_SCALAR);
|
||||
DataSet dataset =
|
||||
group->createDataSet("Quad", PredType::NATIVE_INT, dataspace);
|
||||
group->createDataSet("Quad", PredType::NATIVE_INT, dataspace);
|
||||
dataset.write(&quad, PredType::NATIVE_INT);
|
||||
}
|
||||
// numLinesReadout
|
||||
@ -422,7 +440,8 @@ class EigerMasterAttributes : public MasterAttributes {
|
||||
StrType strdatatype(PredType::C_S1, 1024);
|
||||
DataSet dataset = group->createDataSet("Rate Corrections",
|
||||
strdatatype, dataspace);
|
||||
dataset.write(sls::ToString(ratecorr), strdatatype);
|
||||
sls::strcpy_safe(c, sls::ToString(ratecorr));
|
||||
dataset.write(c, strdatatype);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
@ -465,6 +484,8 @@ class Mythen3MasterAttributes : public MasterAttributes {
|
||||
MasterAttributes::WriteHDF5DynamicRange(fd, group);
|
||||
MasterAttributes::WriteHDF5TenGiga(fd, group);
|
||||
MasterAttributes::WriteHDF5Period(fd, group);
|
||||
char c[1024];
|
||||
memset(c, 0, sizeof(c));
|
||||
// Counter Mask
|
||||
{
|
||||
DataSpace dataspace = DataSpace(H5S_SCALAR);
|
||||
@ -478,7 +499,8 @@ class Mythen3MasterAttributes : public MasterAttributes {
|
||||
StrType strdatatype(PredType::C_S1, 256);
|
||||
DataSet dataset =
|
||||
group->createDataSet("Exposure Time1", strdatatype, dataspace);
|
||||
dataset.write(sls::ToString(exptime1), strdatatype);
|
||||
sls::strcpy_safe(c, sls::ToString(exptime1));
|
||||
dataset.write(c, strdatatype);
|
||||
}
|
||||
// Exptime2
|
||||
{
|
||||
@ -486,7 +508,8 @@ class Mythen3MasterAttributes : public MasterAttributes {
|
||||
StrType strdatatype(PredType::C_S1, 256);
|
||||
DataSet dataset =
|
||||
group->createDataSet("Exposure Time2", strdatatype, dataspace);
|
||||
dataset.write(sls::ToString(exptime2), strdatatype);
|
||||
sls::strcpy_safe(c, sls::ToString(exptime2));
|
||||
dataset.write(c, strdatatype);
|
||||
}
|
||||
// Exptime3
|
||||
{
|
||||
@ -494,7 +517,8 @@ class Mythen3MasterAttributes : public MasterAttributes {
|
||||
StrType strdatatype(PredType::C_S1, 256);
|
||||
DataSet dataset =
|
||||
group->createDataSet("Exposure Time3", strdatatype, dataspace);
|
||||
dataset.write(sls::ToString(exptime3), strdatatype);
|
||||
sls::strcpy_safe(c, sls::ToString(exptime3));
|
||||
dataset.write(c, strdatatype);
|
||||
}
|
||||
// GateDelay1
|
||||
{
|
||||
@ -502,7 +526,8 @@ class Mythen3MasterAttributes : public MasterAttributes {
|
||||
StrType strdatatype(PredType::C_S1, 256);
|
||||
DataSet dataset =
|
||||
group->createDataSet("Gate Delay1", strdatatype, dataspace);
|
||||
dataset.write(sls::ToString(gateDelay1), strdatatype);
|
||||
sls::strcpy_safe(c, sls::ToString(gateDelay1));
|
||||
dataset.write(c, strdatatype);
|
||||
}
|
||||
// GateDelay2
|
||||
{
|
||||
@ -510,7 +535,8 @@ class Mythen3MasterAttributes : public MasterAttributes {
|
||||
StrType strdatatype(PredType::C_S1, 256);
|
||||
DataSet dataset =
|
||||
group->createDataSet("Gate Delay2", strdatatype, dataspace);
|
||||
dataset.write(sls::ToString(gateDelay2), strdatatype);
|
||||
sls::strcpy_safe(c, sls::ToString(gateDelay2));
|
||||
dataset.write(c, strdatatype);
|
||||
}
|
||||
// GateDelay3
|
||||
{
|
||||
@ -518,7 +544,8 @@ class Mythen3MasterAttributes : public MasterAttributes {
|
||||
StrType strdatatype(PredType::C_S1, 256);
|
||||
DataSet dataset =
|
||||
group->createDataSet("Gate Delay3", strdatatype, dataspace);
|
||||
dataset.write(sls::ToString(gateDelay3), strdatatype);
|
||||
sls::strcpy_safe(c, sls::ToString(gateDelay3));
|
||||
dataset.write(c, strdatatype);
|
||||
}
|
||||
// Gates
|
||||
{
|
||||
@ -533,7 +560,8 @@ class Mythen3MasterAttributes : public MasterAttributes {
|
||||
StrType strdatatype(PredType::C_S1, 1024);
|
||||
DataSet dataset = group->createDataSet("Threshold Energies",
|
||||
strdatatype, dataspace);
|
||||
dataset.write(sls::ToString(thresholdAllEnergyeV), strdatatype);
|
||||
sls::strcpy_safe(c, sls::ToString(thresholdAllEnergyeV));
|
||||
dataset.write(c, strdatatype);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
@ -565,7 +593,10 @@ class Gotthard2MasterAttributes : public MasterAttributes {
|
||||
StrType strdatatype(PredType::C_S1, 256);
|
||||
DataSet dataset =
|
||||
group->createDataSet("Burst Mode", strdatatype, dataspace);
|
||||
dataset.write(sls::ToString(burstMode), strdatatype);
|
||||
char c[1024];
|
||||
memset(c, 0, sizeof(c));
|
||||
sls::strcpy_safe(c, sls::ToString(burstMode));
|
||||
dataset.write(c, strdatatype);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
@ -13,6 +13,11 @@
|
||||
#define MAX_SOCKET_INPUT_PACKET_QUEUE (250000)
|
||||
|
||||
// files
|
||||
|
||||
// versions
|
||||
#define HDF5_WRITER_VERSION (6.2) // 1 decimal places
|
||||
#define BINARY_WRITER_VERSION (6.2) // 1 decimal places
|
||||
|
||||
#define MAX_FRAMES_PER_FILE 20000
|
||||
#define SHORT_MAX_FRAMES_PER_FILE 100000
|
||||
#define MOENCH_MAX_FRAMES_PER_FILE 100000
|
||||
|
@ -37,6 +37,7 @@ std::string ToString(const std::vector<defs::dacIndex> &vec);
|
||||
std::string ToString(const defs::burstMode s);
|
||||
std::string ToString(const defs::timingSourceType s);
|
||||
std::string ToString(const defs::M3_GainCaps s);
|
||||
std::string ToString(const defs::portPosition s);
|
||||
|
||||
std::string ToString(const slsDetectorDefs::xy &coord);
|
||||
std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::xy &coord);
|
||||
@ -299,6 +300,7 @@ template <> defs::dacIndex StringTo(const std::string &s);
|
||||
template <> defs::burstMode StringTo(const std::string &s);
|
||||
template <> defs::timingSourceType StringTo(const std::string &s);
|
||||
template <> defs::M3_GainCaps StringTo(const std::string &s);
|
||||
template <> defs::portPosition StringTo(const std::string &s);
|
||||
|
||||
template <> uint32_t StringTo(const std::string &s);
|
||||
template <> uint64_t StringTo(const std::string &s);
|
||||
|
@ -401,6 +401,8 @@ typedef struct {
|
||||
M3_C15pre = 1 << 14,
|
||||
};
|
||||
|
||||
enum portPosition { LEFT, RIGHT, TOP, BOTTOM };
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/** scan structure */
|
||||
@ -459,6 +461,8 @@ typedef struct {
|
||||
int64_t subExpTimeNs{0};
|
||||
int64_t subDeadTimeNs{0};
|
||||
int activate{0};
|
||||
int dataStreamLeft{0};
|
||||
int dataStreamRight{0};
|
||||
int quad{0};
|
||||
int numLinesReadout{0};
|
||||
int thresholdEnergyeV[3]{0, 0, 0};
|
||||
|
@ -224,6 +224,8 @@ enum detFuncs {
|
||||
F_GET_CSR,
|
||||
F_SET_GAIN_CAPS,
|
||||
F_GET_GAIN_CAPS,
|
||||
F_GET_DATASTREAM,
|
||||
F_SET_DATASTREAM,
|
||||
|
||||
NUM_DET_FUNCTIONS,
|
||||
RECEIVER_ENUM_START = 256, /**< detector function should not exceed this
|
||||
@ -328,6 +330,7 @@ enum detFuncs {
|
||||
F_GET_RECEIVER_STREAMING_HWM,
|
||||
F_SET_RECEIVER_STREAMING_HWM,
|
||||
F_RECEIVER_SET_ALL_THRESHOLD,
|
||||
F_RECEIVER_SET_DATASTREAM,
|
||||
|
||||
NUM_REC_FUNCTIONS
|
||||
};
|
||||
@ -551,6 +554,8 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
|
||||
case F_LOAD_DEFAULT_PATTERN: return "F_LOAD_DEFAULT_PATTERN";
|
||||
case F_GET_ALL_THRESHOLD_ENERGY: return "F_GET_ALL_THRESHOLD_ENERGY";
|
||||
case F_GET_MASTER: return "F_GET_MASTER";
|
||||
case F_GET_DATASTREAM: return "F_GET_DATASTREAM";
|
||||
case F_SET_DATASTREAM: return "F_SET_DATASTREAM";
|
||||
|
||||
case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS";
|
||||
case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";
|
||||
@ -654,7 +659,7 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
|
||||
case F_GET_RECEIVER_STREAMING_HWM: return "F_GET_RECEIVER_STREAMING_HWM";
|
||||
case F_SET_RECEIVER_STREAMING_HWM: return "F_SET_RECEIVER_STREAMING_HWM";
|
||||
case F_RECEIVER_SET_ALL_THRESHOLD: return "F_RECEIVER_SET_ALL_THRESHOLD";
|
||||
|
||||
case F_RECEIVER_SET_DATASTREAM: return "F_RECEIVER_SET_DATASTREAM";
|
||||
|
||||
case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS";
|
||||
default: return "Unknown Function";
|
||||
|
@ -10,4 +10,4 @@
|
||||
#define APIMYTHEN3 0x210621
|
||||
#define APIMOENCH 0x210621
|
||||
|
||||
#define APIEIGER 0x210701
|
||||
#define APIEIGER 0x210721
|
||||
|
@ -52,6 +52,8 @@ std::string ToString(const slsDetectorDefs::rxParameters &r) {
|
||||
<< "subDeadTime:" << ToString(std::chrono::nanoseconds(r.subDeadTimeNs))
|
||||
<< std::endl
|
||||
<< "activate:" << r.activate << std::endl
|
||||
<< "leftDataStream:" << r.dataStreamLeft << std::endl
|
||||
<< "rightDataStream:" << r.dataStreamRight << std::endl
|
||||
<< "quad:" << r.quad << std::endl
|
||||
<< "numLinesReadout:" << r.numLinesReadout << std::endl
|
||||
<< "thresholdEnergyeV:" << ToString(r.thresholdEnergyeV) << std::endl
|
||||
@ -519,6 +521,40 @@ std::string ToString(const defs::timingSourceType s) {
|
||||
}
|
||||
}
|
||||
|
||||
std::string ToString(defs::M3_GainCaps s) {
|
||||
std::ostringstream os;
|
||||
if (s & defs::M3_C10pre)
|
||||
os << "C10pre, ";
|
||||
if (s & defs::M3_C15sh)
|
||||
os << "C15sh, ";
|
||||
if (s & defs::M3_C30sh)
|
||||
os << "C30sh, ";
|
||||
if (s & defs::M3_C50sh)
|
||||
os << "C50sh, ";
|
||||
if (s & defs::M3_C225ACsh)
|
||||
os << "C225ACsh, ";
|
||||
if (s & defs::M3_C15pre)
|
||||
os << "C15pre, ";
|
||||
auto rs = os.str();
|
||||
rs.erase(rs.end() - 2);
|
||||
return rs;
|
||||
}
|
||||
|
||||
std::string ToString(const defs::portPosition s) {
|
||||
switch (s) {
|
||||
case defs::LEFT:
|
||||
return std::string("left");
|
||||
case defs::RIGHT:
|
||||
return std::string("right");
|
||||
case defs::TOP:
|
||||
return std::string("top");
|
||||
case defs::BOTTOM:
|
||||
return std::string("bottom");
|
||||
default:
|
||||
return std::string("Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
const std::string &ToString(const std::string &s) { return s; }
|
||||
|
||||
template <> defs::detectorType StringTo(const std::string &s) {
|
||||
@ -859,7 +895,7 @@ template <> defs::timingSourceType StringTo(const std::string &s) {
|
||||
throw sls::RuntimeError("Unknown timing source type " + s);
|
||||
}
|
||||
|
||||
template <> defs::M3_GainCaps StringTo(const std::string &s){
|
||||
template <> defs::M3_GainCaps StringTo(const std::string &s) {
|
||||
if (s == "C10pre")
|
||||
return defs::M3_C10pre;
|
||||
if (s == "C15sh")
|
||||
@ -873,28 +909,18 @@ template <> defs::M3_GainCaps StringTo(const std::string &s){
|
||||
if (s == "C15pre")
|
||||
return defs::M3_C15pre;
|
||||
throw sls::RuntimeError("Unknown gain cap " + s);
|
||||
|
||||
}
|
||||
|
||||
|
||||
std::string ToString(defs::M3_GainCaps s){
|
||||
std::ostringstream os;
|
||||
if (s & defs::M3_C10pre)
|
||||
os << "C10pre, ";
|
||||
if (s & defs::M3_C15sh)
|
||||
os << "C15sh, ";
|
||||
if (s & defs::M3_C30sh)
|
||||
os << "C30sh, ";
|
||||
if (s & defs::M3_C50sh)
|
||||
os << "C50sh, ";
|
||||
if (s & defs::M3_C225ACsh)
|
||||
os << "C225ACsh, ";
|
||||
if (s & defs::M3_C15pre)
|
||||
os << "C15pre, ";
|
||||
auto rs = os.str();
|
||||
rs.erase(rs.end()-2);
|
||||
return rs;
|
||||
|
||||
template <> defs::portPosition StringTo(const std::string &s) {
|
||||
if (s == "left")
|
||||
return defs::LEFT;
|
||||
if (s == "right")
|
||||
return defs::RIGHT;
|
||||
if (s == "top")
|
||||
return defs::TOP;
|
||||
if (s == "bottom")
|
||||
return defs::BOTTOM;
|
||||
throw sls::RuntimeError("Unknown port position " + s);
|
||||
}
|
||||
|
||||
template <> uint32_t StringTo(const std::string &s) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user