xradio 0.0.36__tar.gz → 0.0.38__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.
Files changed (79) hide show
  1. {xradio-0.0.36/src/xradio.egg-info → xradio-0.0.38}/PKG-INFO +3 -4
  2. {xradio-0.0.36 → xradio-0.0.38}/pyproject.toml +3 -4
  3. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/conversion.py +46 -32
  4. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/create_antenna_xds.py +4 -1
  5. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/create_field_and_source_xds.py +7 -3
  6. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/msv4_sub_xdss.py +18 -11
  7. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_utils/xds_helper.py +1 -1
  8. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/read_processing_set.py +1 -1
  9. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/schema.py +278 -99
  10. {xradio-0.0.36 → xradio-0.0.38/src/xradio.egg-info}/PKG-INFO +3 -4
  11. {xradio-0.0.36 → xradio-0.0.38}/src/xradio.egg-info/requires.txt +1 -2
  12. {xradio-0.0.36 → xradio-0.0.38}/LICENSE.txt +0 -0
  13. {xradio-0.0.36 → xradio-0.0.38}/MANIFEST.in +0 -0
  14. {xradio-0.0.36 → xradio-0.0.38}/README.md +0 -0
  15. {xradio-0.0.36 → xradio-0.0.38}/setup.cfg +0 -0
  16. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/__init__.py +0 -0
  17. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/_utils/__init__.py +0 -0
  18. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/_utils/_casacore/tables.py +0 -0
  19. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/_utils/common.py +0 -0
  20. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/_utils/list_and_array.py +0 -0
  21. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/_utils/schema.py +0 -0
  22. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/_utils/zarr/__init__.py +0 -0
  23. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/_utils/zarr/common.py +0 -0
  24. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/image/__init__.py +0 -0
  25. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/image/_util/__init__.py +0 -0
  26. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/image/_util/_casacore/__init__.py +0 -0
  27. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/image/_util/_casacore/common.py +0 -0
  28. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/image/_util/_casacore/xds_from_casacore.py +0 -0
  29. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/image/_util/_casacore/xds_to_casacore.py +0 -0
  30. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/image/_util/_fits/xds_from_fits.py +0 -0
  31. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/image/_util/_zarr/common.py +0 -0
  32. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/image/_util/_zarr/xds_from_zarr.py +0 -0
  33. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/image/_util/_zarr/xds_to_zarr.py +0 -0
  34. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/image/_util/_zarr/zarr_low_level.py +0 -0
  35. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/image/_util/casacore.py +0 -0
  36. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/image/_util/common.py +0 -0
  37. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/image/_util/fits.py +0 -0
  38. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/image/_util/image_factory.py +0 -0
  39. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/image/_util/zarr.py +0 -0
  40. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/image/image.py +0 -0
  41. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/schema/__init__.py +0 -0
  42. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/schema/bases.py +0 -0
  43. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/schema/check.py +0 -0
  44. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/schema/dataclass.py +0 -0
  45. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/schema/metamodel.py +0 -0
  46. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/schema/typing.py +0 -0
  47. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/__init__.py +0 -0
  48. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_processing_set.py +0 -0
  49. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/__init__.py +0 -0
  50. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/_tables/load.py +0 -0
  51. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/_tables/load_main_table.py +0 -0
  52. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/_tables/read.py +0 -0
  53. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/_tables/read_main_table.py +0 -0
  54. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/_tables/read_subtables.py +0 -0
  55. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/_tables/table_query.py +0 -0
  56. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/_tables/write.py +0 -0
  57. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/_tables/write_exp_api.py +0 -0
  58. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/chunks.py +0 -0
  59. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/descr.py +0 -0
  60. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/msv2_msv3.py +0 -0
  61. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/msv2_to_msv4_meta.py +0 -0
  62. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/msv4_infos.py +0 -0
  63. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/optimised_functions.py +0 -0
  64. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/partition_queries.py +0 -0
  65. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/partitions.py +0 -0
  66. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_ms/subtables.py +0 -0
  67. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_utils/cds.py +0 -0
  68. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_utils/partition_attrs.py +0 -0
  69. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_utils/stokes_types.py +0 -0
  70. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_zarr/encoding.py +0 -0
  71. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_zarr/read.py +0 -0
  72. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/_zarr/write.py +0 -0
  73. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/ms.py +0 -0
  74. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/_vis_utils/zarr.py +0 -0
  75. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/convert_msv2_to_processing_set.py +0 -0
  76. {xradio-0.0.36 → xradio-0.0.38}/src/xradio/vis/load_processing_set.py +0 -0
  77. {xradio-0.0.36 → xradio-0.0.38}/src/xradio.egg-info/SOURCES.txt +0 -0
  78. {xradio-0.0.36 → xradio-0.0.38}/src/xradio.egg-info/dependency_links.txt +0 -0
  79. {xradio-0.0.36 → xradio-0.0.38}/src/xradio.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: xradio
