python-microscope / microscope

Python library for control of microscope devices, supporting hardware triggers and distribution of devices over the network for performance and flexibility.
https://www.python-microscope.org
GNU General Public License v3.0
73 stars 42 forks source link

Andor EMCCD interframe timing issue #203

Closed iandobbie closed 3 years ago

iandobbie commented 3 years ago

The Andor atmcd driver returns incorrect info from the get_cycle_time call. The original pyAndor code that Mick wrote had the following code in it....

def get_min_time_between_exposures(self):
    (exposure, accumulate, kinetics) = self.get_acquisition_timings()
    if self.acquisition_mode in [1, 5, 7]:
        # single exposure or run until abort
        t = self.get_read_out_time()
        # Assume worst-case floating point underestimation.
        t += EPSILON * t
        if not self.settings.get('fastTrigger'):
            t_kc = self.get_keep_clean_time()
            # Assume worst-case floating point underestimation.
            t_kc += EPSILON * t_kc
            t += t_kc
        return t
    elif self.acquisition_mode == 2:
        # accumulate mode
        return accumulate - exposure
    elif self.acquisition_mode in [3, 4]:
        # kinetics mode
        return kinetics - exposure
    else:
        # acquisition mode not configured.
        # Return 100ms, although should consider raising an exception here.
        return 0.1

Whereas the current microscope code has:

def get_cycle_time(self):
    """Determine the minimum time between exposures."""
    with self:
        exposure, accumulate, kinetic = GetAcquisitionTimings()
        readout = GetReadOutTime()
    return exposure + readout

The issue is that the camera is permanently set into mode 3 with the cone in _do_enable SetAcquisitionMode(AcquisitionMode.RUNTILLABORT) There is no other acquisition mode setting code.

So the value should be kinetic, not exposure+readout. exposure+readout is several ms too short which can be seen by using the camera arm signal on an oscilloscope. This is not an issue with multiple non-simultaneous exposures as the interleaved exposures allow enough extra time.

iandobbie commented 3 years ago

Checking the code, RUNTILLABORT is actually set to mode 5, this obviously needs more checking, however when I use the kinetic parameter the timing is just correct with about 150us between rearming and trigger a slight jitter of 10-15 us.

iandobbie commented 3 years ago

The andor manual (http://irtfweb.ifa.hawaii.edu/~moris/user/Andor_Ixon_Ultra/iXon%20Ultra%20897%20Hardware%20Guide%201.3.pdf) says:

As at least one Keep Clean Cycle is performed between each exposure, the minimum exposure time is no longer set by the time to read out the image.

This is the critical factor I think and is not taken account of int he current code.

carandraug commented 3 years ago

Both implementations were done by Mick so it's odd that the later one is the simpler and "incorrect?". I've looked into the logs but the commit message where get_cycle_time was implemented in Microscope (da4c1aae935be4800) but it only says "AndorAtmcd - WIP ... still more to do".

iandobbie commented 3 years ago

Obviously we need to implement the last bits of it, It seems like the older code has all the needed details. I think it should be very easy to reimplement the orginal code to cover all acquisition modes although we currently only seem to utilise one.

mickp commented 3 years ago

There was a calculation error in a version of the Andor SDK - the earlier implementation was what I found worked for that version. I reported it to Andor and they rolled a new firmware which resolved the issue, so I then simplified our code.

On Mon, 19 Apr 2021 at 09:27, Ian Dobbie @.***> wrote:

Obviously we need to implement the last bits of it, It seems like the older code has all the needed details. I think it should be very easy to reimplement the orginal code to cover all acquisition modes although we currently only seem to utilise one.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/python-microscope/microscope/issues/203#issuecomment-822604300, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABHGTL2IZRADXATKZNWX2T3TJRKWRANCNFSM43FVF5FQ .

--


Mick Phillips


iandobbie commented 3 years ago

However this is still no enough as I said above

As at least one Keep Clean Cycle is performed between each exposure, the minimum exposure time is no longer set by the time to read out the image.

So just adding the exposure time and the readout time leaves the cycle time short, and therefore missed triggers.

iandobbie commented 3 years ago

fixed by using kinetic timing value. This worked for the collection mode used which cockpit appears not to change so committed the fix and closing this issue.