Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 65 additions & 44 deletions andorApp/src/andorCCD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,15 @@ AndorCCD::AndorCCD(const char *portName, const char *installPath, int cameraSeri
checkStatus(SetReadMode(ARImage));
checkStatus(SetImage(binX, binY, minX+1, minX+sizeX, minY+1, minY+sizeY));
checkStatus(GetShutterMinTimes(&mMinShutterCloseTime, &mMinShutterOpenTime));
checkStatus(GetFastestRecommendedVSSpeed(&mVSIndex, &mVSPeriod));
try {
checkStatus(GetFastestRecommendedVSSpeed(&mVSIndex, &mVSPeriod));
} catch (const std::string &e) {
asynPrint(pasynUserSelf, ASYN_TRACE_WARNING,
"%s:%s: GetFastestRecommendedVSSpeed is not available: %lu: %s\n",
driverName, functionName, e.c_str());
mVSIndex = -1;
mVSPeriod = 0.0f;
}
Comment thread
eddybl marked this conversation as resolved.
mCapabilities.ulSize = sizeof(mCapabilities);
checkStatus(GetCapabilities(&mCapabilities));

Expand Down Expand Up @@ -529,18 +537,23 @@ void AndorCCD::setupVerticalShiftPeriods()
int i, numVSPeriods;
float VSPeriod;
AndorVSPeriod_t *pPeriod = mVSPeriods;
static const char *functionName = "setupVerticalShiftPeriods";

mNumVSPeriods = 0;
checkStatus(GetNumberVSSpeeds(&numVSPeriods));
for (i=0; i<numVSPeriods; i++) {
checkStatus(GetVSSpeed(i, &VSPeriod));
pPeriod->Index = i;
pPeriod->Period = VSPeriod;
epicsSnprintf(pPeriod->EnumString, MAX_ENUM_STRING_SIZE,
"%.2f us", VSPeriod);
mNumVSPeriods++;
if (mNumVSPeriods >= MAX_VS_PERIODS) return;
pPeriod++;
unsigned int error = GetNumberVSSpeeds(&mNumVSPeriods);
if (error == DRV_SUCCESS && mNumVSPeriods > 0) {
for (i=0; i<numVSPeriods; i++) {
Comment on lines +543 to +545
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need the mNumVSPeriods > 0 check in your if, since the for with i<numVSPeriods already accounts for that. That said, why are you moving the code to use mNumVSPeriods?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the catch, I adjusted the if condition.

Not sure I understand the question. Referring to lines 624ff? The idea is that if mNumVSPeriods is zero, we want to avoid calling checkStatus(GetFastestRecommendedVSSpeed(&vsIndex, &vsPeriod)); as this will again throw an exception. The altneratives would be to either adjust checkStatus() to not fail for "feature not available" or use another try-catch block

Copy link
Copy Markdown
Member

@ericonr ericonr Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I mean is that the previous code was doing

checkStatus(GetNumberVSSpeeds(&numVSPeriods));
    for (i=0; i<numVSPeriods; i++) {

But your version is now doing mNumVSPeriods, which seems to be wrong, due to the mNumVSPeriods++; statement in the loop, and numVSPeriods being uninitialized but still used in the loop.

checkStatus(GetVSSpeed(i, &VSPeriod));
pPeriod->Index = i;
pPeriod->Period = VSPeriod;
epicsSnprintf(pPeriod->EnumString, MAX_ENUM_STRING_SIZE,
"%.2f us", VSPeriod);
mNumVSPeriods++;
if (mNumVSPeriods >= MAX_VS_PERIODS) return;
pPeriod++;
}
} else {
printf("%s:%s: unable to set camera parameters\n", driverName, functionName);
}
}

Expand Down Expand Up @@ -608,15 +621,19 @@ void AndorCCD::report(FILE *fp, int details)
mPreAmpGains[i].EnumValue, mPreAmpGains[i].Gain);
}