3
- Version: 0.0.36
3
+ Version: 0.0.38
4
4
  Summary: Xarray Radio Astronomy Data IO
5
5
  Author-email: Jan-Willem Steeb <jsteeb@nrao.edu>
6
6
  License: BSD 3-Clause License
@@ -37,11 +37,10 @@ License: BSD 3-Clause License
37
37
  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38
38
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39
39
 
40
- Requires-Python: <3.12,>=3.9
40
+ Requires-Python: <3.13,>=3.9
41
41
  Description-Content-Type: text/markdown
42
42
  License-File: LICENSE.txt
43
43
  Requires-Dist: astropy
44
- Requires-Dist: casadata
45
44
  Requires-Dist: dask
46
45
  Requires-Dist: distributed
47
46
  Requires-Dist: graphviper
@@ -58,7 +57,7 @@ Requires-Dist: tqdm
58
57
  Requires-Dist: xarray
59
58
  Requires-Dist: zarr
60
59
  Requires-Dist: pyarrow
61
- Requires-Dist: python_casacore>=3.5.2; sys_platform != "darwin"
60
+ Requires-Dist: python_casacore>=3.6.1; sys_platform != "darwin"
62
61
  Requires-Dist: typing_extensions; python_version < "3.10"
63
62
  Requires-Dist: typeguard
64
63
  Provides-Extra: docs
@@ -1,17 +1,16 @@
1
1
  [project]
2
2
  name = "xradio"
3
- version = "0.0.36"
3
+ version = "0.0.38"
4
4
  description = " Xarray Radio Astronomy Data IO"
5
5
  authors = [
6
6
  {name = "Jan-Willem Steeb", email="jsteeb@nrao.edu"},
7
7
  ]
8
8
  license = {file = "LICENSE.txt"}
9
9
  readme = "README.md"
10
- requires-python = ">= 3.9, < 3.12"
10
+ requires-python = ">= 3.9, < 3.13"
11
11
 
12
12
  dependencies = [
13
13
  'astropy',
14
- 'casadata',
15
14
  'dask',
16
15
  'distributed',
17
16
  'graphviper',
@@ -28,7 +27,7 @@ dependencies = [
28
27
  'xarray',
29
28
  'zarr',
30
29
  'pyarrow',
31
- 'python_casacore>=3.5.2; sys_platform != "darwin" ',
30
+ 'python_casacore>=3.6.1; sys_platform != "darwin" ',
32
31
  'typing_extensions; python_version < "3.10"',
33
32
  'typeguard'
34
33
  ]
@@ -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
- "antenna_id",
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, antenna_id/baseline_id, frequency,
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
- baseline_or_antenna_id = find_baseline_or_antenna_var(xds)
153
- total_size = calc_used_gb(xds.sizes, baseline_or_antenna_id, sizeof_vis)
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", baseline_or_antenna_id, "frequency", "polarization"]
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, baseline_or_antenna_id, sizeof_vis
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, xds_dim_sizes: dict, baseline_or_antenna_id: str, sizeof_vis: int
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", baseline_or_antenna_id, "frequency", "polarization"]
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
- baseline_or_antenna_id = "baseline_id"
318
- elif "antenna_id" in xds.coords:
319
- baseline_or_antenna_id = "antenna_id"
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 baseline_or_antenna_id
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, baseline_or_antenna_id: str, sizeof_vis: int
358
+ chunksizes: dict, baseline_or_antenna_name: str, sizeof_vis: int
356
359
  ) -> float:
