mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-12 21:07:13 +02:00
moved headers
This commit is contained in:
@ -1,52 +0,0 @@
|
||||
/*
|
||||
|
||||
This class parses command line input or string input to extract the
|
||||
multi_id, detector_id, command and arguments. It's used in the command
|
||||
line binaries (sls_detector_get/put) to parse commands and in the
|
||||
slsDetectorShared library to parse input from config files.
|
||||
|
||||
This class is fully internal to the project and NO guarantees are given
|
||||
on the stability of the interface or implementation. This is also the
|
||||
reason that the header file is not exposed.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#ifndef CMD_LINE_PARSER_H
|
||||
#define CMD_LINE_PARSER_H
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace sls {
|
||||
|
||||
class CmdLineParser {
|
||||
public:
|
||||
void Parse(int argc, const char *const argv[]);
|
||||
void Parse(const std::string &s);
|
||||
void Print();
|
||||
|
||||
int multi_id() const noexcept { return multi_id_; };
|
||||
int detector_id() const noexcept { return detector_id_; };
|
||||
int n_arguments() const noexcept { return arguments_.size(); }
|
||||
const std::string &command() const noexcept{ return command_; }
|
||||
void setCommand(std::string cmd) { command_ = cmd; }
|
||||
bool isHelp() const noexcept { return help_; }
|
||||
|
||||
const std::string &executable() const noexcept{ return executable_; }
|
||||
const std::vector<std::string> &arguments() const noexcept{ return arguments_; };
|
||||
std::vector<const char *> argv() const;
|
||||
std::string cli_line() const;
|
||||
|
||||
private:
|
||||
void DecodeIdAndPosition(const char *c);
|
||||
void Reset(); // reset all private variables
|
||||
int multi_id_ = 0;
|
||||
int detector_id_ = -1;
|
||||
bool help_ = false;
|
||||
std::string command_;
|
||||
std::string executable_;
|
||||
std::vector<std::string> arguments_;
|
||||
};
|
||||
|
||||
} // namespace sls
|
||||
#endif // CMD_LINE_PARSER_H
|
File diff suppressed because it is too large
Load Diff
@ -1,304 +0,0 @@
|
||||
#pragma once
|
||||
/************************************************
|
||||
* @file SharedMemory.h
|
||||
* @short functions basic implemenation of
|
||||
* shared memory
|
||||
***********************************************/
|
||||
/**
|
||||
*@short functions basic implemenation of shared memory
|
||||
*/
|
||||
|
||||
#include "ansi.h"
|
||||
#include "logger.h"
|
||||
#include "sls_detector_exceptions.h"
|
||||
|
||||
#include "stdlib.h"
|
||||
#include <cerrno> // errno
|
||||
#include <cstring> // strerror
|
||||
#include <fcntl.h> // O_CREAT, O_TRUNC..
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdio.h> // printf
|
||||
#include <sys/mman.h> // shared memory
|
||||
#include <sys/stat.h> // fstat
|
||||
#include <unistd.h>
|
||||
|
||||
#define SHM_MULTI_PREFIX "/slsDetectorPackage_multi_"
|
||||
#define SHM_SLS_PREFIX "_sls_"
|
||||
#define SHM_ENV_NAME "SLSDETNAME"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace sls {
|
||||
|
||||
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
|
||||
*/
|
||||
SharedMemory(int multiId, int slsId) {
|
||||
name = ConstructSharedMemoryName(multiId, slsId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the copy constructor and copy assignment since we don't want two
|
||||
* objects managing the same resource
|
||||
*/
|
||||
SharedMemory(const SharedMemory &) = delete;
|
||||
SharedMemory &operator=(const SharedMemory &other) = delete;
|
||||
|
||||
//Move constructor
|
||||
SharedMemory(SharedMemory &&other) : name(other.name),
|
||||
fd(other.fd),
|
||||
shmSize(other.shmSize),
|
||||
shared_struct(other.shared_struct) {
|
||||
|
||||
other.fd = -1;
|
||||
other.shared_struct = nullptr;
|
||||
other.shmSize = 0;
|
||||
}
|
||||
|
||||
//Move assignment
|
||||
SharedMemory &operator=(SharedMemory &&other) {
|
||||
name = other.name;
|
||||
if (fd) {
|
||||
close(fd);
|
||||
}
|
||||
fd = other.fd;
|
||||
other.fd = -1;
|
||||
|
||||
if (shared_struct != nullptr) {
|
||||
UnmapSharedMemory();
|
||||
}
|
||||
shared_struct = other.shared_struct;
|
||||
other.shared_struct = nullptr;
|
||||
|
||||
shmSize = other.shmSize;
|
||||
other.shmSize = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~SharedMemory() {
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
|
||||
if (shared_struct) {
|
||||
UnmapSharedMemory();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if it exists
|
||||
* @param name of shared memory
|
||||
* @return true if exists, else false
|
||||
*/
|
||||
bool IsExisting() {
|
||||
bool ret = true;
|
||||
int tempfd = shm_open(name.c_str(), O_RDWR, 0);
|
||||
if ((tempfd < 0) && (errno == ENOENT)) {
|
||||
ret = false;
|
||||
}
|
||||
close(tempfd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shared memory name
|
||||
*/
|
||||
std::string GetName() const {
|
||||
return name;
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return shmSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Shared memory and call MapSharedMemory to map it to an address
|
||||
* throws a SharedMemoryError exception on failure to create, ftruncate or map
|
||||
* @param sz of shared memory
|
||||
*/
|
||||
void CreateSharedMemory() {
|
||||
fd = shm_open(name.c_str(), O_CREAT | O_TRUNC | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
if (fd < 0) {
|
||||
std::string msg = "Create shared memory " + name + " failed: " + strerror(errno);
|
||||
FILE_LOG(logERROR) << msg;
|
||||
throw SharedMemoryError(msg);
|
||||
}
|
||||
|
||||
if (ftruncate(fd, sizeof(T)) < 0) {
|
||||
std::string msg = "Create shared memory " + name + " failed at ftruncate: " + strerror(errno);
|
||||
FILE_LOG(logERROR) << msg;
|
||||
close(fd);
|
||||
RemoveSharedMemory();
|
||||
throw SharedMemoryError(msg);
|
||||
}
|
||||
|
||||
shared_struct = MapSharedMemory();
|
||||
FILE_LOG(logINFO) << "Shared memory created " << name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open existing Shared memory and call MapSharedMemory to map it to an address
|
||||
* throws a SharedMemoryError exception on failure to open or map
|
||||
* @param sz of shared memory
|
||||
*/
|
||||
void OpenSharedMemory() {
|
||||
fd = shm_open(name.c_str(), O_RDWR, 0);
|
||||
if (fd < 0) {
|
||||
std::string msg = "Open existing shared memory " + name + " failed: " + strerror(errno);
|
||||
FILE_LOG(logERROR) << msg;
|
||||
throw SharedMemoryError(msg);
|
||||
}
|
||||
|
||||
shared_struct = MapSharedMemory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmap shared memory from an address
|
||||
* throws a SharedMemoryError exception on failure
|
||||
*/
|
||||
void UnmapSharedMemory() {
|
||||
if (shared_struct != nullptr) {
|
||||
if (munmap(shared_struct, shmSize) < 0) {
|
||||
std::string msg = "Unmapping shared memory " + name + " failed: " + strerror(errno);
|
||||
FILE_LOG(logERROR) << msg;
|
||||
close(fd);
|
||||
throw SharedMemoryError(msg);
|
||||
}
|
||||
shared_struct = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove existing Shared memory
|
||||
*/
|
||||
void RemoveSharedMemory() {
|
||||
UnmapSharedMemory();
|
||||
if (shm_unlink(name.c_str()) < 0) {
|
||||
// silent exit if shm did not exist anyway
|
||||
if (errno == ENOENT)
|
||||
return;
|
||||
std::string msg = "Free Shared Memory " + name + " Failed: " + strerror(errno);
|
||||
FILE_LOG(logERROR) << msg;
|
||||
throw SharedMemoryError(msg);
|
||||
}
|
||||
FILE_LOG(logINFO) << "Shared memory deleted " << name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum length of name as from man pages
|
||||
*/
|
||||
static const int NAME_MAX_LENGTH = 255;
|
||||
|
||||
/**
|
||||
*Using the call operator to access the pointer
|
||||
*/
|
||||
T *operator()() {
|
||||
return shared_struct;
|
||||
}
|
||||
|
||||
/**
|
||||
*Using the call operator to access the pointer, const overload
|
||||
*/
|
||||
const T *operator()() const {
|
||||
return shared_struct;
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* 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
|
||||
* @returns shared memory name
|
||||
*/
|
||||
std::string ConstructSharedMemoryName(int multiId, int slsId) {
|
||||
|
||||
// using environment path
|
||||
std::string sEnvPath = "";
|
||||
char *envpath = getenv(SHM_ENV_NAME);
|
||||
if (envpath != nullptr) {
|
||||
sEnvPath.assign(envpath);
|
||||
sEnvPath.insert(0, "_");
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
if (slsId < 0)
|
||||
ss << SHM_MULTI_PREFIX << multiId << sEnvPath;
|
||||
else
|
||||
ss << SHM_MULTI_PREFIX << multiId << SHM_SLS_PREFIX << slsId << sEnvPath;
|
||||
|
||||
std::string temp = ss.str();
|
||||
if (temp.length() > NAME_MAX_LENGTH) {
|
||||
std::string msg = "Shared memory initialization failed. " + temp + " has " + std::to_string(temp.length()) + " characters. \n" + "Maximum is " + std::to_string(NAME_MAX_LENGTH) + ". Change the environment variable " + SHM_ENV_NAME;
|
||||
FILE_LOG(logERROR) << msg;
|
||||
throw SharedMemoryError(msg);
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map shared memory to an address
|
||||
* throws a SharedMemoryException exception on failure
|
||||
* @param sz of shared memory
|
||||
*/
|
||||
|
||||
T *MapSharedMemory() {
|
||||
void *addr = mmap(nullptr, sizeof(T), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (addr == MAP_FAILED) {
|
||||
std::string msg = "Mapping shared memory " + name + " failed: " + strerror(errno);
|
||||
FILE_LOG(logERROR) << msg;
|
||||
close(fd);
|
||||
throw SharedMemoryError(msg);
|
||||
}
|
||||
shmSize = sizeof(T);
|
||||
close(fd);
|
||||
return (T *)addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if existing shared memory size matches expected size
|
||||
* @param expectedSize expected size of shared memory, replaced with smaller size if size does not match
|
||||
* @return 0 for success, 1 for fail
|
||||
*/
|
||||
int VerifySizeMatch(size_t expectedSize) {
|
||||
struct stat sb;
|
||||
// could not fstat
|
||||
if (fstat(fd, &sb) < 0) {
|
||||
std::string msg = "Could not verify existing shared memory " + name + " size match " + "(could not fstat): " + strerror(errno);
|
||||
FILE_LOG(logERROR) << msg;
|
||||
close(fd);
|
||||
throw SharedMemoryError(msg);
|
||||
}
|
||||
|
||||
//size does not match
|
||||
auto sz = static_cast<size_t>(sb.st_size);
|
||||
if (sz != expectedSize) {
|
||||
std::string msg = "Existing shared memory " + name + " size does not match" + "Expected " + std::to_string(expectedSize) + ", found " + std::to_string(sz);
|
||||
FILE_LOG(logERROR) << msg;
|
||||
throw SharedMemoryError(msg);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Shared memory name */
|
||||
std::string name;
|
||||
|
||||
/** File descriptor */
|
||||
int fd{-1};
|
||||
|
||||
/** shm size */
|
||||
size_t shmSize{0};
|
||||
|
||||
T *shared_struct{nullptr};
|
||||
};
|
||||
|
||||
} // namespace sls
|
@ -1,476 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Result.h"
|
||||
#include "SharedMemory.h"
|
||||
#include "logger.h"
|
||||
#include "sls_detector_defs.h"
|
||||
|
||||
class slsDetector;
|
||||
class ZmqSocket;
|
||||
class detectorData;
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <semaphore.h>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#define MULTI_SHMAPIVERSION 0x190809
|
||||
#define MULTI_SHMVERSION 0x190814
|
||||
#define SHORT_STRING_LENGTH 50
|
||||
#define DATE_LENGTH 30
|
||||
|
||||
#include <future>
|
||||
#include <numeric>
|
||||
/**
|
||||
* @short structure allocated in shared memory to store detector settings
|
||||
* for IPC and cache
|
||||
*/
|
||||
struct sharedMultiSlsDetector {
|
||||
|
||||
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND
|
||||
* ------*/
|
||||
|
||||
/** shared memory version */
|
||||
int shmversion;
|
||||
|
||||
/** last process id accessing the shared memory */
|
||||
pid_t lastPID;
|
||||
|
||||
/** last user name accessing the shared memory */
|
||||
char lastUser[SHORT_STRING_LENGTH];
|
||||
|
||||
/** last time stamp when accessing the shared memory */
|
||||
char lastDate[SHORT_STRING_LENGTH];
|
||||
|
||||
/** number of sls detectors in shared memory */
|
||||
int numberOfDetectors;
|
||||
|
||||
/** multi detector type */
|
||||
slsDetectorDefs::detectorType multiDetectorType;
|
||||
|
||||
/** END OF FIXED PATTERN
|
||||
* -----------------------------------------------*/
|
||||
|
||||
/** Number of detectors operated at once */
|
||||
slsDetectorDefs::xy numberOfDetector;
|
||||
|
||||
/** max number of channels for complete detector*/
|
||||
slsDetectorDefs::xy numberOfChannels;
|
||||
|
||||
/** flag for acquiring */
|
||||
bool acquiringFlag;
|
||||
|
||||
/** data streaming (up stream) enable in receiver */
|
||||
bool receiver_upstream;
|
||||
};
|
||||
|
||||
class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* @param 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 multiSlsDetector(int multi_id = 0, bool verify = true,
|
||||
bool update = true);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~multiSlsDetector();
|
||||
|
||||
template <class CT> struct NonDeduced { using type = CT; };
|
||||
template <typename RT, typename... CT>
|
||||
sls::Result<RT> Parallel(RT (slsDetector::*somefunc)(CT...),
|
||||
std::vector<int> positions,
|
||||
typename NonDeduced<CT>::type... Args) {
|
||||
|
||||
if (detectors.size() == 0)
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (positions.empty() ||
|
||||
(positions.size() == 1 && positions[0] == -1)) {
|
||||
positions.resize(detectors.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");
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
detectors[i].get(), Args...));
|
||||
}
|
||||
sls::Result<RT> result;
|
||||
result.reserve(positions.size());
|
||||
for (auto &i : futures) {
|
||||
result.push_back(i.get());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename RT, typename... CT>
|
||||
sls::Result<RT> Parallel(RT (slsDetector::*somefunc)(CT...) const,
|
||||
std::vector<int> positions,
|
||||
typename NonDeduced<CT>::type... Args) const {
|
||||
|
||||
if (detectors.size() == 0)
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (positions.empty() ||
|
||||
(positions.size() == 1 && positions[0] == -1)) {
|
||||
positions.resize(detectors.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");
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
detectors[i].get(), Args...));
|
||||
}
|
||||
sls::Result<RT> result;
|
||||
result.reserve(positions.size());
|
||||
for (auto &i : futures) {
|
||||
result.push_back(i.get());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename... CT>
|
||||
void Parallel(void (slsDetector::*somefunc)(CT...),
|
||||
std::vector<int> positions,
|
||||
typename NonDeduced<CT>::type... Args) {
|
||||
|
||||
if (detectors.size() == 0)
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (positions.empty() ||
|
||||
(positions.size() == 1 && positions[0] == -1)) {
|
||||
positions.resize(detectors.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");
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
detectors[i].get(), Args...));
|
||||
}
|
||||
for (auto &i : futures) {
|
||||
i.get();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... CT>
|
||||
void Parallel(void (slsDetector::*somefunc)(CT...) const,
|
||||
std::vector<int> positions,
|
||||
typename NonDeduced<CT>::type... Args) const {
|
||||
|
||||
if (detectors.size() == 0)
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (positions.empty() ||
|
||||
(positions.size() == 1 && positions[0] == -1)) {
|
||||
positions.resize(detectors.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");
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
detectors[i].get(), Args...));
|
||||
}
|
||||
for (auto &i : futures) {
|
||||
i.get();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/** return multi detector shared memory ID */
|
||||
int getMultiId() const;
|
||||
|
||||
std::string getPackageVersion() const;
|
||||
|
||||
int64_t getClientSoftwareVersion() const;
|
||||
|
||||
/** Free specific shared memory from the command line without creating object */
|
||||
static void freeSharedMemory(int multiId, int detPos = -1);
|
||||
|
||||
/** Free all modules from current multi Id shared memory and delete members */
|
||||
void freeSharedMemory();
|
||||
|
||||
/** Get user details of shared memory */
|
||||
std::string getUserDetails();
|
||||
|
||||
/**
|
||||
* Connect to Virtual Detector Servers at local host
|
||||
* @param ndet number of detectors
|
||||
* @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 local cache */
|
||||
void setHostname(const std::vector<std::string> &name);
|
||||
|
||||
/** Gets the total number of detectors */
|
||||
int size() const;
|
||||
|
||||
slsDetectorDefs::xy getNumberOfDetectors() const;
|
||||
|
||||
slsDetectorDefs::xy getNumberOfChannels() const;
|
||||
|
||||
/** Must be set before setting hostname
|
||||
* Sets maximum number of channels of all sls detectors */
|
||||
void setNumberOfChannels(const slsDetectorDefs::xy c);
|
||||
|
||||
/**
|
||||
* Enable gap pixels, only for Eiger and for 8,16 and 32 bit mode. (Eiger)
|
||||
* 4 bit mode gap pixels only in gui call back
|
||||
*/
|
||||
void setGapPixelsinReceiver(bool enable);
|
||||
|
||||
/**
|
||||
* Enable data streaming to client
|
||||
* @param enable 0 to disable, 1 to enable, -1 to get the value
|
||||
* @returns data streaming to client enable
|
||||
*/
|
||||
bool enableDataStreamingToClient(int enable = -1);
|
||||
|
||||
void savePattern(const std::string &fname);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param pArg argument
|
||||
*/
|
||||
void registerAcquisitionFinishedCallback(void (*func)(double, int, void *),
|
||||
void *pArg);
|
||||
|
||||
/**
|
||||
* register calbback for accessing detector final data,
|
||||
* also enables data streaming in client and receiver
|
||||
* @param userCallback function for plotting/analyzing the data.
|
||||
* Its arguments are
|
||||
* the data structure d and the frame number f,
|
||||
* s is for subframe number for eiger for 32 bit mode
|
||||
* @param pArg argument
|
||||
*/
|
||||
void registerDataCallback(void (*userCallback)(detectorData *, uint64_t,
|
||||
uint32_t, void *),
|
||||
void *pArg);
|
||||
|
||||
/**
|
||||
* Performs a complete acquisition
|
||||
* resets frames caught in receiver, starts receiver, starts detector,
|
||||
* blocks till detector finished acquisition, stop receiver, increments file
|
||||
* index, loops for measurements, calls required call backs.
|
||||
* @returns OK or FAIL depending on if it already started
|
||||
*/
|
||||
int acquire();
|
||||
|
||||
/**
|
||||
* Combines data from all readouts and gives it to the gui
|
||||
* or just gives progress of acquisition by polling receivers
|
||||
*/
|
||||
void processData();
|
||||
|
||||
/**
|
||||
* Convert raw file
|
||||
* @param fname name of pof file
|
||||
* @param fpgasrc pointer in memory to read pof to
|
||||
* @returns file size
|
||||
*/
|
||||
std::vector<char> readPofFile(const std::string &fname);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Creates/open shared memory, initializes detector structure and members
|
||||
* Called by constructor/ set hostname / read config file
|
||||
* @param verify true to verify if shared memory version matches existing
|
||||
* one
|
||||
* @param update true to update last user pid, date etc
|
||||
*/
|
||||
void setupMultiDetector(bool verify = true, bool update = true);
|
||||
|
||||
/**
|
||||
* Creates shm and initializes shm structure OR
|
||||
* Open shm and maps to structure
|
||||
* @param verify true to verify if shm size matches existing one
|
||||
* @param update true to update last user pid, date etc
|
||||
*/
|
||||
void initSharedMemory(bool verify = true);
|
||||
|
||||
/** Initialize detector structure for the shared memory just created */
|
||||
void initializeDetectorStructure();
|
||||
|
||||
/** Initialize members (eg. slsDetectors from shm, zmqsockets)
|
||||
* @param verify true to verify if shm size matches existing one
|
||||
*/
|
||||
void initializeMembers(bool verify = true);
|
||||
|
||||
/** Update in shm */
|
||||
void updateUserdetails();
|
||||
|
||||
bool isAcquireReady();
|
||||
|
||||
/** Execute command in terminal and return result */
|
||||
std::string exec(const char *cmd);
|
||||
|
||||
void addSlsDetector(const std::string &hostname);
|
||||
|
||||
void updateDetectorSize();
|
||||
|
||||
/**
|
||||
* Create Receiving Data Sockets
|
||||
* @param destroy is true to destroy all the sockets
|
||||
* @returns OK or FAIL
|
||||
*/
|
||||
int createReceivingDataSockets(const bool destroy = false);
|
||||
|
||||
/**
|
||||
* Reads frames from receiver through a constant socket
|
||||
* Called during acquire() when call back registered or when using gui
|
||||
*/
|
||||
void readFrameFromReceiver();
|
||||
|
||||
/**
|
||||
* add gap pixels to the image (only for Eiger in 4 bit mode)
|
||||
* @param image pointer to image without gap pixels
|
||||
* @param gpImage poiner to image with gap pixels, if NULL, allocated
|
||||
* inside function
|
||||
* quadEnable quad enabled
|
||||
* @returns number of data bytes of image with gap pixels
|
||||
*/
|
||||
int processImageWithGapPixels(char *image, char *&gpImage, bool quadEnable);
|
||||
|
||||
double setTotalProgress();
|
||||
|
||||
double getCurrentProgress();
|
||||
|
||||
void incrementProgress();
|
||||
|
||||
void setCurrentProgress(int64_t i = 0);
|
||||
|
||||
void startProcessingThread();
|
||||
|
||||
/**
|
||||
* Check if processing thread is ready to join main thread
|
||||
* @returns true if ready, else false
|
||||
*/
|
||||
bool getJoinThreadFlag() const;
|
||||
|
||||
/**
|
||||
* Main thread sets if the processing thread should join it
|
||||
* @param v true if it should join, else false
|
||||
*/
|
||||
void setJoinThreadFlag(bool value);
|
||||
|
||||
/**
|
||||
* Listen to key event to stop acquiring
|
||||
* when using acquire command
|
||||
*/
|
||||
int kbhit();
|
||||
|
||||
/**
|
||||
* Convert a double holding time in seconds to an int64_t with nano seconds
|
||||
* Used for conversion when sending time to detector
|
||||
* @param t time in seconds
|
||||
* @returns time in nano seconds
|
||||
*/
|
||||
int64_t secondsToNanoSeconds(double t);
|
||||
|
||||
/** Multi detector Id */
|
||||
const int multiId{0};
|
||||
|
||||
/** Shared Memory object */
|
||||
sls::SharedMemory<sharedMultiSlsDetector> multi_shm{0, -1};
|
||||
|
||||
/** pointers to the slsDetector structures */
|
||||
std::vector<std::unique_ptr<slsDetector>> detectors;
|
||||
|
||||
/** 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;
|
||||
|
||||
/** semaphore to let postprocessing thread continue for next
|
||||
* scan/measurement */
|
||||
sem_t sem_newRTAcquisition;
|
||||
|
||||
/** semaphore to let main thread know it got all the dummy packets (also
|
||||
* from ext. process) */
|
||||
sem_t sem_endRTAcquisition;
|
||||
|
||||
/** Total number of frames/images for next acquisition */
|
||||
double totalProgress{0};
|
||||
|
||||
/** Current progress or frames/images processed in current acquisition */
|
||||
double progressIndex{0};
|
||||
|
||||
/** mutex to synchronize main and data processing threads */
|
||||
mutable std::mutex mp;
|
||||
|
||||
/** sets when the acquisition is finished */
|
||||
bool jointhread{false};
|
||||
|
||||
/** the data processing thread */
|
||||
// pthread_t dataProcessingThread;
|
||||
std::thread dataProcessingThread;
|
||||
|
||||
/** detector data packed for the gui */
|
||||
detectorData *thisData{nullptr};
|
||||
|
||||
void (*acquisition_finished)(double, int, void *){nullptr};
|
||||
void *acqFinished_p{nullptr};
|
||||
|
||||
void (*dataReady)(detectorData *, uint64_t, uint32_t, void *){nullptr};
|
||||
void *pCallbackArg{nullptr};
|
||||
};
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user