pigeon-tem-comms 1.4.1__tar.gz → 2.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. {pigeon_tem_comms-1.4.1/pigeon_tem_comms.egg-info → pigeon_tem_comms-2.1.0}/PKG-INFO +1 -1
  2. {pigeon_tem_comms-1.4.1 → pigeon_tem_comms-2.1.0}/TEM_comms/__init__.py +21 -7
  3. pigeon_tem_comms-2.1.0/TEM_comms/buffer.py +18 -0
  4. pigeon_tem_comms-2.1.0/TEM_comms/calibration.py +42 -0
  5. pigeon_tem_comms-2.1.0/TEM_comms/camera.py +64 -0
  6. pigeon_tem_comms-2.1.0/TEM_comms/lens_correction.py +10 -0
  7. pigeon_tem_comms-2.1.0/TEM_comms/montage.py +55 -0
  8. pigeon_tem_comms-2.1.0/TEM_comms/qc.py +17 -0
  9. {pigeon_tem_comms-1.4.1 → pigeon_tem_comms-2.1.0}/TEM_comms/roi.py +47 -12
  10. pigeon_tem_comms-2.1.0/TEM_comms/scope/__init__.py +68 -0
  11. pigeon_tem_comms-2.1.0/TEM_comms/scope/image_shift.py +57 -0
  12. pigeon_tem_comms-2.1.0/TEM_comms/stage/aperture.py +35 -0
  13. pigeon_tem_comms-2.1.0/TEM_comms/stage/motion.py +51 -0
  14. pigeon_tem_comms-2.1.0/TEM_comms/stage/rotation.py +44 -0
  15. pigeon_tem_comms-2.1.0/TEM_comms/state.py +23 -0
  16. pigeon_tem_comms-2.1.0/TEM_comms/tile/__init__.py +133 -0
  17. pigeon_tem_comms-2.1.0/TEM_comms/tile/metadata.py +38 -0
  18. pigeon_tem_comms-2.1.0/TEM_comms/tile/statistics.py +34 -0
  19. pigeon_tem_comms-2.1.0/TEM_comms/ui.py +84 -0
  20. {pigeon_tem_comms-1.4.1 → pigeon_tem_comms-2.1.0/pigeon_tem_comms.egg-info}/PKG-INFO +1 -1
  21. {pigeon_tem_comms-1.4.1 → pigeon_tem_comms-2.1.0}/pigeon_tem_comms.egg-info/SOURCES.txt +5 -1
  22. {pigeon_tem_comms-1.4.1 → pigeon_tem_comms-2.1.0}/pyproject.toml +1 -1
  23. pigeon_tem_comms-2.1.0/tests/test_documentation.py +12 -0
  24. {pigeon_tem_comms-1.4.1 → pigeon_tem_comms-2.1.0}/tests/test_stage.py +7 -1
  25. {pigeon_tem_comms-1.4.1 → pigeon_tem_comms-2.1.0}/tests/test_tile.py +0 -2
  26. pigeon_tem_comms-2.1.0/tests/test_ui.py +20 -0
  27. pigeon_tem_comms-1.4.1/TEM_comms/buffer.py +0 -7
  28. pigeon_tem_comms-1.4.1/TEM_comms/calibration.py +0 -18
  29. pigeon_tem_comms-1.4.1/TEM_comms/camera.py +0 -34
  30. pigeon_tem_comms-1.4.1/TEM_comms/montage.py +0 -32
  31. pigeon_tem_comms-1.4.1/TEM_comms/qc.py +0 -6
  32. pigeon_tem_comms-1.4.1/TEM_comms/scope.py +0 -30
  33. pigeon_tem_comms-1.4.1/TEM_comms/stage/aperture.py +0 -17
  34. pigeon_tem_comms-1.4.1/TEM_comms/stage/motion.py +0 -22
  35. pigeon_tem_comms-1.4.1/TEM_comms/stage/rotation.py +0 -16
  36. pigeon_tem_comms-1.4.1/TEM_comms/tile/__init__.py +0 -42
  37. pigeon_tem_comms-1.4.1/TEM_comms/tile/metadata.py +0 -9
  38. pigeon_tem_comms-1.4.1/TEM_comms/tile/statistics.py +0 -17
  39. pigeon_tem_comms-1.4.1/TEM_comms/ui.py +0 -55
  40. pigeon_tem_comms-1.4.1/tests/test_ui.py +0 -29
  41. {pigeon_tem_comms-1.4.1 → pigeon_tem_comms-2.1.0}/LICENSE +0 -0
  42. {pigeon_tem_comms-1.4.1 → pigeon_tem_comms-2.1.0}/README.md +0 -0
  43. {pigeon_tem_comms-1.4.1 → pigeon_tem_comms-2.1.0}/TEM_comms/stage/__init__.py +0 -0
  44. {pigeon_tem_comms-1.4.1 → pigeon_tem_comms-2.1.0}/pigeon_tem_comms.egg-info/dependency_links.txt +0 -0
  45. {pigeon_tem_comms-1.4.1 → pigeon_tem_comms-2.1.0}/pigeon_tem_comms.egg-info/entry_points.txt +0 -0
  46. {pigeon_tem_comms-1.4.1 → pigeon_tem_comms-2.1.0}/pigeon_tem_comms.egg-info/requires.txt +0 -0
  47. {pigeon_tem_comms-1.4.1 → pigeon_tem_comms-2.1.0}/pigeon_tem_comms.egg-info/top_level.txt +0 -0
  48. {pigeon_tem_comms-1.4.1 → pigeon_tem_comms-2.1.0}/setup.cfg +0 -0
  49. {pigeon_tem_comms-1.4.1 → pigeon_tem_comms-2.1.0}/tests/test_buffer.py +0 -0
  50. {pigeon_tem_comms-1.4.1 → pigeon_tem_comms-2.1.0}/tests/test_calibration.py +0 -0
  51. {pigeon_tem_comms-1.4.1 → pigeon_tem_comms-2.1.0}/tests/test_camera.py +0 -0
  52. {pigeon_tem_comms-1.4.1 → pigeon_tem_comms-2.1.0}/tests/test_qc.py +0 -0
  53. {pigeon_tem_comms-1.4.1 → pigeon_tem_comms-2.1.0}/tests/test_scope_command.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pigeon-tem-comms
