xradio 0.0.40__py3-none-any.whl → 0.0.42__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/coord_math.py +100 -0
- xradio/_utils/list_and_array.py +49 -4
- xradio/_utils/schema.py +36 -16
- xradio/image/_util/_casacore/xds_from_casacore.py +5 -5
- xradio/image/_util/_casacore/xds_to_casacore.py +12 -11
- xradio/image/_util/_fits/xds_from_fits.py +18 -17
- xradio/image/_util/_zarr/zarr_low_level.py +29 -12
- xradio/image/_util/common.py +1 -1
- xradio/image/_util/image_factory.py +1 -1
- xradio/measurement_set/__init__.py +18 -0
- xradio/measurement_set/_utils/__init__.py +5 -0
- xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/_tables/load_main_table.py +1 -1
- xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/_tables/read.py +15 -1
- xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/conversion.py +186 -84
- xradio/measurement_set/_utils/_msv2/create_antenna_xds.py +535 -0
- xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/create_field_and_source_xds.py +146 -58
- xradio/measurement_set/_utils/_msv2/msv4_info_dicts.py +203 -0
- xradio/measurement_set/_utils/_msv2/msv4_sub_xdss.py +550 -0
- xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/subtables.py +1 -1
- xradio/{vis/_vis_utils → measurement_set/_utils}/_utils/xds_helper.py +1 -1
- xradio/{vis/_vis_utils/ms.py → measurement_set/_utils/msv2.py} +4 -4
- xradio/{vis/_vis_utils → measurement_set/_utils}/zarr.py +3 -3
- xradio/{vis → measurement_set}/convert_msv2_to_processing_set.py +9 -2
- xradio/{vis → measurement_set}/load_processing_set.py +16 -20
- xradio/measurement_set/measurement_set_xds.py +83 -0
- xradio/{vis/read_processing_set.py → measurement_set/open_processing_set.py} +25 -34
- xradio/measurement_set/processing_set.py +777 -0
- xradio/measurement_set/schema.py +1979 -0
- xradio/schema/check.py +42 -22
- xradio/schema/dataclass.py +56 -6
- xradio/sphinx/__init__.py +12 -0
- xradio/sphinx/schema_table.py +351 -0
- {xradio-0.0.40.dist-info → xradio-0.0.42.dist-info}/METADATA +17 -15
- xradio-0.0.42.dist-info/RECORD +76 -0
- {xradio-0.0.40.dist-info → xradio-0.0.42.dist-info}/WHEEL +1 -1
- xradio/_utils/common.py +0 -101
- xradio/vis/__init__.py +0 -14
- xradio/vis/_processing_set.py +0 -302
- xradio/vis/_vis_utils/__init__.py +0 -5
- xradio/vis/_vis_utils/_ms/create_antenna_xds.py +0 -482
- xradio/vis/_vis_utils/_ms/msv4_infos.py +0 -0
- xradio/vis/_vis_utils/_ms/msv4_sub_xdss.py +0 -306
- xradio/vis/schema.py +0 -1102
- xradio-0.0.40.dist-info/RECORD +0 -73
- /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/_tables/load.py +0 -0
- /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/_tables/read_main_table.py +0 -0
- /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/_tables/read_subtables.py +0 -0
- /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/_tables/table_query.py +0 -0
- /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/_tables/write.py +0 -0
- /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/_tables/write_exp_api.py +0 -0
- /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/chunks.py +0 -0
- /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/descr.py +0 -0
- /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/msv2_msv3.py +0 -0
- /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/msv2_to_msv4_meta.py +0 -0
- /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/optimised_functions.py +0 -0
- /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/partition_queries.py +0 -0
- /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/partitions.py +0 -0
- /xradio/{vis/_vis_utils → measurement_set/_utils}/_utils/cds.py +0 -0
- /xradio/{vis/_vis_utils → measurement_set/_utils}/_utils/partition_attrs.py +0 -0
- /xradio/{vis/_vis_utils → measurement_set/_utils}/_utils/stokes_types.py +0 -0
- /xradio/{vis/_vis_utils → measurement_set/_utils}/_zarr/encoding.py +0 -0
- /xradio/{vis/_vis_utils → measurement_set/_utils}/_zarr/read.py +0 -0
- /xradio/{vis/_vis_utils → measurement_set/_utils}/_zarr/write.py +0 -0
- {xradio-0.0.40.dist-info → xradio-0.0.42.dist-info}/LICENSE.txt +0 -0
- {xradio-0.0.40.dist-info → xradio-0.0.42.dist-info}/top_level.txt +0 -0
|
@@ -1,306 +0,0 @@
|
|
|
1
|
-
import toolviper.utils.logger as logger
|
|
2
|
-
import time
|
|
3
|
-
from typing import Tuple, Union
|
|
4
|
-
|
|
5
|
-
import numpy as np
|
|
6
|
-
import xarray as xr
|
|
7
|
-
|
|
8
|
-
from xradio._utils.schema import (
|
|
9
|
-
column_description_casacore_to_msv4_measure,
|
|
10
|
-
convert_generic_xds_to_xradio_schema,
|
|
11
|
-
)
|
|
12
|
-
from .subtables import subt_rename_ids
|
|
13
|
-
from ._tables.read import make_taql_where_between_min_max, load_generic_table
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def interpolate_to_time(
|
|
17
|
-
xds: xr.Dataset,
|
|
18
|
-
interp_time: Union[xr.DataArray, None],
|
|
19
|
-
message_prefix: str,
|
|
20
|
-
time_name: str = "time",
|
|
21
|
-
) -> xr.Dataset:
|
|
22
|
-
"""
|
|
23
|
-
Interpolate the time coordinate of the input xarray dataset to the
|
|
24
|
-
a data array. This can be used for example to interpolate a pointing_xds
|
|
25
|
-
to the time coord of the (main) MSv4, or similarly the ephemeris
|
|
26
|
-
data variables of a field_and_source_xds.
|
|
27
|
-
|
|
28
|
-
Uses interpolation method "linear", unless the source number of points is
|
|
29
|
-
1 in which case "nearest" is used, to avoid divide-by-zero issues.
|
|
30
|
-
|
|
31
|
-
Parameters:
|
|
32
|
-
----------
|
|
33
|
-
xds : xr.Dataset
|
|
34
|
-
Xarray dataset to interpolate (presumably a pointing_xds or an xds of
|
|
35
|
-
ephemeris variables)
|
|
36
|
-
interp_time : Union[xr.DataArray, None]
|
|
37
|
-
Time axis to interpolate the dataset to (usually main MSv4 time)
|
|
38
|
-
message_prefix: str
|
|
39
|
-
A prefix for info/debug/etc. messages
|
|
40
|
-
|
|
41
|
-
Returns:
|
|
42
|
-
-------
|
|
43
|
-
interpolated_xds : xr.Dataset
|
|
44
|
-
xarray dataset with time axis interpolated to interp_time.
|
|
45
|
-
"""
|
|
46
|
-
if interp_time is not None:
|
|
47
|
-
points_before = xds[time_name].size
|
|
48
|
-
if points_before > 1:
|
|
49
|
-
method = "linear"
|
|
50
|
-
else:
|
|
51
|
-
method = "nearest"
|
|
52
|
-
xds = xds.interp({time_name: interp_time}, method=method, assume_sorted=True)
|
|
53
|
-
points_after = xds[time_name].size
|
|
54
|
-
logger.debug(
|
|
55
|
-
f"{message_prefix}: interpolating the time coordinate "
|
|
56
|
-
f"from {points_before} to {points_after} points"
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
return xds
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def create_weather_xds(in_file: str):
|
|
63
|
-
"""
|
|
64
|
-
Creates a Weather Xarray Dataset from a MS v2 WEATHER table.
|
|
65
|
-
|
|
66
|
-
Parameters
|
|
67
|
-
----------
|
|
68
|
-
in_file : str
|
|
69
|
-
Input MS name.
|
|
70
|
-
|
|
71
|
-
Returns
|
|
72
|
-
-------
|
|
73
|
-
xr.Dataset
|
|
74
|
-
Weather Xarray Dataset.
|
|
75
|
-
"""
|
|
76
|
-
|
|
77
|
-
dims_station_time = ["station_id", "time"]
|
|
78
|
-
to_new_data_variables = {
|
|
79
|
-
"H20": ["H2O", dims_station_time],
|
|
80
|
-
"IONOS_ELECTRON": ["IONOS_ELECTRON", dims_station_time],
|
|
81
|
-
"PRESSURE": ["PRESSURE", dims_station_time],
|
|
82
|
-
"REL_HUMIDITY": ["REL_HUMIDITY", dims_station_time],
|
|
83
|
-
"TEMPERATURE": ["TEMPERATURE", dims_station_time],
|
|
84
|
-
"DEW_POINT": ["DEW_POINT", dims_station_time],
|
|
85
|
-
"WIND_DIRECTION": ["WIND_DIRECTION", dims_station_time],
|
|
86
|
-
"WIND_SPEED": ["WIND_SPEED", dims_station_time],
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
to_new_coords = {
|
|
90
|
-
"ANTENNA_ID": ["station_id", ["station_id"]],
|
|
91
|
-
"TIME": ["time", ["time"]],
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
# Read WEATHER table into a Xarray Dataset.
|
|
95
|
-
try:
|
|
96
|
-
generic_weather_xds = load_generic_table(
|
|
97
|
-
in_file,
|
|
98
|
-
"WEATHER",
|
|
99
|
-
rename_ids=subt_rename_ids["WEATHER"],
|
|
100
|
-
)
|
|
101
|
-
except ValueError as _exc:
|
|
102
|
-
return None
|
|
103
|
-
|
|
104
|
-
weather_xds = xr.Dataset(attrs={"type": "weather"})
|
|
105
|
-
weather_xds = convert_generic_xds_to_xradio_schema(
|
|
106
|
-
generic_weather_xds, weather_xds, to_new_data_variables, to_new_coords
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
# correct expected types
|
|
110
|
-
weather_xds["station_id"] = weather_xds["station_id"].astype(np.int64)
|
|
111
|
-
|
|
112
|
-
return weather_xds
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
def correct_generic_pointing_xds(
|
|
116
|
-
generic_pointing_xds: xr.Dataset, to_new_data_variables: dict[str, list]
|
|
117
|
-
) -> xr.Dataset:
|
|
118
|
-
"""
|
|
119
|
-
Takes a (generic) pointing_xds as read from a POINTING subtable of an MSv2
|
|
120
|
-
and tries to correct several deviations from the MSv2 specs seen in
|
|
121
|
-
common test data.
|
|
122
|
-
The problems fixed here include wrong dimensions:
|
|
123
|
-
- for example transposed dimensions with respect to the MSv2 specs (output
|
|
124
|
-
from CASA simulator),
|
|
125
|
-
- missing/additional unexpected dimensions when some of the columns are
|
|
126
|
-
empty (in the sense of "empty casacore cells").
|
|
127
|
-
|
|
128
|
-
This function modifies the data arrays of the data vars affected by such
|
|
129
|
-
issues.
|
|
130
|
-
|
|
131
|
-
Parameters
|
|
132
|
-
----------
|
|
133
|
-
generic_pointing_xds: xr.Dataset
|
|
134
|
-
The generic pointing dataset (loaded from MSv2) to be fixed
|
|
135
|
-
to_new_data_variables: dict
|
|
136
|
-
The dict used for convert_generic_xds_to_xradio_schema, which gives all
|
|
137
|
-
the data variables relevant for the final MSv4 dataset.
|
|
138
|
-
|
|
139
|
-
Returns:
|
|
140
|
-
--------
|
|
141
|
-
xr.Dataset
|
|
142
|
-
Corrected dataset with dimensions conforming to MSv2 specs.
|
|
143
|
-
"""
|
|
144
|
-
|
|
145
|
-
correct_pointing_xds = generic_pointing_xds.copy()
|
|
146
|
-
|
|
147
|
-
for key in generic_pointing_xds:
|
|
148
|
-
if key in to_new_data_variables:
|
|
149
|
-
data_var_name = to_new_data_variables[key]
|
|
150
|
-
# Corrects dim sizes of "empty cell" variables, such as empty DIRECTION, TARGET, etc.
|
|
151
|
-
if (
|
|
152
|
-
"dim_2" in generic_pointing_xds.sizes
|
|
153
|
-
and generic_pointing_xds.sizes["dim_2"] == 0
|
|
154
|
-
):
|
|
155
|
-
# When all direction variables are "empty"
|
|
156
|
-
data_var_data = xr.DataArray(
|
|
157
|
-
[[[[np.nan, np.nan]]]],
|
|
158
|
-
dims=generic_pointing_xds.dims,
|
|
159
|
-
).isel(n_polynomial=0, drop=True)
|
|
160
|
-
correct_pointing_xds[data_var_name].data = data_var_data
|
|
161
|
-
|
|
162
|
-
elif (
|
|
163
|
-
"dir" in generic_pointing_xds.sizes
|
|
164
|
-
and generic_pointing_xds.sizes["dir"] == 0
|
|
165
|
-
):
|
|
166
|
-
# When some direction variables are "empty" but some are populated properly
|
|
167
|
-
if "dim_2" in generic_pointing_xds[key].sizes:
|
|
168
|
-
data_var_data = xr.DataArray(
|
|
169
|
-
generic_pointing_xds[key].values,
|
|
170
|
-
dims=generic_pointing_xds[key].dims,
|
|
171
|
-
)
|
|
172
|
-
else:
|
|
173
|
-
shape = tuple(
|
|
174
|
-
generic_pointing_xds.sizes[dim]
|
|
175
|
-
for dim in ["TIME", "ANTENNA_ID"]
|
|
176
|
-
) + (2,)
|
|
177
|
-
data_var_data = xr.DataArray(
|
|
178
|
-
np.full(shape, np.nan),
|
|
179
|
-
dims=generic_pointing_xds[key].dims,
|
|
180
|
-
)
|
|
181
|
-
correct_pointing_xds[data_var_name].data = data_var_data
|
|
182
|
-
|
|
183
|
-
return correct_pointing_xds
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
def create_pointing_xds(
|
|
187
|
-
in_file: str,
|
|
188
|
-
ant_xds_name_ids: xr.DataArray,
|
|
189
|
-
time_min_max: Union[Tuple[np.float64, np.float64], None],
|
|
190
|
-
interp_time: Union[xr.DataArray, None] = None,
|
|
191
|
-
) -> xr.Dataset:
|
|
192
|
-
"""
|
|
193
|
-
Creates a Pointing Xarray Dataset from an MS v2 POINTING (sub)table.
|
|
194
|
-
|
|
195
|
-
WIP: details of a few direction variables (and possibly moving some to attributes) to be
|
|
196
|
-
settled (see MSv4 spreadsheet).
|
|
197
|
-
|
|
198
|
-
Parameters
|
|
199
|
-
----------
|
|
200
|
-
in_file : str
|
|
201
|
-
Input MS name.
|
|
202
|
-
ant_xds_name_ids : xr.Dataset
|
|
203
|
-
antenna_name data array from antenna_xds, with name/id information
|
|
204
|
-
time_min_max : tuple
|
|
205
|
-
min / max times values to constrain loading (from the TIME column)
|
|
206
|
-
interp_time : Union[xr.DataArray, None] (Default value = None)
|
|
207
|
-
interpolate time to this (presumably main dataset time)
|
|
208
|
-
|
|
209
|
-
Returns
|
|
210
|
-
-------
|
|
211
|
-
xr.Dataset
|
|
212
|
-
Pointing Xarray dataset
|
|
213
|
-
"""
|
|
214
|
-
start = time.time()
|
|
215
|
-
|
|
216
|
-
time_ant_dims = ["time", "antenna_name"]
|
|
217
|
-
time_ant_dir_dims = time_ant_dims + ["sky_dir_label"]
|
|
218
|
-
to_new_data_variables = {
|
|
219
|
-
"DIRECTION": ["BEAM_POINTING", time_ant_dir_dims],
|
|
220
|
-
"ENCODER": ["DISH_MEASURED_POINTING", time_ant_dir_dims],
|
|
221
|
-
# => attribute?
|
|
222
|
-
"TARGET": ["TARGET", time_ant_dir_dims],
|
|
223
|
-
"POINTING_OFFSET": ["POINTING_OFFSET", time_ant_dir_dims],
|
|
224
|
-
"SOURCE_OFFSET": ["SOURCE_OFFSET", time_ant_dir_dims],
|
|
225
|
-
"OVER_THE_TOP": ["OVER_THE_TOP", time_ant_dims],
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
to_new_coords = {
|
|
229
|
-
"TIME": ["time", ["time"]],
|
|
230
|
-
# "ANTENNA_ID": ["antenna_name", ["antenna_name"]],
|
|
231
|
-
"dim_2": ["sky_dir_label", ["sky_dir_label"]],
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
taql_time_range = make_taql_where_between_min_max(
|
|
235
|
-
time_min_max, in_file, "POINTING", "TIME"
|
|
236
|
-
)
|
|
237
|
-
|
|
238
|
-
if taql_time_range is None:
|
|
239
|
-
taql_where = f"WHERE (ANTENNA_ID IN [{','.join(map(str, ant_xds_name_ids.antenna_id.values))}])"
|
|
240
|
-
else:
|
|
241
|
-
taql_where = (
|
|
242
|
-
taql_time_range
|
|
243
|
-
+ f" AND (ANTENNA_ID IN [{','.join(map(str, ant_xds_name_ids.antenna_id.values))}])"
|
|
244
|
-
)
|
|
245
|
-
# Read POINTING table into a Xarray Dataset.
|
|
246
|
-
generic_pointing_xds = load_generic_table(
|
|
247
|
-
in_file,
|
|
248
|
-
"POINTING",
|
|
249
|
-
rename_ids=subt_rename_ids["POINTING"],
|
|
250
|
-
taql_where=taql_where,
|
|
251
|
-
)
|
|
252
|
-
|
|
253
|
-
if not generic_pointing_xds.data_vars:
|
|
254
|
-
# apparently empty MS/POINTING table => produce empty xds
|
|
255
|
-
return xr.Dataset()
|
|
256
|
-
|
|
257
|
-
# Checking a simple way of using only the one single coefficient of the polynomials
|
|
258
|
-
if "n_polynomial" in generic_pointing_xds.sizes:
|
|
259
|
-
size = generic_pointing_xds.sizes["n_polynomial"]
|
|
260
|
-
if size == 1:
|
|
261
|
-
generic_pointing_xds = generic_pointing_xds.sel({"n_polynomial": 0})
|
|
262
|
-
|
|
263
|
-
generic_pointing_xds = correct_generic_pointing_xds(
|
|
264
|
-
generic_pointing_xds, to_new_data_variables
|
|
265
|
-
)
|
|
266
|
-
|
|
267
|
-
pointing_xds = xr.Dataset(attrs={"type": "pointing"})
|
|
268
|
-
coords = {
|
|
269
|
-
"antenna_name": ant_xds_name_ids.sel(
|
|
270
|
-
antenna_id=generic_pointing_xds["ANTENNA_ID"]
|
|
271
|
-
).data,
|
|
272
|
-
"sky_dir_label": ["ra", "dec"],
|
|
273
|
-
}
|
|
274
|
-
pointing_xds = pointing_xds.assign_coords(coords)
|
|
275
|
-
pointing_xds = convert_generic_xds_to_xradio_schema(
|
|
276
|
-
generic_pointing_xds, pointing_xds, to_new_data_variables, to_new_coords
|
|
277
|
-
)
|
|
278
|
-
|
|
279
|
-
# Add attributes specific to pointing_xds
|
|
280
|
-
if "TRACKING" in generic_pointing_xds.data_vars:
|
|
281
|
-
pointing_xds.attrs["tracking"] = generic_pointing_xds.data_vars[
|
|
282
|
-
"TRACKING"
|
|
283
|
-
].values[0, 0]
|
|
284
|
-
|
|
285
|
-
# Move target from data_vars to attributes?
|
|
286
|
-
move_target_as_attr = False
|
|
287
|
-
if move_target_as_attr:
|
|
288
|
-
pointing_column_descriptions = generic_pointing_xds.attrs["other"]["msv2"][
|
|
289
|
-
"ctds_attrs"
|
|
290
|
-
]["column_descriptions"]
|
|
291
|
-
|
|
292
|
-
target = generic_pointing_xds.data_vars["TARGET"]
|
|
293
|
-
pointing_xds.attrs["target"] = {
|
|
294
|
-
"dims": ["sky_dir_label"],
|
|
295
|
-
"data": target.values[0, 0].tolist(),
|
|
296
|
-
"attrs": column_description_casacore_to_msv4_measure(
|
|
297
|
-
pointing_column_descriptions["TARGET"]
|
|
298
|
-
),
|
|
299
|
-
}
|
|
300
|
-
# TODO: move also source_offset/pointing_offset from data_vars to attrs?
|
|
301
|
-
|
|
302
|
-
pointing_xds = interpolate_to_time(pointing_xds, interp_time, "pointing_xds")
|
|
303
|
-
|
|
304
|
-
logger.debug(f"create_pointing_xds() execution time {time.time() - start:0.2f} s")
|
|
305
|
-
|
|
306
|
-
return pointing_xds
|