Skip to content

Commit 6177455

Browse files
authored
Merge pull request #11 from BAMresearch/populate_io
Populate io
2 parents 09fecf1 + fa7996b commit 6177455

File tree

4 files changed

+287
-3
lines changed

4 files changed

+287
-3
lines changed

src/modacor/io/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# SPDX-License-Identifier: BSD-3-Clause
2+
3+
4+
__license__ = "BSD-3-Clause"
5+
6+
7+
from .io_source import IoSource
8+
from .io_sources import IoSources
9+
10+
__all__ = ["IoSource", "IoSources"]

src/modacor/io/io_registry.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# SPDX-License-Identifier: BSD-3-Clause
2+
# Copyright 2025 MoDaCor Authors
3+
#
4+
# Redistribution and use in source and binary forms, with or without modification,
5+
# are permitted provided that the following conditions are met:
6+
# 1. Redistributions of source code must retain the above copyright notice, this
7+
# list of conditions and the following disclaimer.
8+
# 2. Redistributions in binary form must reproduce the above copyright notice,
9+
# this list of conditions and the following disclaimer in the documentation
10+
# and/or other materials provided with the distribution.
11+
# 3. Neither the name of the copyright holder nor the names of its contributors
12+
# may be used to endorse or promote products derived from this software without
13+
# specific prior written permission.
14+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND
15+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
18+
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21+
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
25+
__license__ = "BSD-3-Clause"
26+
__copyright__ = "Copyright 2025 MoDaCor Authors"
27+
__status__ = "Alpha"
28+
__all__ = ["IoRegistry", "register_as_io_source"]
29+
30+
31+
from modacor.io.io_source import IoSource
32+
33+
IoRegistry: dict[str, IoSource] = {}
34+
35+
36+
def register_as_io_source(cls):
37+
"""
38+
Decorator to register a class as an IO source in the IoRegistry.
39+
"""
40+
if not issubclass(cls, IoSource):
41+
raise TypeError("The class must be a subclass of IoSource to be registered.")
42+
type_ref = getattr(cls, "type_reference", None)
43+
if not isinstance(type_ref, str):
44+
raise AttributeError(
45+
"The class must have a class attribute 'type_reference' of type string."
46+
)
47+
if type_ref in IoRegistry:
48+
raise ValueError(f"Class with type_reference '{type_ref}' is already registered.")
49+
IoRegistry[type_ref] = cls
50+
return cls

src/modacor/io/io_source.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# SPDX-License-Identifier: BSD-3-Clause
2+
# Copyright 2025 MoDaCor Authors
3+
#
4+
# Redistribution and use in source and binary forms, with or without modification,
5+
# are permitted provided that the following conditions are met:
6+
# 1. Redistributions of source code must retain the above copyright notice, this
7+
# list of conditions and the following disclaimer.
8+
# 2. Redistributions in binary form must reproduce the above copyright notice,
9+
# this list of conditions and the following disclaimer in the documentation
10+
# and/or other materials provided with the distribution.
11+
# 3. Neither the name of the copyright holder nor the names of its contributors
12+
# may be used to endorse or promote products derived from this software without
13+
# specific prior written permission.
14+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND
15+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
18+
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21+
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
25+
__license__ = "BSD-3-Clause"
26+
__copyright__ = "Copyright 2025 MoDaCor Authors"
27+
__status__ = "Alpha"
28+
__all__ = ["IoSource"]
29+
30+
31+
from typing import Any
32+
33+
import numpy as np
34+
from attrs import define, field
35+
36+
37+
def default_config() -> dict[str, Any]:
38+
"""
39+
Default configuration for the IoSource class.
40+
41+
Returns
42+
-------
43+
dict[str, Any] :
44+
A dictionary containing the default configuration.
45+
"""
46+
return {
47+
"data_rank": 1,
48+
"data_key": None,
49+
"data_rank_dims": (0,),
50+
"metadata_key": None,
51+
"non_data_slicing": "",
52+
}
53+
54+
55+
@define
56+
class IoSource:
57+
"""
58+
IoSource is a base class for all IO sources in the MoDaCor framework.
59+
60+
It provides access to a specific IO source and its associated methods.
61+
62+
Required configuration keys are:
63+
64+
data_rank : int
65+
The rank of the data.
66+
data_key : str
67+
The key to access the data.
68+
data_rank_dims : tuple[int]
69+
The dimensions of the data rank.
70+
non_data_slicing : str
71+
Slicing information for non-data dimensions. This must be a
72+
string that can be evaluated to a slice object. Multiple data
73+
slices can be separated by double semicolon ';;'.
74+
"""
75+
76+
type_reference = "IoSource"
77+
78+
configuration: dict[str, Any] = field(factory=default_config)
79+
80+
def get_data(self, index: int, data_key: str) -> np.ndarray:
81+
"""
82+
Get data from the IO source using the provided data key.
83+
84+
Parameters
85+
----------
86+
index : int
87+
The index to access the data.
88+
data_key : str
89+
The key to access the data.
90+
91+
Returns
92+
-------
93+
np.ndarray :
94+
The data associated with the provided key.
95+
"""
96+
raise NotImplementedError("This method should be implemented in subclasses.")
97+
98+
def get_static_metadata(self, data_key: str) -> Any:
99+
"""
100+
Get static metadata from the IO source using the provided data key.
101+
102+
Parameters
103+
----------
104+
data_key : str
105+
The key to access the metadata.
106+
107+
Returns
108+
-------
109+
Any :
110+
The static metadata associated with the provided key.
111+
"""
112+
raise NotImplementedError("This method should be implemented in subclasses.")

