xradio 1.0.2__tar.gz → 1.1.1__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.
- {xradio-1.0.2/src/xradio.egg-info → xradio-1.1.1}/PKG-INFO +65 -23
- {xradio-1.0.2 → xradio-1.1.1}/README.md +19 -10
- {xradio-1.0.2 → xradio-1.1.1}/pyproject.toml +42 -8
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/_utils/_casacore/casacore_from_casatools.py +75 -9
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/_utils/dict_helpers.py +38 -7
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/_utils/list_and_array.py +26 -3
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/_utils/schema.py +44 -0
- xradio-1.1.1/src/xradio/_utils/xarray_helpers.py +63 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/_utils/zarr/common.py +4 -2
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/image/__init__.py +4 -2
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/image/_util/_casacore/common.py +2 -1
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/image/_util/_casacore/xds_from_casacore.py +144 -92
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/image/_util/_casacore/xds_to_casacore.py +118 -53
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/image/_util/_fits/xds_from_fits.py +125 -37
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/image/_util/_zarr/common.py +0 -1
- xradio-1.1.1/src/xradio/image/_util/casacore.py +303 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/image/_util/common.py +10 -8
- xradio-1.1.1/src/xradio/image/_util/image_factory.py +709 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/image/image.py +72 -100
- xradio-1.1.1/src/xradio/image/image_xds.py +262 -0
- xradio-1.1.1/src/xradio/image/schema.py +85 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/__init__.py +5 -4
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/_utils/_msv2/_tables/read.py +4 -3
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/_utils/_msv2/conversion.py +6 -9
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/_utils/_msv2/create_field_and_source_xds.py +1 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/_utils/_utils/interpolate.py +5 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/_utils/_utils/partition_attrs.py +0 -1
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/convert_msv2_to_processing_set.py +9 -9
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/load_processing_set.py +2 -2
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/measurement_set_xdt.py +83 -93
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/open_processing_set.py +1 -1
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/processing_set_xdt.py +33 -26
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/schema/check.py +70 -19
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/schema/common.py +0 -1
- xradio-1.1.1/src/xradio/testing/__init__.py +0 -0
- xradio-1.1.1/src/xradio/testing/_utils/__template__.py +58 -0
- xradio-1.1.1/src/xradio/testing/measurement_set/__init__.py +58 -0
- xradio-1.1.1/src/xradio/testing/measurement_set/checker.py +131 -0
- xradio-1.1.1/src/xradio/testing/measurement_set/io.py +22 -0
- xradio-1.1.1/src/xradio/testing/measurement_set/msv2_io.py +1854 -0
- {xradio-1.0.2 → xradio-1.1.1/src/xradio.egg-info}/PKG-INFO +65 -23
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio.egg-info/SOURCES.txt +10 -1
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio.egg-info/requires.txt +46 -10
- xradio-1.0.2/src/xradio/image/_util/casacore.py +0 -145
- xradio-1.0.2/src/xradio/image/_util/image_factory.py +0 -267
- {xradio-1.0.2 → xradio-1.1.1}/LICENSE.txt +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/MANIFEST.in +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/setup.cfg +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/__init__.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/_utils/__init__.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/_utils/_casacore/tables.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/_utils/coord_math.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/_utils/zarr/__init__.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/image/_util/__init__.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/image/_util/_casacore/__init__.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/image/_util/_zarr/xds_from_zarr.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/image/_util/_zarr/xds_to_zarr.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/image/_util/_zarr/zarr_low_level.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/image/_util/zarr.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/_utils/__init__.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/_utils/_msv2/__init__.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/_utils/_msv2/_tables/read_main_table.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/_utils/_msv2/_tables/table_query.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/_utils/_msv2/create_antenna_xds.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/_utils/_msv2/msv2_to_msv4_meta.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/_utils/_msv2/msv4_info_dicts.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/_utils/_msv2/msv4_sub_xdss.py +1 -1
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/_utils/_msv2/optimised_functions.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/_utils/_msv2/partition_queries.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/_utils/_msv2/subtables.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/_utils/_utils/stokes_types.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/_utils/_zarr/encoding.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/measurement_set/schema.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/schema/__init__.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/schema/bases.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/schema/dataclass.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/schema/export.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/schema/metamodel.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/schema/typing.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/sphinx/__init__.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio/sphinx/schema_table.py +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio.egg-info/dependency_links.txt +0 -0
- {xradio-1.0.2 → xradio-1.1.1}/src/xradio.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xradio
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.1
|
|
4
4
|
Summary: Xarray Radio Astronomy Data IO
|
|
5
5
|
Author-email: Jan-Willem Steeb <jsteeb@nrao.edu>, Federico Montesino Pouzols <pouzols@eso.edu>, Dave Mehringer <dmehring@nrao.edu>, Peter Wortmann <peter.wortmann@skao.int>
|
|
6
6
|
License: BSD 3-Clause License
|
|
@@ -40,24 +40,48 @@ License: BSD 3-Clause License
|
|
|
40
40
|
Requires-Python: <3.14,>=3.11
|
|
41
41
|
Description-Content-Type: text/markdown
|
|
42
42
|
License-File: LICENSE.txt
|
|
43
|
-
Requires-Dist: astropy
|
|
44
|
-
Requires-Dist: toolviper>=0.0.12
|
|
45
|
-
Requires-Dist: numba>=0.57.0
|
|
46
|
-
Requires-Dist: s3fs
|
|
47
|
-
Requires-Dist: scipy
|
|
48
43
|
Requires-Dist: xarray
|
|
49
|
-
|
|
50
|
-
Requires-Dist:
|
|
51
|
-
Requires-Dist:
|
|
52
|
-
Requires-Dist:
|
|
53
|
-
Requires-Dist:
|
|
44
|
+
Provides-Extra: zarr
|
|
45
|
+
Requires-Dist: astropy; extra == "zarr"
|
|
46
|
+
Requires-Dist: toolviper>=0.0.12; extra == "zarr"
|
|
47
|
+
Requires-Dist: s3fs; extra == "zarr"
|
|
48
|
+
Requires-Dist: scipy; extra == "zarr"
|
|
49
|
+
Requires-Dist: xarray; extra == "zarr"
|
|
50
|
+
Requires-Dist: zarr<3,>=2; extra == "zarr"
|
|
51
|
+
Requires-Dist: pyarrow; extra == "zarr"
|
|
52
|
+
Requires-Dist: psutil; extra == "zarr"
|
|
54
53
|
Provides-Extra: test
|
|
54
|
+
Requires-Dist: astropy; extra == "test"
|
|
55
|
+
Requires-Dist: toolviper>=0.0.12; extra == "test"
|
|
56
|
+
Requires-Dist: s3fs; extra == "test"
|
|
57
|
+
Requires-Dist: scipy; extra == "test"
|
|
58
|
+
Requires-Dist: xarray; extra == "test"
|
|
59
|
+
Requires-Dist: zarr<3,>=2; extra == "test"
|
|
60
|
+
Requires-Dist: pyarrow; extra == "test"
|
|
61
|
+
Requires-Dist: psutil; extra == "test"
|
|
55
62
|
Requires-Dist: pytest; extra == "test"
|
|
56
63
|
Requires-Dist: pytest-cov; extra == "test"
|
|
57
64
|
Requires-Dist: pytest-html; extra == "test"
|
|
58
|
-
|
|
59
|
-
|
|
65
|
+
Requires-Dist: python_casacore>=3.6.1; sys_platform != "darwin" and extra == "test"
|
|
66
|
+
Provides-Extra: casacore
|
|
67
|
+
Requires-Dist: astropy; extra == "casacore"
|
|
68
|
+
Requires-Dist: toolviper>=0.0.12; extra == "casacore"
|
|
69
|
+
Requires-Dist: s3fs; extra == "casacore"
|
|
70
|
+
Requires-Dist: scipy; extra == "casacore"
|
|
71
|
+
Requires-Dist: xarray; extra == "casacore"
|
|
72
|
+
Requires-Dist: zarr<3,>=2; extra == "casacore"
|
|
73
|
+
Requires-Dist: pyarrow; extra == "casacore"
|
|
74
|
+
Requires-Dist: psutil; extra == "casacore"
|
|
75
|
+
Requires-Dist: python_casacore>=3.6.1; sys_platform != "darwin" and extra == "casacore"
|
|
60
76
|
Provides-Extra: interactive
|
|
77
|
+
Requires-Dist: astropy; extra == "interactive"
|
|
78
|
+
Requires-Dist: toolviper>=0.0.12; extra == "interactive"
|
|
79
|
+
Requires-Dist: s3fs; extra == "interactive"
|
|
80
|
+
Requires-Dist: scipy; extra == "interactive"
|
|
81
|
+
Requires-Dist: xarray; extra == "interactive"
|
|
82
|
+
Requires-Dist: zarr<3,>=2; extra == "interactive"
|
|
83
|
+
Requires-Dist: pyarrow; extra == "interactive"
|
|
84
|
+
Requires-Dist: psutil; extra == "interactive"
|
|
61
85
|
Requires-Dist: matplotlib; extra == "interactive"
|
|
62
86
|
Requires-Dist: prettytable; extra == "interactive"
|
|
63
87
|
Requires-Dist: jupyterlab; extra == "interactive"
|
|
@@ -74,7 +98,16 @@ Requires-Dist: sphinx-autosummary-accessors; extra == "docs"
|
|
|
74
98
|
Requires-Dist: sphinx_rtd_theme; extra == "docs"
|
|
75
99
|
Requires-Dist: twine; extra == "docs"
|
|
76
100
|
Requires-Dist: pandoc; extra == "docs"
|
|
101
|
+
Requires-Dist: toolviper; extra == "docs"
|
|
77
102
|
Provides-Extra: all
|
|
103
|
+
Requires-Dist: astropy; extra == "all"
|
|
104
|
+
Requires-Dist: toolviper>=0.0.12; extra == "all"
|
|
105
|
+
Requires-Dist: s3fs; extra == "all"
|
|
106
|
+
Requires-Dist: scipy; extra == "all"
|
|
107
|
+
Requires-Dist: xarray; extra == "all"
|
|
108
|
+
Requires-Dist: zarr<3,>=2; extra == "all"
|
|
109
|
+
Requires-Dist: pyarrow; extra == "all"
|
|
110
|
+
Requires-Dist: psutil; extra == "all"
|
|
78
111
|
Requires-Dist: pytest; extra == "all"
|
|
79
112
|
Requires-Dist: pytest-cov; extra == "all"
|
|
80
113
|
Requires-Dist: pytest-html; extra == "all"
|
|
@@ -119,28 +152,33 @@ XRADIO can now be installed using:
|
|
|
119
152
|
```sh
|
|
120
153
|
pip install xradio
|
|
121
154
|
```
|
|
122
|
-
This
|
|
155
|
+
This installs only the minimal dependencies for XRADIO, which allow you to use the schema checker and export schemas to JSON. **Note that if only the minimal dependencies are installed, the functionality to open data stored using zarr and to convert MSv2 to MSv4 will not be available.**
|
|
123
156
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
157
|
+
To install the zarr backend use:
|
|
158
|
+
```sh
|
|
159
|
+
pip install "xradio[zarr]"
|
|
160
|
+
```
|
|
161
|
+
This allows for opening data stored using zarr.
|
|
127
162
|
|
|
128
|
-
To install the
|
|
163
|
+
To install the zarr backend and the interactive components (JupyterLab) use:
|
|
129
164
|
```sh
|
|
130
165
|
pip install "xradio[interactive]"
|
|
131
166
|
```
|
|
132
167
|
|
|
133
|
-
To
|
|
168
|
+
To install the casacore backend along with the zarr backend which enables conversion from MSv2 to MSv4 use (this only works for Linux):
|
|
134
169
|
```sh
|
|
135
|
-
pip install "xradio[
|
|
170
|
+
pip install "xradio[casacore]"
|
|
136
171
|
```
|
|
137
|
-
|
|
172
|
+
|
|
173
|
+
To installs all the needed packages to run the unit tests:
|
|
138
174
|
```sh
|
|
139
175
|
pip install "xradio[test]"
|
|
140
176
|
```
|
|
177
|
+
This also installs the zarr backend and the casacore backend on Linux. Note the tests will fail on MacOS if python-casacore is not installed separately using conda.
|
|
178
|
+
|
|
141
179
|
Multiple-dependencies can be installed using:
|
|
142
180
|
```sh
|
|
143
|
-
pip install "xradio[interactive,
|
|
181
|
+
pip install "xradio[interactive,casacore,test]"
|
|
144
182
|
```
|
|
145
183
|
|
|
146
184
|
To install a more complete set of dependencies:
|
|
@@ -148,4 +186,8 @@ To install a more complete set of dependencies:
|
|
|
148
186
|
pip install "xradio[all]"
|
|
149
187
|
```
|
|
150
188
|
This will include the dependencies required to run the interactive Jupyter notebooks, run tests, build documentation,
|
|
151
|
-
and python-casacore to enable MSv2=>MSv4 functionality.
|
|
189
|
+
and python-casacore to enable MSv2=>MSv4 functionality on Linux.
|
|
190
|
+
|
|
191
|
+
Instruction of how to setup a developer environment can be found at [Development](https://xradio.readthedocs.io/en/latest/development.html).
|
|
192
|
+
|
|
193
|
+
Instruction of how to setup a developer environment using casatools instead of python-casacore can be found at [casatools I/O backend guide](docs/source/measurement_set/guides/backends.md).
|
|
@@ -21,28 +21,33 @@ XRADIO can now be installed using:
|
|
|
21
21
|
```sh
|
|
22
22
|
pip install xradio
|
|
23
23
|
```
|
|
24
|
-
This
|
|
24
|
+
This installs only the minimal dependencies for XRADIO, which allow you to use the schema checker and export schemas to JSON. **Note that if only the minimal dependencies are installed, the functionality to open data stored using zarr and to convert MSv2 to MSv4 will not be available.**
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
To install the zarr backend use:
|
|
27
|
+
```sh
|
|
28
|
+
pip install "xradio[zarr]"
|
|
29
|
+
```
|
|
30
|
+
This allows for opening data stored using zarr.
|
|
29
31
|
|
|
30
|
-
To install the
|
|
32
|
+
To install the zarr backend and the interactive components (JupyterLab) use:
|
|
31
33
|
```sh
|
|
32
34
|
pip install "xradio[interactive]"
|
|
33
35
|
```
|
|
34
36
|
|
|
35
|
-
To
|
|
37
|
+
To install the casacore backend along with the zarr backend which enables conversion from MSv2 to MSv4 use (this only works for Linux):
|
|
36
38
|
```sh
|
|
37
|
-
pip install "xradio[
|
|
39
|
+
pip install "xradio[casacore]"
|
|
38
40
|
```
|
|
39
|
-
|
|
41
|
+
|
|
42
|
+
To installs all the needed packages to run the unit tests:
|
|
40
43
|
```sh
|
|
41
44
|
pip install "xradio[test]"
|
|
42
45
|
```
|
|
46
|
+
This also installs the zarr backend and the casacore backend on Linux. Note the tests will fail on MacOS if python-casacore is not installed separately using conda.
|
|
47
|
+
|
|
43
48
|
Multiple-dependencies can be installed using:
|
|
44
49
|
```sh
|
|
45
|
-
pip install "xradio[interactive,
|
|
50
|
+
pip install "xradio[interactive,casacore,test]"
|
|
46
51
|
```
|
|
47
52
|
|
|
48
53
|
To install a more complete set of dependencies:
|
|
@@ -50,4 +55,8 @@ To install a more complete set of dependencies:
|
|
|
50
55
|
pip install "xradio[all]"
|
|
51
56
|
```
|
|
52
57
|
This will include the dependencies required to run the interactive Jupyter notebooks, run tests, build documentation,
|
|
53
|
-
and python-casacore to enable MSv2=>MSv4 functionality.
|
|
58
|
+
and python-casacore to enable MSv2=>MSv4 functionality on Linux.
|
|
59
|
+
|
|
60
|
+
Instruction of how to setup a developer environment can be found at [Development](https://xradio.readthedocs.io/en/latest/development.html).
|
|
61
|
+
|
|
62
|
+
Instruction of how to setup a developer environment using casatools instead of python-casacore can be found at [casatools I/O backend guide](docs/source/measurement_set/guides/backends.md).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "xradio"
|
|
3
|
-
version = "v1.
|
|
3
|
+
version = "v1.1.1"
|
|
4
4
|
description = " Xarray Radio Astronomy Data IO"
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "Jan-Willem Steeb", email="jsteeb@nrao.edu"},
|
|
@@ -13,36 +13,61 @@ readme = "README.md"
|
|
|
13
13
|
requires-python = ">= 3.11, < 3.14"
|
|
14
14
|
|
|
15
15
|
dependencies = [
|
|
16
|
+
'xarray'
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.optional-dependencies]
|
|
20
|
+
zarr = [
|
|
16
21
|
'astropy',
|
|
17
22
|
'toolviper>=0.0.12',
|
|
18
|
-
'numba>=0.57.0',
|
|
19
23
|
's3fs',
|
|
20
24
|
'scipy',
|
|
21
25
|
'xarray',
|
|
22
26
|
'zarr>=2,<3',
|
|
23
27
|
'pyarrow',
|
|
24
|
-
'typeguard',
|
|
25
|
-
'numcodecs<0.16',
|
|
26
28
|
'psutil' # psutil is needed so large FITS images are not loaded into memory
|
|
27
29
|
]
|
|
28
|
-
|
|
29
30
|
# toolviper has the following key dependencies also directly used by XRADIO (https://github.com/casangi/toolviper/blob/main/pyproject.toml):
|
|
30
31
|
# 'numpy',
|
|
31
32
|
# 'dask',
|
|
32
33
|
# 'distributed',
|
|
33
34
|
|
|
34
|
-
[project.optional-dependencies]
|
|
35
35
|
test = [
|
|
36
|
+
'astropy',
|
|
37
|
+
'toolviper>=0.0.12',
|
|
38
|
+
's3fs',
|
|
39
|
+
'scipy',
|
|
40
|
+
'xarray',
|
|
41
|
+
'zarr>=2,<3',
|
|
42
|
+
'pyarrow',
|
|
43
|
+
'psutil',
|
|
36
44
|
'pytest',
|
|
37
45
|
'pytest-cov',
|
|
38
46
|
'pytest-html',
|
|
47
|
+
'python_casacore>=3.6.1; sys_platform != "darwin"'
|
|
39
48
|
]
|
|
40
49
|
|
|
41
|
-
|
|
50
|
+
casacore = [
|
|
51
|
+
'astropy',
|
|
52
|
+
'toolviper>=0.0.12',
|
|
53
|
+
's3fs',
|
|
54
|
+
'scipy',
|
|
55
|
+
'xarray',
|
|
56
|
+
'zarr>=2,<3',
|
|
57
|
+
'pyarrow',
|
|
58
|
+
'psutil',
|
|
42
59
|
'python_casacore>=3.6.1; sys_platform != "darwin"'
|
|
43
60
|
]
|
|
44
61
|
|
|
45
62
|
interactive = [
|
|
63
|
+
'astropy',
|
|
64
|
+
'toolviper>=0.0.12',
|
|
65
|
+
's3fs',
|
|
66
|
+
'scipy',
|
|
67
|
+
'xarray',
|
|
68
|
+
'zarr>=2,<3',
|
|
69
|
+
'pyarrow',
|
|
70
|
+
'psutil',
|
|
46
71
|
'matplotlib',
|
|
47
72
|
'prettytable',
|
|
48
73
|
'jupyterlab',
|
|
@@ -60,10 +85,19 @@ docs = [
|
|
|
60
85
|
'sphinx-autosummary-accessors',
|
|
61
86
|
'sphinx_rtd_theme',
|
|
62
87
|
'twine',
|
|
63
|
-
'pandoc'
|
|
88
|
+
'pandoc',
|
|
89
|
+
'toolviper',
|
|
64
90
|
]
|
|
65
91
|
|
|
66
92
|
all = [
|
|
93
|
+
'astropy',
|
|
94
|
+
'toolviper>=0.0.12',
|
|
95
|
+
's3fs',
|
|
96
|
+
'scipy',
|
|
97
|
+
'xarray',
|
|
98
|
+
'zarr>=2,<3',
|
|
99
|
+
'pyarrow',
|
|
100
|
+
'psutil',
|
|
67
101
|
'pytest',
|
|
68
102
|
'pytest-cov',
|
|
69
103
|
'pytest-html',
|
|
@@ -29,6 +29,24 @@ except ModuleNotFoundError as exc:
|
|
|
29
29
|
f"{exc}"
|
|
30
30
|
)
|
|
31
31
|
|
|
32
|
+
# Valid casacore ImageInfo enum values
|
|
33
|
+
# Reference: https://casacore.github.io/casacore/classcasacore_1_1ImageInfo.html
|
|
34
|
+
_VALID_IMAGE_TYPES = (
|
|
35
|
+
"Undefined",
|
|
36
|
+
"Intensity",
|
|
37
|
+
"Beam",
|
|
38
|
+
"ColumnDensity",
|
|
39
|
+
"DepolarizationRatio",
|
|
40
|
+
"KineticTemperature",
|
|
41
|
+
"MagneticField",
|
|
42
|
+
"OpticalDepth",
|
|
43
|
+
"RotationMeasure",
|
|
44
|
+
"RotationalTemperature",
|
|
45
|
+
"SpectralIndex",
|
|
46
|
+
"Velocity",
|
|
47
|
+
"VelocityDispersion",
|
|
48
|
+
)
|
|
49
|
+
|
|
32
50
|
import numpy as np
|
|
33
51
|
import toolviper.utils.logger as logger
|
|
34
52
|
|
|
@@ -166,6 +184,32 @@ def wrap_class_methods(cls: type) -> type:
|
|
|
166
184
|
return cls
|
|
167
185
|
|
|
168
186
|
|
|
187
|
+
def _validate_image_type(value: str) -> str:
|
|
188
|
+
"""Validate and normalize an image type string.
|
|
189
|
+
|
|
190
|
+
Parameters
|
|
191
|
+
----------
|
|
192
|
+
value
|
|
193
|
+
The image type string to validate.
|
|
194
|
+
|
|
195
|
+
Returns
|
|
196
|
+
-------
|
|
197
|
+
str
|
|
198
|
+
A valid casacore ImageInfo enum value with proper capitalization.
|
|
199
|
+
Returns 'Intensity' if the input is not a valid type.
|
|
200
|
+
|
|
201
|
+
Notes
|
|
202
|
+
-----
|
|
203
|
+
Validation is case-insensitive. The returned string uses the
|
|
204
|
+
canonical capitalization from the casacore ImageInfo enum.
|
|
205
|
+
"""
|
|
206
|
+
value_lower = value.lower()
|
|
207
|
+
for valid_type in _VALID_IMAGE_TYPES:
|
|
208
|
+
if valid_type.lower() == value_lower:
|
|
209
|
+
return valid_type
|
|
210
|
+
return "Intensity"
|
|
211
|
+
|
|
212
|
+
|
|
169
213
|
@wrap_class_methods
|
|
170
214
|
class table(casatools.table):
|
|
171
215
|
"""A wrapper for the casatools table object.
|
|
@@ -513,7 +557,7 @@ class image(casatools.image):
|
|
|
513
557
|
self,
|
|
514
558
|
imagename,
|
|
515
559
|
axis=0,
|
|
516
|
-
maskname="
|
|
560
|
+
maskname="MASK_0",
|
|
517
561
|
images=(),
|
|
518
562
|
values=None,
|
|
519
563
|
coordsys=None,
|
|
@@ -702,18 +746,36 @@ class image(casatools.image):
|
|
|
702
746
|
def imageinfo(self) -> dict:
|
|
703
747
|
"""Retrieve metadata from the image table.
|
|
704
748
|
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
749
|
+
Accesses the image table and retrieves information stored under the
|
|
750
|
+
'imageinfo' keyword. The 'imagetype' value is validated against
|
|
751
|
+
casacore's ImageInfo enumeration values to mimic python-casacore
|
|
752
|
+
`image.imageinfo()` behavior.
|
|
709
753
|
|
|
710
754
|
Returns
|
|
711
755
|
-------
|
|
712
756
|
dict
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
757
|
+
Image metadata dictionary containing:
|
|
758
|
+
|
|
759
|
+
- **imagetype** : str
|
|
760
|
+
Type of the image, validated against casacore ImageInfo enum.
|
|
761
|
+
Defaults to 'Intensity' if invalid or missing.
|
|
762
|
+
- **objectname** : str
|
|
763
|
+
Name of the observed object.
|
|
764
|
+
|
|
765
|
+
Notes
|
|
766
|
+
-----
|
|
767
|
+
image.info()['imageinfo'] and image.imageinfo() from python-casacore
|
|
768
|
+
always returns "imagetype" in a predefined enum value. When the "imageinfo"
|
|
769
|
+
keyword is missing from the image table, or a non-standard value of "imagetype"
|
|
770
|
+
(e.g. 'sky') was written into that keyword, image.info() will just return
|
|
771
|
+
"Intensity" as the imagetype.
|
|
772
|
+
|
|
773
|
+
Examples
|
|
774
|
+
--------
|
|
775
|
+
>>> img = image('my_image.im')
|
|
776
|
+
>>> info = img.imageinfo()
|
|
777
|
+
>>> info['imagetype']
|
|
778
|
+
'Intensity'
|
|
717
779
|
"""
|
|
718
780
|
with table(self._imagename) as tb:
|
|
719
781
|
if "imageinfo" in tb.keywordnames():
|
|
@@ -721,6 +783,10 @@ class image(casatools.image):
|
|
|
721
783
|
else:
|
|
722
784
|
image_metadata = {"imagetype": "Intensity", "objectname": ""}
|
|
723
785
|
|
|
786
|
+
image_metadata["imagetype"] = _validate_image_type(
|
|
787
|
+
image_metadata.get("imagetype", "Intensity")
|
|
788
|
+
)
|
|
789
|
+
|
|
724
790
|
return image_metadata
|
|
725
791
|
|
|
726
792
|
def datatype(self):
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
from xradio._utils.list_and_array import to_python_type
|
|
2
|
+
|
|
3
|
+
|
|
1
4
|
def make_quantity(value, units: str, dims: list = []) -> dict:
|
|
2
5
|
"""
|
|
3
6
|
create a quantity dictionary given value and units
|
|
@@ -13,7 +16,11 @@ def make_quantity(value, units: str, dims: list = []) -> dict:
|
|
|
13
16
|
-------
|
|
14
17
|
dict
|
|
15
18
|
"""
|
|
16
|
-
return {
|
|
19
|
+
return {
|
|
20
|
+
"data": to_python_type(value),
|
|
21
|
+
"dims": dims,
|
|
22
|
+
"attrs": make_quantity_attrs(units),
|
|
23
|
+
}
|
|
17
24
|
|
|
18
25
|
|
|
19
26
|
def ensure_units_are_consistent(units):
|
|
@@ -67,7 +74,7 @@ def make_spectral_coord_reference_dict(
|
|
|
67
74
|
u,
|
|
68
75
|
observer.lower() if observer not in ["TOPO", "BARY", "REST"] else observer,
|
|
69
76
|
),
|
|
70
|
-
"data": value,
|
|
77
|
+
"data": to_python_type(value),
|
|
71
78
|
"dims": [],
|
|
72
79
|
}
|
|
73
80
|
|
|
@@ -98,14 +105,38 @@ def make_skycoord_dict(data: list[float], units: str, frame: str) -> dict:
|
|
|
98
105
|
"type": "sky_coord",
|
|
99
106
|
"units": ensure_units_are_consistent(units),
|
|
100
107
|
},
|
|
101
|
-
"data": data,
|
|
102
|
-
"dims":
|
|
108
|
+
"data": to_python_type(data),
|
|
109
|
+
"dims": "sky_dir_label",
|
|
110
|
+
"coords": {"sky_dir_label": {"data": ["ra", "dec"], "dims": "sky_dir_label"}},
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def make_direction_location_dict(data: list[float], units: str, frame: str) -> dict:
|
|
115
|
+
return {
|
|
116
|
+
"attrs": {
|
|
117
|
+
"frame": frame.upper(),
|
|
118
|
+
"type": "location",
|
|
119
|
+
"units": ensure_units_are_consistent(units),
|
|
120
|
+
},
|
|
121
|
+
"data": to_python_type(data),
|
|
122
|
+
"dims": "ellipsoid_dir_label",
|
|
123
|
+
"coords": {
|
|
124
|
+
"ellipsoid_dir_label": {
|
|
125
|
+
"data": ["lon", "lat"],
|
|
126
|
+
"dims": "ellipsoid_dir_label",
|
|
127
|
+
}
|
|
128
|
+
},
|
|
103
129
|
}
|
|
104
130
|
|
|
105
131
|
|
|
106
132
|
def make_time_measure_attrs(units="s", scale="utc", time_format="mjd") -> dict:
|
|
107
133
|
u = ensure_units_are_consistent(units)
|
|
108
|
-
return {
|
|
134
|
+
return {
|
|
135
|
+
"units": u,
|
|
136
|
+
"scale": scale.lower(),
|
|
137
|
+
"format": time_format.lower(),
|
|
138
|
+
"type": "time",
|
|
139
|
+
}
|
|
109
140
|
|
|
110
141
|
|
|
111
142
|
def make_time_measure_dict(data, units="s", scale="utc", time_format="mjd") -> dict:
|
|
@@ -127,7 +158,7 @@ def make_time_measure_dict(data, units="s", scale="utc", time_format="mjd") -> d
|
|
|
127
158
|
"""
|
|
128
159
|
x = {}
|
|
129
160
|
x["attrs"] = make_time_measure_attrs(units, scale, time_format)
|
|
130
|
-
x["data"] = data
|
|
161
|
+
x["data"] = to_python_type(data)
|
|
131
162
|
x["dims"] = []
|
|
132
163
|
return x
|
|
133
164
|
|
|
@@ -149,7 +180,7 @@ def make_time_coord_attrs(units="s", scale="utc", time_format="mjd") -> dict:
|
|
|
149
180
|
-------
|
|
150
181
|
dict
|
|
151
182
|
"""
|
|
152
|
-
x = make_time_measure_attrs(units, scale, time_format)
|
|
183
|
+
x = make_time_measure_attrs(units, scale.lower(), time_format.lower())
|
|
153
184
|
del x["type"]
|
|
154
185
|
return x
|
|
155
186
|
|
|
@@ -53,11 +53,34 @@ def get_pad_value(col_dtype: np.dtype) -> object:
|
|
|
53
53
|
)
|
|
54
54
|
|
|
55
55
|
|
|
56
|
+
def to_python_type(x):
|
|
57
|
+
"""
|
|
58
|
+
Convert any NumPy scalar, array, or nested structure to native Python types.
|
|
59
|
+
|
|
60
|
+
- np.float32, np.float64 → float
|
|
61
|
+
- np.int32, np.int64 → int
|
|
62
|
+
- np.bool_ → bool
|
|
63
|
+
- np.ndarray → list of Python-native types
|
|
64
|
+
- nested containers (list/tuple/dict) are handled recursively
|
|
65
|
+
"""
|
|
66
|
+
if isinstance(x, np.generic): # covers all numpy scalar types
|
|
67
|
+
return x.item()
|
|
68
|
+
elif isinstance(x, np.ndarray):
|
|
69
|
+
return x.tolist()
|
|
70
|
+
elif isinstance(x, (list, tuple)):
|
|
71
|
+
return type(x)(to_python_type(v) for v in x)
|
|
72
|
+
elif isinstance(x, dict):
|
|
73
|
+
return {k: to_python_type(v) for k, v in x.items()}
|
|
74
|
+
else:
|
|
75
|
+
return x
|
|
76
|
+
|
|
77
|
+
|
|
56
78
|
def to_list(x):
|
|
57
79
|
if isinstance(x, np.ndarray):
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
80
|
+
z = x.astype(float)
|
|
81
|
+
if z.ndim == 0:
|
|
82
|
+
return [z.item()]
|
|
83
|
+
return list(z) # needed for json serialization
|
|
61
84
|
elif isinstance(x, list):
|
|
62
85
|
return x
|
|
63
86
|
return [x]
|
|
@@ -224,3 +224,47 @@ casa_frequency_frames = [
|
|
|
224
224
|
]
|
|
225
225
|
|
|
226
226
|
casa_frequency_frames_codes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 64]
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def get_data_group_keys(schema_name: str) -> list[tuple[str, bool]]:
|
|
230
|
+
"""Return (name, is_optional) pairs for data group keys for the given schema.
|
|
231
|
+
|
|
232
|
+
Parameters
|
|
233
|
+
----------
|
|
234
|
+
schema_name : str
|
|
235
|
+
The name of the schema to retrieve data group keys for. Supported values are "msv4" and "image".
|
|
236
|
+
|
|
237
|
+
Returns
|
|
238
|
+
-------
|
|
239
|
+
list[tuple[str, bool]]
|
|
240
|
+
A list of tuples (key_name, is_optional) for the specified schema.
|
|
241
|
+
|
|
242
|
+
Raises
|
|
243
|
+
------
|
|
244
|
+
ValueError
|
|
245
|
+
If the schema name is unknown.
|
|
246
|
+
"""
|
|
247
|
+
from typing import get_type_hints, get_origin, get_args, Union
|
|
248
|
+
|
|
249
|
+
if schema_name == "msv4":
|
|
250
|
+
from xradio.measurement_set.schema import DataGroupDict
|
|
251
|
+
|
|
252
|
+
cls = DataGroupDict
|
|
253
|
+
elif schema_name == "image":
|
|
254
|
+
from xradio.image.schema import DataGroupDict
|
|
255
|
+
|
|
256
|
+
cls = DataGroupDict
|
|
257
|
+
else:
|
|
258
|
+
raise ValueError(f"Unknown schema name: {schema_name}")
|
|
259
|
+
|
|
260
|
+
annotations = get_type_hints(cls)
|
|
261
|
+
keys_with_optional = {}
|
|
262
|
+
for name, anno in annotations.items():
|
|
263
|
+
origin = get_origin(anno)
|
|
264
|
+
is_optional = False
|
|
265
|
+
if origin is Union:
|
|
266
|
+
args = get_args(anno)
|
|
267
|
+
is_optional = type(None) in args
|
|
268
|
+
keys_with_optional[name] = is_optional
|
|
269
|
+
|
|
270
|
+
return keys_with_optional
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import xarray as xr
|
|
2
|
+
from xradio._utils.schema import get_data_group_keys
|
|
3
|
+
from collections.abc import Mapping, Iterable
|
|
4
|
+
from typing import Any, Union
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def get_data_group_name(
|
|
8
|
+
xdx: Union[xr.Dataset, xr.DataTree], data_group_name: str = None
|
|
9
|
+
) -> str:
|
|
10
|
+
|
|
11
|
+
if data_group_name is None:
|
|
12
|
+
if "base" in xdx.attrs["data_groups"]:
|
|
13
|
+
data_group_name = "base"
|
|
14
|
+
else:
|
|
15
|
+
data_group_name = list(xdx.attrs["data_groups"].keys())[0]
|
|
16
|
+
|
|
17
|
+
return data_group_name
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def create_new_data_group(
|
|
21
|
+
xdx: Union[xr.Dataset, xr.DataTree],
|
|
22
|
+
schema_name: str,
|
|
23
|
+
new_data_group_name: str,
|
|
24
|
+
data_group: dict,
|
|
25
|
+
data_group_dv_shared_with: str = None,
|
|
26
|
+
) -> xr.DataTree:
|
|
27
|
+
"""Adds a data group to Xarray Data Structure (Dataset or DataTree).
|
|
28
|
+
|
|
29
|
+
Parameters
|
|
30
|
+
----------
|
|
31
|
+
new_data_group_name : str
|
|
32
|
+
The name of the new data group to add.
|
|
33
|
+
data_group : dict
|
|
34
|
+
A dictionary containing the data group variables and their attributes.
|
|
35
|
+
data_group_dv_shared_with : str, optional
|
|
36
|
+
The name of the data group to share data variables with, by default "base"
|
|
37
|
+
|
|
38
|
+
Returns
|
|
39
|
+
-------
|
|
40
|
+
xr.DataTree
|
|
41
|
+
MSv4 DataTree with the new group added
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
data_group_dv_shared_with = get_data_group_name(xdx, data_group_dv_shared_with)
|
|
45
|
+
|
|
46
|
+
default_data_group = xdx.attrs["data_groups"][data_group_dv_shared_with]
|
|
47
|
+
|
|
48
|
+
new_data_group = {}
|
|
49
|
+
|
|
50
|
+
data_group_keys = get_data_group_keys(schema_name)
|
|
51
|
+
|
|
52
|
+
for key, optional in data_group_keys.items():
|
|
53
|
+
if key in data_group:
|
|
54
|
+
new_data_group[key] = data_group[key]
|
|
55
|
+
else:
|
|
56
|
+
if key not in default_data_group and not optional:
|
|
57
|
+
raise ValueError(
|
|
58
|
+
f"Data group key '{key}' is required but not provided and not present in shared data group '{data_group_dv_shared_with}'."
|
|
59
|
+
)
|
|
60
|
+
elif key in default_data_group:
|
|
61
|
+
new_data_group[key] = default_data_group[key]
|
|
62
|
+
|
|
63
|
+
return new_data_group_name, new_data_group
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import xarray as xr
|
|
2
|
-
import s3fs
|
|
3
2
|
import os
|
|
4
|
-
from botocore.exceptions import NoCredentialsError
|
|
5
3
|
|
|
6
4
|
# from xradio.vis._vis_utils._ms.msv2_to_msv4_meta import (
|
|
7
5
|
# column_description_casacore_to_msv4_measure,
|
|
@@ -10,6 +8,9 @@ from botocore.exceptions import NoCredentialsError
|
|
|
10
8
|
|
|
11
9
|
def _get_file_system_and_items(ps_store: str):
|
|
12
10
|
|
|
11
|
+
import s3fs
|
|
12
|
+
from botocore.exceptions import NoCredentialsError
|
|
13
|
+
|
|
13
14
|
# default to assuming the data are accessible on local file system
|
|
14
15
|
if os.path.isdir(ps_store):
|
|
15
16
|
# handle a common shell convention
|
|
@@ -74,6 +75,7 @@ def _open_dataset(
|
|
|
74
75
|
"""
|
|
75
76
|
|
|
76
77
|
import dask
|
|
78
|
+
import s3fs
|
|
77
79
|
|
|
78
80
|
if isinstance(file_system, s3fs.core.S3FileSystem):
|
|
79
81
|
mapping = s3fs.S3Map(root=store, s3=file_system, check=False)
|