3
- Version: 1.4.1
3
+ Version: 2.1.0
4
4
  Summary: Pigeon messages for the next generation TEM imaging system.
5
5
  Author-email: Cameron Devine <cameron.devine@alleninstitute.org>
6
6
  License: BSD 3 Clause
@@ -1,9 +1,17 @@
1
- from pigeon import BaseMessage
2
- from . import buffer, camera, montage, qc, roi, scope, stage, tile, ui, calibration
3
-
4
-
5
- class State(BaseMessage):
6
- state: str
1
+ from . import (
2
+ buffer,
3
+ camera,
4
+ montage,
5
+ qc,
6
+ roi,
7
+ scope,
8
+ stage,
9
+ tile,
10
+ ui,
11
+ calibration,
12
+ state,
13
+ lens_correction,
14
+ )
7
15
 
8
16
 
9
17
  topics = {
@@ -14,6 +22,9 @@ topics = {
14
22
  "camera.status": camera.Status,
15
23
  "scope.command": scope.Command,
16
24
  "scope.status": scope.Status,
25
+ "scope.image_shift.status": scope.image_shift.Status,
26
+ "scope.image_shift.command": scope.image_shift.Command,
27
+ "scope.image_shift.calibrate": scope.image_shift.Calibrate,
17
28
  "stage.aperture.command": stage.aperture.Command,
18
29
  "stage.aperture.status": stage.aperture.Status,
19
30
  "stage.motion.command": stage.motion.Command,
@@ -28,6 +39,7 @@ topics = {
28
39
  "tile.statistics.histogram": tile.statistics.Histogram,
29
40
  "tile.statistics.min_max_mean": tile.statistics.MinMaxMean,
30
41
  "tile.matches": tile.Matches,
42
+ "tile.template_matches": tile.TemplateMatches,
31
43
  "ui.edit": ui.Edit,
32
44
  "ui.run": ui.Run,
33
45
  "ui.setup": ui.Setup,
@@ -40,5 +52,7 @@ topics = {
40
52
  "montage.minimaps": montage.Minimaps,
41
53
  "calibration.resolution": calibration.Resolution,
42
54
  "calibration.centroid": calibration.Centroid,
43
- "state": State,
55
+ "state.current": state.Current,
56
+ "state.change": state.Change,
57
+ "lens_correction.transform": lens_correction.Transform,
44
58
  }
@@ -0,0 +1,18 @@
1
+ from pigeon import BaseMessage
2
+ from pydantic import Field
3
+
4
+
5
+ class Status(BaseMessage):
6
+ """
7
+ This message contains information about the status of the tile upload buffer.
8
+ """
9
+
10
+ queue_length: int = Field(
11
+ description="The number of tiles currently stored and waiting to be uploaded."
12
+ )
13
+ free_space: int = Field(
14
+ description="The amount of free space on the tile storage disk in bytes."
15
+ )
16
+ upload_rate: int = Field(
17
+ description="The rate at which data is being uploaded in bits per second."
18
+ )
@@ -0,0 +1,42 @@
1
+ from pigeon import BaseMessage
2
+ from typing import Mapping
3
+ from pydantic import Field
4
+
5
+
6
+ class _Resolution(BaseMessage):
7
+ nm_per_px: tuple[float, float] = Field(
8
+ description="The X-Y size of each pixel in the processed camera image in nanometers.",
9
+ examples=[(3.97, 4.03)],
10
+ )
11
+ rotation: float = Field(
12
+ description="The rotation required to match a right-handed image coordinate system to the coordinate system of the stage in radians."
13
+ )
14
+
15
+
16
+ class Resolution(BaseMessage):
17
+ """
18
+ This message contains the resolutions of all the calibrated magnifications of the microscope.
19
+ """
20
+
21
+ lowmag: Mapping[int, _Resolution] = Field(
22
+ description="A mapping of calibrated low-mag magnifications to thier calibration values."
23
+ )
24
+ mag: Mapping[int, _Resolution] = Field(
25
+ description="A mapping of calibrated high-mag magnifications to their calibration values."
26
+ )
27
+
28
+
29
+ class Centroid(BaseMessage):
30
+ """
31
+ This message contains the location of the centroid of the specified aperture.
32
+ """
33
+
34
+ aperture_id: int = Field(
35
+ description="The ID of the aperture that this centroid pertains to."
36
+ )
37
+ x: int = Field(
38
+ description="The stage coordinate system X axis location of the centroid."
39
+ )
40
+ y: int = Field(
41
+ description="The stage coordinate system Y axis location of the centroid."
42
+ )
@@ -0,0 +1,64 @@
1
+ from pigeon import BaseMessage
2
+ from .tile.metadata import TileMetadata, ProcessingOptions
3
+ from typing import Optional
4
+ from pydantic import Field
5
+
6
+
7
+ class Command(TileMetadata, ProcessingOptions):
8
+ """
9
+ This message is used to instruct the camera to capture an image.
10
+ """
11
+
12
+
13
+ class Image(BaseMessage):
14
+ """
15
+ This message is sent after the camera exposure is complete.
16
+ """
17
+
18
+ tile_id: str = Field(
19
+ description="The tile ID", examples=["69005602-15b0-4407-bf5b-4bddd6629141"]
20
+ )
21
+ montage_id: str = Field(
22
+ description="The montage ID. If a zero length string, the tile is for UI display or calibration purposes only.",
23
+ examples=["4330c7cf-e45b-4950-89cf-82dc0f815fe9"],
24
+ )
25
+
26
+
27
+ class Settings(BaseMessage):
28
+ """
29
+ This message is used to change camera settings.
30
+ """
31
+
32
+ exposure: float | None = Field(
33
+ default=None, description="The length of the camera exposure in microseconds."
34
+ )
35
+ gain: Optional[float] = Field(
36
+ default=None, description="The camera gain in decibels."
37
+ )
38
+ width: int | None = Field(
39
+ default=None, description="The width of the camera frame."
40
+ )
41
+ height: int | None = Field(
42
+ default=None, description="The height of the camera frame."
43
+ )
44
+
45
+
46
+ class Status(BaseMessage):
47
+ """
48
+ This message contains information about the state of the camera.
49
+ """
50
+
51
+ exposure: float = Field(
52
+ description="The length of the camera exposure in microseconds."
53
+ )
54
+ gain: float = Field(description="The camera gain in decibels.")
55
+ width: int = Field(description="The camera frame width.")
56
+ height: int = Field(description="The camera frame height.")
57
+ temp: float = Field(description="The camera temperature.")
58
+ target_temp: float = Field(
59
+ description="The target temperature of the camera cooling system."
60
+ )
61
+ device_name: str = Field(description="The human readable device name.")
62
+ device_model_id: str = Field(description="The device model identifier.")
63
+ device_sn: str = Field(description="The camera serial number.")
64
+ bit_depth: int | str = Field(description="The bit depth of the camera sensor.")
@@ -0,0 +1,10 @@
1
+ from pigeon import BaseMessage
2
+ from pydantic import Field
3
+
4
+
5
+ class Transform(BaseMessage):
6
+ """
7
+ This message contains a compact representation of the generated lens correction transform.
8
+ """
9
+
10
+ transform: str = Field(description="The base64 encoded lens correction transform.")
@@ -0,0 +1,55 @@
1
+ from pigeon import BaseMessage
2
+ from typing import Mapping, Dict, Any, Optional, Tuple
3
+ from datetime import datetime
4
+ from pydantic import Field
5
+
6
+
7
+ class Tile(BaseMessage):
8
+ raster_index: int = Field(
9
+ description="The index of the tile incremented for each subsequent tile in the montage."
10
+ )
11
+ stage_position: Tuple[int, int] = Field(
12
+ description="The X-Y stage position of the tile in nanometers."
13
+ )
14
+ raster_position: Tuple[int, int] = Field(
15
+ description="The X-Y indicies of the tile in the montage."
16
+ )
17
+
18
+
19
+ class Complete(BaseMessage):
20
+ """
21
+ This message is sent after a montage is completed.
22
+ """
23
+
24
+ montage_id: str = Field(description="The unique montage ID.")
25
+ tiles: Dict[str, Tile] = Field(
26
+ description="A mapping from tile IDs to tile metadata."
27
+ )
28
+ acquisition_id: str = Field(description="The corresponding TEMdb acqusition ID.")
29
+ start_time: datetime = Field(
30
+ description="The timestamp when the montage was started."
31
+ )
32
+ pixel_size: float = Field(description="The average size ofee")
33
+ rotation_angle: float = Field(
34
+ description="The necessary tile rotation in radians to line up the right-handed image coordinate system with the Stage x-y coordinate system."
35
+ )
36
+ aperture_centroid: Tuple[int, int] = Field(
37
+ description="The X-Y coordinates of the centroid of the imaged aperture in nanometers."
38
+ )
39
+
40
+
41
+ class Minimap(BaseMessage):
42
+ image: Optional[str] = Field(description="The map as a base 64 encoded image.")
43
+ colorbar: str = Field(description="The colorbar as a base 64 encoded image.")
44
+ min: Optional[float] = Field(description="The minimum value of the colorbar.")
45
+ max: Optional[float] = Field(description="The maximum value of the colorbar.")
46
+
47
+
48
+ class Minimaps(BaseMessage):
49
+ """
50
+ This message contains multiple overview maps including a low resolution version of the montage, along with various statistics.
51
+ """
52
+
53
+ montage_id: str = Field(description="The unique montage ID.")
54
+ montage: Minimap = Field(description="The montage minimap.")
55
+ focus: Minimap = Field(description="The focus score map.")
@@ -0,0 +1,17 @@
1
+ from pigeon import BaseMessage
2
+ from typing import Literal, Optional
3
+ from pydantic import Field
4
+
5
+
6
+ class Status(BaseMessage):
7
+ """
8
+ This message contains the overall QC status of the system.
9
+ """
10
+
11
+ status: Literal["GOOD", "STOP_AT_END", "STOP_NOW"] = Field(
12
+ description='The QC status, "GOOD" if imaging should continue, "STOP_AT_END" if imaging should be stopped at the end of the current montage, and "STOP_NOW" if imaging should be stopped immediately.'
13
+ )
14
+ reason: Optional[str] = Field(
15
+ default=None,
16
+ description="Optionally, a human readable reason for the current status.",
17
+ )
@@ -9,30 +9,61 @@ class Vertex(BaseMessage):
9
9
 
10
10
 
11
11
  class ROI(BaseMessage):
12
- vertices: List[Vertex]
13
- rotation_angle: float
14
- buffer_size: float = 0.0
15
- montage_id: str
16
- specimen_id: Optional[str] = None
17
- grid_id: Optional[str] = None
18
- section_id: Optional[str] = None
19
- metadata: Optional[dict] = None
12
+ """
13
+ Information about the current ROI being imaged.
14
+ """
15
+
16
+ vertices: List[Vertex] = Field(
17
+ description="A list of points defining a polygonal ROI."
18
+ )
19
+ rotation_angle: float = Field(
20
+ description="The rotation angle of the ROI in radians."
21
+ )
22
+ buffer_size: float = Field(
23
+ default=0.0,
24
+ description="The amount to dialate the ROI in nanometers when imaging.",
25
+ )
26
+ montage_id: str = Field(description="The montage ID to use when imaging the ROI.")
27
+ specimen_id: Optional[str] = Field(
28
+ default=None, description="The specimen ID corresponding to this ROI."
29
+ )
30
+ grid_id: Optional[str] = Field(
31
+ default=None, description="The grid ID where this ROI should be imaged."
32
+ )
33
+ section_id: Optional[str] = Field(
34
+ default=None, description="The section ID corresponding to this ROI."
35
+ )
36
+ metadata: Optional[dict] = Field(
37
+ default=None, description="Extra metadata about this ROI."
38
+ )
20
39
  queue_position: Optional[int] = Field(
21
40
  None, description="Position in queue, None means set as current"
22
41
  )
23
42
 
24
43
 
25
44
  class LoadROI(BaseMessage):
26
- specimen_id: str
27
- section_id: str
28
- grid_id: Optional[str] = None
45
+ """
46
+ This message can be used to load an ROI from the database into the ROI queue.
47
+ """
48
+
49
+ specimen_id: str = Field(description="The specimen ID to load from the database.")
50
+ section_id: str = Field(description="The section ID to load from the database.")
51
+ grid_id: Optional[str] = Field(
52
+ default=None, description="The the grid ID where the section is loaded."
53
+ )
29
54
  queue_position: Optional[int] = Field(
30
55
  None, description="Position in queue, None means set as current"
31
56
  )
32
57
 
33
58
 
34
59
  class CreateROI(ROI):
35
- center: Optional[Vertex] = None
60
+ """
61
+ This message can be used to create an ROI and add it to the ROI queue.
62
+ """
63
+
64
+ center: Optional[Vertex] = Field(
65
+ default=None, description="The center point of the ROI."
66
+ )
36
67
  tilt_angles: Optional[List[float]] = Field(
37
68
  default=[0.0],
38
69
  description="List of tilt angles in degrees for tomography series",
@@ -49,6 +80,10 @@ class CreateROI(ROI):
49
80
 
50
81
 
51
82
  class ROIStatus(BaseMessage):
83
+ """
84
+ This message contains information on the status of an individual ROI.
85
+ """
86
+
52
87
  type: str = Field(
53
88
  description="Event type: roi_added, roi_advanced, queue_cleared, queue_empty"
54
89
  )
@@ -0,0 +1,68 @@
1
+ from pigeon import BaseMessage
2
+ from typing import Literal, Optional, Tuple
3
+ from pydantic import model_validator, Field
4
+ from . import image_shift
5
+
6
+
7
+ class Command(BaseMessage):
8
+ """
9
+ This message is used to change microscope settings.
10
+ """
11
+
12
+ focus: Optional[int] = Field(
13
+ default=None,
14
+ description="The desired focus value for the microscope, or None to keep the current value.",
15
+ )
16
+ mag_mode: Optional[Literal["LM", "MAG1", "MAG2"]] = Field(
17
+ default=None,
18
+ description="The desired magnification mode for the microscope, or None to keep the current value.",
19
+ )
20
+ mag: Optional[int] = Field(
21
+ default=None,
22
+ description="The desired magnification for the microscope, or None to keep the current value.",
23
+ )
24
+ brightness: Optional[int] = Field(
25
+ default=None,
26
+ description="The desired beam spread for the microscope, or None to keep the current value.",
27
+ )
28
+ beam_offset: Optional[Tuple[int, int]] = Field(
29
+ default=None,
30
+ description="The desired beam shift values, or None to keep the current value.",
31
+ )
32
+ spot_size: Optional[int] = Field(
33
+ default=None,
34
+ description="The desired spot size, or None to keep the current value.",
35
+ )
36
+ screen: Optional[Literal["up", "down"]] = Field(
37
+ default=None,
38
+ description='"up" to raise the microscope viewscreen, "down" to lower the microscope viewscreen, or None to keep the viewscreen in the current position.',
39
+ )
40
+
41
+ @model_validator(mode="after")
42
+ def check_mag(self):
43
+ assert (self.mag_mode is None) == (self.mag is None)
44
+ return self
45
+
46
+
47
+ class Status(BaseMessage):
48
+ """
49
+ This message contains the state of the microscope.
50
+ """
51
+
52
+ focus: int = Field(description="The current focus value.")
53
+ aperture: str | None = Field(
54
+ description="The current status of the objective aperture, or None if unknown."
55
+ )
56
+ mag_mode: Literal["MAG", "LOWMAG"] = Field(
57
+ description="The curreng magnification mode."
58
+ )
59
+ mag: int = Field(description="The current magnification.")
60
+ tank_voltage: int = Field(
61
+ description="The current voltage of the tank in kilo-volts."
62
+ )
63
+ brightness: int = Field(description="The current beam spread.")
64
+ beam_offset: Tuple[int, int] = Field(description="The current beam shift values.")
65
+ spot_size: int = Field(description="The current spot size.")
66
+ screen: Literal["up", "down"] | None = Field(
67
+ description='Whether the viewscreen is currently "up", "down", or None for an unknown position.'
68
+ )
@@ -0,0 +1,57 @@
1
+ from pigeon import BaseMessage
2
+ from typing import Optional, List, Tuple, Mapping
3
+ from pydantic import model_validator, Field
4
+
5
+
6
+ class Calibrate(BaseMessage):
7
+ """
8
+ This message is used to calibrate the image shifting system.
9
+ """
10
+
11
+ position: int = Field(description="The image shift position index to calibrate.")
12
+ image_shift: Tuple[int, int] = Field(
13
+ description="The new calibration values for this position index."
14
+ )
15
+
16
+
17
+ class Status(BaseMessage):
18
+ """
19
+ This message conatins the status of the image shifting system.
20
+ """
21
+
22
+ enabled: bool = Field(
23
+ description="If the image shifting system is currently enabled."
24
+ )
25
+ current_position: int | None = Field(
26
+ default=None, description="The current position index, or None if disabled."
27
+ )
28
+ image_shift: Tuple[int, int] = Field(
29
+ description="The current image shift calibration values."
30
+ )
31
+ calibration: Mapping[int, Tuple[int, int]] = Field(
32
+ description="The calibration values for each position index."
33
+ )
34
+
35
+ @model_validator(mode="after")
36
+ def check_current_position(self):
37
+ assert self.enabled == (self.current_position is not None)
38
+ return self
39
+
40
+
41
+ class Command(BaseMessage):
42
+ """
43
+ This message is used to enable and disable the image shifting system, and to switch to a predefined position.
44
+ """
45
+
46
+ enable: bool = Field(
47
+ description="Used to enable and disable the image shifting system."
48
+ )
49
+ position: Optional[int] = Field(
50
+ default=None,
51
+ description="The calibrated position index to use, or None if disabled.",
52
+ )
53
+
54
+ @model_validator(mode="after")
55
+ def check_position(self):
56
+ assert self.enable == (self.position is not None)
57
+ return self
@@ -0,0 +1,35 @@
1
+ from pigeon import BaseMessage
2
+ from pydantic import ConfigDict, Field
3
+
4
+
5
+ class Command(BaseMessage):
6
+ """
7
+ This message is uesd to change between apertures on a substrate.
8
+ """
9
+
10
+ model_config = ConfigDict(extra="allow")
11
+
12
+ aperture_id: int | None = Field(
13
+ default=None,
14
+ description="The ID of the aperture to change to, or None to remain at the current aperture.",
15
+ )
16
+ calibrate: bool = Field(
17
+ default=False,
18
+ description="Set to True to initiate aperture changing hardware calibration.",
19
+ )
20
+
21
+
22
+ class Status(BaseMessage):
23
+ """
24
+ This message includes status information about the aperture changing system.
25
+ """
26
+
27
+ model_config = ConfigDict(extra="allow")
28
+
29
+ current_aperture: int | None = Field(
30
+ description="The ID of the current aperture, or None if unknown."
31
+ )
32
+ calibrated: bool = Field(
33
+ description="True if the aperture changing hardware is calibrated."
34
+ )
35
+ error: str = Field(default="", description="An optional error message.")
@@ -0,0 +1,51 @@
1
+ from typing import Optional
2
+ from pigeon import BaseMessage
3
+ from pydantic import ConfigDict, Field
4
+
5
+
6
+ class Command(BaseMessage):
7
+ """
8
+ This message is used to specify how the stage should move the sample.
9
+ """
10
+
11
+ model_config = ConfigDict(extra="allow")
12
+
13
+ x: int | None = Field(
14
+ default=None,
15
+ description="The desired absolute X position of the stage in nanometers, or None to keep the current position.",
16
+ )
17
+ y: int | None = Field(
18
+ default=None,
19
+ description="The desired absolute Y position of the stage in nanometers, or None to keep the current position.",
20
+ )
21
+ z: Optional[int] = Field(
22
+ default=None,
23
+ description="The desired absolute Z position of the stage in nanometers, or None to keep the current position.",
24
+ )
25
+ calibrate: bool = Field(
26
+ default=False, description="Set to True to initiate stage calibration."
27
+ )
28
+
29
+
30
+ class Status(BaseMessage):
31
+ """
32
+ This message includes stage motion status information.
33
+ """
34
+
35
+ model_config = ConfigDict(extra="allow")
36
+
37
+ x: int | None = Field(
38
+ description="The current X position of the stage in nanometers, or None if unknown."
39
+ )
40
+ y: int | None = Field(
41
+ description="The current Y position of the stage in nanometers, or None if unknown."
42
+ )
43
+ z: Optional[int] = Field(
44
+ default=None,
45
+ description="The current Z position of the stage in nanometers, or None if unknown.",
46
+ )
47
+ in_motion: bool = Field(
48
+ description="This value is True if the stage is currently moving."
49
+ )
50
+ calibrated: bool = Field(description="True if the stage is calibrated.")
51
+ error: str = Field(default="", description="An optional error message.")
@@ -0,0 +1,44 @@
1
+ from pigeon import BaseMessage
2
+ from pydantic import Field
3
+
4
+
5
+ class Command(BaseMessage):
6
+ """
7
+ This message is used to rotate the sample, and to calibrate this rotation.
8
+ """
9
+
10
+ angle_x: float | None = Field(
11
+ default=None,
12
+ description="The desired rotation angle around the X axis in radians, or None to keep the current value.",
13
+ )
14
+ angle_y: float | None = Field(
15
+ default=None,
16
+ description="The desired rotation angle around the Y axis in radians, or None to keep the current value.",
17
+ )
18
+ eucentric_height: float | None = Field(
19
+ default=None,
20
+ description="The eucentric height of the stage in nanometers for calibration, or None to keep the current value.",
21
+ )
22
+ calibrate: bool = Field(
23
+ default=False, description="If True, calibrate the sample rotation hardware."
24
+ )
25
+
26
+
27
+ class Status(BaseMessage):
28
+ """
29
+ This message contains the status of the sample rotation system.
30
+ """
31
+
32
+ angle_x: float = Field(
33
+ description="The current angle around the X axis in radians."
34
+ )
35
+ angle_y: float = Field(
36
+ description="The current angle around the Y axis in radians."
37
+ )
38
+ eucentric_height: float = Field(
39
+ description="The current enucentric height value in nanometers."
40
+ )
41
+ in_motion: bool = Field(
42
+ description="True if the rotation stage is currently moving."
43
+ )
44
+ error: str = Field(default="", description="An optional error message.")
@@ -0,0 +1,23 @@
1
+ from pigeon import BaseMessage
2
+ from pydantic import Field
3
+
4
+
5
+ class Current(BaseMessage):
6
+ """
7
+ This message contains the current state of the orchastration state machine.
8
+ """
9
+
10
+ state: str = Field(
11
+ description="The current state of the orchastration state machine."
12
+ )
13
+
14
+
15
+ class Change(BaseMessage):
16
+ """
17
+ This message is sent on a state change of the orchastration state machine.
18
+ """
19
+
20
+ old: str = Field(
21
+ description="The previous state of the orchastration state machine."
22
+ )
23
+ new: str = Field(description="The new state of the orchastration state machine.")