xradio 0.0.55__py3-none-any.whl → 0.0.58__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 (64) hide show
  1. xradio/__init__.py +2 -2
  2. xradio/_utils/_casacore/casacore_from_casatools.py +1001 -0
  3. xradio/_utils/_casacore/tables.py +6 -1
  4. xradio/_utils/coord_math.py +22 -23
  5. xradio/_utils/dict_helpers.py +76 -11
  6. xradio/_utils/schema.py +5 -2
  7. xradio/_utils/zarr/common.py +1 -73
  8. xradio/image/_util/_casacore/common.py +11 -3
  9. xradio/image/_util/_casacore/xds_from_casacore.py +59 -35
  10. xradio/image/_util/_casacore/xds_to_casacore.py +47 -16
  11. xradio/image/_util/_fits/xds_from_fits.py +172 -77
  12. xradio/image/_util/casacore.py +9 -4
  13. xradio/image/_util/common.py +4 -4
  14. xradio/image/_util/image_factory.py +8 -8
  15. xradio/image/image.py +45 -5
  16. xradio/measurement_set/__init__.py +19 -9
  17. xradio/measurement_set/_utils/__init__.py +1 -3
  18. xradio/measurement_set/_utils/_msv2/__init__.py +0 -0
  19. xradio/measurement_set/_utils/_msv2/_tables/read.py +35 -90
  20. xradio/measurement_set/_utils/_msv2/_tables/read_main_table.py +6 -686
  21. xradio/measurement_set/_utils/_msv2/_tables/table_query.py +13 -3
  22. xradio/measurement_set/_utils/_msv2/conversion.py +129 -145
  23. xradio/measurement_set/_utils/_msv2/create_antenna_xds.py +9 -16
  24. xradio/measurement_set/_utils/_msv2/create_field_and_source_xds.py +125 -221
  25. xradio/measurement_set/_utils/_msv2/msv2_to_msv4_meta.py +1 -2
  26. xradio/measurement_set/_utils/_msv2/msv4_info_dicts.py +13 -8
  27. xradio/measurement_set/_utils/_msv2/msv4_sub_xdss.py +27 -72
  28. xradio/measurement_set/_utils/_msv2/partition_queries.py +5 -262
  29. xradio/measurement_set/_utils/_msv2/subtables.py +0 -107
  30. xradio/measurement_set/_utils/_utils/interpolate.py +60 -0
  31. xradio/measurement_set/_utils/_zarr/encoding.py +2 -7
  32. xradio/measurement_set/convert_msv2_to_processing_set.py +0 -2
  33. xradio/measurement_set/load_processing_set.py +2 -2
  34. xradio/measurement_set/measurement_set_xdt.py +14 -14
  35. xradio/measurement_set/open_processing_set.py +1 -3
  36. xradio/measurement_set/processing_set_xdt.py +41 -835
  37. xradio/measurement_set/schema.py +96 -123
  38. xradio/schema/check.py +91 -97
  39. xradio/schema/dataclass.py +159 -22
  40. xradio/schema/export.py +99 -0
  41. xradio/schema/metamodel.py +51 -16
  42. xradio/schema/typing.py +5 -5
  43. {xradio-0.0.55.dist-info → xradio-0.0.58.dist-info}/METADATA +43 -11
  44. xradio-0.0.58.dist-info/RECORD +65 -0
  45. {xradio-0.0.55.dist-info → xradio-0.0.58.dist-info}/WHEEL +1 -1
  46. xradio/image/_util/fits.py +0 -13
  47. xradio/measurement_set/_utils/_msv2/_tables/load.py +0 -63
  48. xradio/measurement_set/_utils/_msv2/_tables/load_main_table.py +0 -487
  49. xradio/measurement_set/_utils/_msv2/_tables/read_subtables.py +0 -395
  50. xradio/measurement_set/_utils/_msv2/_tables/write.py +0 -320
  51. xradio/measurement_set/_utils/_msv2/_tables/write_exp_api.py +0 -385
  52. xradio/measurement_set/_utils/_msv2/chunks.py +0 -115
  53. xradio/measurement_set/_utils/_msv2/descr.py +0 -165
  54. xradio/measurement_set/_utils/_msv2/msv2_msv3.py +0 -7
  55. xradio/measurement_set/_utils/_msv2/partitions.py +0 -392
  56. xradio/measurement_set/_utils/_utils/cds.py +0 -40
  57. xradio/measurement_set/_utils/_utils/xds_helper.py +0 -404
  58. xradio/measurement_set/_utils/_zarr/read.py +0 -263
  59. xradio/measurement_set/_utils/_zarr/write.py +0 -329
  60. xradio/measurement_set/_utils/msv2.py +0 -106
  61. xradio/measurement_set/_utils/zarr.py +0 -133
  62. xradio-0.0.55.dist-info/RECORD +0 -77
  63. {xradio-0.0.55.dist-info → xradio-0.0.58.dist-info}/licenses/LICENSE.txt +0 -0
  64. {xradio-0.0.55.dist-info → xradio-0.0.58.dist-info}/top_level.txt +0 -0
