xradio 0.0.41__tar.gz → 0.0.42__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.41/src/xradio.egg-info → xradio-0.0.42}/PKG-INFO +9 -6
- xradio-0.0.42/README.md +21 -0
- {xradio-0.0.41 → xradio-0.0.42}/pyproject.toml +1 -1
- xradio-0.0.42/src/xradio/_utils/coord_math.py +100 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/_utils/list_and_array.py +49 -4
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/_utils/schema.py +36 -16
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/image/_util/_casacore/xds_from_casacore.py +5 -5
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/image/_util/_casacore/xds_to_casacore.py +12 -11
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/image/_util/_fits/xds_from_fits.py +18 -17
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/image/_util/_zarr/zarr_low_level.py +29 -12
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/image/_util/common.py +1 -1
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/image/_util/image_factory.py +1 -1
- {xradio-0.0.41/src/xradio/correlated_data → xradio-0.0.42/src/xradio/measurement_set}/__init__.py +7 -4
- xradio-0.0.42/src/xradio/measurement_set/_utils/__init__.py +5 -0
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/_tables/load_main_table.py +1 -1
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/_tables/read.py +1 -1
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/conversion.py +78 -35
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/create_antenna_xds.py +62 -37
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/create_field_and_source_xds.py +109 -22
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/msv4_sub_xdss.py +47 -13
- {xradio-0.0.41/src/xradio/correlated_data → xradio-0.0.42/src/xradio/measurement_set}/_utils/_utils/xds_helper.py +1 -1
- xradio-0.0.41/src/xradio/correlated_data/_utils/ms.py → xradio-0.0.42/src/xradio/measurement_set/_utils/msv2.py +4 -4
- {xradio-0.0.41/src/xradio/correlated_data → xradio-0.0.42/src/xradio/measurement_set}/convert_msv2_to_processing_set.py +2 -2
- {xradio-0.0.41/src/xradio/correlated_data → xradio-0.0.42/src/xradio/measurement_set}/load_processing_set.py +5 -5
- xradio-0.0.42/src/xradio/measurement_set/measurement_set_xds.py +83 -0
- {xradio-0.0.41/src/xradio/correlated_data → xradio-0.0.42/src/xradio/measurement_set}/open_processing_set.py +9 -16
- xradio-0.0.42/src/xradio/measurement_set/processing_set.py +777 -0
- {xradio-0.0.41/src/xradio/correlated_data → xradio-0.0.42/src/xradio/measurement_set}/schema.py +1101 -610
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/schema/check.py +42 -22
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/schema/dataclass.py +56 -6
- xradio-0.0.42/src/xradio/sphinx/__init__.py +12 -0
- xradio-0.0.42/src/xradio/sphinx/schema_table.py +351 -0
- {xradio-0.0.41 → xradio-0.0.42/src/xradio.egg-info}/PKG-INFO +9 -6
- xradio-0.0.42/src/xradio.egg-info/SOURCES.txt +80 -0
- xradio-0.0.41/README.md +0 -18
- xradio-0.0.41/src/xradio/_utils/common.py +0 -101
- xradio-0.0.41/src/xradio/correlated_data/_utils/__init__.py +0 -5
- xradio-0.0.41/src/xradio/correlated_data/correlated_xds.py +0 -13
- xradio-0.0.41/src/xradio/correlated_data/processing_set.py +0 -301
- xradio-0.0.41/src/xradio/correlated_data/test__processing_set.py +0 -74
- xradio-0.0.41/src/xradio.egg-info/SOURCES.txt +0 -79
- {xradio-0.0.41 → xradio-0.0.42}/LICENSE.txt +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/MANIFEST.in +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/setup.cfg +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/__init__.py +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/_utils/__init__.py +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/_utils/_casacore/tables.py +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/_utils/zarr/__init__.py +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/_utils/zarr/common.py +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/image/__init__.py +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/image/_util/__init__.py +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/image/_util/_casacore/__init__.py +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/image/_util/_casacore/common.py +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/image/_util/_zarr/common.py +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/image/_util/_zarr/xds_from_zarr.py +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/image/_util/_zarr/xds_to_zarr.py +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/image/_util/casacore.py +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/image/_util/fits.py +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/image/_util/zarr.py +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/image/image.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/_tables/load.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/_tables/read_main_table.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/_tables/read_subtables.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/_tables/table_query.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/_tables/write.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/_tables/write_exp_api.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/chunks.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/descr.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/msv2_msv3.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/msv2_to_msv4_meta.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/msv4_info_dicts.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/optimised_functions.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/partition_queries.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/partitions.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data/_utils/_ms → xradio-0.0.42/src/xradio/measurement_set/_utils/_msv2}/subtables.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data → xradio-0.0.42/src/xradio/measurement_set}/_utils/_utils/cds.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data → xradio-0.0.42/src/xradio/measurement_set}/_utils/_utils/partition_attrs.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data → xradio-0.0.42/src/xradio/measurement_set}/_utils/_utils/stokes_types.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data → xradio-0.0.42/src/xradio/measurement_set}/_utils/_zarr/encoding.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data → xradio-0.0.42/src/xradio/measurement_set}/_utils/_zarr/read.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data → xradio-0.0.42/src/xradio/measurement_set}/_utils/_zarr/write.py +0 -0
- {xradio-0.0.41/src/xradio/correlated_data → xradio-0.0.42/src/xradio/measurement_set}/_utils/zarr.py +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/schema/__init__.py +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/schema/bases.py +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/schema/metamodel.py +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio/schema/typing.py +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio.egg-info/dependency_links.txt +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/src/xradio.egg-info/requires.txt +0 -0
- {xradio-0.0.41 → xradio-0.0.42}/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.
|
|
3
|
+
Version: 0.0.42
|
|
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
|
|
@@ -78,18 +78,21 @@ Requires-Dist: pandoc; extra == "docs"
|
|
|
78
78
|
# xradio
|
|
79
79
|
Xarray Radio Astronomy Data IO is still in development.
|
|
80
80
|
|
|
81
|
-
[](https://www.python.org/downloads/release/python-380/)
|
|
81
|
+
[](https://www.python.org/downloads/release/python-380/)
|
|
82
82
|
|
|
83
83
|
# Installing
|
|
84
|
-
It is recommended to use the [
|
|
84
|
+
It is recommended to use the conda environment manager from [miniforge](https://github.com/conda-forge/miniforge) to create a clean, self-contained runtime where XRADIO and all its dependencies can be installed:
|
|
85
85
|
```sh
|
|
86
|
-
conda create --name xradio python=3.
|
|
86
|
+
conda create --name xradio python=3.12 --no-default-packages
|
|
87
87
|
conda activate xradio
|
|
88
|
-
|
|
89
88
|
```
|
|
90
89
|
> 📝 On macOS it is required to pre-install `python-casacore` using `conda install -c conda-forge python-casacore`.
|
|
91
90
|
|
|
92
|
-
|
|
91
|
+
XRADIO can now be installed using:
|
|
93
92
|
```sh
|
|
94
93
|
pip install xradio
|
|
95
94
|
```
|
|
95
|
+
This will also install the minimal dependencies for XRADIO. To install the minimal dependencies and the interactive components (JupyterLab) use:
|
|
96
|
+
```sh
|
|
97
|
+
pip install "xradio[interactive]"
|
|
98
|
+
```
|
xradio-0.0.42/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# xradio
|
|
2
|
+
Xarray Radio Astronomy Data IO is still in development.
|
|
3
|
+
|
|
4
|
+
[](https://www.python.org/downloads/release/python-380/)
|
|
5
|
+
|
|
6
|
+
# Installing
|
|
7
|
+
It is recommended to use the conda environment manager from [miniforge](https://github.com/conda-forge/miniforge) to create a clean, self-contained runtime where XRADIO and all its dependencies can be installed:
|
|
8
|
+
```sh
|
|
9
|
+
conda create --name xradio python=3.12 --no-default-packages
|
|
10
|
+
conda activate xradio
|
|
11
|
+
```
|
|
12
|
+
> 📝 On macOS it is required to pre-install `python-casacore` using `conda install -c conda-forge python-casacore`.
|
|
13
|
+
|
|
14
|
+
XRADIO can now be installed using:
|
|
15
|
+
```sh
|
|
16
|
+
pip install xradio
|
|
17
|
+
```
|
|
18
|
+
This will also install the minimal dependencies for XRADIO. To install the minimal dependencies and the interactive components (JupyterLab) use:
|
|
19
|
+
```sh
|
|
20
|
+
pip install "xradio[interactive]"
|
|
21
|
+
```
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
_deg_to_rad = np.pi / 180
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def haversine(ra1, dec1, ra2, dec2):
|
|
7
|
+
"""
|
|
8
|
+
Calculate the great circle distance between two points
|
|
9
|
+
on the celestial sphere specified in radians.
|
|
10
|
+
"""
|
|
11
|
+
# Haversine formula
|
|
12
|
+
d_ra = ra2 - ra1
|
|
13
|
+
d_dec = dec2 - dec1
|
|
14
|
+
a = np.sin(d_dec / 2) ** 2 + np.cos(dec1) * np.cos(dec2) * np.sin(d_ra / 2) ** 2
|
|
15
|
+
c = 2 * np.arcsin(np.sqrt(a))
|
|
16
|
+
return c
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def add_position_offsets(dv_1, dv_2):
|
|
20
|
+
# Fun with angles: We are adding angles together. We need to make sure that the results are between -pi and pi.
|
|
21
|
+
new_pos = dv_1 + dv_2
|
|
22
|
+
|
|
23
|
+
new_pos = wrap_to_pi(new_pos)
|
|
24
|
+
|
|
25
|
+
# while np.any(new_pos[:, 0] > np.pi) or np.any(new_pos[:, 0] < -np.pi):
|
|
26
|
+
# new_pos[:, 0] = np.where(
|
|
27
|
+
# new_pos[:, 0] > np.pi, new_pos[:, 0] - 2 * np.pi, new_pos[:, 0]
|
|
28
|
+
# )
|
|
29
|
+
# new_pos[:, 0] = np.where(
|
|
30
|
+
# new_pos[:, 0] < -np.pi, new_pos[:, 0] + 2 * np.pi, new_pos[:, 0]
|
|
31
|
+
# )
|
|
32
|
+
|
|
33
|
+
# while np.any(new_pos[:, 1] > np.pi / 2) or np.any(new_pos[:, 1] < -np.pi / 2):
|
|
34
|
+
# new_pos[:, 1] = np.where(
|
|
35
|
+
# new_pos[:, 1] > np.pi / 2, new_pos[:, 1] - np.pi, new_pos[:, 1]
|
|
36
|
+
# )
|
|
37
|
+
# new_pos[:, 1] = np.where(
|
|
38
|
+
# new_pos[:, 1] < -np.pi / 2, new_pos[:, 1] + np.pi, new_pos[:, 1]
|
|
39
|
+
# )
|
|
40
|
+
|
|
41
|
+
return new_pos
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def wrap_to_pi(angles):
|
|
45
|
+
"""
|
|
46
|
+
Wraps an array of angles in radians to the range (-π, π].
|
|
47
|
+
|
|
48
|
+
Parameters:
|
|
49
|
+
-----------
|
|
50
|
+
angles : array_like
|
|
51
|
+
Input array of angles in radians.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
--------
|
|
55
|
+
array_like
|
|
56
|
+
The input angles wrapped to the range (-π, π].
|
|
57
|
+
|
|
58
|
+
Examples:
|
|
59
|
+
---------
|
|
60
|
+
>>> wrap_to_pi(np.array([0, np.pi, -np.pi, 3*np.pi, -3*np.pi]))
|
|
61
|
+
array([ 0. , 3.14159265, -3.14159265, 3.14159265, -3.14159265])
|
|
62
|
+
"""
|
|
63
|
+
return (angles + np.pi) % (2 * np.pi) - np.pi
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def wrap_to_pi(angles):
|
|
67
|
+
return (angles + np.pi) % (2 * np.pi) - np.pi
|
|
68
|
+
|
|
69
|
+
|
|
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
|
+
if u == "km":
|
|
75
|
+
xds[data_var][..., u_i] = xds[data_var][..., u_i] * 1e3
|
|
76
|
+
xds[data_var].attrs["units"][u_i] = "m"
|
|
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"
|
|
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"
|
|
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"
|
|
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"
|
|
91
|
+
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"
|
|
94
|
+
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"
|
|
97
|
+
if u == "m-2":
|
|
98
|
+
# IONOS_ELECTRON sometimes has "m-2" instead of "/m^2"
|
|
99
|
+
xds[data_var].attrs["units"][u_i] = "/m^2"
|
|
100
|
+
return xds
|
|
@@ -2,6 +2,55 @@
|
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
import xarray as xr
|
|
5
|
+
import pandas as pd
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def cast_to_str(x):
|
|
9
|
+
if isinstance(x, list):
|
|
10
|
+
return x[0]
|
|
11
|
+
else:
|
|
12
|
+
return x
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_pad_value(col_dtype: np.dtype) -> object:
|
|
16
|
+
"""
|
|
17
|
+
Produce a padding/missing/nan value appropriate for a casacore data column
|
|
18
|
+
(for when we need to pad data vars coming from columns with rows of
|
|
19
|
+
variable size array values)
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
col_dtype : dtype
|
|
24
|
+
dtype of data being loaded from a table column
|
|
25
|
+
|
|
26
|
+
Returns
|
|
27
|
+
-------
|
|
28
|
+
object
|
|
29
|
+
pad value ("missing" / "fill") for the type given
|
|
30
|
+
"""
|
|
31
|
+
# Fill values for missing/NaN data in integer variables, based on usual
|
|
32
|
+
# numpy fill values. See https://github.com/numpy/numpy/issues/21166,
|
|
33
|
+
# https://github.com/casangi/xradio/issues/219, https://github.com/casangi/xradio/pull/177
|
|
34
|
+
fill_value_int32 = np.int32(-2147483648)
|
|
35
|
+
fill_value_int64 = np.int64(-9223372036854775808)
|
|
36
|
+
|
|
37
|
+
if col_dtype == np.int32:
|
|
38
|
+
return fill_value_int32
|
|
39
|
+
elif col_dtype == np.int64 or col_dtype == "int":
|
|
40
|
+
return fill_value_int64
|
|
41
|
+
elif np.issubdtype(col_dtype, np.floating):
|
|
42
|
+
return np.nan
|
|
43
|
+
elif np.issubdtype(col_dtype, np.complexfloating):
|
|
44
|
+
return complex(np.nan, np.nan)
|
|
45
|
+
elif np.issubdtype(col_dtype, np.bool_):
|
|
46
|
+
return False
|
|
47
|
+
elif np.issubdtype(col_dtype, str):
|
|
48
|
+
return ""
|
|
49
|
+
else:
|
|
50
|
+
raise RuntimeError(
|
|
51
|
+
"Padding / missing value not defined for the type requested: "
|
|
52
|
+
f"{col_dtype} (of type: {type(col_dtype)})"
|
|
53
|
+
)
|
|
5
54
|
|
|
6
55
|
|
|
7
56
|
def to_list(x):
|
|
@@ -45,10 +94,6 @@ def check_if_consistent(array: np.ndarray, array_name: str) -> np.ndarray:
|
|
|
45
94
|
return array_unique[0]
|
|
46
95
|
|
|
47
96
|
|
|
48
|
-
import numpy as np
|
|
49
|
-
import pandas as pd
|
|
50
|
-
|
|
51
|
-
|
|
52
97
|
def unique_1d(array: np.ndarray) -> np.ndarray:
|
|
53
98
|
"""
|
|
54
99
|
Optimised version of np.unique for 1D arrays.
|
|
@@ -93,7 +93,7 @@ def convert_generic_xds_to_xradio_schema(
|
|
|
93
93
|
|
|
94
94
|
|
|
95
95
|
def column_description_casacore_to_msv4_measure(
|
|
96
|
-
casacore_column_description, ref_code=None, time_format="
|
|
96
|
+
casacore_column_description, ref_code=None, time_format="unix"
|
|
97
97
|
):
|
|
98
98
|
import numpy as np
|
|
99
99
|
|
|
@@ -136,9 +136,14 @@ def column_description_casacore_to_msv4_measure(
|
|
|
136
136
|
casa_ref = msv4_measure_conversion["Ref_map"][casa_ref]
|
|
137
137
|
else:
|
|
138
138
|
logger.debug(
|
|
139
|
-
f"
|
|
140
|
-
f"measure, using verbatim: {casa_ref}"
|
|
139
|
+
f"No translation defined for casacore reference frame ({measinfo['type']} "
|
|
140
|
+
f"measure), using verbatim: {casa_ref}"
|
|
141
141
|
)
|
|
142
|
+
if measinfo["type"] == "direction" and casa_ref == "B1950_VLA":
|
|
143
|
+
raise RuntimeError(
|
|
144
|
+
f"The direction reference frame {casa_ref} is not supported. "
|
|
145
|
+
"Please use CASA to convert the frame to supported frames like J2000 or ICRS."
|
|
146
|
+
)
|
|
142
147
|
|
|
143
148
|
msv4_measure[msv4_measure_conversion["Ref"]] = casa_ref
|
|
144
149
|
|
|
@@ -158,30 +163,45 @@ casacore_to_msv4_measure_type = {
|
|
|
158
163
|
"quanta": {
|
|
159
164
|
"type": "quantity",
|
|
160
165
|
},
|
|
161
|
-
"direction": {
|
|
162
|
-
|
|
166
|
+
"direction": {
|
|
167
|
+
"type": "sky_coord",
|
|
168
|
+
"Ref": "frame",
|
|
169
|
+
"Ref_map": {
|
|
170
|
+
"AZELGEO": "altaz",
|
|
171
|
+
"ICRS": "icrs",
|
|
172
|
+
"J2000": "fk5",
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
"epoch": {
|
|
176
|
+
"type": "time",
|
|
177
|
+
"Ref": "scale",
|
|
178
|
+
"Ref_map": {
|
|
179
|
+
"UTC": "utc",
|
|
180
|
+
"TAI": "tai",
|
|
181
|
+
},
|
|
182
|
+
},
|
|
163
183
|
"frequency": {
|
|
164
184
|
"type": "spectral_coord",
|
|
165
|
-
"Ref": "
|
|
185
|
+
"Ref": "observer",
|
|
166
186
|
"Ref_map": {
|
|
167
187
|
"REST": "REST",
|
|
168
|
-
"LSRK": "
|
|
169
|
-
"LSRD": "
|
|
188
|
+
"LSRK": "lsrk",
|
|
189
|
+
"LSRD": "lsrd",
|
|
170
190
|
"BARY": "BARY",
|
|
171
191
|
"GEO": "GEO",
|
|
172
192
|
"TOPO": "TOPO",
|
|
173
|
-
|
|
174
|
-
"LGROUP": "LGROUP",
|
|
175
|
-
"CMB": "CMB",
|
|
176
|
-
"Undefined": "Undefined",
|
|
177
|
-
},
|
|
193
|
+
}, # The frames/observer we are not sure if/how to translate to astropy are uppercase
|
|
178
194
|
},
|
|
179
195
|
"position": {
|
|
180
|
-
"type": "
|
|
181
|
-
"Ref": "
|
|
196
|
+
"type": "location",
|
|
197
|
+
"Ref": "frame",
|
|
182
198
|
"Ref_map": {"ITRF": "GRS80"},
|
|
183
199
|
},
|
|
184
|
-
"uvw": {
|
|
200
|
+
"uvw": {
|
|
201
|
+
"type": "uvw",
|
|
202
|
+
"Ref": "frame",
|
|
203
|
+
"Ref_map": {"J2000": "fk5", "APP": "APP"},
|
|
204
|
+
},
|
|
185
205
|
"radialvelocity": {"type": "quantity"},
|
|
186
206
|
}
|
|
187
207
|
|
|
@@ -30,7 +30,7 @@ from ..common import (
|
|
|
30
30
|
_l_m_attr_notes,
|
|
31
31
|
)
|
|
32
32
|
from ...._utils._casacore.tables import extract_table_attributes, open_table_ro
|
|
33
|
-
from
|
|
33
|
+
from xradio._utils.coord_math import _deg_to_rad
|
|
34
34
|
|
|
35
35
|
"""
|
|
36
36
|
def _add_coord_attrs(xds: xr.Dataset, icoords: dict, dir_axes: list) -> xr.Dataset:
|
|
@@ -204,7 +204,7 @@ def _casa_image_to_xds_attrs(img_full_path: str, history: bool = True) -> dict:
|
|
|
204
204
|
if k.startswith("telescope"):
|
|
205
205
|
if k == "telescope":
|
|
206
206
|
telescope["name"] = coord_dict[k]
|
|
207
|
-
|
|
207
|
+
elif k in coord_dict:
|
|
208
208
|
telescope["position"] = coord_dict[k]
|
|
209
209
|
telescope["position"]["ellipsoid"] = telescope["position"]["refer"]
|
|
210
210
|
if telescope["position"]["refer"] == "ITRF":
|
|
@@ -362,7 +362,7 @@ def _convert_direction_system(
|
|
|
362
362
|
'This corresponds to FK5(equinox="J2000") in astropy. '
|
|
363
363
|
"Metadata will be written appropriately"
|
|
364
364
|
)
|
|
365
|
-
return ("FK5", "J2000")
|
|
365
|
+
return ("FK5", "J2000.0")
|
|
366
366
|
elif casa_system == "B1950":
|
|
367
367
|
if verbose:
|
|
368
368
|
logger.info(
|
|
@@ -370,9 +370,9 @@ def _convert_direction_system(
|
|
|
370
370
|
'This corresponds to FK4(equinox="B1950") in astropy. '
|
|
371
371
|
"Metadata will be written appropriately"
|
|
372
372
|
)
|
|
373
|
-
return ("FK4", "B1950")
|
|
373
|
+
return ("FK4", "B1950.0")
|
|
374
374
|
elif casa_system in ("GALACTIC", "ICRS"):
|
|
375
|
-
return (casa_system, None)
|
|
375
|
+
return (casa_system.lower(), None)
|
|
376
376
|
else:
|
|
377
377
|
raise Exception(
|
|
378
378
|
f"astropy does not support frame {casa_system} and this "
|
|
@@ -100,17 +100,18 @@ def _coord_dict_from_xds(xds: xr.Dataset) -> dict:
|
|
|
100
100
|
obsdate["m0"]["value"] = xds.coords["time"].values[0]
|
|
101
101
|
coord["obsdate"] = obsdate
|
|
102
102
|
coord["pointingcenter"] = xds.attrs[_pointing_center].copy()
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
103
|
+
if "position" in xds.attrs["telescope"]:
|
|
104
|
+
telpos = {}
|
|
105
|
+
telpos["refer"] = xds.attrs["telescope"]["position"]["ellipsoid"]
|
|
106
|
+
if xds.attrs["telescope"]["position"]["ellipsoid"] == "GRS80":
|
|
107
|
+
telpos["refer"] = "ITRF"
|
|
108
|
+
for i in range(3):
|
|
109
|
+
telpos[f"m{i}"] = {
|
|
110
|
+
"unit": xds.attrs["telescope"]["position"]["units"][i],
|
|
111
|
+
"value": xds.attrs["telescope"]["position"]["value"][i],
|
|
112
|
+
}
|
|
113
|
+
telpos["type"] = "position"
|
|
114
|
+
coord["telescopeposition"] = telpos
|
|
114
115
|
if "l" in xds.coords:
|
|
115
116
|
coord["direction0"] = _compute_direction_dict(xds)
|
|
116
117
|
else:
|
|
@@ -15,7 +15,7 @@ from ..common import (
|
|
|
15
15
|
_image_type,
|
|
16
16
|
_l_m_attr_notes,
|
|
17
17
|
)
|
|
18
|
-
from
|
|
18
|
+
from xradio._utils.coord_math import _deg_to_rad
|
|
19
19
|
import copy
|
|
20
20
|
import dask
|
|
21
21
|
import dask.array as da
|
|
@@ -166,7 +166,7 @@ def _xds_direction_attrs_from_header(helpers: dict, header) -> dict:
|
|
|
166
166
|
ref_sys = header["RADESYS"]
|
|
167
167
|
ref_eqx = header["EQUINOX"]
|
|
168
168
|
if ref_sys == "FK5" and ref_eqx == 2000:
|
|
169
|
-
ref_eqx = "J2000"
|
|
169
|
+
ref_eqx = "J2000.0"
|
|
170
170
|
helpers["ref_sys"] = ref_sys
|
|
171
171
|
helpers["ref_eqx"] = ref_eqx
|
|
172
172
|
# fits does not support conversion frames
|
|
@@ -237,21 +237,22 @@ def _get_telescope_metadata(helpers: dict, header) -> dict:
|
|
|
237
237
|
# The helpers dict is modified in place. header is not modified
|
|
238
238
|
tel = {}
|
|
239
239
|
tel["name"] = header["TELESCOP"]
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
"
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
240
|
+
if "OBSGEO-x" in header:
|
|
241
|
+
x = header["OBSGEO-X"]
|
|
242
|
+
y = header["OBSGEO-Y"]
|
|
243
|
+
z = header["OBSGEO-Z"]
|
|
244
|
+
xyz = np.array([x, y, z])
|
|
245
|
+
r = np.sqrt(np.sum(xyz * xyz))
|
|
246
|
+
lat = np.arcsin(z / r)
|
|
247
|
+
long = np.arctan2(y, x)
|
|
248
|
+
tel["position"] = {
|
|
249
|
+
"type": "position",
|
|
250
|
+
# I haven't seen a FITS keyword for reference frame of telescope posiiton
|
|
251
|
+
"ellipsoid": "GRS80",
|
|
252
|
+
"units": ["rad", "rad", "m"],
|
|
253
|
+
"value": np.array([long, lat, r]),
|
|
254
|
+
}
|
|
255
|
+
helpers["tel_pos"] = tel["position"]
|
|
255
256
|
return tel
|
|
256
257
|
|
|
257
258
|
|
|
@@ -148,7 +148,9 @@ def write_binary_blob_to_disk(arr, file_path, compressor):
|
|
|
148
148
|
|
|
149
149
|
|
|
150
150
|
def write_to_lustre_chunked(
|
|
151
|
-
file_path,
|
|
151
|
+
file_path,
|
|
152
|
+
compressed_arr,
|
|
153
|
+
chunk_size=1024 * 1024 * 128,
|
|
152
154
|
): # 128 MiB chunks
|
|
153
155
|
"""
|
|
154
156
|
Writes compressed data to a Lustre file path with chunking.
|
|
@@ -158,10 +160,18 @@ def write_to_lustre_chunked(
|
|
|
158
160
|
compressed_arr: Compressed data array to write.
|
|
159
161
|
chunk_size: Size of each data chunk in bytes (default: 128 MiB).
|
|
160
162
|
"""
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
163
|
+
fs, items = _get_file_system_and_items(file_path.rsplit("/", 1)[0])
|
|
164
|
+
|
|
165
|
+
if isinstance(fs, s3fs.core.S3FileSystem):
|
|
166
|
+
with fs.open(file_path, "wb") as f:
|
|
167
|
+
for i in range(0, len(compressed_arr), chunk_size):
|
|
168
|
+
chunk = compressed_arr[i : i + chunk_size]
|
|
169
|
+
f.write(chunk)
|
|
170
|
+
else:
|
|
171
|
+
with open(file_path, "wb") as f:
|
|
172
|
+
for i in range(0, len(compressed_arr), chunk_size):
|
|
173
|
+
chunk = compressed_arr[i : i + chunk_size]
|
|
174
|
+
f.write(chunk)
|
|
165
175
|
|
|
166
176
|
|
|
167
177
|
def read_binary_blob_from_disk(file_path, compressor, dtype=np.float64):
|
|
@@ -237,6 +247,7 @@ def write_json_file(data, file_path):
|
|
|
237
247
|
Returns:
|
|
238
248
|
- None
|
|
239
249
|
"""
|
|
250
|
+
|
|
240
251
|
with open(file_path, "w") as file:
|
|
241
252
|
json.dump(
|
|
242
253
|
data,
|
|
@@ -385,13 +396,19 @@ def write_chunk(img_xds, meta, parallel_dims_chunk_id, compressor, image_file):
|
|
|
385
396
|
else:
|
|
386
397
|
array = img_xds[data_variable_name].values
|
|
387
398
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
shape=meta["shape"],
|
|
392
|
-
chunks=meta["chunks"],
|
|
393
|
-
dtype=meta["dtype"],
|
|
399
|
+
write_binary_blob_to_disk(
|
|
400
|
+
array,
|
|
401
|
+
file_path=os.path.join(image_file, data_variable_name, chunk_name),
|
|
394
402
|
compressor=compressor,
|
|
395
403
|
)
|
|
396
404
|
|
|
397
|
-
|
|
405
|
+
# z_chunk = zarr.open(
|
|
406
|
+
# os.path.join(image_file, data_variable_name, chunk_name),
|
|
407
|
+
# mode="a",
|
|
408
|
+
# shape=meta["shape"],
|
|
409
|
+
# chunks=meta["chunks"],
|
|
410
|
+
# dtype=meta["dtype"],
|
|
411
|
+
# compressor=compressor,
|
|
412
|
+
# )
|
|
413
|
+
|
|
414
|
+
# return z_chunk
|
{xradio-0.0.41/src/xradio/correlated_data → xradio-0.0.42/src/xradio/measurement_set}/__init__.py
RENAMED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
from .processing_set import ProcessingSet
|
|
2
2
|
from .open_processing_set import open_processing_set
|
|
3
|
-
from .load_processing_set import load_processing_set
|
|
3
|
+
from .load_processing_set import load_processing_set, ProcessingSetIterator
|
|
4
4
|
from .convert_msv2_to_processing_set import convert_msv2_to_processing_set
|
|
5
|
+
from .measurement_set_xds import MeasurementSetXds
|
|
5
6
|
|
|
6
|
-
from .schema import VisibilityXds
|
|
7
|
+
from .schema import SpectrumXds, VisibilityXds
|
|
7
8
|
|
|
8
9
|
__all__ = [
|
|
10
|
+
"ProcessingSet",
|
|
11
|
+
"MeasurementSetXds",
|
|
9
12
|
"open_processing_set",
|
|
10
13
|
"load_processing_set",
|
|
14
|
+
"ProcessingSetIterator",
|
|
11
15
|
"convert_msv2_to_processing_set",
|
|
16
|
+
"SpectrumXds",
|
|
12
17
|
"VisibilityXds",
|
|
13
|
-
"PointingXds",
|
|
14
|
-
"AntennaXds",
|
|
15
18
|
]
|
|
@@ -12,7 +12,7 @@ from .read_main_table import get_partition_ids, redim_id_data_vars, rename_vars
|
|
|
12
12
|
from .read import add_units_measures, convert_casacore_time, extract_table_attributes
|
|
13
13
|
from .write import revert_time
|
|
14
14
|
from .table_query import open_query, open_table_ro
|
|
15
|
-
from xradio.
|
|
15
|
+
from xradio.measurement_set._utils._ms._tables.read_main_table import (
|
|
16
16
|
get_baselines,
|
|
17
17
|
get_baseline_indices,
|
|
18
18
|
)
|
|
@@ -12,7 +12,7 @@ import astropy.units
|
|
|
12
12
|
from casacore import tables
|
|
13
13
|
|
|
14
14
|
from .table_query import open_query, open_table_ro
|
|
15
|
-
from
|
|
15
|
+
from xradio._utils.list_and_array import get_pad_value
|
|
16
16
|
|
|
17
17
|
CASACORE_TO_PD_TIME_CORRECTION = 3_506_716_800.0
|
|
18
18
|
SECS_IN_DAY = 86400
|