395 lines
13 KiB
C++
395 lines
13 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// FILE: Andor.h
|
|
// PROJECT: Micro-Manager
|
|
// SUBSYSTEM: DeviceAdapters
|
|
//-----------------------------------------------------------------------------
|
|
// DESCRIPTION: Andor camera module
|
|
//
|
|
// AUTHOR: Nenad Amodaj, nenad@amodaj.com, 06/30/2006
|
|
// COPYRIGHT: University of California, San Francisco, 2006
|
|
// 100X Imaging Inc, 2008
|
|
//
|
|
// LICENSE: This file is distributed under the BSD license.
|
|
// License text is included with the source distribution.
|
|
//
|
|
// 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.
|
|
//
|
|
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES.
|
|
//
|
|
// REVISIONS: May 21, 2007, Jizhen Zhao, Andor Technologies
|
|
// Temerature control and other additional related properties added,
|
|
// gain bug fixed, refernce counting fixed for shutter adapter.
|
|
//
|
|
// May 23 & 24, 2007, Daigang Wen, Andor Technology plc added/modified:
|
|
// Cooler is turned on at startup and turned off at shutdown
|
|
// Cooler control is changed to cooler mode control
|
|
// Pre-Amp-Gain property is added
|
|
// Temperature Setpoint property is added
|
|
// Temperature is resumed as readonly
|
|
// EMGainRangeMax and EMGainRangeMin are added
|
|
//
|
|
// FUTURE DEVELOPMENT: From September 1 2007, the development of this adaptor is taken over by Andor Technology plc. Daigang Wen (d.wen@andor.com) is the main contact. Changes made by him will not be labeled.
|
|
//
|
|
// CVS: $Id: Andor.h 10061 2012-10-09 15:38:57Z normanglasgow $
|
|
//
|
|
#ifndef _ANDOR_H_
|
|
#define _ANDOR_H_
|
|
|
|
#include "../../MMDevice/DeviceBase.h"
|
|
#include "../../MMDevice/MMDevice.h"
|
|
#include "../../MMDevice/ImgBuffer.h"
|
|
#include "../../MMDevice/DeviceUtils.h"
|
|
#include "../../MMDevice/DeviceThreads.h"
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <map>
|
|
|
|
// error codes
|
|
#define ERR_BUFFER_ALLOCATION_FAILED 101
|
|
#define ERR_INCOMPLETE_SNAP_IMAGE_CYCLE 102
|
|
#define ERR_INVALID_ROI 103
|
|
#define ERR_INVALID_READOUT_MODE_SETUP 104
|
|
#define ERR_CAMERA_DOES_NOT_EXIST 105
|
|
#define ERR_BUSY_ACQUIRING 106
|
|
#define ERR_INVALID_PREAMPGAIN 107
|
|
#define ERR_INVALID_VSPEED 108
|
|
#define ERR_TRIGGER_NOT_SUPPORTED 109
|
|
#define ERR_OPEN_OR_CLOSE_SHUTTER_IN_ACQUISITION_NOT_ALLOWEDD 110
|
|
#define ERR_NO_AVAIL_AMPS 111
|
|
#define ERR_SOFTWARE_TRIGGER_IN_USE 112
|
|
|
|
class AcqSequenceThread;
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Implementation of the MMDevice and MMCamera interfaces
|
|
//
|
|
class AndorCamera : public CCameraBase<AndorCamera>
|
|
{
|
|
public:
|
|
friend class AcqSequenceThread;
|
|
static AndorCamera* GetInstance();
|
|
|
|
~AndorCamera();
|
|
|
|
// MMDevice API
|
|
int Initialize();
|
|
int Shutdown();
|
|
|
|
void GetName(char* pszName) const;
|
|
bool Busy() {return false;}
|
|
|
|
// MMCamera API
|
|
int SnapImage();
|
|
const unsigned char* GetImageBuffer();
|
|
unsigned GetImageWidth() const {return img_.Width();}
|
|
unsigned GetImageHeight() const {return img_.Height();}
|
|
unsigned GetImageBytesPerPixel() const {return img_.Depth();}
|
|
long GetImageBufferSize() const {return img_.Width() * img_.Height() * GetImageBytesPerPixel();}
|
|
unsigned GetBitDepth() const;
|
|
int GetBinning() const;
|
|
int SetBinning(int binSize);
|
|
double GetExposure() const;
|
|
void SetExposure(double dExp);
|
|
int SetROI(unsigned uX, unsigned uY, unsigned uXSize, unsigned uYSize);
|
|
int GetROI(unsigned& uX, unsigned& uY, unsigned& uXSize, unsigned& uYSize);
|
|
int ClearROI();
|
|
int IsExposureSequenceable(bool& isSequenceable) const {isSequenceable = false; return DEVICE_OK;}
|
|
|
|
// high-speed interface
|
|
int PrepareSequenceAcqusition()
|
|
{
|
|
return DEVICE_OK;
|
|
}
|
|
int StartSequenceAcquisition(long numImages, double interval_ms, bool stopOnOverflow);
|
|
/**
|
|
* Continuous sequence acquisition.
|
|
* Default to sequence acquisition with a high number of images
|
|
*/
|
|
int StartSequenceAcquisition(double interval)
|
|
{
|
|
return StartSequenceAcquisition(LONG_MAX, interval, false);
|
|
}
|
|
|
|
int StopSequenceAcquisition(); // temporary=true
|
|
int StopSequenceAcquisition(bool temporary);
|
|
|
|
bool IsCapturing(){return sequenceRunning_;};
|
|
|
|
// action interface for the camera
|
|
int OnBinning(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnExposure(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnPixelType(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnGain(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnEMSwitch(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnReadoutMode(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnReadoutTime(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnOffset(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnTemperature(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnDriverDir(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
//int OnShutterMode(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnCooler(MM::PropertyBase* pProp, MM::ActionType eAct);// jizhen 05.11.2007
|
|
int OnFanMode(MM::PropertyBase* pProp, MM::ActionType eAct);// jizhen 05.16.2007
|
|
int OnTemperatureSetPoint(MM::PropertyBase* pProp, MM::ActionType eAct);// Daigang 23-May-2007
|
|
int OnEMGainRangeMax(MM::PropertyBase* pProp, MM::ActionType eAct);// Daigang 24-May-2007
|
|
int OnEMGainRangeMin(MM::PropertyBase* pProp, MM::ActionType eAct);// Daigang 24-May-2007
|
|
int OnPreAmpGain(MM::PropertyBase* pProp, MM::ActionType eAct);// Daigang 24-May-2007
|
|
int OnFrameTransfer(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnVSpeed(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnInternalShutter(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnOutputAmplifier(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnADChannel(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnCamera(MM::PropertyBase* pProp, MM::ActionType eAct);//for multiple camera support
|
|
int OnCameraName(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OniCamFeatures(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnTemperatureRangeMin(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnTemperatureRangeMax(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnVCVoltage(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnBaselineClamp(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnCropModeSwitch(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnCropModeWidth(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnCropModeHeight(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnActualIntervalMS(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnSelectTrigger(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnTimeOut(MM::PropertyBase* pProp, MM::ActionType eAct); // kdb July-30-2009
|
|
int OnCountConvert(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnCountConvertWavelength(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnSpuriousNoiseFilter(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnSpuriousNoiseFilterThreshold(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnSpuriousNoiseFilterDescription(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
int OnOptAcquireMode(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
void UpdateOAParams(const char* OAModeName);
|
|
int OnOADescription(MM::PropertyBase* pProp, MM::ActionType eAct);
|
|
|
|
|
|
// custom interface for the thread
|
|
int PushImage();
|
|
|
|
//static void ReleaseInstance(AndorCamera * AndorCamera);
|
|
|
|
int GetNumberOfWorkableCameras() const { return NumberOfWorkableCameras_; }
|
|
int GetMyCameraID() const { return myCameraID_; }
|
|
|
|
private:
|
|
AndorCamera();
|
|
int ResizeImageBuffer();
|
|
int StopCameraAcquisition();
|
|
void UpdateEMGainRange();
|
|
void CheckError(unsigned int errorVal);
|
|
bool IsThermoSteady();
|
|
void SetToIdle();
|
|
bool IsAcquiring();
|
|
|
|
void LogStatus();
|
|
int PrepareSnap();
|
|
unsigned int UpdateSnapTriggerMode();
|
|
|
|
|
|
bool EMSwitch_;
|
|
|
|
unsigned int ui_swVersion;
|
|
|
|
static AndorCamera* instance_;
|
|
static unsigned refCount_;
|
|
static bool softwareTriggerUsed_;
|
|
ImgBuffer img_;
|
|
bool initialized_;
|
|
bool snapInProgress_;
|
|
bool sequenceRunning_;
|
|
long imageCounter_;
|
|
MM::MMTime startTime_;
|
|
long imageTimeOut_ms_;
|
|
long sequenceLength_;
|
|
bool stopOnOverflow_;
|
|
double intervalMs_;
|
|
std::string countConvertMode_;
|
|
double countConvertWavelength_;
|
|
std::string spuriousNoiseFilter_;
|
|
double spuriousNoiseFilterThreshold_;
|
|
std::string spuriousNoiseFilterDescriptionStr_;
|
|
std::string optAcquireModeStr_;
|
|
std::string optAcquireDescriptionStr_;
|
|
|
|
long lSnapImageCnt_;
|
|
std::vector<std::string> PreAmpGains_;
|
|
long currentGain_;
|
|
|
|
bool cropModeSwitch_;
|
|
long currentCropWidth_;
|
|
long currentCropHeight_;
|
|
std::vector<std::string> VSpeeds_;
|
|
|
|
|
|
double currentExpMS_;
|
|
|
|
long ReadoutTime_, KeepCleanTime_;
|
|
|
|
long GetReadoutTime();
|
|
|
|
// kdb 2/27/2009
|
|
#ifdef WIN32
|
|
HMODULE hAndorDll;
|
|
typedef unsigned int (CALLBACK *FPGetReadOutTime)(float *_fReadoutTime);
|
|
typedef unsigned int (CALLBACK *FPGetKeepCleanTime)(float *_ftime);
|
|
#else
|
|
HDEVMODULE hAndorDll;
|
|
typedef unsigned int (*FPGetReadOutTime)(float *_fReadoutTime);
|
|
typedef unsigned int (*FPGetKeepCleanTime)(float *_ftime);
|
|
#endif
|
|
// end of kdb
|
|
FPGetReadOutTime fpGetReadOutTime;
|
|
//typedef unsigned int (CALLBACK *FPGetKeepCleanTime)(float *_ftime);
|
|
FPGetKeepCleanTime fpGetKeepCleanTime;
|
|
//typedef unsigned int (CALLBACK *FPSendSoftwareTrigger)();
|
|
//FPSendSoftwareTrigger fpSendSoftwareTrigger;
|
|
|
|
bool busy_;
|
|
|
|
struct ROI {
|
|
int x;
|
|
int y;
|
|
int xSize;
|
|
int ySize;
|
|
|
|
ROI() : x(0), y(0), xSize(0), ySize(0) {}
|
|
~ROI() {}
|
|
|
|
bool isEmpty() {return x==0 && y==0 && xSize==0 && ySize == 0;}
|
|
};
|
|
|
|
ROI roi_;
|
|
int binSize_;
|
|
double expMs_; //value used by camera
|
|
std::string driverDir_;
|
|
int fullFrameX_;
|
|
int fullFrameY_;
|
|
int tempFrameX_;
|
|
int tempFrameY_;
|
|
short* fullFrameBuffer_;
|
|
std::vector<std::string> readoutModes_;
|
|
|
|
int EmCCDGainLow_, EmCCDGainHigh_;
|
|
int minTemp_, maxTemp_;
|
|
//Daigang 24-may-2007
|
|
bool ThermoSteady_;
|
|
|
|
AcqSequenceThread* seqThread_;
|
|
|
|
bool bShutterIntegrated_;
|
|
int ADChannelIndex_, OutputAmplifierIndex_;
|
|
void UpdateHSSpeeds();
|
|
int UpdatePreampGains();
|
|
|
|
int HSSpeedIdx_;
|
|
|
|
bool bSoftwareTriggerSupported_;
|
|
int iCurrentTriggerMode_;
|
|
|
|
enum {
|
|
INTERNAL,
|
|
EXTERNAL,
|
|
SOFTWARE
|
|
};
|
|
|
|
at_32 myCameraID_;
|
|
at_32 NumberOfAvailableCameras_;
|
|
at_32 NumberOfWorkableCameras_;
|
|
std::vector<std::string> cameraName_;
|
|
std::vector<std::string> cameraSN_;
|
|
std::vector<int> cameraID_;
|
|
int GetListOfAvailableCameras();
|
|
std::string CameraName_;
|
|
std::string iCamFeatures_;
|
|
std::string TemperatureRangeMin_;
|
|
std::string TemperatureRangeMax_;
|
|
std::string PreAmpGain_;
|
|
std::string VSpeed_;
|
|
std::string TemperatureSetPoint_;
|
|
std::vector<std::string> VCVoltages_;
|
|
std::string VCVoltage_;
|
|
std::vector<std::string> BaselineClampValues_;
|
|
std::string BaselineClampValue_;
|
|
float ActualInterval_ms_;
|
|
|
|
std::string strCurrentTriggerMode_;
|
|
std::vector<std::string> vTriggerModes;
|
|
|
|
std::string strCurrentAmp;
|
|
std::vector<std::string> vAvailAmps;
|
|
std::map<std::string, int> mapAmps;
|
|
|
|
std::string strCurrentChannel;
|
|
std::vector<std::string> vChannels;
|
|
|
|
bool bFrameTransfer_;
|
|
|
|
std::string m_str_frameTransferProp;
|
|
std::string m_str_camType;
|
|
std::vector<std::string> vCameraType;
|
|
|
|
unsigned char* pImgBuffer_;
|
|
unsigned char* GetAcquiredImage();
|
|
std::string getCameraType();
|
|
unsigned int createGainProperty(AndorCapabilities * caps);
|
|
unsigned int createTriggerProperty(AndorCapabilities * caps);
|
|
unsigned int createIsolatedCropModeProperty(AndorCapabilities * caps);
|
|
|
|
bool mb_canUseFan;
|
|
bool mb_canSetTemp;
|
|
bool bEMGainSupported;
|
|
|
|
bool sequencePaused_;
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* Acquisition thread
|
|
*/
|
|
class AcqSequenceThread : public MMDeviceThreadBase
|
|
{
|
|
public:
|
|
AcqSequenceThread(AndorCamera* pCam) :
|
|
intervalMs_(100.0),
|
|
numImages_(1),
|
|
waitTime_(10),
|
|
busy_(false),
|
|
stop_(false)
|
|
{
|
|
camera_ = pCam;
|
|
};
|
|
~AcqSequenceThread() {}
|
|
|
|
int svc(void);
|
|
|
|
void SetInterval(double intervalMs) {intervalMs_ = intervalMs;}
|
|
void SetWaitTime (long waitTime) { waitTime_ = waitTime;}
|
|
void SetTimeOut (long imageTimeOut) { imageTimeOut_ = imageTimeOut;}
|
|
void SetLength(long images) {numImages_ = images;}
|
|
void Stop() {stop_ = true;}
|
|
void Start() {stop_ = false; activate();}
|
|
|
|
private:
|
|
AndorCamera* camera_;
|
|
double intervalMs_;
|
|
long numImages_;
|
|
long waitTime_;
|
|
long imageTimeOut_;
|
|
bool busy_;
|
|
bool stop_;
|
|
};
|
|
|
|
|
|
class DriverGuard
|
|
{
|
|
public:
|
|
DriverGuard(const AndorCamera * cam);
|
|
~DriverGuard();
|
|
|
|
};
|
|
|
|
#endif //_ANDOR_H_
|