xradio 0.0.31__py3-none-any.whl → 0.0.33__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/list_and_array.py +5 -3
- xradio/vis/__init__.py +3 -5
- xradio/vis/_processing_set.py +3 -3
- xradio/vis/_vis_utils/_ms/_tables/load_main_table.py +4 -4
- xradio/vis/_vis_utils/_ms/_tables/read.py +57 -41
- xradio/vis/_vis_utils/_ms/_tables/read_main_table.py +17 -18
- xradio/vis/_vis_utils/_ms/_tables/read_subtables.py +5 -5
- xradio/vis/_vis_utils/_ms/_tables/write.py +2 -4
- xradio/vis/_vis_utils/_ms/_tables/write_exp_api.py +19 -13
- xradio/vis/_vis_utils/_ms/chunks.py +5 -72
- xradio/vis/_vis_utils/_ms/conversion.py +168 -27
- xradio/vis/_vis_utils/_ms/{_tables/create_field_and_source_xds.py → create_field_and_source_xds.py} +114 -85
- xradio/vis/_vis_utils/_ms/descr.py +8 -8
- xradio/vis/_vis_utils/_ms/msv4_sub_xdss.py +249 -77
- xradio/vis/_vis_utils/_ms/partition_queries.py +19 -185
- xradio/vis/_vis_utils/_ms/partitions.py +18 -22
- xradio/vis/_vis_utils/_ms/subtables.py +2 -2
- xradio/vis/_vis_utils/_utils/partition_attrs.py +2 -2
- xradio/vis/_vis_utils/_utils/xds_helper.py +12 -12
- xradio/vis/_vis_utils/ms.py +1 -43
- xradio/vis/_vis_utils/zarr.py +0 -1
- xradio/vis/convert_msv2_to_processing_set.py +8 -1
- xradio/vis/load_processing_set.py +0 -3
- xradio/vis/read_processing_set.py +2 -2
- {xradio-0.0.31.dist-info → xradio-0.0.33.dist-info}/METADATA +1 -1
- {xradio-0.0.31.dist-info → xradio-0.0.33.dist-info}/RECORD +29 -31
- {xradio-0.0.31.dist-info → xradio-0.0.33.dist-info}/WHEEL +1 -1
- xradio/vis/_vis_utils/ms_column_descriptions_dicts.py +0 -1360
- xradio/vis/vis_io.py +0 -146
- {xradio-0.0.31.dist-info → xradio-0.0.33.dist-info}/LICENSE.txt +0 -0
- {xradio-0.0.31.dist-info → xradio-0.0.33.dist-info}/top_level.txt +0 -0
|
@@ -7,7 +7,14 @@ import xarray as xr
|
|
|
7
7
|
|
|
8
8
|
from .msv2_to_msv4_meta import column_description_casacore_to_msv4_measure
|
|
9
9
|
from .subtables import subt_rename_ids
|
|
10
|
-
from ._tables.read import make_taql_where_between_min_max,
|
|
10
|
+
from ._tables.read import make_taql_where_between_min_max, load_generic_table
|
|
11
|
+
|
|
12
|
+
from xradio._utils.list_and_array import (
|
|
13
|
+
check_if_consistent,
|
|
14
|
+
unique_1d,
|
|
15
|
+
to_list,
|
|
16
|
+
to_np_array,
|
|
17
|
+
)
|
|
11
18
|
|
|
12
19
|
|
|
13
20
|
def interpolate_to_time(
|
|
@@ -56,7 +63,13 @@ def interpolate_to_time(
|
|
|
56
63
|
return xds
|
|
57
64
|
|
|
58
65
|
|
|
59
|
-
def create_ant_xds(
|
|
66
|
+
def create_ant_xds(
|
|
67
|
+
in_file: str,
|
|
68
|
+
spectral_window_id: int,
|
|
69
|
+
antenna_id: list,
|
|
70
|
+
feed_id: list,
|
|
71
|
+
telescope_name: str,
|
|
72
|
+
):
|
|
60
73
|
"""
|
|
61
74
|
Creates an Antenna Xarray Dataset from a MS v2 ANTENNA table.
|
|
62
75
|
|
|
@@ -70,49 +83,86 @@ def create_ant_xds(in_file: str):
|
|
|
70
83
|
xr.Dataset
|
|
71
84
|
Antenna Xarray Dataset.
|
|
72
85
|
"""
|
|
86
|
+
# generic_obs_xds = load_generic_table(
|
|
87
|
+
# in_file,
|
|
88
|
+
# "OBSERVATION",
|
|
89
|
+
# taql_where=f" where (ROWID() IN [{','.join(map(str,unique_antenna_id))}])", # order is not guaranteed
|
|
90
|
+
# )
|
|
91
|
+
|
|
73
92
|
# Dictionaries that define the conversion from MSv2 to MSv4:
|
|
74
93
|
to_new_data_variable_names = {
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"
|
|
94
|
+
"POSITION": "ANTENNA_POSITION",
|
|
95
|
+
"OFFSET": "ANTENNA_FEED_OFFSET",
|
|
96
|
+
"DISH_DIAMETER": "ANTENNA_DISH_DIAMETER",
|
|
78
97
|
}
|
|
79
98
|
data_variable_dims = {
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
-
"
|
|
99
|
+
"POSITION": ["antenna_id", "cartesian_pos_label"],
|
|
100
|
+
"OFFSET": ["antenna_id", "cartesian_pos_label"],
|
|
101
|
+
"DISH_DIAMETER": ["antenna_id"],
|
|
83
102
|
}
|
|
84
103
|
to_new_coord_names = {
|
|
85
|
-
"
|
|
86
|
-
"
|
|
87
|
-
"
|
|
88
|
-
"
|
|
89
|
-
"phased_array_id": "phased_array_id",
|
|
104
|
+
"NAME": "name",
|
|
105
|
+
"STATION": "station",
|
|
106
|
+
"MOUNT": "mount",
|
|
107
|
+
"PHASED_ARRAY_ID": "phased_array_id",
|
|
90
108
|
}
|
|
109
|
+
|
|
110
|
+
# coord_dims = {
|
|
111
|
+
# "name": ["antenna_id"],
|
|
112
|
+
# "station": ["antenna_id"],
|
|
113
|
+
# "mount": ["antenna_id"],
|
|
114
|
+
# "phased_array_id": ["antenna_id"],
|
|
115
|
+
# "POSITION": "POSITION",
|
|
116
|
+
# "OFFSET": "FEED_OFFSET",
|
|
117
|
+
# "DISH_DIAMETER": "DISH_DIAMETER",
|
|
118
|
+
# }
|
|
119
|
+
# data_variable_dims = {
|
|
120
|
+
# "POSITION": ["antenna_id", "xyz_label"],
|
|
121
|
+
# "OFFSET": ["antenna_id", "xyz_label"],
|
|
122
|
+
# "DISH_DIAMETER": ["antenna_id"],
|
|
123
|
+
# }
|
|
124
|
+
# to_new_coord_names = {
|
|
125
|
+
# "NAME": "name",
|
|
126
|
+
# "STATION": "station",
|
|
127
|
+
# "TYPE": "type",
|
|
128
|
+
# "MOUNT": "mount",
|
|
129
|
+
# "PHASED_ARRAY_ID": "phased_array_id",
|
|
130
|
+
# }
|
|
91
131
|
coord_dims = {
|
|
92
|
-
"
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
"
|
|
132
|
+
"NAME": ["antenna_id"],
|
|
133
|
+
"STATION": ["antenna_id"],
|
|
134
|
+
"TYPE": ["antenna_id"],
|
|
135
|
+
"MOUNT": ["antenna_id"],
|
|
136
|
+
"PHASED_ARRAY_ID": ["antenna_id"],
|
|
97
137
|
}
|
|
98
138
|
|
|
99
139
|
# Read ANTENNA table into a Xarray Dataset.
|
|
100
|
-
|
|
140
|
+
unique_antenna_id = unique_1d(
|
|
141
|
+
antenna_id
|
|
142
|
+
) # Also ensures that it is sorted otherwise TaQL will give wrong results.
|
|
143
|
+
|
|
144
|
+
generic_ant_xds = load_generic_table(
|
|
101
145
|
in_file,
|
|
102
146
|
"ANTENNA",
|
|
103
147
|
rename_ids=subt_rename_ids["ANTENNA"],
|
|
148
|
+
taql_where=f" where (ROWID() IN [{','.join(map(str,unique_antenna_id))}])", # order is not guaranteed
|
|
104
149
|
)
|
|
150
|
+
generic_ant_xds = generic_ant_xds.assign_coords({"antenna_id": unique_antenna_id})
|
|
151
|
+
generic_ant_xds = generic_ant_xds.sel(
|
|
152
|
+
antenna_id=antenna_id, drop=False
|
|
153
|
+
) # Make sure the antenna_id order is correct.
|
|
105
154
|
|
|
106
155
|
ant_column_description = generic_ant_xds.attrs["other"]["msv2"]["ctds_attrs"][
|
|
107
156
|
"column_descriptions"
|
|
108
157
|
]
|
|
109
|
-
|
|
158
|
+
|
|
159
|
+
# ['OFFSET', 'POSITION', 'DISH_DIAMETER', 'FLAG_ROW', 'MOUNT', 'NAME', 'STATION']
|
|
110
160
|
ant_xds = xr.Dataset()
|
|
161
|
+
ant_xds = ant_xds.assign_coords(
|
|
162
|
+
{"antenna_id": antenna_id, "cartesian_pos_label": ["x", "y", "z"]}
|
|
163
|
+
)
|
|
111
164
|
|
|
112
|
-
coords = {
|
|
113
|
-
"antenna_id": np.arange(generic_ant_xds.sizes["antenna_id"]),
|
|
114
|
-
"xyz_label": ["x", "y", "z"],
|
|
115
|
-
}
|
|
165
|
+
coords = {}
|
|
116
166
|
for key in generic_ant_xds:
|
|
117
167
|
msv4_measure = column_description_casacore_to_msv4_measure(
|
|
118
168
|
ant_column_description[key.upper()]
|
|
@@ -125,7 +175,7 @@ def create_ant_xds(in_file: str):
|
|
|
125
175
|
if msv4_measure:
|
|
126
176
|
ant_xds[to_new_data_variable_names[key]].attrs.update(msv4_measure)
|
|
127
177
|
|
|
128
|
-
if key in ["
|
|
178
|
+
if key in ["DISH_DIAMETER"]:
|
|
129
179
|
ant_xds[to_new_data_variable_names[key]].attrs.update(
|
|
130
180
|
{"units": ["m"], "type": "quantity"}
|
|
131
181
|
)
|
|
@@ -136,7 +186,93 @@ def create_ant_xds(in_file: str):
|
|
|
136
186
|
generic_ant_xds[key].data,
|
|
137
187
|
)
|
|
138
188
|
|
|
189
|
+
ant_xds["ANTENNA_FEED_OFFSET"].attrs["type"] = "earth_location_offset"
|
|
190
|
+
ant_xds["ANTENNA_FEED_OFFSET"].attrs["coordinate_system"] = "geocentric"
|
|
191
|
+
ant_xds["ANTENNA_POSITION"].attrs["coordinate_system"] = "geocentric"
|
|
192
|
+
|
|
193
|
+
# Extract feed information
|
|
194
|
+
generic_feed_xds = load_generic_table(
|
|
195
|
+
in_file,
|
|
196
|
+
"FEED",
|
|
197
|
+
rename_ids=subt_rename_ids["FEED"],
|
|
198
|
+
taql_where=f" where (ANTENNA_ID IN [{','.join(map(str, unique_antenna_id))}]) AND (FEED_ID IN [{','.join(map(str, feed_id))}])",
|
|
199
|
+
) # Some Lofar and MeerKAT data have the spw column set to -1 so we can't use '(SPECTRAL_WINDOW_ID = {spectral_window_id})'
|
|
200
|
+
|
|
201
|
+
if "SPECTRAL_WINDOW_ID" in generic_feed_xds and not all(
|
|
202
|
+
generic_feed_xds.SPECTRAL_WINDOW_ID == -1
|
|
203
|
+
):
|
|
204
|
+
generic_feed_xds = generic_feed_xds.where(
|
|
205
|
+
generic_feed_xds.SPECTRAL_WINDOW_ID == spectral_window_id, drop=True
|
|
206
|
+
)
|
|
207
|
+
if "row" in generic_feed_xds and len(generic_feed_xds.row) > 0:
|
|
208
|
+
# Some times the feed table is empty (this is the case with ALMA spw WVR#NOMINAL).
|
|
209
|
+
assert len(generic_feed_xds.ANTENNA_ID) == len(
|
|
210
|
+
ant_xds.antenna_id
|
|
211
|
+
), "Can only process feed table with a single time entry for an antenna and spectral_window_id."
|
|
212
|
+
generic_feed_xds = generic_feed_xds.set_xindex(
|
|
213
|
+
"ANTENNA_ID"
|
|
214
|
+
) # Allows for non-dimension coordinate selection.
|
|
215
|
+
generic_feed_xds = generic_feed_xds.sel(
|
|
216
|
+
ANTENNA_ID=ant_xds.antenna_id
|
|
217
|
+
) # Make sure the antenna_id is in the same order as the xds.
|
|
218
|
+
|
|
219
|
+
num_receptors = np.ravel(generic_feed_xds.NUM_RECEPTORS)
|
|
220
|
+
num_receptors = unique_1d(num_receptors[~np.isnan(num_receptors)])
|
|
221
|
+
|
|
222
|
+
assert (
|
|
223
|
+
len(num_receptors) == 1
|
|
224
|
+
), "The number of receptors must be constant in feed table."
|
|
225
|
+
|
|
226
|
+
feed_column_description = generic_feed_xds.attrs["other"]["msv2"]["ctds_attrs"][
|
|
227
|
+
"column_descriptions"
|
|
228
|
+
]
|
|
229
|
+
|
|
230
|
+
to_new_data_variable_names = {
|
|
231
|
+
"BEAM_OFFSET": "BEAM_OFFSET",
|
|
232
|
+
"RECEPTOR_ANGLE": "RECEPTOR_ANGLE",
|
|
233
|
+
"POLARIZATION_TYPE": "POLARIZATION_TYPE",
|
|
234
|
+
# "pol_response": "POLARIZATION_RESPONSE", ?repeated dim creates problems.
|
|
235
|
+
"FOCUS_LENGTH": "FOCUS_LENGTH", # optional
|
|
236
|
+
# "position": "ANTENNA_FEED_OFFSET" #Will be added to the existing position in ant_xds
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
data_variable_dims = {
|
|
240
|
+
"BEAM_OFFSET": ["antenna_id", "receptor_name", "sky_dir_label"],
|
|
241
|
+
"RECEPTOR_ANGLE": ["antenna_id", "receptor_name"],
|
|
242
|
+
"POLARIZATION_TYPE": ["antenna_id", "receptor_name"],
|
|
243
|
+
# "pol_response": ["antenna_id", "receptor_name", "receptor_name_"],
|
|
244
|
+
"FOCUS_LENGTH": ["antenna_id"],
|
|
245
|
+
# "position": ["antenna_id", "cartesian_pos_label"],
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
for key in generic_feed_xds:
|
|
249
|
+
msv4_measure = column_description_casacore_to_msv4_measure(
|
|
250
|
+
feed_column_description[key.upper()]
|
|
251
|
+
)
|
|
252
|
+
if key in to_new_data_variable_names:
|
|
253
|
+
ant_xds[to_new_data_variable_names[key]] = xr.DataArray(
|
|
254
|
+
generic_feed_xds[key].data, dims=data_variable_dims[key]
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
if msv4_measure:
|
|
258
|
+
ant_xds[to_new_data_variable_names[key]].attrs.update(msv4_measure)
|
|
259
|
+
|
|
260
|
+
if key in to_new_coord_names:
|
|
261
|
+
coords[to_new_coord_names[key]] = (
|
|
262
|
+
coord_dims[key],
|
|
263
|
+
generic_feed_xds[key].data,
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
ant_xds["ANTENNA_FEED_OFFSET"] = (
|
|
267
|
+
ant_xds["ANTENNA_FEED_OFFSET"] + generic_ant_xds["POSITION"].data
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
coords["receptor_name"] = np.arange(ant_xds.sizes["receptor_name"]).astype(str)
|
|
271
|
+
|
|
139
272
|
ant_xds = ant_xds.assign_coords(coords)
|
|
273
|
+
|
|
274
|
+
ant_xds.attrs["overall_telescope_name"] = telescope_name
|
|
275
|
+
|
|
140
276
|
return ant_xds
|
|
141
277
|
|
|
142
278
|
|
|
@@ -155,25 +291,27 @@ def create_weather_xds(in_file: str):
|
|
|
155
291
|
Weather Xarray Dataset.
|
|
156
292
|
"""
|
|
157
293
|
# Dictionaries that define the conversion from MSv2 to MSv4:
|
|
294
|
+
# Dict from col/data_var names in generic_weather_xds (from MSv2) to MSV4
|
|
295
|
+
# weather_xds produced here
|
|
158
296
|
to_new_data_variable_names = {
|
|
159
|
-
"
|
|
160
|
-
"
|
|
161
|
-
"
|
|
162
|
-
"
|
|
163
|
-
"
|
|
164
|
-
"
|
|
165
|
-
"
|
|
166
|
-
"
|
|
297
|
+
"H2O": "H2O",
|
|
298
|
+
"IONOS_ELECTRON": "IONOS_ELECTRON",
|
|
299
|
+
"PRESSURE": "PRESSURE",
|
|
300
|
+
"REL_HUMIDITY": "REL_HUMIDITY",
|
|
301
|
+
"TEMPERATURE": "TEMPERATURE",
|
|
302
|
+
"DEW_POINT": "DEW_POINT",
|
|
303
|
+
"WIND_DIRECTION": "WIND_DIRECTION",
|
|
304
|
+
"WIND_SPEED": "WIND_SPEED",
|
|
167
305
|
}
|
|
168
306
|
data_variable_dims = {
|
|
169
|
-
"
|
|
170
|
-
"
|
|
171
|
-
"
|
|
172
|
-
"
|
|
173
|
-
"
|
|
174
|
-
"
|
|
175
|
-
"
|
|
176
|
-
"
|
|
307
|
+
"H2O": ["station_id", "time"],
|
|
308
|
+
"IONOS_ELECTRON": ["station_id", "time"],
|
|
309
|
+
"PRESSURE": ["station_id", "time"],
|
|
310
|
+
"REL_HUMIDITY": ["station_id", "time"],
|
|
311
|
+
"TEMPERATURE": ["station_id", "time"],
|
|
312
|
+
"DEW_POINT": ["station_id", "time"],
|
|
313
|
+
"WIND_DIRECTION": ["station_id", "time"],
|
|
314
|
+
"WIND_SPEED": ["station_id", "time"],
|
|
177
315
|
}
|
|
178
316
|
to_new_coord_names = {
|
|
179
317
|
# No MS data cols are turned into xds coords
|
|
@@ -182,12 +320,12 @@ def create_weather_xds(in_file: str):
|
|
|
182
320
|
# No MS data cols are turned into xds coords
|
|
183
321
|
}
|
|
184
322
|
to_new_dim_names = {
|
|
185
|
-
"
|
|
323
|
+
"ANTENNA_ID": "STATION_ID",
|
|
186
324
|
}
|
|
187
325
|
|
|
188
326
|
# Read WEATHER table into a Xarray Dataset.
|
|
189
327
|
try:
|
|
190
|
-
generic_weather_xds =
|
|
328
|
+
generic_weather_xds = load_generic_table(
|
|
191
329
|
in_file,
|
|
192
330
|
"WEATHER",
|
|
193
331
|
rename_ids=subt_rename_ids["WEATHER"],
|
|
@@ -206,8 +344,8 @@ def create_weather_xds(in_file: str):
|
|
|
206
344
|
weather_xds = xr.Dataset()
|
|
207
345
|
|
|
208
346
|
coords = {
|
|
209
|
-
"station_id": generic_weather_xds["
|
|
210
|
-
"time": generic_weather_xds["
|
|
347
|
+
"station_id": generic_weather_xds["STATION_ID"].data,
|
|
348
|
+
"time": generic_weather_xds["TIME"].data,
|
|
211
349
|
}
|
|
212
350
|
for key in generic_weather_xds:
|
|
213
351
|
msv4_measure = column_description_casacore_to_msv4_measure(
|
|
@@ -222,31 +360,31 @@ def create_weather_xds(in_file: str):
|
|
|
222
360
|
if msv4_measure:
|
|
223
361
|
weather_xds[var_name].attrs.update(msv4_measure)
|
|
224
362
|
|
|
225
|
-
if key in ["
|
|
363
|
+
if key in ["INTERVAL"]:
|
|
226
364
|
weather_xds[var_name].attrs.update({"units": ["s"], "type": "quantity"})
|
|
227
|
-
elif key in ["
|
|
365
|
+
elif key in ["H2O"]:
|
|
228
366
|
weather_xds[var_name].attrs.update(
|
|
229
367
|
{"units": ["/m^2"], "type": "quantity"}
|
|
230
368
|
)
|
|
231
|
-
elif key in ["
|
|
369
|
+
elif key in ["IONOS_ELECTRON"]:
|
|
232
370
|
weather_xds[var_name].attrs.update(
|
|
233
371
|
{"units": ["/m^2"], "type": "quantity"}
|
|
234
372
|
)
|
|
235
|
-
elif key in ["
|
|
373
|
+
elif key in ["PRESSURE"]:
|
|
236
374
|
weather_xds[var_name].attrs.update(
|
|
237
375
|
{"units": ["Pa"], "type": "quantity"}
|
|
238
376
|
)
|
|
239
|
-
elif key in ["
|
|
377
|
+
elif key in ["REL_HUMIDITY"]:
|
|
240
378
|
weather_xds[var_name].attrs.update({"units": ["%"], "type": "quantity"})
|
|
241
|
-
elif key in ["
|
|
379
|
+
elif key in ["TEMPERATURE"]:
|
|
242
380
|
weather_xds[var_name].attrs.update({"units": ["K"], "type": "quantity"})
|
|
243
|
-
elif key in ["
|
|
381
|
+
elif key in ["DEW_POINT"]:
|
|
244
382
|
weather_xds[var_name].attrs.update({"units": ["K"], "type": "quantity"})
|
|
245
|
-
elif key in ["
|
|
383
|
+
elif key in ["WIND_DIRECTION"]:
|
|
246
384
|
weather_xds[var_name].attrs.update(
|
|
247
385
|
{"units": ["rad"], "type": "quantity"}
|
|
248
386
|
)
|
|
249
|
-
elif key in ["
|
|
387
|
+
elif key in ["WIND_SPEED"]:
|
|
250
388
|
weather_xds[var_name].attrs.update(
|
|
251
389
|
{"units": ["m/s"], "type": "quantity"}
|
|
252
390
|
)
|
|
@@ -292,38 +430,40 @@ def create_pointing_xds(
|
|
|
292
430
|
to_new_data_variable_names = {
|
|
293
431
|
# "name": "NAME", # removed
|
|
294
432
|
# "time_origin": "TIME_ORIGIN", # removed?
|
|
295
|
-
"
|
|
296
|
-
"
|
|
297
|
-
"
|
|
298
|
-
"
|
|
299
|
-
"
|
|
433
|
+
"DIRECTION": "BEAM_POINTING",
|
|
434
|
+
"ENCODER": "DISH_MEASURED_POINTING",
|
|
435
|
+
"TARGET": "TARGET", # => attribute?
|
|
436
|
+
"POINTING_OFFSET": "POINTING_OFFSET",
|
|
437
|
+
"SOURCE_OFFSET": "SOURCE_OFFSET",
|
|
300
438
|
# "pointing_model_id": "POINTING_MODEL_ID", # removed
|
|
301
439
|
# "tracking": "TRACKING", # => attribute
|
|
302
440
|
# "on_source": "ON_SOURCE", # removed
|
|
303
|
-
"
|
|
441
|
+
"OVER_THE_TOP": "OVER_THE_TOP",
|
|
304
442
|
}
|
|
305
|
-
|
|
443
|
+
time_ant_dims = ["time", "antenna_id"]
|
|
444
|
+
time_ant_dir_dims = time_ant_dims + ["direction"]
|
|
306
445
|
data_variable_dims = {
|
|
307
446
|
# "name": ["time", "antenna_id"], # removed
|
|
308
447
|
# "time_origin": ["time", "antenna_id"], # removed?
|
|
309
|
-
"
|
|
310
|
-
"
|
|
311
|
-
"
|
|
312
|
-
"
|
|
313
|
-
"
|
|
448
|
+
"DIRECTION": time_ant_dir_dims,
|
|
449
|
+
"ENCODER": time_ant_dir_dims,
|
|
450
|
+
"TARGET": time_ant_dir_dims,
|
|
451
|
+
"POINTING_OFFSET": time_ant_dir_dims,
|
|
452
|
+
"SOURCE_OFFSET": time_ant_dir_dims,
|
|
314
453
|
# "pointing_model_id": ["time", "antenna_id"], # removed
|
|
315
454
|
# "tracking": ["time", "antenna_id"], # => attribute
|
|
316
455
|
# "on_source": ["time", "antenna_id"], # removed
|
|
317
|
-
"
|
|
456
|
+
"OVER_THE_TOP": time_ant_dims,
|
|
318
457
|
}
|
|
319
|
-
|
|
320
|
-
|
|
458
|
+
# Unused here
|
|
459
|
+
# to_new_coord_names = {"ra/dec": "direction"}
|
|
460
|
+
# coord_dims = {}
|
|
321
461
|
|
|
322
462
|
taql_time_range = make_taql_where_between_min_max(
|
|
323
463
|
time_min_max, in_file, "POINTING", "TIME"
|
|
324
464
|
)
|
|
325
465
|
# Read POINTING table into a Xarray Dataset.
|
|
326
|
-
generic_pointing_xds =
|
|
466
|
+
generic_pointing_xds = load_generic_table(
|
|
327
467
|
in_file,
|
|
328
468
|
"POINTING",
|
|
329
469
|
rename_ids=subt_rename_ids["POINTING"],
|
|
@@ -347,8 +487,41 @@ def create_pointing_xds(
|
|
|
347
487
|
for key in generic_pointing_xds:
|
|
348
488
|
if key in to_new_data_variable_names:
|
|
349
489
|
data_var_name = to_new_data_variable_names[key]
|
|
490
|
+
# Corrects dim sizes of "empty cell" variables, such as empty DIRECTION, TARGET, etc.
|
|
491
|
+
# TODO: this should be moved to a function when/if stable - perhaps 'correct_generic_pointing_xds'
|
|
492
|
+
if (
|
|
493
|
+
"dim_2" in generic_pointing_xds.sizes
|
|
494
|
+
and generic_pointing_xds.sizes["dim_2"] == 0
|
|
495
|
+
):
|
|
496
|
+
# When all direction variables are "empty"
|
|
497
|
+
data_var_data = xr.DataArray(
|
|
498
|
+
[[[[np.nan, np.nan]]]],
|
|
499
|
+
dims=generic_pointing_xds.dims,
|
|
500
|
+
).isel(n_polynomial=0, drop=True)
|
|
501
|
+
elif (
|
|
502
|
+
"dir" in generic_pointing_xds.sizes
|
|
503
|
+
and generic_pointing_xds.sizes["dir"] == 0
|
|
504
|
+
):
|
|
505
|
+
# When some direction variables are "empty" but some are populated properly
|
|
506
|
+
if "dim_2" in generic_pointing_xds[key].sizes:
|
|
507
|
+
data_var_data = xr.DataArray(
|
|
508
|
+
generic_pointing_xds[key].values,
|
|
509
|
+
dims=generic_pointing_xds[key].dims,
|
|
510
|
+
)
|
|
511
|
+
else:
|
|
512
|
+
shape = tuple(
|
|
513
|
+
generic_pointing_xds.sizes[dim]
|
|
514
|
+
for dim in ["TIME", "ANTENNA_ID"]
|
|
515
|
+
) + (2,)
|
|
516
|
+
data_var_data = xr.DataArray(
|
|
517
|
+
np.full(shape, np.nan),
|
|
518
|
+
dims=generic_pointing_xds[key].dims,
|
|
519
|
+
)
|
|
520
|
+
else:
|
|
521
|
+
data_var_data = generic_pointing_xds[key].data
|
|
522
|
+
|
|
350
523
|
pointing_xds[data_var_name] = xr.DataArray(
|
|
351
|
-
|
|
524
|
+
data_var_data, dims=data_variable_dims[key]
|
|
352
525
|
)
|
|
353
526
|
|
|
354
527
|
msv4_measure = column_description_casacore_to_msv4_measure(
|
|
@@ -358,8 +531,8 @@ def create_pointing_xds(
|
|
|
358
531
|
pointing_xds[data_var_name].attrs.update(msv4_measure)
|
|
359
532
|
|
|
360
533
|
coords = {
|
|
361
|
-
"time": generic_pointing_xds["
|
|
362
|
-
"antenna_id": np.arange(generic_pointing_xds.sizes["
|
|
534
|
+
"time": generic_pointing_xds["TIME"].values,
|
|
535
|
+
"antenna_id": np.arange(generic_pointing_xds.sizes["ANTENNA_ID"]),
|
|
363
536
|
"direction": ["ra", "dec"],
|
|
364
537
|
}
|
|
365
538
|
pointing_xds = pointing_xds.assign_coords(coords)
|
|
@@ -367,15 +540,15 @@ def create_pointing_xds(
|
|
|
367
540
|
# missing attributes
|
|
368
541
|
pointing_xds["time"].attrs.update({"units": ["s"], "type": "quantity"})
|
|
369
542
|
|
|
370
|
-
if "
|
|
543
|
+
if "TRACKING" in generic_pointing_xds.data_vars:
|
|
371
544
|
pointing_xds.attrs["tracking"] = generic_pointing_xds.data_vars[
|
|
372
|
-
"
|
|
545
|
+
"TRACKING"
|
|
373
546
|
].values[0, 0]
|
|
374
547
|
|
|
375
548
|
# Move target from data_vars to attributes?
|
|
376
549
|
move_target_as_attr = False
|
|
377
550
|
if move_target_as_attr:
|
|
378
|
-
target = generic_pointing_xds.data_vars["
|
|
551
|
+
target = generic_pointing_xds.data_vars["TARGET"]
|
|
379
552
|
pointing_xds.attrs["target"] = {
|
|
380
553
|
"dims": ["direction"],
|
|
381
554
|
"data": target.values[0, 0].tolist(),
|
|
@@ -388,5 +561,4 @@ def create_pointing_xds(
|
|
|
388
561
|
pointing_xds = interpolate_to_time(pointing_xds, interp_time, "pointing_xds")
|
|
389
562
|
|
|
390
563
|
logger.debug(f"create_pointing_xds() execution time {time.time() - start:0.2f} s")
|
|
391
|
-
|
|
392
564
|
return pointing_xds
|