From 1fb90ab98c95d1c88e0d4bfa732e284164a3b170 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil <33750417+thattil@users.noreply.github.com> Date: Tue, 7 Jun 2022 16:55:33 +0200 Subject: [PATCH 1/8] M3threshold (#475) * vicin default changed to 800, only setting vthx directly allows to set dac even if counter disabled, else disable counter, setallthresholdenergy if an energy is -1, get module value, fix that reg was repaced by isettings * vth3 disabled for interpolation enable, interpolation disable sets counter mask to what it was before (updating old mask whn setting counter mask except for setting all counters for interpolation enable) and enabling vth3 if counter was enabled * refactor and test for previous commit * pump probe only has vth2 enabled, handles both pump probe mode and interpolation mode as well * wip * refactored pump probe and interpolation and added to setmodule * check dacs and trimbits out of range for setmodule (not just threshold) * binaries in * m3: pump probe and interpolation mutually exclusive * minor --- RELEASE.txt | 2 + python/slsdet/detector.py | 8 +- .../bin/mythen3DetectorServer_developer | Bin 287132 -> 287272 bytes .../slsDetectorFunctionList.c | 131 ++++++++---- .../slsDetectorServer_defs.h | 2 +- .../include/slsDetectorFunctionList.h | 6 +- .../src/slsDetectorServer_funcs.c | 55 +++-- slsDetectorSoftware/include/sls/Detector.h | 6 +- slsDetectorSoftware/src/CmdProxy.cpp | 7 +- slsDetectorSoftware/src/CmdProxy.h | 5 +- slsDetectorSoftware/src/Module.cpp | 197 +++++++----------- slsDetectorSoftware/src/Module.h | 38 ++++ .../tests/test-CmdProxy-mythen3.cpp | 103 ++++++--- slsSupportLib/include/sls/versionAPI.h | 2 +- 14 files changed, 335 insertions(+), 227 deletions(-) diff --git a/RELEASE.txt b/RELEASE.txt index abf35629d..c23ae55f6 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -75,8 +75,10 @@ This document describes the differences between v7.0.0 and v6.x.x - rxr src files and classes (detectordata, ZmqSocket, helpDacs) added to sls namespace, and macros (namely from logger (logINFO etc)), slsDetectorGui (make_unique in implemtnation requires sls nemspace (points to std otherwise) but not deectorImpl.cpp) - blackfin programing made seamless (nCE fixed which helps) -save settings file for m3 and eiger +- m3 threshold changes - g2 and m3 clkdiv 2 (system clock) change should affect time settings (g2: exptime, period, delayaftertrigger, burstperiod, m3: exptime, gatedelay, gateperiod, period, delayaftertrigger) - g2 system frequency is the same irrespective of timing source +- (apparently) rxr doesnt get stuck anymore from 6.1.1 2. Resolved Issues ================== diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index 6de5bb9af..4f0c51423 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -1834,13 +1834,13 @@ class Detector(CppDetectorApi): @property @element def threshold(self): - """[Eiger] Threshold in eV + """[Eiger][Mythen3] Threshold in eV Note ---- To change settings as well or set threshold without trimbits, use setThresholdEnergy. - :setter: It loads trim files from settingspath. + :setter: It loads trim files from settingspath.\n [Mythen3] An energy of -1 will pick up values from detector. """ if self.type == detectorType.MYTHEN3: return self.getAllThresholdEnergy() @@ -3516,7 +3516,7 @@ class Detector(CppDetectorApi): @property @element def interpolation(self): - """[Mythen3] Enable or disable interpolation. Enabling also enables all counters """ + """[Mythen3] Enable or disable interpolation. interpolation mode enables all counters and disables vth3. Disabling sets back counter mask and vth3. """ return self.getInterpolation() @interpolation.setter @@ -3526,7 +3526,7 @@ class Detector(CppDetectorApi): @property @element def pumpprobe(self): - """[Mythen3] Enable or disable pump probe mode. """ + """[Mythen3] Enable or disable pump probe mode. Pump probe mode only enables vth2. Disabling sets back to previous value """ return self.getPumpProbe() @pumpprobe.setter diff --git a/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer b/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer index 59ce094ccfa796a4211fb64fb11a4ab711d14591..fe31b3408fbef2b079d9aaeb1800b29353b790bf 100755 GIT binary patch delta 79733 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 MAX_COUNTER_MSK) { return; } - uint32_t oldmask = getCounterMask(); - LOG(logINFO, ("Setting counter mask to 0x%x\n", arg)); + LOG(logINFO, ("\tSetting counter mask to 0x%x\n", arg)); uint32_t addr = CONFIG_REG; bus_w(addr, bus_r(addr) & ~CONFIG_COUNTERS_ENA_MSK); bus_w(addr, bus_r(addr) | ((arg << CONFIG_COUNTERS_ENA_OFST) & @@ -1108,19 +1143,8 @@ void setCounterMask(uint32_t arg) { setGateDelay(i, ns); } - LOG(logINFO, ("\tUpdating Vth dacs\n")); - enum DACINDEX vthdacs[] = {M_VTH1, M_VTH2, M_VTH3}; - for (int i = 0; i < NCOUNTERS; ++i) { - // if change in enable - if ((arg & (1 << i)) ^ (oldmask & (1 << i))) { - // disable, disable value - int value = DEFAULT_COUNTER_DISABLED_VTH_VAL; - // enable, set saved values - if (arg & (1 << i)) { - value = vthEnabledVals[i]; - } - setGeneralDAC(vthdacs[i], value, 0); - } + if (updateMaskFlag) { + counterMask = arg; } } @@ -1241,7 +1265,8 @@ int64_t getMeasurementTime() { int setDACS(int *dacs) { for (int i = 0; i < NDAC; ++i) { if (dacs[i] != -1) { - setDAC((enum DACINDEX)i, dacs[i], 0); + // set to default (last arg to ensure counter check) + setDAC((enum DACINDEX)i, dacs[i], 0, 1); if (dacs[i] != detectorDacs[i]) { // dont complain if that counter was disabled if ((i == M_VTH1 || i == M_VTH2 || i == M_VTH3) && @@ -1300,6 +1325,9 @@ int setModule(sls_detector_module myMod, char *mess) { return FAIL; } + // update vth and countermask + updateVthAndCounterMask(); + // threshold energy for (int i = 0; i < NCOUNTERS; ++i) { if (myMod.eV[i] >= 0) { @@ -1440,7 +1468,8 @@ enum detectorSettings setSettings(enum detectorSettings sett) { // set special dacs const int specialDacs[] = SPECIALDACINDEX; for (int i = 0; i < NSPECIALDACS; ++i) { - setDAC(specialDacs[i], dacVals[i], 0); + // set to default (last arg to ensure counter check) + setDAC(specialDacs[i], dacVals[i], 0, 1); } LOG(logINFO, ("Settings: %d\n", thisSettings)); @@ -1500,7 +1529,8 @@ void setThresholdEnergy(int counterIndex, int eV) { } /* parameters - dac, hv */ -void setDAC(enum DACINDEX ind, int val, int mV) { +// counterEnableCheck false only if setDAC called directly +void setDAC(enum DACINDEX ind, int val, int mV, int counterEnableCheck) { // invalid value if (val < 0) { return; @@ -1511,7 +1541,10 @@ void setDAC(enum DACINDEX ind, int val, int mV) { return; } - // threshold dacs (remember value, vthreshold: skip disabled) + // threshold dacs + // remember value, vthreshold: skip disabled, + // others: disable or enable dac if counter mask + // setDAC called directly: will set independent of counter enable if (ind == M_VTHRESHOLD || ind == M_VTH1 || ind == M_VTH2 || ind == M_VTH3) { char *dac_names[] = {DAC_NAMES}; @@ -1522,7 +1555,6 @@ void setDAC(enum DACINDEX ind, int val, int mV) { int dacval = val; // if not disabled value, remember value if (dacval != DEFAULT_COUNTER_DISABLED_VTH_VAL) { - // convert mv to dac if (mV) { if (LTC2620_D_VoltageToDac(val, &dacval) == FAIL) { return; @@ -1532,9 +1564,16 @@ void setDAC(enum DACINDEX ind, int val, int mV) { LOG(logINFO, ("Remembering %s [%d]\n", dac_names[ind], dacval)); } - // if vthreshold,skip for disabled counters - if ((ind == M_VTHRESHOLD) && (!(counters & (1 << i)))) { - continue; + // disabled counter + if (!(counters & (1 << i))) { + // skip setting vthx dac (value remembered anyway) + if (ind == M_VTHRESHOLD) { + continue; + } + // disable dac (except when setting dac directly) + if (counterEnableCheck) { + val = DEFAULT_COUNTER_DISABLED_VTH_VAL; + } } setGeneralDAC(vthdacs[i], val, mV); } @@ -1575,6 +1614,19 @@ void setGeneralDAC(enum DACINDEX ind, int val, int mV) { } } +void setVthDac(int index, int enable) { + LOG(logINFO, ("\t%s vth%d\n", (enable ? "Enabling" : "Disabing"), index)); + // enables (from remembered values) or disables vthx + enum DACINDEX vthdacs[] = {M_VTH1, M_VTH2, M_VTH3}; + // disable value + int value = DEFAULT_COUNTER_DISABLED_VTH_VAL; + // enable, set saved values + if (enable) { + value = vthEnabledVals[index]; + } + setGeneralDAC(vthdacs[index], value, 0); +} + int getDAC(enum DACINDEX ind, int mV) { if (ind == M_VTHRESHOLD) { int ret = -1, ret1 = -1; @@ -1738,23 +1790,24 @@ int setGainCaps(int caps) { int setInterpolation(int enable) { LOG(logINFO, ("%s Interpolation\n", enable == 0 ? "Disabling" : "Enabling")); - if (enable) { - setCounterMask(MAX_COUNTER_MSK); - if (getCounterMask() != MAX_COUNTER_MSK) { - LOG(logERROR, - ("Could not set interpolation. Could not enable all counters")); - return FAIL; - } - LOG(logINFO, ("\tEnabled all counters\n")); - } + int csr = M3SetInterpolation(enable); - return setChipStatusRegister(csr); + int ret = setChipStatusRegister(csr); + if (ret == OK) { + updateVthAndCounterMask(); + } + return ret; } int setPumpProbe(int enable) { LOG(logINFO, ("%s Pump Probe\n", enable == 0 ? "Disabling" : "Enabling")); + int csr = M3SetPumpProbe(enable); - return setChipStatusRegister(csr); + int ret = setChipStatusRegister(csr); + if (ret == OK) { + updateVthAndCounterMask(); + } + return ret; } int setDigitalPulsing(int enable) { diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h index 5faaf20bf..4956dd52f 100644 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h @@ -105,7 +105,7 @@ enum DACINDEX { 1220, /* vIpreOut */ \ 2800, /* Vth3 */ \ 2800, /* Vth1 */ \ - 1708, /* vIcin */ \ + 800, /* vIcin */ \ 1800, /* cas */ \ 1100, /* Vrpreamp */ \ 1100, /* Vcal_n */ \ diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index 3ae08b95d..d33cec62b 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -281,6 +281,7 @@ int getNumDigitalSamples(); #endif #ifdef MYTHEN3D void setCounterMask(uint32_t arg); +void setCounterMaskWithUpdateFlag(uint32_t arg, int updateMaskFlag); uint32_t getCounterMask(); void updatePacketizing(); #endif @@ -347,9 +348,12 @@ void setThresholdEnergy(int counterIndex, int eV); int setOnChipDAC(enum ONCHIP_DACINDEX ind, int chipIndex, int val); int getOnChipDAC(enum ONCHIP_DACINDEX ind, int chipIndex); #endif -void setDAC(enum DACINDEX ind, int val, int mV); #ifdef MYTHEN3D +void setDAC(enum DACINDEX ind, int val, int mV, int counterEnableCheck); void setGeneralDAC(enum DACINDEX ind, int val, int mV); +void setVthDac(int index, int enable); +#else +void setDAC(enum DACINDEX ind, int val, int mV); #endif int getDAC(enum DACINDEX ind, int mV); int getMaxDacSteps(); diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 988051528..235e8f427 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -1288,7 +1288,12 @@ int validateAndSetDac(enum dacIndex ind, int val, int mV) { LOG(logERROR, (mess)); } else #endif +#ifdef MYTHEN3D + // ignore counter enable to force vth dac values + setDAC(serverDacIndex, val, mV, 0); +#else setDAC(serverDacIndex, val, mV); +#endif retval = getDAC(serverDacIndex, mV); } #ifdef EIGERD @@ -9944,19 +9949,25 @@ int set_interpolation(int file_des) { #else // only set if (Server_VerifyLock() == OK) { - ret = setInterpolation(arg); - if (ret == FAIL) { - if (arg) - sprintf(mess, "Could not set interpolation or enable all " - "counters for it.\n"); - else - sprintf(mess, "Could not set interpolation\n"); + if (getPumpProbe() && arg) { + ret = FAIL; + sprintf(mess, "Could not set interpolation. Disable pump probe mode first.\n"); LOG(logERROR, (mess)); - } else { - int retval = getInterpolation(); - validate(&ret, mess, (int)arg, (int)retval, "set interpolation", - DEC); - LOG(logDEBUG1, ("interpolation retval: %u\n", retval)); + } else { + ret = setInterpolation(arg); + if (ret == FAIL) { + if (arg) + sprintf(mess, "Could not set interpolation or enable all " + "counters for it.\n"); + else + sprintf(mess, "Could not set interpolation\n"); + LOG(logERROR, (mess)); + } else { + int retval = getInterpolation(); + validate(&ret, mess, (int)arg, (int)retval, "set interpolation", + DEC); + LOG(logDEBUG1, ("interpolation retval: %u\n", retval)); + } } } #endif @@ -9994,14 +10005,20 @@ int set_pump_probe(int file_des) { #else // only set if (Server_VerifyLock() == OK) { - ret = setPumpProbe(arg); - if (ret == FAIL) { - sprintf(mess, "Could not set pump probe\n"); + if (getInterpolation() && arg) { + ret = FAIL; + sprintf(mess, "Could not set pump probe mode. Disable interpolation mode first.\n"); LOG(logERROR, (mess)); - } else { - int retval = getPumpProbe(); - validate(&ret, mess, (int)arg, (int)retval, "set pump probe", DEC); - LOG(logDEBUG1, ("pump probe retval: %u\n", retval)); + } else { + ret = setPumpProbe(arg); + if (ret == FAIL) { + sprintf(mess, "Could not set pump probe\n"); + LOG(logERROR, (mess)); + } else { + int retval = getPumpProbe(); + validate(&ret, mess, (int)arg, (int)retval, "set pump probe", DEC); + LOG(logDEBUG1, ("pump probe retval: %u\n", retval)); + } } } #endif diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index 8d428be6a..9afe3ec4a 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -144,7 +144,7 @@ class Detector { defs::detectorSettings settings = defs::STANDARD, bool trimbits = true, Positions pos = {}); - /** [Mythen3] It loads trim files from settingspath */ + /** [Mythen3] It loads trim files from settingspath. An energy of -1 will pick up values from detector */ void setThresholdEnergy(std::array threshold_ev, defs::detectorSettings settings = defs::STANDARD, bool trimbits = true, Positions pos = {}); @@ -1495,13 +1495,13 @@ class Detector { /** [Mythen3] */ Result getInterpolation(Positions pos = {}) const; - /** [Mythen3] Also enables all counters */ + /** [Mythen3] interpolation mode enables all counters and disables vth3. Disabling sets back counter mask and vth3. */ void setInterpolation(bool value, Positions pos = {}); /** [Mythen3] */ Result getPumpProbe(Positions pos = {}) const; - /** [Mythen3] */ + /** [Mythen3] pump probe mode only enables vth2. Disabling sets back to previous value */ void setPumpProbe(bool value, Positions pos = {}); /** [Mythen3] */ diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index 330fad9ae..70546879c 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -382,8 +382,8 @@ std::string CmdProxy::Threshold(int action) { } os << "\n\nthreshold [eV1] [eV2] [eV3] [(optional settings)]" "\n\t[Mythen3] Threshold in eV for each counter. It loads trim " - "files from " - "settingspath."; + "files from settingspath. An energy of -1 will pick up values " + " from detector."; if (cmd == "thresholdnotb") { os << "Trimbits are not loaded."; } @@ -2302,6 +2302,9 @@ std::string CmdProxy::Counters(int action) { if (args.empty()) { WrongNumberOfParameters(1); } + if (std::any_of(args.cbegin(), args.cend(), [](std::string s){ return (StringTo(s) < 0 || StringTo(s) > 2); })) { + throw RuntimeError("Invalid counter indices list. Example: 0 1 2"); + } // convert vector to counter enable mask uint32_t mask = 0; for (size_t i = 0; i < args.size(); ++i) { diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index 3b7aa4886..be90dd5eb 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -2053,12 +2053,11 @@ class CmdProxy { INTEGER_COMMAND_VEC_ID(interpolation, getInterpolation, setInterpolation, StringTo, "[0, 1]\n\t[Mythen3] Enables or disables " - "interpolation. Default is disabled. Enabling also " - "enables all counters. "); + "interpolation. Default is disabled. Interpolation mode enables all counters and disables vth3. Disabling sets back counter mask and vth3."); INTEGER_COMMAND_VEC_ID(pumpprobe, getPumpProbe, setPumpProbe, StringTo, "[0, 1]\n\t[Mythen3] Enables or disables pump probe " - "mode. Default is disabled"); + "mode. Default is disabled. Pump probe mode only enables vth2. Disabling sets back to previous value."); INTEGER_COMMAND_VEC_ID(apulse, getAnalogPulsing, setAnalogPulsing, StringTo, diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index d8898b709..8fb5477cb 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -173,7 +173,9 @@ std::array Module::getAllThresholdEnergy() const { void Module::setThresholdEnergy(int e_eV, detectorSettings isettings, bool trimbits) { - + if (shm()->detType == MYTHEN3) { + throw RuntimeError("Mythen3 should have called with 3 energies"); + } // verify e_eV exists in trimEneregies[] if (shm()->trimEnergies.empty() || (e_eV < shm()->trimEnergies.front()) || (e_eV > shm()->trimEnergies.back())) { @@ -214,21 +216,9 @@ void Module::setThresholdEnergy(int e_eV, detectorSettings isettings, myMod.iodelay = myMod1.iodelay; myMod.tau = linearInterpolation(e_eV, trim1, trim2, myMod1.tau, myMod2.tau); - // m3, reg is used for gaincaps - if (shm()->detType == MYTHEN3) { - if (myMod1.reg != myMod2.reg) { - throw RuntimeError( - "setThresholdEnergyAndSettings: gaincaps do not " - "match between files"); - } - myMod.reg = myMod1.reg; - } - } - // m3, reg is used for gaincaps - if (shm()->detType != MYTHEN3) { - myMod.reg = isettings; } + myMod.reg = isettings; myMod.eV[0] = e_eV; setModule(myMod, trimbits); if (getSettings() != isettings) { @@ -243,42 +233,35 @@ void Module::setThresholdEnergy(int e_eV, detectorSettings isettings, void Module::setAllThresholdEnergy(std::array e_eV, detectorSettings isettings, bool trimbits) { - // only mythen3 + if (shm()->detType != MYTHEN3) { + throw RuntimeError("This detector should have called with 3 energies"); + } if (shm()->trimEnergies.empty()) { throw RuntimeError( - "Trim energies have not been defined for this module yet!"); + "Trim energies have not been defined for this module yet! Use trimen."); } - auto counters = getSetBits(getCounterMask()); - enum mythen3_DacIndex { - M_VCASSH, - M_VTH2, - M_VRSHAPER, - M_VRSHAPER_N, - M_VIPRE_OUT, - M_VTH3, - M_VTH1, - M_VICIN, - M_VCAS, - M_VRPREAMP, - M_VCAL_N, - M_VIPRE, - M_VISHAPER, - M_VCAL_P, - M_VTRIM, - M_VDCSH - }; - - std::vector myMods{shm()->detType}; std::vector energy(e_eV.begin(), e_eV.end()); // if all energies are same if (allEqualTo(energy, energy[0])) { + if (energy[0] == -1) { + throw RuntimeError("Every energy provided to set threshold energy is -1. Typo?"); + } energy.resize(1); } - myMods.resize(energy.size()); // for each threshold + std::vector myMods; for (size_t i = 0; i < energy.size(); ++i) { + if (energy[i] == -1) { + sls_detector_module mod = getModule(); + myMods.push_back(mod); + continue; + } + + sls_detector_module mod{shm()->detType}; + myMods.push_back(mod); + // don't interpolate if (shm()->trimEnergies.anyEqualTo(energy[i])) { std::string settingsfname = @@ -324,10 +307,9 @@ void Module::setAllThresholdEnergy(std::array e_eV, myMods[i] = interpolateTrim(&myMod1, &myMod2, energy[i], trim1, trim2, trimbits); - // gaincaps + // csr if (myMod1.reg != myMod2.reg) { - throw RuntimeError("setAllThresholdEnergy: gaincaps do not " - "match between files for energy (eV) " + + throw RuntimeError("setAllThresholdEnergy: chip shift register values do not match between files for energy (eV) " + std::to_string(energy[i])); } myMods[i].reg = myMod1.reg; @@ -337,8 +319,11 @@ void Module::setAllThresholdEnergy(std::array e_eV, sls_detector_module myMod{shm()->detType}; myMod = myMods[0]; + // if multiple thresholds, combine if (myMods.size() > 1) { + auto counters = getSetBits(getCounterMask()); + // average vtrim of enabled counters int sum = 0; @@ -377,56 +362,15 @@ void Module::setAllThresholdEnergy(std::array e_eV, for (int i = 0; i < myMod.nchan; ++i) { myMod.chanregs[i] = myMods[i % 3].chanregs[i]; } - // gain caps + // csr if (myMods[0].reg != myMods[1].reg || myMods[1].reg != myMods[2].reg) { - throw RuntimeError("setAllThresholdEnergy: gaincaps do not " - "match between files for all energies"); + throw RuntimeError("setAllThresholdEnergy: chip shift register values do not match between files for all energies"); } } - myMod.reg = isettings; std::copy(e_eV.begin(), e_eV.end(), myMod.eV); LOG(logDEBUG) << "ev:" << ToString(myMod.eV); - // check for trimbits that are out of range - bool out_of_range = false; - for (int i = 0; i != myMod.nchan; ++i) { - if (myMod.chanregs[i] < 0) { - myMod.chanregs[i] = 0; - out_of_range = true; - } else if (myMod.chanregs[i] > 63) { - myMod.chanregs[i] = 63; - out_of_range = true; - } - } - if (out_of_range) { - LOG(logWARNING) - << "Some trimbits were out of range after interpolation, these " - "have been replaced with 0 or 63."; - } - - // check dacs - out_of_range = false; - for (int i = 0; i != myMod.ndac; ++i) { - int dacMin = 0; - int dacMax = 2800; - if (i == M_VTH1 || i == M_VTH2 || i == M_VTH3) { - dacMin = 200; - dacMax = 2400; - } - if (myMod.dacs[i] < dacMin) { - myMod.dacs[i] = dacMin; - out_of_range = true; - } else if (myMod.dacs[i] > dacMax) { - myMod.dacs[i] = dacMax; - out_of_range = true; - } - } - if (out_of_range) { - LOG(logWARNING) << "Some dacs were out of range after interpolation, " - "these have been replaced with 600 or 2400."; - } - setModule(myMod, trimbits); if (getSettings() != isettings) { throw RuntimeError("setThresholdEnergyAndSettings: Could not set " @@ -2252,10 +2196,8 @@ uint32_t Module::getCounterMask() const { } void Module::setCounterMask(uint32_t countermask) { - LOG(logDEBUG1) << "Setting Counter mask to " << countermask; sendToDetector(F_SET_COUNTER_MASK, countermask, nullptr); if (shm()->useReceiverFlag) { - LOG(logDEBUG1) << "Sending Reciver counter mask: " << countermask; sendToReceiver(F_RECEIVER_SET_COUNTER_MASK, countermask, nullptr); } } @@ -2315,7 +2257,10 @@ bool Module::getInterpolation() const { void Module::setInterpolation(const bool enable) { sendToDetector(F_SET_INTERPOLATION, static_cast(enable), nullptr); - setCounterMask(getCounterMask()); + int mask = getCounterMask(); + if (shm()->useReceiverFlag) { + sendToReceiver(F_RECEIVER_SET_COUNTER_MASK, mask, nullptr); + } } bool Module::getPumpProbe() const { @@ -2398,12 +2343,9 @@ int Module::getNumberOfDigitalSamples() const { } void Module::setNumberOfDigitalSamples(int value) { - LOG(logDEBUG1) << "Setting number of digital samples to " << value; sendToDetector(F_SET_NUM_DIGITAL_SAMPLES, value, nullptr); updateNumberOfChannels(); // depends on samples and adcmask if (shm()->useReceiverFlag) { - LOG(logDEBUG1) << "Sending number of digital samples to Receiver: " - << value; sendToReceiver(F_RECEIVER_SET_NUM_DIGITAL_SAMPLES, value, nullptr); } } @@ -3338,6 +3280,45 @@ void Module::setModule(sls_detector_module &module, bool trimbits) { module.nchan = 0; module.nchip = 0; } + // validate dacs and trimbits + if (shm()->detType == MYTHEN3) { + // check for trimbits that are out of range + bool out_of_range = false; + for (int i = 0; i != module.nchan; ++i) { + if (module.chanregs[i] < 0) { + module.chanregs[i] = 0; + out_of_range = true; + } else if (module.chanregs[i] > 63) { + module.chanregs[i] = 63; + out_of_range = true; + } + } + if (out_of_range) { + LOG(logWARNING) + << "Some trimbits were out of range, these have been replaced with 0 or 63."; + } + // check dacs + out_of_range = false; + for (int i = 0; i != module.ndac; ++i) { + int dacMin = 0; + int dacMax = 2800; + if (i == M_VTH1 || i == M_VTH2 || i == M_VTH3) { + dacMin = 200; + dacMax = 2400; + } + if (module.dacs[i] < dacMin) { + module.dacs[i] = dacMin; + out_of_range = true; + } else if (module.dacs[i] > dacMax) { + module.dacs[i] = dacMax; + out_of_range = true; + } + } + if (out_of_range) { + LOG(logWARNING) << "Some dacs were out of range, " + "these have been replaced with 0/200 or 2800/2400."; + } + } auto client = DetectorSocket(shm()->hostname, shm()->controlPort); client.Send(F_SET_MODULE); sendModule(&module, client); @@ -3469,42 +3450,6 @@ sls_detector_module Module::interpolateTrim(sls_detector_module *a, } sls_detector_module myMod{shm()->detType}; - enum eiger_DacIndex { - E_SVP, - E_VTR, - E_VRF, - E_VRS, - E_SVN, - E_VTGSTV, - E_VCMP_LL, - E_VCMP_LR, - E_CAL, - E_VCMP_RL, - E_RXB_RB, - E_RXB_LB, - E_VCMP_RR, - E_VCP, - E_VCN, - E_VIS - }; - enum mythen3_DacIndex { - M_VCASSH, - M_VTH2, - M_VRSHAPER, - M_VRSHAPER_N, - M_VIPRE_OUT, - M_VTH3, - M_VTH1, - M_VICIN, - M_VCAS, - M_VRPREAMP, - M_VCAL_N, - M_VIPRE, - M_VISHAPER, - M_VCAL_P, - M_VTRIM, - M_VDCSH - }; // create copy and interpolate dac lists std::vector dacs_to_copy, dacs_to_interpolate; diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 28fd08db5..2ab2f0217 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -789,6 +789,44 @@ class Module : public virtual slsDetectorDefs { static const int NIOS_WRITE_TO_FLASH_TIME_FPGA = 45; static const int NIOS_ERASE_FLASH_TIME_KERNEL = 9; static const int NIOS_WRITE_TO_FLASH_TIME_KERNEL = 40; + + enum mythen3_DacIndex { + M_VCASSH, + M_VTH2, + M_VRSHAPER, + M_VRSHAPER_N, + M_VIPRE_OUT, + M_VTH3, + M_VTH1, + M_VICIN, + M_VCAS, + M_VRPREAMP, + M_VCAL_N, + M_VIPRE, + M_VISHAPER, + M_VCAL_P, + M_VTRIM, + M_VDCSH + }; + + enum eiger_DacIndex { + E_SVP, + E_VTR, + E_VRF, + E_VRS, + E_SVN, + E_VTGSTV, + E_VCMP_LL, + E_VCMP_LR, + E_CAL, + E_VCMP_RL, + E_RXB_RB, + E_RXB_LB, + E_VCMP_RR, + E_VCP, + E_VCN, + E_VIS + }; }; } // namespace sls \ No newline at end of file diff --git a/slsDetectorSoftware/tests/test-CmdProxy-mythen3.cpp b/slsDetectorSoftware/tests/test-CmdProxy-mythen3.cpp index 3eedd9ea4..be6d9877f 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-mythen3.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-mythen3.cpp @@ -496,32 +496,46 @@ TEST_CASE("interpolation", "[.cmd]") { Detector det; CmdProxy proxy(&det); if (det.getDetectorType().squash() == defs::MYTHEN3) { - auto prev_val = det.getInterpolation(); - auto mask = det.getCounterMask(); - { - proxy.Call("counters", {"0", "1"}, -1, PUT); - std::ostringstream oss; - proxy.Call("interpolation", {"1"}, -1, PUT, oss); - REQUIRE(oss.str() == "interpolation 1\n"); - REQUIRE(det.getCounterMask().tsquash("inconsistent counter mask") == - 7); - } - { - proxy.Call("counters", {"0", "1"}, -1, PUT); - std::ostringstream oss; - proxy.Call("interpolation", {"0"}, -1, PUT, oss); - REQUIRE(oss.str() == "interpolation 0\n"); - REQUIRE(det.getCounterMask().tsquash("inconsistent counter mask") == - 3); + auto prev_interpolation = det.getInterpolation(); + auto prev_mask = det.getCounterMask(); + auto prev_vth3DacVal = det.getDAC(defs::VTH3, 0, {}); + + int disabledDacValue = 2800; + auto fixedVth3DacVal = 1000; + det.setDAC(defs::VTH3, fixedVth3DacVal, 0, {}); + // mask with counter 3 disabled and enabled(to test vth3) + uint32_t fixedMask[2] = {0x2, 0x4}; + for (int i = 0; i != 2; ++i) { + det.setCounterMask(fixedMask[i]); + { + std::ostringstream oss; + proxy.Call("interpolation", {"1"}, -1, PUT, oss); + REQUIRE(oss.str() == "interpolation 1\n"); + REQUIRE(det.getCounterMask().tsquash("inconsistent counter mask") == + 7); + REQUIRE(det.getDAC(defs::VTH3, 0, {0}).tsquash("inconsistent vth3 dac value") == disabledDacValue); + } + { + std::ostringstream oss; + proxy.Call("interpolation", {"0"}, -1, PUT, oss); + REQUIRE(oss.str() == "interpolation 0\n"); + REQUIRE(det.getCounterMask().tsquash("inconsistent counter mask") == + fixedMask[i]); + uint32_t expectedVth3DacVal = (fixedMask[i] & 0x4 ? fixedVth3DacVal : disabledDacValue); + REQUIRE(det.getDAC(defs::VTH3, 0, {0}).tsquash("inconsistent vth3 dac value") == expectedVth3DacVal); + } } + { std::ostringstream oss; proxy.Call("interpolation", {}, -1, GET, oss); REQUIRE(oss.str() == "interpolation 0\n"); } for (int i = 0; i != det.size(); ++i) { - det.setCounterMask(mask[i], {i}); - det.setInterpolation(prev_val[i], {i}); + det.setCounterMask(prev_mask[i], {i}); + det.setInterpolation(prev_interpolation[i], {i}); + det.setDAC(defs::VTH3, prev_vth3DacVal[i], 0, {i}); + } } else { REQUIRE_THROWS(proxy.Call("interpolation", {}, -1, GET)); @@ -533,15 +547,43 @@ TEST_CASE("pumpprobe", "[.cmd]") { CmdProxy proxy(&det); if (det.getDetectorType().squash() == defs::MYTHEN3) { auto prev_val = det.getPumpProbe(); - { - std::ostringstream oss; - proxy.Call("pumpprobe", {"1"}, -1, PUT, oss); - REQUIRE(oss.str() == "pumpprobe 1\n"); - } - { - std::ostringstream oss; - proxy.Call("pumpprobe", {"0"}, -1, PUT, oss); - REQUIRE(oss.str() == "pumpprobe 0\n"); + auto prev_interpolation = det.getInterpolation(); + auto prev_mask = det.getCounterMask(); + auto prev_vth1DacVal = det.getDAC(defs::VTH1, 0, {}); + auto prev_vth2DacVal = det.getDAC(defs::VTH2, 0, {}); + auto prev_vth3DacVal = det.getDAC(defs::VTH3, 0, {}); + + int disabledDacValue = 2800; + auto fixedVthDacVal = 1000; + det.setDAC(defs::VTH1, fixedVthDacVal, 0, {}); + det.setDAC(defs::VTH2, fixedVthDacVal, 0, {}); + det.setDAC(defs::VTH3, fixedVthDacVal, 0, {}); + // mask with counter 2 disabled and enabled(to test vth2) + uint32_t fixedMask[2] = {0x4, 0x3}; + for (int i = 0; i != 2; ++i) { + det.setCounterMask(fixedMask[i]); + { + // pump probe + std::ostringstream oss; + proxy.Call("pumpprobe", {"1"}, -1, PUT, oss); + REQUIRE(oss.str() == "pumpprobe 1\n"); + REQUIRE(det.getDAC(defs::VTH1, 0, {0}).tsquash("inconsistent vth2 dac value") == disabledDacValue); + REQUIRE(det.getDAC(defs::VTH2, 0, {0}).tsquash("inconsistent vth2 dac value") == fixedVthDacVal); + REQUIRE(det.getDAC(defs::VTH3, 0, {0}).tsquash("inconsistent vth2 dac value") == disabledDacValue); + } + // interpolation and pump probe + REQUIRE_THROWS(proxy.Call("interpolation", {"1"}, -1, PUT)); + { + // none + std::ostringstream oss; + proxy.Call("pumpprobe", {"0"}, -1, PUT, oss); + REQUIRE(oss.str() == "pumpprobe 0\n"); + REQUIRE(det.getCounterMask().tsquash("inconsistent counter mask") == 7); + REQUIRE(det.getDAC(defs::VTH1, 0, {0}).tsquash("inconsistent vth1 dac value") == (fixedMask[i] & 0x1 ? fixedVthDacVal : disabledDacValue)); + REQUIRE(det.getDAC(defs::VTH2, 0, {0}).tsquash("inconsistent vth2 dac value") == (fixedMask[i] & 0x2 ? fixedVthDacVal : disabledDacValue)); + REQUIRE(det.getDAC(defs::VTH3, 0, {0}).tsquash("inconsistent vth3 dac value") == (fixedMask[i] & 0x4 ? fixedVthDacVal : disabledDacValue)); + } + } { std::ostringstream oss; @@ -549,7 +591,12 @@ TEST_CASE("pumpprobe", "[.cmd]") { REQUIRE(oss.str() == "pumpprobe 0\n"); } for (int i = 0; i != det.size(); ++i) { + det.setCounterMask(prev_mask[i], {i}); det.setPumpProbe(prev_val[i], {i}); + det.setInterpolation(prev_interpolation[i], {i}); + det.setDAC(defs::VTH1, prev_vth1DacVal[i], 0, {i}); + det.setDAC(defs::VTH2, prev_vth2DacVal[i], 0, {i}); + det.setDAC(defs::VTH3, prev_vth3DacVal[i], 0, {i}); } } else { REQUIRE_THROWS(proxy.Call("pumpprobe", {}, -1, GET)); diff --git a/slsSupportLib/include/sls/versionAPI.h b/slsSupportLib/include/sls/versionAPI.h index 97ff2a907..8a8bda755 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -10,5 +10,5 @@ #define APIJUNGFRAU 0x220524 #define APIMOENCH 0x220519 #define APIEIGER 0x220524 -#define APIMYTHEN3 0x220602 #define APIGOTTHARD2 0x220602 +#define APIMYTHEN3 0x220607 From 728cb35c378e397c9fabc2d56f2f556531951af2 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil <33750417+thattil@users.noreply.github.com> Date: Wed, 8 Jun 2022 12:03:13 +0200 Subject: [PATCH 2/8] rxMemsize (#479) * changing fifo header size to 16 to fix the rxr header (112) to be a power of 2 to make it more efficient and reduce packet loss * release notes --- RELEASE.txt | 1 + slsReceiverSoftware/src/receiver_defs.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/RELEASE.txt b/RELEASE.txt index c23ae55f6..453282ae0 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -79,6 +79,7 @@ This document describes the differences between v7.0.0 and v6.x.x - g2 and m3 clkdiv 2 (system clock) change should affect time settings (g2: exptime, period, delayaftertrigger, burstperiod, m3: exptime, gatedelay, gateperiod, period, delayaftertrigger) - g2 system frequency is the same irrespective of timing source - (apparently) rxr doesnt get stuck anymore from 6.1.1 +- rxr mem size changed (fifo header size from 8 to 16) due to sls rxr header = 112.. 112+ 16=128 (reduces packet losss especially for g2) 2. Resolved Issues ================== diff --git a/slsReceiverSoftware/src/receiver_defs.h b/slsReceiverSoftware/src/receiver_defs.h index e65623e90..884005593 100644 --- a/slsReceiverSoftware/src/receiver_defs.h +++ b/slsReceiverSoftware/src/receiver_defs.h @@ -37,7 +37,7 @@ namespace sls { #define FILE_BUFFER_SIZE (16 * 1024 * 1024) // 16mb // fifo -#define FIFO_HEADER_NUMBYTES (8) +#define FIFO_HEADER_NUMBYTES (16) #define FIFO_DATASIZE_NUMBYTES (4) #define FIFO_PADDING_NUMBYTES \ (4) // for 8 byte alignment due to sls_receiver_header structure From 364e0c6268d9dff73d8c6ddec9bc8c2863586d1b Mon Sep 17 00:00:00 2001 From: Dhanya Thattil <33750417+thattil@users.noreply.github.com> Date: Wed, 8 Jun 2022 12:26:49 +0200 Subject: [PATCH 3/8] Udp srcip auto (#480) * able to set udp_srcip and udp_srcip2 to auto * minor * minor --- RELEASE.txt | 1 + slsDetectorSoftware/src/CmdProxy.cpp | 66 ++++++++++++++++++++++++++++ slsDetectorSoftware/src/CmdProxy.h | 19 ++------ 3 files changed, 71 insertions(+), 15 deletions(-) diff --git a/RELEASE.txt b/RELEASE.txt index 453282ae0..eacad4e01 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -80,6 +80,7 @@ This document describes the differences between v7.0.0 and v6.x.x - g2 system frequency is the same irrespective of timing source - (apparently) rxr doesnt get stuck anymore from 6.1.1 - rxr mem size changed (fifo header size from 8 to 16) due to sls rxr header = 112.. 112+ 16=128 (reduces packet losss especially for g2) +-udp_srcip and udp_Srcip2: can set to auto (for virtual or 1g data networks) 2. Resolved Issues ================== diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index 70546879c..d8fbd42ce 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -1539,6 +1539,72 @@ std::string CmdProxy::UDPDestinationList(int action) { return os.str(); } +std::string CmdProxy::UDPSourceIP(int action) { + std::ostringstream os; + os << cmd << ' '; + if (action == defs::HELP_ACTION) { + os << "[x.x.x.x] or auto\n\tIp address of the detector (source) udp interface. Must be same subnet as destination udp ip.\n\t[Eiger] Set only for 10G. For 1G, detector will replace with its own DHCP IP address. If 'auto' used, then ip is set to ip of rx_hostname." + << '\n'; + } else if (action == defs::GET_ACTION) { + auto t = det->getSourceUDPIP(std::vector{det_id}); + if (!args.empty()) { + WrongNumberOfParameters(0); + } + os << OutString(t) << '\n'; + } else if (action == defs::PUT_ACTION) { + if (args.size() != 1) { + WrongNumberOfParameters(1); + } + IpAddr val; + if (args[0] == "auto") { + val = getIpFromAuto(); + LOG(logINFO) << "Setting udp_srcip of detector " << det_id << " to " + << val; + } else { + val = IpAddr(args[0]); + } + det->setSourceUDPIP(val, std::vector{det_id}); + os << val << '\n'; + + } else { + throw RuntimeError("Unknown action"); + } + return os.str(); +} + +std::string CmdProxy::UDPSourceIP2(int action) { + std::ostringstream os; + os << cmd << ' '; + if (action == defs::HELP_ACTION) { + os << "[x.x.x.x] or auto\n\t[Jungfrau][Gotthard2] Ip address of the detector (source) udp interface 2. Must be same subnet as destination udp ip2.\n\t [Jungfrau] top half or inner interface\n\t [Gotthard2] veto debugging. If 'auto' used, then ip is set to ip of rx_hostname." + << '\n'; + } else if (action == defs::GET_ACTION) { + auto t = det->getSourceUDPIP2(std::vector{det_id}); + if (!args.empty()) { + WrongNumberOfParameters(0); + } + os << OutString(t) << '\n'; + } else if (action == defs::PUT_ACTION) { + if (args.size() != 1) { + WrongNumberOfParameters(1); + } + IpAddr val; + if (args[0] == "auto") { + val = getIpFromAuto(); + LOG(logINFO) << "Setting udp_srcip2 of detector " << det_id << " to " + << val; + } else { + val = IpAddr(args[0]); + } + det->setSourceUDPIP2(val, std::vector{det_id}); + os << val << '\n'; + + } else { + throw RuntimeError("Unknown action"); + } + return os.str(); +} + std::string CmdProxy::UDPDestinationIP(int action) { std::ostringstream os; os << cmd << ' '; diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index be90dd5eb..5a9f99553 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -877,8 +877,8 @@ class CmdProxy { {"udp_numdst", &CmdProxy::udp_numdst}, {"udp_cleardst", &CmdProxy::udp_cleardst}, {"udp_firstdst", &CmdProxy::udp_firstdst}, - {"udp_srcip", &CmdProxy::udp_srcip}, - {"udp_srcip2", &CmdProxy::udp_srcip2}, + {"udp_srcip", &CmdProxy::UDPSourceIP}, + {"udp_srcip2", &CmdProxy::UDPSourceIP2}, {"udp_dstip", &CmdProxy::UDPDestinationIP}, {"udp_dstip2", &CmdProxy::UDPDestinationIP2}, {"udp_srcmac", &CmdProxy::udp_srcmac}, @@ -1148,6 +1148,8 @@ class CmdProxy { IpAddr getIpFromAuto(); UdpDestination getUdpEntry(); std::string UDPDestinationList(int action); + std::string UDPSourceIP(int action); + std::string UDPSourceIP2(int action); std::string UDPDestinationIP(int action); std::string UDPDestinationIP2(int action); /* Receiver Config */ @@ -1597,19 +1599,6 @@ class CmdProxy { "out from in a round robin fashion. The entry must not have been " "empty. Default: 0"); - INTEGER_COMMAND_VEC_ID( - udp_srcip, getSourceUDPIP, setSourceUDPIP, IpAddr, - "[x.x.x.x]\n\tIp address of the detector (source) udp " - "interface. Must be same subnet as destination udp " - "ip.\n\t[Eiger] Set only for 10G. For 1G, detector will " - "replace with its own DHCP IP address."); - - INTEGER_COMMAND_VEC_ID( - udp_srcip2, getSourceUDPIP2, setSourceUDPIP2, IpAddr, - "[x.x.x.x]\n\t[Jungfrau][Gotthard2] Ip address of the detector " - "(source) udp interface 2. Must be same subnet as destination udp " - "ip2.\n\t [Jungfrau] top half or inner interface\n\t [Gotthard2] veto " - "debugging."); INTEGER_COMMAND_VEC_ID( udp_srcmac, getSourceUDPMAC, setSourceUDPMAC, MacAddr, From 3cee36a3dba778e34c7d87a64d1c22922789be11 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil <33750417+thattil@users.noreply.github.com> Date: Wed, 8 Jun 2022 17:06:08 +0200 Subject: [PATCH 4/8] gui hv moved to settings tab from developer tab, allowed also for eiger (#482) --- slsDetectorGui/forms/form_tab_developer.ui | 156 +++-------------- slsDetectorGui/forms/form_tab_settings.ui | 188 +++++++++++++++++---- slsDetectorGui/include/qTabDeveloper.h | 9 - slsDetectorGui/include/qTabSettings.h | 8 + slsDetectorGui/src/qTabDeveloper.cpp | 91 ---------- slsDetectorGui/src/qTabSettings.cpp | 116 +++++++++++++ 6 files changed, 296 insertions(+), 272 deletions(-) diff --git a/slsDetectorGui/forms/form_tab_developer.ui b/slsDetectorGui/forms/form_tab_developer.ui index e16e86287..7a0140d97 100755 --- a/slsDetectorGui/forms/form_tab_developer.ui +++ b/slsDetectorGui/forms/form_tab_developer.ui @@ -32,17 +32,29 @@ Form - - + + - - 0 + + 5 0 - - Readout: + + 1 + + + DACs + + + + + + ADCs + + + @@ -77,145 +89,19 @@ - - + + 0 0 - - <html><head/><body><p>High Voltage</p><p> #highvoltage#</p></body></html> - - High Voltage: + Readout: - - - - - 0 - 0 - - - - - 0 - 28 - - - - <html><head/><body><p>High Voltage</p><p> #highvoltage#</p></body></html> - - - - 0 - - - - - 90 - - - - - 110 - - - - - 120 - - - - - 150 - - - - - 180 - - - - - 200 - - - - - - - - - 0 - 0 - - - - <html><head/><body><p>High Voltage. Range: 60 - 200V. Swich off high voltage by setting to 0.</p><p>-1 corresponds to different values from detectors.</p><p>#highvoltage#</p></body></html> - - - High Voltage: - - - - - - - - 0 - 0 - - - - - 0 - 28 - - - - <html><head/><body><p>High Voltage. Range: 60 - 200V. Swich off high voltage by setting to 0.</p><p>-1 corresponds to different values from detectors.</p><p>#highvoltage#</p></body></html> - - - false - - - -1 - - - 200 - - - - - - - - 5 - 0 - - - - 1 - - - - DACs - - - - - - ADCs - - - - - diff --git a/slsDetectorGui/forms/form_tab_settings.ui b/slsDetectorGui/forms/form_tab_settings.ui index 884f9e14e..526e31c72 100755 --- a/slsDetectorGui/forms/form_tab_settings.ui +++ b/slsDetectorGui/forms/form_tab_settings.ui @@ -7,7 +7,7 @@ 0 0 775 - 385 + 400 @@ -32,7 +32,77 @@ Form - + + + + + 0 + 0 + + + + + 140 + 28 + + + + <html><head/><body><p>High Voltage</p><p> #highvoltage#</p></body></html> + + + + 0 + + + + + 90 + + + + + 110 + + + + + 120 + + + + + 150 + + + + + 180 + + + + + 200 + + + + + + + + + 0 + 0 + + + + <html><head/><body><p>High Voltage</p><p> #highvoltage#</p></body></html> + + + High Voltage: + + + + false @@ -54,7 +124,7 @@ - + false @@ -73,7 +143,7 @@ - + Qt::Horizontal @@ -89,7 +159,7 @@ - + true @@ -111,7 +181,7 @@ - + false @@ -130,7 +200,7 @@ - + true @@ -144,7 +214,7 @@ 140 - 25 + 28 @@ -269,7 +339,7 @@ - + false @@ -306,7 +376,7 @@ - + true @@ -381,7 +451,7 @@ - + Qt::Horizontal @@ -397,7 +467,7 @@ - + false @@ -434,7 +504,23 @@ - + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 190 + + + + + false @@ -471,7 +557,7 @@ - + false @@ -493,7 +579,7 @@ - + false @@ -515,23 +601,7 @@ - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 190 - - - - - + false @@ -553,7 +623,7 @@ - + false @@ -561,7 +631,7 @@ 140 - 25 + 28 @@ -597,7 +667,7 @@ - + false @@ -616,7 +686,7 @@ - + false @@ -630,7 +700,7 @@ 140 - 25 + 28 @@ -674,6 +744,50 @@ + + + + + 0 + 0 + + + + <html><head/><body><p>High Voltage. Range: 60 - 200V. Swich off high voltage by setting to 0.</p><p>-1 corresponds to different values from detectors.</p><p>#highvoltage#</p></body></html> + + + High Voltage: + + + + + + + + 0 + 0 + + + + + 140 + 28 + + + + <html><head/><body><p>High Voltage. Range: 60 - 200V. Swich off high voltage by setting to 0.</p><p>-1 corresponds to different values from detectors.</p><p>#highvoltage#</p></body></html> + + + false + + + -1 + + + 200 + + + diff --git a/slsDetectorGui/include/qTabDeveloper.h b/slsDetectorGui/include/qTabDeveloper.h index 90b3da3cd..c672bc69f 100644 --- a/slsDetectorGui/include/qTabDeveloper.h +++ b/slsDetectorGui/include/qTabDeveloper.h @@ -20,25 +20,16 @@ class qTabDeveloper : public QWidget, private Ui::TabDeveloperObject { public slots: void Refresh(); - private slots: - void SetHighVoltage(); - private: void SetupWidgetWindow(); void Initialization(); void PopulateDetectors(); - void GetHighVoltage(); slsDetectorDefs::dacIndex getSLSIndex(slsDetectorDefs::detectorType detType, int index); Detector *det; std::vector dacWidgets; std::vector adcWidgets; - - enum hvVals { HV_0, HV_90, HV_110, HV_120, HV_150, HV_180, HV_200 }; - int hvmin; - static const int HV_MIN = 60; - static const int HV_MAX = 200; }; } // namespace sls diff --git a/slsDetectorGui/include/qTabSettings.h b/slsDetectorGui/include/qTabSettings.h index ef0997c91..6e70b9377 100644 --- a/slsDetectorGui/include/qTabSettings.h +++ b/slsDetectorGui/include/qTabSettings.h @@ -18,6 +18,7 @@ class qTabSettings : public QWidget, private Ui::TabSettingsObject { void SetExportMode(bool exportMode); private slots: + void SetHighVoltage(); void SetSettings(int index); void SetGainMode(int index); void SetDynamicRange(int index); @@ -32,6 +33,7 @@ class qTabSettings : public QWidget, private Ui::TabSettingsObject { void ShowFixG0(bool expertMode); void Initialization(); + void GetHighVoltage(); void GetSettings(); void GetGainMode(); void GetDynamicRange(); @@ -42,6 +44,12 @@ class qTabSettings : public QWidget, private Ui::TabSettingsObject { Detector *det; std::vector counters; + enum hvVals { HV_0, HV_90, HV_110, HV_120, HV_150, HV_180, HV_200 }; + + int hvmin; + static const int HV_MIN = 60; + static const int HV_MAX = 200; + enum { STANDARD, FAST, diff --git a/slsDetectorGui/src/qTabDeveloper.cpp b/slsDetectorGui/src/qTabDeveloper.cpp index c8ee4be6e..7fb6cfdfc 100644 --- a/slsDetectorGui/src/qTabDeveloper.cpp +++ b/slsDetectorGui/src/qTabDeveloper.cpp @@ -18,12 +18,6 @@ qTabDeveloper::~qTabDeveloper() {} void qTabDeveloper::SetupWidgetWindow() { int tempid = 0; - comboHV->hide(); - lblComboHV->hide(); - lblSpinHV->hide(); - spinHV->hide(); - hvmin = HV_MIN; - try { slsDetectorDefs::detectorType detType = det->getDetectorType().squash(); switch (detType) { @@ -84,8 +78,6 @@ void qTabDeveloper::SetupWidgetWindow() { break; case slsDetectorDefs::GOTTHARD: - comboHV->show(); - lblComboHV->show(); dacWidgets.push_back(new qDacWidget( this, det, true, "v Reference: ", getSLSIndex(detType, tempid++))); @@ -119,8 +111,6 @@ void qTabDeveloper::SetupWidgetWindow() { break; case slsDetectorDefs::JUNGFRAU: - lblSpinHV->show(); - spinHV->show(); dacWidgets.push_back( new qDacWidget(this, det, true, "v vb comp: ", getSLSIndex(detType, tempid++))); @@ -150,8 +140,6 @@ void qTabDeveloper::SetupWidgetWindow() { break; case slsDetectorDefs::MOENCH: - lblSpinHV->show(); - spinHV->show(); dacWidgets.push_back( new qDacWidget(this, det, true, "vbp_colbuf: ", getSLSIndex(detType, tempid++))); @@ -175,9 +163,6 @@ void qTabDeveloper::SetupWidgetWindow() { break; case slsDetectorDefs::MYTHEN3: - lblSpinHV->show(); - spinHV->show(); - hvmin = 0; dacWidgets.push_back(new qDacWidget( this, det, true, "vcassh: ", getSLSIndex(detType, tempid++))); dacWidgets.push_back(new qDacWidget( @@ -218,9 +203,6 @@ void qTabDeveloper::SetupWidgetWindow() { break; case slsDetectorDefs::GOTTHARD2: - lblSpinHV->show(); - spinHV->show(); - hvmin = 0; dacWidgets.push_back( new qDacWidget(this, det, true, "vref_h_adc: ", getSLSIndex(detType, tempid++))); @@ -292,9 +274,6 @@ void qTabDeveloper::SetupWidgetWindow() { void qTabDeveloper::Initialization() { connect(comboDetector, SIGNAL(currentIndexChanged(int)), this, SLOT(Refresh())); - connect(comboHV, SIGNAL(currentIndexChanged(int)), this, - SLOT(SetHighVoltage())); - connect(spinHV, SIGNAL(valueChanged(int)), this, SLOT(SetHighVoltage())); } void qTabDeveloper::PopulateDetectors() { @@ -311,75 +290,6 @@ void qTabDeveloper::PopulateDetectors() { comboDetector->setCurrentIndex(0); } -void qTabDeveloper::GetHighVoltage() { - // not enabled for eiger - if (!comboHV->isVisible() && !spinHV->isVisible()) - return; - LOG(logDEBUG) << "Getting High Voltage"; - disconnect(spinHV, SIGNAL(valueChanged(int)), this, SLOT(SetHighVoltage())); - disconnect(comboHV, SIGNAL(currentIndexChanged(int)), this, - SLOT(SetHighVoltage())); - try { - // dac units - auto retval = det->getHighVoltage({comboDetector->currentIndex() - 1}) - .tsquash("Inconsistent values for high voltage."); - // spinHV - if (spinHV->isVisible()) { - if (retval != 0 && retval < hvmin && retval > HV_MAX) { - throw RuntimeError(std::string("Unknown High Voltage: ") + - std::to_string(retval)); - } - spinHV->setValue(retval); - } - // combo HV - else { - switch (retval) { - case 0: - comboHV->setCurrentIndex(HV_0); - break; - case 90: - comboHV->setCurrentIndex(HV_90); - break; - case 110: - comboHV->setCurrentIndex(HV_110); - break; - case 120: - comboHV->setCurrentIndex(HV_120); - break; - case 150: - comboHV->setCurrentIndex(HV_150); - break; - case 180: - comboHV->setCurrentIndex(HV_180); - break; - case 200: - comboHV->setCurrentIndex(HV_200); - break; - default: - throw RuntimeError(std::string("Unknown High Voltage: ") + - std::to_string(retval)); - } - } - } - CATCH_DISPLAY("Could not get high voltage.", - "qTabDeveloper::GetHighVoltage") - connect(spinHV, SIGNAL(valueChanged(int)), this, SLOT(SetHighVoltage())); - connect(comboHV, SIGNAL(currentIndexChanged(int)), this, - SLOT(SetHighVoltage())); -} - -void qTabDeveloper::SetHighVoltage() { - int val = (comboHV->isVisible() ? comboHV->currentText().toInt() - : spinHV->value()); - LOG(logINFO) << "Setting high voltage:" << val; - - try { - det->setHighVoltage({comboDetector->currentIndex() - 1}); - } - CATCH_HANDLE("Could not set high voltage.", "qTabDeveloper::SetHighVoltage", - this, &qTabDeveloper::GetHighVoltage) -} - slsDetectorDefs::dacIndex qTabDeveloper::getSLSIndex(slsDetectorDefs::detectorType detType, int index) { switch (detType) { @@ -606,7 +516,6 @@ void qTabDeveloper::Refresh() { for (const auto &it : adcWidgets) { it->SetDetectorIndex(comboDetector->currentIndex() - 1); } - GetHighVoltage(); LOG(logDEBUG) << "**Updated Developer Tab"; } diff --git a/slsDetectorGui/src/qTabSettings.cpp b/slsDetectorGui/src/qTabSettings.cpp index 23a9f28d6..91f758f28 100644 --- a/slsDetectorGui/src/qTabSettings.cpp +++ b/slsDetectorGui/src/qTabSettings.cpp @@ -19,6 +19,12 @@ qTabSettings::~qTabSettings() {} void qTabSettings::SetupWidgetWindow() { + comboHV->hide(); + lblComboHV->hide(); + lblSpinHV->hide(); + spinHV->hide(); + hvmin = HV_MIN; + counters = std::vector{chkCounter1, chkCounter2, chkCounter3}; spinThreshold2->hide(); @@ -37,6 +43,9 @@ void qTabSettings::SetupWidgetWindow() { // enabling according to det type slsDetectorDefs::detectorType detType = det->getDetectorType().squash(); if (detType == slsDetectorDefs::MYTHEN3) { + lblSpinHV->show(); + spinHV->show(); + hvmin = 0; lblDynamicRange->setEnabled(true); comboDynamicRange->setEnabled(true); @@ -77,13 +86,28 @@ void qTabSettings::SetupWidgetWindow() { } } } else if (detType == slsDetectorDefs::EIGER) { + lblSpinHV->show(); + spinHV->show(); + hvmin = 0; lblDynamicRange->setEnabled(true); comboDynamicRange->setEnabled(true); lblThreshold->setEnabled(true); spinThreshold->setEnabled(true); } else if (detType == slsDetectorDefs::JUNGFRAU) { + lblSpinHV->show(); + spinHV->show(); lblGainMode->setEnabled(true); comboGainMode->setEnabled(true); + } else if (detType == slsDetectorDefs::GOTTHARD) { + comboHV->show(); + lblComboHV->show(); + } else if (detType == slsDetectorDefs::MOENCH) { + lblSpinHV->show(); + spinHV->show(); + } else if (detType == slsDetectorDefs::GOTTHARD2) { + lblSpinHV->show(); + spinHV->show(); + hvmin = 0; } // default settings for the disabled @@ -165,6 +189,11 @@ void qTabSettings::ShowFixG0(bool expertMode) { } void qTabSettings::Initialization() { + // High voltage + connect(comboHV, SIGNAL(currentIndexChanged(int)), this, + SLOT(SetHighVoltage())); + connect(spinHV, SIGNAL(valueChanged(int)), this, SLOT(SetHighVoltage())); + // Settings if (comboSettings->isEnabled()) connect(comboSettings, SIGNAL(currentIndexChanged(int)), this, @@ -201,6 +230,91 @@ void qTabSettings::Initialization() { } } +void qTabSettings::GetHighVoltage() { + // not enabled for eiger + if (!comboHV->isVisible() && !spinHV->isVisible()) + return; + LOG(logDEBUG) << "Getting High Voltage"; + disconnect(spinHV, SIGNAL(valueChanged(int)), this, SLOT(SetHighVoltage())); + disconnect(comboHV, SIGNAL(currentIndexChanged(int)), this, + SLOT(SetHighVoltage())); + try { + Result retvals = det->getHighVoltage(); + + int retval = 0; + if (det->getDetectorType().squash() != slsDetectorDefs::EIGER) { + retval = retvals.tsquash("Inconsistent values for high voltage."); + } + // eiger slaves return -999 + else { + + auto is_master = det->getMaster(); + Result master_retvals; + for (size_t i = 0; i != retvals.size(); ++i) { + if (is_master[i]) { + master_retvals.push_back(retvals[i]); + } + } + retval = master_retvals.tsquash("Inconsistent values for high voltage."); + } + + // spinHV + if (spinHV->isVisible()) { + if (retval != 0 && retval < hvmin && retval > HV_MAX) { + throw RuntimeError(std::string("Unknown High Voltage: ") + + std::to_string(retval)); + } + spinHV->setValue(retval); + } + // combo HV + else { + switch (retval) { + case 0: + comboHV->setCurrentIndex(HV_0); + break; + case 90: + comboHV->setCurrentIndex(HV_90); + break; + case 110: + comboHV->setCurrentIndex(HV_110); + break; + case 120: + comboHV->setCurrentIndex(HV_120); + break; + case 150: + comboHV->setCurrentIndex(HV_150); + break; + case 180: + comboHV->setCurrentIndex(HV_180); + break; + case 200: + comboHV->setCurrentIndex(HV_200); + break; + default: + throw RuntimeError(std::string("Unknown High Voltage: ") + + std::to_string(retval)); + } + } + } + CATCH_DISPLAY("Could not get high voltage.", + "qTabSettings::GetHighVoltage") + connect(spinHV, SIGNAL(valueChanged(int)), this, SLOT(SetHighVoltage())); + connect(comboHV, SIGNAL(currentIndexChanged(int)), this, + SLOT(SetHighVoltage())); +} + +void qTabSettings::SetHighVoltage() { + int val = (comboHV->isVisible() ? comboHV->currentText().toInt() + : spinHV->value()); + LOG(logINFO) << "Setting high voltage:" << val; + + try { + det->setHighVoltage(val); + } + CATCH_HANDLE("Could not set high voltage.", "qTabSettings::SetHighVoltage", + this, &qTabSettings::GetHighVoltage) +} + void qTabSettings::GetSettings() { LOG(logDEBUG) << "Getting settings"; disconnect(comboSettings, SIGNAL(currentIndexChanged(int)), this, @@ -472,6 +586,8 @@ void qTabSettings::SetCounterMask() { void qTabSettings::Refresh() { LOG(logDEBUG) << "**Updating Settings Tab"; + GetHighVoltage(); + if (comboSettings->isEnabled()) { GetSettings(); } From 89aa0760c6222f15dbf5b8104eee4d874d0daaa0 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil <33750417+thattil@users.noreply.github.com> Date: Thu, 9 Jun 2022 11:42:32 +0200 Subject: [PATCH 5/8] Hdf5fix (#483) * hdf5 fix for string reference * fix hdf5 compilation after namespace change --- slsReceiverSoftware/src/DataProcessor.cpp | 4 +- slsReceiverSoftware/src/File.h | 15 +- slsReceiverSoftware/src/HDF5DataFile.cpp | 82 ++-- slsReceiverSoftware/src/HDF5DataFile.h | 18 +- slsReceiverSoftware/src/MasterAttributes.cpp | 430 +++++++++--------- slsReceiverSoftware/src/MasterAttributes.h | 82 ++-- slsReceiverSoftware/src/MasterFileUtility.cpp | 104 ++--- slsReceiverSoftware/src/MasterFileUtility.h | 22 +- 8 files changed, 376 insertions(+), 381 deletions(-) diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index 517f062e5..d5ad4203c 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -211,14 +211,14 @@ void DataProcessor::LinkFileInMaster(const std::string &masterFileName, if (receiverRoiEnabled_) { throw std::runtime_error("Should not be here, roi with hdf5 virtual should throw."); } - std::string fname{virtualFileName}, datasetName{virtualDatasetName}; + std::string fname{virtualFileName}, datasetName{virtualDatasetName}, masterfname{masterFileName}; // if no virtual file, link data file if (virtualFileName.empty()) { auto res = dataFile_->GetFileAndDatasetName(); fname = res[0]; datasetName = res[1]; } - masterFileUtility::LinkHDF5FileInMaster(masterFileName, fname, datasetName, + masterFileUtility::LinkHDF5FileInMaster(masterfname, fname, datasetName, dataFile_->GetParameterNames(), silentMode, hdf5LibMutex); } diff --git a/slsReceiverSoftware/src/File.h b/slsReceiverSoftware/src/File.h index c9cebb276..259bfb1e7 100644 --- a/slsReceiverSoftware/src/File.h +++ b/slsReceiverSoftware/src/File.h @@ -7,15 +7,12 @@ #include -namespace sls { - #ifdef HDF5C #include "H5Cpp.h" -#ifndef H5_NO_NAMESPACE -using namespace H5; -#endif #endif +namespace sls { + struct MasterAttributes; class File : private virtual slsDetectorDefs { @@ -42,10 +39,10 @@ class File : private virtual slsDetectorDefs { return 0; }; - virtual DataType GetPDataType() const { + virtual H5::DataType GetPDataType() const { LOG(logERROR) << "This is a generic function GetPDataType that " "should be overloaded by a derived class"; - return PredType::STD_U16LE; + return H5::PredType::STD_U16LE; } virtual std::vector GetParameterNames() const { @@ -55,11 +52,11 @@ class File : private virtual slsDetectorDefs { return std::vector{}; }; - virtual std::vector GetParameterDataTypes() const { + virtual std::vector GetParameterDataTypes() const { LOG(logERROR) << "This is a generic function GetFilesInAcquisition that " "should be overloaded by a derived class"; - return std::vector{}; + return std::vector{}; }; virtual void CreateFirstHDF5DataFile( diff --git a/slsReceiverSoftware/src/HDF5DataFile.cpp b/slsReceiverSoftware/src/HDF5DataFile.cpp index 2d30b90c3..a3885f705 100644 --- a/slsReceiverSoftware/src/HDF5DataFile.cpp +++ b/slsReceiverSoftware/src/HDF5DataFile.cpp @@ -26,13 +26,13 @@ HDF5DataFile::HDF5DataFile(int index, std::mutex *hdf5Lib) "detector header version", "packets caught bit mask", }; - StrType strdatatype(PredType::C_S1, sizeof(bitset_storage)); - parameterDataTypes_ = std::vector{ - 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}; + ::H5::StrType strdatatype(::H5::PredType::C_S1, sizeof(bitset_storage)); + parameterDataTypes_ = std::vector<::H5::DataType>{ + ::H5::PredType::STD_U64LE, ::H5::PredType::STD_U32LE, ::H5::PredType::STD_U32LE, + ::H5::PredType::STD_U64LE, ::H5::PredType::STD_U64LE, ::H5::PredType::STD_U16LE, + ::H5::PredType::STD_U16LE, ::H5::PredType::STD_U16LE, ::H5::PredType::STD_U16LE, + ::H5::PredType::STD_U32LE, ::H5::PredType::STD_U16LE, ::H5::PredType::STD_U8LE, + ::H5::PredType::STD_U8LE, strdatatype}; } HDF5DataFile::~HDF5DataFile() { CloseFile(); } @@ -45,25 +45,25 @@ uint32_t HDF5DataFile::GetFilesInAcquisition() const { return numFilesInAcquisition_; } -DataType HDF5DataFile::GetPDataType() const { return dataType_; } +::H5::DataType HDF5DataFile::GetPDataType() const { return dataType_; } std::vector HDF5DataFile::GetParameterNames() const { return parameterNames_; } -std::vector HDF5DataFile::GetParameterDataTypes() const { +std::vector<::H5::DataType> HDF5DataFile::GetParameterDataTypes() const { return parameterDataTypes_; } void HDF5DataFile::CloseFile() { std::lock_guard lock(*hdf5Lib_); try { - Exception::dontPrint(); // to handle errors + ::H5::Exception::dontPrint(); // to handle errors if (fd_) { fd_->close(); delete fd_; fd_ = nullptr; } - } catch (const Exception &error) { + } catch (const ::H5::Exception &error) { LOG(logERROR) << "Could not close data HDF5 handles of index " << index_; error.printErrorStack(); @@ -116,13 +116,13 @@ void HDF5DataFile::CreateFirstHDF5DataFile( switch (dynamicRange_) { case 12: case 16: - dataType_ = PredType::STD_U16LE; + dataType_ = ::H5::PredType::STD_U16LE; break; case 32: - dataType_ = PredType::STD_U32LE; + dataType_ = ::H5::PredType::STD_U32LE; break; default: - dataType_ = PredType::STD_U8LE; + dataType_ = ::H5::PredType::STD_U8LE; break; } @@ -153,31 +153,31 @@ void HDF5DataFile::CreateFile() { uint32_t nDimz = ((dynamicRange_ == 4) ? (nPixelsX_ / 2) : nPixelsX_); try { - Exception::dontPrint(); // to handle errors + ::H5::Exception::dontPrint(); // to handle errors // file - FileAccPropList fapl; + ::H5::FileAccPropList fapl; fapl.setFcloseDegree(H5F_CLOSE_STRONG); fd_ = nullptr; if (!overWriteEnable_) - fd_ = new H5File(fileName_.c_str(), H5F_ACC_EXCL, - FileCreatPropList::DEFAULT, fapl); + fd_ = new ::H5::H5File(fileName_.c_str(), H5F_ACC_EXCL, + ::H5::FileCreatPropList::DEFAULT, fapl); else - fd_ = new H5File(fileName_.c_str(), H5F_ACC_TRUNC, - FileCreatPropList::DEFAULT, fapl); + fd_ = new ::H5::H5File(fileName_.c_str(), H5F_ACC_TRUNC, + ::H5::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); + ::H5::DataSpace dataspace_attr = ::H5::DataSpace(H5S_SCALAR); + ::H5::Attribute attribute = fd_->createAttribute( + "version", ::H5::PredType::NATIVE_DOUBLE, dataspace_attr); + attribute.write(::H5::PredType::NATIVE_DOUBLE, &dValue); // dataspace hsize_t srcdims[3] = {nDimx, nDimy, nDimz}; hsize_t srcdimsmax[3] = {H5S_UNLIMITED, nDimy, nDimz}; dataSpace_ = nullptr; - dataSpace_ = new DataSpace(3, srcdims, srcdimsmax); + dataSpace_ = new ::H5::DataSpace(3, srcdims, srcdimsmax); // dataset name std::ostringstream osfn; @@ -188,7 +188,7 @@ void HDF5DataFile::CreateFile() { // dataset // fill value - DSetCreatPropList plist; + ::H5::DSetCreatPropList plist; int fill_value = -1; plist.setFillValue(dataType_, &fill_value); // always create chunked dataset as unlimited is only @@ -196,28 +196,28 @@ void HDF5DataFile::CreateFile() { hsize_t chunk_dims[3] = {MAX_CHUNKED_IMAGES, nDimy, nDimz}; plist.setChunk(3, chunk_dims); dataSet_ = nullptr; - dataSet_ = new DataSet(fd_->createDataSet( + dataSet_ = new ::H5::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); + dataSpacePara_ = new ::H5::DataSpace(1, dims, dimsmax); // always create chunked dataset as unlimited is only // supported with chunked layout - DSetCreatPropList paralist; + ::H5::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( + ::H5::DataSet *ds = new ::H5::DataSet(fd_->createDataSet( parameterNames_[i].c_str(), parameterDataTypes_[i], *dataSpacePara_, paralist)); dataSetPara_.push_back(ds); } - } catch (const Exception &error) { + } catch (const ::H5::Exception &error) { error.printErrorStack(); CloseFile(); throw RuntimeError("Could not create HDF5 handles in object " + @@ -287,16 +287,16 @@ void HDF5DataFile::WriteDataFile(const uint64_t currentFrameNumber, hsize_t start[3] = {nDimx, 0, 0}; hsize_t dims2[2] = {nDimy, nDimz}; try { - Exception::dontPrint(); // to handle errors + ::H5::Exception::dontPrint(); // to handle errors dataSpace_->selectHyperslab(H5S_SELECT_SET, count, start); - DataSpace memspace(2, dims2); + ::H5::DataSpace memspace(2, dims2); dataSet_->write(revBuffer, dataType_, memspace, *dataSpace_); memspace.close(); if (dynamicRange_ == 12) { free(revBuffer); } - } catch (const Exception &error) { + } catch (const ::H5::Exception &error) { if (dynamicRange_ == 12) { free(revBuffer); } @@ -320,9 +320,9 @@ void HDF5DataFile::WriteParameterDatasets(const uint64_t currentFrameNumber, hsize_t start[1] = {fnum}; int i = 0; try { - Exception::dontPrint(); // to handle errors + ::H5::Exception::dontPrint(); // to handle errors dataSpacePara_->selectHyperslab(H5S_SELECT_SET, count, start); - DataSpace memspace(H5S_SCALAR); + ::H5::DataSpace memspace(H5S_SCALAR); dataSetPara_[0]->write(&header.frameNumber, parameterDataTypes_[0], memspace, *dataSpacePara_); i = 1; @@ -383,7 +383,7 @@ void HDF5DataFile::WriteParameterDatasets(const uint64_t currentFrameNumber, memspace, *dataSpacePara_); } i = 14; - } catch (const Exception &error) { + } catch (const ::H5::Exception &error) { error.printErrorStack(); throw RuntimeError( "Could not write parameters (index:" + std::to_string(i) + @@ -395,7 +395,7 @@ void HDF5DataFile::ExtendDataset() { std::lock_guard lock(*hdf5Lib_); try { - Exception::dontPrint(); // to handle errors + ::H5::Exception::dontPrint(); // to handle errors hsize_t dims[3]; dataSpace_->getSimpleExtentDims(dims); @@ -404,16 +404,16 @@ void HDF5DataFile::ExtendDataset() { dataSet_->extend(dims); delete dataSpace_; dataSpace_ = nullptr; - dataSpace_ = new DataSpace(dataSet_->getSpace()); + dataSpace_ = new ::H5::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()); + dataSpacePara_ = new ::H5::DataSpace(dataSetPara_[0]->getSpace()); - } catch (const Exception &error) { + } catch (const ::H5::Exception &error) { error.printErrorStack(); throw RuntimeError("Could not extend dataset in object " + std::to_string(index_)); diff --git a/slsReceiverSoftware/src/HDF5DataFile.h b/slsReceiverSoftware/src/HDF5DataFile.h index 7c0805ea7..7f2fdb56b 100644 --- a/slsReceiverSoftware/src/HDF5DataFile.h +++ b/slsReceiverSoftware/src/HDF5DataFile.h @@ -16,9 +16,9 @@ class HDF5DataFile : private virtual slsDetectorDefs, public File { std::array GetFileAndDatasetName() const override; uint32_t GetFilesInAcquisition() const override; - DataType GetPDataType() const override; + ::H5::DataType GetPDataType() const override; std::vector GetParameterNames() const override; - std::vector GetParameterDataTypes() const override; + std::vector<::H5::DataType> GetParameterDataTypes() const override; void CloseFile() override; @@ -45,17 +45,17 @@ class HDF5DataFile : private virtual slsDetectorDefs, public File { int index_; std::mutex *hdf5Lib_; - H5File *fd_{nullptr}; + ::H5::H5File *fd_{nullptr}; std::string fileName_; std::string dataSetName_; - DataSpace *dataSpace_{nullptr}; - DataSet *dataSet_{nullptr}; - DataType dataType_{PredType::STD_U16LE}; + ::H5::DataSpace *dataSpace_{nullptr}; + ::H5::DataSet *dataSet_{nullptr}; + ::H5::DataType dataType_{::H5::PredType::STD_U16LE}; - DataSpace *dataSpacePara_{nullptr}; - std::vector dataSetPara_{nullptr}; + ::H5::DataSpace *dataSpacePara_{nullptr}; + std::vector<::H5::DataSet *> dataSetPara_{nullptr}; std::vector parameterNames_; - std::vector parameterDataTypes_; + std::vector<::H5::DataType> parameterDataTypes_; uint32_t subFileIndex_{0}; uint32_t numFramesInFile_{0}; diff --git a/slsReceiverSoftware/src/MasterAttributes.cpp b/slsReceiverSoftware/src/MasterAttributes.cpp index 8de7e2f9c..b39921f4a 100644 --- a/slsReceiverSoftware/src/MasterAttributes.cpp +++ b/slsReceiverSoftware/src/MasterAttributes.cpp @@ -1,6 +1,8 @@ // SPDX-License-Identifier: LGPL-3.0-or-other // Copyright (C) 2021 Contributors to the SLS Detector Package #include "MasterAttributes.h" +#include + namespace sls { @@ -39,7 +41,7 @@ void MasterAttributes::GetBinaryAttributes( } #ifdef HDF5C -void MasterAttributes::WriteHDF5Attributes(H5File *fd, Group *group) { +void MasterAttributes::WriteHDF5Attributes(::H5::H5File *fd, ::H5::Group *group) { WriteCommonHDF5Attributes(fd, group); switch (detType) { case slsDetectorDefs::GOTTHARD: @@ -167,40 +169,40 @@ void MasterAttributes::GetFinalBinaryAttributes( } #ifdef HDF5C -void MasterAttributes::WriteCommonHDF5Attributes(H5File *fd, Group *group) { +void MasterAttributes::WriteCommonHDF5Attributes(::H5::H5File *fd, ::H5::Group *group) { char c[1024]{}; // version { double version = BINARY_WRITER_VERSION; - DataSpace dataspace = DataSpace(H5S_SCALAR); - Attribute attribute = - fd->createAttribute("Version", PredType::NATIVE_DOUBLE, dataspace); - attribute.write(PredType::NATIVE_DOUBLE, &version); + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::Attribute attribute = + fd->createAttribute("Version", ::H5::PredType::NATIVE_DOUBLE, dataspace); + attribute.write(::H5::PredType::NATIVE_DOUBLE, &version); } // timestamp { - time_t t = time(nullptr); - StrType strdatatype(PredType::C_S1, 256); - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = + time_t t = std::time(nullptr); + ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = group->createDataSet("Timestamp", strdatatype, dataspace); strcpy_safe(c, std::string(ctime(&t))); dataset.write(c, strdatatype); } // detector type { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); + ::H5::DataSet dataset = group->createDataSet("Detector Type", strdatatype, dataspace); strcpy_safe(c, ToString(detType)); dataset.write(c, strdatatype); } // timing mode { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); + ::H5::DataSet dataset = group->createDataSet("Timing Mode", strdatatype, dataspace); strcpy_safe(c, ToString(timingMode)); dataset.write(c, strdatatype); @@ -208,27 +210,27 @@ void MasterAttributes::WriteCommonHDF5Attributes(H5File *fd, Group *group) { // TODO: make this into an array? // geometry x { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet("Geometry in x axis", - PredType::NATIVE_INT, dataspace); - dataset.write(&geometry.x, PredType::NATIVE_INT); + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = group->createDataSet("Geometry in x axis", + ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&geometry.x, ::H5::PredType::NATIVE_INT); } // geometry y { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet("Geometry in y axis", - PredType::NATIVE_INT, dataspace); - dataset.write(&geometry.y, PredType::NATIVE_INT); + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = group->createDataSet("Geometry in y axis", + ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&geometry.y, ::H5::PredType::NATIVE_INT); } // Image Size { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = - group->createDataSet("Image Size", PredType::NATIVE_INT, dataspace); - dataset.write(&imageSize, PredType::NATIVE_INT); - DataSpace dataspaceAttr = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - Attribute attribute = + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = + group->createDataSet("Image Size", ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&imageSize, ::H5::PredType::NATIVE_INT); + ::H5::DataSpace dataspaceAttr = ::H5::DataSpace(H5S_SCALAR); + ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); + ::H5::Attribute attribute = dataset.createAttribute("Unit", strdatatype, dataspaceAttr); strcpy_safe(c, "bytes"); attribute.write(strdatatype, c); @@ -236,335 +238,335 @@ void MasterAttributes::WriteCommonHDF5Attributes(H5File *fd, Group *group) { // TODO: make this into an array? // npixels x { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet("Number of pixels in x axis", - PredType::NATIVE_INT, dataspace); - dataset.write(&nPixels.x, PredType::NATIVE_INT); + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = group->createDataSet("Number of pixels in x axis", + ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&nPixels.x, ::H5::PredType::NATIVE_INT); } // npixels y { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet("Number of pixels in y axis", - PredType::NATIVE_INT, dataspace); - dataset.write(&nPixels.y, PredType::NATIVE_INT); + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = group->createDataSet("Number of pixels in y axis", + ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&nPixels.y, ::H5::PredType::NATIVE_INT); } // Maximum frames per file { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet("Maximum frames per file", - PredType::NATIVE_INT, dataspace); - dataset.write(&maxFramesPerFile, PredType::NATIVE_INT); + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = group->createDataSet("Maximum frames per file", + ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&maxFramesPerFile, ::H5::PredType::NATIVE_INT); } // Frame Discard Policy { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = group->createDataSet("Frame Discard Policy", + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); + ::H5::DataSet dataset = group->createDataSet("Frame Discard Policy", strdatatype, dataspace); strcpy_safe(c, ToString(frameDiscardMode)); dataset.write(c, strdatatype); } // Frame Padding { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet("Frame Padding", - PredType::NATIVE_INT, dataspace); - dataset.write(&framePadding, PredType::NATIVE_INT); + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = group->createDataSet("Frame Padding", + ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&framePadding, ::H5::PredType::NATIVE_INT); } // Scan Parameters { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); + ::H5::DataSet dataset = group->createDataSet("Scan Parameters", strdatatype, dataspace); strcpy_safe(c, ToString(scanParams)); dataset.write(c, strdatatype); } // Total Frames { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet("Total Frames", - PredType::STD_U64LE, dataspace); - dataset.write(&totalFrames, PredType::STD_U64LE); + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = group->createDataSet("Total Frames", + ::H5::PredType::STD_U64LE, dataspace); + dataset.write(&totalFrames, ::H5::PredType::STD_U64LE); } // Receiver Roi xmin { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet("receiver roi xmin", - PredType::NATIVE_INT, dataspace); - dataset.write(&receiverRoi.xmin, PredType::NATIVE_INT); + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = group->createDataSet("receiver roi xmin", + ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&receiverRoi.xmin, ::H5::PredType::NATIVE_INT); } // Receiver Roi xmax { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet("receiver roi xmax", - PredType::NATIVE_INT, dataspace); - dataset.write(&receiverRoi.xmax, PredType::NATIVE_INT); + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = group->createDataSet("receiver roi xmax", + ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&receiverRoi.xmax, ::H5::PredType::NATIVE_INT); } // Receiver Roi ymin { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet("receiver roi ymin", - PredType::NATIVE_INT, dataspace); - dataset.write(&receiverRoi.ymin, PredType::NATIVE_INT); + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = group->createDataSet("receiver roi ymin", + ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&receiverRoi.ymin, ::H5::PredType::NATIVE_INT); } // Receiver Roi ymax { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet("receiver roi ymax", - PredType::NATIVE_INT, dataspace); - dataset.write(&receiverRoi.ymax, PredType::NATIVE_INT); + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = group->createDataSet("receiver roi ymax", + ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&receiverRoi.ymax, ::H5::PredType::NATIVE_INT); } } -void MasterAttributes::WriteFinalHDF5Attributes(H5File *fd, Group *group) { +void MasterAttributes::WriteFinalHDF5Attributes(::H5::H5File *fd, ::H5::Group *group) { char c[1024]{}; // Total Frames in file { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet("Frames in File", - PredType::STD_U64LE, dataspace); - dataset.write(&framesInFile, PredType::STD_U64LE); + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = group->createDataSet("Frames in File", + ::H5::PredType::STD_U64LE, dataspace); + dataset.write(&framesInFile, ::H5::PredType::STD_U64LE); } // additional json header if (!additionalJsonHeader.empty()) { std::string json = ToString(additionalJsonHeader); - StrType strdatatype(PredType::C_S1, json.length()); - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet("Additional JSON Header", + ::H5::StrType strdatatype(::H5::PredType::C_S1, json.length()); + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = group->createDataSet("Additional JSON Header", strdatatype, dataspace); strcpy_safe(c, ToString(additionalJsonHeader)); dataset.write(c, strdatatype); } } -void MasterAttributes::WriteHDF5Exptime(H5File *fd, Group *group) { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = +void MasterAttributes::WriteHDF5Exptime(::H5::H5File *fd, ::H5::Group *group) { + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); + ::H5::DataSet dataset = group->createDataSet("Exposure Time", strdatatype, dataspace); char c[1024]{}; strcpy_safe(c, ToString(exptime)); dataset.write(c, strdatatype); } -void MasterAttributes::WriteHDF5Period(H5File *fd, Group *group) { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = +void MasterAttributes::WriteHDF5Period(::H5::H5File *fd, ::H5::Group *group) { + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); + ::H5::DataSet dataset = group->createDataSet("Acquisition Period", strdatatype, dataspace); char c[1024]{}; strcpy_safe(c, ToString(period)); dataset.write(c, strdatatype); } -void MasterAttributes::WriteHDF5DynamicRange(H5File *fd, Group *group) { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = - group->createDataSet("Dynamic Range", PredType::NATIVE_INT, dataspace); - dataset.write(&dynamicRange, PredType::NATIVE_INT); - DataSpace dataspaceAttr = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - Attribute attribute = +void MasterAttributes::WriteHDF5DynamicRange(::H5::H5File *fd, ::H5::Group *group) { + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = + group->createDataSet("Dynamic Range", ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&dynamicRange, ::H5::PredType::NATIVE_INT); + ::H5::DataSpace dataspaceAttr = ::H5::DataSpace(H5S_SCALAR); + ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); + ::H5::Attribute attribute = dataset.createAttribute("Unit", strdatatype, dataspaceAttr); char c[1024] = "bits"; attribute.write(strdatatype, c); } -void MasterAttributes::WriteHDF5TenGiga(H5File *fd, Group *group) { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet("Ten Giga Enable", - PredType::NATIVE_INT, dataspace); - dataset.write(&tenGiga, PredType::NATIVE_INT); +void MasterAttributes::WriteHDF5TenGiga(::H5::H5File *fd, ::H5::Group *group) { + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = group->createDataSet("Ten Giga Enable", + ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&tenGiga, ::H5::PredType::NATIVE_INT); } -void MasterAttributes::WriteHDF5ROI(H5File *fd, Group *group) { +void MasterAttributes::WriteHDF5ROI(::H5::H5File *fd, ::H5::Group *group) { // Roi xmin { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = - group->createDataSet("roi xmin", PredType::NATIVE_INT, dataspace); - dataset.write(&detectorRoi.xmin, PredType::NATIVE_INT); + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = + group->createDataSet("roi xmin", ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&detectorRoi.xmin, ::H5::PredType::NATIVE_INT); } // Roi xmax { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = - group->createDataSet("roi xmax", PredType::NATIVE_INT, dataspace); - dataset.write(&detectorRoi.xmax, PredType::NATIVE_INT); + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = + group->createDataSet("roi xmax", ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&detectorRoi.xmax, ::H5::PredType::NATIVE_INT); } } -void MasterAttributes::WriteHDF5NumUDPInterfaces(H5File *fd, Group *group) { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet("Number of UDP Interfaces", - PredType::NATIVE_INT, dataspace); - dataset.write(&numUDPInterfaces, PredType::NATIVE_INT); +void MasterAttributes::WriteHDF5NumUDPInterfaces(::H5::H5File *fd, ::H5::Group *group) { + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = group->createDataSet("Number of UDP Interfaces", + ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&numUDPInterfaces, ::H5::PredType::NATIVE_INT); } -void MasterAttributes::WriteHDF5ReadNRows(H5File *fd, Group *group) { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = - group->createDataSet("Number of rows", PredType::NATIVE_INT, dataspace); - dataset.write(&readNRows, PredType::NATIVE_INT); +void MasterAttributes::WriteHDF5ReadNRows(::H5::H5File *fd, ::H5::Group *group) { + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = + group->createDataSet("Number of rows", ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&readNRows, ::H5::PredType::NATIVE_INT); } -void MasterAttributes::WriteHDF5ThresholdEnergy(H5File *fd, Group *group) { +void MasterAttributes::WriteHDF5ThresholdEnergy(::H5::H5File *fd, ::H5::Group *group) { char c[1024]{}; - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet("Threshold Energy", - PredType::NATIVE_INT, dataspace); - dataset.write(&thresholdEnergyeV, PredType::NATIVE_INT); - DataSpace dataspaceAttr = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - Attribute attribute = + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = group->createDataSet("Threshold Energy", + ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&thresholdEnergyeV, ::H5::PredType::NATIVE_INT); + ::H5::DataSpace dataspaceAttr = ::H5::DataSpace(H5S_SCALAR); + ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); + ::H5::Attribute attribute = dataset.createAttribute("Unit", strdatatype, dataspaceAttr); strcpy_safe(c, "eV"); attribute.write(strdatatype, c); } -void MasterAttributes::WriteHDF5ThresholdEnergies(H5File *fd, Group *group) { +void MasterAttributes::WriteHDF5ThresholdEnergies(::H5::H5File *fd, ::H5::Group *group) { char c[1024]{}; - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 1024); - DataSet dataset = + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::StrType strdatatype(::H5::PredType::C_S1, 1024); + ::H5::DataSet dataset = group->createDataSet("Threshold Energies", strdatatype, dataspace); strcpy_safe(c, ToString(thresholdAllEnergyeV)); dataset.write(c, strdatatype); } -void MasterAttributes::WriteHDF5SubExpTime(H5File *fd, Group *group) { +void MasterAttributes::WriteHDF5SubExpTime(::H5::H5File *fd, ::H5::Group *group) { char c[1024]{}; - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); + ::H5::DataSet dataset = group->createDataSet("Sub Exposure Time", strdatatype, dataspace); strcpy_safe(c, ToString(subExptime)); dataset.write(c, strdatatype); } -void MasterAttributes::WriteHDF5SubPeriod(H5File *fd, Group *group) { +void MasterAttributes::WriteHDF5SubPeriod(::H5::H5File *fd, ::H5::Group *group) { char c[1024]{}; - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); + ::H5::DataSet dataset = group->createDataSet("Sub Period", strdatatype, dataspace); strcpy_safe(c, ToString(subPeriod)); dataset.write(c, strdatatype); } -void MasterAttributes::WriteHDF5SubQuad(H5File *fd, Group *group) { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = - group->createDataSet("Quad", PredType::NATIVE_INT, dataspace); - dataset.write(&quad, PredType::NATIVE_INT); +void MasterAttributes::WriteHDF5SubQuad(::H5::H5File *fd, ::H5::Group *group) { + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = + group->createDataSet("Quad", ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&quad, ::H5::PredType::NATIVE_INT); } -void MasterAttributes::WriteHDF5RateCorrections(H5File *fd, Group *group) { +void MasterAttributes::WriteHDF5RateCorrections(::H5::H5File *fd, ::H5::Group *group) { char c[1024]{}; - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 1024); - DataSet dataset = + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::StrType strdatatype(::H5::PredType::C_S1, 1024); + ::H5::DataSet dataset = group->createDataSet("Rate Corrections", strdatatype, dataspace); strcpy_safe(c, ToString(ratecorr)); dataset.write(c, strdatatype); } -void MasterAttributes::WriteHDF5CounterMask(H5File *fd, Group *group) { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = - group->createDataSet("Counter Mask", PredType::STD_U32LE, dataspace); - dataset.write(&counterMask, PredType::STD_U32LE); +void MasterAttributes::WriteHDF5CounterMask(::H5::H5File *fd, ::H5::Group *group) { + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = + group->createDataSet("Counter Mask", ::H5::PredType::STD_U32LE, dataspace); + dataset.write(&counterMask, ::H5::PredType::STD_U32LE); } -void MasterAttributes::WriteHDF5ExptimeArray(H5File *fd, Group *group) { +void MasterAttributes::WriteHDF5ExptimeArray(::H5::H5File *fd, ::H5::Group *group) { for (int i = 0; i != 3; ++i) { char c[1024]{}; - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); + ::H5::DataSet dataset = group->createDataSet("Exposure Time1", strdatatype, dataspace); strcpy_safe(c, ToString(exptimeArray[i])); dataset.write(c, strdatatype); } } -void MasterAttributes::WriteHDF5GateDelayArray(H5File *fd, Group *group) { +void MasterAttributes::WriteHDF5GateDelayArray(::H5::H5File *fd, ::H5::Group *group) { for (int i = 0; i != 3; ++i) { char c[1024]{}; - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); + ::H5::DataSet dataset = group->createDataSet("Gate Delay1", strdatatype, dataspace); strcpy_safe(c, ToString(gateDelayArray[i])); dataset.write(c, strdatatype); } } -void MasterAttributes::WriteHDF5Gates(H5File *fd, Group *group) { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = - group->createDataSet("Gates", PredType::STD_U32LE, dataspace); - dataset.write(&gates, PredType::STD_U32LE); +void MasterAttributes::WriteHDF5Gates(::H5::H5File *fd, ::H5::Group *group) { + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = + group->createDataSet("Gates", ::H5::PredType::STD_U32LE, dataspace); + dataset.write(&gates, ::H5::PredType::STD_U32LE); } -void MasterAttributes::WriteHDF5BurstMode(H5File *fd, Group *group) { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = +void MasterAttributes::WriteHDF5BurstMode(::H5::H5File *fd, ::H5::Group *group) { + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); + ::H5::DataSet dataset = group->createDataSet("Burst Mode", strdatatype, dataspace); char c[1024]{}; strcpy_safe(c, ToString(burstMode)); dataset.write(c, strdatatype); } -void MasterAttributes::WriteHDF5AdcMask(H5File *fd, Group *group) { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = - group->createDataSet("ADC Mask", PredType::NATIVE_INT, dataspace); - dataset.write(&adcmask, PredType::NATIVE_INT); +void MasterAttributes::WriteHDF5AdcMask(::H5::H5File *fd, ::H5::Group *group) { + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = + group->createDataSet("ADC Mask", ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&adcmask, ::H5::PredType::NATIVE_INT); } -void MasterAttributes::WriteHDF5AnalogFlag(H5File *fd, Group *group) { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = - group->createDataSet("Analog Flag", PredType::NATIVE_INT, dataspace); - dataset.write(&analog, PredType::NATIVE_INT); +void MasterAttributes::WriteHDF5AnalogFlag(::H5::H5File *fd, ::H5::Group *group) { + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = + group->createDataSet("Analog Flag", ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&analog, ::H5::PredType::NATIVE_INT); } -void MasterAttributes::WriteHDF5AnalogSamples(H5File *fd, Group *group) { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = - group->createDataSet("Analog Samples", PredType::NATIVE_INT, dataspace); - dataset.write(&analogSamples, PredType::NATIVE_INT); +void MasterAttributes::WriteHDF5AnalogSamples(::H5::H5File *fd, ::H5::Group *group) { + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = + group->createDataSet("Analog Samples", ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&analogSamples, ::H5::PredType::NATIVE_INT); } -void MasterAttributes::WriteHDF5DigitalFlag(H5File *fd, Group *group) { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = - group->createDataSet("Digital Flag", PredType::NATIVE_INT, dataspace); - dataset.write(&digital, PredType::NATIVE_INT); +void MasterAttributes::WriteHDF5DigitalFlag(::H5::H5File *fd, ::H5::Group *group) { + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = + group->createDataSet("Digital Flag", ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&digital, ::H5::PredType::NATIVE_INT); } -void MasterAttributes::WriteHDF5DigitalSamples(H5File *fd, Group *group) { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet("Digital Samples", - PredType::NATIVE_INT, dataspace); - dataset.write(&digitalSamples, PredType::NATIVE_INT); +void MasterAttributes::WriteHDF5DigitalSamples(::H5::H5File *fd, ::H5::Group *group) { + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = group->createDataSet("Digital Samples", + ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&digitalSamples, ::H5::PredType::NATIVE_INT); } -void MasterAttributes::WriteHDF5DbitOffset(H5File *fd, Group *group) { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = - group->createDataSet("Dbit Offset", PredType::NATIVE_INT, dataspace); - dataset.write(&dbitoffset, PredType::NATIVE_INT); +void MasterAttributes::WriteHDF5DbitOffset(::H5::H5File *fd, ::H5::Group *group) { + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = + group->createDataSet("Dbit Offset", ::H5::PredType::NATIVE_INT, dataspace); + dataset.write(&dbitoffset, ::H5::PredType::NATIVE_INT); } -void MasterAttributes::WriteHDF5DbitList(H5File *fd, Group *group) { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet("Dbit Bitset List", - PredType::STD_U64LE, dataspace); - dataset.write(&dbitlist, PredType::STD_U64LE); +void MasterAttributes::WriteHDF5DbitList(::H5::H5File *fd, ::H5::Group *group) { + ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); + ::H5::DataSet dataset = group->createDataSet("Dbit Bitset List", + ::H5::PredType::STD_U64LE, dataspace); + dataset.write(&dbitlist, ::H5::PredType::STD_U64LE); } #endif @@ -584,7 +586,7 @@ void MasterAttributes::GetGotthardBinaryAttributes( }; #ifdef HDF5C -void MasterAttributes::WriteGotthardHDF5Attributes(H5File *fd, Group *group) { +void MasterAttributes::WriteGotthardHDF5Attributes(::H5::H5File *fd, ::H5::Group *group) { MasterAttributes::WriteHDF5Exptime(fd, group); MasterAttributes::WriteHDF5Period(fd, group); MasterAttributes::WriteHDF5ROI(fd, group); @@ -604,7 +606,7 @@ void MasterAttributes::GetJungfrauBinaryAttributes( } #ifdef HDF5C -void MasterAttributes::WriteJungfrauHDF5Attributes(H5File *fd, Group *group) { +void MasterAttributes::WriteJungfrauHDF5Attributes(::H5::H5File *fd, ::H5::Group *group) { MasterAttributes::WriteHDF5Exptime(fd, group); MasterAttributes::WriteHDF5Period(fd, group); MasterAttributes::WriteHDF5NumUDPInterfaces(fd, group); @@ -637,7 +639,7 @@ void MasterAttributes::GetEigerBinaryAttributes( } #ifdef HDF5C -void MasterAttributes::WriteEigerHDF5Attributes(H5File *fd, Group *group) { +void MasterAttributes::WriteEigerHDF5Attributes(::H5::H5File *fd, ::H5::Group *group) { MasterAttributes::WriteHDF5DynamicRange(fd, group); MasterAttributes::WriteHDF5TenGiga(fd, group); MasterAttributes::WriteHDF5Exptime(fd, group); @@ -676,7 +678,7 @@ void MasterAttributes::GetMythen3BinaryAttributes( } #ifdef HDF5C -void MasterAttributes::WriteMythen3HDF5Attributes(H5File *fd, Group *group) { +void MasterAttributes::WriteMythen3HDF5Attributes(::H5::H5File *fd, ::H5::Group *group) { MasterAttributes::WriteHDF5DynamicRange(fd, group); MasterAttributes::WriteHDF5TenGiga(fd, group); MasterAttributes::WriteHDF5Period(fd, group); @@ -699,7 +701,7 @@ void MasterAttributes::GetGotthard2BinaryAttributes( } #ifdef HDF5C -void MasterAttributes::WriteGotthard2HDF5Attributes(H5File *fd, Group *group) { +void MasterAttributes::WriteGotthard2HDF5Attributes(::H5::H5File *fd, ::H5::Group *group) { MasterAttributes::WriteHDF5Exptime(fd, group); MasterAttributes::WriteHDF5Period(fd, group); MasterAttributes::WriteHDF5BurstMode(fd, group); @@ -721,7 +723,7 @@ void MasterAttributes::GetMoenchBinaryAttributes( } #ifdef HDF5C -void MasterAttributes::WriteMoenchHDF5Attributes(H5File *fd, Group *group) { +void MasterAttributes::WriteMoenchHDF5Attributes(::H5::H5File *fd, ::H5::Group *group) { MasterAttributes::WriteHDF5Exptime(fd, group); MasterAttributes::WriteHDF5Period(fd, group); MasterAttributes::WriteHDF5TenGiga(fd, group); @@ -755,7 +757,7 @@ void MasterAttributes::GetCtbBinaryAttributes( } #ifdef HDF5C -void MasterAttributes::WriteCtbHDF5Attributes(H5File *fd, Group *group) { +void MasterAttributes::WriteCtbHDF5Attributes(::H5::H5File *fd, ::H5::Group *group) { MasterAttributes::WriteHDF5Exptime(fd, group); MasterAttributes::WriteHDF5Period(fd, group); MasterAttributes::WriteHDF5TenGiga(fd, group); diff --git a/slsReceiverSoftware/src/MasterAttributes.h b/slsReceiverSoftware/src/MasterAttributes.h index 5fbb0a41a..904512061 100644 --- a/slsReceiverSoftware/src/MasterAttributes.h +++ b/slsReceiverSoftware/src/MasterAttributes.h @@ -11,16 +11,16 @@ #include #include +#ifdef HDF5C +#include "H5Cpp.h" +#endif + + namespace sls { using ns = std::chrono::nanoseconds; -#ifdef HDF5C -#include "H5Cpp.h" -#ifndef H5_NO_NAMESPACE -using namespace H5; -#endif -#endif + class MasterAttributes { public: @@ -71,7 +71,7 @@ class MasterAttributes { void GetBinaryAttributes(rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteHDF5Attributes(H5File *fd, Group *group); + void WriteHDF5Attributes(::H5::H5File *fd, ::H5::Group *group); #endif void GetCommonBinaryAttributes( @@ -79,75 +79,75 @@ class MasterAttributes { void GetFinalBinaryAttributes( rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteCommonHDF5Attributes(H5File *fd, Group *group); - void WriteFinalHDF5Attributes(H5File *fd, Group *group); - void WriteHDF5Exptime(H5File *fd, Group *group); - void WriteHDF5Period(H5File *fd, Group *group); - void WriteHDF5DynamicRange(H5File *fd, Group *group); - void WriteHDF5TenGiga(H5File *fd, Group *group); - void WriteHDF5ROI(H5File *fd, Group *group); - void WriteHDF5NumUDPInterfaces(H5File *fd, Group *group); - void WriteHDF5ReadNRows(H5File *fd, Group *group); - void WriteHDF5ThresholdEnergy(H5File *fd, Group *group); - void WriteHDF5ThresholdEnergies(H5File *fd, Group *group); - void WriteHDF5SubExpTime(H5File *fd, Group *group); - void WriteHDF5SubPeriod(H5File *fd, Group *group); - void WriteHDF5SubQuad(H5File *fd, Group *group); - void WriteHDF5RateCorrections(H5File *fd, Group *group); - void WriteHDF5CounterMask(H5File *fd, Group *group); - void WriteHDF5ExptimeArray(H5File *fd, Group *group); - void WriteHDF5GateDelayArray(H5File *fd, Group *group); - void WriteHDF5Gates(H5File *fd, Group *group); - void WriteHDF5BurstMode(H5File *fd, Group *group); - void WriteHDF5AdcMask(H5File *fd, Group *group); - void WriteHDF5AnalogFlag(H5File *fd, Group *group); - void WriteHDF5AnalogSamples(H5File *fd, Group *group); - void WriteHDF5DigitalFlag(H5File *fd, Group *group); - void WriteHDF5DigitalSamples(H5File *fd, Group *group); - void WriteHDF5DbitOffset(H5File *fd, Group *group); - void WriteHDF5DbitList(H5File *fd, Group *group); + void WriteCommonHDF5Attributes(::H5::H5File *fd, ::H5::Group *group); + void WriteFinalHDF5Attributes(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5Exptime(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5Period(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5DynamicRange(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5TenGiga(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5ROI(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5NumUDPInterfaces(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5ReadNRows(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5ThresholdEnergy(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5ThresholdEnergies(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5SubExpTime(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5SubPeriod(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5SubQuad(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5RateCorrections(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5CounterMask(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5ExptimeArray(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5GateDelayArray(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5Gates(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5BurstMode(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5AdcMask(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5AnalogFlag(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5AnalogSamples(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5DigitalFlag(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5DigitalSamples(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5DbitOffset(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5DbitList(::H5::H5File *fd, ::H5::Group *group); #endif void GetGotthardBinaryAttributes( rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteGotthardHDF5Attributes(H5File *fd, Group *group); + void WriteGotthardHDF5Attributes(::H5::H5File *fd, ::H5::Group *group); #endif void GetJungfrauBinaryAttributes( rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteJungfrauHDF5Attributes(H5File *fd, Group *group); + void WriteJungfrauHDF5Attributes(::H5::H5File *fd, ::H5::Group *group); #endif void GetEigerBinaryAttributes( rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteEigerHDF5Attributes(H5File *fd, Group *group); + void WriteEigerHDF5Attributes(::H5::H5File *fd, ::H5::Group *group); #endif void GetMythen3BinaryAttributes( rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteMythen3HDF5Attributes(H5File *fd, Group *group); + void WriteMythen3HDF5Attributes(::H5::H5File *fd, ::H5::Group *group); #endif void GetGotthard2BinaryAttributes( rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteGotthard2HDF5Attributes(H5File *fd, Group *group); + void WriteGotthard2HDF5Attributes(::H5::H5File *fd, ::H5::Group *group); #endif void GetMoenchBinaryAttributes( rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteMoenchHDF5Attributes(H5File *fd, Group *group); + void WriteMoenchHDF5Attributes(::H5::H5File *fd, ::H5::Group *group); #endif void GetCtbBinaryAttributes(rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteCtbHDF5Attributes(H5File *fd, Group *group); + void WriteCtbHDF5Attributes(::H5::H5File *fd, ::H5::Group *group); #endif }; diff --git a/slsReceiverSoftware/src/MasterFileUtility.cpp b/slsReceiverSoftware/src/MasterFileUtility.cpp index 22ba0400d..b0052e82f 100644 --- a/slsReceiverSoftware/src/MasterFileUtility.cpp +++ b/slsReceiverSoftware/src/MasterFileUtility.cpp @@ -47,30 +47,30 @@ std::string CreateMasterBinaryFile(const std::string &filePath, } #ifdef HDF5C -void LinkHDF5FileInMaster(const std::string &masterFileName, - const std::string &dataFilename, - const std::string &dataSetname, - const std::vector parameterNames, +void LinkHDF5FileInMaster(std::string &masterFileName, + std::string &dataFilename, + std::string &dataSetname, + std::vector parameterNames, const bool silentMode, std::mutex *hdf5LibMutex) { std::lock_guard lock(*hdf5LibMutex); - std::unique_ptr fd{nullptr}; + std::unique_ptr<::H5::H5File> fd{nullptr}; try { - Exception::dontPrint(); // to handle errors + ::H5::Exception::dontPrint(); // to handle errors - FileAccPropList flist; + ::H5::FileAccPropList flist; flist.setFcloseDegree(H5F_CLOSE_STRONG); // open master file - H5File masterfd(masterFileName.c_str(), H5F_ACC_RDWR, - FileCreatPropList::DEFAULT, flist); + ::H5::H5File masterfd(masterFileName.c_str(), H5F_ACC_RDWR, + ::H5::FileCreatPropList::DEFAULT, flist); // open data file - fd = make_unique(dataFilename.c_str(), H5F_ACC_RDONLY, - FileCreatPropList::DEFAULT, flist); + fd = make_unique<::H5::H5File>(dataFilename.c_str(), H5F_ACC_RDONLY, + ::H5::FileCreatPropList::DEFAULT, flist); // create link for data dataset - DataSet dset = fd->openDataSet(dataSetname.c_str()); + ::H5::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(), @@ -81,7 +81,7 @@ void LinkHDF5FileInMaster(const std::string &masterFileName, // create link for parameter datasets for (unsigned int i = 0; i < parameterNames.size(); ++i) { - DataSet pDset = fd->openDataSet(parameterNames[i].c_str()); + ::H5::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(), @@ -93,7 +93,7 @@ void LinkHDF5FileInMaster(const std::string &masterFileName, } fd->close(); masterfd.close(); - } catch (const Exception &error) { + } catch (const ::H5::Exception &error) { error.printErrorStack(); if (fd != nullptr) fd->close(); @@ -118,38 +118,38 @@ std::string CreateMasterHDF5File(const std::string &filePath, std::lock_guard lock(*hdf5LibMutex); - std::unique_ptr fd{nullptr}; + std::unique_ptr<::H5::H5File> fd{nullptr}; try { - Exception::dontPrint(); // to handle errors + ::H5::Exception::dontPrint(); // to handle errors - FileAccPropList flist; + ::H5::FileAccPropList flist; flist.setFcloseDegree(H5F_CLOSE_STRONG); unsigned int createFlags = H5F_ACC_EXCL; if (overWriteEnable) { createFlags = H5F_ACC_TRUNC; } - fd = make_unique(fileName.c_str(), createFlags, - FileCreatPropList::DEFAULT, flist); + fd = make_unique<::H5::H5File>(fileName.c_str(), createFlags, + ::H5::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); + ::H5::DataSpace dataspace_attr = ::H5::DataSpace(H5S_SCALAR); + ::H5::Attribute attribute = fd->createAttribute( + "version", ::H5::PredType::NATIVE_DOUBLE, dataspace_attr); + attribute.write(::H5::PredType::NATIVE_DOUBLE, &dValue); // Create a group in the file - 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")); + ::H5::Group group1(fd->createGroup("entry")); + ::H5::Group group2(group1.createGroup("data")); + ::H5::Group group3(group1.createGroup("instrument")); + ::H5::Group group4(group3.createGroup("beam")); + ::H5::Group group5(group3.createGroup("detector")); + ::H5::Group group6(group1.createGroup("sample")); attr->WriteHDF5Attributes(fd.get(), &group5); fd->close(); - } catch (const Exception &error) { + } catch (const ::H5::Exception &error) { error.printErrorStack(); if (fd != nullptr) fd->close(); @@ -169,9 +169,9 @@ std::array CreateVirtualHDF5File( 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 int numModX, const int numModY, const ::H5::DataType dataType, const std::vector parameterNames, - const std::vector parameterDataTypes, std::mutex *hdf5LibMutex, + const std::vector<::H5::DataType> parameterDataTypes, std::mutex *hdf5LibMutex, bool gotthard25um) { // virtual file name @@ -189,42 +189,42 @@ std::array CreateVirtualHDF5File( std::lock_guard lock(*hdf5LibMutex); - std::unique_ptr fd{nullptr}; + std::unique_ptr<::H5::H5File> fd{nullptr}; try { - Exception::dontPrint(); // to handle errors + ::H5::Exception::dontPrint(); // to handle errors // file - FileAccPropList fapl; + ::H5::FileAccPropList fapl; fapl.setFcloseDegree(H5F_CLOSE_STRONG); if (!overWriteEnable) - fd = make_unique(fileName.c_str(), H5F_ACC_EXCL, - FileCreatPropList::DEFAULT, fapl); + fd = make_unique<::H5::H5File>(fileName.c_str(), H5F_ACC_EXCL, + ::H5::FileCreatPropList::DEFAULT, fapl); else - fd = make_unique(fileName.c_str(), H5F_ACC_TRUNC, - FileCreatPropList::DEFAULT, fapl); + fd = make_unique<::H5::H5File>(fileName.c_str(), H5F_ACC_TRUNC, + ::H5::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); + ::H5::DataSpace dataspace_attr = ::H5::DataSpace(H5S_SCALAR); + ::H5::Attribute attribute = fd->createAttribute( + "version", ::H5::PredType::NATIVE_DOUBLE, dataspace_attr); + attribute.write(::H5::PredType::NATIVE_DOUBLE, &dValue); // virtual dataspace hsize_t vdsDims[3] = {numImagesCaught, numModY * nDimy, numModZ * nDimz}; - DataSpace vdsDataSpace(3, vdsDims, nullptr); + ::H5::DataSpace vdsDataSpace(3, vdsDims, nullptr); hsize_t vdsDimsPara[2] = {numImagesCaught, (unsigned int)numModY * numModZ}; - DataSpace vdsDataSpacePara(2, vdsDimsPara, nullptr); + ::H5::DataSpace vdsDataSpacePara(2, vdsDimsPara, nullptr); // property list (fill value and datatype) int fill_value = -1; - DSetCreatPropList plist; + ::H5::DSetCreatPropList plist; plist.setFillValue(dataType, &fill_value); // property list for parameters (datatype) - std::vector plistPara(paraSize); + std::vector<::H5::DSetCreatPropList> plistPara(paraSize); // hyperslab (files) int numFiles = numImagesCaught / maxFramesPerFile; @@ -296,10 +296,10 @@ std::array CreateVirtualHDF5File( // source dataspace hsize_t srcDims[3] = {nDimx, nDimy, nDimz}; hsize_t srcDimsMax[3] = {H5S_UNLIMITED, nDimy, nDimz}; - DataSpace srcDataSpace(3, srcDims, srcDimsMax); + ::H5::DataSpace srcDataSpace(3, srcDims, srcDimsMax); hsize_t srcDimsPara[1] = {nDimx}; hsize_t srcDimsMaxPara[1] = {H5S_UNLIMITED}; - DataSpace srcDataSpacePara(1, srcDimsPara, srcDimsMaxPara); + ::H5::DataSpace srcDataSpacePara(1, srcDimsPara, srcDimsMaxPara); // mapping of property list plist.setVirtual(vdsDataSpace, relative_srcFileName.c_str(), @@ -325,17 +325,17 @@ std::array CreateVirtualHDF5File( framesSaved += nDimx; } // datasets - DataSet vdsDataSet(fd->createDataSet(dataSetName.c_str(), dataType, + ::H5::DataSet vdsDataSet(fd->createDataSet(dataSetName.c_str(), dataType, vdsDataSpace, plist)); for (unsigned int p = 0; p < paraSize; ++p) { - DataSet vdsDataSetPara(fd->createDataSet( + ::H5::DataSet vdsDataSetPara(fd->createDataSet( parameterNames[p].c_str(), parameterDataTypes[p], vdsDataSpacePara, plistPara[p])); } fd->close(); - } catch (const Exception &error) { + } catch (const ::H5::Exception &error) { error.printErrorStack(); if (fd) { fd->close(); diff --git a/slsReceiverSoftware/src/MasterFileUtility.h b/slsReceiverSoftware/src/MasterFileUtility.h index 4a4b0e136..3aa2427a5 100644 --- a/slsReceiverSoftware/src/MasterFileUtility.h +++ b/slsReceiverSoftware/src/MasterFileUtility.h @@ -4,17 +4,13 @@ #include "MasterAttributes.h" +#include + namespace sls { namespace masterFileUtility { -#ifdef HDF5C -#include "H5Cpp.h" -#include -#ifndef H5_NO_NAMESPACE -using namespace H5; -#endif -#endif + std::string CreateMasterBinaryFile(const std::string &filePath, @@ -25,10 +21,10 @@ std::string CreateMasterBinaryFile(const std::string &filePath, MasterAttributes *attr); #ifdef HDF5C -void LinkHDF5FileInMaster(const std::string &masterFileName, - const std::string &dataFilename, - const std::string &dataSetname, - const std::vector parameterNames, +void LinkHDF5FileInMaster(std::string &masterFileName, + std::string &dataFilename, + std::string &dataSetname, + std::vector parameterNames, const bool silentMode, std::mutex *hdf5LibMutex); std::string CreateMasterHDF5File(const std::string &filePath, @@ -45,9 +41,9 @@ std::array CreateVirtualHDF5File( 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 int numModX, const int numModY, const ::H5::DataType dataType, const std::vector parameterNames, - const std::vector parameterDataTypes, std::mutex *hdf5LibMutex, + const std::vector<::H5::DataType> parameterDataTypes, std::mutex *hdf5LibMutex, bool gotthard25um); #endif } // namespace masterFileUtility From 8ca8185d410ad06bd440667bb87e3732e9492c81 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil <33750417+thattil@users.noreply.github.com> Date: Thu, 9 Jun 2022 12:35:33 +0200 Subject: [PATCH 6/8] H5 one dataset name (#484) * rename all datasets in hdf5 files to just 'data' * removing the global qualifier H5 * update release notes --- RELEASE.txt | 1 + slsReceiverSoftware/src/DataProcessor.cpp | 13 +- slsReceiverSoftware/src/DataProcessor.h | 3 +- slsReceiverSoftware/src/File.h | 14 +- slsReceiverSoftware/src/HDF5DataFile.cpp | 95 ++-- slsReceiverSoftware/src/HDF5DataFile.h | 20 +- slsReceiverSoftware/src/Implementation.cpp | 7 +- slsReceiverSoftware/src/MasterAttributes.cpp | 426 +++++++++--------- slsReceiverSoftware/src/MasterAttributes.h | 70 +-- slsReceiverSoftware/src/MasterFileUtility.cpp | 118 +++-- slsReceiverSoftware/src/MasterFileUtility.h | 9 +- slsReceiverSoftware/src/receiver_defs.h | 3 + 12 files changed, 380 insertions(+), 399 deletions(-) diff --git a/RELEASE.txt b/RELEASE.txt index eacad4e01..d97c17c88 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -81,6 +81,7 @@ This document describes the differences between v7.0.0 and v6.x.x - (apparently) rxr doesnt get stuck anymore from 6.1.1 - rxr mem size changed (fifo header size from 8 to 16) due to sls rxr header = 112.. 112+ 16=128 (reduces packet losss especially for g2) -udp_srcip and udp_Srcip2: can set to auto (for virtual or 1g data networks) +- set dataset name for all hdf5 files to "data" only 2. Resolved Issues ================== diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index d5ad4203c..f36850572 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -169,7 +169,7 @@ uint32_t DataProcessor::GetFilesInAcquisition() const { return dataFile_->GetFilesInAcquisition(); } -std::array DataProcessor::CreateVirtualFile( +std::string 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, @@ -195,7 +195,7 @@ std::array DataProcessor::CreateVirtualFile( // stop acquisition) return masterFileUtility::CreateVirtualHDF5File( filePath, fileNamePrefix, fileIndex, overWriteEnable, silentMode, - modulePos, numUnitsPerReadout, framesPerFile, numImages, + modulePos, numUnitsPerReadout, framesPerFile, generalData_->nPixelsX, generalData_->nPixelsY, dynamicRange, numFramesCaught_, numModX, numModY, dataFile_->GetPDataType(), dataFile_->GetParameterNames(), dataFile_->GetParameterDataTypes(), @@ -204,21 +204,18 @@ std::array DataProcessor::CreateVirtualFile( void DataProcessor::LinkFileInMaster(const std::string &masterFileName, const std::string &virtualFileName, - const std::string &virtualDatasetName, const bool silentMode, std::mutex *hdf5LibMutex) { if (receiverRoiEnabled_) { throw std::runtime_error("Should not be here, roi with hdf5 virtual should throw."); } - std::string fname{virtualFileName}, datasetName{virtualDatasetName}, masterfname{masterFileName}; + std::string fname{virtualFileName}, masterfname{masterFileName}; // if no virtual file, link data file if (virtualFileName.empty()) { - auto res = dataFile_->GetFileAndDatasetName(); - fname = res[0]; - datasetName = res[1]; + fname = dataFile_->GetFileName(); } - masterFileUtility::LinkHDF5FileInMaster(masterfname, fname, datasetName, + masterFileUtility::LinkHDF5FileInMaster(masterfname, fname, dataFile_->GetParameterNames(), silentMode, hdf5LibMutex); } diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index 2e89ec198..78bcc58d0 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -62,7 +62,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { const bool detectorDataStream); #ifdef HDF5C uint32_t GetFilesInAcquisition() const; - std::array CreateVirtualFile( + std::string CreateVirtualFile( const std::string &filePath, const std::string &fileNamePrefix, const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode, const int modulePos, @@ -71,7 +71,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { const uint32_t dynamicRange, std::mutex *hdf5LibMutex); void LinkFileInMaster(const std::string &masterFileName, const std::string &virtualFileName, - const std::string &virtualDatasetName, const bool silentMode, std::mutex *hdf5LibMutex); #endif diff --git a/slsReceiverSoftware/src/File.h b/slsReceiverSoftware/src/File.h index 259bfb1e7..957d414cd 100644 --- a/slsReceiverSoftware/src/File.h +++ b/slsReceiverSoftware/src/File.h @@ -25,11 +25,11 @@ class File : private virtual slsDetectorDefs { virtual void CloseFile() = 0; #ifdef HDF5C - virtual std::array GetFileAndDatasetName() const { + virtual std::string GetFileName() const { LOG(logERROR) - << "This is a generic function GetFilesInAcquisition that " + << "This is a generic function GetFileName that " "should be overloaded by a derived class"; - return std::array{}; + return std::string{}; } virtual uint32_t GetFilesInAcquisition() const { @@ -47,14 +47,14 @@ class File : private virtual slsDetectorDefs { virtual std::vector GetParameterNames() const { LOG(logERROR) - << "This is a generic function GetFilesInAcquisition that " + << "This is a generic function GetParameterNames that " "should be overloaded by a derived class"; return std::vector{}; }; virtual std::vector GetParameterDataTypes() const { LOG(logERROR) - << "This is a generic function GetFilesInAcquisition that " + << "This is a generic function GetParameterDataTypes that " "should be overloaded by a derived class"; return std::vector{}; }; @@ -67,7 +67,7 @@ class File : private virtual slsDetectorDefs { 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 " + LOG(logERROR) << "This is a generic function CreateFirstHDF5DataFile that " "should be overloaded by a derived class"; }; #endif @@ -77,7 +77,7 @@ class File : private virtual slsDetectorDefs { 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 " + LOG(logERROR) << "This is a generic function CreateFirstBinaryDataFile that " "should be overloaded by a derived class"; }; diff --git a/slsReceiverSoftware/src/HDF5DataFile.cpp b/slsReceiverSoftware/src/HDF5DataFile.cpp index a3885f705..3af531145 100644 --- a/slsReceiverSoftware/src/HDF5DataFile.cpp +++ b/slsReceiverSoftware/src/HDF5DataFile.cpp @@ -26,44 +26,44 @@ HDF5DataFile::HDF5DataFile(int index, std::mutex *hdf5Lib) "detector header version", "packets caught bit mask", }; - ::H5::StrType strdatatype(::H5::PredType::C_S1, sizeof(bitset_storage)); - parameterDataTypes_ = std::vector<::H5::DataType>{ - ::H5::PredType::STD_U64LE, ::H5::PredType::STD_U32LE, ::H5::PredType::STD_U32LE, - ::H5::PredType::STD_U64LE, ::H5::PredType::STD_U64LE, ::H5::PredType::STD_U16LE, - ::H5::PredType::STD_U16LE, ::H5::PredType::STD_U16LE, ::H5::PredType::STD_U16LE, - ::H5::PredType::STD_U32LE, ::H5::PredType::STD_U16LE, ::H5::PredType::STD_U8LE, - ::H5::PredType::STD_U8LE, strdatatype}; + H5::StrType strdatatype(H5::PredType::C_S1, sizeof(bitset_storage)); + parameterDataTypes_ = std::vector{ + H5::PredType::STD_U64LE, H5::PredType::STD_U32LE, H5::PredType::STD_U32LE, + H5::PredType::STD_U64LE, H5::PredType::STD_U64LE, H5::PredType::STD_U16LE, + H5::PredType::STD_U16LE, H5::PredType::STD_U16LE, H5::PredType::STD_U16LE, + H5::PredType::STD_U32LE, H5::PredType::STD_U16LE, H5::PredType::STD_U8LE, + H5::PredType::STD_U8LE, strdatatype}; } HDF5DataFile::~HDF5DataFile() { CloseFile(); } -std::array HDF5DataFile::GetFileAndDatasetName() const { - return std::array{fileName_, dataSetName_}; +std::string HDF5DataFile::GetFileName() const { + return fileName_; } uint32_t HDF5DataFile::GetFilesInAcquisition() const { return numFilesInAcquisition_; } -::H5::DataType HDF5DataFile::GetPDataType() const { return dataType_; } +H5::DataType HDF5DataFile::GetPDataType() const { return dataType_; } std::vector HDF5DataFile::GetParameterNames() const { return parameterNames_; } -std::vector<::H5::DataType> HDF5DataFile::GetParameterDataTypes() const { +std::vector HDF5DataFile::GetParameterDataTypes() const { return parameterDataTypes_; } void HDF5DataFile::CloseFile() { std::lock_guard lock(*hdf5Lib_); try { - ::H5::Exception::dontPrint(); // to handle errors + H5::Exception::dontPrint(); // to handle errors if (fd_) { fd_->close(); delete fd_; fd_ = nullptr; } - } catch (const ::H5::Exception &error) { + } catch (const H5::Exception &error) { LOG(logERROR) << "Could not close data HDF5 handles of index " << index_; error.printErrorStack(); @@ -116,13 +116,13 @@ void HDF5DataFile::CreateFirstHDF5DataFile( switch (dynamicRange_) { case 12: case 16: - dataType_ = ::H5::PredType::STD_U16LE; + dataType_ = H5::PredType::STD_U16LE; break; case 32: - dataType_ = ::H5::PredType::STD_U32LE; + dataType_ = H5::PredType::STD_U32LE; break; default: - dataType_ = ::H5::PredType::STD_U8LE; + dataType_ = H5::PredType::STD_U8LE; break; } @@ -153,42 +153,35 @@ void HDF5DataFile::CreateFile() { uint32_t nDimz = ((dynamicRange_ == 4) ? (nPixelsX_ / 2) : nPixelsX_); try { - ::H5::Exception::dontPrint(); // to handle errors + H5::Exception::dontPrint(); // to handle errors // file - ::H5::FileAccPropList fapl; + H5::FileAccPropList fapl; fapl.setFcloseDegree(H5F_CLOSE_STRONG); fd_ = nullptr; if (!overWriteEnable_) - fd_ = new ::H5::H5File(fileName_.c_str(), H5F_ACC_EXCL, - ::H5::FileCreatPropList::DEFAULT, fapl); + fd_ = new H5::H5File(fileName_.c_str(), H5F_ACC_EXCL, + H5::FileCreatPropList::DEFAULT, fapl); else - fd_ = new ::H5::H5File(fileName_.c_str(), H5F_ACC_TRUNC, - ::H5::FileCreatPropList::DEFAULT, fapl); + fd_ = new H5::H5File(fileName_.c_str(), H5F_ACC_TRUNC, + H5::FileCreatPropList::DEFAULT, fapl); // attributes - version double dValue = HDF5_WRITER_VERSION; - ::H5::DataSpace dataspace_attr = ::H5::DataSpace(H5S_SCALAR); - ::H5::Attribute attribute = fd_->createAttribute( - "version", ::H5::PredType::NATIVE_DOUBLE, dataspace_attr); - attribute.write(::H5::PredType::NATIVE_DOUBLE, &dValue); + H5::DataSpace dataspace_attr = H5::DataSpace(H5S_SCALAR); + H5::Attribute attribute = fd_->createAttribute( + "version", H5::PredType::NATIVE_DOUBLE, dataspace_attr); + attribute.write(H5::PredType::NATIVE_DOUBLE, &dValue); // dataspace hsize_t srcdims[3] = {nDimx, nDimy, nDimz}; hsize_t srcdimsmax[3] = {H5S_UNLIMITED, nDimy, nDimz}; dataSpace_ = nullptr; - dataSpace_ = new ::H5::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(); + dataSpace_ = new H5::DataSpace(3, srcdims, srcdimsmax); // dataset // fill value - ::H5::DSetCreatPropList plist; + H5::DSetCreatPropList plist; int fill_value = -1; plist.setFillValue(dataType_, &fill_value); // always create chunked dataset as unlimited is only @@ -196,28 +189,28 @@ void HDF5DataFile::CreateFile() { hsize_t chunk_dims[3] = {MAX_CHUNKED_IMAGES, nDimy, nDimz}; plist.setChunk(3, chunk_dims); dataSet_ = nullptr; - dataSet_ = new ::H5::DataSet(fd_->createDataSet( - dataSetName_.c_str(), dataType_, *dataSpace_, plist)); + dataSet_ = new H5::DataSet(fd_->createDataSet( + DATASET_NAME, dataType_, *dataSpace_, plist)); // create parameter datasets hsize_t dims[1] = {nDimx}; hsize_t dimsmax[1] = {H5S_UNLIMITED}; dataSpacePara_ = nullptr; - dataSpacePara_ = new ::H5::DataSpace(1, dims, dimsmax); + dataSpacePara_ = new H5::DataSpace(1, dims, dimsmax); // always create chunked dataset as unlimited is only // supported with chunked layout - ::H5::DSetCreatPropList paralist; + H5::DSetCreatPropList paralist; hsize_t chunkpara_dims[3] = {MAX_CHUNKED_IMAGES}; paralist.setChunk(1, chunkpara_dims); for (unsigned int i = 0; i < parameterNames_.size(); ++i) { - ::H5::DataSet *ds = new ::H5::DataSet(fd_->createDataSet( + H5::DataSet *ds = new H5::DataSet(fd_->createDataSet( parameterNames_[i].c_str(), parameterDataTypes_[i], *dataSpacePara_, paralist)); dataSetPara_.push_back(ds); } - } catch (const ::H5::Exception &error) { + } catch (const H5::Exception &error) { error.printErrorStack(); CloseFile(); throw RuntimeError("Could not create HDF5 handles in object " + @@ -287,16 +280,16 @@ void HDF5DataFile::WriteDataFile(const uint64_t currentFrameNumber, hsize_t start[3] = {nDimx, 0, 0}; hsize_t dims2[2] = {nDimy, nDimz}; try { - ::H5::Exception::dontPrint(); // to handle errors + H5::Exception::dontPrint(); // to handle errors dataSpace_->selectHyperslab(H5S_SELECT_SET, count, start); - ::H5::DataSpace memspace(2, dims2); + H5::DataSpace memspace(2, dims2); dataSet_->write(revBuffer, dataType_, memspace, *dataSpace_); memspace.close(); if (dynamicRange_ == 12) { free(revBuffer); } - } catch (const ::H5::Exception &error) { + } catch (const H5::Exception &error) { if (dynamicRange_ == 12) { free(revBuffer); } @@ -320,9 +313,9 @@ void HDF5DataFile::WriteParameterDatasets(const uint64_t currentFrameNumber, hsize_t start[1] = {fnum}; int i = 0; try { - ::H5::Exception::dontPrint(); // to handle errors + H5::Exception::dontPrint(); // to handle errors dataSpacePara_->selectHyperslab(H5S_SELECT_SET, count, start); - ::H5::DataSpace memspace(H5S_SCALAR); + H5::DataSpace memspace(H5S_SCALAR); dataSetPara_[0]->write(&header.frameNumber, parameterDataTypes_[0], memspace, *dataSpacePara_); i = 1; @@ -383,7 +376,7 @@ void HDF5DataFile::WriteParameterDatasets(const uint64_t currentFrameNumber, memspace, *dataSpacePara_); } i = 14; - } catch (const ::H5::Exception &error) { + } catch (const H5::Exception &error) { error.printErrorStack(); throw RuntimeError( "Could not write parameters (index:" + std::to_string(i) + @@ -395,7 +388,7 @@ void HDF5DataFile::ExtendDataset() { std::lock_guard lock(*hdf5Lib_); try { - ::H5::Exception::dontPrint(); // to handle errors + H5::Exception::dontPrint(); // to handle errors hsize_t dims[3]; dataSpace_->getSimpleExtentDims(dims); @@ -404,16 +397,16 @@ void HDF5DataFile::ExtendDataset() { dataSet_->extend(dims); delete dataSpace_; dataSpace_ = nullptr; - dataSpace_ = new ::H5::DataSpace(dataSet_->getSpace()); + dataSpace_ = new H5::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 ::H5::DataSpace(dataSetPara_[0]->getSpace()); + dataSpacePara_ = new H5::DataSpace(dataSetPara_[0]->getSpace()); - } catch (const ::H5::Exception &error) { + } catch (const H5::Exception &error) { error.printErrorStack(); throw RuntimeError("Could not extend dataset in object " + std::to_string(index_)); diff --git a/slsReceiverSoftware/src/HDF5DataFile.h b/slsReceiverSoftware/src/HDF5DataFile.h index 7f2fdb56b..a6d32ae15 100644 --- a/slsReceiverSoftware/src/HDF5DataFile.h +++ b/slsReceiverSoftware/src/HDF5DataFile.h @@ -14,11 +14,11 @@ class HDF5DataFile : private virtual slsDetectorDefs, public File { HDF5DataFile(const int index, std::mutex *hdf5Lib); ~HDF5DataFile(); - std::array GetFileAndDatasetName() const override; + std::string GetFileName() const override; uint32_t GetFilesInAcquisition() const override; - ::H5::DataType GetPDataType() const override; + H5::DataType GetPDataType() const override; std::vector GetParameterNames() const override; - std::vector<::H5::DataType> GetParameterDataTypes() const override; + std::vector GetParameterDataTypes() const override; void CloseFile() override; @@ -45,17 +45,17 @@ class HDF5DataFile : private virtual slsDetectorDefs, public File { int index_; std::mutex *hdf5Lib_; - ::H5::H5File *fd_{nullptr}; + H5::H5File *fd_{nullptr}; std::string fileName_; std::string dataSetName_; - ::H5::DataSpace *dataSpace_{nullptr}; - ::H5::DataSet *dataSet_{nullptr}; - ::H5::DataType dataType_{::H5::PredType::STD_U16LE}; + H5::DataSpace *dataSpace_{nullptr}; + H5::DataSet *dataSet_{nullptr}; + H5::DataType dataType_{H5::PredType::STD_U16LE}; - ::H5::DataSpace *dataSpacePara_{nullptr}; - std::vector<::H5::DataSet *> dataSetPara_{nullptr}; + H5::DataSpace *dataSpacePara_{nullptr}; + std::vector dataSetPara_{nullptr}; std::vector parameterNames_; - std::vector<::H5::DataType> parameterDataTypes_; + std::vector parameterDataTypes_; uint32_t subFileIndex_{0}; uint32_t numFramesInFile_{0}; diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index 97c3719e2..d65c4c75c 100644 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -915,11 +915,11 @@ void Implementation::StartMasterWriter() { } #ifdef HDF5C if (fileFormatType == HDF5) { - std::array virtualFileAndDatasetNames; + std::string virtualFileName; // create virtual hdf5 file (if multiple files) if (dataProcessor[0]->GetFilesInAcquisition() > 1 || (numPorts.x * numPorts.y) > 1) { - virtualFileAndDatasetNames = + virtualFileName = dataProcessor[0]->CreateVirtualFile( filePath, fileName, fileIndex, overwriteEnable, silentMode, modulePos, numUDPInterfaces, framesPerFile, @@ -929,8 +929,7 @@ void Implementation::StartMasterWriter() { // link file in master if (masterFileWriteEnable) { dataProcessor[0]->LinkFileInMaster( - masterFileName, virtualFileAndDatasetNames[0], - virtualFileAndDatasetNames[1], silentMode, &hdf5LibMutex); + masterFileName, virtualFileName, silentMode, &hdf5LibMutex); } } #endif diff --git a/slsReceiverSoftware/src/MasterAttributes.cpp b/slsReceiverSoftware/src/MasterAttributes.cpp index b39921f4a..9047e86e8 100644 --- a/slsReceiverSoftware/src/MasterAttributes.cpp +++ b/slsReceiverSoftware/src/MasterAttributes.cpp @@ -41,7 +41,7 @@ void MasterAttributes::GetBinaryAttributes( } #ifdef HDF5C -void MasterAttributes::WriteHDF5Attributes(::H5::H5File *fd, ::H5::Group *group) { +void MasterAttributes::WriteHDF5Attributes(H5::H5File *fd, H5::Group *group) { WriteCommonHDF5Attributes(fd, group); switch (detType) { case slsDetectorDefs::GOTTHARD: @@ -169,40 +169,40 @@ void MasterAttributes::GetFinalBinaryAttributes( } #ifdef HDF5C -void MasterAttributes::WriteCommonHDF5Attributes(::H5::H5File *fd, ::H5::Group *group) { +void MasterAttributes::WriteCommonHDF5Attributes(H5::H5File *fd, H5::Group *group) { char c[1024]{}; // version { double version = BINARY_WRITER_VERSION; - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::Attribute attribute = - fd->createAttribute("Version", ::H5::PredType::NATIVE_DOUBLE, dataspace); - attribute.write(::H5::PredType::NATIVE_DOUBLE, &version); + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::Attribute attribute = + fd->createAttribute("Version", H5::PredType::NATIVE_DOUBLE, dataspace); + attribute.write(H5::PredType::NATIVE_DOUBLE, &version); } // timestamp { time_t t = std::time(nullptr); - ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = + H5::StrType strdatatype(H5::PredType::C_S1, 256); + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = group->createDataSet("Timestamp", strdatatype, dataspace); strcpy_safe(c, std::string(ctime(&t))); dataset.write(c, strdatatype); } // detector type { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); - ::H5::DataSet dataset = + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::StrType strdatatype(H5::PredType::C_S1, 256); + H5::DataSet dataset = group->createDataSet("Detector Type", strdatatype, dataspace); strcpy_safe(c, ToString(detType)); dataset.write(c, strdatatype); } // timing mode { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); - ::H5::DataSet dataset = + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::StrType strdatatype(H5::PredType::C_S1, 256); + H5::DataSet dataset = group->createDataSet("Timing Mode", strdatatype, dataspace); strcpy_safe(c, ToString(timingMode)); dataset.write(c, strdatatype); @@ -210,27 +210,27 @@ void MasterAttributes::WriteCommonHDF5Attributes(::H5::H5File *fd, ::H5::Group * // TODO: make this into an array? // geometry x { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = group->createDataSet("Geometry in x axis", - ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&geometry.x, ::H5::PredType::NATIVE_INT); + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = group->createDataSet("Geometry in x axis", + H5::PredType::NATIVE_INT, dataspace); + dataset.write(&geometry.x, H5::PredType::NATIVE_INT); } // geometry y { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = group->createDataSet("Geometry in y axis", - ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&geometry.y, ::H5::PredType::NATIVE_INT); + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = group->createDataSet("Geometry in y axis", + H5::PredType::NATIVE_INT, dataspace); + dataset.write(&geometry.y, H5::PredType::NATIVE_INT); } // Image Size { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = - group->createDataSet("Image Size", ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&imageSize, ::H5::PredType::NATIVE_INT); - ::H5::DataSpace dataspaceAttr = ::H5::DataSpace(H5S_SCALAR); - ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); - ::H5::Attribute attribute = + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = + group->createDataSet("Image Size", H5::PredType::NATIVE_INT, dataspace); + dataset.write(&imageSize, H5::PredType::NATIVE_INT); + H5::DataSpace dataspaceAttr = H5::DataSpace(H5S_SCALAR); + H5::StrType strdatatype(H5::PredType::C_S1, 256); + H5::Attribute attribute = dataset.createAttribute("Unit", strdatatype, dataspaceAttr); strcpy_safe(c, "bytes"); attribute.write(strdatatype, c); @@ -238,335 +238,335 @@ void MasterAttributes::WriteCommonHDF5Attributes(::H5::H5File *fd, ::H5::Group * // TODO: make this into an array? // npixels x { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = group->createDataSet("Number of pixels in x axis", - ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&nPixels.x, ::H5::PredType::NATIVE_INT); + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = group->createDataSet("Number of pixels in x axis", + H5::PredType::NATIVE_INT, dataspace); + dataset.write(&nPixels.x, H5::PredType::NATIVE_INT); } // npixels y { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = group->createDataSet("Number of pixels in y axis", - ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&nPixels.y, ::H5::PredType::NATIVE_INT); + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = group->createDataSet("Number of pixels in y axis", + H5::PredType::NATIVE_INT, dataspace); + dataset.write(&nPixels.y, H5::PredType::NATIVE_INT); } // Maximum frames per file { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = group->createDataSet("Maximum frames per file", - ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&maxFramesPerFile, ::H5::PredType::NATIVE_INT); + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = group->createDataSet("Maximum frames per file", + H5::PredType::NATIVE_INT, dataspace); + dataset.write(&maxFramesPerFile, H5::PredType::NATIVE_INT); } // Frame Discard Policy { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); - ::H5::DataSet dataset = group->createDataSet("Frame Discard Policy", + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::StrType strdatatype(H5::PredType::C_S1, 256); + H5::DataSet dataset = group->createDataSet("Frame Discard Policy", strdatatype, dataspace); strcpy_safe(c, ToString(frameDiscardMode)); dataset.write(c, strdatatype); } // Frame Padding { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = group->createDataSet("Frame Padding", - ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&framePadding, ::H5::PredType::NATIVE_INT); + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = group->createDataSet("Frame Padding", + H5::PredType::NATIVE_INT, dataspace); + dataset.write(&framePadding, H5::PredType::NATIVE_INT); } // Scan Parameters { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); - ::H5::DataSet dataset = + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::StrType strdatatype(H5::PredType::C_S1, 256); + H5::DataSet dataset = group->createDataSet("Scan Parameters", strdatatype, dataspace); strcpy_safe(c, ToString(scanParams)); dataset.write(c, strdatatype); } // Total Frames { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = group->createDataSet("Total Frames", - ::H5::PredType::STD_U64LE, dataspace); - dataset.write(&totalFrames, ::H5::PredType::STD_U64LE); + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = group->createDataSet("Total Frames", + H5::PredType::STD_U64LE, dataspace); + dataset.write(&totalFrames, H5::PredType::STD_U64LE); } // Receiver Roi xmin { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = group->createDataSet("receiver roi xmin", - ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&receiverRoi.xmin, ::H5::PredType::NATIVE_INT); + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = group->createDataSet("receiver roi xmin", + H5::PredType::NATIVE_INT, dataspace); + dataset.write(&receiverRoi.xmin, H5::PredType::NATIVE_INT); } // Receiver Roi xmax { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = group->createDataSet("receiver roi xmax", - ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&receiverRoi.xmax, ::H5::PredType::NATIVE_INT); + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = group->createDataSet("receiver roi xmax", + H5::PredType::NATIVE_INT, dataspace); + dataset.write(&receiverRoi.xmax, H5::PredType::NATIVE_INT); } // Receiver Roi ymin { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = group->createDataSet("receiver roi ymin", - ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&receiverRoi.ymin, ::H5::PredType::NATIVE_INT); + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = group->createDataSet("receiver roi ymin", + H5::PredType::NATIVE_INT, dataspace); + dataset.write(&receiverRoi.ymin, H5::PredType::NATIVE_INT); } // Receiver Roi ymax { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = group->createDataSet("receiver roi ymax", - ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&receiverRoi.ymax, ::H5::PredType::NATIVE_INT); + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = group->createDataSet("receiver roi ymax", + H5::PredType::NATIVE_INT, dataspace); + dataset.write(&receiverRoi.ymax, H5::PredType::NATIVE_INT); } } -void MasterAttributes::WriteFinalHDF5Attributes(::H5::H5File *fd, ::H5::Group *group) { +void MasterAttributes::WriteFinalHDF5Attributes(H5::H5File *fd, H5::Group *group) { char c[1024]{}; // Total Frames in file { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = group->createDataSet("Frames in File", - ::H5::PredType::STD_U64LE, dataspace); - dataset.write(&framesInFile, ::H5::PredType::STD_U64LE); + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = group->createDataSet("Frames in File", + H5::PredType::STD_U64LE, dataspace); + dataset.write(&framesInFile, H5::PredType::STD_U64LE); } // additional json header if (!additionalJsonHeader.empty()) { std::string json = ToString(additionalJsonHeader); - ::H5::StrType strdatatype(::H5::PredType::C_S1, json.length()); - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = group->createDataSet("Additional JSON Header", + H5::StrType strdatatype(H5::PredType::C_S1, json.length()); + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = group->createDataSet("Additional JSON Header", strdatatype, dataspace); strcpy_safe(c, ToString(additionalJsonHeader)); dataset.write(c, strdatatype); } } -void MasterAttributes::WriteHDF5Exptime(::H5::H5File *fd, ::H5::Group *group) { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); - ::H5::DataSet dataset = +void MasterAttributes::WriteHDF5Exptime(H5::H5File *fd, H5::Group *group) { + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::StrType strdatatype(H5::PredType::C_S1, 256); + H5::DataSet dataset = group->createDataSet("Exposure Time", strdatatype, dataspace); char c[1024]{}; strcpy_safe(c, ToString(exptime)); dataset.write(c, strdatatype); } -void MasterAttributes::WriteHDF5Period(::H5::H5File *fd, ::H5::Group *group) { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); - ::H5::DataSet dataset = +void MasterAttributes::WriteHDF5Period(H5::H5File *fd, H5::Group *group) { + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::StrType strdatatype(H5::PredType::C_S1, 256); + H5::DataSet dataset = group->createDataSet("Acquisition Period", strdatatype, dataspace); char c[1024]{}; strcpy_safe(c, ToString(period)); dataset.write(c, strdatatype); } -void MasterAttributes::WriteHDF5DynamicRange(::H5::H5File *fd, ::H5::Group *group) { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = - group->createDataSet("Dynamic Range", ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&dynamicRange, ::H5::PredType::NATIVE_INT); - ::H5::DataSpace dataspaceAttr = ::H5::DataSpace(H5S_SCALAR); - ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); - ::H5::Attribute attribute = +void MasterAttributes::WriteHDF5DynamicRange(H5::H5File *fd, H5::Group *group) { + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = + group->createDataSet("Dynamic Range", H5::PredType::NATIVE_INT, dataspace); + dataset.write(&dynamicRange, H5::PredType::NATIVE_INT); + H5::DataSpace dataspaceAttr = H5::DataSpace(H5S_SCALAR); + H5::StrType strdatatype(H5::PredType::C_S1, 256); + H5::Attribute attribute = dataset.createAttribute("Unit", strdatatype, dataspaceAttr); char c[1024] = "bits"; attribute.write(strdatatype, c); } -void MasterAttributes::WriteHDF5TenGiga(::H5::H5File *fd, ::H5::Group *group) { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = group->createDataSet("Ten Giga Enable", - ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&tenGiga, ::H5::PredType::NATIVE_INT); +void MasterAttributes::WriteHDF5TenGiga(H5::H5File *fd, H5::Group *group) { + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = group->createDataSet("Ten Giga Enable", + H5::PredType::NATIVE_INT, dataspace); + dataset.write(&tenGiga, H5::PredType::NATIVE_INT); } -void MasterAttributes::WriteHDF5ROI(::H5::H5File *fd, ::H5::Group *group) { +void MasterAttributes::WriteHDF5ROI(H5::H5File *fd, H5::Group *group) { // Roi xmin { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = - group->createDataSet("roi xmin", ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&detectorRoi.xmin, ::H5::PredType::NATIVE_INT); + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = + group->createDataSet("roi xmin", H5::PredType::NATIVE_INT, dataspace); + dataset.write(&detectorRoi.xmin, H5::PredType::NATIVE_INT); } // Roi xmax { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = - group->createDataSet("roi xmax", ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&detectorRoi.xmax, ::H5::PredType::NATIVE_INT); + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = + group->createDataSet("roi xmax", H5::PredType::NATIVE_INT, dataspace); + dataset.write(&detectorRoi.xmax, H5::PredType::NATIVE_INT); } } -void MasterAttributes::WriteHDF5NumUDPInterfaces(::H5::H5File *fd, ::H5::Group *group) { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = group->createDataSet("Number of UDP Interfaces", - ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&numUDPInterfaces, ::H5::PredType::NATIVE_INT); +void MasterAttributes::WriteHDF5NumUDPInterfaces(H5::H5File *fd, H5::Group *group) { + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = group->createDataSet("Number of UDP Interfaces", + H5::PredType::NATIVE_INT, dataspace); + dataset.write(&numUDPInterfaces, H5::PredType::NATIVE_INT); } -void MasterAttributes::WriteHDF5ReadNRows(::H5::H5File *fd, ::H5::Group *group) { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = - group->createDataSet("Number of rows", ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&readNRows, ::H5::PredType::NATIVE_INT); +void MasterAttributes::WriteHDF5ReadNRows(H5::H5File *fd, H5::Group *group) { + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = + group->createDataSet("Number of rows", H5::PredType::NATIVE_INT, dataspace); + dataset.write(&readNRows, H5::PredType::NATIVE_INT); } -void MasterAttributes::WriteHDF5ThresholdEnergy(::H5::H5File *fd, ::H5::Group *group) { +void MasterAttributes::WriteHDF5ThresholdEnergy(H5::H5File *fd, H5::Group *group) { char c[1024]{}; - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = group->createDataSet("Threshold Energy", - ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&thresholdEnergyeV, ::H5::PredType::NATIVE_INT); - ::H5::DataSpace dataspaceAttr = ::H5::DataSpace(H5S_SCALAR); - ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); - ::H5::Attribute attribute = + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = group->createDataSet("Threshold Energy", + H5::PredType::NATIVE_INT, dataspace); + dataset.write(&thresholdEnergyeV, H5::PredType::NATIVE_INT); + H5::DataSpace dataspaceAttr = H5::DataSpace(H5S_SCALAR); + H5::StrType strdatatype(H5::PredType::C_S1, 256); + H5::Attribute attribute = dataset.createAttribute("Unit", strdatatype, dataspaceAttr); strcpy_safe(c, "eV"); attribute.write(strdatatype, c); } -void MasterAttributes::WriteHDF5ThresholdEnergies(::H5::H5File *fd, ::H5::Group *group) { +void MasterAttributes::WriteHDF5ThresholdEnergies(H5::H5File *fd, H5::Group *group) { char c[1024]{}; - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::StrType strdatatype(::H5::PredType::C_S1, 1024); - ::H5::DataSet dataset = + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::StrType strdatatype(H5::PredType::C_S1, 1024); + H5::DataSet dataset = group->createDataSet("Threshold Energies", strdatatype, dataspace); strcpy_safe(c, ToString(thresholdAllEnergyeV)); dataset.write(c, strdatatype); } -void MasterAttributes::WriteHDF5SubExpTime(::H5::H5File *fd, ::H5::Group *group) { +void MasterAttributes::WriteHDF5SubExpTime(H5::H5File *fd, H5::Group *group) { char c[1024]{}; - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); - ::H5::DataSet dataset = + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::StrType strdatatype(H5::PredType::C_S1, 256); + H5::DataSet dataset = group->createDataSet("Sub Exposure Time", strdatatype, dataspace); strcpy_safe(c, ToString(subExptime)); dataset.write(c, strdatatype); } -void MasterAttributes::WriteHDF5SubPeriod(::H5::H5File *fd, ::H5::Group *group) { +void MasterAttributes::WriteHDF5SubPeriod(H5::H5File *fd, H5::Group *group) { char c[1024]{}; - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); - ::H5::DataSet dataset = + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::StrType strdatatype(H5::PredType::C_S1, 256); + H5::DataSet dataset = group->createDataSet("Sub Period", strdatatype, dataspace); strcpy_safe(c, ToString(subPeriod)); dataset.write(c, strdatatype); } -void MasterAttributes::WriteHDF5SubQuad(::H5::H5File *fd, ::H5::Group *group) { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = - group->createDataSet("Quad", ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&quad, ::H5::PredType::NATIVE_INT); +void MasterAttributes::WriteHDF5SubQuad(H5::H5File *fd, H5::Group *group) { + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = + group->createDataSet("Quad", H5::PredType::NATIVE_INT, dataspace); + dataset.write(&quad, H5::PredType::NATIVE_INT); } -void MasterAttributes::WriteHDF5RateCorrections(::H5::H5File *fd, ::H5::Group *group) { +void MasterAttributes::WriteHDF5RateCorrections(H5::H5File *fd, H5::Group *group) { char c[1024]{}; - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::StrType strdatatype(::H5::PredType::C_S1, 1024); - ::H5::DataSet dataset = + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::StrType strdatatype(H5::PredType::C_S1, 1024); + H5::DataSet dataset = group->createDataSet("Rate Corrections", strdatatype, dataspace); strcpy_safe(c, ToString(ratecorr)); dataset.write(c, strdatatype); } -void MasterAttributes::WriteHDF5CounterMask(::H5::H5File *fd, ::H5::Group *group) { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = - group->createDataSet("Counter Mask", ::H5::PredType::STD_U32LE, dataspace); - dataset.write(&counterMask, ::H5::PredType::STD_U32LE); +void MasterAttributes::WriteHDF5CounterMask(H5::H5File *fd, H5::Group *group) { + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = + group->createDataSet("Counter Mask", H5::PredType::STD_U32LE, dataspace); + dataset.write(&counterMask, H5::PredType::STD_U32LE); } -void MasterAttributes::WriteHDF5ExptimeArray(::H5::H5File *fd, ::H5::Group *group) { +void MasterAttributes::WriteHDF5ExptimeArray(H5::H5File *fd, H5::Group *group) { for (int i = 0; i != 3; ++i) { char c[1024]{}; - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); - ::H5::DataSet dataset = + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::StrType strdatatype(H5::PredType::C_S1, 256); + H5::DataSet dataset = group->createDataSet("Exposure Time1", strdatatype, dataspace); strcpy_safe(c, ToString(exptimeArray[i])); dataset.write(c, strdatatype); } } -void MasterAttributes::WriteHDF5GateDelayArray(::H5::H5File *fd, ::H5::Group *group) { +void MasterAttributes::WriteHDF5GateDelayArray(H5::H5File *fd, H5::Group *group) { for (int i = 0; i != 3; ++i) { char c[1024]{}; - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); - ::H5::DataSet dataset = + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::StrType strdatatype(H5::PredType::C_S1, 256); + H5::DataSet dataset = group->createDataSet("Gate Delay1", strdatatype, dataspace); strcpy_safe(c, ToString(gateDelayArray[i])); dataset.write(c, strdatatype); } } -void MasterAttributes::WriteHDF5Gates(::H5::H5File *fd, ::H5::Group *group) { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = - group->createDataSet("Gates", ::H5::PredType::STD_U32LE, dataspace); - dataset.write(&gates, ::H5::PredType::STD_U32LE); +void MasterAttributes::WriteHDF5Gates(H5::H5File *fd, H5::Group *group) { + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = + group->createDataSet("Gates", H5::PredType::STD_U32LE, dataspace); + dataset.write(&gates, H5::PredType::STD_U32LE); } -void MasterAttributes::WriteHDF5BurstMode(::H5::H5File *fd, ::H5::Group *group) { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::StrType strdatatype(::H5::PredType::C_S1, 256); - ::H5::DataSet dataset = +void MasterAttributes::WriteHDF5BurstMode(H5::H5File *fd, H5::Group *group) { + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::StrType strdatatype(H5::PredType::C_S1, 256); + H5::DataSet dataset = group->createDataSet("Burst Mode", strdatatype, dataspace); char c[1024]{}; strcpy_safe(c, ToString(burstMode)); dataset.write(c, strdatatype); } -void MasterAttributes::WriteHDF5AdcMask(::H5::H5File *fd, ::H5::Group *group) { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = - group->createDataSet("ADC Mask", ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&adcmask, ::H5::PredType::NATIVE_INT); +void MasterAttributes::WriteHDF5AdcMask(H5::H5File *fd, H5::Group *group) { + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = + group->createDataSet("ADC Mask", H5::PredType::NATIVE_INT, dataspace); + dataset.write(&adcmask, H5::PredType::NATIVE_INT); } -void MasterAttributes::WriteHDF5AnalogFlag(::H5::H5File *fd, ::H5::Group *group) { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = - group->createDataSet("Analog Flag", ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&analog, ::H5::PredType::NATIVE_INT); +void MasterAttributes::WriteHDF5AnalogFlag(H5::H5File *fd, H5::Group *group) { + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = + group->createDataSet("Analog Flag", H5::PredType::NATIVE_INT, dataspace); + dataset.write(&analog, H5::PredType::NATIVE_INT); } -void MasterAttributes::WriteHDF5AnalogSamples(::H5::H5File *fd, ::H5::Group *group) { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = - group->createDataSet("Analog Samples", ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&analogSamples, ::H5::PredType::NATIVE_INT); +void MasterAttributes::WriteHDF5AnalogSamples(H5::H5File *fd, H5::Group *group) { + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = + group->createDataSet("Analog Samples", H5::PredType::NATIVE_INT, dataspace); + dataset.write(&analogSamples, H5::PredType::NATIVE_INT); } -void MasterAttributes::WriteHDF5DigitalFlag(::H5::H5File *fd, ::H5::Group *group) { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = - group->createDataSet("Digital Flag", ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&digital, ::H5::PredType::NATIVE_INT); +void MasterAttributes::WriteHDF5DigitalFlag(H5::H5File *fd, H5::Group *group) { + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = + group->createDataSet("Digital Flag", H5::PredType::NATIVE_INT, dataspace); + dataset.write(&digital, H5::PredType::NATIVE_INT); } -void MasterAttributes::WriteHDF5DigitalSamples(::H5::H5File *fd, ::H5::Group *group) { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = group->createDataSet("Digital Samples", - ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&digitalSamples, ::H5::PredType::NATIVE_INT); +void MasterAttributes::WriteHDF5DigitalSamples(H5::H5File *fd, H5::Group *group) { + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = group->createDataSet("Digital Samples", + H5::PredType::NATIVE_INT, dataspace); + dataset.write(&digitalSamples, H5::PredType::NATIVE_INT); } -void MasterAttributes::WriteHDF5DbitOffset(::H5::H5File *fd, ::H5::Group *group) { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = - group->createDataSet("Dbit Offset", ::H5::PredType::NATIVE_INT, dataspace); - dataset.write(&dbitoffset, ::H5::PredType::NATIVE_INT); +void MasterAttributes::WriteHDF5DbitOffset(H5::H5File *fd, H5::Group *group) { + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = + group->createDataSet("Dbit Offset", H5::PredType::NATIVE_INT, dataspace); + dataset.write(&dbitoffset, H5::PredType::NATIVE_INT); } -void MasterAttributes::WriteHDF5DbitList(::H5::H5File *fd, ::H5::Group *group) { - ::H5::DataSpace dataspace = ::H5::DataSpace(H5S_SCALAR); - ::H5::DataSet dataset = group->createDataSet("Dbit Bitset List", - ::H5::PredType::STD_U64LE, dataspace); - dataset.write(&dbitlist, ::H5::PredType::STD_U64LE); +void MasterAttributes::WriteHDF5DbitList(H5::H5File *fd, H5::Group *group) { + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = group->createDataSet("Dbit Bitset List", + H5::PredType::STD_U64LE, dataspace); + dataset.write(&dbitlist, H5::PredType::STD_U64LE); } #endif @@ -586,7 +586,7 @@ void MasterAttributes::GetGotthardBinaryAttributes( }; #ifdef HDF5C -void MasterAttributes::WriteGotthardHDF5Attributes(::H5::H5File *fd, ::H5::Group *group) { +void MasterAttributes::WriteGotthardHDF5Attributes(H5::H5File *fd, H5::Group *group) { MasterAttributes::WriteHDF5Exptime(fd, group); MasterAttributes::WriteHDF5Period(fd, group); MasterAttributes::WriteHDF5ROI(fd, group); @@ -606,7 +606,7 @@ void MasterAttributes::GetJungfrauBinaryAttributes( } #ifdef HDF5C -void MasterAttributes::WriteJungfrauHDF5Attributes(::H5::H5File *fd, ::H5::Group *group) { +void MasterAttributes::WriteJungfrauHDF5Attributes(H5::H5File *fd, H5::Group *group) { MasterAttributes::WriteHDF5Exptime(fd, group); MasterAttributes::WriteHDF5Period(fd, group); MasterAttributes::WriteHDF5NumUDPInterfaces(fd, group); @@ -639,7 +639,7 @@ void MasterAttributes::GetEigerBinaryAttributes( } #ifdef HDF5C -void MasterAttributes::WriteEigerHDF5Attributes(::H5::H5File *fd, ::H5::Group *group) { +void MasterAttributes::WriteEigerHDF5Attributes(H5::H5File *fd, H5::Group *group) { MasterAttributes::WriteHDF5DynamicRange(fd, group); MasterAttributes::WriteHDF5TenGiga(fd, group); MasterAttributes::WriteHDF5Exptime(fd, group); @@ -678,7 +678,7 @@ void MasterAttributes::GetMythen3BinaryAttributes( } #ifdef HDF5C -void MasterAttributes::WriteMythen3HDF5Attributes(::H5::H5File *fd, ::H5::Group *group) { +void MasterAttributes::WriteMythen3HDF5Attributes(H5::H5File *fd, H5::Group *group) { MasterAttributes::WriteHDF5DynamicRange(fd, group); MasterAttributes::WriteHDF5TenGiga(fd, group); MasterAttributes::WriteHDF5Period(fd, group); @@ -701,7 +701,7 @@ void MasterAttributes::GetGotthard2BinaryAttributes( } #ifdef HDF5C -void MasterAttributes::WriteGotthard2HDF5Attributes(::H5::H5File *fd, ::H5::Group *group) { +void MasterAttributes::WriteGotthard2HDF5Attributes(H5::H5File *fd, H5::Group *group) { MasterAttributes::WriteHDF5Exptime(fd, group); MasterAttributes::WriteHDF5Period(fd, group); MasterAttributes::WriteHDF5BurstMode(fd, group); @@ -723,7 +723,7 @@ void MasterAttributes::GetMoenchBinaryAttributes( } #ifdef HDF5C -void MasterAttributes::WriteMoenchHDF5Attributes(::H5::H5File *fd, ::H5::Group *group) { +void MasterAttributes::WriteMoenchHDF5Attributes(H5::H5File *fd, H5::Group *group) { MasterAttributes::WriteHDF5Exptime(fd, group); MasterAttributes::WriteHDF5Period(fd, group); MasterAttributes::WriteHDF5TenGiga(fd, group); @@ -757,7 +757,7 @@ void MasterAttributes::GetCtbBinaryAttributes( } #ifdef HDF5C -void MasterAttributes::WriteCtbHDF5Attributes(::H5::H5File *fd, ::H5::Group *group) { +void MasterAttributes::WriteCtbHDF5Attributes(H5::H5File *fd, H5::Group *group) { MasterAttributes::WriteHDF5Exptime(fd, group); MasterAttributes::WriteHDF5Period(fd, group); MasterAttributes::WriteHDF5TenGiga(fd, group); diff --git a/slsReceiverSoftware/src/MasterAttributes.h b/slsReceiverSoftware/src/MasterAttributes.h index 904512061..89dd4d1b1 100644 --- a/slsReceiverSoftware/src/MasterAttributes.h +++ b/slsReceiverSoftware/src/MasterAttributes.h @@ -71,7 +71,7 @@ class MasterAttributes { void GetBinaryAttributes(rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteHDF5Attributes(::H5::H5File *fd, ::H5::Group *group); + void WriteHDF5Attributes(H5::H5File *fd, H5::Group *group); #endif void GetCommonBinaryAttributes( @@ -79,75 +79,75 @@ class MasterAttributes { void GetFinalBinaryAttributes( rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteCommonHDF5Attributes(::H5::H5File *fd, ::H5::Group *group); - void WriteFinalHDF5Attributes(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5Exptime(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5Period(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5DynamicRange(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5TenGiga(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5ROI(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5NumUDPInterfaces(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5ReadNRows(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5ThresholdEnergy(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5ThresholdEnergies(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5SubExpTime(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5SubPeriod(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5SubQuad(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5RateCorrections(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5CounterMask(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5ExptimeArray(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5GateDelayArray(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5Gates(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5BurstMode(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5AdcMask(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5AnalogFlag(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5AnalogSamples(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5DigitalFlag(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5DigitalSamples(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5DbitOffset(::H5::H5File *fd, ::H5::Group *group); - void WriteHDF5DbitList(::H5::H5File *fd, ::H5::Group *group); + void WriteCommonHDF5Attributes(H5::H5File *fd, H5::Group *group); + void WriteFinalHDF5Attributes(H5::H5File *fd, H5::Group *group); + void WriteHDF5Exptime(H5::H5File *fd, H5::Group *group); + void WriteHDF5Period(H5::H5File *fd, H5::Group *group); + void WriteHDF5DynamicRange(H5::H5File *fd, H5::Group *group); + void WriteHDF5TenGiga(H5::H5File *fd, H5::Group *group); + void WriteHDF5ROI(H5::H5File *fd, H5::Group *group); + void WriteHDF5NumUDPInterfaces(H5::H5File *fd, H5::Group *group); + void WriteHDF5ReadNRows(H5::H5File *fd, H5::Group *group); + void WriteHDF5ThresholdEnergy(H5::H5File *fd, H5::Group *group); + void WriteHDF5ThresholdEnergies(H5::H5File *fd, H5::Group *group); + void WriteHDF5SubExpTime(H5::H5File *fd, H5::Group *group); + void WriteHDF5SubPeriod(H5::H5File *fd, H5::Group *group); + void WriteHDF5SubQuad(H5::H5File *fd, H5::Group *group); + void WriteHDF5RateCorrections(H5::H5File *fd, H5::Group *group); + void WriteHDF5CounterMask(H5::H5File *fd, H5::Group *group); + void WriteHDF5ExptimeArray(H5::H5File *fd, H5::Group *group); + void WriteHDF5GateDelayArray(H5::H5File *fd, H5::Group *group); + void WriteHDF5Gates(H5::H5File *fd, H5::Group *group); + void WriteHDF5BurstMode(H5::H5File *fd, H5::Group *group); + void WriteHDF5AdcMask(H5::H5File *fd, H5::Group *group); + void WriteHDF5AnalogFlag(H5::H5File *fd, H5::Group *group); + void WriteHDF5AnalogSamples(H5::H5File *fd, H5::Group *group); + void WriteHDF5DigitalFlag(H5::H5File *fd, H5::Group *group); + void WriteHDF5DigitalSamples(H5::H5File *fd, H5::Group *group); + void WriteHDF5DbitOffset(H5::H5File *fd, H5::Group *group); + void WriteHDF5DbitList(H5::H5File *fd, H5::Group *group); #endif void GetGotthardBinaryAttributes( rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteGotthardHDF5Attributes(::H5::H5File *fd, ::H5::Group *group); + void WriteGotthardHDF5Attributes(H5::H5File *fd, H5::Group *group); #endif void GetJungfrauBinaryAttributes( rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteJungfrauHDF5Attributes(::H5::H5File *fd, ::H5::Group *group); + void WriteJungfrauHDF5Attributes(H5::H5File *fd, H5::Group *group); #endif void GetEigerBinaryAttributes( rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteEigerHDF5Attributes(::H5::H5File *fd, ::H5::Group *group); + void WriteEigerHDF5Attributes(H5::H5File *fd, H5::Group *group); #endif void GetMythen3BinaryAttributes( rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteMythen3HDF5Attributes(::H5::H5File *fd, ::H5::Group *group); + void WriteMythen3HDF5Attributes(H5::H5File *fd, H5::Group *group); #endif void GetGotthard2BinaryAttributes( rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteGotthard2HDF5Attributes(::H5::H5File *fd, ::H5::Group *group); + void WriteGotthard2HDF5Attributes(H5::H5File *fd, H5::Group *group); #endif void GetMoenchBinaryAttributes( rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteMoenchHDF5Attributes(::H5::H5File *fd, ::H5::Group *group); + void WriteMoenchHDF5Attributes(H5::H5File *fd, H5::Group *group); #endif void GetCtbBinaryAttributes(rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteCtbHDF5Attributes(::H5::H5File *fd, ::H5::Group *group); + void WriteCtbHDF5Attributes(H5::H5File *fd, H5::Group *group); #endif }; diff --git a/slsReceiverSoftware/src/MasterFileUtility.cpp b/slsReceiverSoftware/src/MasterFileUtility.cpp index b0052e82f..2cf48c319 100644 --- a/slsReceiverSoftware/src/MasterFileUtility.cpp +++ b/slsReceiverSoftware/src/MasterFileUtility.cpp @@ -49,30 +49,29 @@ std::string CreateMasterBinaryFile(const std::string &filePath, #ifdef HDF5C void LinkHDF5FileInMaster(std::string &masterFileName, std::string &dataFilename, - std::string &dataSetname, std::vector parameterNames, const bool silentMode, std::mutex *hdf5LibMutex) { std::lock_guard lock(*hdf5LibMutex); - std::unique_ptr<::H5::H5File> fd{nullptr}; + std::unique_ptr fd{nullptr}; try { - ::H5::Exception::dontPrint(); // to handle errors + H5::Exception::dontPrint(); // to handle errors - ::H5::FileAccPropList flist; + H5::FileAccPropList flist; flist.setFcloseDegree(H5F_CLOSE_STRONG); // open master file - ::H5::H5File masterfd(masterFileName.c_str(), H5F_ACC_RDWR, - ::H5::FileCreatPropList::DEFAULT, flist); + H5::H5File masterfd(masterFileName.c_str(), H5F_ACC_RDWR, + H5::FileCreatPropList::DEFAULT, flist); // open data file - fd = make_unique<::H5::H5File>(dataFilename.c_str(), H5F_ACC_RDONLY, - ::H5::FileCreatPropList::DEFAULT, flist); + fd = make_unique(dataFilename.c_str(), H5F_ACC_RDONLY, + H5::FileCreatPropList::DEFAULT, flist); // create link for data dataset - ::H5::DataSet dset = fd->openDataSet(dataSetname.c_str()); - std::string linkname = std::string("/entry/data/") + dataSetname; - if (H5Lcreate_external(dataFilename.c_str(), dataSetname.c_str(), + H5::DataSet dset = fd->openDataSet(DATASET_NAME); + std::string linkname = std::string("/entry/data/") + std::string(DATASET_NAME); + if (H5Lcreate_external(dataFilename.c_str(), DATASET_NAME, masterfd.getLocId(), linkname.c_str(), H5P_DEFAULT, H5P_DEFAULT) < 0) { throw RuntimeError( @@ -81,7 +80,7 @@ void LinkHDF5FileInMaster(std::string &masterFileName, // create link for parameter datasets for (unsigned int i = 0; i < parameterNames.size(); ++i) { - ::H5::DataSet pDset = fd->openDataSet(parameterNames[i].c_str()); + H5::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(), @@ -93,7 +92,7 @@ void LinkHDF5FileInMaster(std::string &masterFileName, } fd->close(); masterfd.close(); - } catch (const ::H5::Exception &error) { + } catch (const H5::Exception &error) { error.printErrorStack(); if (fd != nullptr) fd->close(); @@ -118,38 +117,38 @@ std::string CreateMasterHDF5File(const std::string &filePath, std::lock_guard lock(*hdf5LibMutex); - std::unique_ptr<::H5::H5File> fd{nullptr}; + std::unique_ptr fd{nullptr}; try { - ::H5::Exception::dontPrint(); // to handle errors + H5::Exception::dontPrint(); // to handle errors - ::H5::FileAccPropList flist; + H5::FileAccPropList flist; flist.setFcloseDegree(H5F_CLOSE_STRONG); unsigned int createFlags = H5F_ACC_EXCL; if (overWriteEnable) { createFlags = H5F_ACC_TRUNC; } - fd = make_unique<::H5::H5File>(fileName.c_str(), createFlags, - ::H5::FileCreatPropList::DEFAULT, flist); + fd = make_unique(fileName.c_str(), createFlags, + H5::FileCreatPropList::DEFAULT, flist); // attributes - version double dValue = HDF5_WRITER_VERSION; - ::H5::DataSpace dataspace_attr = ::H5::DataSpace(H5S_SCALAR); - ::H5::Attribute attribute = fd->createAttribute( - "version", ::H5::PredType::NATIVE_DOUBLE, dataspace_attr); - attribute.write(::H5::PredType::NATIVE_DOUBLE, &dValue); + H5::DataSpace dataspace_attr = H5::DataSpace(H5S_SCALAR); + H5::Attribute attribute = fd->createAttribute( + "version", H5::PredType::NATIVE_DOUBLE, dataspace_attr); + attribute.write(H5::PredType::NATIVE_DOUBLE, &dValue); // Create a group in the file - ::H5::Group group1(fd->createGroup("entry")); - ::H5::Group group2(group1.createGroup("data")); - ::H5::Group group3(group1.createGroup("instrument")); - ::H5::Group group4(group3.createGroup("beam")); - ::H5::Group group5(group3.createGroup("detector")); - ::H5::Group group6(group1.createGroup("sample")); + H5::Group group1(fd->createGroup("entry")); + H5::Group group2(group1.createGroup("data")); + H5::Group group3(group1.createGroup("instrument")); + H5::Group group4(group3.createGroup("beam")); + H5::Group group5(group3.createGroup("detector")); + H5::Group group6(group1.createGroup("sample")); attr->WriteHDF5Attributes(fd.get(), &group5); fd->close(); - } catch (const ::H5::Exception &error) { + } catch (const H5::Exception &error) { error.printErrorStack(); if (fd != nullptr) fd->close(); @@ -162,16 +161,16 @@ std::string CreateMasterHDF5File(const std::string &filePath, return fileName; } -std::array CreateVirtualHDF5File( +std::string CreateVirtualHDF5File( 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 maxFramesPerFile, const uint32_t nPixelsX, const uint32_t nPixelsY, const uint32_t dynamicRange, const uint64_t numImagesCaught, - const int numModX, const int numModY, const ::H5::DataType dataType, + const int numModX, const int numModY, const H5::DataType dataType, const std::vector parameterNames, - const std::vector<::H5::DataType> parameterDataTypes, std::mutex *hdf5LibMutex, + const std::vector parameterDataTypes, std::mutex *hdf5LibMutex, bool gotthard25um) { // virtual file name @@ -180,8 +179,6 @@ std::array CreateVirtualHDF5File( << "_" << fileIndex << ".h5"; std::string fileName = osfn.str(); - std::string dataSetName = "data"; - unsigned int paraSize = parameterNames.size(); uint64_t numModZ = numModX; uint32_t nDimy = nPixelsY; @@ -189,42 +186,42 @@ std::array CreateVirtualHDF5File( std::lock_guard lock(*hdf5LibMutex); - std::unique_ptr<::H5::H5File> fd{nullptr}; + std::unique_ptr fd{nullptr}; try { - ::H5::Exception::dontPrint(); // to handle errors + H5::Exception::dontPrint(); // to handle errors // file - ::H5::FileAccPropList fapl; + H5::FileAccPropList fapl; fapl.setFcloseDegree(H5F_CLOSE_STRONG); if (!overWriteEnable) - fd = make_unique<::H5::H5File>(fileName.c_str(), H5F_ACC_EXCL, - ::H5::FileCreatPropList::DEFAULT, fapl); + fd = make_unique(fileName.c_str(), H5F_ACC_EXCL, + H5::FileCreatPropList::DEFAULT, fapl); else - fd = make_unique<::H5::H5File>(fileName.c_str(), H5F_ACC_TRUNC, - ::H5::FileCreatPropList::DEFAULT, fapl); + fd = make_unique(fileName.c_str(), H5F_ACC_TRUNC, + H5::FileCreatPropList::DEFAULT, fapl); // attributes - version double dValue = HDF5_WRITER_VERSION; - ::H5::DataSpace dataspace_attr = ::H5::DataSpace(H5S_SCALAR); - ::H5::Attribute attribute = fd->createAttribute( - "version", ::H5::PredType::NATIVE_DOUBLE, dataspace_attr); - attribute.write(::H5::PredType::NATIVE_DOUBLE, &dValue); + H5::DataSpace dataspace_attr = H5::DataSpace(H5S_SCALAR); + H5::Attribute attribute = fd->createAttribute( + "version", H5::PredType::NATIVE_DOUBLE, dataspace_attr); + attribute.write(H5::PredType::NATIVE_DOUBLE, &dValue); // virtual dataspace hsize_t vdsDims[3] = {numImagesCaught, numModY * nDimy, numModZ * nDimz}; - ::H5::DataSpace vdsDataSpace(3, vdsDims, nullptr); + H5::DataSpace vdsDataSpace(3, vdsDims, nullptr); hsize_t vdsDimsPara[2] = {numImagesCaught, (unsigned int)numModY * numModZ}; - ::H5::DataSpace vdsDataSpacePara(2, vdsDimsPara, nullptr); + H5::DataSpace vdsDataSpacePara(2, vdsDimsPara, nullptr); // property list (fill value and datatype) int fill_value = -1; - ::H5::DSetCreatPropList plist; + H5::DSetCreatPropList plist; plist.setFillValue(dataType, &fill_value); // property list for parameters (datatype) - std::vector<::H5::DSetCreatPropList> plistPara(paraSize); + std::vector plistPara(paraSize); // hyperslab (files) int numFiles = numImagesCaught / maxFramesPerFile; @@ -286,24 +283,17 @@ std::array CreateVirtualHDF5File( p + 1, srcFileName.length() - p)); } - // source dataset name - std::ostringstream osfn; - osfn << "/data"; - if (numImages > 1) - osfn << "_f" << std::setfill('0') << std::setw(12) << iFile; - std::string srcDatasetName = osfn.str(); - // source dataspace hsize_t srcDims[3] = {nDimx, nDimy, nDimz}; hsize_t srcDimsMax[3] = {H5S_UNLIMITED, nDimy, nDimz}; - ::H5::DataSpace srcDataSpace(3, srcDims, srcDimsMax); + H5::DataSpace srcDataSpace(3, srcDims, srcDimsMax); hsize_t srcDimsPara[1] = {nDimx}; hsize_t srcDimsMaxPara[1] = {H5S_UNLIMITED}; - ::H5::DataSpace srcDataSpacePara(1, srcDimsPara, srcDimsMaxPara); + H5::DataSpace srcDataSpacePara(1, srcDimsPara, srcDimsMaxPara); // mapping of property list plist.setVirtual(vdsDataSpace, relative_srcFileName.c_str(), - srcDatasetName.c_str(), srcDataSpace); + DATASET_NAME, srcDataSpace); for (unsigned int p = 0; p < paraSize; ++p) { plistPara[p].setVirtual( vdsDataSpacePara, relative_srcFileName.c_str(), @@ -325,17 +315,17 @@ std::array CreateVirtualHDF5File( framesSaved += nDimx; } // datasets - ::H5::DataSet vdsDataSet(fd->createDataSet(dataSetName.c_str(), dataType, + H5::DataSet vdsDataSet(fd->createDataSet(DATASET_NAME, dataType, vdsDataSpace, plist)); for (unsigned int p = 0; p < paraSize; ++p) { - ::H5::DataSet vdsDataSetPara(fd->createDataSet( + H5::DataSet vdsDataSetPara(fd->createDataSet( parameterNames[p].c_str(), parameterDataTypes[p], vdsDataSpacePara, plistPara[p])); } fd->close(); - } catch (const ::H5::Exception &error) { + } catch (const H5::Exception &error) { error.printErrorStack(); if (fd) { fd->close(); @@ -346,7 +336,7 @@ std::array CreateVirtualHDF5File( if (!silentMode) { LOG(logINFO) << "Virtual File: " << fileName; } - return std::array{fileName, dataSetName}; + return fileName; } #endif diff --git a/slsReceiverSoftware/src/MasterFileUtility.h b/slsReceiverSoftware/src/MasterFileUtility.h index 3aa2427a5..bbce2f4e5 100644 --- a/slsReceiverSoftware/src/MasterFileUtility.h +++ b/slsReceiverSoftware/src/MasterFileUtility.h @@ -23,7 +23,6 @@ std::string CreateMasterBinaryFile(const std::string &filePath, #ifdef HDF5C void LinkHDF5FileInMaster(std::string &masterFileName, std::string &dataFilename, - std::string &dataSetname, std::vector parameterNames, const bool silentMode, std::mutex *hdf5LibMutex); @@ -34,16 +33,16 @@ std::string CreateMasterHDF5File(const std::string &filePath, const bool silentMode, MasterAttributes *attr, std::mutex *hdf5LibMutex); -std::array CreateVirtualHDF5File( +std::string CreateVirtualHDF5File( 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 maxFramesPerFile, const uint32_t nPixelsX, const uint32_t nPixelsY, const uint32_t dynamicRange, const uint64_t numImagesCaught, - const int numModX, const int numModY, const ::H5::DataType dataType, + const int numModX, const int numModY, const H5::DataType dataType, const std::vector parameterNames, - const std::vector<::H5::DataType> parameterDataTypes, std::mutex *hdf5LibMutex, + const std::vector parameterDataTypes, std::mutex *hdf5LibMutex, bool gotthard25um); #endif } // namespace masterFileUtility diff --git a/slsReceiverSoftware/src/receiver_defs.h b/slsReceiverSoftware/src/receiver_defs.h index 884005593..21dfeaa1a 100644 --- a/slsReceiverSoftware/src/receiver_defs.h +++ b/slsReceiverSoftware/src/receiver_defs.h @@ -59,4 +59,7 @@ namespace sls { #define TCP_PRIORITY (10) +#ifdef HDF5C +#define DATASET_NAME "/data" +#endif } // namespace sls From 5490daa0a134aa127cf6555d170f0a7d4fb5fea6 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil <33750417+thattil@users.noreply.github.com> Date: Thu, 9 Jun 2022 13:42:18 +0200 Subject: [PATCH 7/8] storagecells not updated in rx and allowing it in idle mode (#485) --- RELEASE.txt | 1 + slsDetectorSoftware/src/Module.cpp | 3 +++ slsReceiverSoftware/src/ClientInterface.cpp | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/RELEASE.txt b/RELEASE.txt index d97c17c88..0cd4c5f26 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -82,6 +82,7 @@ This document describes the differences between v7.0.0 and v6.x.x - rxr mem size changed (fifo header size from 8 to 16) due to sls rxr header = 112.. 112+ 16=128 (reduces packet losss especially for g2) -udp_srcip and udp_Srcip2: can set to auto (for virtual or 1g data networks) - set dataset name for all hdf5 files to "data" only +- number of storage cells is not updated in teh receiver. done. and also allowing it to be modified in running status 2. Resolved Issues ================== diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 8fb5477cb..05e59c420 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -1768,6 +1768,9 @@ int Module::getNumberOfAdditionalStorageCells() const { void Module::setNumberOfAdditionalStorageCells(int value) { sendToDetector(F_SET_NUM_ADDITIONAL_STORAGE_CELLS, value, nullptr); + if (shm()->useReceiverFlag) { + sendToReceiver(F_SET_RECEIVER_NUM_ADD_STORAGE_CELLS, value, nullptr); + } } int Module::getStorageCellStart() const { diff --git a/slsReceiverSoftware/src/ClientInterface.cpp b/slsReceiverSoftware/src/ClientInterface.cpp index 280ed77a9..c17accb2a 100644 --- a/slsReceiverSoftware/src/ClientInterface.cpp +++ b/slsReceiverSoftware/src/ClientInterface.cpp @@ -581,7 +581,7 @@ int ClientInterface::set_num_add_storage_cells(Interface &socket) { throw RuntimeError("Invalid number of additional storage cells " + std::to_string(value)); } - verifyIdle(socket); + // allowing this to be done even when receiver not idle LOG(logDEBUG1) << "Setting num additional storage cells to " << value; impl()->setNumberOfAdditionalStorageCells(value); return socket.Send(OK); From aa93aed4ed6d557e7389f356ddc08a2c32a6e1cb Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Thu, 9 Jun 2022 13:50:41 +0200 Subject: [PATCH 8/8] updated client versioning --- slsSupportLib/include/sls/versionAPI.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/slsSupportLib/include/sls/versionAPI.h b/slsSupportLib/include/sls/versionAPI.h index 8a8bda755..fb0049e27 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -2,9 +2,6 @@ // Copyright (C) 2021 Contributors to the SLS Detector Package /** API versions */ #define GITBRANCH "developer" -#define APILIB 0x220408 -#define APIRECEIVER 0x220408 -#define APIGUI 0x220328 #define APICTB 0x220524 #define APIGOTTHARD 0x220524 #define APIJUNGFRAU 0x220524 @@ -12,3 +9,6 @@ #define APIEIGER 0x220524 #define APIGOTTHARD2 0x220602 #define APIMYTHEN3 0x220607 +#define APILIB 0x220609 +#define APIRECEIVER 0x220609 +#define APIGUI 0x220609