src/modacor/io/io_sources.py

Lines changed: 115 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,121 @@
11
# SPDX-License-Identifier: BSD-3-Clause
2+
# Copyright 2025 MoDaCor Authors
3+
#
4+
# Redistribution and use in source and binary forms, with or without modification,
5+
# are permitted provided that the following conditions are met:
6+
# 1. Redistributions of source code must retain the above copyright notice, this
7+
# list of conditions and the following disclaimer.
8+
# 2. Redistributions in binary form must reproduce the above copyright notice,
9+
# this list of conditions and the following disclaimer in the documentation
10+
# and/or other materials provided with the distribution.
11+
# 3. Neither the name of the copyright holder nor the names of its contributors
12+
# may be used to endorse or promote products derived from this software without
13+
# specific prior written permission.
14+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND
15+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
18+
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21+
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
224

3-
4-
__all__ = ["IoSources"]
525
__license__ = "BSD-3-Clause"
26+
__copyright__ = "Copyright 2025 MoDaCor Authors"
27+
__status__ = "Alpha"
28+
__all__ = ["IoSources"]
29+
30+
31+
from typing import Any
32+
33+
import numpy as np
34+
from attrs import define, field
35+
36+
from modacor.io.io_source import IoSource
37+
38+
39+
@define
40+
class IoSources:
41+
42+
defined_sources: dict[str, IoSource] = field(factory=dict)
43+
44+
def register_source(self, source_reference: str, source: IoSource):
45+
"""
46+
Register a new source class with the given name.
47+
48+
Parameters
49+
----------
50+
source_reference : str
51+
The reference name of the source to register.
52+
source : IoSource
53+
The class of the source to register.
54+
"""
55+
if not isinstance(source_reference, str):
56+
raise TypeError("source_name must be a string")
57+
if not isinstance(source, IoSource):
58+
raise TypeError("source_class must be a subclass of IoSource")
59+
self.defined_sources[source_reference] = source
60+
61+
def get_source(self, source_reference: str) -> IoSource:
62+
"""
63+
Get the source class associated with the given name.
64+
65+
Parameters
66+
----------
67+
source_reference : str
68+
The reference name of the source to access.
69+
70+
Returns
71+
-------
72+
IoSource :
73+
The source class associated with the provided name.
74+
"""
75+
if source_reference not in self.defined_sources:
76+
raise ValueError(f"Source {source_reference} not registered.")
77+
return self.defined_sources[source_reference]
78+
79+
def get_data(self, data_reference: str, index: int) -> np.ndarray:
80+
"""
81+
Get data from the specified source using the provided data key.
82+
83+
The data_reference is composed of the source reference and the internal
84+
data reference, separated by "::".
85+
86+
Parameters
87+
----------
88+
data_reference : str
89+
The reference name of the source to access.
90+
index : int
91+
The index to access the data.
92+
93+
Returns
94+
-------
95+
Any :
96+
The data associated with the provided key.
97+
"""
98+
_source_ref, _data_key = data_reference.split("::", 1)
99+
_source = self.get_source(_source_ref)
100+
return _source.get_data(index, _data_key)
101+
102+
def get_static_metadata(self, data_reference: str) -> Any:
103+
"""
104+
Get static metadata from the specified source using the provided data key.
6105
106+
The data_reference is composed of the source reference and the internal
107+
data reference, separated by "::".
7108
109+
Parameters
110+
----------
111+
data_reference : str
112+
The reference name of the source to access.
8113
9-
class IoSources: ...
114+
Returns
115+
-------
116+
Any :
117+
The static metadata associated with the provided key.
118+
"""
119+
_source_ref, _data_key = data_reference.split("::", 1)
120+
_source = self.get_source(_source_ref)
121+
return _source.get_static_metadata(_data_key)

0 commit comments

Comments
 (0)