Commit b0707e35 authored by Laurent Claustre's avatar Laurent Claustre

New Saving format HDF5, based on version 1.8.12

Thanks to Goeffrey Mant for the nice job !

* Hdf5 third-party can be compiled now from scratch and installed as deps
* fixed with Geoff some bugs in CtSaving_HDF5

Made some progress, after discussion with Armando Sole and jerome Kieffer
improve the group/dataset organisation.

Modify CtSaving::_prepare to pass CtControl (needed for Hdf5)

Add Multiset saving mode

Close saving file at the end of acquisition or after a stopAcq

improved hdf5 format, acq/image/detinfo parameters now saved

added a calculate_chunk() function to optimized chunking vs image size

fixed scalar attribute and scalar datatset instead of array
parent 282344d1
......@@ -109,3 +109,6 @@
[submodule "camera/aviex"]
path = camera/aviex
url = git://github.com/esrf-bliss/Lima-camera-aviex.git
[submodule "third-party/hdf5"]
path = third-party/hdf5
url = git://github.com/esrf-bliss/hdf5.git
......@@ -77,6 +77,13 @@ ifneq ($(COMPILE_TIFF_SAVING),0)
CORE_LDLIBS += -ltiff
endif
ifneq ($(COMPILE_HDF5_SAVING),0)
PROCESSOR_TYPE := $(shell uname -m)
CORE_LDFLAGS += -L../third-party/hdf5/src/.libs -Wl,-rpath=$(shell pwd)/../third-party/hdf5/src/.libs
CORE_LDFLAGS += -L../third-party/hdf5/c++/src/.libs -Wl,-rpath=$(shell pwd)/../third-party/hdf5/c++/src/.libs
CORE_LDLIBS += -lhdf5_cpp -lhdf5
endif
ifneq ($(COMPILE_CONFIG),0)
CORE_LDLIBS += -L../third-party/libconfig/lib/.libs -Wl,-rpath=$(shell pwd)/../third-party/libconfig/lib/.libs -lconfig++
endif
......@@ -543,7 +550,7 @@ endif
############################
ifneq ($(COMPILE_POINTGREY),0)
POINTGREY_LDFLAGS := $(LDFLAGS)
POINTGREY_LDFLAGS := $(LDFLAGS) -L../camera/pointgrey/sdk/lib
POINTGREY_LDLIBS := $(LDLIBS) -lflycapture
pointgrey-name := pointgrey
......
......@@ -52,6 +52,7 @@ COMPILE_NXS_SAVING=0
COMPILE_FITS_SAVING=0
COMPILE_EDFGZ_SAVING=0
COMPILE_TIFF_SAVING=0
COMPILE_HDF5_SAVING=0
COMPILE_CONFIG=1
COMPILE_GLDISPLAY=0
LINK_STRICT_VERSION=0
......@@ -61,6 +62,6 @@ export COMPILE_CORE COMPILE_SPS_IMAGE COMPILE_SIMULATOR \
COMPILE_MYTHEN COMPILE_UEYE COMPILE_XH COMPILE_XSPRESS3 COMPILE_ULTRA COMPILE_XPAD COMPILE_PERKINELMER \
COMPILE_ANDOR COMPILE_PHOTONICSCIENCE COMPILE_PCO COMPILE_MARCCD COMPILE_DEXELA\
COMPILE_POINTGREY COMPILE_IMXPAD COMPILE_RAYONIXHS COMPILE_AVIEX COMPILE_CBF_SAVING COMPILE_NXS_SAVING \
COMPILE_FITS_SAVING COMPILE_EDFGZ_SAVING COMPILE_TIFF_SAVING COMPILE_CONFIG\
COMPILE_FITS_SAVING COMPILE_EDFGZ_SAVING COMPILE_TIFF_SAVING COMPILE_HDF5_SAVING COMPILE_CONFIG\
COMPILE_GLDISPLAY \
LINK_STRICT_VERSION
......@@ -56,7 +56,8 @@ namespace lima {
enum ManagedMode
{
Software, ///< Saving will be managed by Lima Core (Control)
Hardware ///< Saving will be managed by Hardware or Camera SDK
Hardware, ///< Saving will be managed by Hardware or Camera SDK
Camera ///< Saving will be managed by the Camera plugin
};
enum FileFormat
......@@ -69,6 +70,7 @@ namespace lima {
FITS, ///< Flexible Image Transport Layer (NOST)
EDFGZ, ///< EDF format with gzip compression
TIFFFormat, ///< TIFF format
HDF5, ///< HDF5 format
};
enum SavingMode
......@@ -83,6 +85,7 @@ namespace lima {
Abort, ///< Abort acquisition if file already exist
Overwrite, ///< Overwrite old files
Append, ///< Append new data at the end of already existing files
MultiSet, ///< Like append but doesn't use file counter
};
struct LIMACORE_API Parameters
......@@ -187,6 +190,7 @@ namespace lima {
// --- misc
void clear();
void close();
// frame_nr == -1 => last frame
void writeFrame(int frame_nr = -1, int nb_frames = 1,bool synchronous = true);
......@@ -210,7 +214,7 @@ namespace lima {
void getStatistic(std::list<double>&) const;
void getParameters(CtSaving::Parameters&) const;
void clear();
void prepare(CtControl&);
/** @brief should return true if container has compression or
* havy task to do before saving
* if return is true, getCompressionTask should return a Task
......@@ -231,6 +235,7 @@ namespace lima {
CtSaving::HeaderMap &aHeader,
FileFormat) = 0;
virtual void _clear() {};
virtual void _prepare(CtControl&) {};
int m_written_frames;
Stream &m_stream;
......@@ -239,6 +244,7 @@ namespace lima {
int m_statistic_size;
mutable Cond m_cond;
bool m_file_opened;
long m_nb_frames_to_write;
};
friend class SaveContainer;
......@@ -266,7 +272,8 @@ namespace lima {
void setParameters(const Parameters& pars);
void updateParameters();
void prepare();
void prepare(CtControl& ct);
void close();
void createSaveContainer();
void checkWriteAccess();
void checkDirectoryAccess(const std::string&);
......@@ -354,7 +361,8 @@ namespace lima {
HwSavingCtrlObj* m_hwsaving;
_NewFrameSaveCBK* m_new_frame_save_cbk;
ManagedMode m_managed_mode; ///< two option either harware (manage by SDK,hardware) or software (Lima core)
std::string m_specific_hardware_format;
std::string m_specific_hardware_format;
bool m_saving_stop;
Stream& getStream(int stream_idx)
{ bool stream_ok = (stream_idx >= 0) && (stream_idx < m_nb_stream);
......@@ -386,7 +394,9 @@ namespace lima {
}
// --- internal call
void _prepare();
void _prepare(CtControl&);
void _stop(CtControl&);
void _close();
void _getCommonHeader(HeaderMap&);
void _takeHeader(FrameHeaderMap::iterator&, HeaderMap& header,
bool keep_in_map);
......@@ -426,6 +436,8 @@ namespace lima {
aFileFormatHumanPt = "EDF gzip";break;
case CtSaving::TIFFFormat:
aFileFormatHumanPt = "TIFF";break;
case CtSaving::HDF5:
aFileFormatHumanPt = "HDF5";break;
default:
aFileFormatHumanPt = "RAW";break;
}
......@@ -445,6 +457,7 @@ namespace lima {
else if(buffer == "edf gzip") fileFormat = CtSaving::EDFGZ;
else if(buffer == "raw") fileFormat = CtSaving::RAW;
else if(buffer == "tiff") fileFormat = CtSaving::TIFFFormat;
else if(buffer == "hdf5") fileFormat = CtSaving::HDF5;
else
{
std::ostringstream msg;
......@@ -494,6 +507,8 @@ namespace lima {
anOverwritePolicyHumanPt = "Overwrite";break;
case CtSaving::Append:
anOverwritePolicyHumanPt = "Append";break;
case CtSaving::MultiSet:
anOverwritePolicyHumanPt = "MultiSet";break;
default: // Abort
anOverwritePolicyHumanPt = "Abort";break;
}
......@@ -506,9 +521,10 @@ namespace lima {
std::transform(buffer.begin(),buffer.end(),
buffer.begin(),::tolower);
if(buffer == "overwrite") overwritePolicy = CtSaving::Overwrite;
if(buffer == "overwrite") overwritePolicy = CtSaving::Overwrite;
else if(buffer == "append") overwritePolicy = CtSaving::Append;
else if(buffer == "abort") overwritePolicy = CtSaving::Abort;
else if(buffer == "multiset") overwritePolicy = CtSaving::MultiSet;
else
{
std::ostringstream msg;
......
......@@ -125,6 +125,7 @@ using namespace lima;
FITS,
EDFGZ,
TIFFFormat,
HDF5,
};
enum SavingMode {
......@@ -137,6 +138,7 @@ using namespace lima;
Abort,
Overwrite,
Append,
MultiSet,
};
struct Parameters {
......@@ -233,6 +235,7 @@ using namespace lima;
// --- misc
void clear();
void close();
void writeFrame(int frame_nr = -1, int nb_frames = 1,
bool synchronous = true);
......
......@@ -137,6 +137,7 @@ class CtControl::_ReconstructionChangeCallback : public HwReconstructionCtrlObj:
public:
_ReconstructionChangeCallback(CtControl& ctrl) : m_ct(ctrl) {}
virtual ~_ReconstructionChangeCallback() {}
virtual void change(LinkTask* aNewLinkTaskPt)
{
m_ct.setReconstructionTask(aNewLinkTaskPt);
......@@ -308,7 +309,7 @@ void CtControl::prepareAcq()
m_ct_accumulation->prepare();
DEB_TRACE() << "Prepare Saving if needed";
m_ct_saving->_prepare();
m_ct_saving->_prepare(*this);
m_autosave= m_ct_saving->hasAutoSaveMode();
m_ready= true;
......@@ -424,6 +425,7 @@ void CtControl::stopAcq()
m_running = false;
DEB_TRACE() << "Hardware Acquisition Stopped";
_calcAcqStatus();
m_ct_saving->_stop(*this);
}
void CtControl::getStatus(Status& status) const
{
......
......@@ -53,6 +53,10 @@
#include "CtSaving_Tiff.h"
#endif
#ifdef WITH_HDF5_SAVING
#include "CtSaving_Hdf5.h"
#endif
#include "TaskMgr.h"
#include "SinkTask.h"
......@@ -246,7 +250,7 @@ void CtSaving::Stream::setActive(bool active)
m_active = active;
}
void CtSaving::Stream::prepare()
void CtSaving::Stream::prepare(CtControl& ct)
{
DEB_MEMBER_FUNCT();
......@@ -256,8 +260,13 @@ void CtSaving::Stream::prepare()
updateParameters();
checkWriteAccess();
}
m_save_cnt->prepare(ct);
}
void CtSaving::Stream::close()
{
m_save_cnt->close();
}
void CtSaving::Stream::updateParameters()
{
DEB_MEMBER_FUNCT();
......@@ -307,6 +316,12 @@ void CtSaving::Stream::createSaveContainer()
#ifndef WITH_TIFF_SAVING
THROW_CTL_ERROR(NotSupported) << "Lima is not compiled with the tiff "
"saving option, not managed";
#endif
goto common;
case HDF5:
#ifndef WITH_HDF5_SAVING
THROW_CTL_ERROR(NotSupported) << "Lima is not compiled with the hdf5 "
"saving option, not managed";
#endif
goto common;
case RAW:
......@@ -351,6 +366,11 @@ void CtSaving::Stream::createSaveContainer()
m_save_cnt = new SaveContainerTiff(*this);
m_pars.framesPerFile = 1;
break;
#endif
#ifdef WITH_HDF5_SAVING
case HDF5:
m_save_cnt = new SaveContainerHdf5(*this, m_pars.fileFormat);
break;
#endif
default:
break;
......@@ -827,6 +847,8 @@ void CtSaving::setOverwritePolicy(OverwritePolicy policy, int stream_idx)
Stream& stream = getStream(stream_idx);
Parameters pars = stream.getParameters(Auto);
pars.overwritePolicy = policy;
if(policy == MultiSet)
pars.nextNumber = -1,pars.framesPerFile = -1;
stream.setParameters(pars);
}
/** @brief get the overwrite policy for a saving stream
......@@ -1337,6 +1359,14 @@ void CtSaving::clear()
m_frame_datas.clear();
}
void CtSaving::close()
{
DEB_MEMBER_FUNCT();
AutoMutex aLock(m_cond.mutex());
_close();
}
/** @brief write manually a frame
@param aFrameNumber the frame id you want to save
......@@ -1524,6 +1554,7 @@ void CtSaving::_saveFinished(Data &aData, Stream& stream)
if (!auto_saving || !data_available ||
((saving_mode == AutoHeader) && !header_available)) {
m_ready_flag = true;
if(m_saving_stop) _close();
m_cond.signal();
return;
}
......@@ -1573,7 +1604,7 @@ void CtSaving::_setSavingError(CtControl::ErrorCode anErrorCode)
this methode will resetLastFrameNb if mode is AutoSave
and validate the parameter for this new acquisition
*/
void CtSaving::_prepare()
void CtSaving::_prepare(CtControl& ct)
{
DEB_MEMBER_FUNCT();
......@@ -1591,7 +1622,9 @@ void CtSaving::_prepare()
for (int s = 0; s < m_nb_stream; ++s) {
Stream& stream = getStream(s);
if (stream.isActive()) {
stream.prepare();
aLock.unlock();
stream.prepare(ct);
aLock.lock();
if (stream.needCompression())
m_need_compression = true;
}
......@@ -1624,6 +1657,7 @@ void CtSaving::_prepare()
case CBFFormat: fileFormat = HwSavingCtrlObj::CBF_FORMAT_STR;break;
case HARDWARE_SPECIFIC: fileFormat = m_specific_hardware_format;break;
case TIFFFormat: fileFormat = HwSavingCtrlObj::TIFF_FORMAT_STR;break;
case HDF5: fileFormat = HwSavingCtrlObj::HDF5_FORMAT_STR;break;
default:
THROW_CTL_ERROR(NotSupported) << "Not supported yet";break;
}
......@@ -1636,6 +1670,27 @@ void CtSaving::_prepare()
m_hwsaving->prepare();
m_hwsaving->start();
}
m_saving_stop = false;
}
void CtSaving::_stop(CtControl&)
{
close();
}
void CtSaving::_close()
{
if(m_ready_flag)
{
for (int s = 0; s < m_nb_stream; ++s)
{
Stream& stream = getStream(s);
if(stream.isActive())
stream.close();
}
}
else
m_saving_stop = true;
}
#ifdef WITH_CONFIG
......@@ -1723,7 +1778,11 @@ void CtSaving::SaveContainer::writeFile(Data &aData,HeaderMap &aHeader)
THROW_CTL_ERROR(Error) << "Save unknown error";
}
if(++m_written_frames == pars.framesPerFile) {
++m_written_frames;
if((pars.overwritePolicy != MultiSet &&
m_written_frames == pars.framesPerFile) ||
m_written_frames == m_nb_frames_to_write) // Close file at the end of acquisition
{
try {
close();
} catch (...) {
......@@ -1784,16 +1843,30 @@ void CtSaving::SaveContainer::clear()
_clear(); // call inheritance if needed
}
void CtSaving::SaveContainer::prepare(CtControl& ct)
{
DEB_MEMBER_FUNCT();
int nb_frames;
ct.acquisition()->getAcqNbFrames(nb_frames);
m_nb_frames_to_write = nb_frames;
_prepare(ct); // call inheritance if needed
}
void CtSaving::SaveContainer::open(const CtSaving::Parameters &pars)
{
DEB_MEMBER_FUNCT();
if(!m_file_opened)
{
char idx[64];
snprintf(idx,sizeof(idx),pars.indexFormat.c_str(),pars.nextNumber);
std::string aFileName = pars.directory + DIR_SEPARATOR + pars.prefix + idx + pars.suffix;
std::string aFileName = pars.directory + DIR_SEPARATOR + pars.prefix;
if(pars.overwritePolicy != MultiSet)
{
char idx[64];
snprintf(idx,sizeof(idx),pars.indexFormat.c_str(),pars.nextNumber);
aFileName += idx;
}
aFileName += pars.suffix;
DEB_TRACE() << DEB_VAR1(aFileName);
if(pars.overwritePolicy == Abort &&
......@@ -1804,8 +1877,9 @@ void CtSaving::SaveContainer::open(const CtSaving::Parameters &pars)
output = "Try to over write file: " + aFileName;
THROW_CTL_ERROR(Error) << output;
}
std::ios_base::openmode openFlags = std::ios_base::out | std::ios_base::binary;
if(pars.overwritePolicy == Append)
std::ios_base::openmode openFlags = std::ios_base::out | std::ios_base::binary;
if(pars.overwritePolicy == Append ||
pars.overwritePolicy == MultiSet)
openFlags |= std::ios_base::app;
else if(pars.overwritePolicy == Overwrite)
openFlags |= std::ios_base::trunc;
......@@ -1867,7 +1941,8 @@ void CtSaving::SaveContainer::close()
m_file_opened = false;
m_written_frames = 0;
Parameters& pars = m_stream.getParameters(Acq);
++pars.nextNumber;
if(pars.overwritePolicy != MultiSet)
++pars.nextNumber;
}
/** @brief check if all file can be written
......
//###########################################################################
// This file is part of LImA, a Library for Image Acquisition
//
// Copyright (C) : 2009-2014
// 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/>.
//###########################################################################
#include <cmath>
#include "CtSaving_Hdf5.h"
#include "H5Cpp.h"
#include "CtControl.h"
#include "CtImage.h"
#include "CtAcquisition.h"
#include "HwInterface.h"
#include "HwCap.h"
using namespace lima;
using namespace H5;
using namespace std;
const int RANK_ONE = 1;
const int RANK_TWO = 2;
const int RANK_THREE = 3;
/* Static function helper*/
DataType get_h5_type(unsigned char) {return PredType(PredType::NATIVE_UINT8);}
DataType get_h5_type(char) {return PredType(PredType::NATIVE_INT8);}
DataType get_h5_type(unsigned short) {return PredType(PredType::NATIVE_UINT16);}
DataType get_h5_type(short) {return PredType(PredType::NATIVE_INT16);}
DataType get_h5_type(unsigned int) {return PredType(PredType::NATIVE_UINT32);}
DataType get_h5_type(int) {return PredType(PredType::NATIVE_INT32);}
DataType get_h5_type(unsigned long long) {return PredType(PredType::NATIVE_UINT64);}
DataType get_h5_type(long long) {return PredType(PredType::NATIVE_INT64);}
DataType get_h5_type(float) {return PredType(PredType::NATIVE_FLOAT);}
DataType get_h5_type(double) {return PredType(PredType::NATIVE_DOUBLE);}
DataType get_h5_type(std::string& s) {return StrType(H5T_C_S1, s.size());}
DataType get_h5_type(bool) {return PredType(PredType::NATIVE_UINT8);}
template <class T>
void write_h5_dataset(Group group,const char* entry_name,T& val)
{
//hsize_t strdim[1] = { 1 }; /* Dataspace dimensions */
//DataSpace dataspace(RANK_ONE, strdim);
DataSpace dataspace(H5S_SCALAR);
DataType datatype = get_h5_type(val);
DataSet dataset(group.createDataSet(entry_name,datatype, dataspace));
dataset.write(&val, datatype);
}
template <>
void write_h5_dataset(Group group,const char* entry_name,std::string& val)
{
DataSpace dataspace(H5S_SCALAR);
DataType datatype = get_h5_type(val);
DataSet dataset(group.createDataSet(entry_name,datatype, dataspace));
dataset.write(val.c_str(), datatype);
}
template <class L,class T>
void write_h5_attribute(L location,const char* entry_name,T& val)
{
//hsize_t strdim[1] = { 1 }; /* Dataspace dimensions */
//DataSpace dataspace(RANK_ONE, strdim);
DataSpace dataspace(H5S_SCALAR);
DataType datatype = get_h5_type(val);
Attribute attr(location.createAttribute(entry_name,datatype, dataspace));
attr.write(datatype, &val);
}
template <class L>
void write_h5_attribute(L location,const char* entry_name,std::string& val)
{
DataSpace dataspace(H5S_SCALAR);
DataType datatype = get_h5_type(val);
Attribute attr(location.createAttribute(entry_name,datatype, dataspace));
attr.write(datatype, val.c_str());
}
/** @brief helper to calculate an optimized chuncking of the image data set
*
*
*/
static void calculate_chunck(hsize_t* data_size, hsize_t* chunck, int depth)
{
const double request_chunck_size = 256.;
const double request_chunck_memory_size = 1024.*1024.;
double request_chunck_pixel_nb = request_chunck_memory_size / depth;
long x_chunk = ceil(double(data_size[2]) / request_chunck_size);
long y_chunk = ceil(double(data_size[1]) / request_chunck_size);
long z_chunk = ceil(request_chunck_pixel_nb / ((data_size[2] / x_chunk) * (data_size[1] / y_chunk)));
hsize_t nb_image = data_size[0];
while(hsize_t(z_chunk) > nb_image) {
--x_chunk,--y_chunk;
if(!x_chunk || !y_chunk) break;
z_chunk = ceil(request_chunck_pixel_nb / ((data_size[2] / x_chunk) * (data_size[1] / y_chunk)));
}
if(!x_chunk) x_chunk = 1;
else if(x_chunk > 8) x_chunk = 8;
if(!y_chunk) y_chunk = 1;
else if(y_chunk > 8) y_chunk = 8;
z_chunk = ceil(request_chunck_pixel_nb / ((data_size[2] / x_chunk) * (data_size[1] / y_chunk)));
if(hsize_t(z_chunk) > nb_image) z_chunk = nb_image;
else if(!z_chunk) z_chunk = 1;
chunck[0] = z_chunk;
chunck[1] = ceil(double(data_size[1]) / y_chunk);
chunck[2] = ceil(double(data_size[2]) / x_chunk);
}
/** @brief saving container
*
* This class manage file saving
*/
SaveContainerHdf5::SaveContainerHdf5(CtSaving::Stream& stream, CtSaving::FileFormat format) :
CtSaving::SaveContainer(stream), m_format(format), m_entry_index(0) {
DEB_CONSTRUCTOR();
m_already_opened = false;
m_format_written = false;
}
SaveContainerHdf5::~SaveContainerHdf5() {
DEB_DESTRUCTOR();
}
void SaveContainerHdf5::_prepare(CtControl& control) {
DEB_MEMBER_FUNCT();
m_ct_image = control.image();
m_ct_acq = control.acquisition();
m_hw_int = control.hwInterface();
// Get detector info
HwDetInfoCtrlObj *det_info;
m_hw_int->getHwCtrlObj(det_info);
det_info->getUserDetectorName(m_ct_parameters.det_name);
det_info->getDetectorModel(m_ct_parameters.det_model);
det_info->getDetectorType(m_ct_parameters.det_type);
det_info->getPixelSize(m_ct_parameters.pixel_size[0], m_ct_parameters.pixel_size[1]);
det_info->getMaxImageSize(m_ct_parameters.max_image_size);
det_info->getCurrImageType(m_ct_parameters.curr_image_type);
// Get acquisition parameters
m_ct_acq->getAcqMode(m_ct_parameters.acq_mode);
m_ct_acq->getAcqExpoTime(m_ct_parameters.acq_expo_time);
m_ct_acq->getAcqNbFrames(m_ct_parameters.acq_nbframes);
m_ct_acq->getLatencyTime(m_ct_parameters.acq_latency_time);
m_ct_acq->getTriggerMode(m_ct_parameters.acq_trigger_mode);
if (m_ct_parameters.acq_mode == Accumulation) {
m_ct_acq->getAccTimeMode(m_ct_parameters.acc_time_mode);
m_ct_acq->getAccMaxExpoTime(m_ct_parameters.acc_max_expotime);
m_ct_acq->getAccExpoTime(m_ct_parameters.acc_expotime);
m_ct_acq->getAccLiveTime(m_ct_parameters.acc_livetime);
m_ct_acq->getAccDeadTime(m_ct_parameters.acc_deadtime);
} else if (m_ct_parameters.acq_mode == Concatenation){
m_ct_acq->getConcatNbFrames(m_ct_parameters.concat_nbframes);
}
// Get image operations
m_ct_image->getBin(m_ct_parameters.image_bin);
m_ct_image->getRoi(m_ct_parameters.image_roi);
m_ct_image->getFlip(m_ct_parameters.image_flip);
m_ct_image->getRotation(m_ct_parameters.image_rotation);
m_ct_image->getImageDim(m_ct_parameters.image_dim);
// Check if the overwrite policy if "MultiSet" is activated
CtSaving::OverwritePolicy overwrite_policy;
control.saving()->getOverwritePolicy(overwrite_policy);
m_is_mutltiset = (overwrite_policy == CtSaving::MultiSet);
CtSaving::Parameters pars;
control.saving()->getParameters(pars);
if (m_is_mutltiset)
m_nbframes = m_ct_parameters.acq_nbframes;
else
m_nbframes = pars.framesPerFile;
}
bool SaveContainerHdf5::_open(const std::string &filename, std::ios_base::openmode openFlags) {
DEB_MEMBER_FUNCT();
try
{
// Turn off the auto-printing when failure occurs so that we can
// handle the errors appropriately
H5::Exception::dontPrint();
bool in_append = false;
bool is_hdf5 = false;
bool file_exists = true;
if (!m_already_opened) {
if (openFlags & std::ios_base::trunc) {
// overwrite existing file
m_file = new H5File(filename, H5F_ACC_TRUNC);
m_entry_index = 0;
} else if (openFlags & std::ios_base::app) {
// Append if the file exists and it is a HDF5 file