backscattermeter_analyzer 2.2.0__tar.gz → 2.2.2__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.
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/PKG-INFO +1 -1
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/pyproject.toml +1 -1
- backscattermeter_analyzer-2.2.2/src/backscattermeter_analyzer/characterize/angle/result.py +73 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/characterize/distance/result.py +49 -1
- backscattermeter_analyzer-2.2.2/src/backscattermeter_analyzer/exception/__init__.py +9 -0
- backscattermeter_analyzer-2.2.2/src/backscattermeter_analyzer/exception/base.py +5 -0
- backscattermeter_analyzer-2.2.2/src/backscattermeter_analyzer/exception/io/__init__.py +7 -0
- backscattermeter_analyzer-2.2.2/src/backscattermeter_analyzer/exception/io/base.py +7 -0
- backscattermeter_analyzer-2.2.2/src/backscattermeter_analyzer/exception/io/registry/__init__.py +15 -0
- backscattermeter_analyzer-2.2.2/src/backscattermeter_analyzer/exception/io/registry/already_defined.py +34 -0
- backscattermeter_analyzer-2.2.2/src/backscattermeter_analyzer/exception/io/registry/ambiguous_format.py +22 -0
- backscattermeter_analyzer-2.2.2/src/backscattermeter_analyzer/exception/io/registry/base.py +7 -0
- backscattermeter_analyzer-2.2.2/src/backscattermeter_analyzer/exception/io/registry/identification.py +23 -0
- backscattermeter_analyzer-2.2.2/src/backscattermeter_analyzer/exception/io/registry/not_defined.py +29 -0
- backscattermeter_analyzer-2.2.2/src/backscattermeter_analyzer/io/hdf5/__init__.py +11 -0
- backscattermeter_analyzer-2.2.2/src/backscattermeter_analyzer/io/hdf5/distance/__init__.py +7 -0
- backscattermeter_analyzer-2.2.2/src/backscattermeter_analyzer/io/hdf5/distance/main.py +195 -0
- backscattermeter_analyzer-2.2.2/src/backscattermeter_analyzer/io/hdf5/distance/motor.py +214 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/io/hdf5/measurement/__init__.py +1 -3
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/io/hdf5/measurement/main.py +3 -2
- backscattermeter_analyzer-2.2.2/src/backscattermeter_analyzer/io/hdf5/result.py +199 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/io/hdf5/utils.py +49 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/io/registry/unified_io_registry_base.py +20 -19
- backscattermeter_analyzer-2.2.2/src/backscattermeter_analyzer/utils/distance/connect.py +91 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/distance/distance.py +6 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/distance/motor/state.py +9 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/measurement/measurement.py +3 -4
- backscattermeter_analyzer-2.2.0/src/backscattermeter_analyzer/characterize/angle/result.py +0 -8
- backscattermeter_analyzer-2.2.0/src/backscattermeter_analyzer/io/hdf5/__init__.py +0 -7
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/LICENSE +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/README.md +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/display.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/justfile +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/mise.toml +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/__init__.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/axis.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/characterize/__init__.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/characterize/angle/__init__.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/characterize/distance/__init__.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/characterize/distance/ratio.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/characterize/distance/vector.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/direction.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/hardware/__init__.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/hardware/backscattermeter.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/hardware/camera/__init__.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/hardware/motor/__init__.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/hardware/motor/jump.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/hardware/motor/path.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/hardware/motor/step_numbers.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/hardware/optic/__init__.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/io/__init__.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/io/hdf5/measurement/motor.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/io/registry/__init__.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/io/registry/default.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/io/registry/interface/__init__.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/io/registry/interface/unified_read_write.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/io/registry/interface/unified_read_write_method.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/io/registry/unified_input_registry.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/io/registry/unified_io_registry.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/io/registry/unified_output_registry.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/scale.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/__init__.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/distance/__init__.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/distance/motor/__init__.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/distance/motor/no.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/distance/motor/yes.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/distance/state.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/measurement/__init__.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/measurement/angle/__init__.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/measurement/angle/no.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/measurement/angle/state.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/measurement/angle/yes.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/measurement/camera/__init__.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/measurement/camera/no.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/measurement/camera/state.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/measurement/camera/yes.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/measurement/connect.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/measurement/motor/__init__.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/measurement/motor/no.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/measurement/motor/state.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/measurement/motor/yes.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/measurement/state.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/src/backscattermeter_analyzer/utils/utils.py +0 -0
- {backscattermeter_analyzer-2.2.0 → backscattermeter_analyzer-2.2.2}/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: backscattermeter_analyzer
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.2
|
|
4
4
|
Summary: Tool to work on the backscattermeter at LAPP
|
|
5
5
|
Project-URL: Documentation, https://git.linarphy.net/linarphy/backscattermeter_analyzer/wiki
|
|
6
6
|
Project-URL: Homepage, https://git.linarphy.net/linarphy/backscattermeter_analyzer
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""Result class."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
|
|
7
|
+
from backscattermeter_analyzer import Direction, Distance
|
|
8
|
+
from backscattermeter_analyzer.characterize.distance import (
|
|
9
|
+
Result as DistanceResult,
|
|
10
|
+
)
|
|
11
|
+
from backscattermeter_analyzer.utils.measurement.angle import (
|
|
12
|
+
WithManualAngle,
|
|
13
|
+
)
|
|
14
|
+
from backscattermeter_analyzer.utils.measurement.motor import (
|
|
15
|
+
WithMotorPath,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from backscattermeter_analyzer import Axis, Measurement
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class Result:
|
|
24
|
+
"""Result of an analysis of an angle measurement."""
|
|
25
|
+
|
|
26
|
+
@staticmethod
|
|
27
|
+
def analyze(*measurements: Measurement) -> Result:
|
|
28
|
+
"""
|
|
29
|
+
Link manual angle measurements and motorized angle measurements.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
*measurements: Measurement
|
|
34
|
+
Manuals and Motorized measurements.
|
|
35
|
+
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
dict_manual: dict[tuple[Axis, Direction], list[Distance]] = {}
|
|
39
|
+
motor_measurements: list[DistanceResult] = []
|
|
40
|
+
|
|
41
|
+
for measurement in measurements:
|
|
42
|
+
angle_state = measurement.state.angle
|
|
43
|
+
motor_state = measurement.state.motor
|
|
44
|
+
if isinstance(angle_state, WithManualAngle):
|
|
45
|
+
if isinstance(motor_state, WithMotorPath):
|
|
46
|
+
message = (
|
|
47
|
+
"Cannot have a measurement with a manual "
|
|
48
|
+
"angle and a motor path at the same time"
|
|
49
|
+
)
|
|
50
|
+
raise TypeError(message)
|
|
51
|
+
direction = Direction(angle_state.angle.pdf_mean < 0)
|
|
52
|
+
result = DistanceResult.analyze(measurement)
|
|
53
|
+
if (angle_state.axis, direction) not in dict_manual:
|
|
54
|
+
distances = 0
|
|
55
|
+
dict_manual[(angle_state.axis, direction)] = (
|
|
56
|
+
result.distances
|
|
57
|
+
)
|
|
58
|
+
else:
|
|
59
|
+
dict_manual[(angle_state.axis, direction)].append(
|
|
60
|
+
measurement
|
|
61
|
+
)
|
|
62
|
+
else:
|
|
63
|
+
if not isinstance(motor_state, WithMotorPath):
|
|
64
|
+
message = (
|
|
65
|
+
"Cannot have a measurement with no manual "
|
|
66
|
+
"angle nor motor path."
|
|
67
|
+
)
|
|
68
|
+
raise TypeError(message)
|
|
69
|
+
motor_measurements.append(
|
|
70
|
+
DistanceResult.analyze(measurement)
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
return Result()
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
"""Result class."""
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass, field
|
|
4
|
-
from typing import TYPE_CHECKING
|
|
4
|
+
from typing import TYPE_CHECKING, Any
|
|
5
5
|
from uuid import uuid4
|
|
6
6
|
|
|
7
7
|
from astropy.time import TimeDelta
|
|
8
8
|
from astropy.uncertainty import normal
|
|
9
9
|
from numpy import mean, std
|
|
10
10
|
|
|
11
|
+
from backscattermeter_analyzer.io.registry import (
|
|
12
|
+
UnifiedReadWrite,
|
|
13
|
+
UnifiedReadWriteMethod,
|
|
14
|
+
)
|
|
11
15
|
from backscattermeter_analyzer.utils.distance import Distance
|
|
12
16
|
from backscattermeter_analyzer.utils.measurement.motor import (
|
|
13
17
|
WithMotorPath,
|
|
@@ -16,6 +20,46 @@ from backscattermeter_analyzer.utils.measurement.motor import (
|
|
|
16
20
|
if TYPE_CHECKING:
|
|
17
21
|
from backscattermeter_analyzer.utils.measurement import Measurement
|
|
18
22
|
|
|
23
|
+
_Base = UnifiedReadWrite["Result"]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class Read(_Base):
|
|
27
|
+
"""
|
|
28
|
+
Read and parse a Result.
|
|
29
|
+
|
|
30
|
+
This function provides the Result interface to the
|
|
31
|
+
backscattermeter_analyzer unified I/O layer.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
def __init__(
|
|
35
|
+
self, instance: Result | None, class_: type[Result]
|
|
36
|
+
) -> None:
|
|
37
|
+
"""Initialize this class."""
|
|
38
|
+
super().__init__(instance, class_, "read")
|
|
39
|
+
|
|
40
|
+
def __call__(self, *args: Any, **kwargs: Any) -> Result:
|
|
41
|
+
"""Run the main function."""
|
|
42
|
+
return self._registry.read(self._class_, *args, **kwargs)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class Write(_Base):
|
|
46
|
+
"""
|
|
47
|
+
Write a Result object out in the specified format.
|
|
48
|
+
|
|
49
|
+
This function provides the Result interface to the
|
|
50
|
+
backscattermeter_analyzer unified I/O layer.
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
def __init__(
|
|
54
|
+
self, instance: Result | None, class_: type[Result]
|
|
55
|
+
) -> None:
|
|
56
|
+
"""Initialize this class."""
|
|
57
|
+
super().__init__(instance, class_, "write")
|
|
58
|
+
|
|
59
|
+
def __call__(self, *args: Any, **kwargs: Any) -> object | None:
|
|
60
|
+
"""Run the main function."""
|
|
61
|
+
return self._registry.write(self._instance, *args, **kwargs)
|
|
62
|
+
|
|
19
63
|
|
|
20
64
|
@dataclass
|
|
21
65
|
class Result:
|
|
@@ -23,8 +67,12 @@ class Result:
|
|
|
23
67
|
|
|
24
68
|
measurement: Measurement
|
|
25
69
|
distances: list[Distance]
|
|
70
|
+
|
|
26
71
|
identifier: str = field(default_factory=lambda: str(uuid4()))
|
|
27
72
|
|
|
73
|
+
read = UnifiedReadWriteMethod(Read)
|
|
74
|
+
write = UnifiedReadWriteMethod(Write)
|
|
75
|
+
|
|
28
76
|
@staticmethod
|
|
29
77
|
def analyze(measurement: Measurement) -> Result:
|
|
30
78
|
"""Generate a result from a measurement by analysing it."""
|
backscattermeter_analyzer-2.2.2/src/backscattermeter_analyzer/exception/io/registry/__init__.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Exception about registry registration."""
|
|
2
|
+
|
|
3
|
+
from .already_defined import AlreadyDefinedError
|
|
4
|
+
from .ambiguous_format import AmbiguousFormatError
|
|
5
|
+
from .base import RegistryError
|
|
6
|
+
from .identification import IdentificationError
|
|
7
|
+
from .not_defined import NotDefinedError
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"AlreadyDefinedError",
|
|
11
|
+
"AmbiguousFormatError",
|
|
12
|
+
"IdentificationError",
|
|
13
|
+
"NotDefinedError",
|
|
14
|
+
"RegistryError",
|
|
15
|
+
]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""AlreadyDefinedError class."""
|
|
2
|
+
|
|
3
|
+
from .base import RegistryError
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AlreadyDefinedError(RegistryError):
|
|
7
|
+
"""A function that link a format to a class is already defined."""
|
|
8
|
+
|
|
9
|
+
def __init__(
|
|
10
|
+
self, data_format: str, data_class: type, function_type: str
|
|
11
|
+
) -> None:
|
|
12
|
+
"""
|
|
13
|
+
Error initialization.
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
data_format: str
|
|
18
|
+
Data format linked to the registry entry.
|
|
19
|
+
data_class: type
|
|
20
|
+
Type linked to the registry entry.
|
|
21
|
+
function_type: str
|
|
22
|
+
Type of the entry (identifier, writer, reader, etc.).
|
|
23
|
+
|
|
24
|
+
Notes
|
|
25
|
+
-----
|
|
26
|
+
data_class - write -> data_format
|
|
27
|
+
data_format - read -> data_class
|
|
28
|
+
|
|
29
|
+
"""
|
|
30
|
+
super().__init__(
|
|
31
|
+
f"{function_type.capitalize()} for format `{data_format}`"
|
|
32
|
+
f" and class `{data_class}` is already defined. Use "
|
|
33
|
+
"`force=True` to overwrite and ignore the existing entry."
|
|
34
|
+
)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""AmbiguousFormatError class."""
|
|
2
|
+
|
|
3
|
+
from .base import RegistryError
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AmbiguousFormatError(RegistryError):
|
|
7
|
+
"""Ambiguous format."""
|
|
8
|
+
|
|
9
|
+
def __init__(self, valid_formats: str) -> None:
|
|
10
|
+
"""
|
|
11
|
+
Error initialization.
|
|
12
|
+
|
|
13
|
+
Parameters
|
|
14
|
+
----------
|
|
15
|
+
valid_formats: str
|
|
16
|
+
Valid formats.
|
|
17
|
+
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
super().__init__(
|
|
21
|
+
f"Format is ambiguous. Options are: {valid_formats}."
|
|
22
|
+
)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""IdentificationError class."""
|
|
2
|
+
|
|
3
|
+
from .base import RegistryError
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class IdentificationError(RegistryError):
|
|
7
|
+
"""Impossible to identify format without explicit format arg."""
|
|
8
|
+
|
|
9
|
+
def __init__(self, format_table: str) -> None:
|
|
10
|
+
"""
|
|
11
|
+
Error initialization.
|
|
12
|
+
|
|
13
|
+
Parameters
|
|
14
|
+
----------
|
|
15
|
+
format_table: str
|
|
16
|
+
Available format table.
|
|
17
|
+
|
|
18
|
+
"""
|
|
19
|
+
super().__init__(
|
|
20
|
+
"Format could not be identified based on the file name or "
|
|
21
|
+
"contents, please provide a `format` argument.\n"
|
|
22
|
+
f"The available formats are:\n{format_table}"
|
|
23
|
+
)
|
backscattermeter_analyzer-2.2.2/src/backscattermeter_analyzer/exception/io/registry/not_defined.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""NotDefinedError class."""
|
|
2
|
+
|
|
3
|
+
from .base import RegistryError
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class NotDefinedError(RegistryError):
|
|
7
|
+
"""A function that link a format to a class does not exist."""
|
|
8
|
+
|
|
9
|
+
def __init__(
|
|
10
|
+
self, data_format: str, data_class: type, function_type: str
|
|
11
|
+
) -> None:
|
|
12
|
+
"""
|
|
13
|
+
Error initialization.
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
data_format: str
|
|
18
|
+
Data format linked to the non-existing registry entry.
|
|
19
|
+
data_class: type
|
|
20
|
+
Type linked to the non-existing registry entry.
|
|
21
|
+
function_type: str
|
|
22
|
+
Type of the non-existing entry (identifier, writer, reader,
|
|
23
|
+
etc.)
|
|
24
|
+
|
|
25
|
+
"""
|
|
26
|
+
super().__init__(
|
|
27
|
+
f"No {function_type} defined for format {data_format} and "
|
|
28
|
+
f"class {data_class}."
|
|
29
|
+
)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Sub-package for writing and parsing hdf5 files."""
|
|
2
|
+
|
|
3
|
+
from .distance import register_distance as register_distance_hdf5
|
|
4
|
+
from .measurement import (
|
|
5
|
+
register_measurement as register_measurement_hdf5,
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"register_distance_hdf5",
|
|
10
|
+
"register_measurement_hdf5",
|
|
11
|
+
]
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"""Hdf5 conversion for the main metadata of a Distance."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
from astropy.uncertainty import Distribution
|
|
7
|
+
from gwpy.detector.channel import Channel
|
|
8
|
+
from h5py import Dataset, File, Group
|
|
9
|
+
|
|
10
|
+
from backscattermeter_analyzer.io.hdf5.utils import (
|
|
11
|
+
dataset_to_distribution,
|
|
12
|
+
distribution_to_dataset,
|
|
13
|
+
get_group,
|
|
14
|
+
is_hdf5,
|
|
15
|
+
)
|
|
16
|
+
from backscattermeter_analyzer.io.registry.default import (
|
|
17
|
+
default_registry,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from backscattermeter_analyzer.utils import Distance
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _read(input_: Group, path: str | None = None) -> Distance:
|
|
25
|
+
"""Read a Distance object from a group, internal function."""
|
|
26
|
+
from backscattermeter_analyzer.utils import (
|
|
27
|
+
Distance,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
item = get_group(input_, path)
|
|
31
|
+
|
|
32
|
+
group_distance = item.get("distance", default=None)
|
|
33
|
+
if group_distance is None:
|
|
34
|
+
message = f"No `distance` group in {path} from {input_.name}."
|
|
35
|
+
raise ValueError(message)
|
|
36
|
+
if not isinstance(group_distance, Group):
|
|
37
|
+
message = (
|
|
38
|
+
f"`distance` must be a group in {path} from {input_.name}."
|
|
39
|
+
)
|
|
40
|
+
raise TypeError(message)
|
|
41
|
+
|
|
42
|
+
distance: dict[str | Channel, Distribution] = {}
|
|
43
|
+
for dataset_distance in group_distance:
|
|
44
|
+
if not isinstance(group_distance[dataset_distance], Dataset):
|
|
45
|
+
message = (
|
|
46
|
+
f"`{dataset_distance}` is not a dataset in {path} from "
|
|
47
|
+
f"{input_.name}."
|
|
48
|
+
)
|
|
49
|
+
raise TypeError(message)
|
|
50
|
+
distance[dataset_distance] = dataset_to_distribution(
|
|
51
|
+
group_distance[dataset_distance]
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
identifier = item["identifier"]
|
|
55
|
+
|
|
56
|
+
return Distance(distance=distance, identifier=identifier)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def read(input_: Path | Group, path: str | None = None) -> Distance:
|
|
60
|
+
"""
|
|
61
|
+
Read a Distance object from an HDF5 component/file.
|
|
62
|
+
|
|
63
|
+
Parameters
|
|
64
|
+
----------
|
|
65
|
+
input_: Path | Group
|
|
66
|
+
If a Path, the filename to read the distance from.
|
|
67
|
+
If an h5py object, either the file or the group object to read
|
|
68
|
+
the Distance from.
|
|
69
|
+
path: str | None
|
|
70
|
+
The path from which to read the distance inside the HDF5
|
|
71
|
+
file. This should be relative to the input if the input is a
|
|
72
|
+
Group.
|
|
73
|
+
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
if isinstance(input_, Path):
|
|
77
|
+
with File(input_) as file:
|
|
78
|
+
return _read(input_=file, path=path)
|
|
79
|
+
|
|
80
|
+
return _read(input_=input_, path=path)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _write(
|
|
84
|
+
distance: Distance,
|
|
85
|
+
output: Group,
|
|
86
|
+
path: str | None = None,
|
|
87
|
+
*,
|
|
88
|
+
append: bool = False,
|
|
89
|
+
overwrite: bool = False,
|
|
90
|
+
) -> None:
|
|
91
|
+
"""Write a Distance object to a group, internal function."""
|
|
92
|
+
|
|
93
|
+
if path is not None:
|
|
94
|
+
item = output.get(path, default=None)
|
|
95
|
+
if item is not None and not (append and overwrite):
|
|
96
|
+
message = (
|
|
97
|
+
f"`{path}` already exists in {output.name}, add "
|
|
98
|
+
"`append=True` and `overwrite=True` to proceed anyway."
|
|
99
|
+
)
|
|
100
|
+
raise ValueError(message)
|
|
101
|
+
if item is not None:
|
|
102
|
+
if not isinstance(item, Group):
|
|
103
|
+
message = (
|
|
104
|
+
f"{path} from {output.name} is a {type(item)}"
|
|
105
|
+
", not a Group."
|
|
106
|
+
)
|
|
107
|
+
raise TypeError(message)
|
|
108
|
+
item.clear()
|
|
109
|
+
else:
|
|
110
|
+
item = output.create_group(name=path)
|
|
111
|
+
else:
|
|
112
|
+
item = output
|
|
113
|
+
|
|
114
|
+
item["identifier"] = distance.identifier
|
|
115
|
+
distance_group = item.create_group("distance")
|
|
116
|
+
|
|
117
|
+
for name, distance_item in distance.distance.items():
|
|
118
|
+
distribution_to_dataset(
|
|
119
|
+
store=distance_group,
|
|
120
|
+
name=str(name),
|
|
121
|
+
distribution=distance_item,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def write(
|
|
126
|
+
distance: Distance,
|
|
127
|
+
output: Path | Group,
|
|
128
|
+
path: str | None = None,
|
|
129
|
+
*,
|
|
130
|
+
append: bool = False,
|
|
131
|
+
overwrite: bool = False,
|
|
132
|
+
) -> None:
|
|
133
|
+
"""
|
|
134
|
+
Write a Distance object to an HDF5 file.
|
|
135
|
+
|
|
136
|
+
Parameters
|
|
137
|
+
----------
|
|
138
|
+
distance: Distance
|
|
139
|
+
Distance that is to be written to file.
|
|
140
|
+
output: Path | Group
|
|
141
|
+
If a Path, the path of the file to write the distance to. If
|
|
142
|
+
a Group, the group object to write the distance to, depending
|
|
143
|
+
on `path` value.
|
|
144
|
+
path: str | None
|
|
145
|
+
The path to which to write the distance inside the HDF5 file.
|
|
146
|
+
This should be relative to the output Group (or the root Group
|
|
147
|
+
if output is a Path). Default to None.
|
|
148
|
+
append: bool
|
|
149
|
+
Whether to append the distance to an existing HDF5 file.
|
|
150
|
+
Default to False. This can delete a previous distance.
|
|
151
|
+
overwrite: bool
|
|
152
|
+
Whether to overwrite any existing file without warning. Default
|
|
153
|
+
to False. If `append=True` and `overwrite=True`, then only the
|
|
154
|
+
group will be replaced.
|
|
155
|
+
|
|
156
|
+
"""
|
|
157
|
+
|
|
158
|
+
if isinstance(output, Path):
|
|
159
|
+
mode = "x"
|
|
160
|
+
if overwrite and not append:
|
|
161
|
+
mode = "w"
|
|
162
|
+
elif append:
|
|
163
|
+
mode = "r+"
|
|
164
|
+
|
|
165
|
+
with File(output, mode=mode) as file:
|
|
166
|
+
return _write(
|
|
167
|
+
distance=distance,
|
|
168
|
+
output=file,
|
|
169
|
+
path=path,
|
|
170
|
+
append=append,
|
|
171
|
+
overwrite=overwrite,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
return _write(
|
|
175
|
+
distance=distance,
|
|
176
|
+
output=output,
|
|
177
|
+
path=path,
|
|
178
|
+
append=append,
|
|
179
|
+
overwrite=overwrite,
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def register_distance() -> None:
|
|
184
|
+
"""Register Distance hdf5 conversion in Unified I/O."""
|
|
185
|
+
from backscattermeter_analyzer.utils import (
|
|
186
|
+
Distance,
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
from .motor import register_motor_state
|
|
190
|
+
|
|
191
|
+
register_motor_state()
|
|
192
|
+
|
|
193
|
+
default_registry.register_identifier("hdf5", Distance, is_hdf5)
|
|
194
|
+
default_registry.register_reader("hdf5", Distance, read)
|
|
195
|
+
default_registry.register_writer("hdf5", Distance, write)
|