pymmcore-plus 0.10.2__py3-none-any.whl → 0.11.0__py3-none-any.whl
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.
- pymmcore_plus/__init__.py +4 -1
- pymmcore_plus/_build.py +2 -0
- pymmcore_plus/_cli.py +47 -12
- pymmcore_plus/_util.py +99 -9
- pymmcore_plus/core/__init__.py +2 -0
- pymmcore_plus/core/_constants.py +109 -8
- pymmcore_plus/core/_mmcore_plus.py +67 -47
- pymmcore_plus/mda/__init__.py +2 -2
- pymmcore_plus/mda/_engine.py +148 -98
- pymmcore_plus/mda/_protocol.py +5 -3
- pymmcore_plus/mda/_runner.py +16 -21
- pymmcore_plus/mda/events/_protocol.py +10 -2
- pymmcore_plus/mda/handlers/_5d_writer_base.py +25 -13
- pymmcore_plus/mda/handlers/_img_sequence_writer.py +9 -5
- pymmcore_plus/mda/handlers/_ome_tiff_writer.py +7 -3
- pymmcore_plus/mda/handlers/_ome_zarr_writer.py +9 -4
- pymmcore_plus/mda/handlers/_tensorstore_handler.py +19 -19
- pymmcore_plus/metadata/__init__.py +36 -0
- pymmcore_plus/metadata/functions.py +343 -0
- pymmcore_plus/metadata/schema.py +471 -0
- pymmcore_plus/metadata/serialize.py +116 -0
- pymmcore_plus/model/_config_file.py +2 -4
- pymmcore_plus/model/_config_group.py +29 -3
- pymmcore_plus/model/_device.py +20 -1
- pymmcore_plus/model/_microscope.py +35 -1
- pymmcore_plus/model/_pixel_size_config.py +25 -3
- {pymmcore_plus-0.10.2.dist-info → pymmcore_plus-0.11.0.dist-info}/METADATA +4 -3
- pymmcore_plus-0.11.0.dist-info/RECORD +59 -0
- {pymmcore_plus-0.10.2.dist-info → pymmcore_plus-0.11.0.dist-info}/WHEEL +1 -1
- pymmcore_plus/core/_state.py +0 -244
- pymmcore_plus-0.10.2.dist-info/RECORD +0 -56
- {pymmcore_plus-0.10.2.dist-info → pymmcore_plus-0.11.0.dist-info}/entry_points.txt +0 -0
- {pymmcore_plus-0.10.2.dist-info → pymmcore_plus-0.11.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -15,6 +15,7 @@ from ._pixel_size_config import PixelSizeGroup
|
|
|
15
15
|
|
|
16
16
|
if TYPE_CHECKING:
|
|
17
17
|
from pymmcore_plus import CMMCorePlus
|
|
18
|
+
from pymmcore_plus.metadata.schema import SummaryMetaV1
|
|
18
19
|
|
|
19
20
|
from ._core_link import ErrCallback
|
|
20
21
|
from ._property import Property
|
|
@@ -126,7 +127,7 @@ class Microscope:
|
|
|
126
127
|
# ------------- Config-file methods -------------
|
|
127
128
|
|
|
128
129
|
@classmethod
|
|
129
|
-
def create_from_config(cls, config_file: str) -> Microscope:
|
|
130
|
+
def create_from_config(cls, config_file: str | Path) -> Microscope:
|
|
130
131
|
obj = cls()
|
|
131
132
|
obj.load_config(config_file)
|
|
132
133
|
obj.mark_clean()
|
|
@@ -154,6 +155,39 @@ class Microscope:
|
|
|
154
155
|
|
|
155
156
|
self.mark_clean()
|
|
156
157
|
|
|
158
|
+
@classmethod
|
|
159
|
+
def from_summary_metadata(cls, summary_meta: SummaryMetaV1) -> Microscope:
|
|
160
|
+
"""Create a Microscope model from summary metadata.
|
|
161
|
+
|
|
162
|
+
This may be used to load a model from summary metadata, such as as written
|
|
163
|
+
during the course of a Multi-Dimensional Acquisition. This is useful for
|
|
164
|
+
restoring the state of a microscope from a specific experiment, or writing
|
|
165
|
+
out a cfg file that can be used to restore the state of the microscope.
|
|
166
|
+
"""
|
|
167
|
+
core_device = next(
|
|
168
|
+
(d for d in summary_meta["devices"] if d["name"] == Keyword.CoreDevice),
|
|
169
|
+
None,
|
|
170
|
+
)
|
|
171
|
+
if core_device is None:
|
|
172
|
+
raise ValueError("CoreDevice not found in metadata")
|
|
173
|
+
return cls(
|
|
174
|
+
core_device=CoreDevice.from_metadata(core_device),
|
|
175
|
+
devices=[
|
|
176
|
+
Device.from_metadata(d)
|
|
177
|
+
for d in summary_meta["devices"]
|
|
178
|
+
if d["name"] != Keyword.CoreDevice
|
|
179
|
+
],
|
|
180
|
+
config_groups={
|
|
181
|
+
grp["name"]: ConfigGroup.from_metadata(grp)
|
|
182
|
+
for grp in summary_meta["config_groups"]
|
|
183
|
+
},
|
|
184
|
+
pixel_size_group=PixelSizeGroup.from_metadata(
|
|
185
|
+
summary_meta["pixel_size_configs"]
|
|
186
|
+
),
|
|
187
|
+
config_file=summary_meta["system_info"].get("system_configuration_file")
|
|
188
|
+
or "",
|
|
189
|
+
)
|
|
190
|
+
|
|
157
191
|
# ------------- Core-interacting methods -------------
|
|
158
192
|
|
|
159
193
|
@classmethod
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass, field, fields
|
|
4
|
-
from typing import TYPE_CHECKING
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
5
|
|
|
6
6
|
from ._config_group import ConfigGroup, ConfigPreset, Setting
|
|
7
7
|
|
|
8
8
|
if TYPE_CHECKING:
|
|
9
|
-
from typing import Final
|
|
9
|
+
from typing import Any, Container, Final, Iterable, MutableMapping
|
|
10
10
|
|
|
11
|
-
from typing_extensions import
|
|
11
|
+
from typing_extensions import (
|
|
12
|
+
Self, # py311
|
|
13
|
+
TypeAlias, # py310
|
|
14
|
+
)
|
|
12
15
|
|
|
13
16
|
from pymmcore_plus import CMMCorePlus
|
|
17
|
+
from pymmcore_plus.metadata.schema import PixelSizeConfigPreset
|
|
14
18
|
|
|
15
19
|
from ._core_link import ErrCallback
|
|
16
20
|
|
|
@@ -27,6 +31,14 @@ class PixelSizePreset(ConfigPreset):
|
|
|
27
31
|
pixel_size_um: float = 0.0
|
|
28
32
|
affine: AffineTuple = DEFAULT_AFFINE
|
|
29
33
|
|
|
34
|
+
@classmethod
|
|
35
|
+
def from_metadata(cls, meta: PixelSizeConfigPreset) -> Self: # type: ignore [override]
|
|
36
|
+
obj = super().from_metadata(meta)
|
|
37
|
+
obj.pixel_size_um = meta["pixel_size_um"]
|
|
38
|
+
if "pixel_size_affine" in meta:
|
|
39
|
+
obj.affine = meta["pixel_size_affine"]
|
|
40
|
+
return obj
|
|
41
|
+
|
|
30
42
|
def __rich_repr__(self, *, defaults: bool = False) -> Iterable[tuple[str, Any]]:
|
|
31
43
|
"""Make AvailableDevices look a little less verbose."""
|
|
32
44
|
for f in fields(self):
|
|
@@ -45,6 +57,16 @@ class PixelSizeGroup(ConfigGroup):
|
|
|
45
57
|
name: str = PIXEL_SIZE_GROUP
|
|
46
58
|
presets: MutableMapping[str, PixelSizePreset] = field(default_factory=dict) # type: ignore
|
|
47
59
|
|
|
60
|
+
@classmethod
|
|
61
|
+
def from_metadata(cls, meta: tuple[PixelSizeConfigPreset, ...]) -> Self: # type: ignore [override]
|
|
62
|
+
"""Create a PixelSizeGroup from metadata."""
|
|
63
|
+
return cls(
|
|
64
|
+
presets={
|
|
65
|
+
preset_info["name"]: PixelSizePreset.from_metadata(preset_info)
|
|
66
|
+
for preset_info in meta
|
|
67
|
+
}
|
|
68
|
+
)
|
|
69
|
+
|
|
48
70
|
@classmethod
|
|
49
71
|
def create_from_core(
|
|
50
72
|
cls, core: CMMCorePlus, name: str = PIXEL_SIZE_GROUP
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pymmcore-plus
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.0
|
|
4
4
|
Summary: pymmcore superset providing improved APIs, event handling, and a pure python acquisition engine
|
|
5
5
|
Project-URL: Source, https://github.com/pymmcore-plus/pymmcore-plus
|
|
6
6
|
Project-URL: Tracker, https://github.com/pymmcore-plus/pymmcore-plus/issues
|
|
@@ -47,6 +47,7 @@ Requires-Dist: ruff; extra == 'dev'
|
|
|
47
47
|
Requires-Dist: tensorstore-stubs; extra == 'dev'
|
|
48
48
|
Provides-Extra: docs
|
|
49
49
|
Requires-Dist: mkdocs-material; extra == 'docs'
|
|
50
|
+
Requires-Dist: mkdocs-typer==0.0.3; extra == 'docs'
|
|
50
51
|
Requires-Dist: mkdocs>=1.4; extra == 'docs'
|
|
51
52
|
Requires-Dist: mkdocstrings-python==1.1.2; extra == 'docs'
|
|
52
53
|
Requires-Dist: mkdocstrings==0.22.0; extra == 'docs'
|
|
@@ -55,6 +56,7 @@ Requires-Dist: tifffile>=2021.6.14; extra == 'io'
|
|
|
55
56
|
Requires-Dist: zarr>=2.2; extra == 'io'
|
|
56
57
|
Provides-Extra: test
|
|
57
58
|
Requires-Dist: msgpack; extra == 'test'
|
|
59
|
+
Requires-Dist: msgspec; extra == 'test'
|
|
58
60
|
Requires-Dist: pytest-cov>=4; extra == 'test'
|
|
59
61
|
Requires-Dist: pytest-qt>=4; extra == 'test'
|
|
60
62
|
Requires-Dist: pytest>=7.3.2; extra == 'test'
|
|
@@ -143,8 +145,7 @@ provides a python API to control the C++ core directly, without the need for
|
|
|
143
145
|
Java in the loop. Each has its own advantages and disadvantages! With
|
|
144
146
|
pycro-manager you immediately get the entire existing micro-manager ecosystem
|
|
145
147
|
and GUI application. With pymmcore-plus you don't need to install Java, and you
|
|
146
|
-
have direct access to the memory buffers used by the C++ core
|
|
147
|
-
side of things is far less mature.
|
|
148
|
+
have direct access to the memory buffers used by the C++ core.
|
|
148
149
|
|
|
149
150
|
## Quickstart
|
|
150
151
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
pymmcore_plus/__init__.py,sha256=y2y48MqOnY-B1h7QnJc36HRDuXEegMsPNqKq51bu8DQ,1415
|
|
2
|
+
pymmcore_plus/_build.py,sha256=PU6rm_4l-SGMurPQT5RuloUMkrgqKTI0Y9ePbPmWOmo,10928
|
|
3
|
+
pymmcore_plus/_cli.py,sha256=M2ndZGKv6HN7DtVaeB48bAQiaJN8Yu8GcupjaGZelNQ,14291
|
|
4
|
+
pymmcore_plus/_logger.py,sha256=IQl--kuEQqUwV9C4P1sY-7J5IW6V7q45wsi2NbfnAbM,5088
|
|
5
|
+
pymmcore_plus/_util.py,sha256=mNabztc90ck1rN_15RtaYjk6acyP2azSJGzMkyeJELs,20247
|
|
6
|
+
pymmcore_plus/install.py,sha256=a85-KCifBetKSQXwH1DqEkz7il5iqFcl9LR0qFIVvbk,8503
|
|
7
|
+
pymmcore_plus/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
pymmcore_plus/seq_tester.py,sha256=6PqLFHpd0SvnzYVtE80AxytiqCVtB1ULiU1myzO3G7w,3768
|
|
9
|
+
pymmcore_plus/core/__init__.py,sha256=r9bvL6sqgN72ZV7785WuRKT-o1VlsbYQcAKSy3rNS9k,897
|
|
10
|
+
pymmcore_plus/core/_adapter.py,sha256=eu2BhGe_dnoQrIsh-u3poxWXsiF2Y8pfbKIGWbUgOk8,2857
|
|
11
|
+
pymmcore_plus/core/_config.py,sha256=5Vzwv2QEuJSXgKjERSHiTzwmpWyizY_aa4n3OjpPyPc,10620
|
|
12
|
+
pymmcore_plus/core/_config_group.py,sha256=w-psUtMk3X6MzqU17j4D2yZ_ugLP7u0-mvPIXPuIxwQ,8472
|
|
13
|
+
pymmcore_plus/core/_constants.py,sha256=55lKxI38TXceowsM_Z7ShWZ-DfQiBJB_qqzaU8G9PSc,11743
|
|
14
|
+
pymmcore_plus/core/_device.py,sha256=Uy5A58Jj_bIY5n6OymtTJPRnYkktoCq6ZtQV4KcLwPo,7756
|
|
15
|
+
pymmcore_plus/core/_metadata.py,sha256=64RdptyRGRqtRJ8pWMlAyevSgYMAE1Hzs8TB3DBQHAA,2618
|
|
16
|
+
pymmcore_plus/core/_mmcore_plus.py,sha256=fOtv3hf11YkV7ekEZePOS0tCkDqGdFpihqrIZot20n8,87548
|
|
17
|
+
pymmcore_plus/core/_property.py,sha256=sd28rZE-_l4HaIJxqJlUX7DlM-Fa9_Xr6cLERwOtBYc,8283
|
|
18
|
+
pymmcore_plus/core/_sequencing.py,sha256=ueyuqsUPbfH7FLMdqFUpHoxSZfBRHHkYmv12lOt72hI,11847
|
|
19
|
+
pymmcore_plus/core/events/__init__.py,sha256=8NjFkVdRVRiiLUQ_brGQSlTaK3rqNizdNEX17NEXAis,1106
|
|
20
|
+
pymmcore_plus/core/events/_device_signal_view.py,sha256=st_di51xOmKKOM9-yY8ouKlTZqG-7NWorRaoaN1sJ44,1065
|
|
21
|
+
pymmcore_plus/core/events/_norm_slot.py,sha256=cp6VeH5h98G7bPWrKzTsHJmzCIbi2D4sv6bSdywQbsk,2937
|
|
22
|
+
pymmcore_plus/core/events/_prop_event_mixin.py,sha256=XfoXrMjRRXPHv6XkavBmSuz-6nItpJ8oG60DqK2WBEA,3939
|
|
23
|
+
pymmcore_plus/core/events/_protocol.py,sha256=Cf9uGZe_uP8nIa8rsaDIX5RCW5pNQQt2juLL-rriRn4,7448
|
|
24
|
+
pymmcore_plus/core/events/_psygnal.py,sha256=owaKlW2zpvocXDbAW4kHovBoVv4Fjfn-S5oUJrVWsD4,1646
|
|
25
|
+
pymmcore_plus/core/events/_qsignals.py,sha256=gr-GDiSVLhFhSfaoKrdTz2y3I_2IUg62bYDGuGrB3j0,3018
|
|
26
|
+
pymmcore_plus/mda/__init__.py,sha256=NF4OReQbShxZeLFaNaLPyMwkr1e5j5zMZmzHvHeSBzE,298
|
|
27
|
+
pymmcore_plus/mda/_engine.py,sha256=qHIMwLsl9NROa8pVv41dKzZP3OoNeRhosMjuIL4a0sY,24432
|
|
28
|
+
pymmcore_plus/mda/_protocol.py,sha256=vuotAc2P1zl2EX4wGjfaasarQHNqtF5UpOwPtUqHG2Y,3245
|
|
29
|
+
pymmcore_plus/mda/_runner.py,sha256=edgRQo-YRzF5f2VEVjATsTV70wUjuRcUFF5XtRLgguE,15498
|
|
30
|
+
pymmcore_plus/mda/_thread_relay.py,sha256=wjP1tag7nN2Sr0RzaPnYRqHl8XjAQg2MpXOt0ONLcQ8,6112
|
|
31
|
+
pymmcore_plus/mda/events/__init__.py,sha256=UZFBlIzTmKqgMw_vVSZSSAN1tkAu8qccYb-aXXBRc3I,1192
|
|
32
|
+
pymmcore_plus/mda/events/_protocol.py,sha256=9Q7LjYOgEWQGS8gHMV97UXM9bhoVW2OeyoPyNsQbwzw,1659
|
|
33
|
+
pymmcore_plus/mda/events/_psygnal.py,sha256=TdN1mFGpTPXmEs9iwFKSC1svv87PDZkT2JZvl0tEGrQ,640
|
|
34
|
+
pymmcore_plus/mda/events/_qsignals.py,sha256=tULQg-e_NX197DxJXaWHn1zLJ-4tzc9QyOAnsobEDtA,554
|
|
35
|
+
pymmcore_plus/mda/handlers/_5d_writer_base.py,sha256=myFcpj_uqoBkYb_1JFB0GjmRhFxW-8jyZAhqoO8CRfo,11893
|
|
36
|
+
pymmcore_plus/mda/handlers/__init__.py,sha256=yQFRVDdCyu5t2JilobHGPC8lgCY4htNF5dzctrteSZA,305
|
|
37
|
+
pymmcore_plus/mda/handlers/_img_sequence_writer.py,sha256=bOnw9htxovIqUhJCoJml5YayaWD30IN2uuB_TijNVHk,11522
|
|
38
|
+
pymmcore_plus/mda/handlers/_ome_tiff_writer.py,sha256=pqqdl3KQd0tH5Gp4rHVgYqqh2Y8iwoKRXTjwq1JLy1E,6239
|
|
39
|
+
pymmcore_plus/mda/handlers/_ome_zarr_writer.py,sha256=ReJW8bnk-vQk4J1Zd66swkQATg17uV_hzpoBosUWuP4,12253
|
|
40
|
+
pymmcore_plus/mda/handlers/_tensorstore_handler.py,sha256=gweY2WoXgjPmiQbfTgL3TwB4b-u8cjlrlWEr-5n84OM,14642
|
|
41
|
+
pymmcore_plus/mda/handlers/_util.py,sha256=p-8Gg5Q2Jo0zyYdniP9a0NirUOnuKNLWzwjhzcKqskg,1601
|
|
42
|
+
pymmcore_plus/metadata/__init__.py,sha256=r_2dI4qbc5GPl3MP6ye-W7-c1RBZZXkCgFqJ4HaPJOA,699
|
|
43
|
+
pymmcore_plus/metadata/functions.py,sha256=b9bdLwvzqzhku4cLkFfRiAUXL8-wJNaZKayYzks39qg,12254
|
|
44
|
+
pymmcore_plus/metadata/schema.py,sha256=bP0SMwMfvgTfmTKMIWveAXbw5fDnE18kmFYu-FLenAM,17260
|
|
45
|
+
pymmcore_plus/metadata/serialize.py,sha256=XB-epU7-bJfmP6HItBH9t0-lOsJuW7xSFjc5y3mO1Jg,3701
|
|
46
|
+
pymmcore_plus/model/__init__.py,sha256=zKZkkSpNK4ERu-VMdi9gvRrj1aXAjNaYxlYB5PdYSg0,479
|
|
47
|
+
pymmcore_plus/model/_config_file.py,sha256=46xdrVLa193uNbQxq0puzWYDcfFIqRAw6M8v9TVu3U4,13249
|
|
48
|
+
pymmcore_plus/model/_config_group.py,sha256=O9DzPyKe2Q3iInsQNbDsQfJeCWVcnzgMHGD_zXTMBw0,3376
|
|
49
|
+
pymmcore_plus/model/_core_device.py,sha256=afNYGIRFunUPYNYJ_yHJwOjo7HO9FW8qGWTMeiKRmNU,2370
|
|
50
|
+
pymmcore_plus/model/_core_link.py,sha256=myE0qa2pEWEinbsIhTN4uB_c-lr9dtUG3npLgsHEI_0,2706
|
|
51
|
+
pymmcore_plus/model/_device.py,sha256=IuSTdxR6OwGnmhTgV77QDEwIwuZOLbmU-gCnSdd2H-c,15717
|
|
52
|
+
pymmcore_plus/model/_microscope.py,sha256=CkzkpGtl1n-phMtDBygsIa7wVnTWLtEqgZ-hgZYxdRE,11284
|
|
53
|
+
pymmcore_plus/model/_pixel_size_config.py,sha256=l-BkE7NuBcnXfytEPIblYA5vgCqb4nhvv1yhSCvr8pQ,3499
|
|
54
|
+
pymmcore_plus/model/_property.py,sha256=gJM7SFjLB2HnN0E8HOn4qVlB2wAxmkEFxSJFjKauZEk,3328
|
|
55
|
+
pymmcore_plus-0.11.0.dist-info/METADATA,sha256=DxCVFUfpvr1bEbezpQ6O73IBBAD01sTUiADwP7Tk0Y4,9265
|
|
56
|
+
pymmcore_plus-0.11.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
|
57
|
+
pymmcore_plus-0.11.0.dist-info/entry_points.txt,sha256=NtFyndrQzBpUNJyil-8e5hMGke2utAf7mkGavTLcLOY,51
|
|
58
|
+
pymmcore_plus-0.11.0.dist-info/licenses/LICENSE,sha256=OHJjRpOPKKRc7FEnpehNWdR5LRBdBhUtIFG-ZI0dCEA,1522
|
|
59
|
+
pymmcore_plus-0.11.0.dist-info/RECORD,,
|
pymmcore_plus/core/_state.py
DELETED
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from contextlib import suppress
|
|
4
|
-
from typing import TYPE_CHECKING, Any, Literal, Sequence, TypedDict, cast
|
|
5
|
-
|
|
6
|
-
if TYPE_CHECKING:
|
|
7
|
-
from pymmcore_plus import CMMCorePlus
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class SystemInfoDict(TypedDict):
|
|
11
|
-
APIVersionInfo: str
|
|
12
|
-
BufferFreeCapacity: int
|
|
13
|
-
BufferTotalCapacity: int
|
|
14
|
-
CircularBufferMemoryFootprint: int
|
|
15
|
-
DeviceAdapterSearchPaths: tuple[str, ...]
|
|
16
|
-
PrimaryLogFile: str
|
|
17
|
-
RemainingImageCount: int
|
|
18
|
-
TimeoutMs: int # rarely needed for metadata
|
|
19
|
-
VersionInfo: str
|
|
20
|
-
# these were removed in mmcore11 and probably shouldn't be used anyway
|
|
21
|
-
# HostName: str
|
|
22
|
-
# MACAddresses: tuple[str, ...]
|
|
23
|
-
# UserId: str
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class ImageDict(TypedDict):
|
|
27
|
-
BytesPerPixel: int
|
|
28
|
-
CurrentPixelSizeConfig: str
|
|
29
|
-
Exposure: float
|
|
30
|
-
ImageBitDepth: int
|
|
31
|
-
ImageBufferSize: int
|
|
32
|
-
ImageHeight: int
|
|
33
|
-
ImageWidth: int
|
|
34
|
-
MagnificationFactor: float
|
|
35
|
-
MultiROI: tuple[list[int], list[int], list[int], list[int]] | None
|
|
36
|
-
NumberOfCameraChannels: int
|
|
37
|
-
NumberOfComponents: int
|
|
38
|
-
PixelSizeAffine: tuple[float, float, float, float, float, float]
|
|
39
|
-
PixelSizeUm: int
|
|
40
|
-
ROI: list[int]
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
class PositionDict(TypedDict):
|
|
44
|
-
X: float | None
|
|
45
|
-
Y: float | None
|
|
46
|
-
Focus: float | None
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
class AutoFocusDict(TypedDict):
|
|
50
|
-
CurrentFocusScore: float
|
|
51
|
-
LastFocusScore: float
|
|
52
|
-
AutoFocusOffset: float | None
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
class PixelSizeConfigDict(TypedDict):
|
|
56
|
-
Objective: dict[str, str]
|
|
57
|
-
PixelSizeUm: float
|
|
58
|
-
PixelSizeAffine: tuple[float, float, float, float, float, float]
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
class DeviceTypeDict(TypedDict):
|
|
62
|
-
Type: str
|
|
63
|
-
Description: str
|
|
64
|
-
Adapter: str
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
class SystemStatusDict(TypedDict):
|
|
68
|
-
debugLogEnabled: bool
|
|
69
|
-
isBufferOverflowed: bool
|
|
70
|
-
isContinuousFocusEnabled: bool
|
|
71
|
-
isContinuousFocusLocked: bool
|
|
72
|
-
isSequenceRunning: bool
|
|
73
|
-
stderrLogEnabled: bool
|
|
74
|
-
systemBusy: bool
|
|
75
|
-
autoShutter: bool
|
|
76
|
-
shutterOpen: bool
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
class StateDict(TypedDict, total=False):
|
|
80
|
-
Devices: dict[str, dict[str, str]]
|
|
81
|
-
SystemInfo: SystemInfoDict
|
|
82
|
-
SystemStatus: SystemStatusDict
|
|
83
|
-
ConfigGroups: dict[str, dict[str, Any]]
|
|
84
|
-
Image: ImageDict
|
|
85
|
-
Position: PositionDict
|
|
86
|
-
AutoFocus: AutoFocusDict
|
|
87
|
-
PixelSizeConfig: dict[str, str | PixelSizeConfigDict]
|
|
88
|
-
DeviceTypes: dict[str, DeviceTypeDict]
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
def core_state(
|
|
92
|
-
core: CMMCorePlus,
|
|
93
|
-
*,
|
|
94
|
-
devices: bool = True,
|
|
95
|
-
image: bool = True,
|
|
96
|
-
system_info: bool = False,
|
|
97
|
-
system_status: bool = False,
|
|
98
|
-
config_groups: bool | Sequence[str] = True,
|
|
99
|
-
position: bool = False,
|
|
100
|
-
autofocus: bool = False,
|
|
101
|
-
pixel_size_configs: bool = False,
|
|
102
|
-
device_types: bool = False,
|
|
103
|
-
cached: bool = True,
|
|
104
|
-
error_value: Any = None,
|
|
105
|
-
) -> StateDict:
|
|
106
|
-
out: StateDict = {}
|
|
107
|
-
if devices:
|
|
108
|
-
out["Devices"] = get_device_state(core, error_value)
|
|
109
|
-
if system_info:
|
|
110
|
-
out["SystemInfo"] = get_system_info(core)
|
|
111
|
-
if system_status:
|
|
112
|
-
out["SystemStatus"] = get_system_status(core)
|
|
113
|
-
if config_groups:
|
|
114
|
-
out["ConfigGroups"] = get_config_groups(core, config_groups, cached)
|
|
115
|
-
if image:
|
|
116
|
-
out["Image"] = get_image_info(core, error_value)
|
|
117
|
-
if position:
|
|
118
|
-
out["Position"] = get_position(core, error_value)
|
|
119
|
-
if autofocus:
|
|
120
|
-
out["AutoFocus"] = get_autofocus(core, error_value)
|
|
121
|
-
if pixel_size_configs:
|
|
122
|
-
out["PixelSizeConfig"] = get_pix_size_config(core)
|
|
123
|
-
if device_types:
|
|
124
|
-
out["DeviceTypes"] = get_device_types(core)
|
|
125
|
-
return out
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
def get_device_state(
|
|
129
|
-
core: CMMCorePlus, cached: bool = True, error_value: Any = None
|
|
130
|
-
) -> dict[str, dict[str, Any]]:
|
|
131
|
-
# this actually appears to be faster than getSystemStateCache
|
|
132
|
-
getProp = core.getPropertyFromCache if cached else core.getProperty
|
|
133
|
-
device_state: dict = {}
|
|
134
|
-
for dev in core.getLoadedDevices():
|
|
135
|
-
dd = device_state.setdefault(dev, {})
|
|
136
|
-
for prop in core.getDevicePropertyNames(dev):
|
|
137
|
-
try:
|
|
138
|
-
val = getProp(dev, prop)
|
|
139
|
-
except Exception:
|
|
140
|
-
val = error_value
|
|
141
|
-
dd[prop] = val
|
|
142
|
-
return device_state
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
def get_system_info(core: CMMCorePlus) -> SystemInfoDict:
|
|
146
|
-
return { # type: ignore
|
|
147
|
-
key: getattr(core, f"get{key}")()
|
|
148
|
-
for key in sorted(SystemInfoDict.__annotations__)
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
def get_system_status(core: CMMCorePlus) -> SystemStatusDict:
|
|
153
|
-
out = {
|
|
154
|
-
"autoShutter": core.getAutoShutter(),
|
|
155
|
-
"shutterOpen": core.getShutterOpen(),
|
|
156
|
-
}
|
|
157
|
-
out.update(
|
|
158
|
-
{
|
|
159
|
-
key: getattr(core, key)()
|
|
160
|
-
for key in sorted(SystemStatusDict.__annotations__)
|
|
161
|
-
if key not in {"autoShutter", "shutterOpen"}
|
|
162
|
-
}
|
|
163
|
-
)
|
|
164
|
-
return cast("SystemStatusDict", out)
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
def get_config_groups(
|
|
168
|
-
core: CMMCorePlus,
|
|
169
|
-
config_groups: bool | Sequence[str | Literal["[Channel]"]],
|
|
170
|
-
cached: bool = True,
|
|
171
|
-
) -> dict[str, dict[str, Any]]:
|
|
172
|
-
if not isinstance(config_groups, (list, tuple, set)):
|
|
173
|
-
config_groups = core.getAvailableConfigGroups()
|
|
174
|
-
|
|
175
|
-
getState = core.getConfigGroupStateFromCache if cached else core.getConfigGroupState
|
|
176
|
-
curGrp = core.getCurrentConfigFromCache if cached else core.getCurrentConfig
|
|
177
|
-
cfg_group_dict: dict = {}
|
|
178
|
-
for grp in config_groups:
|
|
179
|
-
if grp == "[Channel]":
|
|
180
|
-
# special case for accessing channel group
|
|
181
|
-
grp = core.getChannelGroup()
|
|
182
|
-
|
|
183
|
-
grp_dict = cfg_group_dict.setdefault(grp, {})
|
|
184
|
-
grp_dict["Current"] = curGrp(grp)
|
|
185
|
-
|
|
186
|
-
for dev, prop, val in getState(grp):
|
|
187
|
-
grp_dict.setdefault(dev, {})[prop] = val
|
|
188
|
-
return cfg_group_dict
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
def get_image_info(core: CMMCorePlus, error_value: Any = None) -> ImageDict:
|
|
192
|
-
img_dict = {}
|
|
193
|
-
for key in sorted(ImageDict.__annotations__):
|
|
194
|
-
try:
|
|
195
|
-
val = getattr(core, f"get{key}")()
|
|
196
|
-
except Exception:
|
|
197
|
-
val = error_value
|
|
198
|
-
img_dict[key] = val
|
|
199
|
-
return cast("ImageDict", img_dict)
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
def get_position(core: CMMCorePlus, error_value: Any = None) -> PositionDict:
|
|
203
|
-
pos: PositionDict = {"X": error_value, "Y": error_value, "Focus": error_value}
|
|
204
|
-
with suppress(Exception):
|
|
205
|
-
pos["X"] = core.getXPosition()
|
|
206
|
-
pos["Y"] = core.getYPosition()
|
|
207
|
-
with suppress(Exception):
|
|
208
|
-
pos["Focus"] = core.getPosition()
|
|
209
|
-
return pos
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
def get_autofocus(core: CMMCorePlus, error_value: Any = None) -> AutoFocusDict:
|
|
213
|
-
out: AutoFocusDict = {
|
|
214
|
-
"CurrentFocusScore": core.getCurrentFocusScore(),
|
|
215
|
-
"LastFocusScore": core.getLastFocusScore(),
|
|
216
|
-
"AutoFocusOffset": error_value,
|
|
217
|
-
}
|
|
218
|
-
with suppress(Exception):
|
|
219
|
-
out["AutoFocusOffset"] = core.getAutoFocusOffset()
|
|
220
|
-
return out
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
def get_pix_size_config(core: CMMCorePlus) -> dict[str, str | PixelSizeConfigDict]:
|
|
224
|
-
# the Current value is a string, all the rest are PixelSizeConfigDict
|
|
225
|
-
px: dict = {"Current": core.getCurrentPixelSizeConfig()}
|
|
226
|
-
for px_cfg_name in core.getAvailablePixelSizeConfigs():
|
|
227
|
-
px_cfg_info: dict = {}
|
|
228
|
-
for dev, prop, val in core.getPixelSizeConfigData(px_cfg_name):
|
|
229
|
-
px_cfg_info.setdefault(dev, {})[prop] = val
|
|
230
|
-
px_cfg_info["PixelSizeUm"] = core.getPixelSizeUmByID(px_cfg_name)
|
|
231
|
-
px_cfg_info["PixelSizeAffine"] = core.getPixelSizeAffineByID(px_cfg_name)
|
|
232
|
-
px[px_cfg_name] = px_cfg_info
|
|
233
|
-
return px
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
def get_device_types(core: CMMCorePlus) -> dict[str, DeviceTypeDict]:
|
|
237
|
-
return {
|
|
238
|
-
dev_name: {
|
|
239
|
-
"Type": core.getDeviceType(dev_name).name,
|
|
240
|
-
"Description": core.getDeviceDescription(dev_name),
|
|
241
|
-
"Adapter": core.getDeviceName(dev_name),
|
|
242
|
-
}
|
|
243
|
-
for dev_name in core.getLoadedDevices()
|
|
244
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
pymmcore_plus/__init__.py,sha256=byZeA2-r2pGztxIZgCDZ__Q2DYddc4aQ2alWg2pgQ5I,1337
|
|
2
|
-
pymmcore_plus/_build.py,sha256=_jw1e1PWaIejjeghPTweySdgeohle0jhqVDagYNT3k8,10892
|
|
3
|
-
pymmcore_plus/_cli.py,sha256=eHKUCGz6l6X3QBnTXzOkRz6odqjaC1_kJ75uAnzzeP0,13115
|
|
4
|
-
pymmcore_plus/_logger.py,sha256=IQl--kuEQqUwV9C4P1sY-7J5IW6V7q45wsi2NbfnAbM,5088
|
|
5
|
-
pymmcore_plus/_util.py,sha256=FahG2TkIee4SPGruW8D0twEUzS729J2fbK8Yc78ocL4,17171
|
|
6
|
-
pymmcore_plus/install.py,sha256=a85-KCifBetKSQXwH1DqEkz7il5iqFcl9LR0qFIVvbk,8503
|
|
7
|
-
pymmcore_plus/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
-
pymmcore_plus/seq_tester.py,sha256=6PqLFHpd0SvnzYVtE80AxytiqCVtB1ULiU1myzO3G7w,3768
|
|
9
|
-
pymmcore_plus/core/__init__.py,sha256=8YNtX8U4PZlEJjmnxoYWbQPY6Y4jHTnYOMO4i5hdrc8,861
|
|
10
|
-
pymmcore_plus/core/_adapter.py,sha256=eu2BhGe_dnoQrIsh-u3poxWXsiF2Y8pfbKIGWbUgOk8,2857
|
|
11
|
-
pymmcore_plus/core/_config.py,sha256=5Vzwv2QEuJSXgKjERSHiTzwmpWyizY_aa4n3OjpPyPc,10620
|
|
12
|
-
pymmcore_plus/core/_config_group.py,sha256=w-psUtMk3X6MzqU17j4D2yZ_ugLP7u0-mvPIXPuIxwQ,8472
|
|
13
|
-
pymmcore_plus/core/_constants.py,sha256=bIXsi8ff-silrCbkrtBFZYG7i5SvQCz68kzPEOV9fDs,8726
|
|
14
|
-
pymmcore_plus/core/_device.py,sha256=Uy5A58Jj_bIY5n6OymtTJPRnYkktoCq6ZtQV4KcLwPo,7756
|
|
15
|
-
pymmcore_plus/core/_metadata.py,sha256=64RdptyRGRqtRJ8pWMlAyevSgYMAE1Hzs8TB3DBQHAA,2618
|
|
16
|
-
pymmcore_plus/core/_mmcore_plus.py,sha256=wMPf-Wtu2hVpRDox9450R-6B4r7rdD7KgyETV1sl_X0,86477
|
|
17
|
-
pymmcore_plus/core/_property.py,sha256=sd28rZE-_l4HaIJxqJlUX7DlM-Fa9_Xr6cLERwOtBYc,8283
|
|
18
|
-
pymmcore_plus/core/_sequencing.py,sha256=ueyuqsUPbfH7FLMdqFUpHoxSZfBRHHkYmv12lOt72hI,11847
|
|
19
|
-
pymmcore_plus/core/_state.py,sha256=80kr-_x9Z8MwZG0-mgIE0lR4XUSNOnlmKm-zzoH3BJA,7535
|
|
20
|
-
pymmcore_plus/core/events/__init__.py,sha256=8NjFkVdRVRiiLUQ_brGQSlTaK3rqNizdNEX17NEXAis,1106
|
|
21
|
-
pymmcore_plus/core/events/_device_signal_view.py,sha256=st_di51xOmKKOM9-yY8ouKlTZqG-7NWorRaoaN1sJ44,1065
|
|
22
|
-
pymmcore_plus/core/events/_norm_slot.py,sha256=cp6VeH5h98G7bPWrKzTsHJmzCIbi2D4sv6bSdywQbsk,2937
|
|
23
|
-
pymmcore_plus/core/events/_prop_event_mixin.py,sha256=XfoXrMjRRXPHv6XkavBmSuz-6nItpJ8oG60DqK2WBEA,3939
|
|
24
|
-
pymmcore_plus/core/events/_protocol.py,sha256=Cf9uGZe_uP8nIa8rsaDIX5RCW5pNQQt2juLL-rriRn4,7448
|
|
25
|
-
pymmcore_plus/core/events/_psygnal.py,sha256=owaKlW2zpvocXDbAW4kHovBoVv4Fjfn-S5oUJrVWsD4,1646
|
|
26
|
-
pymmcore_plus/core/events/_qsignals.py,sha256=gr-GDiSVLhFhSfaoKrdTz2y3I_2IUg62bYDGuGrB3j0,3018
|
|
27
|
-
pymmcore_plus/mda/__init__.py,sha256=MrRYE2rYuIw4dQib4KiRgVbTkjdsE-6tcTjns68Grzk,298
|
|
28
|
-
pymmcore_plus/mda/_engine.py,sha256=vHkMyrOAj7glNgdvltINOzFVOmhnJ1dSmp-S-GJapBE,21953
|
|
29
|
-
pymmcore_plus/mda/_protocol.py,sha256=p98OkG390Q2Rj05Cl5mza6BUTscPol_cgTxXXMkpNcI,3182
|
|
30
|
-
pymmcore_plus/mda/_runner.py,sha256=1U39sfI7g29K7fkrNLqDGyWYSjStIWLymVrp2Kj_HF8,15365
|
|
31
|
-
pymmcore_plus/mda/_thread_relay.py,sha256=wjP1tag7nN2Sr0RzaPnYRqHl8XjAQg2MpXOt0ONLcQ8,6112
|
|
32
|
-
pymmcore_plus/mda/events/__init__.py,sha256=UZFBlIzTmKqgMw_vVSZSSAN1tkAu8qccYb-aXXBRc3I,1192
|
|
33
|
-
pymmcore_plus/mda/events/_protocol.py,sha256=Ve4RbjcdHyDob-GZ2ny4gmw46JhahvI4XbXUwVZ-7zc,1315
|
|
34
|
-
pymmcore_plus/mda/events/_psygnal.py,sha256=TdN1mFGpTPXmEs9iwFKSC1svv87PDZkT2JZvl0tEGrQ,640
|
|
35
|
-
pymmcore_plus/mda/events/_qsignals.py,sha256=tULQg-e_NX197DxJXaWHn1zLJ-4tzc9QyOAnsobEDtA,554
|
|
36
|
-
pymmcore_plus/mda/handlers/_5d_writer_base.py,sha256=9hBW8TH9mLh318QQk4knpCJZuhgKZOPv2X_UVZcDH-c,11515
|
|
37
|
-
pymmcore_plus/mda/handlers/__init__.py,sha256=yQFRVDdCyu5t2JilobHGPC8lgCY4htNF5dzctrteSZA,305
|
|
38
|
-
pymmcore_plus/mda/handlers/_img_sequence_writer.py,sha256=9zIqwTlW1GmgkpSol1V69ADHwAEt-n8E4DkqAiSk5mM,11493
|
|
39
|
-
pymmcore_plus/mda/handlers/_ome_tiff_writer.py,sha256=B4MFJzlY5fzOpFv41aEvBv-rfeU9rasJm4qznCkXsvU,6120
|
|
40
|
-
pymmcore_plus/mda/handlers/_ome_zarr_writer.py,sha256=R70bWNcYhZ4lytv_UZiCkuxNHSQUS2yVyCBeCfIB1Ag,12133
|
|
41
|
-
pymmcore_plus/mda/handlers/_tensorstore_handler.py,sha256=iQOL61ZizcnJIY6cUSB-VpXHHFYdvANioAGxU--yiZI,14573
|
|
42
|
-
pymmcore_plus/mda/handlers/_util.py,sha256=p-8Gg5Q2Jo0zyYdniP9a0NirUOnuKNLWzwjhzcKqskg,1601
|
|
43
|
-
pymmcore_plus/model/__init__.py,sha256=zKZkkSpNK4ERu-VMdi9gvRrj1aXAjNaYxlYB5PdYSg0,479
|
|
44
|
-
pymmcore_plus/model/_config_file.py,sha256=AwUHlCd6PUCCCDJFPBzanhVp7Cv751k6MHVEaUAdsxw,13335
|
|
45
|
-
pymmcore_plus/model/_config_group.py,sha256=zpLimXUSaz2dcqfy2GCI0_MqhjN-A022MOi9QmkiOh4,2517
|
|
46
|
-
pymmcore_plus/model/_core_device.py,sha256=afNYGIRFunUPYNYJ_yHJwOjo7HO9FW8qGWTMeiKRmNU,2370
|
|
47
|
-
pymmcore_plus/model/_core_link.py,sha256=myE0qa2pEWEinbsIhTN4uB_c-lr9dtUG3npLgsHEI_0,2706
|
|
48
|
-
pymmcore_plus/model/_device.py,sha256=cQngFxQ6tufrT9G46oO5iX9wh-44zZraaIFNQCyzMLc,15026
|
|
49
|
-
pymmcore_plus/model/_microscope.py,sha256=-soGj918ue_71mrROQ5_7cbjexKp41wPn7im0l2BfaY,9822
|
|
50
|
-
pymmcore_plus/model/_pixel_size_config.py,sha256=J4qJmPZsN9dwEkoMtct5Ik-8zEC-v0aKxOBKGFH7kOE,2718
|
|
51
|
-
pymmcore_plus/model/_property.py,sha256=gJM7SFjLB2HnN0E8HOn4qVlB2wAxmkEFxSJFjKauZEk,3328
|
|
52
|
-
pymmcore_plus-0.10.2.dist-info/METADATA,sha256=qUaNdtH932kT10tVTpK_tsOIu52o9j3TVC-33DzKoNI,9220
|
|
53
|
-
pymmcore_plus-0.10.2.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
|
|
54
|
-
pymmcore_plus-0.10.2.dist-info/entry_points.txt,sha256=NtFyndrQzBpUNJyil-8e5hMGke2utAf7mkGavTLcLOY,51
|
|
55
|
-
pymmcore_plus-0.10.2.dist-info/licenses/LICENSE,sha256=OHJjRpOPKKRc7FEnpehNWdR5LRBdBhUtIFG-ZI0dCEA,1522
|
|
56
|
-
pymmcore_plus-0.10.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|