xradio 0.0.27__py3-none-any.whl → 0.0.29__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. xradio/__init__.py +5 -4
  2. xradio/_utils/array.py +90 -0
  3. xradio/_utils/zarr/common.py +48 -3
  4. xradio/image/_util/_fits/xds_from_fits.py +10 -5
  5. xradio/image/_util/_zarr/zarr_low_level.py +27 -24
  6. xradio/image/_util/common.py +4 -1
  7. xradio/image/_util/zarr.py +4 -1
  8. xradio/schema/__init__.py +24 -6
  9. xradio/schema/bases.py +440 -2
  10. xradio/schema/check.py +96 -55
  11. xradio/schema/dataclass.py +123 -27
  12. xradio/schema/metamodel.py +21 -4
  13. xradio/schema/typing.py +33 -18
  14. xradio/vis/__init__.py +5 -2
  15. xradio/vis/_processing_set.py +30 -9
  16. xradio/vis/_vis_utils/_ms/_tables/create_field_and_source_xds.py +710 -0
  17. xradio/vis/_vis_utils/_ms/_tables/load.py +23 -10
  18. xradio/vis/_vis_utils/_ms/_tables/load_main_table.py +145 -64
  19. xradio/vis/_vis_utils/_ms/_tables/read.py +782 -156
  20. xradio/vis/_vis_utils/_ms/_tables/read_main_table.py +176 -45
  21. xradio/vis/_vis_utils/_ms/_tables/read_subtables.py +79 -28
  22. xradio/vis/_vis_utils/_ms/_tables/write.py +102 -45
  23. xradio/vis/_vis_utils/_ms/_tables/write_exp_api.py +127 -65
  24. xradio/vis/_vis_utils/_ms/chunks.py +58 -21
  25. xradio/vis/_vis_utils/_ms/conversion.py +536 -67
  26. xradio/vis/_vis_utils/_ms/descr.py +52 -20
  27. xradio/vis/_vis_utils/_ms/msv2_to_msv4_meta.py +70 -35
  28. xradio/vis/_vis_utils/_ms/msv4_infos.py +0 -59
  29. xradio/vis/_vis_utils/_ms/msv4_sub_xdss.py +76 -9
  30. xradio/vis/_vis_utils/_ms/optimised_functions.py +0 -46
  31. xradio/vis/_vis_utils/_ms/partition_queries.py +308 -119
  32. xradio/vis/_vis_utils/_ms/partitions.py +82 -25
  33. xradio/vis/_vis_utils/_ms/subtables.py +32 -14
  34. xradio/vis/_vis_utils/_utils/partition_attrs.py +30 -11
  35. xradio/vis/_vis_utils/_utils/xds_helper.py +136 -45
  36. xradio/vis/_vis_utils/_zarr/read.py +60 -22
  37. xradio/vis/_vis_utils/_zarr/write.py +83 -9
  38. xradio/vis/_vis_utils/ms.py +48 -29
  39. xradio/vis/_vis_utils/zarr.py +44 -20
  40. xradio/vis/convert_msv2_to_processing_set.py +106 -32
  41. xradio/vis/load_processing_set.py +38 -61
  42. xradio/vis/read_processing_set.py +62 -96
  43. xradio/vis/schema.py +687 -0
  44. xradio/vis/vis_io.py +75 -43
  45. {xradio-0.0.27.dist-info → xradio-0.0.29.dist-info}/LICENSE.txt +6 -1
  46. {xradio-0.0.27.dist-info → xradio-0.0.29.dist-info}/METADATA +10 -5
  47. xradio-0.0.29.dist-info/RECORD +73 -0
  48. {xradio-0.0.27.dist-info → xradio-0.0.29.dist-info}/WHEEL +1 -1
  49. xradio/vis/model.py +0 -497
  50. xradio-0.0.27.dist-info/RECORD +0 -71
  51. {xradio-0.0.27.dist-info → xradio-0.0.29.dist-info}/top_level.txt +0 -0
@@ -2,13 +2,13 @@ import os
2
2
  import xarray as xr
3
3
  from ._processing_set import processing_set
4
4
  import graphviper.utils.logger as logger
