Andor3Camera.h 14.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef ANDOR3CAMERA_H
#define ANDOR3CAMERA_H

/* andor3 plugin camera 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/>.
 */

22
23
24
25
26
27
28
29
30
31
32
33
#if defined (__GNUC__) && (__GNUC__ == 3) && defined (__ELF__)
#   define GENAPI_DECL __attribute__((visibility("default")))
#   define GENAPI_DECL_ABSTRACT __attribute__((visibility("default")))
#endif

// System headers :
#include <stdlib.h>
#include <limits>
#include <ostream>

// Camera SDK headers :
#include <atcore.h>
34
#include <atutility.h>
35
36

// LImA headers :
37
38
#include "lima/HwMaxImageSizeCallback.h"
#include "lima/HwBufferMgr.h"
39
40
41
42
43
44
45
46
47
48
49

// Andor3 plugin headers :

namespace lima
{
  namespace Andor3
  {
    /*******************************************************************
     * \class Camera
     * \brief object controlling the andor3 camera via andor3 SDK driver
     *******************************************************************/
50
    class Camera : public HwMaxImageSizeCallbackGen
51
    {
52
53
      friend class Interface;

54
      DEB_CLASS_NAMESPC(DebModCamera, "Camera", "Andor3");
55

56
57
    public:
      
58
      enum Status { Ready, Exposure, Readout, Latency, Fault };
59
60
61
62
63
      enum A3_TypeInfo { Unknown, Int, Float, Bool, Enum, String };

      //! @TODO : later on should do a map (string to int and vice-versa) from parsed enum info for the next 3 :
      // In the same order/index as "PreAmpGainControl"
      enum A3_Gain { Gain1 = 0, Gain2 = 1, Gain3 = 2, Gain4 = 3, Gain1_Gain3 = 4, Gain1_Gain4 = 5, Gain2_Gain3 = 6, Gain2_Gain4 = 7 };
64
65
      // The "simple" version :
      enum A3_SimpleGain { b11_hi_gain=0, b11_low_gain=1, b16_lh_gain=2, none=31};
66
67
68
69
      // In the same order/index as "ElectronicShutteringMode"
      enum A3_ShutterMode { Rolling = 0, Global = 1 };
      // In the same order/index as "PixelReadoutRate"
      enum A3_ReadOutRate { MHz10 = 0, MHz100 = 1, MHz200 = 2, MHz280 = 3 };
70
      // In the same order/index as 'BitDepth'
71
      enum A3_BitDepth { b11 = 0, b16= 1 };
Serge Cohen's avatar
Serge Cohen committed
72
      // The camera trigger mode (in the enum order) :
73
74
//      enum A3_TriggerMode { Internal = 0, ExternalLevelTransition = 1, ExternalStart = 2, ExternalExposure = 3, Software = 4, Advanced = 5, External = 6 };

Serge Cohen's avatar
Serge Cohen committed
75
      // The binning system of andor3 :
76
      enum A3_Binning { B1x1=0, B2x2=1, B3x3=2, B4x4=3, B8x8=4};
77
78
      // The fan speed
      enum A3_FanSpeed { Off=0, Low=1, On=2};
79
      enum A3_PixelEncoding {Mono12=0, Mono12Packed = 1, Mono16=2, Mono32=3};
80
      
81
82
83
84
85
86
87
88
89
90
91
92
93
94
      struct SdkFrameDim {       
	AT_64 width;
	AT_64 height;
	AT_64 stride;
	double bytes_per_pixel;
	AT_64 size;
	A3_PixelEncoding encoding;
	const AT_WC* input_encoding;
	const AT_WC* output_encoding;
	bool is_encoded;
	bool is_strided;
      };
      
      int getHwBitDepth(int *bit_depth);
95
      
96
      Camera(const std::string& bitflow_path, int camera_number=0);
97
98
      ~Camera();

99
      // Preparing the camera's SDK to acquire frames
100
      void prepareAcq();
101
      // Launches the SDK's acquisition and the m_acq_thread to retrieve frame buffers as they are ready
102
      void startAcq();
103
      // Stops the acquisition, as soon as the m_acq_thread is retrieving frame buffers.
104
105
106
107
108
109
110
111
112
113
114
115
116
117
      void stopAcq();

      // -- detector info object
      void getImageType(ImageType& type);
      void setImageType(ImageType type);
      
      void getDetectorType(std::string& type);
      void getDetectorModel(std::string& model);
      void getDetectorImageSize(Size& size);

      // -- Buffer control object
      HwBufferCtrlObj* getBufferCtrlObj();
      
      //-- Synch control object
118
      bool checkTrigMode(TrigMode mode);
119
120
121
122
123
124
125
126
      void setTrigMode(TrigMode  mode);
      void getTrigMode(TrigMode& mode);
      
      void setExpTime(double  exp_time);
      void getExpTime(double& exp_time);
      
      void getExposureTimeRange(double& min_expo, double& max_expo) const;
      void getLatTimeRange(double& min_lat, double& max_lat) const;
127
            
128
129
130
131
132
133
134
135
136
      void setNbFrames(int  nb_frames);
      void getNbFrames(int& nb_frames);
      void getNbHwAcquiredFrames(int &nb_acq_frames);
      
      void checkRoi(const Roi& set_roi, Roi& hw_roi);
      void setRoi(const Roi& set_roi);
      void getRoi(Roi& hw_roi);
      
      bool isBinningAvailable();
Serge Cohen's avatar
Serge Cohen committed
137
138
139
      void checkBin(Bin& ioBin);
      void setBin(const Bin& iBin);
      void getBin(Bin& oBin);
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
      
      void setShutterMode(ShutterMode mode);
      void getShutterMode(ShutterMode& mode);
      
      void getPixelSize(double& sizex, double& sizey);

      void getStatus(Camera::Status& status);
      
      // --- Acquisition interface
      void reset();
      int getNbHwAcquiredFrames();

      // -- andor3 specific, LIMA don't worry about it !
      void initialiseController();

155
156
      // AdcGain is deprecated, should use SimpleGain (Zyla does not have AdcGain feature).
      void setAdcGain(A3_Gain iGain);					
157
      void getAdcGain(A3_Gain &oGain) const;
158
      void getAdcGainString(std::string &oGainString) const;
159

160
      void setAdcRate(A3_ReadOutRate iRate);  // à exporter (avec le get)
161
      void getAdcRate(A3_ReadOutRate &oRate) const;
162
      void getAdcRateString(std::string &oRateString) const;
163
      void setElectronicShutterMode(A3_ShutterMode iMode);  // à exporter (avec le get)
164
      void getElectronicShutterMode(A3_ShutterMode &oMode) const;
165
      void getElectronicShutterModeString(std::string &oModeString) const;
166
      void setBitDepth(A3_BitDepth iMode);
167
      void getBitDepth(A3_BitDepth &oMode) const;
168
      void getBitDepthString(std::string &oDepthString) const;
169
170
      void getPxEncoding(A3_PixelEncoding &oPxEncoding) const;
      void getPxEncodingString(std::string &oPxEncoding) const;
171
172
      // void setTriggerMode(A3_TriggerMode iMode);
      // void getTriggerMode(A3_TriggerMode &oMode) const;
173
      void getTriggerModeString(std::string &oModeString) const;
174
      void setTemperatureSP(double temp);  // à exporter (avec le get)
175
176
      void getTemperatureSP(double& temp) const;
      void getTemperature(double& temp) const;   // à exporter (read-only)
177
      void setCooler(bool flag);					 // à exporter (avec le get)
178
179
      void getCooler(bool& flag) const;
      void getCoolingStatus(std::string& status) const;  // à exporter (read-only)
Serge Cohen's avatar
Serge Cohen committed
180
      
181
182
183
184
185
186
187
188
189
190
191
192
193
      void setBufferOverflow(bool i_overflow);
      void getBufferOverflow(bool &o_overflow) const;
      void setFanSpeed(A3_FanSpeed iFS);
      void getFanSpeed(A3_FanSpeed &oFS) const;
      void getFanSpeedString(std::string &oFSString) const;
      void setOverlap(bool i_overlap);
      void getOverlap(bool &o_overlap) const;
      void setSimpleGain(A3_SimpleGain i_gain);
      void getSimpleGain(A3_SimpleGain &o_gain) const;
      void getSimpleGainString(std::string &o_gainString) const;
      void setSpuriousNoiseFilter(bool i_filter);
      void getSpuriousNoiseFilter(bool &o_filter) const;
      void setSyncTriggering(bool i_sync);
194
      void getSyncTriggering(bool &o_sync) const;
195
196
      
      // -- some readonly attributes :
197
      void getBytesPerPixel(double &o_value) const;
198
      void getFirmwareVersion(std::string &o_fwv) const;
199
      void setFrameRate(double i_frame_rate);
200
201
      void getFrameRate(double &o_frame_rate) const;
      void getFrameRateRange(double& o_min_lat, double& o_max_lat) const;
202
203
      void getFullRoiControl(bool &o_fullROIcontrol) const;
      void getImageSize(int &o_frame_size) const;
204
205
      void getMaxFrameRateTransfer(double &o_max_transfer_rate) const;
      void getReadoutTime(double &o_time) const;
206
      void getSerialNumber(std::string &o_sn) const;
207
      int getPixelStride() const;
208
209
210
      void getSdkFrameDim(SdkFrameDim &frame_dim,bool last);
      HwBufferCtrlObj* getTempBufferCtrlObj();

211
212
213

    protected:
      virtual void setMaxImageSizeCallbackActive(bool cb_active);
214
215

    private:
216
       
217
218
      // -- some internals :
      // Stopping an acquisition, iForce : without waiting the end of frame buffer retrieval by m_acq_thread
219
      void _stopAcq(bool iImmediate);
220
221
      // Setting the status in a thread safe manner :
      void _setStatus(Camera::Status iStatus, bool iForce);
222
      
223
    private:
224
225
      void initTrigMode();

226
      // -- andor3 Lower level functions
227
228
      int printInfoForProp(const AT_WC * iPropName, A3_TypeInfo iPropType) const;
      bool propImplemented(const AT_WC * iPropName) const;
229
      
230
      static int getIntSystem(const AT_WC* Feature, AT_64* Value);
231
      //      static int bufferOverflowCallback(AT_H i_handle, const AT_WC* i_feature, void* i_info);
232
      
233
234
235
236
      int setInt(const AT_WC* Feature, AT_64 Value);
      int getInt(const AT_WC* Feature, AT_64* Value) const;
      int getIntMax(const AT_WC* Feature, AT_64* MaxValue) const;
      int getIntMin(const AT_WC* Feature, AT_64* MinValue) const;
237
      
238
239
240
241
      int setFloat(const AT_WC* Feature, double Value);
      int getFloat(const AT_WC* Feature, double* Value) const;
      int getFloatMax(const AT_WC* Feature, double* MaxValue) const;
      int getFloatMin(const AT_WC* Feature, double* MinValue) const;
242
      
243
244
      int setBool(const AT_WC* Feature, bool Value);
      int getBool(const AT_WC* Feature, bool* Value) const;
245
      
246
247
248
249
      int setEnumIndex(const AT_WC* Feature, int Value);
      int setEnumString(const AT_WC* Feature, const AT_WC* String);
      int getEnumIndex(const AT_WC* Feature, int* Value) const;
      int getEnumString(const AT_WC* Feature, AT_WC* String, int StringLength) const;
250
      int getEnumCount(AT_H Hndl,const  AT_WC* Feature, int* Count) const;
251
252
253
254
      int isEnumIndexAvailable(const AT_WC* Feature, int Index, bool* Available) const;
      int isEnumIndexImplemented(const AT_WC* Feature, int Index, bool* Implemented) const;
      int getEnumStringByIndex(const AT_WC* Feature, int Index, AT_WC* String, int StringLength) const;
      int getEnumIndexByString(const AT_WC* Feature, AT_WC* String, int *Index) const;
255
      
256
257
      int setString(const AT_WC* Feature, const AT_WC* String);
      int getString(const AT_WC* Feature, AT_WC* String, int StringLength) const;
258
      
259
      int sendCommand(const AT_WC* Feature);
260
261
262

    private:
      class _AcqThread;
263
      class _BufferCtrlObj;
264
265
266
      friend class _AcqThread;

      // -- Members
267
      // LIMA / Acquisition (thread) related :
268
269
      SoftBufferCtrlObj*          m_buffer_ctrl_obj;
      SoftBufferCtrlObj*          m_temp_buffer_ctrl_obj;
270
      // Pure thread and signals :
271
272
273
274
275
      _AcqThread*                 m_acq_thread;		   // The thread retieving frame buffers from the SDK
      Cond                        m_cond;		   // Waiting condition for inter thread signaling
      volatile bool               m_acq_thread_waiting;    // The m_acq_thread is waiting (main uses it to tell it to stop waiting)
      volatile bool               m_acq_thread_running;	   // The m_acq_thread is running (main uses it to accept stopAcq)
      volatile bool	          m_acq_thread_should_quit;// The main thread signals to m_acq_thread that it should quit.
276
277

      // A bit more general :
278
279
280
281
      size_t                      m_nb_frames_to_collect;  // The number of frames to collect in current sequence
      size_t                      m_image_index;	   // The index in the current sequence of the next image to retrieve
      bool                        m_buffer_ringing;	   // Should the buffer be considered as a ring buffer rather than a single use buffer.
      Status                      m_status;	           // The current status of the camera
282
      
283
      // LIMA / Not directly acquisition related :
284
      bool                        m_real_camera;	   // Set to false for CameraModel == "SIMCAM CMOS"
285
286
      std::string                 m_detector_model;
      std::string                 m_detector_type;
287
288
289
      std::string		  m_detector_serial;
      Size			  m_detector_size;
      double		          m_exp_time;
290
291

      // -- andor3 SDK stuff
292
      std::string                 m_bitflow_path;
293
294
      int                         m_camera_number;
      AT_H                        m_camera_handle;
295
296
297
298
      A3_Gain                     m_adc_gain;
      A3_SimpleGain               m_simple_gain;
      A3_ReadOutRate	          m_adc_rate;
      A3_ShutterMode		  m_electronic_shutter_mode;
299
      A3_BitDepth                 m_bit_depth;
300
301
      bool                        m_cooler;
      double                      m_temperature_sp;
302
303
      bool                        m_temperature_control_available;

304
305
306
      TrigMode                    m_trig_mode;
      // A3_TriggerMode		  m_trig_mode;
      std::map<TrigMode, int>     m_trig_mode_map;
307

308
      static int                  sAndorSDK3InittedCounter;
309
310
311
    
      bool  m_maximage_size_cb_active;
      Camera::SdkFrameDim m_sdk_frame_dim;
312
    };
Serge Cohen's avatar
Serge Cohen committed
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
    
    // Some inline utility functions; used all-over in Andor3 plugin :
    inline std::wstring StringToWString(const std::string & iStr)
    {
      wchar_t		tmpWStringBuf[1024];
      
      mbstowcs(tmpWStringBuf, iStr.c_str(), 1023);
      return std::wstring(tmpWStringBuf);
      /*std::wostringstream		theWSStream;
       theWSStream << iStr.c_str();
       return theWSStream.str();
       */
    }
    
    inline std::string WStringToString(const std::wstring & iStr)
    {
      // Should use wcstombs
      char			tmpStringBuf[1024];
      
      bzero(tmpStringBuf, 1024);
      wcstombs(tmpStringBuf, iStr.c_str(), 1023);
      return std::string(tmpStringBuf);
      /*    std::ostringstream			theSStream;
       theSStream << iStr.c_str();
       return theSStream.str();
       */
    }
    
    inline std::string atBoolToString(AT_BOOL iBool)
    {
      return (iBool) ? std::string("true") : std::string("false");
    }

346
347
  } // namespace Andor3
} // namespace lima
348
349
350
351
352
353
354
355
356


#endif  /* ANDOR3CAMERA_H */

/*
 Local Variables:
 c-file-style: "gnu"
 End:
 */