@@ -1,392 +0,0 @@
1
- import toolviper.utils.logger as logger
2
- from typing import Any, Dict, List, Tuple, Union
3
-
4
- import numpy as np
5
- import xarray as xr
6
-
7
- from .msv2_msv3 import ignore_msv2_cols
8
- from .partition_queries import (
9
- make_partition_ids_by_ddi_intent,
10
- )
11
- from .subtables import subt_rename_ids, add_pointing_to_partition
12
- from .descr import describe_ms
13
- from ._tables.read import load_generic_table, make_freq_attrs
14
- from ._tables.read_main_table import read_flat_main_table, read_expanded_main_table
15
- from .._utils.partition_attrs import add_partition_attrs
16
- from .._utils.xds_helper import expand_xds, make_coords, optimal_chunking
17
-
18
-
19
- PartitionKey = Tuple[Any, ...]
20
- VisSetMetaInfo = Dict[str, xr.Dataset]
21
- VisSetPartitions = Dict[PartitionKey, xr.Dataset]
22
-
23
-
24
- def make_spw_names_by_ddi(ddi_xds: xr.Dataset, spw_xds: xr.Dataset) -> Dict[int, str]:
25
- spw_ids_by_ddi = ddi_xds.SPECTRAL_WINDOW_ID[ddi_xds.row].values
26
- spw_names = spw_xds.NAME[spw_ids_by_ddi].values
27
- return {ddi: spw_names[ddi] for ddi in np.arange(0, len(spw_names))}
28
-
29
-
30
- def split_intents(intents: str):
31
- """
32
- Make a dict with two scan / subscan levels of intents from an
33
- intent string from the STATE/OBS_MODE of an MS.
34
-
35
- Parameters
36
- ----------
37
- intents : str
38
- intents "OBS_MODE" string from an MS/STATE row
39
-
40
- Returns
41
- -------
42
- Dict[str, list]
43
- per scan intent list of individual subscan intent strings
44
- """
45
- sub_sep = "#"
46
- if sub_sep not in intents:
47
- sub_sep = "."
48
- if sub_sep not in intents:
49
- return intents
50
-
51
- indiv = [intnt for intnt in intents.split(",")]
52
- scan_subscan_intents = {}
53
- for ind in indiv:
54
- scan = ind.split(sub_sep)
55
- if len(scan) == 1:
56
- scan = scan[0]
57
- subscan = ""
58
- elif len(scan) == 2:
59
- scan, subscan = scan
60
- if scan in scan_subscan_intents:
61
- scan_subscan_intents[scan].append(subscan)
62
- else:
63
- scan_subscan_intents[scan] = [subscan]
64
-
65
- return scan_subscan_intents
66
-
67
-
68
- def make_part_key(
69
- xds: xr.Dataset,
70
- partition_scheme: str,
71
- intent: str = "",
72
- scan_state: Union[Tuple, None] = None,
73
- ) -> PartitionKey:
74
- """
75
- Makes the key that a partition (sub)xds will have in the partitions dictionary of a cds.
76
-
77
- Parameters
78
- ----------
79
- xds : xr.Dataset
80
- partition xds with data and attrs
81
- partition_scheme : str
82
- one of the schemes supported in the read_ms_*_partitions() functions
83
- intent : str (Default value = "")
84
- partition intent
85
- scan_state : Union[Tuple, None] (Default value = None)
86
- scan/state ids, required when partition_scheme != 'ddi'
87
-
88
- Returns
89
- -------
90
- PartitionKey
91
- partition key
92
- """
93
- spw_id = xds.attrs["partition_ids"]["spw_id"]
94
- pol_setup_id = xds.attrs["partition_ids"]["pol_setup_id"]
95
-
96
- if partition_scheme == "ddi":
97
- part_key = (spw_id, pol_setup_id)
98
- elif partition_scheme == "intent":
99
- part_key = (spw_id, pol_setup_id, intent)
100
- elif partition_scheme == "scan":
101
- scan, _state = scan_state
102
- part_key = (spw_id, pol_setup_id, scan)
103
- elif partition_scheme == "scan/subscan":
104
- scan, state = scan_state
105
- part_key = (spw_id, pol_setup_id, scan, state)
106
-
107
- return part_key
108
-
109
-
110
- def read_ms_scan_subscan_partitions(
111
- infile: str,
112
- partition_scheme: str,
113
- expand: bool = False,
114
- chunks: Union[Tuple[int], List[int], None] = None,
115
- ) -> Tuple[VisSetPartitions, Dict[str, xr.Dataset], List[str]]:
116
- """
117
- partitions per scan_number/subscans
118
- (main table column SCAN_NUMBER / STATE_ID)
119
-
120
- Parameters
121
- ----------
122
- infile : str
123
- MS path (main table)
124
- partition_scheme : str
125
- this functions can do 'intent', 'scan', and 'scan/subscan'
126
- expand : bool (Default value = False)
127
- wether to use (time, baseline) dimensions rather than 1d (row)
128
- (only relevant when using the read_flat variant of read functions)
129
- chunk : Union[Tuple[int], List[int], None] (Default value = None)
130
- Dask chunking as tuple (time, baseline, chan, pol)
131
-
132
- Returns
133
- -------
134
- Tuple[VisSetPartitions, Dict[str, xr.Dataset], List[str]]
135
- a dictionary of partitions, a dict of subtable
136
- xr.Datasets to use later for metainformation, and a list of the
137
- subtables already read
138
- """
139
-
140
- spw_xds = load_generic_table(
141
- infile,
142
- "SPECTRAL_WINDOW",
143
- rename_ids=subt_rename_ids["SPECTRAL_WINDOW"],
144
- )
145
- ddi_xds = load_generic_table(infile, "DATA_DESCRIPTION")
146
-
147
- if partition_scheme == "intent":
148
- spw_names_by_ddi = make_spw_names_by_ddi(ddi_xds, spw_xds)
149
- (
150
- data_desc_id,
151
- scan_number,
152
- state_id,
153
- distinct_intents,
154
- ) = make_partition_ids_by_ddi_intent(infile, spw_names_by_ddi)
155
- else:
156
- raise ValueError("foo")
157
-
158
- ant_xds = load_generic_table(
159
- infile, "ANTENNA", rename_ids=subt_rename_ids["ANTENNA"]
160
- )
161
- pol_xds = load_generic_table(
162
- infile, "POLARIZATION", rename_ids=subt_rename_ids["POLARIZATION"]
163
- )
164
-
165
- # TODO: change to a map?
166
- partitions = {}
167
- cnt = 0
168
- for ddi, scan, state in zip(data_desc_id, scan_number, state_id):
169
- # msg_chunks = str(chunks[ddi] if type(chunks) == dict else chunks)
170
- if partition_scheme == "intent":
171
- intent = distinct_intents[cnt]
172
- cnt += 1
173
- else:
174
- intent = ""
175
-
176
- if partition_scheme == "scan":
177
- scan_state = (scan, None)
178
- else:
179
- scan_state = (scan, state)
180
- # experimenting, comparing overheads of expanded vs. flat
181
- expanded = not expand
182
- if expanded:
183
- xds, part_ids, attrs = read_expanded_main_table(
184
- infile, ddi, scan_state=scan_state, ignore_msv2_cols=ignore_msv2_cols
185
- )
186
- else:
187
- xds, part_ids, attrs = read_flat_main_table(
188
- infile,
189
- ddi,
190
- scan_state=scan_state,
191
- rowidxs=None,
192
- ignore_msv2_cols=ignore_msv2_cols,
193
- )
194
- if len(xds.sizes) == 0:
195
- continue
196
-
197
- coords = make_coords(xds, ddi, (ant_xds, ddi_xds, spw_xds, pol_xds))
198
- xds = xds.assign_coords(coords)
199
-
200
- if partition_scheme == "intent":
201
- scan_subscan_intents = split_intents(intent)
202
- attrs = dict({"scan_subscan_intents": scan_subscan_intents}, **attrs)
203
- xds = add_partition_attrs(xds, ddi, ddi_xds, part_ids, attrs)
204
-
205
- # freq dim needs to pull its units/measure info from the SPW subtable
206
- spw_id = xds.attrs["partition_ids"]["spw_id"]
207
- xds.freq.attrs.update(make_freq_attrs(spw_xds, spw_id))
208
-
209
- # expand the row dimension out to (time, baseline)
210
- if not expanded and expand:
211
- xds = expand_xds(xds)
212
-
213
- part_key = make_part_key(
214
- xds, partition_scheme, scan_state=scan_state, intent=intent
215
- )
216
- partitions[part_key] = xds
217
-
218
- subtables = {
219
- "antenna": ant_xds,
220
- "spectral_window": spw_xds,
221
- "polarization": pol_xds,
222
- }
223
-
224
- return (
225
- partitions,
226
- subtables,
227
- ["ANTENNA", "SPECTRAL_WINDOW", "POLARTIZATION", "DATA_DESCRIPTION"],
228
- )
229
-
230
-
231
- def read_ms_ddi_partitions(
232
- infile: str,
233
- expand: bool = False,
234
- rowmap: Union[dict, None] = None,
235
- chunks: Union[Tuple[int], List[int], None] = None,
236
- ) -> Tuple[VisSetPartitions, Dict[str, xr.Dataset], List[str]]:
237
- """
238
- Reads data columns from the main table into partitions defined
239
- from the DDIs. First looks into the SPECTRAL_WINDOW, POLARIZATION,
240
- DATA_DESCRIPTION tables to define the partitions.
241
-
242
- Parameters
243
- ----------
244
- infile : str
245
- input MS path
246
- expand : bool (Default value = False)
247
- redimension (row)->(time,baseline)
248
- rowmap : Union[dict, None] (Default value = None)
249
- to be removed
250
- chunks : Union[Tuple[int], List[int], None] (Default value = None)
251
- array data chunk sizes
252
-
253
- Returns
254
- -------
255
- Tuple[VisSetPartitions, Dict[str, xr.Dataset], List[str]]
256
- dictionary of partitions, dict of subtable xr.Datasets to use later
257
- for metainformation, and a list of the subtables already read
258
-
259
- """
260
- # we need the antenna, spectral window, polarization, and data description tables
261
- # to define the (sub)datasets (their dims and coords) and to process the main table
262
- ant_xds = load_generic_table(
263
- infile, "ANTENNA", rename_ids=subt_rename_ids["ANTENNA"]
264
- )
265
- spw_xds = load_generic_table(
266
- infile,
267
- "SPECTRAL_WINDOW",
268
- rename_ids=subt_rename_ids["SPECTRAL_WINDOW"],
269
- )
270
- pol_xds = load_generic_table(
271
- infile, "POLARIZATION", rename_ids=subt_rename_ids["POLARIZATION"]
272
- )
273
- ddi_xds = load_generic_table(infile, "DATA_DESCRIPTION")
274
-
275
- # each DATA_DESC_ID (ddi) is a fixed shape that may differ from others
276
- # form a list of ddis to process, each will be placed it in its own xarray dataset and partition
277
- ddis = np.arange(ddi_xds.row.shape[0]) if rowmap is None else list(rowmap.keys())
278
-
279
- # figure out the chunking for each DDI, either one fixed shape or an auto-computed one
280
- if type(chunks) is not tuple:
281
- mshape = describe_ms(infile, mode="flat", rowmap=rowmap)
282
- chunks = dict(
283
- [
284
- (
285
- ddi,
286
- optimal_chunking(
287
- didxs=chunks, chunk_size="auto", data_shape=mshape[ddi]
288
- ),
289
- )
290
- for ddi in mshape
291
- ]
292
- )
293
-
294
- partitions = {}
295
- ####################################################################
296
- # process each selected DDI from the input MS, assume a fixed shape within the ddi (should always be true)
297
- for ddi in ddis:
298
- rowidxs = None if rowmap is None else rowmap[ddi][0]
299
- chanidxs = None if rowmap is None else rowmap[ddi][1]
300
- if ((rowidxs is not None) and (len(rowidxs) == 0)) or (
301
- (chanidxs is not None) and (len(chanidxs) == 0)
302
- ):
303
- continue
304
- logger.debug(
305
- "reading DDI %i with chunking %s..."
306
- % (ddi, str(chunks[ddi] if type(chunks) is dict else chunks))
307
- )
308
-
309
- # experimenting, comparing overheads of expanded vs. flat
310
- expanded = not expand
311
- if expanded:
312
- xds, part_ids, attrs = read_expanded_main_table(
313
- infile, ddi, ignore_msv2_cols=ignore_msv2_cols
314
- )
315
- else:
316
- xds, part_ids, attrs = read_flat_main_table(
317
- infile,
318
- ddi,
319
- rowidxs=rowidxs,
320
- chunks=chunks[ddi] if type(chunks) is dict else chunks,
321
- ignore_msv2_cols=ignore_msv2_cols,
322
- )
323
- if len(xds.sizes) == 0:
324
- continue
325
-
326
- coords = make_coords(xds, ddi, (ant_xds, ddi_xds, spw_xds, pol_xds))
327
- xds = xds.assign_coords(coords)
328
-
329
- xds = add_partition_attrs(xds, ddi, ddi_xds, part_ids, attrs)
330
-
331
- # freq dim needs to pull its units/measure info from the SPW subtable
332
- spw_id = xds.attrs["partition_ids"]["spw_id"]
333
- xds.freq.attrs.update(make_freq_attrs(spw_xds, spw_id))
334
-
335
- # filter by channel selection
336
- if (chanidxs is not None) and (len(chanidxs) < len(xds.chan)):
337
- xds = xds.isel(chan=chanidxs)
338
- spw_xds["CHAN_FREQ"][
339
- ddi_xds.SPECTRAL_WINDOW_ID.values[ddi], : len(chanidxs)
340
- ] = spw_xds.CHAN_FREQ[ddi_xds.SPECTRAL_WINDOW_ID.values[ddi], chanidxs]
341
-
342
- # expand the row dimension out to (time, baseline)
343
- if not expanded and expand:
344
- xds = expand_xds(xds)
345
-
346
- part_key = make_part_key(xds, partition_scheme="ddi")
347
- partitions[part_key] = xds
348
-
349
- subtables = {
350
- "antenna": ant_xds,
351
- "spectral_window": spw_xds,
352
- "polarization": pol_xds,
353
- "data_description": ddi_xds,
354
- }
355
-
356
- return (
357
- partitions,
358
- subtables,
359
- ["ANTENNA", "SPECTRAL_WINDOW", "POLARTIZATION", "DATA_DESCRIPTION"],
360
- )
361
-
362
-
363
- def finalize_partitions(
364
- parts: Dict[str, xr.Dataset], subts: Dict[str, xr.Dataset]
365
- ) -> Dict[str, xr.Dataset]:
366
- """
367
- Once the partition datasets and the metainfo/subtable datasets
368
- have been read, add to the partitions:
369
- - pointing variables from the pointing subtable
370
-
371
- Parameters
372
- ----------
373
- parts : Dict[str, xr.Dataset]
374
- partitions as xarray datasets, as read from an MS main table
375
- subts : Dict[str, xr.Dataset]
376
- subtables of an MS read as xarray datasets
377
-
378
- Returns
379
- -------
380
- Dict[str, xr.Dataset]
381
- partitions with additions taken from subtables
382
- """
383
- if "pointing" in subts:
384
- pointing = subts["pointing"]
385
- final = {
386
- key: add_pointing_to_partition(xds, pointing)
387
- for (key, xds) in parts.items()
388
- }
389
- else:
390
- final = parts
391
-
392
- return final
@@ -1,40 +0,0 @@
1
- from dataclasses import dataclass
2
- from typing import Any, Dict, NamedTuple, Tuple
3
-
4
- import numpy as np
5
- import xarray as xr
6
-
7
- PartitionKey = Tuple[Any, ...]
8
- # for intent-ddi partitioning
9
- PartitionKeyAsNT = NamedTuple(
10
- "PartitionKey", [("spw_id", np.int32), ("pol_setup_id", np.int32), ("intent", str)]
11
- )
12
- VisSetPartitions = Dict[PartitionKey, xr.Dataset]
13
- VisSetMetainfo = Dict[str, xr.Dataset]
14
-
15
-
16
- @dataclass(frozen=True)
17
- class CASAVisSet:
18
- metainfo: VisSetMetainfo
19
- partitions: VisSetPartitions
20
- descr: str
21
-
22
- def __getitem__(self, key):
23
- return getattr(self, key)
24
-
25
- def __repr__(self):
26
- """
27
- Concise repr for CASA vis sets
28
- """
29
- class_name = type(self).__name__
30
- return (
31
- f"({class_name}\n metainfo (keys)={self.metainfo.keys()}"
32
- f"\n partitions (keys)={self.partitions.keys()}\n descr={self.descr!r})"
33
- )
34
-
35
- def _repr_html_(self):
36
- class_name = type(self).__name__
37
- return (
38
- f"({class_name}<p> <b>metainfo</b> (keys)={self.metainfo.keys()}</p><p>"
39
- f"<b>partitions</b> (keys)={self.partitions.keys()}</p><p> <b>descr</b>={self.descr!r})</p>"
40
- )