merge fix

This commit is contained in:
2021-09-28 16:09:51 +02:00
76 changed files with 2791 additions and 1041 deletions

View File

@ -19,7 +19,7 @@ class IpAddr;
// Free function to avoid dependence on class
// and avoid the option to free another objects
// shm by mistake
void freeSharedMemory(int multiId, int detPos = -1);
void freeSharedMemory(int detectorIndex, int moduleIndex = -1);
/**
* \class Detector
@ -671,8 +671,7 @@ class Detector {
/** [Jungfrau][Eiger] */
Result<int> getNumberofUDPDestinations(Positions pos = {}) const;
/**[Jungfrau][Eiger] Options 1-32 */
void setNumberofUDPDestinations(const int value, Positions pos = {});
void clearUDPDestinations(Positions pos = {});
/** [Jungfrau] */
Result<int> getFirstUDPDestination(Positions pos = {}) const;

View File

@ -67,7 +67,7 @@ int main(int argc, char *argv[]) {
sls::Detector det(parser.multi_id());
sls::CmdProxy proxy(&det);
proxy.Call(parser.command(), parser.arguments(), parser.detector_id(),
action);
action, std::cout, parser.receiver_id());
} catch (const sls::RuntimeError &e) {
exit(EXIT_FAILURE);
}

View File

