xradio 0.0.56__tar.gz → 0.0.58__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 (95) hide show
  1. {xradio-0.0.56/src/xradio.egg-info → xradio-0.0.58}/PKG-INFO +2 -1
  2. {xradio-0.0.56 → xradio-0.0.58}/pyproject.toml +3 -2
  3. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/__init__.py +2 -2
  4. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/_utils/_casacore/casacore_from_casatools.py +12 -2
  5. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/_utils/_casacore/tables.py +1 -0
  6. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/_utils/coord_math.py +22 -23
  7. xradio-0.0.58/src/xradio/_utils/dict_helpers.py +170 -0
  8. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/_utils/schema.py +5 -2
  9. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/_utils/zarr/common.py +1 -73
  10. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/_casacore/xds_from_casacore.py +49 -33
  11. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/_casacore/xds_to_casacore.py +41 -14
  12. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/_fits/xds_from_fits.py +146 -35
  13. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/casacore.py +4 -3
  14. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/common.py +4 -4
  15. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/image_factory.py +8 -8
  16. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/image.py +45 -5
  17. xradio-0.0.58/src/xradio/measurement_set/__init__.py +37 -0
  18. xradio-0.0.58/src/xradio/measurement_set/_utils/__init__.py +3 -0
  19. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/_utils/_msv2/_tables/read.py +17 -76
  20. xradio-0.0.58/src/xradio/measurement_set/_utils/_msv2/_tables/read_main_table.py +102 -0
  21. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/_utils/_msv2/conversion.py +123 -145
  22. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/_utils/_msv2/create_antenna_xds.py +9 -16
  23. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/_utils/_msv2/create_field_and_source_xds.py +125 -221
  24. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/_utils/_msv2/msv2_to_msv4_meta.py +1 -2
  25. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/_utils/_msv2/msv4_info_dicts.py +8 -7
  26. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/_utils/_msv2/msv4_sub_xdss.py +27 -72
  27. xradio-0.0.58/src/xradio/measurement_set/_utils/_msv2/optimised_functions.py +0 -0
  28. xradio-0.0.58/src/xradio/measurement_set/_utils/_msv2/partition_queries.py +150 -0
  29. xradio-0.0.58/src/xradio/measurement_set/_utils/_msv2/subtables.py +16 -0
  30. xradio-0.0.58/src/xradio/measurement_set/_utils/_utils/interpolate.py +60 -0
  31. xradio-0.0.58/src/xradio/measurement_set/_utils/_zarr/encoding.py +9 -0
  32. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/convert_msv2_to_processing_set.py +0 -2
  33. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/load_processing_set.py +2 -2
  34. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/measurement_set_xdt.py +14 -14
  35. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/open_processing_set.py +1 -3
  36. xradio-0.0.58/src/xradio/measurement_set/processing_set_xdt.py +873 -0
  37. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/schema.py +95 -122
  38. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/schema/check.py +91 -97
  39. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/schema/dataclass.py +159 -22
  40. xradio-0.0.58/src/xradio/schema/export.py +99 -0
  41. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/schema/metamodel.py +51 -16
  42. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/schema/typing.py +5 -5
  43. {xradio-0.0.56 → xradio-0.0.58/src/xradio.egg-info}/PKG-INFO +2 -1
  44. {xradio-0.0.56 → xradio-0.0.58}/src/xradio.egg-info/SOURCES.txt +3 -16
  45. {xradio-0.0.56 → xradio-0.0.58}/src/xradio.egg-info/requires.txt +1 -0
  46. xradio-0.0.56/src/xradio/_utils/dict_helpers.py +0 -105
  47. xradio-0.0.56/src/xradio/image/_util/fits.py +0 -13
  48. xradio-0.0.56/src/xradio/measurement_set/__init__.py +0 -27
  49. xradio-0.0.56/src/xradio/measurement_set/_utils/__init__.py +0 -5
  50. xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/_tables/load.py +0 -66
  51. xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/_tables/load_main_table.py +0 -490
  52. xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/_tables/read_main_table.py +0 -785
  53. xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/_tables/read_subtables.py +0 -398
  54. xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/_tables/write.py +0 -323
  55. xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/_tables/write_exp_api.py +0 -388
  56. xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/chunks.py +0 -115
  57. xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/descr.py +0 -165
  58. xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/msv2_msv3.py +0 -7
  59. xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/partition_queries.py +0 -410
  60. xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/partitions.py +0 -392
  61. xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/subtables.py +0 -123
  62. xradio-0.0.56/src/xradio/measurement_set/_utils/_utils/cds.py +0 -40
  63. xradio-0.0.56/src/xradio/measurement_set/_utils/_utils/xds_helper.py +0 -404
  64. xradio-0.0.56/src/xradio/measurement_set/_utils/_zarr/encoding.py +0 -14
  65. xradio-0.0.56/src/xradio/measurement_set/_utils/_zarr/read.py +0 -263
  66. xradio-0.0.56/src/xradio/measurement_set/_utils/_zarr/write.py +0 -329
  67. xradio-0.0.56/src/xradio/measurement_set/_utils/msv2.py +0 -106
  68. xradio-0.0.56/src/xradio/measurement_set/_utils/zarr.py +0 -133
  69. xradio-0.0.56/src/xradio/measurement_set/processing_set_xdt.py +0 -1667
  70. {xradio-0.0.56 → xradio-0.0.58}/LICENSE.txt +0 -0
  71. {xradio-0.0.56 → xradio-0.0.58}/MANIFEST.in +0 -0
  72. {xradio-0.0.56 → xradio-0.0.58}/README.md +0 -0
  73. {xradio-0.0.56 → xradio-0.0.58}/setup.cfg +0 -0
  74. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/_utils/__init__.py +0 -0
  75. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/_utils/list_and_array.py +0 -0
  76. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/_utils/zarr/__init__.py +0 -0
  77. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/__init__.py +0 -0
  78. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/__init__.py +0 -0
  79. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/_casacore/__init__.py +0 -0
  80. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/_casacore/common.py +0 -0
  81. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/_zarr/common.py +0 -0
  82. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/_zarr/xds_from_zarr.py +0 -0
  83. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/_zarr/xds_to_zarr.py +0 -0
  84. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/_zarr/zarr_low_level.py +0 -0
  85. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/image/_util/zarr.py +0 -0
  86. /xradio-0.0.56/src/xradio/measurement_set/_utils/_msv2/optimised_functions.py → /xradio-0.0.58/src/xradio/measurement_set/_utils/_msv2/__init__.py +0 -0
  87. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/_utils/_msv2/_tables/table_query.py +0 -0
  88. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/_utils/_utils/partition_attrs.py +0 -0
  89. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/measurement_set/_utils/_utils/stokes_types.py +0 -0
  90. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/schema/__init__.py +0 -0
  91. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/schema/bases.py +0 -0
  92. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/sphinx/__init__.py +0 -0
  93. {xradio-0.0.56 → xradio-0.0.58}/src/xradio/sphinx/schema_table.py +0 -0
  94. {xradio-0.0.56 → xradio-0.0.58}/src/xradio.egg-info/dependency_links.txt +0 -0
  95. {xradio-0.0.56 → xradio-0.0.58}/src/xradio.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xradio
