xradio 0.0.48__py3-none-any.whl → 0.0.50__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/__init__.py +1 -0
- xradio/_utils/dict_helpers.py +69 -2
- xradio/image/_util/__init__.py +0 -3
- xradio/image/_util/_casacore/common.py +0 -13
- xradio/image/_util/_casacore/xds_from_casacore.py +102 -97
- xradio/image/_util/_casacore/xds_to_casacore.py +36 -24
- xradio/image/_util/_fits/xds_from_fits.py +81 -36
- xradio/image/_util/_zarr/zarr_low_level.py +3 -3
- xradio/image/_util/casacore.py +7 -5
- xradio/image/_util/common.py +13 -26
- xradio/image/_util/image_factory.py +143 -191
- xradio/image/image.py +10 -59
- xradio/measurement_set/__init__.py +11 -6
- xradio/measurement_set/_utils/_msv2/_tables/read.py +187 -46
- xradio/measurement_set/_utils/_msv2/_tables/table_query.py +22 -0
- xradio/measurement_set/_utils/_msv2/conversion.py +352 -318
- xradio/measurement_set/_utils/_msv2/msv4_info_dicts.py +20 -17
- xradio/measurement_set/convert_msv2_to_processing_set.py +46 -6
- xradio/measurement_set/load_processing_set.py +100 -53
- xradio/measurement_set/measurement_set_xdt.py +319 -0
- xradio/measurement_set/open_processing_set.py +122 -86
- xradio/measurement_set/processing_set_xdt.py +1552 -0
- xradio/measurement_set/schema.py +201 -94
- xradio/schema/bases.py +5 -1
- xradio/schema/check.py +97 -5
- {xradio-0.0.48.dist-info → xradio-0.0.50.dist-info}/METADATA +5 -4
- {xradio-0.0.48.dist-info → xradio-0.0.50.dist-info}/RECORD +30 -30
- {xradio-0.0.48.dist-info → xradio-0.0.50.dist-info}/WHEEL +1 -1
- xradio/measurement_set/measurement_set_xds.py +0 -117
- xradio/measurement_set/processing_set.py +0 -803
- {xradio-0.0.48.dist-info → xradio-0.0.50.dist-info/licenses}/LICENSE.txt +0 -0
- {xradio-0.0.48.dist-info → xradio-0.0.50.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from xradio._utils.list_and_array import to_list
|
|
3
|
+
import xarray as xr
|
|
4
|
+
import numpy as np
|
|
5
|
+
import numbers
|
|
6
|
+
import os
|
|
7
|
+
from collections.abc import Mapping, Iterable
|
|
8
|
+
from typing import Any, Union
|
|
9
|
+
|
|
10
|
+
MS_DATASET_TYPES = {"visibility", "spectrum", "radiometer"}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class InvalidAccessorLocation(ValueError):
|
|
14
|
+
"""
|
|
15
|
+
Raised by MeasurementSetXdt accessor functions called on a wrong DataTree node (not MSv4).
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@xr.register_datatree_accessor("xr_ms")
|
|
22
|
+
class MeasurementSetXdt:
|
|
23
|
+
"""Accessor to the Measurement Set DataTree node. Provides MSv4 specific functionality
|
|
24
|
+
such as:
|
|
25
|
+
|
|
26
|
+
- get_partition_info(): produce an info dict with a general MSv4 description including
|
|
27
|
+
intents, SPW name, field and source names, etc.
|
|
28
|
+
- get_field_and_source_xds() to retrieve the field_and_source_xds for a given data
|
|
29
|
+
group.
|
|
30
|
+
- sel(): select data by dimension labels, for example by data group and polaritzation
|
|
31
|
+
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
_xdt: xr.DataTree
|
|
35
|
+
|
|
36
|
+
def __init__(self, datatree: xr.DataTree):
|
|
37
|
+
"""
|
|
38
|
+
Initialize the MeasurementSetXdt instance.
|
|
39
|
+
|
|
40
|
+
Parameters
|
|
41
|
+
----------
|
|
42
|
+
datatree: xarray.DataTree
|
|
43
|
+
The MSv4 DataTree node to construct a MeasurementSetXdt accessor.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
self._xdt = datatree
|
|
47
|
+
self.meta = {"summary": {}}
|
|
48
|
+
|
|
49
|
+
def sel(
|
|
50
|
+
self,
|
|
51
|
+
indexers: Union[Mapping[Any, Any], None] = None,
|
|
52
|
+
method: Union[str, None] = None,
|
|
53
|
+
tolerance: Union[int, float, Iterable[Union[int, float]], None] = None,
|
|
54
|
+
drop: bool = False,
|
|
55
|
+
**indexers_kwargs: Any,
|
|
56
|
+
) -> xr.DataTree:
|
|
57
|
+
"""
|
|
58
|
+
Select data along dimension(s) by label. Alternative to `xarray.Dataset.sel <https://xarray.pydata.org/en/stable/generated/xarray.Dataset.sel.html>`__ so that a data group can be selected by name by using the `data_group_name` parameter.
|
|
59
|
+
For more information on data groups see `Data Groups <https://xradio.readthedocs.io/en/latest/measurement_set_overview.html#Data-Groups>`__ section. See `xarray.Dataset.sel <https://xarray.pydata.org/en/stable/generated/xarray.Dataset.sel.html>`__ for parameter descriptions.
|
|
60
|
+
|
|
61
|
+
Returns
|
|
62
|
+
-------
|
|
63
|
+
xarray.DataTree
|
|
64
|
+
xarray DataTree with MeasurementSetXdt accessors
|
|
65
|
+
|
|
66
|
+
Examples
|
|
67
|
+
--------
|
|
68
|
+
>>> # Select data group 'corrected' and polarization 'XX'.
|
|
69
|
+
>>> selected_ms_xdt = ms_xdt.xr_ms.sel(data_group_name='corrected', polarization='XX')
|
|
70
|
+
|
|
71
|
+
>>> # Select data group 'corrected' and polarization 'XX' using a dict.
|
|
72
|
+
>>> selected_ms_xdt = ms_xdt.xr_ms.sel({'data_group_name':'corrected', 'polarization':'XX')
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
if self._xdt.attrs.get("type") not in MS_DATASET_TYPES:
|
|
76
|
+
raise InvalidAccessorLocation(f"{self._xdt.path} is not a MSv4 node.")
|
|
77
|
+
|
|
78
|
+
assert self._xdt.attrs["type"] in [
|
|
79
|
+
"visibility",
|
|
80
|
+
"spectrum",
|
|
81
|
+
"radiometer",
|
|
82
|
+
], "The type of the xdt must be 'visibility', 'spectrum' or 'radiometer'."
|
|
83
|
+
|
|
84
|
+
if "data_group_name" in indexers_kwargs:
|
|
85
|
+
data_group_name = indexers_kwargs["data_group_name"]
|
|
86
|
+
del indexers_kwargs["data_group_name"]
|
|
87
|
+
elif (indexers is not None) and ("data_group_name" in indexers):
|
|
88
|
+
data_group_name = indexers["data_group_name"]
|
|
89
|
+
del indexers["data_group_name"]
|
|
90
|
+
else:
|
|
91
|
+
data_group_name = None
|
|
92
|
+
|
|
93
|
+
if data_group_name is not None:
|
|
94
|
+
sel_data_group_set = set(
|
|
95
|
+
self._xdt.attrs["data_groups"][data_group_name].values()
|
|
96
|
+
) - set(["date", "description"])
|
|
97
|
+
|
|
98
|
+
sel_field_and_source_xds = self._xdt.attrs["data_groups"][data_group_name][
|
|
99
|
+
"field_and_source"
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
data_variables_to_drop = []
|
|
103
|
+
field_and_source_to_drop = []
|
|
104
|
+
for dg_name, dg in self._xdt.attrs["data_groups"].items():
|
|
105
|
+
print(f"Data group: {dg_name}", dg)
|
|
106
|
+
f_and_s = dg["field_and_source"]
|
|
107
|
+
dg_copy = dg.copy()
|
|
108
|
+
dg_copy.pop("date", None)
|
|
109
|
+
dg_copy.pop("description", None)
|
|
110
|
+
dg_copy.pop("field_and_source", None)
|
|
111
|
+
temp_set = set(dg_copy.values()) - sel_data_group_set
|
|
112
|
+
data_variables_to_drop.extend(list(temp_set))
|
|
113
|
+
|
|
114
|
+
if f_and_s != sel_field_and_source_xds:
|
|
115
|
+
field_and_source_to_drop.append(f_and_s)
|
|
116
|
+
|
|
117
|
+
data_variables_to_drop = list(set(data_variables_to_drop))
|
|
118
|
+
|
|
119
|
+
sel_ms_xdt = self._xdt
|
|
120
|
+
|
|
121
|
+
print("Data variables to drop: ", data_variables_to_drop)
|
|
122
|
+
print("Field and source to drop: ", field_and_source_to_drop)
|
|
123
|
+
|
|
124
|
+
sel_corr_xds = self._xdt.ds.sel(
|
|
125
|
+
indexers, method, tolerance, drop, **indexers_kwargs
|
|
126
|
+
).drop_vars(data_variables_to_drop)
|
|
127
|
+
|
|
128
|
+
sel_ms_xdt.ds = sel_corr_xds
|
|
129
|
+
|
|
130
|
+
sel_ms_xdt.attrs["data_groups"] = {
|
|
131
|
+
data_group_name: self._xdt.attrs["data_groups"][data_group_name]
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return sel_ms_xdt
|
|
135
|
+
else:
|
|
136
|
+
return self._xdt.sel(indexers, method, tolerance, drop, **indexers_kwargs)
|
|
137
|
+
|
|
138
|
+
def get_field_and_source_xds(self, data_group_name: str = None) -> xr.Dataset:
|
|
139
|
+
"""Get the field_and_source_xds associated with data group `data_group_name`.
|
|
140
|
+
|
|
141
|
+
Parameters
|
|
142
|
+
----------
|
|
143
|
+
data_group_name : str, optional
|
|
144
|
+
The data group to process. Default is "base" or if not found to first data group.
|
|
145
|
+
|
|
146
|
+
Returns
|
|
147
|
+
-------
|
|
148
|
+
xarray.Dataset
|
|
149
|
+
field_and_source_xds associated with the data group.
|
|
150
|
+
"""
|
|
151
|
+
if self._xdt.attrs.get("type") not in MS_DATASET_TYPES:
|
|
152
|
+
raise InvalidAccessorLocation(f"{self._xdt.path} is not a MSv4 node.")
|
|
153
|
+
|
|
154
|
+
if data_group_name is None:
|
|
155
|
+
if "base" in self._xdt.attrs["data_groups"].keys():
|
|
156
|
+
data_group_name = "base"
|
|
157
|
+
else:
|
|
158
|
+
data_group_name = list(self._xdt.attrs["data_groups"].keys())[0]
|
|
159
|
+
|
|
160
|
+
field_and_source_xds_name = self._xdt.attrs["data_groups"][data_group_name][
|
|
161
|
+
"field_and_source"
|
|
162
|
+
]
|
|
163
|
+
return self._xdt[field_and_source_xds_name].ds
|
|
164
|
+
|
|
165
|
+
def get_partition_info(self, data_group_name: str = None) -> dict:
|
|
166
|
+
"""
|
|
167
|
+
Generate a partition info dict for an MSv4, with general MSv4 description including
|
|
168
|
+
information such as field and source names, SPW name, scan name, the intents string,
|
|
169
|
+
etc.
|
|
170
|
+
|
|
171
|
+
The information is gathered from various coordinates, secondary datasets, and info
|
|
172
|
+
dicts of the MSv4. For example, the SPW name comes from the attributes of the
|
|
173
|
+
frequency coordinate, whereas field and source related information such as field and
|
|
174
|
+
source names come from the field_and_source_xds (base) dataset of the MSv4.
|
|
175
|
+
|
|
176
|
+
Parameters
|
|
177
|
+
----------
|
|
178
|
+
data_group_name : str, optional
|
|
179
|
+
The data group to process. Default is "base" or if not found to first data group.
|
|
180
|
+
|
|
181
|
+
Returns
|
|
182
|
+
-------
|
|
183
|
+
dict
|
|
184
|
+
Partition info dict for the MSv4
|
|
185
|
+
"""
|
|
186
|
+
if self._xdt.attrs.get("type") not in MS_DATASET_TYPES:
|
|
187
|
+
raise InvalidAccessorLocation(
|
|
188
|
+
f"{self._xdt.path} is not a MSv4 node (type {self._xdt.attrs.get('type')}."
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
if data_group_name is None:
|
|
192
|
+
if "base" in self._xdt.attrs["data_groups"].keys():
|
|
193
|
+
data_group_name = "base"
|
|
194
|
+
else:
|
|
195
|
+
data_group_name = list(self._xdt.attrs["data_groups"].keys())[0]
|
|
196
|
+
|
|
197
|
+
field_and_source_xds = self._xdt.xr_ms.get_field_and_source_xds(data_group_name)
|
|
198
|
+
|
|
199
|
+
if "line_name" in field_and_source_xds.coords:
|
|
200
|
+
line_name = to_list(
|
|
201
|
+
np.unique(np.ravel(field_and_source_xds.line_name.values))
|
|
202
|
+
)
|
|
203
|
+
else:
|
|
204
|
+
line_name = []
|
|
205
|
+
|
|
206
|
+
partition_info = {
|
|
207
|
+
"spectral_window_name": self._xdt.frequency.attrs["spectral_window_name"],
|
|
208
|
+
"field_name": to_list(np.unique(field_and_source_xds.field_name.values)),
|
|
209
|
+
"polarization_setup": to_list(self._xdt.polarization.values),
|
|
210
|
+
"scan_name": to_list(np.unique(self._xdt.scan_name.values)),
|
|
211
|
+
"source_name": to_list(np.unique(field_and_source_xds.source_name.values)),
|
|
212
|
+
"intents": self._xdt.observation_info["intents"],
|
|
213
|
+
"line_name": line_name,
|
|
214
|
+
"data_group_name": data_group_name,
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return partition_info
|
|
218
|
+
|
|
219
|
+
def add_data_group(
|
|
220
|
+
self,
|
|
221
|
+
new_data_group_name: str,
|
|
222
|
+
correlated_data: str = None,
|
|
223
|
+
weight: str = None,
|
|
224
|
+
flag: str = None,
|
|
225
|
+
uvw: str = None,
|
|
226
|
+
field_and_source_xds: str = None,
|
|
227
|
+
date_time: str = None,
|
|
228
|
+
description: str = None,
|
|
229
|
+
data_group_dv_shared_with: str = None,
|
|
230
|
+
) -> xr.DataTree:
|
|
231
|
+
"""_summary_
|
|
232
|
+
|
|
233
|
+
Parameters
|
|
234
|
+
----------
|
|
235
|
+
new_data_group_name : str
|
|
236
|
+
_description_
|
|
237
|
+
correlated_data : str, optional
|
|
238
|
+
_description_, by default None
|
|
239
|
+
weights : str, optional
|
|
240
|
+
_description_, by default None
|
|
241
|
+
flag : str, optional
|
|
242
|
+
_description_, by default None
|
|
243
|
+
uvw : str, optional
|
|
244
|
+
_description_, by default None
|
|
245
|
+
field_and_source_xds : str, optional
|
|
246
|
+
_description_, by default None
|
|
247
|
+
date_time : str, optional
|
|
248
|
+
_description_, by default None
|
|
249
|
+
description : str, optional
|
|
250
|
+
_description_, by default None
|
|
251
|
+
data_group_dv_shared_with : str, optional
|
|
252
|
+
_description_, by default "base"
|
|
253
|
+
|
|
254
|
+
Returns
|
|
255
|
+
-------
|
|
256
|
+
xr.DataTree
|
|
257
|
+
_description_
|
|
258
|
+
"""
|
|
259
|
+
|
|
260
|
+
if data_group_dv_shared_with is None:
|
|
261
|
+
data_group_dv_shared_with = self._xdt.xr_ms._get_default_data_group_name()
|
|
262
|
+
default_data_group = self._xdt.attrs["data_groups"][data_group_dv_shared_with]
|
|
263
|
+
|
|
264
|
+
new_data_group = {}
|
|
265
|
+
|
|
266
|
+
if correlated_data is None:
|
|
267
|
+
correlated_data = default_data_group["correlated_data"]
|
|
268
|
+
new_data_group["correlated_data"] = correlated_data
|
|
269
|
+
assert (
|
|
270
|
+
correlated_data in self._xdt.ds.data_vars
|
|
271
|
+
), f"Data variable {correlated_data} not found in dataset."
|
|
272
|
+
|
|
273
|
+
if weight is None:
|
|
274
|
+
weight = default_data_group["weight"]
|
|
275
|
+
new_data_group["weight"] = weight
|
|
276
|
+
assert (
|
|
277
|
+
weight in self._xdt.ds.data_vars
|
|
278
|
+
), f"Data variable {weight} not found in dataset."
|
|
279
|
+
|
|
280
|
+
if flag is None:
|
|
281
|
+
flag = default_data_group["flag"]
|
|
282
|
+
new_data_group["flag"] = flag
|
|
283
|
+
assert (
|
|
284
|
+
flag in self._xdt.ds.data_vars
|
|
285
|
+
), f"Data variable {flag} not found in dataset."
|
|
286
|
+
|
|
287
|
+
if self._xdt.attrs["type"] == "visibility":
|
|
288
|
+
if uvw is None:
|
|
289
|
+
uvw = default_data_group["uvw"]
|
|
290
|
+
new_data_group["uvw"] = uvw
|
|
291
|
+
assert (
|
|
292
|
+
uvw in self._xdt.ds.data_vars
|
|
293
|
+
), f"Data variable {uvw} not found in dataset."
|
|
294
|
+
|
|
295
|
+
if field_and_source_xds is None:
|
|
296
|
+
field_and_source_xds = default_data_group["field_and_source_xds"]
|
|
297
|
+
new_data_group["field_and_source"] = field_and_source_xds
|
|
298
|
+
assert (
|
|
299
|
+
field_and_source_xds in self._xdt.children
|
|
300
|
+
), f"Data variable {field_and_source_xds} not found in dataset."
|
|
301
|
+
|
|
302
|
+
if date_time is None:
|
|
303
|
+
date_time = datetime.now().isoformat()
|
|
304
|
+
new_data_group["date"] = date_time
|
|
305
|
+
|
|
306
|
+
if description is None:
|
|
307
|
+
description = ""
|
|
308
|
+
new_data_group["description"] = description
|
|
309
|
+
|
|
310
|
+
self._xdt.attrs["data_groups"][new_data_group_name] = new_data_group
|
|
311
|
+
|
|
312
|
+
return self._xdt
|
|
313
|
+
|
|
314
|
+
def _get_default_data_group_name(self):
|
|
315
|
+
if "base" in self._xdt.attrs["data_groups"].keys():
|
|
316
|
+
data_group_name = "base"
|
|
317
|
+
else:
|
|
318
|
+
data_group_name = list(self._xdt.attrs["data_groups"].keys())[0]
|
|
319
|
+
return data_group_name
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import os
|
|
2
|
-
|
|
3
|
-
from xradio.measurement_set import ProcessingSet
|
|
4
2
|
import toolviper.utils.logger as logger
|
|
5
3
|
from xradio._utils.zarr.common import _open_dataset, _get_file_system_and_items
|
|
6
4
|
import s3fs
|
|
5
|
+
import xarray as xr
|
|
7
6
|
|
|
8
7
|
|
|
9
8
|
def open_processing_set(
|
|
10
9
|
ps_store: str,
|
|
11
10
|
intents: list = None,
|
|
12
|
-
) ->
|
|
11
|
+
) -> xr.DataTree:
|
|
13
12
|
"""Creates a lazy representation of a Processing Set (only meta-data is loaded into memory).
|
|
14
13
|
|
|
15
14
|
Parameters
|
|
@@ -17,96 +16,133 @@ def open_processing_set(
|
|
|
17
16
|
ps_store : str
|
|
18
17
|
String of the path and name of the processing set. For example '/users/user_1/uid___A002_Xf07bba_Xbe5c_target.lsrk.vis.zarr'.
|
|
19
18
|
intents : list, optional
|
|
20
|
-
A list of intents to be
|
|
21
|
-
By default None, which will
|
|
19
|
+
A list of intents to be opened for example ['OBSERVE_TARGET#ON_SOURCE']. The intents in a processing_set_xdt can be seen by calling processing_set_xdt.ps.summary().
|
|
20
|
+
By default None, which will include all intents.
|
|
22
21
|
|
|
23
22
|
Returns
|
|
24
23
|
-------
|
|
25
|
-
|
|
26
|
-
Lazy representation of processing set (data
|
|
24
|
+
xarray.DataTree
|
|
25
|
+
Lazy representation of processing set (the data arrays of the datasets are
|
|
26
|
+
represented by Dask.arrays).
|
|
27
27
|
"""
|
|
28
|
-
from xradio.measurement_set import MeasurementSetXds
|
|
29
28
|
|
|
30
29
|
file_system, ms_store_list = _get_file_system_and_items(ps_store)
|
|
31
30
|
|
|
32
|
-
ps = ProcessingSet()
|
|
33
|
-
data_group = "base"
|
|
34
|
-
for ms_name in ms_store_list:
|
|
35
|
-
# try:
|
|
36
|
-
ms_store = os.path.join(ps_store, ms_name)
|
|
37
|
-
correlated_store = os.path.join(ms_store, "correlated_xds")
|
|
38
|
-
|
|
39
|
-
xds = _open_dataset(correlated_store, file_system)
|
|
40
|
-
data_groups = xds.attrs["data_groups"]
|
|
41
|
-
|
|
42
|
-
if (intents is None) or (
|
|
43
|
-
bool(set(xds.attrs["partition_info"]["intents"]).intersection(intents))
|
|
44
|
-
):
|
|
45
|
-
sub_xds_dict, field_and_source_xds_dict = _open_sub_xds(
|
|
46
|
-
ms_store, file_system=file_system, data_groups=data_groups
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
xds.attrs = {
|
|
50
|
-
**xds.attrs,
|
|
51
|
-
**sub_xds_dict,
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
for data_group_name, data_group_vals in data_groups.items():
|
|
55
|
-
xds[data_group_vals["correlated_data"]].attrs[
|
|
56
|
-
"field_and_source_xds"
|
|
57
|
-
] = field_and_source_xds_dict[data_group_name]
|
|
58
|
-
|
|
59
|
-
ps[ms_name] = MeasurementSetXds(xds)
|
|
60
|
-
# except Exception as e:
|
|
61
|
-
# logger.warning(f"Could not open {ms_name} due to {e}")
|
|
62
|
-
# continue
|
|
63
|
-
|
|
64
|
-
return ps
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
def _open_sub_xds(ms_store, file_system, data_groups, load=False):
|
|
68
|
-
sub_xds_dict = {}
|
|
69
|
-
field_and_source_xds_dict = {}
|
|
70
|
-
|
|
71
31
|
if isinstance(file_system, s3fs.core.S3FileSystem):
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
]
|
|
32
|
+
mapping = s3fs.S3Map(root=ps_store, s3=file_system, check=False)
|
|
33
|
+
ps_xdt = xr.open_datatree(mapping, engine="zarr")
|
|
75
34
|
else:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
# field_and_source_xds_name_start = "FIELD"
|
|
84
|
-
for n in file_names:
|
|
85
|
-
xds = _open_dataset(
|
|
86
|
-
os.path.join(ms_store, n), load=load, file_system=file_system
|
|
87
|
-
)
|
|
88
|
-
# Skip empty tables
|
|
89
|
-
if not xds.coords and not xds.data_vars:
|
|
90
|
-
continue
|
|
91
|
-
if n in field_dict.keys():
|
|
92
|
-
field_and_source_xds_dict[field_dict[n]] = xds
|
|
93
|
-
else:
|
|
94
|
-
sub_xds_dict[n] = xds
|
|
95
|
-
|
|
96
|
-
return sub_xds_dict, field_and_source_xds_dict
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
def _get_data_name(xds, data_group):
|
|
100
|
-
if "visibility" in xds.attrs["data_groups"][data_group]:
|
|
101
|
-
data_name = xds.attrs["data_groups"][data_group]["visibility"]
|
|
102
|
-
elif "spectrum" in xds.attrs["data_groups"][data_group]:
|
|
103
|
-
data_name = xds.attrs["data_groups"][data_group]["spectrum"]
|
|
35
|
+
ps_xdt = xr.open_datatree(ps_store, engine="zarr")
|
|
36
|
+
|
|
37
|
+
# Future work is to add ASDM backend
|
|
38
|
+
|
|
39
|
+
if intents is None:
|
|
40
|
+
return ps_xdt
|
|
104
41
|
else:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
42
|
+
return ps_xdt.xr_ps.query(intents=intents)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# def open_processing_set(
|
|
46
|
+
# ps_store: str,
|
|
47
|
+
# intents: list = None,
|
|
48
|
+
# ): #-> ProcessingSet:
|
|
49
|
+
# """Creates a lazy representation of a Processing Set (only meta-data is loaded into memory).
|
|
50
|
+
|
|
51
|
+
# Parameters
|
|
52
|
+
# ----------
|
|
53
|
+
# ps_store : str
|
|
54
|
+
# String of the path and name of the processing set. For example '/users/user_1/uid___A002_Xf07bba_Xbe5c_target.lsrk.vis.zarr'.
|
|
55
|
+
# intents : list, optional
|
|
56
|
+
# A list of intents to be open for example ['OBSERVE_TARGET#ON_SOURCE']. The intents in a processing set can be seen by calling processing_set.summary().
|
|
57
|
+
# By default None, which will open all intents.
|
|
58
|
+
|
|
59
|
+
# Returns
|
|
60
|
+
# -------
|
|
61
|
+
# processing_set
|
|
62
|
+
# Lazy representation of processing set (data is represented by Dask.arrays).
|
|
63
|
+
# """
|
|
64
|
+
# from xradio.measurement_set import MeasurementSetXds
|
|
65
|
+
|
|
66
|
+
# file_system, ms_store_list = _get_file_system_and_items(ps_store)
|
|
67
|
+
# from xradio.measurement_set import ProcessingSet
|
|
68
|
+
# ps = ProcessingSet()
|
|
69
|
+
# data_group = "base"
|
|
70
|
+
# for ms_name in ms_store_list:
|
|
71
|
+
# # try:
|
|
72
|
+
# ms_store = os.path.join(ps_store, ms_name)
|
|
73
|
+
# correlated_store = os.path.join(ms_store, "correlated_xds")
|
|
74
|
+
|
|
75
|
+
# xds = _open_dataset(correlated_store, file_system)
|
|
76
|
+
# data_groups = xds.attrs["data_groups"]
|
|
77
|
+
|
|
78
|
+
# if (intents is None) or (
|
|
79
|
+
# bool(set(xds.attrs["partition_info"]["intents"]).intersection(intents))
|
|
80
|
+
# ):
|
|
81
|
+
# sub_xds_dict, field_and_source_xds_dict = _open_sub_xds(
|
|
82
|
+
# ms_store, file_system=file_system, data_groups=data_groups
|
|
83
|
+
# )
|
|
84
|
+
|
|
85
|
+
# xds.attrs = {
|
|
86
|
+
# **xds.attrs,
|
|
87
|
+
# **sub_xds_dict,
|
|
88
|
+
# }
|
|
89
|
+
|
|
90
|
+
# for data_group_name, data_group_vals in data_groups.items():
|
|
91
|
+
# xds[data_group_vals["correlated_data"]].attrs[
|
|
92
|
+
# "field_and_source_xds"
|
|
93
|
+
# ] = field_and_source_xds_dict[data_group_name]
|
|
94
|
+
|
|
95
|
+
# ps[ms_name] = MeasurementSetXds(xds)
|
|
96
|
+
# # except Exception as e:
|
|
97
|
+
# # logger.warning(f"Could not open {ms_name} due to {e}")
|
|
98
|
+
# # continue
|
|
99
|
+
|
|
100
|
+
# return ps
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
# def _open_sub_xds(ms_store, file_system, data_groups, load=False):
|
|
104
|
+
# sub_xds_dict = {}
|
|
105
|
+
# field_and_source_xds_dict = {}
|
|
106
|
+
|
|
107
|
+
# if isinstance(file_system, s3fs.core.S3FileSystem):
|
|
108
|
+
# file_names = [
|
|
109
|
+
# bd.split(sep="/")[-1] for bd in file_system.listdir(ms_store, detail=False)
|
|
110
|
+
# ]
|
|
111
|
+
# else:
|
|
112
|
+
# file_names = file_system.listdir(ms_store)
|
|
113
|
+
# file_names = [item for item in file_names if not item.startswith(".")]
|
|
114
|
+
|
|
115
|
+
# file_names.remove("correlated_xds")
|
|
116
|
+
|
|
117
|
+
# field_dict = {"field_and_source_xds_" + key: key for key in data_groups.keys()}
|
|
118
|
+
|
|
119
|
+
# # field_and_source_xds_name_start = "FIELD"
|
|
120
|
+
# for n in file_names:
|
|
121
|
+
# xds = _open_dataset(
|
|
122
|
+
# os.path.join(ms_store, n), load=load, file_system=file_system
|
|
123
|
+
# )
|
|
124
|
+
# # Skip empty tables
|
|
125
|
+
# if not xds.coords and not xds.data_vars:
|
|
126
|
+
# continue
|
|
127
|
+
# if n in field_dict.keys():
|
|
128
|
+
# field_and_source_xds_dict[field_dict[n]] = xds
|
|
129
|
+
# else:
|
|
130
|
+
# sub_xds_dict[n] = xds
|
|
131
|
+
|
|
132
|
+
# return sub_xds_dict, field_and_source_xds_dict
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
# def _get_data_name(xds, data_group):
|
|
136
|
+
# if "visibility" in xds.attrs["data_groups"][data_group]:
|
|
137
|
+
# data_name = xds.attrs["data_groups"][data_group]["visibility"]
|
|
138
|
+
# elif "spectrum" in xds.attrs["data_groups"][data_group]:
|
|
139
|
+
# data_name = xds.attrs["data_groups"][data_group]["spectrum"]
|
|
140
|
+
# else:
|
|
141
|
+
# error_message = (
|
|
142
|
+
# "No Visibility or Spectrum data variable found in data_group "
|
|
143
|
+
# + data_group
|
|
144
|
+
# + "."
|
|
145
|
+
# )
|
|
146
|
+
# logger.exception(error_message)
|
|
147
|
+
# raise ValueError(error_message)
|
|
148
|
+
# return data_name
|