Skip to content

Commit c2f086a

Browse files
Baharisstefsmeets
andauthored
Multi-tracking in FastADT experiment (#145)
* Allow server cameras to be streamable by removing precaution checks * Unify interface, naming between get_microscope/camera(_class) * Remove unused _init_attr_dict/get_attrs from microscope client/server * Do not force server-side attributes to be callable, use them first: these 3 lines took ~3h * EAFP: Allow camera to call functions whether they are registered or not * EAFP: Allow camera to call unregistered functions - fixes server cameras * Remove unnecessary print debug statement * Add **streamable** description to `config.md` documentation * Encapsulate FastADT paths in separate prop/method * Add new TrackingArtist to be used with plotting multi-runs * Working multi-tracking FastADT frame! Still needs polish * Change `ClickEvent` to dataclass, implement `ClickEvent.xy` * Optimize clicking logic in FastADT experiment * Streamline the `calibrate_beamshift_live` function * Streamline `CalibBeamShift.plot` * Improvements to `CalibBeamShift` readability (WIP) * Add option to calibrate beamshift with vsp * Fix errors, add beam center * Switch calibration output format from pickle to yaml * Allow delay during calibrate beamshift * Add necessary reflections to fix plotting * Final tweaks * Make the yaml produced by CalibBeamShift human-readable * Update src/instamatic/calibrate/calibrate_beamshift.py Co-authored-by: Stef Smeets <stefsmeets@users.noreply.github.com> * Update src/instamatic/calibrate/calibrate_beamshift.py Co-authored-by: Stef Smeets <stefsmeets@users.noreply.github.com> * Minor post-review type-hint improvements + ruff * Add `instamatic.utils.iterating` with `sawtooth` iterating function * Make the `click_dispatcher:ClickEvent.xy` a property * Rephrase `VideoStreamProcessor.temporary` using `blocked` context * Fix the bug where canceling FastADT did not remove its elements * Fix the bug where colors of crystal tracking repeated after 10 * Remove debug message * Attempt to generalize collecting, revert as needed * Fix: rotation speed for negative target pace is negative, rounds to 0 * Rename tracking "mode" to "algo"; if continuous, track w/ movie * Generalize FastADT run collection (+fix resulting bugs) * Revert change: use stills for continuous tracking * Minor fixes and code quality improvements * Clean, remove unused code * Fix tracking failing for beam not in the center at alignment * Fix Run.__str__, clean up code, method, call order * Log all behavior in two separate message windows. * Fix ignore msg1,2 variables in headless FastADT experiment * Update in tests `tracking_mode` -> `tracking_algo` * Add estimated time required dialog in FastADT message 2 * Display which experiment is being collected in multi-expt * Display which experiment is being collected in multi-expt * Trace variables only after everything was defined to avoid Exceptions * Fix: leaving input empty even temporarily caused exception --------- Co-authored-by: Stef Smeets <stefsmeets@users.noreply.github.com>
1 parent 9e0fc8d commit c2f086a

10 files changed

Lines changed: 385 additions & 288 deletions

File tree

docs/gui.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,8 @@ For optimum performance, the FastADT frame uses three separate TEM setting which
181181
**Diffraction exposure (s)**
182182
: The time taken to collect each diffraction image in seconds. In the `continuous` mode it will additionally dictate the rotation speed.
183183

184-
**Tracking mode**
185-
: Dictates whether `none` or `manual` tracking is to be performed at the start of the experiment.
184+
**Tracking algorithm**
185+
: Dictates whether `none` or `manual` tracking algorithm is to be performed at the start of the experiment to determine pathing.
186186

187187
**Tracking step (deg)**
188188
: The target spacing between angles at which subsequent tracking images are collected within the tracking series in degrees.

src/instamatic/calibrate/calibrate_beamshift.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ class CalibBeamShift:
5757
def __repr__(self):
5858
return f'CalibBeamShift(transform=\n{self.transform},\n reference_shift=\n{self.reference_shift},\n reference_pixel=\n{self.reference_pixel})'
5959

60-
def beamshift_to_pixelcoord(self, beamshift: Sequence[float, float]) -> Vector2:
60+
def beamshift_to_pixelcoord(self, beamshift: Sequence[float]) -> Vector2:
6161
"""Converts from beamshift x,y to pixel coordinates."""
6262
r_i = np.linalg.inv(self.transform)
6363
return np.dot(self.reference_shift - np.array(beamshift), r_i) + self.reference_pixel
6464

65-
def pixelcoord_to_beamshift(self, pixelcoord: Sequence[float, float]) -> Vector2:
65+
def pixelcoord_to_beamshift(self, pixelcoord: Sequence[float]) -> Vector2:
6666
"""Converts from pixel coordinates to beamshift x,y."""
6767
pc = np.array(pixelcoord)
6868
return self.reference_shift - np.dot(pc - self.reference_pixel, self.transform)

src/instamatic/calibrate/calibrate_stage_rotation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ def speed_time_to_span(self, speed: float, time: float) -> float:
137137

138138
def plan_rotation(self, target_pace: float) -> RotationPlan:
139139
"""Given target pace in sec / deg, find nearest pace, speed, delay."""
140-
target_speed = self.alpha_pace / target_pace # exact speed setting needed
140+
target_speed = abs(self.alpha_pace / target_pace) # exact speed setting needed
141141
nearest_speed = self.speed_options.nearest(target_speed) # nearest setting
142142
nearest_pace = self.alpha_pace / nearest_speed # nearest in sec/deg
143143
total_delay = self.alpha_windup / nearest_speed + self.delay

src/instamatic/camera/videostream.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ def unblock(self):
160160
def blocked(self):
161161
yield
162162

163+
@contextmanager
164+
def unblocked(self):
165+
yield
166+
163167

164168
class LiveVideoStream(VideoStream):
165169
"""Handle the continuous stream of incoming data from the ImageGrabber."""
@@ -237,6 +241,17 @@ def blocked(self):
237241
if not was_set_before:
238242
self.grabber.continuousCollectionEvent.clear()
239243

244+
@contextmanager
245+
def unblocked(self):
246+
"""Clear `continuousCollectionEvent` in the statement scope only."""
247+
was_set_before = self.grabber.continuousCollectionEvent.is_set()
248+
try:
249+
self.grabber.continuousCollectionEvent.clear()
250+
yield
251+
finally:
252+
if was_set_before:
253+
self.grabber.continuousCollectionEvent.set()
254+
240255
def show_stream(self):
241256
from instamatic.gui import videostream_frame
242257

0 commit comments

Comments
 (0)