void CAndorSDK3Camera::InitialiseDeviceCircularBuffer() { IInteger* imageSizeBytes = NULL; try { imageSizeBytes = cameraDevice->GetInteger(L"ImageSizeBytes"); AT_64 ImageSize = imageSizeBytes->Get(); image_buffers_ = new unsigned char * [NO_CIRCLE_BUFFER_FRAMES]; for (int i = 0; i < NO_CIRCLE_BUFFER_FRAMES; i++) { image_buffers_[i] = new unsigned char[static_cast<int>(ImageSize+7)]; unsigned char* pucAlignedBuffer = reinterpret_cast<unsigned char*>( (reinterpret_cast<unsigned long>( image_buffers_[i] ) + 7 ) & ~0x7); bufferControl->Queue(pucAlignedBuffer, static_cast<int>(ImageSize)); } cameraDevice->Release(imageSizeBytes); } catch (exception & e) { string s("[InitialiseDeviceCircularBuffer] Caught Exception [Live] with message: "); s += e.what(); LogMessage(s); cameraDevice->Release(imageSizeBytes); } }
AT_64 CAndorSDK3Camera::GetTimeStamp(unsigned char* pBuf) { IInteger* imageSizeBytes = NULL; stringstream ss_logTimeStamp; AT_64 imageSize = 0; try { imageSizeBytes = cameraDevice->GetInteger(L"ImageSizeBytes"); imageSize = imageSizeBytes->Get(); cameraDevice->Release(imageSizeBytes); } catch (exception & e) { string s("[GetTimeStamp] Caught Exception with message: "); s += e.what(); LogMessage(s); cameraDevice->Release(imageSizeBytes); } int i_imageSize = static_cast<int>(imageSize); // Move to end of image. This is assuming reading metadata right to left. unsigned char* puc_metadata = pBuf + i_imageSize; AT_64 i64_timestamp = 0; puc_metadata -= LENGTH_FIELD_SIZE; andoru32 timestampSize = *(reinterpret_cast<andoru32*>(puc_metadata)); puc_metadata -= CID_FIELD_SIZE; andoru32 cid = *(reinterpret_cast<andoru32*>(puc_metadata)); if (CID_FPGA_TICKS == cid) { i64_timestamp = *(reinterpret_cast<AT_64*>(puc_metadata - (timestampSize-CID_FIELD_SIZE))); ss_logTimeStamp << "[GetTimeStamp] found CID, value is: " << i64_timestamp; } else { ss_logTimeStamp << "[GetTimeStamp] No timestamp found in frame: " << thd_->GetImageCounter(); } return i64_timestamp; }
/** * CAndorSDK3Camera constructor. * Setup default all variables and create device properties required to exist * before intialization. In this case, no such properties were required. All * properties will be created in the Initialize() method. * * As a general guideline Micro-Manager devices do not access hardware in the * the constructor. We should do as little as possible in the constructor and * perform most of the initialization in the Initialize() method. */ CAndorSDK3Camera::CAndorSDK3Camera() : CCameraBase<CAndorSDK3Camera> (), deviceManager(NULL), cameraDevice(NULL), bufferControl(NULL), startAcquisitionCommand(NULL), sendSoftwareTrigger(NULL), initialized_(false), b_cameraPresent_(false), number_of_devices_(0), deviceInUseIndex_(0), sequenceStartTime_(0), fpgaTSclockFrequency_(0), timeStamp_(0), defaultExposureTime_(0.0f), pDemoResourceLock_(0), image_buffers_(NULL), numImgBuffersAllocated_(0), currentSeqExposure_(0), keep_trying_(false), stopOnOverflow_(false) { // call the base class method to set-up default error codes/messages InitializeDefaultErrorMessages(); //Add in some others not currently in base impl, will show in CoreLog/Msgbox on error SetErrorText(DEVICE_BUFFER_OVERFLOW, " Circular Buffer Overflow code from MMCore"); SetErrorText(DEVICE_OUT_OF_MEMORY, " Allocation Failure - out of memory"); SetErrorText(DEVICE_SNAP_IMAGE_FAILED, " Snap Image Failure"); #ifdef TESTRESOURCELOCKING pDemoResourceLock_ = new MMThreadLock(); #endif thd_ = new MySequenceThread(this); // Create an atcore++ device manager deviceManager = new TDeviceManager; // Open a system device IDevice * systemDevice = deviceManager->OpenSystemDevice(); IInteger * deviceCount = systemDevice->GetInteger(L"DeviceCount"); SetNumberOfDevicesPresent(static_cast<int>(deviceCount->Get())); systemDevice->Release(deviceCount); IString * swVersion = systemDevice->GetString(L"SoftwareVersion"); currentSoftwareVersion_ = swVersion->Get(); systemDevice->Release(swVersion); deviceManager->CloseDevice(systemDevice); }
AT_64 CAndorSDK3Camera::GetTimeStamp(unsigned char* pBuf) { #if defined(linux) && defined(_LP64) typedef unsigned int AT_U32; #else typedef unsigned long AT_U32; #endif IInteger* imageSizeBytes = NULL; AT_64 imageSize = 0; try { imageSizeBytes = cameraDevice->GetInteger(L"ImageSizeBytes"); imageSize = imageSizeBytes->Get(); cameraDevice->Release(imageSizeBytes); } catch (exception & e) { string s("[GetTimeStamp] Caught Exception with message: "); s += e.what(); LogMessage(s); cameraDevice->Release(imageSizeBytes); } AT_64 i64_timestamp = 0; bool foundTimestamp = false; AT_U8* puc_metadata = pBuf + static_cast<int>(imageSize); //start at end of buffer do { //move pointer to length field puc_metadata -= LENGTH_FIELD_SIZE; AT_U32 featureSize = *(reinterpret_cast<AT_U32*>(puc_metadata)); //move pointer to Chunk identifier puc_metadata -= CID_FIELD_SIZE; AT_U32 cid = *(reinterpret_cast<AT_U32*>(puc_metadata)); //move pointer to start of data puc_metadata -= (featureSize-CID_FIELD_SIZE); if (CID_FPGA_TICKS == cid) { i64_timestamp = *(reinterpret_cast<AT_64*>(puc_metadata)); foundTimestamp = true; } } while(!foundTimestamp && puc_metadata > pBuf); return i64_timestamp; }
bool CAndorSDK3Camera::InitialiseDeviceCircularBuffer(const unsigned numBuffers) { bool b_ret = false; IInteger* imageSizeBytes = NULL; numImgBuffersAllocated_ = 0; try { imageSizeBytes = cameraDevice->GetInteger(L"ImageSizeBytes"); AT_64 ImageSize = imageSizeBytes->Get(); image_buffers_ = new unsigned char * [numBuffers]; for (unsigned int i = 0; i < numBuffers; i++) { image_buffers_[i] = new unsigned char[static_cast<int>(ImageSize)]; memset(image_buffers_[i], 0, static_cast<int>(ImageSize)); ++numImgBuffersAllocated_; bufferControl->Queue(image_buffers_[i], static_cast<int>(ImageSize)); } cameraDevice->Release(imageSizeBytes); b_ret = true; } catch (bad_alloc & ba) { string s("[InitialiseDeviceCircularBuffer] Caught Bad Allocation with message: "); s += ba.what(); LogMessage(s); b_ret = false; } catch (exception & e) { string s("[InitialiseDeviceCircularBuffer] Caught Exception with message: "); s += e.what(); LogMessage(s); b_ret = false; cameraDevice->Release(imageSizeBytes); } return b_ret; }
/** * Simple implementation of Sequence Acquisition * A sequence acquisition should run on its own thread and transport new images * coming of the camera into the MMCore circular buffer. */ int CAndorSDK3Camera::StartSequenceAcquisition(long numImages, double interval_ms, bool stopOnOverflow) { int retCode = DEVICE_OK; // The camera's default state is in software trigger mode, poised to make an // acquisition. Stop acquisition so that properties can be set for the // sequence acquisition. Also release the two buffers that were queued to // to take acquisition snapShotController_->leavePoisedMode(); if (IsCapturing()) { retCode = DEVICE_CAMERA_BUSY_ACQUIRING; } else { retCode = GetCoreCallback()->PrepareForAcq(this); } //MetaData / TimeStamp enable IBool * metadataEnable = NULL; IBool * mdTimeStampEnable = NULL; try { metadataEnable = cameraDevice->GetBool(L"MetadataEnable"); metadataEnable->Set(true); cameraDevice->Release(metadataEnable); } catch (exception & e) { string s("[StartSequenceAcquisition] metadataEnable Caught Exception with message: "); s += e.what(); LogMessage(s); cameraDevice->Release(metadataEnable); } try { mdTimeStampEnable = cameraDevice->GetBool(L"MetadataTimestamp"); mdTimeStampEnable->Set(true); cameraDevice->Release(mdTimeStampEnable); } catch (exception & e) { string s("[StartSequenceAcquisition] metadataEnable TS Caught Exception with message: "); s += e.what(); LogMessage(s); cameraDevice->Release(mdTimeStampEnable); } //TimestampClockFrequency IInteger* tsClkFrequency = NULL; try { tsClkFrequency = cameraDevice->GetInteger(L"TimestampClockFrequency"); fpgaTSclockFrequency_ = tsClkFrequency->Get(); cameraDevice->Release(tsClkFrequency); } catch (exception & e) { string s("[StartSequenceAcquisition] TS Clk Frequency Caught Exception with message: "); s += e.what(); LogMessage(s); cameraDevice->Release(tsClkFrequency); } if (DEVICE_OK == retCode) { InitialiseDeviceCircularBuffer(); if (LONG_MAX != numImages) { cycleMode->Set(L"Fixed"); frameCount->Set(numImages); } else { // When using the Micro-Manager GUI, this code is executed when entering live mode cycleMode->Set(L"Continuous"); snapShotController_->setupTriggerModeSilently(); } ResizeImageBuffer(); //// Set the frame rate to that held by the frame rate holder. Check the limits //double held_fr = 0.0; //if (frameRate->IsWritable()) //{ // held_fr = frameRate_floatHolder->Get(); // if (held_fr > frameRate->Max()) // { // held_fr = frameRate->Max(); // frameRate_floatHolder->Set(held_fr); // } // else if (held_fr < frameRate->Min()) // { // held_fr = frameRate->Min(); // frameRate_floatHolder->Set(held_fr); // } // frameRate->Set(held_fr); //} try { startAcquisitionCommand->Do(); if (snapShotController_->isSoftware()) { sendSoftwareTrigger->Do(); } } catch (exception & e) { string s("[StartSequenceAcquisition] Caught Exception [Live] with message: "); s += e.what(); LogMessage(s); return DEVICE_ERR; } keep_trying_ = true; thd_->Start(numImages, interval_ms); stopOnOverflow_ = stopOnOverflow; if (initialized_) { aoi_property_->SetReadOnly(true); } } return retCode; }
/** * CAndorSDK3Camera constructor. * Setup default all variables and create device properties required to exist * before intialization. In this case, no such properties were required. All * properties will be created in the Initialize() method. * * As a general guideline Micro-Manager devices do not access hardware in the * the constructor. We should do as little as possible in the constructor and * perform most of the initialization in the Initialize() method. */ CAndorSDK3Camera::CAndorSDK3Camera() : CCameraBase<CAndorSDK3Camera> (), deviceManager(NULL), systemDevice(NULL), cameraDevice(NULL), cycleMode(NULL), bufferControl(NULL), startAcquisitionCommand(NULL), stopAcquisitionCommand(NULL), sendSoftwareTrigger(NULL), frameCount(NULL), frameRate(NULL), initialized_(false), b_cameraPresent_(false), number_of_devices_(0), sequenceStartTime_(0), fpgaTSclockFrequency_(0), timeStamp_(0), pDemoResourceLock_(0), image_buffers_(NULL), d_frameRate_(0), keep_trying_(false), roiX_(0), roiY_(0) { // call the base class method to set-up default error codes/messages InitializeDefaultErrorMessages(); readoutStartTime_ = GetCurrentMMTime(); #ifdef TESTRESOURCELOCKING pDemoResourceLock_ = new MMThreadLock(); #endif thd_ = new MySequenceThread(this); // Create an atcore++ device manager deviceManager = new TDeviceManager; // Open a system device systemDevice = deviceManager->OpenSystemDevice(); IInteger * deviceCount = systemDevice->GetInteger(L"DeviceCount"); SetNumberOfDevicesPresent(static_cast<int>(deviceCount->Get())); systemDevice->Release(deviceCount); if (GetNumberOfDevicesPresent() > 0) { for (int i = 0; i < GetNumberOfDevicesPresent(); i++) { cameraDevice = deviceManager->OpenDevice(i); IString * cameraFamilyString = cameraDevice->GetString(L"CameraFamily"); std::wstring temp_ws = cameraFamilyString->Get(); cameraDevice->Release(cameraFamilyString); if (temp_ws.compare(L"Andor sCMOS") == 0) { b_cameraPresent_ = true; break; } else { deviceManager->CloseDevice(cameraDevice); } } } if (GetCameraPresent()) { bufferControl = cameraDevice->GetBufferControl(); startAcquisitionCommand = cameraDevice->GetCommand(L"AcquisitionStart"); stopAcquisitionCommand = cameraDevice->GetCommand(L"AcquisitionStop"); cycleMode = cameraDevice->GetEnum(L"CycleMode"); sendSoftwareTrigger = cameraDevice->GetCommand(L"SoftwareTrigger"); frameCount = cameraDevice->GetInteger(L"FrameCount"); frameRate = cameraDevice->GetFloat(L"FrameRate"); snapShotController_ = new SnapShotControl(cameraDevice); } }
/** * Intializes the hardware. * Required by the MM::Device API. * Typically we access and initialize hardware at this point. * Device properties are typically created here as well, except * the ones we need to use for defining initialization parameters. * Such pre-initialization properties are created in the constructor. * (This device does not have any pre-initialization properties) */ int CAndorSDK3Camera::Initialize() { if (initialized_) return DEVICE_OK; if (0 == GetNumberOfDevicesPresent()) { initialized_ = false; return DEVICE_NOT_CONNECTED; } PerformReleaseVersionCheck(); // set property list // ----------------- // Name int nRet = CreateProperty(MM::g_Keyword_Name, g_CameraName, MM::String, true); if (DEVICE_OK != nRet) return nRet; // CameraName nRet = CreateProperty(MM::g_Keyword_CameraName, g_CameraDeviceName, MM::String, true); assert(nRet == DEVICE_OK); // Description nRet = CreateProperty(MM::g_Keyword_Description, g_CameraDeviceDescription, MM::String, true); if (DEVICE_OK != nRet) return nRet; // CameraID IString * cameraSerialNumber = cameraDevice->GetString(L"SerialNumber"); std::wstring temp_ws = cameraSerialNumber->Get(); char * p_cameraSerialNumber = new char[temp_ws.size() + 1]; memset(p_cameraSerialNumber, 0, temp_ws.size() + 1); wcstombs(p_cameraSerialNumber, temp_ws.c_str(), temp_ws.size()); cameraDevice->Release(cameraSerialNumber); nRet = CreateProperty(MM::g_Keyword_CameraID, p_cameraSerialNumber, MM::String, true); assert(nRet == DEVICE_OK); delete [] p_cameraSerialNumber; temp_ws.erase(4); bool b_zyla = false; if (0 == temp_ws.compare(L"VSC-") ) { b_zyla = true; } // Properties binning_property = new TEnumProperty(MM::g_Keyword_Binning, cameraDevice->GetEnum(L"AOIBinning"), this, thd_, snapShotController_, false, false); AddAllowedValue(MM::g_Keyword_Binning, g_CameraDefaultBinning); SetProperty(MM::g_Keyword_Binning, g_CameraDefaultBinning); preAmpGain_property = new TEnumProperty(TAndorSDK3Strings::GAIN_TEXT, cameraDevice->GetEnum(L"SimplePreAmpGainControl"), this, thd_, snapShotController_, false, true); electronicShutteringMode_property = new TEnumProperty(TAndorSDK3Strings::ELECTRONIC_SHUTTERING_MODE, cameraDevice->GetEnum(L"ElectronicShutteringMode"), this, thd_, snapShotController_, false, false); temperatureControl_proptery = new TEnumProperty(TAndorSDK3Strings::TEMPERATURE_CONTROL, cameraDevice->GetEnum(L"TemperatureControl"), this, thd_, snapShotController_, b_zyla ? true : false, false); pixelReadoutRate_property = new TEnumProperty(TAndorSDK3Strings::PIXEL_READOUT_RATE, cameraDevice->GetEnum(L"PixelReadoutRateMapper"), this, thd_, snapShotController_, false, false); pixelEncoding_property = new TEnumProperty(TAndorSDK3Strings::PIXEL_ENCODING, cameraDevice->GetEnum(L"PixelEncoding"), this, thd_, snapShotController_, true, false); accumulationLength_property = new TIntegerProperty(TAndorSDK3Strings::ACCUMULATE_COUNT, cameraDevice->GetInteger(L"AccumulateCount"), this, thd_, snapShotController_, false, false); temperatureStatus_property = new TEnumProperty(TAndorSDK3Strings::TEMPERATURE_STATUS, cameraDevice->GetEnum(L"TemperatureStatus"), this, thd_, snapShotController_, true, false); fanSpeed_property = new TEnumProperty(TAndorSDK3Strings::FAN_SPEED, cameraDevice->GetEnum(L"FanSpeed"), this, thd_, snapShotController_, false, false); spuriousNoiseFilter_property = new TBooleanProperty(TAndorSDK3Strings::SPURIOUS_NOISE_FILTER, cameraDevice->GetBool(L"SpuriousNoiseFilter"), this, thd_, snapShotController_, false); sensorCooling_property = new TBooleanProperty(TAndorSDK3Strings::SENSOR_COOLING, cameraDevice->GetBool(L"SensorCooling"), this, thd_, snapShotController_, false); overlap_property = new TBooleanProperty(TAndorSDK3Strings::OVERLAP, cameraDevice->GetBool(L"Overlap"), this, thd_, snapShotController_, false); triggerMode_Enum = cameraDevice->GetEnum(L"TriggerMode"); triggerMode_remapper = new TTriggerRemapper(snapShotController_, triggerMode_Enum); std::map<std::wstring, std::wstring> triggerMode_map; triggerMode_map[L"Software"] = L"Software (Recommended for Live Mode)"; triggerMode_map[L"Internal"] = L"Internal (Recommended for fast acquisitions)"; triggerMode_valueMapper = new TAndorEnumValueMapper( triggerMode_remapper, triggerMode_map); triggerMode_property = new TEnumProperty(TAndorSDK3Strings::TRIGGER_MODE, triggerMode_valueMapper, this, thd_, snapShotController_, false, false); readTemperature_property = new TFloatProperty(TAndorSDK3Strings::SENSOR_TEMPERATURE, cameraDevice->GetFloat(L"SensorTemperature"), this, thd_, snapShotController_, true, false); //frameRate_property = new TFloatProperty(TAndorSDK3Strings::FRAME_RATE, // new TAndorFloatHolder(snapShotController_, frameRate), // this, thd_, snapShotController_, false, true); exposureTime_property = new TFloatProperty(MM::g_Keyword_Exposure, new TAndorFloatValueMapper(cameraDevice->GetFloat(L"ExposureTime"), 1000), this, thd_, snapShotController_, false, false); aoi_property_ = new TAOIProperty(TAndorSDK3Strings::ACQUISITION_AOI, this, cameraDevice, thd_, snapShotController_, false); InitialiseSDK3Defaults(); // synchronize all properties // -------------------------- nRet = UpdateStatus(); if (nRet != DEVICE_OK) return nRet; initialized_ = true; ClearROI(); //MetaData / TimeStamp enable IBool * metadataEnable = NULL; IBool * mdTimeStampEnable = NULL; try { metadataEnable = cameraDevice->GetBool(L"MetadataEnable"); metadataEnable->Set(true); cameraDevice->Release(metadataEnable); } catch (exception & e) { string s("[Initialize] metadataEnable Caught Exception with message: "); s += e.what(); LogMessage(s); cameraDevice->Release(metadataEnable); } try { mdTimeStampEnable = cameraDevice->GetBool(L"MetadataTimestamp"); mdTimeStampEnable->Set(true); cameraDevice->Release(mdTimeStampEnable); } catch (exception & e) { string s("[Initialize] metadataEnable TS Caught Exception with message: "); s += e.what(); LogMessage(s); cameraDevice->Release(mdTimeStampEnable); } //TimestampClockFrequency IInteger* tsClkFrequency = NULL; try { tsClkFrequency = cameraDevice->GetInteger(L"TimestampClockFrequency"); fpgaTSclockFrequency_ = tsClkFrequency->Get(); cameraDevice->Release(tsClkFrequency); } catch (exception & e) { string s("[Initialize] TS Clk Frequency Caught Exception with message: "); s += e.what(); LogMessage(s); cameraDevice->Release(tsClkFrequency); } eventsManager_ = new CEventsManager(cameraDevice); char errorStr[MM::MaxStrLength]; if (false == eventsManager_->Initialise(errorStr) ) { LogMessage(errorStr); } snapShotController_->poiseForSnapShot(); return DEVICE_OK; }
/** * CAndorSDK3Camera constructor. * Setup default all variables and create device properties required to exist * before intialization. In this case, no such properties were required. All * properties will be created in the Initialize() method. * * As a general guideline Micro-Manager devices do not access hardware in the * the constructor. We should do as little as possible in the constructor and * perform most of the initialization in the Initialize() method. */ CAndorSDK3Camera::CAndorSDK3Camera() : CCameraBase<CAndorSDK3Camera> (), deviceManager(NULL), systemDevice(NULL), cameraDevice(NULL), cycleMode(NULL), bufferControl(NULL), startAcquisitionCommand(NULL), stopAcquisitionCommand(NULL), sendSoftwareTrigger(NULL), frameCount(NULL), frameRate(NULL), initialized_(false), b_cameraPresent_(false), number_of_devices_(0), sequenceStartTime_(0), fpgaTSclockFrequency_(0), timeStamp_(0), pDemoResourceLock_(0), image_buffers_(NULL), numImgBuffersAllocated_(0), d_frameRate_(0), currentSeqExposure_(0), keep_trying_(false), b_eventsSupported_(false), roiX_(0), roiY_(0) { // call the base class method to set-up default error codes/messages InitializeDefaultErrorMessages(); //Add in some others not currently in base impl, will show in CoreLog/Msgbox on error SetErrorText(DEVICE_BUFFER_OVERFLOW, " Circular Buffer Overflow code from MMCore"); SetErrorText(DEVICE_OUT_OF_MEMORY, " Allocation Failure - out of memory"); SetErrorText(DEVICE_SNAP_IMAGE_FAILED, " Snap Image Failure"); readoutStartTime_ = GetCurrentMMTime(); #ifdef TESTRESOURCELOCKING pDemoResourceLock_ = new MMThreadLock(); #endif thd_ = new MySequenceThread(this); // Create an atcore++ device manager deviceManager = new TDeviceManager; // Open a system device systemDevice = deviceManager->OpenSystemDevice(); IInteger * deviceCount = systemDevice->GetInteger(L"DeviceCount"); SetNumberOfDevicesPresent(static_cast<int>(deviceCount->Get())); systemDevice->Release(deviceCount); if (GetNumberOfDevicesPresent() > 0) { for (int i = 0; i < GetNumberOfDevicesPresent(); i++) { cameraDevice = deviceManager->OpenDevice(i); IString * cameraFamilyString = cameraDevice->GetString(L"CameraFamily"); std::wstring temp_ws = cameraFamilyString->Get(); cameraDevice->Release(cameraFamilyString); if (temp_ws.compare(L"Andor sCMOS") == 0) { b_cameraPresent_ = true; break; } else { deviceManager->CloseDevice(cameraDevice); } } } if (GetCameraPresent()) { bufferControl = cameraDevice->GetBufferControl(); startAcquisitionCommand = cameraDevice->GetCommand(L"AcquisitionStart"); stopAcquisitionCommand = cameraDevice->GetCommand(L"AcquisitionStop"); cycleMode = cameraDevice->GetEnum(L"CycleMode"); sendSoftwareTrigger = cameraDevice->GetCommand(L"SoftwareTrigger"); frameCount = cameraDevice->GetInteger(L"FrameCount"); frameRate = cameraDevice->GetFloat(L"FrameRate"); snapShotController_ = new SnapShotControl(cameraDevice); } }