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.
Files changed (65) hide show
  1. xradio/_utils/coord_math.py +100 -0
  2. xradio/_utils/list_and_array.py +49 -4
  3. xradio/_utils/schema.py +36 -16
  4. xradio/image/_util/_casacore/xds_from_casacore.py +5 -5
  5. xradio/image/_util/_casacore/xds_to_casacore.py +12 -11
  6. xradio/image/_util/_fits/xds_from_fits.py +18 -17
  7. xradio/image/_util/_zarr/zarr_low_level.py +29 -12
  8. xradio/image/_util/common.py +1 -1
  9. xradio/image/_util/image_factory.py +1 -1
  10. xradio/measurement_set/__init__.py +18 -0
  11. xradio/measurement_set/_utils/__init__.py +5 -0
  12. xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/_tables/load_main_table.py +1 -1
  13. xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/_tables/read.py +15 -1
  14. xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/conversion.py +186 -84
  15. xradio/measurement_set/_utils/_msv2/create_antenna_xds.py +535 -0
  16. xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/create_field_and_source_xds.py +146 -58
  17. xradio/measurement_set/_utils/_msv2/msv4_info_dicts.py +203 -0
  18. xradio/measurement_set/_utils/_msv2/msv4_sub_xdss.py +550 -0
  19. xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/subtables.py +1 -1
  20. xradio/{vis/_vis_utils → measurement_set/_utils}/_utils/xds_helper.py +1 -1
  21. xradio/{vis/_vis_utils/ms.py → measurement_set/_utils/msv2.py} +4 -4
  22. xradio/{vis/_vis_utils → measurement_set/_utils}/zarr.py +3 -3
  23. xradio/{vis → measurement_set}/convert_msv2_to_processing_set.py +9 -2
  24. xradio/{vis → measurement_set}/load_processing_set.py +16 -20
  25. xradio/measurement_set/measurement_set_xds.py +83 -0
  26. xradio/{vis/read_processing_set.py → measurement_set/open_processing_set.py} +25 -34
  27. xradio/measurement_set/processing_set.py +777 -0
  28. xradio/measurement_set/schema.py +1979 -0
  29. xradio/schema/check.py +42 -22
  30. xradio/schema/dataclass.py +56 -6
  31. xradio/sphinx/__init__.py +12 -0
  32. xradio/sphinx/schema_table.py +351 -0
  33. {xradio-0.0.40.dist-info → xradio-0.0.42.dist-info}/METADATA +17 -15
  34. xradio-0.0.42.dist-info/RECORD +76 -0
  35. {xradio-0.0.40.dist-info → xradio-0.0.42.dist-info}/WHEEL +1 -1
  36. xradio/_utils/common.py +0 -101
  37. xradio/vis/__init__.py +0 -14
  38. xradio/vis/_processing_set.py +0 -302
  39. xradio/vis/_vis_utils/__init__.py +0 -5
  40. xradio/vis/_vis_utils/_ms/create_antenna_xds.py +0 -482
  41. xradio/vis/_vis_utils/_ms/msv4_infos.py +0 -0
  42. xradio/vis/_vis_utils/_ms/msv4_sub_xdss.py +0 -306
  43. xradio/vis/schema.py +0 -1102
  44. xradio-0.0.40.dist-info/RECORD +0 -73
  45. /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/_tables/load.py +0 -0
  46. /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/_tables/read_main_table.py +0 -0
  47. /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/_tables/read_subtables.py +0 -0
  48. /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/_tables/table_query.py +0 -0
  49. /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/_tables/write.py +0 -0
  50. /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/_tables/write_exp_api.py +0 -0
  51. /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/chunks.py +0 -0
  52. /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/descr.py +0 -0
  53. /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/msv2_msv3.py +0 -0
  54. /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/msv2_to_msv4_meta.py +0 -0
  55. /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/optimised_functions.py +0 -0
  56. /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/partition_queries.py +0 -0
  57. /xradio/{vis/_vis_utils/_ms → measurement_set/_utils/_msv2}/partitions.py +0 -0
  58. /xradio/{vis/_vis_utils → measurement_set/_utils}/_utils/cds.py +0 -0
  59. /xradio/{vis/_vis_utils → measurement_set/_utils}/_utils/partition_attrs.py +0 -0
  60. /xradio/{vis/_vis_utils → measurement_set/_utils}/_utils/stokes_types.py +0 -0
  61. /xradio/{vis/_vis_utils → measurement_set/_utils}/_zarr/encoding.py +0 -0
  62. /xradio/{vis/_vis_utils → measurement_set/_utils}/_zarr/read.py +0 -0
  63. /xradio/{vis/_vis_utils → measurement_set/_utils}/_zarr/write.py +0 -0
  64. {xradio-0.0.40.dist-info → xradio-0.0.42.dist-info}/LICENSE.txt +0 -0
  65. {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