Commit 8f5015f1 authored by esrf-bliss's avatar esrf-bliss

Merge pull request #1 from serge-cohen/master

first released version of andor sdk3 plugin (andor neo + hydra ?)
Not yet tested at ESRF
parents f3608545 63c308e5
*~
*bck
*.swp
*target*
build/
.DS_Store
.AppleDouble
*.o
andor3_pluggin.xcodeproj/project.xcworkspace/xcuserdata/serge.xcuserdatad/WorkspaceSettings.xcsettings
andor3_pluggin.xcodeproj/xcuserdata/
andor3_plugin.xcodeproj/project.xcworkspace/xcuserdata/
andor3_plugin.xcodeproj/xcuserdata/
andor3_plugin.xcodeproj/project.xcworkspace/xcshareddata/
To find out what should go in this file, see "Information For
Maintainers of GNU Software" (maintain.texi), the section called
"Recording Changes".
Serge Cohen:
is the author of this plugin.
This diff is collapsed.
src-dirs = src
test-dirs =
include ../../global.inc
andor3 --- history of user-visible changes.
Copyright (C) 2013 IPANEMA USR3461, CNRS/MCC.
See the end for copying conditions.
Please send andor3 bug reports to serge.cohen@synchrotron-soleil.fr.
Changes in 1.0.0 :
This corresponds to restarting of the implementation of the andor3 plugin (for Neo camera).
The development of this plugin is based both on camera/tutorial and camera/basler.
Copyright information:
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2006 Free Software Foundation, Inc.
Permission is granted to anyone to make or distribute verbatim copies
of this document as received, in any medium, provided that the
copyright notice and this permission notice are preserved,
thus giving the recipient permission to redistribute in turn.
Permission is granted to distribute modified versions
of this document, or of portions of it,
under the above conditions, provided also that they
carry prominent notices stating who last changed them.
Local variables:
mode: outline
paragraph-separate: "[ ]*$"
end:
File currently empty... Should be populated latter to explain the installation of the andor3 plugin.
1.0.0
\ No newline at end of file
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:andor3.xcodeproj">
</FileRef>
</Workspace>
W H t l_12 l_16 c_x c_x
2592 2160 1 1 1 1297 1297
2544 2160 1 17 25 1289 1297
2064 2048 57 257 265 1289 1297
1776 1760 201 401 409 1289 1297
1920 1080 537 337 337 1297 1297
1392 1040 561 593 601 1289 1297
528 512 825 1025 1033 1289 1297
240 256 953 1169 1177 1289 1297
144 128 1017 1217 1225 1289 1297
2592 304 929 1 1 1297 1297
Andor3
-------
.. image:: neo_header.jpg
Intoduction
```````````
CAUTION : This documentation is currently very partial and needs some extra work to be completed !!!
Andor Technology manufactuer offers a large catalogue of scientific cameras. Covered scientific applications are low ligth imaging, spectroscopy, microscopy, time-resolved and high energy detection.
Andor is providing a Software Development Tool (SDK) for both Windows and Linux, supporting different interface buses such as USB, CameraLink and also some specific acquisition PCI board. Unfortunately there was a significant API change between the v2 line of SDK and the brand new v3 of the SDK, and recent cameras are only supported by the v3 SDK, whilst this new SDK is not (yet ?) supporting previously built cameras.
The Lima module as been tested only with this cameras models:
- Neo (3-tap Camera Link, Linux OS)
Module configuration
````````````````````
Previously to this you have to install the Andor SDK the default path (/usr/local).
For our test we used the SDK for Linux version **V3.3.30004.0** and ran the install script "install_andor"
for which option 2 (64b linux) was selected, the default installation is made under /usr/local/ with:
- /usr/local/include, header files
- /usr/local/lib, library files
- /usr/local/andor/bitflow, files for the frame-grabber driver (including camera firmware/frame grabber configuration)
The Linux SDK 3.3 has shared libraries which has been compiled on recent linux kernel, check first you have the right kernel and
libc available by compiling one of the example program available under examples/console.
Andor3 python module needs at least the lima core module.
The best before using this Lima pluggin with a Andor Neo camera is to test the proper setting of the frame-grabber driver and system configuration by
using the two test programs included in the SDK. Those are typically found in /usr/local/andor/examples/ and are listdevices and image.
The minimum configuration file is *config.inc* :
.. code-block:: sh
COMPILE_CORE=1
COMPILE_SIMULATOR=0
COMPILE_SPS_IMAGE=1
COMPILE_ESPIA=0
COMPILE_FRELON=0
COMPILE_MAXIPIX=0
COMPILE_PILATUS=0
COMPILE_BASLER=0
COMPILE_ANDOR=0
COMPILE_ANDOR3=1
COMPILE_CBF_SAVING=0
export COMPILE_CORE COMPILE_SPS_IMAGE COMPILE_SIMULATOR \
COMPILE_ESPIA COMPILE_FRELON COMPILE_MAXIPIX COMPILE_PILATUS \
COMPILE_BASLER COMPILE_ANDOR COMPILE_ANDOR3 COMPILE_CBF_SAVING
See :ref:`Compilation`
Installation
`````````````
- After installing andor3 modules :ref:`installation`
- And probably Tango server :ref:`tango_installation`
Configuration
`````````````
- Still to be written.
\ No newline at end of file
### This [i]python script should be run after making sure that the LD_LIBRARY_PATH contains the
### INSTALL_DIR/Lima/lib (or any other directory containing the *.so from lima).
### Here this gives (since the configuration is well done and no normal library requires the use of the fallback LD_LIBRARY_PATH setting) :
### export LD_LIBRARY_PATH=/usr/local/Lima/lib
### Note also : there is a bug with Sps : if it is not compiled in (COMPILE_SPS=0 in config.inc) then it is still required by limacore !!!
LD_LIBRARY_PATH=/usr/local/Lima/Lima/lib ipython
import sys,time,os
## sys.path.insert(1, "/usr/local/Lima")
sys.path.insert(1, os.environ['LD_LIBRARY_PATH']+"/../..")
from Lima import Core,Andor3
import time
cam = Andor3.Camera("/usr/local/andor/bitflow", 0)
cam_int = Andor3.Interface(cam)
cam_ctr = Core.CtControl(cam_int)
# cam.setNbFrames(3)
## Taking care of the saving :
cam_sav = cam_ctr.saving()
cam_sav.setDirectory("/mnt/local-spool")
cam_sav.setPrefix("testing_A_")
cam_sav.setSavingMode(Core.CtSaving.AutoFrame)
## cam_sav.setSavingMode(Core.CtSaving.Manual)
## Nexus :
cam_sav.setFormat(Core.CtSaving.NXS)
cam_sav.setSuffix(".nxs")
## TIFF :
cam_sav.setFormat(Core.CtSaving.TIFFFormat)
cam_sav.setSuffix(".tiff")
cam_sav.getParameters()
## Proper way of doing that is :
cam_ctr.acquisition().setAcqExpoTime(.001)
cam_ctr.acquisition().setLatencyTime(.001)
cam_ctr.acquisition().setAcqNbFrames(10)
cam_ctr.image().setMode(Core.CtImage.HardOnly)
##cam_ctr.image().setMode(Core.CtImage.HardAndSoft)
cam_ctr.image().setRoi(Core.Roi(409, 201, 1776, 1760)) ### left, top, width, height
## Core.DebParams.setTypeFlags( Core.DebParams.getTypeFlags() | Core.DebTypeTrace )
Core.DebParams.setTypeFlagsNameList(['Fatal', 'Error', 'Warning', 'Trace', 'Funct'])
cam_ctr.video().startLive()
time.sleep(3)
cam_ctr.video().stopLive()
cam_ctr.prepareAcq()
cam_ctr.startAcq()
time.sleep(1)
cam_ctr.stopAcq()
im1 = cam_ctr.ReadImage()
im2 = cam_ctr.ReadImage()
im3 = cam_ctr.ReadImage()
import time
import numpy
import numpy.fft
import matplotlib
matplotlib.use('TkAgg') # do this before importing pylab
import matplotlib.pyplot as plt
def get_image():
cam.setNbFrames(1)
cam_ctr.prepareAcq()
cam_ctr.startAcq()
while cam_ctr.getStatus().AcquisitionStatus: pass
return cam_ctr.ReadImage().buffer
def animate():
tstart = time.time() # for profiling
data=get_image()
im=plt.imshow(data)
while 1:
data=get_image()
im.set_data(data)
fig.canvas.draw() # redraw the canvas
print 'FPS:' , 200/(time.time()-tstart)
fig = plt.figure()
ax = fig.add_subplot(111)
win = fig.canvas.manager.window
fig.canvas.manager.window.after(100, animate)
plt.show()
if __name__ == "__main__":
animate()
## Using the debugging :
## % python
## Python 2.6.4 (r264:75706, Dec 3 2009, 02:54:59)
## [GCC 4.1.2 20070626 (Red Hat 4.1.2-14)] on linux2
## Type "help", "copyright", "credits" or "license" for more information.
## >>> from Lima import Core
## >>> '%x' % Core.DebParams.getTypeFlags()
## '87'
## >>> Core.DebParams.getTypeFlagsNameList()
## ['Fatal', 'Error', 'Warning', 'Always']
## >>> '%x' % Core.DebParams.AllFlags
## 'ffffffff'
## >>> Core.DebParams.setTypeFlags(Core.DebParams.AllFlags)
## >>> Core.DebParams.getTypeFlagsNameList()
## ['Fatal', 'Error', 'Warning', 'Trace', 'Funct', 'Param', 'Return', 'Always']
## >>> Core.DebParams.setTypeFlagsNameList(['Fatal', 'Error', 'Warning',
## 'Trace', 'Funct'])
## >>> Core.DebParams.getTypeFlagsNameList()['Fatal', 'Error', 'Warning',
## 'Trace', 'Funct']
## >>> '%x' % Core.DebParams.getTypeFlags()
## '1f'
* Debug de andor3 :
** Question prepareAcq/startAcq :
Peut-on faire plusieurs startAcq à la suite d\'un seul prepareAcq ?
** Blocage à la 3ème startAcq.
** Vitesse de lecture des frame très lente !!! Vérifier le «FrameRate» au lancement de la caméra
*** Problème sur le réglage de Latency… accepter de la mettre à zero, pour au niveau de startAcq mettre la valeur minimale.
*** Problème de la lecture des frame -> c\'est très lent, même avec un court temps de pause.
** Roi : le checkRoi cause un bug lors de l\'utilisation de HardSoft roi dans CtImage.
#!/usr/bin/python
### This script should be run after :
### export LD_LIBRARY_PATH="/usr/local/Lima/Lima/lib"
### The aim is to test a version installed by
### INSTALL_DIR=/usr/local/Lima make install
import os,sys,time
## os.environ['LD_LIBRARY_PATH']="/usr/local/Lima/Lima/lib"
print("* The general setup :")
print("\n** The environement of the pocess is now : ")
print(os.environ)
print("\n** Now, importing Lima (Core and Andor3 :")
sys.path.insert(1, os.environ['LD_LIBRARY_PATH'] + "/../..")
print("\twith sys.path = " + ":".join(sys.path))
from Lima import Core,Andor3
print("\n** Constructing the camera and the other related object :")
cam = Andor3.Camera("/usr/local/andor/bitflow", 0)
cam_int = Andor3.Interface(cam)
cam_ctr = Core.CtControl(cam_int)
print("\n** Removing all files that could interfer with acquisition :")
os.system("rm -fv /mnt/local-spool/testing_A_*.tiff /mnt/local-spool/testing_A_*.nxs")
print("\n** Taking care of the saving format : 1st serie is wihtOUT saving")
cam_sav = cam_ctr.saving()
cam_sav.setDirectory("/mnt/local-spool")
cam_sav.setPrefix("testing_A_")
cam_sav.setSavingMode(Core.CtSaving.Manual)
print(cam_sav.getParameters())
print("** Testing the ROI : 100, 100, 2360, 1960 (in HardOnly mode)")
cam_ctr.image().setMode(Core.CtImage.HardOnly)
cam_ctr.image().setRoi(Core.Roi(100, 100, 2360, 1960)) ### left, top, width, height
the_roi = cam_ctr.image().getRoi()
print("\tThe retrieved roi is (%d, %d, %d, %d)" % (the_roi.getTopLeft().x, the_roi.getTopLeft().y, the_roi.getSize().getWidth(), the_roi.getSize().getHeight()))
print("\n**Testing the acquisition exposure and latency :")
## ##### Faster frame-rates, lower latency :
## cam.setElectronicShutterMode(Andor3.Camera.Rolling)
## cam.setAdcRate(cam.MHz280)
## cam.getLatTimeRange() ## 0.0103
## ##### Slower frame-rate, higher latency :
## cam.setElectronicShutterMode(Andor3.Camera.Global)
## cam.setAdcRate(cam.MHz100)
## cam.getLatTimeRange() ## 0.0286
cam_acq= cam_ctr.acquisition()
print("Setting the trigger mode to internal :")
cam_acq.setTriggerMode(Core.IntTrig)
print("setting the exposition time to 0.001 ...")
cam_acq.setAcqExpoTime(.001)
print("*** Getting in slow acquisition mode :")
print("setting the true camera speed to Global shutter and 100MHz")
cam.setElectronicShutterMode(Andor3.Camera.Global)
cam.setAdcRate(cam.MHz100)
print("the range of latency time for the hardware is now %.3f to %.3f s" % cam.getLatTimeRange())
print("setting the latency time to 0.015 (below the limit of the hardware")
cam_acq.setLatencyTime(.015)
print("retrieving the values : ")
print("\texpo time = %f" % cam_acq.getAcqExpoTime())
print("\tlat time = %f" % cam_acq.getLatencyTime())
if ( 0.015 != cam_acq.getLatencyTime() ) :
print("\t The retrieved latency is different from the set one (expected)")
if ( cam.getLatTimeRange()[0] != cam_acq.getLatencyTime() ) :
print("\t The retrieved latency time is DIFFERENT from the min latency of the hardware, %.3f vs. %.3f respectively" % (cam_acq.getLatencyTime(), cam.getLatTimeRange()[0]))
print("\nTesting the ROI : 100, 100, 2360, 1960")
cam_ctr.image().setRoi(Core.Roi(100, 100, 2360, 1960)) ### left, top, width, height
the_roi = cam_ctr.image().getRoi()
print("\tThe retrieved roi is (%d, %d, %d, %d)" % (the_roi.getTopLeft().x, the_roi.getTopLeft().y, the_roi.getSize().getWidth(), the_roi.getSize().getHeight()))
print("*** Getting in fast acquisition mode :")
print("setting the true camera speed to Global shutter and 280MHz")
cam.setElectronicShutterMode(Andor3.Camera.Global)
cam.setAdcRate(cam.MHz280)
print("the range of latency time for the hardware is now %.3f to %.3f s" % cam.getLatTimeRange())
print("setting the latency time to 0.015 (below the limit of the hardware")
cam_acq.setLatencyTime(.015)
print("retrieving the values : ")
print("\texpo time = %f" % cam_acq.getAcqExpoTime())
print("\tlat time = %f" % cam_acq.getLatencyTime())
if ( 0.015 != cam_acq.getLatencyTime() ) :
print("\t The retrieved latency is DIFFERENT from the set one (unexpected in fast mode)")
if ( cam.getLatTimeRange()[0] != cam_acq.getLatencyTime() ) :
print("\t The retrieved latency time is DIFFERENT from the min latency of the hardware, %.3f vs. %.3f respectively" % (cam_acq.getLatencyTime(), cam.getLatTimeRange()[0]))
print("* Testing some frame-number based acquisitions")
# print(" Setting the debug to tracing on camera:")
# Core.DebParams.setTypeFlagsNameList(['Fatal', 'Error', 'Warning', 'Trace'])
# Core.DebParams.setModuleFlagsNameList(['Camera'])
print(" Acquiring 3 images, to flush the CtAcquisition and the frame-rate be updated accordingly")
cam_ctr.acquisition().setAcqNbFrames(3)
cam_ctr.prepareAcq()
cam_ctr.startAcq()
time.sleep(5)
print(" Acquiring 50 image using the current settings.")
cam_ctr.acquisition().setAcqNbFrames(50)
print(" Setting the output sink :")
cam_sav = cam_ctr.saving()
cam_sav.setDirectory("/mnt/local-spool")
cam_sav.setPrefix("testing_A_")
print(" The saving parameters are :")
print(cam_sav.getParameters())
print(" Launching acquisition of %d frames whith exposure time of %.3fs and latency time %.3fs." % (cam_ctr.acquisition().getAcqNbFrames(), cam_acq.getAcqExpoTime(), cam_acq.getLatencyTime()))
print("** Setting the output to none")
cam_sav.setSavingMode(Core.CtSaving.Manual)
print(" The saving parameters are :")
print(cam_sav.getParameters())
cam_ctr.prepareAcq()
cam_ctr.startAcq()
the_wait=0
while ( Core.AcqReady != cam_ctr.getStatus().AcquisitionStatus ) :
time.sleep(1)
the_wait += 1
print("Acquisition done with sleep of %ds" % (the_wait))
time.sleep(1)
print("And again...")
cam_ctr.prepareAcq()
cam_ctr.startAcq()
the_wait=0
while ( Core.AcqReady != cam_ctr.getStatus().AcquisitionStatus ) :
time.sleep(1)
the_wait += 1
print("Acquisition done with sleep of %ds" % (the_wait))
time.sleep(1)
print("** Setting the output to tiff")
cam_sav.setSavingMode(Core.CtSaving.AutoFrame)
cam_sav.setFormat(Core.CtSaving.TIFFFormat)
cam_sav.setSuffix(".tiff")
print(" The saving parameters are :")
print(cam_sav.getParameters())
cam_ctr.prepareAcq()
cam_ctr.startAcq()
the_wait=0
while ( Core.AcqReady != cam_ctr.getStatus().AcquisitionStatus ) :
time.sleep(1)
the_wait += 1
print("Acquisition done with sleep of %ds"% (the_wait))
time.sleep(1)
print("And again...")
cam_ctr.prepareAcq()
cam_ctr.startAcq()
the_wait=0
while ( Core.AcqReady != cam_ctr.getStatus().AcquisitionStatus ) :
time.sleep(1)
the_wait += 1
print("Acquisition done with sleep of %ds"% (the_wait))
time.sleep(1)
# print("** Setting the output to nexus")
# cam_sav.setSavingMode(Core.CtSaving.AutoFrame)
# cam_sav.setFormat(Core.CtSaving.NXS)
# cam_sav.setSuffix(".nxs")
# print(" The saving parameters are :")
# print(cam_sav.getParameters())
# cam_ctr.prepareAcq()
# cam_ctr.startAcq()
# the_wait=0
# while ( Core.AcqReady != cam_ctr.getStatus().AcquisitionStatus ) :
# time.sleep(1)
# the_wait += 1
# print("Acquisition done with sleep of %ds"% (the_wait))
#
# print("And again...")
# cam_ctr.prepareAcq()
# cam_ctr.startAcq()
# the_wait=0
# while ( Core.AcqReady != cam_ctr.getStatus().AcquisitionStatus ) :
# time.sleep(1)
# the_wait += 1
# print("Acquisition done with sleep of %ds"% (the_wait))
#
print("* Testing some free-running acquisitions, during approx 2s each test :")
print(" Setting the output sink :")
cam_sav = cam_ctr.saving()
cam_sav.setDirectory("/mnt/local-spool")
cam_sav.setPrefix("testing_A_")
print(" The saving parameters are :")
print(cam_sav.getParameters())
print("** Using the null output sink :")
cam_sav.setSavingMode(Core.CtSaving.Manual)
print(" The saving parameters are :")
print(cam_sav.getParameters())
cam_ctr.video().startLive()
time.sleep(2)
cam_ctr.video().stopLive()
print("Acquisition done in free running while the main thread slept 2s")
time.sleep(1)
print("And again...")
cam_ctr.video().startLive()
time.sleep(2)
cam_ctr.video().stopLive()
print("Acquisition done in free running while the main thread slept 2s")
time.sleep(1)
print("** Setting the output to tiff")
cam_sav.setSavingMode(Core.CtSaving.AutoFrame)
cam_sav.setFormat(Core.CtSaving.TIFFFormat)
cam_sav.setSuffix(".tiff")
print(" The saving parameters are :")
print(cam_sav.getParameters())
cam_ctr.video().startLive()
time.sleep(2)
cam_ctr.video().stopLive()
print("Acquisition done in free running while the main thread slept 2s")
time.sleep(1)
print("And again...")
cam_ctr.video().startLive()
time.sleep(2)
cam_ctr.video().stopLive()
print("Acquisition done in free running while the main thread slept 2s")
time.sleep(1)
## print("** Setting the output to nexus")
## cam_sav.setSavingMode(Core.CtSaving.AutoFrame)
## cam_sav.setFormat(Core.CtSaving.NXS)
## cam_sav.setSuffix(".nxs")
## print(" The saving parameters are :")
## print(cam_sav.getParameters())
## cam_ctr.video().startLive()
## time.sleep(2)
## cam_ctr.video().stopLive()
## print("Acquisition done in free running while the main thread slept 2s")
##
print("And again...")
cam_ctr.video().startLive()
time.sleep(2)
cam_ctr.video().stopLive()
print("Acquisition done in free running while the main thread slept 2s")
#ifndef ANDOR3BINCTRLOBJ_H
#define ANDOR3BINCTRLOBJ_H
/* andor3 plugin binning class
* Copyright (C) 2013 IPANEMA USR3461, CNRS/MCC.
* Written by Serge Cohen <serge.cohen@synchrotron-soleil.fr>
*
* This file 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 file 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 file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "HwInterface.h"
#include "Andor3Camera.h"
namespace lima
{
namespace Andor3
{
class Interface;
/*******************************************************************
* \class BinCtrlObj
* \brief Control object providing Andor3 Bin interface
*******************************************************************/
class BinCtrlObj : public HwBinCtrlObj
{
DEB_CLASS_NAMESPC(DebModCamera, "BinCtrlObj", "Andor3");
public:
BinCtrlObj(Camera& cam, Interface *interface);
virtual ~BinCtrlObj();
virtual void getBin(Bin& bin);
virtual void checkBin(Bin& bin);
virtual void setBin(const Bin& bin);
private:
Camera& m_cam;
Interface *m_interface;
};
} // namespace Andor3
} // namespace lima
#endif // ANDOR3BINCTRLOBJ_H
This diff is collapsed.
#ifndef ANDOR3DETINFOCTRLOBJ_H
#define ANDOR3DETINFOCTRLOBJ_H
/* andor3 plugin detector information class
* Copyright (C) 2013 IPANEMA USR3461, CNRS/MCC.
* Written by Serge Cohen <serge.cohen@synchrotron-soleil.fr>
*
* This file 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 file 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 file. If not, see <http://www.gnu.org/licenses/>.
*/
// System headers :
// Camera SDK headers :
// LImA headers :
#include "HwInterface.h"
// Andor3 plugin headers :
#include "Andor3Camera.h"
namespace lima
{
namespace Andor3
{
class Interface;
/*******************************************************************
* \class DetInfoCtrlObj
* \brief Control object providing Andor3 detector info interface
*******************************************************************/