mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-17 23:37:14 +02:00
merging problem
This commit is contained in:
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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.");
|
||||
|
@ -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 {
|
||||
|
@ -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");
|
||||
}
|
@ -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:
|
||||
/**
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
Reference in New Issue
Block a user