First working version of hardware saving with Pilatus

parent 181c9dea
Subproject commit f62bc46bb4dbca5be759cc3901277e3521ca5bee
Subproject commit a3434f09aaf3d1a623fe1e563b3100f7172bc4a4
......@@ -89,6 +89,8 @@ namespace lima {
void getDataFromHwFrameInfo(Data&,const HwFrameInfoType&,
int readBlockLen=1);
static void transformHwFrameInfoToData(Data&,const HwFrameInfoType&,
int readBlockLen=1);
private:
class _DataDestroyCallback;
friend class _DataDestroyCallback;
......
This diff is collapsed.
......@@ -197,6 +197,8 @@ using namespace lima;
void getFramePerFile(unsigned long& frames_per_file /Out/,
int stream_idx=0) const;
void setManagedMode(ManagedMode mode);
void getManagedMode(ManagedMode &mode /Out/) const;
// --- common headers
void resetCommonHeader();
......
......@@ -256,9 +256,9 @@ void CtBuffer::setup(CtControl *ct)
m_hw_buffer_cb->releaseAll();
}
void CtBuffer::getDataFromHwFrameInfo(Data &fdata,
const HwFrameInfoType& frame_info,
int readBlockLen)
void CtBuffer::transformHwFrameInfoToData(Data &fdata,
const HwFrameInfoType& frame_info,
int readBlockLen)
{
DEB_STATIC_FUNCT();
DEB_PARAM() << DEB_VAR2(frame_info, readBlockLen);
......@@ -302,12 +302,20 @@ void CtBuffer::getDataFromHwFrameInfo(Data &fdata,
fdata.setBuffer(fbuf);
fbuf->unref();
}
void CtBuffer::getDataFromHwFrameInfo(Data &fdata,
const HwFrameInfoType& frame_info,
int readBlockLen)
{
DEB_MEMBER_FUNCT();
transformHwFrameInfoToData(fdata,frame_info,readBlockLen);
// Manage Buffer callback
if(m_hw_buffer_cb)
{
m_hw_buffer_cb->map(frame_info.frame_ptr);
fbuf->callback = m_data_destroy_callback;
fdata.buffer->callback = m_data_destroy_callback;
}
DEB_RETURN() << DEB_VAR1(fdata);
}
......
......@@ -244,6 +244,11 @@ void CtControl::prepareAcq()
DEB_TRACE() << "Prepare Accumulation if needed";
m_ct_accumulation->prepare();
DEB_TRACE() << "Prepare Saving if needed";
m_ct_saving->_prepare();
m_autosave= m_ct_saving->hasAutoSaveMode();
m_ready= true;
DEB_TRACE() << "Prepare Hardware for Acquisition";
m_hw->prepareAcq();
......@@ -283,10 +288,6 @@ void CtControl::prepareAcq()
else
m_op_ext->setEndSinkTaskCallback(NULL);
m_ct_saving->_prepare();
m_autosave= m_ct_saving->hasAutoSaveMode();
m_ready= true;
#ifdef WITH_SPS_IMAGE
m_display_active_flag = m_ct_sps_image->isActive();
if(m_display_active_flag)
......@@ -302,6 +303,19 @@ void CtControl::prepareAcq()
m_images_buffer.clear();
m_ct_video->_prepareAcq();
m_ct_event->_prepareAcq();
//Check that no software operation is done if Hardware saving is activated
CtSaving::ManagedMode savingManagedMode;
m_ct_saving->getManagedMode(savingManagedMode);
if(savingManagedMode == CtSaving::Hardware &&
(m_op_int_active ||
m_op_ext_link_task_active ||
m_op_ext_sink_task_active ||
#ifdef WITH_SPS_IMAGE
m_display_active_flag ||
#endif
m_ct_video->isActive()))
THROW_CTL_ERROR(Error) << "Can't have any software operation if Hardware saving is active";
}
void CtControl::startAcq()
......@@ -472,7 +486,18 @@ void CtControl::ReadImage(Data &aReturnData,long frameNumber,
else
{
aLock.unlock();
ReadBaseImage(aReturnData,frameNumber,readBlockLen); // todo change when external op activated
CtSaving::ManagedMode savingManagedMode;
m_ct_saving->getManagedMode(savingManagedMode);
if(savingManagedMode == CtSaving::Hardware)
{
if (readBlockLen != 1)
THROW_CTL_ERROR(NotSupported) << "Cannot read more than one frame "
<< "at a time with Hardware Saving";
m_ct_saving->_ReadImage(aReturnData,frameNumber);
}
else
ReadBaseImage(aReturnData,frameNumber,readBlockLen);
}
DEB_RETURN() << DEB_VAR1(aReturnData);
......
......@@ -35,6 +35,7 @@
#include "CtSaving.h"
#include "CtSaving_Edf.h"
#include "CtAcquisition.h"
#include "CtBuffer.h"
#ifdef WITH_NXS_SAVING
#include "CtSaving_Nxs.h"
......@@ -141,7 +142,7 @@ private:
*/
CtSaving::Parameters::Parameters()
: nextNumber(0), fileFormat(RAW), savingMode(Manual),
overwritePolicy(Abort),managedMode(Software),
overwritePolicy(Abort),
indexFormat("%04d"),framesPerFile(1)
{
}
......@@ -383,7 +384,7 @@ public:
m_saving(ct_saving)
{
}
bool newFrameWrite(int frame_id)
bool newFrameWritten(int frame_id)
{
return m_saving._newFrameWrite(frame_id);
}
......@@ -398,7 +399,8 @@ CtSaving::CtSaving(CtControl &aCtrl) :
m_ready_flag(true),
m_need_compression(false),
m_nb_save_cbk(0),
m_end_cbk(NULL)
m_end_cbk(NULL),
m_managed_mode(Software)
{
DEB_CONSTRUCTOR();
......@@ -610,6 +612,70 @@ void CtSaving::getFormat(FileFormat& format, int stream_idx) const
DEB_RETURN() << DEB_VAR1(format);
}
/** @brief return a list of hardware possible saving format
*/
void CtSaving::getHardwareFormatList(std::list<std::string> &format_list) const
{
DEB_MEMBER_FUNCT();
if(!m_has_hwsaving)
THROW_CTL_ERROR(NotSupported) << "No hardware saving for this camera";
m_hwsaving->getPossibleSaveFormat(format_list);
}
void CtSaving::setHardwareFormat(const std::string &format)
{
DEB_MEMBER_FUNCT();
if(!m_has_hwsaving)
THROW_CTL_ERROR(NotSupported) << "No hardware saving for this camera";
bool found = _checkHwFileFormat(format);
if(!found)
{
THROW_CTL_ERROR(NotSupported) <<
"Hardware does not support" << DEB_VAR1(format);
}
m_specific_hardware_format = format;
}
bool CtSaving::_checkHwFileFormat(const std::string &format) const
{
std::list<std::string> format_list;
m_hwsaving->getPossibleSaveFormat(format_list);
bool found = false;
for(std::list<std::string>::const_iterator i = format_list.begin();
!found && i != format_list.end();++i)
found = *i == format;
return found;
}
void CtSaving::_ReadImage(Data &image,int frameNumber)
{
DEB_MEMBER_FUNCT();
if(m_hwsaving->getCapabilities() & HwSavingCtrlObj::MANUAL_READ)
{
HwFrameInfoType frame;
m_hwsaving->readFrame(frame,frameNumber);
CtBuffer::transformHwFrameInfoToData(image,frame);
}
else
THROW_CTL_ERROR(NotSupported) << "Image read is not supported for this hardware";
}
void CtSaving::getHardwareFormat(std::string &format) const
{
DEB_MEMBER_FUNCT();
if(!m_has_hwsaving)
THROW_CTL_ERROR(NotSupported) << "No hardware saving for this camera";
format = m_specific_hardware_format;
}
/** @brief set the saving mode for a saving stream
*/
void CtSaving::setSavingMode(SavingMode mode)
......@@ -709,13 +775,21 @@ void CtSaving::setManagedMode(CtSaving::ManagedMode mode)
THROW_CTL_ERROR(InvalidValue) << DEB_VAR1(mode) << "Not supported";
AutoMutex aLock(m_cond.mutex());
for (int s = 0; s < m_nb_stream; ++s)
if(mode == Hardware)
{
Stream& stream = getStream(s);
Parameters pars = stream.getParameters(Auto);
pars.managedMode = mode;
stream.setParameters(pars);
if(!m_has_hwsaving)
THROW_CTL_ERROR(NotSupported) << "Hardware saving is not supported";
int hw_cap = m_hwsaving->getCapabilities();
if(hw_cap & HwSavingCtrlObj::COMMON_HEADER)
m_hwsaving->setCommonHeader(m_common_header);
else if(!m_common_header.empty())
{
THROW_CTL_ERROR(Error) << "Hardware saving do not manage common header"
<< ", clear it first";
}
}
m_managed_mode = mode;
}
void CtSaving::getManagedMode(CtSaving::ManagedMode &mode) const
......@@ -723,9 +797,7 @@ void CtSaving::getManagedMode(CtSaving::ManagedMode &mode) const
DEB_MEMBER_FUNCT();
AutoMutex aLock(m_cond.mutex());
const Stream& stream = getStream(0);
const Parameters& pars = stream.getParameters(Auto);
mode = pars.managedMode;
mode = m_managed_mode;
}
void CtSaving::_getTaskList(TaskType type, long frame_nr,
......@@ -758,9 +830,7 @@ void CtSaving::resetCommonHeader()
AutoMutex aLock(m_cond.mutex());
ManagedMode managed_mode = getManagedMode();
if(managed_mode == Software)
m_common_header.clear();
else
if(managed_mode == Hardware)
{
int hw_cap = m_hwsaving->getCapabilities();
if(hw_cap & HwSavingCtrlObj::COMMON_HEADER)
......@@ -768,6 +838,7 @@ void CtSaving::resetCommonHeader()
else
THROW_CTL_ERROR(NotSupported) << "Common header is not supported";
}
m_common_header.clear();
}
/** @brief set the common header.
This is the header which will be write for all frame for this acquisition
......@@ -779,9 +850,7 @@ void CtSaving::setCommonHeader(const HeaderMap &header)
AutoMutex aLock(m_cond.mutex());
ManagedMode managed_mode = getManagedMode();
if(managed_mode == Software)
m_common_header = header;
else
if(managed_mode == Hardware)
{
int hw_cap = m_hwsaving->getCapabilities();
if(hw_cap & HwSavingCtrlObj::COMMON_HEADER)
......@@ -789,6 +858,7 @@ void CtSaving::setCommonHeader(const HeaderMap &header)
else
THROW_CTL_ERROR(NotSupported) << "Common header is not supported";
}
m_common_header = header;
}
/** @brief replace/add field in the common header
*/
......@@ -1394,21 +1464,58 @@ void CtSaving::_prepare()
DEB_TRACE() << "No auto save activated";
AutoMutex aLock(m_cond.mutex());
if(m_managed_mode == Software)
{
m_need_compression = false;
//prepare all the active streams
for (int s = 0; s < m_nb_stream; ++s) {
Stream& stream = getStream(s);
if (stream.isActive()) {
stream.prepare();
if (stream.needCompression())
m_need_compression = true;
}
}
m_need_compression = false;
m_nb_save_cbk = 0;
m_nb_compression_cbk.clear();
//prepare all the active streams
for (int s = 0; s < m_nb_stream; ++s) {
Stream& stream = getStream(s);
if (stream.isActive()) {
stream.prepare();
if (stream.needCompression())
m_need_compression = true;
if(m_has_hwsaving)
{
m_hwsaving->stop();
m_hwsaving->setActive(false);
}
}
}
else
{
const Stream& stream = getStream(0);
Parameters params = stream.getParameters(Auto);
m_hwsaving->setDirectory(params.directory);
m_hwsaving->setPrefix(params.prefix);
m_hwsaving->setSuffix(params.suffix);
m_hwsaving->setNextNumber(params.nextNumber);
m_hwsaving->setIndexFormat(params.indexFormat);
std::string fileFormat;
switch(params.fileFormat)
{
case RAW: fileFormat = HwSavingCtrlObj::RAW_FORMAT_STR;break;
case EDF: fileFormat = HwSavingCtrlObj::EDF_FORMAT_STR;break;
case CBFFormat: fileFormat = HwSavingCtrlObj::CBF_FORMAT_STR;break;
case HARDWARE_SPECIFIC: fileFormat = m_specific_hardware_format;break;
default:
THROW_CTL_ERROR(NotSupported) << "Not supported yet";break;
}
if(!_checkHwFileFormat(fileFormat))
THROW_CTL_ERROR(NotSupported) << "Hardware doesn't support " << DEB_VAR1(fileFormat);
m_nb_save_cbk = 0;
m_nb_compression_cbk.clear();
m_hwsaving->setSaveFormat(fileFormat);
m_hwsaving->setActive(true);
m_hwsaving->prepare();
m_hwsaving->start();
}
}
CtSaving::SaveContainer::SaveContainer(Stream& stream)
......
......@@ -26,7 +26,10 @@
#include <list>
#include "LimaCompatibility.h"
#include "Debug.h"
#include "HwFrameInfo.h"
#include "DirectoryEventUtils.h"
#ifdef __linux__
namespace lima
{
class LIMACORE_API HwSavingCtrlObj
......@@ -35,46 +38,78 @@ namespace lima
public:
typedef std::map<std::string,std::string> HeaderMap;
//Capabilities
static const int COMMON_HEADER = 0x1; ///< if support common header @see setCommonHeader
static const int MANUAL_WRITE = 0x2; ///< if support manual write @see writeFrame
static const int MANUAL_READ = 0x4; ///< if support manual read @see readFrame
//Basic Managed format
static const char *RAW_FORMAT_STR;
static const char *EDF_FORMAT_STR;
static const char *CBF_FORMAT_STR;
explicit HwSavingCtrlObj(int capabilities = 0);
virtual ~HwSavingCtrlObj();
virtual void setActive(bool) = 0;
virtual void setDirectory(const std::string&) = 0;
virtual void setPrefix(const std::string&) = 0;
virtual void setSuffix(const std::string&) = 0;
void setActive(bool);
bool isActive() const;
virtual void getSaveFormat(std::list<std::string> &format_list) const = 0;
virtual void setSaveFormat(const std::string &format) = 0;
void setDirectory(const std::string&);
void setPrefix(const std::string&);
void setSuffix(const std::string&);
void setNextNumber(long number);
void setIndexFormat(const std::string&);
void setSaveFormat(const std::string &format);
virtual void getPossibleSaveFormat(std::list<std::string> &format_list) const = 0;
int getCapabilities() const;
virtual void writeFrame(int frame_nr = -1,int nb_frames = 1);
virtual void readFrame(HwFrameInfoType&,int frame_nr);
virtual void setCommonHeader(const HeaderMap&);
virtual void resetCommonHeader();
void prepare();
void start();
void stop();
class Callback
{
public:
virtual ~Callback() {}
virtual bool newFrameWrite(int frame_id) = 0;
virtual void prepare(const DirectoryEvent::Parameters &) {};
virtual bool newFrameWritten(int frame_id) = 0;
};
void registerCallback(Callback *cbk);
void unregisterCallback(Callback *cbk);
protected:
/** @brief this methode should be call we a new frame is written
@param frame_id the frame id of the saved frame
virtual void _setActive(bool) {}
virtual void _prepare() {}
virtual void _start() {}
/** @brief return the full path of acquired image
*/
bool newFrameWrite(int frame_id);
std::string _getFullPath(int image_number) const;
int m_caps;
bool m_active;
std::string m_directory;
std::string m_prefix;
std::string m_suffix;
long m_next_number;
std::string m_file_format;
std::string m_index_format;
private:
Callback* m_callback;
class DirectoryCallback;
Callback* m_callback;
DirectoryCallback* m_dir_cbk;
DirectoryEvent m_dir_event;
};
}
#endif
#endif
......@@ -28,21 +28,32 @@ using namespace lima;
public:
static const int COMMON_HEADER;
static const int MANUAL_WRITE;
static const int MANUAL_READ;
//Basic Managed format
static const char *RAW_FORMAT_STR;
static const char *EDF_FORMAT_STR;
static const char *CBF_FORMAT_STR;
explicit HwSavingCtrlObj(int capabilities = 0);
virtual ~HwSavingCtrlObj();
virtual void setActive(bool) = 0;
virtual void setDirectory(const std::string&) = 0;
virtual void setPrefix(const std::string&) = 0;
virtual void setSuffix(const std::string&) = 0;
virtual void setActive(bool);
bool isActive() const;
virtual void getSaveFormat(std::list<std::string> &format_list) const = 0;
virtual void setSaveFormat(const std::string &format) = 0;
void setDirectory(const std::string&);
void setPrefix(const std::string&);
void setSuffix(const std::string&);
void setNextNumber(long number);
void setIndexFormat(const std::string&);
void setSaveFormat(const std::string &format);
virtual void getPossibleSaveFormat(std::list<std::string> &format_list) const = 0;
int getCapabilities() const;
virtual void writeFrame(int frame_nr = -1,int nb_frames = 1);
virtual void readFrame(HwFrameInfoType&,int frame_nr);
//virtual void setCommonHeader(const std::map<std::string,std::string>&);
virtual void resetCommonHeader();
......@@ -51,16 +62,20 @@ public:
{
public:
virtual ~Callback();
virtual bool newFrameWrite(int frame_id) = 0;
virtual void prepare(const DirectoryEvent::Parameters &);
virtual bool newFrameWritten(int frame_id) = 0;
};
void registerCallback(Callback *cbk);
void unregisterCallback(Callback *cbk);
protected:
/** @brief this methode should be call we a new frame is written
@param frame_id the frame id of the saved frame
*/
bool newFrameWrite(int frame_id);
virtual void _setActive(bool);
virtual void _prepare();
virtual void _start();
/** @brief return the full path of acquired image
*/
std::string _getFullPath(int image_number) const;
};
......@@ -21,18 +21,116 @@
//###########################################################################
#include "HwSavingCtrlObj.h"
#include "Exceptions.h"
#include <deque>
#include <algorithm>
using namespace lima;
const char* HwSavingCtrlObj::RAW_FORMAT_STR = "RAW"; ///< Raw format (no header)
const char* HwSavingCtrlObj::EDF_FORMAT_STR = "EDF"; ///< EDF format (Esrf Data Format)
const char* HwSavingCtrlObj::CBF_FORMAT_STR = "CBF"; ///< CBF format
class HwSavingCtrlObj::DirectoryCallback : public DirectoryEvent::Callback
{
public:
DirectoryCallback(HwSavingCtrlObj& saving) :
m_saving(saving),
m_start_file_number(0)
{
}
void prepare(const DirectoryEvent::Parameters& params)
{
m_start_file_number = params.next_file_number_expected;
}
void clear()
{
m_image_ids.clear();
}
virtual bool nextFileExpected(int file_number,
const char*,
int &next_file_number_expected) throw()
{
int image_id = file_number - m_start_file_number;
bool continueFlag = m_saving.m_callback ?
m_saving.m_callback->newFrameWritten(image_id) : false;
int next_file_number = file_number + 1;
std::sort(m_image_ids.begin(),m_image_ids.end());
while(continueFlag &&
!m_image_ids.empty() && m_image_ids.front() == next_file_number)
{
image_id = next_file_number - m_start_file_number;
continueFlag = m_saving.m_callback->newFrameWritten(image_id);
++next_file_number;
m_image_ids.pop_front();
}
next_file_number_expected = next_file_number_expected;
return continueFlag;
}
virtual bool newFile(int file_number,const char*) throw()
{
m_image_ids.push_back(file_number);
return true;
}
private:
HwSavingCtrlObj& m_saving;
int m_start_file_number;
std::deque<int> m_image_ids;
};
HwSavingCtrlObj::HwSavingCtrlObj(int capabilities) :
m_caps(capabilities),
m_callback(NULL)
m_active(false),
m_callback(NULL),
m_dir_cbk(new HwSavingCtrlObj::DirectoryCallback(*this)),
m_dir_event(true,*m_dir_cbk)
{
}
HwSavingCtrlObj::~HwSavingCtrlObj()
{
delete m_dir_cbk;
}
void HwSavingCtrlObj::setActive(bool flag)
{
_setActive(flag);
m_active = flag;
}
bool HwSavingCtrlObj::isActive() const
{
return m_active;
}
void HwSavingCtrlObj::setDirectory(const std::string& directory)
{
m_directory = directory;
}
void HwSavingCtrlObj::setPrefix(const std::string& prefix)
{
m_prefix = prefix;
}
void HwSavingCtrlObj::setSuffix(const std::string& suffix)
{
m_suffix = suffix;
}
void HwSavingCtrlObj::setNextNumber(long number)
{
m_next_number = number;
}
void HwSavingCtrlObj::setIndexFormat(const std::string& indexFormat)
{
m_index_format = indexFormat;
}
void HwSavingCtrlObj::setSaveFormat(const std::string &format)
{
m_file_format = format;
}
/** @brief write manualy a frame