mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-23 01:58:00 +02:00
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:
@ -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;
|
||||
|
||||
|
@ -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 << ' ';
|
||||
|
@ -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 "
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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]") {
|
||||
|
Reference in New Issue
Block a user