@ -29,10 +29,11 @@ std::ostream &operator<<(std::ostream &os,
void CmdProxy::Call(const std::string &command,
const std::vector<std::string> &arguments, int detector_id,
int action, std::ostream &os) {
int action, std::ostream &os, int receiver_id) {
cmd = command;
args = arguments;
det_id = detector_id;
rx_id = receiver_id;
std::string temp;
while (temp != cmd) {
@ -1381,16 +1382,13 @@ IpAddr CmdProxy::getIpFromAuto() {
UdpDestination CmdProxy::getUdpEntry() {
UdpDestination udpDestination{};
bool hasEntry = false;
udpDestination.entry = rx_id;
for (auto it : args) {
size_t pos = it.find('=');
std::string key = it.substr(0, pos);
std::string value = it.substr(pos + 1);
if (key == "entry") {
udpDestination.entry = StringTo<int>(value);
hasEntry = true;
} else if (key == "ip") {
if (key == "ip") {
if (value == "auto") {
auto val = getIpFromAuto();
LOG(logINFO) << "Setting udp_dstip of detector " << det_id
@ -1418,9 +1416,6 @@ UdpDestination CmdProxy::getUdpEntry() {
udpDestination.port2 = StringTo<uint32_t>(value);
}
}
if (!hasEntry) {
throw sls::RuntimeError("Found no entry argument.");
}
return udpDestination;
}
@ -1437,16 +1432,29 @@ std::string CmdProxy::UDPDestinationList(int action) {
"set to ip of rx_hostname."
<< '\n';
} else if (action == defs::GET_ACTION) {
if (args.size() != 1) {
WrongNumberOfParameters(1);
if (!args.empty()) {
WrongNumberOfParameters(0);
}
auto t = det->getDestinationUDPList(StringTo<int>(args[0]),
std::vector<int>{det_id});
if (det_id == -1) {
throw sls::RuntimeError("udp_dstlist must be at module level.");
}
if (rx_id < 0 || rx_id >= MAX_UDP_DESTINATION) {
throw sls::RuntimeError(
"Invalid receiver index to get round robin entry.");
}
auto t = det->getDestinationUDPList(rx_id, std::vector<int>{det_id});
os << OutString(t) << '\n';
} else if (action == defs::PUT_ACTION) {
if (args.empty()) {
WrongNumberOfParameters(1);
}
if (det_id == -1) {
throw sls::RuntimeError("udp_dstlist must be at module level.");
}
if (rx_id < 0 || rx_id >= MAX_UDP_DESTINATION) {
throw sls::RuntimeError(
"Invalid receiver index to set round robin entry.");
}
auto t = getUdpEntry();
det->setDestinationUDPList(t, det_id);
os << ToString(args) << std::endl;

View File

@ -529,7 +529,8 @@ class CmdProxy {
void Call(const std::string &command,
const std::vector<std::string> &arguments, int detector_id = -1,
int action = -1, std::ostream &os = std::cout);
int action = -1, std::ostream &os = std::cout,
int receiver_id = -1);
bool ReplaceIfDepreciated(std::string &command);
size_t GetFunctionMapSize() const noexcept { return functions.size(); };
@ -541,6 +542,7 @@ class CmdProxy {
std::string cmd;
std::vector<std::string> args;
int det_id{-1};
int rx_id{-1};
template <typename V> std::string OutStringHex(const V &value) {
if (value.equal())
@ -859,6 +861,7 @@ class CmdProxy {
{"selinterface", &CmdProxy::selinterface},
{"udp_dstlist", &CmdProxy::UDPDestinationList},
{"udp_numdst", &CmdProxy::udp_numdst},
{"udp_cleardst", &CmdProxy::udp_cleardst},
{"udp_firstdst", &CmdProxy::udp_firstdst},
{"udp_srcip", &CmdProxy::udp_srcip},
{"udp_srcip2", &CmdProxy::udp_srcip2},
@ -1535,11 +1538,13 @@ class CmdProxy {
"[0, 1]\n\t[Jungfrau] The udp interface to stream data from detector. "
"Effective only when number of interfaces is 1. Default: 0 (outer)");
INTEGER_COMMAND_VEC_ID(udp_numdst, getNumberofUDPDestinations,
setNumberofUDPDestinations, StringTo<int>,
"[1 - 32]\n\t[Jungfrau][Eiger] One can set upto 32 "
GET_COMMAND(udp_numdst, getNumberofUDPDestinations,
"\n\t[Jungfrau][Eiger] One can enter upto 32 "
"destinations that the detector will stream images "
"out in a round robin fashion. Default: 1");
"out in a round robin fashion. This is get only command. Default: 1");
EXECUTE_SET_COMMAND(udp_cleardst, clearUDPDestinations,
"\n\tClears udp destination details on the detector.");
INTEGER_COMMAND_VEC_ID(
udp_firstdst, getFirstUDPDestination, setFirstUDPDestination,

View File

@ -17,29 +17,29 @@
namespace sls {
void freeSharedMemory(int multiId, int detPos) {
// single
if (detPos >= 0) {
SharedMemory<sharedSlsDetector> temp_shm(multiId, detPos);
if (temp_shm.IsExisting()) {
temp_shm.RemoveSharedMemory();
void freeSharedMemory(int detectorIndex, int moduleIndex) {
// single module
if (moduleIndex >= 0) {
SharedMemory<sharedModule> moduleShm(detectorIndex, moduleIndex);
if (moduleShm.IsExisting()) {
moduleShm.RemoveSharedMemory();
}
return;
}
// multi - get number of detectors from shm
SharedMemory<sharedMultiSlsDetector> multiShm(multiId, -1);
// detector - multi module - get number of detectors from shm
SharedMemory<sharedDetector> detectorShm(detectorIndex, -1);
int numDetectors = 0;
if (multiShm.IsExisting()) {
multiShm.OpenSharedMemory();
numDetectors = multiShm()->numberOfDetectors;
multiShm.RemoveSharedMemory();
if (detectorShm.IsExisting()) {
detectorShm.OpenSharedMemory();
numDetectors = detectorShm()->numberOfModules;
detectorShm.RemoveSharedMemory();
}
for (int i = 0; i < numDetectors; ++i) {
SharedMemory<sharedSlsDetector> shm(multiId, i);
shm.RemoveSharedMemory();
SharedMemory<sharedModule> moduleShm(detectorIndex, i);
moduleShm.RemoveSharedMemory();
}
}
@ -101,7 +101,7 @@ void Detector::setVirtualDetectorServers(int numServers, int startingPort) {
pimpl->setVirtualDetectorServers(numServers, startingPort);
}
int Detector::getShmId() const { return pimpl->getMultiId(); }
int Detector::getShmId() const { return pimpl->getDetectorIndex(); }
std::string Detector::getPackageVersion() const { return GITBRANCH; }
@ -136,7 +136,7 @@ int Detector::size() const { return pimpl->size(); }
bool Detector::empty() const { return pimpl->size() == 0; }
defs::xy Detector::getModuleGeometry() const {
return pimpl->getNumberOfDetectors();
return pimpl->getNumberOfModules();
}
Result<defs::xy> Detector::getModuleSize(Positions pos) const {
@ -256,7 +256,7 @@ void Detector::setSettingsPath(const std::string &value, Positions pos) {
}
void Detector::loadTrimbits(const std::string &fname, Positions pos) {
pimpl->Parallel(&Module::loadSettingsFile, pos, fname);
pimpl->Parallel(&Module::loadTrimbits, pos, fname);
}
Result<int> Detector::getAllTrimbits(Positions pos) const {
@ -921,8 +921,8 @@ Result<int> Detector::getNumberofUDPDestinations(Positions pos) const {
return pimpl->Parallel(&Module::getNumberofUDPDestinations, pos);
}
void Detector::setNumberofUDPDestinations(const int value, Positions pos) {
pimpl->Parallel(&Module::setNumberofUDPDestinations, pos, value);
void Detector::clearUDPDestinations(Positions pos) {
pimpl->Parallel(&Module::clearUDPDestinations, pos);
}
Result<int> Detector::getFirstUDPDestination(Positions pos) const {

View File

@ -28,14 +28,14 @@
namespace sls {
DetectorImpl::DetectorImpl(int multi_id, bool verify, bool update)
: multiId(multi_id), multi_shm(multi_id, -1) {
setupMultiDetector(verify, update);
DetectorImpl::DetectorImpl(int detector_index, bool verify, bool update)
: detectorIndex(detector_index), shm(detector_index, -1) {
setupDetector(verify, update);
}
DetectorImpl::~DetectorImpl() = default;
void DetectorImpl::setupMultiDetector(bool verify, bool update) {
void DetectorImpl::setupDetector(bool verify, bool update) {
initSharedMemory(verify);
initializeMembers(verify);
if (update) {
@ -43,104 +43,100 @@ void DetectorImpl::setupMultiDetector(bool verify, bool update) {
}
}
void DetectorImpl::setAcquiringFlag(bool flag) {
multi_shm()->acquiringFlag = flag;
}
void DetectorImpl::setAcquiringFlag(bool flag) { shm()->acquiringFlag = flag; }
int DetectorImpl::getMultiId() const { return multiId; }
int DetectorImpl::getDetectorIndex() const { return detectorIndex; }
void DetectorImpl::freeSharedMemory(int multiId, int detPos) {
void DetectorImpl::freeSharedMemory(int detectorIndex, int detPos) {
// single
if (detPos >= 0) {
SharedMemory<sharedSlsDetector> temp_shm(multiId, detPos);
if (temp_shm.IsExisting()) {
temp_shm.RemoveSharedMemory();
SharedMemory<sharedModule> moduleShm(detectorIndex, detPos);
if (moduleShm.IsExisting()) {
moduleShm.RemoveSharedMemory();
}
return;
}
// multi - get number of detectors from shm
SharedMemory<sharedMultiSlsDetector> multiShm(multiId, -1);
int numDetectors = 0;
// multi - get number of modules from shm
SharedMemory<sharedDetector> detectorShm(detectorIndex, -1);
int numModules = 0;
if (multiShm.IsExisting()) {
multiShm.OpenSharedMemory();
numDetectors = multiShm()->numberOfDetectors;
multiShm.RemoveSharedMemory();
if (detectorShm.IsExisting()) {
detectorShm.OpenSharedMemory();
numModules = detectorShm()->numberOfModules;
detectorShm.RemoveSharedMemory();
}
for (int i = 0; i < numDetectors; ++i) {
SharedMemory<sharedSlsDetector> shm(multiId, i);
shm.RemoveSharedMemory();
for (int i = 0; i < numModules; ++i) {
SharedMemory<sharedModule> moduleShm(detectorIndex, i);
moduleShm.RemoveSharedMemory();
}
}
void DetectorImpl::freeSharedMemory() {
zmqSocket.clear();
for (auto &d : detectors) {
d->freeSharedMemory();
for (auto &module : modules) {
module->freeSharedMemory();
}
detectors.clear();
modules.clear();
// clear multi detector shm
multi_shm.RemoveSharedMemory();
// clear detector shm
shm.RemoveSharedMemory();
client_downstream = false;
}
std::string DetectorImpl::getUserDetails() {
if (detectors.empty()) {
if (modules.empty()) {
return std::string("none");
}
std::ostringstream sstream;
sstream << "\nHostname: ";
for (auto &d : detectors) {
sstream << (d->isFixedPatternSharedMemoryCompatible() ? d->getHostname()
: "Unknown")
for (auto &module : modules) {
sstream << (module->isFixedPatternSharedMemoryCompatible()
? module->getHostname()
: "Unknown")
<< "+";
}
sstream << "\nType: ";
// get type from multi shm
if (multi_shm()->shmversion >= MULTI_SHMAPIVERSION) {
sstream << ToString(multi_shm()->multiDetectorType);
// get type from detector version shm
if (shm()->shmversion >= DETECTOR_SHMAPIVERSION) {
sstream << ToString(shm()->detType);
}
// get type from slsdet shm
// get type from module shm
else {
for (auto &d : detectors) {
sstream << (d->isFixedPatternSharedMemoryCompatible()
? ToString(d->getDetectorType())
for (auto &module : modules) {
sstream << (module->isFixedPatternSharedMemoryCompatible()
? ToString(module->getDetectorType())
: "Unknown")
<< "+";
}
}
sstream << "\nPID: " << multi_shm()->lastPID
<< "\nUser: " << multi_shm()->lastUser
<< "\nDate: " << multi_shm()->lastDate << std::endl;
sstream << "\nPID: " << shm()->lastPID << "\nUser: " << shm()->lastUser
<< "\nDate: " << shm()->lastDate << std::endl;
return sstream.str();
}
bool DetectorImpl::getInitialChecks() const {
return multi_shm()->initialChecks;
}
bool DetectorImpl::getInitialChecks() const { return shm()->initialChecks; }
void DetectorImpl::setInitialChecks(const bool value) {
multi_shm()->initialChecks = value;
shm()->initialChecks = value;
}
void DetectorImpl::initSharedMemory(bool verify) {
if (!multi_shm.IsExisting()) {
multi_shm.CreateSharedMemory();
if (!shm.IsExisting()) {
shm.CreateSharedMemory();
initializeDetectorStructure();
} else {
multi_shm.OpenSharedMemory();
if (verify && multi_shm()->shmversion != MULTI_SHMVERSION) {
LOG(logERROR) << "Multi shared memory (" << multiId
shm.OpenSharedMemory();
if (verify && shm()->shmversion != DETECTOR_SHMVERSION) {
LOG(logERROR) << "Detector shared memory (" << detectorIndex
<< ") version mismatch "
"(expected 0x"
<< std::hex << MULTI_SHMVERSION << " but got 0x"
<< multi_shm()->shmversion << std::dec
<< std::hex << DETECTOR_SHMVERSION << " but got 0x"
<< shm()->shmversion << std::dec
<< ". Clear Shared memory to continue.";
throw SharedMemoryError("Shared memory version mismatch!");
}
@ -148,18 +144,18 @@ void DetectorImpl::initSharedMemory(bool verify) {
}
void DetectorImpl::initializeDetectorStructure() {
multi_shm()->shmversion = MULTI_SHMVERSION;
multi_shm()->numberOfDetectors = 0;
multi_shm()->multiDetectorType = GENERIC;
multi_shm()->numberOfDetector.x = 0;
multi_shm()->numberOfDetector.y = 0;
multi_shm()->numberOfChannels.x = 0;
multi_shm()->numberOfChannels.y = 0;
multi_shm()->acquiringFlag = false;
multi_shm()->initialChecks = true;
multi_shm()->gapPixels = false;
shm()->shmversion = DETECTOR_SHMVERSION;
shm()->numberOfModules = 0;
shm()->detType = GENERIC;
shm()->numberOfModule.x = 0;
shm()->numberOfModule.y = 0;
shm()->numberOfChannels.x = 0;
shm()->numberOfChannels.y = 0;
shm()->acquiringFlag = false;
shm()->initialChecks = true;
shm()->gapPixels = false;
// zmqlib default
multi_shm()->zmqHwm = -1;
shm()->zmqHwm = -1;
}
void DetectorImpl::initializeMembers(bool verify) {
@ -167,38 +163,39 @@ void DetectorImpl::initializeMembers(bool verify) {
zmqSocket.clear();
// get objects from single det shared memory (open)
for (int i = 0; i < multi_shm()->numberOfDetectors; i++) {
for (int i = 0; i < shm()->numberOfModules; i++) {
try {
detectors.push_back(sls::make_unique<Module>(multiId, i, verify));
modules.push_back(
sls::make_unique<Module>(detectorIndex, i, verify));
} catch (...) {
detectors.clear();
modules.clear();
throw;
}
}
}
void DetectorImpl::updateUserdetails() {
multi_shm()->lastPID = getpid();
memset(multi_shm()->lastUser, 0, sizeof(multi_shm()->lastUser));
memset(multi_shm()->lastDate, 0, sizeof(multi_shm()->lastDate));
shm()->lastPID = getpid();
memset(shm()->lastUser, 0, sizeof(shm()->lastUser));
memset(shm()->lastDate, 0, sizeof(shm()->lastDate));
try {
sls::strcpy_safe(multi_shm()->lastUser, exec("whoami").c_str());
sls::strcpy_safe(multi_shm()->lastDate, exec("date").c_str());
sls::strcpy_safe(shm()->lastUser, exec("whoami").c_str());
sls::strcpy_safe(shm()->lastDate, exec("date").c_str());
} catch (...) {
sls::strcpy_safe(multi_shm()->lastUser, "errorreading");
sls::strcpy_safe(multi_shm()->lastDate, "errorreading");
sls::strcpy_safe(shm()->lastUser, "errorreading");
sls::strcpy_safe(shm()->lastDate, "errorreading");
}
}
bool DetectorImpl::isAcquireReady() {
if (multi_shm()->acquiringFlag) {
if (shm()->acquiringFlag) {
LOG(logWARNING)
<< "Acquire has already started. "
"If previous acquisition terminated unexpectedly, "
"reset busy flag to restart.(sls_detector_put clearbusy)";
return false;
}
multi_shm()->acquiringFlag = true;
shm()->acquiringFlag = true;
return true;
}
@ -233,22 +230,22 @@ void DetectorImpl::setVirtualDetectorServers(const int numdet, const int port) {
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) {
LOG(logWARNING) << "There are already detector(s) in shared memory."
if (shm()->numberOfModules != 0) {
LOG(logWARNING) << "There are already module(s) in shared memory."
"Freeing Shared memory now.";
bool initialChecks = multi_shm()->initialChecks;
bool initialChecks = shm()->initialChecks;
freeSharedMemory();
setupMultiDetector();
multi_shm()->initialChecks = initialChecks;
setupDetector();
shm()->initialChecks = initialChecks;
}
for (const auto &hostname : name) {
addSlsDetector(hostname);
addModule(hostname);
}
updateDetectorSize();
}
void DetectorImpl::addSlsDetector(const std::string &hostname) {
LOG(logINFO) << "Adding detector " << hostname;
void DetectorImpl::addModule(const std::string &hostname) {
LOG(logINFO) << "Adding module " << hostname;
int port = DEFAULT_PORTNO;
std::string host = hostname;
@ -259,11 +256,11 @@ void DetectorImpl::addSlsDetector(const std::string &hostname) {
}
if (host != "localhost") {
for (auto &d : detectors) {
if (d->getHostname() == host) {
for (auto &module : modules) {
if (module->getHostname() == host) {
LOG(logWARNING)
<< "Detector " << host
<< "already part of the multiDetector!" << std::endl
<< "Module " << host << "already part of the Detector!"
<< std::endl
<< "Remove it before adding it back in a new position!";
return;
}
@ -272,33 +269,33 @@ void DetectorImpl::addSlsDetector(const std::string &hostname) {
// get type by connecting
detectorType type = Module::getTypeFromDetector(host, port);
auto pos = detectors.size();
detectors.emplace_back(sls::make_unique<Module>(type, multiId, pos, false));
multi_shm()->numberOfDetectors = detectors.size();
detectors[pos]->setControlPort(port);
detectors[pos]->setStopPort(port + 1);
detectors[pos]->setHostname(host, multi_shm()->initialChecks);
// detector type updated by now
multi_shm()->multiDetectorType =
Parallel(&Module::getDetectorType, {})
.tsquash("Inconsistent detector types.");
auto pos = modules.size();
modules.emplace_back(
sls::make_unique<Module>(type, detectorIndex, pos, false));
shm()->numberOfModules = modules.size();
modules[pos]->setControlPort(port);
modules[pos]->setStopPort(port + 1);
modules[pos]->setHostname(host, shm()->initialChecks);
// module type updated by now
shm()->detType = Parallel(&Module::getDetectorType, {})
.tsquash("Inconsistent detector types.");
// for moench and ctb
detectors[pos]->updateNumberOfChannels();
modules[pos]->updateNumberOfChannels();
}
void DetectorImpl::updateDetectorSize() {
LOG(logDEBUG) << "Updating Multi-Detector Size: " << size();
LOG(logDEBUG) << "Updating Detector Size: " << size();
const slsDetectorDefs::xy det_size = detectors[0]->getNumberOfChannels();
const slsDetectorDefs::xy det_size = modules[0]->getNumberOfChannels();
if (det_size.x == 0 || det_size.y == 0) {
throw sls::RuntimeError("Module size for x or y dimensions is 0. Unable to proceed in updating detector size. ");
}
int maxx = multi_shm()->numberOfChannels.x;
int maxy = multi_shm()->numberOfChannels.y;
int maxx = shm()->numberOfChannels.x;
int maxy = shm()->numberOfChannels.y;
int ndetx = 0, ndety = 0;
// 1d, add detectors along x axis
// 1d, add modules along x axis
if (det_size.y == 1) {
if (maxx == 0) {
maxx = det_size.x * size();
@ -309,7 +306,7 @@ void DetectorImpl::updateDetectorSize() {
++ndety;
}
}
// 2d, add detectors along y axis (due to eiger top/bottom)
// 2d, add modules along y axis (due to eiger top/bottom)
else {
if (maxy == 0) {
maxy = det_size.y * size();
@ -321,33 +318,33 @@ void DetectorImpl::updateDetectorSize() {
}
}
multi_shm()->numberOfDetector.x = ndetx;
multi_shm()->numberOfDetector.y = ndety;
multi_shm()->numberOfChannels.x = det_size.x * ndetx;
multi_shm()->numberOfChannels.y = det_size.y * ndety;
shm()->numberOfModule.x = ndetx;
shm()->numberOfModule.y = ndety;
shm()->numberOfChannels.x = det_size.x * ndetx;
shm()->numberOfChannels.y = det_size.y * ndety;
LOG(logDEBUG) << "\n\tNumber of Detectors in X direction:"
<< multi_shm()->numberOfDetector.x
<< "\n\tNumber of Detectors in Y direction:"
<< multi_shm()->numberOfDetector.y
LOG(logDEBUG) << "\n\tNumber of Modules in X direction:"
<< shm()->numberOfModule.x
<< "\n\tNumber of Modules in Y direction:"
<< shm()->numberOfModule.y
<< "\n\tNumber of Channels in X direction:"
<< multi_shm()->numberOfChannels.x
<< shm()->numberOfChannels.x
<< "\n\tNumber of Channels in Y direction:"
<< multi_shm()->numberOfChannels.y;
<< shm()->numberOfChannels.y;
for (auto &d : detectors) {
d->updateNumberOfDetector(multi_shm()->numberOfDetector);
for (auto &module : modules) {
module->updateNumberOfModule(shm()->numberOfModule);
}
}
int DetectorImpl::size() const { return detectors.size(); }
int DetectorImpl::size() const { return modules.size(); }
slsDetectorDefs::xy DetectorImpl::getNumberOfDetectors() const {
return multi_shm()->numberOfDetector;
slsDetectorDefs::xy DetectorImpl::getNumberOfModules() const {
return shm()->numberOfModule;
}
slsDetectorDefs::xy DetectorImpl::getNumberOfChannels() const {
return multi_shm()->numberOfChannels;
return shm()->numberOfChannels;
}
void DetectorImpl::setNumberOfChannels(const slsDetectorDefs::xy c) {
@ -355,33 +352,31 @@ void DetectorImpl::setNumberOfChannels(const slsDetectorDefs::xy c) {
throw RuntimeError(
"Set the number of channels before setting hostname.");
}
multi_shm()->numberOfChannels = c;
shm()->numberOfChannels = c;
}
bool DetectorImpl::getGapPixelsinCallback() const {
return multi_shm()->gapPixels;
}
bool DetectorImpl::getGapPixelsinCallback() const { return shm()->gapPixels; }
void DetectorImpl::setGapPixelsinCallback(const bool enable) {
if (enable) {
switch (multi_shm()->multiDetectorType) {
switch (shm()->detType) {
case JUNGFRAU:
break;
case EIGER:
if (size() && detectors[0]->getQuad()) {
if (size() && modules[0]->getQuad()) {
break;
}
if (multi_shm()->numberOfDetector.y % 2 != 0) {
if (shm()->numberOfModule.y % 2 != 0) {
throw RuntimeError("Gap pixels can only be used "
"for full modules.");
}
break;
default:
throw RuntimeError("Gap Pixels is not implemented for " +
ToString(multi_shm()->multiDetectorType));
ToString(shm()->detType));
}
}
multi_shm()->gapPixels = enable;
shm()->gapPixels = enable;
}
int DetectorImpl::destroyReceivingDataSockets() {
@ -400,33 +395,33 @@ int DetectorImpl::createReceivingDataSockets() {
}
LOG(logINFO) << "Going to create data sockets";
size_t numSockets = detectors.size();
size_t numSocketsPerDetector = 1;
if (multi_shm()->multiDetectorType == EIGER) {
numSocketsPerDetector = 2;
size_t numSockets = modules.size();
size_t numSocketsPerModule = 1;
if (shm()->detType == EIGER) {
numSocketsPerModule = 2;
}
// gotthard2 second interface is only for veto debugging
else if (multi_shm()->multiDetectorType != GOTTHARD2) {
else if (shm()->detType != GOTTHARD2) {
if (Parallel(&Module::getNumberofUDPInterfacesFromShm, {}).squash() ==
2) {
numSocketsPerDetector = 2;
numSocketsPerModule = 2;
}
}
numSockets *= numSocketsPerDetector;
numSockets *= numSocketsPerModule;
for (size_t iSocket = 0; iSocket < numSockets; ++iSocket) {
uint32_t portnum = (detectors[iSocket / numSocketsPerDetector]
->getClientStreamingPort());
portnum += (iSocket % numSocketsPerDetector);
uint32_t portnum =
(modules[iSocket / numSocketsPerModule]->getClientStreamingPort());
portnum += (iSocket % numSocketsPerModule);
try {
zmqSocket.push_back(sls::make_unique<ZmqSocket>(
detectors[iSocket / numSocketsPerDetector]
modules[iSocket / numSocketsPerModule]
->getClientStreamingIP()
.str()
.c_str(),
portnum));
// set high water mark
int hwm = multi_shm()->zmqHwm;
int hwm = shm()->zmqHwm;
if (hwm >= 0) {
zmqSocket[iSocket]->SetReceiveHighWaterMark(hwm);
if (zmqSocket[iSocket]->GetReceiveHighWaterMark() != hwm) {
@ -451,7 +446,7 @@ int DetectorImpl::createReceivingDataSockets() {
void DetectorImpl::readFrameFromReceiver() {
bool gapPixels = multi_shm()->gapPixels;
bool gapPixels = shm()->gapPixels;
LOG(logDEBUG) << "Gap pixels: " << gapPixels;
int nX = 0;
int nY = 0;
@ -461,7 +456,7 @@ void DetectorImpl::readFrameFromReceiver() {
bool eiger = false;
bool numInterfaces = 1;
// gotthard2 second interface is veto debugging
if (multi_shm()->multiDetectorType != GOTTHARD2) {
if (shm()->detType != GOTTHARD2) {
numInterfaces = Parallel(&Module::getNumberofUDPInterfacesFromShm, {})
.squash(); // cannot pick up from zmq
}
@ -540,7 +535,7 @@ void DetectorImpl::readFrameFromReceiver() {
// shape
nPixelsX = zHeader.npixelsx;
nPixelsY = zHeader.npixelsy;
// detector shape
// module shape
nX = zHeader.ndetx;
nY = zHeader.ndety;
nY *= numInterfaces;
@ -603,7 +598,7 @@ void DetectorImpl::readFrameFromReceiver() {
uint32_t yoffset = coordY * nPixelsY;
uint32_t singledetrowoffset = nPixelsX * bytesPerPixel;
uint32_t rowoffset = nX * singledetrowoffset;
if (multi_shm()->multiDetectorType == CHIPTESTBOARD) {
if (shm()->detType == CHIPTESTBOARD) {
singledetrowoffset = size;
}
LOG(logDEBUG1)
@ -765,7 +760,7 @@ int DetectorImpl::InsertGapPixels(char *image, char *&gpImage, bool quadEnable,
// eiger requires inter chip gap pixels are halved
// jungfrau prefers same inter chip gap pixels as the boundary pixels
int divisionValue = 2;
slsDetectorDefs::detectorType detType = multi_shm()->multiDetectorType;
slsDetectorDefs::detectorType detType = shm()->detType;
if (detType == JUNGFRAU) {
divisionValue = 1;
}
@ -1001,7 +996,7 @@ void DetectorImpl::setDataStreamingToClient(bool enable) {
int DetectorImpl::getClientStreamingHwm() const {
// disabled
if (!client_downstream) {
return multi_shm()->zmqHwm;
return shm()->zmqHwm;
}
// enabled
sls::Result<int> result;
@ -1019,7 +1014,7 @@ void DetectorImpl::setClientStreamingHwm(const int limit) {
"Cannot set hwm to less than -1 (-1 is lib default).");
}
// update shm
multi_shm()->zmqHwm = limit;
shm()->zmqHwm = limit;
// streaming enabled
if (client_downstream) {
@ -1028,7 +1023,7 @@ void DetectorImpl::setClientStreamingHwm(const int limit) {
for (auto &it : zmqSocket) {
it->SetReceiveHighWaterMark(limit);
if (it->GetReceiveHighWaterMark() != limit) {
multi_shm()->zmqHwm = -1;
shm()->zmqHwm = -1;
throw sls::ZmqSocketError("Could not set zmq rcv hwm to " +
std::to_string(limit));
}
@ -1096,13 +1091,13 @@ int DetectorImpl::acquire() {
// start and read all
try {
if(detector_type == defs::MYTHEN3 && detectors.size() > 1){
if (detector_type == defs::MYTHEN3 && modules.size() > 1) {
//Multi module mythen
std::vector<int> master;
std::vector<int> slaves;
auto is_master = Parallel(&Module::isMaster, {});
slaves.reserve(detectors.size()-1); //check this one!!
for (size_t i = 0; i<detectors.size(); ++i){
slaves.reserve(modules.size() - 1); // check this one!!
for (size_t i = 0; i < modules.size(); ++i) {
if(is_master[i])
master.push_back(i);
else
@ -1110,11 +1105,11 @@ int DetectorImpl::acquire() {
}
Parallel(&Module::startAcquisition, slaves);
Parallel(&Module::startAndReadAll, master);
}else{
} else {
//Normal acquire
Parallel(&Module::startAndReadAll, {});
}
} catch (...) {
if (receiver)
Parallel(&Module::stopReceiver, {});
@ -1243,7 +1238,7 @@ int DetectorImpl::kbhit() {
std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
// validate type of file
bool isPof = false;
switch (multi_shm()->multiDetectorType) {
switch (shm()->detType) {
case JUNGFRAU:
case CHIPTESTBOARD:
case MOENCH:
@ -1266,7 +1261,6 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
<< "Updating Firmware. This can take awhile. Please be patient...";
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) {
@ -1281,6 +1275,16 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
fname);
}
// get srcSize to print progress
if (fseek(src, 0, SEEK_END) != 0) {
throw RuntimeError("Program FPGA: Seek error in src file");
}
size_t srcSize = ftell(src);
if (srcSize <= 0) {
throw RuntimeError("Program FPGA: Could not get length of source file");
}
rewind(src);
// create temp destination file
char destfname[] = "/tmp/SLS_DET_MCB.XXXXXX";
int dst = mkstemp(destfname); // create temporary file and open it in r/w
@ -1294,6 +1298,7 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
// convert src to dst rawbin
LOG(logDEBUG1) << "Converting " << fname << " to " << destfname;
LOG(logINFO) << "Converting program to rawbin";
{
constexpr int pofNumHeaderBytes = 0x11C;
constexpr int pofFooterOfst = 0x1000000;
@ -1312,7 +1317,15 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
}
}
// Swap bits from source and write to dest
int oldProgress = 0;
while (!feof(src)) {
// print progress
int progress = (int)(((double)(dstFilePos) / srcSize) * 100);
if (oldProgress != progress) {
printf("%d%%\r", progress);
fflush(stdout);
oldProgress = progress;
}
// pof: exit early to discard footer
if (isPof && dstFilePos >= pofFooterOfst) {
break;
@ -1342,9 +1355,10 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
if (close(dst) != 0) {
throw RuntimeError("Program FPGA: Could not close destination file");
}
LOG(logDEBUG1) << "File has been converted to " << destfname;
LOG(logINFOBLUE) << "File has been converted to " << destfname;
// loading dst file to memory
// FILE *fp = fopen("/tmp/SLS_DET_MCB.tzgmUT", "r");
FILE *fp = fopen(destfname, "r");
if (fp == nullptr) {
throw RuntimeError("Program FPGA: Could not open rawbin file");
@ -1352,7 +1366,7 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
if (fseek(fp, 0, SEEK_END) != 0) {
throw RuntimeError("Program FPGA: Seek error in rawbin file");
}
filesize = ftell(fp);
size_t filesize = ftell(fp);
if (filesize <= 0) {
throw RuntimeError("Program FPGA: Could not get length of rawbin file");
}
@ -1367,9 +1381,10 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
throw RuntimeError(
"Program FPGA: Could not close destination file after converting");
}
unlink(destfname); // delete temporary file
//unlink(destfname); // delete temporary file
LOG(logDEBUG1) << "Successfully loaded the rawbin file to program memory";
LOG(logINFO) << "Read file into memory";
LOG(logDEBUG1) << "Read file into memory";
return buffer;
}

View File

@ -15,8 +15,8 @@ class detectorData;
#include <thread>
#include <vector>
#define MULTI_SHMAPIVERSION 0x190809
#define MULTI_SHMVERSION 0x201007
#define DETECTOR_SHMAPIVERSION 0x190809
#define DETECTOR_SHMVERSION 0x201007
#define SHORT_STRING_LENGTH 50
#include <future>
@ -30,7 +30,7 @@ class Module;
* @short structure allocated in shared memory to store detector settings
* for IPC and cache
*/
struct sharedMultiSlsDetector {
struct sharedDetector {
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND
* ------*/
@ -47,14 +47,14 @@ struct sharedMultiSlsDetector {
/** last time stamp when accessing the shared memory */
char lastDate[SHORT_STRING_LENGTH];
int numberOfDetectors;
slsDetectorDefs::detectorType multiDetectorType;
int numberOfModules;
slsDetectorDefs::detectorType detType;
/** END OF FIXED PATTERN
* -----------------------------------------------*/
/** Number of detectors operated at once */
slsDetectorDefs::xy numberOfDetector;
/** Number of modules operated at once */
slsDetectorDefs::xy numberOfModule;
/** max number of channels for complete detector*/
slsDetectorDefs::xy numberOfChannels;
@ -69,13 +69,11 @@ struct sharedMultiSlsDetector {
class DetectorImpl : public virtual slsDetectorDefs {
public:
/**
* Constructor
* @param multi_id multi detector id
* @param verify true to verify if shared memory version matches existing
* one
* @param update true to update last user pid, date etc
*/
explicit DetectorImpl(int multi_id = 0, bool verify = true,
explicit DetectorImpl(int detector_index = 0, bool verify = true,
bool update = true);
/**
@ -89,20 +87,20 @@ class DetectorImpl : public virtual slsDetectorDefs {
std::vector<int> positions,
typename NonDeduced<CT>::type... Args) {
if (detectors.empty())
throw sls::RuntimeError("No detectors added");
if (modules.empty())
throw sls::RuntimeError("No modules added");
if (positions.empty() ||
(positions.size() == 1 && positions[0] == -1)) {
positions.resize(detectors.size());
positions.resize(modules.size());
std::iota(begin(positions), end(positions), 0);
}
std::vector<std::future<RT>> futures;
futures.reserve(positions.size());
for (size_t i : positions) {
if (i >= detectors.size())
throw sls::RuntimeError("Detector out of range");
if (i >= modules.size())
throw sls::RuntimeError("Module out of range");
futures.push_back(std::async(std::launch::async, somefunc,
detectors[i].get(), Args...));
modules[i].get(), Args...));
}
sls::Result<RT> result;
result.reserve(positions.size());
@ -117,20 +115,20 @@ class DetectorImpl : public virtual slsDetectorDefs {
std::vector<int> positions,
typename NonDeduced<CT>::type... Args) const {
if (detectors.empty())
throw sls::RuntimeError("No detectors added");
if (modules.empty())
throw sls::RuntimeError("No modules added");
if (positions.empty() ||
(positions.size() == 1 && positions[0] == -1)) {
positions.resize(detectors.size());
positions.resize(modules.size());
std::iota(begin(positions), end(positions), 0);
}
std::vector<std::future<RT>> futures;
futures.reserve(positions.size());
for (size_t i : positions) {
if (i >= detectors.size())
throw sls::RuntimeError("Detector out of range");
if (i >= modules.size())
throw sls::RuntimeError("Module out of range");
futures.push_back(std::async(std::launch::async, somefunc,
detectors[i].get(), Args...));
modules[i].get(), Args...));
}
sls::Result<RT> result;
result.reserve(positions.size());
@ -145,20 +143,20 @@ class DetectorImpl : public virtual slsDetectorDefs {
std::vector<int> positions,
typename NonDeduced<CT>::type... Args) {
if (detectors.empty())
throw sls::RuntimeError("No detectors added");
if (modules.empty())
throw sls::RuntimeError("No modules added");
if (positions.empty() ||
(positions.size() == 1 && positions[0] == -1)) {
positions.resize(detectors.size());
positions.resize(modules.size());
std::iota(begin(positions), end(positions), 0);
}
std::vector<std::future<void>> futures;
futures.reserve(positions.size());
for (size_t i : positions) {
if (i >= detectors.size())
throw sls::RuntimeError("Detector out of range");
if (i >= modules.size())
throw sls::RuntimeError("Module out of range");
futures.push_back(std::async(std::launch::async, somefunc,
detectors[i].get(), Args...));
modules[i].get(), Args...));
}
for (auto &i : futures) {
i.get();
@ -170,20 +168,20 @@ class DetectorImpl : public virtual slsDetectorDefs {
std::vector<int> positions,
typename NonDeduced<CT>::type... Args) const {
if (detectors.empty())
throw sls::RuntimeError("No detectors added");
if (modules.empty())
throw sls::RuntimeError("No modules added");
if (positions.empty() ||
(positions.size() == 1 && positions[0] == -1)) {
positions.resize(detectors.size());
positions.resize(modules.size());
std::iota(begin(positions), end(positions), 0);
}
std::vector<std::future<void>> futures;
futures.reserve(positions.size());
for (size_t i : positions) {
if (i >= detectors.size())
throw sls::RuntimeError("Detector out of range");
if (i >= modules.size())
throw sls::RuntimeError("Module out of range");
futures.push_back(std::async(std::launch::async, somefunc,
detectors[i].get(), Args...));
modules[i].get(), Args...));
}
for (auto &i : futures) {
i.get();
@ -193,12 +191,12 @@ class DetectorImpl : public virtual slsDetectorDefs {
/** set acquiring flag in shared memory */
void setAcquiringFlag(bool flag);
/** return multi detector shared memory ID */
int getMultiId() const;
/** return detector index in shared memory */
int getDetectorIndex() const;
/** Free specific shared memory from the command line without creating
* object */
static void freeSharedMemory(int multiId, int detPos = -1);
static void freeSharedMemory(int detectorIndex, int detPos = -1);
/** Free all modules from current multi Id shared memory and delete members
*/
@ -215,24 +213,24 @@ class DetectorImpl : public virtual slsDetectorDefs {
/**
* Connect to Virtual Detector Servers at local host
* @param numdet number of detectors
* @param numdet number of modules
* @param port starting port number
*/
void setVirtualDetectorServers(const int numdet, const int port);
/** Sets the hostname of all sls detectors in shared memory and updates
/** Sets the hostname of all sls modules in shared memory and updates
* local cache */
void setHostname(const std::vector<std::string> &name);
/** Gets the total number of detectors */
/** Gets the total number of modules */
int size() const;
slsDetectorDefs::xy getNumberOfDetectors() const;
slsDetectorDefs::xy getNumberOfModules() const;
slsDetectorDefs::xy getNumberOfChannels() const;
/** Must be set before setting hostname
* Sets maximum number of channels of all sls detectors */
* Sets maximum number of channels of all sls modules */
void setNumberOfChannels(const slsDetectorDefs::xy c);
/** [Eiger][Jungfrau] */
@ -248,14 +246,14 @@ class DetectorImpl : public virtual slsDetectorDefs {
/**
* register callback for accessing acquisition final data
* @param func function to be called at the end of the acquisition.
* gets detector status and progress index as arguments
* gets module status and progress index as arguments
* @param pArg argument
*/
void registerAcquisitionFinishedCallback(void (*func)(double, int, void *),
void *pArg);
/**
* register calbback for accessing detector final data,
* register calbback for accessing module final data,
* also enables data streaming in client and receiver
* @param userCallback function for plotting/analyzing the data.
* Its arguments are
@ -307,7 +305,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
* one
* @param update true to update last user pid, date etc
*/
void setupMultiDetector(bool verify = true, bool update = true);
void setupDetector(bool verify = true, bool update = true);
/**
* Creates shm and initializes shm structure OR
@ -319,7 +317,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
/** Initialize detector structure for the shared memory just created */
void initializeDetectorStructure();
/** Initialize members (eg. slsDetectors from shm, zmqsockets)
/** Initialize members (eg. modules from shm, zmqsockets)
* @param verify true to verify if shm size matches existing one
*/
void initializeMembers(bool verify = true);
@ -332,7 +330,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
/** Execute command in terminal and return result */
std::string exec(const char *cmd);
void addSlsDetector(const std::string &hostname);
void addModule(const std::string &hostname);
void updateDetectorSize();
@ -380,22 +378,13 @@ class DetectorImpl : public virtual slsDetectorDefs {
*/
int kbhit();
/** Multi detector Id */
const int multiId{0};
/** Shared Memory object */
sls::SharedMemory<sharedMultiSlsDetector> multi_shm{0, -1};
/** pointers to the Module structures */
std::vector<std::unique_ptr<sls::Module>> detectors;
const int detectorIndex{0};
sls::SharedMemory<sharedDetector> shm{0, -1};
std::vector<std::unique_ptr<sls::Module>> modules;
/** data streaming (down stream) enabled in client (zmq sckets created) */
bool client_downstream{false};
/** ZMQ Socket - Receiver to Client */
std::vector<std::unique_ptr<ZmqSocket>> zmqSocket;
/** number of zmq sockets running currently */
volatile int numZmqRunning{0};
/** mutex to synchronize main and data processing threads */

View File

@ -5,11 +5,13 @@
#include "sls/bit_utils.h"
#include "sls/container_utils.h"
#include "sls/file_utils.h"
#include "sls/md5_helper.h"
#include "sls/network_utils.h"
#include "sls/sls_detector_exceptions.h"
#include "sls/sls_detector_funcs.h"
#include "sls/string_utils.h"
#include "sls/versionAPI.h"
#include <algorithm>
#include <array>
#include <bitset>
@ -57,7 +59,7 @@ void Module::freeSharedMemory() {
}
bool Module::isFixedPatternSharedMemoryCompatible() const {
return (shm()->shmversion >= SLS_SHMAPIVERSION);
return (shm()->shmversion >= MODULE_SHMAPIVERSION);
}
std::string Module::getHostname() const { return shm()->hostname; }
@ -69,7 +71,7 @@ void Module::setHostname(const std::string &hostname,
client.close();
try {
checkDetectorVersionCompatibility();
LOG(logINFO) << "Detector Version Compatibility - Success";
LOG(logINFO) << "Module Version Compatibility - Success";
} catch (const DetectorError &e) {
if (!initialChecks) {
LOG(logWARNING) << "Bypassing Initial Checks at your own risk!";
@ -77,7 +79,7 @@ void Module::setHostname(const std::string &hostname,
throw;
}
}
if (shm()->myDetectorType == EIGER) {
if (shm()->detType == EIGER) {
setActivate(true);
}
}
@ -107,22 +109,21 @@ int64_t Module::getReceiverSoftwareVersion() const {
// static function
slsDetectorDefs::detectorType
Module::getTypeFromDetector(const std::string &hostname, int cport) {
LOG(logDEBUG1) << "Getting detector type ";
LOG(logDEBUG1) << "Getting Module type ";
sls::ClientSocket socket("Detector", hostname, cport);
socket.Send(F_GET_DETECTOR_TYPE);
socket.Receive<int>(); // TODO! Should we look at this OK/FAIL?
auto retval = socket.Receive<detectorType>();
LOG(logDEBUG1) << "Detector type is " << retval;
LOG(logDEBUG1) << "Module type is " << retval;
return retval;
}
slsDetectorDefs::detectorType Module::getDetectorType() const {
return shm()->myDetectorType;
return shm()->detType;
}
void Module::updateNumberOfChannels() {
if (shm()->myDetectorType == CHIPTESTBOARD ||
shm()->myDetectorType == MOENCH) {
if (shm()->detType == CHIPTESTBOARD || shm()->detType == MOENCH) {
std::array<int, 2> retvals{};
sendToDetector(F_GET_NUM_CHANNELS, nullptr, retvals);
shm()->nChan.x = retvals[0];
@ -137,9 +138,9 @@ slsDetectorDefs::xy Module::getNumberOfChannels() const {
return coord;
}
void Module::updateNumberOfDetector(slsDetectorDefs::xy det) {
shm()->numberOfDetector = det;
int args[2] = {shm()->numberOfDetector.y, moduleIndex};
void Module::updateNumberOfModule(slsDetectorDefs::xy det) {
shm()->numberOfModule = det;
int args[2] = {shm()->numberOfModule.y, moduleIndex};
sendToDetector(F_SET_POSITION, args, nullptr);
}
@ -148,7 +149,7 @@ slsDetectorDefs::detectorSettings Module::getSettings() const {
}
void Module::setSettings(detectorSettings isettings) {
if (shm()->myDetectorType == EIGER) {
if (shm()->detType == EIGER) {
throw RuntimeError(
"Cannot set settings for Eiger. Use threshold energy.");
}
@ -176,7 +177,7 @@ void Module::setThresholdEnergy(int e_eV, detectorSettings isettings,
std::all_of(shm()->trimEnergies.begin(), shm()->trimEnergies.end(),
[e_eV](const int &e) { return e != e_eV; });
sls_detector_module myMod{shm()->myDetectorType};
sls_detector_module myMod{shm()->detType};
if (!interpolate) {
std::string settingsfname = getTrimbitFilename(isettings, e_eV);
@ -213,7 +214,7 @@ void Module::setThresholdEnergy(int e_eV, detectorSettings isettings,
setModule(myMod, trimbits);
if (getSettings() != isettings) {
throw RuntimeError("setThresholdEnergyAndSettings: Could not set "
"settings in detector");
"settings in Module");
}
if (shm()->useReceiverFlag) {
@ -249,7 +250,7 @@ void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
M_VDCSH
};
std::vector<sls_detector_module> myMods{shm()->myDetectorType};
std::vector<sls_detector_module> myMods{shm()->detType};
std::vector<int> energy(e_eV.begin(), e_eV.end());
// if all energies are same
if (allEqualTo(energy, energy[0])) {
@ -307,7 +308,7 @@ void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
}
}
sls_detector_module myMod{shm()->myDetectorType};
sls_detector_module myMod{shm()->detType};
myMod = myMods[0];
// if multiple thresholds, combine
@ -392,7 +393,7 @@ void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
setModule(myMod, trimbits);
if (getSettings() != isettings) {
throw RuntimeError("setThresholdEnergyAndSettings: Could not set "
"settings in detector");
"settings in Module");
}
if (shm()->useReceiverFlag) {
@ -410,13 +411,13 @@ std::string Module::setSettingsDir(const std::string &dir) {
return shm()->settingsDir;
}
void Module::loadSettingsFile(const std::string &fname) {
void Module::loadTrimbits(const std::string &fname) {
// find specific file if it has detid in file name (.snxxx)
if (shm()->myDetectorType == EIGER || shm()->myDetectorType == MYTHEN3) {
if (shm()->detType == EIGER || shm()->detType == MYTHEN3) {
std::ostringstream ostfn;
ostfn << fname;
int moduleIdWidth = 3;
if (shm()->myDetectorType == MYTHEN3) {
if (shm()->detType == MYTHEN3) {
moduleIdWidth = 4;
}
if ((fname.find(".sn") == std::string::npos) &&
@ -440,7 +441,7 @@ void Module::setAllTrimbits(int val) {
}
std::vector<int> Module::getTrimEn() const {
if (shm()->myDetectorType != EIGER && shm()->myDetectorType != MYTHEN3) {
if (shm()->detType != EIGER && shm()->detType != MYTHEN3) {
throw RuntimeError("getTrimEn not implemented for this detector.");
}
return std::vector<int>(shm()->trimEnergies.begin(),
@ -448,7 +449,7 @@ std::vector<int> Module::getTrimEn() const {
}
int Module::setTrimEn(const std::vector<int> &energies) {
if (shm()->myDetectorType != EIGER && shm()->myDetectorType != MYTHEN3) {
if (shm()->detType != EIGER && shm()->detType != MYTHEN3) {
throw RuntimeError("setTrimEn not implemented for this detector.");
}
if (energies.size() > MAX_TRIMEN) {
@ -464,7 +465,7 @@ int Module::setTrimEn(const std::vector<int> &energies) {
}
bool Module::getFlipRows() const {
if (shm()->myDetectorType == EIGER) {
if (shm()->detType == EIGER) {
const int rxIndex = 0;
return sendToReceiver<int>(rxIndex, F_GET_FLIP_ROWS_RECEIVER);
}
@ -472,7 +473,7 @@ bool Module::getFlipRows() const {
}
void Module::setFlipRows(bool value) {
if (shm()->myDetectorType == EIGER) {
if (shm()->detType == EIGER) {
const int rxIndex = -1;
sendToReceiver<int>(rxIndex, F_SET_FLIP_ROWS_RECEIVER, static_cast<int>(value));
} else {
@ -514,7 +515,7 @@ int64_t Module::getExptime(int gateIndex) const {
void Module::setExptime(int gateIndex, int64_t value) {
int64_t prevVal = value;
if (shm()->myDetectorType == EIGER) {
if (shm()->detType == EIGER) {
prevVal = getExptime(-1);
}
int64_t args[]{static_cast<int64_t>(gateIndex), value};
@ -570,7 +571,7 @@ int Module::getDynamicRange() const {
void Module::setDynamicRange(int dr) {
int prev_val = dr;
if (shm()->myDetectorType == EIGER) {
if (shm()->detType == EIGER) {
prev_val = getDynamicRange();
}
@ -581,7 +582,7 @@ void Module::setDynamicRange(int dr) {
}
// update speed
if (shm()->myDetectorType == EIGER) {
if (shm()->detType == EIGER) {
if (dr == 32) {
LOG(logINFO) << "Setting Clock to Quarter Speed to cope with "
"Dynamic Range of 32";
@ -991,9 +992,7 @@ int Module::getNumberofUDPDestinations() const {
return sendToDetector<int>(F_GET_NUM_DEST_UDP);
}
void Module::setNumberofUDPDestinations(const int value) {
sendToDetector(F_SET_NUM_DEST_UDP, value, nullptr);
}
void Module::clearUDPDestinations() { sendToDetector(F_CLEAR_ALL_UDP_DEST); }
int Module::getFirstUDPDestination() const {
return sendToDetector<int>(F_GET_UDP_FIRST_DEST);
@ -1026,7 +1025,7 @@ void Module::setDestinationUDPIP(const IpAddr ip, const int rxIndex) {
if (shm()->useReceiverFlag) {
sls::MacAddr retval(0LU);
sendToReceiver(rxIndex, F_SET_RECEIVER_UDP_IP, ip, retval);
LOG(logINFO) << "Setting destination udp mac of detector [" << moduleIndex
LOG(logINFO) << "Setting destination udp mac of Module [" << moduleIndex
<< ", " << rxIndex << "] to " << retval;
if (rxIndex == 0) {
sendToDetector(F_SET_DEST_UDP_MAC, retval, nullptr);
@ -1063,7 +1062,7 @@ void Module::setDestinationUDPIP2(const IpAddr ip, const int rxIndex) {
if (shm()->useReceiverFlag) {
sls::MacAddr retval(0LU);
sendToReceiver(rxIndex, F_SET_RECEIVER_UDP_IP2, ip, retval);
LOG(logINFO) << "Setting destination udp mac2 of detector " << moduleIndex
LOG(logINFO) << "Setting destination udp mac2 of Module " << moduleIndex
<< " to " << retval;
if (rxIndex == 0) {
sendToDetector(F_SET_DEST_UDP_MAC2, retval, nullptr);
@ -1167,28 +1166,28 @@ void Module::validateUDPConfiguration() {
std::string Module::printReceiverConfiguration(const int rxIndex) {
std::ostringstream os;
os << "\n\nDetector " << moduleIndex << "\nReceiver [" << rxIndex << "] Hostname:\t"
os << "\n\nModule " << moduleIndex << "\nReceiver [" << rxIndex << "] Hostname:\t"
<< getReceiverHostname(rxIndex);
if (shm()->myDetectorType == JUNGFRAU) {
if (shm()->detType == JUNGFRAU) {
os << "\nNumber of Interfaces:\t" << getNumberofUDPInterfaces()
<< "\nSelected Interface:\t" << getSelectedUDPInterface();
}
auto t = getDestinationUDPList(rxIndex);
os << "\nDetector UDP IP:\t" << getSourceUDPIP() << "\nDetector UDP MAC:\t"
<< getSourceUDPMAC() << "\nReceiver UDP IP:\t" << t.ip
<< "\nReceiver UDP MAC:\t" << t.mac;
os << "\nSource UDP IP:\t" << getSourceUDPIP() << "\nSource UDP MAC:\t"
<< getSourceUDPMAC() << "\nDestination UDP IP:\t" << t.ip
<< "\nDestination UDP MAC:\t" << t.mac;
if (shm()->myDetectorType == JUNGFRAU) {
os << "\nDetector UDP IP2:\t" << getSourceUDPIP2()
<< "\nDetector UDP MAC2:\t" << getSourceUDPMAC2()
<< "\nReceiver UDP IP2:\t" << t.ip2
<< "\nReceiver UDP MAC2:\t" << t.mac2;
if (shm()->detType == JUNGFRAU) {
os << "\nSource UDP IP2:\t" << getSourceUDPIP2()
<< "\nSource UDP MAC2:\t" << getSourceUDPMAC2()
<< "\nDestination UDP IP2:\t" << t.ip2
<< "\nDestination UDP MAC2:\t" << t.mac2;
}
os << "\nReceiver UDP Port:\t" << t.port;
if (shm()->myDetectorType == JUNGFRAU || shm()->myDetectorType == EIGER) {
os << "\nReceiver UDP Port2:\t" << t.port2;
os << "\nDestination UDP Port:\t" << t.port;
if (shm()->detType == JUNGFRAU || shm()->detType == EIGER) {
os << "\nDestination UDP Port2:\t" << t.port2;
}
os << "\n";
return os.str();
@ -1280,25 +1279,25 @@ void Module::setReceiverHostname(const std::string &receiverIP, const int rxInde
sendToDetector(F_GET_RECEIVER_PARAMETERS, nullptr, retval);
// populate from shared memory
retval.detType = shm()->myDetectorType;
retval.numberOfDetector.x = shm()->numberOfDetector.x;
retval.numberOfDetector.y = shm()->numberOfDetector.y;
retval.detType = shm()->detType;
retval.numberOfModule.x = shm()->numberOfModule.x;
retval.numberOfModule.y = shm()->numberOfModule.y;
retval.moduleIndex = moduleIndex;
memset(retval.hostname, 0, sizeof(retval.hostname));
strcpy_safe(retval.hostname, shm()->hostname);
sls::MacAddr retvals[2];
sendToReceiver(rxIndex, F_SETUP_RECEIVER, retval, retvals);
// update detectors with dest mac
// update Modules with dest mac
if (retval.udp_dstmac == 0 && retvals[0] != 0) {
LOG(logINFO) << "Setting destination udp mac of "
"detector "
"Module "
<< moduleIndex << " to " << retvals[0];
sendToDetector(F_SET_DEST_UDP_MAC, retvals[0], nullptr);
}
if (retval.udp_dstmac2 == 0 && retvals[1] != 0) {
LOG(logINFO) << "Setting destination udp mac2 of "
"detector "
"Module "
<< moduleIndex << " to " << retvals[1];
sendToDetector(F_SET_DEST_UDP_MAC2, retvals[1], nullptr);
}
@ -1610,7 +1609,7 @@ int64_t Module::getSubExptime() const {
void Module::setSubExptime(int64_t value) {
int64_t prevVal = value;
if (shm()->myDetectorType == EIGER) {
if (shm()->detType == EIGER) {
prevVal = getSubExptime();
}
sendToDetector(F_SET_SUB_EXPTIME, value, nullptr);
@ -1977,7 +1976,7 @@ void Module::getVetoPhoton(const int chipIndex,
void Module::setVetoPhoton(const int chipIndex, const int numPhotons,
const int energy, const std::string &fname) {
if (shm()->myDetectorType != GOTTHARD2) {
if (shm()->detType != GOTTHARD2) {
throw RuntimeError(
"Set Veto reference is not implemented for this detector");
}
@ -2058,7 +2057,7 @@ void Module::setVetoReference(const int gainIndex, const int value) {
}
void Module::setVetoFile(const int chipIndex, const std::string &fname) {
if (shm()->myDetectorType != GOTTHARD2) {
if (shm()->detType != GOTTHARD2) {
throw RuntimeError(
"Set Veto file is not implemented for this detector");
}
@ -2386,7 +2385,7 @@ void Module::setReadoutMode(const slsDetectorDefs::readoutMode mode) {
auto arg = static_cast<uint32_t>(mode); // TODO! unit?
sendToDetector(F_SET_READOUT_MODE, arg, nullptr);
// update #nchan, as it depends on #samples, adcmask,
if (shm()->myDetectorType == CHIPTESTBOARD) {
if (shm()->detType == CHIPTESTBOARD) {
updateNumberOfChannels();
}
if (shm()->useReceiverFlag) {
@ -2651,7 +2650,7 @@ void Module::setAdditionalJsonParameter(const std::string &key,
// Advanced
void Module::programFPGA(std::vector<char> buffer) {
switch (shm()->myDetectorType) {
switch (shm()->detType) {
case JUNGFRAU:
case CHIPTESTBOARD:
case MOENCH:
@ -3197,42 +3196,42 @@ slsDetectorDefs::detectorType Module::getDetectorTypeFromShm(int det_id,
}
shm.OpenSharedMemory();
if (verify && shm()->shmversion != SLS_SHMVERSION) {
if (verify && shm()->shmversion != MODULE_SHMVERSION) {
std::ostringstream ss;
ss << "Single shared memory (" << det_id << "-" << moduleIndex
<< ":)version mismatch (expected 0x" << std::hex << SLS_SHMVERSION
<< ":)version mismatch (expected 0x" << std::hex << MODULE_SHMVERSION
<< " but got 0x" << shm()->shmversion << ")" << std::dec
<< ". Clear Shared memory to continue.";
shm.UnmapSharedMemory();
throw SharedMemoryError(ss.str());
}
return shm()->myDetectorType;
return shm()->detType;
}
void Module::initSharedMemory(detectorType type, int det_id, bool verify) {
shm = SharedMemory<sharedSlsDetector>(det_id, moduleIndex);
shm = SharedMemory<sharedModule>(det_id, moduleIndex);
if (!shm.IsExisting()) {
shm.CreateSharedMemory();
initializeDetectorStructure(type);
initializeModuleStructure(type);
} else {
shm.OpenSharedMemory();
if (verify && shm()->shmversion != SLS_SHMVERSION) {
if (verify && shm()->shmversion != MODULE_SHMVERSION) {
std::ostringstream ss;
ss << "Single shared memory (" << det_id << "-" << moduleIndex
<< ":) version mismatch (expected 0x" << std::hex
<< SLS_SHMVERSION << " but got 0x" << shm()->shmversion << ")"
<< MODULE_SHMVERSION << " but got 0x" << shm()->shmversion << ")"
<< std::dec << ". Clear Shared memory to continue.";
throw SharedMemoryError(ss.str());
}
}
}
void Module::initializeDetectorStructure(detectorType type) {
shm()->shmversion = SLS_SHMVERSION;
void Module::initializeModuleStructure(detectorType type) {
shm()->shmversion = MODULE_SHMVERSION;
memset(shm()->hostname, 0, MAX_STR_LENGTH);
shm()->myDetectorType = type;
shm()->numberOfDetector.x = 0;
shm()->numberOfDetector.y = 0;
shm()->detType = type;
shm()->numberOfModule.x = 0;
shm()->numberOfModule.y = 0;
shm()->controlPort = DEFAULT_PORTNO;
shm()->stopPort = DEFAULT_PORTNO + 1;
sls::strcpy_safe(shm()->settingsDir, getenv("HOME"));
@ -3243,12 +3242,12 @@ void Module::initializeDetectorStructure(detectorType type) {
}
shm()->useReceiverFlag = false;
shm()->zmqport = DEFAULT_ZMQ_CL_PORTNO +
(moduleIndex * ((shm()->myDetectorType == EIGER) ? 2 : 1));
(moduleIndex * ((shm()->detType == EIGER) ? 2 : 1));
shm()->zmqip = IpAddr{};
shm()->numUDPInterfaces = 1;
shm()->stoppedFlag = false;
// get the detector parameters based on type
// get the Module parameters based on type
detParameters parameters{type};
shm()->nChan.x = parameters.nChanX;
shm()->nChan.y = parameters.nChanY;
@ -3259,7 +3258,7 @@ void Module::initializeDetectorStructure(detectorType type) {
void Module::checkDetectorVersionCompatibility() {
int64_t arg = 0;
switch (shm()->myDetectorType) {
switch (shm()->detType) {
case EIGER:
arg = APIEIGER;
break;
@ -3338,7 +3337,7 @@ int Module::sendModule(sls_detector_module *myMod, sls::ClientSocket &client) {
ts += n;
LOG(level) << "dacs sent. " << n << " bytes";
if (shm()->myDetectorType == EIGER || shm()->myDetectorType == MYTHEN3) {
if (shm()->detType == EIGER || shm()->detType == MYTHEN3) {
n = client.Send(myMod->chanregs, sizeof(int) * (myMod->nchan));
ts += n;
LOG(level) << "channels sent. " << n << " bytes";
@ -3386,12 +3385,12 @@ sls_detector_module Module::interpolateTrim(sls_detector_module *a,
const int energy, const int e1,
const int e2, bool trimbits) {
// dacs specified only for eiger and mythen3
if (shm()->myDetectorType != EIGER && shm()->myDetectorType != MYTHEN3) {
if (shm()->detType != EIGER && shm()->detType != MYTHEN3) {
throw NotImplementedError(
"Interpolation of Trim values not implemented for this detector!");
}
sls_detector_module myMod{shm()->myDetectorType};
sls_detector_module myMod{shm()->detType};
enum eiger_DacIndex {
E_SVP,
E_VTR,
@ -3431,7 +3430,7 @@ sls_detector_module Module::interpolateTrim(sls_detector_module *a,
// create copy and interpolate dac lists
std::vector<int> dacs_to_copy, dacs_to_interpolate;
if (shm()->myDetectorType == EIGER) {
if (shm()->detType == EIGER) {
dacs_to_copy.insert(
dacs_to_copy.end(),
{E_SVP, E_VTR, E_SVN, E_VTGSTV, E_RXB_RB, E_RXB_LB, E_VCN, E_VIS});
@ -3466,7 +3465,7 @@ sls_detector_module Module::interpolateTrim(sls_detector_module *a,
}
// Copy irrelevant dacs (without failing)
if (shm()->myDetectorType == EIGER) {
if (shm()->detType == EIGER) {
// CAL
if (a->dacs[E_CAL] != b->dacs[E_CAL]) {
LOG(logWARNING)
@ -3514,16 +3513,16 @@ std::string Module::getTrimbitFilename(detectorSettings s, int e_eV) {
}
std::ostringstream ostfn;
ostfn << shm()->settingsDir << ssettings << "/" << e_eV << "eV";
if (shm()->myDetectorType == EIGER) {
if (shm()->detType == EIGER) {
ostfn << "/noise.sn";
} else if (shm()->myDetectorType == MYTHEN3) {
} else if (shm()->detType == MYTHEN3) {
ostfn << "/trim.sn";
} else {
throw RuntimeError(
"Settings or trimbit files not defined for this detector.");
}
int moduleIdWidth = 3;
if (shm()->myDetectorType == MYTHEN3) {
if (shm()->detType == MYTHEN3) {
moduleIdWidth = 4;
}
ostfn << std::setfill('0') << std::setw(moduleIdWidth) << std::dec
@ -3534,10 +3533,10 @@ std::string Module::getTrimbitFilename(detectorSettings s, int e_eV) {
sls_detector_module Module::readSettingsFile(const std::string &fname,
bool trimbits) {
LOG(logDEBUG1) << "Read settings file " << fname;
sls_detector_module myMod(shm()->myDetectorType);
sls_detector_module myMod(shm()->detType);
// open file
std::ifstream infile;
if (shm()->myDetectorType == EIGER || shm()->myDetectorType == MYTHEN3) {
if (shm()->detType == EIGER || shm()->detType == MYTHEN3) {
infile.open(fname.c_str(), std::ifstream::binary);
} else {
infile.open(fname.c_str(), std::ios_base::in);
@ -3549,7 +3548,7 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
auto file_size = getFileSize(infile);
// eiger
if (shm()->myDetectorType == EIGER) {
if (shm()->detType == EIGER) {
infile.read(reinterpret_cast<char *>(myMod.dacs),
sizeof(int) * (myMod.ndac));
infile.read(reinterpret_cast<char *>(&myMod.iodelay),
@ -3572,7 +3571,7 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
}
// mythen3 (dacs, trimbits)
else if (shm()->myDetectorType == MYTHEN3) {
else if (shm()->detType == MYTHEN3) {
int expected_size = sizeof(int) * myMod.ndac +
sizeof(int) * myMod.nchan + sizeof(myMod.reg);
if (file_size != expected_size) {
@ -3606,107 +3605,192 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
}
void Module::programFPGAviaBlackfin(std::vector<char> buffer) {
uint64_t filesize = buffer.size();
// send program from memory to detector
LOG(logINFO) << "Sending programming binary (from pof) to detector "
LOG(logINFO) << "Sending programming binary (from pof) to module "
<< moduleIndex << " (" << shm()->hostname << ")";
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(F_PROGRAM_FPGA);
uint64_t filesize = buffer.size();
client.Send(filesize);
// error in detector at opening file pointer to flash
// checksum
std::string checksum = sls::md5_calculate_checksum(buffer.data(), filesize);
LOG(logDEBUG1) << "Checksum:" << checksum;
char cChecksum[MAX_STR_LENGTH];
memset(cChecksum, 0, MAX_STR_LENGTH);
strcpy(cChecksum, checksum.c_str());
client.Send(cChecksum);
// opening file fail
if (client.Receive<int>() == FAIL) {
std::cout << '\n';
std::ostringstream os;
os << "Detector " << moduleIndex << " (" << shm()->hostname << ")"
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
<< " returned error: " << client.readErrorMessage();
throw RuntimeError(os.str());
}
// erasing flash
LOG(logINFO) << "Erasing Flash for detector " << moduleIndex << " ("
<< 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) {
std::this_thread::sleep_for(std::chrono::seconds(1));
--count;
printf(
"%d%%\r",
static_cast<int>(
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) * 100));
std::cout << std::flush;
}
printf("\n");
LOG(logINFO) << "Writing to Flash to detector " << moduleIndex << " ("
<< shm()->hostname << ")";
printf("%d%%\r", 0);
std::cout << std::flush;
// sending program in parts of 2mb each
uint64_t unitprogramsize = 0;
int currentPointer = 0;
uint64_t totalsize = filesize;
while (filesize > 0) {
unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb
if (unitprogramsize > filesize) { // less than 2mb
unitprogramsize = filesize;
}
LOG(logDEBUG1) << "unitprogramsize:" << unitprogramsize
<< "\t filesize:" << filesize;
LOG(logDEBUG) << "unitprogramsize:" << unitprogramsize
<< "\t filesize:" << filesize;
client.Send(&buffer[currentPointer], unitprogramsize);
if (client.Receive<int>() == FAIL) {
std::cout << '\n';
std::ostringstream os;
os << "Detector " << moduleIndex << " (" << shm()->hostname << ")"
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
<< " returned error: " << client.readErrorMessage();
throw RuntimeError(os.str());
}
filesize -= unitprogramsize;
currentPointer += unitprogramsize;
// print progress
printf(
"%d%%\r",
static_cast<int>(
(static_cast<double>(totalsize - filesize) / totalsize) * 100));
std::cout << std::flush;
}
std::cout << '\n';
// fpga has picked up from flash successfully
// checksum
if (client.Receive<int>() == FAIL) {
std::ostringstream os;
os << "Detector " << moduleIndex << " (" << shm()->hostname << ")"
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
<< " returned error: " << client.readErrorMessage();
throw RuntimeError(os.str());
}
LOG(logINFO) << "Checksum verified for module " << moduleIndex << " ("
<< shm()->hostname << ")";
// simulating erasing flash
{
LOG(logINFO) << "(Simulating) Erasing Flash for module " << moduleIndex << " ("
<< 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) {
std::this_thread::sleep_for(std::chrono::seconds(1));
--count;
printf(
"%d%%\r",
static_cast<int>(
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) * 100));
std::cout << std::flush;
}
printf("\n");
}
// simulating writing to flash
{
LOG(logINFO) << "(Simulating) Writing to Flash for module " << moduleIndex << " (" << shm()->hostname << ")";
printf("%d%%\r", 0);
std::cout << std::flush;
// writing takes 30 seconds, printing here (otherwise need threads
// in server-unnecessary)
const int ERASE_TIME = 30;
int count = ERASE_TIME + 1;
while (count > 0) {
std::this_thread::sleep_for(std::chrono::seconds(1));
--count;
printf(
"%d%%\r",
static_cast<int>(
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) * 100));
std::cout << std::flush;
}
printf("\n");
}
if (client.Receive<int>() == FAIL) {
std::ostringstream os;
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
<< " returned error: " << client.readErrorMessage();
throw RuntimeError(os.str());
}
if (moduleIndex == 0) {
LOG(logINFO) << "Copied to flash and checksum verified";
}
LOG(logINFO) << "FPGA programmed successfully";
rebootController();
}
void Module::programFPGAviaNios(std::vector<char> buffer) {
LOG(logINFO) << "Sending programming binary (from rbf) to detector "
LOG(logINFO) << "Sending programming binary (from rbf) to Module "
<< moduleIndex << " (" << shm()->hostname << ")";
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(F_PROGRAM_FPGA);
uint64_t filesize = buffer.size();
client.Send(filesize);
// checksum
std::string checksum = sls::md5_calculate_checksum(buffer.data(), filesize);
LOG(logDEBUG1) << "Checksum:" << checksum;
char cChecksum[MAX_STR_LENGTH];
memset(cChecksum, 0, MAX_STR_LENGTH);
strcpy(cChecksum, checksum.c_str());
client.Send(cChecksum);
// validate file size before sending program
if (client.Receive<int>() == FAIL) {
std::ostringstream os;
os << "Detector " << moduleIndex << " (" << shm()->hostname << ")"
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
<< " returned error: " << client.readErrorMessage();
throw RuntimeError(os.str());
}
client.Send(buffer);
// simulating erasing flash
{
LOG(logINFO) << "(Simulating) Erasing Flash for module " << moduleIndex << " ("
<< shm()->hostname << ")";
printf("%d%%\r", 0);
std::cout << std::flush;
// erasing takes 10 seconds, printing here (otherwise need threads
// in server-unnecessary)
const int ERASE_TIME = 10;
int count = ERASE_TIME + 1;
while (count > 0) {
std::this_thread::sleep_for(std::chrono::seconds(1));
--count;
printf(
"%d%%\r",
static_cast<int>(
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) * 100));
std::cout << std::flush;
}
printf("\n");
}
// simulating writing to flash
{
LOG(logINFO) << "(Simulating) Writing to Flash for module " << moduleIndex << " (" << shm()->hostname << ")";
printf("%d%%\r", 0);
std::cout << std::flush;
// writing takes 45 seconds, printing here (otherwise need threads
// in server-unnecessary)
const int ERASE_TIME = 45;
int count = ERASE_TIME + 1;
while (count > 0) {
std::this_thread::sleep_for(std::chrono::seconds(1));
--count;
printf(
"%d%%\r",
static_cast<int>(
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) * 100));
std::cout << std::flush;
}
printf("\n");
}
if (client.Receive<int>() == FAIL) {
std::ostringstream os;
os << "Detector " << moduleIndex << " (" << shm()->hostname << ")"
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
<< " returned error: " << client.readErrorMessage();
throw RuntimeError(os.str());
}

View File

@ -14,8 +14,8 @@
class ServerInterface;
#define SLS_SHMAPIVERSION 0x190726
#define SLS_SHMVERSION 0x210913
#define MODULE_SHMAPIVERSION 0x190726
#define MODULE_SHMVERSION 0x210913
namespace sls {
@ -25,24 +25,24 @@ struct sharedReceiver {
};
/**
* @short structure allocated in shared memory to store detector settings for
* @short structure allocated in shared memory to store Module settings for
* IPC and cache
*/
struct sharedSlsDetector {
struct sharedModule {
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND ------*/
int shmversion;
char hostname[MAX_STR_LENGTH];
slsDetectorDefs::detectorType myDetectorType;
slsDetectorDefs::detectorType detType;
/** END OF FIXED PATTERN -----------------------------------------------*/
slsDetectorDefs::xy numberOfDetector;
slsDetectorDefs::xy numberOfModule;
int controlPort;
int stopPort;
char settingsDir[MAX_STR_LENGTH];
/** list of the energies at which the detector has been trimmed */
/** list of the energies at which the Module has been trimmed */
sls::StaticVector<int, MAX_TRIMEN> trimEnergies;
/** number of channels per chip */
slsDetectorDefs::xy nChan;
@ -84,7 +84,7 @@ class Module : public virtual slsDetectorDefs {
virtual ~Module();
/** Frees shared memory and deletes shared memory structure
Safe to call only if detector shm also deleted or its numberOfDetectors is
Safe to call only if detector shm also deleted or its numberOfModules is
updated */
void freeSharedMemory();
bool isFixedPatternSharedMemoryCompatible() const;
@ -107,7 +107,7 @@ class Module : public virtual slsDetectorDefs {
detectorType getDetectorType() const;
void updateNumberOfChannels();
slsDetectorDefs::xy getNumberOfChannels() const;
void updateNumberOfDetector(slsDetectorDefs::xy det);
void updateNumberOfModule(slsDetectorDefs::xy det);
detectorSettings getSettings() const;
void setSettings(detectorSettings isettings);
int getThresholdEnergy() const;
@ -118,7 +118,7 @@ class Module : public virtual slsDetectorDefs {
detectorSettings isettings, bool trimbits);
std::string getSettingsDir() const;
std::string setSettingsDir(const std::string &dir);
void loadSettingsFile(const std::string &fname);
void loadTrimbits(const std::string &fname);
int getAllTrimbits() const;
void setAllTrimbits(int val);
std::vector<int> getTrimEn() const;
@ -232,7 +232,7 @@ class Module : public virtual slsDetectorDefs {
sls::UdpDestination getDestinationUDPList(const uint32_t entry) const;
void setDestinationUDPList(const sls::UdpDestination dest);
int getNumberofUDPDestinations() const;
void setNumberofUDPDestinations(const int value);
void clearUDPDestinations();
int getFirstUDPDestination() const;
void setFirstUDPDestination(const int value);
sls::IpAddr getDestinationUDPIP(const int rxIndex) const;
@ -718,9 +718,9 @@ class Module : public virtual slsDetectorDefs {
verify is if shm size matches existing one */
void initSharedMemory(detectorType type, int det_id, bool verify = true);
/** Initialize detector structure to defaults,
/** Initialize module structure to defaults,
Called when new shared memory is created */
void initializeDetectorStructure(detectorType type);
void initializeModuleStructure(detectorType type);
void checkDetectorVersionCompatibility();
void checkReceiverVersionCompatibility();
@ -763,7 +763,7 @@ class Module : public virtual slsDetectorDefs {
void programFPGAviaNios(std::vector<char> buffer);
const int moduleIndex;
mutable sls::SharedMemory<sharedSlsDetector> shm{0, 0};
mutable sls::SharedMemory<sharedModule> shm{0, 0};
};
} // namespace sls

View File

@ -22,8 +22,8 @@
#include <sys/stat.h> // fstat
#include <unistd.h>
#define SHM_MULTI_PREFIX "/slsDetectorPackage_multi_"
#define SHM_SLS_PREFIX "_sls_"
#define SHM_DETECTOR_PREFIX "/slsDetectorPackage_detector_"
#define SHM_MODULE_PREFIX "_module_"
#define SHM_ENV_NAME "SLSDETNAME"
#include <iostream>
@ -35,13 +35,10 @@ template <typename T> class SharedMemory {
public:
/**
* Constructor
* creates the single/multi detector shared memory name
* @param multiId multi detector id
* @param slsId sls detector id, -1 if a multi detector shared memory
* moduleid of -1 creates a detector only shared memory
*/
SharedMemory(int multiId, int slsId) {
name = ConstructSharedMemoryName(multiId, slsId);
SharedMemory(int detectorId, int moduleIndex) {
name = ConstructSharedMemoryName(detectorId, moduleIndex);
}
/**
@ -208,11 +205,11 @@ template <typename T> class SharedMemory {
/**
* Create Shared memory name
* throws exception if name created is longer than required 255(manpages)
* @param multiId multi detector id
* @param slsId sls detector id, -1 if a multi detector shared memory
* @param detectorId detector id
* @param moduleIndex module id, -1 if a detector shared memory
* @returns shared memory name
*/
std::string ConstructSharedMemoryName(int multiId, int slsId) {
std::string ConstructSharedMemoryName(int detectorId, int moduleIndex) {
// using environment path
std::string sEnvPath;
@ -223,11 +220,11 @@ template <typename T> class SharedMemory {
}
std::stringstream ss;
if (slsId < 0)
ss << SHM_MULTI_PREFIX << multiId << sEnvPath;
if (moduleIndex < 0)
ss << SHM_DETECTOR_PREFIX << detectorId << sEnvPath;
else
ss << SHM_MULTI_PREFIX << multiId << SHM_SLS_PREFIX << slsId
<< sEnvPath;
ss << SHM_DETECTOR_PREFIX << detectorId << SHM_MODULE_PREFIX
<< moduleIndex << sEnvPath;
std::string temp = ss.str();
if (temp.length() > NAME_MAX_LENGTH) {

View File

@ -2215,13 +2215,12 @@ TEST_CASE("udp_dstlist", "[.cmd]") {
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::JUNGFRAU || det_type == defs::EIGER) {
REQUIRE_NOTHROW(proxy.Call("udp_dstlist", {"0"}, -1, GET));
REQUIRE_NOTHROW(proxy.Call("udp_dstlist", {}, 0, GET, std::cout, 0));
REQUIRE_THROWS(proxy.Call(
"udp_dstlist",
{"entry=0", "ip=0.0.0.0", "mac=00:00:00:00:00:00", "port=1233"}, -1,
PUT));
"udp_dstlist", {"ip=0.0.0.0", "mac=00:00:00:00:00:00", "port=1233"},
-1, PUT, std::cout, 0));
} else {
REQUIRE_THROWS(proxy.Call("udp_dstlist", {"0"}, -1, GET));
REQUIRE_THROWS(proxy.Call("udp_dstlist", {}, -1, GET, std::cout, 0));
}
}
@ -2230,33 +2229,20 @@ TEST_CASE("udp_numdst", "[.cmd]") {
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::JUNGFRAU || det_type == defs::EIGER) {
auto prev_val = det.getNumberofUDPDestinations();
{
std::ostringstream oss;
proxy.Call("udp_numdst", {"10"}, -1, PUT, oss);
REQUIRE(oss.str() == "udp_numdst 10\n");
}
{
std::ostringstream oss;
proxy.Call("udp_numdst", {}, -1, GET, oss);
REQUIRE(oss.str() == "udp_numdst 10\n");
}
{
std::ostringstream oss;
proxy.Call("udp_numdst", {"32"}, -1, PUT, oss);
REQUIRE(oss.str() == "udp_numdst 32\n");
}
REQUIRE_THROWS(proxy.Call("udp_numdst", {"0"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("udp_numdst", {"33"}, -1, PUT));
for (int i = 0; i != det.size(); ++i) {
det.setNumberofUDPDestinations(prev_val[i], {i});
}
REQUIRE_NOTHROW(proxy.Call("udp_numdst", {}, -1, GET));
} else {
REQUIRE_THROWS(proxy.Call("udp_numdst", {}, -1, GET));
}
}
TEST_CASE("udp_cleardst", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
REQUIRE_THROWS(proxy.Call("udp_cleardst", {}, -1, GET));
REQUIRE_NOTHROW(proxy.Call("udp_cleardst", {}, -1, PUT));
}
TEST_CASE("udp_firstdst", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);

View File

@ -29,7 +29,7 @@ TEST_CASE("Is shm fixed pattern shm compatible") {
REQUIRE(m.isFixedPatternSharedMemoryCompatible() == true);
// Set shm version to 0
sls::SharedMemory<sls::sharedSlsDetector> shm(0, 0);
sls::SharedMemory<sls::sharedModule> shm(0, 0);
REQUIRE(shm.IsExisting() == true);
shm.OpenSharedMemory();
shm()->shmversion = 0;