backscattering_simulation_data 1.0.1__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.
- backscattering_simulation_data/__init__.py +17 -0
- backscattering_simulation_data/__init__.pyi +19 -0
- backscattering_simulation_data/metadata/__init__.py +24 -0
- backscattering_simulation_data/metadata/__init__.pyi +25 -0
- backscattering_simulation_data/metadata/elementtype.py +6 -0
- backscattering_simulation_data/metadata/elementtype.pyi +5 -0
- backscattering_simulation_data/metadata/git.py +77 -0
- backscattering_simulation_data/metadata/git.pyi +23 -0
- backscattering_simulation_data/metadata/interferometer.py +135 -0
- backscattering_simulation_data/metadata/interferometer.pyi +33 -0
- backscattering_simulation_data/metadata/map.py +127 -0
- backscattering_simulation_data/metadata/map.pyi +31 -0
- backscattering_simulation_data/metadata/metadata.py +7 -0
- backscattering_simulation_data/metadata/metadata.pyi +3 -0
- backscattering_simulation_data/metadata/modelmodifier.py +47 -0
- backscattering_simulation_data/metadata/modelmodifier.pyi +8 -0
- backscattering_simulation_data/metadata/modifiers/__init__.py +9 -0
- backscattering_simulation_data/metadata/modifiers/__init__.pyi +5 -0
- backscattering_simulation_data/metadata/modifiers/addition.py +101 -0
- backscattering_simulation_data/metadata/modifiers/addition.pyi +25 -0
- backscattering_simulation_data/metadata/modifiers/deletion.py +31 -0
- backscattering_simulation_data/metadata/modifiers/deletion.pyi +11 -0
- backscattering_simulation_data/metadata/modifiers/update.py +55 -0
- backscattering_simulation_data/metadata/modifiers/update.pyi +13 -0
- backscattering_simulation_data/metadata/pointabsorber.py +94 -0
- backscattering_simulation_data/metadata/pointabsorber.pyi +22 -0
- backscattering_simulation_data/metadata/powermeasurement.py +48 -0
- backscattering_simulation_data/metadata/powermeasurement.pyi +13 -0
- backscattering_simulation_data/metadata/root.py +108 -0
- backscattering_simulation_data/metadata/root.pyi +26 -0
- backscattering_simulation_data/metadata/scatterer.py +71 -0
- backscattering_simulation_data/metadata/scatterer.pyi +17 -0
- backscattering_simulation_data/metadata/simulation.py +68 -0
- backscattering_simulation_data/metadata/simulation.pyi +17 -0
- backscattering_simulation_data/powermeasurement.py +47 -0
- backscattering_simulation_data/powermeasurement.pyi +15 -0
- backscattering_simulation_data/root.py +146 -0
- backscattering_simulation_data/root.pyi +35 -0
- backscattering_simulation_data/scatterer.py +61 -0
- backscattering_simulation_data/scatterer.pyi +27 -0
- backscattering_simulation_data/section.py +105 -0
- backscattering_simulation_data/section.pyi +22 -0
- backscattering_simulation_data/typed.py +0 -0
- backscattering_simulation_data/typed.pyi +0 -0
- backscattering_simulation_data/utils.py +90 -0
- backscattering_simulation_data/utils.pyi +9 -0
- backscattering_simulation_data-1.0.1.dist-info/METADATA +113 -0
- backscattering_simulation_data-1.0.1.dist-info/RECORD +50 -0
- backscattering_simulation_data-1.0.1.dist-info/WHEEL +4 -0
- backscattering_simulation_data-1.0.1.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
3
|
+
from astropy.table import QTable
|
|
4
|
+
from h5py import Dataset, Group
|
|
5
|
+
|
|
6
|
+
from ..elementtype import ElementType
|
|
7
|
+
from ..modelmodifier import ModelModifier
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from .deletion import ElementDeletion
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ElementAddition(ModelModifier):
|
|
14
|
+
"""Information about an addition of an element to the model"""
|
|
15
|
+
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
requirements: list["ElementAddition | ElementDeletion"],
|
|
19
|
+
port: str,
|
|
20
|
+
element: str,
|
|
21
|
+
element_type: ElementType,
|
|
22
|
+
parameters: QTable,
|
|
23
|
+
) -> None:
|
|
24
|
+
self.requirements = requirements
|
|
25
|
+
self.port = port
|
|
26
|
+
self.element = element
|
|
27
|
+
self.element_type = element_type
|
|
28
|
+
self.parameters = parameters
|
|
29
|
+
|
|
30
|
+
@staticmethod
|
|
31
|
+
def from_hdf5(store: Group) -> "ElementAddition":
|
|
32
|
+
for attribute in ["element", "element type", "port"]:
|
|
33
|
+
if attribute not in store.attrs:
|
|
34
|
+
raise ValueError(
|
|
35
|
+
f"no {attribute} in model addition metadata",
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
element = store.attrs["element"]
|
|
39
|
+
element_type_str = store.attrs["element type"]
|
|
40
|
+
port = store.attrs["port"]
|
|
41
|
+
|
|
42
|
+
message = "model addition {} should be a string, not {}"
|
|
43
|
+
if not isinstance(element, str):
|
|
44
|
+
raise TypeError(message.format("element", type(element)))
|
|
45
|
+
if not isinstance(element_type_str, str):
|
|
46
|
+
raise TypeError(
|
|
47
|
+
message.format(
|
|
48
|
+
element_type_str,
|
|
49
|
+
type(element_type_str),
|
|
50
|
+
),
|
|
51
|
+
)
|
|
52
|
+
if not isinstance(port, str):
|
|
53
|
+
raise TypeError(message.format(port, type(port)))
|
|
54
|
+
|
|
55
|
+
element_type = ElementType(element_type_str)
|
|
56
|
+
|
|
57
|
+
requirements_dataset = store.get("requirements")
|
|
58
|
+
|
|
59
|
+
if not isinstance(requirements_dataset, Dataset):
|
|
60
|
+
message = (
|
|
61
|
+
"requirements must be stored in a Dataset, not "
|
|
62
|
+
f"{type(requirements_dataset)}"
|
|
63
|
+
)
|
|
64
|
+
raise TypeError(message)
|
|
65
|
+
|
|
66
|
+
requirements = list(requirements_dataset)
|
|
67
|
+
|
|
68
|
+
parameters = QTable.read(
|
|
69
|
+
store,
|
|
70
|
+
format="hdf5",
|
|
71
|
+
path="parameters",
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
return ElementAddition(
|
|
75
|
+
element=element,
|
|
76
|
+
element_type=element_type,
|
|
77
|
+
port=port,
|
|
78
|
+
requirements=requirements,
|
|
79
|
+
parameters=parameters,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
def to_hdf5(self, store: Group) -> Group:
|
|
83
|
+
store.attrs["element"] = self.element
|
|
84
|
+
store.attrs["element type"] = self.element_type
|
|
85
|
+
store.attrs["port"] = self.port
|
|
86
|
+
|
|
87
|
+
_ = store.create_dataset(
|
|
88
|
+
"requirements",
|
|
89
|
+
data=[
|
|
90
|
+
requirement.element for requirement in self.requirements
|
|
91
|
+
],
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
self.parameters.write(
|
|
95
|
+
store,
|
|
96
|
+
format="hdf5",
|
|
97
|
+
path="parameters",
|
|
98
|
+
serialize_meta=True,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
return ModelModifier.to_hdf5(self, store)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from _typeshed import Incomplete
|
|
2
|
+
from astropy.table import QTable
|
|
3
|
+
from h5py import Group as Group
|
|
4
|
+
|
|
5
|
+
from ..elementtype import ElementType as ElementType
|
|
6
|
+
from ..modelmodifier import ModelModifier as ModelModifier
|
|
7
|
+
from .deletion import ElementDeletion as ElementDeletion
|
|
8
|
+
|
|
9
|
+
class ElementAddition(ModelModifier):
|
|
10
|
+
requirements: Incomplete
|
|
11
|
+
port: Incomplete
|
|
12
|
+
element: Incomplete
|
|
13
|
+
element_type: Incomplete
|
|
14
|
+
parameters: Incomplete
|
|
15
|
+
def __init__(
|
|
16
|
+
self,
|
|
17
|
+
requirements: list[ElementAddition | ElementDeletion],
|
|
18
|
+
port: str,
|
|
19
|
+
element: str,
|
|
20
|
+
element_type: ElementType,
|
|
21
|
+
parameters: QTable,
|
|
22
|
+
) -> None: ...
|
|
23
|
+
@staticmethod
|
|
24
|
+
def from_hdf5(store: Group) -> ElementAddition: ...
|
|
25
|
+
def to_hdf5(self, store: Group) -> Group: ...
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from h5py import Group
|
|
2
|
+
|
|
3
|
+
from ..modelmodifier import ModelModifier
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ElementDeletion(ModelModifier):
|
|
7
|
+
"""Information about the deletion of an element to the model"""
|
|
8
|
+
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
element: str,
|
|
12
|
+
) -> None:
|
|
13
|
+
self.element = element
|
|
14
|
+
|
|
15
|
+
@staticmethod
|
|
16
|
+
def from_hdf5(store: Group) -> "ElementDeletion":
|
|
17
|
+
if "element" not in store.attrs:
|
|
18
|
+
raise ValueError("no element in model deletion metadata")
|
|
19
|
+
element = store.attrs["element"]
|
|
20
|
+
if not isinstance(element, str):
|
|
21
|
+
message = (
|
|
22
|
+
"element of model deletion must be a string, not "
|
|
23
|
+
f"{type(element)}"
|
|
24
|
+
)
|
|
25
|
+
raise TypeError(message)
|
|
26
|
+
return ElementDeletion(element=element)
|
|
27
|
+
|
|
28
|
+
def to_hdf5(self, store: Group) -> Group:
|
|
29
|
+
store.attrs["element"] = self.element
|
|
30
|
+
|
|
31
|
+
return ModelModifier.to_hdf5(self, store)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from _typeshed import Incomplete
|
|
2
|
+
from h5py import Group as Group
|
|
3
|
+
|
|
4
|
+
from ..modelmodifier import ModelModifier as ModelModifier
|
|
5
|
+
|
|
6
|
+
class ElementDeletion(ModelModifier):
|
|
7
|
+
element: Incomplete
|
|
8
|
+
def __init__(self, element: str) -> None: ...
|
|
9
|
+
@staticmethod
|
|
10
|
+
def from_hdf5(store: Group) -> ElementDeletion: ...
|
|
11
|
+
def to_hdf5(self, store: Group) -> Group: ...
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from astropy.table import QTable
|
|
2
|
+
from h5py import Group
|
|
3
|
+
|
|
4
|
+
from ..modelmodifier import ModelModifier
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ElementUpdate(ModelModifier):
|
|
8
|
+
"""
|
|
9
|
+
Information about the update of an existing element to the model
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
element: str,
|
|
15
|
+
parameters: QTable,
|
|
16
|
+
) -> None:
|
|
17
|
+
self.element = element
|
|
18
|
+
self.parameters = parameters
|
|
19
|
+
|
|
20
|
+
@staticmethod
|
|
21
|
+
def from_hdf5(store: Group) -> "ElementUpdate":
|
|
22
|
+
if "element" not in store.attrs:
|
|
23
|
+
raise ValueError("no element in model update metadata")
|
|
24
|
+
|
|
25
|
+
element = store.attrs["element"]
|
|
26
|
+
|
|
27
|
+
if not isinstance(element, str):
|
|
28
|
+
message = (
|
|
29
|
+
"element of model update must be a string, not",
|
|
30
|
+
f"{type(element)}",
|
|
31
|
+
)
|
|
32
|
+
raise TypeError(message)
|
|
33
|
+
|
|
34
|
+
parameters = QTable.read(
|
|
35
|
+
store,
|
|
36
|
+
format="hdf5",
|
|
37
|
+
path="parameters",
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
return ElementUpdate(
|
|
41
|
+
element=element,
|
|
42
|
+
parameters=parameters,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
def to_hdf5(self, store: Group) -> Group:
|
|
46
|
+
store.attrs["element"] = self.element
|
|
47
|
+
|
|
48
|
+
self.parameters.write(
|
|
49
|
+
store,
|
|
50
|
+
format="hdf5",
|
|
51
|
+
path="parameters",
|
|
52
|
+
serialize_meta=True,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
return ModelModifier.to_hdf5(self, store)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from _typeshed import Incomplete
|
|
2
|
+
from astropy.table import QTable
|
|
3
|
+
from h5py import Group as Group
|
|
4
|
+
|
|
5
|
+
from ..modelmodifier import ModelModifier as ModelModifier
|
|
6
|
+
|
|
7
|
+
class ElementUpdate(ModelModifier):
|
|
8
|
+
element: Incomplete
|
|
9
|
+
parameters: Incomplete
|
|
10
|
+
def __init__(self, element: str, parameters: QTable) -> None: ...
|
|
11
|
+
@staticmethod
|
|
12
|
+
def from_hdf5(store: Group) -> ElementUpdate: ...
|
|
13
|
+
def to_hdf5(self, store: Group) -> Group: ...
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
from astropy.units import Quantity
|
|
2
|
+
from h5py import File, Group
|
|
3
|
+
|
|
4
|
+
from .metadata import Metadata
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class PointAbsorber(Metadata):
|
|
8
|
+
"""Information about a point absorber"""
|
|
9
|
+
|
|
10
|
+
def __init__(
|
|
11
|
+
self,
|
|
12
|
+
x: Quantity,
|
|
13
|
+
y: Quantity,
|
|
14
|
+
radius: Quantity,
|
|
15
|
+
power: Quantity,
|
|
16
|
+
) -> None:
|
|
17
|
+
"""Parameters
|
|
18
|
+
----------
|
|
19
|
+
x: Quantity[length]
|
|
20
|
+
X position of the point
|
|
21
|
+
y: Quantity[length]
|
|
22
|
+
Y position of the point
|
|
23
|
+
radius: Quantity[length]
|
|
24
|
+
Radius of the point
|
|
25
|
+
power: Quantity[power]
|
|
26
|
+
Absorption power of the point
|
|
27
|
+
|
|
28
|
+
"""
|
|
29
|
+
if (
|
|
30
|
+
x.unit is None
|
|
31
|
+
or y.unit is None
|
|
32
|
+
or radius.unit is None
|
|
33
|
+
or power.unit is None
|
|
34
|
+
):
|
|
35
|
+
raise TypeError("every quantities must have an unit")
|
|
36
|
+
if (
|
|
37
|
+
x.unit.physical_type != "length"
|
|
38
|
+
or y.unit.physical_type != "length"
|
|
39
|
+
or radius.unit.physical_type != "length"
|
|
40
|
+
):
|
|
41
|
+
raise TypeError("x, y and radius must be length")
|
|
42
|
+
if power.unit.physical_type != "power":
|
|
43
|
+
raise TypeError("power must be power")
|
|
44
|
+
if radius <= Quantity(0, "m"):
|
|
45
|
+
raise ValueError("radius must be positive")
|
|
46
|
+
if power <= Quantity(0, "W"):
|
|
47
|
+
raise ValueError("power must be positive")
|
|
48
|
+
|
|
49
|
+
self.x = x
|
|
50
|
+
self.y = y
|
|
51
|
+
self.radius = radius
|
|
52
|
+
self.power = power
|
|
53
|
+
|
|
54
|
+
@staticmethod
|
|
55
|
+
def from_hdf5(store: File | Group) -> "PointAbsorber":
|
|
56
|
+
for attribute in ["x", "y", "radius", "power"]:
|
|
57
|
+
if attribute not in store.attrs:
|
|
58
|
+
raise ValueError(
|
|
59
|
+
f"no {attribute} in absorber point metadata",
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
x = store.attrs["x"]
|
|
63
|
+
y = store.attrs["y"]
|
|
64
|
+
radius = store.attrs["radius"]
|
|
65
|
+
power = store.attrs["power"]
|
|
66
|
+
|
|
67
|
+
message = "absorber point {} should be a string, not {}"
|
|
68
|
+
if not isinstance(x, str):
|
|
69
|
+
raise TypeError(message.format("x", type(x)))
|
|
70
|
+
if not isinstance(y, str):
|
|
71
|
+
raise TypeError(message.format("y", type(y)))
|
|
72
|
+
if not isinstance(radius, str):
|
|
73
|
+
raise TypeError(message.format("radius", type(radius)))
|
|
74
|
+
if not isinstance(power, str):
|
|
75
|
+
raise TypeError(message.format("power", type(power)))
|
|
76
|
+
|
|
77
|
+
x = Quantity(x)
|
|
78
|
+
y = Quantity(y)
|
|
79
|
+
radius = Quantity(radius)
|
|
80
|
+
power = Quantity(power)
|
|
81
|
+
|
|
82
|
+
return PointAbsorber(
|
|
83
|
+
x=x,
|
|
84
|
+
y=y,
|
|
85
|
+
radius=radius,
|
|
86
|
+
power=power,
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
def to_hdf5(self, store: File | Group) -> Group | File:
|
|
90
|
+
store.attrs["x"] = self.x.to_string()
|
|
91
|
+
store.attrs["y"] = self.y.to_string()
|
|
92
|
+
store.attrs["radius"] = self.radius.to_string()
|
|
93
|
+
store.attrs["power"] = self.power.to_string()
|
|
94
|
+
return store
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from _typeshed import Incomplete
|
|
2
|
+
from astropy.units import Quantity
|
|
3
|
+
from h5py import File as File
|
|
4
|
+
from h5py import Group as Group
|
|
5
|
+
|
|
6
|
+
from .metadata import Metadata as Metadata
|
|
7
|
+
|
|
8
|
+
class PointAbsorber(Metadata):
|
|
9
|
+
x: Incomplete
|
|
10
|
+
y: Incomplete
|
|
11
|
+
radius: Incomplete
|
|
12
|
+
power: Incomplete
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
x: Quantity,
|
|
16
|
+
y: Quantity,
|
|
17
|
+
radius: Quantity,
|
|
18
|
+
power: Quantity,
|
|
19
|
+
) -> None: ...
|
|
20
|
+
@staticmethod
|
|
21
|
+
def from_hdf5(store: File | Group) -> PointAbsorber: ...
|
|
22
|
+
def to_hdf5(self, store: File | Group) -> Group | File: ...
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
from h5py import File, Group
|
|
2
|
+
|
|
3
|
+
from .metadata import Metadata
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class PowerMeasurement(Metadata):
|
|
7
|
+
"""Information about a power measurement"""
|
|
8
|
+
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
port: str,
|
|
12
|
+
name: str,
|
|
13
|
+
) -> None:
|
|
14
|
+
"""Parameters
|
|
15
|
+
----------
|
|
16
|
+
port : str
|
|
17
|
+
Specific port where the power was measured in the simulation
|
|
18
|
+
model
|
|
19
|
+
name : str
|
|
20
|
+
Simple name of the place where the power was measured
|
|
21
|
+
|
|
22
|
+
"""
|
|
23
|
+
self.port = port
|
|
24
|
+
self.name = name
|
|
25
|
+
|
|
26
|
+
@staticmethod
|
|
27
|
+
def from_hdf5(store: Group | File) -> "PowerMeasurement":
|
|
28
|
+
for attribute in ["port", "name"]:
|
|
29
|
+
if attribute not in store.attrs:
|
|
30
|
+
raise ValueError(
|
|
31
|
+
f"no {attribute} in power measurement metadata",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
port = store.attrs["port"]
|
|
35
|
+
name = store.attrs["name"]
|
|
36
|
+
|
|
37
|
+
message = "power measurement {} should be a string, not {}"
|
|
38
|
+
if not isinstance(port, str):
|
|
39
|
+
raise TypeError(message.format("port", type(port)))
|
|
40
|
+
if not isinstance(name, str):
|
|
41
|
+
raise TypeError(message.format("name", type(name)))
|
|
42
|
+
|
|
43
|
+
return PowerMeasurement(port=port, name=name)
|
|
44
|
+
|
|
45
|
+
def to_hdf5(self, store: File | Group) -> Group | File:
|
|
46
|
+
store.attrs["port"] = self.port
|
|
47
|
+
store.attrs["name"] = self.name
|
|
48
|
+
return store
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from _typeshed import Incomplete
|
|
2
|
+
from h5py import File as File
|
|
3
|
+
from h5py import Group as Group
|
|
4
|
+
|
|
5
|
+
from .metadata import Metadata as Metadata
|
|
6
|
+
|
|
7
|
+
class PowerMeasurement(Metadata):
|
|
8
|
+
port: Incomplete
|
|
9
|
+
name: Incomplete
|
|
10
|
+
def __init__(self, port: str, name: str) -> None: ...
|
|
11
|
+
@staticmethod
|
|
12
|
+
def from_hdf5(store: Group | File) -> PowerMeasurement: ...
|
|
13
|
+
def to_hdf5(self, store: File | Group) -> Group | File: ...
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
from h5py import File, Group
|
|
2
|
+
from numpy import int64
|
|
3
|
+
|
|
4
|
+
from .git import Git
|
|
5
|
+
from .interferometer import Interferometer
|
|
6
|
+
from .metadata import Metadata
|
|
7
|
+
from .simulation import Simulation
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Root(Metadata):
|
|
11
|
+
"""Metadata associated to the Root section"""
|
|
12
|
+
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
name: str,
|
|
16
|
+
maxtem: int,
|
|
17
|
+
git: Git,
|
|
18
|
+
interferometer: Interferometer,
|
|
19
|
+
simulation: Simulation,
|
|
20
|
+
) -> None:
|
|
21
|
+
"""Parameters
|
|
22
|
+
----------
|
|
23
|
+
name : str
|
|
24
|
+
Unique name to indentify this simulation data
|
|
25
|
+
maxtem : int
|
|
26
|
+
Number of High Order Modes modelised
|
|
27
|
+
git : Git
|
|
28
|
+
Information about the git repo that generated this data
|
|
29
|
+
interferometer : Interferometer
|
|
30
|
+
Information about the simulated interferometer for this data
|
|
31
|
+
simulation : Simulation
|
|
32
|
+
Information about the simulation details for this data
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
if maxtem < 0:
|
|
36
|
+
raise ValueError("maxtem must be positive")
|
|
37
|
+
|
|
38
|
+
self.name = name
|
|
39
|
+
self.maxtem = maxtem
|
|
40
|
+
self.git = git
|
|
41
|
+
self.interferometer = interferometer
|
|
42
|
+
self.simulation = simulation
|
|
43
|
+
|
|
44
|
+
@staticmethod
|
|
45
|
+
def from_hdf5(store: File | Group) -> "Root":
|
|
46
|
+
for attribute in ["name", "maxtem"]:
|
|
47
|
+
if attribute not in store.attrs:
|
|
48
|
+
raise ValueError(f"no {attribute} for simulation data")
|
|
49
|
+
name = store.attrs["name"]
|
|
50
|
+
maxtem = store.attrs["maxtem"]
|
|
51
|
+
|
|
52
|
+
message = "simulation {} should be a {}, not {}"
|
|
53
|
+
if not isinstance(name, str):
|
|
54
|
+
raise ValueError(
|
|
55
|
+
message.format("name", "string", type(name)),
|
|
56
|
+
)
|
|
57
|
+
if not isinstance(maxtem, int64):
|
|
58
|
+
raise ValueError(
|
|
59
|
+
message.format("maxtem", "int", type(maxtem)),
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
git_group = store.get("git")
|
|
63
|
+
interferometer_group = store.get("interferometer")
|
|
64
|
+
message = "{} information should be stored in a group, not {}"
|
|
65
|
+
if not isinstance(git_group, Group):
|
|
66
|
+
raise ValueError(message.format("git", type(git_group)))
|
|
67
|
+
if not isinstance(interferometer_group, Group):
|
|
68
|
+
raise ValueError(
|
|
69
|
+
message.format(
|
|
70
|
+
"interferometer",
|
|
71
|
+
type(interferometer_group),
|
|
72
|
+
),
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
try:
|
|
76
|
+
simulation_group = store["simulation"] # can throw KeyError
|
|
77
|
+
if not isinstance(simulation_group, Group):
|
|
78
|
+
raise TypeError(
|
|
79
|
+
message.format(
|
|
80
|
+
"simulation",
|
|
81
|
+
type(simulation_group),
|
|
82
|
+
),
|
|
83
|
+
)
|
|
84
|
+
simulation = Simulation.from_hdf5(simulation_group)
|
|
85
|
+
except KeyError:
|
|
86
|
+
# Legacy support, simulation is not defined for file
|
|
87
|
+
# generated before 0.3.0
|
|
88
|
+
simulation = Simulation(maps=[], model_modifiers=[])
|
|
89
|
+
|
|
90
|
+
git = Git.from_hdf5(git_group)
|
|
91
|
+
interferometer = Interferometer.from_hdf5(interferometer_group)
|
|
92
|
+
return Root(
|
|
93
|
+
name=name,
|
|
94
|
+
maxtem=maxtem,
|
|
95
|
+
git=git,
|
|
96
|
+
interferometer=interferometer,
|
|
97
|
+
simulation=simulation,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
def to_hdf5(self, store: File | Group) -> Group | File:
|
|
101
|
+
store.attrs["name"] = self.name
|
|
102
|
+
store.attrs["maxtem"] = self.maxtem
|
|
103
|
+
_ = self.git.to_hdf5(store.create_group("git"))
|
|
104
|
+
_ = self.interferometer.to_hdf5(
|
|
105
|
+
store.create_group("interferometer"),
|
|
106
|
+
)
|
|
107
|
+
_ = self.simulation.to_hdf5(store.create_group("simulation"))
|
|
108
|
+
return store
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from _typeshed import Incomplete
|
|
2
|
+
from h5py import File as File
|
|
3
|
+
from h5py import Group
|
|
4
|
+
|
|
5
|
+
from .git import Git as Git
|
|
6
|
+
from .interferometer import Interferometer as Interferometer
|
|
7
|
+
from .metadata import Metadata as Metadata
|
|
8
|
+
from .simulation import Simulation as Simulation
|
|
9
|
+
|
|
10
|
+
class Root(Metadata):
|
|
11
|
+
name: Incomplete
|
|
12
|
+
maxtem: Incomplete
|
|
13
|
+
git: Incomplete
|
|
14
|
+
interferometer: Incomplete
|
|
15
|
+
simulation: Incomplete
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
name: str,
|
|
19
|
+
maxtem: int,
|
|
20
|
+
git: Git,
|
|
21
|
+
interferometer: Interferometer,
|
|
22
|
+
simulation: Simulation,
|
|
23
|
+
) -> None: ...
|
|
24
|
+
@staticmethod
|
|
25
|
+
def from_hdf5(store: File | Group) -> Root: ...
|
|
26
|
+
def to_hdf5(self, store: File | Group) -> Group | File: ...
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
from astropy.units import Quantity
|
|
2
|
+
from astropy.units.physical import dimensionless
|
|
3
|
+
from h5py import File, Group
|
|
4
|
+
from numpy import float64
|
|
5
|
+
|
|
6
|
+
from .metadata import Metadata
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Scatterer(Metadata):
|
|
10
|
+
"""Metadata associated to a scatterer"""
|
|
11
|
+
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
name: str,
|
|
15
|
+
reflectivity: Quantity[dimensionless],
|
|
16
|
+
) -> None:
|
|
17
|
+
"""Parameters
|
|
18
|
+
----------
|
|
19
|
+
name : str
|
|
20
|
+
Name of the scatterer
|
|
21
|
+
reflectivity : Quantity[dimensionless]
|
|
22
|
+
The reflectivity of the scatterer (simulated as a mirror)
|
|
23
|
+
in the simulation
|
|
24
|
+
|
|
25
|
+
"""
|
|
26
|
+
if (
|
|
27
|
+
reflectivity.unit is not None
|
|
28
|
+
and reflectivity.unit.physical_type != "dimensionless"
|
|
29
|
+
):
|
|
30
|
+
raise TypeError("reflectivity must not have any unit")
|
|
31
|
+
if reflectivity < Quantity(0):
|
|
32
|
+
raise ValueError("reflectivity must be positive")
|
|
33
|
+
if reflectivity > Quantity(1):
|
|
34
|
+
raise ValueError("reflectivity must be below 1")
|
|
35
|
+
|
|
36
|
+
self.name = name
|
|
37
|
+
self.reflectivity = reflectivity
|
|
38
|
+
|
|
39
|
+
@staticmethod
|
|
40
|
+
def from_hdf5(store: File | Group) -> "Scatterer":
|
|
41
|
+
if "name" not in store.attrs:
|
|
42
|
+
raise ValueError("no name for a scatterer")
|
|
43
|
+
if "reflectivity" not in store.attrs:
|
|
44
|
+
raise ValueError("no reflectivity for a scatterer")
|
|
45
|
+
name = store.attrs["name"]
|
|
46
|
+
reflectivity = store.attrs["reflectivity"]
|
|
47
|
+
if not isinstance(name, str):
|
|
48
|
+
raise ValueError(f"name must be a string, not {type(name)}")
|
|
49
|
+
if not isinstance(reflectivity, str) and not isinstance(
|
|
50
|
+
reflectivity,
|
|
51
|
+
float64,
|
|
52
|
+
):
|
|
53
|
+
message = (
|
|
54
|
+
"reflectivity must be a string or a float, not"
|
|
55
|
+
f"{type(reflectivity)}"
|
|
56
|
+
)
|
|
57
|
+
raise ValueError(message)
|
|
58
|
+
reflectivity = Quantity(value=reflectivity, unit=None)
|
|
59
|
+
return Scatterer(name=name, reflectivity=reflectivity)
|
|
60
|
+
|
|
61
|
+
def to_hdf5(self, store: File | Group) -> File | Group:
|
|
62
|
+
store.attrs["name"] = self.name
|
|
63
|
+
if isinstance(self.reflectivity, Quantity):
|
|
64
|
+
store.attrs["reflectivity"] = self.reflectivity.to_string()
|
|
65
|
+
else:
|
|
66
|
+
message = (
|
|
67
|
+
"reflectivity must be an unitless Quantity, not"
|
|
68
|
+
f"{self.reflectivity}"
|
|
69
|
+
)
|
|
70
|
+
raise ValueError(message)
|
|
71
|
+
return store
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from _typeshed import Incomplete
|
|
2
|
+
from astropy.units import Quantity
|
|
3
|
+
from astropy.units.physical import dimensionless as dimensionless
|
|
4
|
+
from h5py import File as File
|
|
5
|
+
from h5py import Group as Group
|
|
6
|
+
|
|
7
|
+
from .metadata import Metadata as Metadata
|
|
8
|
+
|
|
9
|
+
class Scatterer(Metadata):
|
|
10
|
+
name: Incomplete
|
|
11
|
+
reflectivity: Incomplete
|
|
12
|
+
def __init__(
|
|
13
|
+
self, name: str, reflectivity: Quantity[dimensionless]
|
|
14
|
+
) -> None: ...
|
|
15
|
+
@staticmethod
|
|
16
|
+
def from_hdf5(store: File | Group) -> Scatterer: ...
|
|
17
|
+
def to_hdf5(self, store: File | Group) -> File | Group: ...
|