Merge branch 'developer' into g2rxr

This commit is contained in:
maliakal_d 2022-06-07 17:02:47 +02:00
commit 23e4dde063
14 changed files with 335 additions and 227 deletions

View File

@ -75,8 +75,10 @@ This document describes the differences between v7.0.0 and v6.x.x
- rxr src files and classes (detectordata, ZmqSocket, helpDacs) added to sls namespace, and macros (namely from logger (logINFO etc)), slsDetectorGui (make_unique in implemtnation requires sls nemspace (points to std otherwise) but not deectorImpl.cpp)
- blackfin programing made seamless (nCE fixed which helps)
-save settings file for m3 and eiger
- m3 threshold changes
- g2 and m3 clkdiv 2 (system clock) change should affect time settings (g2: exptime, period, delayaftertrigger, burstperiod, m3: exptime, gatedelay, gateperiod, period, delayaftertrigger)
- g2 system frequency is the same irrespective of timing source
- (apparently) rxr doesnt get stuck anymore from 6.1.1
2. Resolved Issues
==================

View File

@ -1834,13 +1834,13 @@ class Detector(CppDetectorApi):
@property
@element
def threshold(self):
"""[Eiger] Threshold in eV
"""[Eiger][Mythen3] Threshold in eV
Note
----
To change settings as well or set threshold without trimbits, use setThresholdEnergy.
:setter: It loads trim files from settingspath.
:setter: It loads trim files from settingspath.\n [Mythen3] An energy of -1 will pick up values from detector.
"""
if self.type == detectorType.MYTHEN3:
return self.getAllThresholdEnergy()
@ -3516,7 +3516,7 @@ class Detector(CppDetectorApi):
@property
@element
def interpolation(self):
"""[Mythen3] Enable or disable interpolation. Enabling also enables all counters """
"""[Mythen3] Enable or disable interpolation. interpolation mode enables all counters and disables vth3. Disabling sets back counter mask and vth3. """
return self.getInterpolation()
@interpolation.setter
@ -3526,7 +3526,7 @@ class Detector(CppDetectorApi):
@property
@element
def pumpprobe(self):
"""[Mythen3] Enable or disable pump probe mode. """
"""[Mythen3] Enable or disable pump probe mode. Pump probe mode only enables vth2. Disabling sets back to previous value """
return self.getPumpProbe()
@pumpprobe.setter

View File

@ -68,6 +68,7 @@ int64_t exptimeReg[NCOUNTERS] = {0, 0, 0};
int64_t gateDelayReg[NCOUNTERS] = {0, 0, 0};
int vthEnabledVals[NCOUNTERS] = {0, 0, 0};
int detID = 0;
int counterMask = 0x0;
int isInitCheckDone() { return initCheckDone; }
@ -474,17 +475,19 @@ void setupDetector() {
// defaults
setHighVoltage(DEFAULT_HIGH_VOLTAGE);
resetToDefaultDacs(0);
setASICDefaults();
setADIFDefaults();
// enable all counters before setting dacs (vthx)
setCounterMask(MAX_COUNTER_MSK);
resetToDefaultDacs(0);
// set trigger flow for m3 (for all timing modes)
bus_w(FLOW_TRIGGER_REG, bus_r(FLOW_TRIGGER_REG) | FLOW_TRIGGER_MSK);
// dynamic range
setDynamicRange(DEFAULT_DYNAMIC_RANGE);
// enable all counters
setCounterMask(MAX_COUNTER_MSK);
// Initialization of acquistion parameters
setNumFrames(DEFAULT_NUM_FRAMES);
@ -596,8 +599,8 @@ int resetToDefaultDacs(int hardReset) {
}
}
// set to defualt
setDAC((enum DACINDEX)i, value, 0);
// set to default (last arg to ensure counter check)
setDAC((enum DACINDEX)i, value, 0, 1);
if (detectorDacs[i] != value) {
LOG(logERROR, ("Setting dac %d failed, wrote %d, read %d\n", i,
value, detectorDacs[i]));
@ -1087,12 +1090,44 @@ int64_t getGateDelay(int gateIndex) {
return retval / (1E-9 * getFrequency(SYSTEM_C0));
}
void updateVthAndCounterMask() {
LOG(logINFO, ("\tUpdating Vth and countermask\n"));
int interpolation = getInterpolation();
int pumpProbe = getPumpProbe();
if (interpolation) {
// enable all counters
setCounterMaskWithUpdateFlag(MAX_COUNTER_MSK, 0);
// disable vth3
setVthDac(2, 0);
} else {
// previous counter values
setCounterMaskWithUpdateFlag(counterMask, 0);
}
if (pumpProbe) {
// enable only vth2
setVthDac(0, 0);
setVthDac(1, 1);
setVthDac(2, 0);
} else {
setVthDac(0, (counterMask & (1 << 0)));
setVthDac(1, (counterMask & (1 << 1)));
}
if (!interpolation && !pumpProbe) {
setVthDac(2, (counterMask & (1 << 2)));
}
}
void setCounterMask(uint32_t arg) {
setCounterMaskWithUpdateFlag(arg, 1);
updateVthAndCounterMask();
}
void setCounterMaskWithUpdateFlag(uint32_t arg, int updateMaskFlag) {
if (arg == 0 || arg > MAX_COUNTER_MSK) {
return;
}
uint32_t oldmask = getCounterMask();
LOG(logINFO, ("Setting counter mask to 0x%x\n", arg));
LOG(logINFO, ("\tSetting counter mask to 0x%x\n", arg));
uint32_t addr = CONFIG_REG;
bus_w(addr, bus_r(addr) & ~CONFIG_COUNTERS_ENA_MSK);
bus_w(addr, bus_r(addr) | ((arg << CONFIG_COUNTERS_ENA_OFST) &
@ -1108,19 +1143,8 @@ void setCounterMask(uint32_t arg) {
setGateDelay(i, ns);
}
LOG(logINFO, ("\tUpdating Vth dacs\n"));
enum DACINDEX vthdacs[] = {M_VTH1, M_VTH2, M_VTH3};
for (int i = 0; i < NCOUNTERS; ++i) {
// if change in enable
if ((arg & (1 << i)) ^ (oldmask & (1 << i))) {
// disable, disable value
int value = DEFAULT_COUNTER_DISABLED_VTH_VAL;
// enable, set saved values
if (arg & (1 << i)) {
value = vthEnabledVals[i];
}
setGeneralDAC(vthdacs[i], value, 0);
}
if (updateMaskFlag) {
counterMask = arg;
}
}
@ -1241,7 +1265,8 @@ int64_t getMeasurementTime() {
int setDACS(int *dacs) {
for (int i = 0; i < NDAC; ++i) {
if (dacs[i] != -1) {
setDAC((enum DACINDEX)i, dacs[i], 0);
// set to default (last arg to ensure counter check)
setDAC((enum DACINDEX)i, dacs[i], 0, 1);
if (dacs[i] != detectorDacs[i]) {
// dont complain if that counter was disabled
if ((i == M_VTH1 || i == M_VTH2 || i == M_VTH3) &&
@ -1300,6 +1325,9 @@ int setModule(sls_detector_module myMod, char *mess) {
return FAIL;
}
// update vth and countermask
updateVthAndCounterMask();
// threshold energy
for (int i = 0; i < NCOUNTERS; ++i) {
if (myMod.eV[i] >= 0) {
@ -1440,7 +1468,8 @@ enum detectorSettings setSettings(enum detectorSettings sett) {
// set special dacs
const int specialDacs[] = SPECIALDACINDEX;
for (int i = 0; i < NSPECIALDACS; ++i) {
setDAC(specialDacs[i], dacVals[i], 0);
// set to default (last arg to ensure counter check)
setDAC(specialDacs[i], dacVals[i], 0, 1);
}
LOG(logINFO, ("Settings: %d\n", thisSettings));
@ -1500,7 +1529,8 @@ void setThresholdEnergy(int counterIndex, int eV) {
}
/* parameters - dac, hv */
void setDAC(enum DACINDEX ind, int val, int mV) {
// counterEnableCheck false only if setDAC called directly
void setDAC(enum DACINDEX ind, int val, int mV, int counterEnableCheck) {
// invalid value
if (val < 0) {
return;
@ -1511,7 +1541,10 @@ void setDAC(enum DACINDEX ind, int val, int mV) {
return;
}
// threshold dacs (remember value, vthreshold: skip disabled)
// threshold dacs
// remember value, vthreshold: skip disabled,
// others: disable or enable dac if counter mask
// setDAC called directly: will set independent of counter enable
if (ind == M_VTHRESHOLD || ind == M_VTH1 || ind == M_VTH2 ||
ind == M_VTH3) {
char *dac_names[] = {DAC_NAMES};
@ -1522,7 +1555,6 @@ void setDAC(enum DACINDEX ind, int val, int mV) {
int dacval = val;
// if not disabled value, remember value
if (dacval != DEFAULT_COUNTER_DISABLED_VTH_VAL) {
// convert mv to dac
if (mV) {
if (LTC2620_D_VoltageToDac(val, &dacval) == FAIL) {
return;
@ -1532,9 +1564,16 @@ void setDAC(enum DACINDEX ind, int val, int mV) {
LOG(logINFO,
("Remembering %s [%d]\n", dac_names[ind], dacval));
}
// if vthreshold,skip for disabled counters
if ((ind == M_VTHRESHOLD) && (!(counters & (1 << i)))) {
continue;
// disabled counter
if (!(counters & (1 << i))) {
// skip setting vthx dac (value remembered anyway)
if (ind == M_VTHRESHOLD) {
continue;
}
// disable dac (except when setting dac directly)
if (counterEnableCheck) {
val = DEFAULT_COUNTER_DISABLED_VTH_VAL;
}
}
setGeneralDAC(vthdacs[i], val, mV);
}
@ -1575,6 +1614,19 @@ void setGeneralDAC(enum DACINDEX ind, int val, int mV) {
}
}
void setVthDac(int index, int enable) {
LOG(logINFO, ("\t%s vth%d\n", (enable ? "Enabling" : "Disabing"), index));
// enables (from remembered values) or disables vthx
enum DACINDEX vthdacs[] = {M_VTH1, M_VTH2, M_VTH3};
// disable value
int value = DEFAULT_COUNTER_DISABLED_VTH_VAL;
// enable, set saved values
if (enable) {
value = vthEnabledVals[index];
}
setGeneralDAC(vthdacs[index], value, 0);
}
int getDAC(enum DACINDEX ind, int mV) {
if (ind == M_VTHRESHOLD) {
int ret = -1, ret1 = -1;
@ -1738,23 +1790,24 @@ int setGainCaps(int caps) {
int setInterpolation(int enable) {
LOG(logINFO,
("%s Interpolation\n", enable == 0 ? "Disabling" : "Enabling"));
if (enable) {
setCounterMask(MAX_COUNTER_MSK);
if (getCounterMask() != MAX_COUNTER_MSK) {
LOG(logERROR,
("Could not set interpolation. Could not enable all counters"));
return FAIL;
}
LOG(logINFO, ("\tEnabled all counters\n"));
}
int csr = M3SetInterpolation(enable);
return setChipStatusRegister(csr);
int ret = setChipStatusRegister(csr);
if (ret == OK) {
updateVthAndCounterMask();
}
return ret;
}
int setPumpProbe(int enable) {
LOG(logINFO, ("%s Pump Probe\n", enable == 0 ? "Disabling" : "Enabling"));
int csr = M3SetPumpProbe(enable);
return setChipStatusRegister(csr);
int ret = setChipStatusRegister(csr);
if (ret == OK) {
updateVthAndCounterMask();
}
return ret;
}
int setDigitalPulsing(int enable) {

View File

@ -105,7 +105,7 @@ enum DACINDEX {
1220, /* vIpreOut */ \
2800, /* Vth3 */ \
2800, /* Vth1 */ \
1708, /* vIcin */ \
800, /* vIcin */ \
1800, /* cas */ \
1100, /* Vrpreamp */ \
1100, /* Vcal_n */ \

View File

@ -281,6 +281,7 @@ int getNumDigitalSamples();
#endif
#ifdef MYTHEN3D
void setCounterMask(uint32_t arg);
void setCounterMaskWithUpdateFlag(uint32_t arg, int updateMaskFlag);
uint32_t getCounterMask();
void updatePacketizing();
#endif
@ -347,9 +348,12 @@ void setThresholdEnergy(int counterIndex, int eV);
int setOnChipDAC(enum ONCHIP_DACINDEX ind, int chipIndex, int val);
int getOnChipDAC(enum ONCHIP_DACINDEX ind, int chipIndex);
#endif
void setDAC(enum DACINDEX ind, int val, int mV);
#ifdef MYTHEN3D
void setDAC(enum DACINDEX ind, int val, int mV, int counterEnableCheck);
void setGeneralDAC(enum DACINDEX ind, int val, int mV);
void setVthDac(int index, int enable);
#else
void setDAC(enum DACINDEX ind, int val, int mV);
#endif
int getDAC(enum DACINDEX ind, int mV);
int getMaxDacSteps();

View File

@ -1288,7 +1288,12 @@ int validateAndSetDac(enum dacIndex ind, int val, int mV) {
LOG(logERROR, (mess));
} else
#endif
#ifdef MYTHEN3D
// ignore counter enable to force vth dac values
setDAC(serverDacIndex, val, mV, 0);
#else
setDAC(serverDacIndex, val, mV);
#endif
retval = getDAC(serverDacIndex, mV);
}
#ifdef EIGERD
@ -9944,19 +9949,25 @@ int set_interpolation(int file_des) {
#else
// only set
if (Server_VerifyLock() == OK) {
ret = setInterpolation(arg);
if (ret == FAIL) {
if (arg)
sprintf(mess, "Could not set interpolation or enable all "
"counters for it.\n");
else
sprintf(mess, "Could not set interpolation\n");
if (getPumpProbe() && arg) {
ret = FAIL;
sprintf(mess, "Could not set interpolation. Disable pump probe mode first.\n");
LOG(logERROR, (mess));
} else {
int retval = getInterpolation();
validate(&ret, mess, (int)arg, (int)retval, "set interpolation",
DEC);
LOG(logDEBUG1, ("interpolation retval: %u\n", retval));
ret = setInterpolation(arg);
if (ret == FAIL) {
if (arg)
sprintf(mess, "Could not set interpolation or enable all "
"counters for it.\n");
else
sprintf(mess, "Could not set interpolation\n");
LOG(logERROR, (mess));
} else {
int retval = getInterpolation();
validate(&ret, mess, (int)arg, (int)retval, "set interpolation",
DEC);
LOG(logDEBUG1, ("interpolation retval: %u\n", retval));
}
}
}
#endif
@ -9994,14 +10005,20 @@ int set_pump_probe(int file_des) {
#else
// only set
if (Server_VerifyLock() == OK) {
ret = setPumpProbe(arg);
if (ret == FAIL) {
sprintf(mess, "Could not set pump probe\n");
if (getInterpolation() && arg) {
ret = FAIL;
sprintf(mess, "Could not set pump probe mode. Disable interpolation mode first.\n");
LOG(logERROR, (mess));
} else {
int retval = getPumpProbe();
validate(&ret, mess, (int)arg, (int)retval, "set pump probe", DEC);
LOG(logDEBUG1, ("pump probe retval: %u\n", retval));
ret = setPumpProbe(arg);
if (ret == FAIL) {
sprintf(mess, "Could not set pump probe\n");
LOG(logERROR, (mess));
} else {
int retval = getPumpProbe();
validate(&ret, mess, (int)arg, (int)retval, "set pump probe", DEC);
LOG(logDEBUG1, ("pump probe retval: %u\n", retval));
}
}
}
#endif

View File

@ -144,7 +144,7 @@ class Detector {
defs::detectorSettings settings = defs::STANDARD,
bool trimbits = true, Positions pos = {});
/** [Mythen3] It loads trim files from settingspath */
/** [Mythen3] It loads trim files from settingspath. An energy of -1 will pick up values from detector */
void setThresholdEnergy(std::array<int, 3> threshold_ev,
defs::detectorSettings settings = defs::STANDARD,
bool trimbits = true, Positions pos = {});
@ -1504,13 +1504,13 @@ class Detector {
/** [Mythen3] */
Result<bool> getInterpolation(Positions pos = {}) const;
/** [Mythen3] Also enables all counters */
/** [Mythen3] interpolation mode enables all counters and disables vth3. Disabling sets back counter mask and vth3. */
void setInterpolation(bool value, Positions pos = {});
/** [Mythen3] */
Result<bool> getPumpProbe(Positions pos = {}) const;
/** [Mythen3] */
/** [Mythen3] pump probe mode only enables vth2. Disabling sets back to previous value */
void setPumpProbe(bool value, Positions pos = {});
/** [Mythen3] */

View File

@ -382,8 +382,8 @@ std::string CmdProxy::Threshold(int action) {
}
os << "\n\nthreshold [eV1] [eV2] [eV3] [(optional settings)]"
"\n\t[Mythen3] Threshold in eV for each counter. It loads trim "
"files from "
"settingspath.";
"files from settingspath. An energy of -1 will pick up values "
" from detector.";
if (cmd == "thresholdnotb") {
os << "Trimbits are not loaded.";
}
@ -2302,6 +2302,9 @@ std::string CmdProxy::Counters(int action) {
if (args.empty()) {
WrongNumberOfParameters(1);
}
if (std::any_of(args.cbegin(), args.cend(), [](std::string s){ return (StringTo<int>(s) < 0 || StringTo<int>(s) > 2); })) {
throw RuntimeError("Invalid counter indices list. Example: 0 1 2");
}
// convert vector to counter enable mask
uint32_t mask = 0;
for (size_t i = 0; i < args.size(); ++i) {

View File

@ -2058,12 +2058,11 @@ class CmdProxy {
INTEGER_COMMAND_VEC_ID(interpolation, getInterpolation, setInterpolation,
StringTo<int>,
"[0, 1]\n\t[Mythen3] Enables or disables "
"interpolation. Default is disabled. Enabling also "
"enables all counters. ");
"interpolation. Default is disabled. Interpolation mode enables all counters and disables vth3. Disabling sets back counter mask and vth3.");
INTEGER_COMMAND_VEC_ID(pumpprobe, getPumpProbe, setPumpProbe, StringTo<int>,
"[0, 1]\n\t[Mythen3] Enables or disables pump probe "
"mode. Default is disabled");
"mode. Default is disabled. Pump probe mode only enables vth2. Disabling sets back to previous value.");
INTEGER_COMMAND_VEC_ID(apulse, getAnalogPulsing, setAnalogPulsing,
StringTo<int>,

View File

@ -173,7 +173,9 @@ std::array<int, 3> Module::getAllThresholdEnergy() const {
void Module::setThresholdEnergy(int e_eV, detectorSettings isettings,
bool trimbits) {
if (shm()->detType == MYTHEN3) {
throw RuntimeError("Mythen3 should have called with 3 energies");
}
// verify e_eV exists in trimEneregies[]
if (shm()->trimEnergies.empty() || (e_eV < shm()->trimEnergies.front()) ||
(e_eV > shm()->trimEnergies.back())) {
@ -214,21 +216,9 @@ void Module::setThresholdEnergy(int e_eV, detectorSettings isettings,
myMod.iodelay = myMod1.iodelay;
myMod.tau =
linearInterpolation(e_eV, trim1, trim2, myMod1.tau, myMod2.tau);
// m3, reg is used for gaincaps
if (shm()->detType == MYTHEN3) {
if (myMod1.reg != myMod2.reg) {
throw RuntimeError(
"setThresholdEnergyAndSettings: gaincaps do not "
"match between files");
}
myMod.reg = myMod1.reg;
}
}
// m3, reg is used for gaincaps
if (shm()->detType != MYTHEN3) {
myMod.reg = isettings;
}
myMod.reg = isettings;
myMod.eV[0] = e_eV;
setModule(myMod, trimbits);
if (getSettings() != isettings) {
@ -243,42 +233,35 @@ void Module::setThresholdEnergy(int e_eV, detectorSettings isettings,
void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
detectorSettings isettings, bool trimbits) {
// only mythen3
if (shm()->detType != MYTHEN3) {
throw RuntimeError("This detector should have called with 3 energies");
}
if (shm()->trimEnergies.empty()) {
throw RuntimeError(
"Trim energies have not been defined for this module yet!");
"Trim energies have not been defined for this module yet! Use trimen.");
}
auto counters = getSetBits(getCounterMask());
enum mythen3_DacIndex {
M_VCASSH,
M_VTH2,
M_VRSHAPER,
M_VRSHAPER_N,
M_VIPRE_OUT,
M_VTH3,
M_VTH1,
M_VICIN,
M_VCAS,
M_VRPREAMP,
M_VCAL_N,
M_VIPRE,
M_VISHAPER,
M_VCAL_P,
M_VTRIM,
M_VDCSH
};
std::vector<sls_detector_module> myMods{shm()->detType};
std::vector<int> energy(e_eV.begin(), e_eV.end());
// if all energies are same
if (allEqualTo(energy, energy[0])) {
if (energy[0] == -1) {
throw RuntimeError("Every energy provided to set threshold energy is -1. Typo?");
}
energy.resize(1);
}
myMods.resize(energy.size());
// for each threshold
std::vector<sls_detector_module> myMods;
for (size_t i = 0; i < energy.size(); ++i) {
if (energy[i] == -1) {
sls_detector_module mod = getModule();
myMods.push_back(mod);
continue;
}
sls_detector_module mod{shm()->detType};
myMods.push_back(mod);
// don't interpolate
if (shm()->trimEnergies.anyEqualTo(energy[i])) {
std::string settingsfname =
@ -324,10 +307,9 @@ void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
myMods[i] = interpolateTrim(&myMod1, &myMod2, energy[i], trim1,
trim2, trimbits);
// gaincaps
// csr
if (myMod1.reg != myMod2.reg) {
throw RuntimeError("setAllThresholdEnergy: gaincaps do not "
"match between files for energy (eV) " +
throw RuntimeError("setAllThresholdEnergy: chip shift register values do not match between files for energy (eV) " +
std::to_string(energy[i]));
}
myMods[i].reg = myMod1.reg;
@ -337,8 +319,11 @@ void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
sls_detector_module myMod{shm()->detType};
myMod = myMods[0];
// if multiple thresholds, combine
if (myMods.size() > 1) {
auto counters = getSetBits(getCounterMask());
// average vtrim of enabled counters
int sum = 0;
@ -377,56 +362,15 @@ void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
for (int i = 0; i < myMod.nchan; ++i) {
myMod.chanregs[i] = myMods[i % 3].chanregs[i];
}
// gain caps
// csr
if (myMods[0].reg != myMods[1].reg || myMods[1].reg != myMods[2].reg) {
throw RuntimeError("setAllThresholdEnergy: gaincaps do not "
"match between files for all energies");
throw RuntimeError("setAllThresholdEnergy: chip shift register values do not match between files for all energies");
}
}
myMod.reg = isettings;
std::copy(e_eV.begin(), e_eV.end(), myMod.eV);
LOG(logDEBUG) << "ev:" << ToString(myMod.eV);
// check for trimbits that are out of range
bool out_of_range = false;
for (int i = 0; i != myMod.nchan; ++i) {
if (myMod.chanregs[i] < 0) {
myMod.chanregs[i] = 0;
out_of_range = true;
} else if (myMod.chanregs[i] > 63) {
myMod.chanregs[i] = 63;
out_of_range = true;
}
}
if (out_of_range) {
LOG(logWARNING)
<< "Some trimbits were out of range after interpolation, these "
"have been replaced with 0 or 63.";
}
// check dacs
out_of_range = false;
for (int i = 0; i != myMod.ndac; ++i) {
int dacMin = 0;
int dacMax = 2800;
if (i == M_VTH1 || i == M_VTH2 || i == M_VTH3) {
dacMin = 200;
dacMax = 2400;
}
if (myMod.dacs[i] < dacMin) {
myMod.dacs[i] = dacMin;
out_of_range = true;
} else if (myMod.dacs[i] > dacMax) {
myMod.dacs[i] = dacMax;
out_of_range = true;
}
}
if (out_of_range) {
LOG(logWARNING) << "Some dacs were out of range after interpolation, "
"these have been replaced with 600 or 2400.";
}
setModule(myMod, trimbits);
if (getSettings() != isettings) {
throw RuntimeError("setThresholdEnergyAndSettings: Could not set "
@ -2261,10 +2205,8 @@ uint32_t Module::getCounterMask() const {
}
void Module::setCounterMask(uint32_t countermask) {
LOG(logDEBUG1) << "Setting Counter mask to " << countermask;
sendToDetector(F_SET_COUNTER_MASK, countermask, nullptr);
if (shm()->useReceiverFlag) {
LOG(logDEBUG1) << "Sending Reciver counter mask: " << countermask;
sendToReceiver(F_RECEIVER_SET_COUNTER_MASK, countermask, nullptr);
}
}
@ -2324,7 +2266,10 @@ bool Module::getInterpolation() const {
void Module::setInterpolation(const bool enable) {
sendToDetector(F_SET_INTERPOLATION, static_cast<int>(enable), nullptr);
setCounterMask(getCounterMask());
int mask = getCounterMask();
if (shm()->useReceiverFlag) {
sendToReceiver(F_RECEIVER_SET_COUNTER_MASK, mask, nullptr);
}
}
bool Module::getPumpProbe() const {
@ -2407,12 +2352,9 @@ int Module::getNumberOfDigitalSamples() const {
}
void Module::setNumberOfDigitalSamples(int value) {
LOG(logDEBUG1) << "Setting number of digital samples to " << value;
sendToDetector(F_SET_NUM_DIGITAL_SAMPLES, value, nullptr);
updateNumberOfChannels(); // depends on samples and adcmask
if (shm()->useReceiverFlag) {
LOG(logDEBUG1) << "Sending number of digital samples to Receiver: "
<< value;
sendToReceiver(F_RECEIVER_SET_NUM_DIGITAL_SAMPLES, value, nullptr);
}
}
@ -3347,6 +3289,45 @@ void Module::setModule(sls_detector_module &module, bool trimbits) {
module.nchan = 0;
module.nchip = 0;
}
// validate dacs and trimbits
if (shm()->detType == MYTHEN3) {
// check for trimbits that are out of range
bool out_of_range = false;
for (int i = 0; i != module.nchan; ++i) {
if (module.chanregs[i] < 0) {
module.chanregs[i] = 0;
out_of_range = true;
} else if (module.chanregs[i] > 63) {
module.chanregs[i] = 63;
out_of_range = true;
}
}
if (out_of_range) {
LOG(logWARNING)
<< "Some trimbits were out of range, these have been replaced with 0 or 63.";
}
// check dacs
out_of_range = false;
for (int i = 0; i != module.ndac; ++i) {
int dacMin = 0;
int dacMax = 2800;
if (i == M_VTH1 || i == M_VTH2 || i == M_VTH3) {
dacMin = 200;
dacMax = 2400;
}
if (module.dacs[i] < dacMin) {
module.dacs[i] = dacMin;
out_of_range = true;
} else if (module.dacs[i] > dacMax) {
module.dacs[i] = dacMax;
out_of_range = true;
}
}
if (out_of_range) {
LOG(logWARNING) << "Some dacs were out of range, "
"these have been replaced with 0/200 or 2800/2400.";
}
}
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(F_SET_MODULE);
sendModule(&module, client);
@ -3478,42 +3459,6 @@ sls_detector_module Module::interpolateTrim(sls_detector_module *a,
}
sls_detector_module myMod{shm()->detType};
enum eiger_DacIndex {
E_SVP,
E_VTR,
E_VRF,
E_VRS,
E_SVN,
E_VTGSTV,
E_VCMP_LL,
E_VCMP_LR,
E_CAL,
E_VCMP_RL,
E_RXB_RB,
E_RXB_LB,
E_VCMP_RR,
E_VCP,
E_VCN,
E_VIS
};
enum mythen3_DacIndex {
M_VCASSH,
M_VTH2,
M_VRSHAPER,
M_VRSHAPER_N,
M_VIPRE_OUT,
M_VTH3,
M_VTH1,
M_VICIN,
M_VCAS,
M_VRPREAMP,
M_VCAL_N,
M_VIPRE,
M_VISHAPER,
M_VCAL_P,
M_VTRIM,
M_VDCSH
};
// create copy and interpolate dac lists
std::vector<int> dacs_to_copy, dacs_to_interpolate;

View File

@ -791,6 +791,44 @@ class Module : public virtual slsDetectorDefs {
static const int NIOS_WRITE_TO_FLASH_TIME_FPGA = 45;
static const int NIOS_ERASE_FLASH_TIME_KERNEL = 9;
static const int NIOS_WRITE_TO_FLASH_TIME_KERNEL = 40;
enum mythen3_DacIndex {
M_VCASSH,
M_VTH2,
M_VRSHAPER,
M_VRSHAPER_N,
M_VIPRE_OUT,
M_VTH3,
M_VTH1,
M_VICIN,
M_VCAS,
M_VRPREAMP,
M_VCAL_N,
M_VIPRE,
M_VISHAPER,
M_VCAL_P,
M_VTRIM,
M_VDCSH
};
enum eiger_DacIndex {
E_SVP,
E_VTR,
E_VRF,
E_VRS,
E_SVN,
E_VTGSTV,
E_VCMP_LL,
E_VCMP_LR,
E_CAL,
E_VCMP_RL,
E_RXB_RB,
E_RXB_LB,
E_VCMP_RR,
E_VCP,
E_VCN,
E_VIS
};
};
} // namespace sls

View File

@ -496,32 +496,46 @@ TEST_CASE("interpolation", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
if (det.getDetectorType().squash() == defs::MYTHEN3) {
auto prev_val = det.getInterpolation();
auto mask = det.getCounterMask();
{
proxy.Call("counters", {"0", "1"}, -1, PUT);
std::ostringstream oss;
proxy.Call("interpolation", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "interpolation 1\n");
REQUIRE(det.getCounterMask().tsquash("inconsistent counter mask") ==
7);
}
{
proxy.Call("counters", {"0", "1"}, -1, PUT);
std::ostringstream oss;
proxy.Call("interpolation", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "interpolation 0\n");
REQUIRE(det.getCounterMask().tsquash("inconsistent counter mask") ==
3);
auto prev_interpolation = det.getInterpolation();
auto prev_mask = det.getCounterMask();
auto prev_vth3DacVal = det.getDAC(defs::VTH3, 0, {});
int disabledDacValue = 2800;
auto fixedVth3DacVal = 1000;
det.setDAC(defs::VTH3, fixedVth3DacVal, 0, {});
// mask with counter 3 disabled and enabled(to test vth3)
uint32_t fixedMask[2] = {0x2, 0x4};
for (int i = 0; i != 2; ++i) {
det.setCounterMask(fixedMask[i]);
{
std::ostringstream oss;
proxy.Call("interpolation", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "interpolation 1\n");
REQUIRE(det.getCounterMask().tsquash("inconsistent counter mask") ==
7);
REQUIRE(det.getDAC(defs::VTH3, 0, {0}).tsquash("inconsistent vth3 dac value") == disabledDacValue);
}
{
std::ostringstream oss;
proxy.Call("interpolation", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "interpolation 0\n");
REQUIRE(det.getCounterMask().tsquash("inconsistent counter mask") ==
fixedMask[i]);
uint32_t expectedVth3DacVal = (fixedMask[i] & 0x4 ? fixedVth3DacVal : disabledDacValue);
REQUIRE(det.getDAC(defs::VTH3, 0, {0}).tsquash("inconsistent vth3 dac value") == expectedVth3DacVal);
}
}
{
std::ostringstream oss;
proxy.Call("interpolation", {}, -1, GET, oss);
REQUIRE(oss.str() == "interpolation 0\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setCounterMask(mask[i], {i});
det.setInterpolation(prev_val[i], {i});
det.setCounterMask(prev_mask[i], {i});
det.setInterpolation(prev_interpolation[i], {i});
det.setDAC(defs::VTH3, prev_vth3DacVal[i], 0, {i});
}
} else {
REQUIRE_THROWS(proxy.Call("interpolation", {}, -1, GET));
@ -533,15 +547,43 @@ TEST_CASE("pumpprobe", "[.cmd]") {
CmdProxy proxy(&det);
if (det.getDetectorType().squash() == defs::MYTHEN3) {
auto prev_val = det.getPumpProbe();
{
std::ostringstream oss;
proxy.Call("pumpprobe", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "pumpprobe 1\n");
}
{
std::ostringstream oss;
proxy.Call("pumpprobe", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "pumpprobe 0\n");
auto prev_interpolation = det.getInterpolation();
auto prev_mask = det.getCounterMask();
auto prev_vth1DacVal = det.getDAC(defs::VTH1, 0, {});
auto prev_vth2DacVal = det.getDAC(defs::VTH2, 0, {});
auto prev_vth3DacVal = det.getDAC(defs::VTH3, 0, {});
int disabledDacValue = 2800;
auto fixedVthDacVal = 1000;
det.setDAC(defs::VTH1, fixedVthDacVal, 0, {});
det.setDAC(defs::VTH2, fixedVthDacVal, 0, {});
det.setDAC(defs::VTH3, fixedVthDacVal, 0, {});
// mask with counter 2 disabled and enabled(to test vth2)
uint32_t fixedMask[2] = {0x4, 0x3};
for (int i = 0; i != 2; ++i) {
det.setCounterMask(fixedMask[i]);
{
// pump probe
std::ostringstream oss;
proxy.Call("pumpprobe", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "pumpprobe 1\n");
REQUIRE(det.getDAC(defs::VTH1, 0, {0}).tsquash("inconsistent vth2 dac value") == disabledDacValue);
REQUIRE(det.getDAC(defs::VTH2, 0, {0}).tsquash("inconsistent vth2 dac value") == fixedVthDacVal);
REQUIRE(det.getDAC(defs::VTH3, 0, {0}).tsquash("inconsistent vth2 dac value") == disabledDacValue);
}
// interpolation and pump probe
REQUIRE_THROWS(proxy.Call("interpolation", {"1"}, -1, PUT));
{
// none
std::ostringstream oss;
proxy.Call("pumpprobe", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "pumpprobe 0\n");
REQUIRE(det.getCounterMask().tsquash("inconsistent counter mask") == 7);
REQUIRE(det.getDAC(defs::VTH1, 0, {0}).tsquash("inconsistent vth1 dac value") == (fixedMask[i] & 0x1 ? fixedVthDacVal : disabledDacValue));
REQUIRE(det.getDAC(defs::VTH2, 0, {0}).tsquash("inconsistent vth2 dac value") == (fixedMask[i] & 0x2 ? fixedVthDacVal : disabledDacValue));
REQUIRE(det.getDAC(defs::VTH3, 0, {0}).tsquash("inconsistent vth3 dac value") == (fixedMask[i] & 0x4 ? fixedVthDacVal : disabledDacValue));
}
}
{
std::ostringstream oss;
@ -549,7 +591,12 @@ TEST_CASE("pumpprobe", "[.cmd]") {
REQUIRE(oss.str() == "pumpprobe 0\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setCounterMask(prev_mask[i], {i});
det.setPumpProbe(prev_val[i], {i});
det.setInterpolation(prev_interpolation[i], {i});
det.setDAC(defs::VTH1, prev_vth1DacVal[i], 0, {i});
det.setDAC(defs::VTH2, prev_vth2DacVal[i], 0, {i});
det.setDAC(defs::VTH3, prev_vth3DacVal[i], 0, {i});
}
} else {
REQUIRE_THROWS(proxy.Call("pumpprobe", {}, -1, GET));

View File

@ -10,5 +10,5 @@
#define APIJUNGFRAU 0x220524
#define APIMOENCH 0x220519
#define APIEIGER 0x220524
#define APIMYTHEN3 0x220602
#define APIGOTTHARD2 0x220602
#define APIMYTHEN3 0x220607