M3badchannels (#526)

* badchannels for m3 and modify for g2 (file from single and multi)

* m3: invert polarity of bit 7 and 11 signals from setmodule, allow commas in bad channel file

* badchannel file can take commas, colons and comments (also taking care of spaces at the end of channel numbers)

* tests 'badchannels' and 'Channel file reading' added, removing duplicates in badchannel list, defining macro for num counters in client side

* fix segfault when list from file is empty, 

* fix tests assertion for ctbconfig (adding message) for c++11

* fixed badchannels in m3server (clocking in trimming) 

* badchannel tests can be run from any folder (finds the file)
This commit is contained in:
Dhanya Thattil
2022-09-01 15:30:04 +02:00
committed by GitHub
parent 02322bb3c2
commit 7de6f157b5
36 changed files with 499 additions and 221 deletions

View File

@ -540,6 +540,32 @@ std::string CmdProxy::GapPixels(int action) {
return os.str();
}
std::string CmdProxy::BadChannels(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[fname]\n\t[Gotthard2][Mythen3] Sets the bad channels (from "
"file of bad channel numbers) to be masked out."
"\n\t[Mythen3] Also does trimming"
<< '\n';
} else if (action == defs::GET_ACTION) {
if (args.size() != 1) {
WrongNumberOfParameters(1);
}
det->getBadChannels(args[0], std::vector<int>{det_id});
os << "successfully retrieved" << '\n';
} else if (action == defs::PUT_ACTION) {
if (args.size() != 1) {
WrongNumberOfParameters(1);
}
det->setBadChannels(args[0], std::vector<int>{det_id});
os << "successfully loaded" << '\n';
} else {
throw RuntimeError("Unknown action");
}
return os.str();
}
/* acquisition parameters */
std::string CmdProxy::Exptime(int action) {
@ -2320,31 +2346,6 @@ std::string CmdProxy::ConfigureADC(int action) {
return os.str();
}
std::string CmdProxy::BadChannels(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[fname]\n\t[Gotthard2] Sets the bad channels (from file of bad "
"channel numbers) to be masked out."
<< '\n';
} else if (action == defs::GET_ACTION) {
if (args.size() != 1) {
WrongNumberOfParameters(1);
}
det->getBadChannels(args[0], std::vector<int>{det_id});
os << "successfully retrieved" << '\n';
} else if (action == defs::PUT_ACTION) {
if (args.size() != 1) {
WrongNumberOfParameters(1);
}
det->setBadChannels(args[0], std::vector<int>{det_id});
os << "successfully loaded" << '\n';
} else {
throw RuntimeError("Unknown action");
}
return os.str();
}
/* Mythen3 Specific */
std::string CmdProxy::Counters(int action) {

View File

@ -788,6 +788,7 @@ class CmdProxy {
{"fliprows", &CmdProxy::fliprows},
{"master", &CmdProxy::master},
{"sync", &CmdProxy::sync},
{"badchannels", &CmdProxy::BadChannels},
/* acquisition parameters */
{"acquire", &CmdProxy::Acquire},
@ -984,7 +985,6 @@ class CmdProxy {
{"vetostream", &CmdProxy::VetoStreaming},
{"vetoalg", &CmdProxy::VetoAlgorithm},
{"confadc", &CmdProxy::ConfigureADC},
{"badchannels", &CmdProxy::BadChannels},
/* Mythen3 Specific */
{"counters", &CmdProxy::Counters},
@ -1122,6 +1122,7 @@ class CmdProxy {
std::string Trimbits(int action);
std::string TrimEnergies(int action);
std::string GapPixels(int action);
std::string BadChannels(int action);
/* acquisition parameters */
std::string Acquire(int action);
std::string Exptime(int action);
@ -1182,7 +1183,6 @@ class CmdProxy {
std::string VetoStreaming(int action);
std::string VetoAlgorithm(int action);
std::string ConfigureADC(int action);
std::string BadChannels(int action);
/* Mythen3 Specific */
std::string Counters(int action);
std::string GateDelay(int action);

View File

@ -333,6 +333,14 @@ void Detector::setSynchronization(bool value) {
pimpl->Parallel(&Module::setSynchronization, {}, value);
}
void Detector::getBadChannels(const std::string &fname, Positions pos) const {
pimpl->getBadChannels(fname, pos);
}
void Detector::setBadChannels(const std::string &fname, Positions pos) {
pimpl->setBadChannels(fname, pos);
}
Result<bool> Detector::isVirtualDetectorServer(Positions pos) const {
return pimpl->Parallel(&Module::isVirtualDetectorServer, pos);
}
@ -1819,14 +1827,6 @@ void Detector::setADCConfiguration(const int chipIndex, const int adcIndex,
value);
}
void Detector::getBadChannels(const std::string &fname, Positions pos) const {
pimpl->Parallel(&Module::getBadChannels, pos, fname);
}
void Detector::setBadChannels(const std::string &fname, Positions pos) {
pimpl->Parallel(&Module::setBadChannels, pos, fname);
}
// Mythen3 Specific
Result<uint32_t> Detector::getCounterMask(Positions pos) const {

View File

@ -50,6 +50,11 @@ void DetectorImpl::setupDetector(bool verify, bool update) {
ctb_shm.openSharedMemory(verify);
}
bool DetectorImpl::isAllPositions(const Positions pos) const {
return (pos.empty() || (pos.size() == 1 && pos[0] == -1) ||
(pos.size() == modules.size()));
}
void DetectorImpl::setAcquiringFlag(bool flag) { shm()->acquiringFlag = flag; }
int DetectorImpl::getDetectorIndex() const { return detectorIndex; }
@ -1645,6 +1650,85 @@ void DetectorImpl::clearRxROI() {
shm()->rx_roi.ymax = -1;
}
void DetectorImpl::getBadChannels(const std::string &fname,
Positions pos) const {
auto res = Parallel(&Module::getBadChannels, pos);
std::vector<int> badchannels(res[0]);
// update to multi values if multi modules
if (isAllPositions(pos)) {
badchannels.clear();
int nchan = modules[0]->getNumberOfChannels().x;
if (shm()->detType == MYTHEN3) {
// assuming single counter
nchan /= MAX_NUM_COUNTERS;
}
int imod = 0;
for (auto vec : res) {
for (auto badch : vec) {
badchannels.push_back(imod * nchan + badch);
}
++imod;
}
} else if (pos.size() != 1) {
throw RuntimeError("Can get bad channels only for 1 or all modules.\n");
}
// save to file
LOG(logDEBUG1) << "Getting bad channels to " << fname;
std::ofstream outfile(fname);
if (!outfile) {
throw RuntimeError("Could not create file to save bad channels");
}
for (auto ch : badchannels)
outfile << ch << '\n';
LOG(logDEBUG1) << badchannels.size() << " bad channels saved to file";
}
void DetectorImpl::setBadChannels(const std::string &fname, Positions pos) {
std::vector<int> list = sls::getChannelsFromFile(fname);
if (list.empty()) {
throw RuntimeError("Bad channel file is empty.");
}
// update to multi values if multi modules
if (isAllPositions(pos)) {
std::vector<std::vector<int>> badchannels;
int nchan = modules[0]->getNumberOfChannels().x;
if (shm()->detType == MYTHEN3) {
// assuming single counter
nchan /= MAX_NUM_COUNTERS;
}
for (auto badchannel : list) {
if (badchannel < 0) {
throw RuntimeError("Invalid bad channel list. " +
std::to_string(badchannel) +
" out of bounds.");
}
int ch = badchannel % nchan;
int imod = badchannel / nchan;
if (imod >= (int)modules.size()) {
throw RuntimeError("Invalid bad channel list. " +
std::to_string(badchannel) +
" out of bounds.");
}
if ((int)badchannels.size() != imod + 1) {
badchannels.push_back(std::vector<int>{});
}
badchannels[imod].push_back(ch);
}
for (int imod = 0; imod != (int)modules.size(); ++imod) {
Parallel(&Module::setBadChannels, {imod}, badchannels[imod]);
}
} else if (pos.size() != 1) {
throw RuntimeError("Can set bad channels only for 1 or all modules.\n");
} else {
Parallel(&Module::setBadChannels, pos, list);
}
}
std::vector<std::string> DetectorImpl::getCtbDacNames() const {
return ctb_shm()->getDacNames();
}

View File

@ -190,6 +190,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
}
}
bool isAllPositions(const Positions pos) const;
/** set acquiring flag in shared memory */
void setAcquiringFlag(bool flag);
@ -303,6 +305,9 @@ class DetectorImpl : public virtual slsDetectorDefs {
void setRxROI(const defs::ROI arg);
void clearRxROI();
void getBadChannels(const std::string &fname, Positions pos) const;
void setBadChannels(const std::string &fname, Positions pos);
std::vector<std::string> getCtbDacNames() const;
std::string getCtbDacName(defs::dacIndex i) const;
void setCtbDacNames(const std::vector<std::string> &names);

View File

@ -498,6 +498,40 @@ void Module::setSynchronization(const bool value) {
sendToDetector(F_SET_SYNCHRONIZATION, static_cast<int>(value), nullptr);
}
std::vector<int> Module::getBadChannels() const {
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(F_GET_BAD_CHANNELS);
if (client.Receive<int>() == FAIL) {
throw DetectorError("Detector " + std::to_string(moduleIndex) +
" returned error: " + client.readErrorMessage());
}
// receive badchannels
auto nch = client.Receive<int>();
std::vector<int> badchannels(nch);
if (nch > 0) {
client.Receive(badchannels);
for (size_t i = 0; i < badchannels.size(); ++i) {
LOG(logDEBUG1) << i << ":" << badchannels[i];
}
}
return badchannels;
}
void Module::setBadChannels(std::vector<int> list) {
auto nch = static_cast<int>(list.size());
LOG(logDEBUG1) << "Sending bad channels to detector, nch:" << nch;
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(F_SET_BAD_CHANNELS);
client.Send(nch);
if (nch > 0) {
client.Send(list);
}
if (client.Receive<int>() == FAIL) {
throw DetectorError("Detector " + std::to_string(moduleIndex) +
" returned error: " + client.readErrorMessage());
}
}
bool Module::isVirtualDetectorServer() const {
return sendToDetector<int>(F_IS_VIRTUAL);
}
@ -2136,73 +2170,6 @@ void Module::setADCConfiguration(const int chipIndex, const int adcIndex,
sendToDetector(F_SET_ADC_CONFIGURATION, args, nullptr);
}
void Module::getBadChannels(const std::string &fname) const {
LOG(logDEBUG1) << "Getting bad channels to " << fname;
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(F_GET_BAD_CHANNELS);
if (client.Receive<int>() == FAIL) {
throw DetectorError("Detector " + std::to_string(moduleIndex) +
" returned error: " + client.readErrorMessage());
}
// receive badchannels
auto nch = client.Receive<int>();
std::vector<int> badchannels(nch);
if (nch > 0) {
client.Receive(badchannels);
for (size_t i = 0; i < badchannels.size(); ++i) {
LOG(logDEBUG1) << i << ":" << badchannels[i];
}
}
// save to file
std::ofstream outfile(fname);
if (!outfile) {
throw RuntimeError("Could not create file to save bad channels");
}
for (auto ch : badchannels)
outfile << ch << '\n';
LOG(logDEBUG1) << nch << " bad channels saved to file";
}
void Module::setBadChannels(const std::string &fname) {
// read bad channels file
std::ifstream input_file(fname);
if (!input_file) {
throw RuntimeError("Could not open bad channels file " + fname +
" for reading");
}
std::vector<int> badchannels;
for (std::string line; std::getline(input_file, line);) {
line.erase(std::remove_if(begin(line), end(line), isspace),
end(line)); // remove space
if (!line.empty()) {
std::istringstream iss(line);
int ival = 0;
iss >> ival;
if (iss.fail()) {
throw RuntimeError("Could not load bad channels file. Invalid "
"channel number at position " +
std::to_string(badchannels.size()));
}
badchannels.push_back(ival);
}
}
// send bad channels to module
auto nch = static_cast<int>(badchannels.size());
LOG(logDEBUG1) << "Sending bad channels to detector, nch:" << nch;
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(F_SET_BAD_CHANNELS);
client.Send(nch);
if (nch > 0) {
client.Send(badchannels);
}
if (client.Receive<int>() == FAIL) {
throw DetectorError("Detector " + std::to_string(moduleIndex) +
" returned error: " + client.readErrorMessage());
}
}
// Mythen3 Specific
uint32_t Module::getCounterMask() const {

View File

@ -125,6 +125,8 @@ class Module : public virtual slsDetectorDefs {
void setMaster(const bool master);
bool getSynchronization() const;
void setSynchronization(const bool value);
std::vector<int> getBadChannels() const;
void setBadChannels(std::vector<int> list);
bool isVirtualDetectorServer() const;
@ -453,8 +455,6 @@ class Module : public virtual slsDetectorDefs {
int getADCConfiguration(const int chipIndex, const int adcIndex) const;
void setADCConfiguration(const int chipIndex, const int adcIndex,
int value);
void getBadChannels(const std::string &fname) const;
void setBadChannels(const std::string &fname);
/**************************************************
* *