xradio 1.0.2__py3-none-any.whl → 1.1.0__py3-none-any.whl
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/_utils/_casacore/casacore_from_casatools.py +1 -1
- xradio/_utils/dict_helpers.py +38 -7
- xradio/_utils/list_and_array.py +26 -3
- xradio/_utils/schema.py +44 -0
- xradio/_utils/xarray_helpers.py +63 -0
- xradio/_utils/zarr/common.py +4 -2
- xradio/image/__init__.py +4 -2
- xradio/image/_util/_casacore/common.py +2 -1
- xradio/image/_util/_casacore/xds_from_casacore.py +105 -51
- xradio/image/_util/_casacore/xds_to_casacore.py +117 -52
- xradio/image/_util/_fits/xds_from_fits.py +124 -36
- xradio/image/_util/_zarr/common.py +0 -1
- xradio/image/_util/casacore.py +133 -16
- xradio/image/_util/common.py +6 -5
- xradio/image/_util/image_factory.py +466 -27
- xradio/image/image.py +72 -100
- xradio/image/image_xds.py +262 -0
- xradio/image/schema.py +85 -0
- xradio/measurement_set/__init__.py +5 -4
- xradio/measurement_set/_utils/_msv2/_tables/read.py +7 -3
- xradio/measurement_set/_utils/_msv2/conversion.py +6 -9
- xradio/measurement_set/_utils/_msv2/create_field_and_source_xds.py +1 -0
- xradio/measurement_set/_utils/_msv2/msv4_sub_xdss.py +1 -1
- xradio/measurement_set/_utils/_utils/interpolate.py +5 -0
- xradio/measurement_set/_utils/_utils/partition_attrs.py +0 -1
- xradio/measurement_set/convert_msv2_to_processing_set.py +9 -9
- xradio/measurement_set/load_processing_set.py +2 -2
- xradio/measurement_set/measurement_set_xdt.py +83 -93
- xradio/measurement_set/open_processing_set.py +1 -1
- xradio/measurement_set/processing_set_xdt.py +33 -26
- xradio/schema/check.py +70 -19
- xradio/schema/common.py +0 -1
- xradio/testing/__init__.py +0 -0
- xradio/testing/_utils/__template__.py +58 -0
- xradio/testing/measurement_set/__init__.py +58 -0
- xradio/testing/measurement_set/checker.py +131 -0
- xradio/testing/measurement_set/io.py +22 -0
- xradio/testing/measurement_set/msv2_io.py +1854 -0
- {xradio-1.0.2.dist-info → xradio-1.1.0.dist-info}/METADATA +64 -23
- xradio-1.1.0.dist-info/RECORD +75 -0
- {xradio-1.0.2.dist-info → xradio-1.1.0.dist-info}/WHEEL +1 -1
- xradio-1.0.2.dist-info/RECORD +0 -66
- {xradio-1.0.2.dist-info → xradio-1.1.0.dist-info}/licenses/LICENSE.txt +0 -0
- {xradio-1.0.2.dist-info → xradio-1.1.0.dist-info}/top_level.txt +0 -0
xradio/image/_util/casacore.py
CHANGED
|
@@ -9,14 +9,17 @@ import warnings
|
|
|
9
9
|
from typing import Union
|
|
10
10
|
|
|
11
11
|
import xarray as xr
|
|
12
|
+
import re
|
|
13
|
+
|
|
14
|
+
from xradio._utils.schema import get_data_group_keys
|
|
12
15
|
|
|
13
16
|
try:
|
|
14
17
|
from casacore import tables
|
|
15
18
|
except ImportError:
|
|
16
19
|
import xradio._utils._casacore.casacore_from_casatools as tables
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
from ._casacore.xds_from_casacore import (
|
|
21
|
+
|
|
22
|
+
from xradio.image._util._casacore.xds_from_casacore import (
|
|
20
23
|
_add_mask,
|
|
21
24
|
_add_sky_or_aperture,
|
|
22
25
|
_casa_image_to_xds_attrs,
|
|
@@ -28,18 +31,25 @@ from ._casacore.xds_from_casacore import (
|
|
|
28
31
|
_get_beam,
|
|
29
32
|
_read_image_array,
|
|
30
33
|
)
|
|
31
|
-
from ._casacore.xds_to_casacore import (
|
|
34
|
+
from xradio.image._util._casacore.xds_to_casacore import (
|
|
32
35
|
_coord_dict_from_xds,
|
|
33
36
|
_history_from_xds,
|
|
34
37
|
_imageinfo_dict_from_xds,
|
|
35
38
|
_write_casa_data,
|
|
36
39
|
)
|
|
37
|
-
from .common import
|
|
40
|
+
from xradio.image._util.common import (
|
|
41
|
+
_aperture_or_sky,
|
|
42
|
+
_get_xds_dim_order,
|
|
43
|
+
_dask_arrayize_dv,
|
|
44
|
+
)
|
|
45
|
+
from xradio.image._util._casacore.common import _beam_fit_params, _open_image_ro
|
|
38
46
|
|
|
39
47
|
warnings.filterwarnings("ignore", category=FutureWarning)
|
|
40
48
|
|
|
41
49
|
|
|
42
|
-
def _load_casa_image_block(
|
|
50
|
+
def _load_casa_image_block(
|
|
51
|
+
infile: str, block_des: dict, do_sky_coords, image_type: str
|
|
52
|
+
) -> xr.Dataset:
|
|
43
53
|
image_full_path = os.path.expanduser(infile)
|
|
44
54
|
with _open_image_ro(image_full_path) as casa_image:
|
|
45
55
|
coords = casa_image.coordinates()
|
|
@@ -55,7 +65,7 @@ def _load_casa_image_block(infile: str, block_des: dict, do_sky_coords) -> xr.Da
|
|
|
55
65
|
image_full_path, shapes, starts, dimorder, transpose_list, new_axes
|
|
56
66
|
)
|
|
57
67
|
xds = _add_sky_or_aperture(
|
|
58
|
-
xds, block, dimorder, image_full_path, ret["sphr_dims"],
|
|
68
|
+
xds, block, dimorder, image_full_path, ret["sphr_dims"], False, image_type
|
|
59
69
|
)
|
|
60
70
|
mymasks = _get_mask_names(image_full_path)
|
|
61
71
|
for m in mymasks:
|
|
@@ -64,26 +74,35 @@ def _load_casa_image_block(infile: str, block_des: dict, do_sky_coords) -> xr.Da
|
|
|
64
74
|
full_path, shapes, starts, dimorder, transpose_list, new_axes
|
|
65
75
|
)
|
|
66
76
|
# data vars are all caps by convention
|
|
67
|
-
|
|
77
|
+
mask_name = re.sub(r"\bMASK(\d+)\b", r"MASK_\1", m.upper())
|
|
78
|
+
xds = _add_mask(xds, mask_name, block, dimorder)
|
|
68
79
|
xds.attrs = _casa_image_to_xds_attrs(image_full_path)
|
|
69
|
-
beam = _get_beam(image_full_path, nchan, npol, False)
|
|
80
|
+
beam = _get_beam(image_full_path, nchan, npol, False, image_type)
|
|
81
|
+
|
|
70
82
|
if beam is not None:
|
|
71
83
|
selectors = {
|
|
72
84
|
k: block_des[k]
|
|
73
85
|
for k in ("time", "frequency", "polarization")
|
|
74
86
|
if k in block_des
|
|
75
87
|
}
|
|
76
|
-
xds["
|
|
88
|
+
xds["BEAM_FIT_PARAMS_" + image_type.upper()] = beam.isel(selectors)
|
|
89
|
+
xds["BEAM_FIT_PARAMS_" + image_type.upper()].attrs["type"] = (
|
|
90
|
+
"beam_fit_params_" + image_type.lower()
|
|
91
|
+
)
|
|
92
|
+
xds[image_type.upper()].attrs[_beam_fit_params] = (
|
|
93
|
+
"BEAM_FIT_PARAMS_" + image_type.upper()
|
|
94
|
+
)
|
|
77
95
|
return xds
|
|
78
96
|
|
|
79
97
|
|
|
80
|
-
def
|
|
98
|
+
def _open_casa_image(
|
|
81
99
|
infile: str,
|
|
82
100
|
chunks: Union[list, dict],
|
|
83
101
|
verbose: bool,
|
|
84
102
|
do_sky_coords: bool,
|
|
85
103
|
masks: bool = True,
|
|
86
|
-
history: bool =
|
|
104
|
+
history: bool = False,
|
|
105
|
+
image_type: str = "SKY",
|
|
87
106
|
) -> xr.Dataset:
|
|
88
107
|
img_full_path = os.path.expanduser(infile)
|
|
89
108
|
ret = _casa_image_to_xds_coords(img_full_path, verbose, do_sky_coords)
|
|
@@ -96,26 +115,124 @@ def _read_casa_image(
|
|
|
96
115
|
img_full_path,
|
|
97
116
|
ret["sphr_dims"],
|
|
98
117
|
history,
|
|
118
|
+
image_type=image_type,
|
|
99
119
|
)
|
|
100
120
|
if masks:
|
|
101
121
|
mymasks = _get_mask_names(img_full_path)
|
|
102
122
|
for m in mymasks:
|
|
103
123
|
ary = _read_image_array(img_full_path, chunks, mask=m, verbose=verbose)
|
|
104
124
|
# data var names are all caps by convention
|
|
105
|
-
|
|
125
|
+
mask_name = re.sub(r"\bMASK(\d+)\b", r"MASK_\1", m.upper())
|
|
126
|
+
xds = _add_mask(xds, mask_name, ary, dimorder)
|
|
106
127
|
xds.attrs = _casa_image_to_xds_attrs(img_full_path)
|
|
107
128
|
beam = _get_beam(
|
|
108
|
-
img_full_path,
|
|
129
|
+
img_full_path,
|
|
130
|
+
xds.sizes["frequency"],
|
|
131
|
+
xds.sizes["polarization"],
|
|
132
|
+
True,
|
|
133
|
+
image_type,
|
|
109
134
|
)
|
|
110
135
|
if beam is not None:
|
|
111
|
-
xds["
|
|
136
|
+
xds["BEAM_FIT_PARAMS_" + image_type.upper()] = beam
|
|
137
|
+
xds["BEAM_FIT_PARAMS_" + image_type.upper()].attrs["type"] = (
|
|
138
|
+
"beam_fit_params_" + image_type.lower()
|
|
139
|
+
)
|
|
140
|
+
xds[image_type.upper()].attrs[_beam_fit_params] = (
|
|
141
|
+
"BEAM_FIT_PARAMS_" + image_type.upper()
|
|
142
|
+
)
|
|
143
|
+
|
|
112
144
|
# xds = _add_coord_attrs(xds, ret["icoords"], ret["dir_axes"])
|
|
113
145
|
xds = _dask_arrayize_dv(xds)
|
|
146
|
+
|
|
114
147
|
return xds
|
|
115
148
|
|
|
116
149
|
|
|
117
|
-
def
|
|
118
|
-
|
|
150
|
+
def _xds_to_multiple_casa_images(xds: xr.Dataset, image_store_name: str) -> None:
|
|
151
|
+
"""Function disentagles xradio xr.Dataset into multiple casa images based on data_groups attribute.
|
|
152
|
+
An xr.Dataset may contain multiple images (sky, residual, psf, etc) stored under different data variables sharing common coordinates.
|
|
153
|
+
An addtional complication is that CASA images allow for internal masks and beam fit parameters to be stored alongside the main image data so these also need to be handled.
|
|
154
|
+
This function creates separate casa images for each image type found in the data_groups attribute of the xr.Dataset.
|
|
155
|
+
|
|
156
|
+
Parameters
|
|
157
|
+
----------
|
|
158
|
+
xds : xr.Dataset
|
|
159
|
+
The xradio xr.Dataset containing multiple images and associated data.
|
|
160
|
+
image_store_name : str
|
|
161
|
+
The base name or path for storing the output CASA images.
|
|
162
|
+
If only one image is written, it will be named image_store_name, esle the images
|
|
163
|
+
will be named image_store_name.<image_type> where <image_type> is sky, residual, point_spread_function, etc.
|
|
164
|
+
"""
|
|
165
|
+
|
|
166
|
+
data_vars_name_set = set(xds.data_vars.keys())
|
|
167
|
+
|
|
168
|
+
data_group_keys = list(get_data_group_keys(schema_name="image").keys())
|
|
169
|
+
internal_image_types_to_exclude = [
|
|
170
|
+
"flag",
|
|
171
|
+
"beam_fit_params_sky",
|
|
172
|
+
"beam_fit_params_point_spread_function",
|
|
173
|
+
]
|
|
174
|
+
n_image_written = 0
|
|
175
|
+
last_image_written = ""
|
|
176
|
+
for data_group in xds.attrs["data_groups"].keys():
|
|
177
|
+
for image_type in data_group_keys:
|
|
178
|
+
if (image_type in xds.attrs["data_groups"][data_group]) and (
|
|
179
|
+
image_type not in internal_image_types_to_exclude
|
|
180
|
+
):
|
|
181
|
+
image_name = xds.attrs["data_groups"][data_group][image_type]
|
|
182
|
+
if image_name in data_vars_name_set:
|
|
183
|
+
image_to_write_xds = xr.Dataset()
|
|
184
|
+
image_to_write_xds.attrs = xds.attrs.copy()
|
|
185
|
+
|
|
186
|
+
if image_type == "aperture":
|
|
187
|
+
image_to_write_xds["APERTURE"] = xds[image_name]
|
|
188
|
+
else:
|
|
189
|
+
image_to_write_xds["SKY"] = xds[image_name]
|
|
190
|
+
|
|
191
|
+
# This code handles adding internal masks and beam fit params if they exist.
|
|
192
|
+
if image_type == "sky":
|
|
193
|
+
if (
|
|
194
|
+
"beam_fit_params_sky"
|
|
195
|
+
in xds.attrs["data_groups"][data_group]
|
|
196
|
+
):
|
|
197
|
+
beam_fit_params_name = xds.attrs["data_groups"][data_group][
|
|
198
|
+
"beam_fit_params_sky"
|
|
199
|
+
]
|
|
200
|
+
image_to_write_xds["BEAM_FIT_PARAMS"] = xds[
|
|
201
|
+
beam_fit_params_name
|
|
202
|
+
]
|
|
203
|
+
|
|
204
|
+
if "flag" in xds.attrs["data_groups"][data_group]:
|
|
205
|
+
mask_sky_name = xds.attrs["data_groups"][data_group]["flag"]
|
|
206
|
+
image_to_write_xds["MASK_0"] = xds[mask_sky_name]
|
|
207
|
+
image_to_write_xds["SKY"].attrs["flag"] = "MASK_0"
|
|
208
|
+
|
|
209
|
+
if image_type == "point_spread_function":
|
|
210
|
+
if (
|
|
211
|
+
"beam_fit_params_point_spread_function"
|
|
212
|
+
in xds.attrs["data_groups"][data_group]
|
|
213
|
+
):
|
|
214
|
+
beam_fit_params_name = xds.attrs["data_groups"][data_group][
|
|
215
|
+
"beam_fit_params_point_spread_function"
|
|
216
|
+
]
|
|
217
|
+
image_to_write_xds["BEAM_FIT_PARAMS"] = xds[
|
|
218
|
+
beam_fit_params_name
|
|
219
|
+
]
|
|
220
|
+
outname = image_store_name + "." + image_type
|
|
221
|
+
_xds_to_casa_image(image_to_write_xds, outname)
|
|
222
|
+
if not os.path.exists(outname):
|
|
223
|
+
raise IOError(f"Failed to write CASA image {outname}")
|
|
224
|
+
n_image_written += 1
|
|
225
|
+
last_image_written = outname
|
|
226
|
+
data_vars_name_set.remove(image_name)
|
|
227
|
+
if n_image_written == 0:
|
|
228
|
+
raise ValueError("No valid image types found in xds to write to CASA images.")
|
|
229
|
+
if n_image_written == 1:
|
|
230
|
+
# rename the single written image to what the user requested
|
|
231
|
+
os.rename(last_image_written, image_store_name)
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def _xds_to_casa_image(xds: xr.Dataset, image_store_name: str) -> None:
|
|
235
|
+
image_full_path = os.path.expanduser(image_store_name)
|
|
119
236
|
_write_casa_data(xds, image_full_path)
|
|
120
237
|
# create coordinates
|
|
121
238
|
ap_sky = _aperture_or_sky(xds)
|
xradio/image/_util/common.py
CHANGED
|
@@ -7,6 +7,7 @@ from typing import Dict, List
|
|
|
7
7
|
import xarray as xr
|
|
8
8
|
from xradio._utils.coord_math import _deg_to_rad
|
|
9
9
|
from xradio._utils.dict_helpers import make_quantity
|
|
10
|
+
import toolviper.utils.logger as logger
|
|
10
11
|
|
|
11
12
|
_c = 2.99792458e08 * u.m / u.s
|
|
12
13
|
# OPTICAL = Z
|
|
@@ -17,7 +18,7 @@ _doppler_types = [
|
|
|
17
18
|
"beta",
|
|
18
19
|
"gamma",
|
|
19
20
|
]
|
|
20
|
-
_image_type = "
|
|
21
|
+
_image_type = "type"
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
def _aperture_or_sky(xds: xr.Dataset) -> str:
|
|
@@ -252,10 +253,10 @@ def _compute_sky_reference_pixel(xds: xr.Dataset) -> np.ndarray:
|
|
|
252
253
|
|
|
253
254
|
def _l_m_attr_notes() -> Dict[str, str]:
|
|
254
255
|
return {
|
|
255
|
-
"l": "l is the angle measured from the
|
|
256
|
-
"So l = x*cdelt, where x is the number of pixels from the
|
|
256
|
+
"l": "l is the angle measured from the reference direction to the east. "
|
|
257
|
+
"So l = x*cdelt, where x is the number of pixels from the reference direction. "
|
|
257
258
|
"See AIPS Memo #27, Section III.",
|
|
258
|
-
"m": "m is the angle measured from the
|
|
259
|
-
"So m = y*cdelt, where y is the number of pixels from the
|
|
259
|
+
"m": "m is the angle measured from the reference direction to the north. "
|
|
260
|
+
"So m = y*cdelt, where y is the number of pixels from the reference direction. "
|
|
260
261
|
"See AIPS Memo #27, Section III.",
|
|
261
262
|
}
|