pigeon-tem-comms 0.2.0__tar.gz → 0.4.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 (28) hide show
  1. {pigeon_tem_comms-0.2.0/pigeon_tem_comms.egg-info → pigeon_tem_comms-0.4.0}/PKG-INFO +1 -1
  2. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/TEM_comms/__init__.py +3 -7
  3. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/TEM_comms/camera.py +8 -1
  4. pigeon_tem_comms-0.4.0/TEM_comms/montage.py +15 -0
  5. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/TEM_comms/scope.py +2 -1
  6. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/TEM_comms/stage/__init__.py +1 -1
  7. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/TEM_comms/stage/aperture.py +3 -1
  8. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/TEM_comms/stage/motion.py +3 -1
  9. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/TEM_comms/stage/rotation.py +3 -1
  10. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/TEM_comms/tile/__init__.py +8 -6
  11. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/TEM_comms/tile/statistics.py +8 -1
  12. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0/pigeon_tem_comms.egg-info}/PKG-INFO +1 -1
  13. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/pigeon_tem_comms.egg-info/SOURCES.txt +1 -0
  14. pigeon_tem_comms-0.4.0/pigeon_tem_comms.egg-info/entry_points.txt +2 -0
  15. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/pyproject.toml +2 -2
  16. pigeon_tem_comms-0.4.0/tests/test_buffer.py +64 -0
  17. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/tests/test_scope_command.py +4 -2
  18. pigeon_tem_comms-0.2.0/pigeon_tem_comms.egg-info/entry_points.txt +0 -2
  19. pigeon_tem_comms-0.2.0/tests/test_buffer.py +0 -41
  20. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/LICENSE +0 -0
  21. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/README.md +0 -0
  22. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/TEM_comms/buffer.py +0 -0
  23. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/TEM_comms/ui.py +0 -0
  24. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/pigeon_tem_comms.egg-info/dependency_links.txt +0 -0
  25. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/pigeon_tem_comms.egg-info/requires.txt +0 -0
  26. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/pigeon_tem_comms.egg-info/top_level.txt +0 -0
  27. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/setup.cfg +0 -0
  28. {pigeon_tem_comms-0.2.0 → pigeon_tem_comms-0.4.0}/tests/test_ui.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pigeon-tem-comms
3
- Version: 0.2.0
3
+ Version: 0.4.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
@@ -4,11 +4,8 @@ from . import scope
4
4
  from . import stage
5
5
  from . import tile
6
6
  from . import ui
7
+ from . import montage
7
8
 
8
- import importlib.metadata
9
-
10
-
11
- __version__ = importlib.metadata.version("pigeon-tem-comms")
12
9
 
