trimEn now takes vector

This commit is contained in:
Erik Frojdh
2019-04-04 12:19:30 +02:00
parent c284b24397
commit 85516e42c0
14 changed files with 318 additions and 229 deletions

View File

@@ -1355,16 +1355,15 @@ class multiSlsDetector : public virtual slsDetectorDefs {
* @param detPos -1 for all detectors in list or specific detector position
* @returns number of trim energies
*/
int setTrimEn(int nen, int *en = nullptr, int detPos = -1);
int setTrimEn(std::vector<int> energies, int detPos = -1);
/**
* Returns the number of trim energies and their value (Eiger)
*
* @param en array of energies
* @param detPos -1 for all detectors in list or specific detector position
* @returns number of trim energies
* @returns vector of trim energies
*/
int getTrimEn(int *en = nullptr, int detPos = -1);
std::vector<int> getTrimEn(int detPos = -1);
/**
* Pulse Pixel (Eiger)
@@ -1953,6 +1952,8 @@ class multiSlsDetector : public virtual slsDetectorDefs {
*/
void processData();
void addSlsDetector(std::unique_ptr<slsDetector> det);
private:
/**
* Initialize (open/create) shared memory for the sharedMultiDetector
@@ -1992,14 +1993,16 @@ class multiSlsDetector : public virtual slsDetectorDefs {
*/
void addSlsDetector(const std::string &hostname);
/**
* add gap pixels to the image (only for Eiger in 4 bit mode)
* @param image pointer to image without gap pixels
* @param gpImage poiner to image with gap pixels, if NULL, allocated inside
* function
* @returns number of data bytes of image with gap pixels
*/
int processImageWithGapPixels(char *image, char *&gpImage);
/**
* add gap pixels to the image (only for Eiger in 4 bit mode)
* @param image pointer to image without gap pixels
* @param gpImage poiner to image with gap pixels, if NULL, allocated
* inside function
* @returns number of data bytes of image with gap pixels
*/
int processImageWithGapPixels(char *image, char *&gpImage);
/**
* Set total progress (total number of frames/images in an acquisition)

View File

@@ -1208,18 +1208,17 @@ class slsDetector : public virtual slsDetectorDefs{
* Sets the number of trim energies and their value (Eiger)
* \sa sharedSlsDetector
* @param nen number of energies
* @param en array of energies
* @param vector os trimmed energies
* @returns number of trim energies
*/
int setTrimEn(int nen, int *en = nullptr);
int setTrimEn(std::vector<int> energies={});
/**
* Returns the number of trim energies and their value (Eiger)
* \sa sharedSlsDetector
* @param en array of energies
* @returns number of trim energies
*/
int getTrimEn(int *en = nullptr);
* Returns a vector with the trimmed energies (Eiger)
* \sa sharedSlsDetector
* @returns vector with the trimmed energies
*/
std::vector<int> getTrimEn();
/**
* Pulse Pixel (Eiger)

View File

@@ -426,6 +426,15 @@ void multiSlsDetector::addSlsDetector(const std::string &hostname) {
detectors[pos]->setOnline(true);
}
void multiSlsDetector::addSlsDetector(std::unique_ptr<slsDetector> det){
detectors.push_back(std::move(det));
multi_shm()->numberOfDetectors = detectors.size();
multi_shm()->dataBytes += detectors.back()->getDataBytes();
multi_shm()->dataBytesInclGapPixels +=
detectors.back()->getDataBytesInclGapPixels();
multi_shm()->numberOfChannels += detectors.back()->getTotalNumberOfChannels();
}
slsDetectorDefs::detectorType multiSlsDetector::getDetectorTypeAsEnum(int detPos) {
// single
if (detPos >= 0) {
@@ -2524,25 +2533,19 @@ int multiSlsDetector::enableGapPixels(int val, int detPos) {
return ret;
}
int multiSlsDetector::setTrimEn(int ne, int *ene, int detPos) {
// single
int multiSlsDetector::setTrimEn(std::vector<int> energies, int detPos) {
if (detPos >= 0) {
return detectors[detPos]->setTrimEn(ne, ene);
return detectors[detPos]->setTrimEn(energies);
}
// multi
auto r = serialCall(&slsDetector::setTrimEn, ne, ene);
auto r = parallelCall(&slsDetector::setTrimEn, energies);
return sls::minusOneIfDifferent(r);
}
int multiSlsDetector::getTrimEn(int *ene, int detPos) {
// single
std::vector<int> multiSlsDetector::getTrimEn(int detPos) {
if (detPos >= 0) {
return detectors[detPos]->getTrimEn(ene);
return detectors[detPos]->getTrimEn();
}
// multi
auto r = serialCall(&slsDetector::getTrimEn, ene);
auto r = parallelCall(&slsDetector::getTrimEn);
return sls::minusOneIfDifferent(r);
}

View File

@@ -3125,23 +3125,28 @@ int slsDetector::enableGapPixels(int val) {
return detector_shm()->gappixels;
}
int slsDetector::setTrimEn(int nen, int *en) {
if (en) {
for (int ien = 0; ien < nen; ++ien) {
detector_shm()->trimEnergies[ien] = en[ien];
}
detector_shm()->nTrimEn = nen;
int slsDetector::setTrimEn(std::vector<int> energies) {
if (energies.size()>MAX_TRIMEN){
std::ostringstream os;
os << "Size of trim energies: " << energies.size() << " exceeds what can "
<< "be stored in shared memory: " << MAX_TRIMEN << "\n";
throw RuntimeError(os.str());
}
for (int i = 0; i != energies.size(); ++i) {
detector_shm()->trimEnergies[i] = energies[i];
}
detector_shm()->nTrimEn = energies.size();
return (detector_shm()->nTrimEn);
}
int slsDetector::getTrimEn(int *en) {
if (en) {
for (int ien = 0; ien < detector_shm()->nTrimEn; ++ien) {
en[ien] = detector_shm()->trimEnergies[ien];
}
std::vector<int> slsDetector::getTrimEn() {
std::vector<int> energies;
energies.reserve(detector_shm()->nTrimEn);
for (int i = 0; i != detector_shm()->nTrimEn; ++i) {
energies.push_back(detector_shm()->trimEnergies[i]);
}
return (detector_shm()->nTrimEn);
return energies;
}
int slsDetector::pulsePixel(int n, int x, int y) {

View File

@@ -2505,41 +2505,24 @@ std::string slsDetectorCommand::helpSettingsDir(int action) {
}
std::string slsDetectorCommand::cmdTrimEn(int narg, char *args[], int action, int detPos) {
int ival;
int ip;
char answer[1000];
if (action == HELP_ACTION)
std::vector<int> energies;
if (action == HELP_ACTION)
return helpTrimEn(action);
if (action == PUT_ACTION) {
if (sscanf(args[1], "%d", &ival)) {
int pos[ival];
for (ip = 0; ip < ival; ++ip) {
if ((2 + ip) < narg) {
if (sscanf(args[2 + ip], "%d", pos + ip)) {
} else
break;
}
}
myDet->setTrimEn(ip, pos, detPos);
energies.reserve(narg-1);
for(int i=1; i!=narg; ++i){
energies.push_back(std::stoi(args[i]));
}
myDet->setTrimEn(energies, detPos);
energies.clear();
}
int npos = myDet->getTrimEn(nullptr, detPos);
if (npos != -1) {
sprintf(answer, "%d", npos);
int opos[npos];
npos = myDet->getTrimEn(opos, detPos);
if (npos != -1) {
for (int ip = 0; ip < npos; ++ip) {
sprintf(answer, "%s %d", answer, opos[ip]);
}
}
energies = myDet->getTrimEn(detPos);
std::ostringstream os;
for(const auto& en : energies){
os << en << ' ';
}
if (npos == -1)
sprintf(answer, "%d", -1);
return std::string(answer);
return os.str();
}
std::string slsDetectorCommand::helpTrimEn(int action) {

View File

@@ -1 +1,5 @@
target_sources(tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/test-SharedMemory.cpp)
target_sources(tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/test-SharedMemory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-slsDetector.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-multiSlsDetector.cpp
)

View File

@@ -0,0 +1,63 @@
#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(0, -1);
GIVEN("An empty multi detector") {
multiSlsDetector m(0);
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, 0, 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, 0, 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();
}
}

View File

@@ -0,0 +1,49 @@
#include "catch.hpp"
#include "container_utils.h"
#include "slsDetector.h"
#include "string_utils.h"
#include <iostream>
using namespace sls;
TEST_CASE("Set and get trimen", "[detector]") {
// Free shared memory to be sure that we start in a clean state
slsDetector::freeSharedMemory(0, 0);
// Create a detector and check that the type is set correctly
slsDetector d(slsDetectorDefs::detectorType::EIGER, 0, 0);
CHECK(d.getDetectorTypeAsEnum() == slsDetectorDefs::detectorType::EIGER);
// At the beginning there should be no trimen set
auto res = d.getTrimEn();
CHECK(res.size() == 0);
std::vector<int> energies{5200, 6400, 8500, 9900, 12000};
d.setTrimEn(energies);
auto res2 = d.getTrimEn();
// Check that the size and every element matches what we set
CHECK(res2.size() == energies.size());
for (size_t i = 0; i != res2.size(); ++i)
CHECK(res2[i] == energies[i]);
// Setting trimen with too many vales throws an exception and keeps the
// old values
std::vector<int> too_many(150, 1000);
CHECK_THROWS(d.setTrimEn(too_many));
auto res3 = d.getTrimEn();
CHECK(res3.size() == energies.size());
for (size_t i = 0; i != res3.size(); ++i)
CHECK(res3[i] == energies[i]);
// Setting trimen without arguments resets to zero
d.setTrimEn();
CHECK(d.getTrimEn().size() == 0);
// Clean up before next test
d.freeSharedMemory();
}