New command line app and removing slsDetectorCommand (#69)

* WIP

* WIP

* WIP

* WIP

* config2 working

* removed slsDetectorCommand

* WIP

* added test file

* more tests
This commit is contained in:
Erik Fröjdh 2019-11-18 09:29:17 +01:00 committed by Dhanya Thattil
parent 6a27207875
commit fa2c842745
23 changed files with 5964 additions and 1451 deletions

View File

@ -26,7 +26,6 @@
#include "ctbAdcs.h" #include "ctbAdcs.h"
#include "ctbDefs.h" #include "ctbDefs.h"
#include "Detector.h" #include "Detector.h"
#include "slsDetectorCommand.h"
using namespace std; using namespace std;

View File

@ -59,48 +59,6 @@ void init_enums(py::module &m) {
slsDetectorDefs::fileFormat::NUM_FILE_FORMATS) slsDetectorDefs::fileFormat::NUM_FILE_FORMATS)
.export_values(); .export_values();
py::enum_<slsDetectorDefs::networkParameter>(Defs, "networkParameter")
.value("DETECTOR_MAC", slsDetectorDefs::networkParameter::DETECTOR_MAC)
.value("DETECTOR_IP", slsDetectorDefs::networkParameter::DETECTOR_IP)
.value("RECEIVER_HOSTNAME",
slsDetectorDefs::networkParameter::RECEIVER_HOSTNAME)
.value("RECEIVER_UDP_IP",
slsDetectorDefs::networkParameter::RECEIVER_UDP_IP)
.value("RECEIVER_UDP_PORT",
slsDetectorDefs::networkParameter::RECEIVER_UDP_PORT)
.value("RECEIVER_UDP_MAC",
slsDetectorDefs::networkParameter::RECEIVER_UDP_MAC)
.value("RECEIVER_UDP_PORT2",
slsDetectorDefs::networkParameter::RECEIVER_UDP_PORT2)
.value("DETECTOR_TXN_DELAY_LEFT",
slsDetectorDefs::networkParameter::DETECTOR_TXN_DELAY_LEFT)
.value("DETECTOR_TXN_DELAY_RIGHT",
slsDetectorDefs::networkParameter::DETECTOR_TXN_DELAY_RIGHT)
.value("DETECTOR_TXN_DELAY_FRAME",
slsDetectorDefs::networkParameter::DETECTOR_TXN_DELAY_FRAME)
.value("FLOW_CONTROL_10G",
slsDetectorDefs::networkParameter::FLOW_CONTROL_10G)
.value("FLOW_CONTROL_WR_PTR",
slsDetectorDefs::networkParameter::FLOW_CONTROL_WR_PTR)
.value("FLOW_CONTROL_RD_PTR",
slsDetectorDefs::networkParameter::FLOW_CONTROL_RD_PTR)
.value("RECEIVER_STREAMING_PORT",
slsDetectorDefs::networkParameter::RECEIVER_STREAMING_PORT)
.value("CLIENT_STREAMING_PORT",
slsDetectorDefs::networkParameter::CLIENT_STREAMING_PORT)
.value("RECEIVER_STREAMING_SRC_IP",
slsDetectorDefs::networkParameter::RECEIVER_STREAMING_SRC_IP)
.value("CLIENT_STREAMING_SRC_IP",
slsDetectorDefs::networkParameter::CLIENT_STREAMING_SRC_IP)
.value("ADDITIONAL_JSON_HEADER",
slsDetectorDefs::networkParameter::ADDITIONAL_JSON_HEADER)
.value("RECEIVER_UDP_SCKT_BUF_SIZE",
slsDetectorDefs::networkParameter::RECEIVER_UDP_SCKT_BUF_SIZE)
.value(
"RECEIVER_REAL_UDP_SCKT_BUF_SIZE",
slsDetectorDefs::networkParameter::RECEIVER_REAL_UDP_SCKT_BUF_SIZE)
.export_values();
py::enum_<slsDetectorDefs::dimension>(Defs, "dimension") py::enum_<slsDetectorDefs::dimension>(Defs, "dimension")
.value("X", slsDetectorDefs::dimension::X) .value("X", slsDetectorDefs::dimension::X)
.value("Y", slsDetectorDefs::dimension::Y) .value("Y", slsDetectorDefs::dimension::Y)
@ -150,32 +108,6 @@ void init_enums(py::module &m) {
.value("BURST_TRIGGER", slsDetectorDefs::timingMode::BURST_TRIGGER) .value("BURST_TRIGGER", slsDetectorDefs::timingMode::BURST_TRIGGER)
.export_values(); .export_values();
py::enum_<slsDetectorDefs::idMode>(Defs, "idMode")
.value("DETECTOR_SERIAL_NUMBER",
slsDetectorDefs::idMode::DETECTOR_SERIAL_NUMBER)
.value("DETECTOR_FIRMWARE_VERSION",
slsDetectorDefs::idMode::DETECTOR_FIRMWARE_VERSION)
.value("DETECTOR_SOFTWARE_VERSION",
slsDetectorDefs::idMode::DETECTOR_SOFTWARE_VERSION)
.value("THIS_SOFTWARE_VERSION",
slsDetectorDefs::idMode::THIS_SOFTWARE_VERSION)
.value("RECEIVER_VERSION", slsDetectorDefs::idMode::RECEIVER_VERSION)
.value("SOFTWARE_FIRMWARE_API_VERSION",
slsDetectorDefs::idMode::SOFTWARE_FIRMWARE_API_VERSION)
.value("CLIENT_SOFTWARE_API_VERSION",
slsDetectorDefs::idMode::CLIENT_SOFTWARE_API_VERSION)
.value("CLIENT_RECEIVER_API_VERSION",
slsDetectorDefs::idMode::CLIENT_RECEIVER_API_VERSION)
.export_values();
py::enum_<slsDetectorDefs::digitalTestMode>(Defs, "digitalTestMode")
.value("DETECTOR_FIRMWARE_TEST",
slsDetectorDefs::digitalTestMode::DETECTOR_FIRMWARE_TEST)
.value("DETECTOR_BUS_TEST",
slsDetectorDefs::digitalTestMode::DETECTOR_BUS_TEST)
.value("IMAGE_TEST", slsDetectorDefs::digitalTestMode::IMAGE_TEST)
.export_values();
py::enum_<slsDetectorDefs::dacIndex>(Defs, "dacIndex") py::enum_<slsDetectorDefs::dacIndex>(Defs, "dacIndex")
.value("THRESHOLD", slsDetectorDefs::dacIndex::THRESHOLD) .value("THRESHOLD", slsDetectorDefs::dacIndex::THRESHOLD)
.value("CALIBRATION_PULSE", .value("CALIBRATION_PULSE",

View File

@ -19,7 +19,7 @@ void init_experimental(py::module &m) {
.def(py::init<int>()) .def(py::init<int>())
// Configuration // Configuration
.def("freeSharedMemory", &Detector::freeSharedMemory) .def("freeSharedMemory", (void (Detector::*)()) &Detector::freeSharedMemory)
.def("loadConfig", &Detector::loadConfig) .def("loadConfig", &Detector::loadConfig)
.def("loadParameters", &Detector::loadParameters) .def("loadParameters", &Detector::loadParameters)
.def("setHostname", &Detector::setHostname) .def("setHostname", &Detector::setHostname)

View File

@ -1,8 +1,6 @@
set(SOURCES set(SOURCES
src/multiSlsDetector.cpp src/multiSlsDetector.cpp
src/multiSlsDetectorClient.cpp
src/slsDetectorUsers.cpp src/slsDetectorUsers.cpp
src/slsDetectorCommand.cpp
src/slsDetector.cpp src/slsDetector.cpp
src/Detector.cpp src/Detector.cpp
src/CmdProxy.cpp src/CmdProxy.cpp
@ -18,9 +16,9 @@ add_library(slsDetectorShared SHARED
) )
# Do we have link time optimization?
check_ipo_supported(RESULT result) check_ipo_supported(RESULT LTO_AVAILABLE)
if(result) if(LTO_AVAILABLE)
set_property(TARGET slsDetectorShared PROPERTY INTERPROCEDURAL_OPTIMIZATION True) set_property(TARGET slsDetectorShared PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
endif() endif()
@ -52,92 +50,41 @@ set_target_properties(slsDetectorShared PROPERTIES
PUBLIC_HEADER "${PUBLICHEADERS}" PUBLIC_HEADER "${PUBLICHEADERS}"
) )
# add_subdirectory(slsDetectorClient)
add_executable(sls_detector_get
src/sls_detector_client.cpp
)
target_link_libraries(sls_detector_get
slsProjectOptions
slsProjectWarnings
slsDetectorShared
slsSupportLib
pthread
${ZeroMQ_LIBRARIES}
rt
)
set_target_properties(sls_detector_get PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
COMPILE_DEFINITIONS GET=1
)
add_executable(sls_detector_put # Loop over list to generate command line binaries
src/sls_detector_client.cpp set(bin_names "sls_detector_put"
) "sls_detector_get"
target_link_libraries(sls_detector_put "sls_detector_acquire"
slsProjectOptions "sls_detector_help")
slsProjectWarnings set(cmd_name "PUT" "GET" "READOUT" "HELP")
list(LENGTH bin_names len1)
math(EXPR len2 "${len1} - 1")
foreach(val RANGE ${len2})
list(GET bin_names ${val} val1)
list(GET cmd_name ${val} val2)
message(STATUS "${val1} ${val2}")
add_executable(${val1} src/CmdLineApp.cpp)
target_link_libraries(${val1}
slsDetectorShared slsDetectorShared
pthread pthread
${ZeroMQ_LIBRARIES} ${ZeroMQ_LIBRARIES}
rt rt
) )
set_target_properties(sls_detector_put PROPERTIES set_target_properties(${val1} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
COMPILE_DEFINITIONS PUT=1 COMPILE_DEFINITIONS ${val2}=1
) )
if(LTO_AVAILABLE)
add_executable(sls_detector_acquire set_property(TARGET ${val1} PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
src/sls_detector_client.cpp endif()
) endforeach()
target_link_libraries(sls_detector_acquire
slsProjectOptions
slsProjectWarnings
slsDetectorShared
pthread
${ZeroMQ_LIBRARIES}
rt
)
set_target_properties(sls_detector_acquire PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
COMPILE_DEFINITIONS READOUT=1
)
add_executable(sls_detector_help
src/sls_detector_client.cpp
)
target_link_libraries(sls_detector_help
slsProjectOptions
slsProjectWarnings
slsDetectorShared
pthread
${ZeroMQ_LIBRARIES}
rt
)
set_target_properties(sls_detector_help PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
COMPILE_DEFINITIONS HELP=1
)
check_ipo_supported(RESULT result)
if(result)
set_property(TARGET sls_detector_help PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
set_property(TARGET sls_detector_get PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
set_property(TARGET sls_detector_put PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
set_property(TARGET sls_detector_acquire PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
endif()
install(TARGETS sls_detector_put sls_detector_get sls_detector_acquire sls_detector_help DESTINATION bin)
# if(DOXYGEN_FOUND) install(TARGETS ${bin_names} DESTINATION bin)
# add_custom_target(doc
# ${DOXYGEN_EXECUTABLE}
# ${CMAKE_CURRENT_SOURCE_DIR}/slsDetectorUsers.doxy
# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
# COMMENT "Generating API documentation with Doxygen" VERBATIM
# )
# endif()
if (SLS_USE_TESTS) if (SLS_USE_TESTS)
add_subdirectory(tests) add_subdirectory(tests)

View File

@ -417,12 +417,11 @@ class CmdProxy {
explicit CmdProxy(Detector *ptr) : det(ptr) {} explicit CmdProxy(Detector *ptr) : det(ptr) {}
std::string Call(const std::string &command, std::string Call(const std::string &command,
const std::vector<std::string> &arguments, int detector_id, 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);
bool ReplaceIfDepreciated(std::string &command); bool ReplaceIfDepreciated(std::string &command);
size_t GetFunctionMapSize() const noexcept { return functions.size(); }; size_t GetFunctionMapSize() const noexcept { return functions.size(); };
std::vector<std::string> GetAllCommands();
std::vector<std::string> GetProxyCommands(); std::vector<std::string> GetProxyCommands();
private: private:
@ -549,7 +548,8 @@ class CmdProxy {
FunctionMap functions{{"list", &CmdProxy::ListCommands}, FunctionMap functions{{"list", &CmdProxy::ListCommands},
/* configuration */ /* configuration */
//{"config", &CmdProxy::config}, {"config", &CmdProxy::config},
{"free2", &CmdProxy::free},
{"parameters", &CmdProxy::parameters}, {"parameters", &CmdProxy::parameters},
{"hostname", &CmdProxy::Hostname}, {"hostname", &CmdProxy::Hostname},
{"virtual", &CmdProxy::VirtualServer}, {"virtual", &CmdProxy::VirtualServer},
@ -565,6 +565,7 @@ class CmdProxy {
{"settings", &CmdProxy::settings}, {"settings", &CmdProxy::settings},
/* acquisition parameters */ /* acquisition parameters */
{"acquire", &CmdProxy::acquire},
{"frames", &CmdProxy::frames}, {"frames", &CmdProxy::frames},
{"triggers", &CmdProxy::triggers}, {"triggers", &CmdProxy::triggers},
{"exptime", &CmdProxy::exptime}, {"exptime", &CmdProxy::exptime},
@ -885,6 +886,8 @@ class CmdProxy {
/* Commands */ /* Commands */
std::string ListCommands(int action); std::string ListCommands(int action);
/* configuration */ /* configuration */
std::string free(int action);
// std::string config2(int action);
std::string Hostname(int action); std::string Hostname(int action);
std::string VirtualServer(int action); std::string VirtualServer(int action);
std::string FirmwareVersion(int action); std::string FirmwareVersion(int action);
@ -893,6 +896,7 @@ class CmdProxy {
std::string ClientVersion(int action); std::string ClientVersion(int action);
std::string DetectorSize(int action); std::string DetectorSize(int action);
/* acquisition parameters */ /* acquisition parameters */
std::string acquire(int action);
std::string Speed(int action); std::string Speed(int action);
std::string Adcphase(int action); std::string Adcphase(int action);
std::string ClockFrequency(int action); std::string ClockFrequency(int action);

View File

@ -13,6 +13,12 @@ using ns = std::chrono::nanoseconds;
class MacAddr; class MacAddr;
class IpAddr; 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);
/** /**
* \class Detector * \class Detector
*/ */
@ -73,6 +79,8 @@ class Detector {
/** Gets the total number of detectors */ /** Gets the total number of detectors */
int size() const; int size() const;
bool empty() const;
defs::xy getModuleGeometry() const; defs::xy getModuleGeometry() const;
Result<defs::xy> getModuleSize(Positions pos = {}) const; Result<defs::xy> getModuleSize(Positions pos = {}) const;

View File

@ -261,8 +261,6 @@ class multiSlsDetector : public virtual slsDetectorDefs {
* Sets maximum number of channels of all sls detectors */ * Sets maximum number of channels of all sls detectors */
void setNumberOfChannels(const slsDetectorDefs::xy c); void setNumberOfChannels(const slsDetectorDefs::xy c);
void readConfigurationFile(const std::string &fname);
/** /**
* Enable gap pixels, only for Eiger and for 8,16 and 32 bit mode. (Eiger) * 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 * 4 bit mode gap pixels only in gui call back
@ -278,8 +276,6 @@ class multiSlsDetector : public virtual slsDetectorDefs {
void savePattern(const std::string &fname); void savePattern(const std::string &fname);
void loadParameters(const std::string &fname);
/** /**
* register callback for accessing acquisition final data * register callback for accessing acquisition final data
* @param func function to be called at the end of the acquisition. * @param func function to be called at the end of the acquisition.

View File

@ -1,72 +0,0 @@
#ifndef SLS_DETECTOR_COMMAND_H
#define SLS_DETECTOR_COMMAND_H
#include "sls_detector_defs.h"
#include <vector>
class multiSlsDetector;
/** @short This class handles the command line I/Os, help etc. of the text clients */
class slsDetectorCommand : public virtual slsDetectorDefs {
public:
slsDetectorCommand(multiSlsDetector *det);
/*
* Executes a set of string arguments according to a given format.
* It is used to read/write configuration file, dump and retrieve detector
* settings and for the command line interface command parsing
* @param narg number of arguments
* @param args array of string arguments
* @param action can be PUT_ACTION or GET_ACTION(from text client even READOUT_ACTION for acquisition)
* @param detPos -1 for all detectors in multi detector list or position of a specific detector in list
*/
std::string executeLine(int narg, const char * const args[], int action, int detPos = -1);
std::vector<std::string> getAllCommands();
static std::string helpAcquire(int action);
static std::string helpConfiguration(int action);
private:
multiSlsDetector *myDet;
std::string cmdUnknown(int narg, const char * const args[], int action, int detPos = -1);
std::string cmdAcquire(int narg, const char * const args[], int action, int detPos = -1);
std::string cmdConfiguration(int narg, const char * const args[], int action, int detPos = -1);
int numberOfCommands;
std::string cmd;
typedef std::string (slsDetectorCommand::*MemFuncGetter)(int narg, const char * const args[], int action, int detPos);
struct FuncTable
{
std::string m_pFuncName;
MemFuncGetter m_pFuncPtr;
};
FuncTable descrToFuncMap[1000];
};
#endif

View File

@ -0,0 +1,74 @@
#include "CmdLineParser.h"
#include "CmdProxy.h"
#include "Detector.h"
#include "sls_detector_defs.h"
#include "versionAPI.h"
#include <cstring> //strcmp
#include <iostream>
int main(int argc, char *argv[]) {
// To genereate sepereate binaries for put, get, acquire and help
#ifdef PUT
int action = slsDetectorDefs::PUT_ACTION;
#endif
#ifdef GET
int action = slsDetectorDefs::GET_ACTION;
#endif
#ifdef READOUT
int action = slsDetectorDefs::READOUT_ACTION;
#endif
#ifdef HELP
int action = slsDetectorDefs::HELP_ACTION;
#endif
// Check for --version in the arguments
for (int i = 1; i < argc; ++i) {
if (!(strcmp(argv[i], "--version")) || !(strcmp(argv[i], "-v"))) {
int64_t tempval = APILIB;
std::cout << argv[0] << " " << GITBRANCH << " (0x" << std::hex
<< tempval << ")" << std::endl;
return 0;
}
}
sls::CmdLineParser parser;
parser.Parse(argc, argv);
// If we called sls_detector_acquire, add the acquire command
if (action == slsDetectorDefs::READOUT_ACTION)
parser.setCommand("acquire");
if (parser.isHelp())
action = slsDetectorDefs::HELP_ACTION;
// Free shared memory should work also without a detector
// if we have an option for verify in the detector constructor
// we could avoid this but clutter the code
if (parser.command() == "free" && action != slsDetectorDefs::HELP_ACTION) {
if (parser.detector_id() != -1)
std::cout << "Cannot free shared memory of sub-detector\n";
else
sls::freeSharedMemory(parser.multi_id());
return 0;
}
try {
//How big should this try block be?
sls::Detector det(parser.multi_id());
sls::CmdProxy proxy(&det);
auto cmd = proxy.Call(parser.command(), parser.arguments(),
parser.detector_id(), action);
// TODO! move this check into CmdProxy
if (!cmd.empty()) {
std::cout << cmd
<< " Unknown command, use list to list all commands\n";
}
} catch (const sls::RuntimeError &e) {
// OK to catch and do nothing since this will print the error message
// and command line app will anyway exit
}
}

View File

@ -24,6 +24,7 @@ void CmdLineParser::Print() {
}; };
void CmdLineParser::Parse(int argc, const char *const argv[]) { void CmdLineParser::Parse(int argc, const char *const argv[]) {
Reset();
executable_ = argv[0]; // first arg is calling binary executable_ = argv[0]; // first arg is calling binary
if (argc > 1) { if (argc > 1) {
std::string s = argv[1]; std::string s = argv[1];
@ -36,6 +37,7 @@ void CmdLineParser::Parse(int argc, const char *const argv[]) {
} }
void CmdLineParser::Parse(const std::string &s) { void CmdLineParser::Parse(const std::string &s) {
Reset();
std::istringstream iss(s); std::istringstream iss(s);
auto it = std::istream_iterator<std::string>(iss); auto it = std::istream_iterator<std::string>(iss);
arguments_ = arguments_ =
@ -109,4 +111,13 @@ std::string CmdLineParser::cli_line() const{
return os.str(); return os.str();
} }
void CmdLineParser::Reset(){
multi_id_ = 0;
detector_id_ = -1;
help_ = false;
command_.clear();
executable_.clear();
arguments_.clear();
}
} // namespace sls } // namespace sls

View File

@ -39,9 +39,10 @@ class CmdLineParser {
private: private:
void DecodeIdAndPosition(const char *c); void DecodeIdAndPosition(const char *c);
void Reset(); // reset all private variables
int multi_id_ = 0; int multi_id_ = 0;
int detector_id_ = -1; int detector_id_ = -1;
bool help_{false}; bool help_ = false;
std::string command_; std::string command_;
std::string executable_; std::string executable_;
std::vector<std::string> arguments_; std::vector<std::string> arguments_;

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,6 @@
#include "Detector.h" #include "Detector.h"
#include "CmdLineParser.h"
#include "CmdProxy.h"
#include "container_utils.h" #include "container_utils.h"
#include "detectorData.h" #include "detectorData.h"
#include "logger.h" #include "logger.h"
@ -6,23 +8,78 @@
#include "slsDetector.h" #include "slsDetector.h"
#include "sls_detector_defs.h" #include "sls_detector_defs.h"
#include <fstream>
namespace sls { 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();
}
return;
}
// multi - get number of detectors from shm
SharedMemory<sharedMultiSlsDetector> multiShm(multiId, -1);
int numDetectors = 0;
if (multiShm.IsExisting()) {
multiShm.OpenSharedMemory();
numDetectors = multiShm()->numberOfDetectors;
multiShm.RemoveSharedMemory();
}
for (int i = 0; i < numDetectors; ++i) {
SharedMemory<sharedSlsDetector> shm(multiId, i);
shm.RemoveSharedMemory();
}
}
using defs = slsDetectorDefs; using defs = slsDetectorDefs;
Detector::Detector(int shm_id) Detector::Detector(int shm_id)
: pimpl(sls::make_unique<multiSlsDetector>(shm_id)) {} : pimpl(sls::make_unique<multiSlsDetector>(shm_id)) {}
Detector::~Detector() = default; Detector::~Detector() = default;
// Configuration // Configuration
void Detector::freeSharedMemory() { pimpl->freeSharedMemory(); } void Detector::freeSharedMemory() { pimpl->freeSharedMemory(); }
void Detector::loadConfig(const std::string &fname) { void Detector::loadConfig(const std::string &fname) {
pimpl->readConfigurationFile(fname); int shm_id = getShmId();
freeSharedMemory();
pimpl = sls::make_unique<multiSlsDetector>(shm_id);
FILE_LOG(logINFO) << "Loading configuration file: " << fname;
loadParameters(fname);
} }
void Detector::loadParameters(const std::string &fname) { void Detector::loadParameters(const std::string &fname) {
pimpl->loadParameters(fname); CmdProxy proxy(this);
CmdLineParser parser;
std::ifstream input_file;
input_file.open(fname.c_str(), std::ios_base::in);
if (!input_file.is_open()) {
throw RuntimeError("Could not open configuration file " + fname +
" for reading");
}
std::string current_line;
while (input_file.good()) {
getline(input_file, current_line);
if (current_line.find('#') != std::string::npos) {
current_line.erase(current_line.find('#'));
}
FILE_LOG(logDEBUG1)
<< "current_line after removing comments:\n\t" << current_line;
if (current_line.length() > 1) {
parser.Parse(current_line);
proxy.Call(parser.command(), parser.arguments(),
parser.detector_id(), defs::PUT_ACTION);
}
}
input_file.close();
} }
Result<std::string> Detector::getHostname(Positions pos) const { Result<std::string> Detector::getHostname(Positions pos) const {
@ -69,6 +126,8 @@ Result<defs::detectorType> Detector::getDetectorType(Positions pos) const {
int Detector::size() const { return pimpl->size(); } int Detector::size() const { return pimpl->size(); }
bool Detector::empty() const { return pimpl->size() == 0; }
defs::xy Detector::getModuleGeometry() const { defs::xy Detector::getModuleGeometry() const {
return pimpl->getNumberOfDetectors(); return pimpl->getNumberOfDetectors();
} }
@ -166,7 +225,8 @@ Result<ns> Detector::getPeriodLeft(Positions pos) const {
} }
Result<defs::speedLevel> Detector::getSpeed(Positions pos) const { Result<defs::speedLevel> Detector::getSpeed(Positions pos) const {
auto res = pimpl->Parallel(&slsDetector::getClockDivider, pos, defs::RUN_CLOCK); auto res =
pimpl->Parallel(&slsDetector::getClockDivider, pos, defs::RUN_CLOCK);
Result<defs::speedLevel> speedResult(res.size()); Result<defs::speedLevel> speedResult(res.size());
for (unsigned int i = 0; i < res.size(); ++i) { for (unsigned int i = 0; i < res.size(); ++i) {
speedResult[i] = static_cast<defs::speedLevel>(res[i]); speedResult[i] = static_cast<defs::speedLevel>(res[i]);
@ -180,11 +240,13 @@ void Detector::setSpeed(defs::speedLevel value, Positions pos) {
} }
Result<int> Detector::getADCPhase(Positions pos) const { Result<int> Detector::getADCPhase(Positions pos) const {
return pimpl->Parallel(&slsDetector::getClockPhase, pos, defs::ADC_CLOCK, false); return pimpl->Parallel(&slsDetector::getClockPhase, pos, defs::ADC_CLOCK,
false);
} }
void Detector::setADCPhase(int value, Positions pos) { void Detector::setADCPhase(int value, Positions pos) {
pimpl->Parallel(&slsDetector::setClockPhase, pos, defs::ADC_CLOCK, value, false); pimpl->Parallel(&slsDetector::setClockPhase, pos, defs::ADC_CLOCK, value,
false);
} }
Result<int> Detector::getMaxADCPhaseShift(Positions pos) const { Result<int> Detector::getMaxADCPhaseShift(Positions pos) const {
@ -193,11 +255,13 @@ Result<int> Detector::getMaxADCPhaseShift(Positions pos) const {
} }
Result<int> Detector::getADCPhaseInDegrees(Positions pos) const { Result<int> Detector::getADCPhaseInDegrees(Positions pos) const {
return pimpl->Parallel(&slsDetector::getClockPhase, pos, defs::ADC_CLOCK, true); return pimpl->Parallel(&slsDetector::getClockPhase, pos, defs::ADC_CLOCK,
true);
} }
void Detector::setADCPhaseInDegrees(int value, Positions pos) { void Detector::setADCPhaseInDegrees(int value, Positions pos) {
pimpl->Parallel(&slsDetector::setClockPhase, pos, defs::ADC_CLOCK, value, true); pimpl->Parallel(&slsDetector::setClockPhase, pos, defs::ADC_CLOCK, value,
true);
} }
Result<int> Detector::getClockFrequency(int clkIndex, Positions pos) { Result<int> Detector::getClockFrequency(int clkIndex, Positions pos) {
@ -285,11 +349,13 @@ void Detector::setDAC(defs::dacIndex index, int value, bool mV, Positions pos) {
pimpl->Parallel(&slsDetector::setDAC, pos, value, index, mV); pimpl->Parallel(&slsDetector::setDAC, pos, value, index, mV);
} }
Result<int> Detector::getOnChipDAC(defs::dacIndex index, int chipIndex, Positions pos) const { Result<int> Detector::getOnChipDAC(defs::dacIndex index, int chipIndex,
Positions pos) const {
return pimpl->Parallel(&slsDetector::getOnChipDAC, pos, index, chipIndex); return pimpl->Parallel(&slsDetector::getOnChipDAC, pos, index, chipIndex);
} }
void Detector::setOnChipDAC(defs::dacIndex index, int chipIndex, int value, Positions pos) { void Detector::setOnChipDAC(defs::dacIndex index, int chipIndex, int value,
Positions pos) {
pimpl->Parallel(&slsDetector::setOnChipDAC, pos, index, chipIndex, value); pimpl->Parallel(&slsDetector::setOnChipDAC, pos, index, chipIndex, value);
} }
@ -472,7 +538,8 @@ void Detector::setDestinationUDPPort2(int port, int module_id) {
port_list[idet]); port_list[idet]);
} }
} else { } else {
pimpl->Parallel(&slsDetector::setDestinationUDPPort2, {module_id}, port); pimpl->Parallel(&slsDetector::setDestinationUDPPort2, {module_id},
port);
} }
} }
@ -542,7 +609,7 @@ Result<int> Detector::getRxPort(Positions pos) const {
void Detector::setRxPort(int port, int module_id) { void Detector::setRxPort(int port, int module_id) {
if (module_id == -1) { if (module_id == -1) {
std::vector<int> port_list(size()); std::vector<int> port_list(size());
for (auto &it: port_list) { for (auto &it : port_list) {
it = port++; it = port++;
} }
for (int idet = 0; idet < size(); ++idet) { for (int idet = 0; idet < size(); ++idet) {
@ -1023,7 +1090,8 @@ void Detector::setAutoCompDisable(bool value, Positions pos) {
} }
Result<int> Detector::getNumberOfAdditionalStorageCells(Positions pos) const { Result<int> Detector::getNumberOfAdditionalStorageCells(Positions pos) const {
return pimpl->Parallel(&slsDetector::getNumberOfAdditionalStorageCells, pos); return pimpl->Parallel(&slsDetector::getNumberOfAdditionalStorageCells,
pos);
} }
void Detector::setNumberOfAdditionalStorageCells(int value) { void Detector::setNumberOfAdditionalStorageCells(int value) {
@ -1143,11 +1211,13 @@ void Detector::setReadoutMode(defs::readoutMode value, Positions pos) {
} }
Result<int> Detector::getDBITPhase(Positions pos) const { Result<int> Detector::getDBITPhase(Positions pos) const {
return pimpl->Parallel(&slsDetector::getClockPhase, pos, defs::DBIT_CLOCK, false); return pimpl->Parallel(&slsDetector::getClockPhase, pos, defs::DBIT_CLOCK,
false);
} }
void Detector::setDBITPhase(int value, Positions pos) { void Detector::setDBITPhase(int value, Positions pos) {
pimpl->Parallel(&slsDetector::setClockPhase, pos, defs::DBIT_CLOCK, value, false); pimpl->Parallel(&slsDetector::setClockPhase, pos, defs::DBIT_CLOCK, value,
false);
} }
Result<int> Detector::getMaxDBITPhaseShift(Positions pos) const { Result<int> Detector::getMaxDBITPhaseShift(Positions pos) const {
@ -1156,39 +1226,48 @@ Result<int> Detector::getMaxDBITPhaseShift(Positions pos) const {
} }
Result<int> Detector::getDBITPhaseInDegrees(Positions pos) const { Result<int> Detector::getDBITPhaseInDegrees(Positions pos) const {
return pimpl->Parallel(&slsDetector::getClockPhase, pos, defs::DBIT_CLOCK, true); return pimpl->Parallel(&slsDetector::getClockPhase, pos, defs::DBIT_CLOCK,
true);
} }
void Detector::setDBITPhaseInDegrees(int value, Positions pos) { void Detector::setDBITPhaseInDegrees(int value, Positions pos) {
pimpl->Parallel(&slsDetector::setClockPhase, pos, defs::DBIT_CLOCK, value, true); pimpl->Parallel(&slsDetector::setClockPhase, pos, defs::DBIT_CLOCK, value,
true);
} }
Result<int> Detector::getADCClock(Positions pos) const { Result<int> Detector::getADCClock(Positions pos) const {
return pimpl->Parallel(&slsDetector::getClockFrequency, pos, defs::ADC_CLOCK); return pimpl->Parallel(&slsDetector::getClockFrequency, pos,
defs::ADC_CLOCK);
} }
void Detector::setADCClock(int value_in_MHz, Positions pos) { void Detector::setADCClock(int value_in_MHz, Positions pos) {
pimpl->Parallel(&slsDetector::setClockFrequency, pos, defs::ADC_CLOCK, value_in_MHz); pimpl->Parallel(&slsDetector::setClockFrequency, pos, defs::ADC_CLOCK,
value_in_MHz);
} }
Result<int> Detector::getDBITClock(Positions pos) const { Result<int> Detector::getDBITClock(Positions pos) const {
return pimpl->Parallel(&slsDetector::getClockFrequency, pos, defs::DBIT_CLOCK); return pimpl->Parallel(&slsDetector::getClockFrequency, pos,
defs::DBIT_CLOCK);
} }
void Detector::setDBITClock(int value_in_MHz, Positions pos) { void Detector::setDBITClock(int value_in_MHz, Positions pos) {
pimpl->Parallel(&slsDetector::setClockFrequency, pos, defs::DBIT_CLOCK, value_in_MHz); pimpl->Parallel(&slsDetector::setClockFrequency, pos, defs::DBIT_CLOCK,
value_in_MHz);
} }
Result<int> Detector::getRUNClock(Positions pos) const { Result<int> Detector::getRUNClock(Positions pos) const {
return pimpl->Parallel(&slsDetector::getClockFrequency, pos, defs::RUN_CLOCK); return pimpl->Parallel(&slsDetector::getClockFrequency, pos,
defs::RUN_CLOCK);
} }
void Detector::setRUNClock(int value_in_MHz, Positions pos) { void Detector::setRUNClock(int value_in_MHz, Positions pos) {
pimpl->Parallel(&slsDetector::setClockFrequency, pos, defs::RUN_CLOCK, value_in_MHz); pimpl->Parallel(&slsDetector::setClockFrequency, pos, defs::RUN_CLOCK,
value_in_MHz);
} }
Result<int> Detector::getSYNCClock(Positions pos) const { Result<int> Detector::getSYNCClock(Positions pos) const {
return pimpl->Parallel(&slsDetector::getClockFrequency, pos, defs::SYNC_CLOCK); return pimpl->Parallel(&slsDetector::getClockFrequency, pos,
defs::SYNC_CLOCK);
} }
Result<int> Detector::getADCPipeline(Positions pos) const { Result<int> Detector::getADCPipeline(Positions pos) const {
@ -1340,7 +1419,45 @@ void Detector::setLEDEnable(bool enable, Positions pos) {
// Pattern // Pattern
void Detector::savePattern(const std::string &fname) { void Detector::savePattern(const std::string &fname) {
pimpl->savePattern(fname); std::ofstream outfile;
outfile.open(fname.c_str(), std::ios_base::out);
if (!outfile.is_open()) {
throw RuntimeError("Could not create file to save pattern");
}
// get pattern limits
auto r = pimpl->Parallel(&slsDetector::setPatternLoopAddresses, {}, -1, -1, -1)
.tsquash("Inconsistent pattern limits");
CmdProxy proxy(this);
// pattern words
for (int i = r[0]; i <= r[1]; ++i) {
std::ostringstream os;
os << "0x" << std::hex << i;
auto addr = os.str();
proxy.Call("patword", {addr}, -1, defs::GET_ACTION, outfile);
}
// rest of pattern file
const std::vector<std::string> commands{
"patioctrl",
"patclkctrl",
"patlimits",
"patloop0",
"patnloop0",
"patloop1",
"patnloop1",
"patloop2",
"patnloop2",
"patwait0",
"patwaittime0",
"patwait1",
"patwaittime1",
"patwait2",
"patwaittime2",
"patmask",
"patsetbit",
};
for (const auto &cmd : commands)
proxy.Call(cmd, {}, -1, defs::GET_ACTION, outfile);
} }
void Detector::setPattern(const std::string &fname, Positions pos) { void Detector::setPattern(const std::string &fname, Positions pos) {
@ -1371,12 +1488,16 @@ void Detector::setPatternWord(int addr, uint64_t word, Positions pos) {
pimpl->Parallel(&slsDetector::setPatternWord, pos, addr, word); pimpl->Parallel(&slsDetector::setPatternWord, pos, addr, word);
} }
Result<std::array<int, 2>> Detector::getPatternLoopAddresses(int level, Positions pos) const { Result<std::array<int, 2>>
return pimpl->Parallel(&slsDetector::setPatternLoopAddresses, pos, level, -1, -1); Detector::getPatternLoopAddresses(int level, Positions pos) const {
return pimpl->Parallel(&slsDetector::setPatternLoopAddresses, pos, level,
-1, -1);
} }
void Detector::setPatternLoopAddresses(int level, int start, int stop, Positions pos) { void Detector::setPatternLoopAddresses(int level, int start, int stop,
pimpl->Parallel(&slsDetector::setPatternLoopAddresses, pos, level, start, stop); Positions pos) {
pimpl->Parallel(&slsDetector::setPatternLoopAddresses, pos, level, start,
stop);
} }
Result<int> Detector::getPatternLoopCycles(int level, Positions pos) const { Result<int> Detector::getPatternLoopCycles(int level, Positions pos) const {
@ -1470,7 +1591,8 @@ Result<defs::frameModeType> Detector::getFrameMode(Positions pos) const {
Result<defs::frameModeType> intResult(res.size()); Result<defs::frameModeType> intResult(res.size());
try { try {
for (unsigned int i = 0; i < res.size(); ++i) { for (unsigned int i = 0; i < res.size(); ++i) {
intResult[i] = sls::StringTo<slsDetectorDefs::frameModeType>(res[i]); intResult[i] =
sls::StringTo<slsDetectorDefs::frameModeType>(res[i]);
} }
} catch (...) { } catch (...) {
throw RuntimeError( throw RuntimeError(
@ -1490,7 +1612,8 @@ Result<defs::detectorModeType> Detector::getDetectorMode(Positions pos) const {
Result<defs::detectorModeType> intResult(res.size()); Result<defs::detectorModeType> intResult(res.size());
try { try {
for (unsigned int i = 0; i < res.size(); ++i) { for (unsigned int i = 0; i < res.size(); ++i) {
intResult[i] = sls::StringTo<slsDetectorDefs::detectorModeType>(res[i]); intResult[i] =
sls::StringTo<slsDetectorDefs::detectorModeType>(res[i]);
} }
} catch (...) { } catch (...) {
throw RuntimeError( throw RuntimeError(

View File

@ -4,9 +4,7 @@
#include "detectorData.h" #include "detectorData.h"
#include "file_utils.h" #include "file_utils.h"
#include "logger.h" #include "logger.h"
#include "multiSlsDetectorClient.h"
#include "slsDetector.h" #include "slsDetector.h"
#include "slsDetectorCommand.h"
#include "sls_detector_exceptions.h" #include "sls_detector_exceptions.h"
#include "versionAPI.h" #include "versionAPI.h"
@ -423,32 +421,6 @@ void multiSlsDetector::setNumberOfChannels(const slsDetectorDefs::xy c) {
multi_shm()->numberOfChannels = c; multi_shm()->numberOfChannels = c;
} }
void multiSlsDetector::readConfigurationFile(const std::string &fname) {
freeSharedMemory();
setupMultiDetector();
FILE_LOG(logINFO) << "Loading configuration file: " << fname;
std::ifstream input_file;
input_file.open(fname.c_str(), std::ios_base::in);
if (!input_file.is_open()) {
throw RuntimeError("Could not open configuration file " + fname +
" for reading");
}
std::string current_line;
while (input_file.good()) {
getline(input_file, current_line);
if (current_line.find('#') != std::string::npos) {
current_line.erase(current_line.find('#'));
}
FILE_LOG(logDEBUG1)
<< "current_line after removing comments:\n\t" << current_line;
if (current_line.length() > 1) {
multiSlsDetectorClient(current_line, PUT_ACTION, nullptr);
}
}
input_file.close();
}
void multiSlsDetector::setGapPixelsinReceiver(bool enable) { void multiSlsDetector::setGapPixelsinReceiver(bool enable) {
Parallel(&slsDetector::enableGapPixels, {}, static_cast<int>(enable)); Parallel(&slsDetector::enableGapPixels, {}, static_cast<int>(enable));
// update number of channels // update number of channels
@ -922,66 +894,45 @@ bool multiSlsDetector::enableDataStreamingToClient(int enable) {
void multiSlsDetector::savePattern(const std::string &fname) { void multiSlsDetector::savePattern(const std::string &fname) {
std::ofstream outfile; // std::ofstream outfile;
outfile.open(fname.c_str(), std::ios_base::out); // outfile.open(fname.c_str(), std::ios_base::out);
if (!outfile.is_open()) { // if (!outfile.is_open()) {
throw RuntimeError("Could not create file to save pattern"); // throw RuntimeError("Could not create file to save pattern");
} // }
// get pattern limits // // get pattern limits
auto r = Parallel(&slsDetector::setPatternLoopAddresses, {}, -1, -1, -1) // auto r = Parallel(&slsDetector::setPatternLoopAddresses, {}, -1, -1, -1)
.tsquash("Inconsistent pattern limits"); // .tsquash("Inconsistent pattern limits");
// pattern words // // pattern words
for (int i = r[0]; i <= r[1]; ++i) { // for (int i = r[0]; i <= r[1]; ++i) {
std::ostringstream os; // std::ostringstream os;
os << "patword 0x" << std::hex << i; // os << "patword 0x" << std::hex << i;
std::string cmd = os.str(); // std::string cmd = os.str();
multiSlsDetectorClient(cmd, GET_ACTION, this, outfile); // multiSlsDetectorClient(cmd, GET_ACTION, this, outfile);
} // }
// rest of pattern file // // rest of pattern file
const std::vector<std::string> commands{ // const std::vector<std::string> commands{
"patioctrl", // "patioctrl",
"patclkctrl", // "patclkctrl",
"patlimits", // "patlimits",
"patloop0", // "patloop0",
"patnloop0", // "patnloop0",
"patloop1", // "patloop1",
"patnloop1", // "patnloop1",
"patloop2", // "patloop2",
"patnloop2", // "patnloop2",
"patwait0", // "patwait0",
"patwaittime0", // "patwaittime0",
"patwait1", // "patwait1",
"patwaittime1", // "patwaittime1",
"patwait2", // "patwait2",
"patwaittime2", // "patwaittime2",
"patmask", // "patmask",
"patsetbit", // "patsetbit",
}; // };
for (const auto &cmd : commands) // for (const auto &cmd : commands)
multiSlsDetectorClient(cmd, GET_ACTION, this, outfile); // multiSlsDetectorClient(cmd, GET_ACTION, this, outfile);
} }
void multiSlsDetector::loadParameters(const std::string &fname) {
std::ifstream input_file;
input_file.open(fname.c_str(), std::ios_base::in);
if (!input_file.is_open()) {
throw RuntimeError("Could not open parameter file " + fname +
" for reading");
}
std::string current_line;
while (input_file.good()) {
getline(input_file, current_line);
if (current_line.find('#') != std::string::npos) {
current_line.erase(current_line.find('#'));
}
FILE_LOG(logDEBUG1)
<< "current_line after removing comments:\n\t" << current_line;
if (current_line.length() > 1) {
multiSlsDetectorClient(current_line, PUT_ACTION, this);
}
}
input_file.close();
}
void multiSlsDetector::registerAcquisitionFinishedCallback( void multiSlsDetector::registerAcquisitionFinishedCallback(

View File

@ -1,119 +0,0 @@
#include "multiSlsDetectorClient.h"
#include "CmdProxy.h"
#include "Detector.h"
#include "multiSlsDetector.h"
#include "slsDetectorCommand.h"
#include "sls_detector_exceptions.h"
#include <memory>
multiSlsDetectorClient::multiSlsDetectorClient(int argc, char *argv[],
int action,
multiSlsDetector *myDetector,
std::ostream &output)
: action_(action), detPtr(myDetector), os(output) {
parser.Parse(argc, argv);
runCommand();
}
multiSlsDetectorClient::multiSlsDetectorClient(const std::string &args,
int action,
multiSlsDetector *myDetector,
std::ostream &output)
: action_(action), detPtr(myDetector), os(output) {
parser.Parse(args);
runCommand();
}
void multiSlsDetectorClient::runCommand() {
if (parser.isHelp())
action_ = slsDetectorDefs::HELP_ACTION;
bool verify = true;
bool update = true;
if (action_ == slsDetectorDefs::PUT_ACTION && parser.command().empty()) {
os << "Wrong usage - should be: " << parser.executable()
<< "[id-][pos:]channel arg" << std::endl;
os << std::endl;
return;
};
if (action_ == slsDetectorDefs::GET_ACTION && parser.command().empty()) {
os << "Wrong usage - should be: " << parser.executable()
<< "[id-][pos:]channel arg" << std::endl;
os << std::endl;
return;
};
if (action_ == slsDetectorDefs::READOUT_ACTION &&
parser.detector_id() != -1) {
os << "detector_id: " << parser.detector_id()
<< " ,readout of individual detectors is not allowed!" << std::endl;
return;
}
// special commands
if (parser.command() == "free") {
multiSlsDetector::freeSharedMemory(parser.multi_id(),
parser.detector_id());
return;
} // get user details without verify sharedMultiSlsDetector version
else if ((parser.command() == "user") &&
(action_ == slsDetectorDefs::GET_ACTION)) {
verify = false;
update = false;
}
// create multiSlsDetector class if required
std::unique_ptr<multiSlsDetector> localDet;
if (detPtr == nullptr) {
try {
localDet = sls::make_unique<multiSlsDetector>(parser.multi_id(),
verify, update);
detPtr = localDet.get();
} catch (const sls::RuntimeError &e) {
/*os << e.GetMessage() << std::endl;*/
return;
} catch (...) {
os << " caught exception\n";
return;
}
}
if (parser.detector_id() >= static_cast<int>(detPtr->size())) {
os << "position " << parser.detector_id() << " is out of bounds (max " << detPtr->size() << ").\n";
return;
}
// Call CmdProxy which execute the command if it exists, on success
// returns an empty string If the command is not in CmdProxy but
// deprecated the new command is returned
if (action_ != slsDetectorDefs::READOUT_ACTION) {
int multi_id = 0;
if (detPtr != nullptr)
multi_id = detPtr->getMultiId();
sls::Detector d(multi_id);
sls::CmdProxy proxy(&d);
auto cmd = proxy.Call(parser.command(), parser.arguments(),
parser.detector_id(), action_, os);
if (cmd.empty()) {
return;
} else {
parser.setCommand(cmd);
}
}
// call multi detector command line
slsDetectorCommand myCmd(detPtr);
std::string answer =
myCmd.executeLine(parser.n_arguments() + 1, parser.argv().data(),
action_, parser.detector_id());
if (parser.multi_id() != 0)
os << parser.multi_id() << '-';
if (parser.detector_id() != -1)
os << parser.detector_id() << ':';
if (action_ != slsDetectorDefs::READOUT_ACTION) {
os << parser.command() << " ";
}
os << answer << std::endl;
}

View File

@ -1,23 +0,0 @@
#pragma once
#include <iostream>
#include "CmdLineParser.h"
class multiSlsDetector;
class multiSlsDetectorClient {
public:
multiSlsDetectorClient(int argc, char *argv[], int action,
multiSlsDetector *myDetector = nullptr,
std::ostream &output = std::cout);
multiSlsDetectorClient(const std::string &args, int action,
multiSlsDetector *myDetector = nullptr,
std::ostream &output = std::cout);
private:
int action_;
sls::CmdLineParser parser;
multiSlsDetector *detPtr = nullptr;
std::ostream &os;
void runCommand();
};

View File

@ -3,7 +3,6 @@
#include "SharedMemory.h" #include "SharedMemory.h"
#include "file_utils.h" #include "file_utils.h"
#include "network_utils.h" #include "network_utils.h"
#include "slsDetectorCommand.h"
#include "sls_detector_exceptions.h" #include "sls_detector_exceptions.h"
#include "string_utils.h" #include "string_utils.h"
#include "versionAPI.h" #include "versionAPI.h"

View File

@ -1,221 +0,0 @@
#include "slsDetectorCommand.h"
#include "multiSlsDetector.h"
#include "slsDetector.h"
#include "string_utils.h"
#include <cstdlib>
#include <cmath>
#include <fstream>
#include <iostream>
#include <sstream>
#include <iomanip>
/*! \page CLI Command line interface
This program is intended to control the SLS detectors via command line interface.
This is the only way to access all possible functionality of the detectors, however it is often recommendable to avoid changing the most advanced settings, rather leaving the task to configuration files, as when using the GUI or the API provided.
The command line interface consists in four main functions:
- \b sls_detector_acquire to acquire data from the detector
- \b sls_detector_put to set detector parameters
- \b sls_detector_get to retrieve detector parameters
- \b sls_detector_help to get help concerning the text commands
Additionally the program slsReceiver should be started on the machine expected to receive the data from the detector.
If you need control a single detector, the use of the command line interface does not need any additional arguments.
For commands addressing a single controller of your detector, the command cmd should be called with the index i of the controller:
<b>sls_detector_clnt i:cmd</b>
where \b sls_detector_clnt is the text client (put, get, acquire, help).
In case more than one detector is configured on the control PC, the command cmd should be called with their respective index j:
<b>sls_detector_clnt j-cmd</b>
where \b sls_detector_clnt is the text client (put, get, acquire, help).
To address a specific controller i of detector j use:
<b>sls_detector_clnt j-i:cmd</b>
To use different shared memory segements for different detectors on the same
client pc, one can use environment variable <b>SLSDETNAME</b> set to any string to
different strings to make the shared memory segments unique. One can then use
the same multi detector id for both detectors as they have a different shared memory names.
For additional questions concerning the indexing of the detector, please refer to the SLS Detectors FAQ documentation.
The commands are sudivided into different pages depending on their functionalities:
- \subpage acquisition "Acquisition": commands to start/stop the acquisition and retrieve data
- \subpage config "Configuration": commands to configure the detector
- \subpage timing "Timing": commands to configure the detector timing
- \subpage data "Data postprocessing": commands to process the data
- \subpage settings "Settings": commands to define detector settings/threshold.
- \subpage output "Output": commands to define output file destination and format
- \subpage network "Network": commands to setup the network between client, detector and receiver
- \subpage receiver "Receiver": commands to configure the receiver
- \subpage prototype "Chip Test Board / Moench": commands specific for the chiptest board or moench
- \subpage test "Developer": commands to be used only for software debugging. Avoid using them!
*/
slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) {
myDet = det;
int i = 0;
cmd = std::string("none");
/* Acquisition and status commands */
/*! \page acquisition Acquition commands
Commands to control the acquisition
*/
/*! \page acquisition
- \b acquire blocking acquisition (like calling sls_detector_acquire). Starts receiver and detector, writes and processes the data, stops detector. Only get!
\c Returns (string)\c "acquire failed" if fails, else \c "Acquired (int)", where int is number of frames caught.
*/
descrToFuncMap[i].m_pFuncName = "acquire";
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdAcquire;
++i;
/* settings dump/retrieve */
descrToFuncMap[i].m_pFuncName = "config";
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdConfiguration;
++i;
numberOfCommands = i;
}
std::string slsDetectorCommand::executeLine(int narg, const char * const args[], int action, int detPos) {
if (action == READOUT_ACTION)
return cmdAcquire(narg, args, action, detPos);
size_t s = std::string(args[0]).find(':');
std::string key = std::string(args[0]).substr(0, s); // truncate at :
if (action == PUT_ACTION && narg < 1)
action = HELP_ACTION;
for (int i = 0; i < numberOfCommands; ++i) {
/* this works only if the command completely matches the key */
/* otherwise one could try if truncated key is unique */
if (key == descrToFuncMap[i].m_pFuncName) {
#ifdef VERBOSE
std::cout << i << " command=" << descrToFuncMap[i].m_pFuncName << " key=" << key << std::endl;
#endif
cmd = descrToFuncMap[i].m_pFuncName;
MemFuncGetter memFunc = descrToFuncMap[i].m_pFuncPtr;
std::string dResult = (this->*memFunc)(narg, args, action, detPos);
return dResult;
}
}
return cmdUnknown(narg, args, action, detPos);
}
std::string slsDetectorCommand::cmdUnknown(int narg, const char * const args[], int action, int detPos) {
return std::string("Unknown command, use list to list all commands ");
}
std::vector<std::string> slsDetectorCommand::getAllCommands(){
std::vector<std::string> commands;
for (int i = 0; i!= numberOfCommands; ++i)
commands.emplace_back(descrToFuncMap[i].m_pFuncName);
return commands;
}
std::string slsDetectorCommand::cmdAcquire(int narg, const char * const args[], int action, int detPos) {
#ifdef VERBOSE
std::cout << std::string("Executing command ") + std::string(args[0]) + std::string(" ( ") + cmd + std::string(" )\n");
#endif
if (action == HELP_ACTION) {
return helpAcquire(HELP_ACTION);
}
if (!myDet->size()) {
FILE_LOG(logERROR) << "This shared memory has no detectors added. Aborting.";
return std::string("acquire failed");
}
if (detPos >= 0) {
FILE_LOG(logERROR) << "Individual detectors not allowed for readout. Aborting.";
return std::string("acquire failed");
}
if (myDet->acquire() == FAIL)
return std::string("acquire failed");
if (myDet->Parallel(&slsDetector::getUseReceiverFlag, {}).squash(false)) {
std::ostringstream os;
os << "\nAcquired ";
os << sls::ToString(myDet->Parallel(&slsDetector::getFramesCaughtByReceiver, {}));
return os.str();
}
return std::string();
}
std::string slsDetectorCommand::helpAcquire(int action) {
if (action == PUT_ACTION)
return std::string("");
std::ostringstream os;
os << "Usage is " << std::endl
<< "sls_detector_acquire id " << std::endl;
os << "where id is the id of the detector " << std::endl;
os << "the detector will be started, the data acquired, processed and written to file according to the preferences configured " << std::endl;
return os.str();
}
std::string slsDetectorCommand::cmdConfiguration(int narg, const char * const args[], int action, int detPos) {
if (action == HELP_ACTION)
return helpConfiguration(action);
if (cmd == "config") {
if (action == PUT_ACTION) {
myDet->readConfigurationFile(std::string(args[1]));
}
return std::string("success");
}
return std::string("could not decode conf mode");
}
std::string slsDetectorCommand::helpConfiguration(int action) {
std::ostringstream os;
return os.str();
}

View File

@ -1,37 +0,0 @@
#include "multiSlsDetectorClient.h"
#include "sls_detector_defs.h"
#include "versionAPI.h"
#include <cstring> //strcmp
int main(int argc, char *argv[]) {
for (int i = 1; i < argc; ++i) {
if (!(strcmp(argv[i], "--version")) || !(strcmp(argv[i], "-v"))) {
int64_t tempval = APILIB;
std::cout << argv[0] << " " << GITBRANCH << " (0x" << std::hex
<< tempval << ")" << std::endl;
return 0;
}
}
#ifdef PUT
int action = slsDetectorDefs::PUT_ACTION;
#endif
#ifdef GET
int action = slsDetectorDefs::GET_ACTION;
#endif
#ifdef READOUT
int action = slsDetectorDefs::READOUT_ACTION;
#endif
#ifdef HELP
int action = slsDetectorDefs::HELP_ACTION;
#endif
try {
multiSlsDetectorClient(argc, argv, action);
} catch (const sls::RuntimeError &e) {
}
}

View File

@ -1,8 +1,9 @@
target_sources(tests PRIVATE target_sources(tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/test-SharedMemory.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-SharedMemory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-slsDetector.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-slsDetector.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-multiSlsDetector.cpp # ${CMAKE_CURRENT_SOURCE_DIR}/test-multiSlsDetectorClient.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-multiSlsDetectorClient.cpp # TODO! Migrate tests!
${CMAKE_CURRENT_SOURCE_DIR}/test-CmdProxy.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-Result.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-Result.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-CmdLineParser.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-CmdLineParser.cpp
) )

View File

@ -158,6 +158,25 @@ SCENARIO("Parsing strings with -h or --help", "[support]") {
} }
} }
TEST_CASE("Parsing consecutive strings resets not found det id"){
CmdLineParser p;
p.Parse("1:exptime 0.5");
REQUIRE(p.detector_id() == 1);
p.Parse("exptime 0.5");
REQUIRE(p.detector_id() == -1);
p.Parse("3:exptime 0.5");
REQUIRE(p.detector_id() == 3);
}
TEST_CASE("Parsing consecutive strings resets not found multi id"){
CmdLineParser p;
p.Parse("1-1:exptime 0.5");
REQUIRE(p.multi_id() == 1);
p.Parse("1:exptime 0.5");
REQUIRE(p.multi_id() == 0);
}
TEST_CASE("Parse with no arguments results in no command and default id", TEST_CASE("Parse with no arguments results in no command and default id",
"[support]") { "[support]") {
// build up argc and argv // build up argc and argv

File diff suppressed because it is too large Load Diff

View File

@ -1,83 +0,0 @@
#include "catch.hpp"
#include "container_utils.h"
#include "multiSlsDetector.h"
#include "slsDetector.h"
#include "string_utils.h"
#include <iostream>
using namespace sls;
// SCENARIO("Multi detector operation", "[detector]") {
// multiSlsDetector::freeSharedMemory(20, -1);
// GIVEN("An empty multi detector") {
// multiSlsDetector m(20);
// THEN("the size is zero") {
// CHECK(m.getNumberOfDetectors() == 0);
// CHECK(m.getDataBytes() == 0);
// CHECK(m.getTotalNumberOfChannels() == 0);
// }
// WHEN("we add a detector") {
// m.addSlsDetector(sls::make_unique<slsDetector>(
// slsDetectorDefs::detectorType::EIGER, 20, 0));
// THEN("the size and number of detector changes") {
// CHECK(m.getNumberOfDetectors() == 1);
// CHECK(m.getTotalNumberOfChannels() == 256 * 1024);
// }
// WHEN("we add another detector") {
// m.addSlsDetector(sls::make_unique<slsDetector>(
// slsDetectorDefs::detectorType::EIGER, 20, 1));
// THEN("the size and number of detector changes") {
// CHECK(m.getNumberOfDetectors() == 2);
// CHECK(m.getTotalNumberOfChannels() == 2 * 256 * 1024);
// }
// WHEN("We set the trimen") {
// std::vector<int> energies{5000, 6000, 7000, 8000, 9000};
// m.setTrimEn(energies);
// THEN("we read back the same values") {
// CHECK(m.getTrimEn() == energies);
// }
// }
// WHEN("We set the trimen to different values") {
// std::vector<int> en0{5000, 6000, 7000, 8000, 9000};
// std::vector<int> en1{6000, 7000, 8000, 9000};
// m.setTrimEn(en0, 0);
// m.setTrimEn(en1, 1);
// THEN("we read back the same values") {
// CHECK(m.getTrimEn(0) == en0);
// CHECK(m.getTrimEn(1) == en1);
// CHECK(m.getTrimEn() == std::vector<int>{-1});
// }
// }
// }
// }
// m.freeSharedMemory();
// }
// }
// TEST_CASE("Set and get partialFramesPadding", "[detector][somenewtag]"){
// multiSlsDetector::freeSharedMemory(20, -1);
// multiSlsDetector m(20);
// m.addSlsDetector(sls::make_unique<slsDetector>(
// slsDetectorDefs::detectorType::EIGER, 20, 0));
// m.addSlsDetector(sls::make_unique<slsDetector>(
// slsDetectorDefs::detectorType::EIGER, 20, 1));
// m.setPartialFramesPadding(false);
// CHECK(m.getPartialFramesPadding() == 0);
// m.setPartialFramesPadding(true);
// CHECK(m.getPartialFramesPadding() == 1);
// m.setPartialFramesPadding(false, 0);
// CHECK(m.getPartialFramesPadding() == -1);
// m.freeSharedMemory();
// }