mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-14 22:07:12 +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:
@ -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 {
|
||||
|
Reference in New Issue
Block a user