...
 
Commits (133)
......@@ -4,9 +4,6 @@ stages:
.build-conda: &build-conda
stage: build
script:
- git submodule update --init --recursive third-party/bitshuffle
- conda build ./conda --prefix-length=80 --output-folder=dist/ --channel=http://bcu-ci.esrf.fr/stable
artifacts:
paths:
- dist/
......@@ -15,11 +12,19 @@ stages:
build-linux:
<<: *build-conda
script:
- git submodule update --init --recursive third-party/bitshuffle
- conda build ./conda/debug --prefix-length=80 --output-folder=dist/ --channel=http://bcu-ci.esrf.fr/stable
- conda build ./conda/release --prefix-length=80 --output-folder=dist/ --channel=http://bcu-ci.esrf.fr/stable
tags:
- linux
build-win:
<<: *build-conda
script:
- git submodule update --init --recursive third-party/bitshuffle
- call conda build ./conda/debug --prefix-length=80 --output-folder=dist/ --channel=http://bcu-ci.esrf.fr/stable
- call conda build ./conda/release --prefix-length=80 --output-folder=dist/ --channel=http://bcu-ci.esrf.fr/stable
tags:
- win
......
......@@ -120,7 +120,7 @@
url = git://github.com/kiyo-masui/bitshuffle
[submodule "camera/lambda"]
path = camera/lambda
url = git://github.com/esrf-bliss/Lima-camera-lambda
url = ../Lima-camera-lambda
[submodule "camera/fli"]
path = camera/fli
url = ../Lima-camera-fli
......@@ -130,3 +130,9 @@
[submodule "camera/simulator"]
path = camera/simulator
url = ../Lima-camera-simulator.git
[submodule "camera/common/meta"]
path = camera/common/meta
url = ../Lima-camera-meta.git
[submodule "camera/qhyccd"]
path = camera/qhyccd
url = ../Lima-camera-qhyccd
......@@ -24,7 +24,7 @@
cmake_minimum_required(VERSION 3.1)
project (lima)
project (Lima)
include(cmake/project_version.cmake)
set(NAME "core")
......@@ -60,6 +60,11 @@ endif()
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
include(LimaTools)
if(UNIX AND LIMA_ENABLE_NUMA)
# Numa is needed for advanced buffer management
find_package(Numa REQUIRED)
endif()
# Import pthread
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads REQUIRED)
......@@ -79,31 +84,8 @@ endif()
# Enable python binding code compilation using sip generator
if(LIMA_ENABLE_PYTHON)
find_package(PythonInterp)
find_package(PythonLibs)
if(${PYTHONINTERP_FOUND})
# python site-packages folder
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print (get_python_lib())"
OUTPUT_VARIABLE _PYTHON_SITE_PACKAGES_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE)
else()
message(FATAL_ERROR "No python found, please install or disable LIMA_ENABLE_PYTHON")
endif()
set(PYTHON_SITE_PACKAGES_DIR ${_PYTHON_SITE_PACKAGES_DIR} CACHE PATH "where should python modules be installed?")
find_package(SIP REQUIRED)
include(SIPMacros)
if(WIN32)
set(SIP_TAGS WIN32_PLATFORM)
elseif(UNIX)
set(SIP_TAGS POSIX_PLATFORM)
endif(WIN32)
set(SIP_EXTRA_OPTIONS -e -g)
find_package(NumPy REQUIRED)
endif()
limatools_find_python_and_sip()
endif()
#--------------------------------------------------------------------------------
# Define source files
......@@ -253,13 +235,20 @@ if(LIMA_BUILD_SUBMODULES)
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/third-party/Processlib/tasks/include>")
endif()
if(UNIX AND LIMA_ENABLE_NUMA)
target_compile_definitions(limacore PUBLIC LIMA_USE_NUMA)
target_include_directories(limacore PRIVATE "${NUMA_INCLUDE_DIR}")
endif()
if(LIMA_ENABLE_SPS_IMAGE)
target_compile_definitions(limacore PUBLIC -DWITH_SPS_IMAGE)
target_compile_definitions(limacore PUBLIC WITH_SPS_IMAGE)
target_include_directories(limacore PRIVATE "${CMAKE_SOURCE_DIR}/third-party/Sps/Include")
endif()
# Set LIMA_NO_DEBUG if the build type is not debug
target_compile_definitions(limacore PUBLIC $<$<NOT:$<CONFIG:DEBUG>>:LIMA_NO_DEBUG>)
# Set LIMA_NO_DEBUG if LIMA_ENABLE_DEBUG is set
if(NOT LIMA_ENABLE_DEBUG)
target_compile_definitions(limacore PUBLIC LIMA_NO_DEBUG)
endif()
# add all include paths coming from saving format options
target_include_directories(limacore PRIVATE ${extra_includes} ${saving_includes})
......@@ -275,6 +264,9 @@ target_link_libraries(limacore PRIVATE ${saving_private_libs})
if(UNIX)
target_compile_definitions(limacore PUBLIC -DHAS_INOTIFY)
target_link_libraries(limacore PUBLIC "rt")
if(LIMA_ENABLE_NUMA)
target_link_libraries(limacore PUBLIC ${NUMA_LIBRARY})
endif()
endif()
if(WIN32)
......@@ -305,7 +297,6 @@ if(LIMA_ENABLE_PYTHON)
endforeach()
configure_file(sip/limacore.sip.in sip/limacore.sip)
configure_file(sip/lima_init_numpy.cpp.in sip/core/limacore_init_numpy.cpp)
list(APPEND LIMA_SIP_INCLUDE_DIRS
"${CMAKE_CURRENT_BINARY_DIR}/sip"
"${CMAKE_CURRENT_SOURCE_DIR}/common/sip"
......@@ -361,9 +352,7 @@ endif()
if(LIMA_ENABLE_TESTS)
enable_testing()
add_subdirectory(control/test)
if (NOT WIN32)
add_subdirectory(common/test)
endif()
add_subdirectory(common/test)
endif()
#--------------------------------------------------------------------------------
......
# Set install dir for SIP files and CMake packages
set(SIP_INSTALL_DIR ${CMAKE_INSTALL_DATADIR}/sip/lima)
set(CMAKE_INSTALL_DIR ${CMAKE_INSTALL_DATADIR}/cmake/lima)
if(NOT LIMA_BUILD_SUBMODULES)
# Generate and install package config file and version
set(PROJECT_LIBRARIES limacore h5bshuf)
set(SIP_INSTALL_DIR ${CMAKE_INSTALL_DATADIR}/sip/lima)
set(CMAKE_INSTALL_DIR ${CMAKE_INSTALL_DATADIR}/cmake/lima)
include(cmake/package_config.cmake)
include(cmake/components_config.cmake)
endif()
install(
TARGETS limacore
EXPORT "${TARGETS_EXPORT_NAME}"
COMPONENT runtime
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} # import library
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} # .so files are libraries
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} # .dll files are binaries
......@@ -25,24 +29,28 @@ install(
install(
DIRECTORY ${CMAKE_SOURCE_DIR}/common/include/
COMPONENT devel
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN "*.h"
)
install(
DIRECTORY ${CMAKE_SOURCE_DIR}/hardware/include/
COMPONENT devel
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN "*.h"
)
install(
DIRECTORY ${CMAKE_SOURCE_DIR}/control/include/
COMPONENT devel
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN "*.h"
)
install(
DIRECTORY ${CMAKE_SOURCE_DIR}/control/software_operation/include/
COMPONENT devel
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN "*.h"
)
......@@ -56,17 +64,21 @@ if(NOT LIMA_BUILD_SUBMODULES)
${CMAKE_SOURCE_DIR}/cmake/SIPMacros.cmake
${CMAKE_SOURCE_DIR}/cmake/sip_init_numpy.cpp.in
${CMAKE_SOURCE_DIR}/cmake/package_config.cmake
${CMAKE_SOURCE_DIR}/cmake/components_config.cmake
${CMAKE_SOURCE_DIR}/cmake/project_version.cmake
${CMAKE_SOURCE_DIR}/cmake/project_version.cc.in
${CMAKE_SOURCE_DIR}/cmake/project_version.h.in
${CMAKE_SOURCE_DIR}/cmake/LimaTools.cmake
COMPONENT devel
COMPONENT tools
DESTINATION ${CMAKE_INSTALL_DIR}
)
endif()
if(LIMA_ENABLE_PYTHON)
install(DIRECTORY python/Lima/ DESTINATION "${PYTHON_SITE_PACKAGES_DIR}/Lima")
install(
DIRECTORY python/Lima/
COMPONENT sip
DESTINATION "${PYTHON_SITE_PACKAGES_DIR}/Lima")
file(GLOB SIP_SOURCES
"${CMAKE_SOURCE_DIR}/common/sip/*.sip"
......@@ -80,7 +92,7 @@ if(LIMA_ENABLE_PYTHON)
FILES ${SIP_SOURCES}
${CMAKE_CURRENT_BINARY_DIR}/sip/limacore.sip
${CMAKE_SOURCE_DIR}/sip/limamodules.sip.in
COMPONENT devel
COMPONENT sip
DESTINATION ${SIP_INSTALL_DIR}
)
endif()
......
//###########################################################################
// This file is part of LImA, a Library for Image Acquisition
//
// Copyright (C) : 2009-2017
// Copyright (C) : 2009-2019
// European Synchrotron Radiation Facility
// CS40220 38043 Grenoble Cedex 9
// FRANCE
......
###########################################################################
This file is part of LImA, a Library for Image Acquisition
Copyright (C) : 2009-2017
Copyright (C) : 2009-2019
European Synchrotron Radiation Facility
CS40220 38043 Grenoble Cedex 9
FRANCE
......
......@@ -46,6 +46,11 @@ endif()
#--------------------------------------------------------------------------------
option(LIMA_ENABLE_TESTS "compile test directories ?" OFF)
#--------------------------------------------------------------------------------
# Compile with trace (debug information)
#--------------------------------------------------------------------------------
option(LIMA_ENABLE_DEBUG "compile with trace ?" ON)
#--------------------------------------------------------------------------------
# libconfig
#--------------------------------------------------------------------------------
......
# LImA
[![License](https://img.shields.io/github/license/esrf-bliss/lima.svg?style=flat)](https://opensource.org/licenses/GPL-3.0)
[![Gitter](https://img.shields.io/gitter/room/esrf-bliss/lima.svg?style=flat)](https://gitter.im/esrf-bliss/LImA)
[![Conda](https://img.shields.io/conda/dn/esrf-bcu/lima-core.svg?style=flat)](https://anaconda.org/esrf-bcu)
[![Version](https://img.shields.io/conda/vn/esrf-bcu/lima-core.svg?style=flat)](https://anaconda.org/esrf-bcu)
[![Platform](https://img.shields.io/conda/pn/esrf-bcu/lima-core.svg?style=flat)](https://anaconda.org/esrf-bcu)
Lima ( **L** ibrary for **Im** age **A** cquisition) is a project for the unified control of 2D detectors. The aim is to clearly separate hardware specific code from common software configuration and features, like setting standard acquisition parameters (exposure time, external trigger), file saving and image processing.
Lima is a C++ library which can be used with many different cameras. The library also comes with a [Python](http://python.org) binding and provides a [PyTango](http://pytango.readthedocs.io/en/stable/) device server for remote control.
## Documentation
The documentation is available [here](http://lima-doc.readthedocs.io/). Thank you to the people running Read the Docs for such an excellent service.
The documentation is available [here](http://lima.blissgarden.org). Thank you to the people running Read the Docs for such an excellent service.
The source for the documentation is in the `docs` folder. Here are the instructions to built and read it locally. The documentation is built with [Doxygen](http://www.doxygen.org/) and [Sphinx](http://www.sphinx-doc.org). The sphinx template is from [ReadtheDocs](https://docs.readthedocs.io). [Breathe](https://breathe.readthedocs.io) provides a bridge between the Sphinx and Doxygen documentation systems.
......
.. image:: http://lima.blissgarden.org/_static/lima-logo-2-40perc.png
=============================
Library for Image Acquisition
=============================
|Linux Status|
|Windows Status|
Description
-----------
Lima ( **L** ibrary for **Im** age **A** cquisition) is a project for the unified control of 2D detectors. The aim is to clearly separate hardware specific code from common software configuration and features, like setting standard acquisition parameters (exposure time, external trigger), file saving and image processing.
Lima is a C++ library which can be used for many different cameras. The library is also available for Python_ and it provides a PyTango_ server for remote control.
Documentation: http://lima.blissgarden.org
.. _requirements:
Requirements
------------
You need to install some tools and libraries for building Lima for both windows and Linux.
Build dependencies:
- gcc for Linux
- Visual Studio 2008 for x86 or x64 for Python 2.7.x
- Visual Studio 2008 Express for x86 only for Python 2.7.x
- Visual Studio 2015 for x86 and x64 for Python >= 3.5
- git_
- CMake_ >= 3.1
- gsl_: For windows, download the esrf binary package `gsl-windows`_ and install it under "c:\\program files\\"
**Python** dependencies:
Lima_ can be compiled for python 2 and 3. The following packages must be installed, development versions with header files (include files) are mandatory.
- numpy_ >= 1.1
- sip_ <= 4.18
The following requirements are optional.
Saving format dependencies:
- tiff_
- zlib_: for windows, you can download the esrf binary package `zlib-windows`_ and install it under "c:\\program files\\"
- cbf_
- hdf5_
- ccfits_
- lz4_ = 1.7.x
- libconfig_: for windows you can download the ESRF binary package `libconfig-windows`_ and install it under "c:\\program files\\"
PyTango_ server dependencies:
The LimaCCDs PyTango server only works for Python 2, it will be updated for Python 3 soon !!
- PyTango_
- libtango_
.. _git: https://git-scm.com
.. _Python: http://python.org
.. _Lima: http://lima.blissgarden.org
.. _gsl: https://www.gnu.org/software/gsl
.. _gsl-windows: http://ftp.esrf.fr/pub/bliss/lima/gsl-windows.zip
.. _zlib-windows: http://ftp.esrf.fr/pub/bliss/lima/zlib-windows.zip
.. _libconfig-windows: http://ftp.esrf.fr/pub/bliss/lima/libconfig-windows.zip
.. _CMake: https://cmake.org
.. _Tango: http://tango-control.org
.. _PyTango: http://github.com/tango-cs/pytango
.. _libtango: http://tango-controls.org/downloads/source
.. _numpy: http://pypi.python.org/pypi/numpy
.. _sip: https://www.riverbankcomputing.com/software/sip
.. _tiff: http://www.libtiff.org/
.. _zlib: https://zlib.net/
.. _cbf: http://www.bernstein-plus-sons.com/software/CBF
.. _hdf5: https://support.hdfgroup.org/HDF5
.. _ccfits: https://heasarc.gsfc.nasa.gov/fitsio/ccfits
.. _lz4: https://lz4.github.io/lz4
.. _libconfig: http://www.hyperrealm.com/libconfig
.. _build_installation:
Build and Install
-----------------
Using scripts
^^^^^^^^^^^^^
the **install** scripts will run cmake, compile and install.
It accepts input arguments (see below) but it also uses a configuration file **scripts/config.txt**. Feel free to update this file for setting a permanent configuration for your own installation.
Linux::
[sudo] install.sh
[--git]
[--prefix=<desired installation path>]
[--python-packages=<desired python installation path>]
[options]
Windows::
install.bat
[--prefix=<desired installation path>]
[--python-packages=<desired python installation path>]
[options]
The **--git** (Linux only) option cab be used to clone the required submodules as a prerequisite. Otherwise you should install the submodules with git commands, for instance::
$ git submodule init third-party/Processlib
$ git submodule init camera/basler
$ git submodule init applications/tango/python
$ git submodule update
Options are <camera-name> <saving-format> python pytango-server:
- camera-name::
andor|andor3|basler|prosilica|adsc|mythen3|ueye|xh|xspress3|ultra|
xpad|mythen|pco|marccd|pointgrey|imxpad|dexela|merlin|v4l2|
eiger|pixirad|hexitec|aviex|roperscientific|rayonixhs|espia|maxipix|frelon
- saving-format::
cbf|nxs|fits|edfgz|edflz4|tiff|hdf5
- python: to compile python module
- pytango-server: to install the PyTango_ server
Example::
$ sudo install.sh --git
--prefix=./install
--python-packages=./install/python
tiff basler python pytango-server
Using cmake
^^^^^^^^^^^
Install first the project submodules::
$ git submodule init third-party/Processlib
$ git submodule init camera/basler
$ git submodule init applications/tango/python
$ git submodule update
Run cmake in the build directory::
$ mkdir build
$ cd build
$ cmake ..
[-G "Visual Studio 9 2008 Win64" | -G "Visual Studio 9 2008" | -G "Unix Makefiles"]
[-DCMAKE_INSTALL_PREFIX=<desired installation path>]
[-DPYTHON_SITE_PACKAGES_DIR=<desired python installation path>]
-DLIMA_ENABLE_TIFF=true
-DLIMACAMERA_BASLER=true
-DLIMA_ENABLE_PYTANGO_SERVER=true
-DLIMA_ENABLE_PYTHON=true
Then compile and install::
$ cmake --build
$ sudo cmake --build --target install
May you need to update your environment?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you have changed the default destination path for both libraries and python modules you should update
your environment variables.
For Linux:
.. code-block:: sh
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:<my-new-install-dir>/Lima/lib
export PYTHONPATH=$PYTHONPATH:<my-new-install-dir>
For Windows:
Update the system wide variables PATH for the libraries and PYTHONPATH for python.
.. _PyTango: http://github.com/tango-cs/pytango
Lima Team contact: lima@esrf.fr
.. |Linux Status| image:: https://travis-ci.org/esrf-bliss/Lima.svg?branch=cmake
:target: https://travis-ci.org/esrf-bliss/Lima
:alt:
.. |Windows Status| image:: https://ci.appveyor.com/api/projects/status/rk0yqwem1jqxwubu?svg=true
:target: https://ci.appveyor.com/api/projects/status/rk0yqwem1jqxwubu/branch/cmake?svg=true
.. _Python: http://python.org
.. _PyTango: http://github.com/tango-cs/pytango
......@@ -3,15 +3,55 @@ LIMA Release Notes
This is the release notes of LIMA, the library for image acquisition.
You can find information related to new features and bug fixes. The notes are ordered by branch and release number.
The notes are prefixed with a category name for core, subsystems image/saving/processlib/..., camera names andor/andor3/basler..., windows, applications tango python/tango c++/spec and third-party submodules sps/processlib/...
Stable branch core-1.8
----------------------
Version v1.9.0 released on September 13th 2019
----------------------------------------------
Revamp the build system to use CMake, a cross-platform family of tools designed to build, test and package software.
New features
* More conda packages for cameras are now supported:
andor3, andor, basler, dexela, eiger, frelon,
frelon, imxpad, maxipix, marccd, merlin,
mythen3, pco, pilatus, pixirad, pointgrey,
prosilica, simulator, slsdetector, ueye,
v4l2, xh
* Some refactoring and optimisation of the software buffer classes
* Support added for Numa (non-uniform memory access) memory management
Bug Fixes
* CBF saving format now fits with miniCBF spec for Pilatus detectors
* Video: fixed issue when taking 8/16-bit images and then changing to Accumulation
New cameras
* PCO usb
* Frelon 16
Version v1.8.0 released on February 2nd 2019
--------------------------------------------
With this release we introduced the following new features:
* Build system has been refactored to use CMake, a cross-platform build system (Windows and Linux)
* Building camera either standalone or using Lima as master project
* Better support for C++ developers (with CMake packages)
* Install.(sh|bat) to ease build and installation for CMake averse :-)
* Conda binary packages for processlib, LImA core and some cameras and pytango device server
* Support for Python 3
* CI running on ESRF's Gitlab instance
* Documentation improvements and migrated to ReadTheDocs (https://lima1.readthedocs.io)
* Use semantic versionning
* New HDF5 layout, direct chunk and bitshuffle LZ4 / gzip compression support
* New BPM pytango plugin, Beam Position Monitor
* Simulator improvements (new prefetch and read from files modes)
## New camera plugins
* ZWO camera plugin (thanks to Jens Krueger)
* SlsDetector (PSI Eiger) camera plugin (thanks to Alejandro Homs)
* FLI (Finger Lake Instrument) camera plugin (thanks to Laurent Claustre)
* Lambda (Quantum) camera plugin (thanks to Teresa Nunez)
Stable branch core-1.7
----------------------
......
This diff is collapsed.
Subproject commit c572422f3905664267c88255e8e5e10e1d819a52
Subproject commit 91d21e0b8cc84f16de506b8a2b57d4c31f37b0f2
Subproject commit 6a537e383a77e3c80299e16c5148eee5fd247960
Subproject commit df09b4e4a373220c73414965f9a0b5a456b789de
Subproject commit cf317bbb082eefdbc43d2b6ad0a1989793415314
Subproject commit 11d463d2bb88fbbf7b4ab37b2d8a8a5cc6622f80
Subproject commit 05fa3370c45bee7c164b16b104d43b13d6eb6e21
Subproject commit 00f52b4cad2179082b8a7b43b11c9be03a57b7c6
Subproject commit 20d7f4a75ac5b65daf51af314fa18e7432d8af3b
Subproject commit 826a4795eace6d3ae89d7168944a78d214785801
Subproject commit 485871741e4aa58f0c3edddb3552c606c570e846
Subproject commit 0180cd19446b01d48ecf76982c17fe217a2552ab
Subproject commit 2e3fc4df5063380337adbf2eca6a6814a2f8aefa
src-dirs = src
test-dirs =
include ../../../global.inc
//###########################################################################
// 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 <http://www.gnu.org/licenses/>.
//###########################################################################
#ifndef METADETINFOCTRLOBJ_H
#define METADETINFOCTRLOBJ_H
#include "lima/HwDetInfoCtrlObj.h"
#include "lima/Debug.h"
namespace lima
{
class HwInterface;
namespace Meta
{
class Interface;
class DetInfoCtrlObj : public HwDetInfoCtrlObj, public HwMaxImageSizeCallbackGen
{
DEB_CLASS_NAMESPC(DebModCamera, "DetInfoCtrlObj","Meta");
class _MaxImageSizeCallback;
friend class _MaxImageSizeCallback;
friend class Interface;
public:
DetInfoCtrlObj(Interface&);
virtual ~DetInfoCtrlObj();
virtual void getMaxImageSize(Size& max_image_size);
virtual void getDetectorImageSize(Size& det_image_size);
virtual void getDefImageType(ImageType& def_image_type);
virtual void getCurrImageType(ImageType& curr_image_type);
virtual void setCurrImageType(ImageType curr_image_type);
virtual void getPixelSize(double& x_size,double &y_size);
virtual void getDetectorType(std::string& det_type);
virtual void getDetectorModel(std::string& det_model);
virtual void registerMaxImageSizeCallback(HwMaxImageSizeCallback& cb);
virtual void unregisterMaxImageSizeCallback(HwMaxImageSizeCallback& cb);
private:
Interface& m_interface;
std::list<_MaxImageSizeCallback*> m_cbk;
void _maxImageSizeChanged();
void _addInterface(HwInterface*);
};
} // namespace Meta
} // namespace lima
#endif // METADETINFOCTRLOBJ_H
//###########################################################################
// 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 <http://www.gnu.org/licenses/>.
//###########################################################################
#ifndef METAINTERFACE_H
#define METAINTERFACE_H
#include <map>
#include "lima/HwInterface.h"
#include "processlib/Data.h"
namespace lima
{
namespace Meta
{
class DetInfoCtrlObj;
class SyncCtrlObj;
class Interface : public HwInterface
{
DEB_CLASS_NAMESPC(DebModCamera, "MetaInterface", "Meta");
friend class DetInfoCtrlObj;
friend class SyncCtrlObj;
public:
enum Geometry {TILE};
Interface(Geometry = TILE);
virtual ~Interface();
void addInterface(int row,int column,HwInterface*);
//- From HwInterface
virtual void getCapList(CapList&) const;
virtual void reset(ResetLevel reset_level);
virtual void prepareAcq();
virtual void startAcq();
virtual void stopAcq();
virtual void getStatus(StatusType& status);
virtual int getNbHwAcquiredFrames();
private:
class _BufferFrameCBK;
friend class _BufferFrameCBK;
typedef std::pair<int,int> ColumnRow;
struct ltColumnRow
{
bool operator()(const ColumnRow& a,const ColumnRow& b)
{
return a.second == b.second ?
a.first < b.first : a.second < b.second;
}
};
typedef std::map<ColumnRow,HwInterface*,ltColumnRow> TileCnt;
typedef std::map<ColumnRow,int> TileOffset;
typedef std::map<int,int> PendingFrames;
typedef std::vector<_BufferFrameCBK*> BufferFrameCBKs;
bool _newFrameReady(int row,int column,const Data&);
TileCnt m_tiles;
Geometry m_geometry;
DetInfoCtrlObj* m_det_info;
SyncCtrlObj* m_sync;
SoftBufferCtrlObj m_buffer;
bool m_dirty_geom_flag;
int m_width_step;
ImageType m_curr_type;
TileOffset m_tiles_offset;
bool m_continue_acq;
Mutex m_lock;
PendingFrames m_pending_frames;
BufferFrameCBKs m_buffer_cbks;
};
}
}
#endif
############################################################################
# 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 <http://www.gnu.org/licenses/>.
############################################################################
from Lima import module_helper
mod_path = __path__
depends_on = 'Core'
has_dependent = False
cleanup_data = module_helper.load_prepare(mod_path, depends_on, has_dependent)
from Lima import Core
cleanup_data = module_helper.load_dep_cleanup(cleanup_data)
from Lima.Meta.limameta import Meta as _B
globals().update(_B.__dict__)
module_helper.load_cleanup(cleanup_data)
del mod_path, depends_on, has_dependent, cleanup_data
del module_helper
namespace Meta
{
class Interface : HwInterface
{
%TypeHeaderCode
#include <MetaInterface.h>
%End
public:
enum Geometry {TILE};
Interface(Geometry = TILE);
virtual ~Interface();
void addInterface(int row,int column,HwInterface*);
//- From HwInterface
// virtual void getCapList(CapList& /Out/) const;
virtual void getCapList(std::vector<HwCap> &cap_list /Out/) const;
virtual void reset(ResetLevel reset_level);
virtual void prepareAcq();
virtual void startAcq();
virtual void stopAcq();
virtual void getStatus(StatusType& status /Out/);
virtual int getNbHwAcquiredFrames();
};
};
meta-objs = MetaInterface.o MetaDetInfoCtrlObj.o MetaSyncCtrlObj.o
SRCS = $(meta-objs:.o=.cpp)
CXXFLAGS += -I../include -I../../../../hardware/include -I../../../../common/include \
-I../../../../control/include -I../../../../control/software_operation/include \
-I../../../../third-party/Processlib/core/include -Wall -pthread -fPIC -g
all: Meta.o
Meta.o: $(meta-objs)
$(LD) -o $@ -r $+
clean:
rm -f *.o *.P
%.o : %.cpp
$(COMPILE.cpp) -MD $(CXXFLAGS) -o $@ $<
@cp $*.d $*.P; \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $*.d >> $*.P; \
rm -f $*.d
-include $(SRCS:.cpp=.P)
.PHONY: check-syntax
check-syntax:
$(CXX) -Wall -Wextra -fsyntax-only $(CXXFLAGS) $(CHK_SOURCES)
//###########################################################################
// 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 <http://www.gnu.org/licenses/>.
//###########################################################################
#include <cstdlib>
#include "MetaDetInfoCtrlObj.h"
#include "MetaInterface.h"
using namespace lima;
using namespace lima::Meta;
#define GET_LOCAL_DET_INFO \
Interface::TileCnt::iterator i = m_interface.m_tiles.begin(); \
HwDetInfoCtrlObj* local_det_info; \
if(i == m_interface.m_tiles.end()) \
THROW_HW_ERROR(Error) << "Meta doesn't have any sub detector"; \
if(!i->second->getHwCtrlObj(local_det_info)) \
THROW_HW_ERROR(Error) << "Cannot get hardware det info";
class DetInfoCtrlObj::_MaxImageSizeCallback : public HwMaxImageSizeCallback
{
public:
_MaxImageSizeCallback(DetInfoCtrlObj &det) : m_det(det) {}
protected:
virtual void maxImageSizeChanged(const Size& size,ImageType image_type)
{
m_det._maxImageSizeChanged();
}
private:
DetInfoCtrlObj& m_det;
};
DetInfoCtrlObj::DetInfoCtrlObj(Interface& interface):
m_interface(interface)
{
}
DetInfoCtrlObj::~DetInfoCtrlObj()
{
for(std::list<_MaxImageSizeCallback*>::iterator i = m_cbk.begin();
i != m_cbk.end();++i)
delete *i;
}
void DetInfoCtrlObj::getMaxImageSize(Size& max_image_size)
{
DEB_MEMBER_FUNCT();
max_image_size = Size(0,0);
GET_LOCAL_DET_INFO;
Size local_max_image_size;
int prev_row = i->first.second;
local_det_info->getMaxImageSize(local_max_image_size);
int row_width = local_max_image_size.getWidth();
int row_height = local_max_image_size.getHeight();
for(++i;i != m_interface.m_tiles.end();++i)
{
if(!i->second->getHwCtrlObj(local_det_info))
THROW_HW_ERROR(Error) << "Cannot get hardware det info";
local_det_info->getMaxImageSize(local_max_image_size);
if(prev_row == i->first.second) // new column, same row
{
row_height = std::max(row_height,
local_max_image_size.getHeight());
row_width += local_max_image_size.getWidth();
}
else // new row
{
prev_row = i->first.second;
max_image_size = Size(std::max(max_image_size.getWidth(),row_width),
max_image_size.getHeight() + row_height);
row_height = local_max_image_size.getHeight();
row_width = local_max_image_size.getWidth();
}
}
max_image_size = Size(std::max(max_image_size.getWidth(),row_width),
max_image_size.getHeight() + row_height);
DEB_RETURN() << DEB_VAR1(max_image_size);
}
void DetInfoCtrlObj::getDetectorImageSize(Size& det_image_size)
{
DEB_MEMBER_FUNCT();
getMaxImageSize(det_image_size);
}
void DetInfoCtrlObj::getDefImageType(ImageType& def_image_type)
{
DEB_MEMBER_FUNCT();
GET_LOCAL_DET_INFO;
local_det_info->getDefImageType(def_image_type);
DEB_RETURN() << DEB_VAR1(def_image_type);
}
void DetInfoCtrlObj::getCurrImageType(ImageType& curr_image_type)
{
DEB_MEMBER_FUNCT();
getDefImageType(curr_image_type);
}
void DetInfoCtrlObj::setCurrImageType(ImageType curr_image_type)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(curr_image_type);
for(Interface::TileCnt::iterator i = m_interface.m_tiles.begin();
i != m_interface.m_tiles.end();++i)
{
HwDetInfoCtrlObj* local_det_info;
if(!i->second->getHwCtrlObj(local_det_info))
THROW_HW_ERROR(Error) << "Cannot get hardware det info";
local_det_info->setCurrImageType(curr_image_type);
}
}
/** @brief get pixel size of detector
assumed that all detector have the same resolution, it might be wrong in some cases.
*/
void DetInfoCtrlObj::getPixelSize(double& x_size,double& y_size)
{
DEB_MEMBER_FUNCT();
GET_LOCAL_DET_INFO;
local_det_info->getPixelSize(x_size,y_size);
DEB_RETURN() << DEB_VAR2(x_size,y_size);
}
void DetInfoCtrlObj::getDetectorType(std::string& det_type)
{
DEB_MEMBER_FUNCT();
GET_LOCAL_DET_INFO;
std::string local_det_type;
local_det_info->getDetectorType(local_det_type);
bool allMatch = true;
for(++i;allMatch && i != m_interface.m_tiles.end();++i)
{
std::string loop_det_type;
if(!i->second->getHwCtrlObj(local_det_info))
THROW_HW_ERROR(Error) << "Cannot get hardware det info";
local_det_info->getDetectorType(loop_det_type);
allMatch = loop_det_type == local_det_type;
}
if(allMatch)
det_type = "Meta_" + local_det_type;
else
det_type = "Meta_Hybrid";
DEB_RETURN() << DEB_VAR1(det_type);
}
void DetInfoCtrlObj::getDetectorModel(std::string& det_model)
{
DEB_MEMBER_FUNCT();
det_model = "";
for(Interface::TileCnt::iterator i = m_interface.m_tiles.begin();
i != m_interface.m_tiles.end();++i)
{
std::string local_det_model;
HwDetInfoCtrlObj* local_det_info;
if(!i->second->getHwCtrlObj(local_det_info))
THROW_HW_ERROR(Error) << "Cannot get hardware det info";
local_det_info->getDetectorModel(local_det_model);
if(!det_model.size())
det_model = local_det_model;
else
det_model += " / " + local_det_model;
}
}
void DetInfoCtrlObj::registerMaxImageSizeCallback(HwMaxImageSizeCallback& cb)
{
this->HwMaxImageSizeCallbackGen::registerMaxImageSizeCallback(cb);
}
void DetInfoCtrlObj::unregisterMaxImageSizeCallback(HwMaxImageSizeCallback &cb)
{
this->HwMaxImageSizeCallbackGen::unregisterMaxImageSizeCallback(cb);
}
void DetInfoCtrlObj::_maxImageSizeChanged()
{
Size max_image_size;
getMaxImageSize(max_image_size);
ImageType def_image_type;
getCurrImageType(def_image_type);
maxImageSizeChanged(max_image_size,def_image_type);
m_interface.m_dirty_geom_flag = true;
}
void DetInfoCtrlObj::_addInterface(HwInterface* i)
{
DEB_MEMBER_FUNCT();
_MaxImageSizeCallback *cbk = new _MaxImageSizeCallback(*this);
HwDetInfoCtrlObj* local_det_info;
if(!i->getHwCtrlObj(local_det_info))
THROW_HW_ERROR(Error) << "Cannot get hardware det info";
local_det_info->registerMaxImageSizeCallback(*cbk);
m_cbk.push_back(cbk);
}
//###########################################################################
// 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 <http://www.gnu.org/licenses/>.
//###########################################################################
#include "MetaInterface.h"
#include "MetaDetInfoCtrlObj.h"
#include "MetaSyncCtrlObj.h"
#include "lima/HwReconstructionCtrlObj.h"
#include "processlib/PoolThreadMgr.h"
#include "processlib/TaskMgr.h"
#include "processlib/LinkTask.h"
#include "lima/CtBuffer.h"
using namespace lima;
using namespace lima::Meta;
#define FOR_ALL(fct) \
for(Interface::TileCnt::iterator i = m_tiles.begin(); \
i != m_tiles.end();++i) \
{ \
i->second->fct; \
}
class Interface::_BufferFrameCBK : public HwFrameCallback
{
DEB_CLASS_NAMESPC(DebModCamera,"_BufferFrameCBK","Meta");
public:
class cbk : public TaskEventCallback
{
public:
cbk(Interface::_BufferFrameCBK& i) : m_cnt(i) {}
virtual void finished(Data& aData);
private:
Interface::_BufferFrameCBK& m_cnt;
};
friend class cbk;
_BufferFrameCBK(Interface& i,
int row,int column,HwInterface* hwInterface) :
m_interface(i),
m_row(row),
m_column(column),
m_hwinterface(hwInterface)
{
m_reconstruction_cbk = new cbk(*this);
}
~_BufferFrameCBK()
{
delete m_reconstruction_cbk;
}
protected:
bool newFrameReady(const HwFrameInfoType& frame_info)
{
Data aFrameData;
CtBuffer::transformHwFrameInfoToData(aFrameData,frame_info);
HwReconstructionCtrlObj* reconstruction;
m_hwinterface->getHwCtrlObj(reconstruction);
if(reconstruction)
{
LinkTask* rTaskPt = reconstruction->getReconstructionTask();
if(rTaskPt)
{
TaskMgr *mgr = new TaskMgr();
mgr->setInputData(aFrameData);
rTaskPt->setEventCallback(m_reconstruction_cbk);
mgr->setLinkTask(0,rTaskPt);
PoolThreadMgr::get().addProcess(mgr);
return true;
}
}
return m_interface._newFrameReady(m_row,m_column,aFrameData);
}
void newFrameReconstructed(Data& data)
{
m_interface._newFrameReady(m_row,m_column,data);
}
private:
Interface& m_interface;
int m_row;
int m_column;
HwInterface* m_hwinterface;
cbk* m_reconstruction_cbk;
};
void Interface::_BufferFrameCBK::cbk::finished(Data& data)
{
m_cnt.newFrameReconstructed(data);
}
Interface::Interface(Interface::Geometry geom) :
m_geometry(geom),
m_dirty_geom_flag(true)
{
DEB_CONSTRUCTOR();
m_det_info = new DetInfoCtrlObj(*this);
m_sync = new SyncCtrlObj(*this);
}
Interface::~Interface()
{
delete m_det_info;
delete m_sync;
for(BufferFrameCBKs::iterator i = m_buffer_cbks.begin();
i != m_buffer_cbks.end();++i)
delete *i;
}
void Interface::addInterface(int row,int column,HwInterface* i)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR3(row,column,i);
m_det_info->_addInterface(i);
HwBufferCtrlObj* hw_buffer;
if(!i->getHwCtrlObj(hw_buffer))
THROW_HW_ERROR(Error) << "Cannot get hardware buffer object";
_BufferFrameCBK *cbk = new _BufferFrameCBK(*this,row,column,i);
m_buffer_cbks.push_back(cbk);
hw_buffer->registerFrameCallback(*cbk);
m_tiles[ColumnRow(column,row)] = i;
m_dirty_geom_flag = true;
}
void Interface::getCapList(CapList& cap_list) const
{
cap_list.push_back(HwCap(m_det_info));
cap_list.push_back(HwCap(m_sync));
cap_list.push_back(HwCap(const_cast<SoftBufferCtrlObj*>(&m_buffer)));
}
void Interface::reset(ResetLevel reset_level)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(reset_level);
FOR_ALL(reset(reset_level));
}
void Interface::prepareAcq()
{
DEB_MEMBER_FUNCT();
m_continue_acq = true;
// preparing buffer
int nb_frames;
m_sync->getNbHwFrames(nb_frames);
if(nb_frames > 8 || !nb_frames) nb_frames = 8;
for(Interface::TileCnt::iterator i = m_tiles.begin();
i != m_tiles.end();++i)
{
HwBufferCtrlObj* hw_buffer;
if(!i->second->getHwCtrlObj(hw_buffer))
THROW_HW_ERROR(Error) << "Cannot get hardware buffer object";
HwDetInfoCtrlObj* hw_det;
if(!i->second->getHwCtrlObj(hw_det))
THROW_HW_ERROR(Error) << "Cannot get hardware detector info";
Size max_size;
hw_det->getMaxImageSize(max_size);
ImageType img_type;
hw_det->getCurrImageType(img_type);
FrameDim fdim(max_size,img_type);
hw_buffer->setFrameDim(fdim);
hw_buffer->setNbConcatFrames(1);
int max_nbuffers;
hw_buffer->getMaxNbBuffers(max_nbuffers);
int nb_buffer = nb_frames > max_nbuffers ? max_nbuffers : nb_frames;
hw_buffer->setNbBuffers(nb_buffer);
}
FOR_ALL(prepareAcq());
if(m_dirty_geom_flag)
{
m_dirty_geom_flag = false;
m_tiles_offset.clear();
Size det_image_size;
m_det_info->getDetectorImageSize(det_image_size);
m_det_info->getCurrImageType(m_curr_type);
int depth = FrameDim::getImageTypeDepth(m_curr_type);
m_width_step = det_image_size.getWidth() * depth;
Interface::TileCnt::iterator i = m_tiles.begin();
HwDetInfoCtrlObj* local_det_info;
if(i == m_tiles.end())
THROW_HW_ERROR(Error) << "Meta doesn't have any sub detector";
if(!i->second->getHwCtrlObj(local_det_info))
THROW_HW_ERROR(Error) << "Cannot get hardware det info";
Size local_max_image_size;
int prev_row = i->first.second;
local_det_info->getMaxImageSize(local_max_image_size);
int row_width = local_max_image_size.getWidth();
int row_height = local_max_image_size.getHeight();
int offset = 0;
m_tiles_offset[ColumnRow(i->first.first,i->first.second)] = offset;
for(++i;i != m_tiles.end();++i)
{
if(!i->second->getHwCtrlObj(local_det_info))
THROW_HW_ERROR(Error) << "Cannot get hardware det info";
local_det_info->getMaxImageSize(local_max_image_size);
if(prev_row == i->first.second) // new column, same row
{
m_tiles_offset[ColumnRow(i->first.first,
i->first.second)] = offset + row_width * depth;
row_height = std::max(row_height,
local_max_image_size.getHeight());
row_width += local_max_image_size.getWidth();
}
else // new row
{
prev_row = i->first.second;
offset += row_width * row_height * depth;
m_tiles_offset[ColumnRow(i->first.first,i->first.second)] = offset;
row_height = local_max_image_size.getHeight();
row_width = local_max_image_size.getWidth();
}
}
}
}
void Interface::startAcq()
{
DEB_MEMBER_FUNCT();
m_buffer.getBuffer().setStartTimestamp(Timestamp::now());
FOR_ALL(startAcq());
}
void Interface::stopAcq()
{
DEB_MEMBER_FUNCT();
FOR_ALL(stopAcq());
}
void Interface::getStatus(StatusType& status)
{
DEB_MEMBER_FUNCT();
Interface::TileCnt::iterator i = m_tiles.begin();
i->second->getStatus(status);
for(++i;i != m_tiles.end();++i)
{
StatusType local_status;
i->second->getStatus(local_status);
if(local_status.acq == AcqFault)
{
status = local_status;
break;
}
else if(local_status.acq != AcqReady)
status = local_status;
}
DEB_RETURN() << DEB_VAR1(status);
}
int Interface::getNbHwAcquiredFrames()
{
DEB_MEMBER_FUNCT();
Interface::TileCnt::iterator i = m_tiles.begin();
int nb_frames = i->second->getNbHwAcquiredFrames();
for(++i;i != m_tiles.end();++i)
{
int local_nb_frames = i->second->getNbHwAcquiredFrames();
if(local_nb_frames < nb_frames)
nb_frames = local_nb_frames;
}
DEB_RETURN() << DEB_VAR1(nb_frames);
return nb_frames;
}
bool Interface::_newFrameReady(int row,int column,
const Data& frame)
{
int offset = m_tiles_offset[ColumnRow(column,row)];
int frame_width = frame.dimensions[0];
int frame_height = frame.dimensions[1];
int depth = frame.depth();
StdBufferCbMgr& buffer_mgr = m_buffer.getBuffer();
char *ptr = (char*)buffer_mgr.getFrameBufferPtr(frame.frameNumber);
ptr += offset;
if(column == 0 && frame_width * depth == m_width_step)
memcpy(ptr,frame.data(),frame.size());
else
{
int nb_row = frame_height;
int src_width_step = frame_width * depth;
char* srcPt = (char*)frame.data();
for(int row = 0;row < nb_row;++row,srcPt += src_width_step,ptr += m_width_step)
memcpy(ptr,srcPt,src_width_step);
}
AutoMutex aLock(m_lock);
std::pair<PendingFrames::iterator,bool> result=
m_pending_frames.insert(std::pair<int,int>(frame.frameNumber,1));
//if it exist, increment
if(!result.second) ++result.first->second;
if(result.first->second == int(m_tiles.size())) // frame is finished
{
for(PendingFrames::iterator k = m_pending_frames.begin();
m_continue_acq && k != m_pending_frames.end();
m_pending_frames.erase(k++))
{
if(k->second == int(m_tiles.size()))
{
HwFrameInfoType new_frame_info;
new_frame_info.acq_frame_nb = k->first;
if(!buffer_mgr.newFrameReady(new_frame_info))
m_continue_acq = false;
}
else
break;
}
}
return m_continue_acq;
}
//###########################################################################
// 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