Commit 3f964249 authored by Alejandro Homs Puron's avatar Alejandro Homs Puron Committed by operator for beamline
Browse files

Jungfrau: add ImgProc, featuring GainADCMap

parent 4adcb005
...@@ -204,6 +204,7 @@ std::ostream& operator <<(std::ostream& os, const FrameArray& a); ...@@ -204,6 +204,7 @@ std::ostream& operator <<(std::ostream& os, const FrameArray& a);
typedef PrettyList<IntList> PrettyIntList; typedef PrettyList<IntList> PrettyIntList;
typedef PrettyList<SortedIntList> PrettySortedList; typedef PrettyList<SortedIntList> PrettySortedList;
StringList SplitString(const std::string& s, const std::string& sep = ",");
struct TimeRanges { struct TimeRanges {
TimeRanges() : TimeRanges() :
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include "SlsDetectorCamera.h" #include "SlsDetectorCamera.h"
#include "processlib/LinkTask.h" #include "processlib/SinkTask.h"
namespace lima namespace lima
{ {
...@@ -42,6 +42,21 @@ class Jungfrau : public Model ...@@ -42,6 +42,21 @@ class Jungfrau : public Model
typedef unsigned short Word; typedef unsigned short Word;
typedef unsigned int Long; typedef unsigned int Long;
class ImgProcTask : public SinkTaskBase
{
DEB_CLASS_NAMESPC(DebModCamera, "Jungfrau::ImgProcTask",
"SlsDetector");
public:
ImgProcTask(Jungfrau *jungfrau);
void setConfig(std::string config);
void getConfig(std::string &config);
virtual void process(Data& data);
private:
Jungfrau *m_jungfrau;
};
Jungfrau(Camera *cam); Jungfrau(Camera *cam);
~Jungfrau(); ~Jungfrau();
...@@ -58,12 +73,20 @@ class Jungfrau : public Model ...@@ -58,12 +73,20 @@ class Jungfrau : public Model
virtual void getTimeRanges(TimeRanges& time_ranges); virtual void getTimeRanges(TimeRanges& time_ranges);
// the returned object must be deleted by the caller
ImgProcTask *createImgProcTask();
void setHighVoltage(int hvolt); void setHighVoltage(int hvolt);
void getHighVoltage(int& hvolt); void getHighVoltage(int& hvolt);
void setThresholdEnergy(int thres); void setThresholdEnergy(int thres);
void getThresholdEnergy(int& thres); void getThresholdEnergy(int& thres);
void setImgProcConfig(std::string config);
void getImgProcConfig(std::string &config);
void readGainADCMaps(Data& gain_map, Data& adc_map);
virtual bool isXferActive(); virtual bool isXferActive();
protected: protected:
...@@ -158,6 +181,93 @@ class Jungfrau : public Model ...@@ -158,6 +181,93 @@ class Jungfrau : public Model
}; };
typedef std::vector<AutoPtr<Thread> > ThreadList; typedef std::vector<AutoPtr<Thread> > ThreadList;
class ImgProcBase
{
DEB_CLASS_NAMESPC(DebModCamera, "Jungfrau::ImgProcBase",
"SlsDetector");
public:
typedef std::vector<int> DataDims;
ImgProcBase(Jungfrau *jungfrau, std::string name);
virtual ~ImgProcBase();
int getNbJungfrauModules()
{ return m_nb_jungfrau_modules; }
virtual void updateImageSize(Size size, bool raw);
virtual void prepareAcq();
virtual void processFrame(Data& data) = 0;
static void updateDataSize(Data& d, Size size) {
DataDims data_dims{size.getWidth(), size.getHeight()};
if (d.empty() || (d.dimensions != data_dims)) {
d.dimensions = data_dims;
d.setBuffer(new Buffer(d.size()));
}
}
static void clearData(Data& d) {
memset(d.data(), 0, d.size());
}
protected:
friend class Jungfrau;
Jungfrau *m_jungfrau;
std::string m_name;
int m_nb_jungfrau_modules;
bool m_raw;
int m_pixels;
Size m_frame_size;
Point m_det_mods;
};
typedef std::vector<ImgProcBase *> ImgProcList;
class GainADCMapImgProc : public ImgProcBase
{
DEB_CLASS_NAMESPC(DebModCamera, "Jungfrau::GainADCMapImgProc",
"SlsDetector");
public:
struct MapData {
Data gain_map;
Data adc_map;
Mutex mutex;
AutoMutex lock() { return mutex; }
MapData() {
gain_map.type = Data::UINT8;
adc_map.type = Data::UINT16;
}
void updateSize(Size size) {
AutoMutex l = lock();
updateDataSize(gain_map, size);
updateDataSize(adc_map, size);
};
void clear() {
AutoMutex l = lock();
clearData(gain_map);
clearData(adc_map);
}
};
GainADCMapImgProc(Jungfrau *jungfrau);
virtual void updateImageSize(Size size, bool raw);
virtual void prepareAcq();
virtual void processFrame(Data& data);
private:
friend class Jungfrau;
MapData m_data;
};
void addImgProc(ImgProcBase *img_proc);
void removeImgProc(ImgProcBase *img_proc);
void removeAllImgProc();
ImgProcBase *createGainADCMapImgProc();
int getNbJungfrauModules() int getNbJungfrauModules()
{ return getNbDetModules(); } { return getNbDetModules(); }
...@@ -185,6 +295,8 @@ class Jungfrau : public Model ...@@ -185,6 +295,8 @@ class Jungfrau : public Model
void processOneFrame(AutoMutex& l); void processOneFrame(AutoMutex& l);
Cond m_cond; Cond m_cond;
std::string m_img_proc_config;
ImgProcList m_img_proc_list;
RecvList m_recv_list; RecvList m_recv_list;
FrameType m_nb_frames; FrameType m_nb_frames;
FrameType m_next_frame; FrameType m_next_frame;
......
...@@ -36,10 +36,23 @@ class Jungfrau : public SlsDetector::Model ...@@ -36,10 +36,23 @@ class Jungfrau : public SlsDetector::Model
%End %End
public: public:
class ImgProcTask : public SinkTaskBase
{
public:
ImgProcTask(SlsDetector::Jungfrau *jungfrau);
void setConfig(std::string config);
void getConfig(std::string &config /Out/);
virtual void process(Data& data);
};
Jungfrau(SlsDetector::Camera *cam); Jungfrau(SlsDetector::Camera *cam);
virtual void getFrameDim(FrameDim& frame_dim /Out/, bool raw = false); virtual void getFrameDim(FrameDim& frame_dim /Out/, bool raw = false);
SlsDetector::Jungfrau::ImgProcTask *createImgProcTask() /Factory/;
virtual std::string getName(); virtual std::string getName();
virtual void getPixelSize(double& x_size /Out/, double& y_size /Out/); virtual void getPixelSize(double& x_size /Out/, double& y_size /Out/);
...@@ -59,6 +72,11 @@ class Jungfrau : public SlsDetector::Model ...@@ -59,6 +72,11 @@ class Jungfrau : public SlsDetector::Model
void setThresholdEnergy(int thres); void setThresholdEnergy(int thres);
void getThresholdEnergy(int& thres /Out/); void getThresholdEnergy(int& thres /Out/);
void setImgProcConfig(std::string config);
void getImgProcConfig(std::string &config /Out/);
void readGainADCMaps(Data& gain_map /Out/, Data& adc_map /Out/);
virtual bool isXferActive(); virtual bool isXferActive();
protected: protected:
......
...@@ -1150,16 +1150,7 @@ string SystemCPUAffinityMgr::WatchDog::concatStringList(StringList list) ...@@ -1150,16 +1150,7 @@ string SystemCPUAffinityMgr::WatchDog::concatStringList(StringList list)
StringList SystemCPUAffinityMgr::WatchDog::splitStringList(string str) StringList SystemCPUAffinityMgr::WatchDog::splitStringList(string str)
{ {
StringList list; return SplitString(str);
string::size_type i, p, n;
for (i = 0; (i != string::npos) && (i != str.size()); i = p) {
p = str.find(",", i);
n = (p == string::npos) ? p : (p - i);
list.push_back(string(str, i, n));
if (p != string::npos)
++p;
}
return list;
} }
NetDevGroupCPUAffinity NetDevGroupCPUAffinity
......
...@@ -127,6 +127,20 @@ ostream& lima::SlsDetector::Defs::operator <<(ostream& os, DetStatus status) ...@@ -127,6 +127,20 @@ ostream& lima::SlsDetector::Defs::operator <<(ostream& os, DetStatus status)
return os << name; return os << name;
} }
StringList lima::SlsDetector::SplitString(const std::string& s,
const std::string& sep)
{
StringList list;
string::size_type i, p, n;
for (i = 0; (i != string::npos) && (i != s.size()); i = p) {
p = s.find(sep, i);
n = (p == string::npos) ? p : (p - i);
list.push_back(string(s, i, n));
if (p != string::npos)
++p;
}
return list;
}
Glob::Glob(string pattern) Glob::Glob(string pattern)
: m_pattern(pattern) : m_pattern(pattern)
......
...@@ -34,6 +34,28 @@ using namespace lima::SlsDetector; ...@@ -34,6 +34,28 @@ using namespace lima::SlsDetector;
using namespace lima::SlsDetector::Defs; using namespace lima::SlsDetector::Defs;
#define applyDetGeom(j, f, raw) \
using namespace sls::Geom::Jungfrau; \
int ifaces; \
j->getNbUDPInterfaces(ifaces); \
auto any_nb_ifaces = AnyNbUDPIfacesFromNbUDPIfaces(ifaces); \
std::visit([&](auto nb) { \
constexpr int nb_udp_ifaces = nb; \
Defs::xy det_size = j->m_det->getDetectorSize(); \
auto any_geom = AnyDetGeomFromDetSize<nb_udp_ifaces>({det_size.x, \
det_size.y});\
std::visit([&](auto geom) { \
if (raw) \
f(geom.raw_geom); \
else \
f(geom.asm_wg_geom); \
}, any_geom); \
}, any_nb_ifaces);
/*
* Jungfrau::Recv class
*/
Jungfrau::Recv::Recv(Jungfrau *jungfrau, int idx) Jungfrau::Recv::Recv(Jungfrau *jungfrau, int idx)
: m_jungfrau(jungfrau), m_idx(idx) : m_jungfrau(jungfrau), m_idx(idx)
{ {
...@@ -72,6 +94,11 @@ void Jungfrau::Recv::processBadFrame(FrameType frame, char *bptr) ...@@ -72,6 +94,11 @@ void Jungfrau::Recv::processBadFrame(FrameType frame, char *bptr)
memset(bptr + m_data_offset, 0xff, m_frame_dim.getMemSize()); memset(bptr + m_data_offset, 0xff, m_frame_dim.getMemSize());
} }
/*
* Jungfrau::Thread class
*/
Jungfrau::Thread::Thread(Jungfrau *jungfrau, int idx) Jungfrau::Thread::Thread(Jungfrau *jungfrau, int idx)
: m_jungfrau(jungfrau), m_idx(idx) : m_jungfrau(jungfrau), m_idx(idx)
{ {
...@@ -143,6 +170,141 @@ void Jungfrau::Thread::prepareAcq() ...@@ -143,6 +170,141 @@ void Jungfrau::Thread::prepareAcq()
DEB_MEMBER_FUNCT(); DEB_MEMBER_FUNCT();
} }
/*
* Jungfrau::ImgProcTask class
*/
Jungfrau::ImgProcTask::ImgProcTask(Jungfrau *jungfrau)
: m_jungfrau(jungfrau)
{
DEB_CONSTRUCTOR();
}
void Jungfrau::ImgProcTask::setConfig(string config)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(config);
m_jungfrau->setImgProcConfig(config);
}
void Jungfrau::ImgProcTask::getConfig(string &config)
{
DEB_MEMBER_FUNCT();
m_jungfrau->getImgProcConfig(config);
DEB_RETURN() << DEB_VAR1(config);
}
void Jungfrau::ImgProcTask::process(Data& data)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR2(data.frameNumber, data.data());
ImgProcList& img_proc_list = m_jungfrau->m_img_proc_list;
ImgProcList::iterator it, end = img_proc_list.end();
for (it = img_proc_list.begin(); it != end; ++it)
(*it)->processFrame(data);
}
/*
* Jungfrau::ImgProcBase class
*/
Jungfrau::ImgProcBase::ImgProcBase(Jungfrau *jungfrau, std::string name)
: m_jungfrau(jungfrau), m_name(name)
{
DEB_CONSTRUCTOR();
DEB_PARAM() << DEB_VAR1(m_name);
m_nb_jungfrau_modules = m_jungfrau->getNbJungfrauModules();
auto f = [&](auto det_geom) {
m_det_mods = Point(det_geom.det_mods.x, det_geom.det_mods.y);
DEB_TRACE() << DEB_VAR2(m_det_mods, m_nb_jungfrau_modules);
};
applyDetGeom(m_jungfrau, f, false);
}
Jungfrau::ImgProcBase::~ImgProcBase()
{
DEB_DESTRUCTOR();
if (m_jungfrau)
m_jungfrau->removeImgProc(this);
}
void Jungfrau::ImgProcBase::updateImageSize(Size size, bool raw)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR3(m_name, size, raw);
m_pixels = size.getWidth() * size.getHeight();
m_frame_size = size;
m_raw = raw;
}
void Jungfrau::ImgProcBase::prepareAcq()
{
DEB_MEMBER_FUNCT();
if (!m_jungfrau)
THROW_HW_ERROR(InvalidValue) << "ImgProc already removed";
}
/*
* Jungfrau::ImgProcBase class
*/
Jungfrau::GainADCMapImgProc::GainADCMapImgProc(Jungfrau *jungfrau)
: ImgProcBase(jungfrau, "gain_adc_map")
{
DEB_CONSTRUCTOR();
}
void Jungfrau::GainADCMapImgProc::updateImageSize(Size size, bool raw)
{
DEB_MEMBER_FUNCT();
DEB_ALWAYS() << DEB_VAR3(m_name, size, raw);
ImgProcBase::updateImageSize(size, raw);
m_data.updateSize(size);
}
void Jungfrau::GainADCMapImgProc::prepareAcq()
{
DEB_MEMBER_FUNCT();
ImgProcBase::prepareAcq();
m_data.clear();
}
void Jungfrau::GainADCMapImgProc::processFrame(Data& data)
{
DEB_MEMBER_FUNCT();
long frame = data.frameNumber;
DEB_ALWAYS() << DEB_VAR1(frame);
MapData& m = m_data;
AutoMutex l = m.lock();
unsigned short *src;
{
src = (unsigned short *) data.data();
unsigned char *dst = (unsigned char *) m.gain_map.data();
for (int i = 0; i < m_pixels; ++i)
*dst++ = *src++ >> 14;
m.gain_map.frameNumber = frame;
}
{
src = (unsigned short *) data.data();
unsigned short *dst = (unsigned short *) m.adc_map.data();
for (int i = 0; i < m_pixels; ++i)
*dst++ = *src++ & 0x3fff;
m.adc_map.frameNumber = frame;
}
}
/*
* Jungfrau detector class
*/
Jungfrau::Jungfrau(Camera *cam) Jungfrau::Jungfrau(Camera *cam)
: Model(cam, JungfrauDet) : Model(cam, JungfrauDet)
{ {
...@@ -166,26 +328,9 @@ Jungfrau::~Jungfrau() ...@@ -166,26 +328,9 @@ Jungfrau::~Jungfrau()
{ {
DEB_DESTRUCTOR(); DEB_DESTRUCTOR();
getCamera()->waitAcqState(Idle); getCamera()->waitAcqState(Idle);
removeAllImgProc();
} }
#define applyDetGeom(f, raw) \
using namespace sls::Geom::Jungfrau; \
int ifaces; \
getNbUDPInterfaces(ifaces); \
auto any_nb_ifaces = AnyNbUDPIfacesFromNbUDPIfaces(ifaces); \
std::visit([&](auto nb) { \
constexpr int nb_udp_ifaces = nb; \
Defs::xy det_size = m_det->getDetectorSize(); \
auto any_geom = AnyDetGeomFromDetSize<nb_udp_ifaces>({det_size.x, \
det_size.y});\
std::visit([&](auto geom) { \
if (raw) \
f(geom.raw_geom); \
else \
f(geom.asm_wg_geom); \
}, any_geom); \
}, any_nb_ifaces);
void Jungfrau::getFrameDim(FrameDim& frame_dim, bool raw) void Jungfrau::getFrameDim(FrameDim& frame_dim, bool raw)
{ {
DEB_MEMBER_FUNCT(); DEB_MEMBER_FUNCT();
...@@ -195,7 +340,7 @@ void Jungfrau::getFrameDim(FrameDim& frame_dim, bool raw) ...@@ -195,7 +340,7 @@ void Jungfrau::getFrameDim(FrameDim& frame_dim, bool raw)
size = Size(det_geom.size.x, det_geom.size.y); size = Size(det_geom.size.x, det_geom.size.y);
DEB_TRACE() << DEB_VAR1(size); DEB_TRACE() << DEB_VAR1(size);
}; };
applyDetGeom(f, raw); applyDetGeom(this, f, raw);
frame_dim = FrameDim(size, Bpp16); frame_dim = FrameDim(size, Bpp16);
DEB_RETURN() << DEB_VAR1(frame_dim); DEB_RETURN() << DEB_VAR1(frame_dim);
} }
...@@ -227,7 +372,7 @@ FrameDim Jungfrau::getModuleFrameDim(int idx, bool raw) ...@@ -227,7 +372,7 @@ FrameDim Jungfrau::getModuleFrameDim(int idx, bool raw)
!last_y ? det_geom.mod_step.y : mod_geom.size.y); !last_y ? det_geom.mod_step.y : mod_geom.size.y);
DEB_TRACE() << DEB_VAR1(size); DEB_TRACE() << DEB_VAR1(size);
}; };
applyDetGeom(f, raw); applyDetGeom(this, f, raw);
FrameDim frame_dim(size, Bpp16); FrameDim frame_dim(size, Bpp16);
DEB_RETURN() << DEB_VAR1(frame_dim); DEB_RETURN() << DEB_VAR1(frame_dim);
return frame_dim; return frame_dim;
...@@ -247,7 +392,7 @@ int Jungfrau::getModuleDataOffset(int idx, bool raw) ...@@ -247,7 +392,7 @@ int Jungfrau::getModuleDataOffset(int idx, bool raw)
data_offset = pixel_offset * sls::Geom::Pixel16::depth(); data_offset = pixel_offset * sls::Geom::Pixel16::depth();
DEB_TRACE() << DEB_VAR1(data_offset); DEB_TRACE() << DEB_VAR1(data_offset);
}; };
applyDetGeom(f, raw); applyDetGeom(this, f, raw);
DEB_RETURN() << DEB_VAR1(data_offset); DEB_RETURN() << DEB_VAR1(data_offset);
return data_offset; return data_offset;
} }
...@@ -395,7 +540,13 @@ void Jungfrau::updateImageSize() ...@@ -395,7 +540,13 @@ void Jungfrau::updateImageSize()
Camera *cam = getCamera(); Camera *cam = getCamera();
bool raw; bool raw;
cam->getRawMode(raw); cam->getRawMode(raw);
DEB_TRACE() << DEB_VAR1(raw); FrameDim frame_dim;
getFrameDim(frame_dim, raw);
DEB_TRACE() << DEB_VAR2(frame_dim, raw);
ImgProcList::iterator it, end = m_img_proc_list.end();
for (it = m_img_proc_list.begin(); it != end; ++it)
(*it)->updateImageSize(frame_dim.getSize(), raw);
} }
bool Jungfrau::checkSettings(Settings settings) bool Jungfrau::checkSettings(Settings settings)
...@@ -607,3 +758,89 @@ bool Jungfrau::isXferActive() ...@@ -607,3 +758,89 @@ bool Jungfrau::isXferActive()
return xfer_active; return xfer_active;
} }
Jungfrau::ImgProcTask *Jungfrau::createImgProcTask()
{
DEB_MEMBER_FUNCT();
return new ImgProcTask(this);
}
void Jungfrau::addImgProc(ImgProcBase *img_proc)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(img_proc);
m_img_proc_list.push_back(img_proc);
bool raw;
getCamera()->getRawMode(raw);
FrameDim frame_dim;
getFrameDim(frame_dim, raw);
img_proc->updateImageSize(frame_dim.getSize(), raw);
}
void Jungfrau::removeImgProc(ImgProcBase *img_proc)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(img_proc);
ImgProcList::iterator it, end = m_img_proc_list.end();
it = find(m_img_proc_list.begin(), end, img_proc);
if (it != end)
m_img_proc_list.erase(it);
img_proc->m_jungfrau = NULL;
}
void Jungfrau::removeAllImgProc()
{
DEB_MEMBER_FUNCT();
while (m_img_proc_list.size() > 0)