Merge branch 'developer' into eiger

This commit is contained in:
2020-07-31 17:15:07 +02:00
6 changed files with 160 additions and 169 deletions

View File

@ -747,6 +747,35 @@ void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex,
LOG(logDEBUG) << "[ Progress:" << progress << ", Frame:" << currentFrame LOG(logDEBUG) << "[ Progress:" << progress << ", Frame:" << currentFrame
<< " ]"; << " ]";
// 1d check if npixelX has changed (m3 for different counters enabled)
if (is1d && static_cast<int>(nPixelsX) != data->nx) {
nPixelsX = data->nx;
LOG(logINFO) << "Change in Detector Shape:\n\tnPixelsX:" << nPixelsX;
delete[] datax1d;
datax1d = new double[nPixelsX];
for (unsigned int px = 0; px < nPixelsX; ++px) {
datax1d[px] = px;
}
if (datay1d.size()) {
for (auto &it : datay1d) {
delete[] it;
}
datay1d.clear();
}
datay1d.push_back(new double[nPixelsX]);
for (unsigned int px = 0; px < nPixelsX; ++px) {
datax1d[px] = px;
datay1d[0][px] = 0;
}
currentPersistency = 0;
if (gainDatay1d) {
delete[] gainDatay1d;
gainDatay1d = new double[nPixelsX];
std::fill(gainDatay1d, gainDatay1d + nPixelsX, 0);
}
}
// 2d (only image, not gain data, not pedestalvals), // 2d (only image, not gain data, not pedestalvals),
// check if npixelsX and npixelsY is the same (quad is different) // check if npixelsX and npixelsY is the same (quad is different)
if (!is1d && (static_cast<int>(nPixelsX) != data->nx || if (!is1d && (static_cast<int>(nPixelsX) != data->nx ||

View File

@ -24,8 +24,6 @@
namespace sls { namespace sls {
// Configuration
// creating new shm // creating new shm
Module::Module(detectorType type, int det_id, int module_id, bool verify) Module::Module(detectorType type, int det_id, int module_id, bool verify)
: moduleId(module_id), shm(det_id, module_id) { : moduleId(module_id), shm(det_id, module_id) {
@ -106,14 +104,11 @@ int64_t Module::getReceiverSoftwareVersion() const {
// static function // static function
slsDetectorDefs::detectorType slsDetectorDefs::detectorType
Module::getTypeFromDetector(const std::string &hostname, int cport) { Module::getTypeFromDetector(const std::string &hostname, int cport) {
int fnum = F_GET_DETECTOR_TYPE;
int ret = FAIL;
detectorType retval = GENERIC;
LOG(logDEBUG1) << "Getting detector type "; LOG(logDEBUG1) << "Getting detector type ";
sls::ClientSocket cs("Detector", hostname, cport); sls::ClientSocket socket("Detector", hostname, cport);
cs.Send(reinterpret_cast<char *>(&fnum), sizeof(fnum)); socket.Send(F_GET_DETECTOR_TYPE);
cs.Receive(reinterpret_cast<char *>(&ret), sizeof(ret)); socket.Receive<int>(); // TODO! Should we look at this OK/FAIL?
cs.Receive(reinterpret_cast<char *>(&retval), sizeof(retval)); auto retval = socket.Receive<detectorType>();
LOG(logDEBUG1) << "Detector type is " << retval; LOG(logDEBUG1) << "Detector type is " << retval;
return retval; return retval;
} }
@ -159,24 +154,21 @@ void Module::setSettings(detectorSettings isettings) {
} }
void Module::loadSettingsFile(const std::string &fname) { void Module::loadSettingsFile(const std::string &fname) {
std::string fn = fname;
std::ostringstream ostfn;
ostfn << fname;
// find specific file if it has detid in file name (.snxxx) // find specific file if it has detid in file name (.snxxx)
if (shm()->myDetectorType == EIGER || shm()->myDetectorType == MYTHEN3) { if (shm()->myDetectorType == EIGER || shm()->myDetectorType == MYTHEN3) {
std::ostringstream ostfn;
ostfn << fname;
if (fname.find(".sn") == std::string::npos && if (fname.find(".sn") == std::string::npos &&
fname.find(".trim") == std::string::npos && fname.find(".trim") == std::string::npos &&
fname.find(".settings") == std::string::npos) { fname.find(".settings") == std::string::npos) {
ostfn << ".sn" << std::setfill('0') << std::setw(3) << std::dec ostfn << ".sn" << std::setfill('0') << std::setw(3) << std::dec
<< getSerialNumber(); << getSerialNumber();
} }
auto myMod = readSettingsFile(ostfn.str());
setModule(myMod);
} else { } else {
throw RuntimeError("not implemented for this detector"); throw RuntimeError("not implemented for this detector");
} }
fn = ostfn.str();
auto myMod = readSettingsFile(fn);
setModule(myMod);
} }
int Module::getAllTrimbits() const { int Module::getAllTrimbits() const {
@ -450,22 +442,15 @@ std::vector<uint64_t> Module::getNumMissingPackets() const {
// TODO!(Erik) Refactor // TODO!(Erik) Refactor
LOG(logDEBUG1) << "Getting num missing packets"; LOG(logDEBUG1) << "Getting num missing packets";
if (shm()->useReceiverFlag) { if (shm()->useReceiverFlag) {
int fnum = F_GET_NUM_MISSING_PACKETS;
int ret = FAIL;
auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort); auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort);
client.Send(&fnum, sizeof(fnum)); client.Send(F_GET_NUM_MISSING_PACKETS);
client.Receive(&ret, sizeof(ret)); if (client.Receive<int>() == FAIL) {
if (ret == FAIL) {
char mess[MAX_STR_LENGTH]{};
client.Receive(mess, MAX_STR_LENGTH);
throw RuntimeError("Receiver " + std::to_string(moduleId) + throw RuntimeError("Receiver " + std::to_string(moduleId) +
" returned error: " + std::string(mess)); " returned error: " + client.readErrorMessage());
} else { } else {
int nports = 0; auto nports = client.Receive<int>();
client.Receive(&nports, sizeof(nports));
std::vector<uint64_t> retval(nports); std::vector<uint64_t> retval(nports);
client.Receive(retval.data(), client.Receive(retval);
sizeof(decltype(retval[0])) * retval.size());
LOG(logDEBUG1) << "Missing packets of Receiver" << moduleId << ": " LOG(logDEBUG1) << "Missing packets of Receiver" << moduleId << ": "
<< sls::ToString(retval); << sls::ToString(retval);
return retval; return retval;
@ -738,14 +723,13 @@ std::string Module::getReceiverHostname() const {
void Module::setReceiverHostname(const std::string &receiverIP) { void Module::setReceiverHostname(const std::string &receiverIP) {
LOG(logDEBUG1) << "Setting up Receiver with " << receiverIP; LOG(logDEBUG1) << "Setting up Receiver with " << receiverIP;
// recieverIP is none
if (receiverIP == "none") { if (receiverIP == "none") {
memset(shm()->rxHostname, 0, MAX_STR_LENGTH); memset(shm()->rxHostname, 0, MAX_STR_LENGTH);
sls::strcpy_safe(shm()->rxHostname, "none"); sls::strcpy_safe(shm()->rxHostname, "none");
shm()->useReceiverFlag = false; shm()->useReceiverFlag = false;
} }
// stop acquisition if running
if (getRunStatus() == RUNNING) { if (getRunStatus() == RUNNING) {
LOG(logWARNING) << "Acquisition already running, Stopping it."; LOG(logWARNING) << "Acquisition already running, Stopping it.";
stopAcquisition(); stopAcquisition();
@ -790,7 +774,6 @@ void Module::setReceiverHostname(const std::string &receiverIP) {
sendToDetector(F_SET_DEST_UDP_MAC2, retvals[1], nullptr); sendToDetector(F_SET_DEST_UDP_MAC2, retvals[1], nullptr);
} }
// update numinterfaces if different
shm()->numUDPInterfaces = retval.udpInterfaces; shm()->numUDPInterfaces = retval.udpInterfaces;
if (shm()->myDetectorType == MOENCH) { if (shm()->myDetectorType == MOENCH) {
@ -910,9 +893,9 @@ void Module::setFilePath(const std::string &path) {
} }
std::string Module::getFileName() const { std::string Module::getFileName() const {
char retvals[MAX_STR_LENGTH]{}; char buff[MAX_STR_LENGTH]{};
sendToReceiver(F_GET_RECEIVER_FILE_NAME, nullptr, retvals); sendToReceiver(F_GET_RECEIVER_FILE_NAME, nullptr, buff);
return std::string(retvals); return buff;
} }
void Module::setFileName(const std::string &fname) { void Module::setFileName(const std::string &fname) {
@ -1391,8 +1374,9 @@ void Module::setInjectChannel(const int offsetChannel,
sendToDetector(F_SET_INJECT_CHANNEL, args, nullptr); sendToDetector(F_SET_INJECT_CHANNEL, args, nullptr);
} }
void Module::sendVetoPhoton(const int chipIndex, const std::vector<int>& gainIndices, void Module::sendVetoPhoton(const int chipIndex,
const std::vector<int>& values) { const std::vector<int> &gainIndices,
const std::vector<int> &values) {
const int nch = gainIndices.size(); const int nch = gainIndices.size();
if (gainIndices.size() != values.size()) { if (gainIndices.size() != values.size()) {
throw RuntimeError("Number of Gain Indices and values do not match! " throw RuntimeError("Number of Gain Indices and values do not match! "
@ -1402,43 +1386,31 @@ void Module::sendVetoPhoton(const int chipIndex, const std::vector<int>& gainInd
} }
LOG(logDEBUG1) << "Sending veto photon/file to detector [chip:" << chipIndex LOG(logDEBUG1) << "Sending veto photon/file to detector [chip:" << chipIndex
<< ", nch:" << nch << "]"; << ", nch:" << nch << "]";
int fnum = F_SET_VETO_PHOTON;
int ret = FAIL; const int args[]{chipIndex, nch};
int args[]{chipIndex, nch};
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(&fnum, sizeof(fnum)); client.Send(F_SET_VETO_PHOTON);
client.Send(args, sizeof(args)); client.Send(args);
client.Send(gainIndices.data(), sizeof(decltype(gainIndices[0])) * nch); client.Send(gainIndices);
client.Send(values.data(), sizeof(decltype(values[0])) * nch); client.Send(values);
client.Send(gainIndices.data(), sizeof(int) * nch); if (client.Receive<int>() == FAIL) {
client.Send(values.data(), sizeof(int) * nch);
client.Receive(&ret, sizeof(ret));
if (ret == FAIL) {
char mess[MAX_STR_LENGTH]{};
client.Receive(mess, MAX_STR_LENGTH);
throw RuntimeError("Detector " + std::to_string(moduleId) + throw RuntimeError("Detector " + std::to_string(moduleId) +
" returned error: " + std::string(mess)); " returned error: " + client.readErrorMessage());
} }
} }
void Module::getVetoPhoton(const int chipIndex, void Module::getVetoPhoton(const int chipIndex,
const std::string &fname) const { const std::string &fname) const {
LOG(logDEBUG1) << "Getting veto photon [" << chipIndex << "]\n"; LOG(logDEBUG1) << "Getting veto photon [" << chipIndex << "]\n";
int fnum = F_GET_VETO_PHOTON;
int ret = FAIL;
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(&fnum, sizeof(fnum)); client.Send(F_GET_VETO_PHOTON);
client.Send(&chipIndex, sizeof(chipIndex)); client.Send(chipIndex);
client.Receive(&ret, sizeof(ret)); if (client.Receive<int>() == FAIL) {
if (ret == FAIL) {
char mess[MAX_STR_LENGTH]{};
client.Receive(mess, MAX_STR_LENGTH);
throw RuntimeError("Detector " + std::to_string(moduleId) + throw RuntimeError("Detector " + std::to_string(moduleId) +
" returned error: " + std::string(mess)); " returned error: " + client.readErrorMessage());
} }
int nch = -1; auto nch = client.Receive<int>();
client.Receive(&nch, sizeof(nch));
if (nch != shm()->nChan.x) { if (nch != shm()->nChan.x) {
throw RuntimeError("Could not get veto photon. Expected " + throw RuntimeError("Could not get veto photon. Expected " +
std::to_string(shm()->nChan.x) + " channels, got " + std::to_string(shm()->nChan.x) + " channels, got " +
@ -1446,13 +1418,13 @@ void Module::getVetoPhoton(const int chipIndex,
} }
std::vector<int> gainIndices(nch); std::vector<int> gainIndices(nch);
std::vector<int> values(nch); std::vector<int> values(nch);
client.Receive(gainIndices.data(), nch * sizeof(int)); client.Receive(gainIndices);
client.Receive(values.data(), nch * sizeof(int)); client.Receive(values);
// save to file // save to file
std::ofstream outfile; std::ofstream outfile(fname);
outfile.open(fname.c_str(), std::ios_base::out);
if (!outfile.is_open()) { if (!outfile) {
throw RuntimeError("Could not create file to save veto photon"); throw RuntimeError("Could not create file to save veto photon");
} }
for (int i = 0; i < nch; ++i) { for (int i = 0; i < nch; ++i) {
@ -1481,13 +1453,13 @@ void Module::setVetoPhoton(const int chipIndex, const int numPhotons,
std::to_string(energy)); std::to_string(energy));
} }
std::ifstream infile(fname.c_str()); std::ifstream infile(fname.c_str());
if (!infile.is_open()) { if (!infile) {
throw RuntimeError("Could not set veto photon. Could not open file: " + throw RuntimeError("Could not set veto photon. Could not open file: " +
fname); fname);
} }
LOG(logDEBUG1) << "Setting veto photon. Reading Gain values from file"; LOG(logDEBUG1) << "Setting veto photon. Reading Gain values from file";
int totalEnergy = numPhotons * energy; const int totalEnergy = numPhotons * energy;
std::vector<int> gainIndices; std::vector<int> gainIndices;
std::vector<int> values; std::vector<int> values;
@ -1515,7 +1487,7 @@ void Module::setVetoPhoton(const int chipIndex, const int numPhotons,
std::to_string(gainIndices.size())); std::to_string(gainIndices.size()));
} }
// caluclate gain index from gain thresholds and threhsold energy // caluclate gain index from gain thresholds and threshold energy
int gainIndex = 2; int gainIndex = 2;
if (totalEnergy < gainThreshold[0]) { if (totalEnergy < gainThreshold[0]) {
gainIndex = 0; gainIndex = 0;
@ -1552,19 +1524,14 @@ void Module::setVetoFile(const int chipIndex, const std::string &fname) {
throw RuntimeError("Could not set veto file. Invalid chip index: " + throw RuntimeError("Could not set veto file. Invalid chip index: " +
std::to_string(chipIndex)); std::to_string(chipIndex));
} }
std::ifstream infile(fname.c_str());
if (!infile.is_open()) { std::ifstream input_file(fname);
if (!input_file) {
throw RuntimeError("Could not set veto file for chip " + throw RuntimeError("Could not set veto file for chip " +
std::to_string(chipIndex) + std::to_string(chipIndex) +
". Could not open file: " + fname); ". Could not open file: " + fname);
} }
std::ifstream input_file(fname);
if (!input_file.is_open()) {
throw RuntimeError("Could not open veto file " + fname +
" for reading");
}
std::vector<int> gainIndices; std::vector<int> gainIndices;
std::vector<int> values; std::vector<int> values;
@ -1668,24 +1635,17 @@ void Module::setADCConfiguration(const int chipIndex, const int adcIndex,
void Module::getBadChannels(const std::string &fname) const { void Module::getBadChannels(const std::string &fname) const {
LOG(logDEBUG1) << "Getting bad channels to " << fname; LOG(logDEBUG1) << "Getting bad channels to " << fname;
int fnum = F_GET_BAD_CHANNELS;
int ret = FAIL;
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(&fnum, sizeof(fnum)); client.Send(F_GET_BAD_CHANNELS);
client.Receive(&ret, sizeof(ret)); if (client.Receive<int>() == FAIL) {
if (ret == FAIL) {
char mess[MAX_STR_LENGTH]{};
client.Receive(mess, MAX_STR_LENGTH);
throw RuntimeError("Detector " + std::to_string(moduleId) + throw RuntimeError("Detector " + std::to_string(moduleId) +
" returned error: " + std::string(mess)); " returned error: " + client.readErrorMessage());
} }
// receive badchannels // receive badchannels
int nch = -1; auto nch = client.Receive<int>();
client.Receive(&nch, sizeof(nch));
std::vector<int> badchannels(nch); std::vector<int> badchannels(nch);
if (nch > 0) { if (nch > 0) {
client.Receive(badchannels.data(), client.Receive(badchannels);
sizeof(badchannels[0]) * badchannels.size());
for (size_t i = 0; i < badchannels.size(); ++i) { for (size_t i = 0; i < badchannels.size(); ++i) {
LOG(logDEBUG1) << i << ":" << badchannels[i]; LOG(logDEBUG1) << i << ":" << badchannels[i];
} }
@ -1693,7 +1653,7 @@ void Module::getBadChannels(const std::string &fname) const {
// save to file // save to file
std::ofstream outfile(fname); std::ofstream outfile(fname);
if (!outfile.is_open()) { if (!outfile) {
throw RuntimeError("Could not create file to save bad channels"); throw RuntimeError("Could not create file to save bad channels");
} }
for (auto ch : badchannels) for (auto ch : badchannels)
@ -1704,7 +1664,7 @@ void Module::getBadChannels(const std::string &fname) const {
void Module::setBadChannels(const std::string &fname) { void Module::setBadChannels(const std::string &fname) {
// read bad channels file // read bad channels file
std::ifstream input_file(fname); std::ifstream input_file(fname);
if (!input_file.is_open()) { if (!input_file) {
throw RuntimeError("Could not open bad channels file " + fname + throw RuntimeError("Could not open bad channels file " + fname +
" for reading"); " for reading");
} }
@ -1726,22 +1686,17 @@ void Module::setBadChannels(const std::string &fname) {
} }
// send bad channels to module // send bad channels to module
int fnum = F_SET_BAD_CHANNELS; auto nch = static_cast<int>(badchannels.size());
int ret = FAIL;
int nch = badchannels.size();
LOG(logDEBUG1) << "Sending bad channels to detector, nch:" << nch; LOG(logDEBUG1) << "Sending bad channels to detector, nch:" << nch;
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(&fnum, sizeof(fnum)); client.Send(F_SET_BAD_CHANNELS);
client.Send(&nch, sizeof(nch)); client.Send(nch);
if (nch > 0) { if (nch > 0) {
client.Send(badchannels.data(), sizeof(int) * nch); client.Send(badchannels);
} }
client.Receive(&ret, sizeof(ret)); if (client.Receive<int>() == FAIL) {
if (ret == FAIL) {
char mess[MAX_STR_LENGTH]{};
client.Receive(mess, MAX_STR_LENGTH);
throw RuntimeError("Detector " + std::to_string(moduleId) + throw RuntimeError("Detector " + std::to_string(moduleId) +
" returned error: " + std::string(mess)); " returned error: " + client.readErrorMessage());
} }
} }
@ -1842,8 +1797,7 @@ uint32_t Module::getTenGigaADCEnableMask() const {
void Module::setTenGigaADCEnableMask(uint32_t mask) { void Module::setTenGigaADCEnableMask(uint32_t mask) {
sendToDetector(F_SET_ADC_ENABLE_MASK_10G, mask, nullptr); sendToDetector(F_SET_ADC_ENABLE_MASK_10G, mask, nullptr);
// update #nchan, as it depends on #samples, adcmask, updateNumberOfChannels(); // depends on samples and adcmask
updateNumberOfChannels();
// send to processor // send to processor
if (shm()->myDetectorType == MOENCH) if (shm()->myDetectorType == MOENCH)
@ -1863,8 +1817,7 @@ int Module::getNumberOfDigitalSamples() const {
void Module::setNumberOfDigitalSamples(int value) { void Module::setNumberOfDigitalSamples(int value) {
LOG(logDEBUG1) << "Setting number of digital samples to " << value; LOG(logDEBUG1) << "Setting number of digital samples to " << value;
sendToDetector(F_SET_NUM_DIGITAL_SAMPLES, value, nullptr); sendToDetector(F_SET_NUM_DIGITAL_SAMPLES, value, nullptr);
// update #nchan, as it depends on #samples, adcmask updateNumberOfChannels(); // depends on samples and adcmask
updateNumberOfChannels();
if (shm()->useReceiverFlag) { if (shm()->useReceiverFlag) {
LOG(logDEBUG1) << "Sending number of digital samples to Receiver: " LOG(logDEBUG1) << "Sending number of digital samples to Receiver: "
<< value; << value;
@ -1952,7 +1905,7 @@ void Module::setLEDEnable(bool enable) {
void Module::setPattern(const std::string &fname) { void Module::setPattern(const std::string &fname) {
auto pat = sls::make_unique<patternParameters>(); auto pat = sls::make_unique<patternParameters>();
std::ifstream input_file(fname); std::ifstream input_file(fname);
if (!input_file.is_open()) { if (!input_file) {
throw RuntimeError("Could not open pattern file " + fname + throw RuntimeError("Could not open pattern file " + fname +
" for reading"); " for reading");
} }
@ -2136,7 +2089,7 @@ void Module::startPattern() { sendToDetector(F_START_PATTERN); }
// Moench // Moench
std::map<std::string, std::string> Module::getAdditionalJsonHeader() const { std::map<std::string, std::string> Module::getAdditionalJsonHeader() const {
//TODO, refactor this function with a more robust sending. // TODO, refactor this function with a more robust sending.
// Now assuming whitespace separated key value // Now assuming whitespace separated key value
if (!shm()->useReceiverFlag) { if (!shm()->useReceiverFlag) {
throw RuntimeError("Set rx_hostname first to use receiver parameters " throw RuntimeError("Set rx_hostname first to use receiver parameters "
@ -2144,12 +2097,9 @@ std::map<std::string, std::string> Module::getAdditionalJsonHeader() const {
} }
auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort); auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort);
client.Send(F_GET_ADDITIONAL_JSON_HEADER); client.Send(F_GET_ADDITIONAL_JSON_HEADER);
auto ret = client.Receive<int>(); if (client.Receive<int>() == FAIL) {
if (ret == FAIL) {
char mess[MAX_STR_LENGTH]{};
client.Receive(mess, MAX_STR_LENGTH);
throw RuntimeError("Receiver " + std::to_string(moduleId) + throw RuntimeError("Receiver " + std::to_string(moduleId) +
" returned error: " + std::string(mess)); " returned error: " + client.readErrorMessage());
} else { } else {
auto size = client.Receive<int>(); auto size = client.Receive<int>();
std::string buff(size, '\0'); std::string buff(size, '\0');
@ -2158,7 +2108,7 @@ std::map<std::string, std::string> Module::getAdditionalJsonHeader() const {
client.Receive(&buff[0], buff.size()); client.Receive(&buff[0], buff.size());
std::istringstream iss(buff); std::istringstream iss(buff);
std::string key, value; std::string key, value;
while(iss >> key){ while (iss >> key) {
iss >> value; iss >> value;
retval[key] = value; retval[key] = value;
} }
@ -2184,7 +2134,7 @@ void Module::setAdditionalJsonHeader(
} }
} }
std::ostringstream oss; std::ostringstream oss;
for (auto& it : jsonHeader) for (auto &it : jsonHeader)
oss << it.first << ' ' << it.second << ' '; oss << it.first << ' ' << it.second << ' ';
auto buff = oss.str(); auto buff = oss.str();
const auto size = static_cast<int>(buff.size()); const auto size = static_cast<int>(buff.size());
@ -2196,12 +2146,9 @@ void Module::setAdditionalJsonHeader(
if (size > 0) if (size > 0)
client.Send(&buff[0], buff.size()); client.Send(&buff[0], buff.size());
auto ret = client.Receive<int>(); if (client.Receive<int>() == FAIL) {
if (ret == FAIL) {
char mess[MAX_STR_LENGTH]{};
client.Receive(mess, MAX_STR_LENGTH);
throw RuntimeError("Receiver " + std::to_string(moduleId) + throw RuntimeError("Receiver " + std::to_string(moduleId) +
" returned error: " + std::string(mess)); " returned error: " + client.readErrorMessage());
} }
} }
@ -2904,8 +2851,6 @@ int Module::sendModule(sls_detector_module *myMod, sls::ClientSocket &client) {
} }
void Module::setModule(sls_detector_module &module, bool trimbits) { void Module::setModule(sls_detector_module &module, bool trimbits) {
int fnum = F_SET_MODULE;
int ret = FAIL;
LOG(logDEBUG1) << "Setting module with trimbits:" << trimbits; LOG(logDEBUG1) << "Setting module with trimbits:" << trimbits;
// to exclude trimbits // to exclude trimbits
if (!trimbits) { if (!trimbits) {
@ -2913,14 +2858,11 @@ void Module::setModule(sls_detector_module &module, bool trimbits) {
module.nchip = 0; module.nchip = 0;
} }
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(&fnum, sizeof(fnum)); client.Send(F_SET_MODULE);
sendModule(&module, client); sendModule(&module, client);
client.Receive(&ret, sizeof(ret)); if (client.Receive<int>() == FAIL) {
if (ret == FAIL) {
char mess[MAX_STR_LENGTH] = {0};
client.Receive(mess, sizeof(mess));
throw RuntimeError("Detector " + std::to_string(moduleId) + throw RuntimeError("Detector " + std::to_string(moduleId) +
" returned error: " + mess); " returned error: " + client.readErrorMessage());
} }
} }
@ -3108,7 +3050,7 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
} else { } else {
infile.open(fname.c_str(), std::ios_base::in); infile.open(fname.c_str(), std::ios_base::in);
} }
if (!infile.is_open()) { if (!infile) {
throw RuntimeError("Could not open settings file: " + fname); throw RuntimeError("Could not open settings file: " + fname);
} }
@ -3161,24 +3103,17 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
void Module::programFPGAviaBlackfin(std::vector<char> buffer) { void Module::programFPGAviaBlackfin(std::vector<char> buffer) {
uint64_t filesize = buffer.size(); uint64_t filesize = buffer.size();
// send program from memory to detector // send program from memory to detector
int fnum = F_PROGRAM_FPGA;
int ret = FAIL;
char mess[MAX_STR_LENGTH] = {0};
LOG(logINFO) << "Sending programming binary (from pof) to detector " LOG(logINFO) << "Sending programming binary (from pof) to detector "
<< moduleId << " (" << shm()->hostname << ")"; << moduleId << " (" << shm()->hostname << ")";
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(&fnum, sizeof(fnum)); client.Send(F_PROGRAM_FPGA);
client.Send(&filesize, sizeof(filesize)); client.Send(filesize);
client.Receive(&ret, sizeof(ret));
// error in detector at opening file pointer to flash // error in detector at opening file pointer to flash
if (ret == FAIL) { if (client.Receive<int>() == FAIL) {
client.Receive(mess, sizeof(mess));
std::ostringstream os; std::ostringstream os;
os << "Detector " << moduleId << " (" << shm()->hostname << ")" os << "Detector " << moduleId << " (" << shm()->hostname << ")"
<< " returned error: " << mess; << " returned error: " << client.readErrorMessage();
throw RuntimeError(os.str()); throw RuntimeError(os.str());
} }
@ -3219,13 +3154,11 @@ void Module::programFPGAviaBlackfin(std::vector<char> buffer) {
<< "\t filesize:" << filesize; << "\t filesize:" << filesize;
client.Send(&buffer[currentPointer], unitprogramsize); client.Send(&buffer[currentPointer], unitprogramsize);
client.Receive(&ret, sizeof(ret)); if (client.Receive<int>() == FAIL) {
if (ret == FAIL) { std::cout << '\n';
printf("\n");
client.Receive(mess, sizeof(mess));
std::ostringstream os; std::ostringstream os;
os << "Detector " << moduleId << " (" << shm()->hostname << ")" os << "Detector " << moduleId << " (" << shm()->hostname << ")"
<< " returned error: " << mess; << " returned error: " << client.readErrorMessage();
throw RuntimeError(os.str()); throw RuntimeError(os.str());
} }
filesize -= unitprogramsize; filesize -= unitprogramsize;
@ -3238,39 +3171,32 @@ void Module::programFPGAviaBlackfin(std::vector<char> buffer) {
(static_cast<double>(totalsize - filesize) / totalsize) * 100)); (static_cast<double>(totalsize - filesize) / totalsize) * 100));
std::cout << std::flush; std::cout << std::flush;
} }
printf("\n"); std::cout << '\n';
LOG(logINFO) << "FPGA programmed successfully"; LOG(logINFO) << "FPGA programmed successfully";
rebootController(); rebootController();
} }
void Module::programFPGAviaNios(std::vector<char> buffer) { void Module::programFPGAviaNios(std::vector<char> buffer) {
uint64_t filesize = buffer.size(); uint64_t filesize = buffer.size();
int fnum = F_PROGRAM_FPGA;
int ret = FAIL;
char mess[MAX_STR_LENGTH] = {0};
LOG(logINFO) << "Sending programming binary (from rbf) to detector " LOG(logINFO) << "Sending programming binary (from rbf) to detector "
<< moduleId << " (" << shm()->hostname << ")"; << moduleId << " (" << shm()->hostname << ")";
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(&fnum, sizeof(fnum)); client.Send(F_PROGRAM_FPGA);
// filesize // filesize
client.Send(&filesize, sizeof(filesize)); client.Send(filesize);
client.Receive(&ret, sizeof(ret)); if (client.Receive<int>() == FAIL) {
if (ret == FAIL) {
client.Receive(mess, sizeof(mess));
std::ostringstream os; std::ostringstream os;
os << "Detector " << moduleId << " (" << shm()->hostname << ")" os << "Detector " << moduleId << " (" << shm()->hostname << ")"
<< " returned error: " << mess; << " returned error: " << client.readErrorMessage();
throw RuntimeError(os.str()); throw RuntimeError(os.str());
} }
// program // program
client.Send(&buffer[0], filesize); client.Send(buffer);
client.Receive(&ret, sizeof(ret)); if (client.Receive<int>() == FAIL) {
if (ret == FAIL) {
client.Receive(mess, sizeof(mess));
std::ostringstream os; std::ostringstream os;
os << "Detector " << moduleId << " (" << shm()->hostname << ")" os << "Detector " << moduleId << " (" << shm()->hostname << ")"
<< " returned error: " << mess; << " returned error: " << client.readErrorMessage();
throw RuntimeError(os.str()); throw RuntimeError(os.str());
} }
LOG(logINFO) << "FPGA programmed successfully"; LOG(logINFO) << "FPGA programmed successfully";

View File

@ -15,6 +15,7 @@ class ClientSocket : public DataSocket {
int sendCommandThenRead(int fnum, const void *args, size_t args_size, int sendCommandThenRead(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size); void *retval, size_t retval_size);
std::string readErrorMessage();
private: private:
void readReply(int &ret, void *retval, size_t retval_size); void readReply(int &ret, void *retval, size_t retval_size);
struct sockaddr_in serverAddr {}; struct sockaddr_in serverAddr {};

View File

@ -1,10 +1,12 @@
#pragma once #pragma once
#include "TypeTraits.h"
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <netdb.h> #include <netdb.h>
#include <numeric> #include <numeric>
#include <string> #include <string>
#include <vector>
namespace sls { namespace sls {
/* Base class for TCP socket, this is used to send data between detector, client /* Base class for TCP socket, this is used to send data between detector, client
@ -24,9 +26,21 @@ class DataSocket {
int getSocketId() const { return sockfd_; } int getSocketId() const { return sockfd_; }
int Send(const void *buffer, size_t size); int Send(const void *buffer, size_t size);
template <typename T> int Send(T &&data) {
// Send everything that is not a vector by using address and sizeof
// TODO! We probably should restrict this even more to avoid bugs when
// we send object instead of data
template <typename T>
typename std::enable_if<
!is_vector<typename std::remove_reference<T>::type>::value, int>::type
Send(T &&data) {
return Send(&data, sizeof(data)); return Send(&data, sizeof(data));
} }
template <typename T> int Send(const std::vector<T> &vec) {
return Send(vec.data(), sizeof(T) * vec.size());
}
// Variadic template to send all arguments // Variadic template to send all arguments
template <class... Args> int SendAll(Args &&... args) { template <class... Args> int SendAll(Args &&... args) {
auto l = std::initializer_list<int>{Send(args)...}; auto l = std::initializer_list<int>{Send(args)...};
@ -34,10 +48,16 @@ class DataSocket {
return sum; return sum;
} }
int Receive(void *buffer, size_t size); int Receive(void *buffer, size_t size);
template <typename T> int Receive(T &arg) { template <typename T> int Receive(T &arg) {
return Receive(&arg, sizeof(arg)); return Receive(&arg, sizeof(arg));
} }
template<typename T>
int Receive(std::vector<T>& buff){
return Receive(buff.data(), sizeof(T) * buff.size());
}
template <typename T> T Receive() { template <typename T> T Receive() {
T arg; T arg;
Receive(&arg, sizeof(arg)); Receive(&arg, sizeof(arg));

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <type_traits> #include <type_traits>
#include <vector>
namespace sls { namespace sls {
@ -62,8 +63,11 @@ template <typename T>
struct is_container< struct is_container<
T, typename std::conditional< T, typename std::conditional<
false, false,
is_container_helper<typename T::value_type, typename T::size_type, is_container_helper<
typename T::iterator, typename T::const_iterator, typename std::remove_reference<T>::type::value_type,
typename std::remove_reference<T>::type::size_type,
typename std::remove_reference<T>::type::iterator,
typename std::remove_reference<T>::type::const_iterator,
decltype(std::declval<T>().size()), decltype(std::declval<T>().size()),
decltype(std::declval<T>().begin()), decltype(std::declval<T>().begin()),
decltype(std::declval<T>().end()), decltype(std::declval<T>().end()),
@ -92,4 +96,9 @@ struct is_light_container<
decltype(std::declval<T>().end())>, decltype(std::declval<T>().end())>,
void>::type> : public std::true_type {}; void>::type> : public std::true_type {};
template <typename T> struct is_vector : public std::false_type {};
template <typename T>
struct is_vector<std::vector<T>> : public std::true_type {};
} // namespace sls } // namespace sls

View File

@ -101,4 +101,10 @@ void ClientSocket::readReply(int &ret, void *retval, size_t retval_size) {
} }
} }
std::string ClientSocket::readErrorMessage(){
std::string error_msg(MAX_STR_LENGTH, '\0');
Receive(&error_msg[0], error_msg.size());
return error_msg;
}
}; // namespace sls }; // namespace sls