mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-16 06:47:14 +02:00
Merge branch 'refactor' of github.com:slsdetectorgroup/slsDetectorPackage into refactor
This commit is contained in:
@ -9,9 +9,9 @@ option (USE_GUI "GUI" OFF)
|
|||||||
|
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.0)
|
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.0)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++98 -Wno-misleading-indentation")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11 -Wno-misleading-indentation")
|
||||||
else ()
|
else ()
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++98")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
find_package(Qt4)
|
find_package(Qt4)
|
||||||
@ -46,6 +46,9 @@ if (USE_GUI)
|
|||||||
endif()
|
endif()
|
||||||
endif (USE_GUI)
|
endif (USE_GUI)
|
||||||
|
|
||||||
|
if (USE_SUPPORT_LIB)
|
||||||
|
add_subdirectory(slsSupportLib)
|
||||||
|
endif(USE_SUPPORT_LIB)
|
||||||
|
|
||||||
if (CALIBRATE)
|
if (CALIBRATE)
|
||||||
if (DEFINED ENV{ROOTSYS})
|
if (DEFINED ENV{ROOTSYS})
|
||||||
|
13050
catch/catch.hpp
Normal file
13050
catch/catch.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,10 @@
|
|||||||
#include <sys/shm.h>
|
#include <sys/shm.h>
|
||||||
//#include <time.h> //clock()
|
//#include <time.h> //clock()
|
||||||
|
|
||||||
|
#include "container_utils.h"
|
||||||
|
#include <future>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
multiSlsDetector::multiSlsDetector(int id, bool verify, bool update)
|
multiSlsDetector::multiSlsDetector(int id, bool verify, bool update)
|
||||||
: slsDetectorUtils(),
|
: slsDetectorUtils(),
|
||||||
@ -87,6 +91,33 @@ void multiSlsDetector::setupMultiDetector(bool verify, bool update) {
|
|||||||
updateUserdetails();
|
updateUserdetails();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <typename RT, typename... CT>
|
||||||
|
std::vector<RT> multiSlsDetector::serialCall(RT (slsDetector::*somefunc)(CT...), CT... Args)
|
||||||
|
{
|
||||||
|
std::vector<RT> result;
|
||||||
|
for (size_t det_id = 0; det_id < thisMultiDetector->numberOfDetectors; ++det_id) {
|
||||||
|
result.push_back(((*this)[det_id]->*somefunc)(Args...));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename RT, typename... CT>
|
||||||
|
std::vector<RT> multiSlsDetector::parallelCall(RT (slsDetector::*somefunc)(CT...), CT... Args)
|
||||||
|
{
|
||||||
|
std::vector<std::future<RT>> futures;
|
||||||
|
for (size_t det_id = 0; det_id < thisMultiDetector->numberOfDetectors; ++det_id) {
|
||||||
|
futures.push_back(std::async(somefunc, (*this)[det_id], Args...));
|
||||||
|
}
|
||||||
|
std::vector<RT> result;
|
||||||
|
for (auto& i : futures)
|
||||||
|
result.push_back(i.get());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string multiSlsDetector::concatResultOrPos(std::string (slsDetector::*somefunc)(int), int pos) {
|
std::string multiSlsDetector::concatResultOrPos(std::string (slsDetector::*somefunc)(int), int pos) {
|
||||||
if (pos >= 0 && pos < (int)detectors.size()) {
|
if (pos >= 0 && pos < (int)detectors.size()) {
|
||||||
return (detectors[pos]->*somefunc)(pos);
|
return (detectors[pos]->*somefunc)(pos);
|
||||||
@ -99,209 +130,6 @@ std::string multiSlsDetector::concatResultOrPos(std::string (slsDetector::*somef
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T multiSlsDetector::callDetectorMember(T (slsDetector::*somefunc)())
|
|
||||||
{
|
|
||||||
//(Erik) to handle enums, probably a bad idea but follow previous code
|
|
||||||
T defaultValue = static_cast<T>(-1);
|
|
||||||
std::vector<T> values(detectors.size(), defaultValue);
|
|
||||||
for (unsigned int idet = 0; idet < detectors.size(); ++idet) {
|
|
||||||
values[idet] = (detectors[idet]->*somefunc)();
|
|
||||||
if (detectors[idet]->getErrorMask())
|
|
||||||
setErrorMask(getErrorMask() | (1 << idet));
|
|
||||||
}
|
|
||||||
return minusOneIfDifferent(values);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string multiSlsDetector::callDetectorMember(std::string (slsDetector::*somefunc)()) {
|
|
||||||
std::string concatenatedValue, firstValue;
|
|
||||||
bool valueNotSame = false;
|
|
||||||
|
|
||||||
for (unsigned int idet = 0; idet < detectors.size(); ++idet) {
|
|
||||||
std::string thisValue = (detectors[idet]->*somefunc)();
|
|
||||||
|
|
||||||
if (detectors[idet]->getErrorMask())
|
|
||||||
setErrorMask(getErrorMask() | (1 << idet));
|
|
||||||
|
|
||||||
if (firstValue.empty()) {
|
|
||||||
concatenatedValue = thisValue;
|
|
||||||
firstValue = thisValue;
|
|
||||||
} else {
|
|
||||||
concatenatedValue += "+" + thisValue;
|
|
||||||
}
|
|
||||||
if (firstValue != thisValue)
|
|
||||||
valueNotSame = true;
|
|
||||||
}
|
|
||||||
if (valueNotSame)
|
|
||||||
return concatenatedValue;
|
|
||||||
else
|
|
||||||
return firstValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string multiSlsDetector::callDetectorMember(std::string (slsDetector::*somefunc)(std::string),
|
|
||||||
std::string s0) {
|
|
||||||
std::vector<std::string> return_values(detectors.size(), "");
|
|
||||||
for (unsigned int idet = 0; idet < detectors.size(); ++idet) {
|
|
||||||
return_values[idet] = (detectors[idet]->*somefunc)(s0);
|
|
||||||
if (detectors[idet]->getErrorMask())
|
|
||||||
setErrorMask(getErrorMask() | (1 << idet));
|
|
||||||
}
|
|
||||||
return concatenateIfDifferent(return_values);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename V>
|
|
||||||
T multiSlsDetector::callDetectorMember(T (slsDetector::*somefunc)(V), V value) {
|
|
||||||
//(Erik) to handle enums, probably a bad idea but follow previous code
|
|
||||||
T defaultValue = static_cast<T>(-1);
|
|
||||||
std::vector<T> values(detectors.size(), defaultValue);
|
|
||||||
for (unsigned int idet = 0; idet < detectors.size(); ++idet) {
|
|
||||||
values[idet] = (detectors[idet]->*somefunc)(value);
|
|
||||||
if (detectors[idet]->getErrorMask())
|
|
||||||
setErrorMask(getErrorMask() | (1 << idet));
|
|
||||||
}
|
|
||||||
return minusOneIfDifferent(values);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename P1, typename P2>
|
|
||||||
T multiSlsDetector::callDetectorMember(T (slsDetector::*somefunc)(P1, P2),
|
|
||||||
P1 par1, P2 par2) {
|
|
||||||
//(Erik) to handle enums, probably a bad idea but follow previous code
|
|
||||||
T defaultValue = static_cast<T>(-1);
|
|
||||||
std::vector<T> values(detectors.size(), defaultValue);
|
|
||||||
for (unsigned int idet = 0; idet < detectors.size(); ++idet) {
|
|
||||||
values[idet] = (detectors[idet]->*somefunc)(par1, par2);
|
|
||||||
if (detectors[idet]->getErrorMask())
|
|
||||||
setErrorMask(getErrorMask() | (1 << idet));
|
|
||||||
}
|
|
||||||
return minusOneIfDifferent(values);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T multiSlsDetector::parallelCallDetectorMember(T (slsDetector::*somefunc)()) {
|
|
||||||
if (!threadpool) {
|
|
||||||
std::cout << "Error in creating threadpool. Exiting" << std::endl;
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
std::vector<T> return_values(detectors.size(), -1);
|
|
||||||
for (unsigned int idet = 0; idet < detectors.size(); ++idet) {
|
|
||||||
Task* task = new Task(new func0_t<T>(somefunc,
|
|
||||||
detectors[idet], &return_values[idet]));
|
|
||||||
threadpool->add_task(task);
|
|
||||||
}
|
|
||||||
threadpool->startExecuting();
|
|
||||||
threadpool->wait_for_tasks_to_complete();
|
|
||||||
return minusOneIfDifferent(return_values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename P1>
|
|
||||||
T multiSlsDetector::parallelCallDetectorMember(T (slsDetector::*somefunc)(P1),
|
|
||||||
P1 value) {
|
|
||||||
if (!threadpool) {
|
|
||||||
std::cout << "Error in creating threadpool. Exiting" << std::endl;
|
|
||||||
return (T)-1;
|
|
||||||
} else {
|
|
||||||
std::vector<T> return_values(detectors.size(), (T)-1);
|
|
||||||
for (unsigned int idet = 0; idet < detectors.size(); ++idet) {
|
|
||||||
Task* task = new Task(new func1_t<T, P1>(somefunc,
|
|
||||||
detectors[idet], value, &return_values[idet]));
|
|
||||||
threadpool->add_task(task);
|
|
||||||
}
|
|
||||||
threadpool->startExecuting();
|
|
||||||
threadpool->wait_for_tasks_to_complete();
|
|
||||||
return minusOneIfDifferent(return_values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename P1, typename P2>
|
|
||||||
T multiSlsDetector::parallelCallDetectorMember(T (slsDetector::*somefunc)(P1, P2),
|
|
||||||
P1 par1, P2 par2) {
|
|
||||||
if (!threadpool) {
|
|
||||||
std::cout << "Error in creating threadpool. Exiting" << std::endl;
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
std::vector<T> return_values(detectors.size(), -1);
|
|
||||||
for (unsigned int idet = 0; idet < detectors.size(); ++idet) {
|
|
||||||
Task* task = new Task(new func2_t<T, P1, P2>(somefunc,
|
|
||||||
detectors[idet], par1, par2, &return_values[idet]));
|
|
||||||
threadpool->add_task(task);
|
|
||||||
}
|
|
||||||
threadpool->startExecuting();
|
|
||||||
threadpool->wait_for_tasks_to_complete();
|
|
||||||
return minusOneIfDifferent(return_values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int multiSlsDetector::parallelCallDetectorMember(int (slsDetector::*somefunc)(int, int, int),
|
|
||||||
int v0, int v1, int v2) {
|
|
||||||
if (!threadpool) {
|
|
||||||
std::cout << "Error in creating threadpool. Exiting" << std::endl;
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
std::vector<int> return_values(detectors.size(), -1);
|
|
||||||
for (unsigned int idet = 0; idet < detectors.size(); ++idet) {
|
|
||||||
Task* task = new Task(new func3_t<int, int, int, int>(somefunc,
|
|
||||||
detectors[idet], v0, v1, v2, &return_values[idet]));
|
|
||||||
threadpool->add_task(task);
|
|
||||||
}
|
|
||||||
threadpool->startExecuting();
|
|
||||||
threadpool->wait_for_tasks_to_complete();
|
|
||||||
return minusOneIfDifferent(return_values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string multiSlsDetector::parallelCallDetectorMember(std::string (slsDetector::*somefunc)(std::string),
|
|
||||||
std::string s0) {
|
|
||||||
if (!threadpool) {
|
|
||||||
std::cout << "Error in creating threadpool. Exiting" << std::endl;
|
|
||||||
return "";
|
|
||||||
} else {
|
|
||||||
std::vector<std::string> return_values(detectors.size(), "");
|
|
||||||
for (unsigned int idet = 0; idet < detectors.size(); ++idet) {
|
|
||||||
Task* task = new Task(new func1_t<std::string, std::string>(somefunc,
|
|
||||||
detectors[idet], s0, &return_values[idet]));
|
|
||||||
threadpool->add_task(task);
|
|
||||||
}
|
|
||||||
threadpool->startExecuting();
|
|
||||||
threadpool->wait_for_tasks_to_complete();
|
|
||||||
|
|
||||||
return concatenateIfDifferent(return_values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T multiSlsDetector::minusOneIfDifferent(const std::vector<T>& return_values) {
|
|
||||||
T ret = static_cast<T>(-100);
|
|
||||||
for (unsigned int idet = 0; idet < detectors.size(); ++idet) {
|
|
||||||
if (ret == static_cast<T>(-100))
|
|
||||||
ret = return_values[idet];
|
|
||||||
else if (ret != return_values[idet])
|
|
||||||
ret = static_cast<T>(-1);
|
|
||||||
if (detectors[idet]->getErrorMask())
|
|
||||||
setErrorMask(getErrorMask() | (1 << idet));
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string multiSlsDetector::concatenateIfDifferent(const std::vector<std::string>& return_values) {
|
|
||||||
std::string concatenatedValue, firstValue;
|
|
||||||
bool valueNotSame = false;
|
|
||||||
|
|
||||||
for (unsigned int idet = 0; idet < detectors.size(); ++idet) {
|
|
||||||
if (firstValue.empty()) {
|
|
||||||
concatenatedValue = return_values[idet];
|
|
||||||
firstValue = return_values[idet];
|
|
||||||
} else {
|
|
||||||
concatenatedValue += "+" + return_values[idet];
|
|
||||||
}
|
|
||||||
if (firstValue != return_values[idet])
|
|
||||||
valueNotSame = true;
|
|
||||||
}
|
|
||||||
if (valueNotSame)
|
|
||||||
return concatenatedValue;
|
|
||||||
else
|
|
||||||
return firstValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int multiSlsDetector::decodeNChannel(int offsetX, int offsetY, int& channelX, int& channelY) {
|
int multiSlsDetector::decodeNChannel(int offsetX, int offsetY, int& channelX, int& channelY) {
|
||||||
channelX = -1;
|
channelX = -1;
|
||||||
@ -445,19 +273,10 @@ bool multiSlsDetector::isAcquireReady() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int multiSlsDetector::checkVersionCompatibility(portType t, int detPos) {
|
int multiSlsDetector::checkVersionCompatibility(portType t, int detPos) {
|
||||||
|
|
||||||
// single
|
// single
|
||||||
if (detPos >= 0) {
|
if (detPos >= 0) {
|
||||||
|
return = detectors[detPos]->checkVersionCompatibility(t);
|
||||||
if(isDetectorIndexOutOfBounds(detPos))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
int ret = detectors[detPos]->checkVersionCompatibility(t);
|
|
||||||
if (detectors[detPos]->getErrorMask())
|
|
||||||
setErrorMask(getErrorMask() | (1 << detPos));
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// multi
|
// multi
|
||||||
return parallelCallDetectorMember(&slsDetector::checkVersionCompatibility, t);
|
return parallelCallDetectorMember(&slsDetector::checkVersionCompatibility, t);
|
||||||
}
|
}
|
||||||
@ -779,7 +598,8 @@ void multiSlsDetector::setHostname(const char* name) {
|
|||||||
|
|
||||||
|
|
||||||
std::string multiSlsDetector::getHostname(int pos) {
|
std::string multiSlsDetector::getHostname(int pos) {
|
||||||
return concatResultOrPos(&slsDetector::getHostname, pos);
|
auto r = parallelCall(&slsDetector::getHostname, pos);
|
||||||
|
return sls::concatenateIfDifferent(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
void multiSlsDetector::addMultipleDetectors(const char* name) {
|
void multiSlsDetector::addMultipleDetectors(const char* name) {
|
||||||
@ -855,10 +675,15 @@ slsDetectorDefs::detectorType multiSlsDetector::getDetectorsType(int pos) {
|
|||||||
|
|
||||||
|
|
||||||
std::string multiSlsDetector::sgetDetectorsType(int pos) {
|
std::string multiSlsDetector::sgetDetectorsType(int pos) {
|
||||||
return concatResultOrPos(&slsDetector::sgetDetectorsType, pos);
|
if (pos >= 0) {
|
||||||
|
return detectors[pos]->sgetDetectorsType(pos);
|
||||||
|
} else {
|
||||||
|
auto r = parallelCall(&slsDetector::sgetDetectorsType, pos);
|
||||||
|
return sls::concatenateIfDifferent(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::string multiSlsDetector::getDetectorType() {
|
std::string multiSlsDetector::getDetectorType() {
|
||||||
return sgetDetectorsType();
|
return sgetDetectorsType();
|
||||||
}
|
}
|
||||||
@ -1092,8 +917,10 @@ void multiSlsDetector::updateOffsets() {
|
|||||||
|
|
||||||
|
|
||||||
int multiSlsDetector::setOnline(int off) {
|
int multiSlsDetector::setOnline(int off) {
|
||||||
if (off != GET_ONLINE_FLAG)
|
if (off != GET_ONLINE_FLAG) {
|
||||||
thisMultiDetector->onlineFlag = parallelCallDetectorMember(&slsDetector::setOnline, off);
|
auto r = parallelCall(&slsDetector::setOnline, off);
|
||||||
|
thisMultiDetector->onlineFlag = sls::minusOneIfDifferent(r);
|
||||||
|
}
|
||||||
return thisMultiDetector->onlineFlag;
|
return thisMultiDetector->onlineFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1122,13 +949,8 @@ std::string multiSlsDetector::getLastClientIP() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int multiSlsDetector::exitServer() {
|
int multiSlsDetector::exitServer() {
|
||||||
int ival = FAIL, iv;
|
auto r = parallelCall(&slsDetector::exitServer);
|
||||||
for (unsigned int idet = 0; idet < detectors.size(); ++idet) {
|
return sls::allEqualTo(r, static_cast<int>(OK)) ? OK : FAIL;
|
||||||
iv = detectors[idet]->exitServer();
|
|
||||||
if (iv == OK)
|
|
||||||
ival = iv;
|
|
||||||
}
|
|
||||||
return ival;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int multiSlsDetector::readConfigurationFile(std::string const fname) {
|
int multiSlsDetector::readConfigurationFile(std::string const fname) {
|
||||||
@ -1489,7 +1311,8 @@ std::string multiSlsDetector::setSettingsDir(std::string s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string multiSlsDetector::getCalDir() {
|
std::string multiSlsDetector::getCalDir() {
|
||||||
return callDetectorMember(&slsDetector::getCalDir);
|
auto r = parallelCall(&slsDetector::getCalDir);
|
||||||
|
return sls::concatenateIfDifferent(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string multiSlsDetector::setCalDir(std::string s) {
|
std::string multiSlsDetector::setCalDir(std::string s) {
|
||||||
|
@ -149,6 +149,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setupMultiDetector(bool verify = true, bool update = true);
|
void setupMultiDetector(bool verify = true, bool update = true);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <typename RT, typename... CT>
|
||||||
|
std::vector<RT> serialCall(RT (slsDetector::*somefunc)(CT...), CT... Args);
|
||||||
|
|
||||||
|
template <typename RT, typename... CT>
|
||||||
|
std::vector<RT> parallelCall(RT (slsDetector::*somefunc)(CT...), CT... Args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specific position, then provide result with that detector at position pos
|
* If specific position, then provide result with that detector at position pos
|
||||||
* else concatenate the result of all detectors
|
* else concatenate the result of all detectors
|
||||||
@ -158,121 +167,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
std::string concatResultOrPos(std::string (slsDetector::*somefunc)(int), int pos);
|
std::string concatResultOrPos(std::string (slsDetector::*somefunc)(int), int pos);
|
||||||
|
|
||||||
/**
|
|
||||||
* Loop serially through all the detectors in calling a particular method
|
|
||||||
* @param somefunc function pointer
|
|
||||||
* @returns -1 if values are different, otherwise result in calling method
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
T callDetectorMember(T (slsDetector::*somefunc)());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loop serially through all the detectors in calling a particular method
|
|
||||||
* with string as return
|
|
||||||
* @param somefunc function pointer
|
|
||||||
* @returns concatenated string of results ifdifferent, otherwise result in
|
|
||||||
* calling method
|
|
||||||
*/
|
|
||||||
std::string callDetectorMember(std::string(slsDetector::*somefunc)());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loop serially through all the detectors in calling a particular method
|
|
||||||
* with string argument and string return
|
|
||||||
* @param somefunc function pointer
|
|
||||||
* @param s0 argument for calling method
|
|
||||||
* @returns concatenated result if values are different, otherwise result in calling method
|
|
||||||
*/
|
|
||||||
std::string callDetectorMember(std::string (slsDetector::*somefunc)(std::string),
|
|
||||||
std::string s0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loop serially through all the detectors in calling a particular method
|
|
||||||
* with an extra argument
|
|
||||||
* @param somefunc function pointer
|
|
||||||
* @param value argument for calling method
|
|
||||||
* @returns -1 if values are different, otherwise result in calling method
|
|
||||||
*/
|
|
||||||
template<typename T, typename V>
|
|
||||||
T callDetectorMember(T (slsDetector::*somefunc)(V), V value);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loop serially through all the detectors in calling a particular method
|
|
||||||
* with two extra arguments
|
|
||||||
* @param somefunc function pointer
|
|
||||||
* @param par1 argument for calling method
|
|
||||||
* @param par2 second argument for calling method
|
|
||||||
* @returns -1 if values are different, otherwise result in calling method
|
|
||||||
*/
|
|
||||||
template<typename T, typename P1, typename P2>
|
|
||||||
T callDetectorMember(T (slsDetector::*somefunc)(P1, P2), P1 par1, P2 par2);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parallel calls to all the detectors in calling a particular method
|
|
||||||
* @param somefunc function pointer
|
|
||||||
* @returns -1 if values are different, otherwise result in calling method
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
T parallelCallDetectorMember(T (slsDetector::*somefunc)());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parallel calls to all the detectors in calling a particular method
|
|
||||||
* with an extra argument
|
|
||||||
* @param somefunc function pointer
|
|
||||||
* @param value argument for calling method
|
|
||||||
* @returns -1 if values are different, otherwise result in calling method
|
|
||||||
*/
|
|
||||||
template<typename T, typename P1>
|
|
||||||
T parallelCallDetectorMember(T (slsDetector::*somefunc)(P1), P1 value);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parallel calls to all the detectors in calling a particular method
|
|
||||||
* with two extra arguments
|
|
||||||
* @param somefunc function pointer
|
|
||||||
* @param par1 argument for calling method
|
|
||||||
* @param par2 second argument for calling method
|
|
||||||
* @returns -1 if values are different, otherwise result in calling method
|
|
||||||
*/
|
|
||||||
template<typename T, typename P1, typename P2>
|
|
||||||
T parallelCallDetectorMember(T (slsDetector::*somefunc)(P1, P2), P1 par1, P2 par2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parallel calls to all the detectors in calling a particular method
|
|
||||||
* with three int arguments
|
|
||||||
* @param somefunc function pointer
|
|
||||||
* @param v0 argument for calling method
|
|
||||||
* @param v1 second argument for calling method
|
|
||||||
* @param v2 third argument for calling method
|
|
||||||
* @returns -1 if values are different, otherwise result in calling method
|
|
||||||
*/
|
|
||||||
int parallelCallDetectorMember(int (slsDetector::*somefunc)(int, int, int),
|
|
||||||
int v0, int v1, int v2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parallel calls to all the detectors in calling a particular method
|
|
||||||
* with string argument and string return
|
|
||||||
* @param somefunc function pointer
|
|
||||||
* @param s0 argument for calling method
|
|
||||||
* @returns concatenated result if values are different, otherwise result in calling method
|
|
||||||
*/
|
|
||||||
std::string parallelCallDetectorMember(std::string (slsDetector::*somefunc)(std::string),
|
|
||||||
std::string s0);
|
|
||||||
/**
|
|
||||||
* Loop serially through all results and
|
|
||||||
* return a value if they are all same, else return -1
|
|
||||||
* @param return_values vector of results
|
|
||||||
* @returns -1 if values are different, otherwise result
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
T minusOneIfDifferent(const std::vector<T>&);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loop serially through all results and
|
|
||||||
* return a value if they are all same, else concatenate them
|
|
||||||
* @param return_values vector of results
|
|
||||||
* @returns concatenated result if values are different, otherwise result
|
|
||||||
*/
|
|
||||||
std::string concatenateIfDifferent(const std::vector<std::string>& return_values);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes which detector and the corresponding channel numbers for it
|
* Decodes which detector and the corresponding channel numbers for it
|
||||||
|
54
slsSupportLib/CMakeLists.txt
Normal file
54
slsSupportLib/CMakeLists.txt
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
MESSAGE( STATUS "CMAKE_CURRENT_SOURCE_DIR: " ${CMAKE_CURRENT_SOURCE_DIR} )
|
||||||
|
MESSAGE( STATUS "PROJECT_SOURCE_DIR: " ${PROJECT_SOURCE_DIR} )
|
||||||
|
|
||||||
|
# set(SOURCES
|
||||||
|
# slsDetectorClient.cpp
|
||||||
|
# )
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
include
|
||||||
|
tests
|
||||||
|
${PROJECT_SOURCE_DIR}/catch
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(USE_TESTS)
|
||||||
|
set(LOCAL_TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tests)
|
||||||
|
set(TEST_SOURCES
|
||||||
|
# ${BASE_TEST_DIR}/test-MultiDetectorCaller.cpp
|
||||||
|
${LOCAL_TEST_DIR}/test-container_utils.cpp
|
||||||
|
${LOCAL_TEST_DIR}/test.cpp
|
||||||
|
# PARENT_SCOPE
|
||||||
|
)
|
||||||
|
add_executable(t2 ${TEST_SOURCES})
|
||||||
|
set_target_properties(t2 PROPERTIES
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#option(USE_TESTS "Determines whether to build tests." OFF)
|
||||||
|
# if(USE_TESTS)
|
||||||
|
# # Prepare "Catch" library for other executables
|
||||||
|
# set(CATCH_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/catch)
|
||||||
|
# add_library(Catch INTERFACE)
|
||||||
|
# target_include_directories(Catch INTERFACE ${CATCH_INCLUDE_DIR})
|
||||||
|
|
||||||
|
# # Make test executable
|
||||||
|
# add_executable(tests ${BASE_TEST_SOURCES})
|
||||||
|
# target_link_libraries(tests Catch)
|
||||||
|
|
||||||
|
# set_target_properties(tests PROPERTIES
|
||||||
|
# RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
||||||
|
# )
|
||||||
|
|
||||||
|
# #enable_testing()
|
||||||
|
# #add_test(NAME CommandLineClient COMMAND tests)
|
||||||
|
|
||||||
|
# endif()
|
||||||
|
|
||||||
|
|
||||||
|
# install(TARGETS sls_client DESTINATION bin)
|
||||||
|
|
40
slsSupportLib/include/Timer.h
Normal file
40
slsSupportLib/include/Timer.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#ifndef TIMER_H
|
||||||
|
#define TIMER_H
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class Timer {
|
||||||
|
using clock = std::chrono::high_resolution_clock;
|
||||||
|
using time_point = std::chrono::time_point<clock>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Timer(std::string name = "0")
|
||||||
|
: t0(clock::now())
|
||||||
|
, name_(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
double elapsed_ms()
|
||||||
|
{
|
||||||
|
return std::chrono::duration<double, std::milli>(clock::now() - t0).count();
|
||||||
|
}
|
||||||
|
double elapsed_s()
|
||||||
|
{
|
||||||
|
return std::chrono::duration<double>(clock::now() - t0).count();
|
||||||
|
}
|
||||||
|
void print_elapsed()
|
||||||
|
{
|
||||||
|
std::cout << "Timer \"" << name_ << "\": Elapsed time " << elapsed_ms() << " ms\n";
|
||||||
|
}
|
||||||
|
void restart()
|
||||||
|
{
|
||||||
|
t0 = clock::now();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
time_point t0;
|
||||||
|
std::string name_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TIMER_H
|
126
slsSupportLib/include/container_utils.h
Normal file
126
slsSupportLib/include/container_utils.h
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
#ifndef CONTAINER_UTILS_H
|
||||||
|
#define CONTAINER_UTILS_H
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <numeric>
|
||||||
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <vector>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace sls {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool allEqual(const std::vector<T>& container)
|
||||||
|
{
|
||||||
|
if (container.empty())
|
||||||
|
return false;
|
||||||
|
const auto& first = container[0];
|
||||||
|
return std::all_of(container.cbegin(), container.cend(),
|
||||||
|
[first](const T& element) { return element == first; });
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
typename std::enable_if<std::is_arithmetic<T>::value, bool>::type
|
||||||
|
allEqualWithTol(const std::vector<T>& container, const T tol)
|
||||||
|
{
|
||||||
|
if (container.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const auto& first = container[0];
|
||||||
|
return std::all_of(container.cbegin(), container.cend(),
|
||||||
|
[first, tol](const T& element) {
|
||||||
|
return (std::abs(element - first) < tol);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool allEqualTo(const std::vector<T>& container, const T value)
|
||||||
|
{
|
||||||
|
if (container.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return std::all_of(container.cbegin(), container.cend(),
|
||||||
|
[value](const T& element) { return element == value; });
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool allEqualToWithTol(const std::vector<T>& container, const T value,
|
||||||
|
const T tol)
|
||||||
|
{
|
||||||
|
if (container.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return std::all_of(container.cbegin(), container.cend(),
|
||||||
|
[value, tol](const T& element) {
|
||||||
|
return (std::abs(element - value) < tol);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool anyEqualTo(const std::vector<T>& container, const T value)
|
||||||
|
{
|
||||||
|
return std::any_of(container.cbegin(), container.cend(),
|
||||||
|
[value](const T& element) { return element == value; });
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool anyEqualToWithTol(const std::vector<T>& container, const T value,
|
||||||
|
const T tol)
|
||||||
|
{
|
||||||
|
return std::any_of(container.cbegin(), container.cend(),
|
||||||
|
[value, tol](const T& element) { return (std::abs(element - value) < tol); });
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
typename std::enable_if<std::is_arithmetic<T>::value, T>::type
|
||||||
|
sum(const std::vector<T>& container)
|
||||||
|
{
|
||||||
|
return std::accumulate(container.cbegin(), container.cend(), T{ 0 });
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T minusOneIfDifferent(const std::vector<T>& container)
|
||||||
|
{
|
||||||
|
if (allEqual(container)) {
|
||||||
|
return container.front();
|
||||||
|
} else {
|
||||||
|
return static_cast<T>(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO!(Erik)Should try to move away from using this in the slsDetectorPackage
|
||||||
|
std::string concatenateIfDifferent(std::vector<std::string> container)
|
||||||
|
{
|
||||||
|
if (allEqual(container)) {
|
||||||
|
return container.front();
|
||||||
|
} else {
|
||||||
|
std::string result;
|
||||||
|
for (const auto& s : container)
|
||||||
|
result += s + "+";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> split(const std::string& strToSplit, char delimeter)
|
||||||
|
{
|
||||||
|
std::stringstream ss(strToSplit);
|
||||||
|
std::string item;
|
||||||
|
std::vector<std::string> splittedStrings;
|
||||||
|
while (std::getline(ss, item, delimeter)) {
|
||||||
|
splittedStrings.push_back(item);
|
||||||
|
}
|
||||||
|
return splittedStrings;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string concatenateNonEmptyStrings(const std::vector<std::string>& vec){
|
||||||
|
std::string ret;
|
||||||
|
for (const auto& s : vec)
|
||||||
|
if (!s.empty())
|
||||||
|
ret += s + "+";
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace sls
|
||||||
|
|
||||||
|
#endif // CONTAINER_UTILS_H
|
161
slsSupportLib/tests/test-container_utils.cpp
Normal file
161
slsSupportLib/tests/test-container_utils.cpp
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
#include "catch.hpp"
|
||||||
|
#include "container_utils.h"
|
||||||
|
#include <exception>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using sls::allEqual;
|
||||||
|
using sls::allEqualTo;
|
||||||
|
using sls::anyEqualTo;
|
||||||
|
|
||||||
|
using sls::allEqualToWithTol;
|
||||||
|
using sls::allEqualWithTol;
|
||||||
|
using sls::anyEqualToWithTol;
|
||||||
|
|
||||||
|
using sls::sum;
|
||||||
|
|
||||||
|
TEST_CASE("Equality of an empty vector") {
|
||||||
|
std::vector<int> v;
|
||||||
|
REQUIRE(v.empty());
|
||||||
|
REQUIRE_FALSE(allEqual(v));
|
||||||
|
REQUIRE_FALSE(allEqualWithTol(v, 2));
|
||||||
|
REQUIRE_FALSE(allEqualTo(v, 5));
|
||||||
|
REQUIRE_FALSE(anyEqualTo(v, 5));
|
||||||
|
REQUIRE_FALSE(anyEqualToWithTol(v, 5, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Equality of a vector with one element") {
|
||||||
|
std::vector<int> v{5};
|
||||||
|
REQUIRE(v.size() == 1);
|
||||||
|
REQUIRE(allEqual(v));
|
||||||
|
REQUIRE(allEqualWithTol(v, 1));
|
||||||
|
REQUIRE(allEqualTo(v, 5));
|
||||||
|
REQUIRE(allEqualToWithTol(v, 5, 2));
|
||||||
|
REQUIRE(anyEqualTo(v, 5));
|
||||||
|
REQUIRE(anyEqualToWithTol(v, 5, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("A larger vector of the same elements") {
|
||||||
|
std::vector<int> v(101, 5);
|
||||||
|
REQUIRE(v.size() == 101);
|
||||||
|
REQUIRE(allEqual(v));
|
||||||
|
REQUIRE(allEqualWithTol(v, 1));
|
||||||
|
REQUIRE(allEqualTo(v, 5));
|
||||||
|
REQUIRE(anyEqualTo(v, 5));
|
||||||
|
|
||||||
|
SECTION(
|
||||||
|
"Push back another element to create a vector where not all are equal") {
|
||||||
|
v.push_back(7);
|
||||||
|
REQUIRE(v.size() == 102);
|
||||||
|
REQUIRE_FALSE(allEqual(v));
|
||||||
|
|
||||||
|
REQUIRE_FALSE(allEqualWithTol(v, 1));
|
||||||
|
REQUIRE(allEqualWithTol(v, 3));
|
||||||
|
|
||||||
|
REQUIRE_FALSE(allEqualTo(v, 5));
|
||||||
|
|
||||||
|
REQUIRE_FALSE(allEqualToWithTol(v, 5, 1));
|
||||||
|
REQUIRE(allEqualToWithTol(v, 5, 3));
|
||||||
|
REQUIRE(anyEqualTo(v, 5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("A vector of double with different values") {
|
||||||
|
std::vector<double> v{1.2, 2., 4.2, 4, 1.1};
|
||||||
|
|
||||||
|
REQUIRE(allEqual(v) == false);
|
||||||
|
REQUIRE(allEqualWithTol(v, 0.3) == false);
|
||||||
|
REQUIRE(allEqualWithTol(v, 3.2));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Sum of empty vector") {
|
||||||
|
std::vector<float> v;
|
||||||
|
REQUIRE(sls::sum(v) == Approx(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Sum of vector") {
|
||||||
|
std::vector<double> v{1.2, 2., 4.2, 4, 1.13};
|
||||||
|
REQUIRE(sls::sum(v) == Approx(12.53));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Minus one if different") {
|
||||||
|
std::vector<double> v;
|
||||||
|
REQUIRE(v.empty());
|
||||||
|
double d = -1;
|
||||||
|
REQUIRE(sls::minusOneIfDifferent(v) == d);
|
||||||
|
|
||||||
|
SECTION("single element") {
|
||||||
|
v.push_back(7.3);
|
||||||
|
REQUIRE(v.size() == 1);
|
||||||
|
REQUIRE(sls::minusOneIfDifferent(v) == Approx(7.3));
|
||||||
|
}
|
||||||
|
SECTION("different elements") {
|
||||||
|
v.push_back(7.3);
|
||||||
|
v.push_back(1.0);
|
||||||
|
v.push_back(62.1);
|
||||||
|
REQUIRE(sls::minusOneIfDifferent(v) == Approx(-1.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("minus one does not have side effects"){
|
||||||
|
std::vector<int> v{1,1,1};
|
||||||
|
int i = sls::minusOneIfDifferent(v);
|
||||||
|
REQUIRE(i==1);
|
||||||
|
i=5;
|
||||||
|
REQUIRE(v[0]==1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Concat") {
|
||||||
|
std::vector<std::string> v{"one", "one", "one"};
|
||||||
|
std::vector<std::string> v2{"one", "one", "one"};
|
||||||
|
auto r = sls::concatenateIfDifferent(v);
|
||||||
|
REQUIRE(r == std::string("one"));
|
||||||
|
r.clear();
|
||||||
|
|
||||||
|
// make sure we didn't modify the string
|
||||||
|
REQUIRE(v == v2);
|
||||||
|
|
||||||
|
SECTION("add a different value"){
|
||||||
|
v.push_back("two");
|
||||||
|
REQUIRE(v!=v2);
|
||||||
|
REQUIRE( sls::concatenateIfDifferent(v) == "one+one+one+two+");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("split a string with end delimiter"){
|
||||||
|
std::string s("abra+kadabra+");
|
||||||
|
auto r =sls::split(s, '+');
|
||||||
|
REQUIRE(r.size()==2);
|
||||||
|
REQUIRE(r[0]=="abra");
|
||||||
|
REQUIRE(r[1]=="kadabra");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("split a string without end delimiter"){
|
||||||
|
std::string s("abra+kadabra+filibom");
|
||||||
|
auto r =sls::split(s, '+');
|
||||||
|
REQUIRE(r.size()==3);
|
||||||
|
REQUIRE(r[0]=="abra");
|
||||||
|
REQUIRE(r[1]=="kadabra");
|
||||||
|
REQUIRE(r[2]=="filibom");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("concatenate non empty strings"){
|
||||||
|
std::vector<std::string> vec{"hej", "kalas", "", "foto"};
|
||||||
|
REQUIRE(vec.size()==4);
|
||||||
|
auto ret = sls::concatenateNonEmptyStrings(vec);
|
||||||
|
REQUIRE(ret == "hej+kalas+foto+");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("concatenate non empty strings with only emty"){
|
||||||
|
std::vector<std::string> vec{"", "", ""};
|
||||||
|
REQUIRE(vec.size()==3);
|
||||||
|
auto ret = sls::concatenateNonEmptyStrings(vec);
|
||||||
|
REQUIRE(ret.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("concatenate non empty strings with one element"){
|
||||||
|
std::vector<std::string> vec{"", "hej", "", "", ""};
|
||||||
|
REQUIRE(vec.size()==5);
|
||||||
|
auto ret = sls::concatenateNonEmptyStrings(vec);
|
||||||
|
REQUIRE(ret=="hej+");
|
||||||
|
}
|
3
slsSupportLib/tests/test.cpp
Normal file
3
slsSupportLib/tests/test.cpp
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
// tests-main.cpp
|
||||||
|
#define CATCH_CONFIG_MAIN
|
||||||
|
#include "catch.hpp"
|
Reference in New Issue
Block a user