xradio 0.0.52__tar.gz → 0.0.53__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.52/src/xradio.egg-info → xradio-0.0.53}/PKG-INFO +1 -1
- {xradio-0.0.52 → xradio-0.0.53}/pyproject.toml +1 -1
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/image/_util/_casacore/xds_to_casacore.py +3 -1
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/image/_util/_fits/xds_from_fits.py +17 -26
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/image/_util/_zarr/xds_to_zarr.py +17 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/image/image.py +20 -8
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/conversion.py +12 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/msv4_sub_xdss.py +116 -1
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/schema.py +104 -1
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/schema/check.py +3 -2
- {xradio-0.0.52 → xradio-0.0.53/src/xradio.egg-info}/PKG-INFO +1 -1
- {xradio-0.0.52 → xradio-0.0.53}/LICENSE.txt +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/MANIFEST.in +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/README.md +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/setup.cfg +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/__init__.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/_utils/__init__.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/_utils/_casacore/tables.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/_utils/coord_math.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/_utils/dict_helpers.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/_utils/list_and_array.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/_utils/schema.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/_utils/zarr/__init__.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/_utils/zarr/common.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/image/__init__.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/image/_util/__init__.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/image/_util/_casacore/__init__.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/image/_util/_casacore/common.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/image/_util/_casacore/xds_from_casacore.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/image/_util/_zarr/common.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/image/_util/_zarr/xds_from_zarr.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/image/_util/_zarr/zarr_low_level.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/image/_util/casacore.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/image/_util/common.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/image/_util/fits.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/image/_util/image_factory.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/image/_util/zarr.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/__init__.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/__init__.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/_tables/load.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/_tables/load_main_table.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/_tables/read.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/_tables/read_main_table.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/_tables/read_subtables.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/_tables/table_query.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/_tables/write.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/_tables/write_exp_api.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/chunks.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/create_antenna_xds.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/create_field_and_source_xds.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/descr.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/msv2_msv3.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/msv2_to_msv4_meta.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/msv4_info_dicts.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/optimised_functions.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/partition_queries.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/partitions.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/subtables.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_utils/cds.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_utils/partition_attrs.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_utils/stokes_types.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_utils/xds_helper.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_zarr/encoding.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_zarr/read.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_zarr/write.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/msv2.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/zarr.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/convert_msv2_to_processing_set.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/load_processing_set.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/measurement_set_xdt.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/open_processing_set.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/processing_set_xdt.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/schema/__init__.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/schema/bases.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/schema/dataclass.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/schema/metamodel.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/schema/typing.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/sphinx/__init__.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio/sphinx/schema_table.py +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio.egg-info/SOURCES.txt +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio.egg-info/dependency_links.txt +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/src/xradio.egg-info/requires.txt +0 -0
- {xradio-0.0.52 → xradio-0.0.53}/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.53
|
|
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
|
|
@@ -198,7 +198,9 @@ def _imageinfo_dict_from_xds(xds: xr.Dataset) -> dict:
|
|
|
198
198
|
ii["image_type"] = (
|
|
199
199
|
xds[ap_sky].attrs["image_type"] if "image_type" in xds[ap_sky].attrs else ""
|
|
200
200
|
)
|
|
201
|
-
ii["objectname"] =
|
|
201
|
+
ii["objectname"] = (
|
|
202
|
+
xds[ap_sky].attrs[_object_name] if _object_name in xds[ap_sky].attrs else ""
|
|
203
|
+
)
|
|
202
204
|
if "BEAM" in xds.data_vars:
|
|
203
205
|
# multi beam
|
|
204
206
|
pp = {}
|
|
@@ -82,8 +82,6 @@ def _add_freq_attrs(xds: xr.Dataset, helpers: dict) -> xr.Dataset:
|
|
|
82
82
|
if helpers["has_freq"]:
|
|
83
83
|
meta["rest_frequency"] = make_quantity(helpers["restfreq"], "Hz")
|
|
84
84
|
meta["rest_frequencies"] = [meta["rest_frequency"]]
|
|
85
|
-
# meta["frame"] = helpers["specsys"]
|
|
86
|
-
# meta["units"] = "Hz"
|
|
87
85
|
meta["type"] = "frequency"
|
|
88
86
|
meta["wave_unit"] = "mm"
|
|
89
87
|
freq_axis = helpers["freq_axis"]
|
|
@@ -123,16 +121,6 @@ def _add_l_m_attrs(xds: xr.Dataset, helpers: dict) -> xr.Dataset:
|
|
|
123
121
|
|
|
124
122
|
|
|
125
123
|
def _add_lin_attrs(xds: xr.Dataset, helpers: dict) -> xr.Dataset:
|
|
126
|
-
"""
|
|
127
|
-
if helpers["sphr_dims"]:
|
|
128
|
-
for i, name in zip(helpers["dir_axes"], helpers["sphr_axis_names"]):
|
|
129
|
-
meta = {
|
|
130
|
-
"units": "rad",
|
|
131
|
-
"crval": helpers["crval"][i],
|
|
132
|
-
"cdelt": helpers["cdelt"][i],
|
|
133
|
-
}
|
|
134
|
-
xds.coords[name].attrs = meta
|
|
135
|
-
"""
|
|
136
124
|
if not helpers["sphr_dims"]:
|
|
137
125
|
for i, j in zip(helpers["dir_axes"], ("u", "v")):
|
|
138
126
|
meta = {
|
|
@@ -162,7 +150,7 @@ def _xds_direction_attrs_from_header(helpers: dict, header) -> dict:
|
|
|
162
150
|
direction["projection"] = p0
|
|
163
151
|
helpers["projection"] = p0
|
|
164
152
|
ref_sys = header["RADESYS"]
|
|
165
|
-
ref_eqx = header["EQUINOX"]
|
|
153
|
+
ref_eqx = None if ref_sys.upper() == "ICRS" else header["EQUINOX"]
|
|
166
154
|
if ref_sys == "FK5" and ref_eqx == 2000:
|
|
167
155
|
ref_eqx = "J2000.0"
|
|
168
156
|
helpers["ref_sys"] = ref_sys
|
|
@@ -180,9 +168,10 @@ def _xds_direction_attrs_from_header(helpers: dict, header) -> dict:
|
|
|
180
168
|
ddata.append(x.value)
|
|
181
169
|
# direction["reference"]["value"][i] = x.value
|
|
182
170
|
x = helpers["cdelt"][i] * u.Unit(_get_unit(helpers["cunit"][i]))
|
|
183
|
-
dunits.append(
|
|
171
|
+
dunits.append("rad")
|
|
184
172
|
direction["reference"] = make_skycoord_dict(ddata, units=dunits, frame=ref_sys)
|
|
185
|
-
|
|
173
|
+
if ref_eqx is not None:
|
|
174
|
+
direction["reference"]["attrs"]["equinox"] = ref_eqx.lower()
|
|
186
175
|
direction["latpole"] = make_quantity(
|
|
187
176
|
header["LATPOLE"] * _deg_to_rad, "rad", dims=["l", "m"]
|
|
188
177
|
)
|
|
@@ -285,6 +274,9 @@ def _user_attrs_from_header(header) -> dict:
|
|
|
285
274
|
"ALTRPIX",
|
|
286
275
|
"ALTRVAL",
|
|
287
276
|
"BITPIX",
|
|
277
|
+
"BMAJ",
|
|
278
|
+
"BMIN",
|
|
279
|
+
"BPA",
|
|
288
280
|
"BSCALE",
|
|
289
281
|
"BTYPE",
|
|
290
282
|
"BUNIT",
|
|
@@ -310,21 +302,20 @@ def _user_attrs_from_header(header) -> dict:
|
|
|
310
302
|
]
|
|
311
303
|
regex = r"|".join(
|
|
312
304
|
[
|
|
313
|
-
"^NAXIS
|
|
314
|
-
"^CRVAL
|
|
315
|
-
"^CRPIX
|
|
316
|
-
"^CTYPE
|
|
317
|
-
"^CDELT
|
|
318
|
-
"^CUNIT
|
|
319
|
-
"^OBSGEO-(X|Y|Z)$",
|
|
320
|
-
"^P(C|V)
|
|
305
|
+
r"^NAXIS\d?$",
|
|
306
|
+
r"^CRVAL\d$",
|
|
307
|
+
r"^CRPIX\d$",
|
|
308
|
+
r"^CTYPE\d$",
|
|
309
|
+
r"^CDELT\d$",
|
|
310
|
+
r"^CUNIT\d$",
|
|
311
|
+
r"^OBSGEO-(X|Y|Z)$",
|
|
312
|
+
r"^P(C|V)0?\d_0?\d",
|
|
321
313
|
]
|
|
322
314
|
)
|
|
323
315
|
user = {}
|
|
324
316
|
for k, v in header.items():
|
|
325
|
-
if re.search(regex, k) or k in exclude:
|
|
326
|
-
|
|
327
|
-
user[k.lower()] = v
|
|
317
|
+
if not (re.search(regex, k) or k in exclude):
|
|
318
|
+
user[k.lower()] = v
|
|
328
319
|
return user
|
|
329
320
|
|
|
330
321
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import dask.array as da
|
|
1
2
|
import logging
|
|
2
3
|
import numpy as np
|
|
3
4
|
import xarray as xr
|
|
@@ -6,6 +7,22 @@ from .common import _np_types, _top_level_sub_xds
|
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
def _write_zarr(xds: xr.Dataset, zarr_store: str):
|
|
10
|
+
max_chunk_size = 0.95 * 2**30
|
|
11
|
+
for dv in xds.data_vars:
|
|
12
|
+
obj = xds[dv]
|
|
13
|
+
if isinstance(obj, xr.core.dataarray.DataArray) and isinstance(
|
|
14
|
+
obj.data, da.Array
|
|
15
|
+
):
|
|
16
|
+
# get chunk size to make sure it is small enough to be compressed
|
|
17
|
+
ary = obj.data
|
|
18
|
+
chunk_size_bytes = np.prod(ary.chunksize) * np.dtype(ary.dtype).itemsize
|
|
19
|
+
if chunk_size_bytes > max_chunk_size:
|
|
20
|
+
raise ValueError(
|
|
21
|
+
f"Chunk size of {chunk_size_bytes/1e9} GB for data variable {dv} "
|
|
22
|
+
"bytes is too large for compression. To fix this, "
|
|
23
|
+
"reduce the chunk size of the dask array in the data variable "
|
|
24
|
+
f"by at least a factor of {chunk_size_bytes/max_chunk_size}."
|
|
25
|
+
)
|
|
9
26
|
xds_copy = xds.copy(deep=True)
|
|
10
27
|
sub_xds_dict = _encode(xds_copy, zarr_store)
|
|
11
28
|
z_obj = xds_copy.to_zarr(store=zarr_store, compute=True)
|
|
@@ -7,6 +7,9 @@ import warnings
|
|
|
7
7
|
from typing import List, Union
|
|
8
8
|
import copy
|
|
9
9
|
import numpy as np
|
|
10
|
+
import os
|
|
11
|
+
import shutil
|
|
12
|
+
import toolviper.utils.logger as logger
|
|
10
13
|
import xarray as xr
|
|
11
14
|
|
|
12
15
|
# from .._utils.zarr.common import _load_no_dask_zarr
|
|
@@ -182,27 +185,36 @@ def load_image(infile: str, block_des: dict = {}, do_sky_coords=True) -> xr.Data
|
|
|
182
185
|
|
|
183
186
|
|
|
184
187
|
def write_image(
|
|
185
|
-
xds: xr.Dataset, imagename: str, out_format: str = "casa", overwrite=False
|
|
188
|
+
xds: xr.Dataset, imagename: str, out_format: str = "casa", overwrite: bool = False
|
|
186
189
|
) -> None:
|
|
187
190
|
"""
|
|
188
191
|
Convert an xds image to CASA or zarr image.
|
|
189
192
|
xds : xarray.Dataset
|
|
190
193
|
XDS to convert
|
|
191
194
|
imagename : str
|
|
192
|
-
Path to output
|
|
195
|
+
Path to output image
|
|
193
196
|
out_format : str
|
|
194
197
|
Format of output image, currently "casa" and "zarr" are supported
|
|
198
|
+
overwrite : bool
|
|
199
|
+
If True, overwrite existing image. Default is False.
|
|
195
200
|
Returns
|
|
196
201
|
-------
|
|
197
202
|
None
|
|
198
203
|
"""
|
|
204
|
+
if os.path.exists(imagename):
|
|
205
|
+
if overwrite:
|
|
206
|
+
logger.warning(
|
|
207
|
+
f"Because overwrite=True, removing existing path {imagename}"
|
|
208
|
+
)
|
|
209
|
+
if os.path.isdir(imagename):
|
|
210
|
+
shutil.rmtree(imagename)
|
|
211
|
+
else:
|
|
212
|
+
os.remove(imagename)
|
|
213
|
+
else:
|
|
214
|
+
raise FileExistsError(
|
|
215
|
+
f"Path {imagename} already exists. Set overwrite=True to remove it."
|
|
216
|
+
)
|
|
199
217
|
my_format = out_format.lower()
|
|
200
|
-
|
|
201
|
-
if overwrite:
|
|
202
|
-
import os
|
|
203
|
-
|
|
204
|
-
os.system("rm -rf " + imagename)
|
|
205
|
-
|
|
206
218
|
if my_format == "casa":
|
|
207
219
|
_xds_to_casa_image(xds, imagename)
|
|
208
220
|
elif my_format == "zarr":
|
|
@@ -16,6 +16,7 @@ from xradio.measurement_set._utils._msv2.msv4_sub_xdss import (
|
|
|
16
16
|
create_pointing_xds,
|
|
17
17
|
create_system_calibration_xds,
|
|
18
18
|
create_weather_xds,
|
|
19
|
+
create_phased_array_xds,
|
|
19
20
|
)
|
|
20
21
|
from .msv4_info_dicts import create_info_dicts
|
|
21
22
|
from xradio.measurement_set.schema import MSV4_SCHEMA_VERSION
|
|
@@ -1243,6 +1244,14 @@ def convert_and_write_partition(
|
|
|
1243
1244
|
+ str(time.time() - start)
|
|
1244
1245
|
)
|
|
1245
1246
|
|
|
1247
|
+
# Create phased array xds
|
|
1248
|
+
phased_array_xds = create_phased_array_xds(
|
|
1249
|
+
in_file,
|
|
1250
|
+
ant_xds.antenna_name,
|
|
1251
|
+
ant_xds.receptor_label,
|
|
1252
|
+
ant_xds.polarization_type,
|
|
1253
|
+
)
|
|
1254
|
+
|
|
1246
1255
|
start = time.time()
|
|
1247
1256
|
|
|
1248
1257
|
# Time and frequency should always be increasing
|
|
@@ -1358,6 +1367,9 @@ def convert_and_write_partition(
|
|
|
1358
1367
|
if weather_xds:
|
|
1359
1368
|
ms_xdt["/weather_xds"] = weather_xds
|
|
1360
1369
|
|
|
1370
|
+
if phased_array_xds:
|
|
1371
|
+
ms_xdt["/phased_array_xds"] = phased_array_xds
|
|
1372
|
+
|
|
1361
1373
|
if storage_backend == "zarr":
|
|
1362
1374
|
ms_xdt.to_zarr(store=os.path.join(out_file, ms_v4_name))
|
|
1363
1375
|
elif storage_backend == "netcdf":
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import toolviper.utils.logger as logger
|
|
2
2
|
import os
|
|
3
3
|
import time
|
|
4
|
-
from typing import Tuple, Union
|
|
4
|
+
from typing import Optional, Tuple, Union
|
|
5
5
|
|
|
6
6
|
import numpy as np
|
|
7
7
|
import xarray as xr
|
|
8
|
+
from numpy.typing import ArrayLike
|
|
8
9
|
|
|
9
10
|
from xradio._utils.coord_math import convert_to_si_units
|
|
10
11
|
from xradio._utils.schema import (
|
|
@@ -741,3 +742,117 @@ def create_system_calibration_xds(
|
|
|
741
742
|
sys_cal_xds[data_var] = sys_cal_xds[data_var].astype(np.float64)
|
|
742
743
|
|
|
743
744
|
return sys_cal_xds
|
|
745
|
+
|
|
746
|
+
|
|
747
|
+
def create_phased_array_xds(
|
|
748
|
+
in_file: str,
|
|
749
|
+
antenna_names: list[str],
|
|
750
|
+
receptor_label: list[str],
|
|
751
|
+
polarization_type: ArrayLike,
|
|
752
|
+
) -> Optional[xr.Dataset]:
|
|
753
|
+
"""
|
|
754
|
+
Create an Xarray Dataset containing phased array information.
|
|
755
|
+
|
|
756
|
+
Parameters
|
|
757
|
+
----------
|
|
758
|
+
in_file : str
|
|
759
|
+
Path to the input MSv2.
|
|
760
|
+
antenna_names: DataArray or Sequence[str]
|
|
761
|
+
Content of the antenna_name coordinate of the antenna_xds.
|
|
762
|
+
receptor_label: DataArray or Sequence[str]
|
|
763
|
+
Content of the receptor_label coordinate of the antenna_xds. Used to
|
|
764
|
+
label the corresponding axis of ELEMENT_FLAG.
|
|
765
|
+
polarization_type: DataArray or ArrayLike
|
|
766
|
+
Contents of the polarization_type coordinate of the antenna_xds.
|
|
767
|
+
Array-like of shape (num_antennas, 2) containing the polarization
|
|
768
|
+
hands for each antenna.
|
|
769
|
+
|
|
770
|
+
Returns
|
|
771
|
+
----------
|
|
772
|
+
xr.Dataset or None: If the input MS contains a PHASED_ARRAY table,
|
|
773
|
+
returns the Xarray Dataset containing the phased array information.
|
|
774
|
+
Otherwise, return None.
|
|
775
|
+
"""
|
|
776
|
+
|
|
777
|
+
def extract_data(dataarray_or_sequence):
|
|
778
|
+
if hasattr(dataarray_or_sequence, "data"):
|
|
779
|
+
return dataarray_or_sequence.data.tolist()
|
|
780
|
+
return dataarray_or_sequence
|
|
781
|
+
|
|
782
|
+
antenna_names = extract_data(antenna_names)
|
|
783
|
+
receptor_label = extract_data(receptor_label)
|
|
784
|
+
polarization_type = extract_data(polarization_type)
|
|
785
|
+
|
|
786
|
+
# NOTE: We cannot use the dimension renaming option of `load_generic_table`
|
|
787
|
+
# here, because it leads to a dimension name collision. This is caused by
|
|
788
|
+
# the presence of two dimensions of size 3 in multiple arrays.
|
|
789
|
+
# Instead, we do the renaming manually below.
|
|
790
|
+
try:
|
|
791
|
+
raw_xds = load_generic_table(
|
|
792
|
+
in_file,
|
|
793
|
+
"PHASED_ARRAY",
|
|
794
|
+
# Some MSes carry COORDINATE_SYSTEM as a copy of COORDINATE_AXES
|
|
795
|
+
# due to a past ambiguity on the PHASED_ARRAY schema
|
|
796
|
+
ignore=["COORDINATE_SYSTEM", "ANTENNA_ID"],
|
|
797
|
+
)
|
|
798
|
+
except ValueError:
|
|
799
|
+
return None
|
|
800
|
+
|
|
801
|
+
# Defend against empty PHASED_ARRAY table.
|
|
802
|
+
# The test MS "AA2-Mid-sim_00000.ms" has that problem.
|
|
803
|
+
required_keys = {"COORDINATE_AXES", "ELEMENT_OFFSET", "ELEMENT_FLAG"}
|
|
804
|
+
if not all(k in raw_xds for k in required_keys):
|
|
805
|
+
return None
|
|
806
|
+
|
|
807
|
+
def msv4_measure(raw_name: str) -> dict:
|
|
808
|
+
coldesc = raw_xds.attrs["other"]["msv2"]["ctds_attrs"]["column_descriptions"]
|
|
809
|
+
return column_description_casacore_to_msv4_measure(coldesc[raw_name])
|
|
810
|
+
|
|
811
|
+
def make_data_variable(raw_name: str, dim_names: list[str]) -> xr.DataArray:
|
|
812
|
+
da = raw_xds[raw_name]
|
|
813
|
+
da = xr.DataArray(da.data, dims=tuple(dim_names))
|
|
814
|
+
return da.assign_attrs(msv4_measure(raw_name))
|
|
815
|
+
|
|
816
|
+
raw_datavar_names_and_dims = [
|
|
817
|
+
(
|
|
818
|
+
"COORDINATE_AXES",
|
|
819
|
+
("antenna_name", "cartesian_pos_label_local", "cartesian_pos_label"),
|
|
820
|
+
),
|
|
821
|
+
("ELEMENT_OFFSET", ("antenna_name", "cartesian_pos_label_local", "element_id")),
|
|
822
|
+
("ELEMENT_FLAG", ("antenna_name", "receptor_label", "element_id")),
|
|
823
|
+
]
|
|
824
|
+
|
|
825
|
+
data_vars = {
|
|
826
|
+
name: make_data_variable(name, dims)
|
|
827
|
+
for name, dims in raw_datavar_names_and_dims
|
|
828
|
+
}
|
|
829
|
+
data_vars["COORDINATE_AXES"].attrs = {
|
|
830
|
+
"type": "rotation_matrix",
|
|
831
|
+
"units": ["undimensioned", "undimensioned", "undimensioned"],
|
|
832
|
+
}
|
|
833
|
+
# Remove the "frame" attribute if it exists, because ELEMENT_OFFSET is
|
|
834
|
+
# defined in a station-local frame for which no standard name exists
|
|
835
|
+
data_vars["ELEMENT_OFFSET"].attrs.pop("frame", None)
|
|
836
|
+
data_vars["ELEMENT_OFFSET"].attrs.update(
|
|
837
|
+
{
|
|
838
|
+
"coordinate_system": "topocentric",
|
|
839
|
+
"origin": "ANTENNA_POSITION",
|
|
840
|
+
}
|
|
841
|
+
)
|
|
842
|
+
|
|
843
|
+
num_elements = data_vars["ELEMENT_OFFSET"].sizes["element_id"]
|
|
844
|
+
|
|
845
|
+
data_vars = {"PHASED_ARRAY_" + key: val for key, val in data_vars.items()}
|
|
846
|
+
coords = {
|
|
847
|
+
"antenna_name": antenna_names,
|
|
848
|
+
"element_id": np.arange(num_elements),
|
|
849
|
+
"receptor_label": receptor_label,
|
|
850
|
+
"polarization_type": (
|
|
851
|
+
("antenna_name", "receptor_label"),
|
|
852
|
+
polarization_type,
|
|
853
|
+
),
|
|
854
|
+
"cartesian_pos_label": ["x", "y", "z"],
|
|
855
|
+
"cartesian_pos_label_local": ["p", "q", "r"],
|
|
856
|
+
}
|
|
857
|
+
attrs = {"type": "phased_array"}
|
|
858
|
+
return xr.Dataset(data_vars, coords, attrs)
|
|
@@ -26,6 +26,8 @@ TimeWeather = Literal["time_weather"]
|
|
|
26
26
|
""" time dimension of weather dataset (when not interpolated to main time) """
|
|
27
27
|
AntennaName = Literal["antenna_name"]
|
|
28
28
|
""" Antenna name dimension """
|
|
29
|
+
ElementId = Literal["element_id"]
|
|
30
|
+
""" Element Id dimension of phased_array_xds"""
|
|
29
31
|
StationName = Literal["station_name"]
|
|
30
32
|
""" Station name dimension """
|
|
31
33
|
ReceptorLabel = Literal["receptor_label"]
|
|
@@ -56,6 +58,8 @@ EllipsoidPosLabel = Literal["ellipsoid_pos_label"]
|
|
|
56
58
|
""" Coordinate labels of geodetic earth location data (typically shape 3 and 'lon', 'lat', 'height')"""
|
|
57
59
|
CartesianPosLabel = Literal["cartesian_pos_label"]
|
|
58
60
|
""" Coordinate labels of geocentric earth location data (typically shape 3 and 'x', 'y', 'z')"""
|
|
61
|
+
CartesianPosLabelLocal = Literal["cartesian_pos_label_local"]
|
|
62
|
+
""" Coordinate labels for phased array elements positions relative to their parent station position; defined in a station-local frame (typically shape 3 and 'p', 'q', 'r')"""
|
|
59
63
|
nPolynomial = Literal["n_polynomial"]
|
|
60
64
|
""" For data that is represented as variable in time using Taylor expansion """
|
|
61
65
|
PolyTerm = Literal["poly_term"]
|
|
@@ -76,9 +80,12 @@ SkyCoord = Literal["sky_coord"]
|
|
|
76
80
|
SpectralCoord = Literal["spectral_coord"]
|
|
77
81
|
Location = Literal["location"]
|
|
78
82
|
Doppler = Literal["doppler"]
|
|
79
|
-
|
|
83
|
+
RotationMatrix = Literal["rotation_matrix"]
|
|
80
84
|
|
|
81
85
|
# Units of quantities and measures
|
|
86
|
+
UnitsUndimensioned = list[
|
|
87
|
+
Literal["undimensioned"]
|
|
88
|
+
] # name consistent with casacore measures
|
|
82
89
|
UnitsSeconds = list[Literal["s"]]
|
|
83
90
|
UnitsHertz = list[Literal["Hz"]]
|
|
84
91
|
UnitsMeters = list[Literal["m"]]
|
|
@@ -562,6 +569,7 @@ AllowedLocationCoordinateSystems = Literal[
|
|
|
562
569
|
"geodetic",
|
|
563
570
|
"planetodetic",
|
|
564
571
|
"orbital",
|
|
572
|
+
"topocentric",
|
|
565
573
|
]
|
|
566
574
|
|
|
567
575
|
|
|
@@ -2217,3 +2225,98 @@ class SpectrumXds:
|
|
|
2217
2225
|
"""The channel bandwidth that includes the effects of missing data."""
|
|
2218
2226
|
FREQUENCY_CENTROID: Optional[Dataof[FrequencyCentroidArray]] = None
|
|
2219
2227
|
"""Includes the effects of missing data unlike ``frequency``."""
|
|
2228
|
+
|
|
2229
|
+
|
|
2230
|
+
@xarray_dataarray_schema
|
|
2231
|
+
class PhasedArrayElementOffsetArray:
|
|
2232
|
+
"""
|
|
2233
|
+
Schema for PHASED_ARRAY_ELEMENT_OFFSET.
|
|
2234
|
+
"""
|
|
2235
|
+
|
|
2236
|
+
data: Data[
|
|
2237
|
+
tuple[AntennaName, CartesianPosLabelLocal, ElementId],
|
|
2238
|
+
float,
|
|
2239
|
+
]
|
|
2240
|
+
|
|
2241
|
+
units: Attr[list[Literal["m"]]]
|
|
2242
|
+
|
|
2243
|
+
type: Attr[Location]
|
|
2244
|
+
""" Measure type. Should be ``"location"``."""
|
|
2245
|
+
|
|
2246
|
+
coordinate_system: Attr[Literal["topocentric"]]
|
|
2247
|
+
"""
|
|
2248
|
+
Coordinate system in which the element offsets are expressed.
|
|
2249
|
+
Should be ``"topocentric"``.
|
|
2250
|
+
"""
|
|
2251
|
+
|
|
2252
|
+
origin: Attr[Literal["ANTENNA_POSITION"]]
|
|
2253
|
+
""" Origin of the coordinate system. Should be ``"ANTENNA_POSITION"``."""
|
|
2254
|
+
|
|
2255
|
+
|
|
2256
|
+
@xarray_dataarray_schema
|
|
2257
|
+
class PhasedArrayCoordinateAxesArray:
|
|
2258
|
+
"""
|
|
2259
|
+
Schema for PHASED_ARRAY_COORDINATE_AXES
|
|
2260
|
+
"""
|
|
2261
|
+
|
|
2262
|
+
data: Data[tuple[AntennaName, CartesianPosLabelLocal, CartesianPosLabel], float]
|
|
2263
|
+
|
|
2264
|
+
units: Attr[UnitsUndimensioned]
|
|
2265
|
+
|
|
2266
|
+
type: Attr[RotationMatrix]
|
|
2267
|
+
""" Measure type. Should be ``"rotation_matrix"``."""
|
|
2268
|
+
|
|
2269
|
+
|
|
2270
|
+
@xarray_dataset_schema
|
|
2271
|
+
class PhasedArrayXds:
|
|
2272
|
+
"""
|
|
2273
|
+
Phased array dataset: define stations made of multiple receiver elements.
|
|
2274
|
+
"""
|
|
2275
|
+
|
|
2276
|
+
# Coordinates
|
|
2277
|
+
antenna_name: Coordof[AntennaNameArray]
|
|
2278
|
+
""" Antenna name """
|
|
2279
|
+
|
|
2280
|
+
element_id: Coord[ElementId, Union[numpy.int64, numpy.int32]]
|
|
2281
|
+
""" Element Id within a station/antenna """
|
|
2282
|
+
|
|
2283
|
+
receptor_label: Coord[ReceptorLabel, str]
|
|
2284
|
+
""" Names of receptors, i.e. polarization hands. """
|
|
2285
|
+
|
|
2286
|
+
polarization_type: Coord[tuple[AntennaName, ReceptorLabel], str]
|
|
2287
|
+
""" Polarization type to which each receptor responds (e.g. ”R”,”L”,”X” or ”Y”).
|
|
2288
|
+
This is the receptor polarization type as recorded in the final correlated data (e.g. ”RR”); i.e.
|
|
2289
|
+
as measured after all polarization combiners. ['X','Y'], ['R','L'] """
|
|
2290
|
+
|
|
2291
|
+
cartesian_pos_label: Coord[CartesianPosLabel, str]
|
|
2292
|
+
""" (x,y,z) - either cartesian or ellipsoid """
|
|
2293
|
+
|
|
2294
|
+
cartesian_pos_label_local: Coord[CartesianPosLabelLocal, str]
|
|
2295
|
+
""" (p,q,r) - cartesian station-local frame of reference """
|
|
2296
|
+
|
|
2297
|
+
# Data variables
|
|
2298
|
+
PHASED_ARRAY_COORDINATE_AXES: Dataof[PhasedArrayCoordinateAxesArray]
|
|
2299
|
+
"""
|
|
2300
|
+
3x3 Rotation M such that X_geo = M X_local.
|
|
2301
|
+
Used to convert PHASED_ARRAY_ELEMENT_OFFSET coordinates from a station-local
|
|
2302
|
+
frame to a geocentric frame.
|
|
2303
|
+
"""
|
|
2304
|
+
|
|
2305
|
+
PHASED_ARRAY_ELEMENT_OFFSET: Dataof[PhasedArrayElementOffsetArray]
|
|
2306
|
+
"""
|
|
2307
|
+
Offsets of each array element from its parent station position, expressed
|
|
2308
|
+
in a station-local frame. Station positions are stored in
|
|
2309
|
+
antenna_xds.ANTENNA_POSITION.
|
|
2310
|
+
"""
|
|
2311
|
+
|
|
2312
|
+
PHASED_ARRAY_ELEMENT_FLAG: Data[tuple[AntennaName, ReceptorLabel, ElementId], bool]
|
|
2313
|
+
"""
|
|
2314
|
+
Boolean flag set to True if the data from a given polarisation receptor of a station element
|
|
2315
|
+
should be ignored.
|
|
2316
|
+
"""
|
|
2317
|
+
|
|
2318
|
+
# Attributes
|
|
2319
|
+
type: Attr[Literal["phased_array"]]
|
|
2320
|
+
"""
|
|
2321
|
+
Type of dataset. Expected to be ``phased_array``
|
|
2322
|
+
"""
|
|
@@ -628,14 +628,15 @@ def check_datatree(
|
|
|
628
628
|
continue
|
|
629
629
|
|
|
630
630
|
# Look up schema
|
|
631
|
-
|
|
631
|
+
typ = node.attrs.get("type")
|
|
632
|
+
schema = _DATASET_TYPES.get(typ)
|
|
632
633
|
if schema is None:
|
|
633
634
|
issues.add(
|
|
634
635
|
SchemaIssue(
|
|
635
636
|
[("", xds_name)],
|
|
636
637
|
message="Unknown dataset type!",
|
|
637
638
|
found=typ,
|
|
638
|
-
expected=
|
|
639
|
+
expected=None,
|
|
639
640
|
)
|
|
640
641
|
)
|
|
641
642
|
continue
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xradio
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.53
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/_tables/load_main_table.py
RENAMED
|
File without changes
|
|
File without changes
|
{xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/_tables/read_main_table.py
RENAMED
|
File without changes
|
{xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/_tables/read_subtables.py
RENAMED
|
File without changes
|
{xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/_tables/table_query.py
RENAMED
|
File without changes
|
|
File without changes
|
{xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/_tables/write_exp_api.py
RENAMED
|
File without changes
|
|
File without changes
|
{xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/create_antenna_xds.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/msv2_to_msv4_meta.py
RENAMED
|
File without changes
|
|
File without changes
|
{xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/optimised_functions.py
RENAMED
|
File without changes
|
{xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/_utils/_msv2/partition_queries.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{xradio-0.0.52 → xradio-0.0.53}/src/xradio/measurement_set/convert_msv2_to_processing_set.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|