Skip to content

Fix ExternalSeries acquisition when DataSource is None#95

Open
ericonr wants to merge 2 commits intoareaDetector:masterfrom
ericonr:externalseries-datasource-none
Open

Fix ExternalSeries acquisition when DataSource is None#95
ericonr wants to merge 2 commits intoareaDetector:masterfrom
ericonr:externalseries-datasource-none

Conversation

@ericonr
Copy link
Copy Markdown
Member

@ericonr ericonr commented Apr 16, 2026

Second commit is the main one, first one is just a small cleanup.

Reasoning is contained in the commit message fully.


Since this changes the logic to be shared for all trigger modes, I have managed to test it just fine for internal manual triggering. Will only be able to test it with external triggering tomorrow.

ericonr added 2 commits April 16, 2026 18:23
file->refCount is already set to 'parse+save' in the pollTask loop that
initializes all file objects.
The comment in the branch that handled TMExternalSeries and
TMExternalEnable trigger modes was misleading, since it claimed the
Eiger does not indicate when an acquisition is complete, even though the
detector state parameter is available.

This fix is important for the trigger modes above because otherwise they
won't ever complete acquisitions where DataSource is None, because
numImagesCounter won't be incremented. With this commit, such
acquisitions can be completed. This logic, however, isn't specific to
acquisitions with those trigger modes, so it can be applied to all of
them equally, which simplifies the implementation. It does mean delaying
disarming the detector for the other trigger modes until the acquisition
is over.

Moving the disarm command to after waiting for the poll and stream tasks
was considered, but that wouldn't have been enough if the driver was
used to simply control the detector (DataSource is None and SaveFiles is
Disabled). Doing this on top of the current commit, as a precaution, was
also considered, but it would delay disarming and user feedback further
for little gain.

For the implementation, it was necessary to check for three possible
states, because the detector state will be "configure" when sending the
acquisition commands, then, when waiting for triggers, will be "ready",
and ongoing acquisitions will indicate "acquiring".

The change to the verification loop also allowed us to remove the
epicsThreadSleep call and sleep while waiting for mStopEvent, because we
can simply relinquish the lock for its entire duration and for the
disarm command afterwards.
@ericonr ericonr force-pushed the externalseries-datasource-none branch from 46640c4 to d533dc0 Compare April 17, 2026 12:53
@ericonr
Copy link
Copy Markdown
Member Author

ericonr commented Apr 17, 2026

When I call mState->get(state), I get returned garbage. So my conditional isn't actually properly checking for the detector state.

If I understand the eigerParam API correctly, get simply forwards the value from the paramLibrary... How is this safe to access when not holding a lock? Does this mean that any such calls, including mFWState->get a little bit below my changes, depend on eigerStatus() having been called at a convenient time?

@MarkRivers
Copy link
Copy Markdown
Member

You can call mState->fetch() to read from the detector in the parameter library first. You should have the lock held when accessing the parameter library.

@MarkRivers
Copy link
Copy Markdown
Member

I think the code could be:

        string state;
        bool waitStatus;
        for(;;)
        {
            mState->fetch();
            mState->get(state);
            if (state != "configure" && state != "ready" && state != "acquire") break;
            unlock();
            waitStatus = mStopEvent.wait(0.1);
            lock();
            if (waitStatus) break;
           }
      }

@ericonr
Copy link
Copy Markdown
Member Author

ericonr commented Apr 17, 2026

Mark, that looks reasonable, thanks! I won't be able to test this on our detector until the 27th, unfortunately, so I will update the PR in the meantime but won't have results from it yet.

I was worried about the State_RBV and FWState_RBV PVs not being updated during acquisitions and that meaning something for using these parameters in the code. However, I have determined that was due to the following conditional in eigerStatus:

asynStatus eigerDetector::eigerStatus (void)
{
// If we are acquiring return immediately
int acquiring;
getIntegerParam(ADAcquire, &acquiring);
if (acquiring)
return asynSuccess;

I wonder if this behavior could be made more flexible... as is, I only ever see State_RBV as idle, so it can't be used to debug the IOC/detector.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants