Merge branch 'developer' of github.com:slsdetectorgroup/slsDetectorPackage into developer

This commit is contained in:
2019-08-26 09:59:52 +02:00
23 changed files with 931 additions and 720 deletions

View File

@ -44,6 +44,7 @@ option(SLS_USE_SANITIZER "Sanitizers for debugging" OFF)
option(SLS_USE_PYTHON "Python bindings" OFF)
option(SLS_USE_CTBGUI "ctb GUI" OFF)
option(SLS_BUILD_DOCS "docs" OFF)
option(SLS_BUILD_EXAMPLES "examples" OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
@ -185,8 +186,9 @@ configure_file( .clang-tidy
${CMAKE_BINARY_DIR}/.clang-tidy
)
#add_subdirectory(sample)
if (SLS_BUILD_EXAMPLES)
add_subdirectory(sample)
endif(SLS_BUILD_EXAMPLES)
if(SLS_BUILD_DOCS)
add_subdirectory(docs)

View File

@ -36,7 +36,7 @@ int main() {
std::cout << "Generating command line documentation!\n";
sls::CmdProxy<sls::Detector> proxy(nullptr);
sls::CmdProxy proxy(nullptr);
auto commands = proxy.GetProxyCommands();
std::ofstream fs("commands.rst");

View File

@ -47,7 +47,7 @@ using std::chrono::seconds;
int main() {
Detector d;
d.setConfig("/home/l_frojdh/virtual.config");
// d.setConfig("/home/l_frojdh/virtual.config");
// d.setExptime(nanoseconds(500)); // set exptime of all modules
// auto t0 = d.getExptime();

View File

@ -1,38 +1,43 @@
/** Examples on how to use Result<T> */
#include "Result.h"
#include "ToString.h"
#include <algorithm>
#include <iostream>
auto main() -> int {
using sls::Result;
using sls::ToString;
using sls::Result; // declared in namespace sls
using sls::ToString;
auto main() -> int {
std::cout << "Examples on usage of Result<T>\n";
// Result exposes the underlying constructors of std::vector
/** Constructing Result<T> can be done in the same way as vectors */
Result<int> res{1, 2, 3, 4, 5};
std::cout << "res: " << res << '\n';
Result<double> res2(5, 3.7);
std::cout << "res2: " << res2 << '\n';
// and can be converted to and from a vector. However, the
// conversion to a vector is not efficient since a copy is made
// and should only be done when a vector is needed for further use
// in most sense and in standard algorithms Result<T> behaves as a
// vector.
/** and Result can be converted to and from a vector. However, the
* conversion to a vector is not efficient since a copy is made
* and should only be done when a vector is needed for further use
* in most cases Result behaved as a vector, for example with standard
* algorithms */
std::vector<int> vec(5, 5);
std::cout << "vec: " << ToString(vec) << "\n";
//Result from vector
Result<int> res3 = vec;
std::cout << "res3: " << res3 << '\n';
// Vector from Result
std::vector<int> vec2 = res3;
std::cout << "vec2: " << ToString(vec2) << "\n";
// Using squash we can also convert to a single value
// Using squash we can convert to a single value
std::cout << "res.squash(): " << res.squash() << '\n';
std::cout << "res3.squash(): " << res3.squash() << '\n';
@ -43,8 +48,14 @@ auto main() -> int {
Result<int> ivec{1, 3, 5};
Result<sls::time::ns> nres(ivec);
// for (const auto& i : ivec)
// nres.push_back(sls::time::ns(i));
std::cout << "nres: " << sls::ToString(nres) << '\n';
//
/* Convert from Result<int> to Result<bool> */
Result<int> int_result{0, 1, 0, 3, -5};
Result<bool> bool_result{int_result};
std::cout << bool_result << '\n';
// Result can be printed using <<
Result<std::string> string_res{"ein", "zwei", "drei"};
std::cout << string_res << '\n';
}

View File

@ -0,0 +1,268 @@
#ifndef MOENCH03T1ZMQDATA_H
#define MOENCH03T1ZMQDATA_H
#include "slsDetectorData.h"
class moench03T1ZmqData : public slsDetectorData<uint16_t> {
private:
int iframe;
int nadc;
int sc_width;
int sc_height;
const int nPackets; /**<number of UDP packets constituting one frame */
const int packetSize; /**< size of a udp packet */
public:
/**
Implements the slsReceiverData structure for the moench02 prototype read out by a module i.e. using the slsReceiver
(160x160 pixels, 40 packets 1286 large etc.)
\param c crosstalk parameter for the output buffer
*/
moench03T1ZmqData(int npackets=40, int ps=8192): slsDetectorData<uint16_t>(400, 400, ps*npackets), packetSize(ps), nPackets(npackets) {
int nadc=32;
int sc_width=25;
int sc_height=200;
int adc_nr[32]={300,325,350,375,300,325,350,375, \
200,225,250,275,200,225,250,275,\
100,125,150,175,100,125,150,175,\
0,25,50,75,0,25,50,75};
int row, col;
int isample;
int iadc;
int ix, iy;
// int npackets=40;
int i;
int adc4(0);
for (int ip=0; ip<npackets; ip++) {
for (int is=0; is<128; is++) {
for (iadc=0; iadc<nadc; iadc++) {
i=128*ip+is;
adc4=(int)iadc/4;
if (i<sc_width*sc_height) {
// for (int i=0; i<sc_width*sc_height; i++) {
col=adc_nr[iadc]+(i%sc_width);
if (adc4%2==0) {
row=199-i/sc_width;
} else {
row=200+i/sc_width;
}
dataMap[row][col]=(nadc*i+iadc)*2;//+16*(ip+1);
if (dataMap[row][col]<0 || dataMap[row][col]>=8192*40)
cout << "Error: pointer " << dataMap[row][col] << " out of range "<< endl;
}
}
}
}
int ipacket;
int ibyte;
int ii=0;
for (int ipacket=0; ipacket<npackets; ipacket++) {
for (int ibyte=0; ibyte< 8192/2; ibyte++) {
i=ipacket*8208/2+ibyte;
/* if (ibyte<8) { */
/* //header! */
/* xmap[i]=-1; */
/* ymap[i]=-1; */
/* } else { */
// ii=ibyte+128*32*ipacket;
isample=ii/nadc;
iadc=ii%nadc;
adc4 = (int)iadc/4;
ix=isample%sc_width;
iy=isample/sc_width;
if (adc4%2==0) {
xmap[i]=adc_nr[iadc]+ix;
ymap[i]=ny/2-1-iy;
} else {
xmap[i]=adc_nr[iadc]+ix;
ymap[i]=ny/2+iy;
}
ii++;
// }
}
}
iframe=0;
// cout << "data struct created" << endl;
};
/**
Returns the frame number for the given dataset. Purely virtual func.
\param buff pointer to the dataset
\returns frame number
*/
/* class jfrau_packet_header_t { */
/* public: */
/* unsigned char reserved[4]; */
/* unsigned char packetNumber[1]; */
/* unsigned char frameNumber[3]; */
/* unsigned char bunchid[8]; */
/* }; */
int getFrameNumber(char *buff){return iframe;};//*((int*)(buff+5))&0xffffff;};
/**
Returns the packet number for the given dataset. purely virtual func
\param buff pointer to the dataset
\returns packet number number
*/
int getPacketNumber(char *buff){return 0;}//((*(((int*)(buff+4))))&0xff)+1;};
/* /\** */
/* Loops over a memory slot until a complete frame is found (i.e. all packets 0 to nPackets, same frame number). purely virtual func */
/* \param data pointer to the memory to be analyzed */
/* \param ndata reference to the amount of data found for the frame, in case the frame is incomplete at the end of the memory slot */
/* \param dsize size of the memory slot to be analyzed */
/* \returns pointer to the beginning of the last good frame (might be incomplete if ndata smaller than dataSize), or NULL if no frame is found */
/* *\/ */
/* virtual char *findNextFrame(char *data, int &ndata, int dsize){ndata=dsize; setDataSize(dsize); return data;}; */
/* /\** */
/* Loops over a file stream until a complete frame is found (i.e. all packets 0 to nPackets, same frame number). Can be overloaded for different kind of detectors! */
/* \param filebin input file stream (binary) */
/* \returns pointer to the begin of the last good frame, NULL if no frame is found or last frame is incomplete */
/* *\/ */
/* virtual char *readNextFrame(ifstream &filebin){ */
/* // int afifo_length=0; */
/* uint16_t *afifo_cont; */
/* int ib=0; */
/* if (filebin.is_open()) { */
/* afifo_cont=new uint16_t[dataSize/2]; */
/* while (filebin.read(((char*)afifo_cont)+ib,2)) { */
/* ib+=2; */
/* if (ib==dataSize) break; */
/* } */
/* if (ib>0) { */
/* iframe++; */
/* // cout << ib << "-" << endl; */
/* return (char*)afifo_cont; */
/* } else { */
/* delete [] afifo_cont; */
/* return NULL; */
/* } */
/* } */
/* return NULL; */
/* }; */
virtual char *readNextFrame(ifstream &filebin) {
int ff=-1, np=-1;
return readNextFrame(filebin, ff, np);
};
virtual char *readNextFrame(ifstream &filebin, int &ff) {
int np=-1;
return readNextFrame(filebin, ff, np);
};
virtual char *readNextFrame(ifstream &filebin, int& ff, int &np) {
char *data=new char[packetSize*nPackets];
char *d=readNextFrame(filebin, ff, np, data);
if (d==NULL) {delete [] data; data=NULL;}
return data;
}
virtual char *readNextFrame(ifstream &filebin, int& ff, int &np, char *data) {
char *retval=0;
int nd;
int fnum = -1;
np=0;
int pn;
if (ff>=0)
fnum=ff;
if (filebin.is_open()) {
if (filebin.read(data, packetSize*nPackets) ){
iframe++;
ff=iframe;
return data;
}
}
return NULL;
};
/**
Loops over a memory slot until a complete frame is found (i.e. all packets 0 to nPackets, same frame number). purely virtual func
\param data pointer to the memory to be analyzed
\param ndata reference to the amount of data found for the frame, in case the frame is incomplete at the end of the memory slot
\param dsize size of the memory slot to be analyzed
\returns pointer to the beginning of the last good frame (might be incomplete if ndata smaller than dataSize), or NULL if no frame is found
*/
virtual char *findNextFrame(char *data, int &ndata, int dsize){
if (dsize<packetSize*nPackets) ndata=dsize;
else ndata=packetSize*nPackets;
return data;
}
int getPacketNumber(int x, int y) {return dataMap[y][x]/packetSize;};
};
#endif

View File

@ -1,9 +1,11 @@
set(SOURCES
src/multiSlsDetector.cpp
src/multiSlsDetectorClient.cpp
src/slsDetectorUsers.cpp
src/slsDetectorCommand.cpp
src/slsDetector.cpp
src/Detector.cpp
src/CmdProxy.cpp
)
set(HEADERS

View File

@ -0,0 +1,198 @@
#pragma once
#include "Detector.h"
#include "Result.h"
#include "sls_detector_exceptions.h"
#include <iostream>
#include <map>
#include <string>
#include <vector>
/** Macro to make an integer command.
* CMDNAME name of the function that does the command
* GETFCN Detector function to get
* SETFCN Detector function to set
* CONV Function to convert from string to the correct integer type
* HLPSTR Help string for --help and docs
*/
#define INTEGER_COMMAND(CMDNAME, GETFCN, SETFCN, CONV, HLPSTR) \
std::string CMDNAME(const int action) { \
std::ostringstream os; \
os << cmd << ' '; \
if (action == slsDetectorDefs::HELP_ACTION) \
os << HLPSTR << '\n'; \
else if (action == slsDetectorDefs::GET_ACTION) { \
auto t = det->GETFCN({det_id}); \
if (args.size() == 0) { \
os << OutString(t) << '\n'; \
} else { \
WrongNumberOfParameters(2); \
} \
} else if (action == slsDetectorDefs::PUT_ACTION) { \
if (args.size() == 1) { \
auto val = CONV(args[0]); \
det->SETFCN(val, {det_id}); \
os << args.front() << '\n'; \
} else { \
WrongNumberOfParameters(1); \
} \
\
} else { \
throw sls::RuntimeError("Unknown action"); \
} \
return os.str(); \
}
#define INTEGER_COMMAND_NOID(CMDNAME, GETFCN, SETFCN, CONV, HLPSTR) \
std::string CMDNAME(const int action) { \
std::ostringstream os; \
os << cmd << ' '; \
if (action == slsDetectorDefs::HELP_ACTION) \
os << HLPSTR << '\n'; \
else if (action == slsDetectorDefs::GET_ACTION) { \
auto t = det->GETFCN(); \
if (args.size() == 0) { \
os << OutString(t) << '\n'; \
} else { \
WrongNumberOfParameters(2); \
} \
} else if (action == slsDetectorDefs::PUT_ACTION) { \
if (args.size() == 1) { \
auto val = CONV(args[0]); \
det->SETFCN(val); \
os << args.front() << '\n'; \
} else { \
WrongNumberOfParameters(1); \
} \
\
} else { \
throw sls::RuntimeError("Unknown action"); \
} \
return os.str(); \
}
namespace sls {
class CmdProxy {
public:
explicit CmdProxy(Detector *ptr) : det(ptr) {}
std::string Call(const std::string &command,
const std::vector<std::string> &arguments, int detector_id,
int action = -1, std::ostream &os = std::cout);
bool ReplaceIfDepreciated(std::string &command);
size_t GetFunctionMapSize() const noexcept { return functions.size(); };
std::vector<std::string> GetAllCommands();
std::vector<std::string> GetProxyCommands();
private:
Detector *det;
std::string cmd;
std::vector<std::string> args;
int det_id{-1};
template <typename V> std::string OutString(const V &value) {
if (value.equal())
return ToString(value.front());
return ToString(value);
}
template <typename V>
std::string OutString(const V &value, const std::string &unit) {
if (value.equal())
return ToString(value.front(), unit);
return ToString(value, unit);
}
using FunctionMap = std::map<std::string, std::string (CmdProxy::*)(int)>;
using StringMap = std::map<std::string, std::string>;
// Initialize maps for translating name and function
FunctionMap functions{{"list", &CmdProxy::ListCommands},
{"exptime", &CmdProxy::Exptime},
{"period", &CmdProxy::Period},
{"subexptime", &CmdProxy::SubExptime},
{"frames", &CmdProxy::frames},
{"fwrite", &CmdProxy::fwrite},
{"fmaster", &CmdProxy::fmaster},
{"foverwrite", &CmdProxy::foverwrite},
{"findex", &CmdProxy::findex},
{"rx_fifodepth", &CmdProxy::rx_fifodepth},
{"rx_silent", &CmdProxy::rx_silent},
{"rx_lock", &CmdProxy::rx_lock},
{"lock", &CmdProxy::lock},
{"rx_readfreq", &CmdProxy::rx_readfreq},
{"rx_padding", &CmdProxy::rx_padding},
{"rx_framesperfile", &CmdProxy::rx_framesperfile}};
StringMap depreciated_functions{{"r_readfreq", "rx_readfreq"},
{"r_padding", "rx_padding"},
{"r_silent", "rx_silent"},
{"r_lastclient", "rx_lastclient"},
{"r_lock", "rx_lock"},
{"r_online", "rx_online"},
{"r_checkonline", "rx_checkonline"},
{"r_framesperfile", "rx_framesperfile"},
{"r_discardpolicy", "rx_discardpolicy"},
{"receiverversion", "rx_version"},
{"receiver", "rx_status"},
{"index", "findex"},
{"exitreceiver", "rx_exit"},
{"enablefwrite", "fwrite"},
{"checkrecversion", "rx_checkversion"},
{"masterfile", "fmaster"},
{"outdir", "fpath"},
{"fileformat", "fformat"},
{"overwrite", "foverwrite"}};
void WrongNumberOfParameters(size_t expected);
/* Commands */
std::string ListCommands(int action);
std::string Period(int action);
std::string Exptime(int action);
std::string SubExptime(int action);
INTEGER_COMMAND(
rx_fifodepth, getRxFifoDepth, setRxFifoDepth, std::stoi,
"[n_frames]\n\tSet the number of frames in the receiver fifo");
INTEGER_COMMAND(rx_silent, getRxSilentMode, setRxSilentMode, std::stoi,
"[0, 1]\n\tSwitch on or off receiver text output");
INTEGER_COMMAND(rx_lock, getRxLock, setRxLock, std::stoi,
"[0, 1]\n\tLock receiver to one IP, 1: locks");
INTEGER_COMMAND(lock, getDetectorLock, setDetectorLock, std::stoi,
"[0, 1]\n\tLock detector to one IP, 1: locks");
INTEGER_COMMAND(rx_readfreq, getRxZmqFrequency, setRxZmqFrequency,
std::stoi, "[nth frame]\n\tStream out every nth frame");
INTEGER_COMMAND(rx_padding, getPartialFramesPadding,
setPartialFramesPadding, std::stoi,
"[0, 1]\n\tgets partial frames padding enable in the "
"receiver. 0 does not pad partial frames(fastest), 1 "
"(default) pads partial frames");
INTEGER_COMMAND(rx_framesperfile, getFramesPerFile, setFramesPerFile,
std::stoi, "[n_frames]\n\tNumber of frames per file");
INTEGER_COMMAND_NOID(frames, getNumberOfFrames, setNumberOfFrames,
std::stol,
"[n_frames]\n\tNumber of frames per aquire");
INTEGER_COMMAND(fwrite, getFileWrite, setFileWrite, std::stoi,
"[0, 1]\n\tEnable or disable receiver file write");
INTEGER_COMMAND(fmaster, getMasterFileWrite, setMasterFileWrite, std::stoi,
"[0, 1]\n\tEnable or disable receiver master file");
INTEGER_COMMAND(foverwrite, getFileOverWrite, setFileOverWrite, std::stoi,
"[0, 1]\n\tEnable or disable file overwriting");
INTEGER_COMMAND(findex, getAcquisitionIndex, setAcquisitionIndex, std::stoi,
"[0, 1]\n\tFile index");
};
} // namespace sls

View File

@ -488,7 +488,7 @@ class Detector {
*/
void setFileNamePrefix(const std::string &fname, Positions pos = {});
Result<int> getAcquisitonIndex(Positions pos = {}) const;
Result<int> getAcquisitionIndex(Positions pos = {}) const;
void setAcquisitionIndex(int i, Positions pos = {});

View File

@ -1,144 +1,23 @@
#pragma once
#include <iostream>
#include <string>
#include "CmdLineParser.h"
#include "CmdProxy.h"
#include "Detector.h"
#include "container_utils.h"
#include "multiSlsDetector.h"
#include "slsDetectorCommand.h"
#include "sls_detector_exceptions.h"
#include "string_utils.h"
#include <cstdlib>
#include <memory>
using sls::RuntimeError;
inline int dummyCallback(detectorData *d, int p, void *) {
std::cout << "got data " << p << std::endl;
return 0;
};
class multiSlsDetector;
class multiSlsDetectorClient {
public:
multiSlsDetectorClient(int argc, char *argv[], int action,
multiSlsDetector *myDetector = nullptr,
std::ostream &output = std::cout)
: action_(action), detPtr(myDetector), os(output) {
parser.Parse(argc, argv);
if (parser.isHelp())
action_ = slsDetectorDefs::HELP_ACTION;
runCommand();
}
std::ostream &output = std::cout);
multiSlsDetectorClient(const std::string &args, int action,
multiSlsDetector *myDetector = nullptr,
std::ostream &output = std::cout)
: action_(action), detPtr(myDetector), os(output) {
parser.Parse(args);
if (parser.isHelp())
action_ = slsDetectorDefs::HELP_ACTION;
runCommand();
}
std::ostream &output = std::cout);
private:
int action_;
CmdLineParser parser;
sls::CmdLineParser parser;
multiSlsDetector *detPtr = nullptr;
std::ostream &os;
void runCommand() {
bool verify = true;
bool update = true;
if (action_ == slsDetectorDefs::PUT_ACTION &&
parser.n_arguments() == 0) {
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 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 is out of bounds.\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<sls::Detector> proxy(&d);
// sls::CmdProxy<multiSlsDetector> proxy(detPtr);
auto cmd = proxy.Call(parser.command(), parser.arguments(),
parser.detector_id(), action_);
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;
}
void runCommand();
};

View File

@ -52,12 +52,10 @@ class slsDetectorCommand : public virtual slsDetectorDefs {
static std::string helpTrimEn(int action);
static std::string helpOutDir(int action);
static std::string helpFileName(int action);
static std::string helpFileIndex(int action);
static std::string helpRateCorr(int action);
static std::string helpThreaded(int action);
static std::string helpNetworkParameter(int action);
static std::string helpPort(int action);
static std::string helpLock(int action);
static std::string helpLastClient(int action);
static std::string helpOnline(int action);
static std::string helpConfigureMac(int action);
@ -76,26 +74,12 @@ class slsDetectorCommand : public virtual slsDetectorDefs {
static std::string helpCounter(int action);
static std::string helpADC(int action);
static std::string helpTempControl(int action);
static std::string helpEnablefwrite(int action);
static std::string helpOverwrite(int action);
static std::string helpReceiver(int action);
static std::string helpPattern(int action);
static std::string helpPulse(int action);
static std::string helpProcessor(int action);
private:
multiSlsDetector *myDet;
std::string cmdUnderDevelopment(int narg, const char * const args[], int action, int detPos = -1);
@ -113,11 +97,9 @@ class slsDetectorCommand : public virtual slsDetectorDefs {
std::string cmdTrimEn(int narg, const char * const args[], int action, int detPos = -1);
std::string cmdOutDir(int narg, const char * const args[], int action, int detPos = -1);
std::string cmdFileName(int narg, const char * const args[], int action, int detPos = -1);
std::string cmdFileIndex(int narg, const char * const args[], int action, int detPos = -1);
std::string cmdRateCorr(int narg, const char * const args[], int action, int detPos = -1);
std::string cmdNetworkParameter(int narg, const char * const args[], int action, int detPos = -1);
std::string cmdPort(int narg, const char * const args[], int action, int detPos = -1);
std::string cmdLock(int narg, const char * const args[], int action, int detPos = -1);
std::string cmdLastClient(int narg, const char * const args[], int action, int detPos = -1);
std::string cmdOnline(int narg, const char * const args[], int action, int detPos = -1);
std::string cmdConfigureMac(int narg, const char * const args[], int action, int detPos = -1);
@ -136,8 +118,6 @@ class slsDetectorCommand : public virtual slsDetectorDefs {
std::string cmdCounter(int narg, const char * const args[], int action, int detPos = -1);
std::string cmdADC(int narg, const char * const args[], int action, int detPos = -1);
std::string cmdTempControl(int narg, const char * const args[], int action, int detPos = -1);
std::string cmdEnablefwrite(int narg, const char * const args[], int action, int detPos = -1);
std::string cmdOverwrite(int narg, const char * const args[], int action, int detPos = -1);
std::string cmdReceiver(int narg, const char * const args[], int action, int detPos = -1);
std::string cmdPattern(int narg, const char * const args[], int action, int detPos = -1);
std::string cmdPulse(int narg, const char * const args[], int action, int detPos = -1);

View File

@ -0,0 +1,184 @@
#include "CmdProxy.h"
#include "TimeHelper.h"
#include "ToString.h"
#include "logger.h"
#include "slsDetectorCommand.h"
#include "sls_detector_defs.h"
#include <iomanip>
#include <iostream>
#include <sstream>
#include <vector>
#define TIME_COMMAND(GETFCN, SETFCN, HLPSTR) \
std::ostringstream os; \
os << cmd << ' '; \
if (action == slsDetectorDefs::HELP_ACTION) \
os << HLPSTR << '\n'; \
else if (action == slsDetectorDefs::GET_ACTION) { \
auto t = det->GETFCN({det_id}); \
if (args.size() == 0) { \
os << OutString(t) << '\n'; \
} else if (args.size() == 1) { \
os << OutString(t, args[0]) << '\n'; \
} else { \
WrongNumberOfParameters(2); \
} \
} else if (action == slsDetectorDefs::PUT_ACTION) { \
if (args.size() == 1) { \
std::string time_str(args[0]); \
std::string unit = RemoveUnit(time_str); \
auto t = StringTo<time::ns>(time_str, unit); \
det->SETFCN(t, {det_id}); \
} else if (args.size() == 2) { \
auto t = StringTo<time::ns>(args[0], args[1]); \
det->SETFCN(t, {det_id}); \
} else { \
WrongNumberOfParameters(2); \
} \
os << args << '\n'; \
} else { \
throw sls::RuntimeError("Unknown action"); \
} \
return os.str();
namespace sls {
std::ostream &operator<<(std::ostream &os,
const std::vector<std::string> &vec) {
if (!vec.empty()) {
auto it = vec.begin();
os << *it++;
while (it != vec.end())
os << ' ' << *it++;
}
return os;
}
std::string CmdProxy::Call(const std::string &command,
const std::vector<std::string> &arguments,
int detector_id, int action, std::ostream &os) {
cmd = command;
args = arguments;
det_id = detector_id;
ReplaceIfDepreciated(cmd);
auto it = functions.find(cmd);
if (it != functions.end()) {
os << ((*this).*(it->second))(action);
return {};
} else {
return cmd;
}
}
bool CmdProxy::ReplaceIfDepreciated(std::string &command) {
auto d_it = depreciated_functions.find(command);
if (d_it != depreciated_functions.end()) {
FILE_LOG(logWARNING)
<< command
<< " is depreciated and will be removed. Please migrate to: "
<< d_it->second;
command = d_it->second;
return true;
}
return false;
}
std::vector<std::string> CmdProxy::GetAllCommands() {
auto commands = slsDetectorCommand(nullptr).getAllCommands();
for (const auto &it : functions)
commands.emplace_back(it.first);
std::sort(begin(commands), end(commands));
return commands;
}
std::vector<std::string> CmdProxy::GetProxyCommands() {
std::vector<std::string> commands;
for (const auto &it : functions)
commands.emplace_back(it.first);
std::sort(begin(commands), end(commands));
return commands;
}
void CmdProxy::WrongNumberOfParameters(size_t expected) {
throw RuntimeError(
"Command " + cmd + " expected <=" + std::to_string(expected) +
" parameter/s but got " + std::to_string(args.size()) + "\n");
}
/************************************************
* *
* COMMANDS *
* *
************************************************/
std::string CmdProxy::Period(int action) {
TIME_COMMAND(getPeriod, setPeriod,
"[duration] [(optional unit) ns|us|ms|s]\n\tSet the period");
}
std::string CmdProxy::Exptime(int action) {
TIME_COMMAND(
getExptime, setExptime,
"[duration] [(optional unit) ns|us|ms|s]\n\tSet the exposure time");
}
std::string CmdProxy::SubExptime(int action) {
TIME_COMMAND(getSubExptime, setSubExptime,
"[duration] [(optional unit) ns|us|ms|s]\n\tSet the "
"exposure time of EIGER subframes");
}
std::string CmdProxy::ListCommands(int action) {
if (action == slsDetectorDefs::HELP_ACTION)
return "list\n\tlists all available commands, list deprecated - "
"list deprecated commands\n";
if (args.size() == 0) {
auto commands = slsDetectorCommand(nullptr).getAllCommands();
for (const auto &it : functions)
commands.emplace_back(it.first);
std::sort(begin(commands), end(commands));
std::cout << "These " << commands.size() << " commands are available\n";
for (auto &c : commands)
std::cout << c << '\n';
return "";
} else if (args.size() == 1) {
if (args[0] == "deprecated") {
std::cout << "The following " << depreciated_functions.size()
<< " commands are deprecated\n";
size_t field_width = 20;
for (const auto &it : depreciated_functions) {
std::cout << std::right << std::setw(field_width) << it.first
<< " -> " << it.second << '\n';
}
return "";
} else if (args[0] == "migrated") {
std::cout << "The following " << functions.size()
<< " commands have been migrated to the new API\n";
for (const auto &it : functions) {
std::cout << it.first << '\n';
}
return "";
} else {
throw RuntimeError(
"Could not decode argument. Possible options: deprecated");
}
} else {
WrongNumberOfParameters(1);
return "";
}
}
} // namespace sls

View File

@ -578,7 +578,7 @@ void Detector::setFileNamePrefix(const std::string &fname, Positions pos) {
pimpl->Parallel(&slsDetector::setFileName, pos, fname);
}
Result<int> Detector::getAcquisitonIndex(Positions pos) const {
Result<int> Detector::getAcquisitionIndex(Positions pos) const {
return pimpl->Parallel(&slsDetector::getFileIndex, pos);
}
@ -631,7 +631,7 @@ void Detector::setRxZmqDataStream(bool enable, Positions pos) {
}
Result<int> Detector::getRxZmqFrequency(Positions pos) const {
return pimpl->Parallel(&slsDetector::setReceiverStreamingTimer, pos, -1);
return pimpl->Parallel(&slsDetector::setReceiverStreamingFrequency, pos, -1);
}
void Detector::setRxZmqFrequency(int freq, Positions pos) {

View File

@ -0,0 +1,118 @@
#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.n_arguments() == 0) {
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 is out of bounds.\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

@ -534,27 +534,6 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) {
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdTiming;
++i;
/*! \page timing
- <b>exptime [i]</b> sets/gets exposure time in s. \c Returns \c (double with 9 decimal digits)
*/
descrToFuncMap[i].m_pFuncName = "exptime";
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdTimer;
++i;
/*! \page timing
- <b>subexptime [i]</b> sets/gets sub exposure time in s. Used in EIGER only in 32 bit mode. \c Returns \c (double with 9 decimal digits)
*/
descrToFuncMap[i].m_pFuncName = "subexptime";
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdTimer;
++i;
/*! \page timing
- <b>period [i]</b> sets/gets frame period in s. \c Returns \c (double with 9 decimal digits)
*/
descrToFuncMap[i].m_pFuncName = "period";
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdTimer;
++i;
/*! \page timing
- <b>subdeadtime [i]</b> sets/gets sub frame dead time in s. Subperiod is set in the detector = subexptime + subdeadtime. This value is normally a constant in the config file. Used in EIGER only in 32 bit mode. \c Returns \c (double with 9 decimal digits)
*/
@ -569,12 +548,6 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) {
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdTimer;
++i;
/*! \page timing
- <b>frames [i]</b> sets/gets number of frames. If \c timing is not \c auto, then it is the number of frames per cycle/trigger. \c Returns \c (long long int)
*/
descrToFuncMap[i].m_pFuncName = "frames";
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdTimer;
++i;
/*! \page timing
- <b>startingfnum [i]</b> sets/gets starting frame number for the next acquisition. Only for Jungfrau and Eiger. \c Returns \c (long long int)
@ -1502,39 +1475,11 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) {
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdFileName;
++i;
/*! \page output
- <b>findex [i]</b> Sets/gets the current file index. \c Returns \c (int)
*/
descrToFuncMap[i].m_pFuncName = "findex";
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdFileIndex;
++i;
/*! \page output
- <b>fwrite [i]</b> Enables/disables file writing. 1 enables, 0 disables. \c Returns \c (int)
*/
descrToFuncMap[i].m_pFuncName = "fwrite";
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdEnablefwrite;
++i;
/*! \page output
- <b>foverwrite [i]</b> enables(1) /disables(0) file overwriting. \c Returns \c (int)
*/
descrToFuncMap[i].m_pFuncName = "foverwrite";
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdOverwrite;
++i;
/*! \page output
- <b>fformat [i]</b> sets/gets the file format for data in receiver. Options: [binary, hdf5]. \c Returns \c (string)
*/
descrToFuncMap[i].m_pFuncName = "fformat";
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdFileName;
++i;
/*! \page output
- <b>fmaster [i]</b> sets/gets the master file write enable in receiver. \c Returns \c (int)
*/
descrToFuncMap[i].m_pFuncName = "fmaster";
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdEnablefwrite;
++i;
/* communication configuration */
@ -1736,13 +1681,6 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) {
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdPort;
++i;
/*! \page network
- <b>lock [i]</b> Locks/Unlocks the detector to communicate with this client. 1 locks, 0 unlocks. \c Returns \c (int)
*/
descrToFuncMap[i].m_pFuncName = "lock";
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdLock;
++i;
/*! \page network
- <b>lastclient </b> Gets the last client communicating with the detector. Cannot put!. \c Returns \c (string)
*/
@ -1784,13 +1722,6 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) {
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdReceiver;
++i;
/*! \page receiver
- <b>rx_lock [i]</b> locks/unlocks the receiver to communicate with only this client. 1 locks, 0 unlocks. \c Returns \c (int)
*/
descrToFuncMap[i].m_pFuncName = "rx_lock";
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdLock;
++i;
/*! \page receiver
- <b>rx_lastclient</b> gets the last client communicating with the receiver. Only get! \c Returns \c (int)
*/
@ -1798,27 +1729,6 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) {
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdLastClient;
++i;
/*! \page receiver
- <b>rx_readfreq [i]</b> sets/gets the stream frequency of data from receiver to client. i > 0 is the nth frame being streamed. 0 sets frequency to a default timer (200ms). Default: sends every frame \c Returns \c (int)
*/
descrToFuncMap[i].m_pFuncName = "rx_readfreq";
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdReceiver;
++i;
/*! \page receiver
- <b>rx_fifodepth [i]</b> sets/gets receiver fifo (between Listener and Writer Threads) depth to i number of frames. Can improve listener packet loss (loss due to packet processing time in Listener threads), not if limited by writing. \c Returns \c (int)
*/
descrToFuncMap[i].m_pFuncName = "rx_fifodepth";
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdReceiver;
++i;
/*! \page receiver
- <b>rx_silent [i]</b> sets/gets receiver in silent mode, ie. it will not print anything during real time acquisition. 1 sets, 0 unsets. \c Returns \c (int)
*/
descrToFuncMap[i].m_pFuncName = "rx_silent";
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdReceiver;
++i;
/*! \page receiver
- <b>rx_framesperfile [i]</b> sets/gets the frames per file in receiver to i. 0 means infinite or all frames in a single file. \c Returns \c (int)
*/
@ -1833,13 +1743,6 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) {
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdReceiver;
++i;
/*! \page receiver
- <b>rx_padding</b> sets/gets the frame padding in the receiver. 0 does not pad partial frames(fastest), 1 (default) pads partial frames. \c Returns \c (int)
*/
descrToFuncMap[i].m_pFuncName = "rx_padding";
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdReceiver;
++i;
/*! \page receiver
- <b>rx_jsonaddheader [t]</b> sets/gets additional json header to be streamed out with the zmq from receiver. Default is empty. \c t must be in the format "\"label1\":\"value1\",\"label2\":\"value2\"" etc. Use only if it needs to be processed by an intermediate process. \c Returns \c (string)
*/
@ -2565,94 +2468,6 @@ std::string slsDetectorCommand::helpFileName(int action) {
return os.str();
}
std::string slsDetectorCommand::cmdEnablefwrite(int narg, const char * const args[], int action, int detPos) {
int i;
char ans[100];
if (action == HELP_ACTION) {
return helpEnablefwrite(action);
}
if (cmd == "fwrite") {
if (action == PUT_ACTION) {
if (sscanf(args[1], "%d", &i))
myDet->setFileWrite(i, detPos);
else
return std::string("could not decode enable file write");
}
sprintf(ans, "%d", myDet->getFileWrite(detPos));
return std::string(ans);
}
else if (cmd == "fmaster") {
if (action == PUT_ACTION) {
if (sscanf(args[1], "%d", &i))
myDet->setMasterFileWrite(i, detPos);
else
return std::string("could not decode master file enable");
}
sprintf(ans, "%d", myDet->getMasterFileWrite(detPos));
return std::string(ans);
}
else return std::string("unknown command " + cmd);
}
std::string slsDetectorCommand::helpEnablefwrite(int action) {
std::ostringstream os;
if (action == GET_ACTION || action == HELP_ACTION) {
os << std::string("fwrite \t When Enabled writes the data into the file\n");
os << std::string("fmaster \t When Enabled writes the master file\n");
}
if (action == PUT_ACTION || action == HELP_ACTION) {
os << std::string("fwrite i \t should be 1 or 0\n");
os << std::string("fmaster i \t sets the master file write enable. should be 1 or 0\n");
}
return os.str();
}
std::string slsDetectorCommand::cmdOverwrite(int narg, const char * const args[], int action, int detPos) {
int i;
char ans[100];
if (action == HELP_ACTION) {
return helpOverwrite(action);
}
if (action == PUT_ACTION) {
if (sscanf(args[1], "%d", &i))
myDet->setFileOverWrite(i, detPos);
else
return std::string("could not decode foverwrite");
}
sprintf(ans, "%d", myDet->getFileOverWrite(detPos));
return std::string(ans);
}
std::string slsDetectorCommand::helpOverwrite(int action) {
std::ostringstream os;
if (action == GET_ACTION || action == HELP_ACTION)
os << std::string("foverwrite \t When Enabled overwrites files\n");
if (action == PUT_ACTION || action == HELP_ACTION)
os << std::string("foverwrite i \t should be 1 or 0 or -1\n");
return os.str();
}
std::string slsDetectorCommand::cmdFileIndex(int narg, const char * const args[], int action, int detPos) {
if (action == HELP_ACTION) {
return helpFileName(action);
} else if (action == PUT_ACTION) {
int i = std::stoi(args[1]);
myDet->setFileIndex(i, detPos);
}
return std::to_string(myDet->getFileIndex(detPos));
}
std::string slsDetectorCommand::helpFileIndex(int action) {
std::ostringstream os;
if (action == GET_ACTION || action == HELP_ACTION)
os << std::string("findex \t gets the file index for the next the data file\n");
if (action == PUT_ACTION || action == HELP_ACTION)
os << std::string("findex i \t sets the fileindex for the next data file\n");
return os.str();
}
std::string slsDetectorCommand::cmdRateCorr(int narg, const char * const args[], int action, int detPos) {
@ -3040,55 +2855,6 @@ std::string slsDetectorCommand::helpPort(int action) {
return os.str();
}
std::string slsDetectorCommand::cmdLock(int narg, const char * const args[], int action, int detPos) {
if (action == HELP_ACTION)
return helpLock(action);
int val; //, ret;
char ans[1000];
if (cmd == "lock") {
if (action == PUT_ACTION) {
if (sscanf(args[1], "%d", &val))
myDet->lockServer(val, detPos);
else
return std::string("could not lock status") + std::string(args[1]);
}
sprintf(ans, "%d", myDet->lockServer(-1, detPos));
}
else if (cmd == "rx_lock") {
if (action == PUT_ACTION) {
if (sscanf(args[1], "%d", &val))
myDet->lockReceiver(val, detPos);
else
return std::string("could not decode lock status") + std::string(args[1]);
}
sprintf(ans, "%d", myDet->lockReceiver(-1, detPos));
}
else
return std::string("could not decode command");
return std::string(ans);
}
std::string slsDetectorCommand::helpLock(int action) {
std::ostringstream os;
if (action == PUT_ACTION || action == HELP_ACTION) {
os << "lock i \n locks (1) or unlocks (0) the detector to communicate to this client" << std::endl;
os << "rx_lock i \n locks (1) or unlocks (0) the receiver to communicate to this client" << std::endl;
}
if (action == GET_ACTION || action == HELP_ACTION) {
os << "lock \n returns the detector lock status" << std::endl;
os << "rx_lock \n returns the receiver lock status" << std::endl;
}
return os.str();
}
std::string slsDetectorCommand::cmdLastClient(int narg, const char * const args[], int action, int detPos) {
if (action == HELP_ACTION)
@ -4266,8 +4032,6 @@ std::string slsDetectorCommand::cmdTimer(int narg, const char * const args[], in
index = SUBFRAME_DEADTIME;
else if (cmd == "delay")
index = DELAY_AFTER_TRIGGER;
else if (cmd == "frames")
index = FRAME_NUMBER;
else if (cmd == "cycles")
index = CYCLES_NUMBER;
// also does digital sample
@ -4894,18 +4658,7 @@ std::string slsDetectorCommand::cmdReceiver(int narg, const char * const args[],
sprintf(answer, "%lu", myDet->getReceiverCurrentFrameIndex(detPos));
return std::string(answer);
}
} else if (cmd == "rx_readfreq") {
if (action == PUT_ACTION) {
if (!sscanf(args[1], "%d", &ival))
return std::string("Could not scan read frequency mode ") + std::string(args[1]);
if (ival >= 0)
myDet->setReceiverStreamingFrequency(ival, detPos);
}
sprintf(answer, "%d", myDet->setReceiverStreamingFrequency(-1, detPos));
return std::string(answer);
}
else if (cmd == "tengiga") {
if (action == PUT_ACTION) {
if (!sscanf(args[1], "%d", &ival))
@ -4918,30 +4671,6 @@ std::string slsDetectorCommand::cmdReceiver(int narg, const char * const args[],
}
else if (cmd == "rx_fifodepth") {
if (action == PUT_ACTION) {
if (!sscanf(args[1], "%d", &ival))
return std::string("Could not scan rx_fifodepth input ") + std::string(args[1]);
if (ival >= 0)
sprintf(answer, "%d", myDet->setReceiverFifoDepth(ival, detPos));
} else
sprintf(answer, "%d", myDet->setReceiverFifoDepth(-1, detPos));
return std::string(answer);
}
else if (cmd == "rx_silent") {
if (action == PUT_ACTION) {
if (!sscanf(args[1], "%d", &ival))
return std::string("Could not scan rx_silent input ") + std::string(args[1]);
if (ival >= 0)
sprintf(answer, "%d", myDet->setReceiverSilentMode(ival, detPos));
} else
sprintf(answer, "%d", myDet->setReceiverSilentMode(-1, detPos));
return std::string(answer);
}
else if (cmd == "rx_framesperfile") {
if (action == PUT_ACTION) {
if (sscanf(args[1], "%d", &ival)) {
@ -4964,18 +4693,6 @@ std::string slsDetectorCommand::cmdReceiver(int narg, const char * const args[],
return myDet->getReceiverFrameDiscardPolicy(myDet->setReceiverFramesDiscardPolicy(GET_FRAME_DISCARD_POLICY, detPos));
}
else if (cmd == "rx_padding") {
if (action == PUT_ACTION) {
if (sscanf(args[1], "%d", &ival)) {
myDet->setPartialFramesPadding(ival, detPos);
} else
return std::string("could not scan receiver padding enable\n");
}
memset(answer, 0, 100);
sprintf(answer, "%d", myDet->getPartialFramesPadding(detPos));
return std::string(answer);
}
else if (cmd == "rx_jsonaddheader") {
if (action == PUT_ACTION) {
myDet->setAdditionalJsonHeader(args[1], detPos);

View File

@ -1,6 +1,8 @@
#include "multiSlsDetectorClient.h"
#include "sls_detector_defs.h"
#include "versionAPI.h"
#include <cstdlib>
#include <cstring> //strcmp
int main(int argc, char *argv[]) {
for (int i = 1; i < argc; ++i) {

View File

@ -156,3 +156,19 @@ TEST_CASE("Sorting a Result"){
REQUIRE(res[2] == 4);
REQUIRE(res[3] == 5);
}
TEST_CASE("Printing Result<std::string>"){
Result<std::string> res{"ein", "zwei", "drei"};
std::ostringstream os;
os << res;
REQUIRE(os.str() == "[ein, zwei, drei]");
}
TEST_CASE("Printing Result<int>"){
Result<int> res{1, 2, 3};
std::ostringstream os;
os << res;
REQUIRE(os.str() == "[1, 2, 3]");
}

View File

@ -376,6 +376,25 @@ TEST_CASE("rx_lock", "[.cmd]") {
}
}
TEST_CASE("lock", "[.cmd]") {
{
std::ostringstream oss;
multiSlsDetectorClient("lock 1", PUT, nullptr, oss);
REQUIRE(oss.str() == "lock 1\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("lock", GET, nullptr, oss);
REQUIRE(oss.str() == "lock 1\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("lock 0", PUT, nullptr, oss);
REQUIRE(oss.str() == "lock 0\n");
}
}
TEST_CASE("rx_lastclient", "[.cmd]") {
std::ostringstream oss;
@ -384,12 +403,6 @@ TEST_CASE("rx_lastclient", "[.cmd]") {
}
TEST_CASE("rx_checkonline", "[.cmd]") {
std::ostringstream oss;
multiSlsDetectorClient("rx_checkonline", GET, nullptr, oss);
REQUIRE(oss.str() == "rx_checkonline All receiver online\n");
}
TEST_CASE("rx_checkversion", "[.cmd]") {
@ -402,34 +415,35 @@ TEST_CASE("exptime", "[.cmd]") {
{
std::ostringstream oss;
multiSlsDetectorClient("exptime 0.05", PUT, nullptr, oss);
REQUIRE(oss.str() == "exptime 0.050000000\n");
REQUIRE(oss.str() == "exptime 0.05\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("exptime", GET, nullptr, oss);
REQUIRE(oss.str() == "exptime 0.050000000\n");
REQUIRE(oss.str() == "exptime 50ms\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("exptime 1", PUT, nullptr, oss);
REQUIRE(oss.str() == "exptime 1.000000000\n");
REQUIRE(oss.str() == "exptime 1\n");
}
}
// TEST_CASE("exptime2", "[.cmd]") {
// {
// std::ostringstream oss;
// multiSlsDetectorClient("exptime2 0.05", PUT, nullptr, oss);
// REQUIRE(oss.str() == "exptime2 0.05s\n");
// }
// {
// std::ostringstream oss;
// multiSlsDetectorClient("exptime2", GET, nullptr, oss);
// REQUIRE(oss.str() == "exptime2 0.05s\n");
// }
// {
// std::ostringstream oss;
// multiSlsDetectorClient("exptime2 1", PUT, nullptr, oss);
// REQUIRE(oss.str() == "exptime2 1s\n");
// }
// }
TEST_CASE("period", "[.cmd]") {
{
std::ostringstream oss;
multiSlsDetectorClient("period 1.25s", PUT, nullptr, oss);
REQUIRE(oss.str() == "period 1.25s\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("period", GET, nullptr, oss);
REQUIRE(oss.str() == "period 1.25s\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("period 0", PUT, nullptr, oss);
REQUIRE(oss.str() == "period 0\n");
}
}

View File

@ -1,12 +1,13 @@
#ifndef CMD_LINE_PARSER_H
#define CMD_LINE_PARSER_H
#include <stdexcept>
#include <string>
#include <vector>
namespace sls {
class CmdLineParser {
public:
void Parse(int argc, const char * const argv[]);
void Parse(int argc, const char *const argv[]);
void Parse(const std::string &s);
void Print();
@ -14,11 +15,12 @@ class CmdLineParser {
int detector_id() const { return detector_id_; };
int n_arguments() const { return arguments_.size(); }
const std::string &command() const { return command_; }
bool isHelp() const{return help_;}
void setCommand(std::string cmd){command_ = cmd;}
bool isHelp() const { return help_; }
void setCommand(std::string cmd) { command_ = cmd; }
const std::string &executable() const { return executable_; }
const std::vector<std::string> &arguments() const { return arguments_; };
std::vector<const char *> argv() const;
std::string cli_line() const;
private:
void DecodeIdAndPosition(const char *c);
@ -30,4 +32,5 @@ class CmdLineParser {
std::vector<std::string> arguments_;
};
} // namespace sls
#endif // CMD_LINE_PARSER_H

View File

@ -1,214 +0,0 @@
#pragma once
#include <chrono>
#include <iomanip>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>
#include "Result.h"
#include "TimeHelper.h"
#include "ToString.h"
#include "container_utils.h"
#include "logger.h"
#include "slsDetectorCommand.h"
#include "sls_detector_defs.h"
#include "sls_detector_exceptions.h"
#include "string_utils.h"
#define TIME_COMMAND(GETFCN, SETFCN, HLPSTR) \
std::ostringstream os; \
os << cmd << ' '; \
if (action == slsDetectorDefs::HELP_ACTION) \
os << HLPSTR << '\n'; \
else if (action == slsDetectorDefs::GET_ACTION) { \
auto t = det->GETFCN({det_id}); \
if (args.size() == 0) { \
os << OutString(t) << '\n'; \
} else if (args.size() == 1) { \
os << OutString(t, args[0]) << '\n'; \
} else { \
WrongNumberOfParameters(2); \
} \
} else if (action == slsDetectorDefs::PUT_ACTION) { \
if (args.size() == 1) { \
std::string time_str(args[0]); \
std::string unit = RemoveUnit(time_str); \
auto t = StringTo<time::ns>(time_str, unit); \
det->SETFCN(t, {det_id}); \
} else if (args.size() == 2) { \
auto t = StringTo<time::ns>(args[0], args[1]); \
det->SETFCN(t, {det_id}); \
} else { \
WrongNumberOfParameters(2); \
} \
os << ToString(args) << '\n'; \
} else { \
throw sls::RuntimeError("Unknown action"); \
} \
return os.str();
namespace sls {
template <typename T> class CmdProxy {
public:
explicit CmdProxy(T *detectorPtr) : det(detectorPtr) {}
std::string Call(const std::string &command,
const std::vector<std::string> &arguments, int detector_id,
int action = -1, std::ostream &os = std::cout) {
cmd = command;
args = arguments;
det_id = detector_id;
ReplaceIfDepreciated(cmd);
auto it = functions.find(cmd);
if (it != functions.end()) {
os << ((*this).*(it->second))(action);
return {};
} else {
return cmd;
}
}
bool ReplaceIfDepreciated(std::string &command) {
auto d_it = depreciated_functions.find(command);
if (d_it != depreciated_functions.end()) {
FILE_LOG(logWARNING)
<< command
<< " is depreciated and will be removed. Please migrate to: "
<< d_it->second;
command = d_it->second;
return true;
}
return false;
}
size_t GetFunctionMapSize() const noexcept { return functions.size(); };
std::vector<std::string> GetAllCommands() {
auto commands = slsDetectorCommand(nullptr).getAllCommands();
for (const auto &it : functions)
commands.emplace_back(it.first);
std::sort(begin(commands), end(commands));
return commands;
}
std::vector<std::string> GetProxyCommands() {
std::vector<std::string> commands;
for (const auto &it : functions)
commands.emplace_back(it.first);
std::sort(begin(commands), end(commands));
return commands;
}
private:
T *det;
std::string cmd;
std::vector<std::string> args;
int det_id{-1};
template <typename V> std::string OutString(const V &value) {
if (value.equal())
return ToString(value.front());
return ToString(value);
}
template <typename V>
std::string OutString(const V &value, const std::string &unit) {
if (value.equal())
return ToString(value.front(), unit);
return ToString(value, unit);
}
using FunctionMap = std::map<std::string, std::string (CmdProxy::*)(int)>;
using StringMap = std::map<std::string, std::string>;
// Initialize maps for translating name and function
FunctionMap functions{{"list", &CmdProxy::ListCommands},
{"exptime2", &CmdProxy::Exptime},
{"period2", &CmdProxy::Period},
{"subexptime2", &CmdProxy::SubExptime}};
StringMap depreciated_functions{{"r_readfreq", "rx_readfreq"},
{"r_padding", "rx_padding"},
{"r_silent", "rx_silent"},
{"r_lastclient", "rx_lastclient"},
{"r_lock", "rx_lock"},
{"r_online", "rx_online"},
{"r_checkonline", "rx_checkonline"},
{"r_framesperfile", "rx_framesperfile"},
{"r_discardpolicy", "rx_discardpolicy"},
{"receiverversion", "rx_version"},
{"receiver", "rx_status"},
{"index", "findex"},
{"exitreceiver", "rx_exit"},
{"enablefwrite", "fwrite"},
{"checkrecversion", "rx_checkversion"},
{"masterfile", "fmaster"},
{"outdir", "fpath"},
{"fileformat", "fformat"},
{"overwrite", "foverwrite"}};
void WrongNumberOfParameters(size_t expected) {
throw RuntimeError(
"Command " + cmd + " expected <=" + std::to_string(expected) +
" parameter/s but got " + std::to_string(args.size()) + "\n");
}
// Mapped functions
std::string ListCommands(int action) {
if (action == slsDetectorDefs::HELP_ACTION)
return "list\n\tlists all available commands, list deprecated - "
"list deprecated commands\n";
if (args.size() == 0) {
auto commands = slsDetectorCommand(nullptr).getAllCommands();
for (const auto &it : functions)
commands.emplace_back(it.first);
std::sort(begin(commands), end(commands));
std::cout << "These " << commands.size()
<< " commands are available\n";
for (auto &c : commands)
std::cout << c << '\n';
return "";
} else if (args.size() == 1) {
if (args[0] == "deprecated") {
std::cout << "The following " << depreciated_functions.size()
<< " commands are deprecated\n";
size_t field_width = 20;
for (const auto &it : depreciated_functions) {
std::cout << std::right << std::setw(field_width)
<< it.first << " -> " << it.second << '\n';
}
return "";
} else {
throw RuntimeError(
"Could not decode argument. Possible options: deprecated");
}
} else {
WrongNumberOfParameters(1);
return "";
}
}
std::string Period(int action) {
TIME_COMMAND(
getPeriod, setPeriod,
"[duration] [(optional unit) ns|us|ms|s]\n\tSet the period");
}
std::string Exptime(int action) {
TIME_COMMAND(
getExptime, setExptime,
"[duration] [(optional unit) ns|us|ms|s]\n\tSet the exposure time");
}
std::string SubExptime(int action) {
TIME_COMMAND(getSubExptime, setSubExptime,
"[duration] [(optional unit) ns|us|ms|s]\n\tSet the "
"exposure time of EIGER subframes");
}
};
} // namespace sls

View File

@ -19,18 +19,6 @@
namespace sls {
inline std::string ToString(const std::vector<std::string> &vec,
const char delimiter = ' ') {
std::ostringstream os;
if(!vec.empty()){
auto it = vec.begin();
os << *it++;
while(it != vec.end())
os << delimiter << *it++;
}
return os.str();
}
/** Convert std::chrono::duration with specified output unit */
template <typename T, typename Rep = double>
typename std::enable_if<is_duration<T>::value, std::string>::type
@ -84,9 +72,15 @@ ToString(const T &value) {
return std::to_string(value);
}
/** For a container loop over all elements and call ToString */
/**
* For a container loop over all elements and call ToString on the element
* Container<std::string> is excluded
*/
template <typename T>
typename std::enable_if<is_container<T>::value, std::string>::type
typename std::enable_if<
is_container<T>::value &&
!std::is_same<typename T::value_type, std::string>::value,
std::string>::type
ToString(const T &container) {
std::ostringstream os;
os << '[';
@ -100,6 +94,29 @@ ToString(const T &container) {
return os.str();
}
/**
* Special case when container holds a string, don't call ToString again but
* print directly to stream
*/
template <typename T>
typename std::enable_if<
is_container<T>::value &&
std::is_same<typename T::value_type, std::string>::value,
std::string>::type
ToString(const T &vec) {
std::ostringstream os;
os << '[';
if (!vec.empty()) {
auto it = vec.begin();
os << *it++;
while (it != vec.end())
os << ", " << *it++;
}
os << ']';
return os.str();
}
/** Container and specified unit, call ToString(value, unit) */
template <typename T>
typename std::enable_if<is_container<T>::value, std::string>::type

View File

@ -7,6 +7,8 @@
#include <iterator>
#include <sstream>
namespace sls {
void CmdLineParser::Print() {
std::cout << "\nCmdLineParser::Print()\n";
std::cout << "\tmulti_id: " << multi_id_
@ -48,7 +50,7 @@ void CmdLineParser::Parse(const std::string &s) {
end(arguments_));
if (old_size - arguments_.size() > 0)
help_ = true;
if(!arguments_.empty()){
if (!arguments_.empty()) {
command_ = arguments_[0];
arguments_.erase(begin(arguments_));
}
@ -97,3 +99,14 @@ std::vector<const char *> CmdLineParser::argv() const {
}
return vec;
}
std::string CmdLineParser::cli_line() const{
std::ostringstream os;
os << command_;
for (const auto & arg : arguments_)
os << " " << arg;
return os.str();
}
} // namespace sls

View File

@ -9,6 +9,7 @@
// command for all depreciated commands
using vs = std::vector<std::string>;
using sls::CmdLineParser;
SCENARIO("Construction", "[support]") {
GIVEN("A default constructed CmdLineParser") {

View File

@ -99,9 +99,9 @@ TEST_CASE("Convert types with str method"){
TEST_CASE("vector of strings"){
std::vector<std::string> vec{"5", "s"};
REQUIRE(ToString(vec) == "5 s");
REQUIRE(ToString(vec) == "[5, s]");
std::vector<std::string> vec2{"some", "strange", "words", "75"};
REQUIRE(ToString(vec2) == "some strange words 75");
REQUIRE(ToString(vec2) == "[some, strange, words, 75]");
}