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

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

View File

@ -39,9 +39,10 @@ class CmdLineParser {
private:
void DecodeIdAndPosition(const char *c);
void Reset(); // reset all private variables
int multi_id_ = 0;
int detector_id_ = -1;
bool help_{false};
bool help_ = false;
std::string command_;
std::string executable_;
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 "CmdLineParser.h"
#include "CmdProxy.h"
#include "container_utils.h"
#include "detectorData.h"
#include "logger.h"
@ -6,23 +8,78 @@
#include "slsDetector.h"
#include "sls_detector_defs.h"
#include <fstream>
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;
Detector::Detector(int shm_id)
: pimpl(sls::make_unique<multiSlsDetector>(shm_id)) {}
Detector::~Detector() = default;
// Configuration
void Detector::freeSharedMemory() { pimpl->freeSharedMemory(); }
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) {
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 {
@ -69,6 +126,8 @@ Result<defs::detectorType> Detector::getDetectorType(Positions pos) const {
int Detector::size() const { return pimpl->size(); }
bool Detector::empty() const { return pimpl->size() == 0; }
defs::xy Detector::getModuleGeometry() const {
return pimpl->getNumberOfDetectors();
}
@ -166,7 +225,8 @@ Result<ns> Detector::getPeriodLeft(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());
for (unsigned int i = 0; i < res.size(); ++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 {
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) {
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 {
@ -193,11 +255,13 @@ Result<int> Detector::getMaxADCPhaseShift(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) {
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) {
@ -285,11 +349,13 @@ void Detector::setDAC(defs::dacIndex index, int value, bool mV, Positions pos) {
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);
}
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);
}
@ -472,7 +538,8 @@ void Detector::setDestinationUDPPort2(int port, int module_id) {
port_list[idet]);
}
} 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) {
if (module_id == -1) {
std::vector<int> port_list(size());
for (auto &it: port_list) {
for (auto &it : port_list) {
it = port++;
}
for (int idet = 0; idet < size(); ++idet) {
@ -962,7 +1029,7 @@ Result<bool> Detector::getQuad(Positions pos) const {
void Detector::setQuad(const bool value) {
if (value && size() > 1) {
throw RuntimeError("Cannot set Quad type as it is available only for 1 "
"Eiger Quad Half module.");
"Eiger Quad Half module.");
}
pimpl->Parallel(&slsDetector::setQuad, {}, value);
}
@ -1023,7 +1090,8 @@ void Detector::setAutoCompDisable(bool value, Positions pos) {
}
Result<int> Detector::getNumberOfAdditionalStorageCells(Positions pos) const {
return pimpl->Parallel(&slsDetector::getNumberOfAdditionalStorageCells, pos);
return pimpl->Parallel(&slsDetector::getNumberOfAdditionalStorageCells,
pos);
}
void Detector::setNumberOfAdditionalStorageCells(int value) {
@ -1143,11 +1211,13 @@ void Detector::setReadoutMode(defs::readoutMode value, Positions pos) {
}
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) {
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 {
@ -1156,39 +1226,48 @@ Result<int> Detector::getMaxDBITPhaseShift(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) {
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 {
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) {
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 {
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) {
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 {
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) {
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 {
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 {
@ -1340,7 +1419,45 @@ void Detector::setLEDEnable(bool enable, Positions pos) {
// Pattern
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) {
@ -1371,12 +1488,16 @@ void Detector::setPatternWord(int addr, uint64_t word, Positions pos) {
pimpl->Parallel(&slsDetector::setPatternWord, pos, addr, word);
}
Result<std::array<int, 2>> Detector::getPatternLoopAddresses(int level, Positions pos) const {
return pimpl->Parallel(&slsDetector::setPatternLoopAddresses, pos, level, -1, -1);
Result<std::array<int, 2>>
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) {
pimpl->Parallel(&slsDetector::setPatternLoopAddresses, pos, level, start, stop);
void Detector::setPatternLoopAddresses(int level, int start, int stop,
Positions pos) {
pimpl->Parallel(&slsDetector::setPatternLoopAddresses, pos, level, start,
stop);
}
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());
try {
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 (...) {
throw RuntimeError(
@ -1490,7 +1612,8 @@ Result<defs::detectorModeType> Detector::getDetectorMode(Positions pos) const {
Result<defs::detectorModeType> intResult(res.size());
try {
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 (...) {
throw RuntimeError(

View File

@ -4,9 +4,7 @@
#include "detectorData.h"
#include "file_utils.h"
#include "logger.h"
#include "multiSlsDetectorClient.h"
#include "slsDetector.h"
#include "slsDetectorCommand.h"
#include "sls_detector_exceptions.h"
#include "versionAPI.h"
@ -423,32 +421,6 @@ void multiSlsDetector::setNumberOfChannels(const slsDetectorDefs::xy 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) {
Parallel(&slsDetector::enableGapPixels, {}, static_cast<int>(enable));
// update number of channels
@ -922,66 +894,45 @@ bool multiSlsDetector::enableDataStreamingToClient(int enable) {
void multiSlsDetector::savePattern(const std::string &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 = Parallel(&slsDetector::setPatternLoopAddresses, {}, -1, -1, -1)
.tsquash("Inconsistent pattern limits");
// pattern words
for (int i = r[0]; i <= r[1]; ++i) {
std::ostringstream os;
os << "patword 0x" << std::hex << i;
std::string cmd = os.str();
multiSlsDetectorClient(cmd, GET_ACTION, this, 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)
multiSlsDetectorClient(cmd, GET_ACTION, this, outfile);
// 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 = Parallel(&slsDetector::setPatternLoopAddresses, {}, -1, -1, -1)
// .tsquash("Inconsistent pattern limits");
// // pattern words
// for (int i = r[0]; i <= r[1]; ++i) {
// std::ostringstream os;
// os << "patword 0x" << std::hex << i;
// std::string cmd = os.str();
// multiSlsDetectorClient(cmd, GET_ACTION, this, 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)
// 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(

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 "file_utils.h"
#include "network_utils.h"
#include "slsDetectorCommand.h"
#include "sls_detector_exceptions.h"
#include "string_utils.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) {
}
}