Removed AcquireTimeActual, etc. parameters, use RBV instead; remove shutter private variables, not needed; remove data array, not needed; add desired values of AcquireTime, etc. to store desired values even when SDK changes them; added setupShutter function; print AndorCapabilities in report function; removed support for saving as TEXT file; change order of reading image and saving to disk
git-svn-id: https://subversion.xor.aps.anl.gov/synApps/areaDetector/trunk@14396 dc6c5ff5-0b8b-c028-a01f-ffb33f00fc8b
This commit is contained in:
+191
-218
@@ -104,16 +104,8 @@ AndorCCD::AndorCCD(const char *portName, int maxBuffers, size_t maxMemory,
|
||||
createParam(AndorShutterExTTLString, asynParamInt32, &AndorShutterExTTL);
|
||||
createParam(AndorPalFileNameString, asynParamOctet, &AndorPalFileName);
|
||||
createParam(AndorAccumulatePeriodString, asynParamFloat64, &AndorAccumulatePeriod);
|
||||
createParam(AndorAcquireTimeActualString, asynParamFloat64, &AndorAcquireTimeActual);
|
||||
createParam(AndorAcquirePeriodActualString, asynParamFloat64, &AndorAcquirePeriodActual);
|
||||
createParam(AndorAccumulatePeriodActualString,asynParamFloat64, &AndorAccumulatePeriodActual);
|
||||
createParam(AndorAdcSpeedString, asynParamInt32, &AndorAdcSpeed);
|
||||
|
||||
mShutterExTTL = 1; //Use high TTL signal for external shutter
|
||||
mShutterMode = AShutterAuto; //Auto mode
|
||||
mShutterCloseTime = 0; //milliseconds
|
||||
mShutterOpenTime = 0; //milliseconds
|
||||
|
||||
//Create the epicsEvent for signaling to the status task when parameters should have changed.
|
||||
//This will cause it to do a poll immediately, rather than wait for the poll time period.
|
||||
this->statusEvent = epicsEventMustCreate(epicsEventEmpty);
|
||||
@@ -138,7 +130,6 @@ AndorCCD::AndorCCD(const char *portName, int maxBuffers, size_t maxMemory,
|
||||
checkStatus(GetHeadModel(model));
|
||||
checkStatus(SetReadMode(ARImage));
|
||||
checkStatus(SetImage(binX, binY, minX+1, minX+sizeX, minY+1, minY+sizeY));
|
||||
checkStatus(SetShutter(mShutterExTTL, mShutterMode, mShutterCloseTime, mShutterOpenTime));
|
||||
callParamCallbacks();
|
||||
} catch (const std::string &e) {
|
||||
cout << e << endl;
|
||||
@@ -161,16 +152,24 @@ AndorCCD::AndorCCD(const char *portName, int maxBuffers, size_t maxMemory,
|
||||
status |= setIntegerParam(ADMaxSizeY, sizeY);
|
||||
status |= setIntegerParam(ADImageMode, ADImageSingle);
|
||||
status |= setIntegerParam(ADTriggerMode, AndorCCD::ATInternal);
|
||||
status |= setDoubleParam (ADAcquireTime, 1.0);
|
||||
status |= setDoubleParam (ADAcquirePeriod, 1.0);
|
||||
mAcquireTime = 1.0;
|
||||
status |= setDoubleParam (ADAcquireTime, mAcquireTime);
|
||||
mAcquirePeriod = 5.0;
|
||||
status |= setDoubleParam (ADAcquirePeriod, mAcquirePeriod);
|
||||
status |= setIntegerParam(ADNumImages, 1);
|
||||
status |= setIntegerParam(ADNumExposures, 1);
|
||||
status |= setIntegerParam(NDArraySizeX, sizeX);
|
||||
status |= setIntegerParam(NDArraySizeY, sizeY);
|
||||
status |= setIntegerParam(NDArraySize, sizeX*sizeY*sizeof(at_32));
|
||||
status |= setDoubleParam(AndorAccumulatePeriod, 2.0);
|
||||
mAccumulatePeriod = 2.0;
|
||||
status |= setDoubleParam(AndorAccumulatePeriod, mAccumulatePeriod);
|
||||
status |= setIntegerParam(AndorAdcSpeed, 0);
|
||||
|
||||
status |= setIntegerParam(AndorShutterExTTL, 1);
|
||||
status |= setIntegerParam(AndorShutterMode, AShutterAuto);
|
||||
status |= setDoubleParam(ADShutterOpenDelay, 0.);
|
||||
status |= setDoubleParam(ADShutterCloseDelay, 0.);
|
||||
status |= setupShutter(-1);
|
||||
|
||||
callParamCallbacks();
|
||||
|
||||
/* Send a signal to the poller task which will make it do a poll, and switch to the fast poll rate */
|
||||
@@ -186,15 +185,6 @@ AndorCCD::AndorCCD(const char *portName, int maxBuffers, size_t maxMemory,
|
||||
mFastPollingPeriod = 0.05; //seconds
|
||||
|
||||
mAcquiringData = 0;
|
||||
|
||||
//Allocate space for data (single image)
|
||||
mDataSize = sizeX * sizeY;
|
||||
mData = NULL;
|
||||
mData = (at_32 *) calloc(mDataSize, sizeof(at_32));
|
||||
if (mData == NULL) {
|
||||
cout << driverName << ":" << functionName << " ERROR: Could not allocate enough memory for data" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (stackSize == 0) stackSize = epicsThreadGetStackSize(epicsThreadStackMedium);
|
||||
printf("Stack size = %d\n", stackSize);
|
||||
@@ -233,8 +223,6 @@ AndorCCD::~AndorCCD()
|
||||
checkStatus(FreeInternalMemory());
|
||||
checkStatus(ShutDown());
|
||||
cout << "Camera shutting down as part of IOC exit." << endl;
|
||||
//Free data memory
|
||||
free(mData);
|
||||
this->unlock();
|
||||
} catch (const std::string &e) {
|
||||
cout << e << endl;
|
||||
@@ -265,33 +253,51 @@ void AndorCCD::report(FILE *fp, int details)
|
||||
unsigned int uIntParam4;
|
||||
unsigned int uIntParam5;
|
||||
unsigned int uIntParam6;
|
||||
AndorCapabilities capabilities;
|
||||
|
||||
fprintf(fp, "Andor CCD port=%s\n", this->portName);
|
||||
try {
|
||||
checkStatus(GetCameraSerialNumber(¶m1));
|
||||
fprintf(fp, " serial number: %d\n", param1);
|
||||
checkStatus(GetHardwareVersion(&uIntParam1, &uIntParam2, &uIntParam3, &uIntParam4, &uIntParam5, &uIntParam6));
|
||||
fprintf(fp, " PCB Version: %d\n", uIntParam1);
|
||||
fprintf(fp, " Flex File Version: %d\n", uIntParam2);
|
||||
fprintf(fp, " Firmware Version: %d\n", uIntParam5);
|
||||
fprintf(fp, " Firmware Build: %d\n", uIntParam6);
|
||||
getIntegerParam(ADMaxSizeX, &xsize);
|
||||
getIntegerParam(ADMaxSizeY, &ysize);
|
||||
fprintf(fp, " xpixels: %d\n", xsize);
|
||||
fprintf(fp, " ypixels: %d\n", ysize);
|
||||
checkStatus(GetNumberAmp(¶m1));
|
||||
fprintf(fp, " Number of amplifier channels: %d\n", param1);
|
||||
checkStatus(GetNumberADChannels(¶m1));
|
||||
fprintf(fp, " Number of ADC channels: %d\n", param1);
|
||||
checkStatus(GetNumberPreAmpGains(¶m1));
|
||||
fprintf(fp, " Number of pre-amp gains: %d\n", param1);
|
||||
for (i=0; i<param1; i++) {
|
||||
checkStatus(GetPreAmpGain(i, &fParam1));
|
||||
fprintf(fp, " Gain[%d]: %f\n", i, fParam1);
|
||||
if (details > 0) {
|
||||
try {
|
||||
checkStatus(GetCameraSerialNumber(¶m1));
|
||||
fprintf(fp, " serial number: %d\n", param1);
|
||||
checkStatus(GetHardwareVersion(&uIntParam1, &uIntParam2, &uIntParam3,
|
||||
&uIntParam4, &uIntParam5, &uIntParam6));
|
||||
fprintf(fp, " PCB Version: %d\n", uIntParam1);
|
||||
fprintf(fp, " Flex File Version: %d\n", uIntParam2);
|
||||
fprintf(fp, " Firmware Version: %d\n", uIntParam5);
|
||||
fprintf(fp, " Firmware Build: %d\n", uIntParam6);
|
||||
getIntegerParam(ADMaxSizeX, &xsize);
|
||||
getIntegerParam(ADMaxSizeY, &ysize);
|
||||
fprintf(fp, " xpixels: %d\n", xsize);
|
||||
fprintf(fp, " ypixels: %d\n", ysize);
|
||||
checkStatus(GetNumberAmp(¶m1));
|
||||
fprintf(fp, " Number of amplifier channels: %d\n", param1);
|
||||
checkStatus(GetNumberADChannels(¶m1));
|
||||
fprintf(fp, " Number of ADC channels: %d\n", param1);
|
||||
checkStatus(GetNumberPreAmpGains(¶m1));
|
||||
fprintf(fp, " Number of pre-amp gains: %d\n", param1);
|
||||
for (i=0; i<param1; i++) {
|
||||
checkStatus(GetPreAmpGain(i, &fParam1));
|
||||
fprintf(fp, " Gain[%d]: %f\n", i, fParam1);
|
||||
}
|
||||
capabilities.ulSize = sizeof(capabilities);
|
||||
checkStatus(GetCapabilities(&capabilities));
|
||||
fprintf(fp, " Capabilities\n");
|
||||
fprintf(fp, " AcqModes=0x%lx\n", capabilities.ulAcqModes);
|
||||
fprintf(fp, " ReadModes=0x%lx\n", capabilities.ulReadModes);
|
||||
fprintf(fp, " FTReadModes=0x%lx\n", capabilities.ulFTReadModes);
|
||||
fprintf(fp, " TriggerModes=0x%lx\n", capabilities.ulTriggerModes);
|
||||
fprintf(fp, " CameraType=0x%lx\n", capabilities.ulCameraType);
|
||||
fprintf(fp, " PixelModes=0x%lx\n", capabilities.ulPixelMode);
|
||||
fprintf(fp, " SetFunctions=0x%lx\n", capabilities.ulSetFunctions);
|
||||
fprintf(fp, " GetFunctions=0x%lx\n", capabilities.ulGetFunctions);
|
||||
fprintf(fp, " Features=0x%lx\n", capabilities.ulFeatures);
|
||||
fprintf(fp, " PCI MHz=%ld\n", capabilities.ulPCICard);
|
||||
fprintf(fp, " EMGain=0x%lx\n", capabilities.ulEMGainCapability);
|
||||
|
||||
} catch (const std::string &e) {
|
||||
cout << e << endl;
|
||||
}
|
||||
|
||||
} catch (const std::string &e) {
|
||||
cout << e << endl;
|
||||
}
|
||||
// Call the base class method
|
||||
ADDriver::report(fp, details);
|
||||
@@ -356,10 +362,10 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value)
|
||||
else if (function == AndorCoolerParam) {
|
||||
try {
|
||||
if (value == 0) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s, CoolerOFF().\n", functionName);
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s, CoolerOFF()\n", functionName);
|
||||
checkStatus(CoolerOFF());
|
||||
} else if (value == 1) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s, CoolerON().\n", functionName);
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s, CoolerON()\n", functionName);
|
||||
checkStatus(CoolerON());
|
||||
}
|
||||
} catch (const std::string &e) {
|
||||
@@ -368,52 +374,12 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value)
|
||||
}
|
||||
}
|
||||
else if (function == ADShutterControl) {
|
||||
try {
|
||||
if (value == 0) { //Close shutter
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s, SetShutter(%d,%d,%d,%d).\n", functionName, mShutterExTTL, AShutterClose, mShutterCloseTime, mShutterOpenTime);
|
||||
checkStatus(SetShutter(mShutterExTTL, AShutterClose, mShutterCloseTime, mShutterOpenTime));
|
||||
mShutterMode = AShutterClose;
|
||||
} else { //Open shutter (check current value of AndorShutterMode)
|
||||
int aShutter = 999;
|
||||
getIntegerParam(AndorShutterMode, &aShutter);
|
||||
if (aShutter == AShutterAuto) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s, SetShutter(%d,%d,%d,%d).\n", functionName, mShutterExTTL, AShutterAuto, mShutterCloseTime, mShutterOpenTime);
|
||||
checkStatus(SetShutter(mShutterExTTL, AShutterAuto, mShutterCloseTime, mShutterOpenTime));
|
||||
mShutterMode = AShutterAuto;
|
||||
} else if (aShutter == AShutterOpen) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s, SetShutter(%d,%d,%d,%d).\n", functionName, mShutterExTTL, AShutterOpen, mShutterCloseTime, mShutterOpenTime);
|
||||
checkStatus(SetShutter(mShutterExTTL, AShutterOpen, mShutterCloseTime, mShutterOpenTime));
|
||||
mShutterMode = AShutterOpen;
|
||||
}
|
||||
}
|
||||
} catch (const std::string &e) {
|
||||
cout << e << endl;
|
||||
status = asynError;
|
||||
}
|
||||
status = setupShutter(value);
|
||||
}
|
||||
|
||||
else if (function == AndorShutterMode) {
|
||||
try {
|
||||
checkStatus(SetShutter(mShutterExTTL, static_cast<int>(value), mShutterCloseTime, mShutterOpenTime));
|
||||
mShutterMode = static_cast<int>(value);
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s, SetShutter(%d,%d,%d,%d).\n", functionName, mShutterExTTL, mShutterMode, mShutterCloseTime, mShutterOpenTime);
|
||||
} catch (const std::string &e) {
|
||||
cout << e << endl;
|
||||
status = asynError;
|
||||
}
|
||||
else if ((function == AndorShutterMode) ||
|
||||
(function == AndorShutterExTTL)) {
|
||||
status = setupShutter(-1);
|
||||
}
|
||||
|
||||
else if (function == AndorShutterExTTL) {
|
||||
try {
|
||||
checkStatus(SetShutter(static_cast<int>(value), mShutterMode, mShutterCloseTime, mShutterOpenTime));
|
||||
mShutterExTTL = static_cast<int>(value);
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s, SetShutter(%d,%d,%d,%d).\n", functionName, mShutterExTTL, mShutterMode, mShutterCloseTime, mShutterOpenTime);
|
||||
} catch (const std::string &e) {
|
||||
cout << e << endl;
|
||||
status = asynError;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
status = ADDriver::writeInt32(pasynUser, value);
|
||||
}
|
||||
@@ -455,23 +421,41 @@ asynStatus AndorCCD::writeFloat64(asynUser *pasynUser, epicsFloat64 value)
|
||||
int minTemp = 0;
|
||||
int maxTemp = 0;
|
||||
|
||||
/* Set the parameter and readback in the parameter library. This may be overwritten when we read back the
|
||||
* status at the end, but that's OK */
|
||||
/* Set the parameter and readback in the parameter library. */
|
||||
status = setDoubleParam(function, value);
|
||||
|
||||
if ((function == ADAcquireTime) ||
|
||||
(function == ADAcquirePeriod) ||
|
||||
(function == AndorAccumulatePeriod)) {
|
||||
if (function == ADAcquireTime) {
|
||||
mAcquireTime = (float)value;
|
||||
status = setupAcquisition();
|
||||
}
|
||||
else if (function == ADAcquirePeriod) {
|
||||
mAcquirePeriod = (float)value;
|
||||
status = setupAcquisition();
|
||||
}
|
||||
else if (function == ADGain) {
|
||||
try {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, SetPreAmpGain(%d)\n", functionName, (int)value);
|
||||
checkStatus(SetPreAmpGain((int)value));
|
||||
} catch (const std::string &e) {
|
||||
cout << e << endl;
|
||||
status = asynError;
|
||||
}
|
||||
}
|
||||
else if (function == AndorAccumulatePeriod) {
|
||||
mAccumulatePeriod = (float)value;
|
||||
status = setupAcquisition();
|
||||
}
|
||||
else if (function == ADTemperature) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, Setting temperature value %f.\n", functionName, value);
|
||||
"%s, Setting temperature value %f\n", functionName, value);
|
||||
try {
|
||||
checkStatus(GetTemperatureRange(&minTemp, &maxTemp));
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, CCD Min Temp: %d, Max Temp %d.\n", functionName, minTemp, maxTemp);
|
||||
"%s, CCD Min Temp: %d, Max Temp %d\n", functionName, minTemp, maxTemp);
|
||||
checkStatus(GetTemperatureRange(&minTemp, &maxTemp));
|
||||
if ((static_cast<int>(value) > minTemp) & (static_cast<int>(value) < maxTemp)) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, SetTemperature(%d)\n", functionName, static_cast<int>(value));
|
||||
checkStatus(SetTemperature(static_cast<int>(value)));
|
||||
} else {
|
||||
setStringParam(AndorMessage, "Temperature is out of range.");
|
||||
@@ -483,34 +467,11 @@ asynStatus AndorCCD::writeFloat64(asynUser *pasynUser, epicsFloat64 value)
|
||||
status = asynError;
|
||||
}
|
||||
}
|
||||
else if (function == ADShutterOpenDelay) {
|
||||
try {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, Setting ADShutterOpenDelay to %f.\n", functionName, value);
|
||||
checkStatus(SetShutter(mShutterExTTL, mShutterMode, mShutterCloseTime, static_cast<int>(value)));
|
||||
mShutterOpenTime = static_cast<int>(value);
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, SetShutter(%d,%d,%d,%d).\n",
|
||||
functionName, mShutterExTTL, mShutterMode, mShutterCloseTime, mShutterOpenTime);
|
||||
} catch (const std::string &e) {
|
||||
cout << e << endl;
|
||||
status = asynError;
|
||||
}
|
||||
}
|
||||
else if (function == ADShutterCloseDelay) {
|
||||
try {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, Setting ADShutterCloseDelay to %f.\n", functionName, value);
|
||||
checkStatus(SetShutter(mShutterExTTL, mShutterMode, static_cast<int>(value), mShutterOpenTime));
|
||||
mShutterCloseTime = static_cast<int>(value);
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, SetShutter(%d,%d,%d,%d).\n",
|
||||
functionName, mShutterExTTL, mShutterMode, mShutterCloseTime, mShutterOpenTime);
|
||||
} catch (const std::string &e) {
|
||||
cout << e << endl;
|
||||
status = asynError;
|
||||
}
|
||||
else if ((function == ADShutterOpenDelay) ||
|
||||
(function == ADShutterCloseDelay)) {
|
||||
status = setupShutter(-1);
|
||||
}
|
||||
|
||||
else {
|
||||
status = ADDriver::writeFloat64(pasynUser, value);
|
||||
}
|
||||
@@ -531,6 +492,52 @@ asynStatus AndorCCD::writeFloat64(asynUser *pasynUser, epicsFloat64 value)
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
// command: 0=close, 1=open, -1=no change, only set other parameters
|
||||
asynStatus AndorCCD::setupShutter(int command)
|
||||
{
|
||||
double dTemp;
|
||||
int openTime, closeTime;
|
||||
int shutterExTTL;
|
||||
int shutterMode;
|
||||
asynStatus status=asynSuccess;
|
||||
static const char *functionName = "AndorCCD::setupShutter";
|
||||
|
||||
getDoubleParam(ADShutterOpenDelay, &dTemp);
|
||||
// Convert to ms
|
||||
openTime = (int)(dTemp * 1000.);
|
||||
getDoubleParam(ADShutterCloseDelay, &dTemp);
|
||||
closeTime = (int)(dTemp * 1000.);
|
||||
getIntegerParam(AndorShutterMode, &shutterMode);
|
||||
getIntegerParam(AndorShutterExTTL, &shutterExTTL);
|
||||
|
||||
if (command == ADShutterClosed) {
|
||||
shutterMode = AShutterClose;
|
||||
setIntegerParam(ADShutterStatus, ADShutterClosed);
|
||||
}
|
||||
else if (command == ADShutterOpen) {
|
||||
if (shutterMode == AShutterOpen) {
|
||||
setIntegerParam(ADShutterStatus, ADShutterOpen);
|
||||
}
|
||||
// No need to change shutterMode, we leave it alone and it shutter
|
||||
// will do correct thing, i.e. auto or open depending shutterMode
|
||||
}
|
||||
|
||||
try {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, SetShutter(%d,%d,%d,%d)\n",
|
||||
functionName, shutterExTTL, shutterMode, closeTime, openTime);
|
||||
checkStatus(SetShutter(shutterExTTL, shutterMode, closeTime, openTime));
|
||||
|
||||
} catch (const std::string &e) {
|
||||
cout << e << endl;
|
||||
status = asynError;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Function to check the return status of Andor SDK library functions.
|
||||
* @param returnStatus The return status of the SDK function
|
||||
@@ -661,30 +668,18 @@ void AndorCCD::statusTask(void)
|
||||
this->lock();
|
||||
//cout << " Status poll." << endl;
|
||||
|
||||
//Only read these if we are not acquiring data
|
||||
if (!mAcquiringData) {
|
||||
|
||||
//Read cooler status
|
||||
try {
|
||||
try {
|
||||
//Only read these if we are not acquiring data
|
||||
if (!mAcquiringData) {
|
||||
//Read cooler status
|
||||
checkStatus(IsCoolerOn(&value));
|
||||
status = setIntegerParam(AndorCoolerParam, value);
|
||||
} catch (const std::string &e) {
|
||||
cout << e << endl;
|
||||
setStringParam(AndorMessage, e.c_str());
|
||||
}
|
||||
|
||||
//Read temperature of CCD
|
||||
try {
|
||||
//Read temperature of CCD
|
||||
checkStatus(GetTemperature(&value));
|
||||
status = setDoubleParam(ADTemperatureActual, static_cast<double>(value));
|
||||
} catch (const std::string &e) {
|
||||
cout << e << endl;
|
||||
setStringParam(AndorMessage, e.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
//Read detector status (idle, acquiring, error, etc.)
|
||||
try {
|
||||
//Read detector status (idle, acquiring, error, etc.)
|
||||
checkStatus(GetStatus(&value));
|
||||
uvalue = static_cast<unsigned int>(value);
|
||||
if (uvalue == ASIdle) {
|
||||
@@ -733,7 +728,6 @@ asynStatus AndorCCD::setupAcquisition()
|
||||
int adcChannel;
|
||||
int triggerMode;
|
||||
int binX, binY, minX, minY, sizeX, sizeY, maxSizeX, maxSizeY;
|
||||
double acquireTime, acquirePeriod, accumulatePeriod;
|
||||
float acquireTimeAct, acquirePeriodAct, accumulatePeriodAct;
|
||||
int FKmode = 4;
|
||||
static const char *functionName = "AndorCCD::setupAcquisition";
|
||||
@@ -781,15 +775,12 @@ asynStatus AndorCCD::setupAcquisition()
|
||||
sizeY = maxSizeY - minY;
|
||||
setIntegerParam(ADSizeY, sizeY);
|
||||
}
|
||||
getDoubleParam(ADAcquireTime, &acquireTime);
|
||||
getDoubleParam(ADAcquirePeriod, &acquirePeriod);
|
||||
getDoubleParam(AndorAccumulatePeriod, &accumulatePeriod);
|
||||
|
||||
getIntegerParam(ADTriggerMode, &triggerMode);
|
||||
getIntegerParam(AndorAdcSpeed, &adcChannel);
|
||||
|
||||
// Unfortunately there does not seem to be a way to query the Andor SDK for the actual size of the image,
|
||||
// so we must compute it.
|
||||
// Unfortunately there does not seem to be a way to query the Andor SDK
|
||||
// for the actual size of the image, so we must compute it.
|
||||
setIntegerParam(NDArraySizeX, sizeX/binX);
|
||||
setIntegerParam(NDArraySizeY, sizeY/binY);
|
||||
setIntegerParam(NDArraySize, sizeX/binX * sizeY/binY * sizeof(at_32));
|
||||
@@ -811,8 +802,8 @@ asynStatus AndorCCD::setupAcquisition()
|
||||
checkStatus(SetImage(binX, binY, minX+1, minX+sizeX, minY+1, minY+sizeY));
|
||||
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, SetExposureTime(%f).\n", functionName, acquireTime);
|
||||
checkStatus(SetExposureTime((float)acquireTime));
|
||||
"%s, SetExposureTime(%f)\n", functionName, mAcquireTime);
|
||||
checkStatus(SetExposureTime(mAcquireTime));
|
||||
|
||||
switch (imageMode) {
|
||||
case ADImageSingle:
|
||||
@@ -829,8 +820,8 @@ asynStatus AndorCCD::setupAcquisition()
|
||||
functionName, numExposures);
|
||||
checkStatus(SetNumberAccumulations(numExposures));
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, SetAccumulationCycleTime(%f).\n", functionName, accumulatePeriod);
|
||||
checkStatus(SetAccumulationCycleTime((float)accumulatePeriod));
|
||||
"%s, SetAccumulationCycleTime(%f)\n", functionName, mAccumulatePeriod);
|
||||
checkStatus(SetAccumulationCycleTime(mAccumulatePeriod));
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -843,14 +834,14 @@ asynStatus AndorCCD::setupAcquisition()
|
||||
functionName, numExposures);
|
||||
checkStatus(SetNumberAccumulations(numExposures));
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, SetAccumulationCycleTime(%f).\n", functionName, accumulatePeriod);
|
||||
checkStatus(SetAccumulationCycleTime((float)accumulatePeriod));
|
||||
"%s, SetAccumulationCycleTime(%f)\n", functionName, mAccumulatePeriod);
|
||||
checkStatus(SetAccumulationCycleTime(mAccumulatePeriod));
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, SetNumberKinetics(%d).\n", functionName, numImages);
|
||||
"%s, SetNumberKinetics(%d)\n", functionName, numImages);
|
||||
checkStatus(SetNumberKinetics(numImages));
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, SetKineticCycleTime(%f).\n", functionName,acquirePeriod);
|
||||
checkStatus(SetKineticCycleTime((float)acquirePeriod));
|
||||
"%s, SetKineticCycleTime(%f)\n", functionName, mAcquirePeriod);
|
||||
checkStatus(SetKineticCycleTime(mAcquirePeriod));
|
||||
break;
|
||||
|
||||
case ADImageContinuous:
|
||||
@@ -858,8 +849,8 @@ asynStatus AndorCCD::setupAcquisition()
|
||||
"%s, SetAcquisitionMode(AARunTillAbort)\n", functionName);
|
||||
checkStatus(SetAcquisitionMode(AARunTillAbort));
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, SetKineticCycleTime(%f).\n", functionName,acquirePeriod);
|
||||
checkStatus(SetKineticCycleTime((float)acquirePeriod));
|
||||
"%s, SetKineticCycleTime(%f)\n", functionName, mAcquirePeriod);
|
||||
checkStatus(SetKineticCycleTime(mAcquirePeriod));
|
||||
break;
|
||||
|
||||
case AImageFastKinetics:
|
||||
@@ -867,9 +858,16 @@ asynStatus AndorCCD::setupAcquisition()
|
||||
"%s, SetAcquisitionMode(AAFastKinetics)\n", functionName);
|
||||
checkStatus(SetAcquisitionMode(AAFastKinetics));
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, SetFastKineticsEx(%d,%d,%f,%d,%d,%d,%d).\n",
|
||||
functionName, sizeY, numExposures, acquireTime, FKmode, binX, binY, minY);
|
||||
checkStatus(SetFastKineticsEx(sizeY, numImages, (float)acquireTime, FKmode, binX, binY, minY));
|
||||
"%s, SetImage(%d,%d,%d,%d,%d,%d)\n",
|
||||
functionName, binX, binY, 1, maxSizeX, 1, maxSizeY);
|
||||
checkStatus(SetImage(binX, binY, 1, maxSizeX, 1, maxSizeY));
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, SetFastKineticsEx(%d,%d,%f,%d,%d,%d,%d)\n",
|
||||
functionName, sizeY, numImages, mAcquireTime, FKmode, binX, binY, minY);
|
||||
checkStatus(SetFastKineticsEx(sizeY, numImages, mAcquireTime, FKmode, binX, binY, minY));
|
||||
setIntegerParam(NDArraySizeX, maxSizeX/binX);
|
||||
setIntegerParam(NDArraySizeY, maxSizeY/binY);
|
||||
setIntegerParam(NDArraySize, maxSizeX/binX * maxSizeY/binY * sizeof(at_32));
|
||||
break;
|
||||
}
|
||||
// Read the actual times
|
||||
@@ -881,9 +879,9 @@ asynStatus AndorCCD::setupAcquisition()
|
||||
"%s, GetAcquisitionTimings(exposure=%f, accumulate=%f, kinetic=%f\n",
|
||||
functionName, acquireTimeAct, accumulatePeriodAct, acquirePeriodAct);
|
||||
}
|
||||
setDoubleParam(AndorAcquireTimeActual, acquireTimeAct);
|
||||
setDoubleParam(AndorAcquirePeriodActual, acquirePeriodAct);
|
||||
setDoubleParam(AndorAccumulatePeriodActual, accumulatePeriodAct);
|
||||
setDoubleParam(ADAcquireTime, acquireTimeAct);
|
||||
setDoubleParam(ADAcquirePeriod, acquirePeriodAct);
|
||||
setDoubleParam(AndorAccumulatePeriod, accumulatePeriodAct);
|
||||
|
||||
|
||||
} catch (const std::string &e) {
|
||||
@@ -992,8 +990,6 @@ void AndorCCD::dataTask(void)
|
||||
getIntegerParam(ADNumImagesCounter, &numImagesCounter);
|
||||
numImagesCounter++;
|
||||
setIntegerParam(ADNumImagesCounter, numImagesCounter);
|
||||
// Save data if autosave is enabled
|
||||
if (autoSave) this->saveDataFrame();
|
||||
// If array callbacks are enabled then read data into NDArray, do callbacks
|
||||
if (arrayCallbacks) {
|
||||
epicsTimeGetCurrent(&startTime);
|
||||
@@ -1002,7 +998,14 @@ void AndorCCD::dataTask(void)
|
||||
dims[1] = sizeY;
|
||||
pArray = this->pNDArrayPool->alloc(nDims, dims, dataType, 0, NULL);
|
||||
// Read the oldest array
|
||||
status = GetOldestImage((at_32*)pArray->pData, sizeX*sizeY);
|
||||
// Is there still an image available?
|
||||
status = GetNumberNewImages(&firstImage, &lastImage);
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, GetNumberNewImages, status=%d, firstImage=%d, lastImage=%d\n",
|
||||
functionName, status, firstImage, lastImage);
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, GetOldestImage(%p, %d)\n", functionName, pArray->pData, sizeX*sizeY);
|
||||
checkStatus(GetOldestImage((at_32*)pArray->pData, sizeX*sizeY));
|
||||
/* Put the frame number and time stamp into the buffer */
|
||||
pArray->uniqueId = imageCounter;
|
||||
pArray->timeStamp = startTime.secPastEpoch + startTime.nsec / 1.e9;
|
||||
@@ -1012,17 +1015,22 @@ void AndorCCD::dataTask(void)
|
||||
/* Must release the lock here, or we can get into a deadlock, because we can
|
||||
* block on the plugin lock, and the plugin can be calling us */
|
||||
this->unlock();
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s:, first pixel value=%d\n", functionName, *(at_32*)pArray->pData);
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s:, calling array callbacks\n", functionName);
|
||||
doCallbacksGenericPointer(pArray, NDArrayData, 0);
|
||||
this->lock();
|
||||
pArray->release();
|
||||
}
|
||||
// Save data if autosave is enabled
|
||||
if (autoSave) this->saveDataFrame();
|
||||
callParamCallbacks();
|
||||
}
|
||||
} catch (const std::string &e) {
|
||||
cout << e << endl;
|
||||
errorString = const_cast<char *>(e.c_str());
|
||||
setStringParam(AndorMessage, errorString);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1044,8 +1052,6 @@ void AndorCCD::dataTask(void)
|
||||
*/
|
||||
void AndorCCD::saveDataFrame()
|
||||
{
|
||||
|
||||
at_32 *dP = NULL;
|
||||
char *errorString = NULL;
|
||||
int fileFormat;
|
||||
char fullFileName[MAX_FILENAME_LEN];
|
||||
@@ -1056,65 +1062,32 @@ void AndorCCD::saveDataFrame()
|
||||
// Fetch the file format
|
||||
getIntegerParam(NDFileFormat, &fileFormat);
|
||||
|
||||
////////////////////////////////////
|
||||
//Put data into waveforms, or save to file
|
||||
|
||||
if (fileFormat == AFFTIFF) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s, Saving data in TIFF format.\n", functionName);
|
||||
} else if (fileFormat == AFFBMP) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s, Saving data in BMP format.\n", functionName);
|
||||
} else if (fileFormat == AFFSIF) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s, Saving data in SIF format.\n", functionName);
|
||||
} else if (fileFormat == AFFEDF) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s, Saving data in EDF format.\n", functionName);
|
||||
} else if (fileFormat == AFFRAW) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s, Saving data in RAW format.\n", functionName);
|
||||
} else if (fileFormat == AFFTEXT) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s, Saving data in TEXT format.\n", functionName);
|
||||
}
|
||||
|
||||
this->createFileName(255, fullFileName);
|
||||
setStringParam(NDFullFileName, fullFileName);
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s, file name is %s.\n", functionName, fullFileName);
|
||||
getStringParam(AndorPalFileName, 255, palFilePath);
|
||||
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s, Saving data...\n", functionName);
|
||||
|
||||
try {
|
||||
if (fileFormat == AFFTIFF) {
|
||||
//checkStatus(SaveAsTiff(fullFileName, palFilePath, 1, 1)); //Didn't work
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, SaveAsTiffEx(%s, %s, 1, 1, 1)\n", functionName, fullFileName, palFilePath);
|
||||
checkStatus(SaveAsTiffEx(fullFileName, palFilePath, 1, 1, 1));
|
||||
} else if (fileFormat == AFFBMP) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, SaveAsBmp(%s, %s, 0, 0)\n", functionName, fullFileName, palFilePath);
|
||||
checkStatus(SaveAsBmp(fullFileName, palFilePath, 0, 0));
|
||||
} else if (fileFormat == AFFSIF) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, SaveAsSif(%s)\n", functionName, fullFileName);
|
||||
checkStatus(SaveAsSif(fullFileName));
|
||||
} else if (fileFormat == AFFEDF) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, SaveAsEDF(%s, 0)\n", functionName, fullFileName);
|
||||
checkStatus(SaveAsEDF(fullFileName, 0));
|
||||
} else if (fileFormat == AFFRAW) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"%s, SaveAsRaw(%s, 1)\n", functionName, fullFileName);
|
||||
checkStatus(SaveAsRaw(fullFileName, 1));
|
||||
} else if (fileFormat == AFFTEXT) {
|
||||
//Get data into buffer and dump to file
|
||||
checkStatus(GetMostRecentImage(mData, mDataSize));
|
||||
|
||||
ofstream datafile;
|
||||
datafile.open(fullFileName);
|
||||
|
||||
if (datafile.is_open()) {
|
||||
datafile << fullFileName << endl;
|
||||
|
||||
dP = mData;
|
||||
for (int d=0; d<mDataSize; ++d) {
|
||||
datafile << *dP << endl;
|
||||
//cout << "mData[" << d << "]: " << *dP << endl;
|
||||
dP++;
|
||||
}
|
||||
|
||||
datafile << flush;
|
||||
datafile.close();
|
||||
} else {
|
||||
setStringParam(AndorMessage, "ERROR: Could not open file.");
|
||||
}
|
||||
|
||||
}
|
||||
} catch (const std::string &e) {
|
||||
cout << e << endl;
|
||||
|
||||
Reference in New Issue
Block a user