Merge pull request #256 from slsdetectorgroup/disabledata

Disabledata
This commit is contained in:
Dhanya Thattil 2021-07-21 17:02:25 +02:00 committed by GitHub
commit fd6e44c396
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 2358 additions and 2031 deletions

View File

@ -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):

View File

@ -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,

View File

@ -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();
}

View File

@ -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;

View File

@ -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();

View File

@ -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, &regval)) {
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(),

View File

@ -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);

View File

@ -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

View File

@ -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,11 +2409,15 @@ void *start_timer(void *arg) {
}
}
}
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)));
clock_gettime(CLOCK_REALTIME, &end);

View File

@ -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

View File

@ -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

View File

@ -247,3 +247,5 @@ int get_master(int);
int get_csr();
int set_gain_caps(int);
int get_gain_caps(int);
int get_datastream(int);
int set_datastream(int);

View File

@ -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);
}

View File

@ -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 */

View File

@ -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) {

View File

@ -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 */

View File

@ -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 {

View File

@ -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 {

View File

@ -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);
/**************************************************
* *

View File

@ -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));
}
}

View File

@ -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)

View 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));
}
}

View 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};
};

View File

@ -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;
}
}

View File

@ -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;
};

View 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();
}

View 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_;
};

View File

@ -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);
}

View File

@ -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) {

View File

@ -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;

View File

@ -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
/**

View File

@ -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;

View File

@ -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;

View File

@ -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_; }

View File

@ -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_;
};

View 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_;
}

View 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};
};

View File

@ -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;
}
}

View File

@ -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;
};

View 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_;
}
}

View 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_;
};

View 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_;
}
}

View 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_;
};

View File

@ -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], &eth[i],
i, detType, fifo_ptr, &status, &udpPortNum[i], &eth[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,19 +328,23 @@ slsDetectorDefs::fileFormat Implementation::getFileFormat() const {
}
void Implementation::setFileFormat(const fileFormat f) {
if (f != fileFormatType) {
switch (f) {
#ifdef HDF5C
case HDF5:
fileFormatType = HDF5;
break;
#endif
default:
case BINARY:
fileFormatType = BINARY;
break;
default:
throw sls::RuntimeError("Unknown file format");
}
for (const auto &it : dataProcessor)
it->SetFileFormat(f);
it->SetupFileWriter(fileWriteEnable, masterFileWriteEnable,
fileFormatType, modulePos);
}
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) {
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]);
}
// to create virtual file & set files/acquisition to 0 (only hdf5 at the
// moment)
dataProcessor[0]->EndofAcquisition(anycaught, maxIndexCaught);
// link file in master
dataProcessor[0]->LinkDataInMasterFile(silentMode);
}
}
#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,8 +715,10 @@ void Implementation::CreateUDPSockets() {
}
void Implementation::SetupWriter() {
// master file
std::unique_ptr<MasterAttributes> masterAttributes;
switch (myDetectorType) {
if (masterFileWriteEnable && modulePos == 0) {
switch (detType) {
case GOTTHARD:
masterAttributes = sls::make_unique<GotthardMasterAttributes>();
break;
@ -746,7 +744,7 @@ void Implementation::SetupWriter() {
throw sls::RuntimeError(
"Unknown detector type to set up master file attributes");
}
masterAttributes->detType = myDetectorType;
masterAttributes->detType = detType;
masterAttributes->timingMode = timingMode;
masterAttributes->imageSize = generalData->imageSize;
masterAttributes->nPixels =
@ -772,11 +770,13 @@ void Implementation::SetupWriter() {
masterAttributes->adcmask =
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga;
masterAttributes->analog =
(readoutType == ANALOG_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1
(readoutType == ANALOG_ONLY || readoutType == ANALOG_AND_DIGITAL)
? 1
: 0;
masterAttributes->analogSamples = numberOfAnalogSamples;
masterAttributes->digital =
(readoutType == DIGITAL_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1
(readoutType == DIGITAL_ONLY || readoutType == ANALOG_AND_DIGITAL)
? 1
: 0;
masterAttributes->digitalSamples = numberOfDigitalSamples;
masterAttributes->dbitoffset = ctbDbitOffset;
@ -794,15 +794,21 @@ void Implementation::SetupWriter() {
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],
&eth[i], &numberOfTotalFrames, &udpSocketBufferSize,
i, detType, fifo_ptr, &status, &udpPortNum[i], &eth[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

View File

@ -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;
};

View File

@ -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

View File

@ -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;

View File

@ -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
{
@ -146,7 +145,8 @@ struct MasterAttributes {
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset =
group->createDataSet("Timestamp", strdatatype, dataspace);
dataset.write(std::string(ctime(&t)), strdatatype);
sls::strcpy_safe(c, std::string(ctime(&t)));
dataset.write(c, strdatatype);
}
// detector type
{
@ -154,7 +154,8 @@ struct MasterAttributes {
StrType strdatatype(PredType::C_S1, 256);
DataSet dataset =
group->createDataSet("Detector Type", strdatatype, dataspace);
dataset.write(sls::ToString(detType), strdatatype);
sls::strcpy_safe(c, sls::ToString(detType));
dataset.write(c, strdatatype);
}
// timing mode
{
@ -162,7 +163,8 @@ struct MasterAttributes {
StrType strdatatype(PredType::C_S1, 256);
DataSet dataset =
group->createDataSet("Timing Mode", strdatatype, dataspace);
dataset.write(sls::ToString(timingMode), strdatatype);
sls::strcpy_safe(c, sls::ToString(timingMode));
dataset.write(c, strdatatype);
}
// Image Size
{
@ -174,7 +176,8 @@ struct MasterAttributes {
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("Unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("bytes"));
sls::strcpy_safe(c, "bytes");
attribute.write(strdatatype, c);
}
//TODO: make this into an array?
// x
@ -204,7 +207,8 @@ struct MasterAttributes {
StrType strdatatype(PredType::C_S1, 256);
DataSet dataset =
group->createDataSet("Frame Discard Policy", strdatatype, dataspace);
dataset.write(sls::ToString(frameDiscardMode), strdatatype);
sls::strcpy_safe(c, sls::ToString(frameDiscardMode));
dataset.write(c, strdatatype);
}
// Frame Padding
{
@ -219,7 +223,8 @@ struct MasterAttributes {
StrType strdatatype(PredType::C_S1, 256);
DataSet dataset =
group->createDataSet("Scan Parameters", strdatatype, dataspace);
dataset.write(sls::ToString(scanParams), strdatatype);
sls::strcpy_safe(c, sls::ToString(scanParams));
dataset.write(c, strdatatype);
}
// Total Frames
{
@ -235,7 +240,8 @@ struct MasterAttributes {
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset =
group->createDataSet("Additional JSON Header", strdatatype, dataspace);
dataset.write(sls::ToString(additionalJsonHeader), strdatatype);
sls::strcpy_safe(c, sls::ToString(additionalJsonHeader));
dataset.write(c, strdatatype);
}
};
@ -244,7 +250,10 @@ struct MasterAttributes {
StrType strdatatype(PredType::C_S1, 256);
DataSet dataset =
group->createDataSet("Exposure Time", strdatatype, dataspace);
dataset.write(sls::ToString(exptime), strdatatype);
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) {
@ -252,7 +261,10 @@ struct MasterAttributes {
StrType strdatatype(PredType::C_S1, 256);
DataSet dataset =
group->createDataSet("Acquisition Period", strdatatype, dataspace);
dataset.write(sls::ToString(period), strdatatype);
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) {
@ -264,7 +276,8 @@ struct MasterAttributes {
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("Unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("bits"));
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);
@ -384,7 +399,8 @@ class EigerMasterAttributes : public MasterAttributes {
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("Unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("eV"));
sls::strcpy_safe(c, "eV");
attribute.write(strdatatype, c);
}
// SubExptime
{
@ -392,7 +408,8 @@ 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
{
@ -400,7 +417,8 @@ class EigerMasterAttributes : public MasterAttributes {
StrType strdatatype(PredType::C_S1, 256);
DataSet dataset =
group->createDataSet("Sub Period", strdatatype, dataspace);
dataset.write(sls::ToString(subPeriod), strdatatype);
sls::strcpy_safe(c, sls::ToString(subPeriod));
dataset.write(c, strdatatype);
}
// Quad
{
@ -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

View File

@ -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

View File

@ -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);

View File

@ -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};

View File

@ -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";

View File

@ -10,4 +10,4 @@
#define APIMYTHEN3 0x210621
#define APIMOENCH 0x210621
#define APIEIGER 0x210701
#define APIEIGER 0x210721

View File

@ -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) {