-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[TRCL-570][feat] introduce startScan Event to synchronize CCD with e-beam during SPARC acq #3027
base: master
Are you sure you want to change the base?
Conversation
No code ever used this functionality. The semnidaq has something a little similar, but it's a hardware event. So it actually could even brinkg confusion. Now that we'll add another Event, remove this code.
Introduce a new (and almost first) software Event on the e-beam scanners: startScan. It is emitted at the very beginning of the first frame of a scan. If a scan acquires multiple frames, startScan is emitted just once. This will be used for better software synchronization of SPARC acquisitions.
… e-beam From the momement that the acquisition ask the e-beam scanner to start and the e-beam is actually at the right position, it takes *some* time. It's in the order of a few ms. So far, the only e-beam scanner was semcomedi, and it was (surprisingly) constant in terms of time. It would take between 2 and 5 ms. So it was good enough to just always wait 5ms. We now also have semnidaq, and the NI-DAQ library introduces a lot longer latency. While it can be as "fast" as 10ms, it sometimes takes 40ms to start a scan. There are probably ways to make it a little faster, but it's unlikely it will be possible to always keep all scanners < 5ms. => Use a new Event, startScan, for the e-beam scanner to report the e-beam is ready. Then, we can use it to directly start a CCD acquisition.
self.assertEqual(evt_counter.count, 1) | ||
self.scanner.startScan.unsubscribe(evt_counter) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to remove the extra space between the functions
@@ -1887,26 +1888,10 @@ def _acquireImage(self, n, px_idx, img_time, sem_time, | |||
raise CancelledError() | |||
|
|||
# subscribe to _subscribers | |||
# As soon as the e-beam start scanning (which can take a couple of ms), the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# As soon as the e-beam start scanning (which can take a couple of ms), the | |
# As soon as the e-beam starts scanning (which can take a couple of ms), the |
@@ -1887,26 +1888,10 @@ def _acquireImage(self, n, px_idx, img_time, sem_time, | |||
raise CancelledError() | |||
|
|||
# subscribe to _subscribers | |||
# As soon as the e-beam start scanning (which can take a couple of ms), the | |||
# startScan event is sent, which triggers the acquisition of one CCD frame. | |||
for s, sub in zip(self._streams[:-1], self._subscribers[:-1]): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you comment on why the last element is excluded?
@@ -2119,12 +2112,11 @@ def _runAcquisitionScanStage(self, future): | |||
if self._acq_state == CANCELLED: | |||
raise CancelledError() | |||
|
|||
# Start e-beam scan. As soon as it really start, a startScan event is sent, which |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# Start e-beam scan. As soon as it really start, a startScan event is sent, which | |
# Start e-beam scan. As soon as it really starts, a startScan event is sent, which |
@@ -2008,9 +2001,9 @@ def _runAcquisitionScanStage(self, future): | |||
# The idea of the acquiring with a scan stage: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# The idea of the acquiring with a scan stage: | |
# The idea of acquisition with a scan stage: |
@@ -2251,6 +2253,23 @@ def _set_state(self, active): | |||
time.sleep(self._activation_delay) | |||
|
|||
|
|||
class EventOnce(model.Event): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is duplication of the function at the semcomedi driver. Maybe put it in a shared module?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed. moved to driver.EventOnce
@@ -540,6 +544,9 @@ def _acquire_thread(self, callback): | |||
# as in Odemis the convention for SEM is that the ebeam waits | |||
# for _all_ the detectors to be ready before scanning. | |||
self.data._waitSync() | |||
if first_frame: | |||
self.parent._scanner.startScan.notify() | |||
first_frame = False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this automatically stop notifying something which is similar to the unsubscribe used in the testcases when self._acquisition_must_stop.clear() is called in finally: section?
# Temporarily switch the CCD to a different event trigger, so that it | ||
# doesn't get triggered while the leech is running (because it could use the | ||
# e-beam, which would send a startScan event) | ||
self._ccd_df.synchronizedOn(self._ccd.softwareTrigger) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe an assert line can be used to check that the notification boolean value of startscan is False before reusing the real trigger? Same for _acquireImage
From the moment that the acquisition ask the e-beam scanner to start and the e-beam is actually at the right position, it takes some time. It's in the order of a few ms. So far, the only e-beam scanner was semcomedi, and it was (surprisingly) constant in terms of time. It would take between 2 and 5 ms. So it was good enough to just always wait 5ms.
We now also have semnidaq, and the NI-DAQ library introduces a lot longer latency. While it can be as "fast" as 10ms, it sometimes takes 40ms to start a scan. There are probably ways to make it a little faster, but it's unlikely it will be possible to always keep all scanners < 5ms.
=> Use a new Event, startScan, for the e-beam scanner to report the e-beam is ready. Then, we can use it to directly start a CCD acquisition.