5
- from xradio._utils.zarr.common import _open_dataset
5
+ from xradio._utils.zarr.common import _open_dataset, _get_ms_stores_and_file_system
6
6
  import s3fs
7
- from botocore.exceptions import NoCredentialsError
8
7
 
9
8
 
10
9
  def read_processing_set(
11
- ps_store: str, intents: list = None, fields: str = None
10
+ ps_store: str,
11
+ intents: list = None,
12
12
  ) -> processing_set:
13
13
  """Creates a lazy representation of a Processing Set (only meta-data is loaded into memory).
14
14
 
@@ -19,119 +19,85 @@ def read_processing_set(
19
19
  intents : list, optional
20
20
  A list of the intents to be read for example ['OBSERVE_TARGET#ON_SOURCE']. The intents in a processing set can be seem by calling processing_set.summary().
21
21
  By default None, which will read all intents.
22
- fields : str, optional
23
- The list of field names that will be read, by default None which will read all fields.
24
22
 
25
23
  Returns
26
24
  -------
27
25
  processing_set
28
26
  Lazy representation of processing set (data is represented by Dask.arrays).
29
27
  """
30
- s3 = None
31
- ps_store_is_s3dir = None
28
+ file_system, ms_store_list = _get_ms_stores_and_file_system(ps_store)
32
29
 
33
- if os.path.isdir(ps_store):
34
- ps_store_is_s3dir = False
35
- # default to assuming the data are accessible on local file system
36
- items = os.listdir(ps_store)
30
+ ps = processing_set()
31
+ data_group = "base"
32
+ for ms_name in ms_store_list:
33
+ # try:
34
+ ms_store = os.path.join(ps_store, ms_name)
35
+ ms_main_store = os.path.join(ms_store, "MAIN")
37
36
 
38
- elif ps_store.startswith("s3"):
39
- # only if not found locally, check if dealing with an S3 bucket URL
40
- ps_store_is_s3dir = True
41
- if not ps_store.endswith("/"):
42
- # just for consistency, as there is no os.path equivalent in s3fs
43
- ps_store = ps_store + "/"
37
+ xds = _open_dataset(ms_main_store, file_system)
38
+ data_groups = xds.attrs["data_groups"]
44
39
 
45
- try:
46
- # initialize the S3 "file system", first attempting to use pre-configured credentials
47
- s3 = s3fs.S3FileSystem(anon=False, requester_pays=False)
40
+ if (intents is None) or (xds.attrs["intent"] in intents):
41
+ sub_xds_dict, field_and_source_xds_dict = _read_sub_xds(
42
+ ms_store, file_system=file_system, data_groups=data_groups
43
+ )
48
44
 
49
- items = [bd.split(sep="/")[-1] for bd in s3.listdir(ps_store, detail=False)]
45
+ xds.attrs = {
46
+ **xds.attrs,
47
+ **sub_xds_dict,
48
+ }
49
+
50
+ for data_group_name, data_group_vals in data_groups.items():
51
+ if "visibility" in data_group_vals:
52
+ xds[data_group_vals["visibility"]].attrs["field_and_source_xds"] = (
53
+ field_and_source_xds_dict[data_group_name]
54
+ )
55
+ elif "spectrum" in data_group_vals:
56
+ xds[data_group_vals["spectrum"]].attrs["field_and_source_xds"] = (
57
+ field_and_source_xds_dict[data_group_name]
58
+ )
59
+
60
+ ps[ms_name] = xds
61
+ # except Exception as e:
62
+ # logger.warning(f"Could not read {ms_name} due to {e}")
63
+ # continue
50
64
 
51
- except (NoCredentialsError, PermissionError) as e:
52
- # only public, read-only buckets will be accessible
53
- # we will want to add messaging and error handling here
54
- s3 = s3fs.S3FileSystem(anon=True)
65
+ return ps
55
66
 
56
- items = [bd.split(sep="/")[-1] for bd in s3.listdir(ps_store, detail=False)]
57
67
 
58
- else:
59
- raise (
60
- FileNotFoundError,
61
- f"Could not find {ps_store} either locally or in the cloud.",
62
- )
68
+ def _read_sub_xds(ms_store, file_system, data_groups, load=False):
69
+ sub_xds_dict = {}
70
+ field_and_source_xds_dict = {}
63
71
 
