M3settings (#228)

* added temp m3 settings files

* renames settings noise to trim

* get threshold for M3

* some changes to compile on RH7 and in the server to load the default chip status register at startup

* Updated mythen3DeectorServer_developer executable with correct initialization at startup

Co-authored-by: Erik Frojdh <erik.frojdh@gmail.com>
Co-authored-by: Anna Bergamaschi <anna.bergamaschi@psi.ch>
This commit is contained in:
Dhanya Thattil
2021-01-14 12:34:13 +01:00
committed by GitHub
parent a62e068a9a
commit f9f50f1d84
89 changed files with 1715 additions and 8446 deletions

View File

@ -110,7 +110,7 @@ class Detector {
/** list of possible settings for this detector */
std::vector<defs::detectorSettings> getSettingsList() const;
/** [Jungfrau][Gotthard][Gotthard2] */
/** [Jungfrau][Gotthard][Gotthard2][Mythen3] */
Result<defs::detectorSettings> getSettings(Positions pos = {}) const;
/** [Jungfrau] DYNAMICGAIN, DYNAMICHG0, FIXGAIN1, FIXGAIN2,
@ -118,12 +118,34 @@ class Detector {
* LOWGAIN, MEDIUMGAIN, VERYHIGHGAIN \n [Gotthard2] DYNAMICGAIN,
* FIXGAIN1, FIXGAIN2 \n [Moench] G1_HIGHGAIN, G1_LOWGAIN,
* G2_HIGHCAP_HIGHGAIN, G2_HIGHCAP_LOWGAIN, G2_LOWCAP_HIGHGAIN,
* G2_LOWCAP_LOWGAIN, G4_HIGHGAIN, G4_LOWGAIN \n [Eiger] Use threshold
* command. Settings loaded from file found in
* settingspath
* G2_LOWCAP_LOWGAIN, G4_HIGHGAIN, G4_LOWGAIN \n [Mythen3] STANDARD, FAST,
* HIGHGAIN. Also changes vrshaper and vrpreamp \n [Eiger] Use threshold
* command. Settings loaded from file found in settingspath
*/
void setSettings(defs::detectorSettings value, Positions pos = {});
/** [Eiger] */
Result<int> getThresholdEnergy(Positions pos = {}) const;
/** Mythen3] threshold energy for the three counters */
Result<std::array<int, 3>> getAllThresholdEnergy(Positions pos = {}) const;
/** [Eiger][Mythen3] It loads trim files from settingspath */
void setThresholdEnergy(int threshold_ev,
defs::detectorSettings settings = defs::STANDARD,
bool trimbits = true, Positions pos = {});
/** [Mythen3] It loads trim files from settingspath */
void setThresholdEnergy(std::array<int, 3> threshold_ev,
defs::detectorSettings settings = defs::STANDARD,
bool trimbits = true, Positions pos = {});
/** [Eiger][Mythen3] */
Result<std::string> getSettingsPath(Positions pos = {}) const;
/** [Eiger][Mythen3] Directory where settings files are loaded from/to */
void setSettingsPath(const std::string &value, Positions pos = {});
/** [Eiger][Mythen3] If no extension specified, serial number of each module
* is attached. */
void loadTrimbits(const std::string &fname, Positions pos = {});
@ -134,6 +156,13 @@ class Detector {
/**[Eiger][Mythen3] */
void setAllTrimbits(int value, Positions pos = {});
/**[Eiger][Mythen3] Returns energies in eV where the module is trimmed */
Result<std::vector<int>> getTrimEnergies(Positions pos = {}) const;
/** [Eiger][Mythen3] List of trim energies, where corresponding default trim
* files exist in corresponding trim folders */
void setTrimEnergies(std::vector<int> energies, Positions pos = {});
/**[Eiger][Jungfrau] */
bool getGapPixelsinCallback() const;
@ -940,20 +969,6 @@ class Detector {
/** [Eiger] in 32 bit mode */
void setSubDeadTime(ns value, Positions pos = {});
/** [Eiger] */
Result<int> getThresholdEnergy(Positions pos = {}) const;
/** [Eiger] It loads trim files from settingspath */
void setThresholdEnergy(int threshold_ev,
defs::detectorSettings settings = defs::STANDARD,
bool trimbits = true, Positions pos = {});
/** [Eiger] */
Result<std::string> getSettingsPath(Positions pos = {}) const;
/** [Eiger] Directory where settings files are loaded from/to */
void setSettingsPath(const std::string &value, Positions pos = {});
/** [Eiger] */
Result<bool> getOverFlowMode(Positions pos = {}) const;
@ -966,13 +981,6 @@ class Detector {
/** [Eiger] for client call back (gui) purposes to flip bottom image */
void setBottom(bool value, Positions pos = {});
/**[Eiger] Returns energies in eV where the module is trimmed */
Result<std::vector<int>> getTrimEnergies(Positions pos = {}) const;
/** [Eiger] List of trim energies, where corresponding default trim files
* exist in corresponding trim folders */
void setTrimEnergies(std::vector<int> energies, Positions pos = {});
/** [Eiger] deadtime in ns, 0 = disabled */
Result<ns> getRateCorrection(Positions pos = {}) const;

View File

@ -356,6 +356,119 @@ std::string CmdProxy::DetectorSize(int action) {
return os.str();
}
std::string CmdProxy::Threshold(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[eV] [(optinal settings)"
"\n\t[Eiger][Mythen3] Threshold in eV. It loads trim files from "
"settingspath.";
if (cmd == "thresholdnotb") {
os << "Trimbits are not loaded.";
}
os << "\n\nthreshold [eV1] [eV2] [eV3] [(optional settings)]"
"\n\t[Mythen3] Threshold in eV for each counter. It loads trim "
"files from "
"settingspath.";
if (cmd == "thresholdnotb") {
os << "Trimbits are not loaded.";
}
os << '\n';
} else if (action == defs::GET_ACTION) {
if (cmd == "thresholdnotb") {
throw sls::RuntimeError("cannot get");
}
if (!args.empty()) {
WrongNumberOfParameters(0);
}
defs::detectorType type = det->getDetectorType().squash();
if (type == defs::EIGER) {
auto t = det->getThresholdEnergy(std::vector<int>{det_id});
os << OutString(t) << '\n';
} else if (type == defs::MYTHEN3) {
auto t = det->getAllThresholdEnergy(std::vector<int>{det_id});
os << OutString(t) << '\n';
} else {
throw RuntimeError("Not implemented for this detector\n");
}
} else if (action == defs::PUT_ACTION) {
defs::detectorType type = det->getDetectorType().squash();
if (type == defs::EIGER && args.size() != 1 && args.size() != 2) {
WrongNumberOfParameters(1);
}
if (type == defs::MYTHEN3 && (args.size() < 1 || args.size() > 4)) {
WrongNumberOfParameters(1);
}
bool trimbits = (cmd == "thresholdnotb") ? false : true;
std::array<int, 3> energy = {StringTo<int>(args[0]), 0, 0};
energy[1] = energy[0];
energy[2] = energy[0];
defs::detectorSettings sett = defs::STANDARD;
// check if argument has settings or get it
if (args.size() == 2 || args.size() == 4) {
sett = StringTo<defs::detectorSettings>(args[args.size() - 1]);
} else {
sett = det->getSettings(std::vector<int>{det_id})
.tsquash("Inconsistent settings between detectors");
}
// get other threshold values
if (args.size() > 2) {
energy[1] = StringTo<int>(args[1]);
energy[2] = StringTo<int>(args[2]);
}
switch (type) {
case defs::EIGER:
det->setThresholdEnergy(energy[0], sett, trimbits,
std::vector<int>{det_id});
break;
case defs::MYTHEN3:
det->setThresholdEnergy(energy, sett, trimbits,
std::vector<int>{det_id});
break;
default:
throw RuntimeError("Not implemented for this detector\n");
}
os << ToString(args) << '\n';
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
std::string CmdProxy::TrimEnergies(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[trim_ev1] [trim_Ev2 (optional)] [trim_ev3 (optional)] "
"...\n\t[Eiger][Mythen3] Number of trim energies and list of "
"trim "
"energies, where corresponding default trim files exist in "
"corresponding trim folders."
<< '\n';
} else if (action == defs::GET_ACTION) {
if (!args.empty()) {
WrongNumberOfParameters(0);
}
auto t = det->getTrimEnergies(std::vector<int>{det_id});
os << OutString(t) << '\n';
} else if (action == defs::PUT_ACTION) {
std::vector<int> t(args.size());
if (!args.empty()) {
for (size_t i = 0; i < t.size(); ++i) {
t[i] = StringTo<int>(args[i]);
}
}
det->setTrimEnergies(t, std::vector<int>{det_id});
os << sls::ToString(args) << '\n';
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
std::string CmdProxy::GapPixels(int action) {
std::ostringstream os;
os << cmd << ' ';
@ -1264,103 +1377,6 @@ std::string CmdProxy::ZMQHWM(int action) {
/* Eiger Specific */
std::string CmdProxy::Threshold(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[eV] [(optinal settings) standard, lowgain, veryhighgain, "
"verylowgain]"
"\n\t[Eiger] Threshold in eV. It loads trim files from "
"settingspath."
<< '\n';
} else if (action == defs::GET_ACTION) {
if (!args.empty()) {
WrongNumberOfParameters(0);
}
auto t = det->getThresholdEnergy(std::vector<int>{det_id});
os << OutString(t) << '\n';
} else if (action == defs::PUT_ACTION) {
if (args.size() == 1) {
auto t = det->getSettings(std::vector<int>{det_id})
.tsquash("Inconsistent settings between detectors");
det->setThresholdEnergy(StringTo<int>(args[0]), t, true,
std::vector<int>{det_id});
} else if (args.size() == 2) {
det->setThresholdEnergy(
StringTo<int>(args[0]),
sls::StringTo<slsDetectorDefs::detectorSettings>(args[1]), true,
{det_id});
} else {
WrongNumberOfParameters(1);
}
os << ToString(args) << '\n';
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
std::string CmdProxy::ThresholdNoTb(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[eV] [(optional settings) standard, lowgain, veryhighgain, "
"verylowgain]"
"\n\t[Eiger] Threshold in eV set without setting trimbits"
<< '\n';
} else if (action == defs::GET_ACTION) {
throw sls::RuntimeError("cannot get");
} else if (action == defs::PUT_ACTION) {
if (args.size() == 1) {
auto t = det->getSettings(std::vector<int>{det_id})
.tsquash("Inconsistent settings between detectors");
det->setThresholdEnergy(StringTo<int>(args[0]), t, false,
std::vector<int>{det_id});
} else if (args.size() == 2) {
det->setThresholdEnergy(
StringTo<int>(args[0]),
sls::StringTo<slsDetectorDefs::detectorSettings>(args[1]),
false, std::vector<int>{det_id});
} else {
WrongNumberOfParameters(1);
}
os << ToString(args) << '\n';
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
std::string CmdProxy::TrimEnergies(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[trim_ev1] [trim_Ev2 (optional)] [trim_ev3 (optional)] "
"...\n\t[Eiger] Number of trim energies and list of trim "
"energies, where corresponding default trim files exist in "
"corresponding trim folders."
<< '\n';
} else if (action == defs::GET_ACTION) {
if (!args.empty()) {
WrongNumberOfParameters(0);
}
auto t = det->getTrimEnergies(std::vector<int>{det_id});
os << OutString(t) << '\n';
} else if (action == defs::PUT_ACTION) {
std::vector<int> t(args.size());
if (!args.empty()) {
for (size_t i = 0; i < t.size(); ++i) {
t[i] = StringTo<int>(args[i]);
}
}
det->setTrimEnergies(t, std::vector<int>{det_id});
os << sls::ToString(args) << '\n';
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
std::string CmdProxy::RateCorrection(int action) {
std::ostringstream os;
os << cmd << ' ';

View File

@ -596,6 +596,8 @@ class CmdProxy {
{"detectornumber", "serialnumber"},
{"thisversion", "clientversion"},
{"detsizechan", "detsize"},
{"trimdir", "settingspath"},
{"settingsdir", "settingspath"},
/* acquisition parameters */
{"cycles", "triggers"},
@ -724,8 +726,6 @@ class CmdProxy {
{"rx_datastream", "rx_zmqstream"},
/* Eiger Specific */
{"trimdir", "settingspath"},
{"settingsdir", "settingspath"},
{"resmat", "partialreset"},
/* Jungfrau Specific */
@ -774,8 +774,12 @@ class CmdProxy {
{"detsize", &CmdProxy::DetectorSize},
{"settingslist", &CmdProxy::settingslist},
{"settings", &CmdProxy::settings},
{"threshold", &CmdProxy::Threshold},
{"thresholdnotb", &CmdProxy::Threshold},
{"settingspath", &CmdProxy::settingspath},
{"trimbits", &CmdProxy::trimbits},
{"trimval", &CmdProxy::trimval},
{"trimen", &CmdProxy::TrimEnergies},
{"gappixels", &CmdProxy::GapPixels},
/* acquisition parameters */
@ -911,12 +915,8 @@ class CmdProxy {
/* Eiger Specific */
{"subexptime", &CmdProxy::subexptime},
{"subdeadtime", &CmdProxy::subdeadtime},
{"threshold", &CmdProxy::Threshold},
{"thresholdnotb", &CmdProxy::ThresholdNoTb},
{"settingspath", &CmdProxy::settingspath},
{"overflow", &CmdProxy::overflow},
{"flippeddatax", &CmdProxy::flippeddatax},
{"trimen", &CmdProxy::TrimEnergies},
{"ratecorr", &CmdProxy::RateCorrection},
{"readnlines", &CmdProxy::readnlines},
{"interruptsubframe", &CmdProxy::interruptsubframe},
@ -1082,6 +1082,8 @@ class CmdProxy {
std::string PackageVersion(int action);
std::string ClientVersion(int action);
std::string DetectorSize(int action);
std::string Threshold(int action);
std::string TrimEnergies(int action);
std::string GapPixels(int action);
/* acquisition parameters */
std::string Acquire(int action);
@ -1113,9 +1115,6 @@ class CmdProxy {
/* ZMQ Streaming Parameters (Receiver<->Client) */
std::string ZMQHWM(int action);
/* Eiger Specific */
std::string Threshold(int action);
std::string ThresholdNoTb(int action);
std::string TrimEnergies(int action);
std::string RateCorrection(int action);
std::string Activate(int action);
std::string PulsePixel(int action);
@ -1212,9 +1211,14 @@ class CmdProxy {
"\n\t[Gotthard2] - [dynamicgain | fixgain1 | fixgain2]"
"\n\t[Moench] - [g1_hg | g1_lg | g2_hc_hg | g2_hc_lg | "
"g2_lc_hg | g2_lc_lg | g4_hg | g4_lg]"
"\n\t[Eiger] Use threshold or thresholdnotb. \n\t[Eiger] "
"settings loaded from file found in settingspath. \n\t[Gotthard] Also "
"loads default dacs on to the detector.");
"\n\t[Mythen3] - [standard | fast | highgain] Also changes vrshaper "
"and vrpreamp. \n\t[Eiger] Use threshold or thresholdnotb. \n\t[Eiger] "
"threshold and settings loaded from file found in settingspath. "
"\n\t[Gotthard] Also loads default dacs on to the detector.");
STRING_COMMAND(settingspath, getSettingsPath, setSettingsPath,
"[path]\n\t[Eiger][Mythen3] Directory where settings files "
"are loaded from/to.");
EXECUTE_SET_COMMAND_1ARG(
trimbits, loadTrimbits,
@ -1776,10 +1780,6 @@ class CmdProxy {
"of EIGER subframes in 32 bit mode. Subperiod = subexptime + "
"subdeadtime.");
STRING_COMMAND(
settingspath, getSettingsPath, setSettingsPath,
"[path]\n\t[Eiger] Directory where settings files are loaded from/to.");
INTEGER_COMMAND_VEC_ID(
overflow, getOverFlowMode, setOverFlowMode, StringTo<int>,
"[0, 1]\n\t[Eiger] Enable or disable show overflow flag in "

View File

@ -171,8 +171,10 @@ std::vector<defs::detectorSettings> Detector::getSettingsList() const {
defs::G2_HIGHCAP_HIGHGAIN, defs::G2_HIGHCAP_LOWGAIN,
defs::G2_LOWCAP_HIGHGAIN, defs::G2_LOWCAP_LOWGAIN,
defs::G4_HIGHGAIN, defs::G4_LOWGAIN};
case defs::CHIPTESTBOARD:
case defs::MYTHEN3:
return std::vector<defs::detectorSettings>{defs::STANDARD, defs::FAST,
defs::HIGHGAIN};
case defs::CHIPTESTBOARD:
throw RuntimeError("Settings not implemented for this detector");
default:
throw RuntimeError("Unknown detector type");
@ -184,7 +186,71 @@ Result<defs::detectorSettings> Detector::getSettings(Positions pos) const {
}
void Detector::setSettings(const defs::detectorSettings value, Positions pos) {
pimpl->Parallel(&Module::setSettings, pos, value);
if (value == defs::UNINITIALIZED || value == defs::UNDEFINED) {
throw RuntimeError(
"Cannot set settings with undefined or uninitialized settings.");
}
if (anyEqualTo<defs::detectorSettings>(getSettingsList(), value)) {
pimpl->Parallel(&Module::setSettings, pos, value);
} else {
throw RuntimeError("Unknown Settings " + ToString(value) +
" for this detector\n");
}
}
Result<int> Detector::getThresholdEnergy(Positions pos) const {
return pimpl->Parallel(&Module::getThresholdEnergy, pos);
}
Result<std::array<int, 3>>
Detector::getAllThresholdEnergy(Positions pos) const {
return pimpl->Parallel(&Module::getAllThresholdEnergy, pos);
}
void Detector::setThresholdEnergy(int threshold_ev,
defs::detectorSettings settings,
bool trimbits, Positions pos) {
defs::detectorType type = getDetectorType().squash();
if (type == defs::MYTHEN3) {
std::array<int, 3> energy = {threshold_ev, threshold_ev, threshold_ev};
setThresholdEnergy(energy, settings, trimbits, pos);
return;
}
if (type != defs::EIGER) {
throw RuntimeError(
"Set threshold energy not implemented for this detector");
}
if (anyEqualTo<defs::detectorSettings>(getSettingsList(), settings)) {
pimpl->Parallel(&Module::setThresholdEnergy, pos, threshold_ev,
settings, static_cast<int>(trimbits));
} else {
throw RuntimeError("Unknown Settings " + ToString(settings) +
" for this detector\n");
}
}
void Detector::setThresholdEnergy(std::array<int, 3> threshold_ev,
defs::detectorSettings settings,
bool trimbits, Positions pos) {
if (getDetectorType().squash() != defs::MYTHEN3) {
throw RuntimeError("Set threshold energy for different counters not "
"implemented for this detector");
}
if (anyEqualTo<defs::detectorSettings>(getSettingsList(), settings)) {
pimpl->Parallel(&Module::setAllThresholdEnergy, pos, threshold_ev,
settings, static_cast<int>(trimbits));
} else {
throw RuntimeError("Unknown Settings " + ToString(settings) +
" for this detector\n");
}
}
Result<std::string> Detector::getSettingsPath(Positions pos) const {
return pimpl->Parallel(&Module::getSettingsDir, pos);
}
void Detector::setSettingsPath(const std::string &value, Positions pos) {
pimpl->Parallel(&Module::setSettingsDir, pos, value);
}
void Detector::loadTrimbits(const std::string &fname, Positions pos) {
@ -199,6 +265,14 @@ void Detector::setAllTrimbits(int value, Positions pos) {
pimpl->Parallel(&Module::setAllTrimbits, pos, value);
}
Result<std::vector<int>> Detector::getTrimEnergies(Positions pos) const {
return pimpl->Parallel(&Module::getTrimEn, pos);
}
void Detector::setTrimEnergies(std::vector<int> energies, Positions pos) {
pimpl->Parallel(&Module::setTrimEn, pos, energies);
}
bool Detector::getGapPixelsinCallback() const {
return pimpl->getGapPixelsinCallback();
}
@ -1158,25 +1232,6 @@ void Detector::setSubDeadTime(ns value, Positions pos) {
pimpl->Parallel(&Module::setSubDeadTime, pos, value.count());
}
Result<int> Detector::getThresholdEnergy(Positions pos) const {
return pimpl->Parallel(&Module::getThresholdEnergy, pos);
}
void Detector::setThresholdEnergy(int threshold_ev,
defs::detectorSettings settings,
bool trimbits, Positions pos) {
pimpl->Parallel(&Module::setThresholdEnergy, pos, threshold_ev, settings,
static_cast<int>(trimbits));
}
Result<std::string> Detector::getSettingsPath(Positions pos) const {
return pimpl->Parallel(&Module::getSettingsDir, pos);
}
void Detector::setSettingsPath(const std::string &value, Positions pos) {
pimpl->Parallel(&Module::setSettingsDir, pos, value);
}
Result<bool> Detector::getOverFlowMode(Positions pos) const {
return pimpl->Parallel(&Module::getOverFlowMode, pos);
}
@ -1193,14 +1248,6 @@ void Detector::setBottom(bool value, Positions pos) {
pimpl->Parallel(&Module::setFlippedDataX, pos, value);
}
Result<std::vector<int>> Detector::getTrimEnergies(Positions pos) const {
return pimpl->Parallel(&Module::getTrimEn, pos);
}
void Detector::setTrimEnergies(std::vector<int> energies, Positions pos) {
pimpl->Parallel(&Module::setTrimEn, pos, energies);
}
Result<ns> Detector::getRateCorrection(Positions pos) const {
return pimpl->Parallel(&Module::getRateCorrection, pos);
}

View File

@ -2,6 +2,7 @@
#include "SharedMemory.h"
#include "sls/ClientSocket.h"
#include "sls/ToString.h"
#include "sls/bit_utils.h"
#include "sls/container_utils.h"
#include "sls/file_utils.h"
#include "sls/network_utils.h"
@ -9,7 +10,6 @@
#include "sls/sls_detector_funcs.h"
#include "sls/string_utils.h"
#include "sls/versionAPI.h"
#include <algorithm>
#include <array>
#include <bitset>
@ -152,16 +152,237 @@ void Module::setSettings(detectorSettings isettings) {
sendToDetector<int>(F_SET_SETTINGS, isettings);
}
int Module::getThresholdEnergy() const {
return sendToDetector<int>(F_GET_THRESHOLD_ENERGY);
}
std::array<int, 3> Module::getAllThresholdEnergy() const {
return sendToDetector<std::array<int, 3>>(F_GET_ALL_THRESHOLD_ENERGY);
}
void Module::setThresholdEnergy(int e_eV, detectorSettings isettings,
bool trimbits) {
// verify e_eV exists in trimEneregies[]
if (shm()->trimEnergies.empty() || (e_eV < shm()->trimEnergies.front()) ||
(e_eV > shm()->trimEnergies.back())) {
throw RuntimeError("This energy " + std::to_string(e_eV) +
" not defined for this module!");
}
bool interpolate =
std::all_of(shm()->trimEnergies.begin(), shm()->trimEnergies.end(),
[e_eV](const int &e) { return e != e_eV; });
sls_detector_module myMod{shm()->myDetectorType};
if (!interpolate) {
std::string settingsfname = getTrimbitFilename(isettings, e_eV);
LOG(logDEBUG1) << "Settings File is " << settingsfname;
myMod = readSettingsFile(settingsfname, trimbits);
} else {
// find the trim values
int trim1 = -1, trim2 = -1;
for (size_t i = 0; i < shm()->trimEnergies.size(); ++i) {
if (e_eV < shm()->trimEnergies[i]) {
trim2 = shm()->trimEnergies[i];
trim1 = shm()->trimEnergies[i - 1];
break;
}
}
std::string settingsfname1 = getTrimbitFilename(isettings, trim1);
std::string settingsfname2 = getTrimbitFilename(isettings, trim2);
LOG(logDEBUG1) << "Settings Files are " << settingsfname1 << " and "
<< settingsfname2;
auto myMod1 = readSettingsFile(settingsfname1, trimbits);
auto myMod2 = readSettingsFile(settingsfname2, trimbits);
if (myMod1.iodelay != myMod2.iodelay) {
throw RuntimeError("setThresholdEnergyAndSettings: Iodelays do not "
"match between files");
}
myMod = interpolateTrim(&myMod1, &myMod2, e_eV, trim1, trim2, trimbits);
myMod.iodelay = myMod1.iodelay;
myMod.tau =
linearInterpolation(e_eV, trim1, trim2, myMod1.tau, myMod2.tau);
}
myMod.reg = isettings;
myMod.eV[0] = e_eV;
setModule(myMod, trimbits);
if (getSettings() != isettings) {
throw RuntimeError("setThresholdEnergyAndSettings: Could not set "
"settings in detector");
}
if (shm()->useReceiverFlag) {
sendToReceiver(F_RECEIVER_SET_THRESHOLD, e_eV, nullptr);
}
}
void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
detectorSettings isettings, bool trimbits) {
if (shm()->trimEnergies.empty()) {
throw RuntimeError(
"Trim energies have not been defined for this module yet!");
}
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<sls_detector_module> myMods{shm()->myDetectorType};
std::vector<int> energy(e_eV.begin(), e_eV.end());
// if all energies are same
if (allEqualTo(energy, energy[0])) {
energy.resize(1);
}
myMods.resize(energy.size());
// for each threshold
for (size_t i = 0; i < energy.size(); ++i) {
// don't interpolate
if (shm()->trimEnergies.anyEqualTo(energy[i])) {
std::string settingsfname =
getTrimbitFilename(isettings, energy[i]);
LOG(logDEBUG1) << "Settings File is " << settingsfname;
myMods[i] = readSettingsFile(settingsfname, trimbits);
}
// interpolate
else {
if (shm()->trimEnergies.size() < 2) {
throw RuntimeError(
"Cannot interpolate with less than 2 trim energies");
}
// find the trim values
int trim1 = -1, trim2 = -1;
if (energy[i] < shm()->trimEnergies[0]) {
trim1 = shm()->trimEnergies[0];
trim2 = shm()->trimEnergies[1];
} else if (energy[i] >
shm()->trimEnergies[shm()->trimEnergies.size() - 1]) {
trim1 = shm()->trimEnergies[shm()->trimEnergies.size() - 2];
trim2 = shm()->trimEnergies[shm()->trimEnergies.size() - 1];
} else {
for (size_t j = 0; j < shm()->trimEnergies.size(); ++j) {
// std::cout << "checking " << energy[i] << " and "
// << shm()->trimEnergies[j] << std::endl;
if (energy[i] < shm()->trimEnergies[j]) {
trim1 = shm()->trimEnergies[j - 1];
trim2 = shm()->trimEnergies[j];
break;
}
}
}
LOG(logINFO) << "e_eV:" << energy[i] << " [" << trim1 << ", "
<< trim2 << "]";
std::string settingsfname1 = getTrimbitFilename(isettings, trim1);
std::string settingsfname2 = getTrimbitFilename(isettings, trim2);
LOG(logDEBUG1) << "Settings Files are " << settingsfname1 << " and "
<< settingsfname2;
auto myMod1 = readSettingsFile(settingsfname1, trimbits);
auto myMod2 = readSettingsFile(settingsfname2, trimbits);
myMods[i] = interpolateTrim(&myMod1, &myMod2, energy[i], trim1,
trim2, trimbits);
}
}
sls_detector_module myMod{shm()->myDetectorType};
myMod = myMods[0];
// if multiple thresholds, combine
if (myMods.size() > 1) {
// average vtrim of enabled counters
int sum = 0;
for (size_t i = 0; i < counters.size(); ++i) {
sum += myMods[counters[i]].dacs[M_VTRIM];
}
myMod.dacs[M_VTRIM] = sum / counters.size();
// copy vth1, vth2 and vth3 from the correct threshold mods
myMod.dacs[VTH1] = myMods[0].dacs[VTH1];
myMod.dacs[VTH2] = myMods[1].dacs[VTH2];
myMod.dacs[VTH3] = myMods[2].dacs[VTH3];
// check if dacs are different
for (size_t j = 0; j < 16; ++j) {
if (j == M_VTRIM || j == M_VTH1 || j == M_VTH2 || j == M_VTH3)
continue;
if (myMods[0].dacs[j] != myMods[1].dacs[j]) {
throw RuntimeError("Dac Index " + std::to_string(j) +
" differs for threshold[0]:[" +
std::to_string(myMods[0].dacs[j]) +
"] and threshold[1]:" +
std::to_string(myMods[1].dacs[j]) + "]");
}
if (myMods[1].dacs[j] != myMods[2].dacs[j]) {
throw RuntimeError("Dac Index " + std::to_string(j) +
" differs for threshold[1]:[" +
std::to_string(myMods[1].dacs[j]) +
"] and threshold[2]:" +
std::to_string(myMods[2].dacs[j]) + "]");
}
}
// replace correct trim values (interleaved)
for (int i = 0; i < myMod.nchan; ++i) {
myMod.chanregs[i] = myMods[i % 3].chanregs[i];
}
}
myMod.reg = isettings;
std::copy(e_eV.begin(), e_eV.end(), myMod.eV);
LOG(logDEBUG) << "ev:" << ToString(myMod.eV);
setModule(myMod, trimbits);
if (getSettings() != isettings) {
throw RuntimeError("setThresholdEnergyAndSettings: Could not set "
"settings in detector");
}
if (shm()->useReceiverFlag) {
sendToReceiver(F_RECEIVER_SET_ALL_THRESHOLD, e_eV, nullptr);
}
}
std::string Module::getSettingsDir() const {
return std::string(shm()->settingsDir);
}
std::string Module::setSettingsDir(const std::string &dir) {
sls::strcpy_safe(shm()->settingsDir, dir.c_str());
return shm()->settingsDir;
}
void Module::loadSettingsFile(const std::string &fname) {
// find specific file if it has detid in file name (.snxxx)
if (shm()->myDetectorType == EIGER || shm()->myDetectorType == MYTHEN3) {
std::ostringstream ostfn;
ostfn << fname;
if (fname.find(".sn") == std::string::npos &&
fname.find(".trim") == std::string::npos &&
fname.find(".settings") == std::string::npos) {
ostfn << ".sn" << std::setfill('0') << std::setw(3) << std::dec
<< getSerialNumber();
int serialNumberWidth = 3;
if (shm()->myDetectorType == MYTHEN3) {
serialNumberWidth = 4;
}
if (fname.find(".sn") == std::string::npos) {
ostfn << ".sn" << std::setfill('0') << std::setw(serialNumberWidth)
<< std::dec << getSerialNumber();
}
auto myMod = readSettingsFile(ostfn.str());
setModule(myMod);
@ -178,6 +399,30 @@ void Module::setAllTrimbits(int val) {
sendToDetector<int>(F_SET_ALL_TRIMBITS, val);
}
std::vector<int> Module::getTrimEn() const {
if (shm()->myDetectorType != EIGER && shm()->myDetectorType != MYTHEN3) {
throw RuntimeError("getTrimEn not implemented for this detector.");
}
return std::vector<int>(shm()->trimEnergies.begin(),
shm()->trimEnergies.end());
}
int Module::setTrimEn(const std::vector<int> &energies) {
if (shm()->myDetectorType != EIGER && shm()->myDetectorType != MYTHEN3) {
throw RuntimeError("setTrimEn not implemented for this detector.");
}
if (energies.size() > MAX_TRIMEN) {
std::ostringstream os;
os << "Size of trim energies: " << energies.size()
<< " exceeds what can be stored in shared memory: " << MAX_TRIMEN
<< "\n";
throw RuntimeError(os.str());
}
shm()->trimEnergies = energies;
std::sort(shm()->trimEnergies.begin(), shm()->trimEnergies.end());
return shm()->trimEnergies.size();
}
bool Module::isVirtualDetectorServer() const {
return sendToDetector<int>(F_IS_VIRTUAL);
}
@ -1095,33 +1340,6 @@ void Module::setSubDeadTime(int64_t value) {
}
}
int Module::getThresholdEnergy() const {
return sendToDetector<int>(F_GET_THRESHOLD_ENERGY);
}
void Module::setThresholdEnergy(int e_eV, detectorSettings isettings,
bool trimbits) {
// check as there is client processing
if (shm()->myDetectorType == EIGER) {
setThresholdEnergyAndSettings(e_eV, isettings, trimbits);
if (shm()->useReceiverFlag) {
sendToReceiver(F_RECEIVER_SET_THRESHOLD, e_eV, nullptr);
}
} else {
throw RuntimeError(
"Set threshold energy not implemented for this detector");
}
}
std::string Module::getSettingsDir() const {
return std::string(shm()->settingsDir);
}
std::string Module::setSettingsDir(const std::string &dir) {
sls::strcpy_safe(shm()->settingsDir, dir.c_str());
return shm()->settingsDir;
}
bool Module::getOverFlowMode() const {
return sendToDetector<int>(F_GET_OVERFLOW_MODE);
}
@ -1138,29 +1356,6 @@ void Module::setFlippedDataX(bool value) {
sendToReceiver<int>(F_SET_FLIPPED_DATA_RECEIVER, static_cast<int>(value));
}
std::vector<int> Module::getTrimEn() const {
if (shm()->myDetectorType != EIGER) {
throw RuntimeError("getTrimEn not implemented for this detector.");
}
return std::vector<int>(shm()->trimEnergies.begin(),
shm()->trimEnergies.end());
}
int Module::setTrimEn(const std::vector<int> &energies) {
if (shm()->myDetectorType != EIGER) {
throw RuntimeError("setTrimEn not implemented for this detector.");
}
if (energies.size() > MAX_TRIMEN) {
std::ostringstream os;
os << "Size of trim energies: " << energies.size()
<< " exceeds what can be stored in shared memory: " << MAX_TRIMEN
<< "\n";
throw RuntimeError(os.str());
}
shm()->trimEnergies = energies;
return shm()->trimEnergies.size();
}
int64_t Module::getRateCorrection() const {
return sendToDetector<int64_t>(F_GET_RATE_CORRECT);
}
@ -2749,9 +2944,9 @@ int Module::sendModule(sls_detector_module *myMod, sls::ClientSocket &client) {
ts += n;
LOG(level) << "tau sent. " << n << " bytes. tau: " << myMod->tau;
n = client.Send(&(myMod->eV), sizeof(myMod->eV));
n = client.Send(myMod->eV, sizeof(myMod->eV));
ts += n;
LOG(level) << "ev sent. " << n << " bytes. ev: " << myMod->eV;
LOG(level) << "ev sent. " << n << " bytes. ev: " << ToString(myMod->eV);
n = client.Send(myMod->dacs, sizeof(int) * (myMod->ndac));
ts += n;
@ -2799,68 +2994,12 @@ void Module::updateRateCorrection() {
sendToDetector(F_UPDATE_RATE_CORRECTION);
}
void Module::setThresholdEnergyAndSettings(int e_eV, detectorSettings isettings,
bool trimbits) {
// verify e_eV exists in trimEneregies[]
if (shm()->trimEnergies.empty() || (e_eV < shm()->trimEnergies.front()) ||
(e_eV > shm()->trimEnergies.back())) {
throw RuntimeError("This energy " + std::to_string(e_eV) +
" not defined for this module!");
}
bool interpolate =
std::all_of(shm()->trimEnergies.begin(), shm()->trimEnergies.end(),
[e_eV](const int &e) { return e != e_eV; });
sls_detector_module myMod{shm()->myDetectorType};
if (!interpolate) {
std::string settingsfname = getTrimbitFilename(isettings, e_eV);
LOG(logDEBUG1) << "Settings File is " << settingsfname;
myMod = readSettingsFile(settingsfname, trimbits);
} else {
// find the trim values
int trim1 = -1, trim2 = -1;
for (size_t i = 0; i < shm()->trimEnergies.size(); ++i) {
if (e_eV < shm()->trimEnergies[i]) {
trim2 = shm()->trimEnergies[i];
trim1 = shm()->trimEnergies[i - 1];
break;
}
}
std::string settingsfname1 = getTrimbitFilename(isettings, trim1);
std::string settingsfname2 = getTrimbitFilename(isettings, trim2);
LOG(logDEBUG1) << "Settings Files are " << settingsfname1 << " and "
<< settingsfname2;
auto myMod1 = readSettingsFile(settingsfname1, trimbits);
auto myMod2 = readSettingsFile(settingsfname2, trimbits);
if (myMod1.iodelay != myMod2.iodelay) {
throw RuntimeError("setThresholdEnergyAndSettings: Iodelays do not "
"match between files");
}
myMod = interpolateTrim(&myMod1, &myMod2, e_eV, trim1, trim2, trimbits);
myMod.iodelay = myMod1.iodelay;
myMod.tau =
linearInterpolation(e_eV, trim1, trim2, myMod1.tau, myMod2.tau);
}
myMod.reg = isettings;
myMod.eV = e_eV;
setModule(myMod, trimbits);
if (getSettings() != isettings) {
throw RuntimeError("setThresholdEnergyAndSettings: Could not set "
"settings in detector");
}
}
sls_detector_module Module::interpolateTrim(sls_detector_module *a,
sls_detector_module *b,
const int energy, const int e1,
const int e2, bool trimbits) {
// only implemented for eiger currently (in terms of which dacs)
if (shm()->myDetectorType != EIGER) {
// dacs specified only for eiger and mythen3
if (shm()->myDetectorType != EIGER && shm()->myDetectorType != MYTHEN3) {
throw NotImplementedError(
"Interpolation of Trim values not implemented for this detector!");
}
@ -2884,36 +3023,72 @@ sls_detector_module Module::interpolateTrim(sls_detector_module *a,
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
};
// Copy other dacs
int dacs_to_copy[] = {E_SVP, E_VTR, E_SVN, E_VTGSTV,
E_RXB_RB, E_RXB_LB, E_VCN, E_VIS};
int num_dacs_to_copy = sizeof(dacs_to_copy) / sizeof(dacs_to_copy[0]);
for (int i = 0; i < num_dacs_to_copy; ++i) {
// create copy and interpolate dac lists
std::vector<int> dacs_to_copy, dacs_to_interpolate;
if (shm()->myDetectorType == EIGER) {
dacs_to_copy.insert(
dacs_to_copy.end(),
{E_SVP, E_VTR, E_SVN, E_VTGSTV, E_RXB_RB, E_RXB_LB, E_VCN, E_VIS});
// interpolate vrf, vcmp, vcp
dacs_to_interpolate.insert(
dacs_to_interpolate.end(),
{E_VRF, E_VCMP_LL, E_VCMP_LR, E_VCMP_RL, E_VCMP_RR, E_VCP, E_VRS});
} else {
dacs_to_copy.insert(dacs_to_copy.end(),
{M_VCASSH, M_VRSHAPER, M_VRSHAPER_N, M_VIPRE_OUT,
M_VICIN, M_VCAS, M_VRPREAMP, M_VCAL_N, M_VIPRE,
M_VISHAPER, M_VCAL_P, M_VDCSH});
// interpolate vtrim, vth1, vth2, vth3
dacs_to_interpolate.insert(dacs_to_interpolate.end(),
{M_VTH1, M_VTH2, M_VTH3, M_VTRIM});
}
// Copy Dacs
for (size_t i = 0; i < dacs_to_copy.size(); ++i) {
if (a->dacs[dacs_to_copy[i]] != b->dacs[dacs_to_copy[i]]) {
throw RuntimeError("Interpolate module: dacs different");
throw RuntimeError("Interpolate module: dacs " + std::to_string(i) +
" different");
}
myMod.dacs[dacs_to_copy[i]] = a->dacs[dacs_to_copy[i]];
}
// Copy irrelevant dacs (without failing): CAL
if (a->dacs[E_CAL] != b->dacs[E_CAL]) {
LOG(logWARNING) << "DAC CAL differs in both energies ("
<< a->dacs[E_CAL] << "," << b->dacs[E_CAL]
<< ")!\nTaking first: " << a->dacs[E_CAL];
}
myMod.dacs[E_CAL] = a->dacs[E_CAL];
// Interpolate vrf, vcmp, vcp
int dacs_to_interpolate[] = {E_VRF, E_VCMP_LL, E_VCMP_LR, E_VCMP_RL,
E_VCMP_RR, E_VCP, E_VRS};
int num_dacs_to_interpolate =
sizeof(dacs_to_interpolate) / sizeof(dacs_to_interpolate[0]);
for (int i = 0; i < num_dacs_to_interpolate; ++i) {
// Interpolate Dacs
for (size_t i = 0; i < dacs_to_interpolate.size(); ++i) {
myMod.dacs[dacs_to_interpolate[i]] =
linearInterpolation(energy, e1, e2, a->dacs[dacs_to_interpolate[i]],
b->dacs[dacs_to_interpolate[i]]);
}
// Copy irrelevant dacs (without failing)
if (shm()->myDetectorType == EIGER) {
// CAL
if (a->dacs[E_CAL] != b->dacs[E_CAL]) {
LOG(logWARNING)
<< "DAC CAL differs in both energies (" << a->dacs[E_CAL] << ","
<< b->dacs[E_CAL] << ")!\nTaking first: " << a->dacs[E_CAL];
}
myMod.dacs[E_CAL] = a->dacs[E_CAL];
}
// Interpolate all trimbits
if (trimbits) {
for (int i = 0; i < myMod.nchan; ++i) {
@ -2930,6 +3105,9 @@ std::string Module::getTrimbitFilename(detectorSettings s, int e_eV) {
case STANDARD:
ssettings = "/standard";
break;
case FAST:
ssettings = "/fast";
break;
case HIGHGAIN:
ssettings = "/highgain";
break;
@ -2948,8 +3126,20 @@ std::string Module::getTrimbitFilename(detectorSettings s, int e_eV) {
throw RuntimeError(ss.str());
}
std::ostringstream ostfn;
ostfn << shm()->settingsDir << ssettings << "/" << e_eV << "eV"
<< "/noise.sn" << std::setfill('0') << std::setw(3) << std::dec
ostfn << shm()->settingsDir << ssettings << "/" << e_eV << "eV";
if (shm()->myDetectorType == EIGER) {
ostfn << "/noise.sn";
} else if (shm()->myDetectorType == MYTHEN3) {
ostfn << "/trim.sn";
} else {
throw RuntimeError(
"Settings or trimbit files not defined for this detector.");
}
int serialNumberWidth = 3;
if (shm()->myDetectorType == MYTHEN3) {
serialNumberWidth = 4;
}
ostfn << std::setfill('0') << std::setw(serialNumberWidth) << std::dec
<< getSerialNumber() << std::setbase(10);
return ostfn.str();
}
@ -2976,6 +3166,11 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
infile.read(reinterpret_cast<char *>(&myMod.iodelay),
sizeof(myMod.iodelay));
infile.read(reinterpret_cast<char *>(&myMod.tau), sizeof(myMod.tau));
for (int i = 0; i < myMod.ndac; ++i) {
LOG(logDEBUG1) << "dac " << i << ":" << myMod.dacs[i];
}
LOG(logDEBUG1) << "iodelay:" << myMod.iodelay;
LOG(logDEBUG1) << "tau:" << myMod.tau;
if (trimbits) {
infile.read(reinterpret_cast<char *>(myMod.chanregs),
sizeof(int) * (myMod.nchan));
@ -2985,28 +3180,24 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
"for settings for " +
fname);
}
for (int i = 0; i < myMod.ndac; ++i) {
LOG(logDEBUG1) << "dac " << i << ":" << myMod.dacs[i];
}
LOG(logDEBUG1) << "iodelay:" << myMod.iodelay;
LOG(logDEBUG1) << "tau:" << myMod.tau;
}
// mythen3 (dacs, trimbits)
else if (shm()->myDetectorType == MYTHEN3) {
infile.read(reinterpret_cast<char *>(myMod.dacs),
sizeof(int) * (myMod.ndac));
infile.read(reinterpret_cast<char *>(myMod.chanregs),
sizeof(int) * (myMod.nchan));
for (int i = 0; i < myMod.ndac; ++i) {
LOG(logDEBUG) << "dac " << i << ":" << myMod.dacs[i];
}
if (trimbits) {
infile.read(reinterpret_cast<char *>(myMod.chanregs),
sizeof(int) * (myMod.nchan));
}
if (!infile) {
throw RuntimeError("readSettingsFile: Could not load all values "
"for settings for " +
fname);
}
for (int i = 0; i < myMod.ndac; ++i) {
LOG(logDEBUG1) << "dac " << i << ":" << myMod.dacs[i];
}
}
else {

View File

@ -101,9 +101,19 @@ class Module : public virtual slsDetectorDefs {
void updateNumberOfDetector(slsDetectorDefs::xy det);
detectorSettings getSettings() const;
void setSettings(detectorSettings isettings);
int getThresholdEnergy() const;
std::array<int, 3> getAllThresholdEnergy() const;
void setThresholdEnergy(int e_eV, detectorSettings isettings,
bool trimbits);
void setAllThresholdEnergy(std::array<int, 3> e_eV,
detectorSettings isettings, bool trimbits);
std::string getSettingsDir() const;
std::string setSettingsDir(const std::string &dir);
void loadSettingsFile(const std::string &fname);
int getAllTrimbits() const;
void setAllTrimbits(int val);
std::vector<int> getTrimEn() const;
int setTrimEn(const std::vector<int> &energies = {});
bool isVirtualDetectorServer() const;
/**************************************************
@ -308,17 +318,10 @@ class Module : public virtual slsDetectorDefs {
void setSubExptime(int64_t value);
int64_t getSubDeadTime() const;
void setSubDeadTime(int64_t value);
int getThresholdEnergy() const;
void setThresholdEnergy(int e_eV, detectorSettings isettings,
bool trimbits);
std::string getSettingsDir() const;
std::string setSettingsDir(const std::string &dir);
bool getOverFlowMode() const;
void setOverFlowMode(const bool enable);
bool getFlippedDataX() const;
void setFlippedDataX(bool value);
std::vector<int> getTrimEn() const;
int setTrimEn(const std::vector<int> &energies = {});
int64_t getRateCorrection() const;
void setDefaultRateCorrection();
void setRateCorrection(int64_t t = 0);
@ -680,8 +683,6 @@ class Module : public virtual slsDetectorDefs {
void updateReceiverStreamingIP();
void updateRateCorrection();
void setThresholdEnergyAndSettings(int e_eV, detectorSettings isettings,
bool trimbits = true);
/** Template function to do linear interpolation between two points (Eiger
only) */
template <typename E, typename V>

View File

@ -319,80 +319,6 @@ TEST_CASE("subdeadtime", "[.cmd]") {
}
}
TEST_CASE("threshold", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
auto prev_threshold = det.getThresholdEnergy();
auto prev_energies =
det.getTrimEnergies().tsquash("inconsistent trim energies to test");
if (!prev_energies.empty()) {
std::ostringstream oss1, oss2;
proxy.Call("threshold", {"4500", "standard"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "threshold [4500, standard]\n");
proxy.Call("threshold", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "threshold 4500\n");
det.setTrimEnergies(prev_energies);
for (int i = 0; i != det.size(); ++i) {
if (prev_threshold[i] >= 0) {
det.setThresholdEnergy(prev_threshold[i], defs::STANDARD,
true, {i});
}
}
}
REQUIRE_NOTHROW(proxy.Call("threshold", {}, -1, GET));
} else {
REQUIRE_THROWS(proxy.Call("threshold", {}, -1, GET));
}
}
TEST_CASE("thresholdnotb", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
auto prev_threshold = det.getThresholdEnergy();
auto prev_energies =
det.getTrimEnergies().tsquash("inconsistent trim energies to test");
if (!prev_energies.empty()) {
std::ostringstream oss1, oss2;
proxy.Call("thresholdnotb", {"4500 standard"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "thresholdnotb [4500 standard]\n");
proxy.Call("threshold", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "threshold 4500\n");
det.setTrimEnergies(prev_energies);
for (int i = 0; i != det.size(); ++i) {
if (prev_threshold[i] >= 0) {
det.setThresholdEnergy(prev_threshold[i], defs::STANDARD,
false, {i});
}
}
}
REQUIRE_NOTHROW(proxy.Call("threshold", {}, -1, GET));
} else {
REQUIRE_THROWS(proxy.Call("thresholdnotb", {}, -1, GET));
}
}
TEST_CASE("settingspath", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto prev_val = det.getSettingsPath();
{
std::ostringstream oss1, oss2;
proxy.Call("settingspath", {"/tmp"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "settingspath /tmp\n");
proxy.Call("settingspath", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "settingspath /tmp\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setSettingsPath(prev_val[i], {i});
}
}
TEST_CASE("overflow", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
@ -435,27 +361,6 @@ TEST_CASE("flippeddatax", "[.cmd]") {
}
}
TEST_CASE("trimen", "[.cmd][.this]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
auto previous = det.getTrimEnergies();
std::ostringstream oss1, oss2;
proxy.Call("trimen", {"4500", "5400", "6400"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "trimen [4500, 5400, 6400]\n");
proxy.Call("trimen", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "trimen [4500, 5400, 6400]\n");
for (int i = 0; i != det.size(); ++i) {
det.setTrimEnergies(previous[i], {i});
}
} else {
REQUIRE_THROWS(proxy.Call("trimen", {"4500", "5400", "6400"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("trimen", {}, -1, GET));
}
}
TEST_CASE("ratecorr", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);

View File

@ -130,7 +130,7 @@ TEST_CASE("settingslist", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::CHIPTESTBOARD || det_type == defs::MYTHEN3) {
if (det_type == defs::CHIPTESTBOARD) {
REQUIRE_THROWS(proxy.Call("settingslist", {}, -1, GET));
} else {
REQUIRE_NOTHROW(proxy.Call("settingslist", {}, -1, GET));
@ -174,6 +174,11 @@ TEST_CASE("settings", "[.cmd]") {
sett.push_back("g4_hg");
sett.push_back("g4_lg");
break;
case defs::MYTHEN3:
sett.push_back("standard");
sett.push_back("fast");
sett.push_back("highgain");
break;
default:
if (det_type == defs::EIGER) {
// FIXME: need to remove when settings removed
@ -206,6 +211,181 @@ TEST_CASE("settings", "[.cmd]") {
}
}
TEST_CASE("threshold", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
auto prev_threshold = det.getThresholdEnergy();
auto prev_energies =
det.getTrimEnergies().tsquash("inconsistent trim energies to test");
if (!prev_energies.empty()) {
std::string senergy = std::to_string(prev_energies[0]);
std::ostringstream oss1, oss2;
proxy.Call("threshold", {senergy, "standard"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "threshold [" + senergy + ", standard]\n");
proxy.Call("threshold", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "threshold " + senergy + "\n");
REQUIRE_THROWS(proxy.Call(
"threshold", {senergy, senergy, senergy, "standard"}, -1, PUT));
REQUIRE_THROWS(
proxy.Call("threshold", {senergy, "undefined"}, -1, PUT));
det.setTrimEnergies(prev_energies);
for (int i = 0; i != det.size(); ++i) {
if (prev_threshold[i] >= 0) {
det.setThresholdEnergy(prev_threshold[i], defs::STANDARD,
true, {i});
}
}
}
REQUIRE_NOTHROW(proxy.Call("threshold", {}, -1, GET));
} else if (det_type == defs::MYTHEN3) {
auto prev_threshold = det.getAllThresholdEnergy();
auto prev_settings =
det.getSettings().tsquash("inconsistent settings to test");
auto prev_energies =
det.getTrimEnergies().tsquash("inconsistent trim energies to test");
if (!prev_energies.empty()) {
std::string senergy = std::to_string(prev_energies[0]);
std::ostringstream oss1, oss2;
proxy.Call("threshold", {senergy, "standard"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "threshold [" + senergy + ", standard]\n");
proxy.Call("threshold", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "threshold [" + senergy + ", " + senergy +
", " + senergy + "]\n");
std::string senergy2 = std::to_string(prev_energies[1]);
std::string senergy3 = std::to_string(prev_energies[2]);
std::ostringstream oss3, oss4;
proxy.Call("threshold", {senergy, senergy2, senergy3, "standard"},
-1, PUT, oss3);
REQUIRE(oss3.str() == "threshold [" + senergy + ", " + senergy2 +
", " + senergy3 + ", standard]\n");
proxy.Call("threshold", {}, -1, GET, oss4);
REQUIRE(oss4.str() == "threshold [" + senergy + ", " + senergy2 +
", " + senergy3 + "]\n");
REQUIRE_THROWS(proxy.Call("threshold",
{senergy, senergy, "standard"}, -1, PUT));
REQUIRE_THROWS(
proxy.Call("threshold", {senergy, "undefined"}, -1, PUT));
REQUIRE_NOTHROW(proxy.Call("threshold", {senergy}, -1, PUT));
REQUIRE_NOTHROW(proxy.Call("threshold",
{senergy, senergy2, senergy3}, -1, PUT));
det.setTrimEnergies(prev_energies);
for (int i = 0; i != det.size(); ++i) {
if (prev_threshold[i][0] >= 0) {
std::cout
<< "prev cvalues:" << sls::ToString(prev_threshold[i])
<< std::endl;
det.setThresholdEnergy(prev_threshold[i], prev_settings,
true, {i});
}
}
}
REQUIRE_NOTHROW(proxy.Call("threshold", {}, -1, GET));
} else {
REQUIRE_THROWS(proxy.Call("threshold", {}, -1, GET));
}
}
TEST_CASE("thresholdnotb", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
auto prev_threshold = det.getThresholdEnergy();
auto prev_energies =
det.getTrimEnergies().tsquash("inconsistent trim energies to test");
if (!prev_energies.empty()) {
std::string senergy = std::to_string(prev_energies[0]);
std::ostringstream oss1, oss2;
proxy.Call("thresholdnotb", {senergy, "standard"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "threshold [" + senergy + ", standard]\n");
proxy.Call("threshold", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "threshold " + senergy + "\n");
REQUIRE_THROWS(proxy.Call("thresholdnotb",
{senergy, senergy, senergy, "standard"},
-1, PUT));
REQUIRE_THROWS(
proxy.Call("thresholdnotb", {senergy, "undefined"}, -1, PUT));
det.setTrimEnergies(prev_energies);
for (int i = 0; i != det.size(); ++i) {
if (prev_threshold[i] >= 0) {
det.setThresholdEnergy(prev_threshold[i], defs::STANDARD,
false, {i});
}
}
}
REQUIRE_NOTHROW(proxy.Call("threshold", {}, -1, GET));
} else if (det_type == defs::MYTHEN3) {
auto prev_threshold = det.getAllThresholdEnergy();
auto prev_settings =
det.getSettings().tsquash("inconsistent settings to test");
auto prev_energies =
det.getTrimEnergies().tsquash("inconsistent trim energies to test");
if (!prev_energies.empty()) {
std::string senergy = std::to_string(prev_energies[0]);
std::ostringstream oss1, oss2;
proxy.Call("thresholdnotb", {senergy, "standard"}, -1, PUT, oss1);
REQUIRE(oss1.str() ==
"thresholdnotb [" + senergy + ", standard]\n");
proxy.Call("threshold", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "threshold [" + senergy + ", " + senergy +
", " + senergy + "]\n");
std::string senergy2 = std::to_string(prev_energies[1]);
std::string senergy3 = std::to_string(prev_energies[2]);
std::ostringstream oss3, oss4;
proxy.Call("thresholdnotb",
{senergy, senergy2, senergy3, "standard"}, -1, PUT,
oss3);
REQUIRE(oss3.str() == "thresholdnotb [" + senergy + ", " +
senergy2 + ", " + senergy3 +
", standard]\n");
proxy.Call("threshold", {}, -1, GET, oss4);
REQUIRE(oss4.str() == "threshold [" + senergy + ", " + senergy2 +
", " + senergy3 + "]\n");
REQUIRE_THROWS(proxy.Call("thresholdnotb",
{senergy, senergy, "standard"}, -1, PUT));
REQUIRE_THROWS(
proxy.Call("thresholdnotb", {senergy, "undefined"}, -1, PUT));
REQUIRE_NOTHROW(proxy.Call("thresholdnotb", {senergy}, -1, PUT));
REQUIRE_NOTHROW(proxy.Call("thresholdnotb",
{senergy, senergy2, senergy3}, -1, PUT));
det.setTrimEnergies(prev_energies);
for (int i = 0; i != det.size(); ++i) {
if (prev_threshold[i][0] >= 0) {
det.setThresholdEnergy(prev_threshold[i], prev_settings,
true, {i});
}
}
}
REQUIRE_NOTHROW(proxy.Call("threshold", {}, -1, GET));
} else {
REQUIRE_THROWS(proxy.Call("thresholdnotb", {}, -1, GET));
}
}
TEST_CASE("settingspath", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto prev_val = det.getSettingsPath();
{
std::ostringstream oss1, oss2;
proxy.Call("settingspath", {"/tmp"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "settingspath /tmp\n");
proxy.Call("settingspath", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "settingspath /tmp\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setSettingsPath(prev_val[i], {i});
}
}
TEST_CASE("trimbits", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
@ -246,6 +426,65 @@ TEST_CASE("trimval", "[.cmd]") {
}
}
TEST_CASE("trimen", "[.cmd][.this]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER || det_type == defs::MYTHEN3) {
auto previous = det.getTrimEnergies();
std::ostringstream oss1, oss2;
proxy.Call("trimen", {"4500", "5400", "6400"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "trimen [4500, 5400, 6400]\n");
proxy.Call("trimen", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "trimen [4500, 5400, 6400]\n");
for (int i = 0; i != det.size(); ++i) {
det.setTrimEnergies(previous[i], {i});
}
} else {
REQUIRE_THROWS(proxy.Call("trimen", {"4500", "5400", "6400"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("trimen", {}, -1, GET));
}
}
TEST_CASE("gappixels", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::JUNGFRAU || det_type == defs::EIGER) {
auto prev_val = det.getGapPixelsinCallback();
{
std::ostringstream oss;
proxy.Call("gappixels", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "gappixels 1\n");
}
{
std::ostringstream oss;
proxy.Call("gappixels", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "gappixels 0\n");
}
{
std::ostringstream oss;
proxy.Call("gappixels", {}, -1, GET, oss);
REQUIRE(oss.str() == "gappixels 0\n");
}
det.setGapPixelsinCallback(prev_val);
} else {
{
std::ostringstream oss;
proxy.Call("gappixels", {}, -1, GET, oss);
REQUIRE(oss.str() == "gappixels 0\n");
}
{
std::ostringstream oss;
proxy.Call("gappixels", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "gappixels 0\n");
}
REQUIRE_THROWS(proxy.Call("gappixels", {"1"}, -1, PUT));
}
}
/* acquisition parameters */
// acquire: not testing
@ -1510,44 +1749,6 @@ TEST_CASE("scanerrmsg", "[.cmd]") {
REQUIRE_THROWS(proxy.Call("scanerrmsg", {""}, -1, PUT));
}
TEST_CASE("gappixels", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::JUNGFRAU || det_type == defs::EIGER) {
auto prev_val = det.getGapPixelsinCallback();
{
std::ostringstream oss;
proxy.Call("gappixels", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "gappixels 1\n");
}
{
std::ostringstream oss;
proxy.Call("gappixels", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "gappixels 0\n");
}
{
std::ostringstream oss;
proxy.Call("gappixels", {}, -1, GET, oss);
REQUIRE(oss.str() == "gappixels 0\n");
}
det.setGapPixelsinCallback(prev_val);
} else {
{
std::ostringstream oss;
proxy.Call("gappixels", {}, -1, GET, oss);
REQUIRE(oss.str() == "gappixels 0\n");
}
{
std::ostringstream oss;
proxy.Call("gappixels", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "gappixels 0\n");
}
REQUIRE_THROWS(proxy.Call("gappixels", {"1"}, -1, PUT));
}
}
/* Network Configuration (Detector<->Receiver) */
TEST_CASE("numinterfaces", "[.cmd]") {