* roi structure expanded to have ymin and ymax

* compile with 'detector roi'

* wip

* wip, rx_roi, rx_clearroi

* wip rxroi

* rxroi wip

* wip rxroi

* merge fix

* wip

* rx_roi works, impl wip, test

* tests in, impl left

* wip, rxroi impl

* wip, rxroi impl

* wip

* setrx_Roi works, getrx_roi, wip

* rx_roi impl done

* wip, rxroi

* wip, getrx_roi rxr ports

* fix ports

* wip

* wip

* fix positions on server side

* wip

* numports wip

* wip

* jungfrau top inner interface row increment

* x, y detpos, wip

* removed eiger row indices flipping in gui (bottom flipping maintained)

* wip

* wip, jungfrau numinterfaces2

* jungfrau virtual works

* eiger, jungfrau, g2 virtual server works

* eiger positions fix, wip

* binaries in

* minor printout

* binaries in

* merge fix

* merge fix

* removing getposition

* setrxroi wip

* set upto port

* get messed, wip

* roi multi to module works, wip

* wip

* roi dont return -1

* added rxroi metadata in master file

* added rxroifromshm, not yet in detector

* rx roi in gui with box, also for gap pixels (gappixels for jungfrau mess)

* fix for segfault in gui with detaching roi box in gui

* wip

* m3 gui: slave timing modes should be discarded when squashing

* fixed m3 virtual data, and fixed counters in gui asthetics

* m3 roi works

* wip, g2

* wip

* handling g225um boards, and showing roi for gainplot as well

* udpate python functions

* fix for 1d and a2d roi written

* fixed actual roi written to file

* no virtual hdf5 when handling rx roi

* test

* minor

* binarie in
This commit is contained in:
Dhanya Thattil
2022-05-16 12:35:06 +02:00
committed by GitHub
parent 9808376207
commit fcc7f7aef8
53 changed files with 1713 additions and 859 deletions

View File