64
- ms_xds = xr.Dataset()
65
- ps = processing_set()
66
- data_group = "base"
67
- for ms_dir_name in items:
68
- if "ddi" in ms_dir_name:
69
- if ps_store_is_s3dir:
70
- store_path = ps_store + ms_dir_name
71
- store_path_main = store_path + "/MAIN"
72
- else:
73
- store_path_main = os.path.join(ps_store, ms_dir_name, "MAIN")
74
- store_path = os.path.split(store_path_main)[0]
75
- if s3 is not None:
76
- xds = _open_dataset(store_path_main, s3=s3)
77
- else:
78
- xds = _open_dataset(store_path_main)
79
-
80
- if (intents is None) or (xds.attrs["intent"] in intents):
81
- data_name = _get_data_name(xds, data_group)
82
-
83
- if (fields is None) or (
84
- xds[data_name].attrs["field_info"]["name"] in fields
85
- ):
86
- if s3 is not None:
87
- xds.attrs = {
88
- **xds.attrs,
89
- **_read_sub_xds(store_path, s3=s3),
90
- }
91
- ps[ms_dir_name] = xds
92
- else:
93
- xds.attrs = {
94
- **xds.attrs,
95
- **_read_sub_xds(store_path),
96
- }
97
- ps[ms_dir_name] = xds
72
+ xds_names = {
73
+ "ANTENNA": "antenna_xds",
74
+ "WEATHER": "weather_xds",
75
+ "POINTING": "pointing_xds",
76
+ }
98
77
 
99
- return ps
78
+ if isinstance(file_system, s3fs.core.S3FileSystem):
79
+ file_names = [
80
+ bd.split(sep="/")[-1] for bd in file_system.listdir(ms_store, detail=False)
81
+ ]
82
+ else:
83
+ file_names = file_system.listdir(ms_store)
84
+ file_names = [item for item in file_names if not item.startswith(".")]
100
85
 
86
+ file_names.remove("MAIN")
101
87
 
102
- def _read_sub_xds(ms_store, load=False, **kwargs):
103
- sub_xds_dict = {}
88
+ field_dict = {"FIELD_AND_SOURCE_" + key.upper(): key for key in data_groups.keys()}
104
89
 
105
- sub_xds = {
106
- "antenna_xds": "ANTENNA",
107
- }
108
- for sub_xds_key, sub_xds_name in sub_xds.items():
109
- if "s3" in kwargs.keys():
110
- joined_store = ms_store + "/" + sub_xds_name
111
- sub_xds_dict[sub_xds_key] = _open_dataset(
112
- joined_store, load=load, s3=kwargs["s3"]
113
- )
90
+ # field_and_source_xds_name_start = "FIELD"
91
+ for n in file_names:
92
+ xds = _open_dataset(
93
+ os.path.join(ms_store, n), load=load, file_system=file_system
94
+ )
95
+ if n in field_dict.keys():
96
+ field_and_source_xds_dict[field_dict[n]] = xds
114
97
  else:
115
- sub_xds_dict[sub_xds_key] = _open_dataset(
116
- os.path.join(ms_store, sub_xds_name), load=load
117
- )
98
+ sub_xds_dict[xds_names[n]] = xds
118
99
 
119
- optional_sub_xds = {
120
- "weather_xds": "WEATHER",
121
- "pointing_xds": "POINTING",
122
- }
123
- for sub_xds_key, sub_xds_name in optional_sub_xds.items():
124
- sub_xds_path = os.path.join(ms_store, sub_xds_name)
125
- if os.path.isdir(sub_xds_path):
126
- sub_xds_dict[sub_xds_key] = _open_dataset(sub_xds_path, load=load)
127
- elif "s3" in kwargs.keys():
128
- joined_store = ms_store + "/" + sub_xds_name
129
- if kwargs["s3"].isdir(joined_store):
130
- sub_xds_dict[sub_xds_key] = _open_dataset(
131
- joined_store, load=load, s3=kwargs["s3"]
132
- )
133
-
134
- return sub_xds_dict
100
+ return sub_xds_dict, field_and_source_xds_dict
135
101
 
136
102
 
137
103
  def _get_data_name(xds, data_group):