357
360
  return (
358
361
  chunksizes["time"]
359
- * chunksizes[baseline_or_antenna_id]
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"
@@ -974,11 +976,7 @@ def convert_and_write_partition(
974
976
 
975
977
  file_name = os.path.join(
976
978
  out_file,
977
- pathlib.Path(out_file)
978
- .name.replace(".vis.zarr", "")
979
- .replace(".zarr", "")
980
- + "_"
981
- + str(ms_v4_id),
979
+ pathlib.Path(in_file).name.replace(".ms", "") + "_" + str(ms_v4_id),
982
980
  )
983
981
 
984
982
  if "line_name" in field_and_source_xds.coords:
@@ -1037,17 +1035,19 @@ def convert_and_write_partition(
1037
1035
  # logger.info("Saved ms_v4 " + file_name + " in " + str(time.time() - start_with) + "s")
1038
1036
 
1039
1037
 
1040
- def antenna_ids_to_names(xds, ant_xds):
1038
+ def antenna_ids_to_names(
1039
+ xds: xr.Dataset, ant_xds: xr.Dataset, is_single_dish: bool
1040
+ ) -> xr.Dataset:
1041
1041
  ant_xds = ant_xds.set_xindex(
1042
1042
  "antenna_id"
1043
1043
  ) # Allows for non-dimension coordinate selection.
1044
1044
 
1045
- if "baseline_antenna1_id" in xds: # Interferometer
1046
- xds["baseline_antenna1_id"] = ant_xds["antenna_name"].sel(
1047
- antenna_id=xds["baseline_antenna1_id"]
1045
+ if not is_single_dish: # Interferometer
1046
+ xds["baseline_antenna1_id"].data = ant_xds["antenna_name"].sel(
1047
+ antenna_id=xds["baseline_antenna1_id"].data
1048
1048
  )
1049
- xds["baseline_antenna2_id"] = ant_xds["antenna_name"].sel(
1050
- antenna_id=xds["baseline_antenna2_id"]
1049
+ xds["baseline_antenna2_id"].data = ant_xds["antenna_name"].sel(
1050
+ antenna_id=xds["baseline_antenna2_id"].data
1051
1051
  )
1052
1052
  xds = xds.rename(
1053
1053
  {
@@ -1055,9 +1055,23 @@ def antenna_ids_to_names(xds, ant_xds):
1055
1055
  "baseline_antenna2_id": "baseline_antenna2_name",
1056
1056
  }
1057
1057
  )
1058
- else: # Single Dish
1059
- xds["antenna_id"] = ant_xds["antenna_name"].sel(antenna_id=xds["antenna_id"])
1060
- xds = xds.rename({"antenna_id": "antenna_name"})
1058
+ else:
1059
+ xds["baseline_id"] = ant_xds["antenna_name"].sel(antenna_id=xds["baseline_id"])
1060
+ unwanted_coords_from_ant_xds = [
1061
+ "antenna_id",
1062
+ "antenna_name",
1063
+ "mount",
1064
+ "station",
1065
+ ]
1066
+ for unwanted_coord in unwanted_coords_from_ant_xds:
1067
+ xds = xds.drop_vars(unwanted_coord)
1068
+ xds = xds.rename({"baseline_id": "antenna_name"})
1069
+
1070
+ # drop more vars that seem unwanted in main_sd_xds, but there shouuld be a better way
1071
+ # of not creating them in the first place
1072
+ unwanted_coords_sd = ["baseline_antenna1_id", "baseline_antenna2_id"]
1073
+ for unwanted_coord in unwanted_coords_sd:
1074
+ xds = xds.drop_vars(unwanted_coord)
1061
1075
 
1062
1076
  return xds
1063
1077
 
@@ -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(
@@ -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(xds, path, source_id, spectral_window_id):
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", "antenna_id"]
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", "antenna_id"], # removed
227
- # "time_origin": ["time", "antenna_id"], # removed?
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", "antenna_id"], # removed
234
- # "tracking": ["time", "antenna_id"], # => attribute
235
- # "on_source": ["time", "antenna_id"], # removed
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
- "antenna_id": np.arange(generic_pointing_xds.sizes["ANTENNA_ID"]),
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)
@@ -1,4 +1,4 @@
1
- from importlib_metadata import version
1
+ from importlib.metadata import version
2
2
  import graphviper.utils.logger as logger, multiprocessing, psutil
3
3
  from typing import Any, Dict, List, Tuple, Union
4
4
 
@@ -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"] in obs_modes
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