xradio 0.0.48__tar.gz → 0.0.50__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.48/src/xradio.egg-info → xradio-0.0.50}/PKG-INFO +5 -4
- {xradio-0.0.48 → xradio-0.0.50}/pyproject.toml +5 -5
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/__init__.py +1 -0
- xradio-0.0.50/src/xradio/_utils/dict_helpers.py +81 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/image/_util/_casacore/common.py +0 -13
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/image/_util/_casacore/xds_from_casacore.py +102 -97
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/image/_util/_casacore/xds_to_casacore.py +36 -24
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/image/_util/_fits/xds_from_fits.py +81 -36
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/image/_util/_zarr/zarr_low_level.py +3 -3
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/image/_util/casacore.py +7 -5
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/image/_util/common.py +13 -26
- xradio-0.0.50/src/xradio/image/_util/image_factory.py +267 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/image/image.py +10 -59
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/__init__.py +11 -6
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_msv2/_tables/read.py +187 -46
- xradio-0.0.50/src/xradio/measurement_set/_utils/_msv2/_tables/table_query.py +46 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_msv2/conversion.py +352 -318
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_msv2/msv4_info_dicts.py +20 -17
- xradio-0.0.50/src/xradio/measurement_set/_utils/_msv2/optimised_functions.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/convert_msv2_to_processing_set.py +46 -6
- xradio-0.0.50/src/xradio/measurement_set/load_processing_set.py +188 -0
- xradio-0.0.50/src/xradio/measurement_set/measurement_set_xdt.py +319 -0
- xradio-0.0.50/src/xradio/measurement_set/open_processing_set.py +148 -0
- xradio-0.0.50/src/xradio/measurement_set/processing_set_xdt.py +1552 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/schema.py +201 -94
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/schema/bases.py +5 -1
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/schema/check.py +97 -5
- {xradio-0.0.48 → xradio-0.0.50/src/xradio.egg-info}/PKG-INFO +5 -4
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio.egg-info/SOURCES.txt +2 -2
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio.egg-info/requires.txt +1 -3
- xradio-0.0.48/src/xradio/_utils/dict_helpers.py +0 -14
- xradio-0.0.48/src/xradio/image/_util/__init__.py +0 -3
- xradio-0.0.48/src/xradio/image/_util/image_factory.py +0 -315
- xradio-0.0.48/src/xradio/measurement_set/_utils/_msv2/_tables/table_query.py +0 -24
- xradio-0.0.48/src/xradio/measurement_set/load_processing_set.py +0 -141
- xradio-0.0.48/src/xradio/measurement_set/measurement_set_xds.py +0 -117
- xradio-0.0.48/src/xradio/measurement_set/open_processing_set.py +0 -112
- xradio-0.0.48/src/xradio/measurement_set/processing_set.py +0 -803
- {xradio-0.0.48 → xradio-0.0.50}/LICENSE.txt +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/MANIFEST.in +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/README.md +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/setup.cfg +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/_utils/__init__.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/_utils/_casacore/tables.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/_utils/coord_math.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/_utils/list_and_array.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/_utils/schema.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/_utils/zarr/__init__.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/_utils/zarr/common.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/image/__init__.py +0 -0
- /xradio-0.0.48/src/xradio/measurement_set/_utils/_msv2/optimised_functions.py → /xradio-0.0.50/src/xradio/image/_util/__init__.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/image/_util/_casacore/__init__.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/image/_util/_zarr/common.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/image/_util/_zarr/xds_from_zarr.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/image/_util/_zarr/xds_to_zarr.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/image/_util/fits.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/image/_util/zarr.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/__init__.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_msv2/_tables/load.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_msv2/_tables/load_main_table.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_msv2/_tables/read_main_table.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_msv2/_tables/read_subtables.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_msv2/_tables/write.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_msv2/_tables/write_exp_api.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_msv2/chunks.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_msv2/create_antenna_xds.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_msv2/create_field_and_source_xds.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_msv2/descr.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_msv2/msv2_msv3.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_msv2/msv2_to_msv4_meta.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_msv2/msv4_sub_xdss.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_msv2/partition_queries.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_msv2/partitions.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_msv2/subtables.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_utils/cds.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_utils/partition_attrs.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_utils/stokes_types.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_utils/xds_helper.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_zarr/encoding.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_zarr/read.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/_zarr/write.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/msv2.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/measurement_set/_utils/zarr.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/schema/__init__.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/schema/dataclass.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/schema/metamodel.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/schema/typing.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/sphinx/__init__.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio/sphinx/schema_table.py +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio.egg-info/dependency_links.txt +0 -0
- {xradio-0.0.48 → xradio-0.0.50}/src/xradio.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: xradio
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.50
|
|
4
4
|
Summary: Xarray Radio Astronomy Data IO
|
|
5
5
|
Author-email: Jan-Willem Steeb <jsteeb@nrao.edu>
|
|
6
6
|
License: BSD 3-Clause License
|
|
@@ -37,7 +37,7 @@ License: BSD 3-Clause License
|
|
|
37
37
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
38
38
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
39
39
|
|
|
40
|
-
Requires-Python: <3.14,>=3.
|
|
40
|
+
Requires-Python: <3.14,>=3.11
|
|
41
41
|
Description-Content-Type: text/markdown
|
|
42
42
|
License-File: LICENSE.txt
|
|
43
43
|
Requires-Dist: astropy
|
|
@@ -55,8 +55,8 @@ Requires-Dist: xarray
|
|
|
55
55
|
Requires-Dist: zarr<3,>=2
|
|
56
56
|
Requires-Dist: pyarrow
|
|
57
57
|
Requires-Dist: python_casacore>=3.6.1; sys_platform != "darwin"
|
|
58
|
-
Requires-Dist: typing_extensions; python_version < "3.10"
|
|
59
58
|
Requires-Dist: typeguard
|
|
59
|
+
Requires-Dist: numcodecs<0.16
|
|
60
60
|
Provides-Extra: interactive
|
|
61
61
|
Requires-Dist: matplotlib; extra == "interactive"
|
|
62
62
|
Requires-Dist: prettytable; extra == "interactive"
|
|
@@ -74,6 +74,7 @@ Requires-Dist: sphinx-autosummary-accessors; extra == "docs"
|
|
|
74
74
|
Requires-Dist: sphinx_rtd_theme; extra == "docs"
|
|
75
75
|
Requires-Dist: twine; extra == "docs"
|
|
76
76
|
Requires-Dist: pandoc; extra == "docs"
|
|
77
|
+
Dynamic: license-file
|
|
77
78
|
|
|
78
79
|
# xradio
|
|
79
80
|
Xarray Radio Astronomy Data IO is still in development.
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "xradio"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.50"
|
|
4
4
|
description = " Xarray Radio Astronomy Data IO"
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "Jan-Willem Steeb", email="jsteeb@nrao.edu"},
|
|
7
7
|
]
|
|
8
8
|
license = {file = "LICENSE.txt"}
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
requires-python = ">= 3.
|
|
10
|
+
requires-python = ">= 3.11, < 3.14"
|
|
11
11
|
|
|
12
12
|
dependencies = [
|
|
13
13
|
'astropy',
|
|
@@ -25,8 +25,8 @@ dependencies = [
|
|
|
25
25
|
'zarr>=2,<3',
|
|
26
26
|
'pyarrow',
|
|
27
27
|
'python_casacore>=3.6.1; sys_platform != "darwin" ',
|
|
28
|
-
'
|
|
29
|
-
'
|
|
28
|
+
'typeguard',
|
|
29
|
+
'numcodecs<0.16'
|
|
30
30
|
]
|
|
31
31
|
|
|
32
32
|
[project.optional-dependencies]
|
|
@@ -65,5 +65,5 @@ pythonpath = [
|
|
|
65
65
|
|
|
66
66
|
[tool.black]
|
|
67
67
|
line-length = 88
|
|
68
|
-
target-version = ['
|
|
68
|
+
target-version = ['py312']
|
|
69
69
|
include = '\.py$'
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
def make_quantity(value, units: str, dims: list = []) -> dict:
|
|
2
|
+
"""
|
|
3
|
+
create a quantity dictionary given value and units
|
|
4
|
+
Parameters
|
|
5
|
+
----------
|
|
6
|
+
value : numeric or array of numerics
|
|
7
|
+
Quantity value
|
|
8
|
+
units: str
|
|
9
|
+
Quantity units
|
|
10
|
+
Returns
|
|
11
|
+
-------
|
|
12
|
+
dict
|
|
13
|
+
"""
|
|
14
|
+
u = units if isinstance(units, list) else [units]
|
|
15
|
+
return {"data": value, "dims": dims, "attrs": {"units": u, "type": "quantity"}}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def make_frequency_reference_dict(
|
|
19
|
+
value: float, units: str, observer: str = "lsrk"
|
|
20
|
+
) -> dict:
|
|
21
|
+
u = units if isinstance(units, list) else [units]
|
|
22
|
+
return {
|
|
23
|
+
"attrs": {"units": u, "observer": observer.lower(), "type": "frequency"},
|
|
24
|
+
"data": value,
|
|
25
|
+
"dims": [],
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def make_skycoord_dict(data: list[float], units: list[str], frame: str) -> dict:
|
|
30
|
+
return {
|
|
31
|
+
"attrs": {
|
|
32
|
+
"frame": frame.lower(),
|
|
33
|
+
"type": "sky_coord",
|
|
34
|
+
"units": units,
|
|
35
|
+
},
|
|
36
|
+
"data": data,
|
|
37
|
+
"dims": ["l", "m"],
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def make_time_measure_attrs(units=["s"], scale="utc", time_format="mjd") -> dict:
|
|
42
|
+
u = units if isinstance(units, list) else [units]
|
|
43
|
+
return {"units": u, "scale": scale, "format": time_format, "type": "time"}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def make_time_coord_attrs(units=["s"], scale="utc", time_format="mjd") -> dict:
|
|
47
|
+
"""
|
|
48
|
+
create a time measure dictionary given value and units
|
|
49
|
+
Parameters
|
|
50
|
+
----------
|
|
51
|
+
value : numeric or array of numerics
|
|
52
|
+
Time value
|
|
53
|
+
units: str
|
|
54
|
+
Time units
|
|
55
|
+
scale: str
|
|
56
|
+
Time scale
|
|
57
|
+
time_format: str
|
|
58
|
+
Time format
|
|
59
|
+
Returns
|
|
60
|
+
-------
|
|
61
|
+
dict
|
|
62
|
+
"""
|
|
63
|
+
x = make_time_measure_attrs(units, scale, time_format)
|
|
64
|
+
del x["type"]
|
|
65
|
+
return x
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _casacore_q_to_xradio_q(q: dict) -> dict:
|
|
69
|
+
"""
|
|
70
|
+
Convert a casacore quantity to an xradio quantity
|
|
71
|
+
"""
|
|
72
|
+
if isinstance(q, dict):
|
|
73
|
+
if "value" in q and "unit" in q:
|
|
74
|
+
return make_quantity(q["value"], q["unit"])
|
|
75
|
+
else:
|
|
76
|
+
p = {}
|
|
77
|
+
for k in q:
|
|
78
|
+
p[k] = _casacore_q_to_xradio_q(q[k])
|
|
79
|
+
return p
|
|
80
|
+
else:
|
|
81
|
+
raise ValueError(f"Cannot convert {q} to xradio quantity")
|
|
@@ -15,19 +15,6 @@ def _open_image_ro(infile: str) -> Generator[images.image, None, None]:
|
|
|
15
15
|
del image
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
"""
|
|
19
|
-
@contextmanager
|
|
20
|
-
def _open_image_rw(
|
|
21
|
-
infile: str, mask: str, shape: tuple
|
|
22
|
-
) -> Generator[images.image, None, None]:
|
|
23
|
-
image = images.image(infile, maskname=mask, shape=shape)
|
|
24
|
-
try:
|
|
25
|
-
yield image
|
|
26
|
-
finally:
|
|
27
|
-
del image
|
|
28
|
-
"""
|
|
29
|
-
|
|
30
|
-
|
|
31
18
|
@contextmanager
|
|
32
19
|
def _create_new_image(
|
|
33
20
|
outfile: str, shape: List[int], mask="", value="default"
|
|
@@ -31,16 +31,12 @@ from ..common import (
|
|
|
31
31
|
)
|
|
32
32
|
from ...._utils._casacore.tables import extract_table_attributes, open_table_ro
|
|
33
33
|
from xradio._utils.coord_math import _deg_to_rad
|
|
34
|
-
from xradio._utils.dict_helpers import
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
xds = _add_vel_attrs(xds, icoords)
|
|
41
|
-
xds = _add_lin_attrs(xds, icoords, dir_axes)
|
|
42
|
-
return xds
|
|
43
|
-
"""
|
|
34
|
+
from xradio._utils.dict_helpers import (
|
|
35
|
+
make_quantity,
|
|
36
|
+
make_frequency_reference_dict,
|
|
37
|
+
make_skycoord_dict,
|
|
38
|
+
_casacore_q_to_xradio_q,
|
|
39
|
+
)
|
|
44
40
|
|
|
45
41
|
|
|
46
42
|
def _add_lin_attrs(xds, coord_dict, dir_axes):
|
|
@@ -65,11 +61,16 @@ def _add_freq_attrs(xds, coord_dict):
|
|
|
65
61
|
sd = coord_dict[k]
|
|
66
62
|
meta["rest_frequency"] = make_quantity(sd["restfreq"], "Hz")
|
|
67
63
|
meta["type"] = "frequency"
|
|
68
|
-
meta["units"] = sd["unit"]
|
|
69
|
-
meta["frame"] = sd["system"]
|
|
64
|
+
# meta["units"] = sd["unit"]
|
|
65
|
+
# meta["frame"] = sd["system"]
|
|
70
66
|
meta["wave_unit"] = sd["waveUnit"]
|
|
71
|
-
meta["crval"] = sd["wcs"]["crval"]
|
|
72
|
-
meta["cdelt"] = sd["wcs"]["cdelt"]
|
|
67
|
+
# meta["crval"] = sd["wcs"]["crval"]
|
|
68
|
+
# meta["cdelt"] = sd["wcs"]["cdelt"]
|
|
69
|
+
meta["reference_value"] = make_frequency_reference_dict(
|
|
70
|
+
value=sd["wcs"]["crval"],
|
|
71
|
+
units=sd["unit"],
|
|
72
|
+
observer=sd["system"],
|
|
73
|
+
)
|
|
73
74
|
if not meta:
|
|
74
75
|
# this is the default frequency information CASA creates
|
|
75
76
|
meta = _default_freq_info()
|
|
@@ -108,7 +109,7 @@ def _add_sky_or_aperture(
|
|
|
108
109
|
|
|
109
110
|
|
|
110
111
|
def _get_time_format(value: float, unit: str) -> str:
|
|
111
|
-
if value >= 40000 and value <= 100000 and unit == "d":
|
|
112
|
+
if value >= 40000 and value <= 100000 and (unit == "d" or unit == ["d"]):
|
|
112
113
|
return "MJD"
|
|
113
114
|
else:
|
|
114
115
|
return ""
|
|
@@ -119,7 +120,7 @@ def _add_time_attrs(xds: xr.Dataset, coord_dict: dict) -> xr.Dataset:
|
|
|
119
120
|
meta = {}
|
|
120
121
|
meta["type"] = "time"
|
|
121
122
|
meta["scale"] = coord_dict["obsdate"]["refer"]
|
|
122
|
-
meta["units"] = coord_dict["obsdate"]["m0"]["unit"]
|
|
123
|
+
meta["units"] = [coord_dict["obsdate"]["m0"]["unit"]]
|
|
123
124
|
meta["format"] = _get_time_format(xds["time"][0], meta["units"])
|
|
124
125
|
xds["time"].attrs = copy.deepcopy(meta)
|
|
125
126
|
# xds['time'] = time_coord
|
|
@@ -128,7 +129,7 @@ def _add_time_attrs(xds: xr.Dataset, coord_dict: dict) -> xr.Dataset:
|
|
|
128
129
|
|
|
129
130
|
def _add_vel_attrs(xds: xr.Dataset, coord_dict: dict) -> xr.Dataset:
|
|
130
131
|
vel_coord = xds["velocity"]
|
|
131
|
-
meta = {"units": "m/s"}
|
|
132
|
+
meta = {"units": ["m/s"]}
|
|
132
133
|
for k in coord_dict:
|
|
133
134
|
if k.startswith("spectral"):
|
|
134
135
|
sd = coord_dict[k]
|
|
@@ -164,22 +165,24 @@ def _casa_image_to_xds_attrs(img_full_path: str, history: bool = True) -> dict:
|
|
|
164
165
|
casa_system = coord_dir_dict[system]
|
|
165
166
|
ap_system, ap_equinox = _convert_direction_system(casa_system, "native")
|
|
166
167
|
dir_dict = {}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
"
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
"
|
|
173
|
-
}
|
|
168
|
+
|
|
169
|
+
dir_dict["reference"] = make_skycoord_dict(
|
|
170
|
+
data=[0.0, 0.0], units=["rad", "rad"], frame=ap_system
|
|
171
|
+
)
|
|
172
|
+
if ap_equinox:
|
|
173
|
+
dir_dict["reference"]["attrs"]["equinox"] = ap_equinox
|
|
174
174
|
for i in range(2):
|
|
175
175
|
unit = u.Unit(_get_unit(coord_dir_dict["units"][i]))
|
|
176
176
|
q = coord_dir_dict["crval"][i] * unit
|
|
177
177
|
x = q.to("rad")
|
|
178
|
-
dir_dict["reference"]["
|
|
178
|
+
dir_dict["reference"]["data"][i] = x.value
|
|
179
179
|
k = "latpole"
|
|
180
180
|
if k in coord_dir_dict:
|
|
181
|
-
for j in (k, "
|
|
182
|
-
|
|
181
|
+
for j in (k, "lonpole"):
|
|
182
|
+
m = "longpole" if j == "lonpole" else j
|
|
183
|
+
dir_dict[j] = make_quantity(
|
|
184
|
+
value=coord_dir_dict[m] * _deg_to_rad, units="rad", dims=["l", "m"]
|
|
185
|
+
)
|
|
183
186
|
for j in ("pc", "projection_parameters", "projection"):
|
|
184
187
|
if j in coord_dir_dict:
|
|
185
188
|
dir_dict[j] = coord_dir_dict[j]
|
|
@@ -216,7 +219,8 @@ def _casa_image_to_xds_attrs(img_full_path: str, history: bool = True) -> dict:
|
|
|
216
219
|
)
|
|
217
220
|
elif k == "obsdate":
|
|
218
221
|
obsdate["scale"] = coord_dict[k]["refer"]
|
|
219
|
-
|
|
222
|
+
myu = coord_dict[k]["m0"]["unit"]
|
|
223
|
+
obsdate["units"] = myu if isinstance(myu, list) else [myu]
|
|
220
224
|
obsdate["value"] = coord_dict[k]["m0"]["value"]
|
|
221
225
|
obsdate["format"] = _get_time_format(obsdate["value"], obsdate["units"])
|
|
222
226
|
obsdate["type"] = "time"
|
|
@@ -225,12 +229,12 @@ def _casa_image_to_xds_attrs(img_full_path: str, history: bool = True) -> dict:
|
|
|
225
229
|
imageinfo = meta_dict["imageinfo"]
|
|
226
230
|
obj = "objectname"
|
|
227
231
|
attrs[_object_name] = imageinfo[obj] if obj in imageinfo else ""
|
|
228
|
-
attrs["beam"] = _get_beam(imageinfo)
|
|
229
232
|
attrs["user"] = meta_dict["miscinfo"]
|
|
230
233
|
defmask = "Image_defaultmask"
|
|
231
234
|
with open_table_ro(img_full_path) as casa_table:
|
|
235
|
+
# the actual mask is a data var and data var names are all caps by convention
|
|
232
236
|
attrs[_active_mask] = (
|
|
233
|
-
casa_table.getkeyword(defmask)
|
|
237
|
+
casa_table.getkeyword(defmask).upper()
|
|
234
238
|
if defmask in casa_table.keywordnames()
|
|
235
239
|
else None
|
|
236
240
|
)
|
|
@@ -280,15 +284,15 @@ def _casa_image_to_xds_coords(
|
|
|
280
284
|
coords = {}
|
|
281
285
|
coord_attrs = {}
|
|
282
286
|
(coords["time"], coord_attrs["time"]) = _get_time_values_attrs(coord_dict)
|
|
283
|
-
(coords["polarization"], coord_attrs["polarization"]) = _get_pol_values_attrs(
|
|
284
|
-
coord_dict
|
|
285
|
-
)
|
|
286
287
|
(coords["frequency"], coord_attrs["frequency"]) = _get_freq_values_attrs(
|
|
287
288
|
csys, shape
|
|
288
289
|
)
|
|
289
290
|
(velocity_vals, coord_attrs["velocity"]) = _get_velocity_values_attrs(
|
|
290
291
|
coord_dict, coords["frequency"]
|
|
291
292
|
)
|
|
293
|
+
(coords["polarization"], coord_attrs["polarization"]) = _get_pol_values_attrs(
|
|
294
|
+
coord_dict
|
|
295
|
+
)
|
|
292
296
|
coords["velocity"] = (["frequency"], velocity_vals)
|
|
293
297
|
if len(sphr_dims) > 0:
|
|
294
298
|
crpix = _flatten_list(csys.get_referencepixel())[::-1]
|
|
@@ -302,10 +306,6 @@ def _casa_image_to_xds_coords(
|
|
|
302
306
|
naxis=shape[idx], crval=0.0, crpix=crpix[idx], cdelt=delta
|
|
303
307
|
)
|
|
304
308
|
coord_attrs[c] = {
|
|
305
|
-
"crval": 0.0,
|
|
306
|
-
"cdelt": delta,
|
|
307
|
-
"units": "rad",
|
|
308
|
-
"type": "quantity",
|
|
309
309
|
"note": attr_note[c],
|
|
310
310
|
}
|
|
311
311
|
if do_sky_coords:
|
|
@@ -333,6 +333,7 @@ def _casa_image_to_xds_coords(
|
|
|
333
333
|
ret = _get_uv_values_attrs(coord_dict, axis_names, shape)
|
|
334
334
|
for z in ["u", "v"]:
|
|
335
335
|
coords[z], coord_attrs[z] = ret[z]
|
|
336
|
+
coords["beam_param"] = ["major", "minor", "pa"]
|
|
336
337
|
attrs["shape"] = shape
|
|
337
338
|
xds = xr.Dataset(coords=coords)
|
|
338
339
|
for c in coord_attrs.keys():
|
|
@@ -348,18 +349,18 @@ def _convert_direction_system(
|
|
|
348
349
|
if verbose:
|
|
349
350
|
logger.info(
|
|
350
351
|
f"J2000 found as {which} reference frame in CASA image "
|
|
351
|
-
'This corresponds to
|
|
352
|
+
'This corresponds to fk5(equinox="j2000") in astropy. '
|
|
352
353
|
"Metadata will be written appropriately"
|
|
353
354
|
)
|
|
354
|
-
return ("
|
|
355
|
+
return ("fk5", "j2000.0")
|
|
355
356
|
elif casa_system == "B1950":
|
|
356
357
|
if verbose:
|
|
357
358
|
logger.info(
|
|
358
359
|
f"B1950 found as {which} reference frame in CASA image "
|
|
359
|
-
'This corresponds to
|
|
360
|
+
'This corresponds to fk4(equinox="b1950") in astropy. '
|
|
360
361
|
"Metadata will be written appropriately"
|
|
361
362
|
)
|
|
362
|
-
return ("
|
|
363
|
+
return ("fk4", "b1950.0")
|
|
363
364
|
elif casa_system in ("GALACTIC", "ICRS"):
|
|
364
365
|
return (casa_system.lower(), None)
|
|
365
366
|
else:
|
|
@@ -382,14 +383,6 @@ def _flatten_list(list_of_lists: list) -> list:
|
|
|
382
383
|
return flat
|
|
383
384
|
|
|
384
385
|
|
|
385
|
-
def _get_beam(imageinfo: dict):
|
|
386
|
-
"""Returns None if no beam. Multiple beams are handled elsewhere"""
|
|
387
|
-
k = "restoringbeam"
|
|
388
|
-
if k in imageinfo and "major" in imageinfo[k]:
|
|
389
|
-
return _convert_beam_to_rad(imageinfo[k])
|
|
390
|
-
return None
|
|
391
|
-
|
|
392
|
-
|
|
393
386
|
def _get_chunk_list(
|
|
394
387
|
chunks: dict, coords: list, image_shape: Union[list, tuple]
|
|
395
388
|
) -> tuple:
|
|
@@ -510,12 +503,19 @@ def _get_freq_values_attrs(
|
|
|
510
503
|
cdelt=wcs["cdelt"],
|
|
511
504
|
)
|
|
512
505
|
attrs["rest_frequency"] = make_quantity(sd["restfreq"], "Hz")
|
|
513
|
-
attrs["type"] = "frequency"
|
|
514
|
-
attrs["units"] = sd["unit"]
|
|
515
|
-
attrs["frame"] = sd["system"]
|
|
506
|
+
# attrs["type"] = "frequency"
|
|
507
|
+
# attrs["units"] = sd["unit"]
|
|
508
|
+
# attrs["frame"] = sd["system"]
|
|
516
509
|
attrs["wave_unit"] = sd["waveUnit"]
|
|
517
|
-
attrs["crval"] = sd["wcs"]["crval"]
|
|
518
|
-
attrs["cdelt"] = sd["wcs"]["cdelt"]
|
|
510
|
+
# attrs["crval"] = sd["wcs"]["crval"]
|
|
511
|
+
# attrs["cdelt"] = sd["wcs"]["cdelt"]
|
|
512
|
+
|
|
513
|
+
attrs["reference_value"] = make_frequency_reference_dict(
|
|
514
|
+
value=sd["wcs"]["crval"],
|
|
515
|
+
units=sd["unit"],
|
|
516
|
+
observer=sd["system"],
|
|
517
|
+
)
|
|
518
|
+
|
|
519
519
|
attrs = copy.deepcopy(attrs)
|
|
520
520
|
break
|
|
521
521
|
else:
|
|
@@ -576,23 +576,33 @@ def _get_mask_names(infile: str) -> list:
|
|
|
576
576
|
return mymasks
|
|
577
577
|
|
|
578
578
|
|
|
579
|
-
def
|
|
580
|
-
"""Returns None if the image
|
|
581
|
-
|
|
582
|
-
|
|
579
|
+
def _get_beam(imageinfo: dict, nchan: int, npol: int) -> Union[np.ndarray, None]:
|
|
580
|
+
"""Returns None if the image has no beam(s)"""
|
|
581
|
+
x = ["perplanebeams", "restoringbeam"]
|
|
582
|
+
r = None
|
|
583
|
+
for z in x:
|
|
584
|
+
if z in imageinfo:
|
|
585
|
+
r = z
|
|
586
|
+
break
|
|
587
|
+
if r is None:
|
|
583
588
|
return None
|
|
584
|
-
beam = imageinfo[
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
589
|
+
beam = imageinfo[r]
|
|
590
|
+
beam_array = np.zeros([1, nchan, npol, 3])
|
|
591
|
+
if r == "perplanebeams":
|
|
592
|
+
for c in range(nchan):
|
|
593
|
+
for p in range(npol):
|
|
594
|
+
k = nchan * p + c
|
|
595
|
+
b = _casacore_q_to_xradio_q(beam["*" + str(k)])
|
|
596
|
+
beam_dict = _convert_beam_to_rad(b)
|
|
597
|
+
beam_array[0][c][p][0] = beam_dict["major"]["data"]
|
|
598
|
+
beam_array[0][c][p][1] = beam_dict["minor"]["data"]
|
|
599
|
+
beam_array[0][c][p][2] = beam_dict["pa"]["data"]
|
|
600
|
+
elif r == "restoringbeam":
|
|
601
|
+
b = _casacore_q_to_xradio_q(beam)
|
|
602
|
+
beam_dict = _convert_beam_to_rad(b)
|
|
603
|
+
beam_array[0, :, :, 0] = beam_dict["major"]["data"]
|
|
604
|
+
beam_array[0, :, :, 1] = beam_dict["minor"]["data"]
|
|
605
|
+
beam_array[0, :, :, 2] = beam_dict["pa"]["data"]
|
|
596
606
|
return beam_array
|
|
597
607
|
|
|
598
608
|
|
|
@@ -661,7 +671,7 @@ def _get_time_values_attrs(cimage_coord_dict: dict) -> Tuple[List[float], dict]:
|
|
|
661
671
|
attrs["type"] = "time"
|
|
662
672
|
attrs["scale"] = cimage_coord_dict["obsdate"]["refer"]
|
|
663
673
|
unit = cimage_coord_dict["obsdate"]["m0"]["unit"]
|
|
664
|
-
attrs["units"] = unit
|
|
674
|
+
attrs["units"] = unit if isinstance(unit, list) else [unit]
|
|
665
675
|
time_val = cimage_coord_dict["obsdate"]["m0"]["value"]
|
|
666
676
|
attrs["format"] = _get_time_format(time_val, unit)
|
|
667
677
|
return ([time_val], copy.deepcopy(attrs))
|
|
@@ -694,15 +704,15 @@ def _get_transpose_list(coords: coordinates.coordinatesystem) -> list:
|
|
|
694
704
|
not_covered.remove("v")
|
|
695
705
|
elif b.startswith("frequency"):
|
|
696
706
|
# transpose_list[2] = csys['pixelmap1'][0]
|
|
697
|
-
transpose_list[
|
|
707
|
+
transpose_list[1] = i
|
|
698
708
|
not_covered.remove("f")
|
|
699
709
|
elif b.startswith("stok"):
|
|
700
|
-
transpose_list[
|
|
710
|
+
transpose_list[2] = i
|
|
701
711
|
# transpose_list[1] = csys['pixelmap2'][0]
|
|
702
712
|
not_covered.remove("s")
|
|
703
713
|
else:
|
|
704
714
|
raise Exception(f"Unhandled axis name {c}")
|
|
705
|
-
h = {"l": 3, "m": 4, "u": 3, "v": 4, "f":
|
|
715
|
+
h = {"l": 3, "m": 4, "u": 3, "v": 4, "f": 1, "s": 2}
|
|
706
716
|
for p in not_covered:
|
|
707
717
|
transpose_list[h[p]] = last_axis
|
|
708
718
|
new_axes.append(last_axis)
|
|
@@ -773,7 +783,7 @@ def _get_velocity_values(coord_dict: dict, freq_values: list) -> list:
|
|
|
773
783
|
restfreq = coord_dict[k]["restfreq"]
|
|
774
784
|
break
|
|
775
785
|
return _compute_velocity_values(
|
|
776
|
-
restfreq=restfreq, freq_values=freq_values, doppler="
|
|
786
|
+
restfreq=restfreq, freq_values=freq_values, doppler="radio"
|
|
777
787
|
)
|
|
778
788
|
|
|
779
789
|
|
|
@@ -791,11 +801,11 @@ def _get_velocity_values_attrs(
|
|
|
791
801
|
if not attrs:
|
|
792
802
|
attrs["doppler_type"] = _doppler_types[0]
|
|
793
803
|
|
|
794
|
-
attrs["units"] = "m/s"
|
|
804
|
+
attrs["units"] = ["m/s"]
|
|
795
805
|
attrs["type"] = "doppler"
|
|
796
806
|
return (
|
|
797
807
|
_compute_velocity_values(
|
|
798
|
-
restfreq=restfreq, freq_values=freq_values, doppler="
|
|
808
|
+
restfreq=restfreq, freq_values=freq_values, doppler="radio"
|
|
799
809
|
),
|
|
800
810
|
copy.deepcopy(attrs),
|
|
801
811
|
)
|
|
@@ -804,25 +814,20 @@ def _get_velocity_values_attrs(
|
|
|
804
814
|
def _multibeam_array(
|
|
805
815
|
xds: xr.Dataset, img_full_path: str, as_dask_array: bool
|
|
806
816
|
) -> Union[xr.DataArray, None]:
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
)
|
|
822
|
-
xdb = xdb.rename("beam")
|
|
823
|
-
xdb = xdb.assign_coords(beam_param=["major", "minor", "pa"])
|
|
824
|
-
xdb.attrs["units"] = "rad"
|
|
825
|
-
return xdb
|
|
817
|
+
# the image may have multiple beams
|
|
818
|
+
with _open_image_ro(img_full_path) as casa_image:
|
|
819
|
+
imageinfo = casa_image.info()["imageinfo"]
|
|
820
|
+
mb = _get_beam(
|
|
821
|
+
imageinfo, nchan=xds.sizes["frequency"], npol=xds.sizes["polarization"]
|
|
822
|
+
)
|
|
823
|
+
if mb is not None:
|
|
824
|
+
if as_dask_array:
|
|
825
|
+
mb = da.array(mb)
|
|
826
|
+
xdb = xr.DataArray(mb, dims=["time", "frequency", "polarization", "beam_param"])
|
|
827
|
+
xdb = xdb.rename("BEAM")
|
|
828
|
+
xdb = xdb.assign_coords(beam_param=["major", "minor", "pa"])
|
|
829
|
+
xdb.attrs["units"] = "rad"
|
|
830
|
+
return xdb
|
|
826
831
|
else:
|
|
827
832
|
return None
|
|
828
833
|
|
|
@@ -1023,7 +1028,7 @@ def _read_image_array(
|
|
|
1023
1028
|
:type blc: a type that is convertable to a list via list(blc)
|
|
1024
1029
|
:param trc: top right corner, given in the axes ordering of the input image.None=>image shape - 1
|
|
1025
1030
|
:type trc: a type that is convertable to a list via list(trc)
|
|
1026
|
-
:return: Dask array in time,
|
|
1031
|
+
:return: Dask array in time, frequency, polarization, l, m order
|
|
1027
1032
|
:rtype: dask.array
|
|
1028
1033
|
|
|
1029
1034
|
"""
|