Commit 23d9eb6d authored by Alejandro Homs Puron's avatar Alejandro Homs Puron Committed by operator for beamline
Browse files

Jungfrau: add measureGainPedestal, based on AveImgProc

* Perform pedestal measurement seq in a Python thread
* Improve synchronisation around ReadHelper
parent 7b4ed52f
Pipeline #42053 failed with stages
in 6 minutes and 9 seconds
......@@ -79,7 +79,7 @@ class Jungfrau : public Model
static constexpr MapType Type = Map32;
static constexpr double DefaultCoeffs[3][2] = {
{ 0.999952, 0.4}, // effectively {1, 0}
{ -26.144935, 394047.3}, // G0 x16
{ -26.144935, 394047.3}, // G0 x26
{-368.163215, 5531211.9}, // G1 x14
};
static constexpr Data::TYPE DataType = Data::UINT32;
......@@ -177,10 +177,13 @@ class Jungfrau : public Model
void readGainADCMaps(Data& gain_map, Data& adc_map, FrameType& frame);
void readGainPedProcMap(Data& proc_map, FrameType& frame);
void readAveMap(Data& ave_map, FrameType& nb_frames, FrameType& frame);
void setGainPedMapType(GainPed::MapType map_type);
void getGainPedMapType(GainPed::MapType& map_type);
void setGainPedCalib(const GainPed::Calib& calib)
{ m_gain_ped_img_proc->m_gain_ped.setCalib(calib); }
void getGainPedCalib(GainPed::Calib& calib)
{ m_gain_ped_img_proc->m_gain_ped.getCalib(calib); }
......@@ -318,51 +321,98 @@ class Jungfrau : public Model
typedef std::vector<ImgProcBase *> ImgProcList;
template <class T>
class ReaderHelper : public Buffer::Callback {
DEB_CLASS_NAMESPC(DebModCamera, "Jungfrau::ReaderHelper",
class ReadHelper : public Buffer::Callback {
DEB_CLASS_NAMESPC(DebModCamera, "Jungfrau::ReadHelper",
"SlsDetector");
public:
typedef DoubleBuffer<T> DBuffer;
typedef DoubleBufferReader<T> DBufferReader;
T& addRead(DBuffer& b, FrameType& frame) {
DEB_MEMBER_FUNCT();
if (m_reader)
THROW_HW_ERROR(Error)
<< "A reader is already active";
m_reader = new Reader(b, frame);
frame = m_reader->getCounter();
return m_reader->getBuffer();
class Reader : public DBufferReader {
DEB_CLASS_NAMESPC(DebModCamera,
"Jungfrau::ReadHelper::Reader",
"SlsDetector");
public:
Reader(DBuffer& db, FrameType f, ReadHelper *h)
: DBufferReader(db, f), m_helper(h)
{ DEB_CONSTRUCTOR(); }
~Reader()
{ DEB_DESTRUCTOR(); }
void addData(Data& src, Data& ref) {
DEB_MEMBER_FUNCT();
makeDataRef(src, ref, m_helper);
m_buffer_list.insert(ref.data());
DEB_TRACE() << DEB_VAR1(m_buffer_list.size());
}
private:
friend class ReadHelper;
typedef std::set<void *> BufferList;
std::pair<bool, bool> destroy(void *buffer) {
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(m_buffer_list.size());
typedef typename BufferList::iterator BufferIt;
BufferIt it, end = m_buffer_list.end();
it = find(m_buffer_list.begin(), end, buffer);
bool found = (it != end);
if (found)
m_buffer_list.erase(it);
return {found, m_buffer_list.empty()};
}
ReadHelper *m_helper;
BufferList m_buffer_list;
};
~ReadHelper() {
DEB_DESTRUCTOR();
AutoMutex l(m_mutex);
while (!m_reader_list.empty())
deleteReader(m_reader_list.begin(), l);
}
void addData(Data& src, Data& ref) {
Reader *addRead(DBuffer& b, FrameType& frame) {
DEB_MEMBER_FUNCT();
makeDataRef(src, ref, this);
m_buffer_list.insert(ref.data());
DEB_TRACE() << DEB_VAR1(m_buffer_list.size());
Reader *r = new Reader(b, frame, this);
frame = r->getCounter();
AutoMutex l(m_mutex);
m_reader_list.insert(r);
return r;
}
protected:
virtual void destroy(void *buffer) {
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(m_buffer_list.size());
if (m_buffer_list.empty() || !m_reader)
DEB_ERROR() << "Unexpected "
<< DEB_VAR1(buffer);
BufferList::iterator it, end = m_buffer_list.end();
it = find(m_buffer_list.begin(), end, buffer);
if (it == end)
DEB_ERROR() << "Bad " << DEB_VAR1(buffer);
m_buffer_list.erase(it);
if (m_buffer_list.empty())
m_reader = NULL;
AutoMutex l(m_mutex);
ReaderIt it, end = m_reader_list.end();
for (it = m_reader_list.begin(); it != end; ++it) {
auto [found, empty] = (*it)->destroy(buffer);
if (!found)
continue;
else if (empty)
deleteReader(it, l);
return;
}
DEB_ERROR() << "Bad " << DEB_VAR1(buffer);
}
private:
typedef DoubleBufferReader<T> Reader;
typedef std::set<void *> BufferList;
typedef std::set<Reader *> ReaderList;
typedef typename ReaderList::iterator ReaderIt;
AutoPtr<Reader> m_reader;
BufferList m_buffer_list;
void deleteReader(ReaderIt it, AutoMutex& l) {
DEB_MEMBER_FUNCT();
Reader *r = *it;
m_reader_list.erase(it);
AutoMutexUnlock u(l);
delete r;
}
Mutex m_mutex;
ReaderList m_reader_list;
};
class GainADCMapImgProc : public ImgProcBase
......@@ -398,11 +448,11 @@ class Jungfrau : public Model
}
};
typedef ReaderHelper<MapData> Reader;
typedef typename Reader::DBuffer DBuffer;
typedef ReadHelper<MapData> Helper;
typedef typename Helper::DBuffer DBuffer;
DBuffer m_buffer;
AutoPtr<Reader> m_reader;
AutoPtr<Helper> m_helper;
};
class GainPedImgProc : public ImgProcBase
......@@ -432,11 +482,50 @@ class Jungfrau : public Model
void clear() { clearData(proc_map); }
};
typedef ReaderHelper<MapData> Reader;
typedef typename Reader::DBuffer DBuffer;
typedef ReadHelper<MapData> Helper;
typedef typename Helper::DBuffer DBuffer;
DBuffer m_buffer;
AutoPtr<Reader> m_reader;
AutoPtr<Helper> m_helper;
};
class AveImgProc : public ImgProcBase
{
DEB_CLASS_NAMESPC(DebModCamera, "Jungfrau::AveImgProc",
"SlsDetector");
public:
AveImgProc(Jungfrau *jungfrau);
virtual void updateImageSize(Size size, bool raw);
virtual void clear();
virtual void processFrame(Data& data);
void readAveMap(Data& ave_map, FrameType& nb_frames,
FrameType& frame);
private:
template <class M>
void processFrameFunct(Data& data);
struct MapData {
Data ave_map;
FrameType nb_frames;
MapData() { ave_map.type = Data::DOUBLE; }
void updateSize(Size size) {
updateDataSize(ave_map, size);
};
void clear() { clearData(ave_map); }
};
typedef ReadHelper<MapData> Helper;
typedef typename Helper::DBuffer DBuffer;
DBuffer m_buffer;
AutoPtr<Helper> m_helper;
Data m_acc;
int m_nb_frames;
};
class ModelReconstruction : public SlsDetector::Reconstruction
......@@ -472,7 +561,9 @@ class Jungfrau : public Model
}
static void clearData(Data& d) {
memset(d.data(), 0, d.size());
void *p = d.data();
if (p)
memset(p, 0, d.size());
}
static void makeDataRef(Data& src, Data& ref, Buffer::Callback *cb) {
......@@ -506,6 +597,15 @@ class Jungfrau : public Model
void removeAllImgProc();
void doSetImgProcConfig(std::string config, bool force);
Data getRawData(Data& data)
{
if (m_img_src == Raw)
return data;
BufferMgr *buffer_mgr = getBuffer();
BufferCtrlObj *buffer = buffer_mgr->getBufferCtrlObj(AcqBuffer);
return buffer->getFrameData(data.frameNumber);
}
int getNbJungfrauModules()
{ return getNbDetModules(); }
......@@ -535,6 +635,7 @@ class Jungfrau : public Model
Cond m_cond;
AutoPtr<GainPedImgProc> m_gain_ped_img_proc;
AutoPtr<GainADCMapImgProc> m_gain_adc_map_img_proc;
AutoPtr<AveImgProc> m_ave_img_proc;
std::string m_img_proc_config;
ImgProcList m_img_proc_list;
ImgSrc m_img_src;
......
......@@ -177,10 +177,13 @@ class Jungfrau : public SlsDetector::Model
void readGainPedProcMap(Data& proc_map /Out/,
unsigned long& frame /In,Out/);
void readAveMap(Data& proc_map /Out/, unsigned long& nb_frames /Out/,
unsigned long& frame /In,Out/);
void setGainPedMapType(Jungfrau::GainPed::MapType map_type);
void getGainPedMapType(Jungfrau::GainPed::MapType& map_type /Out/);
void setGainPedCalib(const SlsDetector::Jungfrau::GainPed::Calib& calib);
void getGainPedCalib(SlsDetector::Jungfrau::GainPed::Calib& calib /Out/);
void setImgSrc(Jungfrau::ImgSrc img_src);
......
......@@ -368,19 +368,10 @@ void Jungfrau::ImgProcTask::process(Data& data)
DEB_PARAM() << DEB_VAR2(data.frameNumber, data.data());
Data src;
if (m_jungfrau->m_img_src == Raw) {
src = data;
} else {
BufferMgr *buffer_mgr = m_jungfrau->getBuffer();
BufferCtrlObj *buffer = buffer_mgr->getBufferCtrlObj(AcqBuffer);
src = buffer->getFrameData(data.frameNumber);
}
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(src);
(*it)->processFrame(data);
}
......@@ -437,7 +428,7 @@ void Jungfrau::ImgProcBase::clear()
*/
Jungfrau::GainADCMapImgProc::GainADCMapImgProc(Jungfrau *jungfrau)
: ImgProcBase(jungfrau, "gain_adc_map"), m_reader(new Reader)
: ImgProcBase(jungfrau, "gain_adc_map"), m_helper(new Helper)
{
DEB_CONSTRUCTOR();
}
......@@ -468,19 +459,21 @@ void Jungfrau::GainADCMapImgProc::processFrame(Data& data)
long frame = data.frameNumber;
DEB_PARAM() << DEB_VAR1(frame);
Data raw = m_jungfrau->getRawData(data);
DoubleBufferWriter<MapData> w(m_buffer);
MapData& m = w.getBuffer();
DEB_TRACE() << DEB_VAR1(&m);
unsigned short *src;
{
src = (unsigned short *) data.data();
src = (unsigned short *) raw.data();
unsigned char *dst = (unsigned char *) m.gain_map.data();
for (int i = 0; i < m_pixels; ++i, ++src, ++dst)
*dst = *src >> 14;
m.gain_map.frameNumber = frame;
}
{
src = (unsigned short *) data.data();
src = (unsigned short *) raw.data();
unsigned short *dst = (unsigned short *) m.adc_map.data();
for (int i = 0; i < m_pixels; ++i, ++src, ++dst)
*dst = *src & 0x3fff;
......@@ -494,9 +487,10 @@ void Jungfrau::GainADCMapImgProc::readGainADCMaps(Data& gain_map, Data& adc_map,
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(frame);
MapData &m = m_reader->addRead(m_buffer, frame);
m_reader->addData(m.gain_map, gain_map);
m_reader->addData(m.adc_map, adc_map);
Helper::Reader *r = m_helper->addRead(m_buffer, frame);
MapData &m = r->getBuffer();
r->addData(m.gain_map, gain_map);
r->addData(m.adc_map, adc_map);
DEB_RETURN() << DEB_VAR3(gain_map, adc_map, frame);
}
......@@ -506,7 +500,7 @@ void Jungfrau::GainADCMapImgProc::readGainADCMaps(Data& gain_map, Data& adc_map,
Jungfrau::GainPedImgProc::GainPedImgProc(Jungfrau *jungfrau)
: ImgProcBase(jungfrau, "gain_ped"), m_gain_ped(jungfrau),
m_reader(new Reader)
m_helper(new Helper)
{
DEB_CONSTRUCTOR();
}
......@@ -547,10 +541,12 @@ void Jungfrau::GainPedImgProc::processFrame(Data& data)
long frame = data.frameNumber;
DEB_PARAM() << DEB_VAR1(frame);
Data raw = m_jungfrau->getRawData(data);
DoubleBufferWriter<MapData> w(m_buffer);
MapData& m = w.getBuffer();
DEB_TRACE() << DEB_VAR1(&m);
m_gain_ped.processFrame(data, m.proc_map);
m_gain_ped.processFrame(raw, m.proc_map);
m.proc_map.frameNumber = frame;
w.setCounter(frame);
}
......@@ -559,11 +555,97 @@ void Jungfrau::GainPedImgProc::readProcMap(Data& proc_map, FrameType& frame)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(frame);
MapData &m = m_reader->addRead(m_buffer, frame);
m_reader->addData(m.proc_map, proc_map);
Helper::Reader *r = m_helper->addRead(m_buffer, frame);
MapData &m = r->getBuffer();
r->addData(m.proc_map, proc_map);
DEB_RETURN() << DEB_VAR2(proc_map, frame);
}
/*
* Jungfrau::AveImgProc class
*/
Jungfrau::AveImgProc::AveImgProc(Jungfrau *jungfrau)
: ImgProcBase(jungfrau, "ave"), m_helper(new Helper), m_nb_frames(0)
{
DEB_CONSTRUCTOR();
m_acc.type = Data::UINT32;
}
void Jungfrau::AveImgProc::updateImageSize(Size size, bool raw)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR3(m_name, size, raw);
ImgProcBase::updateImageSize(size, raw);
for (auto& d : m_buffer)
d.updateSize(size);
updateDataSize(m_acc, size);
}
void Jungfrau::AveImgProc::clear()
{
DEB_MEMBER_FUNCT();
ImgProcBase::clear();
for (auto& d : m_buffer)
d.clear();
m_buffer.reset();
clearData(m_acc);
m_nb_frames = 0;
}
template <class M>
void Jungfrau::AveImgProc::processFrameFunct(Data& data)
{
DEB_MEMBER_FUNCT();
long frame = data.frameNumber;
DEB_PARAM() << DEB_VAR1(frame);
DoubleBufferWriter<MapData> w(m_buffer);
MapData& m = w.getBuffer();
DEB_TRACE() << DEB_VAR1(&m);
++m_nb_frames;
using S = typename M::Pixel;
S *src = (S *) data.data();
unsigned int *acc = (unsigned int *) m_acc.data();
double *ave = (double *) m.ave_map.data();
for (int i = 0; i < m_pixels; ++i, ++src, ++acc, ++ave) {
*acc += *src;
*ave = *acc / m_nb_frames;
}
m.ave_map.frameNumber = frame;
m.nb_frames = m_nb_frames;
w.setCounter(frame);
}
void Jungfrau::AveImgProc::processFrame(Data& data)
{
DEB_MEMBER_FUNCT();
GainPed& gain_ped = m_jungfrau->m_gain_ped_img_proc->m_gain_ped;
GainPed::MapType map_type;
gain_ped.getMapType(map_type);
if (map_type == GainPed::Map16)
processFrameFunct<GainPed::Map16Data>(data);
else
processFrameFunct<GainPed::Map32Data>(data);
}
void Jungfrau::AveImgProc::readAveMap(Data& ave_map, FrameType& nb_frames,
FrameType& frame)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(frame);
Helper::Reader *r = m_helper->addRead(m_buffer, frame);
MapData &m = r->getBuffer();
r->addData(m.ave_map, ave_map);
nb_frames = m.nb_frames;
DEB_RETURN() << DEB_VAR3(ave_map, nb_frames, frame);
}
/*
* Jungfrau::ModelReconstruction class
*/
......@@ -612,6 +694,7 @@ Jungfrau::Jungfrau(Camera *cam)
m_gain_ped_img_proc = new GainPedImgProc(this);
m_gain_adc_map_img_proc = new GainADCMapImgProc(this);
m_ave_img_proc = new AveImgProc(this);
m_reconstruction = new ModelReconstruction(this);
......@@ -913,6 +996,7 @@ void Jungfrau::updateImageSize()
m_gain_ped_img_proc->updateImageSize(size, raw);
m_gain_adc_map_img_proc->updateImageSize(size, raw);
m_ave_img_proc->updateImageSize(size, raw);
}
bool Jungfrau::checkSettings(Settings settings)
......@@ -1209,6 +1293,15 @@ void Jungfrau::doSetImgProcConfig(std::string config, bool force)
DEB_TRACE() << "Adding gain_adc_map";
img_proc_list.push_back(m_gain_adc_map_img_proc);
}
if (checkConfigAndDelete("ave")) {
if (m_img_src == GainPedCorr) {
DEB_TRACE() << "Adding ave";
img_proc_list.push_back(m_ave_img_proc);
} else {
DEB_TRACE() << "Ignoring ave";
m_ave_img_proc->clear();
}
}
if (!config_list.empty())
THROW_HW_ERROR(InvalidValue) << "Invalid " << DEB_VAR1(config);
......@@ -1231,6 +1324,11 @@ void Jungfrau::readGainPedProcMap(Data& proc_map, FrameType& frame)
m_gain_ped_img_proc->readProcMap(proc_map, frame);
}
void Jungfrau::readAveMap(Data& ave_map, FrameType& nb_frames, FrameType& frame)
{
DEB_MEMBER_FUNCT();
m_ave_img_proc->readAveMap(ave_map, nb_frames, frame);
}
void Jungfrau::setGainPedMapType(GainPed::MapType map_type)
{
......
......@@ -41,6 +41,9 @@
#
from .SlsDetector import *
from threading import Thread
import contextlib
#------------------------------------------------------------------
# SlsDetectorJungfrau device class
......@@ -67,6 +70,12 @@ class SlsDetectorJungfrau(SlsDetector):
GainPedProcAttrRe = re.compile('((?P<action>read|write)_)?'
'gain_ped_proc_map(?P<map_type>16|32)')
Tango2NpType = {PyTango.DevUChar: 'uint8',
PyTango.DevUShort: 'uint16',
PyTango.DevULong: 'uint32',
PyTango.DevFloat: 'float32',
PyTango.DevDouble: 'float64'}
def __init__(self,*args) :
SlsDetector.__init__(self,*args)
......@@ -84,6 +93,7 @@ class SlsDetectorJungfrau(SlsDetector):
SlsDetector.init_device(self)
self.gain_ped_bckgnd = None
self.gain_ped_seq = None
def init_list_attr(self):
SlsDetector.init_list_attr(self)
......@@ -117,8 +127,30 @@ class SlsDetectorJungfrau(SlsDetector):
det_map = self.model.getDetMap();
attr.set_value(det_map.buffer)
@Core.DEB_MEMBER_FUNCT
def getFrameSize(self):
raw = self.cam.getRawMode()
size = self.cam.getFrameDim(raw).getSize()
res = size.getWidth(), size.getHeight()
deb.Return('width=%d, height=%d' % res)
return res
@Core.DEB_MEMBER_FUNCT
def readMapCheckGainPedSeq(self, attr):
if not self.gain_ped_seq:
return True
deb.Trace('Pedestal sequence active. Skipping!')
if attr:
width, height = self.getFrameSize()
dtype = self.Tango2NpType[attr.get_data_type()]
d = np.zeros((height, width), dtype)
attr.set_value(d)
return False
@Core.DEB_MEMBER_FUNCT
def read_gain_map(self, attr):
if not self.readMapCheckGainPedSeq(attr):
return
jungfrau = _SlsDetectorJungfrau
gain_data, adc_data, frame = jungfrau.readGainADCMaps(-1)
deb.Return("frame=%s, gain_data=%s" % (frame, gain_data))
......@@ -126,6 +158,8 @@ class SlsDetectorJungfrau(SlsDetector):
@Core.DEB_MEMBER_FUNCT
def read_adc_map(self, attr):
if not self.readMapCheckGainPedSeq(attr):
return
jungfrau = _SlsDetectorJungfrau
gain_data, adc_data, frame = jungfrau.readGainADCMaps(-1)
deb.Return("frame=%s, adc_data=%s" % (frame, adc_data))
......@@ -141,6 +175,8 @@ class SlsDetectorJungfrau(SlsDetector):
@Core.DEB_MEMBER_FUNCT
def read_gain_ped_proc_map(self, attr, map_type):
if not self.readMapCheckGainPedSeq(attr):
return
proc_data, frame = self.getGainPedProcMap(map_type)
data = proc_data.buffer
if self.gain_ped_bckgnd is not None:
......@@ -148,6 +184,16 @@ class SlsDetectorJungfrau(SlsDetector):
deb.Return("frame=%s, data=%s" % (frame, data))
attr.set_value(data)
@Core.DEB_MEMBER_FUNCT
def read_ave_map(self, attr):
if not self.readMapCheckGainPedSeq(attr):
return
jungfrau = _SlsDetectorJungfrau
ave_data, nb_frames, frame = jungfrau.readAveMap(-1)
deb.Return("frame=%s, nb_frames=%s, ave_data=%s" % (frame, nb_frames,
ave_data))
attr.set_value(ave_data.buffer)
@Core.DEB_MEMBER_FUNCT
def setGainPedBackground(self, level=0):
proc_data, frame = self.getGainPedProcMap('32')
......@@ -157,13 +203,163 @@ class SlsDetectorJungfrau(SlsDetector):
def clearGainPedBackground(self):
self.gain_ped_bckgnd = None
@Core.DEB_MEMBER_FUNCT
def write_gain_ped_calib_map(self, attr, map_select, gain):
d = attr.get_write_value()
attr_name = "%s_%d" % (map_select, gain)
deb.Param("%s=%s" % (attr_name, d))
jungfrau = _SlsDetectorJungfrau
c = jungfrau.getGainPedCalib()
l_name = '%s_map' % map_select