Source code for magscope.utils

from __future__ import annotations

from datetime import datetime
from enum import IntEnum, StrEnum
from typing import TYPE_CHECKING, Callable, Type

import magtrack
import numpy as np
from PyQt6.QtGui import QImage

from magscope.ipc_commands import Command


[docs] class AcquisitionMode(StrEnum): """ Enum for the different acquisition modes """
[docs] TRACK = 'track'
[docs] TRACK_AND_CROP_VIDEO = 'track & video (cropped)'
[docs] TRACK_AND_FULL_VIDEO = 'track & video (full)'
[docs] CROP_VIDEO = 'video (cropped)'
[docs] FULL_VIDEO = 'video (full)'
[docs] def crop_stack_to_rois(stack, rois): rois = np.asarray(rois, dtype=np.int64) # Pre-allocate space for cropped_stack n_images = stack.shape[2] n_rois = len(rois) width = rois[0, 1] - rois[0, 0] shape = (width, width, n_images, n_rois) cropped_stack = np.ndarray( shape, dtype=stack.dtype ) # width, width, frames, rois # Crop for i, roi in enumerate(rois): cropped_stack[:, :, :, i] = ( stack[roi[0]:roi[1], roi[2]:roi[3], :] ) return cropped_stack
[docs] def numpy_type_to_qt_image_type(numpy_type): NP2QT = { np.uint8: QImage.Format.Format_Grayscale8, np.uint16: QImage.Format.Format_Grayscale16 } if numpy_type not in NP2QT: raise ValueError(f"Unsupported bit type: {numpy_type}") return NP2QT[numpy_type]
[docs] def date_timestamp_str(timestamp): date_str = datetime.today().strftime('%Y-%m-%d') hour = (timestamp // 3600 % 24 - 5) % 24 minutes = timestamp // 60 % 60 seconds = timestamp // 1 % 60 milliseconds = timestamp % 1 * 1000 return f'{date_str} {hour:02.0f}-{minutes:02.0f}-{seconds:02.0f}.{milliseconds:03.0f}'
[docs] class PoolVideoFlag(IntEnum):
[docs] READY = 0
[docs] RUNNING = 1
[docs] FINISHED = 2
[docs] class Units: # Meters
[docs] m = 1.
[docs] cm = 1e-2
[docs] mm = 1e-3
[docs] um = 1e-6
[docs] nm = 1e-9
# Newtons
[docs] N = 1.
[docs] mN = 1e-3
[docs] uN = 1e-6
[docs] nN = 1e-9
[docs] pN = 1e-12
[docs] fN = 1e-15
# Seconds sec = s = 1.
[docs] ms = 1e-3
[docs] us = 1e-6
[docs] ns = 1e-9
[docs] ps = 1e-12
[docs] fs = 1e-15
# Directions clockwise = cw = 1. counterclockwise = ccw = -1.
[docs] def register_script_command(command_type: type[Command]): """Decorator marking a method as callable from a MagScope script. Each script command must be paired with the IPC :class:`~magscope.ipc_commands.Command` that will be dispatched when the script executes that step. The decorator mirrors :func:`magscope.ipc_commands.command_handler` by attaching metadata to the wrapped function without constraining how it is collected. """ def decorator(meth: callable): meth._scriptable = True meth._script_command_type = command_type return meth return decorator
[docs] def check_cupy() -> bool: """Return ``True`` when the CuPy package is usable.""" return magtrack.check_cupy()