merging problem

This commit is contained in:
2020-02-18 10:55:41 +01:00
138 changed files with 2252 additions and 1698 deletions

View File

@ -45,9 +45,7 @@ void CmdParser::Parse(const std::string &s) {
auto old_size = arguments_.size();
arguments_.erase(std::remove_if(begin(arguments_), end(arguments_),
[](const std::string &item) {
if (item == "-h" || item == "--help")
return true;
return false;
return (item == "-h" || item == "--help");
}),
end(arguments_));
if (old_size - arguments_.size() > 0)

View File

@ -1288,7 +1288,7 @@ std::string CmdProxy::Counters(int action) {
std::vector <int> result;
for (size_t i = 0; i < 32; ++i) {
if (mask & (1 << i)) {
result.push_back((int)i);
result.push_back(static_cast<int>(i));
}
}
os << sls::ToString(result) << '\n';
@ -1807,7 +1807,8 @@ std::string CmdProxy::ProgramFpga(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[fname.pof]\n\t[Jungfrau][Ctb] Programs FPGA from pof file."
os << "[fname.pof | fname.rbf]\n\t[Jungfrau][Ctb] Programs FPGA from pof file."
<< "\n\t[Mythen3][Gotthard2] Programs FPGA from rbf file."
<< '\n';
} else if (action == defs::GET_ACTION) {
throw sls::RuntimeError("Cannot get");
@ -1815,9 +1816,6 @@ std::string CmdProxy::ProgramFpga(int action) {
if (args.size() != 1) {
WrongNumberOfParameters(1);
}
if (args[0].find(".pof") == std::string::npos) {
throw sls::RuntimeError("Programming file must be a pof file.");
}
det->programFPGA(args[0], {det_id});
os << "successful\n";
} else {
@ -1980,6 +1978,39 @@ std::string CmdProxy::BitOperations(int action) {
return os.str();
}
std::string CmdProxy::InitialChecks(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[0, 1]\n\tEnable or disable intial compatibility and other checks at detector start up. It is enabled by default. Must come before 'hostname' command to take effect. Can be used to reprogram fpga when current firmware is incompatible."
<< '\n';
} else if (action == defs::GET_ACTION) {
if (det_id != -1) {
throw sls::RuntimeError(
"Cannot enable/disable initial checks at module level");
}
if (!args.empty()) {
WrongNumberOfParameters(0);
}
auto t = det->getInitialChecks();
os << t << '\n';
} else if (action == defs::PUT_ACTION) {
if (det_id != -1) {
throw sls::RuntimeError(
"Cannot get initial checks enable at module level");
}
if (args.size() != 1) {
WrongNumberOfParameters(1);
}
det->setInitialChecks(std::stoi(args[0]));
os << args.front() << '\n';
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
/* Insignificant */
std::string CmdProxy::ExecuteCommand(int action) {

View File

@ -876,6 +876,7 @@ class CmdProxy {
{"getbit", &CmdProxy::BitOperations},
{"firmwaretest", &CmdProxy::firmwaretest},
{"bustest", &CmdProxy::bustest},
{"initialchecks", &CmdProxy::InitialChecks},
/* Insignificant */
{"port", &CmdProxy::port},
@ -973,6 +974,7 @@ class CmdProxy {
std::string Register(int action);
std::string AdcRegister(int action);
std::string BitOperations(int action);
std::string InitialChecks(int action);
/* Insignificant */
std::string ExecuteCommand(int action);
std::string UserDetails(int action);
@ -1009,7 +1011,7 @@ class CmdProxy {
INTEGER_COMMAND_NOID(frames, getNumberOfFrames, setNumberOfFrames,
std::stol,
"[n_frames]\n\tNumber of frames per aquire. In trigger mode, number of frames per trigger."
"\n\t[Gotthard2] Burst mode has a maximum of 2720 frames. Frames number for both modes are uploaded to detector just before acquisition starts");
"\n\t[Gotthard2] Burst mode has a maximum of 2720 frames.");
INTEGER_COMMAND_NOID(triggers, getNumberOfTriggers, setNumberOfTriggers,
std::stol,
@ -1696,7 +1698,7 @@ class CmdProxy {
"\n\t[Jungfrau][Ctb] Reset FPGA.");
EXECUTE_SET_COMMAND(rebootcontroller, rebootController,
"\n\t[Jungfrau][Ctb] Reboot controler (blackfin) of detector.");
"\n\t[Jungfrau][Ctb][Gotthard][Mythen3][Gotthard2] Reboot controler (blackfin) of detector.");
EXECUTE_SET_COMMAND(firmwaretest, executeFirmwareTest,
"\n\t[Jungfrau][Gotthard][Mythen3][Gotthard2][Ctb] Firmware test, ie. reads a read fixed pattern from a register.");

View File

@ -4,7 +4,7 @@
#include "container_utils.h"
#include "detectorData.h"
#include "logger.h"
#include "multiSlsDetector.h"
#include "DetectorImpl.h"
#include "slsDetector.h"
#include "sls_detector_defs.h"
@ -41,7 +41,7 @@ void freeSharedMemory(int multiId, int detPos) {
using defs = slsDetectorDefs;
Detector::Detector(int shm_id)
: pimpl(sls::make_unique<multiSlsDetector>(shm_id)) {}
: pimpl(sls::make_unique<DetectorImpl>(shm_id)) {}
Detector::~Detector() = default;
@ -51,7 +51,7 @@ void Detector::freeSharedMemory() { pimpl->freeSharedMemory(); }
void Detector::loadConfig(const std::string &fname) {
int shm_id = getShmId();
freeSharedMemory();
pimpl = sls::make_unique<multiSlsDetector>(shm_id);
pimpl = sls::make_unique<DetectorImpl>(shm_id);
FILE_LOG(logINFO) << "Loading configuration file: " << fname;
loadParameters(fname);
}
@ -148,7 +148,7 @@ Result<defs::detectorSettings> Detector::getSettings(Positions pos) const {
return pimpl->Parallel(&slsDetector::getSettings, pos);
}
void Detector::setSettings(defs::detectorSettings value, Positions pos) {
void Detector::setSettings(const defs::detectorSettings value, Positions pos) {
pimpl->Parallel(&slsDetector::setSettings, pos, value);
}
@ -1652,9 +1652,7 @@ void Detector::setDetectorMode(defs::detectorModeType value, Positions pos) {
// Advanced
void Detector::programFPGA(const std::string &fname, Positions pos) {
FILE_LOG(logINFO)
<< "Updating Firmware. This can take awhile. Please be patient...";
std::vector<char> buffer = pimpl->readPofFile(fname);
std::vector<char> buffer = pimpl->readProgrammingFile(fname);
pimpl->Parallel(&slsDetector::programFPGA, pos, buffer);
}
@ -1709,6 +1707,14 @@ void Detector::writeAdcRegister(uint32_t addr, uint32_t value, Positions pos) {
pimpl->Parallel(&slsDetector::writeAdcRegister, pos, addr, value);
}
bool Detector::getInitialChecks() const {
return pimpl->getInitialChecks();
}
void Detector::setInitialChecks(const bool value) {
pimpl->setInitialChecks(value);
}
// Insignificant
Result<int> Detector::getControlPort(Positions pos) const {

View File

@ -1,4 +1,4 @@
#include "multiSlsDetector.h"
#include "DetectorImpl.h"
#include "SharedMemory.h"
#include "ZmqSocket.h"
#include "detectorData.h"
@ -28,14 +28,14 @@
using namespace sls;
multiSlsDetector::multiSlsDetector(int multi_id, bool verify, bool update)
DetectorImpl::DetectorImpl(int multi_id, bool verify, bool update)
: multiId(multi_id), multi_shm(multi_id, -1) {
setupMultiDetector(verify, update);
}
multiSlsDetector::~multiSlsDetector() = default;
DetectorImpl::~DetectorImpl() = default;
void multiSlsDetector::setupMultiDetector(bool verify, bool update) {
void DetectorImpl::setupMultiDetector(bool verify, bool update) {
initSharedMemory(verify);
initializeMembers(verify);
if (update) {
@ -43,104 +43,17 @@ void multiSlsDetector::setupMultiDetector(bool verify, bool update) {
}
}
template <typename RT, typename... CT>
std::vector<RT>
multiSlsDetector::serialCall(RT (slsDetector::*somefunc)(CT...),
typename NonDeduced<CT>::type... Args) {
std::vector<RT> result;
result.reserve(detectors.size());
for (auto &d : detectors) {
result.push_back((d.get()->*somefunc)(Args...));
}
return result;
}
template <typename RT, typename... CT>
std::vector<RT>
multiSlsDetector::serialCall(RT (slsDetector::*somefunc)(CT...) const,
typename NonDeduced<CT>::type... Args) const {
std::vector<RT> result;
result.reserve(detectors.size());
for (auto &d : detectors) {
result.push_back((d.get()->*somefunc)(Args...));
}
return result;
}
template <typename RT, typename... CT>
std::vector<RT>
multiSlsDetector::parallelCall(RT (slsDetector::*somefunc)(CT...),
typename NonDeduced<CT>::type... Args) {
std::vector<std::future<RT>> futures;
for (auto &d : detectors) {
futures.push_back(
std::async(std::launch::async, somefunc, d.get(), Args...));
}
std::vector<RT> result;
result.reserve(detectors.size());
for (auto &i : futures) {
result.push_back(i.get());
}
return result;
}
template <typename RT, typename... CT>
std::vector<RT>
multiSlsDetector::parallelCall(RT (slsDetector::*somefunc)(CT...) const,
typename NonDeduced<CT>::type... Args) const {
std::vector<std::future<RT>> futures;
for (auto &d : detectors) {
futures.push_back(
std::async(std::launch::async, somefunc, d.get(), Args...));
}
std::vector<RT> result;
result.reserve(detectors.size());
for (auto &i : futures) {
result.push_back(i.get());
}
return result;
}
template <typename... CT>
void multiSlsDetector::parallelCall(void (slsDetector::*somefunc)(CT...),
typename NonDeduced<CT>::type... Args) {
std::vector<std::future<void>> futures;
for (auto &d : detectors) {
futures.push_back(
std::async(std::launch::async, somefunc, d.get(), Args...));
}
for (auto &i : futures) {
i.get();
}
return;
}
template <typename... CT>
void multiSlsDetector::parallelCall(
void (slsDetector::*somefunc)(CT...) const,
typename NonDeduced<CT>::type... Args) const {
std::vector<std::future<void>> futures;
for (auto &d : detectors) {
futures.push_back(
std::async(std::launch::async, somefunc, d.get(), Args...));
}
for (auto &i : futures) {
i.get();
}
return;
}
void multiSlsDetector::setAcquiringFlag(bool flag) {
void DetectorImpl::setAcquiringFlag(bool flag) {
multi_shm()->acquiringFlag = flag;
}
int multiSlsDetector::getMultiId() const { return multiId; }
int DetectorImpl::getMultiId() const { return multiId; }
std::string multiSlsDetector::getPackageVersion() const { return GITBRANCH; }
std::string DetectorImpl::getPackageVersion() const { return GITBRANCH; }
int64_t multiSlsDetector::getClientSoftwareVersion() const { return APILIB; }
int64_t DetectorImpl::getClientSoftwareVersion() const { return APILIB; }
void multiSlsDetector::freeSharedMemory(int multiId, int detPos) {
void DetectorImpl::freeSharedMemory(int multiId, int detPos) {
// single
if (detPos >= 0) {
SharedMemory<sharedSlsDetector> temp_shm(multiId, detPos);
@ -166,7 +79,7 @@ void multiSlsDetector::freeSharedMemory(int multiId, int detPos) {
}
}
void multiSlsDetector::freeSharedMemory() {
void DetectorImpl::freeSharedMemory() {
zmqSocket.clear();
for (auto &d : detectors) {
d->freeSharedMemory();
@ -178,7 +91,7 @@ void multiSlsDetector::freeSharedMemory() {
client_downstream = false;
}
std::string multiSlsDetector::getUserDetails() {
std::string DetectorImpl::getUserDetails() {
if (detectors.empty()) {
return std::string("none");
}
@ -212,7 +125,15 @@ std::string multiSlsDetector::getUserDetails() {
return sstream.str();
}
void multiSlsDetector::initSharedMemory(bool verify) {
bool DetectorImpl::getInitialChecks() const {
return multi_shm()->initialChecks;
}
void DetectorImpl::setInitialChecks(const bool value) {
multi_shm()->initialChecks = value;
}
void DetectorImpl::initSharedMemory(bool verify) {
if (!multi_shm.IsExisting()) {
multi_shm.CreateSharedMemory();
initializeDetectorStructure();
@ -230,7 +151,7 @@ void multiSlsDetector::initSharedMemory(bool verify) {
}
}
void multiSlsDetector::initializeDetectorStructure() {
void DetectorImpl::initializeDetectorStructure() {
multi_shm()->shmversion = MULTI_SHMVERSION;
multi_shm()->numberOfDetectors = 0;
multi_shm()->multiDetectorType = GENERIC;
@ -240,10 +161,11 @@ void multiSlsDetector::initializeDetectorStructure() {
multi_shm()->numberOfChannels.y = 0;
multi_shm()->acquiringFlag = false;
multi_shm()->receiver_upstream = false;
multi_shm()->initialChecks = true;
}
void multiSlsDetector::initializeMembers(bool verify) {
// multiSlsDetector
void DetectorImpl::initializeMembers(bool verify) {
// DetectorImpl
zmqSocket.clear();
// get objects from single det shared memory (open)
@ -258,10 +180,10 @@ void multiSlsDetector::initializeMembers(bool verify) {
}
}
void multiSlsDetector::updateUserdetails() {
void DetectorImpl::updateUserdetails() {
multi_shm()->lastPID = getpid();
memset(multi_shm()->lastUser, 0, SHORT_STRING_LENGTH);
memset(multi_shm()->lastDate, 0, SHORT_STRING_LENGTH);
memset(multi_shm()->lastUser, 0, sizeof(multi_shm()->lastUser));
memset(multi_shm()->lastDate, 0, sizeof(multi_shm()->lastDate));
try {
sls::strcpy_safe(multi_shm()->lastUser, exec("whoami").c_str());
sls::strcpy_safe(multi_shm()->lastDate, exec("date").c_str());
@ -271,7 +193,7 @@ void multiSlsDetector::updateUserdetails() {
}
}
bool multiSlsDetector::isAcquireReady() {
bool DetectorImpl::isAcquireReady() {
if (multi_shm()->acquiringFlag) {
FILE_LOG(logWARNING)
<< "Acquire has already started. "
@ -283,31 +205,26 @@ bool multiSlsDetector::isAcquireReady() {
return true;
}
std::string multiSlsDetector::exec(const char *cmd) {
int bufsize = 128;
char buffer[bufsize];
std::string result = "";
std::string DetectorImpl::exec(const char *cmd) {
char buffer[128];
std::string result;
FILE *pipe = popen(cmd, "r");
if (pipe == nullptr) {
throw RuntimeError("Could not open pipe");
}
try {
while (feof(pipe) == 0) {
if (fgets(buffer, bufsize, pipe) != nullptr) {
result += buffer;
}
while (feof(pipe) == 0) {
if (fgets(buffer, sizeof(buffer), pipe) != nullptr) {
result += buffer;
}
} catch (...) {
pclose(pipe);
throw;
}
pclose(pipe);
result.erase(result.find_last_not_of(" \t\n\r") + 1);
return result;
}
void multiSlsDetector::setVirtualDetectorServers(const int numdet,
const int port) {
void DetectorImpl::setVirtualDetectorServers(const int numdet, const int port) {
std::vector<std::string> hostnames;
for (int i = 0; i < numdet; ++i) {
// * 2 is for control and stop port
@ -317,14 +234,16 @@ void multiSlsDetector::setVirtualDetectorServers(const int numdet,
setHostname(hostnames);
}
void multiSlsDetector::setHostname(const std::vector<std::string> &name) {
void DetectorImpl::setHostname(const std::vector<std::string> &name) {
// this check is there only to allow the previous detsizechan command
if (multi_shm()->numberOfDetectors != 0) {
FILE_LOG(logWARNING)
<< "There are already detector(s) in shared memory."
"Freeing Shared memory now.";
bool initialChecks = multi_shm()->initialChecks;
freeSharedMemory();
setupMultiDetector();
multi_shm()->initialChecks = initialChecks;
}
for (const auto &hostname : name) {
addSlsDetector(hostname);
@ -332,7 +251,7 @@ void multiSlsDetector::setHostname(const std::vector<std::string> &name) {
updateDetectorSize();
}
void multiSlsDetector::addSlsDetector(const std::string &hostname) {
void DetectorImpl::addSlsDetector(const std::string &hostname) {
FILE_LOG(logINFO) << "Adding detector " << hostname;
int port = DEFAULT_PORTNO;
@ -357,18 +276,20 @@ void multiSlsDetector::addSlsDetector(const std::string &hostname) {
// get type by connecting
detectorType type = slsDetector::getTypeFromDetector(host, port);
int pos = (int)detectors.size();
detectors.push_back(
auto pos = detectors.size();
detectors.emplace_back(
sls::make_unique<slsDetector>(type, multiId, pos, false));
multi_shm()->numberOfDetectors = detectors.size();
detectors[pos]->setControlPort(port);
detectors[pos]->setStopPort(port + 1);
detectors[pos]->setHostname(host);
detectors[pos]->setHostname(host, multi_shm()->initialChecks);
// detector type updated by now
multi_shm()->multiDetectorType = Parallel(&slsDetector::getDetectorType, {}).tsquash("Inconsistent detector types.");
multi_shm()->multiDetectorType =
Parallel(&slsDetector::getDetectorType, {})
.tsquash("Inconsistent detector types.");
}
void multiSlsDetector::updateDetectorSize() {
void DetectorImpl::updateDetectorSize() {
FILE_LOG(logDEBUG) << "Updating Multi-Detector Size: " << size();
const slsDetectorDefs::xy det_size = detectors[0]->getNumberOfChannels();
@ -403,17 +324,17 @@ void multiSlsDetector::updateDetectorSize() {
}
}
int multiSlsDetector::size() const { return detectors.size(); }
int DetectorImpl::size() const { return detectors.size(); }
slsDetectorDefs::xy multiSlsDetector::getNumberOfDetectors() const {
slsDetectorDefs::xy DetectorImpl::getNumberOfDetectors() const {
return multi_shm()->numberOfDetector;
}
slsDetectorDefs::xy multiSlsDetector::getNumberOfChannels() const {
slsDetectorDefs::xy DetectorImpl::getNumberOfChannels() const {
return multi_shm()->numberOfChannels;
}
void multiSlsDetector::setNumberOfChannels(const slsDetectorDefs::xy c) {
void DetectorImpl::setNumberOfChannels(const slsDetectorDefs::xy c) {
if (size() > 1) {
throw RuntimeError(
"Set the number of channels before setting hostname.");
@ -421,7 +342,7 @@ void multiSlsDetector::setNumberOfChannels(const slsDetectorDefs::xy c) {
multi_shm()->numberOfChannels = c;
}
void multiSlsDetector::setGapPixelsinReceiver(bool enable) {
void DetectorImpl::setGapPixelsinReceiver(bool enable) {
Parallel(&slsDetector::enableGapPixels, {}, static_cast<int>(enable));
// update number of channels
Result<slsDetectorDefs::xy> res =
@ -434,7 +355,7 @@ void multiSlsDetector::setGapPixelsinReceiver(bool enable) {
}
}
int multiSlsDetector::createReceivingDataSockets(const bool destroy) {
int DetectorImpl::createReceivingDataSockets(const bool destroy) {
if (destroy) {
FILE_LOG(logINFO) << "Going to destroy data sockets";
// close socket
@ -452,7 +373,8 @@ int multiSlsDetector::createReceivingDataSockets(const bool destroy) {
if (multi_shm()->multiDetectorType == EIGER) {
numSocketsPerDetector = 2;
}
if (Parallel(&slsDetector::getNumberofUDPInterfacesFromShm, {}).squash() == 2) {
if (Parallel(&slsDetector::getNumberofUDPInterfacesFromShm, {}).squash() ==
2) {
numSocketsPerDetector = 2;
}
numSockets *= numSocketsPerDetector;
@ -464,7 +386,8 @@ int multiSlsDetector::createReceivingDataSockets(const bool destroy) {
try {
zmqSocket.push_back(sls::make_unique<ZmqSocket>(
detectors[iSocket / numSocketsPerDetector]
->getClientStreamingIP().str()
->getClientStreamingIP()
.str()
.c_str(),
portnum));
FILE_LOG(logINFO) << "Zmq Client[" << iSocket << "] at "
@ -482,7 +405,7 @@ int multiSlsDetector::createReceivingDataSockets(const bool destroy) {
return OK;
}
void multiSlsDetector::readFrameFromReceiver() {
void DetectorImpl::readFrameFromReceiver() {
int nX = 0;
int nY = 0;
@ -491,7 +414,9 @@ void multiSlsDetector::readFrameFromReceiver() {
bool gappixelsenable = false;
bool quadEnable = false;
bool eiger = false;
bool numInterfaces = Parallel(&slsDetector::getNumberofUDPInterfacesFromShm, {}).squash(); // cannot pick up from zmq
bool numInterfaces =
Parallel(&slsDetector::getNumberofUDPInterfacesFromShm, {})
.squash(); // cannot pick up from zmq
bool runningList[zmqSocket.size()], connectList[zmqSocket.size()];
int numRunning = 0;
@ -518,7 +443,7 @@ void multiSlsDetector::readFrameFromReceiver() {
uint32_t size = 0, nPixelsX = 0, nPixelsY = 0, dynamicRange = 0;
float bytesPerPixel = 0;
// header info every header
std::string currentFileName = "";
std::string currentFileName;
uint64_t currentAcquisitionIndex = -1, currentFrameIndex = -1,
currentFileIndex = -1;
uint32_t currentSubFrameIndex = -1, coordX = -1, coordY = -1,
@ -651,19 +576,19 @@ void multiSlsDetector::readFrameFromReceiver() {
if (eiger && (flippedDataX != 0U)) {
for (uint32_t i = 0; i < nPixelsY; ++i) {
memcpy(((char *)multiframe) +
memcpy((multiframe) +
((yoffset + (nPixelsY - 1 - i)) *
rowoffset) +
xoffset,
(char *)image + (i * singledetrowoffset),
image + (i * singledetrowoffset),
singledetrowoffset);
}
} else {
for (uint32_t i = 0; i < nPixelsY; ++i) {
std::cout << i << " " << std::endl;
memcpy(((char *)multiframe) +
((yoffset + i) * rowoffset) + xoffset,
(char *)image + (i * singledetrowoffset),
memcpy((multiframe) + ((yoffset + i) * rowoffset) +
xoffset,
image + (i * singledetrowoffset),
singledetrowoffset);
}
}
@ -695,21 +620,22 @@ void multiSlsDetector::readFrameFromReceiver() {
<< "\n\t nDetPixelsX: " << nDetPixelsX
<< "\n\t nDetPixelsY: " << nDetPixelsY
<< "\n\t databytes: " << n;
thisData = new detectorData(
getCurrentProgress(), currentFileName.c_str(), nDetPixelsX,
nDetPixelsY, multigappixels, n, dynamicRange,
currentFileIndex);
thisData =
new detectorData(getCurrentProgress(), currentFileName,
nDetPixelsX, nDetPixelsY, multigappixels,
n, dynamicRange, currentFileIndex);
}
// normal pixels
else {
thisData = new detectorData(
getCurrentProgress(), currentFileName.c_str(), nDetPixelsX,
nDetPixelsY, multiframe, multisize, dynamicRange,
currentFileIndex);
thisData =
new detectorData(getCurrentProgress(), currentFileName,
nDetPixelsX, nDetPixelsY, multiframe,
multisize, dynamicRange, currentFileIndex);
}
dataReady(thisData, currentFrameIndex,
((dynamicRange == 32 && eiger) ? currentSubFrameIndex : -1),
pCallbackArg);
dataReady(
thisData, currentFrameIndex,
((dynamicRange == 32 && eiger) ? currentSubFrameIndex : -1),
pCallbackArg);
delete thisData;
}
@ -750,8 +676,8 @@ void multiSlsDetector::readFrameFromReceiver() {
delete[] multigappixels;
}
int multiSlsDetector::processImageWithGapPixels(char *image, char *&gpImage,
bool quadEnable) {
int DetectorImpl::processImageWithGapPixels(char *image, char *&gpImage,
bool quadEnable) {
// eiger 4 bit mode
int nxb =
multi_shm()->numberOfDetector.x * (512 + 3); //(divided by 2 already)
@ -885,7 +811,7 @@ int multiSlsDetector::processImageWithGapPixels(char *image, char *&gpImage,
return gapdatabytes;
}
bool multiSlsDetector::enableDataStreamingToClient(int enable) {
bool DetectorImpl::enableDataStreamingToClient(int enable) {
if (enable >= 0) {
// destroy data threads
if (enable == 0) {
@ -900,8 +826,7 @@ bool multiSlsDetector::enableDataStreamingToClient(int enable) {
return client_downstream;
}
void multiSlsDetector::savePattern(const std::string &fname) {
void DetectorImpl::savePattern(const std::string &fname) {
// std::ofstream outfile;
// outfile.open(fname.c_str(), std::ios_base::out);
// if (!outfile.is_open()) {
@ -919,7 +844,7 @@ void multiSlsDetector::savePattern(const std::string &fname) {
// }
// // rest of pattern file
// const std::vector<std::string> commands{
// "patioctrl",
// "patioctrl",
// "patclkctrl",
// "patlimits",
// "patloop0",
@ -941,43 +866,36 @@ void multiSlsDetector::savePattern(const std::string &fname) {
// multiSlsDetectorClient(cmd, GET_ACTION, this, outfile);
}
void multiSlsDetector::registerAcquisitionFinishedCallback(
void (*func)(double, int, void *), void *pArg) {
void DetectorImpl::registerAcquisitionFinishedCallback(void (*func)(double, int,
void *),
void *pArg) {
acquisition_finished = func;
acqFinished_p = pArg;
}
void multiSlsDetector::registerDataCallback(
void (*userCallback)(detectorData *, uint64_t, uint32_t, void *),
void *pArg) {
void DetectorImpl::registerDataCallback(void (*userCallback)(detectorData *,
uint64_t, uint32_t,
void *),
void *pArg) {
dataReady = userCallback;
pCallbackArg = pArg;
if (Parallel(&slsDetector::getUseReceiverFlag, {}).squash(false)) {
if (dataReady == nullptr) {
enableDataStreamingToClient(0);
Parallel(&slsDetector::enableDataStreamingFromReceiver, {}, 0);
} else {
enableDataStreamingToClient(1);
Parallel(&slsDetector::enableDataStreamingFromReceiver, {}, 1);
}
}
enableDataStreamingToClient(dataReady == nullptr ? 0 : 1);
}
double multiSlsDetector::setTotalProgress() {
double DetectorImpl::setTotalProgress() {
int64_t nf = Parallel(&slsDetector::getNumberOfFramesFromShm, {})
.tsquash("Inconsistent number of frames");
.tsquash("Inconsistent number of frames");
int64_t nc = Parallel(&slsDetector::getNumberOfTriggersFromShm, {})
.tsquash("Inconsistent number of triggers");
.tsquash("Inconsistent number of triggers");
if (nf == 0 || nc == 0) {
throw RuntimeError("Number of frames or triggers is 0");
}
int ns = 1;
if (multi_shm()->multiDetectorType == JUNGFRAU) {
ns = Parallel(&slsDetector::getNumberOfAdditionalStorageCellsFromShm, {})
.tsquash("Inconsistent number of additional storage cells");
ns =
Parallel(&slsDetector::getNumberOfAdditionalStorageCellsFromShm, {})
.tsquash("Inconsistent number of additional storage cells");
++ns;
}
@ -987,30 +905,28 @@ double multiSlsDetector::setTotalProgress() {
return totalProgress;
}
double multiSlsDetector::getCurrentProgress() {
double DetectorImpl::getCurrentProgress() {
std::lock_guard<std::mutex> lock(mp);
return 100. * progressIndex / totalProgress;
}
void multiSlsDetector::incrementProgress() {
void DetectorImpl::incrementProgress() {
std::lock_guard<std::mutex> lock(mp);
progressIndex += 1;
std::cout << std::fixed << std::setprecision(2) << std::setw(6)
<< 100. * progressIndex / totalProgress
<< " \%";
<< 100. * progressIndex / totalProgress << " \%";
std::cout << '\r' << std::flush;
}
void multiSlsDetector::setCurrentProgress(int64_t i) {
void DetectorImpl::setCurrentProgress(int64_t i) {
std::lock_guard<std::mutex> lock(mp);
progressIndex = (double)i;
std::cout << std::fixed << std::setprecision(2) << std::setw(6)
<< 100. * progressIndex / totalProgress
<< " \%";
<< 100. * progressIndex / totalProgress << " \%";
std::cout << '\r' << std::flush;
}
int multiSlsDetector::acquire() {
int DetectorImpl::acquire() {
// ensure acquire isnt started multiple times by same client
if (!isAcquireReady()) {
return FAIL;
@ -1020,21 +936,23 @@ int multiSlsDetector::acquire() {
struct timespec begin, end;
clock_gettime(CLOCK_REALTIME, &begin);
// in the real time acquisition loop, processing thread will wait for a post
// each time
// in the real time acquisition loop, processing thread will wait for a
// post each time
sem_init(&sem_newRTAcquisition, 1, 0);
// in the real time acquistion loop, main thread will wait for processing
// thread to be done each time (which in turn waits for receiver/ext
// process)
// in the real time acquistion loop, main thread will wait for
// processing thread to be done each time (which in turn waits for
// receiver/ext process)
sem_init(&sem_endRTAcquisition, 1, 0);
bool receiver = Parallel(&slsDetector::getUseReceiverFlag, {}).squash(false);
bool receiver =
Parallel(&slsDetector::getUseReceiverFlag, {}).squash(false);
progressIndex = 0;
setJoinThreadFlag(false);
// verify receiver is idle
if (receiver) {
if (Parallel(&slsDetector::getReceiverStatus, {}).squash(ERROR) != IDLE) {
if (Parallel(&slsDetector::getReceiverStatus, {}).squash(ERROR) !=
IDLE) {
Parallel(&slsDetector::stopReceiver, {});
}
}
@ -1083,8 +1001,7 @@ int multiSlsDetector::acquire() {
auto t = Parallel(&slsDetector::getRunStatus, {});
if (t.equal())
status = t.front();
acquisition_finished(getCurrentProgress(), status,
acqFinished_p);
acquisition_finished(getCurrentProgress(), status, acqFinished_p);
}
sem_destroy(&sem_newRTAcquisition);
@ -1103,12 +1020,12 @@ int multiSlsDetector::acquire() {
return OK;
}
void multiSlsDetector::startProcessingThread() {
void DetectorImpl::startProcessingThread() {
setTotalProgress();
dataProcessingThread = std::thread(&multiSlsDetector::processData, this);
dataProcessingThread = std::thread(&DetectorImpl::processData, this);
}
void multiSlsDetector::processData() {
void DetectorImpl::processData() {
if (Parallel(&slsDetector::getUseReceiverFlag, {}).squash(false)) {
if (dataReady != nullptr) {
readFrameFromReceiver();
@ -1126,7 +1043,8 @@ void multiSlsDetector::processData() {
}
}
// get progress
caught = Parallel(&slsDetector::getFramesCaughtByReceiver, {0}).squash();
caught = Parallel(&slsDetector::getFramesCaughtByReceiver, {0})
.squash();
// updating progress
if (caught != -1) {
@ -1143,17 +1061,17 @@ void multiSlsDetector::processData() {
}
}
bool multiSlsDetector::getJoinThreadFlag() const {
bool DetectorImpl::getJoinThreadFlag() const {
std::lock_guard<std::mutex> lock(mp);
return jointhread;
}
void multiSlsDetector::setJoinThreadFlag(bool value) {
void DetectorImpl::setJoinThreadFlag(bool value) {
std::lock_guard<std::mutex> lock(mp);
jointhread = value;
}
int multiSlsDetector::kbhit() {
int DetectorImpl::kbhit() {
struct timeval tv;
fd_set fds;
tv.tv_sec = 0;
@ -1164,11 +1082,33 @@ int multiSlsDetector::kbhit() {
return FD_ISSET(STDIN_FILENO, &fds);
}
std::vector<char> multiSlsDetector::readPofFile(const std::string &fname) {
std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
// validate type of file
bool isPof = false;
switch (multi_shm()->multiDetectorType) {
case JUNGFRAU:
case CHIPTESTBOARD:
if (fname.find(".pof") == std::string::npos) {
throw RuntimeError("Programming file must be a pof file.");
}
isPof = true;
break;
case MYTHEN3:
case GOTTHARD2:
if (fname.find(".rbf") == std::string::npos) {
throw RuntimeError("Programming file must be an rbf file.");
}
break;
default:
throw RuntimeError("Not implemented for this detector");
}
FILE_LOG(logINFO)
<< "Updating Firmware. This can take awhile. Please be patient...";
FILE_LOG(logDEBUG1) << "Programming FPGA with file name:" << fname;
size_t filesize = 0;
// check if it exists
struct stat st;
if (stat(fname.c_str(), &st) != 0) {
throw RuntimeError("Program FPGA: Programming file does not exist");
@ -1196,32 +1136,43 @@ std::vector<char> multiSlsDetector::readPofFile(const std::string &fname) {
// convert src to dst rawbin
FILE_LOG(logDEBUG1) << "Converting " << fname << " to " << destfname;
{
int filepos, x, y, i;
// Remove header (0...11C)
for (filepos = 0; filepos < 0x11C; ++filepos) {
fgetc(src);
}
// Write 0x80 times 0xFF (0...7F)
{
char c = 0xFF;
for (filepos = 0; filepos < 0x80; ++filepos) {
write(dst, &c, 1);
constexpr int pofNumHeaderBytes = 0x11C;
constexpr int pofFooterOfst = 0x1000000;
int dstFilePos = 0;
if (isPof) {
// Read header and discard
for (int i = 0; i < pofNumHeaderBytes; ++i) {
fgetc(src);
}
// Write 0xFF to destination 0x80 times (padding)
constexpr int pofNumPadding{0x80};
constexpr uint8_t c{0xFF};
while (dstFilePos < pofNumPadding) {
write(dst, &c, sizeof(c));
++dstFilePos;
}
}
// Swap bits and write to file
for (filepos = 0x80; filepos < 0x1000000; ++filepos) {
x = fgetc(src);
if (x < 0) {
// Swap bits from source and write to dest
while (!feof(src)) {
// pof: exit early to discard footer
if (isPof && dstFilePos >= pofFooterOfst) {
break;
}
y = 0;
for (i = 0; i < 8; ++i) {
y = y |
(((x & (1 << i)) >> i) << (7 - i)); // This swaps the bits
// read source
int s = fgetc(src);
if (s < 0) {
break;
}
write(dst, &y, 1);
// swap bits
int d = 0;
for (int i = 0; i < 8; ++i) {
d = d | (((s & (1 << i)) >> i) << (7 - i));
}
write(dst, &d, 1);
++dstFilePos;
}
if (filepos < 0x1000000) {
// validate pof: read less than footer offset
if (isPof && dstFilePos < pofFooterOfst) {
throw RuntimeError(
"Could not convert programming file. EOF before end of flash");
}

View File

@ -17,9 +17,8 @@ class detectorData;
#include <vector>
#define MULTI_SHMAPIVERSION 0x190809
#define MULTI_SHMVERSION 0x190819
#define MULTI_SHMVERSION 0x200131
#define SHORT_STRING_LENGTH 50
#define DATE_LENGTH 30
#include <future>
#include <numeric>
@ -64,9 +63,12 @@ struct sharedMultiSlsDetector {
/** data streaming (up stream) enable in receiver */
bool receiver_upstream;
/** initial checks */
bool initialChecks;
};
class multiSlsDetector : public virtual slsDetectorDefs {
class DetectorImpl : public virtual slsDetectorDefs {
public:
/**
* Constructor
@ -75,13 +77,13 @@ class multiSlsDetector : public virtual slsDetectorDefs {
* one
* @param update true to update last user pid, date etc
*/
explicit multiSlsDetector(int multi_id = 0, bool verify = true,
explicit DetectorImpl(int multi_id = 0, bool verify = true,
bool update = true);
/**
* Destructor
*/
virtual ~multiSlsDetector();
virtual ~DetectorImpl();
template <class CT> struct NonDeduced { using type = CT; };
template <typename RT, typename... CT>
@ -190,44 +192,6 @@ class multiSlsDetector : public virtual slsDetectorDefs {
}
}
/**
* Loop through the detectors serially and return the result as a vector
*/
template <typename RT, typename... CT>
std::vector<RT> serialCall(RT (slsDetector::*somefunc)(CT...),
typename NonDeduced<CT>::type... Args);
/**
* Loop through the detectors serially and return the result as a vector
* Const qualified version
*/
template <typename RT, typename... CT>
std::vector<RT> serialCall(RT (slsDetector::*somefunc)(CT...) const,
typename NonDeduced<CT>::type... Args) const;
/**
* Loop through the detectors in parallel and return the result as a vector
*/
template <typename RT, typename... CT>
std::vector<RT> parallelCall(RT (slsDetector::*somefunc)(CT...),
typename NonDeduced<CT>::type... Args);
/**
* Loop through the detectors in parallel and return the result as a vector
* Const qualified version
*/
template <typename RT, typename... CT>
std::vector<RT> parallelCall(RT (slsDetector::*somefunc)(CT...) const,
typename NonDeduced<CT>::type... Args) const;
template <typename... CT>
void parallelCall(void (slsDetector::*somefunc)(CT...),
typename NonDeduced<CT>::type... Args);
template <typename... CT>
void parallelCall(void (slsDetector::*somefunc)(CT...) const,
typename NonDeduced<CT>::type... Args) const;
/** set acquiring flag in shared memory */
void setAcquiringFlag(bool flag);
@ -248,6 +212,12 @@ class multiSlsDetector : public virtual slsDetectorDefs {
/** Get user details of shared memory */
std::string getUserDetails();
bool getInitialChecks() const;
/** initial compaibility and other server start up checks
* default enabled */
void setInitialChecks(const bool value);
/**
* Connect to Virtual Detector Servers at local host
* @param ndet number of detectors
@ -323,11 +293,13 @@ class multiSlsDetector : public virtual slsDetectorDefs {
/**
* Convert raw file
* @param fname name of pof file
* @param fpgasrc pointer in memory to read pof to
* [Jungfrau][Ctb] from pof file
* [Mythen3][Gotthard2] from rbf file
* @param fname name of pof/rbf file
* @param fpgasrc pointer in memory to read programming file to
* @returns file size
*/
std::vector<char> readPofFile(const std::string &fname);
std::vector<char> readProgrammingFile(const std::string &fname);
private:
/**

View File

@ -279,13 +279,21 @@ void slsDetector::freeSharedMemory() {
}
}
void slsDetector::setHostname(const std::string &hostname) {
void slsDetector::setHostname(const std::string &hostname, const bool initialChecks) {
sls::strcpy_safe(shm()->hostname, hostname.c_str());
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.close();
FILE_LOG(logINFO) << "Checking Detector Version Compatibility";
checkDetectorVersionCompatibility();
if (!initialChecks) {
try {
checkDetectorVersionCompatibility();
} catch (const DetectorError& e) {
FILE_LOG(logWARNING) << "Bypassing Initial Checks at your own risk!";
}
} else {
checkDetectorVersionCompatibility();
}
FILE_LOG(logINFO) << "Detector connecting - updating!";
updateCachedDetectorVariables();
@ -1156,7 +1164,7 @@ void slsDetector::stopAcquisition() {
void slsDetector::sendSoftwareTrigger() {
FILE_LOG(logDEBUG1) << "Sending software trigger";
sendToDetector(F_SOFTWARE_TRIGGER);
sendToDetectorStop(F_SOFTWARE_TRIGGER);
FILE_LOG(logDEBUG1) << "Sending software trigger successful";
}
@ -1518,8 +1526,8 @@ int slsDetector::setDynamicRange(int n) {
// update speed for usability
if (dr == 32) {
FILE_LOG(logINFO) << "Setting Clock to Quarter Speed to cope with Dynamic Range of 32"; setClockDivider(RUN_CLOCK, 2);
} else if (dr == 16) {
FILE_LOG(logINFO) << "Setting Clock to Half Speed to cope with Dynamic Range of 16"; setClockDivider(RUN_CLOCK, 1);
} else {
FILE_LOG(logINFO) << "Setting Clock to Full Speed to cope with Dynamic Range of " << dr; setClockDivider(RUN_CLOCK, 0);
}
}
@ -2888,23 +2896,28 @@ int slsDetector::setStoragecellStart(int pos) {
}
void slsDetector::programFPGA(std::vector<char> buffer) {
// validate type
switch (shm()->myDetectorType) {
case JUNGFRAU:
case CHIPTESTBOARD:
case MOENCH:
programFPGAviaBlackfin(buffer);
break;
case MYTHEN3:
case GOTTHARD2:
programFPGAviaNios(buffer);
break;
default:
throw RuntimeError("Program FPGA is not implemented for this detector");
}
}
size_t filesize = buffer.size();
void slsDetector::programFPGAviaBlackfin(std::vector<char> buffer) {
uint64_t filesize = buffer.size();
// send program from memory to detector
int fnum = F_PROGRAM_FPGA;
int ret = FAIL;
char mess[MAX_STR_LENGTH] = {0};
FILE_LOG(logINFO) << "Sending programming binary to detector " << detId
FILE_LOG(logINFO) << "Sending programming binary (from pof) to detector " << detId
<< " (" << shm()->hostname << ")";
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
@ -2921,35 +2934,34 @@ void slsDetector::programFPGA(std::vector<char> buffer) {
}
// erasing flash
if (ret != FAIL) {
FILE_LOG(logINFO) << "Erasing Flash for detector " << detId << " ("
<< shm()->hostname << ")";
printf("%d%%\r", 0);
std::cout << std::flush;
// erasing takes 65 seconds, printing here (otherwise need threads
// in server-unnecessary)
const int ERASE_TIME = 65;
int count = ERASE_TIME + 1;
while (count > 0) {
usleep(1 * 1000 * 1000);
--count;
printf("%d%%\r",
static_cast<int>(
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) *
100));
std::cout << std::flush;
}
printf("\n");
FILE_LOG(logINFO) << "Writing to Flash to detector " << detId << " ("
<< shm()->hostname << ")";
printf("%d%%\r", 0);
FILE_LOG(logINFO) << "Erasing Flash for detector " << detId << " ("
<< shm()->hostname << ")";
printf("%d%%\r", 0);
std::cout << std::flush;
// erasing takes 65 seconds, printing here (otherwise need threads
// in server-unnecessary)
const int ERASE_TIME = 65;
int count = ERASE_TIME + 1;
while (count > 0) {
usleep(1 * 1000 * 1000);
--count;
printf("%d%%\r",
static_cast<int>(
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) *
100));
std::cout << std::flush;
}
printf("\n");
FILE_LOG(logINFO) << "Writing to Flash to detector " << detId << " ("
<< shm()->hostname << ")";
printf("%d%%\r", 0);
std::cout << std::flush;
// sending program in parts of 2mb each
size_t unitprogramsize = 0;
// sending program in parts of 2mb each
uint64_t unitprogramsize = 0;
int currentPointer = 0;
size_t totalsize = filesize;
uint64_t totalsize = filesize;
while (filesize > 0) {
unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb
if (unitprogramsize > filesize) { // less than 2mb
@ -2967,19 +2979,53 @@ void slsDetector::programFPGA(std::vector<char> buffer) {
os << "Detector " << detId << " (" << shm()->hostname << ")"
<< " returned error: " << mess;
throw RuntimeError(os.str());
} else {
filesize -= unitprogramsize;
currentPointer += unitprogramsize;
// print progress
printf("%d%%\r",
static_cast<int>(
(static_cast<double>(totalsize - filesize) / totalsize) *
100));
std::cout << std::flush;
}
filesize -= unitprogramsize;
currentPointer += unitprogramsize;
// print progress
printf("%d%%\r",
static_cast<int>(
(static_cast<double>(totalsize - filesize) / totalsize) *
100));
std::cout << std::flush;
}
printf("\n");
FILE_LOG(logINFO) << "FPGA programmed successfully";
rebootController();
}
void slsDetector::programFPGAviaNios(std::vector<char> buffer) {
uint64_t filesize = buffer.size();
int fnum = F_PROGRAM_FPGA;
int ret = FAIL;
char mess[MAX_STR_LENGTH] = {0};
FILE_LOG(logINFO) << "Sending programming binary (from rbf) to detector " << detId
<< " (" << shm()->hostname << ")";
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(&fnum, sizeof(fnum));
// filesize
client.Send(&filesize, sizeof(filesize));
client.Receive(&ret, sizeof(ret));
if (ret == FAIL) {
client.Receive(mess, sizeof(mess));
std::ostringstream os;
os << "Detector " << detId << " (" << shm()->hostname << ")"
<< " returned error: " << mess;
throw RuntimeError(os.str());
}
// program
client.Send(&buffer[0], filesize);
client.Receive(&ret, sizeof(ret));
if (ret == FAIL) {
client.Receive(mess, sizeof(mess));
std::ostringstream os;
os << "Detector " << detId << " (" << shm()->hostname << ")"
<< " returned error: " << mess;
throw RuntimeError(os.str());
}
FILE_LOG(logINFO) << "FPGA programmed successfully";
rebootController();
}
@ -2999,15 +3045,9 @@ void slsDetector::copyDetectorServer(const std::string &fname,
}
void slsDetector::rebootController() {
if (shm()->myDetectorType == EIGER) {
throw RuntimeError(
"Reboot controller not implemented for this detector");
}
int fnum = F_REBOOT_CONTROLLER;
FILE_LOG(logINFO) << "Sending reboot controller to detector " << detId
<< " (" << shm()->hostname << ")";
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(&fnum, sizeof(fnum));
FILE_LOG(logDEBUG1) << "Rebooting Controller";
sendToDetector(F_REBOOT_CONTROLLER, nullptr, nullptr);
FILE_LOG(logINFO) << "Controller rebooted successfully!";
}
int slsDetector::powerChip(int ival) {

View File

@ -252,8 +252,11 @@ class slsDetector : public virtual slsDetectorDefs {
/**
* Sets the hostname, if online flag is set connects to update the detector
* @param name hostname
* @param initialChecks enable or disable initial compatibility checks
* and other server start up checks. Enabled by default. Disable only
* for advanced users!
*/
void setHostname(const std::string &hostname);
void setHostname(const std::string &hostname, const bool initialChecks);
/**
* Gets the hostname of detector
@ -1382,11 +1385,17 @@ class slsDetector : public virtual slsDetectorDefs {
int setStoragecellStart(int pos = -1);
/**
* Programs FPGA with pof file (Jungfrau, CTB, Moench)
* [Jungfau][Ctb] Programs FPGA with raw file from pof file
* [Mythen3][Gotthard2] Programs FPGA with raw file from rbf file
* @param buffer programming file in memory
*/
void programFPGA(std::vector<char> buffer);
/** [Jungfau][Ctb] */
void programFPGAviaBlackfin(std::vector<char> buffer);
/** [Mythen3][Gotthard2] */
void programFPGAviaNios(std::vector<char> buffer);
/**
* Resets FPGA (Jungfrau)
*/
@ -1401,6 +1410,7 @@ class slsDetector : public virtual slsDetectorDefs {
const std::string &hostname);
/**
* [Jungfrau][Ctb][Gotthard][Mythen3][Gotthard2]
* Reboot detector controller (blackfin/ powerpc)
*/
void rebootController();