...
 
Commits (75)
......@@ -19,9 +19,6 @@
[submodule "camera/pilatus"]
path = camera/pilatus
url = git://github.com/esrf-bliss/Lima-camera-pilatus
[submodule "applications/tango"]
path = applications/tango
url = git://github.com/esrf-bliss/Lima-tango
[submodule "camera/maxipix"]
path = camera/maxipix
url = git://github.com/esrf-bliss/Lima-camera-maxipix
......@@ -124,3 +121,9 @@
[submodule "camera/v4l2"]
path = camera/v4l2
url = git://github.com/esrf-bliss/Lima-camera-v4l2.git
[submodule "applications/tango/python"]
path = applications/tango/python
url = git://github.com/esrf-bliss/Lima-tango-python
[submodule "applications/tango/cpp"]
path = applications/tango/cpp
url = git://github.com/esrf-bliss/Lima-tango-cpp
Stable branch core-1.5
----------------------
core-1.5.6 2015-12-21
Features
* New tags for submodules: frelon-1.5.0/andor-1.5.0/pilatus-1.5.0
* Include Simulator test_prepare_timeout.py script
* Include COMPILE_MYTHEN3 into list of exported vars in config.inc_default
* frelon: Added Frelon native min_latency_time (Readout & Transfer) support
* control: Support dynamic min_latency_time with Accumulation in CtAcquisition
Bug Fixes
* control: Synchronize with ImageStatusCallbacks at the beginning of prepareAcq
* control: Added set/getPrepareTimeout methods (default 2 sec)
core-1.5.5 2015-12-11
Features
* New tags for submodules: spec-1.4.7/andor3.1.5.1/tango-camera-andor3-1.5.1
* andor3: Compressed data (Mono12Packed) and IntTrigMult trigger mode
* tango python: andor3 updaded, no more destride attr
* spec: andor3 updaded, no more destride option
Bug Fixes
* image: fixed checkValid() missing #ifdef for TIFF, only 1 frame per file supported
* saving: Fixed a infinite loop in checkDirectoryAccess() when dir is an empty string
* image: fixed in reevalutation with _setHSRoi
* basler: external trigger fixes
* image: reevaluate software roi when binning change
core-1.5.4 2015-08-14
Features
* New tags for submodules: Espia-1.5.1/maxipix-1.5.2/v4l2-1.5.3/ueye-1.5.0/tango-camera-andor3-1.5.0
Bug Fixes
* hdf5: revert install in Makefile
core.1.5.3 2015-08-12
Features
* control: accumalation mode enhanced again
core-1.5.2 2015-07-27
Features
* New tag for andor3 needs core-1.5 for using accumulation mode
* New tag for prosilica under core-1.5
* simulator: add IntTrigMulti capability
* Updated camera/prosilica
Bug Fixes
* control: fixed deadlock in unregisterImageStatusCallback
* video: fixing dead lock when stopping and changing expo time.
core-1.5.1 2015-06-19
Features
* New tags: v4l2, basler, tango/camera/v4l2. basler-1.5.1/tango-camera-v4l2-1.5.1/v4l2-1.5.1
* Enhanced Accumulation and acc_mode with new mode for threshold and/or offset correction. Updated Spec and Tango for that purpose too.
* accumulation: extend accumulation algorithm to be able to ignore noise lower than a threshold
......@@ -133,21 +133,27 @@ mod_version_data = {
'simulator': 'camera/simulator/VERSION',
'roperscientific': 'camera/roperscientific/VERSION',
'rayonixhs': 'camera/rayonixhs/VERSION',
'v4l2': 'camera/v4l2/VERSION',
'xh': 'camera/xh/VERSION',
'spec': 'applications/spec/VERSION',
'taco/camera/frelon': 'applications/taco/VERSION',
'tango/common': 'applications/tango/VERSION',
'tango/camera/maxipix': 'applications/tango/camera/Maxipix_VERSION',
'tango/camera/pilatus': 'applications/tango/camera/Pilatus_VERSION',
'tango/camera/frelon': 'applications/tango/camera/Frelon_VERSION',
'tango/camera/basler': 'applications/tango/camera/Basler_VERSION',
'tango/camera/prosilica': 'applications/tango/camera/Prosilica_VERSION',
'tango/camera/andor': 'applications/tango/camera/Andor_VERSION',
'tango/camera/andor3': 'applications/tango/camera/Andor3_VERSION',
'tango/camera/perkinelmer': 'applications/tango/camera/PerkinElmer_VERSION',
'tango/camera/xpad': 'applications/tango/camera/Xpad_VERSION',
'tango/camera/pco': 'applications/tango/camera/Pco_VERSION',
'tango/camera/ueye': 'applications/tango/camera/Ueye_VERSION',
'tango/common': 'applications/tango/python/VERSION',
'tango/camera/maxipix': 'applications/tango/python/camera/Maxipix_VERSION',
'tango/camera/pilatus': 'applications/tango/python/camera/Pilatus_VERSION',
'tango/camera/frelon': 'applications/tango/python/camera/Frelon_VERSION',
'tango/camera/basler': 'applications/tango/python/camera/Basler_VERSION',
'tango/camera/prosilica': 'applications/tango/python/camera/Prosilica_VERSION',
'tango/camera/andor': 'applications/tango/python/camera/Andor_VERSION',
'tango/camera/andor3': 'applications/tango/python/camera/Andor3_VERSION',
'tango/camera/perkinelmer': 'applications/tango/python/camera/PerkinElmer_VERSION',
'tango/camera/xpad': 'applications/tango/python/camera/Xpad_VERSION',
'tango/camera/pco': 'applications/tango/python/camera/Pco_VERSION',
'tango/camera/ueye': 'applications/tango/python/camera/Ueye_VERSION',
'tango/camera/simulator': 'applications/tango/camera/Simulator_VERSION',
'tango/camera/roperscientific': 'applications/tango/camera/RoperScientific_VERSION',
'tango/camera/roperscientific': 'applications/python/tango/camera/RoperScientific_VERSION',
'tango/camera/v4l2': 'applications/tango/python/camera/V4l2_VERSION',
'tango/camera/xh': 'applications/tango/python/camera/Xh_VERSION',
'tango/camera/rayonixhs': 'applications/tango/python/camera/RayonixHs_VERSION',
}
windows_plugins = ['pco', 'perkinelmer']
......
Subproject commit 063407a1cac3fd1d5ac7f3420dbb850e6781e1fc
Subproject commit a5b9be5efd7916a28cf0ab06fcc6f17e19194605
Subproject commit 3258a04fa3167a764c381fc6af3aa06b91e9adbc
Subproject commit 66c2e0dc0d8bbb72d74cc921fa8f2cc9cde46a31
Subproject commit ff318c2d96e076cdcd9d1696ef32546e098acbd0
......@@ -440,7 +440,7 @@ endif
ifneq ($(COMPILE_ANDOR3),0)
ANDOR3_LDFLAGS := $(LDFLAGS) -L. -L/usr/local/lib
ANDOR3_LDLIBS := $(LDLIBS) -latcore
ANDOR3_LDLIBS := $(LDLIBS) -latcore -latutility
andor3-name := andor3
andor3-objs := ../camera/andor3/src/Andor3.o
......
Subproject commit 9c52e749543d6355bcd674fa381a0e037dde74c5
Subproject commit 80e3bca060b1d2acd29551c9ca7b1b0b032723fb
Subproject commit 2ee44c51d0edecb9251012e938f22cc763b7f696
Subproject commit 4f66bf26f270a5807bf2ecb2b0ebadcb7f91589d
Subproject commit 492e9742b7b3d0c2fb5b48fcbfc179a9459fee1d
Subproject commit e8ba366ccaa9aeb6d4584ff55a097e631ad2f04d
Subproject commit bbdaca98d6b9a16b8a5beb93da4cd6bd5a3cf934
Subproject commit b38546fdfde96602912dd5abc039c06110e07eb3
Subproject commit e05bde7dbb401285f0a8a39c265878a0360d9fed
Subproject commit 65dac9aab50c13577dfc3134c30bc14ead7b26cc
Subproject commit 29cb8155fe12392a3b31920003b605ded315dd8e
Subproject commit 175bf987a0ffe9d0074e143174807be44c2c16e3
Subproject commit ee418814a33cc279dc7d91dab2a0898b7b42e8ac
Subproject commit 82466182aaddf1574d59350eb0af9b86005bbb35
Subproject commit 39be733d9e93f5bcd5b8e898f7a311e99e110cb2
Subproject commit e9436d7eb0e24835d72ed1b32d1cd0841f04bf8f
Subproject commit 71555458bbf3dfc809b0ddc898a5f272c2a3283a
Subproject commit b73c21d74983609cb9d04caf682dd9f2f67c0913
......@@ -45,6 +45,7 @@ class LIBSIMULATOR_API Camera
HwBufferCtrlObj *getBufferCtrlObj();
FrameBuilder *getFrameBuilder();
void prepareAcq();
void startAcq();
void stopAcq();
......@@ -57,6 +58,8 @@ class LIBSIMULATOR_API Camera
void setLatTime(double lat_time);
void getLatTime(double& lat_time);
void setTrigMode(TrigMode trig_mode) {m_trig_mode = trig_mode;};
void getTrigMode(TrigMode& trig_mode) {trig_mode = m_trig_mode;};
void setBin(const Bin& bin);
void getBin(Bin& bin);
void checkBin(Bin& bin);
......@@ -93,16 +96,14 @@ class LIBSIMULATOR_API Camera
virtual void start();
int getNbAcquiredFrames();
bool m_force_stop;
int m_acq_frame_nb;
protected:
virtual void init();
virtual void execCmd(int cmd);
private:
void execStartAcq();
Camera* m_simu;
int m_acq_frame_nb;
};
friend class SimuThread;
......@@ -113,7 +114,7 @@ class LIBSIMULATOR_API Camera
double m_exp_time;
double m_lat_time;
int m_nb_frames;
TrigMode m_trig_mode;
SimuThread m_thread;
};
......
......@@ -77,9 +77,9 @@ void Camera::SimuThread::execStartAcq()
FrameBuilder& frame_builder = m_simu->m_frame_builder;
frame_builder.resetFrameNr();
int nb_frames = m_simu->m_nb_frames;
int nb_frames = m_simu->m_trig_mode == IntTrig ? m_simu->m_nb_frames : m_acq_frame_nb + 1;
int& frame_nb = m_acq_frame_nb;
for (frame_nb = 0; (frame_nb < nb_frames)||(nb_frames==0); frame_nb++) {
for (;(frame_nb < nb_frames)||(nb_frames==0); frame_nb++) {
double req_time;
if(m_force_stop)
{
......@@ -111,13 +111,6 @@ void Camera::SimuThread::execStartAcq()
setStatus(Ready);
}
int Camera::SimuThread::getNbAcquiredFrames()
{
DEB_MEMBER_FUNCT();
return m_acq_frame_nb;
}
Camera::Camera() :
m_thread(*this)
{
......@@ -244,6 +237,10 @@ HwInterface::StatusType::Basic Camera::getStatus()
throw LIMA_HW_EXC(Error, "Invalid thread status");
}
}
void Camera::prepareAcq()
{
m_thread.m_acq_frame_nb = 0;
}
void Camera::startAcq()
{
......@@ -267,7 +264,7 @@ void Camera::stopAcq()
int Camera::getNbAcquiredFrames()
{
return m_thread.getNbAcquiredFrames();
return m_thread.m_acq_frame_nb;
}
ostream& lima::Simulator::operator <<(ostream& os, Camera& simu)
......
......@@ -95,6 +95,7 @@ void Interface::reset(ResetLevel reset_level)
void Interface::prepareAcq()
{
m_simu.prepareAcq();
}
void Interface::startAcq()
......
......@@ -41,18 +41,26 @@ SyncCtrlObj::~SyncCtrlObj()
bool SyncCtrlObj::checkTrigMode(TrigMode trig_mode)
{
return (trig_mode == IntTrig);
switch(trig_mode)
{
case IntTrig:
case IntTrigMult:
return true;
default:
return false;
}
}
void SyncCtrlObj::setTrigMode(TrigMode trig_mode)
{
if (!checkTrigMode(trig_mode))
throw LIMA_HW_EXC(InvalidValue, "Invalid (external) trigger");
m_simu.setTrigMode(trig_mode);
}
void SyncCtrlObj::getTrigMode(TrigMode& trig_mode)
{
trig_mode = IntTrig;
m_simu.getTrigMode(trig_mode);
}
void SyncCtrlObj::setExpTime(double exp_time)
......
############################################################################
# This file is part of gldisplay, a submodule of LImA project the
# Library for Image Acquisition
#
# Copyright (C) : 2009-2011
# European Synchrotron Radiation Facility
# BP 220, Grenoble 38043
# FRANCE
#
# This is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http:#www.gnu.org/licenses/>.
############################################################################
import sys
import time
import weakref
import threading
import getopt
from Lima import Core
from Lima import Simulator
Core.DEB_GLOBAL(Core.DebModTest)
class TestControl:
Core.DEB_CLASS(Core.DebModTest, 'TestControl')
class ImageStatusCallback(Core.CtControl.ImageStatusCallback):
def __init__(self, test_control, cb_end):
Core.CtControl.ImageStatusCallback.__init__(self)
self.test_control = weakref.ref(test_control)
self.cb_end = cb_end
def imageStatusChanged(self, image_status):
test_control = self.test_control()
if not test_control:
return
self.cb_end.clear()
test_control.imageStatusChanged(image_status)
del test_control
self.cb_end.set()
@Core.DEB_MEMBER_FUNCT
def __init__(self):
self.simu = Simulator.Camera()
self.simu_hw = Simulator.Interface(self.simu)
self.ct_control = Core.CtControl(self.simu_hw)
self.cb_end = threading.Event()
self.cb = self.ImageStatusCallback(self, self.cb_end)
self.ct_control.registerImageStatusCallback(self.cb)
@Core.DEB_MEMBER_FUNCT
def __del__(self):
del self.ct_control
del self.simu_hw
@Core.DEB_MEMBER_FUNCT
def start(self, exp_time, nb_frames, prepare_timeout, sleep_time):
ct_acq = self.ct_control.acquisition()
ct_acq.setAcqExpoTime(exp_time)
ct_acq.setAcqNbFrames(nb_frames)
self.sleep_time = sleep_time
if hasattr(self.ct_control, 'setPrepareTimeout'):
self.ct_control.setPrepareTimeout(prepare_timeout)
self.ct_control.prepareAcq()
deb.Always('prepareAcq finished')
self.ct_control.startAcq()
@Core.DEB_MEMBER_FUNCT
def waitAcq(self):
def acq_status():
return self.ct_control.getStatus().AcquisitionStatus
while acq_status() == Core.AcqRunning:
time.sleep(10e-3)
deb.Always('Acq. is ready')
@Core.DEB_MEMBER_FUNCT
def sync(self):
self.waitAcq()
self.cb_end.wait()
@Core.DEB_MEMBER_FUNCT
def imageStatusChanged(self, img_status):
last_img_ready = img_status.LastImageReady
if last_img_ready < 0:
return
image = self.ct_control.ReadImage(last_img_ready)
time.sleep(self.sleep_time)
deb.Always('Forcing read frame %d memory' % last_img_ready)
data = ' ' + image.buffer.tostring()
class TestControlAutoSync:
Core.DEB_CLASS(Core.DebModTest, 'TestControlAutoSync')
def __init__(self):
self.test_control = TestControl()
self.traceRefCount(1)
def __del__(self):
self.traceRefCount(2)
self.test_control.sync()
self.traceRefCount(3)
@Core.DEB_MEMBER_FUNCT
def traceRefCount(self, point):
deb.Trace("%s* refcount(test_control): %s" %
(point, sys.getrefcount(self.test_control)))
def __getattr__(self, name):
return getattr(self.test_control, name)
@Core.DEB_FUNCT
def main(argv):
verbose = False
opts, args = getopt.getopt(argv[1:], 'v')
for opt, val in opts:
if opt == '-v':
verbose = True
deb_type_flags = Core.DebParams.AllFlags if verbose else 0
Core.DebParams.setTypeFlags(deb_type_flags)
exp_time = 0.1
test_control = TestControlAutoSync()
i = 0
nb_frames = 2
prepare_timeout = 0.2
sleep_time = 0.1
deb.Always("AcqNb: %s" % i)
test_control.start(exp_time, nb_frames, prepare_timeout, sleep_time)
test_control.waitAcq()
i += 1
deb.Always("AcqNb: %s" % i)
nb_frames = 1
sleep_time = 0.5
test_control.start(exp_time, nb_frames, prepare_timeout, sleep_time)
test_control.waitAcq()
i += 1
deb.Always("AcqNb: %s" % i)
err = 'ImageStatusCallback still active'
ok = False
try:
test_control.start(exp_time, nb_frames, prepare_timeout,
sleep_time)
except Core.Exception, e:
if err in e.args[0]:
ok = True
deb.Always('Got good exception: %s' % e)
if not ok:
raise RuntimeError, 'Expected exception: %s' % err
if __name__ == '__main__':
main(sys.argv)
Subproject commit 82aae155fcb31bbf7c4c8d10da64d7a401fbf209
Subproject commit 25e795950ad30878a58e122f2c94fe292831d1a7
Subproject commit 531170d68f5bbe652d024cad90ee0af241f49494
Subproject commit b78dd2aeefc7d66f4b734fe413148e5414d0e2ff
Subproject commit f7472dab046b5d2fcf0ea48b12fed7c3d0d98edd
Subproject commit ccb7c8b5744101233dcc21a96e0e58ef035dad8b
......@@ -64,7 +64,8 @@ LINK_STRICT_VERSION=0
export COMPILE_CORE COMPILE_SPS_IMAGE COMPILE_SIMULATOR \
COMPILE_ESPIA COMPILE_FRELON COMPILE_MAXIPIX COMPILE_PILATUS \
COMPILE_BASLER COMPILE_PROSILICA COMPILE_ROPERSCIENTIFIC COMPILE_ADSC \
COMPILE_MYTHEN COMPILE_UEYE COMPILE_XH COMPILE_XSPRESS3 COMPILE_ULTRA COMPILE_XPAD COMPILE_PERKINELMER \
COMPILE_UEYE COMPILE_XH COMPILE_XSPRESS3 COMPILE_ULTRA COMPILE_XPAD COMPILE_PERKINELMER \
COMPILE_MYTHEN COMPILE_MYTHEN3 \
COMPILE_ANDOR COMPILE_ANDOR3 COMPILE_PHOTONICSCIENCE COMPILE_PCO COMPILE_MARCCD COMPILE_DEXELA\
COMPILE_POINTGREY COMPILE_IMXPAD COMPILE_RAYONIXHS COMPILE_AVIEX COMPILE_META COMPILE_MERLIN COMPILE_V4l2\
COMPILE_CBF_SAVING COMPILE_NXS_SAVING COMPILE_FITS_SAVING COMPILE_EDFGZ_SAVING COMPILE_TIFF_SAVING \
......
//###########################################################################
// This file is part of LImA, a Library for Image Acquisition
//
// Copyright (C) : 2009-2011
// Copyright (C) : 2009-2015
// European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// FRANCE
......@@ -48,6 +48,7 @@ namespace lima
{
DEB_CLASS_NAMESPC(DebModControl,"Accumulation::Parameters","Control");
public:
enum Mode {STANDARD,THRESHOLD_BEFORE, OFFSET_THEN_THRESHOLD_BEFORE};
Parameters();
void reset();
......@@ -56,6 +57,9 @@ namespace lima
bool savingFlag; ///< saving flag if true save saturatedImageCounter
std::string savePrefix; ///< prefix filename of saturatedImageCounter (default is saturated_image_counter)
Mode mode;
long long thresholdB4Acc; ///< value used in mode THRESHOLD_BEFORE
long long offsetB4Acc; ///< value used in OFFSET_THEN_THRESHOLD_BEFORE
};
class ThresholdCallback
......@@ -94,6 +98,15 @@ namespace lima
void setSavePrefix(const std::string &savePrefix);
void getSavePrefix(std::string &savePrefix) const;
void getMode(Parameters::Mode& mode) const;
void setMode(Parameters::Mode mode);
void getThresholdBefore(long long&) const;
void setThresholdBefore(const long long&);
void getOffsetBefore(long long&) const;
void setOffsetBefore(const long long&);
// --- variable and data result of Concatenation or Accumulation
void readSaturatedImageCounter(Data&,long frameNumber = -1);
......@@ -159,6 +172,8 @@ namespace lima
void getFrame(Data &,int frameNumber);
void _accFrame(Data &src,Data &dst);
void _accFrameWithThreshold(Data &src,Data &dst,long long threshold_value);
void _accFrameWithOffsetThenThreshold(Data &src,Data &dst,long long offset, long long threshold_value);
void _calcSaturatedImageNCounters(Data &src,Data &dst);
inline void _callIfNeedThresholdCallback(Data &aData,long long value);
......
......@@ -210,6 +210,9 @@ namespace lima
void setReconstructionTask(LinkTask*);
void setPrepareTimeout(double timeout);
void getPrepareTimeout(double& timeout) const;
protected:
bool newFrameReady(Data& data);
void newFrameToSave(Data& data);
......@@ -286,6 +289,8 @@ namespace lima
SoftOpErrorHandler* m_soft_op_error_handler;
_ReconstructionChangeCallback* m_reconstruction_cbk;
static double m_prepare_timeout;
inline bool _checkOverrun(Data&);
inline void _calcAcqStatus();
......
......@@ -186,6 +186,7 @@ class LIMACORE_API CtImage {
private:
void _setMaxImage(const Size &size, ImageType type);
void _setHSRoi(const Roi &roi);
void _completeWithSoftRoi(Roi roi_set,Roi hw_roi);
void _setHSBin(const Bin &bin);
void _setHSFlip(const Flip &flip);
void _resetFlip();
......
......@@ -31,6 +31,7 @@ public:
struct Parameters
{
enum Mode {STANDARD,THRESHOLD_BEFORE, OFFSET_THEN_THRESHOLD_BEFORE};
Parameters();
void reset();
......@@ -39,7 +40,9 @@ public:
bool savingFlag; ///< saving flag if true save saturatedImageCounter
std::string savePrefix; ///< prefix filename of saturatedImageCounter (default is saturated_image_counter)
const char* __repr__();
Mode mode;
long long thresholdB4Acc; ///< value used in mode THRESHOLD_BEFORE
const char* __repr__();
%MethodCode
std::ostringstream str;
str << *sipCpp;
......@@ -82,6 +85,16 @@ public:
void setSavePrefix(const std::string &savePrefix);
void getSavePrefix(std::string &savePrefix /Out/) const;
void getMode(Parameters::Mode& mode) const;
void setMode(Parameters::Mode mode);
void getThresholdBefore(long long&) const;
void setThresholdBefore(const long long&);
void getOffsetBefore(long long&) const;
void setOffsetBefore(const long long&);
// --- variable and data result of Concatenation or Accumulation
void readSaturatedImageCounter(Data& /Out/,long frameNumber = -1);
......
......@@ -168,6 +168,9 @@ using namespace lima;
void setReconstructionTask(LinkTask*);
void setPrepareTimeout(double timeout);
void getPrepareTimeout(double& timeout /Out/) const;
protected:
bool newFrameReady(Data& data);
void newFrameToSave(Data& data);
......
......@@ -188,7 +188,10 @@ private:
CtAccumulation::Parameters::Parameters() :
pixelThresholdValue(2^16),
savingFlag(false),
savePrefix("saturated_")
savePrefix("saturated_"),
mode(CtAccumulation::Parameters::STANDARD),
thresholdB4Acc(0),
offsetB4Acc(0)
{
reset();
}
......@@ -350,6 +353,42 @@ void CtAccumulation::getSavePrefix(std::string &savePrefix) const
savePrefix = m_pars.savePrefix;
}
void CtAccumulation::getMode(Parameters::Mode &mode) const
{
AutoMutex aLock(m_cond.mutex());
mode = m_pars.mode;
}
void CtAccumulation::setMode(Parameters::Mode mode)
{
AutoMutex aLock(m_cond.mutex());
m_pars.mode = mode;
}
void CtAccumulation::getThresholdBefore(long long& threshold) const
{
AutoMutex aLock(m_cond.mutex());
threshold = m_pars.thresholdB4Acc;
}
void CtAccumulation::setThresholdBefore(const long long& threshold)
{
AutoMutex aLock(m_cond.mutex());
m_pars.thresholdB4Acc = threshold;
}
void CtAccumulation::getOffsetBefore(long long& offset) const
{
AutoMutex aLock(m_cond.mutex());
offset = m_pars.offsetB4Acc;
}
void CtAccumulation::setOffsetBefore(const long long& offset)
{
AutoMutex aLock(m_cond.mutex());
m_pars.offsetB4Acc = offset;
}
/** @brief read the saturated image of accumulated image which id is frameNumber
@param saturatedImage the saturated image conter (empty if not yet available)
@param frameNumber the frame acquisition id
......@@ -614,12 +653,24 @@ bool CtAccumulation::_newBaseFrameReady(Data &aData)
Data saturatedImg;
if(active)
saturatedImg = m_saturated_images.back();
Parameters::Mode aMode = m_pars.mode;
long long threshold_value = m_pars.thresholdB4Acc;
long long offset_value = m_pars.offsetB4Acc;
aLock.unlock();
if(active)
_calcSaturatedImageNCounters(aData,saturatedImg);
_accFrame(aData,accFrame);
switch(aMode)
{
case Parameters::STANDARD:
_accFrame(aData,accFrame);break;
case Parameters::THRESHOLD_BEFORE:
_accFrameWithThreshold(aData,accFrame, threshold_value);break;
case Parameters::OFFSET_THEN_THRESHOLD_BEFORE:
_accFrameWithOffsetThenThreshold(aData,accFrame,offset_value, threshold_value);break;
}
if(!((aData.frameNumber + 1) % nb_acc_frame))
m_last_continue_flag = m_ct.newFrameReady(accFrame);
......@@ -685,10 +736,73 @@ void CtAccumulation::_accFrame(Data &src,Data &dst)
THROW_CTL_ERROR(Error) << "Data type for accumulation is not yet managed";
}
}
template <class SrcType, class DstType>
void accumulateFrameThreshold(void *src_ptr,void *dst_ptr,int nb_items,long long threshold)
{
SrcType *sp = (SrcType *) src_ptr;
DstType *dp = (DstType *) dst_ptr;
for(int i = nb_items;i;--i,++sp,++dp)
if(*sp > threshold)
*dp += *sp;
}
void CtAccumulation::_accFrameWithThreshold(Data &src,Data &dst,long long threshold_value)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR2(src,dst);
int nb_items = src.dimensions[0] * src.dimensions[1];
switch(src.type)
{
case Data::UINT8: accumulateFrameThreshold<unsigned char,int> (src.data(),dst.data(),nb_items,threshold_value);break;
case Data::INT8: accumulateFrameThreshold<char,int> (src.data(),dst.data(),nb_items,threshold_value);break;
case Data::UINT16: accumulateFrameThreshold<unsigned short,int> (src.data(),dst.data(),nb_items,threshold_value);break;
case Data::INT16: accumulateFrameThreshold<short,int> (src.data(),dst.data(),nb_items,threshold_value);break;
case Data::UINT32: accumulateFrameThreshold<unsigned int,int> (src.data(),dst.data(),nb_items,threshold_value);break;
case Data::INT32: accumulateFrameThreshold<int,int> (src.data(),dst.data(),nb_items,threshold_value);break;
default:
THROW_CTL_ERROR(Error) << "Data type for accumulation is not yet managed";
}
}
template <class SrcType, class DstType>
void accumulateFrameOffsetThenThreshold(void *src_ptr,void *dst_ptr,int nb_items,long long offset, long long threshold)
{
SrcType *sp = (SrcType *) src_ptr;
DstType *dp = (DstType *) dst_ptr;
DstType tmp_d;
for(int i = nb_items;i;--i,++sp,++dp)
{
tmp_d = DstType(*sp) - offset;
if(tmp_d > threshold)
*dp += tmp_d;
}
}
void CtAccumulation::_accFrameWithOffsetThenThreshold(Data &src,Data &dst,long long offset_value, long long threshold_value)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR2(src,dst);
int nb_items = src.dimensions[0] * src.dimensions[1];
switch(src.type)
{
case Data::UINT8: accumulateFrameOffsetThenThreshold<unsigned char,int> (src.data(),dst.data(),nb_items,offset_value, threshold_value);break;
case Data::INT8: accumulateFrameOffsetThenThreshold<char,int> (src.data(),dst.data(),nb_items,offset_value, threshold_value);break;
case Data::UINT16: accumulateFrameOffsetThenThreshold<unsigned short,int> (src.data(),dst.data(),nb_items,offset_value, threshold_value);break;
case Data::INT16: accumulateFrameOffsetThenThreshold<short,int> (src.data(),dst.data(),nb_items,offset_value, threshold_value);break;
case Data::UINT32: accumulateFrameOffsetThenThreshold<unsigned int,int> (src.data(),dst.data(),nb_items,offset_value, threshold_value);break;
case Data::INT32: accumulateFrameOffsetThenThreshold<int,int> (src.data(),dst.data(),nb_items,offset_value, threshold_value);break;
default:
THROW_CTL_ERROR(Error) << "Data type for accumulation is not yet managed";
}
}
#ifdef WITH_CONFIG
CtConfig::ModuleTypeCallback* CtAccumulation::_getConfigHandler()
{
return new _ConfigHandler(*this);
}
#endif //WITH_CONFIG
\ No newline at end of file
#endif //WITH_CONFIG
......@@ -22,6 +22,8 @@
#include "lima/CtAcquisition.h"
#include "math.h"
#include <algorithm>
using std::max;
#define CHECK_EXPOTIME(val) \
if (val < m_valid_ranges.min_exp_time) \
......@@ -142,7 +144,6 @@ CtAcquisition::CtAcquisition(HwInterface *hw) :
CtAcquisition::~CtAcquisition()
{
DEB_DESTRUCTOR();
m_hw_sync->unregisterValidRangesCallback(m_valid_ranges_cb);
delete m_valid_ranges_cb;
}
......@@ -175,7 +176,7 @@ void CtAcquisition::reset()
DEB_MEMBER_FUNCT();
m_inpars.reset();
m_inpars.latencyTime = m_valid_ranges.min_lat_time;
m_inpars.latencyTime = 0;
m_applied_once= false;
//Check auto exposure capability
......@@ -249,6 +250,8 @@ void CtAcquisition::_hwRead()
m_hw_sync->getTrigMode(m_hwpars.triggerMode);
m_hw_sync->getExpTime(m_hwpars.acqExpoTime);
m_hw_sync->getLatTime(m_hwpars.latencyTime);
if (m_hwpars.latencyTime <= m_valid_ranges.min_lat_time)
m_hwpars.latencyTime = 0;
m_hw_sync->getNbFrames(m_hwpars.acqNbFrames);
switch (m_hwpars.acqMode) {
......@@ -276,7 +279,8 @@ void CtAcquisition::_apply()
m_hw_sync->setAcqMode(m_inpars.acqMode);
if (m_changes.triggerMode) m_hw_sync->setTrigMode(m_inpars.triggerMode);
if (m_changes.latencyTime) m_hw_sync->setLatTime(m_inpars.latencyTime);
double lat_time = max(m_inpars.latencyTime, m_valid_ranges.min_lat_time);
if (m_changes.latencyTime) m_hw_sync->setLatTime(lat_time);
if(m_changes.acqMode || m_changes.acqNbFrames)
{
......@@ -638,8 +642,8 @@ void CtAcquisition::setLatencyTime(double lat_time)
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(lat_time);
if (lat_time < m_valid_ranges.min_lat_time)
lat_time = m_valid_ranges.min_lat_time;
if (lat_time <= m_valid_ranges.min_lat_time)
lat_time = 0;
if (lat_time > m_valid_ranges.max_lat_time)
THROW_CTL_ERROR(InvalidValue)
<< "Specified latency time " << DEB_VAR1(lat_time) << " too long: "
......@@ -651,7 +655,7 @@ void CtAcquisition::getLatencyTime(double& time) const
{
DEB_MEMBER_FUNCT();
time= m_inpars.latencyTime;
time= max(m_inpars.latencyTime, m_valid_ranges.min_lat_time);
DEB_RETURN() << DEB_VAR1(time);
}
......
......@@ -163,6 +163,8 @@ public:
void imageStatusChanged(const ImageStatus& status, bool force=false,
bool wait=false);
bool waitIdle(double timeout=-1.0);
protected:
virtual void threadFunction();
......@@ -177,14 +179,16 @@ private:
ImageStatusCallback *m_cb;
ImageStatus m_last_status;
std::list<ChangeEvent *> m_event_list;
bool m_waiting;
};
CtControl::ImageStatusThread::ImageStatusThread(Cond& cond,
ImageStatusCallback *cb)
: m_cond(cond), m_cb(cb)
: m_cond(cond), m_cb(cb), m_waiting(false)
{
DEB_CONSTRUCTOR();
start();
waitIdle();
}
CtControl::ImageStatusThread::~ImageStatusThread()
......@@ -252,8 +256,15 @@ void CtControl::ImageStatusThread::threadFunction()
AutoMutex lock(m_cond.mutex());
while (true) {
while (m_event_list.empty())
while (m_event_list.empty()) {
if (!m_waiting) {
m_waiting = true;
m_cond.broadcast();
}
m_cond.wait();
}
m_waiting = false;
ChangeEvent *event = m_event_list.back();
m_event_list.pop_back();
......@@ -274,12 +285,27 @@ void CtControl::ImageStatusThread::threadFunction()
delete event;
}
m_waiting = false;
m_cond.broadcast();
}
bool CtControl::ImageStatusThread::waitIdle(double timeout)
{
DEB_MEMBER_FUNCT();
AutoMutex lock(m_cond.mutex());
while (!m_waiting)
if (!m_cond.wait(timeout))
break;
return m_waiting;
}
// --- helper
double CtControl::m_prepare_timeout = 2;
CtControl::CtControl(HwInterface *hw) :
m_hw(hw),
......@@ -416,6 +442,12 @@ void CtControl::prepareAcq()
{
DEB_MEMBER_FUNCT();
ImageStatusThreadList::iterator i, end = m_img_status_thread_list.end();
for (i = m_img_status_thread_list.begin(); i != end; ++i)
if (!(*i)->waitIdle(m_prepare_timeout))
THROW_CTL_ERROR(Error) << "ImageStatusCallback still active after "
<< m_prepare_timeout << " sec";
Status aStatus;
getStatus(aStatus);
......@@ -830,6 +862,22 @@ void CtControl::setReconstructionTask(LinkTask *task)
m_op_int->setReconstructionTask(task);
}
void CtControl::setPrepareTimeout(double timeout)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(timeout);
if ((timeout < 0) && (timeout != -1))
THROW_CTL_ERROR(InvalidValue) << "Invalid timeout: " << timeout;
m_prepare_timeout = timeout;
}
void CtControl::getPrepareTimeout(double& timeout) const
{
DEB_MEMBER_FUNCT();
timeout = m_prepare_timeout;
DEB_RETURN() << DEB_VAR1(timeout);
}
void CtControl::reset()
{
DEB_MEMBER_FUNCT();
......@@ -1101,9 +1149,11 @@ void CtControl::unregisterImageStatusCallback(ImageStatusCallback& cb)
if((*i)->cb() == &cb)
{
found = true;
delete *i;
ImageStatusThread* status_thread = *i;
m_img_status_thread_list.erase(i);
cb.setImageStatusCallbackGen(NULL);
aLock.unlock();
delete status_thread;
break;
}
}
......
......@@ -743,6 +743,7 @@ void CtImage::_setHSBin(const Bin &bin)
Bin set_sw_bin= bin / set_hw_bin;
m_sw->setBin(set_sw_bin);
}
_completeWithSoftRoi(m_hw->getSetRoi(),m_hw->getRealRoi());
} else {
m_sw->setBin(bin);
}
......@@ -755,10 +756,9 @@ void CtImage::_setHSRoi(const Roi &roi)
DEB_PARAM() << DEB_VAR1(roi);
if (m_hw->hasRoiCapability()) {
Roi roi_unbin, roi_by_hw, roi_set_hw, roi_by_sw;
Roi roi_unbin, roi_by_hw, roi_set_hw;
Bin bin_total, bin_by_hw, bin_by_sw;
RotationMode aSoftwareRotation = m_sw->getRotation();
bin_by_hw= m_hw->getBin();
......@@ -769,39 +769,54 @@ void CtImage::_setHSRoi(const Roi &roi)
roi_unbin= roi.getUnbinned(bin_total);
roi_by_hw= roi_unbin.getBinned(bin_by_hw);
const Size& max_roi_size = m_hw->getMaxRoiSize();
// Remove the rotation to hardware Roi
roi_by_hw= roi_by_hw.getUnrotated(aSoftwareRotation,max_roi_size);
// Remove the software Flip to hardware Roi
const Flip &aSoftwareFlip = m_sw->getFlip();
roi_by_hw= roi_by_hw.getFlipped(aSoftwareFlip,max_roi_size);
roi_set_hw= roi_by_hw;
m_hw->setRoi(roi_set_hw, true);
DEB_TRACE() << DEB_VAR2(roi_by_hw, roi_set_hw);
if (roi_set_hw==roi_by_hw) {
m_sw->resetRoi();
} else {
// Apply software flip to hardware roi
roi_set_hw = roi_set_hw.getFlipped(aSoftwareFlip,max_roi_size);
roi_by_hw = roi_by_hw.getFlipped(aSoftwareFlip,max_roi_size);
//Apply software rotation to hardware roi
roi_set_hw = roi_set_hw.getRotated(aSoftwareRotation,max_roi_size);
roi_by_hw = roi_by_hw.getRotated(aSoftwareRotation,max_roi_size);
//Calc the roi by soft needed
roi_by_sw= roi_set_hw.subRoiAbs2Rel(roi_by_hw);
roi_by_sw= roi_by_sw.getBinned(bin_by_sw);
m_sw->setRoi(roi_by_sw);
}
_completeWithSoftRoi(roi_by_hw, roi_set_hw);
} else {
m_sw->setRoi(roi);
}
}
void CtImage::_completeWithSoftRoi(Roi roi_set,Roi hw_roi)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR2(roi_set,hw_roi);
if (roi_set==hw_roi) {
m_sw->resetRoi();
} else {
const Size& max_roi_size = m_hw->getMaxRoiSize();
RotationMode aSoftwareRotation = m_sw->getRotation();
// Remove the rotation to hardware Roi
hw_roi= hw_roi.getUnrotated(aSoftwareRotation,max_roi_size);
// Remove the software Flip to hardware Roi
const Flip &aSoftwareFlip = m_sw->getFlip();
hw_roi= hw_roi.getFlipped(aSoftwareFlip,max_roi_size);
// Apply software flip to hardware roi
roi_set = roi_set.getFlipped(aSoftwareFlip,max_roi_size);
hw_roi = hw_roi.getFlipped(aSoftwareFlip,max_roi_size);
//Apply software rotation to hardware roi
roi_set = roi_set.getRotated(aSoftwareRotation,max_roi_size);
hw_roi = hw_roi.getRotated(aSoftwareRotation,max_roi_size);
//Calc the roi by soft needed
Bin bin_by_sw = m_sw->getBin();
Roi roi_by_sw;
roi_by_sw= hw_roi.subRoiAbs2Rel(roi_set);
roi_by_sw= roi_by_sw.getBinned(bin_by_sw);
m_sw->setRoi(roi_by_sw);
DEB_TRACE() << DEB_VAR1(roi_by_sw);
}
}
void CtImage::setFlip(Flip &flip)
{
DEB_MEMBER_FUNCT();
......
......@@ -167,6 +167,8 @@ void CtSaving::Parameters::checkValid() const
THROW_CTL_ERROR(InvalidValue) << "CBF file format does not support "
"multi frame per file";
break;
#endif
#ifdef WITH_TIFF_SAVING
case TIFFFormat :
if(framesPerFile > 1)
THROW_CTL_ERROR(InvalidValue) << "TIFF file format does not support "
......@@ -2141,9 +2143,13 @@ void CtSaving::Stream::checkDirectoryAccess(const std::string& directory)
size_t pos = local_directory.find_last_of("/");
#endif
size_t string_length = local_directory.size() - 1;
continue_flag = pos == string_length;
if(pos != std::string::npos)
local_directory = local_directory.substr(0,pos);
{
local_directory = local_directory.substr(0,pos);
continue_flag = pos == string_length;
}
else
continue_flag = false;
}
while(continue_flag);
......
......@@ -517,9 +517,10 @@ void CtVideo::_setLive(bool liveFlag)
DEB_TRACE() << "Done with the startAcq.";
}
else {
//aLock.unlock();
aLock.unlock();
DEB_TRACE() << "Stopping the acquisition at the controller level";
m_ct.stopAcq();
aLock.lock();
}
}
m_pars.live = liveFlag;
......@@ -898,11 +899,11 @@ void CtVideo::_apply_params(AutoMutex &aLock,bool aForceLiveFlag)
acquisition->setAcqExpoTime(m_pars.exposure);
if(m_pars.live)
{
m_ct.stopAcq();
aLock.unlock();
m_ct.stopAcq();
m_ct.prepareAcq();
aLock.lock();
m_ct.startAcq();
aLock.lock();
m_pars.live = true;
}
}
......
......@@ -70,12 +70,14 @@ public:
class ValidRangesCallback
{
DEB_CLASS(DebModHardware,"HwSyncCtrlObj::ValidRangesCallback");
friend class HwSyncCtrlObj;
public:
virtual ~ValidRangesCallback() {};
ValidRangesCallback();
virtual ~ValidRangesCallback();
protected:
virtual void validRangesChanged(const HwSyncCtrlObj::ValidRangesType&) = 0;
private:
friend class HwSyncCtrlObj;
HwSyncCtrlObj* m_hw_sync;
};
HwSyncCtrlObj();
......
......@@ -54,6 +54,7 @@ sipRes = tmpString.c_str();
class ValidRangesCallback
{
public:
ValidRangesCallback();
virtual ~ValidRangesCallback();
protected:
virtual void validRangesChanged(const HwSyncCtrlObj::ValidRangesType&) = 0;
......
......@@ -24,16 +24,29 @@
using namespace lima;
HwSyncCtrlObj::ValidRangesCallback::ValidRangesCallback()
: m_hw_sync(NULL)
{
}
HwSyncCtrlObj::ValidRangesCallback::~ValidRangesCallback()
{
if (m_hw_sync)
m_hw_sync->unregisterValidRangesCallback(this);
}
HwSyncCtrlObj::HwSyncCtrlObj()
: m_acq_mode(Single),
m_valid_ranges_cb(NULL)
{
DEB_CONSTRUCTOR();
DEB_CONSTRUCTOR();
}
HwSyncCtrlObj::~HwSyncCtrlObj()
{
DEB_DESTRUCTOR();
DEB_DESTRUCTOR();
if (m_valid_ranges_cb)
unregisterValidRangesCallback(m_valid_ranges_cb);
}
bool HwSyncCtrlObj::checkAutoExposureMode(AutoExposureMode mode) const
......@@ -92,6 +105,7 @@ void HwSyncCtrlObj::registerValidRangesCallback(ValidRangesCallback *cb)
throw LIMA_CTL_EXC(InvalidValue,"ValidRangesCallback already registered");
}
cb->m_hw_sync = this;
m_valid_ranges_cb = cb;
}
......@@ -107,6 +121,7 @@ void HwSyncCtrlObj::unregisterValidRangesCallback(ValidRangesCallback *cb)
}
m_valid_ranges_cb = NULL;
cb->m_hw_sync = NULL;
}
std::ostream& lima::operator<<(std::ostream& os,const HwSyncCtrlObj::ValidRangesType &range)
......
......@@ -258,4 +258,9 @@ hdf5.confsrc:
--prefix=$(INSTALL_PLAT_DIR)
hdf5.install:
$(MAKE) -C hdf5 install prefix=$(INSTALL_PLAT_DIR)
cd hdf5 && ./configure --enable-cxx \
--enable-unsupported \
--enable-threadsafe \
--with-pthread=/usr/lib,/usr/include \
--prefix=$(INSTALL_PLAT_DIR) \
&& $(MAKE) install