3
- Version: 0.0.56
3
+ Version: 0.0.58
4
4
  Summary: Xarray Radio Astronomy Data IO
5
5
  Author-email: Jan-Willem Steeb <jsteeb@nrao.edu>, Federico Montesino Pouzols <pouzols@eso.edu>, Dave Mehringer <dmehring@nrao.edu>, Peter Wortmann <peter.wortmann@skao.int>
6
6
  License: BSD 3-Clause License
@@ -50,6 +50,7 @@ Requires-Dist: zarr<3,>=2
50
50
  Requires-Dist: pyarrow
51
51
  Requires-Dist: typeguard
52
52
  Requires-Dist: numcodecs<0.16
53
+ Requires-Dist: psutil
53
54
  Provides-Extra: test
54
55
  Requires-Dist: pytest; extra == "test"
55
56
  Requires-Dist: pytest-cov; extra == "test"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "xradio"
3
- version = "v0.0.56"
3
+ version = "v0.0.58"
4
4
  description = " Xarray Radio Astronomy Data IO"
5
5
  authors = [
6
6
  {name = "Jan-Willem Steeb", email="jsteeb@nrao.edu"},
@@ -22,7 +22,8 @@ dependencies = [
22
22
  'zarr>=2,<3',
23
23
  'pyarrow',
24
24
  'typeguard',
25
- 'numcodecs<0.16'
25
+ 'numcodecs<0.16',
26
+ 'psutil' # psutil is needed so large FITS images are not loaded into memory
26
27
  ]
27
28
 
28
29
  # toolviper has the following key dependencies also directly used by XRADIO (https://github.com/casangi/toolviper/blob/main/pyproject.toml):
@@ -1,5 +1,5 @@
1
- import os
2
- from toolviper.utils.logger import setup_logger
1
+ # import os
2
+ # from toolviper.utils.logger import setup_logger
3
3
 
4
4
 
5
5
  # _logger_name = "xradio"
@@ -18,7 +18,17 @@ from typing import Any, Dict, List, Sequence, Union
18
18
  # Configure casaconfig settings prior to casatools import
19
19
  # this ensures optimal initialization and resource allocation for casatools
20
20
  # Also see : https://casadocs.readthedocs.io/en/stable/api/casaconfig.html
21
- import casaconfig.config
21
+ try:
22
+ import casaconfig.config
23
+ except ModuleNotFoundError as exc:
24
+ raise ModuleNotFoundError(
25
+ f"casaconfig.config cannot be found, probably because the package "
26
+ "casatools is not available. If you are here that is probably because "
27
+ "python-casacore is not available either. MSv2 related functionality "
28
+ "requires either python-casacore or casatools. Import failure details: "
29
+ f"{exc}"
30
+ )
31
+
22
32
  import numpy as np
23
33
  import toolviper.utils.logger as logger
24
34
 
@@ -70,7 +80,7 @@ else:
70
80
  casaconfig.config.logfile = "/dev/null"
71
81
  casaconfig.config.nologfile = True
72
82
 
73
- import casatools
83
+ import casatools # noqa: E402 (because of previous config initialization)
74
84
 
75
85
  casatools.logger.setglobal(True)
76
86
  casatools.logger.ompSetNumThreads(1)
@@ -4,6 +4,7 @@ except ImportError:
4
4
  import xradio._utils._casacore.casacore_from_casatools as tables
5
5
 
6
6
  from contextlib import contextmanager
7
+ import os
7
8
  from typing import Dict, Generator
8
9
 
9
10
  # common casacore table handling code
@@ -63,38 +63,37 @@ def wrap_to_pi(angles):
63
63
  return (angles + np.pi) % (2 * np.pi) - np.pi
64
64
 
65
65
 
66
- def wrap_to_pi(angles):
67
- return (angles + np.pi) % (2 * np.pi) - np.pi
66
+ def convert_to_si_units(xds):
67
+ import xarray as xr
68
68
 
69
+ with xr.set_options(keep_attrs=True):
70
+ for data_var in xds.data_vars:
71
+ if "units" in xds[data_var].attrs:
72
+ u = xds[data_var].attrs["units"]
69
73
 
70
- def convert_to_si_units(xds):
71
- for data_var in xds.data_vars:
72
- if "units" in xds[data_var].attrs:
73
- for u_i, u in enumerate(xds[data_var].attrs["units"]):
74
74
  if u == "km":
75
- xds[data_var][..., u_i] = xds[data_var][..., u_i] * 1e3
76
- xds[data_var].attrs["units"][u_i] = "m"
75
+ xds[data_var] = xds[data_var] * 1e3
76
+ xds[data_var].attrs["units"] = "m"
77
77
  if u == "km/s":
78
- xds[data_var][..., u_i] = xds[data_var][..., u_i] * 1e3
79
- xds[data_var].attrs["units"][u_i] = "m/s"
78
+ xds[data_var] = xds[data_var] * 1e3
79
+ xds[data_var].attrs["units"] = "m/s"
80
80
  if u == "deg":
81
- xds[data_var][..., u_i] = xds[data_var][..., u_i] * np.pi / 180
82
- xds[data_var].attrs["units"][u_i] = "rad"
81
+ xds[data_var] = xds[data_var] * np.pi / 180
82
+ xds[data_var].attrs["units"] = "rad"
83
83
  if u == "Au" or u == "AU":
84
- xds[data_var][..., u_i] = xds[data_var][..., u_i] * 149597870700
85
- xds[data_var].attrs["units"][u_i] = "m"
84
+ xds[data_var] = xds[data_var] * 149597870700
85
+ xds[data_var].attrs["units"] = "m"
86
86
  if u == "Au/d" or u == "AU/d":
87
- xds[data_var][..., u_i] = (
88
- xds[data_var][..., u_i] * 149597870700 / 86400
89
- )
90
- xds[data_var].attrs["units"][u_i] = "m/s"
87
+ xds[data_var] = xds[data_var] * 149597870700 / 86400
88
+ xds[data_var].attrs["units"] = "m/s"
91
89
  if u == "arcsec":
92
- xds[data_var][..., u_i] = xds[data_var][..., u_i] * np.pi / 648000
93
- xds[data_var].attrs["units"][u_i] = "rad"
90
+ xds[data_var] = xds[data_var] * np.pi / 648000
91
+ xds[data_var].attrs["units"] = "rad"
94
92
  if u == "hPa":
95
- xds[data_var][..., u_i] = xds[data_var][..., u_i] * 100.0
96
- xds[data_var].attrs["units"][u_i] = "Pa"
93
+ xds[data_var] = xds[data_var] * 100.0
94
+ xds[data_var].attrs["units"] = "Pa"
97
95
  if u == "m-2":
98
96
  # IONOS_ELECTRON sometimes has "m-2" instead of "/m^2"
99
- xds[data_var].attrs["units"][u_i] = "/m^2"
97
+ xds[data_var].attrs["units"] = "/m^2"
98
+
100
99
  return xds
@@ -0,0 +1,170 @@
1
+ def make_quantity(value, units: str, dims: list = []) -> dict:
2
+ """
3
+ create a quantity dictionary given value and units
4
+
5
+ Parameters
6
+ ----------
7
+ value : numeric or array of numerics
8
+ Quantity value
9
+ units: str
10
+ Quantity units
11
+
12
+ Returns
13
+ -------
14
+ dict
15
+ """
16
+ return {"data": value, "dims": dims, "attrs": make_quantity_attrs(units)}
17
+
18
+
19
+ def ensure_units_are_consistent(units):
20
+ if isinstance(units, str):
21
+ return units
22
+ else:
23
+ u0 = units[0]
24
+ for u in units:
25
+ assert u0 == u, f"Units are not consistent: {u0} != {u}. "
26
+ return u0
27
+
28
+
29
+ def make_quantity_attrs(units: str) -> dict:
30
+ """
31
+ Creates the dict of attributes of a quantity
32
+
33
+ Parameters
34
+ ----------
35
+ units: str
36
+ Quantity units
37
+
38
+ Returns
39
+ -------
40
+ dict
41
+ """
42
+ return {"units": ensure_units_are_consistent(units), "type": "quantity"}
43
+
44
+
45
+ def make_spectral_coord_reference_dict(
46
+ value: float, units: str, observer: str = "lsrk"
47
+ ) -> dict:
48
+ """
49
+ creates a spectral_coord measure dict given the value, units, and observer
50
+
51
+ Parameters
52
+ ----------
53
+ value : numeric or array of numerics
54
+ measure value
55
+ units : str
56
+ measure units
57
+ observer :
58
+ observer reference frame
59
+
60
+ Returns
61
+ -------
62
+ dict
63
+ """
64
+ u = ensure_units_are_consistent(units)
65
+ return {
66
+ "attrs": make_spectral_coord_measure_attrs(
67
+ u,
68
+ observer.lower() if observer not in ["TOPO", "BARY", "REST"] else observer,
69
+ ),
70
+ "data": value,
71
+ "dims": [],
72
+ }
73
+
74
+
75
+ def make_spectral_coord_measure_attrs(units: str, observer: str = "lsrk") -> dict:
76
+ """
77
+ Creates a spectral_coord measure attrs dict given units and observer
78
+
79
+ Parameters
80
+ ----------
81
+ units: str or list of str
82
+ Spectral coordinate units
83
+ observer: str
84
+ Spectral reference frame
85
+ Returns
86
+ -------
87
+ dict
88
+ Attrs dict for a spectral_coord measure
89
+ """
90
+ u = ensure_units_are_consistent(units)
91
+ return {"units": u, "observer": observer, "type": "spectral_coord"}
92
+
93
+
94
+ def make_skycoord_dict(data: list[float], units: str, frame: str) -> dict:
95
+ return {
96
+ "attrs": {
97
+ "frame": frame.lower(),
98
+ "type": "sky_coord",
99
+ "units": ensure_units_are_consistent(units),
100
+ },
101
+ "data": data,
102
+ "dims": ["l", "m"],
103
+ }
104
+
105
+
106
+ def make_time_measure_attrs(units="s", scale="utc", time_format="mjd") -> dict:
107
+ u = ensure_units_are_consistent(units)
108
+ return {"units": u, "scale": scale, "format": time_format, "type": "time"}
109
+
110
+
111
+ def make_time_measure_dict(data, units="s", scale="utc", time_format="mjd") -> dict:
112
+ """
113
+ create a time measure dictionary given value and units
114
+ Parameters
115
+ ----------
116
+ value : numeric or array of numerics
117
+ Time value
118
+ units: str
119
+ Time units
120
+ scale: str
121
+ Time scale
122
+ time_format: str
123
+ Time format
124
+ Returns
125
+ -------
126
+ dict
127
+ """
128
+ x = {}
129
+ x["attrs"] = make_time_measure_attrs(units, scale, time_format)
130
+ x["data"] = data
131
+ x["dims"] = []
132
+ return x
133
+
134
+
135
+ def make_time_coord_attrs(units="s", scale="utc", time_format="mjd") -> dict:
136
+ """
137
+ create a time measure dictionary given value and units
138
+ Parameters
139
+ ----------
140
+ value : numeric or array of numerics
141
+ Time value
142
+ units: str
143
+ Time units
144
+ scale: str
145
+ Time scale
146
+ time_format: str
147
+ Time format
148
+ Returns
149
+ -------
150
+ dict
151
+ """
152
+ x = make_time_measure_attrs(units, scale, time_format)
153
+ del x["type"]
154
+ return x
155
+
156
+
157
+ def _casacore_q_to_xradio_q(q: dict) -> dict:
158
+ """
159
+ Convert a casacore quantity to an xradio quantity
160
+ """
161
+ if isinstance(q, dict):
162
+ if "value" in q and "unit" in q:
163
+ return make_quantity(q["value"], q["unit"])
164
+ else:
165
+ p = {}
166
+ for k in q:
167
+ p[k] = _casacore_q_to_xradio_q(q[k])
168
+ return p
169
+ else:
170
+ raise ValueError(f"Cannot convert {q} to xradio quantity")
@@ -1,6 +1,7 @@
1
1
  import toolviper.utils.logger as logger
2
2
  import xarray as xr
3
3
  from typing import Union
4
+ from xradio._utils.dict_helpers import ensure_units_are_consistent
4
5
 
5
6
 
6
7
  def convert_generic_xds_to_xradio_schema(
@@ -108,7 +109,7 @@ def column_description_casacore_to_msv4_measure(
108
109
 
109
110
  # Convert type, copy unit
110
111
  msv4_measure["type"] = msv4_measure_conversion["type"]
111
- msv4_measure["units"] = list(
112
+ msv4_measure["units"] = ensure_units_are_consistent(
112
113
  casacore_column_description["keywords"]["QuantumUnits"]
113
114
  )
114
115
 
@@ -154,7 +155,9 @@ def column_description_casacore_to_msv4_measure(
154
155
  elif "QuantumUnits" in casacore_column_description["keywords"]:
155
156
  msv4_measure = {
156
157
  "type": "quantity",
157
- "units": list(casacore_column_description["keywords"]["QuantumUnits"]),
158
+ "units": ensure_units_are_consistent(
159
+ casacore_column_description["keywords"]["QuantumUnits"]
160
+ ),
158
161
  }
159
162
 
160
163
  return msv4_measure
@@ -1,6 +1,4 @@
1
- import copy
2
1
  import xarray as xr
3
- import zarr
4
2
  import s3fs
5
3
  import os
6
4
  from botocore.exceptions import NoCredentialsError
@@ -34,7 +32,7 @@ def _get_file_system_and_items(ps_store: str):
34
32
  for bd in file_system.listdir(ps_store, detail=False)
35
33
  ]
36
34
 
37
- except (NoCredentialsError, PermissionError) as e:
35
+ except (NoCredentialsError, PermissionError):
38
36
  # only public, read-only buckets will be accessible
39
37
  # we will want to add messaging and error handling here
40
38
  file_system = s3fs.S3FileSystem(anon=True)
@@ -97,73 +95,3 @@ def _open_dataset(
97
95
  with dask.config.set(scheduler="synchronous"):
98
96
  xds = xds.load()
99
97
  return xds
100
-
101
-
102
- # Code to depricate:
103
- def _get_attrs(zarr_obj):
104
- """
105
- get attributes of zarr obj (groups or arrays)
106
- """
107
- return {k: v for k, v in zarr_obj.attrs.asdict().items() if not k.startswith("_NC")}
108
-
109
-
110
- def _load_no_dask_zarr(zarr_name, slice_dict={}):
111
- """
112
- Alternative to xarray open_zarr where the arrays are not Dask Arrays.
113
-
114
- slice_dict: A dictionary of slice objects for which values to read form a dimension.
115
- For example silce_dict={'time':slice(0,10)} would select the first 10 elements in the time dimension.
116
- If a dim is not specified all values are retruned.
117
- return:
118
- xarray.Dataset()
119
-
120
- #Should go into general utils.
121
- """
122
- # Used by xarray to store array labeling info in zarr meta data.
123
- DIMENSION_KEY = "_ARRAY_DIMENSIONS"
124
-
125
- # logger = _get_logger()
126
- zarr_group = zarr.open_group(store=zarr_name, mode="r")
127
- group_attrs = _get_attrs(zarr_group)
128
-
129
- slice_dict_complete = copy.deepcopy(slice_dict)
130
- coords = {}
131
- xds = xr.Dataset()
132
- for var_name, var in zarr_group.arrays():
133
- print("Hallo 3", var_name, var.shape)
134
- var_attrs = _get_attrs(var)
135
-
136
- for dim in var_attrs[DIMENSION_KEY]:
137
- if dim not in slice_dict_complete:
138
- slice_dict_complete[dim] = slice(None) # No slicing.
139
-
140
- if (var_attrs[DIMENSION_KEY][0] == var_name) and (
141
- len(var_attrs[DIMENSION_KEY]) == 1
142
- ):
143
- coord = var[
144
- slice_dict_complete[var_attrs[DIMENSION_KEY][0]]
145
- ] # Dimension coordinates.
146
- del var_attrs["_ARRAY_DIMENSIONS"]
147
- xds = xds.assign_coords({var_name: coord})
148
- xds[var_name].attrs = var_attrs
149
- else:
150
- # Construct slicing
151
- slicing_list = []
152
- for dim in var_attrs[DIMENSION_KEY]:
153
- slicing_list.append(slice_dict_complete[dim])
154
- slicing_tuple = tuple(slicing_list)
155
-
156
- print(var_attrs[DIMENSION_KEY])
157
-
158
- xds[var_name] = xr.DataArray(
159
- var[slicing_tuple], dims=var_attrs[DIMENSION_KEY]
160
- )
161
-
162
- if "coordinates" in var_attrs:
163
- del var_attrs["coordinates"]
164
- del var_attrs["_ARRAY_DIMENSIONS"]
165
- xds[var_name].attrs = var_attrs
166
-
167
- xds.attrs = group_attrs
168
-
169
- return xds
@@ -41,7 +41,7 @@ from ...._utils._casacore.tables import extract_table_attributes, open_table_ro
41
41
  from xradio._utils.coord_math import _deg_to_rad
42
42
  from xradio._utils.dict_helpers import (
43
43
  _casacore_q_to_xradio_q,
44
- make_frequency_reference_dict,
44
+ make_spectral_coord_reference_dict,
45
45
  make_quantity,
46
46
  make_skycoord_dict,
47
47
  make_time_measure_dict,
@@ -85,34 +85,50 @@ def _casa_image_to_xds_image_attrs(image: casa_image, history: bool = True) -> d
85
85
  attrs["units"] = image.unit()
86
86
  attrs["telescope"] = {}
87
87
  telescope = attrs["telescope"]
88
+
88
89
  for k in ("observer", "obsdate", "telescope", "telescopeposition"):
89
90
  if k.startswith("telescope"):
90
91
  if k == "telescope":
91
92
  telescope["name"] = coord_dict[k]
92
93
  elif k in coord_dict:
93
94
  casa_pos = coord_dict[k]
94
- location = {}
95
- loc_attrs = {}
96
- loc_attrs["type"] = "location"
97
- loc_attrs["frame"] = casa_pos["refer"]
98
- """
99
- if casa_pos["refer"] == "ITRF":
100
- loc_attrs["ellipsoid"] = "GRS80"
101
- """
102
- loc_attrs["units"] = [
103
- casa_pos["m0"]["unit"],
104
- casa_pos["m1"]["unit"],
105
- casa_pos["m2"]["unit"],
106
- ]
107
- loc_attrs["coordinate_system"] = "geocentric"
108
- loc_attrs["origin_object_name"] = "earth"
109
- location["attrs"] = loc_attrs
110
- location["data"] = [
111
- casa_pos["m0"]["value"],
112
- casa_pos["m1"]["value"],
113
- casa_pos["m2"]["value"],
114
- ]
115
- telescope["location"] = location
95
+ telescope["direction"] = {
96
+ "attrs": {
97
+ "coordinate_system": "geocentric",
98
+ "frame": casa_pos["refer"],
99
+ "origin_object_name": "earth",
100
+ "type": "location",
101
+ "units": casa_pos["m0"]["unit"],
102
+ },
103
+ "data": [casa_pos["m0"]["value"], casa_pos["m1"]["value"]],
104
+ "dims": ["ellipsoid_dir_label"],
105
+ "coords": {
106
+ "ellipsoid_dir_label": {
107
+ "dims": ["ellipsoid_dir_label"],
108
+ "data": ["lon", "lat"],
109
+ }
110
+ },
111
+ }
112
+ telescope["distance"] = {
113
+ "attrs": {
114
+ "coordinate_system": "geocentric",
115
+ "frame": casa_pos["refer"],
116
+ "origin_object_name": "earth",
117
+ "type": "location",
118
+ "units": casa_pos["m2"]["unit"],
119
+ },
120
+ "data": [casa_pos["m2"]["value"]],
121
+ "dims": ["ellipsoid_dis_label"],
122
+ "coords": {
123
+ "ellipsoid_dis_label": {
124
+ "dims": ["ellipsoid_dis_label"],
125
+ "data": [
126
+ "dist",
127
+ ],
128
+ }
129
+ },
130
+ }
131
+
116
132
  """
117
133
  del (
118
134
  telescope["position"]["refer"],
@@ -155,7 +171,7 @@ def _casa_image_to_xds_image_attrs(image: casa_image, history: bool = True) -> d
155
171
  # associated with it.
156
172
  # point_center = coord_dict["pointingcenter"]
157
173
  attrs[_pointing_center] = make_skycoord_dict(
158
- coord_dict["pointingcenter"]["value"].tolist(), ["rad", "rad"], frame
174
+ coord_dict["pointingcenter"]["value"].tolist(), "rad", frame
159
175
  )
160
176
  imageinfo = meta_dict["imageinfo"]
161
177
  obj = "objectname"
@@ -221,7 +237,7 @@ def _add_time_attrs(xds: xr.Dataset, coord_dict: dict) -> xr.Dataset:
221
237
 
222
238
  def _add_vel_attrs(xds: xr.Dataset, coord_dict: dict) -> xr.Dataset:
223
239
  vel_coord = xds["velocity"]
224
- meta = {"units": ["m/s"]}
240
+ meta = {"units": "m/s"}
225
241
  for k in coord_dict:
226
242
  if k.startswith("spectral"):
227
243
  sd = coord_dict[k]
@@ -259,7 +275,7 @@ def _casa_image_to_xds_attrs(img_full_path: str) -> dict:
259
275
  dir_dict = {}
260
276
 
261
277
  dir_dict["reference"] = make_skycoord_dict(
262
- data=[0.0, 0.0], units=["rad", "rad"], frame=ap_system
278
+ data=[0.0, 0.0], units="rad", frame=ap_system
263
279
  )
264
280
  if ap_equinox:
265
281
  dir_dict["reference"]["attrs"]["equinox"] = ap_equinox
@@ -534,14 +550,14 @@ def _get_freq_values_attrs(
534
550
  cdelt=wcs["cdelt"],
535
551
  )
536
552
  attrs["rest_frequency"] = make_quantity(sd["restfreq"], "Hz")
537
- # attrs["type"] = "frequency"
538
- # attrs["units"] = sd["unit"]
539
- # attrs["frame"] = sd["system"]
540
- attrs["wave_unit"] = [sd["waveUnit"]]
553
+ attrs["type"] = "spectral_coord"
554
+ attrs["units"] = sd["unit"]
555
+ attrs["frame"] = sd["system"]
556
+ attrs["wave_units"] = sd["waveUnit"]
541
557
  # attrs["crval"] = sd["wcs"]["crval"]
542
558
  # attrs["cdelt"] = sd["wcs"]["cdelt"]
543
559
 
544
- attrs["reference_value"] = make_frequency_reference_dict(
560
+ attrs["reference_frequency"] = make_spectral_coord_reference_dict(
545
561
  value=sd["wcs"]["crval"],
546
562
  units=sd["unit"],
547
563
  observer=sd["system"],
@@ -672,7 +688,7 @@ def _get_time_values_attrs(cimage_coord_dict: dict) -> Tuple[List[float], dict]:
672
688
  attrs["type"] = "time"
673
689
  attrs["scale"] = cimage_coord_dict["obsdate"]["refer"]
674
690
  unit = cimage_coord_dict["obsdate"]["m0"]["unit"]
675
- attrs["units"] = unit if isinstance(unit, list) else [unit]
691
+ attrs["units"] = unit
676
692
  time_val = cimage_coord_dict["obsdate"]["m0"]["value"]
677
693
  attrs["format"] = _get_time_format(time_val, unit)
678
694
  return ([time_val], copy.deepcopy(attrs))
@@ -802,7 +818,7 @@ def _get_velocity_values_attrs(
802
818
  if not attrs:
803
819
  attrs["doppler_type"] = _doppler_types[0]
804
820
 
805
- attrs["units"] = ["m/s"]
821
+ attrs["units"] = "m/s"
806
822
  attrs["type"] = "doppler"
807
823
  return (
808
824
  _compute_velocity_values(