xradio 0.0.36__tar.gz → 0.0.37__tar.gz
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-0.0.36/src/xradio.egg-info → xradio-0.0.37}/PKG-INFO +1 -1
- {xradio-0.0.36 → xradio-0.0.37}/pyproject.toml +1 -1
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/conversion.py +45 -27
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/create_antenna_xds.py +4 -1
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/create_field_and_source_xds.py +7 -3
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/msv4_sub_xdss.py +18 -11
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/read_processing_set.py +1 -1
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/schema.py +278 -99
- {xradio-0.0.36 → xradio-0.0.37/src/xradio.egg-info}/PKG-INFO +1 -1
- {xradio-0.0.36 → xradio-0.0.37}/LICENSE.txt +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/MANIFEST.in +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/README.md +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/setup.cfg +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/__init__.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/_utils/__init__.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/_utils/_casacore/tables.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/_utils/common.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/_utils/list_and_array.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/_utils/schema.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/_utils/zarr/__init__.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/_utils/zarr/common.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/image/__init__.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/image/_util/__init__.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/image/_util/_casacore/__init__.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/image/_util/_casacore/common.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/image/_util/_casacore/xds_from_casacore.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/image/_util/_casacore/xds_to_casacore.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/image/_util/_fits/xds_from_fits.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/image/_util/_zarr/common.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/image/_util/_zarr/xds_from_zarr.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/image/_util/_zarr/xds_to_zarr.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/image/_util/_zarr/zarr_low_level.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/image/_util/casacore.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/image/_util/common.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/image/_util/fits.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/image/_util/image_factory.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/image/_util/zarr.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/image/image.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/schema/__init__.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/schema/bases.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/schema/check.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/schema/dataclass.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/schema/metamodel.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/schema/typing.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/__init__.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_processing_set.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/__init__.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/_tables/load.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/_tables/load_main_table.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/_tables/read.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/_tables/read_main_table.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/_tables/read_subtables.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/_tables/table_query.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/_tables/write.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/_tables/write_exp_api.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/chunks.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/descr.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/msv2_msv3.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/msv2_to_msv4_meta.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/msv4_infos.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/optimised_functions.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/partition_queries.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/partitions.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/subtables.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_utils/cds.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_utils/partition_attrs.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_utils/stokes_types.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_utils/xds_helper.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_zarr/encoding.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_zarr/read.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_zarr/write.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/ms.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/zarr.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/convert_msv2_to_processing_set.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/load_processing_set.py +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio.egg-info/SOURCES.txt +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio.egg-info/dependency_links.txt +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio.egg-info/requires.txt +0 -0
- {xradio-0.0.36 → xradio-0.0.37}/src/xradio.egg-info/top_level.txt +0 -0
|
@@ -80,7 +80,7 @@ def check_chunksize(chunksize: dict, xds_type: str) -> None:
|
|
|
80
80
|
allowed_dims = [
|
|
81
81
|
"time",
|
|
82
82
|
"baseline_id",
|
|
83
|
-
"
|
|
83
|
+
"antenna_name",
|
|
84
84
|
"frequency",
|
|
85
85
|
"polarization",
|
|
86
86
|
]
|
|
@@ -138,7 +138,7 @@ def mem_chunksize_to_dict_main(chunksize: float, xds: xr.Dataset) -> Dict[str, i
|
|
|
138
138
|
It presently relies on the logic of mem_chunksize_to_dict_main_balanced() to find a
|
|
139
139
|
balanced list of dimension sizes for the chunks
|
|
140
140
|
|
|
141
|
-
Assumes these relevant dims: (time,
|
|
141
|
+
Assumes these relevant dims: (time, antenna_name/baseline_id, frequency,
|
|
142
142
|
polarization).
|
|
143
143
|
"""
|
|
144
144
|
|
|
@@ -149,11 +149,11 @@ def mem_chunksize_to_dict_main(chunksize: float, xds: xr.Dataset) -> Dict[str, i
|
|
|
149
149
|
"Cannot calculate chunk sizes when memory bound ({chunksize}) does not even allow all polarizations in one chunk"
|
|
150
150
|
)
|
|
151
151
|
|
|
152
|
-
|
|
153
|
-
total_size = calc_used_gb(xds.sizes,
|
|
152
|
+
baseline_or_antenna_name = find_baseline_or_antenna_var(xds)
|
|
153
|
+
total_size = calc_used_gb(xds.sizes, baseline_or_antenna_name, sizeof_vis)
|
|
154
154
|
|
|
155
155
|
ratio = chunksize / total_size
|
|
156
|
-
chunked_dims = ["time",
|
|
156
|
+
chunked_dims = ["time", baseline_or_antenna_name, "frequency", "polarization"]
|
|
157
157
|
if ratio >= 1:
|
|
158
158
|
result = {dim: xds.sizes[dim] for dim in chunked_dims}
|
|
159
159
|
logger.debug(
|
|
@@ -162,14 +162,17 @@ def mem_chunksize_to_dict_main(chunksize: float, xds: xr.Dataset) -> Dict[str, i
|
|
|
162
162
|
else:
|
|
163
163
|
xds_dim_sizes = {k: xds.sizes[k] for k in chunked_dims}
|
|
164
164
|
result = mem_chunksize_to_dict_main_balanced(
|
|
165
|
-
chunksize, xds_dim_sizes,
|
|
165
|
+
chunksize, xds_dim_sizes, baseline_or_antenna_name, sizeof_vis
|
|
166
166
|
)
|
|
167
167
|
|
|
168
168
|
return result
|
|
169
169
|
|
|
170
170
|
|
|
171
171
|
def mem_chunksize_to_dict_main_balanced(
|
|
172
|
-
chunksize: float,
|
|
172
|
+
chunksize: float,
|
|
173
|
+
xds_dim_sizes: dict,
|
|
174
|
+
baseline_or_antenna_name: str,
|
|
175
|
+
sizeof_vis: int,
|
|
173
176
|
) -> Dict[str, int]:
|
|
174
177
|
"""
|
|
175
178
|
Assumes the ratio is <1 and all pols can fit in memory (from
|
|
@@ -236,7 +239,7 @@ def mem_chunksize_to_dict_main_balanced(
|
|
|
236
239
|
dim_chunksizes[idx] += int_delta
|
|
237
240
|
used = np.prod(dim_chunksizes) * sizeof_vis / GiBYTES_TO_BYTES
|
|
238
241
|
|
|
239
|
-
chunked_dim_names = ["time",
|
|
242
|
+
chunked_dim_names = ["time", baseline_or_antenna_name, "frequency", "polarization"]
|
|
240
243
|
dim_chunksizes_int = [int(v) for v in dim_chunksizes]
|
|
241
244
|
result = dict(zip(chunked_dim_names, dim_chunksizes_int))
|
|
242
245
|
|
|
@@ -314,11 +317,11 @@ def mem_chunksize_to_dict_pointing(chunksize: float, xds: xr.Dataset) -> Dict[st
|
|
|
314
317
|
|
|
315
318
|
def find_baseline_or_antenna_var(xds: xr.Dataset) -> str:
|
|
316
319
|
if "baseline_id" in xds.coords:
|
|
317
|
-
|
|
318
|
-
elif "
|
|
319
|
-
|
|
320
|
+
baseline_or_antenna_name = "baseline_id"
|
|
321
|
+
elif "antenna_name" in xds.coords:
|
|
322
|
+
baseline_or_antenna_name = "antenna_name"
|
|
320
323
|
|
|
321
|
-
return
|
|
324
|
+
return baseline_or_antenna_name
|
|
322
325
|
|
|
323
326
|
|
|
324
327
|
def itemsize_vis_spec(xds: xr.Dataset) -> int:
|
|
@@ -352,11 +355,11 @@ def itemsize_pointing_spec(xds: xr.Dataset) -> int:
|
|
|
352
355
|
|
|
353
356
|
|
|
354
357
|
def calc_used_gb(
|
|
355
|
-
chunksizes: dict,
|
|
358
|
+
chunksizes: dict, baseline_or_antenna_name: str, sizeof_vis: int
|
|
356
359
|
) -> float:
|
|
357
360
|
return (
|
|
358
361
|
chunksizes["time"]
|
|
359
|
-
* chunksizes[
|
|
362
|
+
* chunksizes[baseline_or_antenna_name]
|
|
360
363
|
* chunksizes["frequency"]
|
|
361
364
|
* chunksizes["polarization"]
|
|
362
365
|
* sizeof_vis
|
|
@@ -734,7 +737,6 @@ def convert_and_write_partition(
|
|
|
734
737
|
"""
|
|
735
738
|
|
|
736
739
|
taql_where = create_taql_query(partition_info)
|
|
737
|
-
# print("taql_where", taql_where)
|
|
738
740
|
ddi = partition_info["DATA_DESC_ID"][0]
|
|
739
741
|
obs_mode = str(partition_info["OBS_MODE"][0])
|
|
740
742
|
|
|
@@ -877,7 +879,8 @@ def convert_and_write_partition(
|
|
|
877
879
|
)
|
|
878
880
|
|
|
879
881
|
# Change antenna_ids to antenna_names
|
|
880
|
-
xds = antenna_ids_to_names(xds, ant_xds)
|
|
882
|
+
xds = antenna_ids_to_names(xds, ant_xds, is_single_dish)
|
|
883
|
+
ant_xds_name_ids = ant_xds["antenna_name"].set_xindex("antenna_id")
|
|
881
884
|
ant_xds = ant_xds.drop_vars(
|
|
882
885
|
"antenna_id"
|
|
883
886
|
) # No longer needed after converting to name.
|
|
@@ -897,7 +900,7 @@ def convert_and_write_partition(
|
|
|
897
900
|
else:
|
|
898
901
|
pointing_interp_time = None
|
|
899
902
|
pointing_xds = create_pointing_xds(
|
|
900
|
-
in_file, time_min_max, pointing_interp_time
|
|
903
|
+
in_file, ant_xds_name_ids, time_min_max, pointing_interp_time
|
|
901
904
|
)
|
|
902
905
|
pointing_chunksize = parse_chunksize(
|
|
903
906
|
pointing_chunksize, "pointing", pointing_xds
|
|
@@ -953,7 +956,6 @@ def convert_and_write_partition(
|
|
|
953
956
|
|
|
954
957
|
# Fix UVW frame
|
|
955
958
|
# From CASA fixvis docs: clean and the im tool ignore the reference frame claimed by the UVW column (it is often mislabelled as ITRF when it is really FK5 (J2000)) and instead assume the (u, v, w)s are in the same frame as the phase tracking center. calcuvw does not yet force the UVW column and field centers to use the same reference frame! Blank = use the phase tracking frame of vis.
|
|
956
|
-
# print('##################',field_and_source_xds)
|
|
957
959
|
if is_single_dish:
|
|
958
960
|
xds.UVW.attrs["frame"] = field_and_source_xds[
|
|
959
961
|
"FIELD_REFERENCE_CENTER"
|
|
@@ -1037,17 +1039,19 @@ def convert_and_write_partition(
|
|
|
1037
1039
|
# logger.info("Saved ms_v4 " + file_name + " in " + str(time.time() - start_with) + "s")
|
|
1038
1040
|
|
|
1039
1041
|
|
|
1040
|
-
def antenna_ids_to_names(
|
|
1042
|
+
def antenna_ids_to_names(
|
|
1043
|
+
xds: xr.Dataset, ant_xds: xr.Dataset, is_single_dish: bool
|
|
1044
|
+
) -> xr.Dataset:
|
|
1041
1045
|
ant_xds = ant_xds.set_xindex(
|
|
1042
1046
|
"antenna_id"
|
|
1043
1047
|
) # Allows for non-dimension coordinate selection.
|
|
1044
1048
|
|
|
1045
|
-
if
|
|
1046
|
-
xds["baseline_antenna1_id"] = ant_xds["antenna_name"].sel(
|
|
1047
|
-
antenna_id=xds["baseline_antenna1_id"]
|
|
1049
|
+
if not is_single_dish: # Interferometer
|
|
1050
|
+
xds["baseline_antenna1_id"].data = ant_xds["antenna_name"].sel(
|
|
1051
|
+
antenna_id=xds["baseline_antenna1_id"].data
|
|
1048
1052
|
)
|
|
1049
|
-
xds["baseline_antenna2_id"] = ant_xds["antenna_name"].sel(
|
|
1050
|
-
antenna_id=xds["baseline_antenna2_id"]
|
|
1053
|
+
xds["baseline_antenna2_id"].data = ant_xds["antenna_name"].sel(
|
|
1054
|
+
antenna_id=xds["baseline_antenna2_id"].data
|
|
1051
1055
|
)
|
|
1052
1056
|
xds = xds.rename(
|
|
1053
1057
|
{
|
|
@@ -1055,9 +1059,23 @@ def antenna_ids_to_names(xds, ant_xds):
|
|
|
1055
1059
|
"baseline_antenna2_id": "baseline_antenna2_name",
|
|
1056
1060
|
}
|
|
1057
1061
|
)
|
|
1058
|
-
else:
|
|
1059
|
-
xds["
|
|
1060
|
-
|
|
1062
|
+
else:
|
|
1063
|
+
xds["baseline_id"] = ant_xds["antenna_name"].sel(antenna_id=xds["baseline_id"])
|
|
1064
|
+
unwanted_coords_from_ant_xds = [
|
|
1065
|
+
"antenna_id",
|
|
1066
|
+
"antenna_name",
|
|
1067
|
+
"mount",
|
|
1068
|
+
"station",
|
|
1069
|
+
]
|
|
1070
|
+
for unwanted_coord in unwanted_coords_from_ant_xds:
|
|
1071
|
+
xds = xds.drop_vars(unwanted_coord)
|
|
1072
|
+
xds = xds.rename({"baseline_id": "antenna_name"})
|
|
1073
|
+
|
|
1074
|
+
# drop more vars that seem unwanted in main_sd_xds, but there shouuld be a better way
|
|
1075
|
+
# of not creating them in the first place
|
|
1076
|
+
unwanted_coords_sd = ["baseline_antenna1_id", "baseline_antenna2_id"]
|
|
1077
|
+
for unwanted_coord in unwanted_coords_sd:
|
|
1078
|
+
xds = xds.drop_vars(unwanted_coord)
|
|
1061
1079
|
|
|
1062
1080
|
return xds
|
|
1063
1081
|
|
|
@@ -127,7 +127,6 @@ def extract_antenna_info(
|
|
|
127
127
|
) # Make sure the antenna_id order is correct.
|
|
128
128
|
|
|
129
129
|
# ['OFFSET', 'POSITION', 'DISH_DIAMETER', 'FLAG_ROW', 'MOUNT', 'NAME', 'STATION']
|
|
130
|
-
ant_xds = xr.Dataset()
|
|
131
130
|
ant_xds = ant_xds.assign_coords({"cartesian_pos_label": ["x", "y", "z"]})
|
|
132
131
|
|
|
133
132
|
ant_xds = convert_generic_xds_to_xradio_schema(
|
|
@@ -254,9 +253,13 @@ def extract_feed_info(
|
|
|
254
253
|
|
|
255
254
|
# print('ant_xds["ANTENNA_FEED_OFFSET"]',ant_xds["ANTENNA_FEED_OFFSET"].data)
|
|
256
255
|
# print('generic_feed_xds["POSITION"].data',generic_feed_xds["POSITION"].data)
|
|
256
|
+
feed_offset_attrs = ant_xds["ANTENNA_FEED_OFFSET"].attrs
|
|
257
257
|
ant_xds["ANTENNA_FEED_OFFSET"] = (
|
|
258
258
|
ant_xds["ANTENNA_FEED_OFFSET"] + generic_feed_xds["POSITION"].data
|
|
259
259
|
)
|
|
260
|
+
# recover attrs after arithmetic operation
|
|
261
|
+
ant_xds["ANTENNA_FEED_OFFSET"].attrs.update(feed_offset_attrs)
|
|
262
|
+
|
|
260
263
|
coords = {}
|
|
261
264
|
# coords["receptor_label"] = "pol_" + np.arange(ant_xds.sizes["receptor_label"]).astype(str) #Works on laptop but fails in github test runner.
|
|
262
265
|
coords["receptor_label"] = np.array(
|
{xradio-0.0.36 → xradio-0.0.37}/src/xradio/vis/_vis_utils/_ms/create_field_and_source_xds.py
RENAMED
|
@@ -30,7 +30,7 @@ def create_field_and_source_xds(
|
|
|
30
30
|
is_single_dish: bool,
|
|
31
31
|
time_min_max: Tuple[np.float64, np.float64],
|
|
32
32
|
ephemeris_interp_time: Union[xr.DataArray, None] = None,
|
|
33
|
-
):
|
|
33
|
+
) -> tuple[xr.Dataset, int]:
|
|
34
34
|
"""
|
|
35
35
|
Create a field and source xarray dataset (xds) from the given input file, field ID, and spectral window ID.
|
|
36
36
|
Data is extracted from the FIELD and SOURCE tables and if there is ephemeris data, it is also extracted.
|
|
@@ -57,11 +57,13 @@ def create_field_and_source_xds(
|
|
|
57
57
|
-------
|
|
58
58
|
field_and_source_xds : xr.Dataset
|
|
59
59
|
The xarray dataset containing the field and source information.
|
|
60
|
+
num_lines : int
|
|
61
|
+
Sum of num_lines for all unique sources.
|
|
60
62
|
"""
|
|
61
63
|
|
|
62
64
|
start_time = time.time()
|
|
63
65
|
|
|
64
|
-
field_and_source_xds = xr.Dataset()
|
|
66
|
+
field_and_source_xds = xr.Dataset(attrs={"type": "field_and_source"})
|
|
65
67
|
|
|
66
68
|
field_and_source_xds, ephemeris_path, ephemeris_table_name, source_id = (
|
|
67
69
|
extract_field_info_and_check_ephemeris(
|
|
@@ -433,7 +435,9 @@ def extract_ephemeris_info(
|
|
|
433
435
|
return xds
|
|
434
436
|
|
|
435
437
|
|
|
436
|
-
def extract_source_info(
|
|
438
|
+
def extract_source_info(
|
|
439
|
+
xds: xr.Dataset, path: str, source_id: int, spectral_window_id: int
|
|
440
|
+
) -> tuple[xr.Dataset, int]:
|
|
437
441
|
"""
|
|
438
442
|
Extracts source information from the given path and adds it to the xarray dataset.
|
|
439
443
|
|
|
@@ -121,11 +121,13 @@ def create_weather_xds(in_file: str):
|
|
|
121
121
|
# ['ANTENNA_ID', 'TIME', 'INTERVAL', 'H2O', 'IONOS_ELECTRON',
|
|
122
122
|
# 'PRESSURE', 'REL_HUMIDITY', 'TEMPERATURE', 'DEW_POINT',
|
|
123
123
|
# 'WIND_DIRECTION', 'WIND_SPEED']
|
|
124
|
-
weather_xds = xr.Dataset()
|
|
125
|
-
|
|
124
|
+
weather_xds = xr.Dataset(attrs={"type": "weather"})
|
|
125
|
+
time_attrs = column_description_casacore_to_msv4_measure(
|
|
126
|
+
weather_column_description["TIME"]
|
|
127
|
+
)
|
|
126
128
|
coords = {
|
|
127
129
|
"station_id": generic_weather_xds["STATION_ID"].data,
|
|
128
|
-
"time": generic_weather_xds["TIME"].data,
|
|
130
|
+
"time": ("time", generic_weather_xds["TIME"].data, time_attrs),
|
|
129
131
|
}
|
|
130
132
|
for key in generic_weather_xds:
|
|
131
133
|
msv4_measure = column_description_casacore_to_msv4_measure(
|
|
@@ -181,6 +183,7 @@ def create_weather_xds(in_file: str):
|
|
|
181
183
|
|
|
182
184
|
def create_pointing_xds(
|
|
183
185
|
in_file: str,
|
|
186
|
+
ant_xds_name_ids: xr.DataArray,
|
|
184
187
|
time_min_max: Union[Tuple[np.float64, np.float64], None],
|
|
185
188
|
interp_time: Union[xr.DataArray, None] = None,
|
|
186
189
|
) -> xr.Dataset:
|
|
@@ -194,6 +197,8 @@ def create_pointing_xds(
|
|
|
194
197
|
----------
|
|
195
198
|
in_file : str
|
|
196
199
|
Input MS name.
|
|
200
|
+
ant_xds_name_ids : xr.Dataset
|
|
201
|
+
antenna_name data array from antenna_xds, with name/id information
|
|
197
202
|
time_min_max : tuple
|
|
198
203
|
min / max times values to constrain loading (from the TIME column)
|
|
199
204
|
interp_time : Union[xr.DataArray, None] (Default value = None)
|
|
@@ -220,19 +225,19 @@ def create_pointing_xds(
|
|
|
220
225
|
# "on_source": "ON_SOURCE", # removed
|
|
221
226
|
"OVER_THE_TOP": "OVER_THE_TOP",
|
|
222
227
|
}
|
|
223
|
-
time_ant_dims = ["time", "
|
|
228
|
+
time_ant_dims = ["time", "antenna_name"]
|
|
224
229
|
time_ant_dir_dims = time_ant_dims + ["sky_dir_label"]
|
|
225
230
|
data_variable_dims = {
|
|
226
|
-
# "name": ["time", "
|
|
227
|
-
# "time_origin": ["time", "
|
|
231
|
+
# "name": ["time", "antenna_name"], # removed
|
|
232
|
+
# "time_origin": ["time", "antenna_name"], # removed?
|
|
228
233
|
"DIRECTION": time_ant_dir_dims,
|
|
229
234
|
"ENCODER": time_ant_dir_dims,
|
|
230
235
|
"TARGET": time_ant_dir_dims,
|
|
231
236
|
"POINTING_OFFSET": time_ant_dir_dims,
|
|
232
237
|
"SOURCE_OFFSET": time_ant_dir_dims,
|
|
233
|
-
# "pointing_model_id": ["time", "
|
|
234
|
-
# "tracking": ["time", "
|
|
235
|
-
# "on_source": ["time", "
|
|
238
|
+
# "pointing_model_id": ["time", "antenna_name"], # removed
|
|
239
|
+
# "tracking": ["time", "antenna_name"], # => attribute
|
|
240
|
+
# "on_source": ["time", "antenna_name"], # removed
|
|
236
241
|
"OVER_THE_TOP": time_ant_dims,
|
|
237
242
|
}
|
|
238
243
|
# Unused here
|
|
@@ -263,7 +268,7 @@ def create_pointing_xds(
|
|
|
263
268
|
"ctds_attrs"
|
|
264
269
|
]["column_descriptions"]
|
|
265
270
|
|
|
266
|
-
pointing_xds = xr.Dataset()
|
|
271
|
+
pointing_xds = xr.Dataset(attrs={"type": "pointing"})
|
|
267
272
|
for key in generic_pointing_xds:
|
|
268
273
|
if key in to_new_data_variable_names:
|
|
269
274
|
data_var_name = to_new_data_variable_names[key]
|
|
@@ -312,7 +317,9 @@ def create_pointing_xds(
|
|
|
312
317
|
|
|
313
318
|
coords = {
|
|
314
319
|
"time": generic_pointing_xds["TIME"].values,
|
|
315
|
-
"
|
|
320
|
+
"antenna_name": ant_xds_name_ids.sel(
|
|
321
|
+
antenna_id=generic_pointing_xds["ANTENNA_ID"]
|
|
322
|
+
).data,
|
|
316
323
|
"sky_dir_label": ["ra", "dec"],
|
|
317
324
|
}
|
|
318
325
|
pointing_xds = pointing_xds.assign_coords(coords)
|
|
@@ -38,7 +38,7 @@ def read_processing_set(
|
|
|
38
38
|
data_groups = xds.attrs["data_groups"]
|
|
39
39
|
|
|
40
40
|
if (obs_modes is None) or (
|
|
41
|
-
xds.attrs["partition_info"]["obs_mode"]
|
|
41
|
+
bool(set(xds.attrs["partition_info"]["obs_mode"]).intersection(obs_modes))
|
|
42
42
|
):
|
|
43
43
|
sub_xds_dict, field_and_source_xds_dict = _read_sub_xds(
|
|
44
44
|
ms_store, file_system=file_system, data_groups=data_groups
|
|
@@ -12,14 +12,16 @@ import numpy
|
|
|
12
12
|
# Dimensions
|
|
13
13
|
Time = Literal["time"]
|
|
14
14
|
""" Observation time dimension """
|
|
15
|
-
|
|
16
|
-
""" Antenna
|
|
15
|
+
AntennaName = Literal["antenna_name"]
|
|
16
|
+
""" Antenna name dimension """
|
|
17
17
|
StationId = Literal["station_id"]
|
|
18
18
|
""" Station ID dimension """
|
|
19
19
|
ReceptorId = Literal["receptor_id"]
|
|
20
20
|
""" Receptor ID dimension """
|
|
21
|
-
|
|
22
|
-
""" Receptor
|
|
21
|
+
ReceptorLabel = Literal["receptor_label"]
|
|
22
|
+
""" Receptor label dimension """
|
|
23
|
+
ToneLabel = Literal["tone_label"]
|
|
24
|
+
""" Tone label dimension """
|
|
23
25
|
BaselineId = Literal["baseline_id"]
|
|
24
26
|
""" Baseline ID dimension """
|
|
25
27
|
Frequency = Literal["frequency"]
|
|
@@ -40,8 +42,12 @@ EllipsoidPosLabel = Literal["ellipsoid_pos_label"]
|
|
|
40
42
|
""" Coordinate labels of geodetic earth location data (typically shape 3 and 'lon', 'lat', 'height')"""
|
|
41
43
|
CartesianPosLabel = Literal["cartesian_pos_label"]
|
|
42
44
|
""" Coordinate labels of geocentric earth location data (typically shape 3 and 'x', 'y', 'z')"""
|
|
45
|
+
TimePhaseCal = Literal["time_phase_cal"]
|
|
46
|
+
""" Coordinate label for VLBI-specific phase cal time axis """
|
|
43
47
|
TimePolynomial = Literal["time_polynomial"]
|
|
44
48
|
""" For data that is represented as variable in time using Taylor expansion """
|
|
49
|
+
PolyTerm = Literal["poly_term"]
|
|
50
|
+
""" Polynomial term used in VLBI GAIN_CURVE """
|
|
45
51
|
LineLabel = Literal["line_label"]
|
|
46
52
|
""" Line labels (for line names and variables). """
|
|
47
53
|
|
|
@@ -276,6 +282,11 @@ class FieldSourceXds:
|
|
|
276
282
|
"""
|
|
277
283
|
is_ephemeris: Attr[bool] = False
|
|
278
284
|
|
|
285
|
+
type: Attr[str] = "field_and_source"
|
|
286
|
+
"""
|
|
287
|
+
Type of dataset.
|
|
288
|
+
"""
|
|
289
|
+
|
|
279
290
|
# --- Optional coordinates ---
|
|
280
291
|
sky_dir_label: Optional[Coord[SkyDirLabel, str]] = ("ra", "dec")
|
|
281
292
|
""" Coordinate labels of sky directions (typically shape 2 and 'ra', 'dec') """
|
|
@@ -319,6 +330,22 @@ class EarthLocationArray:
|
|
|
319
330
|
"""
|
|
320
331
|
|
|
321
332
|
|
|
333
|
+
@dict_schema
|
|
334
|
+
class PartitionInfoDict:
|
|
335
|
+
# spectral_window_id: missing / remove for good?
|
|
336
|
+
spectral_window_name: str
|
|
337
|
+
# field_id: missing / probably remove for good?
|
|
338
|
+
field_name: list[str]
|
|
339
|
+
# source_id: mising / remove for good?
|
|
340
|
+
line_name: list[str]
|
|
341
|
+
scan_number: list[int]
|
|
342
|
+
source_name: list[str]
|
|
343
|
+
polarization_setup: list[str]
|
|
344
|
+
num_lines: int
|
|
345
|
+
obs_mode: list[str]
|
|
346
|
+
taql: Optional[str]
|
|
347
|
+
|
|
348
|
+
|
|
322
349
|
@dict_schema
|
|
323
350
|
class ObservationInfoDict:
|
|
324
351
|
observer: list
|
|
@@ -366,13 +393,22 @@ class BaselineArray:
|
|
|
366
393
|
|
|
367
394
|
|
|
368
395
|
@xarray_dataarray_schema
|
|
369
|
-
class
|
|
370
|
-
|
|
371
|
-
"""
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
"""
|
|
375
|
-
long_name: Optional[Attr[str]] = "
|
|
396
|
+
class BaselineAntennaNameArray:
|
|
397
|
+
"""Array of antenna_name by baseline_id, as used in main_xds and main_sd_xds
|
|
398
|
+
(antenna_name by baseline_id dim"""
|
|
399
|
+
|
|
400
|
+
data: Data[BaselineId, str]
|
|
401
|
+
"""Unique id for each baseline."""
|
|
402
|
+
long_name: Optional[Attr[str]] = "Antenna name by baseline_id"
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
@xarray_dataarray_schema
|
|
406
|
+
class AntennaNameArray:
|
|
407
|
+
"""TODO: documentation"""
|
|
408
|
+
|
|
409
|
+
data: Data[AntennaName, str]
|
|
410
|
+
"""Unique name for each antenna(_station)."""
|
|
411
|
+
long_name: Optional[Attr[str]] = "Antenna name"
|
|
376
412
|
|
|
377
413
|
|
|
378
414
|
@xarray_dataset_schema
|
|
@@ -485,17 +521,15 @@ class SpectrumArray:
|
|
|
485
521
|
"""Definition of xr.DataArray for SPECTRUM data (single dish)"""
|
|
486
522
|
|
|
487
523
|
data: Data[
|
|
488
|
-
tuple[Time,
|
|
524
|
+
tuple[Time, AntennaName, Frequency, Polarization],
|
|
489
525
|
Union[numpy.float64, numpy.float32, numpy.float16],
|
|
490
526
|
]
|
|
491
|
-
time: Coord[tuple[()], TimeCoordArray]
|
|
492
527
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
528
|
+
time: Coordof[TimeCoordArray]
|
|
529
|
+
antenna_name: Coordof[AntennaNameArray]
|
|
530
|
+
frequency: Coordof[FrequencyArray]
|
|
531
|
+
polarization: Coordof[PolarizationArray]
|
|
496
532
|
|
|
497
|
-
polarization: Coord[tuple[()], PolarizationArray]
|
|
498
|
-
frequency: Coord[tuple[()], FrequencyArray]
|
|
499
533
|
field_and_source_xds: Attr[FieldSourceXds]
|
|
500
534
|
long_name: Optional[Attr[str]] = "Spectrum values"
|
|
501
535
|
""" Long-form name to use for axis. Should be ``"Spectrum values"``"""
|
|
@@ -515,11 +549,13 @@ class FlagArray:
|
|
|
515
549
|
tuple[Time, BaselineId, Frequency, Polarization],
|
|
516
550
|
tuple[Time, BaselineId, Frequency],
|
|
517
551
|
tuple[Time, BaselineId],
|
|
552
|
+
tuple[Time, AntennaName, Frequency, Polarization], # SD
|
|
518
553
|
],
|
|
519
554
|
bool,
|
|
520
555
|
]
|
|
521
556
|
time: Coordof[TimeCoordArray]
|
|
522
|
-
baseline_id: Coordof[BaselineArray]
|
|
557
|
+
baseline_id: Optional[Coordof[BaselineArray]] # Only IF
|
|
558
|
+
antenna_name: Optional[Coordof[AntennaNameArray]] # Only SD
|
|
523
559
|
frequency: Coordof[FrequencyArray]
|
|
524
560
|
polarization: Optional[Coordof[PolarizationArray]] = None
|
|
525
561
|
long_name: Optional[Attr[str]] = "Visibility flags"
|
|
@@ -540,12 +576,14 @@ class WeightArray:
|
|
|
540
576
|
tuple[Time, BaselineId, Frequency, Polarization],
|
|
541
577
|
tuple[Time, BaselineId, Frequency],
|
|
542
578
|
tuple[Time, BaselineId],
|
|
579
|
+
tuple[Time, AntennaName, Frequency, Polarization], # SD
|
|
543
580
|
],
|
|
544
581
|
Union[numpy.float16, numpy.float32, numpy.float64],
|
|
545
582
|
]
|
|
546
583
|
"""Visibility weights"""
|
|
547
584
|
time: Coordof[TimeCoordArray]
|
|
548
|
-
baseline_id: Coordof[BaselineArray]
|
|
585
|
+
baseline_id: Optional[Coordof[BaselineArray]] # Only IF
|
|
586
|
+
antenna_name: Optional[Coordof[AntennaNameArray]] # Only SD
|
|
549
587
|
frequency: Optional[Coordof[FrequencyArray]] = None
|
|
550
588
|
polarization: Optional[Coordof[PolarizationArray]] = None
|
|
551
589
|
long_name: Optional[Attr[str]] = "Visibility weights"
|
|
@@ -586,6 +624,9 @@ class UvwArray:
|
|
|
586
624
|
tuple[Time, BaselineId, Frequency, Polarization, UvwLabel],
|
|
587
625
|
tuple[Time, BaselineId, Frequency, UvwLabel],
|
|
588
626
|
tuple[Time, BaselineId, UvwLabel],
|
|
627
|
+
tuple[Time, AntennaName, UvwLabel], # SD
|
|
628
|
+
tuple[Time, AntennaName, Frequency, UvwLabel], # SD
|
|
629
|
+
tuple[Time, AntennaName, Frequency, Polarization], # SD
|
|
589
630
|
],
|
|
590
631
|
Union[
|
|
591
632
|
numpy.float16,
|
|
@@ -595,7 +636,8 @@ class UvwArray:
|
|
|
595
636
|
]
|
|
596
637
|
"""Baseline coordinates from ``baseline_antenna2_id`` to ``baseline_antenna1_id``"""
|
|
597
638
|
time: Coordof[TimeCoordArray]
|
|
598
|
-
baseline_id: Coordof[BaselineArray]
|
|
639
|
+
baseline_id: Optional[Coordof[BaselineArray]] # Only IF
|
|
640
|
+
antenna_name: Optional[Coordof[AntennaNameArray]] # Only SD
|
|
599
641
|
frequency: Optional[Coordof[FrequencyArray]] = None
|
|
600
642
|
polarization: Optional[Coordof[PolarizationArray]] = None
|
|
601
643
|
uvw_label: Coordof[UvwLabelArray] = ("u", "v", "w")
|
|
@@ -613,12 +655,14 @@ class TimeSamplingArray:
|
|
|
613
655
|
tuple[Time, BaselineId, Frequency, Polarization],
|
|
614
656
|
tuple[Time, BaselineId, Frequency],
|
|
615
657
|
tuple[Time, BaselineId],
|
|
658
|
+
tuple[Time, AntennaName], # SD
|
|
616
659
|
],
|
|
617
660
|
float,
|
|
618
661
|
]
|
|
619
662
|
|
|
620
663
|
time: Coordof[TimeCoordArray]
|
|
621
|
-
baseline_id: Coordof[BaselineArray]
|
|
664
|
+
baseline_id: Optional[Coordof[BaselineArray]] # Only IF
|
|
665
|
+
antenna_name: Optional[Coordof[AntennaNameArray]] # Only SD
|
|
622
666
|
frequency: Optional[Coordof[FrequencyArray]] = None
|
|
623
667
|
polarization: Optional[Coordof[PolarizationArray]] = None
|
|
624
668
|
|
|
@@ -667,88 +711,147 @@ class FreqSamplingArray:
|
|
|
667
711
|
# Data Sets
|
|
668
712
|
|
|
669
713
|
|
|
670
|
-
@xarray_dataset_schema
|
|
671
|
-
class AntennaXdsEmptyWhileRevampedTODO:
|
|
672
|
-
"""Minimal placeholder so that it shows in the main xds
|
|
673
|
-
docs. TODO: update AntennaXds once review moves on
|
|
674
|
-
"""
|
|
675
|
-
|
|
676
|
-
antenna_name: Coord[Literal["antenna_name"], str]
|
|
677
|
-
receptor_label: Optional[Coord[ReceptorName, str]]
|
|
678
|
-
cartesian_pos_label: Coord[CartesianPosLabel, str]
|
|
679
|
-
sky_dir_label: Optional[Coord[SkyDirLabel, str]]
|
|
680
|
-
gain_curve_time: Optional[Coord[Literal["gain_curve_time"], numpy.float64]]
|
|
681
|
-
poly_term: Optional[Coord[Literal["poly_term"], numpy.int64]]
|
|
682
|
-
phase_cal_time: Optional[Coord[Literal["phase_cal_time"], numpy.float64]]
|
|
683
|
-
tone_label: Optional[Coord[Literal["tone_label"], numpy.int64]]
|
|
684
|
-
|
|
685
|
-
|
|
686
714
|
@xarray_dataset_schema
|
|
687
715
|
class AntennaXds:
|
|
688
|
-
#
|
|
689
|
-
|
|
690
|
-
"""Antenna
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
""
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
716
|
+
# Coordinates
|
|
717
|
+
antenna_name: Coordof[AntennaNameArray]
|
|
718
|
+
""" Antenna name """
|
|
719
|
+
station: Coord[AntennaName, str]
|
|
720
|
+
""" Name of the station pad (relevant to arrays with moving antennas). """
|
|
721
|
+
mount: Coord[AntennaName, str]
|
|
722
|
+
""" Mount type of the antenna. Reserved keywords include: ”EQUATORIAL” - equatorial mount;
|
|
723
|
+
”ALT-AZ” - azimuth-elevation mount;
|
|
724
|
+
"ALT-AZ+ROTATOR" alt-az mount with feed rotator; introduced for ASKAP dishes;
|
|
725
|
+
"ALT-AZ+NASMYTH-R": Nasmyth mount with receivers at the right-hand side of the cabin. Many high-frequency antennas used for VLBI have such a mount typel;
|
|
726
|
+
"ALT-AZ+NASMYTH-L:: Nasmyth mount with receivers at the left-hand side of the cabin.
|
|
727
|
+
”X-Y” - x-y mount;
|
|
728
|
+
”SPACE-HALCA” - specific orientation model."""
|
|
729
|
+
telescope_name: Optional[Coord[AntennaName, str]]
|
|
730
|
+
""" Useful when data is combined from mutiple arrays for example ACA + ALMA. """
|
|
731
|
+
# TODO: receptor_label, polarization_type, sky_dir_label set as optional
|
|
732
|
+
# for datasets like test_alma_ephemris_mosaic. See also BEAM_OFFSET below.
|
|
733
|
+
receptor_label: Optional[Coord[ReceptorLabel, str]]
|
|
734
|
+
""" Names of receptors """
|
|
735
|
+
polarization_type: Optional[Coord[tuple[AntennaName, ReceptorLabel], str]]
|
|
736
|
+
""" Polarization type to which each receptor responds (e.g. ”R”,”L”,”X” or ”Y”).
|
|
737
|
+
This is the receptor polarization type as recorded in the final correlated data (e.g. ”RR”); i.e.
|
|
738
|
+
as measured after all polarization combiners. ['X','Y'], ['R','L'] """
|
|
739
|
+
cartesian_pos_label: Optional[Coord[CartesianPosLabel, str]]
|
|
740
|
+
""" (x,y,z) - either cartesian or ellipsoid """
|
|
741
|
+
ellipsoid_pos_label: Optional[Coord[EllipsoidPosLabel, str]]
|
|
742
|
+
""" (lon, lat, dist) - either cartesian or ellipsoid"""
|
|
714
743
|
sky_dir_label: Optional[Coord[SkyDirLabel, str]]
|
|
715
|
-
"""
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
744
|
+
""" ra, dec """
|
|
745
|
+
time: Optional[Coordof[TimeCoordArray]]
|
|
746
|
+
""" Time for VLBI phase cal"""
|
|
747
|
+
time_phase_cal: Optional[Coord[TimePhaseCal, numpy.float64]]
|
|
748
|
+
""" Time for VLBI phase cal"""
|
|
749
|
+
tone_label: Optional[Coord[ToneLabel, str]]
|
|
750
|
+
""" ? """
|
|
751
|
+
gain_curve_type: Optional[Coord[AntennaName, str]]
|
|
752
|
+
""" ? """
|
|
753
|
+
|
|
754
|
+
# Data variables
|
|
755
|
+
ANTENNA_POSITION: Data[
|
|
756
|
+
Union[
|
|
757
|
+
tuple[AntennaName, EllipsoidPosLabel], tuple[AntennaName, CartesianPosLabel]
|
|
758
|
+
],
|
|
759
|
+
QuantityArray,
|
|
760
|
+
] # EarthLocationArray
|
|
719
761
|
"""
|
|
720
762
|
In a right-handed frame, X towards the intersection of the equator and
|
|
721
763
|
the Greenwich meridian, Z towards the pole.
|
|
722
764
|
"""
|
|
723
|
-
ANTENNA_FEED_OFFSET: Data[
|
|
765
|
+
ANTENNA_FEED_OFFSET: Data[
|
|
766
|
+
Union[
|
|
767
|
+
tuple[AntennaName, EllipsoidPosLabel], tuple[AntennaName, CartesianPosLabel]
|
|
768
|
+
],
|
|
769
|
+
QuantityArray,
|
|
770
|
+
]
|
|
724
771
|
"""
|
|
725
772
|
Offset of feed relative to position (``Antenna_Table.offset + Feed_Table.position``).
|
|
726
773
|
"""
|
|
727
|
-
ANTENNA_DISH_DIAMETER: Data[
|
|
774
|
+
ANTENNA_DISH_DIAMETER: Optional[Data[tuple[AntennaName], QuantityArray]]
|
|
728
775
|
"""
|
|
729
776
|
Nominal diameter of dish, as opposed to the effective diameter.
|
|
730
777
|
"""
|
|
731
|
-
|
|
778
|
+
ANTENNA_EFFECTIVE_DISH_DIAMETER: Optional[
|
|
779
|
+
Data[tuple[AntennaName, ReceptorLabel, SkyDirLabel], QuantityArray]
|
|
780
|
+
]
|
|
781
|
+
""" Airy Disk Model .... """
|
|
782
|
+
|
|
783
|
+
# TODO: setting BEAM_OFFSET and RECEPTOR_ANGLE as optional for now, as it
|
|
784
|
+
# is not present in some datasets (example: test_alma_ephemris_mosaic)
|
|
785
|
+
BEAM_OFFSET: Optional[Data[tuple[AntennaName, ReceptorLabel], SkyCoordArray]]
|
|
732
786
|
"""
|
|
733
787
|
Beam position offset, as defined on the sky but in the antenna
|
|
734
788
|
reference frame.
|
|
735
789
|
"""
|
|
736
|
-
RECEPTOR_ANGLE: Optional[Data[tuple[
|
|
790
|
+
RECEPTOR_ANGLE: Optional[Data[tuple[AntennaName, ReceptorLabel], QuantityArray]]
|
|
737
791
|
"""
|
|
738
792
|
Polarization reference angle. Converts into parallactic angle in the sky domain.
|
|
739
793
|
"""
|
|
740
|
-
FOCUS_LENGTH: Optional[Data[
|
|
794
|
+
FOCUS_LENGTH: Optional[Data[tuple[AntennaName], QuantityArray]]
|
|
741
795
|
"""
|
|
742
796
|
Focus length. As defined along the optical axis of the antenna.
|
|
743
797
|
"""
|
|
744
|
-
ARRAY_CENTER: Optional[Data[AntennaId, EarthLocationArray]]
|
|
745
|
-
EFFECTIVE_DISH_DIAMETER: Optional[Data[AntennaId, QuantityArray]]
|
|
746
798
|
|
|
747
|
-
|
|
748
|
-
|
|
799
|
+
GAIN_CURVE: Optional[
|
|
800
|
+
Data[tuple[AntennaName, ReceptorLabel, PolyTerm], numpy.float32]
|
|
801
|
+
]
|
|
802
|
+
""" VLBI. ? """
|
|
803
|
+
GAIN_CURVE_INTERVAL: Optional[Data[tuple[AntennaName], QuantityArray]]
|
|
804
|
+
""" VLBI. ? """
|
|
805
|
+
GAIN_CURVE_SENSITIVITY: Optional[
|
|
806
|
+
Data[tuple[AntennaName, ReceptorLabel], numpy.float32]
|
|
807
|
+
]
|
|
808
|
+
""" VLBI. ? """
|
|
809
|
+
PHASE_CAL: Optional[
|
|
810
|
+
Data[
|
|
811
|
+
Union[
|
|
812
|
+
tuple[AntennaName, Time, ReceptorLabel, ToneLabel],
|
|
813
|
+
tuple[AntennaName, TimePhaseCal, ReceptorLabel, ToneLabel],
|
|
814
|
+
],
|
|
815
|
+
numpy.complex64,
|
|
816
|
+
]
|
|
817
|
+
]
|
|
818
|
+
""" VLBI. ? """
|
|
819
|
+
PHASE_CAL_CABLE_CAL: Optional[
|
|
820
|
+
Data[
|
|
821
|
+
Union[tuple[AntennaName, Time], tuple[AntennaName, TimePhaseCal]],
|
|
822
|
+
QuantityArray,
|
|
823
|
+
]
|
|
824
|
+
]
|
|
825
|
+
""" VLBI. ? """
|
|
826
|
+
PHASE_CAL_INTERVAL: Optional[
|
|
827
|
+
Data[
|
|
828
|
+
Union[tuple[AntennaName, Time], tuple[AntennaName, TimePhaseCal]],
|
|
829
|
+
QuantityArray,
|
|
830
|
+
]
|
|
831
|
+
]
|
|
832
|
+
""" VLBI. ? """
|
|
833
|
+
PHASE_CAL_TONE_FREQUENCY: Optional[
|
|
834
|
+
Data[
|
|
835
|
+
Union[
|
|
836
|
+
tuple[AntennaName, Time, ReceptorLabel, ToneLabel],
|
|
837
|
+
tuple[AntennaName, TimePhaseCal, ReceptorLabel, ToneLabel],
|
|
838
|
+
],
|
|
839
|
+
QuantityArray,
|
|
840
|
+
]
|
|
841
|
+
]
|
|
842
|
+
""" VLBI. ? """
|
|
843
|
+
|
|
844
|
+
# Attributes
|
|
845
|
+
overall_telescope_name: Optional[Attr[str]]
|
|
749
846
|
"""
|
|
750
|
-
|
|
847
|
+
The name of the collection of arrays and dishes that were used for the observation.
|
|
848
|
+
In many instances this will only be a single array or dish. An example of a
|
|
849
|
+
telescope consistening of mutiple arrays and dishes is the EHT. The coordinate
|
|
850
|
+
telescope_name will give the names of the constituent arrays and dishes. From
|
|
851
|
+
MSv2 observation table.
|
|
751
852
|
"""
|
|
853
|
+
relocatable_antennas: Optional[Attr[bool]]
|
|
854
|
+
""" Can the antennas be moved (ALMA, VLA, NOEMA) """
|
|
752
855
|
type: Attr[str] = "antenna"
|
|
753
856
|
"""
|
|
754
857
|
Type of dataset. Expected to be ``antenna``
|
|
@@ -757,12 +860,42 @@ class AntennaXds:
|
|
|
757
860
|
|
|
758
861
|
@xarray_dataset_schema
|
|
759
862
|
class WeatherXds:
|
|
760
|
-
"""
|
|
863
|
+
"""Weather. Contains station positions and time-dependent mean external
|
|
864
|
+
atmosphere and weather information"""
|
|
761
865
|
|
|
866
|
+
# Coordinates
|
|
867
|
+
time: Coordof[TimeCoordArray]
|
|
868
|
+
""" Mid-point of the time interval """
|
|
762
869
|
station_id: Coord[StationId, numpy.int64]
|
|
763
870
|
""" Station identifier """
|
|
764
|
-
|
|
765
|
-
"""
|
|
871
|
+
antenna_name: Optional[Coordof[AntennaNameArray]]
|
|
872
|
+
""" Antenna identifier """
|
|
873
|
+
|
|
874
|
+
# Data variables (all optional)
|
|
875
|
+
H2O: Optional[Data[tuple[StationId, Time], QuantityArray]] = None
|
|
876
|
+
""" Average column density of water """
|
|
877
|
+
IONOS_ELECTRON: Optional[Data[tuple[StationId, Time], QuantityArray]] = None
|
|
878
|
+
""" Average column density of electrons """
|
|
879
|
+
PRESSURE: Optional[Data[tuple[StationId, Time], QuantityArray]] = None
|
|
880
|
+
""" Ambient atmospheric pressure """
|
|
881
|
+
REL_HUMIDITY: Optional[Data[tuple[StationId, Time], QuantityArray]] = None
|
|
882
|
+
""" Ambient relative humidity """
|
|
883
|
+
TEMPERATURE: Optional[Data[tuple[StationId, Time], QuantityArray]] = None
|
|
884
|
+
""" Ambient air temperature for an antenna """
|
|
885
|
+
DEW_POINT: Optional[Data[tuple[StationId, Time], QuantityArray]] = None
|
|
886
|
+
""" Dew point """
|
|
887
|
+
WIND_DIRECTION: Optional[Data[tuple[StationId, Time], QuantityArray]] = None
|
|
888
|
+
""" Average wind direction """
|
|
889
|
+
WIND_SPEED: Optional[Data[tuple[StationId, Time], QuantityArray]] = None
|
|
890
|
+
""" Average wind speed """
|
|
891
|
+
STATION_POSITION: Optional[Data[tuple[StationId], QuantityArray]] = None
|
|
892
|
+
""" Station position """
|
|
893
|
+
|
|
894
|
+
# Attributes
|
|
895
|
+
type: Attr[str] = "weather"
|
|
896
|
+
"""
|
|
897
|
+
Type of dataset.
|
|
898
|
+
"""
|
|
766
899
|
|
|
767
900
|
|
|
768
901
|
@xarray_dataset_schema
|
|
@@ -772,9 +905,9 @@ class PointingXds:
|
|
|
772
905
|
Mid-point of the time interval for which the information in this row is
|
|
773
906
|
valid. Required to use the same time measure reference as in visibility dataset
|
|
774
907
|
"""
|
|
775
|
-
|
|
908
|
+
antenna_name: Coordof[AntennaNameArray]
|
|
776
909
|
"""
|
|
777
|
-
Antenna
|
|
910
|
+
Antenna name, as specified by baseline_antenna1/2_name in visibility dataset
|
|
778
911
|
"""
|
|
779
912
|
sky_dir_label: Coord[SkyDirLabel, str]
|
|
780
913
|
"""
|
|
@@ -782,18 +915,18 @@ class PointingXds:
|
|
|
782
915
|
"""
|
|
783
916
|
|
|
784
917
|
BEAM_POINTING: Data[
|
|
785
|
-
Union[tuple[Time,
|
|
918
|
+
Union[tuple[Time, AntennaName, TimePolynomial], tuple[Time, AntennaName]],
|
|
786
919
|
SkyCoordArray,
|
|
787
920
|
]
|
|
788
921
|
"""
|
|
789
922
|
Antenna pointing direction, optionally expressed as polynomial coefficients. DIRECTION in MSv3.
|
|
790
923
|
"""
|
|
791
|
-
DISH_MEASURED_POINTING: Optional[Data[tuple[Time,
|
|
924
|
+
DISH_MEASURED_POINTING: Optional[Data[tuple[Time, AntennaName], SkyCoordArray]]
|
|
792
925
|
"""
|
|
793
926
|
The current encoder values on the primary axes of the mount type for
|
|
794
927
|
the antenna. ENCODER in MSv3.
|
|
795
928
|
"""
|
|
796
|
-
OVER_THE_TOP: Optional[Data[tuple[Time,
|
|
929
|
+
OVER_THE_TOP: Optional[Data[tuple[Time, AntennaName], bool]]
|
|
797
930
|
|
|
798
931
|
|
|
799
932
|
@xarray_dataset_schema
|
|
@@ -810,15 +943,53 @@ class PhasedArrayXds:
|
|
|
810
943
|
|
|
811
944
|
@xarray_dataset_schema
|
|
812
945
|
class SystemCalibrationXds:
|
|
813
|
-
"""
|
|
946
|
+
"""System calibration. Contains time- and frequency- variable
|
|
947
|
+
calibration measurements for each antenna, as indexed on receptor"""
|
|
814
948
|
|
|
815
|
-
|
|
949
|
+
# Coordinates
|
|
950
|
+
antenna_name: Coordof[AntennaNameArray]
|
|
816
951
|
""" Antenna identifier """
|
|
817
|
-
time:
|
|
952
|
+
time: Coordof[TimeCoordArray]
|
|
818
953
|
""" Midpoint of time for which this set of parameters is accurate """
|
|
819
|
-
receptor_id: Coord[ReceptorId, numpy.float64]
|
|
954
|
+
receptor_id: Optional[Coord[ReceptorId, numpy.float64]] = None
|
|
955
|
+
""" """
|
|
956
|
+
frequency: Optional[Coordof[FrequencyArray]] = None
|
|
820
957
|
""" """
|
|
821
958
|
|
|
959
|
+
# Data variables (all optional)
|
|
960
|
+
PHASE_DIFFERENCE: Optional[Data[tuple[Time, AntennaName], numpy.float64]] = None
|
|
961
|
+
""" Phase difference between receptor 0 and receptor 1 """
|
|
962
|
+
TCAL: Optional[
|
|
963
|
+
Data[tuple[Time, AntennaName, ReceptorId, Frequency], QuantityArray]
|
|
964
|
+
] = None
|
|
965
|
+
""" Calibration temp """
|
|
966
|
+
TRX: Optional[
|
|
967
|
+
Data[tuple[Time, AntennaName, ReceptorId, Frequency], QuantityArray]
|
|
968
|
+
] = None
|
|
969
|
+
""" Receiver temperature """
|
|
970
|
+
TSKY: Optional[
|
|
971
|
+
Data[tuple[Time, AntennaName, ReceptorId, Frequency], QuantityArray]
|
|
972
|
+
] = None
|
|
973
|
+
""" Sky temperature """
|
|
974
|
+
TSYS: Optional[
|
|
975
|
+
Data[tuple[Time, AntennaName, ReceptorId, Frequency], QuantityArray]
|
|
976
|
+
] = None
|
|
977
|
+
""" System temperature """
|
|
978
|
+
TANT: Optional[
|
|
979
|
+
Data[tuple[Time, AntennaName, ReceptorId, Frequency], QuantityArray]
|
|
980
|
+
] = None
|
|
981
|
+
""" Antenna temperature """
|
|
982
|
+
TANT_SYS: Optional[
|
|
983
|
+
Data[tuple[Time, AntennaName, ReceptorId, Frequency], QuantityArray]
|
|
984
|
+
] = None
|
|
985
|
+
""" TANT/TSYS """
|
|
986
|
+
|
|
987
|
+
# Attributes
|
|
988
|
+
type: Attr[str] = "system_calibration"
|
|
989
|
+
"""
|
|
990
|
+
Type of dataset.
|
|
991
|
+
"""
|
|
992
|
+
|
|
822
993
|
|
|
823
994
|
@xarray_dataset_schema
|
|
824
995
|
class VisibilityXds:
|
|
@@ -830,7 +1001,12 @@ class VisibilityXds:
|
|
|
830
1001
|
The time coordinate is the mid-point of the nominal sampling interval, as
|
|
831
1002
|
specified in the ``ms_v4.time.attrs['integration_time']`` (ms v2 interval).
|
|
832
1003
|
"""
|
|
833
|
-
baseline_id: Coordof[BaselineArray]
|
|
1004
|
+
baseline_id: Optional[Coordof[BaselineArray]] # IF. not present in main_sd_xds
|
|
1005
|
+
""" Baseline ID """
|
|
1006
|
+
antenna_name: Optional[
|
|
1007
|
+
Coordof[AntennaNameArray]
|
|
1008
|
+
] # Single-dish. not present in main_xds
|
|
1009
|
+
""" antenna_name """
|
|
834
1010
|
frequency: Coordof[FrequencyArray]
|
|
835
1011
|
"""Center frequencies for each channel."""
|
|
836
1012
|
polarization: Coordof[PolarizationArray]
|
|
@@ -838,18 +1014,18 @@ class VisibilityXds:
|
|
|
838
1014
|
Labels for polarization types, e.g. ``['XX','XY','YX','YY']``, ``['RR','RL','LR','LL']``.
|
|
839
1015
|
"""
|
|
840
1016
|
uvw_label: Optional[Coordof[UvwLabelArray]]
|
|
1017
|
+
""" u,v,w """
|
|
1018
|
+
baseline_antenna1_name: Optional[Coordof[BaselineAntennaNameArray]] # IF
|
|
1019
|
+
"""Antenna name for 1st antenna in baseline. Maps to ``attrs['antenna_xds'].antenna_name``"""
|
|
1020
|
+
baseline_antenna2_name: Optional[Coordof[BaselineAntennaNameArray]] # IF
|
|
1021
|
+
"""Antenna name for 2nd antenna in baseline. Maps to ``attrs['antenna_xds'].antenna_name``"""
|
|
841
1022
|
|
|
842
1023
|
# --- Required Attributes ---
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
# antenna_xds: Attr[AntennaXdsEmptyWhileRevampedTODO]
|
|
1024
|
+
partition_info: Attr[PartitionInfoDict]
|
|
1025
|
+
antenna_xds: Attr[AntennaXds]
|
|
846
1026
|
|
|
847
1027
|
# --- Optional Coordinates ---
|
|
848
|
-
|
|
849
|
-
"""Antenna id for 1st antenna in baseline. Maps to ``attrs['antenna_xds'].antenna_id``"""
|
|
850
|
-
baseline_antenna2_id: Optional[Coordof[BaselineAntennaArray]] = None
|
|
851
|
-
"""Antenna id for 2nd antenna in baseline. Maps to ``attrs['antenna_xds'].antenna_id``"""
|
|
852
|
-
scan_id: Optional[Coord[Time, int]] = None
|
|
1028
|
+
scan_number: Optional[Coord[Time, Union[numpy.int64, numpy.int32]]] = None
|
|
853
1029
|
"""Arbitary scan number to identify data taken in the same logical scan."""
|
|
854
1030
|
|
|
855
1031
|
# --- Required data variables ---
|
|
@@ -875,6 +1051,9 @@ class VisibilityXds:
|
|
|
875
1051
|
tuple[Time, BaselineId],
|
|
876
1052
|
tuple[Time, BaselineId, Frequency],
|
|
877
1053
|
tuple[Time, BaselineId, Frequency, Polarization],
|
|
1054
|
+
tuple[Time, AntennaName], # SD
|
|
1055
|
+
tuple[Time, AntennaName, Frequency], # SD
|
|
1056
|
+
tuple[Time, AntennaName, Frequency, Polarization], # SD
|
|
878
1057
|
],
|
|
879
1058
|
QuantityArray,
|
|
880
1059
|
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|