-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add simple experiment base class * Use pytest's `tmp_path` for IO testing * Refactor format tests * Properly separate read/write tests * Add context manager for experiments * Refactor experiment tests * Microscope base class * Sort alphabethically * Use microscope base class; add type hints * Base camera class proposal * Add mock cameras for testing * Run ruff * Use the camera base class * Add rudimentary camera tests * Add type hints * PR feedback; 3.7 compatibility * Run pre-commit
- Loading branch information
Showing
33 changed files
with
708 additions
and
305 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
from abc import ABC, abstractmethod | ||
from typing import Tuple | ||
|
||
|
||
class MicroscopeBase(ABC): | ||
@abstractmethod | ||
def getBeamShift(self) -> Tuple[int, int]: | ||
pass | ||
|
||
@abstractmethod | ||
def getBeamTilt(self) -> Tuple[int, int]: | ||
pass | ||
|
||
@abstractmethod | ||
def getBrightness(self) -> int: | ||
pass | ||
|
||
@abstractmethod | ||
def getCondensorLensStigmator(self) -> Tuple[int, int]: | ||
pass | ||
|
||
@abstractmethod | ||
def getCurrentDensity(self) -> float: | ||
pass | ||
|
||
@abstractmethod | ||
def getDiffFocus(self, confirm_mode: bool) -> int: | ||
pass | ||
|
||
@abstractmethod | ||
def getDiffShift(self) -> Tuple[int, int]: | ||
pass | ||
|
||
@abstractmethod | ||
def getFunctionMode(self) -> str: | ||
pass | ||
|
||
@abstractmethod | ||
def getGunShift(self) -> Tuple[int, int]: | ||
pass | ||
|
||
@abstractmethod | ||
def getGunTilt(self) -> Tuple[int, int]: | ||
pass | ||
|
||
@abstractmethod | ||
def getHTValue(self) -> float: | ||
pass | ||
|
||
@abstractmethod | ||
def getImageShift1(self) -> Tuple[int, int]: | ||
pass | ||
|
||
@abstractmethod | ||
def getImageShift2(self) -> Tuple[int, int]: | ||
pass | ||
|
||
@abstractmethod | ||
def getIntermediateLensStigmator(self) -> Tuple[int, int]: | ||
pass | ||
|
||
@abstractmethod | ||
def getMagnification(self) -> int: | ||
pass | ||
|
||
@abstractmethod | ||
def getMagnificationAbsoluteIndex(self) -> int: | ||
pass | ||
|
||
@abstractmethod | ||
def getMagnificationIndex(self) -> int: | ||
pass | ||
|
||
@abstractmethod | ||
def getMagnificationRanges(self) -> dict: | ||
pass | ||
|
||
@abstractmethod | ||
def getObjectiveLensStigmator(self) -> Tuple[int, int]: | ||
pass | ||
|
||
@abstractmethod | ||
def getSpotSize(self) -> int: | ||
pass | ||
|
||
@abstractmethod | ||
def getStagePosition(self) -> Tuple[int, int, int, int, int]: | ||
pass | ||
|
||
@abstractmethod | ||
def isBeamBlanked(self) -> bool: | ||
pass | ||
|
||
@abstractmethod | ||
def isStageMoving(self) -> bool: | ||
pass | ||
|
||
@abstractmethod | ||
def release_connection(self) -> None: | ||
pass | ||
|
||
@abstractmethod | ||
def setBeamBlank(self, mode: bool) -> None: | ||
pass | ||
|
||
@abstractmethod | ||
def setBeamShift(self, x: int, y: int) -> None: | ||
pass | ||
|
||
@abstractmethod | ||
def setBeamTilt(self, x: int, y: int) -> None: | ||
pass | ||
|
||
@abstractmethod | ||
def setBrightness(self, value: int) -> None: | ||
pass | ||
|
||
@abstractmethod | ||
def setCondensorLensStigmator(self, x: int, y: int) -> None: | ||
pass | ||
|
||
@abstractmethod | ||
def setDiffFocus(self, value: int, confirm_mode: bool) -> None: | ||
pass | ||
|
||
@abstractmethod | ||
def setDiffShift(self, x: int, y: int) -> None: | ||
pass | ||
|
||
@abstractmethod | ||
def setFunctionMode(self, value: int) -> None: | ||
pass | ||
|
||
@abstractmethod | ||
def setGunShift(self, x: int, y: int) -> None: | ||
pass | ||
|
||
@abstractmethod | ||
def setGunTilt(self, x: int, y: int) -> None: | ||
pass | ||
|
||
@abstractmethod | ||
def setImageShift1(self, x: int, y: int) -> None: | ||
pass | ||
|
||
@abstractmethod | ||
def setImageShift2(self, x: int, y: int) -> None: | ||
pass | ||
|
||
@abstractmethod | ||
def setIntermediateLensStigmator(self, x: int, y: int) -> None: | ||
pass | ||
|
||
@abstractmethod | ||
def setMagnification(self, value: int) -> None: | ||
pass | ||
|
||
@abstractmethod | ||
def setMagnificationIndex(self, index: int) -> None: | ||
pass | ||
|
||
@abstractmethod | ||
def setObjectiveLensStigmator(self, x: int, y: int) -> None: | ||
pass | ||
|
||
@abstractmethod | ||
def setSpotSize(self, value: int) -> None: | ||
pass | ||
|
||
@abstractmethod | ||
def setStagePosition(self, x: int, y: int, z: int, a: int, b: int, wait: bool) -> None: | ||
pass | ||
|
||
@abstractmethod | ||
def stopStage(self) -> None: | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
from abc import ABC, abstractmethod | ||
from typing import List, Tuple | ||
|
||
from numpy import ndarray | ||
|
||
from instamatic import config | ||
|
||
|
||
class CameraBase(ABC): | ||
|
||
# Set manually | ||
name: str | ||
streamable: bool | ||
|
||
# Set by `load_defaults` | ||
camera_rotation_vs_stage_xy: float | ||
default_binsize: int | ||
default_exposure: float | ||
dimensions: Tuple[int, int] | ||
interface: str | ||
possible_binsizes: List[int] | ||
stretch_amplitude: float | ||
stretch_azimuth: float | ||
|
||
@abstractmethod | ||
def __init__(self, name: str): | ||
self.name = name | ||
self.load_defaults() | ||
|
||
@abstractmethod | ||
def establish_connection(self): | ||
pass | ||
|
||
@abstractmethod | ||
def release_connection(self): | ||
pass | ||
|
||
@abstractmethod | ||
def get_image( | ||
self, exposure: float = None, binsize: int = None, **kwargs | ||
) -> ndarray: | ||
pass | ||
|
||
def get_movie( | ||
self, n_frames: int, exposure: float = None, binsize: int = None, **kwargs | ||
) -> List[ndarray]: | ||
"""Basic implementation, subclasses should override with appropriate | ||
optimization.""" | ||
return [ | ||
self.get_image(exposure=exposure, binsize=binsize, **kwargs) | ||
for _ in range(n_frames) | ||
] | ||
|
||
def __enter__(self): | ||
self.establish_connection() | ||
return self | ||
|
||
def __exit__(self, kind, value, traceback): | ||
self.release_connection() | ||
|
||
def get_camera_dimensions(self) -> Tuple[int, int]: | ||
return self.dimensions | ||
|
||
def get_name(self) -> str: | ||
return self.name | ||
|
||
def load_defaults(self): | ||
if self.name != config.settings.camera: | ||
config.load_camera_config(camera_name=self.name) | ||
for key, val in config.camera.mapping.items(): | ||
setattr(self, key, val) |
Oops, something went wrong.