13
10
  topics = {
14
11
  "buffer.status": buffer.Status,
@@ -35,7 +32,6 @@ topics = {
35
32
  "ui.edit": ui.Edit,
36
33
  "ui.run": ui.Run,
37
34
  "ui.setup": ui.Setup,
35
+ "montage.start": montage.Start,
36
+ "montage.finished": montage.Finished,
38
37
  }
39
-
40
-
41
- msgs = (topics, __version__)
@@ -1,23 +1,30 @@
1
1
  from pigeon import BaseMessage
2
+ from typing import Optional
3
+
2
4
 
3
5
  class Command(BaseMessage):
4
6
  tile_id: str
5
7
 
8
+
6
9
  class Image(BaseMessage):
7
10
  tile_id: str
8
11
  path: str
9
12
 
13
+
10
14
  class Settings(BaseMessage):
11
15
  exposure: float | None = None
16
+ gain: Optional[float] = None
12
17
  width: int | None = None
13
18
  height: int | None = None
14
19
 
20
+
15
21
  class Status(BaseMessage):
16
22
  exposure: float
23
+ gain: float
17
24
  width: int
18
25
  height: int
19
26
  temp: float
20
27
  target_temp: float
21
28
  device_name: str
22
29
  device_model_id: int
23
- device_sn: str
30
+ device_sn: str
@@ -0,0 +1,15 @@
1
+ from pigeon import BaseMessage
2
+ from typing import Mapping, List, Any
3
+
4
+
5
+ class Start(BaseMessage):
6
+ montage_id: str
7
+ num_tiles: int
8
+
9
+
10
+ class Finished(BaseMessage):
11
+ montage_id: str
12
+ num_tiles: int
13
+ roi: str
14
+ specimen: str
15
+ metadata: Mapping[str, Any] | List[Any]
@@ -2,6 +2,7 @@ from pigeon import BaseMessage
2
2
  from typing import Literal
3
3
  from pydantic import model_validator
4
4
 
5
+
5
6
  class Command(BaseMessage):
6
7
  focus: int | None = None
7
8
  mag_mode: Literal["LM", "MAG1", "MAG2"] | None = None
@@ -18,4 +19,4 @@ class Status(BaseMessage):
18
19
  aperture: str | None
19
20
  mag_mode: str
20
21
  mag: int
21
- tank_voltage: int
22
+ tank_voltage: int
@@ -1,3 +1,3 @@
1
1
  from . import aperture
2
2
  from . import motion
3
- from . import rotation
3
+ from . import rotation
@@ -1,10 +1,12 @@
1
1
  from pigeon import BaseMessage
2
2
 
3
+
3
4
  class Command(BaseMessage):
4
5
  aperture_id: int | None = None
5
6
  calibrate: bool = False
6
7
 
8
+
7
9
  class Status(BaseMessage):
8
10
  current_aperture: int
9
11
  calibrated: bool
10
- error: str = ""
12
+ error: str = ""
@@ -1,12 +1,14 @@
1
1
  from pigeon import BaseMessage
2
2
 
3
+
3
4
  class Command(BaseMessage):
4
5
  x: int | None = None
5
6
  y: int | None = None
6
7
  calibrate: bool = False
7
8
 
9
+
8
10
  class Status(BaseMessage):
9
11
  x: int
10
12
  y: int
11
13
  in_motion: bool
12
- error: str = ""
14
+ error: str = ""
@@ -1,12 +1,14 @@
1
1
  from pigeon import BaseMessage
2
2
 
3
+
3
4
  class Command(BaseMessage):
4
5
  angle_x: float | None = None
5
6
  angle_y: float | None = None
6
7
  calibrate: bool = False
7
8
 
9
+
8
10
  class Status(BaseMessage):
9
11
  angle_x: float
10
12
  angle_y: float
11
13
  in_motion: bool
12
- error: str = ""
14
+ error: str = ""
@@ -12,22 +12,24 @@ class Minimap(BaseMessage):
12
12
  path: str
13
13
 
14
14
 
15
- class Processed(BaseMessage):
16
- tile_id: str
17
- path: str
18
-
19
-
20
15
  class Raw(BaseMessage):
21
16
  tile_id: str
22
17
  montage_id: str
23
18
  path: str
24
19
  row: int
25
20
  column: int
26
- overlap: float
21
+ overlap: int
27
22
 
28
23
 
29
24
  class Transform(BaseMessage):
25
+ montage_id: str
30
26
  tile_id: str
31
27
  rotation: float
32
28
  x: float
33
29
  y: float
30
+
31
+
32
+ class Processed(BaseMessage):
33
+ montage_id: str
34
+ tile_id: str
35
+ path: str
@@ -1,15 +1,22 @@
1
1
  from pigeon import BaseMessage
2
2
 
3
+
3
4
  class Focus(BaseMessage):
5
+ montage_id: str
4
6
  tile_id: str
5
7
  focus: float
6
8
 
9
+
7
10
  class Histogram(BaseMessage):
11
+ montage_id: str
8
12
  tile_id: str
9
13
  path: str
10
14
 
15
+
11
16
  class MinMaxMean(BaseMessage):
17
+ montage_id: str
12
18
  tile_id: str
13
19
  min: int
14
20
  max: int
15
- mean: int
21
+ mean: int
22
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pigeon-tem-comms
3
- Version: 0.2.0
3
+ Version: 0.4.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
@@ -4,6 +4,7 @@ pyproject.toml
4
4
  TEM_comms/__init__.py
5
5
  TEM_comms/buffer.py
6
6
  TEM_comms/camera.py
7
+ TEM_comms/montage.py
7
8
  TEM_comms/scope.py
8
9
  TEM_comms/ui.py
9
10
  TEM_comms/stage/__init__.py
@@ -0,0 +1,2 @@
1
+ [pigeon.msgs]
2
+ msgs = TEM_comms:topics
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pigeon-tem-comms"
3
- version = "0.2.0"
3
+ version = "0.4.0"
4
4
  authors = [
5
5
  { name="Cameron Devine", email="cameron.devine@alleninstitute.org" },
6
6
  ]
@@ -21,7 +21,7 @@ classifiers = [
21
21
  ]
22
22
 
23
23
  [project.entry-points."pigeon.msgs"]
24
- msgs = "TEM_comms:msgs"
24
+ msgs = "TEM_comms:topics"
25
25
 
26
26
  [project.urls]
27
27
  Homepage = "https://github.com/AllenInstitute/TEM_comms"
@@ -0,0 +1,64 @@
1
+ import re
2
+
3
+ import pytest
4
+ from TEM_comms.buffer import Status
5
+
6
+ from pydantic import ValidationError
7
+
8
+
9
+ # Test cases for the Status class
10
+ @pytest.mark.parametrize(
11
+ "queue_length, free_space, upload_rate, test_id",
12
+ [
13
+ (10, 100, 20, "test_id_01"), # Happy path: normal values
14
+ (0, 0, 0, "test_id_02"), # Edge case: zero values
15
+ (100, 500, 100, "test_id_03"), # Happy path: higher values
16
+ (-1, -100, -10, "test_id_04"), # Error case: negative values
17
+ (1e6, 1e6, 1e4, "test_id_05"), # Edge case: very large values
18
+ ],
19
+ )
20
+ def test_status_initialization(queue_length, free_space, upload_rate, test_id):
21
+ # Act
22
+ status = Status(
23
+ queue_length=queue_length, free_space=free_space, upload_rate=upload_rate
24
+ )
25
+
26
+ # Assert
27
+ assert (
28
+ status.queue_length == queue_length
29
+ ), f"{test_id}: queue_length does not match"
30
+ assert status.free_space == free_space, f"{test_id}: free_space does not match"
31
+ assert status.upload_rate == upload_rate, f"{test_id}: upload_rate does not match"
32
+
33
+
34
+ # Test cases for handling type errors
35
+ @pytest.mark.parametrize(
36
+ "queue_length, free_space, upload_rate, test_id",
37
+ [
38
+ (
39
+ "ten",
40
+ 100,
41
+ 20,
42
+ "test_id_06",
43
+ ), # Error case: string instead of int for queue_length
44
+ (
45
+ 10,
46
+ "hundred",
47
+ 20,
48
+ "test_id_07",
49
+ ), # Error case: string instead of int for free_space
50
+ (
51
+ 10,
52
+ 100,
53
+ "twenty",
54
+ "test_id_08",
55
+ ), # Error case: string instead of int for upload_rate
56
+ ],
57
+ )
58
+ def test_status_type_errors(queue_length, free_space, upload_rate, test_id):
59
+ # Act and Assert
60
+ expected_error_pattern = re.escape("validation error")
61
+ with pytest.raises(ValidationError, match=expected_error_pattern):
62
+ Status(
63
+ queue_length=queue_length, free_space=free_space, upload_rate=upload_rate
64
+ )
@@ -2,20 +2,22 @@ from TEM_comms.scope import Command
2
2
  from pydantic import ValidationError
3
3
  import pytest
4
4
 
5
+
5
6
  def test_mag():
6
7
  with pytest.raises(ValidationError):
7
8
  Command(mag_mode="LM")
8
-
9
+
9
10
  with pytest.raises(ValidationError):
10
11
  Command(mag=10)
11
12
 
12
13
  Command()
13
14
  Command(mag_mode="LM", mag=1)
14
15
 
16
+
15
17
  def test_mag_mode():
16
18
  with pytest.raises(ValidationError):
17
19
  Command(mag_mode="test", mag=1)
18
20
 
19
21
  Command(mag_mode="LM", mag=1)
20
22
  Command(mag_mode="MAG2", mag=1)
21
- Command(mag_mode="MAG2", mag=1)
23
+ Command(mag_mode="MAG2", mag=1)
@@ -1,2 +0,0 @@
1
- [pigeon.msgs]
2
- msgs = TEM_comms:msgs
@@ -1,41 +0,0 @@
1
- import re
2
-
3
- import pytest
4
- from TEM_comms.buffer import Status
5
-
6
- from pydantic import ValidationError
7
-
8
- # Test cases for the Status class
9
- @pytest.mark.parametrize(
10
- "queue_length, free_space, upload_rate, test_id",
11
- [
12
- (10, 100, 20, "test_id_01"), # Happy path: normal values
13
- (0, 0, 0, "test_id_02"), # Edge case: zero values
14
- (100, 500, 100, "test_id_03"), # Happy path: higher values
15
- (-1, -100, -10, "test_id_04"), # Error case: negative values
16
- (1e6, 1e6, 1e4, "test_id_05"), # Edge case: very large values
17
- ]
18
- )
19
- def test_status_initialization(queue_length, free_space, upload_rate, test_id):
20
- # Act
21
- status = Status(queue_length=queue_length, free_space=free_space, upload_rate=upload_rate)
22
-
23
- # Assert
24
- assert status.queue_length == queue_length, f"{test_id}: queue_length does not match"
25
- assert status.free_space == free_space, f"{test_id}: free_space does not match"
26
- assert status.upload_rate == upload_rate, f"{test_id}: upload_rate does not match"
27
-
28
- # Test cases for handling type errors
29
- @pytest.mark.parametrize(
30
- "queue_length, free_space, upload_rate, test_id",
31
- [
32
- ("ten", 100, 20, "test_id_06"), # Error case: string instead of int for queue_length
33
- (10, "hundred", 20, "test_id_07"), # Error case: string instead of int for free_space
34
- (10, 100, "twenty", "test_id_08"), # Error case: string instead of int for upload_rate
35
- ]
36
- )
37
- def test_status_type_errors(queue_length, free_space, upload_rate, test_id):
38
- # Act and Assert
39
- expected_error_pattern = re.escape("validation error")
40
- with pytest.raises(ValidationError, match=expected_error_pattern):
41
- Status(queue_length=queue_length, free_space=free_space, upload_rate=upload_rate)