diff --git a/.gitmodules b/.gitmodules index cd512241383d35f69618690af718197e6c17d51e..c5e914fe7c73da4d1e5796cfd52634cf05a817a6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 diff --git a/build/Makefile b/build/Makefile index 0cbaf5b4a477cabe770b95976022caa4335466b2..7a50200f6d02d8bcebd2c58e38c5c4f96e827f60 100644 --- a/build/Makefile +++ b/build/Makefile @@ -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 diff --git a/common/VERSION b/common/VERSION index f0bb29e76388856b273698ae6064b0380ce5e5d2..88c5fb891dcf1d1647d2b84bac0630cf9570d213 100644 --- a/common/VERSION +++ b/common/VERSION @@ -1 +1 @@ -1.3.0 +1.4.0 diff --git a/config.inc_default b/config.inc_default index c0d9bf4b58144b1e9e1608feefd03032ecd5e66f..18bdad07eddbc0c12e71bcfd2f9ff7cf113fb8af 100644 --- a/config.inc_default +++ b/config.inc_default @@ -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 diff --git a/control/include/CtSaving.h b/control/include/CtSaving.h index d6138e8d8e26d1f730b1d2e947c53127bafd9eaa..3a0d3f29fbe98113df5605d1593ceb1712395312 100644 --- a/control/include/CtSaving.h +++ b/control/include/CtSaving.h @@ -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&) 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; diff --git a/control/sip/CtSaving.sip b/control/sip/CtSaving.sip index f304060ff4a3fc39006d18367718b9b8a0a1939f..a4c8ed88643f1ae36f10f31f85b06fa47dd95954 100644 --- a/control/sip/CtSaving.sip +++ b/control/sip/CtSaving.sip @@ -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); diff --git a/control/src/CtControl.cpp b/control/src/CtControl.cpp index 4181def8428871ee58cce0d63ec861e3db11248b..63f1f2394e41b1343fe639b3774daf556a93e088 100644 --- a/control/src/CtControl.cpp +++ b/control/src/CtControl.cpp @@ -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 { diff --git a/control/src/CtSaving.cpp b/control/src/CtSaving.cpp index 9fcd7886508b8aaa1545736912441136189038d2..f1bf31d59e58b3f58cc1219b5395fbebd593df9e 100644 --- a/control/src/CtSaving.cpp +++ b/control/src/CtSaving.cpp @@ -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 diff --git a/control/src/CtSaving_Hdf5.cpp b/control/src/CtSaving_Hdf5.cpp new file mode 100644 index 0000000000000000000000000000000000000000..61c1c76caee6dd5b5b0badcb2820aaa272dafe85 --- /dev/null +++ b/control/src/CtSaving_Hdf5.cpp @@ -0,0 +1,516 @@ +//########################################################################### +// 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 . +//########################################################################### +#include +#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 +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 +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 +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 + try{ + m_file = new H5File(); + is_hdf5 = m_file->isHdf5(filename); + } catch (FileIException &error){ + //error.printError(); + file_exists = false; + + } + if (file_exists && is_hdf5){ + m_file->openFile(filename, H5F_ACC_RDWR); + in_append = true; + } else if (!file_exists){ + DEB_TRACE() << "append mode but file does not exist, " << filename; + delete m_file; + m_file = new H5File(filename, H5F_ACC_EXCL); + m_entry_index = 0; + } else { + THROW_CTL_ERROR(Error) << "File " << filename + << "is not an HDF5 file, bad or corrupted format !" ; + } + } else { + // fail if file already exists + m_file = new H5File(filename, H5F_ACC_EXCL); + m_entry_index = 0; + } + + // create the next entry name and + //fails if it already exists in the file + char strname[256]; + sprintf(strname,"/entry_%04d", m_entry_index); + Group *group = NULL; + if (in_append) { + try { + group = new Group(m_file->openGroup(strname)); + DEB_TRACE() << "Hoops the new entry " << strname << " already exists in file " << filename; + delete group; + THROW_CTL_ERROR(Error) << "In file " << filename + << " the entry " + << strname << " already exists"; + } catch (...) { + DEB_TRACE() << "Ok the new entry " << strname << " is free in file " << filename; + } + } + // fine, this entry does not exist + m_entry_name = strname; + // Create the new entry for the dataset + m_entry = new Group(m_file->createGroup(m_entry_name)); + string nxentry = "NXentry"; + write_h5_attribute(*m_entry, "NX_class", nxentry); + string title = "Lima 2D detector acquisition"; + write_h5_dataset(*m_entry, "title", title); + + Group instrument = Group(m_entry->createGroup("instrument")); + string nxinstrument = "NXinstrument"; + write_h5_attribute(instrument, "NX_class", nxinstrument); + + m_instrument_detector = new Group(instrument.createGroup(m_ct_parameters.det_name)); + + Group measurement = Group(m_entry->createGroup("measurement")); + string nxcollection = "NXcollection"; + write_h5_attribute(measurement, "NX_class", nxcollection); + + m_measurement_detector = new Group(measurement.createGroup(m_ct_parameters.det_name)); + m_measurement_detector_info = new Group(m_measurement_detector->createGroup("info")); + string grppath = m_entry_name + "/instrument/" + m_ct_parameters.det_name; + // link between /entry_xxxx/instrument/ and /entry_xxxx/measurement//info/detector + m_measurement_detector_info->link(H5L_TYPE_HARD, grppath, "detector"); + + // write the control parameters (detinfo, acq and image) + + //Det Info + Group det_info = Group(m_instrument_detector->createGroup("detector_information")); + write_h5_dataset(det_info,"type",m_ct_parameters.det_type); + write_h5_dataset(det_info,"model",m_ct_parameters.det_model); + Group pixelsize = Group(det_info.createGroup("pixel_size")); + write_h5_dataset(pixelsize,"xsize",m_ct_parameters.pixel_size[0]); + write_h5_dataset(pixelsize,"ysize",m_ct_parameters.pixel_size[1]); + Group imagesize = Group(det_info.createGroup("max_image_size")); + int width = m_ct_parameters.max_image_size.getWidth(); + int height = m_ct_parameters.max_image_size.getHeight(); + write_h5_dataset(imagesize,"xsize",width); + write_h5_dataset(imagesize,"ysize",height); + string im_type=lima::convert_2_string(m_ct_parameters.curr_image_type); + write_h5_dataset(det_info,"image_lima_type",im_type); + // Acquisition + Group acq = Group(m_instrument_detector->createGroup("acquisition")); + string acq_mode = lima::convert_2_string(m_ct_parameters.acq_mode); + write_h5_dataset(acq,"mode",acq_mode); + write_h5_dataset(acq,"exposure_time",m_ct_parameters.acq_expo_time); + write_h5_dataset(acq,"latency_time",m_ct_parameters.acq_latency_time); + write_h5_dataset(acq,"nb_frames",m_ct_parameters.acq_nbframes); + string trig_mode = lima::convert_2_string(m_ct_parameters.acq_trigger_mode); + write_h5_dataset(acq,"trigger_mode",trig_mode); + if (m_ct_parameters.acq_mode == Accumulation) { + Group acc = Group(acq.createGroup("accumulation")); + string time_mode = lima::convert_2_string(m_ct_parameters.acc_time_mode); + write_h5_dataset(acc,"time_mode",time_mode); + write_h5_dataset(acc,"max_exposure_time",m_ct_parameters.acc_max_expotime); + write_h5_dataset(acc,"exposure_time",m_ct_parameters.acc_expotime); + write_h5_dataset(acc,"live_time",m_ct_parameters.acc_livetime); + write_h5_dataset(acc,"dead_time",m_ct_parameters.acc_deadtime); + } + if (m_ct_parameters.acq_mode == Concatenation) { + Group concat = Group(acq.createGroup("concatenation")); + write_h5_dataset(concat,"nb_frames",m_ct_parameters.concat_nbframes); + } + // Image + Group image = Group(m_instrument_detector->createGroup("image_operation")); + Group dim = Group(image.createGroup("dimension")); + int xsize = m_ct_parameters.image_dim.getSize().getWidth(); + int ysize = m_ct_parameters.image_dim.getSize().getHeight(); + write_h5_dataset(dim,"xsize",xsize); + write_h5_dataset(dim,"ysize",ysize); + Group bin = Group(image.createGroup("binning")); + int xbin = m_ct_parameters.image_bin.getX(); + int ybin = m_ct_parameters.image_bin.getY(); + write_h5_dataset(bin,"x",xbin); + write_h5_dataset(bin,"y",ybin); + Group roi = Group(image.createGroup("region_of_interest")); + Point roip = m_ct_parameters.image_roi.getTopLeft(); + Size roiz = m_ct_parameters.image_roi.getSize(); + xsize = roiz.getWidth(); + ysize = roiz.getHeight(); + write_h5_dataset(roi,"xstart",roip.x); + write_h5_dataset(roi,"ystart",roip.y); + write_h5_dataset(roi,"xsize",xsize); + write_h5_dataset(roi,"ysize",ysize); + Group flipping = Group(image.createGroup("flipping")); + write_h5_dataset(flipping,"x",m_ct_parameters.image_flip.x); + write_h5_dataset(flipping,"y",m_ct_parameters.image_flip.y); + string rot = lima::convert_2_string(m_ct_parameters.image_rotation); + write_h5_dataset(image, "rotation", rot); + + m_already_opened = true; + } + } catch (FileIException &error) { + THROW_CTL_ERROR(Error) << "File " << filename << " not opened successfully"; + } + + return true; +} + + +void SaveContainerHdf5::_close() { + DEB_MEMBER_FUNCT(); + + // Create hard link to the Data group. + string img_path = m_entry_name; img_path += "/measurement/" + m_ct_parameters.det_name+"/data"; + m_instrument_detector->link(H5L_TYPE_HARD, img_path, "data"); + + // ISO 8601 Time format + time_t now; + time(&now); + char buf[sizeof("2011-10-08T07:07:09Z")]; + strftime(buf, sizeof(buf), "%FT%TZ", gmtime(&now)); + string etime = string(buf); + write_h5_dataset(*m_entry,"end_time",etime); + + + m_already_opened = false; + m_format_written = false; + delete m_image_dataspace; + delete m_image_dataset; + delete m_measurement_detector_info; + delete m_measurement_detector; + delete m_instrument_detector; + delete m_entry; + delete m_file; + DEB_TRACE() << "Close current file"; + // increase the entry number for the next acquisition if MultiSet mode + m_entry_index++; + return; +} + +void SaveContainerHdf5::_writeFile(Data &aData, CtSaving::HeaderMap &aHeader, CtSaving::FileFormat aFormat) { + DEB_MEMBER_FUNCT(); + if (aFormat == CtSaving::HDF5) { + + // get the proper data type + PredType data_type(PredType::NATIVE_UINT8); + switch (aData.type) { + case Data::UINT8: + break; + case Data::INT8: + data_type = PredType::NATIVE_INT8; + break; + case Data::UINT16: + data_type = PredType::NATIVE_UINT16; + break; + case Data::INT16: + data_type = PredType::NATIVE_INT16; + break; + case Data::UINT32: + data_type = PredType::NATIVE_UINT32; + break; + case Data::INT32: + data_type = PredType::NATIVE_INT32; + break; + case Data::UINT64: + data_type = PredType::NATIVE_UINT64; + break; + case Data::INT64: + data_type = PredType::NATIVE_INT64; + break; + case Data::FLOAT: + data_type = PredType::NATIVE_FLOAT; + break; + case Data::DOUBLE: + data_type = PredType::NATIVE_DOUBLE; + break; + case Data::UNDEF: + default: + THROW_CTL_ERROR(Error) << "Invalid image type"; + } + + try { + if (!m_format_written) { + + // ISO 8601 Time format + time_t now; + time(&now); + char buf[sizeof("2011-10-08T07:07:09Z")]; + strftime(buf, sizeof(buf), "%FT%TZ", gmtime(&now)); + string stime = string(buf); + write_h5_dataset(*m_entry,"start_time",stime); + // write header only once into "info" group + // but we should write some keys into measurement, like motor_pos counter_pos (spec)??? + if (!aHeader.empty()) { + for (map::const_iterator it = aHeader.begin(); it != aHeader.end(); it++) { + + string key = it->first; + string value = it->second; + write_h5_dataset(*m_measurement_detector_info,key.c_str(),value); + } + } + + // create the image data structure in the file + hsize_t data_dims[3]; + data_dims[1] = aData.dimensions[1]; + data_dims[2] = aData.dimensions[0]; + data_dims[0] = m_nbframes; + // Create property list for the dataset and setup chunk size + DSetCreatPropList plist; + hsize_t chunk_dims[3]; + // calculate a optimized chunking + calculate_chunck(data_dims, chunk_dims, aData.depth()); + //chunk_dims[0] = 1; + //chunk_dims[1] = aData.dimensions[1]/4; + //chunk_dims[2] = aData.dimensions[0]/4; + plist.setChunk(RANK_THREE, chunk_dims); + + m_image_dataspace = new DataSpace(RANK_THREE, data_dims); // create new dspace + m_image_dataset = new DataSet(m_measurement_detector->createDataSet("data", data_type, *m_image_dataspace, plist)); + string nxdata = "NXdata"; + write_h5_attribute(*m_image_dataset, "NX_class", nxdata); + string image = "image"; + write_h5_attribute(*m_image_dataset, "interpretation", image); + m_format_written = true; + } + // write the image data + hsize_t slab_dim[3]; + slab_dim[2] = aData.dimensions[0]; + slab_dim[1] = aData.dimensions[1]; + slab_dim[0] = 1; + DataSpace slabspace = DataSpace(RANK_THREE, slab_dim); + int image_nb = aData.frameNumber % m_nbframes; + hsize_t start[] = { image_nb, 0, 0 }; + hsize_t count[] = { 1, aData.dimensions[1], aData.dimensions[0] }; + m_image_dataspace->selectHyperslab(H5S_SELECT_SET, count, start); + m_image_dataset->write((u_int8_t*) aData.data(), data_type, slabspace, *m_image_dataspace); + // catch failure caused by the DataSet operations + + } catch (DataSetIException& error) { + THROW_CTL_ERROR(Error) << "DataSet not created successfully " << error.getCDetailMsg(); + error.printError(); + } + // catch failure caused by the DataSpace operations + catch (DataSpaceIException& error) { + THROW_CTL_ERROR(Error) << "DataSpace not created successfully " << error.getCDetailMsg(); + } + // catch failure caused by any other HDF5 error + catch (H5::Exception &e) { + THROW_CTL_ERROR(Error) << e.getCDetailMsg(); + } + // catch anything not hdf5 related + catch (Exception &e) { + THROW_CTL_ERROR(Error) << e.getErrMsg(); + } + } + DEB_RETURN(); +} + + +void SaveContainerHdf5::_clear() +{ + // dont know what to do yet! + // Inheritance requires me. +} + diff --git a/control/src/CtSaving_Hdf5.h b/control/src/CtSaving_Hdf5.h new file mode 100644 index 0000000000000000000000000000000000000000..f20f960d904c2e5c6730255d9bf14a5062121a1f --- /dev/null +++ b/control/src/CtSaving_Hdf5.h @@ -0,0 +1,101 @@ +//########################################################################### +// This file is part of LImA, a 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 . +//########################################################################### +#ifndef CTSAVING_HDF5_H +#define CTSAVING_HDF5_H + +#include "H5Cpp.h" +#include "CtSaving.h" +#include "CtAcquisition.h" +#include + +using namespace H5; +using namespace std; + +namespace lima { + +class CtControl; +class CtImage; +class CtAcquisition; +class HwInterface; + +class SaveContainerHdf5: public CtSaving::SaveContainer { +DEB_CLASS_NAMESPC(DebModControl,"Saving HDF5 Container","Control"); + +public: + + SaveContainerHdf5(CtSaving::Stream& stream, CtSaving::FileFormat format); + virtual ~SaveContainerHdf5(); + +protected: + virtual void _prepare(CtControl &control); + virtual bool _open(const std::string &filename, std::ios_base::openmode flags); + virtual void _close(); + virtual void _writeFile(Data &data, CtSaving::HeaderMap &aHeader, CtSaving::FileFormat); + virtual void _clear(); + +private: + + struct Parameters{ + string det_name; + string det_model; + string det_type; + double pixel_size[2]; + Size max_image_size; + ImageType curr_image_type; + AcqMode acq_mode; + double acq_expo_time; + double acq_latency_time; + int acq_nbframes; + TrigMode acq_trigger_mode; + CtAcquisition::AccTimeMode acc_time_mode; + double acc_max_expotime; + double acc_expotime; + double acc_livetime; + double acc_deadtime; + int concat_nbframes; + Bin image_bin; + Roi image_roi; + Flip image_flip; + RotationMode image_rotation; + FrameDim image_dim; + }; + + CtSaving::FileFormat m_format; + Parameters m_ct_parameters; + CtImage *m_ct_image; + CtAcquisition *m_ct_acq; + HwInterface *m_hw_int; + bool m_is_mutltiset; + int m_nbframes; + Mutex m_lock; + bool m_already_opened; + bool m_format_written; + DataSpace *m_image_dataspace; + DataSet *m_image_dataset; + H5File *m_file; + Group *m_entry, *m_measurement_detector, *m_instrument_detector, *m_measurement_detector_info; + int m_entry_index; + string m_entry_name; +}; + +} +#endif // CTSAVING_HDF5_H diff --git a/control/src/Makefile b/control/src/Makefile index cc7fd087f6ef62c647d5786df8c6c1256ef40646..cdeceda1430694a21a0932b55ad2624f29f8070a 100644 --- a/control/src/Makefile +++ b/control/src/Makefile @@ -61,6 +61,13 @@ INCLUDES += -I../../third-party/CBFLib/include CXXFLAGS += -DWITH_CBF_SAVING endif +ifneq ($(COMPILE_HDF5_SAVING),0) +ct-objs += CtSaving_Hdf5.o +INCLUDES += -I../../third-party/hdf5/src +INCLUDES += -I../../third-party/hdf5/c++/src +CXXFLAGS += -DWITH_HDF5_SAVING +endif + ifneq ($(COMPILE_NXS_SAVING),0) ct-objs += CtSaving_Nxs.o # nexuscpp lib is not yet available but soon ! diff --git a/hardware/include/HwDetInfoCtrlObj.h b/hardware/include/HwDetInfoCtrlObj.h index 91acb485ec2725f33dc11f4f532e9f6ffa3c664c..3f1f889b259e4badfb8b750af8e673927877f9f2 100644 --- a/hardware/include/HwDetInfoCtrlObj.h +++ b/hardware/include/HwDetInfoCtrlObj.h @@ -52,7 +52,14 @@ class LIMACORE_API HwDetInfoCtrlObj HwMaxImageSizeCallback& cb) = 0; virtual void unregisterMaxImageSizeCallback( HwMaxImageSizeCallback& cb) = 0; + virtual void setUserDetectorName(const std::string &username){m_username = username;}; + virtual void getUserDetectorName(std::string &username) { + if (!m_username.empty()) username = m_username; + else getDetectorType(username); + }; +private: + std::string m_username; }; diff --git a/hardware/include/HwSavingCtrlObj.h b/hardware/include/HwSavingCtrlObj.h index 6d24e23ac11c9e5d92a9329edfeaf38d23b7de68..0b81dbae4cae7dd877aea2068f5ad68b80c53ac5 100644 --- a/hardware/include/HwSavingCtrlObj.h +++ b/hardware/include/HwSavingCtrlObj.h @@ -46,6 +46,7 @@ namespace lima static const char *EDF_FORMAT_STR; static const char *CBF_FORMAT_STR; static const char *TIFF_FORMAT_STR; + static const char *HDF5_FORMAT_STR; explicit HwSavingCtrlObj(int capabilities = 0); virtual ~HwSavingCtrlObj(); diff --git a/hardware/sip/HwDetInfoCtrlObj.sip b/hardware/sip/HwDetInfoCtrlObj.sip index 3d3a635f90c81733392c8eee1eb2480edf0d997c..acc2766b1d9ba03e0bd445f16245f39380794d2a 100644 --- a/hardware/sip/HwDetInfoCtrlObj.sip +++ b/hardware/sip/HwDetInfoCtrlObj.sip @@ -38,6 +38,8 @@ using namespace lima; virtual void getPixelSize(double& x_size /Out/,double &y_size /Out/) = 0; virtual void getDetectorType(std::string& det_type /Out/) = 0; virtual void getDetectorModel(std::string& det_model /Out/) = 0; + virtual void setUserDetectorName(const std::string &username); + virtual void getUserDetectorName(std::string& username /Out/); virtual void registerMaxImageSizeCallback( HwMaxImageSizeCallback& cb) = 0; diff --git a/hardware/sip/HwSavingCtrlObj.sip b/hardware/sip/HwSavingCtrlObj.sip index 1eb1749a090062107b1281df596ce3e762e3555f..45c17f6d0b7eb80f29ed40f57037e9c0e9afe9cb 100644 --- a/hardware/sip/HwSavingCtrlObj.sip +++ b/hardware/sip/HwSavingCtrlObj.sip @@ -35,6 +35,7 @@ public: static const char *EDF_FORMAT_STR; static const char *CBF_FORMAT_STR; static const char *TIFF_FORMAT_STR; + static const char *HDF5_FORMAT_STR; explicit HwSavingCtrlObj(int capabilities = 0); virtual ~HwSavingCtrlObj(); diff --git a/hardware/src/HwSavingCtrlObj.cpp b/hardware/src/HwSavingCtrlObj.cpp index e134e358d7af7ac3589cb24eea65491a3ce8a2f2..5fcd3e3f35e65b6808202754da3bdbd33585c013 100644 --- a/hardware/src/HwSavingCtrlObj.cpp +++ b/hardware/src/HwSavingCtrlObj.cpp @@ -29,6 +29,7 @@ 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 const char* HwSavingCtrlObj::TIFF_FORMAT_STR = "TIFF"; ///< TIFF format +const char* HwSavingCtrlObj::HDF5_FORMAT_STR = "HDF5"; ///< HDF5 format #ifdef __linux__ class HwSavingCtrlObj::DirectoryCallback : public DirectoryEvent::Callback { diff --git a/install.inc b/install.inc index cd403a310a233e160b99da6472f3883fef355131..eb8ca35f73062796e760b77d11cc338a65d74098 100644 --- a/install.inc +++ b/install.inc @@ -221,6 +221,11 @@ ifneq ($(COMPILE_TIFF_SAVING),0) INSTALL_CONFIG_DEFINES += -DWITH_TIFF_SAVING endif +ifneq ($(COMPILE_HDF5_SAVING),0) +INSTALL_CONFIG_DEFINES += -DWITH_HDF5_SAVING +INSTALL_DEPS += hdf5.install +endif + ifneq ($(COMPILE_CONFIG),0) INSTALL_CONFIG_DEFINES += -DWITH_CONFIG INSTALL_DEPS += libconfig.install @@ -254,6 +259,8 @@ CCfits.install: libconfig.install: $(MAKE) -C third-party libconfig.install +hdf5.install: + $(MAKE) -C third-party hdf5.install ################## # INSTALL TARGET # diff --git a/sip/configure.py b/sip/configure.py index 7bd4ab301fb9c45c6c8e441e23acaf6353ca7a2d..dde8cad1935eb3306ef431925802c66f183dcc69 100644 --- a/sip/configure.py +++ b/sip/configure.py @@ -177,6 +177,8 @@ def main(): extraIncludes += ['/usr/local/include'] elif(modName == 'xpad'): extraIncludes += ['../../third-party/yat/include','/home/xpix_user/PCI_VALIDATED/trunk/sw/xpci_lib'] + elif(modName == 'xspress3'): + extraIncludes += ['../../third-party/hdf5/include'] elif(modName == 'pco'): extraIncludes += ['R:/bliss/projects/LIMA/package/WIN32/PCO/sdkPco/include'] elif(modName == 'marccd'): diff --git a/third-party/Makefile b/third-party/Makefile index 00c3ebb5140a8e68ff34109bd942a4b613412467..783cbe9751a29b65137561081d2b7b5f5f07af31 100644 --- a/third-party/Makefile +++ b/third-party/Makefile @@ -1,7 +1,7 @@ ############################################################################ # This file is part of LImA, a Library for Image Acquisition # -# Copyright (C) : 2009-2011 +# Copyright (C) : 2009-2014 # European Synchrotron Radiation Facility # BP 220, Grenoble 38043 # FRANCE @@ -103,6 +103,7 @@ ifeq ($(COMPILE_SPS_IMAGE),0) $(error "GLDisplay requires SPS. Please set COMPILE_SPS_IMAGE=1 in config.inc) endif + PROJECTS += gldisplay.src PROJECTS_TEST += gldisplay.test PROJECTS_POSTLIMA_CONFIG += gldisplay.config @@ -110,6 +111,21 @@ PROJECTS_POSTLIMA_SIP += gldisplay.sip PROJECTS_CLEAN += gldisplay.clean endif + +ifndef COMPILE_HDF5_SAVING +COMPILE_HDF5_SAVING = 0 +endif + +ifneq ($(COMPILE_HDF5_SAVING),0) +ifneq ($(wildcard hdf5/Makefile),) +PROJECTS_CLEAN += hdf5.clean +else +PROJECTS += hdf5.confsrc +endif + +PROJECTS += hdf5.src +endif + # meta targets all: src test @@ -228,3 +244,23 @@ gldisplay/sip/gldisplay.so: gldisplay_build_libgldisplay.so \ gldisplay/sip/Makefile $(MAKE) -C gldisplay sip +hdf5.src: + $(MAKE) -C hdf5 all + +hdf5.clean: + $(MAKE) -C hdf5 clean + +hdf5.confsrc: + cd hdf5 && ./configure --enable-cxx \ + --enable-unsupported \ + --enable-threadsafe \ + --with-pthread=/usr/lib,/usr/include \ + --prefix=$(INSTALL_PLAT_DIR) + +hdf5.install: + cd hdf5 && ./configure --enable-cxx \ + --enable-unsupported \ + --enable-threadsafe \ + --with-pthread=/usr/lib,/usr/include \ + --prefix=$(INSTALL_PLAT_DIR) \ + && $(MAKE) install diff --git a/third-party/hdf5 b/third-party/hdf5 new file mode 160000 index 0000000000000000000000000000000000000000..37532f50371258abde1371e9d1087d6033ae30b7 --- /dev/null +++ b/third-party/hdf5 @@ -0,0 +1 @@ +Subproject commit 37532f50371258abde1371e9d1087d6033ae30b7