From 86153c20ca59eec5f1cbf25cdc2bc1fcb90fad2e Mon Sep 17 00:00:00 2001 From: Benjamin Bradnick Date: Wed, 19 Feb 2020 11:15:00 +0000 Subject: [PATCH 1/6] Now set ADAcquire parameter to 1 after detector acquisition has started --- andorApp/src/andorCCD.cpp | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/andorApp/src/andorCCD.cpp b/andorApp/src/andorCCD.cpp index 7efb253..cb32783 100755 --- a/andorApp/src/andorCCD.cpp +++ b/andorApp/src/andorCCD.cpp @@ -627,16 +627,18 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value) asynStatus status = asynSuccess; static const char *functionName = "writeInt32"; - //Set in param lib so the user sees a readback straight away. Save a backup in case of errors. + // Set in param lib so the user sees a readback straight away. Save a backup in case of errors. getIntegerParam(function, &oldValue); status = setIntegerParam(function, value); if (function == ADAcquire) { getIntegerParam(ADStatus, &adstatus); + // Temporarily set ADAcquire back to 0 until Acquisition is started by dataTask + status = setIntegerParam(ADAcquire, 0); if (value && (adstatus == ADStatusIdle)) { try { mAcquiringData = 1; - //We send an event at the bottom of this function. + // We send an event at the bottom of this function. } catch (const std::string &e) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: %s\n", @@ -724,9 +726,6 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value) status = ADDriver::writeInt32(pasynUser, value); } - //For a successful write, clear the error message. - setStringParam(AndorMessage, " "); - /* Do callbacks so higher layers see any changes */ callParamCallbacks(); @@ -737,18 +736,22 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value) asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s:, Sending dataEvent to dataTask ...\n", driverName, functionName); - //Also signal the data readout thread + // Also signal the data readout thread epicsEventSignal(dataEvent); } - if (status) + if (status) { asynPrint(pasynUser, ASYN_TRACE_ERROR, "%s:%s: error, status=%d function=%d, value=%d\n", driverName, functionName, status, function, value); - else + } + else { asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s:%s: function=%d, value=%d\n", driverName, functionName, function, value); + /* For a successful write, clear the error message. */ + setStringParam(AndorMessage, " "); + } return status; } @@ -1479,7 +1482,7 @@ void AndorCCD::dataTask(void) epicsTimeStamp startTime; NDArray *pArray; int autoSave; - int readOutMode; + int readOutMode; static const char *functionName = "dataTask"; printf("%s:%s: Data thread started...\n", driverName, functionName); @@ -1515,13 +1518,16 @@ void AndorCCD::dataTask(void) driverName, functionName); checkStatus(StartAcquisition()); acquiring = 1; + asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, + "%s:%s: Acquisition started\n", + driverName, functionName); } catch (const std::string &e) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: %s\n", driverName, functionName, e.c_str()); continue; } - //Read some parameters + // Read some parameters getIntegerParam(NDDataType, &itemp); dataType = (NDDataType_t)itemp; getIntegerParam(NDAutoSave, &autoSave); getIntegerParam(NDArrayCallbacks, &arrayCallbacks); @@ -1531,6 +1537,9 @@ void AndorCCD::dataTask(void) setIntegerParam(ADNumImagesCounter, 0); setIntegerParam(ADNumExposuresCounter, 0); callParamCallbacks(); + // Set ADAcquire to 1 + setIntegerParam(ADAcquire, 1); + callParamCallbacks(); } else { asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s:, Data thread is running but main thread thinks we are not acquiring.\n", @@ -1579,8 +1588,8 @@ void AndorCCD::dataTask(void) dims[0] = sizeX; dims[1] = sizeY; pArray = this->pNDArrayPool->alloc(nDims, dims, dataType, 0, NULL); - if (readOutMode == ARRandomTrack) - mMultiTrack.storeTrackAttributes(pArray->pAttributeList); + if (readOutMode == ARRandomTrack) + mMultiTrack.storeTrackAttributes(pArray->pAttributeList); // Read the oldest array // Is there still an image available? status = GetNumberNewImages(&firstImage, &lastImage); From 45b8b8af12c29f136c7136ab8382c1def5b9dcae Mon Sep 17 00:00:00 2001 From: Benjamin Bradnick Date: Thu, 20 Feb 2020 13:15:44 +0000 Subject: [PATCH 2/6] Revert "Now set ADAcquire parameter to 1 after detector acquisition has started" This reverts commit 86153c20ca59eec5f1cbf25cdc2bc1fcb90fad2e. --- andorApp/src/andorCCD.cpp | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/andorApp/src/andorCCD.cpp b/andorApp/src/andorCCD.cpp index cb32783..7efb253 100755 --- a/andorApp/src/andorCCD.cpp +++ b/andorApp/src/andorCCD.cpp @@ -627,18 +627,16 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value) asynStatus status = asynSuccess; static const char *functionName = "writeInt32"; - // Set in param lib so the user sees a readback straight away. Save a backup in case of errors. + //Set in param lib so the user sees a readback straight away. Save a backup in case of errors. getIntegerParam(function, &oldValue); status = setIntegerParam(function, value); if (function == ADAcquire) { getIntegerParam(ADStatus, &adstatus); - // Temporarily set ADAcquire back to 0 until Acquisition is started by dataTask - status = setIntegerParam(ADAcquire, 0); if (value && (adstatus == ADStatusIdle)) { try { mAcquiringData = 1; - // We send an event at the bottom of this function. + //We send an event at the bottom of this function. } catch (const std::string &e) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: %s\n", @@ -726,6 +724,9 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value) status = ADDriver::writeInt32(pasynUser, value); } + //For a successful write, clear the error message. + setStringParam(AndorMessage, " "); + /* Do callbacks so higher layers see any changes */ callParamCallbacks(); @@ -736,22 +737,18 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value) asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s:, Sending dataEvent to dataTask ...\n", driverName, functionName); - // Also signal the data readout thread + //Also signal the data readout thread epicsEventSignal(dataEvent); } - if (status) { + if (status) asynPrint(pasynUser, ASYN_TRACE_ERROR, "%s:%s: error, status=%d function=%d, value=%d\n", driverName, functionName, status, function, value); - } - else { + else asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s:%s: function=%d, value=%d\n", driverName, functionName, function, value); - /* For a successful write, clear the error message. */ - setStringParam(AndorMessage, " "); - } return status; } @@ -1482,7 +1479,7 @@ void AndorCCD::dataTask(void) epicsTimeStamp startTime; NDArray *pArray; int autoSave; - int readOutMode; + int readOutMode; static const char *functionName = "dataTask"; printf("%s:%s: Data thread started...\n", driverName, functionName); @@ -1518,16 +1515,13 @@ void AndorCCD::dataTask(void) driverName, functionName); checkStatus(StartAcquisition()); acquiring = 1; - asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, - "%s:%s: Acquisition started\n", - driverName, functionName); } catch (const std::string &e) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: %s\n", driverName, functionName, e.c_str()); continue; } - // Read some parameters + //Read some parameters getIntegerParam(NDDataType, &itemp); dataType = (NDDataType_t)itemp; getIntegerParam(NDAutoSave, &autoSave); getIntegerParam(NDArrayCallbacks, &arrayCallbacks); @@ -1537,9 +1531,6 @@ void AndorCCD::dataTask(void) setIntegerParam(ADNumImagesCounter, 0); setIntegerParam(ADNumExposuresCounter, 0); callParamCallbacks(); - // Set ADAcquire to 1 - setIntegerParam(ADAcquire, 1); - callParamCallbacks(); } else { asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s:, Data thread is running but main thread thinks we are not acquiring.\n", @@ -1588,8 +1579,8 @@ void AndorCCD::dataTask(void) dims[0] = sizeX; dims[1] = sizeY; pArray = this->pNDArrayPool->alloc(nDims, dims, dataType, 0, NULL); - if (readOutMode == ARRandomTrack) - mMultiTrack.storeTrackAttributes(pArray->pAttributeList); + if (readOutMode == ARRandomTrack) + mMultiTrack.storeTrackAttributes(pArray->pAttributeList); // Read the oldest array // Is there still an image available? status = GetNumberNewImages(&firstImage, &lastImage); From 323eece01c0e511e627a7b7bd647d67ce8653758 Mon Sep 17 00:00:00 2001 From: Benjamin Bradnick Date: Thu, 20 Feb 2020 13:19:40 +0000 Subject: [PATCH 3/6] Cleaned up comments --- andorApp/src/andorCCD.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/andorApp/src/andorCCD.cpp b/andorApp/src/andorCCD.cpp index 7efb253..495f9a9 100755 --- a/andorApp/src/andorCCD.cpp +++ b/andorApp/src/andorCCD.cpp @@ -1479,7 +1479,7 @@ void AndorCCD::dataTask(void) epicsTimeStamp startTime; NDArray *pArray; int autoSave; - int readOutMode; + int readOutMode; static const char *functionName = "dataTask"; printf("%s:%s: Data thread started...\n", driverName, functionName); @@ -1490,7 +1490,7 @@ void AndorCCD::dataTask(void) errorString = NULL; - //Wait for event from main thread to signal that data acquisition has started. + // Wait for event from main thread to signal that data acquisition has started. this->unlock(); status = epicsEventWait(dataEvent); if (mExiting) @@ -1500,7 +1500,7 @@ void AndorCCD::dataTask(void) driverName, functionName); this->lock(); - //Sanity check that main thread thinks we are acquiring data + // Sanity check that main thread thinks we are acquiring data if (mAcquiringData) { try { status = setupAcquisition(); @@ -1521,7 +1521,7 @@ void AndorCCD::dataTask(void) driverName, functionName, e.c_str()); continue; } - //Read some parameters + // Read some parameters getIntegerParam(NDDataType, &itemp); dataType = (NDDataType_t)itemp; getIntegerParam(NDAutoSave, &autoSave); getIntegerParam(NDArrayCallbacks, &arrayCallbacks); @@ -1579,8 +1579,8 @@ void AndorCCD::dataTask(void) dims[0] = sizeX; dims[1] = sizeY; pArray = this->pNDArrayPool->alloc(nDims, dims, dataType, 0, NULL); - if (readOutMode == ARRandomTrack) - mMultiTrack.storeTrackAttributes(pArray->pAttributeList); + if (readOutMode == ARRandomTrack) + mMultiTrack.storeTrackAttributes(pArray->pAttributeList); // Read the oldest array // Is there still an image available? status = GetNumberNewImages(&firstImage, &lastImage); @@ -1638,14 +1638,14 @@ void AndorCCD::dataTask(void) ADDriver::setShutter(ADShutterClosed); } - //Now clear main thread flag + // Now clear main thread flag mAcquiringData = 0; setIntegerParam(ADAcquire, 0); //setIntegerParam(ADStatus, 0); //Dont set this as the status thread sets it. /* Call the callbacks to update any changes */ callParamCallbacks(); - } //End of loop + } // End of loop mExited++; this->unlock(); } @@ -1934,7 +1934,7 @@ done: } -//C utility functions to tie in with EPICS +// C utility functions to tie in with EPICS static void andorStatusTaskC(void *drvPvt) { From d2320b8b762473cb5be713eae833b94fdcef50e2 Mon Sep 17 00:00:00 2001 From: Benjamin Bradnick Date: Fri, 21 Feb 2020 09:03:40 +0000 Subject: [PATCH 4/6] Acquisition setup and start now occur in writeInt32 --- andorApp/src/andorCCD.cpp | 84 +++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 43 deletions(-) diff --git a/andorApp/src/andorCCD.cpp b/andorApp/src/andorCCD.cpp index 495f9a9..90eb271 100755 --- a/andorApp/src/andorCCD.cpp +++ b/andorApp/src/andorCCD.cpp @@ -311,9 +311,9 @@ AndorCCD::AndorCCD(const char *portName, const char *installPath, int cameraSeri return; } - //Define the polling periods for the status thread. - mPollingPeriod = 0.2; //seconds - mFastPollingPeriod = 0.05; //seconds + // Define the polling periods for the status thread. + mPollingPeriod = 0.2; // seconds + mFastPollingPeriod = 0.05; // seconds mAcquiringData = 0; @@ -627,7 +627,7 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value) asynStatus status = asynSuccess; static const char *functionName = "writeInt32"; - //Set in param lib so the user sees a readback straight away. Save a backup in case of errors. + // Set in param lib so the user sees a readback straight away. Save a backup in case of errors. getIntegerParam(function, &oldValue); status = setIntegerParam(function, value); @@ -635,13 +635,28 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value) getIntegerParam(ADStatus, &adstatus); if (value && (adstatus == ADStatusIdle)) { try { + // Set up acquisition mAcquiringData = 1; - //We send an event at the bottom of this function. + status = setupAcquisition(); + if (status != asynSuccess) throw std::string("Setup acquisition failed"); + // Open the shutter if we control it + int adShutterMode; + getIntegerParam(ADShutterMode, &adShutterMode); + if (adShutterMode == ADShutterModeEPICS) { + ADDriver::setShutter(ADShutterOpen); + } + // Start acquisition + asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, + "%s:%s:, StartAcquisition()\n", + driverName, functionName); + checkStatus(StartAcquisition()); + // Reset the counters + setIntegerParam(ADNumImagesCounter, 0); + setIntegerParam(ADNumExposuresCounter, 0); } catch (const std::string &e) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: %s\n", driverName, functionName, e.c_str()); - status = asynError; } } if (!value && (adstatus != ADStatusIdle)) { @@ -724,7 +739,7 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value) status = ADDriver::writeInt32(pasynUser, value); } - //For a successful write, clear the error message. + // For a successful write, clear the error message. setStringParam(AndorMessage, " "); /* Do callbacks so higher layers see any changes */ @@ -737,7 +752,7 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value) asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s:, Sending dataEvent to dataTask ...\n", driverName, functionName); - //Also signal the data readout thread + // Also signal the data readout thread epicsEventSignal(dataEvent); } @@ -816,7 +831,7 @@ asynStatus AndorCCD::writeFloat64(asynUser *pasynUser, epicsFloat64 value) status = ADDriver::writeFloat64(pasynUser, value); } - //For a successful write, clear the error message. + // For a successful write, clear the error message. setStringParam(AndorMessage, " "); /* Do callbacks so higher layers see any changes */ @@ -1063,7 +1078,7 @@ void AndorCCD::statusTask(void) printf("%s:%s: Status thread started...\n", driverName, functionName); while(!mExiting) { - //Read timeout for polling freq. + // Read timeout for polling freq. this->lock(); if (forcedFastPolls > 0) { timeout = mFastPollingPeriod; @@ -1082,10 +1097,10 @@ void AndorCCD::statusTask(void) asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s: Got status event\n", driverName, functionName); - //We got an event, rather than a timeout. This is because other software - //knows that data has arrived, or device should have changed state (parameters changed, etc.). - //Force a minimum number of fast polls, because the device status - //might not have changed in the first few polls + // We got an event, rather than a timeout. This is because other software + // knows that data has arrived, or device should have changed state (parameters changed, etc.). + // Force a minimum number of fast polls, because the device status + // might not have changed in the first few polls forcedFastPolls = 5; } @@ -1093,17 +1108,17 @@ void AndorCCD::statusTask(void) this->lock(); try { - //Only read these if we are not acquiring data + // Only read these if we are not acquiring data if (!mAcquiringData) { - //Read cooler status + // Read cooler status checkStatus(IsCoolerOn(&value)); status = setIntegerParam(AndorCoolerParam, value); - //Read temperature of CCD + // Read temperature of CCD checkStatus(GetTemperatureF(&temperature)); status = setDoubleParam(ADTemperatureActual, temperature); } - //Read detector status (idle, acquiring, error, etc.) + // Read detector status (idle, acquiring, error, etc.) checkStatus(GetStatus(&value)); uvalue = static_cast(value); if (uvalue == ASIdle) { @@ -1142,7 +1157,7 @@ void AndorCCD::statusTask(void) callParamCallbacks(); this->unlock(); - } //End of loop + } // End of loop asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s: Status thread exiting ...\n", driverName, functionName); @@ -1502,39 +1517,21 @@ void AndorCCD::dataTask(void) // Sanity check that main thread thinks we are acquiring data if (mAcquiringData) { - try { - status = setupAcquisition(); - if (status != asynSuccess) continue; - getIntegerParam(ADShutterMode, &adShutterMode); - getIntegerParam(AndorReadOutMode, &readOutMode); - if (adShutterMode == ADShutterModeEPICS) { - ADDriver::setShutter(ADShutterOpen); - } - asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, - "%s:%s:, StartAcquisition()\n", - driverName, functionName); - checkStatus(StartAcquisition()); - acquiring = 1; - } catch (const std::string &e) { - asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, - "%s:%s: %s\n", - driverName, functionName, e.c_str()); - continue; - } // Read some parameters + getIntegerParam(ADShutterMode, &adShutterMode); + getIntegerParam(AndorReadOutMode, &readOutMode); getIntegerParam(NDDataType, &itemp); dataType = (NDDataType_t)itemp; getIntegerParam(NDAutoSave, &autoSave); getIntegerParam(NDArrayCallbacks, &arrayCallbacks); getIntegerParam(NDArraySizeX, &sizeX); getIntegerParam(NDArraySizeY, &sizeY); - // Reset the counters - setIntegerParam(ADNumImagesCounter, 0); - setIntegerParam(ADNumExposuresCounter, 0); - callParamCallbacks(); + // Set acquiring to 1 + acquiring = 1; } else { asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s:, Data thread is running but main thread thinks we are not acquiring.\n", driverName, functionName); + // Set acquiring to 0 acquiring = 0; } @@ -1633,7 +1630,8 @@ void AndorCCD::dataTask(void) } } } - + + // Close the shutter if we are controlling it if (adShutterMode == ADShutterModeEPICS) { ADDriver::setShutter(ADShutterClosed); } From 30bc883ea5566c4a3077b5132fc80f8b20dedb3f Mon Sep 17 00:00:00 2001 From: Benjamin Bradnick Date: Fri, 21 Feb 2020 09:09:38 +0000 Subject: [PATCH 5/6] Re-add setting status to asynError when starting acquisition throws exception --- andorApp/src/andorCCD.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/andorApp/src/andorCCD.cpp b/andorApp/src/andorCCD.cpp index 90eb271..386bef6 100755 --- a/andorApp/src/andorCCD.cpp +++ b/andorApp/src/andorCCD.cpp @@ -657,6 +657,7 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value) asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: %s\n", driverName, functionName, e.c_str()); + status = asynError; } } if (!value && (adstatus != ADStatusIdle)) { @@ -739,9 +740,6 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value) status = ADDriver::writeInt32(pasynUser, value); } - // For a successful write, clear the error message. - setStringParam(AndorMessage, " "); - /* Do callbacks so higher layers see any changes */ callParamCallbacks(); @@ -764,6 +762,8 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value) asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s:%s: function=%d, value=%d\n", driverName, functionName, function, value); + // For a successful write, clear the error message. + setStringParam(AndorMessage, " "); return status; } From ee79be3f5a3d354a03bba14ee60ec42127546a4a Mon Sep 17 00:00:00 2001 From: Benjamin Bradnick Date: Wed, 26 Feb 2020 14:12:54 +0000 Subject: [PATCH 6/6] Re-added comment for dataTask event --- andorApp/src/andorCCD.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/andorApp/src/andorCCD.cpp b/andorApp/src/andorCCD.cpp index 386bef6..9eda11f 100755 --- a/andorApp/src/andorCCD.cpp +++ b/andorApp/src/andorCCD.cpp @@ -634,6 +634,7 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value) if (function == ADAcquire) { getIntegerParam(ADStatus, &adstatus); if (value && (adstatus == ADStatusIdle)) { + // Start the acqusition here, then send an event to the dataTask at the end of this function try { // Set up acquisition mAcquiringData = 1;