xradio 0.0.31__py3-none-any.whl → 0.0.34__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 +238 -55
- 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.34.dist-info}/METADATA +1 -1
- {xradio-0.0.31.dist-info → xradio-0.0.34.dist-info}/RECORD +29 -31
- {xradio-0.0.31.dist-info → xradio-0.0.34.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.34.dist-info}/LICENSE.txt +0 -0
- {xradio-0.0.31.dist-info → xradio-0.0.34.dist-info}/top_level.txt +0 -0
xradio/vis/_vis_utils/_ms/{_tables/create_field_and_source_xds.py → create_field_and_source_xds.py}
RENAMED
|
@@ -13,14 +13,12 @@ from xradio.vis._vis_utils._ms.subtables import subt_rename_ids
|
|
|
13
13
|
from xradio.vis._vis_utils._ms._tables.read import (
|
|
14
14
|
convert_casacore_time_to_mjd,
|
|
15
15
|
make_taql_where_between_min_max,
|
|
16
|
-
|
|
16
|
+
load_generic_table,
|
|
17
17
|
)
|
|
18
|
-
from xradio.vis._vis_utils._ms._tables.table_query import open_table_ro
|
|
19
18
|
import graphviper.utils.logger as logger
|
|
20
19
|
from xradio._utils.list_and_array import (
|
|
21
20
|
check_if_consistent,
|
|
22
21
|
unique_1d,
|
|
23
|
-
to_list,
|
|
24
22
|
to_np_array,
|
|
25
23
|
)
|
|
26
24
|
from xradio._utils.common import cast_to_str, convert_to_si_units, add_position_offsets
|
|
@@ -87,6 +85,16 @@ def create_field_and_source_xds(
|
|
|
87
85
|
f"create_field_and_source_xds() execution time {time.time() - start_time:0.2f} s"
|
|
88
86
|
)
|
|
89
87
|
|
|
88
|
+
# Check if we can drop time axis. The phase centers are repeated.
|
|
89
|
+
if field_times is not None:
|
|
90
|
+
if is_single_dish:
|
|
91
|
+
center_dv = "FIELD_REFERENCE_CENTER"
|
|
92
|
+
else:
|
|
93
|
+
center_dv = "FIELD_PHASE_CENTER"
|
|
94
|
+
|
|
95
|
+
if np.unique(field_and_source_xds[center_dv], axis=0).shape[0] == 1:
|
|
96
|
+
field_and_source_xds = field_and_source_xds.isel(time=0).drop_vars("time")
|
|
97
|
+
|
|
90
98
|
return field_and_source_xds, source_id
|
|
91
99
|
|
|
92
100
|
|
|
@@ -131,7 +139,7 @@ def extract_ephemeris_info(
|
|
|
131
139
|
taql_time_range = make_taql_where_between_min_max(
|
|
132
140
|
min_max_mjd, path, table_name, "MJD"
|
|
133
141
|
)
|
|
134
|
-
ephemeris_xds =
|
|
142
|
+
ephemeris_xds = load_generic_table(
|
|
135
143
|
path, table_name, timecols=["MJD"], taql_where=taql_time_range
|
|
136
144
|
)
|
|
137
145
|
|
|
@@ -141,6 +149,7 @@ def extract_ephemeris_info(
|
|
|
141
149
|
ephemeris_xds = ephemeris_xds.isel(
|
|
142
150
|
ephemeris_id=0
|
|
143
151
|
) # Collapse the ephemeris_id dimension.
|
|
152
|
+
# Data varaibles ['time', 'RA', 'DEC', 'Rho', 'RadVel', 'NP_ang', 'NP_dist', 'DiskLong', 'DiskLat', 'Sl_lon', 'Sl_lat', 'r', 'rdot', 'phang']
|
|
144
153
|
|
|
145
154
|
# Get meta data.
|
|
146
155
|
ephemeris_meta = ephemeris_xds.attrs["other"]["msv2"]["ctds_attrs"]
|
|
@@ -177,9 +186,9 @@ def extract_ephemeris_info(
|
|
|
177
186
|
temp_xds["SOURCE_POSITION"] = xr.DataArray(
|
|
178
187
|
np.column_stack(
|
|
179
188
|
(
|
|
180
|
-
ephemeris_xds["
|
|
181
|
-
ephemeris_xds["
|
|
182
|
-
ephemeris_xds["
|
|
189
|
+
ephemeris_xds["RA"].data,
|
|
190
|
+
ephemeris_xds["DEC"].data,
|
|
191
|
+
ephemeris_xds["Rho"].data,
|
|
183
192
|
)
|
|
184
193
|
),
|
|
185
194
|
dims=["ephem_time", "sky_pos_label"],
|
|
@@ -196,7 +205,7 @@ def extract_ephemeris_info(
|
|
|
196
205
|
|
|
197
206
|
# Add mandatory data: SOURCE_RADIAL_VELOCITY
|
|
198
207
|
temp_xds["SOURCE_RADIAL_VELOCITY"] = xr.DataArray(
|
|
199
|
-
ephemeris_xds["
|
|
208
|
+
ephemeris_xds["RadVel"].data, dims=["ephem_time"]
|
|
200
209
|
)
|
|
201
210
|
temp_xds["SOURCE_RADIAL_VELOCITY"].attrs.update(
|
|
202
211
|
{
|
|
@@ -230,9 +239,9 @@ def extract_ephemeris_info(
|
|
|
230
239
|
) # I think the units are ['deg','deg','m'] and 'WGS84'.
|
|
231
240
|
|
|
232
241
|
# Add optional data NORTH_POLE_POSITION_ANGLE and NORTH_POLE_ANGULAR_DISTANCE
|
|
233
|
-
if "
|
|
242
|
+
if "NP_ang" in ephemeris_xds.data_vars:
|
|
234
243
|
temp_xds["NORTH_POLE_POSITION_ANGLE"] = xr.DataArray(
|
|
235
|
-
ephemeris_xds["
|
|
244
|
+
ephemeris_xds["NP_ang"].data, dims=["ephem_time"]
|
|
236
245
|
)
|
|
237
246
|
temp_xds["NORTH_POLE_POSITION_ANGLE"].attrs.update(
|
|
238
247
|
{
|
|
@@ -245,9 +254,9 @@ def extract_ephemeris_info(
|
|
|
245
254
|
}
|
|
246
255
|
)
|
|
247
256
|
|
|
248
|
-
if "
|
|
257
|
+
if "NP_dist" in ephemeris_xds.data_vars:
|
|
249
258
|
temp_xds["NORTH_POLE_ANGULAR_DISTANCE"] = xr.DataArray(
|
|
250
|
-
ephemeris_xds["
|
|
259
|
+
ephemeris_xds["NP_dist"].data, dims=["ephem_time"]
|
|
251
260
|
)
|
|
252
261
|
temp_xds["NORTH_POLE_ANGULAR_DISTANCE"].attrs.update(
|
|
253
262
|
{
|
|
@@ -261,25 +270,25 @@ def extract_ephemeris_info(
|
|
|
261
270
|
)
|
|
262
271
|
|
|
263
272
|
# Add optional data: SUB_OBSERVER_POSITION and SUB_SOLAR_POSITION
|
|
264
|
-
if "
|
|
273
|
+
if "DiskLong" in ephemris_column_description:
|
|
274
|
+
key_lon = "DiskLong"
|
|
275
|
+
key_lat = "DiskLat"
|
|
276
|
+
else:
|
|
277
|
+
key_lon = "diskLong"
|
|
278
|
+
key_lat = "diskLat"
|
|
279
|
+
|
|
280
|
+
if key_lon in ephemeris_xds.data_vars:
|
|
265
281
|
temp_xds["SUB_OBSERVER_POSITION"] = xr.DataArray(
|
|
266
282
|
np.column_stack(
|
|
267
283
|
(
|
|
268
|
-
ephemeris_xds[
|
|
269
|
-
ephemeris_xds[
|
|
270
|
-
np.zeros(ephemeris_xds[
|
|
284
|
+
ephemeris_xds[key_lon].data,
|
|
285
|
+
ephemeris_xds[key_lat].data,
|
|
286
|
+
np.zeros(ephemeris_xds[key_lon].shape),
|
|
271
287
|
)
|
|
272
288
|
),
|
|
273
289
|
dims=["ephem_time", "ellipsoid_pos_label"],
|
|
274
290
|
)
|
|
275
291
|
|
|
276
|
-
if "DiskLong" in ephemris_column_description:
|
|
277
|
-
units_key_lon = "DiskLong"
|
|
278
|
-
units_key_lat = "DiskLat"
|
|
279
|
-
else:
|
|
280
|
-
units_key_lon = "diskLong"
|
|
281
|
-
units_key_lat = "diskLat"
|
|
282
|
-
|
|
283
292
|
temp_xds["SUB_OBSERVER_POSITION"].attrs.update(
|
|
284
293
|
{
|
|
285
294
|
"type": "location",
|
|
@@ -288,26 +297,22 @@ def extract_ephemeris_info(
|
|
|
288
297
|
"coordinate_system": "planetodetic",
|
|
289
298
|
"units": [
|
|
290
299
|
cast_to_str(
|
|
291
|
-
ephemris_column_description[
|
|
292
|
-
unit_keyword
|
|
293
|
-
]
|
|
300
|
+
ephemris_column_description[key_lon]["keywords"][unit_keyword]
|
|
294
301
|
),
|
|
295
302
|
cast_to_str(
|
|
296
|
-
ephemris_column_description[
|
|
297
|
-
unit_keyword
|
|
298
|
-
]
|
|
303
|
+
ephemris_column_description[key_lat]["keywords"][unit_keyword]
|
|
299
304
|
),
|
|
300
305
|
"m",
|
|
301
306
|
],
|
|
302
307
|
}
|
|
303
308
|
)
|
|
304
309
|
|
|
305
|
-
if "
|
|
310
|
+
if "SI_lon" in ephemeris_xds.data_vars:
|
|
306
311
|
temp_xds["SUB_SOLAR_POSITION"] = xr.DataArray(
|
|
307
312
|
np.column_stack(
|
|
308
313
|
(
|
|
309
|
-
ephemeris_xds["
|
|
310
|
-
ephemeris_xds["
|
|
314
|
+
ephemeris_xds["SI_lon"].data,
|
|
315
|
+
ephemeris_xds["SI_lat"].data,
|
|
311
316
|
ephemeris_xds["r"].data,
|
|
312
317
|
)
|
|
313
318
|
),
|
|
@@ -413,7 +418,7 @@ def extract_ephemeris_info(
|
|
|
413
418
|
dims=[xds["SOURCE_POSITION"].dims[0], "sky_pos_label"],
|
|
414
419
|
)
|
|
415
420
|
|
|
416
|
-
xds[
|
|
421
|
+
xds[center_dv].attrs.update(xds["SOURCE_POSITION"].attrs)
|
|
417
422
|
|
|
418
423
|
return xds
|
|
419
424
|
|
|
@@ -438,7 +443,7 @@ def extract_source_info(xds, path, source_id, spectral_window_id):
|
|
|
438
443
|
xds : xr.Dataset
|
|
439
444
|
The xarray dataset with the added source information.
|
|
440
445
|
"""
|
|
441
|
-
|
|
446
|
+
coords = {}
|
|
442
447
|
is_ephemeris = xds.attrs[
|
|
443
448
|
"is_ephemeris"
|
|
444
449
|
] # If ephemeris data is present we ignore the SOURCE_DIRECTION in the source table.
|
|
@@ -452,12 +457,10 @@ def extract_source_info(xds, path, source_id, spectral_window_id):
|
|
|
452
457
|
) # Need to add this for ps.summary() to work.
|
|
453
458
|
return xds
|
|
454
459
|
|
|
455
|
-
from xradio._utils.list_and_array import check_if_consistent, unique_1d
|
|
456
|
-
|
|
457
460
|
unique_source_id = unique_1d(source_id)
|
|
458
461
|
taql_where = f"where (SOURCE_ID IN [{','.join(map(str, unique_source_id))}]) AND (SPECTRAL_WINDOW_ID = {spectral_window_id})"
|
|
459
462
|
|
|
460
|
-
source_xds =
|
|
463
|
+
source_xds = load_generic_table(
|
|
461
464
|
path,
|
|
462
465
|
"SOURCE",
|
|
463
466
|
ignore=["SOURCE_MODEL"], # Trying to read SOURCE_MODEL causes an error.
|
|
@@ -466,7 +469,7 @@ def extract_source_info(xds, path, source_id, spectral_window_id):
|
|
|
466
469
|
|
|
467
470
|
if len(source_xds.data_vars) == 0: # The source xds is empty.
|
|
468
471
|
logger.warning(
|
|
469
|
-
f"SOURCE table empty for source_id {
|
|
472
|
+
f"SOURCE table empty for (unique) source_id {unique_source_id} and spectral_window_id {spectral_window_id}."
|
|
470
473
|
)
|
|
471
474
|
xds = xds.assign_coords(
|
|
472
475
|
{"source_name": "Unknown"}
|
|
@@ -474,36 +477,35 @@ def extract_source_info(xds, path, source_id, spectral_window_id):
|
|
|
474
477
|
return xds
|
|
475
478
|
|
|
476
479
|
assert (
|
|
477
|
-
len(source_xds.
|
|
480
|
+
len(source_xds.SPECTRAL_WINDOW_ID) == 1
|
|
478
481
|
), "Can only process source table with a single spectral_window_id for a given MSv4 partition."
|
|
479
482
|
|
|
480
483
|
# This source table time is not the same as the time in the field_and_source_xds that is derived from the main MSv4 time axis.
|
|
481
484
|
# The source_id maps to the time axis in the field_and_source_xds. That is why "if len(source_id) == 1" is used to check if there should be a time axis.
|
|
482
|
-
assert (
|
|
483
|
-
|
|
485
|
+
assert len(source_xds.TIME) <= len(
|
|
486
|
+
unique_source_id
|
|
484
487
|
), "Can only process source table with a single time entry for a source_id and spectral_window_id."
|
|
485
488
|
|
|
486
|
-
source_xds = source_xds.isel(
|
|
489
|
+
source_xds = source_xds.isel(TIME=0, SPECTRAL_WINDOW_ID=0, drop=True)
|
|
487
490
|
source_column_description = source_xds.attrs["other"]["msv2"]["ctds_attrs"][
|
|
488
491
|
"column_descriptions"
|
|
489
492
|
]
|
|
490
493
|
|
|
491
494
|
# Get source name (the time axis is optional and will probably be required if the partition scheme does not include 'FIELD_ID' or 'SOURCE_ID'.).
|
|
492
495
|
# Note again that this optional time axis has nothing to do with the original time axis in the source table that we drop.
|
|
493
|
-
coords = {}
|
|
494
496
|
if len(source_id) == 1:
|
|
495
|
-
source_xds = source_xds.sel(
|
|
497
|
+
source_xds = source_xds.sel(SOURCE_ID=source_id[0])
|
|
496
498
|
coords["source_name"] = (
|
|
497
|
-
source_xds["
|
|
499
|
+
source_xds["NAME"].values.item() + "_" + str(source_id[0])
|
|
498
500
|
)
|
|
499
501
|
direction_dims = ["sky_dir_label"]
|
|
500
502
|
# coords["source_id"] = source_id[0]
|
|
501
503
|
else:
|
|
502
|
-
source_xds = source_xds.sel(
|
|
504
|
+
source_xds = source_xds.sel(SOURCE_ID=source_id)
|
|
503
505
|
coords["source_name"] = (
|
|
504
506
|
"time",
|
|
505
507
|
np.char.add(
|
|
506
|
-
source_xds["
|
|
508
|
+
source_xds["NAME"].data, np.char.add("_", source_id.astype(str))
|
|
507
509
|
),
|
|
508
510
|
)
|
|
509
511
|
direction_dims = ["time", "sky_dir_label"]
|
|
@@ -511,41 +513,67 @@ def extract_source_info(xds, path, source_id, spectral_window_id):
|
|
|
511
513
|
|
|
512
514
|
# If ephemeris data is present we ignore the SOURCE_DIRECTION.
|
|
513
515
|
if not is_ephemeris:
|
|
516
|
+
direction_msv2_col = "DIRECTION"
|
|
514
517
|
msv4_measure = column_description_casacore_to_msv4_measure(
|
|
515
|
-
source_column_description[
|
|
516
|
-
)
|
|
517
|
-
xds["SOURCE_DIRECTION"] = xr.DataArray(
|
|
518
|
-
source_xds["direction"].data, dims=direction_dims
|
|
518
|
+
source_column_description[direction_msv2_col]
|
|
519
519
|
)
|
|
520
|
+
|
|
521
|
+
msv2_direction_dims = source_xds[direction_msv2_col].dims
|
|
522
|
+
if (
|
|
523
|
+
len(msv2_direction_dims) == len(direction_dims) + 1
|
|
524
|
+
and "dim_1" in msv2_direction_dims
|
|
525
|
+
and "dim_2" in msv2_direction_dims
|
|
526
|
+
):
|
|
527
|
+
# CASA simulator produces transposed direction values, adding an
|
|
528
|
+
# unexpected dimension. Drop it (https://github.com/casangi/xradio/issues/#196)
|
|
529
|
+
direction_var = source_xds[direction_msv2_col].isel(dim_1=0, drop=True)
|
|
530
|
+
else:
|
|
531
|
+
direction_var = source_xds[direction_msv2_col]
|
|
532
|
+
|
|
533
|
+
xds["SOURCE_DIRECTION"] = xr.DataArray(direction_var.data, dims=direction_dims)
|
|
520
534
|
xds["SOURCE_DIRECTION"].attrs.update(msv4_measure)
|
|
521
535
|
|
|
522
536
|
# Do we have line data:
|
|
523
|
-
if source_xds["
|
|
524
|
-
num_lines = np.array([source_xds["
|
|
537
|
+
if source_xds["NUM_LINES"].data.ndim == 0:
|
|
538
|
+
num_lines = np.array([source_xds["NUM_LINES"].data.item()])
|
|
525
539
|
else:
|
|
526
|
-
num_lines = source_xds["
|
|
540
|
+
num_lines = source_xds["NUM_LINES"].data
|
|
527
541
|
|
|
528
542
|
if any(num_lines > 0):
|
|
529
543
|
|
|
544
|
+
# Transition is an optional column and occasionally not populated
|
|
545
|
+
if "TRANSITION" in source_xds.data_vars:
|
|
546
|
+
transition_var_data = source_xds["TRANSITION"].data
|
|
547
|
+
else:
|
|
548
|
+
transition_var_data = np.zeros(source_xds["DIRECTION"].shape, dtype="str")
|
|
549
|
+
|
|
550
|
+
# if TRANSITION is left empty (or otherwise incomplete), and num_lines > 1,
|
|
551
|
+
# the data_vars expect a "num_lines" size in the last dimension
|
|
552
|
+
vars_shape = transition_var_data.shape[:-1] + (np.max(num_lines),)
|
|
553
|
+
if transition_var_data.shape == vars_shape:
|
|
554
|
+
coords_lines_data = transition_var_data
|
|
555
|
+
else:
|
|
556
|
+
coords_lines_data = np.broadcast_to(
|
|
557
|
+
transition_var_data, max(transition_var_data.shape, vars_shape)
|
|
558
|
+
)
|
|
559
|
+
|
|
530
560
|
if len(source_id) == 1:
|
|
531
|
-
coords_lines = {"line_name":
|
|
561
|
+
coords_lines = {"line_name": coords_lines_data}
|
|
532
562
|
xds = xds.assign_coords(coords_lines)
|
|
533
563
|
line_dims = ["line_label"]
|
|
534
564
|
else:
|
|
535
|
-
coords_lines = {
|
|
536
|
-
"line_name": (("time", "line_label"), source_xds["transition"].data)
|
|
537
|
-
}
|
|
565
|
+
coords_lines = {"line_name": (("time", "line_label"), coords_lines_data)}
|
|
538
566
|
xds = xds.assign_coords(coords_lines)
|
|
539
567
|
line_dims = ["time", "line_label"]
|
|
540
568
|
|
|
541
569
|
optional_data_variables = {
|
|
542
|
-
"
|
|
543
|
-
"
|
|
570
|
+
"REST_FREQUENCY": "LINE_REST_FREQUENCY",
|
|
571
|
+
"SYSVEL": "LINE_SYSTEMIC_VELOCITY",
|
|
544
572
|
}
|
|
545
573
|
for generic_name, msv4_name in optional_data_variables.items():
|
|
546
574
|
if generic_name in source_xds:
|
|
547
575
|
msv4_measure = column_description_casacore_to_msv4_measure(
|
|
548
|
-
source_column_description[generic_name
|
|
576
|
+
source_column_description[generic_name]
|
|
549
577
|
)
|
|
550
578
|
|
|
551
579
|
xds[msv4_name] = xr.DataArray(
|
|
@@ -555,7 +583,7 @@ def extract_source_info(xds, path, source_id, spectral_window_id):
|
|
|
555
583
|
|
|
556
584
|
# Need to add doppler info if present. Add check.
|
|
557
585
|
try:
|
|
558
|
-
doppler_xds =
|
|
586
|
+
doppler_xds = load_generic_table(
|
|
559
587
|
path,
|
|
560
588
|
"DOPPLER",
|
|
561
589
|
)
|
|
@@ -593,13 +621,13 @@ def create_field_info_and_check_ephemeris(
|
|
|
593
621
|
ephemeris_table_name : str
|
|
594
622
|
The name of the ephemeris table.
|
|
595
623
|
"""
|
|
624
|
+
coords = {}
|
|
596
625
|
|
|
597
|
-
|
|
598
|
-
unqiue_field_id = unique_1d(
|
|
626
|
+
unique_field_id = unique_1d(
|
|
599
627
|
field_id
|
|
600
|
-
) # field_ids can be repeated so that the time mapping is correct if there are multiple fields. The
|
|
601
|
-
taql_where = f"where (ROWID() IN [{','.join(map(str,
|
|
602
|
-
field_xds =
|
|
628
|
+
) # field_ids can be repeated so that the time mapping is correct if there are multiple fields. The load_generic_table required unique field_ids.
|
|
629
|
+
taql_where = f"where (ROWID() IN [{','.join(map(str, unique_field_id))}])"
|
|
630
|
+
field_xds = load_generic_table(
|
|
603
631
|
in_file,
|
|
604
632
|
"FIELD",
|
|
605
633
|
rename_ids=subt_rename_ids["FIELD"],
|
|
@@ -611,9 +639,11 @@ def create_field_info_and_check_ephemeris(
|
|
|
611
639
|
), "Polynomial field positions not supported. Please open an issue on https://github.com/casangi/xradio/issues so that we can add support for this."
|
|
612
640
|
field_xds = field_xds.isel(poly_id=0, drop=True)
|
|
613
641
|
# field_xds = field_xds.assign_coords({'field_id':field_xds['field_id'].data})
|
|
614
|
-
field_xds = field_xds.assign_coords({"field_id":
|
|
615
|
-
field_xds = field_xds.sel(
|
|
616
|
-
|
|
642
|
+
field_xds = field_xds.assign_coords({"field_id": unique_field_id})
|
|
643
|
+
field_xds = field_xds.sel(
|
|
644
|
+
field_id=field_id, drop=False
|
|
645
|
+
) # Make sure field_id match up with time axis (duplicate fields are allowed).
|
|
646
|
+
source_id = to_np_array(field_xds.SOURCE_ID.values)
|
|
617
647
|
|
|
618
648
|
ephemeris_table_name = None
|
|
619
649
|
ephemeris_path = None
|
|
@@ -623,10 +653,9 @@ def create_field_info_and_check_ephemeris(
|
|
|
623
653
|
)
|
|
624
654
|
|
|
625
655
|
# Need to check if ephemeris_id is present and if ephemeris table is present.
|
|
626
|
-
if "
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
) # int(field_xds["ephemeris_id"].data)
|
|
656
|
+
if "EPHEMERIS_ID" in field_xds:
|
|
657
|
+
# Note: this assumes partition_scheme includes "FIELD_ID"
|
|
658
|
+
ephemeris_id = check_if_consistent(field_xds.EPHEMERIS_ID, "EPHEMERIS_ID")
|
|
630
659
|
|
|
631
660
|
if ephemeris_id > -1:
|
|
632
661
|
files = os.listdir(os.path.join(in_file, "FIELD"))
|
|
@@ -654,48 +683,48 @@ def create_field_info_and_check_ephemeris(
|
|
|
654
683
|
|
|
655
684
|
if is_single_dish:
|
|
656
685
|
field_data_variables = {
|
|
657
|
-
"
|
|
686
|
+
"REFERENCE_DIR": "FIELD_REFERENCE_CENTER",
|
|
658
687
|
}
|
|
659
688
|
else:
|
|
660
689
|
field_data_variables = {
|
|
661
|
-
# "
|
|
662
|
-
"
|
|
663
|
-
# "
|
|
690
|
+
# "DELAY_DIR": "FIELD_DELAY_CENTER",
|
|
691
|
+
"PHASE_DIR": "FIELD_PHASE_CENTER",
|
|
692
|
+
# "REFERENCE_DIR": "FIELD_REFERENCE_CENTER",
|
|
664
693
|
}
|
|
665
694
|
|
|
666
695
|
field_measures_type = "sky_coord"
|
|
667
696
|
|
|
668
|
-
coords = {}
|
|
669
697
|
coords["sky_dir_label"] = ["ra", "dec"]
|
|
670
698
|
field_column_description = field_xds.attrs["other"]["msv2"]["ctds_attrs"][
|
|
671
699
|
"column_descriptions"
|
|
672
700
|
]
|
|
673
701
|
|
|
674
|
-
coords = {}
|
|
675
702
|
# field_times is the same as the time axis in the main MSv4 dataset and is used if more than one field is present.
|
|
676
703
|
if field_times is not None:
|
|
677
704
|
coords["time"] = field_times
|
|
678
705
|
dims = ["time", "sky_dir_label"]
|
|
679
706
|
coords["field_name"] = (
|
|
680
707
|
"time",
|
|
681
|
-
np.char.add(field_xds["
|
|
708
|
+
np.char.add(field_xds["NAME"].data, np.char.add("_", field_id.astype(str))),
|
|
682
709
|
)
|
|
683
710
|
# coords["field_id"] = ("time", field_id)
|
|
684
711
|
else:
|
|
685
|
-
coords["field_name"] = field_xds["
|
|
712
|
+
coords["field_name"] = field_xds["NAME"].values.item() + "_" + str(field_id)
|
|
686
713
|
# coords["field_id"] = field_id
|
|
687
714
|
dims = ["sky_dir_label"]
|
|
688
715
|
|
|
689
716
|
for generic_name, msv4_name in field_data_variables.items():
|
|
690
717
|
|
|
691
|
-
|
|
718
|
+
delay_dir_ref_col = "DelayDir_Ref"
|
|
719
|
+
if field_xds.get(delay_dir_ref_col) is None:
|
|
692
720
|
delaydir_ref = None
|
|
693
721
|
else:
|
|
694
722
|
delaydir_ref = check_if_consistent(
|
|
695
|
-
field_xds.get(
|
|
723
|
+
field_xds.get(delay_dir_ref_col), delay_dir_ref_col
|
|
696
724
|
)
|
|
725
|
+
|
|
697
726
|
msv4_measure = column_description_casacore_to_msv4_measure(
|
|
698
|
-
field_column_description[generic_name
|
|
727
|
+
field_column_description[generic_name], ref_code=delaydir_ref
|
|
699
728
|
)
|
|
700
729
|
|
|
701
730
|
field_and_source_xds[msv4_name] = xr.DataArray.from_dict(
|
|
@@ -5,7 +5,7 @@ import numpy as np
|
|
|
5
5
|
import pandas as pd
|
|
6
6
|
import xarray as xr
|
|
7
7
|
|
|
8
|
-
from ._tables.read import
|
|
8
|
+
from ._tables.read import load_generic_table, read_flat_col_chunk
|
|
9
9
|
from ._tables.table_query import open_query, open_table_ro
|
|
10
10
|
from xradio._utils.list_and_array import unique_1d
|
|
11
11
|
|
|
@@ -45,7 +45,7 @@ def describe_ms(
|
|
|
45
45
|
]:
|
|
46
46
|
raise ValueError("invalid mode, must be summary, flat or expanded")
|
|
47
47
|
|
|
48
|
-
ddi_xds =
|
|
48
|
+
ddi_xds = load_generic_table(infile, "DATA_DESCRIPTION")
|
|
49
49
|
ddis = list(ddi_xds.row.values) if rowmap is None else list(rowmap.keys())
|
|
50
50
|
summary: Union[pd.DataFrame, Dict] = []
|
|
51
51
|
if mode == "summary":
|
|
@@ -100,8 +100,8 @@ def populate_ms_descr(
|
|
|
100
100
|
-------
|
|
101
101
|
pd.DataFrame
|
|
102
102
|
"""
|
|
103
|
-
spw_ids = ddi_xds.
|
|
104
|
-
pol_ids = ddi_xds.
|
|
103
|
+
spw_ids = ddi_xds.SPECTRAL_WINDOW_ID.values
|
|
104
|
+
pol_ids = ddi_xds.POLARIZATION_ID.values
|
|
105
105
|
sdf = {
|
|
106
106
|
"ddi": ddi,
|
|
107
107
|
"spw_id": spw_ids[ddi],
|
|
@@ -110,8 +110,8 @@ def populate_ms_descr(
|
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
# figure out characteristics of main table from select subtables (must all be present)
|
|
113
|
-
spw_xds =
|
|
114
|
-
pol_xds =
|
|
113
|
+
spw_xds = load_generic_table(infile, "SPECTRAL_WINDOW")
|
|
114
|
+
pol_xds = load_generic_table(infile, "POLARIZATION")
|
|
115
115
|
|
|
116
116
|
if mode in ["expanded", "summary"]:
|
|
117
117
|
times = (
|
|
@@ -134,8 +134,8 @@ def populate_ms_descr(
|
|
|
134
134
|
}
|
|
135
135
|
)
|
|
136
136
|
|
|
137
|
-
chans = spw_xds.
|
|
138
|
-
pols = pol_xds.
|
|
137
|
+
chans = spw_xds.NUM_CHAN.values
|
|
138
|
+
pols = pol_xds.NUM_CORR.values
|
|
139
139
|
sdf.update(
|
|
140
140
|
{
|
|
141
141
|
"chans": (
|