xradio 0.0.50__tar.gz → 0.0.52__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.50/src/xradio.egg-info → xradio-0.0.52}/PKG-INFO +10 -4
- xradio-0.0.52/README.md +27 -0
- {xradio-0.0.50 → xradio-0.0.52}/pyproject.toml +5 -2
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/_utils/dict_helpers.py +24 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/_utils/schema.py +2 -2
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/image/_util/_casacore/xds_from_casacore.py +116 -69
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/image/_util/_casacore/xds_to_casacore.py +51 -32
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/image/_util/_fits/xds_from_fits.py +43 -52
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/image/_util/_zarr/common.py +1 -1
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/image/_util/_zarr/xds_from_zarr.py +37 -20
- xradio-0.0.52/src/xradio/image/_util/_zarr/xds_to_zarr.py +48 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/image/_util/casacore.py +6 -3
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/conversion.py +3 -3
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/create_antenna_xds.py +5 -5
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/create_field_and_source_xds.py +11 -3
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/msv4_sub_xdss.py +151 -13
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/processing_set_xdt.py +146 -31
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/schema.py +40 -25
- {xradio-0.0.50 → xradio-0.0.52/src/xradio.egg-info}/PKG-INFO +10 -4
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio.egg-info/requires.txt +1 -1
- xradio-0.0.50/README.md +0 -21
- xradio-0.0.50/src/xradio/image/_util/_zarr/xds_to_zarr.py +0 -49
- {xradio-0.0.50 → xradio-0.0.52}/LICENSE.txt +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/MANIFEST.in +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/setup.cfg +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/__init__.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/_utils/__init__.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/_utils/_casacore/tables.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/_utils/coord_math.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/_utils/list_and_array.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/_utils/zarr/__init__.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/_utils/zarr/common.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/image/__init__.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/image/_util/__init__.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/image/_util/_casacore/__init__.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/image/_util/_casacore/common.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/image/_util/_zarr/zarr_low_level.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/image/_util/common.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/image/_util/fits.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/image/_util/image_factory.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/image/_util/zarr.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/image/image.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/__init__.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/__init__.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/_tables/load.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/_tables/load_main_table.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/_tables/read.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/_tables/read_main_table.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/_tables/read_subtables.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/_tables/table_query.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/_tables/write.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/_tables/write_exp_api.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/chunks.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/descr.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/msv2_msv3.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/msv2_to_msv4_meta.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/msv4_info_dicts.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/optimised_functions.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/partition_queries.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/partitions.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_msv2/subtables.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_utils/cds.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_utils/partition_attrs.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_utils/stokes_types.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_utils/xds_helper.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_zarr/encoding.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_zarr/read.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/_zarr/write.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/msv2.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/_utils/zarr.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/convert_msv2_to_processing_set.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/load_processing_set.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/measurement_set_xdt.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/measurement_set/open_processing_set.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/schema/__init__.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/schema/bases.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/schema/check.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/schema/dataclass.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/schema/metamodel.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/schema/typing.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/sphinx/__init__.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio/sphinx/schema_table.py +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio.egg-info/SOURCES.txt +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio.egg-info/dependency_links.txt +0 -0
- {xradio-0.0.50 → xradio-0.0.52}/src/xradio.egg-info/top_level.txt +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xradio
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.52
|
|
4
4
|
Summary: Xarray Radio Astronomy Data IO
|
|
5
|
-
Author-email: Jan-Willem Steeb <jsteeb@nrao.edu>
|
|
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
|
|
7
7
|
|
|
8
8
|
All works in this repository are copyrighted 2024.
|
|
@@ -43,7 +43,7 @@ License-File: LICENSE.txt
|
|
|
43
43
|
Requires-Dist: astropy
|
|
44
44
|
Requires-Dist: dask
|
|
45
45
|
Requires-Dist: distributed
|
|
46
|
-
Requires-Dist: toolviper
|
|
46
|
+
Requires-Dist: toolviper>=0.0.11
|
|
47
47
|
Requires-Dist: numba>=0.57.0
|
|
48
48
|
Requires-Dist: numpy
|
|
49
49
|
Requires-Dist: pytest
|
|
@@ -79,7 +79,13 @@ Dynamic: license-file
|
|
|
79
79
|
# xradio
|
|
80
80
|
Xarray Radio Astronomy Data IO is still in development.
|
|
81
81
|
|
|
82
|
-
[](https://www.python.org/downloads/release/python-3130/)
|
|
83
|
+
[](https://github.com/casangi/xradio/actions/workflows/python-testing-linux.yml?query=branch%3Amain)
|
|
84
|
+
[](https://github.com/casangi/xradio/actions/workflows/python-testing-macos.yml?query=branch%3Amain)
|
|
85
|
+
[](https://github.com/casangi/xradio/actions/workflows/run-ipynb.yml?query=branch%3Amain)
|
|
86
|
+
[](https://codecov.io/gh/casangi/xradio/branch/main/xradio)
|
|
87
|
+
[](https://xradio.readthedocs.io)
|
|
88
|
+
[](https://pypi.python.org/pypi/xradio/)
|
|
83
89
|
|
|
84
90
|
# Installing
|
|
85
91
|
It is recommended to use the conda environment manager from [miniforge](https://github.com/conda-forge/miniforge) to create a clean, self-contained runtime where XRADIO and all its dependencies can be installed:
|
xradio-0.0.52/README.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# xradio
|
|
2
|
+
Xarray Radio Astronomy Data IO is still in development.
|
|
3
|
+
|
|
4
|
+
[](https://www.python.org/downloads/release/python-3130/)
|
|
5
|
+
[](https://github.com/casangi/xradio/actions/workflows/python-testing-linux.yml?query=branch%3Amain)
|
|
6
|
+
[](https://github.com/casangi/xradio/actions/workflows/python-testing-macos.yml?query=branch%3Amain)
|
|
7
|
+
[](https://github.com/casangi/xradio/actions/workflows/run-ipynb.yml?query=branch%3Amain)
|
|
8
|
+
[](https://codecov.io/gh/casangi/xradio/branch/main/xradio)
|
|
9
|
+
[](https://xradio.readthedocs.io)
|
|
10
|
+
[](https://pypi.python.org/pypi/xradio/)
|
|
11
|
+
|
|
12
|
+
# Installing
|
|
13
|
+
It is recommended to use the conda environment manager from [miniforge](https://github.com/conda-forge/miniforge) to create a clean, self-contained runtime where XRADIO and all its dependencies can be installed:
|
|
14
|
+
```sh
|
|
15
|
+
conda create --name xradio python=3.12 --no-default-packages
|
|
16
|
+
conda activate xradio
|
|
17
|
+
```
|
|
18
|
+
> 📝 On macOS it is required to pre-install `python-casacore` using `conda install -c conda-forge python-casacore`.
|
|
19
|
+
|
|
20
|
+
XRADIO can now be installed using:
|
|
21
|
+
```sh
|
|
22
|
+
pip install xradio
|
|
23
|
+
```
|
|
24
|
+
This will also install the minimal dependencies for XRADIO. To install the minimal dependencies and the interactive components (JupyterLab) use:
|
|
25
|
+
```sh
|
|
26
|
+
pip install "xradio[interactive]"
|
|
27
|
+
```
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "xradio"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.52"
|
|
4
4
|
description = " Xarray Radio Astronomy Data IO"
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "Jan-Willem Steeb", email="jsteeb@nrao.edu"},
|
|
7
|
+
{name = "Federico Montesino Pouzols", email="pouzols@eso.edu"},
|
|
8
|
+
{name = "Dave Mehringer", email="dmehring@nrao.edu"},
|
|
9
|
+
{name = "Peter Wortmann", email="peter.wortmann@skao.int"}
|
|
7
10
|
]
|
|
8
11
|
license = {file = "LICENSE.txt"}
|
|
9
12
|
readme = "README.md"
|
|
@@ -13,7 +16,7 @@ dependencies = [
|
|
|
13
16
|
'astropy',
|
|
14
17
|
'dask',
|
|
15
18
|
'distributed',
|
|
16
|
-
'toolviper',
|
|
19
|
+
'toolviper>=0.0.11',
|
|
17
20
|
'numba>=0.57.0',
|
|
18
21
|
'numpy',
|
|
19
22
|
'pytest',
|
|
@@ -43,6 +43,30 @@ def make_time_measure_attrs(units=["s"], scale="utc", time_format="mjd") -> dict
|
|
|
43
43
|
return {"units": u, "scale": scale, "format": time_format, "type": "time"}
|
|
44
44
|
|
|
45
45
|
|
|
46
|
+
def make_time_measure_dict(data, 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 = {}
|
|
64
|
+
x["attrs"] = make_time_measure_attrs(units, scale, time_format)
|
|
65
|
+
x["data"] = data
|
|
66
|
+
x["dims"] = []
|
|
67
|
+
return x
|
|
68
|
+
|
|
69
|
+
|
|
46
70
|
def make_time_coord_attrs(units=["s"], scale="utc", time_format="mjd") -> dict:
|
|
47
71
|
"""
|
|
48
72
|
create a time measure dictionary given value and units
|
|
@@ -190,14 +190,14 @@ casacore_to_msv4_measure_type = {
|
|
|
190
190
|
"LSRK": "lsrk",
|
|
191
191
|
"LSRD": "lsrd",
|
|
192
192
|
"BARY": "BARY",
|
|
193
|
-
"GEO": "
|
|
193
|
+
"GEO": "gcrs",
|
|
194
194
|
"TOPO": "TOPO",
|
|
195
195
|
}, # The frames/observer we are not sure if/how to translate to astropy are uppercase
|
|
196
196
|
},
|
|
197
197
|
"position": {
|
|
198
198
|
"type": "location",
|
|
199
199
|
"Ref": "frame",
|
|
200
|
-
"Ref_map": {"ITRF": "
|
|
200
|
+
"Ref_map": {"ITRF": "ITRS"},
|
|
201
201
|
},
|
|
202
202
|
"uvw": {
|
|
203
203
|
"type": "uvw",
|
|
@@ -10,7 +10,7 @@ import numpy as np
|
|
|
10
10
|
import xarray as xr
|
|
11
11
|
from astropy import units as u
|
|
12
12
|
from casacore import tables
|
|
13
|
-
from casacore.images import coordinates
|
|
13
|
+
from casacore.images import coordinates, image as casa_image
|
|
14
14
|
|
|
15
15
|
from .common import (
|
|
16
16
|
_active_mask,
|
|
@@ -32,10 +32,11 @@ from ..common import (
|
|
|
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
34
|
from xradio._utils.dict_helpers import (
|
|
35
|
-
|
|
35
|
+
_casacore_q_to_xradio_q,
|
|
36
36
|
make_frequency_reference_dict,
|
|
37
|
+
make_quantity,
|
|
37
38
|
make_skycoord_dict,
|
|
38
|
-
|
|
39
|
+
make_time_measure_dict,
|
|
39
40
|
)
|
|
40
41
|
|
|
41
42
|
|
|
@@ -89,19 +90,126 @@ def _add_mask(
|
|
|
89
90
|
return xds
|
|
90
91
|
|
|
91
92
|
|
|
93
|
+
def _casa_image_to_xds_image_attrs(image: casa_image, history: bool = True) -> dict:
|
|
94
|
+
"""
|
|
95
|
+
get the image attributes from the casacoreimage object
|
|
96
|
+
"""
|
|
97
|
+
meta_dict = image.info()
|
|
98
|
+
coord_dict = copy.deepcopy(meta_dict["coordinates"])
|
|
99
|
+
attrs = {}
|
|
100
|
+
attrs[_image_type] = image.info()["imageinfo"]["imagetype"]
|
|
101
|
+
attrs["units"] = image.unit()
|
|
102
|
+
attrs["telescope"] = {}
|
|
103
|
+
telescope = attrs["telescope"]
|
|
104
|
+
for k in ("observer", "obsdate", "telescope", "telescopeposition"):
|
|
105
|
+
if k.startswith("telescope"):
|
|
106
|
+
if k == "telescope":
|
|
107
|
+
telescope["name"] = coord_dict[k]
|
|
108
|
+
elif k in coord_dict:
|
|
109
|
+
casa_pos = coord_dict[k]
|
|
110
|
+
location = {}
|
|
111
|
+
loc_attrs = {}
|
|
112
|
+
loc_attrs["type"] = "location"
|
|
113
|
+
loc_attrs["frame"] = casa_pos["refer"]
|
|
114
|
+
"""
|
|
115
|
+
if casa_pos["refer"] == "ITRF":
|
|
116
|
+
loc_attrs["ellipsoid"] = "GRS80"
|
|
117
|
+
"""
|
|
118
|
+
loc_attrs["units"] = [
|
|
119
|
+
casa_pos["m0"]["unit"],
|
|
120
|
+
casa_pos["m1"]["unit"],
|
|
121
|
+
casa_pos["m2"]["unit"],
|
|
122
|
+
]
|
|
123
|
+
loc_attrs["coordinate_system"] = "geocentric"
|
|
124
|
+
loc_attrs["origin_object_name"] = "earth"
|
|
125
|
+
location["attrs"] = loc_attrs
|
|
126
|
+
location["data"] = [
|
|
127
|
+
casa_pos["m0"]["value"],
|
|
128
|
+
casa_pos["m1"]["value"],
|
|
129
|
+
casa_pos["m2"]["value"],
|
|
130
|
+
]
|
|
131
|
+
telescope["location"] = location
|
|
132
|
+
"""
|
|
133
|
+
del (
|
|
134
|
+
telescope["position"]["refer"],
|
|
135
|
+
telescope["position"]["m0"],
|
|
136
|
+
telescope["position"]["m1"],
|
|
137
|
+
telescope["position"]["m2"],
|
|
138
|
+
)
|
|
139
|
+
"""
|
|
140
|
+
elif k == "obsdate":
|
|
141
|
+
obsdate = coord_dict[k]
|
|
142
|
+
"""
|
|
143
|
+
o_attrs = {"type": "time"}
|
|
144
|
+
o_attrs["scale"] = coord_dict[k]["refer"]
|
|
145
|
+
myu = coord_dict[k]["m0"]["unit"]
|
|
146
|
+
o_attrs["units"] = myu if isinstance(myu, list) else [myu]
|
|
147
|
+
o_attrs["format"] = _get_time_format(m0["value"], m0["unit"])
|
|
148
|
+
o_date = {}
|
|
149
|
+
o_date["attrs"] = o_attrs
|
|
150
|
+
"""
|
|
151
|
+
m0 = obsdate["m0"]
|
|
152
|
+
attrs["obsdate"] = make_time_measure_dict(
|
|
153
|
+
data=m0["value"],
|
|
154
|
+
units=m0["unit"],
|
|
155
|
+
scale=obsdate["refer"],
|
|
156
|
+
time_format=_get_time_format(m0["value"], m0["unit"]),
|
|
157
|
+
)
|
|
158
|
+
else:
|
|
159
|
+
attrs[k] = coord_dict[k] if k in coord_dict else ""
|
|
160
|
+
dir_key = next((k for k in coord_dict if k.startswith("direction")), None)
|
|
161
|
+
if dir_key:
|
|
162
|
+
frame, eqnx = _convert_direction_system(coord_dict[dir_key]["system"], "system")
|
|
163
|
+
else:
|
|
164
|
+
frame = "icrs"
|
|
165
|
+
logger.warning(
|
|
166
|
+
"No direction coordinate found from which "
|
|
167
|
+
"to get pointing center frame. Assuming ICRS"
|
|
168
|
+
)
|
|
169
|
+
# it looks like the pointing center is always in radians in a casa image coord system dict
|
|
170
|
+
# note that in a casa image, the pointing center does not explicitly have a reference frame
|
|
171
|
+
# associated with it.
|
|
172
|
+
# point_center = coord_dict["pointingcenter"]
|
|
173
|
+
attrs[_pointing_center] = make_skycoord_dict(
|
|
174
|
+
coord_dict["pointingcenter"]["value"].tolist(), ["rad", "rad"], frame
|
|
175
|
+
)
|
|
176
|
+
imageinfo = meta_dict["imageinfo"]
|
|
177
|
+
obj = "objectname"
|
|
178
|
+
attrs[_object_name] = imageinfo[obj] if obj in imageinfo else ""
|
|
179
|
+
attrs["user"] = meta_dict["miscinfo"]
|
|
180
|
+
defmask = "Image_defaultmask"
|
|
181
|
+
with open_table_ro(image.name()) as casa_table:
|
|
182
|
+
# the actual mask is a data var and data var names are all caps by convention
|
|
183
|
+
attrs[_active_mask] = (
|
|
184
|
+
casa_table.getkeyword(defmask).upper()
|
|
185
|
+
if defmask in casa_table.keywordnames()
|
|
186
|
+
else None
|
|
187
|
+
)
|
|
188
|
+
attrs["description"] = None
|
|
189
|
+
# if also loading history, put it as another xds in the image attrs
|
|
190
|
+
if history:
|
|
191
|
+
htable = os.sep.join([os.path.abspath(image.name()), "logtable"])
|
|
192
|
+
if os.path.isdir(htable):
|
|
193
|
+
attrs["history"] = read_generic_table(htable)
|
|
194
|
+
else:
|
|
195
|
+
logger.warning(
|
|
196
|
+
f"Unable to find history table {htable}. History will not be included"
|
|
197
|
+
)
|
|
198
|
+
return attrs
|
|
199
|
+
|
|
200
|
+
|
|
92
201
|
def _add_sky_or_aperture(
|
|
93
202
|
xds: xr.Dataset,
|
|
94
203
|
ary: Union[np.ndarray, da.array],
|
|
95
204
|
dimorder: list,
|
|
96
205
|
img_full_path: str,
|
|
97
206
|
has_sph_dims: bool,
|
|
207
|
+
history: bool,
|
|
98
208
|
) -> xr.Dataset:
|
|
99
209
|
xda = xr.DataArray(ary, dims=dimorder).astype(ary.dtype)
|
|
100
210
|
with _open_image_ro(img_full_path) as casa_image:
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
xda.attrs[_image_type] = image_type
|
|
104
|
-
xda.attrs["units"] = unit
|
|
211
|
+
xda.attrs = _casa_image_to_xds_image_attrs(casa_image, history)
|
|
212
|
+
# xds.attrs = attrs
|
|
105
213
|
name = "SKY" if has_sph_dims else "APERTURE"
|
|
106
214
|
xda = xda.rename(name)
|
|
107
215
|
xds[xda.name] = xda
|
|
@@ -143,7 +251,7 @@ def _add_vel_attrs(xds: xr.Dataset, coord_dict: dict) -> xr.Dataset:
|
|
|
143
251
|
return xds
|
|
144
252
|
|
|
145
253
|
|
|
146
|
-
def _casa_image_to_xds_attrs(img_full_path: str
|
|
254
|
+
def _casa_image_to_xds_attrs(img_full_path: str) -> dict:
|
|
147
255
|
"""
|
|
148
256
|
Get the xds level attribut/es as a python dictionary
|
|
149
257
|
"""
|
|
@@ -187,67 +295,6 @@ def _casa_image_to_xds_attrs(img_full_path: str, history: bool = True) -> dict:
|
|
|
187
295
|
if j in coord_dir_dict:
|
|
188
296
|
dir_dict[j] = coord_dir_dict[j]
|
|
189
297
|
attrs["direction"] = dir_dict
|
|
190
|
-
attrs["telescope"] = {}
|
|
191
|
-
telescope = attrs["telescope"]
|
|
192
|
-
attrs["obsdate"] = {"type": "time"}
|
|
193
|
-
obsdate = attrs["obsdate"]
|
|
194
|
-
attrs[_pointing_center] = coord_dict["pointingcenter"].copy()
|
|
195
|
-
for k in ("observer", "obsdate", "telescope", "telescopeposition"):
|
|
196
|
-
if k.startswith("telescope"):
|
|
197
|
-
if k == "telescope":
|
|
198
|
-
telescope["name"] = coord_dict[k]
|
|
199
|
-
elif k in coord_dict:
|
|
200
|
-
telescope["position"] = coord_dict[k]
|
|
201
|
-
telescope["position"]["ellipsoid"] = telescope["position"]["refer"]
|
|
202
|
-
if telescope["position"]["refer"] == "ITRF":
|
|
203
|
-
telescope["position"]["ellipsoid"] = "GRS80"
|
|
204
|
-
telescope["position"]["units"] = [
|
|
205
|
-
telescope["position"]["m0"]["unit"],
|
|
206
|
-
telescope["position"]["m1"]["unit"],
|
|
207
|
-
telescope["position"]["m2"]["unit"],
|
|
208
|
-
]
|
|
209
|
-
telescope["position"]["value"] = [
|
|
210
|
-
telescope["position"]["m0"]["value"],
|
|
211
|
-
telescope["position"]["m1"]["value"],
|
|
212
|
-
telescope["position"]["m2"]["value"],
|
|
213
|
-
]
|
|
214
|
-
del (
|
|
215
|
-
telescope["position"]["refer"],
|
|
216
|
-
telescope["position"]["m0"],
|
|
217
|
-
telescope["position"]["m1"],
|
|
218
|
-
telescope["position"]["m2"],
|
|
219
|
-
)
|
|
220
|
-
elif k == "obsdate":
|
|
221
|
-
obsdate["scale"] = coord_dict[k]["refer"]
|
|
222
|
-
myu = coord_dict[k]["m0"]["unit"]
|
|
223
|
-
obsdate["units"] = myu if isinstance(myu, list) else [myu]
|
|
224
|
-
obsdate["value"] = coord_dict[k]["m0"]["value"]
|
|
225
|
-
obsdate["format"] = _get_time_format(obsdate["value"], obsdate["units"])
|
|
226
|
-
obsdate["type"] = "time"
|
|
227
|
-
else:
|
|
228
|
-
attrs[k] = coord_dict[k] if k in coord_dict else ""
|
|
229
|
-
imageinfo = meta_dict["imageinfo"]
|
|
230
|
-
obj = "objectname"
|
|
231
|
-
attrs[_object_name] = imageinfo[obj] if obj in imageinfo else ""
|
|
232
|
-
attrs["user"] = meta_dict["miscinfo"]
|
|
233
|
-
defmask = "Image_defaultmask"
|
|
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
|
|
236
|
-
attrs[_active_mask] = (
|
|
237
|
-
casa_table.getkeyword(defmask).upper()
|
|
238
|
-
if defmask in casa_table.keywordnames()
|
|
239
|
-
else None
|
|
240
|
-
)
|
|
241
|
-
attrs["description"] = None
|
|
242
|
-
# if also loading history, put it as another xds in the attrs
|
|
243
|
-
if history:
|
|
244
|
-
htable = os.sep.join([img_full_path, "logtable"])
|
|
245
|
-
if os.path.isdir(htable):
|
|
246
|
-
attrs["history"] = read_generic_table(htable)
|
|
247
|
-
else:
|
|
248
|
-
logger.warning(
|
|
249
|
-
f"Unable to find history table {htable}. History will not be included"
|
|
250
|
-
)
|
|
251
298
|
return copy.deepcopy(attrs)
|
|
252
299
|
|
|
253
300
|
|
|
@@ -19,12 +19,16 @@ def _compute_direction_dict(xds: xr.Dataset) -> dict:
|
|
|
19
19
|
"""
|
|
20
20
|
direction = {}
|
|
21
21
|
xds_dir = xds.attrs["direction"]
|
|
22
|
+
direction["_axes_sizes"] = np.array(
|
|
23
|
+
[xds.sizes[dim] for dim in ("l", "m")], dtype=np.int32
|
|
24
|
+
)
|
|
25
|
+
direction["_image_axes"] = np.array([2, 3], dtype=np.int32)
|
|
22
26
|
direction["system"] = xds_dir["reference"]["attrs"]["equinox"].upper()
|
|
23
27
|
if direction["system"] == "J2000.0":
|
|
24
28
|
direction["system"] = "J2000"
|
|
25
29
|
direction["projection"] = xds_dir["projection"]
|
|
26
30
|
direction["projection_parameters"] = xds_dir["projection_parameters"]
|
|
27
|
-
direction["units"] =
|
|
31
|
+
direction["units"] = xds_dir["reference"]["attrs"]["units"]
|
|
28
32
|
direction["crval"] = np.array(xds_dir["reference"]["data"])
|
|
29
33
|
direction["cdelt"] = np.array((xds.l[1] - xds.l[0], xds.m[1] - xds.m[0]))
|
|
30
34
|
direction["crpix"] = _compute_sky_reference_pixel(xds)
|
|
@@ -34,9 +38,9 @@ def _compute_direction_dict(xds: xr.Dataset) -> dict:
|
|
|
34
38
|
for s in ["longpole", "latpole"]:
|
|
35
39
|
m = "lonpole" if s == "longpole" else s
|
|
36
40
|
# lonpole, latpole are numerical values in degrees in casa images
|
|
37
|
-
direction[s] =
|
|
38
|
-
str(xds_dir[m]["data"]) + xds_dir[m]["attrs"]["units"][0]
|
|
39
|
-
)
|
|
41
|
+
direction[s] = float(
|
|
42
|
+
Angle(str(xds_dir[m]["data"]) + xds_dir[m]["attrs"]["units"][0]).deg
|
|
43
|
+
)
|
|
40
44
|
return direction
|
|
41
45
|
|
|
42
46
|
|
|
@@ -69,6 +73,8 @@ def _compute_spectral_dict(xds: xr.Dataset) -> dict:
|
|
|
69
73
|
for a CASA image coordinate system
|
|
70
74
|
"""
|
|
71
75
|
spec = {}
|
|
76
|
+
spec["_axes_sizes"] = np.array([xds.sizes["frequency"]], dtype=np.int32)
|
|
77
|
+
spec["_image_axes"] = np.array([0], dtype=np.int32)
|
|
72
78
|
spec["formatUnit"] = ""
|
|
73
79
|
spec["name"] = "Frequency"
|
|
74
80
|
# spec["nativeType"] = _native_types.index(xds.frequency.attrs["native_type"])
|
|
@@ -76,7 +82,7 @@ def _compute_spectral_dict(xds: xr.Dataset) -> dict:
|
|
|
76
82
|
spec["nativeType"] = 0
|
|
77
83
|
spec["restfreq"] = xds.frequency.attrs["rest_frequency"]["data"]
|
|
78
84
|
# spec["restfreqs"] = copy.deepcopy(xds.frequency.attrs["restfreqs"]["value"])
|
|
79
|
-
spec["restfreqs"] = [spec["restfreq"]]
|
|
85
|
+
spec["restfreqs"] = np.array([spec["restfreq"]])
|
|
80
86
|
spec["system"] = xds.frequency.attrs["reference_value"]["attrs"]["observer"].upper()
|
|
81
87
|
u = xds.frequency.attrs["reference_value"]["attrs"]["units"]
|
|
82
88
|
spec["unit"] = u if isinstance(u, str) else u[0]
|
|
@@ -88,53 +94,65 @@ def _compute_spectral_dict(xds: xr.Dataset) -> dict:
|
|
|
88
94
|
wcs = {}
|
|
89
95
|
wcs["ctype"] = "FREQ"
|
|
90
96
|
wcs["pc"] = 1.0
|
|
91
|
-
wcs["crval"] = xds.frequency.attrs["reference_value"]["data"]
|
|
92
|
-
wcs["cdelt"] = xds.frequency.values[1] - xds.frequency.values[0]
|
|
93
|
-
wcs["crpix"] = (wcs["crval"] - xds.frequency.values[0]) / wcs["cdelt"]
|
|
97
|
+
wcs["crval"] = float(xds.frequency.attrs["reference_value"]["data"])
|
|
98
|
+
wcs["cdelt"] = float(xds.frequency.values[1] - xds.frequency.values[0])
|
|
99
|
+
wcs["crpix"] = float((wcs["crval"] - xds.frequency.values[0]) / wcs["cdelt"])
|
|
94
100
|
spec["wcs"] = wcs
|
|
95
101
|
return spec
|
|
96
102
|
|
|
97
103
|
|
|
98
104
|
def _coord_dict_from_xds(xds: xr.Dataset) -> dict:
|
|
99
105
|
coord = {}
|
|
100
|
-
|
|
101
|
-
|
|
106
|
+
sky_ap = "SKY" if "SKY" in xds.data_vars else "APERTURE"
|
|
107
|
+
if "telescope" in xds[sky_ap].attrs:
|
|
108
|
+
tel = xds[sky_ap].attrs["telescope"]
|
|
109
|
+
if "name" in tel:
|
|
110
|
+
coord["telescope"] = xds[sky_ap].attrs["telescope"]["name"]
|
|
111
|
+
if "location" in tel:
|
|
112
|
+
xds_telloc = tel["location"]
|
|
113
|
+
telloc = {}
|
|
114
|
+
telloc["refer"] = xds_telloc["attrs"]["frame"]
|
|
115
|
+
if telloc["refer"] == "GRS80":
|
|
116
|
+
telloc["refer"] = "ITRF"
|
|
117
|
+
for i in range(3):
|
|
118
|
+
telloc[f"m{i}"] = {
|
|
119
|
+
"unit": xds_telloc["attrs"]["units"][i],
|
|
120
|
+
"value": xds_telloc["data"][i],
|
|
121
|
+
}
|
|
122
|
+
telloc["type"] = "position"
|
|
123
|
+
coord["telescopeposition"] = telloc
|
|
124
|
+
if "observer" in xds[sky_ap].attrs:
|
|
125
|
+
coord["observer"] = xds[sky_ap].attrs["observer"]
|
|
102
126
|
obsdate = {}
|
|
103
127
|
obsdate["refer"] = xds.coords["time"].attrs["scale"]
|
|
104
128
|
obsdate["type"] = "epoch"
|
|
105
129
|
obsdate["m0"] = {}
|
|
106
130
|
obsdate["m0"]["unit"] = xds.coords["time"].attrs["units"][0]
|
|
107
|
-
obsdate["m0"]["value"] = xds.coords["time"].values[0]
|
|
131
|
+
obsdate["m0"]["value"] = float(xds.coords["time"].values[0])
|
|
108
132
|
coord["obsdate"] = obsdate
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
telpos["refer"] = "ITRF"
|
|
115
|
-
for i in range(3):
|
|
116
|
-
telpos[f"m{i}"] = {
|
|
117
|
-
"unit": xds.attrs["telescope"]["position"]["units"][i],
|
|
118
|
-
"value": xds.attrs["telescope"]["position"]["value"][i],
|
|
119
|
-
}
|
|
120
|
-
telpos["type"] = "position"
|
|
121
|
-
coord["telescopeposition"] = telpos
|
|
133
|
+
if _pointing_center in xds[sky_ap].attrs:
|
|
134
|
+
coord["pointingcenter"] = {
|
|
135
|
+
"initial": True,
|
|
136
|
+
"value": xds[sky_ap].attrs[_pointing_center]["data"],
|
|
137
|
+
}
|
|
122
138
|
if "l" in xds.coords:
|
|
123
139
|
coord["direction0"] = _compute_direction_dict(xds)
|
|
124
140
|
else:
|
|
125
141
|
coord["linear0"] = _compute_linear_dict(xds)
|
|
126
142
|
coord["stokes1"] = {
|
|
127
|
-
"
|
|
143
|
+
"_axes_sizes": np.array([xds.sizes["polarization"]], dtype=np.int32),
|
|
144
|
+
"_image_axes": np.array([1], dtype=np.int32),
|
|
145
|
+
"axes": ["Stokes"],
|
|
128
146
|
"cdelt": np.array([1.0]),
|
|
129
147
|
"crpix": np.array([0.0]),
|
|
130
148
|
"crval": np.array([1.0]),
|
|
131
149
|
"pc": np.array([[1.0]]),
|
|
132
|
-
"stokes":
|
|
150
|
+
"stokes": xds.polarization.values.tolist(),
|
|
133
151
|
}
|
|
134
152
|
coord["spectral2"] = _compute_spectral_dict(xds)
|
|
135
|
-
coord["pixelmap0"] = np.array([0, 1])
|
|
136
|
-
coord["pixelmap1"] = np.array([2])
|
|
137
|
-
coord["pixelmap2"] = np.array([3])
|
|
153
|
+
coord["pixelmap0"] = np.array([0, 1], dtype=np.int32)
|
|
154
|
+
coord["pixelmap1"] = np.array([2], dtype=np.int32)
|
|
155
|
+
coord["pixelmap2"] = np.array([3], dtype=np.int32)
|
|
138
156
|
coord["pixelreplace0"] = np.array([0.0, 0.0])
|
|
139
157
|
coord["pixelreplace1"] = np.array([0.0])
|
|
140
158
|
coord["pixelreplace2"] = np.array([0.0])
|
|
@@ -144,7 +162,6 @@ def _coord_dict_from_xds(xds: xr.Dataset) -> dict:
|
|
|
144
162
|
# this probbably needs some verification
|
|
145
163
|
coord["worldreplace0"] = [0.0, 0.0]
|
|
146
164
|
coord["worldreplace1"] = np.array(coord["stokes1"]["crval"])
|
|
147
|
-
# print("spectral", coord["spectral2"])
|
|
148
165
|
coord["worldreplace2"] = np.array(coord["spectral2"]["wcs"]["crval"])
|
|
149
166
|
return coord
|
|
150
167
|
|
|
@@ -181,7 +198,7 @@ def _imageinfo_dict_from_xds(xds: xr.Dataset) -> dict:
|
|
|
181
198
|
ii["image_type"] = (
|
|
182
199
|
xds[ap_sky].attrs["image_type"] if "image_type" in xds[ap_sky].attrs else ""
|
|
183
200
|
)
|
|
184
|
-
ii["objectname"] = xds.attrs[_object_name]
|
|
201
|
+
ii["objectname"] = xds[ap_sky].attrs[_object_name]
|
|
185
202
|
if "BEAM" in xds.data_vars:
|
|
186
203
|
# multi beam
|
|
187
204
|
pp = {}
|
|
@@ -231,7 +248,9 @@ def _write_casa_data(xds: xr.Dataset, image_full_path: str) -> None:
|
|
|
231
248
|
else ("frequency", "polarization", "v", "u")
|
|
232
249
|
)
|
|
233
250
|
casa_image_shape = xds[sky_ap].isel(time=0).transpose(*trans_coords).shape[::-1]
|
|
234
|
-
active_mask =
|
|
251
|
+
active_mask = (
|
|
252
|
+
xds[sky_ap].attrs["active_mask"] if _active_mask in xds[sky_ap].attrs else ""
|
|
253
|
+
)
|
|
235
254
|
masks = []
|
|
236
255
|
masks_rec = {}
|
|
237
256
|
mask_rec = {
|