@ -70,7 +70,7 @@ void DetectorImpl::freeSharedMemory(int detectorIndex, int detPos) {
if (detectorShm.exists()) {
detectorShm.openSharedMemory(false);
numModules = detectorShm()->numberOfModules;
numModules = detectorShm()->totalNumberOfModules;
detectorShm.removeSharedMemory();
}
@ -161,10 +161,10 @@ void DetectorImpl::initSharedMemory(bool verify) {
void DetectorImpl::initializeDetectorStructure() {
shm()->shmversion = DETECTOR_SHMVERSION;
shm()->numberOfModules = 0;
shm()->totalNumberOfModules = 0;
shm()->detType = GENERIC;
shm()->numberOfModule.x = 0;
shm()->numberOfModule.y = 0;
shm()->numberOfModules.x = 0;
shm()->numberOfModules.y = 0;
shm()->numberOfChannels.x = 0;
shm()->numberOfChannels.y = 0;
shm()->acquiringFlag = false;
@ -172,6 +172,10 @@ void DetectorImpl::initializeDetectorStructure() {
shm()->gapPixels = false;
// zmqlib default
shm()->zmqHwm = -1;
shm()->rx_roi.xmin = -1;
shm()->rx_roi.xmax = -1;
shm()->rx_roi.ymin = -1;
shm()->rx_roi.ymax = -1;
}
void DetectorImpl::initializeMembers(bool verify) {
@ -179,7 +183,7 @@ void DetectorImpl::initializeMembers(bool verify) {
zmqSocket.clear();
// get objects from single det shared memory (open)
for (int i = 0; i < shm()->numberOfModules; i++) {
for (int i = 0; i < shm()->totalNumberOfModules; i++) {
try {
modules.push_back(
sls::make_unique<Module>(detectorIndex, i, verify));
@ -246,7 +250,7 @@ void DetectorImpl::setVirtualDetectorServers(const int numdet, const int port) {
void DetectorImpl::setHostname(const std::vector<std::string> &name) {
// this check is there only to allow the previous detsizechan command
if (shm()->numberOfModules != 0) {
if (shm()->totalNumberOfModules != 0) {
LOG(logWARNING) << "There are already module(s) in shared memory."
"Freeing Shared memory now.";
bool initialChecks = shm()->initialChecks;
@ -305,7 +309,7 @@ void DetectorImpl::addModule(const std::string &hostname) {
auto pos = modules.size();
modules.emplace_back(
sls::make_unique<Module>(type, detectorIndex, pos, false));
shm()->numberOfModules = modules.size();
shm()->totalNumberOfModules = modules.size();
modules[pos]->setControlPort(port);
modules[pos]->setStopPort(port + 1);
modules[pos]->setHostname(host, shm()->initialChecks);
@ -328,9 +332,8 @@ void DetectorImpl::addModule(const std::string &hostname) {
void DetectorImpl::updateDetectorSize() {
LOG(logDEBUG) << "Updating Detector Size: " << size();
const slsDetectorDefs::xy det_size = modules[0]->getNumberOfChannels();
if (det_size.x == 0 || det_size.y == 0) {
const slsDetectorDefs::xy modSize = modules[0]->getNumberOfChannels();
if (modSize.x == 0 || modSize.y == 0) {
throw sls::RuntimeError(
"Module size for x or y dimensions is 0. Unable to proceed in "
"updating detector size. ");
@ -338,39 +341,39 @@ void DetectorImpl::updateDetectorSize() {
int maxx = shm()->numberOfChannels.x;
int maxy = shm()->numberOfChannels.y;
int ndetx = 0, ndety = 0;
int nModx = 0, nMody = 0;
// 1d, add modules along x axis
if (det_size.y == 1) {
if (modSize.y == 1) {
if (maxx == 0) {
maxx = det_size.x * size();
maxx = modSize.x * size();
}
ndetx = maxx / det_size.x;
ndety = size() / ndetx;
if ((maxx % det_size.x) > 0) {
++ndety;
nModx = maxx / modSize.x;
nMody = size() / nModx;
if ((maxx % modSize.x) > 0) {
++nMody;
}
}
// 2d, add modules along y axis (due to eiger top/bottom)
else {
if (maxy == 0) {
maxy = det_size.y * size();
maxy = modSize.y * size();
}
ndety = maxy / det_size.y;
ndetx = size() / ndety;
if ((maxy % det_size.y) > 0) {
++ndetx;
nMody = maxy / modSize.y;
nModx = size() / nMody;
if ((maxy % modSize.y) > 0) {
++nModx;
}
}
shm()->numberOfModule.x = ndetx;
shm()->numberOfModule.y = ndety;
shm()->numberOfChannels.x = det_size.x * ndetx;
shm()->numberOfChannels.y = det_size.y * ndety;
shm()->numberOfModules.x = nModx;
shm()->numberOfModules.y = nMody;
shm()->numberOfChannels.x = modSize.x * nModx;
shm()->numberOfChannels.y = modSize.y * nMody;
LOG(logDEBUG) << "\n\tNumber of Modules in X direction:"
<< shm()->numberOfModule.x
<< shm()->numberOfModules.x
<< "\n\tNumber of Modules in Y direction:"
<< shm()->numberOfModule.y
<< shm()->numberOfModules.y
<< "\n\tNumber of Channels in X direction:"
<< shm()->numberOfChannels.x
<< "\n\tNumber of Channels in Y direction:"
@ -378,7 +381,7 @@ void DetectorImpl::updateDetectorSize() {
for (auto &module : modules) {
if (module->getUpdateMode() == 0) {
module->updateNumberOfModule(shm()->numberOfModule);
module->updateNumberOfModule(shm()->numberOfModules);
}
}
}
@ -386,7 +389,7 @@ void DetectorImpl::updateDetectorSize() {
int DetectorImpl::size() const { return modules.size(); }
slsDetectorDefs::xy DetectorImpl::getNumberOfModules() const {
return shm()->numberOfModule;
return shm()->numberOfModules;
}
slsDetectorDefs::xy DetectorImpl::getNumberOfChannels() const {
@ -412,7 +415,7 @@ void DetectorImpl::setGapPixelsinCallback(const bool enable) {
if (size() && modules[0]->getQuad()) {
break;
}
if (shm()->numberOfModule.y % 2 != 0) {
if (shm()->numberOfModules.y % 2 != 0) {
throw RuntimeError("Gap pixels can only be used "
"for full modules.");
}
@ -495,6 +498,7 @@ void DetectorImpl::readFrameFromReceiver() {
bool quadEnable = false;
// to flip image
bool eiger = false;
std::array<int, 4> rxRoi = shm()->rx_roi.getIntArray();
std::vector<bool> runningList(zmqSocket.size());
std::vector<bool> connectList(zmqSocket.size());
@ -571,7 +575,7 @@ void DetectorImpl::readFrameFromReceiver() {
// shape
nPixelsX = zHeader.npixelsx;
nPixelsY = zHeader.npixelsy;
// module shape (port)
// port geometry
nX = zHeader.ndetx;
nY = zHeader.ndety;
nDetPixelsX = nX * nPixelsX;
@ -668,6 +672,7 @@ void DetectorImpl::readFrameFromReceiver() {
<< "\n\t databytes: " << multisize
<< "\n\t dynamicRange: " << dynamicRange;
// send data to callback
if (data) {
char *callbackImage = multiframe.get();
@ -691,7 +696,7 @@ void DetectorImpl::readFrameFromReceiver() {
thisData = new detectorData(currentProgress, currentFileName,
nDetActualPixelsX, nDetActualPixelsY,
callbackImage, imagesize, dynamicRange,
currentFileIndex, completeImage);
currentFileIndex, completeImage, rxRoi);
try {
dataReady(
thisData, currentFrameIndex,
@ -1094,9 +1099,6 @@ int DetectorImpl::acquire() {
return FAIL;
}
// We need this to handle Mythen3 synchronization
auto detector_type = Parallel(&Module::getDetectorType, {}).squash();
try {
struct timespec begin, end;
clock_gettime(CLOCK_REALTIME, &begin);
@ -1174,6 +1176,7 @@ int DetectorImpl::acquire() {
}
void DetectorImpl::startAcquisition(bool blocking, std::vector<int> positions) {
// handle Mythen3 synchronization
if (shm()->detType == defs::MYTHEN3 && size() > 1) {
std::vector<int> master;
std::vector<int> slaves;
@ -1425,6 +1428,218 @@ void DetectorImpl::setDefaultDac(defs::dacIndex index, int defaultValue,
Parallel(&Module::setDefaultDac, pos, index, defaultValue, sett);
}
defs::xy DetectorImpl::getPortGeometry() const {
defs::xy portGeometry(1, 1);
switch (shm()->detType) {
case EIGER:
portGeometry.x = modules[0]->getNumberofUDPInterfacesFromShm();
break;
case JUNGFRAU:
portGeometry.y = modules[0]->getNumberofUDPInterfacesFromShm();
break;
default:
break;
}
return portGeometry;
}
defs::xy DetectorImpl::calculatePosition(int moduleIndex,
defs::xy geometry) const {
defs::xy pos{};
int maxYMods = shm()->numberOfModules.y;
pos.y = (moduleIndex % maxYMods) * geometry.y;
pos.x = (moduleIndex / maxYMods) * geometry.x;
return pos;
}
defs::ROI DetectorImpl::getRxROI() const {
if (shm()->detType == CHIPTESTBOARD || shm()->detType == MOENCH) {
throw RuntimeError("RxRoi not implemented for this Detector");
}
if (modules.size() == 0) {
throw RuntimeError("No Modules added");
}
// complete detector in roi
auto t = Parallel(&Module::getRxROI, {});
if (t.equal() && t.front().completeRoi()) {
LOG(logDEBUG) << "no roi";
return defs::ROI (0, shm()->numberOfChannels.x - 1, 0, shm()->numberOfChannels.y - 1);
}
defs::xy numChansPerMod = modules[0]->getNumberOfChannels();
bool is2D = (numChansPerMod.y > 1 ? true : false);
defs::xy geometry = getPortGeometry();
defs::ROI retval{};
for (size_t iModule = 0; iModule != modules.size(); ++iModule) {
defs::ROI moduleRoi = modules[iModule]->getRxROI();
if (moduleRoi.noRoi()) {
LOG(logDEBUG) << iModule << ": no roi";
} else {
// expand complete roi
if (moduleRoi.completeRoi()) {
moduleRoi.xmin = 0;
moduleRoi.xmax = numChansPerMod.x;
if (is2D) {
moduleRoi.ymin = 0;
moduleRoi.ymax = numChansPerMod.y;
}
}
LOG(logDEBUG) << iModule << ": " << moduleRoi;
// get roi at detector level
defs::xy pos = calculatePosition(iModule, geometry);
defs::ROI moduleFullRoi{};
moduleFullRoi.xmin = numChansPerMod.x * pos.x + moduleRoi.xmin;
moduleFullRoi.xmax = numChansPerMod.x * pos.x + moduleRoi.xmax;
if (is2D) {
moduleFullRoi.ymin = numChansPerMod.y * pos.y + moduleRoi.ymin;
moduleFullRoi.ymax = numChansPerMod.y * pos.y + moduleRoi.ymax;
}
LOG(logDEBUG) << iModule << ": (full roi)" << moduleFullRoi;
// get min and max
if (retval.xmin == -1 || moduleFullRoi.xmin < retval.xmin) {
LOG(logDEBUG) << iModule << ": xmin updated";
retval.xmin = moduleFullRoi.xmin;
}
if (retval.xmax == -1 || moduleFullRoi.xmax > retval.xmax) {
LOG(logDEBUG) << iModule << ": xmax updated";
retval.xmax = moduleFullRoi.xmax;
}
if (retval.ymin == -1 || moduleFullRoi.ymin < retval.ymin) {
LOG(logDEBUG) << iModule << ": ymin updated";
retval.ymin = moduleFullRoi.ymin;
}
if (retval.ymax == -1 || moduleFullRoi.ymax > retval.ymax) {
LOG(logDEBUG) << iModule << ": ymax updated";
retval.ymax = moduleFullRoi.ymax;
}
}
LOG(logDEBUG) << iModule << ": (retval): " << retval;
}
if (retval.ymin == -1) {
retval.ymin = 0;
retval.ymax = 0;
}
return retval;
}
void DetectorImpl::setRxROI(const defs::ROI arg) {
if (shm()->detType == CHIPTESTBOARD || shm()->detType == MOENCH) {
throw RuntimeError("RxRoi not implemented for this Detector");
}
if (modules.size() == 0) {
throw RuntimeError("No Modules added");
}
if (arg.noRoi()) {
throw RuntimeError("Invalid Roi of size 0.");
}
if (arg.completeRoi()) {
throw RuntimeError("Did you mean the clear roi command (API: clearRxROI, cmd: rx_clearroi)?");
}
if (arg.xmin > arg.xmax || arg.ymin > arg.ymax) {
throw RuntimeError("Invalid Receiver Roi. xmin/ymin exceeds xmax/ymax.");
}
defs::xy numChansPerMod = modules[0]->getNumberOfChannels();
bool is2D = (numChansPerMod.y > 1 ? true : false);
defs::xy geometry = getPortGeometry();
if (!is2D && ((arg.ymin != -1 && arg.ymin != 0) || (arg.ymax != -1 && arg.ymax != 0))) {
throw RuntimeError("Invalid Receiver roi. Cannot set 2d roi for a 1d detector.");
}
if (arg.xmin < 0 || arg.xmax >= shm()->numberOfChannels.x || (is2D && (arg.ymin < 0 || arg.ymax >= shm()->numberOfChannels.y))) {
throw RuntimeError("Invalid Receiver Roi. Outside detector range.");
}
for (size_t iModule = 0; iModule != modules.size(); ++iModule) {
// default init = complete roi
defs::ROI moduleRoi{};
// incomplete roi
if (!arg.completeRoi()) {
// multi module Gotthard2
if (shm()->detType == GOTTHARD2 && size() > 1) {
moduleRoi.xmin = arg.xmin / 2;
moduleRoi.xmax = arg.xmax / 2;
if (iModule == 0) {
// all should be even
if (arg.xmin % 2 != 0) {
++moduleRoi.xmin;
}
} else if (iModule == 1) {
// all should be odd
if (arg.xmax % 2 == 0) {
--moduleRoi.xmax;
}
} else {
throw RuntimeError("Cannot have more than 2 modules for a Gotthard2 detector");
}
} else {
// get module limits
defs::xy pos = calculatePosition(iModule, geometry);
defs::ROI moduleFullRoi{};
moduleFullRoi.xmin = numChansPerMod.x * pos.x;
moduleFullRoi.xmax = numChansPerMod.x * (pos.x + 1) - 1;
if (is2D) {
moduleFullRoi.ymin = numChansPerMod.y * pos.y;
moduleFullRoi.ymax = numChansPerMod.y * (pos.y + 1) - 1;
}
// no roi
if (arg.xmin > moduleFullRoi.xmax ||
arg.xmax < moduleFullRoi.xmin ||
(is2D && (arg.ymin > moduleFullRoi.ymax ||
arg.ymax < moduleFullRoi.ymin))) {
moduleRoi.setNoRoi();
}
// incomplete module roi
else if (arg.xmin > moduleFullRoi.xmin ||
arg.xmax < moduleFullRoi.xmax ||
(is2D && (arg.ymin > moduleFullRoi.ymin ||
arg.ymax < moduleFullRoi.ymax))) {
moduleRoi.xmin = (arg.xmin <= moduleFullRoi.xmin)
? 0
: (arg.xmin % numChansPerMod.x);
moduleRoi.xmax = (arg.xmax >= moduleFullRoi.xmax)
? numChansPerMod.x - 1
: (arg.xmax % numChansPerMod.x);
if (is2D) {
moduleRoi.ymin = (arg.ymin <= moduleFullRoi.ymin)
? 0
: (arg.ymin % numChansPerMod.y);
moduleRoi.ymax = (arg.ymax >= moduleFullRoi.ymax)
? numChansPerMod.y - 1
: (arg.ymax % numChansPerMod.y);
}
}
}
}
modules[iModule]->setRxROI(moduleRoi);
}
// updating shm rx_roi for gui purposes
shm()->rx_roi = arg;
// metadata
if (arg.completeRoi()) {
modules[0]->setRxROIMetadata(defs::ROI (0, shm()->numberOfChannels.x - 1, 0, shm()->numberOfChannels.y - 1));
} else {
modules[0]->setRxROIMetadata(arg);
}
}
void DetectorImpl::clearRxROI() {
Parallel(&Module::setRxROI, {}, defs::ROI{});
shm()->rx_roi.xmin = -1;
shm()->rx_roi.ymin = -1;
shm()->rx_roi.xmax = -1;
shm()->rx_roi.ymax = -1;
}
std::vector<std::string> DetectorImpl::getCtbDacNames() const {
return ctb_shm()->getDacNames();
}