fprintf(fp, " Vertical Shift Periods available: %d\n", mNumVSPeriods);
for (i=0; i<mNumVSPeriods; i++) {
fprintf(fp, " Index=%d, Period=%f [us per pixel shift]\n",
mVSPeriods[i].EnumValue, mVSPeriods[i].Period);
if (mNumVSPeriods == 0) {
fprintf(fp, " No Vertical Shift Periods available\n");
} else {
fprintf(fp, " Vertical Shift Periods available: %d\n", mNumVSPeriods);
for (i=0; i<mNumVSPeriods; i++) {
fprintf(fp, " Index=%d, Period=%f [us per pixel shift]\n",
mVSPeriods[i].EnumValue, mVSPeriods[i].Period);
}
fprintf(fp, " Fastest recommended Vertical Shift Period:\n");
checkStatus(GetFastestRecommendedVSSpeed(&vsIndex, &vsPeriod));
fprintf(fp, " Index=%d, Period=%f [us per pixel shift]\n", vsIndex, vsPeriod);
}
fprintf(fp, " Fastest recommended Vertical Shift Period:\n");
checkStatus(GetFastestRecommendedVSSpeed(&vsIndex, &vsPeriod));
fprintf(fp, " Index=%d, Period=%f [us per pixel shift]\n", vsIndex, vsPeriod);


fprintf(fp, " Capabilities\n");
fprintf(fp, " AcqModes=0x%X\n", (int)mCapabilities.ulAcqModes);
fprintf(fp, " ReadModes=0x%X\n", (int)mCapabilities.ulReadModes);
Expand Down Expand Up @@ -904,25 +921,25 @@ void AndorCCD::setupTrackDefn(int minX, int sizeX, int binX)
setIntegerParam(NDArraySizeY, mMultiTrack.DataHeight());
for (size_t TrackNo = 0; TrackNo < mMultiTrack.size(); TrackNo++)
{
/*
Each track must be defined by a group of six integers.
- The top and bottom positions of the tracks.
- The left and right positions for the area of interest within each track
- The horizontal and vertical binning for each track. */
/*
Andor use 1-based exclusive co-ordinates.
e.g. from SDK manual:
1 2 1 1024 1 1
3 4 1 1024 1 1
5 6 1 1024 1 1
7 8 1 1024 1 1
9 10 1 1024 1 1 */
TrackDefn[TrackNo * 6 + 0] = mMultiTrack.TrackStart(TrackNo) + 1;
TrackDefn[TrackNo * 6 + 1] = mMultiTrack.TrackEnd(TrackNo) + 2; // CCDMultiTrack uses 0-based inlcusive co-ordinates.
TrackDefn[TrackNo * 6 + 2] = minX + 1;
TrackDefn[TrackNo * 6 + 3] = minX + sizeX;
TrackDefn[TrackNo * 6 + 4] = binX;
TrackDefn[TrackNo * 6 + 5] = mMultiTrack.TrackBin(TrackNo);
/*
Each track must be defined by a group of six integers.
- The top and bottom positions of the tracks.
- The left and right positions for the area of interest within each track
- The horizontal and vertical binning for each track. */
/*
Andor use 1-based exclusive co-ordinates.
e.g. from SDK manual:
1 2 1 1024 1 1
3 4 1 1024 1 1
5 6 1 1024 1 1
7 8 1 1024 1 1
9 10 1 1024 1 1 */
TrackDefn[TrackNo * 6 + 0] = mMultiTrack.TrackStart(TrackNo) + 1;
TrackDefn[TrackNo * 6 + 1] = mMultiTrack.TrackEnd(TrackNo) + 2; // CCDMultiTrack uses 0-based inlcusive co-ordinates.
TrackDefn[TrackNo * 6 + 2] = minX + 1;
TrackDefn[TrackNo * 6 + 3] = minX + sizeX;
TrackDefn[TrackNo * 6 + 4] = binX;
TrackDefn[TrackNo * 6 + 5] = mMultiTrack.TrackBin(TrackNo);
}
checkStatus(SetCustomTrackHBin(binX));
checkStatus(SetComplexImage(int(TrackDefn.size() / ValuesPerTrack), &TrackDefn[0]));
Expand Down Expand Up @@ -1407,13 +1424,17 @@ asynStatus AndorCCD::setupAcquisition()
driverName, functionName, frameTransferMode);
checkStatus(SetFrameTransferMode(frameTransferMode));

asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
"%s:%s:, SetVSSpeed(%d)\n",
driverName, functionName, verticalShiftPeriod);
checkStatus(SetVSSpeed(verticalShiftPeriod));
float s = 0.0f;
unsigned int error = GetVSSpeed(0, &s);
if (error == DRV_SUCCESS ) {
Comment thread
eddybl marked this conversation as resolved.
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
"%s:%s:, SetVSSpeed(%d)\n",
driverName, functionName, verticalShiftPeriod);
checkStatus(SetVSSpeed(verticalShiftPeriod));
}

if ((mCapabilities.ulSetFunctions & AC_SETFUNCTION_VSAMPLITUDE) != 0)
{
if ((mCapabilities.ulSetFunctions & AC_SETFUNCTION_VSAMPLITUDE) != 0)
{
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
"%s:%s:, SetVSAmplitude(%d)\n",
driverName, functionName, verticalShiftAmplitude);
Expand Down