xradio 0.0.56__tar.gz → 0.0.58__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-0.0.56/src/xradio.egg-info → xradio-0.0.58}/PKG-INFO +2 -1
- {xradio-0.0.56 → xradio-0.0.58}/pyproject.toml +3 -2
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/__init__.py +2 -2
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/_utils/_casacore/casacore_from_casatools.py +12 -2
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/_utils/_casacore/tables.py +1 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/_utils/coord_math.py +22 -23
- xradio-0.0.58/src/xradio/_utils/dict_helpers.py +170 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/_utils/schema.py +5 -2
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/_utils/zarr/common.py +1 -73
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/_casacore/xds_from_casacore.py +49 -33
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/_casacore/xds_to_casacore.py +41 -14
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/_fits/xds_from_fits.py +146 -35
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/casacore.py +4 -3
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/common.py +4 -4
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/image_factory.py +8 -8
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/image.py +45 -5
- xradio-0.0.58/src/xradio/measurement_set/__init__.py +37 -0
- xradio-0.0.58/src/xradio/measurement_set/_utils/__init__.py +3 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/_utils/_msv2/_tables/read.py +17 -76
- xradio-0.0.58/src/xradio/measurement_set/_utils/_msv2/_tables/read_main_table.py +102 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/_utils/_msv2/conversion.py +123 -145
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/_utils/_msv2/create_antenna_xds.py +9 -16
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/_utils/_msv2/create_field_and_source_xds.py +125 -221
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/_utils/_msv2/msv2_to_msv4_meta.py +1 -2
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/_utils/_msv2/msv4_info_dicts.py +8 -7
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/_utils/_msv2/msv4_sub_xdss.py +27 -72
- xradio-0.0.58/src/xradio/measurement_set/_utils/_msv2/optimised_functions.py +0 -0
- xradio-0.0.58/src/xradio/measurement_set/_utils/_msv2/partition_queries.py +150 -0
- xradio-0.0.58/src/xradio/measurement_set/_utils/_msv2/subtables.py +16 -0
- xradio-0.0.58/src/xradio/measurement_set/_utils/_utils/interpolate.py +60 -0
- xradio-0.0.58/src/xradio/measurement_set/_utils/_zarr/encoding.py +9 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/convert_msv2_to_processing_set.py +0 -2
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/load_processing_set.py +2 -2
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/measurement_set_xdt.py +14 -14
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/open_processing_set.py +1 -3
- xradio-0.0.58/src/xradio/measurement_set/processing_set_xdt.py +873 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/schema.py +95 -122
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/schema/check.py +91 -97
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/schema/dataclass.py +159 -22
- xradio-0.0.58/src/xradio/schema/export.py +99 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/schema/metamodel.py +51 -16
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/schema/typing.py +5 -5
- {xradio-0.0.56 → xradio-0.0.58/src/xradio.egg-info}/PKG-INFO +2 -1
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio.egg-info/SOURCES.txt +3 -16
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio.egg-info/requires.txt +1 -0
- xradio-0.0.56/src/xradio/_utils/dict_helpers.py +0 -105
- xradio-0.0.56/src/xradio/image/_util/fits.py +0 -13
- xradio-0.0.56/src/xradio/measurement_set/__init__.py +0 -27
- xradio-0.0.56/src/xradio/measurement_set/_utils/__init__.py +0 -5
- xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/_tables/load.py +0 -66
- xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/_tables/load_main_table.py +0 -490
- xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/_tables/read_main_table.py +0 -785
- xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/_tables/read_subtables.py +0 -398
- xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/_tables/write.py +0 -323
- xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/_tables/write_exp_api.py +0 -388
- xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/chunks.py +0 -115
- xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/descr.py +0 -165
- xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/msv2_msv3.py +0 -7
- xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/partition_queries.py +0 -410
- xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/partitions.py +0 -392
- xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/subtables.py +0 -123
- xradio-0.0.56/src/xradio/measurement_set/_utils/_utils/cds.py +0 -40
- xradio-0.0.56/src/xradio/measurement_set/_utils/_utils/xds_helper.py +0 -404
- xradio-0.0.56/src/xradio/measurement_set/_utils/_zarr/encoding.py +0 -14
- xradio-0.0.56/src/xradio/measurement_set/_utils/_zarr/read.py +0 -263
- xradio-0.0.56/src/xradio/measurement_set/_utils/_zarr/write.py +0 -329
- xradio-0.0.56/src/xradio/measurement_set/_utils/msv2.py +0 -106
- xradio-0.0.56/src/xradio/measurement_set/_utils/zarr.py +0 -133
- xradio-0.0.56/src/xradio/measurement_set/processing_set_xdt.py +0 -1667
- {xradio-0.0.56 → xradio-0.0.58}/LICENSE.txt +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/MANIFEST.in +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/README.md +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/setup.cfg +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/_utils/__init__.py +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/_utils/list_and_array.py +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/_utils/zarr/__init__.py +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/__init__.py +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/__init__.py +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/_casacore/__init__.py +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/_casacore/common.py +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/_zarr/common.py +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/_zarr/xds_from_zarr.py +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/_zarr/xds_to_zarr.py +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/_zarr/zarr_low_level.py +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/zarr.py +0 -0
- /xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/optimised_functions.py → /xradio-0.0.58/src/xradio/measurement_set/_utils/_msv2/__init__.py +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/_utils/_msv2/_tables/table_query.py +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/_utils/_utils/partition_attrs.py +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/_utils/_utils/stokes_types.py +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/schema/__init__.py +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/schema/bases.py +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/sphinx/__init__.py +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio/sphinx/schema_table.py +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/src/xradio.egg-info/dependency_links.txt +0 -0
- {xradio-0.0.56 → xradio-0.0.58}/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: 0.0.
|
|
3
|
+
Version: 0.0.58
|
|
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
|
|
@@ -50,6 +50,7 @@ Requires-Dist: zarr<3,>=2
|
|
|
50
50
|
Requires-Dist: pyarrow
|
|
51
51
|
Requires-Dist: typeguard
|
|
52
52
|
Requires-Dist: numcodecs<0.16
|
|
53
|
+
Requires-Dist: psutil
|
|
53
54
|
Provides-Extra: test
|
|
54
55
|
Requires-Dist: pytest; extra == "test"
|
|
55
56
|
Requires-Dist: pytest-cov; extra == "test"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "xradio"
|
|
3
|
-
version = "v0.0.
|
|
3
|
+
version = "v0.0.58"
|
|
4
4
|
description = " Xarray Radio Astronomy Data IO"
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "Jan-Willem Steeb", email="jsteeb@nrao.edu"},
|
|
@@ -22,7 +22,8 @@ dependencies = [
|
|
|
22
22
|
'zarr>=2,<3',
|
|
23
23
|
'pyarrow',
|
|
24
24
|
'typeguard',
|
|
25
|
-
'numcodecs<0.16'
|
|
25
|
+
'numcodecs<0.16',
|
|
26
|
+
'psutil' # psutil is needed so large FITS images are not loaded into memory
|
|
26
27
|
]
|
|
27
28
|
|
|
28
29
|
# toolviper has the following key dependencies also directly used by XRADIO (https://github.com/casangi/toolviper/blob/main/pyproject.toml):
|
|
@@ -18,7 +18,17 @@ from typing import Any, Dict, List, Sequence, Union
|
|
|
18
18
|
# Configure casaconfig settings prior to casatools import
|
|
19
19
|
# this ensures optimal initialization and resource allocation for casatools
|
|
20
20
|
# Also see : https://casadocs.readthedocs.io/en/stable/api/casaconfig.html
|
|
21
|
-
|
|
21
|
+
try:
|
|
22
|
+
import casaconfig.config
|
|
23
|
+
except ModuleNotFoundError as exc:
|
|
24
|
+
raise ModuleNotFoundError(
|
|
25
|
+
f"casaconfig.config cannot be found, probably because the package "
|
|
26
|
+
"casatools is not available. If you are here that is probably because "
|
|
27
|
+
"python-casacore is not available either. MSv2 related functionality "
|
|
28
|
+
"requires either python-casacore or casatools. Import failure details: "
|
|
29
|
+
f"{exc}"
|
|
30
|
+
)
|
|
31
|
+
|
|
22
32
|
import numpy as np
|
|
23
33
|
import toolviper.utils.logger as logger
|
|
24
34
|
|
|
@@ -70,7 +80,7 @@ else:
|
|
|
70
80
|
casaconfig.config.logfile = "/dev/null"
|
|
71
81
|
casaconfig.config.nologfile = True
|
|
72
82
|
|
|
73
|
-
import casatools
|
|
83
|
+
import casatools # noqa: E402 (because of previous config initialization)
|
|
74
84
|
|
|
75
85
|
casatools.logger.setglobal(True)
|
|
76
86
|
casatools.logger.ompSetNumThreads(1)
|
|
@@ -63,38 +63,37 @@ def wrap_to_pi(angles):
|
|
|
63
63
|
return (angles + np.pi) % (2 * np.pi) - np.pi
|
|
64
64
|
|
|
65
65
|
|
|
66
|
-
def
|
|
67
|
-
|
|
66
|
+
def convert_to_si_units(xds):
|
|
67
|
+
import xarray as xr
|
|
68
68
|
|
|
69
|
+
with xr.set_options(keep_attrs=True):
|
|
70
|
+
for data_var in xds.data_vars:
|
|
71
|
+
if "units" in xds[data_var].attrs:
|
|
72
|
+
u = xds[data_var].attrs["units"]
|
|
69
73
|
|
|
70
|
-
def convert_to_si_units(xds):
|
|
71
|
-
for data_var in xds.data_vars:
|
|
72
|
-
if "units" in xds[data_var].attrs:
|
|
73
|
-
for u_i, u in enumerate(xds[data_var].attrs["units"]):
|
|
74
74
|
if u == "km":
|
|
75
|
-
xds[data_var]
|
|
76
|
-
xds[data_var].attrs["units"]
|
|
75
|
+
xds[data_var] = xds[data_var] * 1e3
|
|
76
|
+
xds[data_var].attrs["units"] = "m"
|
|
77
77
|
if u == "km/s":
|
|
78
|
-
xds[data_var]
|
|
79
|
-
xds[data_var].attrs["units"]
|
|
78
|
+
xds[data_var] = xds[data_var] * 1e3
|
|
79
|
+
xds[data_var].attrs["units"] = "m/s"
|
|
80
80
|
if u == "deg":
|
|
81
|
-
xds[data_var]
|
|
82
|
-
xds[data_var].attrs["units"]
|
|
81
|
+
xds[data_var] = xds[data_var] * np.pi / 180
|
|
82
|
+
xds[data_var].attrs["units"] = "rad"
|
|
83
83
|
if u == "Au" or u == "AU":
|
|
84
|
-
xds[data_var]
|
|
85
|
-
xds[data_var].attrs["units"]
|
|
84
|
+
xds[data_var] = xds[data_var] * 149597870700
|
|
85
|
+
xds[data_var].attrs["units"] = "m"
|
|
86
86
|
if u == "Au/d" or u == "AU/d":
|
|
87
|
-
xds[data_var][
|
|
88
|
-
|
|
89
|
-
)
|
|
90
|
-
xds[data_var].attrs["units"][u_i] = "m/s"
|
|
87
|
+
xds[data_var] = xds[data_var] * 149597870700 / 86400
|
|
88
|
+
xds[data_var].attrs["units"] = "m/s"
|
|
91
89
|
if u == "arcsec":
|
|
92
|
-
xds[data_var]
|
|
93
|
-
xds[data_var].attrs["units"]
|
|
90
|
+
xds[data_var] = xds[data_var] * np.pi / 648000
|
|
91
|
+
xds[data_var].attrs["units"] = "rad"
|
|
94
92
|
if u == "hPa":
|
|
95
|
-
xds[data_var]
|
|
96
|
-
xds[data_var].attrs["units"]
|
|
93
|
+
xds[data_var] = xds[data_var] * 100.0
|
|
94
|
+
xds[data_var].attrs["units"] = "Pa"
|
|
97
95
|
if u == "m-2":
|
|
98
96
|
# IONOS_ELECTRON sometimes has "m-2" instead of "/m^2"
|
|
99
|
-
xds[data_var].attrs["units"]
|
|
97
|
+
xds[data_var].attrs["units"] = "/m^2"
|
|
98
|
+
|
|
100
99
|
return xds
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
def make_quantity(value, units: str, dims: list = []) -> dict:
|
|
2
|
+
"""
|
|
3
|
+
create a quantity dictionary given value and units
|
|
4
|
+
|
|
5
|
+
Parameters
|
|
6
|
+
----------
|
|
7
|
+
value : numeric or array of numerics
|
|
8
|
+
Quantity value
|
|
9
|
+
units: str
|
|
10
|
+
Quantity units
|
|
11
|
+
|
|
12
|
+
Returns
|
|
13
|
+
-------
|
|
14
|
+
dict
|
|
15
|
+
"""
|
|
16
|
+
return {"data": value, "dims": dims, "attrs": make_quantity_attrs(units)}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def ensure_units_are_consistent(units):
|
|
20
|
+
if isinstance(units, str):
|
|
21
|
+
return units
|
|
22
|
+
else:
|
|
23
|
+
u0 = units[0]
|
|
24
|
+
for u in units:
|
|
25
|
+
assert u0 == u, f"Units are not consistent: {u0} != {u}. "
|
|
26
|
+
return u0
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def make_quantity_attrs(units: str) -> dict:
|
|
30
|
+
"""
|
|
31
|
+
Creates the dict of attributes of a quantity
|
|
32
|
+
|
|
33
|
+
Parameters
|
|
34
|
+
----------
|
|
35
|
+
units: str
|
|
36
|
+
Quantity units
|
|
37
|
+
|
|
38
|
+
Returns
|
|
39
|
+
-------
|
|
40
|
+
dict
|
|
41
|
+
"""
|
|
42
|
+
return {"units": ensure_units_are_consistent(units), "type": "quantity"}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def make_spectral_coord_reference_dict(
|
|
46
|
+
value: float, units: str, observer: str = "lsrk"
|
|
47
|
+
) -> dict:
|
|
48
|
+
"""
|
|
49
|
+
creates a spectral_coord measure dict given the value, units, and observer
|
|
50
|
+
|
|
51
|
+
Parameters
|
|
52
|
+
----------
|
|
53
|
+
value : numeric or array of numerics
|
|
54
|
+
measure value
|
|
55
|
+
units : str
|
|
56
|
+
measure units
|
|
57
|
+
observer :
|
|
58
|
+
observer reference frame
|
|
59
|
+
|
|
60
|
+
Returns
|
|
61
|
+
-------
|
|
62
|
+
dict
|
|
63
|
+
"""
|
|
64
|
+
u = ensure_units_are_consistent(units)
|
|
65
|
+
return {
|
|
66
|
+
"attrs": make_spectral_coord_measure_attrs(
|
|
67
|
+
u,
|
|
68
|
+
observer.lower() if observer not in ["TOPO", "BARY", "REST"] else observer,
|
|
69
|
+
),
|
|
70
|
+
"data": value,
|
|
71
|
+
"dims": [],
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def make_spectral_coord_measure_attrs(units: str, observer: str = "lsrk") -> dict:
|
|
76
|
+
"""
|
|
77
|
+
Creates a spectral_coord measure attrs dict given units and observer
|
|
78
|
+
|
|
79
|
+
Parameters
|
|
80
|
+
----------
|
|
81
|
+
units: str or list of str
|
|
82
|
+
Spectral coordinate units
|
|
83
|
+
observer: str
|
|
84
|
+
Spectral reference frame
|
|
85
|
+
Returns
|
|
86
|
+
-------
|
|
87
|
+
dict
|
|
88
|
+
Attrs dict for a spectral_coord measure
|
|
89
|
+
"""
|
|
90
|
+
u = ensure_units_are_consistent(units)
|
|
91
|
+
return {"units": u, "observer": observer, "type": "spectral_coord"}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def make_skycoord_dict(data: list[float], units: str, frame: str) -> dict:
|
|
95
|
+
return {
|
|
96
|
+
"attrs": {
|
|
97
|
+
"frame": frame.lower(),
|
|
98
|
+
"type": "sky_coord",
|
|
99
|
+
"units": ensure_units_are_consistent(units),
|
|
100
|
+
},
|
|
101
|
+
"data": data,
|
|
102
|
+
"dims": ["l", "m"],
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def make_time_measure_attrs(units="s", scale="utc", time_format="mjd") -> dict:
|
|
107
|
+
u = ensure_units_are_consistent(units)
|
|
108
|
+
return {"units": u, "scale": scale, "format": time_format, "type": "time"}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def make_time_measure_dict(data, units="s", scale="utc", time_format="mjd") -> dict:
|
|
112
|
+
"""
|
|
113
|
+
create a time measure dictionary given value and units
|
|
114
|
+
Parameters
|
|
115
|
+
----------
|
|
116
|
+
value : numeric or array of numerics
|
|
117
|
+
Time value
|
|
118
|
+
units: str
|
|
119
|
+
Time units
|
|
120
|
+
scale: str
|
|
121
|
+
Time scale
|
|
122
|
+
time_format: str
|
|
123
|
+
Time format
|
|
124
|
+
Returns
|
|
125
|
+
-------
|
|
126
|
+
dict
|
|
127
|
+
"""
|
|
128
|
+
x = {}
|
|
129
|
+
x["attrs"] = make_time_measure_attrs(units, scale, time_format)
|
|
130
|
+
x["data"] = data
|
|
131
|
+
x["dims"] = []
|
|
132
|
+
return x
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def make_time_coord_attrs(units="s", scale="utc", time_format="mjd") -> dict:
|
|
136
|
+
"""
|
|
137
|
+
create a time measure dictionary given value and units
|
|
138
|
+
Parameters
|
|
139
|
+
----------
|
|
140
|
+
value : numeric or array of numerics
|
|
141
|
+
Time value
|
|
142
|
+
units: str
|
|
143
|
+
Time units
|
|
144
|
+
scale: str
|
|
145
|
+
Time scale
|
|
146
|
+
time_format: str
|
|
147
|
+
Time format
|
|
148
|
+
Returns
|
|
149
|
+
-------
|
|
150
|
+
dict
|
|
151
|
+
"""
|
|
152
|
+
x = make_time_measure_attrs(units, scale, time_format)
|
|
153
|
+
del x["type"]
|
|
154
|
+
return x
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _casacore_q_to_xradio_q(q: dict) -> dict:
|
|
158
|
+
"""
|
|
159
|
+
Convert a casacore quantity to an xradio quantity
|
|
160
|
+
"""
|
|
161
|
+
if isinstance(q, dict):
|
|
162
|
+
if "value" in q and "unit" in q:
|
|
163
|
+
return make_quantity(q["value"], q["unit"])
|
|
164
|
+
else:
|
|
165
|
+
p = {}
|
|
166
|
+
for k in q:
|
|
167
|
+
p[k] = _casacore_q_to_xradio_q(q[k])
|
|
168
|
+
return p
|
|
169
|
+
else:
|
|
170
|
+
raise ValueError(f"Cannot convert {q} to xradio quantity")
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import toolviper.utils.logger as logger
|
|
2
2
|
import xarray as xr
|
|
3
3
|
from typing import Union
|
|
4
|
+
from xradio._utils.dict_helpers import ensure_units_are_consistent
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
def convert_generic_xds_to_xradio_schema(
|
|
@@ -108,7 +109,7 @@ def column_description_casacore_to_msv4_measure(
|
|
|
108
109
|
|
|
109
110
|
# Convert type, copy unit
|
|
110
111
|
msv4_measure["type"] = msv4_measure_conversion["type"]
|
|
111
|
-
msv4_measure["units"] =
|
|
112
|
+
msv4_measure["units"] = ensure_units_are_consistent(
|
|
112
113
|
casacore_column_description["keywords"]["QuantumUnits"]
|
|
113
114
|
)
|
|
114
115
|
|
|
@@ -154,7 +155,9 @@ def column_description_casacore_to_msv4_measure(
|
|
|
154
155
|
elif "QuantumUnits" in casacore_column_description["keywords"]:
|
|
155
156
|
msv4_measure = {
|
|
156
157
|
"type": "quantity",
|
|
157
|
-
"units":
|
|
158
|
+
"units": ensure_units_are_consistent(
|
|
159
|
+
casacore_column_description["keywords"]["QuantumUnits"]
|
|
160
|
+
),
|
|
158
161
|
}
|
|
159
162
|
|
|
160
163
|
return msv4_measure
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import copy
|
|
2
1
|
import xarray as xr
|
|
3
|
-
import zarr
|
|
4
2
|
import s3fs
|
|
5
3
|
import os
|
|
6
4
|
from botocore.exceptions import NoCredentialsError
|
|
@@ -34,7 +32,7 @@ def _get_file_system_and_items(ps_store: str):
|
|
|
34
32
|
for bd in file_system.listdir(ps_store, detail=False)
|
|
35
33
|
]
|
|
36
34
|
|
|
37
|
-
except (NoCredentialsError, PermissionError)
|
|
35
|
+
except (NoCredentialsError, PermissionError):
|
|
38
36
|
# only public, read-only buckets will be accessible
|
|
39
37
|
# we will want to add messaging and error handling here
|
|
40
38
|
file_system = s3fs.S3FileSystem(anon=True)
|
|
@@ -97,73 +95,3 @@ def _open_dataset(
|
|
|
97
95
|
with dask.config.set(scheduler="synchronous"):
|
|
98
96
|
xds = xds.load()
|
|
99
97
|
return xds
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
# Code to depricate:
|
|
103
|
-
def _get_attrs(zarr_obj):
|
|
104
|
-
"""
|
|
105
|
-
get attributes of zarr obj (groups or arrays)
|
|
106
|
-
"""
|
|
107
|
-
return {k: v for k, v in zarr_obj.attrs.asdict().items() if not k.startswith("_NC")}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def _load_no_dask_zarr(zarr_name, slice_dict={}):
|
|
111
|
-
"""
|
|
112
|
-
Alternative to xarray open_zarr where the arrays are not Dask Arrays.
|
|
113
|
-
|
|
114
|
-
slice_dict: A dictionary of slice objects for which values to read form a dimension.
|
|
115
|
-
For example silce_dict={'time':slice(0,10)} would select the first 10 elements in the time dimension.
|
|
116
|
-
If a dim is not specified all values are retruned.
|
|
117
|
-
return:
|
|
118
|
-
xarray.Dataset()
|
|
119
|
-
|
|
120
|
-
#Should go into general utils.
|
|
121
|
-
"""
|
|
122
|
-
# Used by xarray to store array labeling info in zarr meta data.
|
|
123
|
-
DIMENSION_KEY = "_ARRAY_DIMENSIONS"
|
|
124
|
-
|
|
125
|
-
# logger = _get_logger()
|
|
126
|
-
zarr_group = zarr.open_group(store=zarr_name, mode="r")
|
|
127
|
-
group_attrs = _get_attrs(zarr_group)
|
|
128
|
-
|
|
129
|
-
slice_dict_complete = copy.deepcopy(slice_dict)
|
|
130
|
-
coords = {}
|
|
131
|
-
xds = xr.Dataset()
|
|
132
|
-
for var_name, var in zarr_group.arrays():
|
|
133
|
-
print("Hallo 3", var_name, var.shape)
|
|
134
|
-
var_attrs = _get_attrs(var)
|
|
135
|
-
|
|
136
|
-
for dim in var_attrs[DIMENSION_KEY]:
|
|
137
|
-
if dim not in slice_dict_complete:
|
|
138
|
-
slice_dict_complete[dim] = slice(None) # No slicing.
|
|
139
|
-
|
|
140
|
-
if (var_attrs[DIMENSION_KEY][0] == var_name) and (
|
|
141
|
-
len(var_attrs[DIMENSION_KEY]) == 1
|
|
142
|
-
):
|
|
143
|
-
coord = var[
|
|
144
|
-
slice_dict_complete[var_attrs[DIMENSION_KEY][0]]
|
|
145
|
-
] # Dimension coordinates.
|
|
146
|
-
del var_attrs["_ARRAY_DIMENSIONS"]
|
|
147
|
-
xds = xds.assign_coords({var_name: coord})
|
|
148
|
-
xds[var_name].attrs = var_attrs
|
|
149
|
-
else:
|
|
150
|
-
# Construct slicing
|
|
151
|
-
slicing_list = []
|
|
152
|
-
for dim in var_attrs[DIMENSION_KEY]:
|
|
153
|
-
slicing_list.append(slice_dict_complete[dim])
|
|
154
|
-
slicing_tuple = tuple(slicing_list)
|
|
155
|
-
|
|
156
|
-
print(var_attrs[DIMENSION_KEY])
|
|
157
|
-
|
|
158
|
-
xds[var_name] = xr.DataArray(
|
|
159
|
-
var[slicing_tuple], dims=var_attrs[DIMENSION_KEY]
|
|
160
|
-
)
|
|
161
|
-
|
|
162
|
-
if "coordinates" in var_attrs:
|
|
163
|
-
del var_attrs["coordinates"]
|
|
164
|
-
del var_attrs["_ARRAY_DIMENSIONS"]
|
|
165
|
-
xds[var_name].attrs = var_attrs
|
|
166
|
-
|
|
167
|
-
xds.attrs = group_attrs
|
|
168
|
-
|
|
169
|
-
return xds
|
|
@@ -41,7 +41,7 @@ from ...._utils._casacore.tables import extract_table_attributes, open_table_ro
|
|
|
41
41
|
from xradio._utils.coord_math import _deg_to_rad
|
|
42
42
|
from xradio._utils.dict_helpers import (
|
|
43
43
|
_casacore_q_to_xradio_q,
|
|
44
|
-
|
|
44
|
+
make_spectral_coord_reference_dict,
|
|
45
45
|
make_quantity,
|
|
46
46
|
make_skycoord_dict,
|
|
47
47
|
make_time_measure_dict,
|
|
@@ -85,34 +85,50 @@ def _casa_image_to_xds_image_attrs(image: casa_image, history: bool = True) -> d
|
|
|
85
85
|
attrs["units"] = image.unit()
|
|
86
86
|
attrs["telescope"] = {}
|
|
87
87
|
telescope = attrs["telescope"]
|
|
88
|
+
|
|
88
89
|
for k in ("observer", "obsdate", "telescope", "telescopeposition"):
|
|
89
90
|
if k.startswith("telescope"):
|
|
90
91
|
if k == "telescope":
|
|
91
92
|
telescope["name"] = coord_dict[k]
|
|
92
93
|
elif k in coord_dict:
|
|
93
94
|
casa_pos = coord_dict[k]
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
95
|
+
telescope["direction"] = {
|
|
96
|
+
"attrs": {
|
|
97
|
+
"coordinate_system": "geocentric",
|
|
98
|
+
"frame": casa_pos["refer"],
|
|
99
|
+
"origin_object_name": "earth",
|
|
100
|
+
"type": "location",
|
|
101
|
+
"units": casa_pos["m0"]["unit"],
|
|
102
|
+
},
|
|
103
|
+
"data": [casa_pos["m0"]["value"], casa_pos["m1"]["value"]],
|
|
104
|
+
"dims": ["ellipsoid_dir_label"],
|
|
105
|
+
"coords": {
|
|
106
|
+
"ellipsoid_dir_label": {
|
|
107
|
+
"dims": ["ellipsoid_dir_label"],
|
|
108
|
+
"data": ["lon", "lat"],
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
}
|
|
112
|
+
telescope["distance"] = {
|
|
113
|
+
"attrs": {
|
|
114
|
+
"coordinate_system": "geocentric",
|
|
115
|
+
"frame": casa_pos["refer"],
|
|
116
|
+
"origin_object_name": "earth",
|
|
117
|
+
"type": "location",
|
|
118
|
+
"units": casa_pos["m2"]["unit"],
|
|
119
|
+
},
|
|
120
|
+
"data": [casa_pos["m2"]["value"]],
|
|
121
|
+
"dims": ["ellipsoid_dis_label"],
|
|
122
|
+
"coords": {
|
|
123
|
+
"ellipsoid_dis_label": {
|
|
124
|
+
"dims": ["ellipsoid_dis_label"],
|
|
125
|
+
"data": [
|
|
126
|
+
"dist",
|
|
127
|
+
],
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
}
|
|
131
|
+
|
|
116
132
|
"""
|
|
117
133
|
del (
|
|
118
134
|
telescope["position"]["refer"],
|
|
@@ -155,7 +171,7 @@ def _casa_image_to_xds_image_attrs(image: casa_image, history: bool = True) -> d
|
|
|
155
171
|
# associated with it.
|
|
156
172
|
# point_center = coord_dict["pointingcenter"]
|
|
157
173
|
attrs[_pointing_center] = make_skycoord_dict(
|
|
158
|
-
coord_dict["pointingcenter"]["value"].tolist(),
|
|
174
|
+
coord_dict["pointingcenter"]["value"].tolist(), "rad", frame
|
|
159
175
|
)
|
|
160
176
|
imageinfo = meta_dict["imageinfo"]
|
|
161
177
|
obj = "objectname"
|
|
@@ -221,7 +237,7 @@ def _add_time_attrs(xds: xr.Dataset, coord_dict: dict) -> xr.Dataset:
|
|
|
221
237
|
|
|
222
238
|
def _add_vel_attrs(xds: xr.Dataset, coord_dict: dict) -> xr.Dataset:
|
|
223
239
|
vel_coord = xds["velocity"]
|
|
224
|
-
meta = {"units":
|
|
240
|
+
meta = {"units": "m/s"}
|
|
225
241
|
for k in coord_dict:
|
|
226
242
|
if k.startswith("spectral"):
|
|
227
243
|
sd = coord_dict[k]
|
|
@@ -259,7 +275,7 @@ def _casa_image_to_xds_attrs(img_full_path: str) -> dict:
|
|
|
259
275
|
dir_dict = {}
|
|
260
276
|
|
|
261
277
|
dir_dict["reference"] = make_skycoord_dict(
|
|
262
|
-
data=[0.0, 0.0], units=
|
|
278
|
+
data=[0.0, 0.0], units="rad", frame=ap_system
|
|
263
279
|
)
|
|
264
280
|
if ap_equinox:
|
|
265
281
|
dir_dict["reference"]["attrs"]["equinox"] = ap_equinox
|
|
@@ -534,14 +550,14 @@ def _get_freq_values_attrs(
|
|
|
534
550
|
cdelt=wcs["cdelt"],
|
|
535
551
|
)
|
|
536
552
|
attrs["rest_frequency"] = make_quantity(sd["restfreq"], "Hz")
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
attrs["
|
|
553
|
+
attrs["type"] = "spectral_coord"
|
|
554
|
+
attrs["units"] = sd["unit"]
|
|
555
|
+
attrs["frame"] = sd["system"]
|
|
556
|
+
attrs["wave_units"] = sd["waveUnit"]
|
|
541
557
|
# attrs["crval"] = sd["wcs"]["crval"]
|
|
542
558
|
# attrs["cdelt"] = sd["wcs"]["cdelt"]
|
|
543
559
|
|
|
544
|
-
attrs["
|
|
560
|
+
attrs["reference_frequency"] = make_spectral_coord_reference_dict(
|
|
545
561
|
value=sd["wcs"]["crval"],
|
|
546
562
|
units=sd["unit"],
|
|
547
563
|
observer=sd["system"],
|
|
@@ -672,7 +688,7 @@ def _get_time_values_attrs(cimage_coord_dict: dict) -> Tuple[List[float], dict]:
|
|
|
672
688
|
attrs["type"] = "time"
|
|
673
689
|
attrs["scale"] = cimage_coord_dict["obsdate"]["refer"]
|
|
674
690
|
unit = cimage_coord_dict["obsdate"]["m0"]["unit"]
|
|
675
|
-
attrs["units"] = unit
|
|
691
|
+
attrs["units"] = unit
|
|
676
692
|
time_val = cimage_coord_dict["obsdate"]["m0"]["value"]
|
|
677
693
|
attrs["format"] = _get_time_format(time_val, unit)
|
|
678
694
|
return ([time_val], copy.deepcopy(attrs))
|
|
@@ -802,7 +818,7 @@ def _get_velocity_values_attrs(
|
|
|
802
818
|
if not attrs:
|
|
803
819
|
attrs["doppler_type"] = _doppler_types[0]
|
|
804
820
|
|
|
805
|
-
attrs["units"] =
|
|
821
|
+
attrs["units"] = "m/s"
|
|
806
822
|
attrs["type"] = "doppler"
|
|
807
823
|
return (
|
|
808
824
|
_compute_velocity_values(
|