Commit 553a2547 authored by Laurent Claustre's avatar Laurent Claustre
Browse files

Merge branch 'eiger2' into 'master'

Improve reliability and support Eiger2

See merge request !7
parents bd88f47e f873b50a
Pipeline #21713 failed with stages
in 3 minutes and 6 seconds
......@@ -86,9 +86,11 @@ add_library(eiger SHARED
src/EigerInterface.cpp
src/EigerDetInfoCtrlObj.cpp
src/EigerSyncCtrlObj.cpp
src/EigerEventCtrlObj.cpp
src/EigerDecompress.cpp
src/EigerSavingCtrlObj.cpp
src/EigerStream.cpp
src/EigerStreamInfo.cpp
sdk/linux/EigerAPI/src/CurlLoop.cpp
sdk/linux/EigerAPI/src/Requests.cpp
${EIGER_INCS}
......@@ -118,6 +120,7 @@ target_link_libraries(eiger PUBLIC
${ZMQ_LIBRARIES}
JsonCpp::JsonCpp
limacore
h5bshuf
)
if(WIN32)
......@@ -142,6 +145,13 @@ endif()
## Installation
if(TARGET jsoncpp_interface)
install(
TARGETS jsoncpp_interface
EXPORT "${TARGETS_EXPORT_NAME}"
)
endif()
install(
TARGETS eiger
EXPORT "${TARGETS_EXPORT_NAME}"
......
#!/bin/bash
cmake -Bbuild -H. -DLIMA_ENABLE_PYTHON=1 -DCAMERA_ENABLE_TESTS=1 -DCMAKE_INSTALL_PREFIX=$PREFIX -DPYTHON_SITE_PACKAGES_DIR=$SP_DIR -DCMAKE_FIND_ROOT_PATH=$PREFIX
cmake --build build --target install
cmake -Bbuild -H. -DLIMA_ENABLE_PYTHON=1 -DCAMERA_ENABLE_TESTS=1 -DCMAKE_INSTALL_PREFIX=$PREFIX -DPYTHON_SITE_PACKAGES_DIR=$SP_DIR -DCMAKE_FIND_ROOT_PATH=$PREFIX \
&& cmake --build build --target install
......@@ -18,9 +18,8 @@ build:
requirements:
host:
- python {{ python }}
- numpy
- sip 4.19.8 # For compatibility with pyqt 5.9.2
- lima-core
- lima-core >1.9.2
- libcurl
- lz4
- zeromq
......
......@@ -39,6 +39,8 @@
#include <ostream>
DEB_GLOBAL_NAMESPC(DebModCamera, "Eiger");
namespace eigerapi
{
class Requests;
......@@ -46,148 +48,213 @@ namespace eigerapi
namespace lima
{
namespace Eiger
{
class SavingCtrlObj;
class Stream;
/*******************************************************************
* \class Camera
* \brief object controlling the Eiger camera via EigerAPI
*******************************************************************/
class LIBEIGER Camera : public HwMaxImageSizeCallbackGen, public EventCallbackGen
{
DEB_CLASS_NAMESPC(DebModCamera, "Camera", "Eiger");
friend class Interface;
friend class SavingCtrlObj;
friend class Stream;
namespace Eiger
{
struct SuccessAck
{
void succeeded() {}
};
public:
class SavingCtrlObj;
class Stream;
class MultiParamRequest;
enum Status { Ready, Initialising, Exposure, Readout, Fault };
enum CompressionType {LZ4,BSLZ4};
/*******************************************************************
* \class Camera
* \brief object controlling the Eiger camera via EigerAPI
*******************************************************************/
class LIBEIGER Camera : public HwMaxImageSizeCallbackGen, public EventCallbackGen
{
DEB_CLASS_NAMESPC(DebModCamera, "Camera", "Eiger");
Camera(const std::string& detector_ip);
~Camera();
public:
enum ApiGeneration { Eiger1, Eiger2 };
enum Status { Initializing, Ready, Armed, Exposure, Fault };
enum CompressionType {NoCompression,LZ4,BSLZ4};
void initialize();
Camera(const std::string& detector_ip);
~Camera();
void startAcq();
void stopAcq();
void prepareAcq();
void initialize();
// -- detector info object
void getImageType(ImageType& type);
void setImageType(ImageType type);
void startAcq();
void stopAcq();
void prepareAcq();
void getDetectorType(std::string& type);
void getDetectorModel(std::string& model);
void getDetectorImageSize(Size& size);
void getDetectorMaxImageSize(Size& size);
// -- detector info object
void getImageType(ImageType& type);
void setImageType(ImageType type);
//-- Synch control object
bool checkTrigMode(TrigMode trig_mode);
void setTrigMode(TrigMode mode);
void getTrigMode(TrigMode& mode);
void getDetectorType(std::string& type);
void getDetectorModel(std::string& model);
void getDetectorImageSize(Size& size);
void getDetectorMaxImageSize(Size& size);
void setExpTime(double exp_time);
void getExpTime(double& exp_time);
//-- Synch control object
bool checkTrigMode(TrigMode trig_mode);
void setTrigMode(TrigMode mode);
void getTrigMode(TrigMode& mode);
void setLatTime(double lat_time);
void getLatTime(double& lat_time);
void setExpTime(double exp_time, bool force = false);
void getExpTime(double& exp_time);
void getExposureTimeRange(double& min_expo, double& max_expo) const;
void getLatTimeRange(double& min_lat, double& max_lat) const;
void setLatTime(double lat_time);
void getLatTime(double& lat_time);
void setNbFrames(int nb_frames);
void getNbFrames(int& nb_frames);
void getNbHwAcquiredFrames(int &nb_acq_frames);
void getExposureTimeRange(double& min_expo, double& max_expo);
void getLatTimeRange(double& min_lat, double& max_lat);
bool isBinningAvailable();
void setNbFrames(int nb_frames);
void getNbFrames(int& nb_frames);
void getNbHwAcquiredFrames(int &nb_acq_frames);
void getPixelSize(double& sizex, double& sizey);
bool isBinningAvailable();
Camera::Status getStatus();
std::string getCamStatus();
// void reset();
void getPixelSize(double& sizex, double& sizey);
// -- Eiger specific
void getTemperature(double&);
void getHumidity(double&);
void setCountrateCorrection(bool);
void getCountrateCorrection(bool&);
void setFlatfieldCorrection(bool);
void getFlatfieldCorrection(bool&);
void setAutoSummation(bool);
void getAutoSummation(bool&);
void setEfficiencyCorrection(bool);
void getEfficiencyCorrection(bool& value);
void setPixelMask(bool);
void getPixelMask(bool&);
void setThresholdEnergy(double);
void getThresholdEnergy(double&);
void setVirtualPixelCorrection(bool);
void getVirtualPixelCorrection(bool&);
void setPhotonEnergy(double);
void getPhotonEnergy(double&);
void setWavelength(double);
void getWavelength(double&);
void setBeamCenterX(double);
void getBeamCenterX(double&);
void setBeamCenterY(double);
void getBeamCenterY(double&);
void setDetectorDistance(double);
void getDetectorDistance(double&);
void getDataCollectionDate(std::string&);
void getSoftwareVersion(std::string&);
void getCompression(bool&);
void setCompression(bool);
void getCompressionType(CompressionType&) const;
void setCompressionType(CompressionType);
void getSerieId(int&);
void deleteMemoryFiles();
void disarm();
const std::string& getDetectorIp() const;
private:
enum InternalStatus {IDLE,RUNNING,ERROR};
class AcqCallback;
friend class AcqCallback;
class InitCallback;
friend class InitCallback;
void initialiseController(); /// Used during plug-in initialization
void _acquisition_finished(bool);
//-----------------------------------------------------------------------------
//- lima stuff
int m_nb_frames;
int m_image_number;
double m_latency_time;
TrigMode m_trig_mode;
//- camera stuff
std::string m_detector_model;
std::string m_detector_type;
unsigned int m_maxImageWidth, m_maxImageHeight;
ImageType m_detectorImageType;
InternalStatus m_initilize_state;
InternalStatus m_trigger_state;
int m_serie_id;
//- EigerAPI stuff
eigerapi::Requests* m_requests;
Camera::Status getStatus();
std::string getCamStatus();
//void reset();
// -- Eiger specific
void getApiGeneration(ApiGeneration&);
void getTemperature(double&);
void getHumidity(double&);
double m_temperature;
double m_humidity;
double m_exp_time;
double m_readout_time;
double m_x_pixelsize, m_y_pixelsize;
Cond m_cond;
std::string m_detector_ip;
double m_min_frame_time;
};
} // namespace Eiger
void setCountrateCorrection(bool);
void getCountrateCorrection(bool&);
void setFlatfieldCorrection(bool);
void getFlatfieldCorrection(bool&);
void setAutoSummation(bool);
void getAutoSummation(bool&);
void setEfficiencyCorrection(bool);
void getEfficiencyCorrection(bool& value);
void setPixelMask(bool);
void getPixelMask(bool&);
void setThresholdEnergy(double);
void getThresholdEnergy(double&);
void setVirtualPixelCorrection(bool);
void getVirtualPixelCorrection(bool&);
void setPhotonEnergy(double);
void getPhotonEnergy(double&);
void setWavelength(double);
void getWavelength(double&);
void setBeamCenterX(double);
void getBeamCenterX(double&);
void setBeamCenterY(double);
void getBeamCenterY(double&);
void setDetectorDistance(double);
void getDetectorDistance(double&);
void getDataCollectionDate(std::string&);
void getSoftwareVersion(std::string&);
void getCompression(bool&);
void setCompression(bool);
void getCompressionType(CompressionType&);
void setCompressionType(CompressionType);
void getSerieId(int&);
void deleteMemoryFiles();
void disarm();
const std::string& getDetectorIp() const;
private:
friend class Interface;
friend class SavingCtrlObj;
friend class Stream;
friend class MultiParamRequest;
friend class CameraRequest;
enum InternalStatus {IDLE,RUNNING,ERROR};
class TriggerCallback;
friend class TriggerCallback;
class InitCallback;
friend class InitCallback;
Camera::Status _getStatus();
void _synchronize(); /// Used during plug-in initialization
void _trigger_finished(bool);
void _initialization_finished(bool ok);
void _updateImageSize();
void getNbTriggeredFrames(int& nb_trig_frames);
void newFrameAcquired();
bool allFramesAcquired();
template <typename T>
struct Cache
{
struct ChangeInfo : public SuccessAck
{
ChangeInfo(Cache& c, T v) : cache(c), new_val(v)
{}
operator bool()
{ return new_val != cache.val; }
void succeeded()
{ cache.val = new_val; }
Cache& cache;
T new_val;
};
T val;
Cache() = default;
Cache(T v) : val(v) {}
operator T&() { return val; }
T& value() { return val; }
Cache& operator =(T new_val)
{ val = new_val; return *this; }
ChangeInfo change(T new_val)
{ return {*this, new_val}; }
};
//-----------------------------------------------------------------------------
//- lima stuff
int m_nb_frames;
Cache<unsigned int> m_nb_images;
Cache<unsigned int> m_nb_triggers;
int m_frames_triggered;
int m_frames_acquired;
double m_latency_time;
TrigMode m_trig_mode;
Cache<std::string> m_trig_mode_name;
//- camera stuff
ApiGeneration m_api;
std::string m_detector_model;
std::string m_detector_type;
unsigned int m_maxImageWidth, m_maxImageHeight;
ImageType m_detectorImageType;
InternalStatus m_initialize_state;
InternalStatus m_trigger_state;
bool m_armed;
int m_serie_id;
//- EigerAPI stuff
eigerapi::Requests* m_requests;
double m_temperature;
double m_humidity;
Cache<double> m_exp_time;
Cache<double> m_frame_time;
double m_readout_time;
double m_x_pixelsize, m_y_pixelsize;
Cond m_cond;
std::string m_detector_ip;
double m_min_frame_time;
CompressionType m_compression_type;
};
} // namespace Eiger
} // namespace lima
......
//###########################################################################
// 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/>.
//###########################################################################
#ifndef EIGEREVENTCTRLOBJ_H
#define EIGEREVENTCTRLOBJ_H
#include "lima/HwEventCtrlObj.h"
#include "EigerCamera.h"
namespace lima
{
namespace Eiger
{
/*******************************************************************
* \class EventCtrlObj
* \brief Control object providing Eiger event interface
*******************************************************************/
class /*LIBEIGER*/ EventCtrlObj : public HwEventCtrlObj
{
DEB_CLASS_NAMESPC(DebModCamera, "EventCtrlObj", "Eiger");
public:
EventCtrlObj(Camera& cam);
virtual ~EventCtrlObj();
private:
class EventCallback : public lima::EventCallback {
public:
EventCallback(EventCtrlObj& ctrl_obj)
: m_ctrl_obj(ctrl_obj) {}
virtual void processEvent(Event *event)
{ m_ctrl_obj.reportEvent(event); }
private:
EventCtrlObj& m_ctrl_obj;
};
Camera& m_cam;
std::unique_ptr<EventCallback> m_cbk;
};
} // namespace Eiger
} // namespace lima
#endif // EIGEREVENTCTRLOBJ
......@@ -36,9 +36,13 @@ namespace lima
class DetInfoCtrlObj;
class SyncCtrlObj;
class SavingCtrlObj;
class EventCtrlObj;
class Camera;
class Stream;
class StreamInfo;
class StreamStatistics;
class Decompress;
/*******************************************************************
* \class Interface
* \brief Eiger hardware interface
......@@ -63,12 +67,17 @@ namespace lima
//! get the camera object to access it directly from client
Camera& getCamera() { return m_cam;}
void getLastStreamInfo(StreamInfo& info);
void latchStreamStatistics(StreamStatistics& stat,
bool reset=false);
private:
Camera& m_cam;
CapList m_cap_list;
DetInfoCtrlObj* m_det_info;
SyncCtrlObj* m_sync;
SavingCtrlObj* m_saving;
EventCtrlObj* m_event;
Stream* m_stream;
Decompress* m_decompress;
};
......
......@@ -51,9 +51,11 @@ namespace lima
class _EndDownloadCallback;
friend class _EndDownloadCallback;
virtual void _prepare();
virtual void _start();
virtual void _setActive(bool);
virtual void _prepare(int =0) override;
virtual void _start(int =0) override;
virtual void _setActive(bool, int =0) override;
void _download_finished(std::string filename, bool ok, std::string error);
Camera& m_cam;
int m_serie_id;
......
//###########################################################################
// This file is part of LImA, a Library for Image Acquisition
//
// Copyright (C) : 2009-2015
// 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 EIGERSTATISTICS_H
#define EIGERSTATISTICS_H
#include <type_traits>
#include <cmath>
namespace lima
{
namespace Eiger
{
template <typename T,
typename A=typename std::conditional<std::is_integral<T>::value,
long long, double>::type>
struct Statistics
{
int n;
A sx;
A sx2;
T xmin;
T xmax;
Statistics()
{ reset(); }
void reset()
{ sx = sx2 = xmin = xmax = n = 0; }
void add(T x)
{
sx += x;
sx2 += x * x;
++n;
if (x < xmin)
xmin = x;
if (x > xmax)
xmax = x;
}
operator bool() const
{ return n; }
double ave() const
{ return n ? (double(sx) / n) : 0; }
double std() const
{
if (!n)
return 0;
double xm = ave();
return std::sqrt(double(sx2) / n - xm * xm);
}
};
struct StreamStatistics
{
Statistics<int> stat_size;
Statistics<double> stat_time;
void reset()
{
stat_size.reset();
stat_time.reset();
}
void add(int size, double elapsed)
{
stat_size.add(size);
stat_time.add(elapsed);
}
operator bool() const
{ return stat_size && stat_time; }
int n() const
{ return std::min(stat_size.n, stat_time.n); }
double ave_size() const
{ return stat_size.ave(); }
double ave_time() const
{ return stat_time.ave(); }
double ave_speed() const
{ return *this ? (ave_size() / ave_time()) : 0; }