tabsim 0.0.4__tar.gz → 0.0.6__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 (54) hide show
  1. {tabsim-0.0.4 → tabsim-0.0.6}/PKG-INFO +4 -4
  2. {tabsim-0.0.4 → tabsim-0.0.6}/pyproject.toml +5 -4
  3. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/config.py +37 -8
  4. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/dask/coordinates.py +34 -26
  5. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/dask/interferometry.py +35 -27
  6. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/dask/observation.py +59 -31
  7. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/data/config/sim_config_base.yaml +2 -0
  8. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/jax/coordinates.py +62 -37
  9. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/jax/interferometry.py +10 -38
  10. tabsim-0.0.6/tabsim/jax/utils.py +11 -0
  11. tabsim-0.0.6/tabsim/read_ms.py +137 -0
  12. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/scripts/sim_vis.py +4 -0
  13. tabsim-0.0.6/tabsim/scripts/write_config_from_ms.py +40 -0
  14. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/write.py +57 -23
  15. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim.egg-info/PKG-INFO +4 -4
  16. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim.egg-info/SOURCES.txt +2 -0
  17. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim.egg-info/entry_points.txt +1 -0
  18. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim.egg-info/requires.txt +2 -2
  19. tabsim-0.0.4/tabsim/jax/utils.py +0 -90
  20. {tabsim-0.0.4 → tabsim-0.0.6}/LICENSE +0 -0
  21. {tabsim-0.0.4 → tabsim-0.0.6}/README.md +0 -0
  22. {tabsim-0.0.4 → tabsim-0.0.6}/docs/conf.py +0 -0
  23. {tabsim-0.0.4 → tabsim-0.0.6}/setup.cfg +0 -0
  24. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/__init__.py +0 -0
  25. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/dask/__init__.py +0 -0
  26. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/dask/extras.py +0 -0
  27. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/data/__init__.py +0 -0
  28. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/data/config/tab_config_base.yaml +0 -0
  29. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/data/rfi/norad_satellite.rfimodel +0 -0
  30. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/data/rfi/satellite.ole +0 -0
  31. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/data/rfi/satellite.rfimodel +0 -0
  32. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/data/rfi/stationary.loc +0 -0
  33. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/data/rfi/stationary.rfimodel +0 -0
  34. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/data/rfi/tles/2023-02-21-J8HE0T.json +0 -0
  35. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/data/rfi/tles/2023-02-21-navstar.json +0 -0
  36. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/data/sky/calibrator.skymodel +0 -0
  37. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/data/telescopes/EDA2.itrf.txt +0 -0
  38. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/data/telescopes/MWA.itrf.txt +0 -0
  39. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/data/telescopes/MeerKAT.itrf.txt +0 -0
  40. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/data/telescopes/_telescopes.yaml +0 -0
  41. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/jax/__init__.py +0 -0
  42. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/plot.py +0 -0
  43. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/scripts/__init__.py +0 -0
  44. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/scripts/ast_region.py +0 -0
  45. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/scripts/flag_data.py +0 -0
  46. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/scripts/tle_sat_region.py +0 -0
  47. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/sky.py +0 -0
  48. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/tle.py +0 -0
  49. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim/tools.py +0 -0
  50. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim.egg-info/dependency_links.txt +0 -0
  51. {tabsim-0.0.4 → tabsim-0.0.6}/tabsim.egg-info/top_level.txt +0 -0
  52. {tabsim-0.0.4 → tabsim-0.0.6}/tests/test_basic.py +0 -0
  53. {tabsim-0.0.4 → tabsim-0.0.6}/tests/test_sim-vis.py +0 -0
  54. {tabsim-0.0.4 → tabsim-0.0.6}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tabsim
3
- Version: 0.0.4
3
+ Version: 0.0.6
4
4
  Summary: Trajectory-based Radio Frequency Interference (RFI) simulations for radio interferometeric data.
5
5
  Author-email: Chris Finlay <christopher.finlay@epfl.ch>
6
6
  Maintainer-email: Chris Finlay <christopher.finlay@epfl.ch>
@@ -680,11 +680,11 @@ License: GNU GENERAL PUBLIC LICENSE
680
680
  <https://www.gnu.org/licenses/why-not-lgpl.html>.
681
681
 
682
682
  Project-URL: Repository, https://github.com/chrisfinlay/tab-sim.git
683
- Requires-Python: <3.13,>=3.9
683
+ Requires-Python: >=3.9
684
684
  Description-Content-Type: text/markdown
685
685
  License-File: LICENSE
686
686
  Requires-Dist: jax
687
- Requires-Dist: dask<=2024.10.0
687
+ Requires-Dist: dask
688
688
  Requires-Dist: xarray
689
689
  Requires-Dist: zarr<3.0.0
690
690
  Requires-Dist: dask-ms>=0.2.21
@@ -694,7 +694,7 @@ Requires-Dist: matplotlib
694
694
  Requires-Dist: astropy
695
695
  Requires-Dist: spacetrack
696
696
  Requires-Dist: skyfield
697
- Requires-Dist: numpy<2.0.0
697
+ Requires-Dist: numpy
698
698
  Provides-Extra: gpu
699
699
  Requires-Dist: jax[cuda12]; extra == "gpu"
700
700
  Provides-Extra: sat
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "tabsim"
8
- version = "0.0.4"
8
+ version = "0.0.6"
9
9
  license = {file = "LICENSE"}
10
10
  readme = "README.md"
11
11
  # dynamic = ["version", "readme"]
@@ -17,11 +17,11 @@ maintainers = [
17
17
  ]
18
18
  description = "Trajectory-based Radio Frequency Interference (RFI) simulations for radio interferometeric data."
19
19
 
20
- requires-python = ">=3.9,<3.13"
20
+ requires-python = ">=3.9"
21
21
  dependencies = [
22
- "jax", "dask<=2024.10.0", "xarray", "zarr<3.0.0",
22
+ "jax", "dask", "xarray", "zarr<3.0.0",
23
23
  "dask-ms>=0.2.21", "scipy", "tqdm", "matplotlib",
24
- "astropy", "spacetrack", "skyfield", "numpy<2.0.0",
24
+ "astropy", "spacetrack", "skyfield", "numpy",
25
25
  ]
26
26
 
27
27
  [project.optional-dependencies]
@@ -51,3 +51,4 @@ tle-region = "tabsim.scripts.tle_sat_region:main"
51
51
  ast-region = "tabsim.scripts.ast_region:main"
52
52
  flag-data = "tabsim.scripts.flag_data:main"
53
53
  sim-vis = "tabsim.scripts.sim_vis:main"
54
+ write-config = "tabsim.scripts.write_config_from_ms:main"
@@ -18,7 +18,6 @@ from astropy.time import Time
18
18
 
19
19
  from tabsim.dask.observation import Observation
20
20
  from tabsim.sky import generate_random_sky
21
- from tabsim.plot import plot_uv, plot_src_alt, plot_angular_seps
22
21
  from tabsim.write import write_ms, mk_obs_name, mk_obs_dir
23
22
  from tabsim.jax.coordinates import calculate_fringe_frequency, jd_to_mjd
24
23
  from tabsim.tle import get_visible_satellite_tles, id_generator
@@ -256,9 +255,7 @@ def load_obs(obs_spec: dict) -> Observation:
256
255
  start_time_mjd = jd_to_mjd(obs_["start_time_jd"])
257
256
  elif obs_["start_time_isot"]:
258
257
 
259
- start_time_mjd = jd_to_mjd(
260
- Time(obs_["start_time_isot"], format="isot", scale="ut1").jd
261
- )
258
+ start_time_mjd = jd_to_mjd(Time(obs_["start_time_isot"], format="isot").jd)
262
259
  elif obs_["start_time_lha"] is not None:
263
260
  gsa = obs_["start_time_lha"] - tel_["longitude"] + obs_["ra"]
264
261
  start_time_mjd = MJD0 + (gsa / 360)
@@ -668,6 +665,8 @@ def add_gains(obs: Observation, obs_spec: dict) -> None:
668
665
 
669
666
  def plot_diagnostics(obs: Observation, obs_spec: dict, save_path: str) -> None:
670
667
 
668
+ from tabsim.plot import plot_uv, plot_src_alt, plot_angular_seps
669
+
671
670
  diag_ = obs_spec["diagnostics"]
672
671
 
673
672
  if diag_["src_alt"]:
@@ -808,11 +807,14 @@ def print_fringe_freq_sat(obs: Observation):
808
807
  for i in range(obs.n_rfi_satellite)
809
808
  ]
810
809
  fringe_freq = [calculate_fringe_frequency(**f_params) for f_params in fringe_params]
810
+ noise_std = obs.noise_std.mean().compute()
811
+ if noise_std == 0:
812
+ noise_std = 1.0
811
813
  f_sample = (
812
814
  np.pi
813
815
  * np.max(np.abs(fringe_freq))
814
816
  * np.max(obs.rfi_satellite_A_app)
815
- / np.sqrt(6 * obs.noise_std.mean()).compute()
817
+ / np.sqrt(6 * noise_std)
816
818
  )
817
819
  n_int = int(np.ceil(obs.int_time * f_sample))
818
820
 
@@ -843,11 +845,14 @@ def print_fringe_freq_tle_sat(obs: Observation):
843
845
  for i in range(obs.n_rfi_tle_satellite)
844
846
  ]
845
847
  fringe_freq = [calculate_fringe_frequency(**f_params) for f_params in fringe_params]
848
+ noise_std = obs.noise_std.mean().compute()
849
+ if noise_std == 0:
850
+ noise_std = 1.0
846
851
  f_sample = (
847
852
  np.pi
848
853
  * np.max(np.abs(fringe_freq))
849
854
  * np.max(obs.rfi_tle_satellite_A_app)
850
- / np.sqrt(6 * obs.noise_std.mean()).compute()
855
+ / np.sqrt(6 * noise_std)
851
856
  )
852
857
  n_int = int(np.ceil(obs.int_time * f_sample))
853
858
 
@@ -933,9 +938,26 @@ def run_sim_config(
933
938
  print()
934
939
  print(f"Writing data to : {save_path}")
935
940
 
936
- plot_diagnostics(obs, obs_spec, save_path)
941
+ plot_cond = np.array(
942
+ [
943
+ obs_spec["diagnostics"]["rfi_seps"],
944
+ obs_spec["diagnostics"]["src_alt"],
945
+ obs_spec["diagnostics"]["uv_cov"],
946
+ ]
947
+ )
948
+ if np.any(plot_cond):
949
+ plot_diagnostics(obs, obs_spec, save_path)
950
+ else:
951
+ print("\nNo diagnostic plots.")
952
+
937
953
  save_data(obs, obs_spec, zarr_path, ms_path)
938
954
 
955
+ if obs_spec["output"]["accumulate_ms"] is not None:
956
+ from tabsim.write import add_to_ms
957
+
958
+ xds = xr.open_zarr(zarr_path)
959
+ add_to_ms(xds, obs_spec["output"]["accumulate_ms"])
960
+
939
961
  end = datetime.now()
940
962
  print()
941
963
  print(f"Total simulation time : {end - start}")
@@ -947,4 +969,11 @@ def run_sim_config(
947
969
  os.remove(log_path)
948
970
  sys.stdout = backup
949
971
 
950
- return obs, save_path
972
+ if (
973
+ not obs_spec["output"]["keep_sim"]
974
+ and obs_spec["output"]["accumulate_ms"] is not None
975
+ ):
976
+ shutil.rmtree(save_path)
977
+ return obs, save_path
978
+ else:
979
+ return obs, save_path
@@ -1,5 +1,7 @@
1
1
  from tabsim.jax import coordinates as coord
2
2
 
3
+ from jax import jit
4
+
3
5
  import dask.array as da
4
6
  from dask.delayed import delayed
5
7
  from dask.array.core import Array
@@ -22,7 +24,7 @@ def radec_to_lmn(ra: Array, dec: Array, phase_centre: Array) -> Array:
22
24
  {
23
25
  "lmn": (
24
26
  ["src", "lmn_space"],
25
- da.zeros(
27
+ da.zeros( # type: ignore
26
28
  shape=(n_src, 3),
27
29
  chunks=(src_chunk, 3),
28
30
  dtype=float,
@@ -32,7 +34,7 @@ def radec_to_lmn(ra: Array, dec: Array, phase_centre: Array) -> Array:
32
34
  )
33
35
 
34
36
  def _radec_to_lmn(ds):
35
- lmn = delayed(coord.radec_to_lmn, pure=True)(
37
+ lmn = delayed(jit(coord.radec_to_lmn), pure=True)(
36
38
  ds.ra.data, ds.dec.data, ds.phase_centre.data
37
39
  ).compute()
38
40
  ds_out = xr.Dataset({"lmn": (["src", "lmn_space"], lmn)})
@@ -61,7 +63,7 @@ def radec_to_XYZ(ra: Array, dec: Array) -> Array:
61
63
  {
62
64
  "XYZ": (
63
65
  ["src", "space"],
64
- da.zeros(
66
+ da.zeros( # type: ignore
65
67
  shape=(n_src, 3),
66
68
  chunks=(src_chunk, 3),
67
69
  dtype=float,
@@ -71,7 +73,9 @@ def radec_to_XYZ(ra: Array, dec: Array) -> Array:
71
73
  )
72
74
 
73
75
  def _radec_to_XYZ(ds):
74
- XYZ = delayed(coord.radec_to_XYZ, pure=True)(ds.ra.data, ds.dec.data).compute()
76
+ XYZ = delayed(jit(coord.radec_to_XYZ), pure=True)(
77
+ ds.ra.data, ds.dec.data
78
+ ).compute()
75
79
  ds_out = xr.Dataset({"XYZ": (["src", "space"], XYZ)})
76
80
  return ds_out
77
81
 
@@ -98,7 +102,7 @@ def ENU_to_GEO(geo_ref: Array, ENU: Array) -> Array:
98
102
  {
99
103
  "GEO": (
100
104
  ["bl", "space"],
101
- da.zeros(
105
+ da.zeros( # type: ignore
102
106
  shape=(n_ant, 3),
103
107
  chunks=(ant_chunk, 3),
104
108
  dtype=float,
@@ -108,7 +112,7 @@ def ENU_to_GEO(geo_ref: Array, ENU: Array) -> Array:
108
112
  )
109
113
 
110
114
  def _ENU_to_GEO(ds):
111
- GEO = delayed(coord.ENU_to_GEO, pure=True)(
115
+ GEO = delayed(jit(coord.ENU_to_GEO), pure=True)(
112
116
  ds.geo_ref.data, ds.ENU.data
113
117
  ).compute()
114
118
  ds_out = xr.Dataset({"GEO": (["ant", "space"], GEO)})
@@ -137,7 +141,7 @@ def GEO_to_XYZ(geo: Array, times: Array) -> Array:
137
141
  {
138
142
  "XYZ": (
139
143
  ["time", "space"],
140
- da.zeros(
144
+ da.zeros( # type: ignore
141
145
  shape=(n_time, 3),
142
146
  chunks=(time_chunk, 3),
143
147
  dtype=float,
@@ -147,7 +151,9 @@ def GEO_to_XYZ(geo: Array, times: Array) -> Array:
147
151
  )
148
152
 
149
153
  def _GEO_to_XYZ(ds):
150
- XYZ = delayed(coord.GEO_to_XYZ, pure=True)(ds.geo.data, ds.times.data).compute()
154
+ XYZ = delayed(jit(coord.GEO_to_XYZ), pure=True)(
155
+ ds.geo.data, ds.times.data
156
+ ).compute()
151
157
  ds_out = xr.Dataset({"XYZ": (["time", "space"], XYZ)})
152
158
  return ds_out
153
159
 
@@ -175,7 +181,7 @@ def GEO_to_XYZ_vmap0(geo: Array, times: Array) -> Array:
175
181
  {
176
182
  "XYZ": (
177
183
  ["src", "time", "space"],
178
- da.zeros(
184
+ da.zeros( # type: ignore
179
185
  shape=(n_src, n_time, 3),
180
186
  chunks=(src_chunk, time_chunk, 3),
181
187
  dtype=float,
@@ -185,7 +191,7 @@ def GEO_to_XYZ_vmap0(geo: Array, times: Array) -> Array:
185
191
  )
186
192
 
187
193
  def _GEO_to_XYZ(ds):
188
- XYZ = delayed(coord.GEO_to_XYZ_vmap0, pure=True)(
194
+ XYZ = delayed(jit(coord.GEO_to_XYZ_vmap0), pure=True)(
189
195
  ds.geo.data, ds.times.data
190
196
  ).compute()
191
197
  ds_out = xr.Dataset({"XYZ": (["src", "time", "space"], XYZ)})
@@ -214,7 +220,7 @@ def GEO_to_XYZ_vmap1(geo: Array, times: Array) -> Array:
214
220
  {
215
221
  "XYZ": (
216
222
  ["time", "ant", "space"],
217
- da.zeros(
223
+ da.zeros( # type: ignore
218
224
  shape=(n_time, n_ant, 3),
219
225
  chunks=(time_chunk, ant_chunk, 3),
220
226
  dtype=float,
@@ -224,7 +230,7 @@ def GEO_to_XYZ_vmap1(geo: Array, times: Array) -> Array:
224
230
  )
225
231
 
226
232
  def _GEO_to_XYZ(ds):
227
- XYZ = delayed(coord.GEO_to_XYZ_vmap1, pure=True)(
233
+ XYZ = delayed(jit(coord.GEO_to_XYZ_vmap1), pure=True)(
228
234
  ds.geo.data, ds.times.data
229
235
  ).compute()
230
236
  ds_out = xr.Dataset({"XYZ": (["time", "ant", "space"], XYZ)})
@@ -255,7 +261,7 @@ def ITRF_to_XYZ(itrf: Array, gsa: Array) -> Array:
255
261
  {
256
262
  "xyz": (
257
263
  ["time", "ant", "space"],
258
- da.zeros(
264
+ da.zeros( # type: ignore
259
265
  shape=(n_time, n_ant, 3),
260
266
  chunks=(time_chunk, ant_chunk, 3),
261
267
  dtype=float,
@@ -265,7 +271,9 @@ def ITRF_to_XYZ(itrf: Array, gsa: Array) -> Array:
265
271
  )
266
272
 
267
273
  def _ITRF_to_XYZ(ds):
268
- XYZ = delayed(coord.itrf_to_xyz, pure=True)(ds.itrf.data, ds.gsa.data).compute()
274
+ XYZ = delayed(jit(coord.itrf_to_xyz), pure=True)(
275
+ ds.itrf.data, ds.gsa.data
276
+ ).compute()
269
277
  ds_out = xr.Dataset({"xyz": (["time", "ant", "space"], XYZ)})
270
278
  return ds_out
271
279
 
@@ -294,7 +302,7 @@ def ENU_to_ITRF(ENU: Array, lat: Array, lon: Array, el: Array) -> Array:
294
302
  {
295
303
  "ITRF": (
296
304
  ["ant", "space"],
297
- da.zeros(
305
+ da.zeros( # type: ignore
298
306
  shape=(n_ant, 3),
299
307
  chunks=(ant_chunk, 3),
300
308
  dtype=float,
@@ -304,7 +312,7 @@ def ENU_to_ITRF(ENU: Array, lat: Array, lon: Array, el: Array) -> Array:
304
312
  )
305
313
 
306
314
  def _ENU_to_ITRF(ds):
307
- ITRF = delayed(coord.enu_to_itrf, pure=True)(
315
+ ITRF = delayed(jit(coord.enu_to_itrf), pure=True)(
308
316
  ds.ENU.data,
309
317
  ds.lat.data,
310
318
  ds.lon.data,
@@ -335,8 +343,8 @@ def ITRF_to_UVW(
335
343
  input = xr.Dataset(
336
344
  {
337
345
  "itrf": (["ant", "space"], itrf),
338
- "h0": (["time"], da.atleast_1d(h0)),
339
- "dec": (["cel_space_1"], da.atleast_1d(dec)),
346
+ "h0": (["time"], da.atleast_1d(h0)), # type: ignore
347
+ "dec": (["cel_space_1"], da.atleast_1d(dec)), # type: ignore
340
348
  }
341
349
  )
342
350
 
@@ -344,7 +352,7 @@ def ITRF_to_UVW(
344
352
  {
345
353
  "uvw": (
346
354
  ["time", "ant", "space"],
347
- da.zeros(
355
+ da.zeros( # type: ignore
348
356
  shape=(n_time, n_ant, 3),
349
357
  chunks=(time_chunk, ant_chunk, 3),
350
358
  dtype=float,
@@ -354,7 +362,7 @@ def ITRF_to_UVW(
354
362
  )
355
363
 
356
364
  def _ITRF_to_UVW(ds):
357
- uvw = delayed(coord.itrf_to_uvw, pure=True)(
365
+ uvw = delayed(jit(coord.itrf_to_uvw), pure=True)(
358
366
  ds.itrf.data,
359
367
  ds.h0.data,
360
368
  ds.dec.data,
@@ -381,8 +389,8 @@ def angular_separation(rfi_xyz: Array, ants_xyz: Array, ra: Array, dec: Array) -
381
389
  {
382
390
  "rfi_xyz": (["src", "time", "space"], rfi_xyz),
383
391
  "ants_xyz": (["time", "ant", "space"], ants_xyz),
384
- "ra": (["cel_space_0"], da.from_array([ra])),
385
- "dec": (["cel_space_1"], da.from_array([dec])),
392
+ "ra": (["cel_space_0"], da.from_array([ra])), # type: ignore
393
+ "dec": (["cel_space_1"], da.from_array([dec])), # type: ignore
386
394
  }
387
395
  )
388
396
 
@@ -390,7 +398,7 @@ def angular_separation(rfi_xyz: Array, ants_xyz: Array, ra: Array, dec: Array) -
390
398
  {
391
399
  "sep": (
392
400
  ["src", "time", "ant"],
393
- da.zeros(
401
+ da.zeros( # type: ignore
394
402
  shape=(n_src, n_time, n_ant),
395
403
  chunks=(src_chunk, time_chunk, ant_chunk),
396
404
  dtype=float,
@@ -400,7 +408,7 @@ def angular_separation(rfi_xyz: Array, ants_xyz: Array, ra: Array, dec: Array) -
400
408
  )
401
409
 
402
410
  def _angular_separation(ds):
403
- sep = delayed(coord.angular_separation, pure=True)(
411
+ sep = delayed(jit(coord.angular_separation), pure=True)(
404
412
  ds.rfi_xyz.data, ds.ants_xyz.data, ds.ra.data, ds.dec.data
405
413
  ).compute()
406
414
  ds_out = xr.Dataset({"sep": (["src", "time", "ant"], sep)})
@@ -441,7 +449,7 @@ def orbit_vmap(
441
449
  {
442
450
  "orbit": (
443
451
  ["src", "time", "space"],
444
- da.zeros(
452
+ da.zeros( # type: ignore
445
453
  shape=(n_src, n_time, 3),
446
454
  chunks=(src_chunk, time_chunk, 3),
447
455
  dtype=float,
@@ -451,7 +459,7 @@ def orbit_vmap(
451
459
  )
452
460
 
453
461
  def _orbit_vmap(ds):
454
- orbit = delayed(coord.orbit_vmap, pure=True)(
462
+ orbit = delayed(jit(coord.orbit_vmap), pure=True)(
455
463
  ds.times.data,
456
464
  ds.elevation.data,
457
465
  ds.inclination.data,
@@ -1,10 +1,16 @@
1
- import dask.array as da
1
+ from jax import jit
2
+
2
3
  import numpy as np
3
4
  import xarray as xr
5
+
6
+ import dask.array as da
4
7
  from dask.delayed import delayed
5
8
  from dask.array.core import Array
9
+
6
10
  from tabsim.jax import interferometry as itf
7
11
 
12
+ from typing import Optional
13
+
8
14
 
9
15
  def astro_vis(sources: Array, uvw: Array, lmn: Array, freqs: Array) -> Array:
10
16
  """Calculate visibilities from sources, uvw, lmn, and freqs.
@@ -51,7 +57,7 @@ def astro_vis(sources: Array, uvw: Array, lmn: Array, freqs: Array) -> Array:
51
57
  {
52
58
  "vis": (
53
59
  ["time", "bl", "freq"],
54
- da.zeros(
60
+ da.zeros( # type: ignore
55
61
  shape=(n_time, n_bl, n_freq),
56
62
  chunks=(time_chunk, bl_chunk, freq_chunk),
57
63
  dtype=complex,
@@ -61,7 +67,7 @@ def astro_vis(sources: Array, uvw: Array, lmn: Array, freqs: Array) -> Array:
61
67
  )
62
68
 
63
69
  def _astro_vis(ds):
64
- vis = delayed(itf.astro_vis)(
70
+ vis = delayed(jit(itf.astro_vis), pure=True)(
65
71
  ds.I.data, ds.uvw.data, ds.lmn.data, ds.freqs.data
66
72
  ).compute()
67
73
  ds_out = xr.Dataset({"vis": (["time", "bl", "freq"], vis)})
@@ -122,7 +128,7 @@ def astro_vis_gauss(
122
128
  {
123
129
  "vis": (
124
130
  ["time", "bl", "freq"],
125
- da.zeros(
131
+ da.zeros( # type: ignore
126
132
  shape=(n_time, n_bl, n_freq),
127
133
  chunks=(time_chunk, bl_chunk, freq_chunk),
128
134
  dtype=complex,
@@ -132,7 +138,7 @@ def astro_vis_gauss(
132
138
  )
133
139
 
134
140
  def _astro_vis_gauss(ds):
135
- vis = delayed(itf.astro_vis_gauss)(
141
+ vis = delayed(jit(itf.astro_vis_gauss), pure=True)(
136
142
  ds.I.data,
137
143
  ds.major.data,
138
144
  ds.minor.data,
@@ -191,7 +197,7 @@ def astro_vis_exp(
191
197
  {
192
198
  "vis": (
193
199
  ["time", "bl", "freq"],
194
- da.zeros(
200
+ da.zeros( # type: ignore
195
201
  shape=(n_time, n_bl, n_freq),
196
202
  chunks=(time_chunk, bl_chunk, freq_chunk),
197
203
  dtype=complex,
@@ -201,7 +207,7 @@ def astro_vis_exp(
201
207
  )
202
208
 
203
209
  def _astro_vis_exp(ds):
204
- vis = delayed(itf.astro_vis_exp)(
210
+ vis = delayed(jit(itf.astro_vis_exp), pure=True)(
205
211
  ds.I.data, ds.sigmas.data, ds.uvw.data, ds.lmn.data, ds.freqs.data
206
212
  ).compute()
207
213
  ds_out = xr.Dataset({"vis": (["time", "bl", "freq"], vis)})
@@ -259,7 +265,7 @@ def rfi_vis(
259
265
  {
260
266
  "vis": (
261
267
  ["time", "bl", "freq"],
262
- da.zeros(
268
+ da.zeros( # type: ignore
263
269
  shape=(n_time, n_bl, n_freq),
264
270
  chunks=(time_chunk, bl_chunk, freq_chunk),
265
271
  dtype=complex,
@@ -269,7 +275,7 @@ def rfi_vis(
269
275
  )
270
276
 
271
277
  def _rfi_vis(ds):
272
- vis = delayed(itf.rfi_vis)(
278
+ vis = delayed(jit(itf.rfi_vis), pure=True)(
273
279
  ds.app_amplitude.data,
274
280
  ds.c_distances.data,
275
281
  ds.freqs.data,
@@ -299,7 +305,7 @@ def ants_to_bl(G: Array, a1: Array, a2: Array) -> Array:
299
305
  {
300
306
  "G_bl": (
301
307
  ["time", "bl", "freq"],
302
- da.zeros(
308
+ da.zeros( # type: ignore
303
309
  (n_time, n_bl, n_freq), chunks=(time_chunk, bl_chunk, freq_chunk)
304
310
  ),
305
311
  )
@@ -307,7 +313,9 @@ def ants_to_bl(G: Array, a1: Array, a2: Array) -> Array:
307
313
  )
308
314
 
309
315
  def _ants_to_bl(ds):
310
- G_bl = delayed(itf.ants_to_bl)(ds.G.data, ds.a1.data, ds.a2.data).compute()
316
+ G_bl = delayed(jit(itf.ants_to_bl), pure=True)(
317
+ ds.G.data, ds.a1.data, ds.a2.data
318
+ ).compute()
311
319
  ds_out = xr.Dataset({"G_bl": (["time", "bl", "freq"], G_bl)})
312
320
  return ds_out
313
321
 
@@ -330,7 +338,7 @@ def airy_beam(theta, freqs, dish_d):
330
338
  {
331
339
  "theta": (["src", "time", "ant"], theta),
332
340
  "freqs": (["freq"], freqs),
333
- "dish_d": (["space_0"], da.from_array([dish_d])),
341
+ "dish_d": (["space_0"], da.from_array([dish_d])), # type: ignore
334
342
  }
335
343
  )
336
344
 
@@ -338,7 +346,7 @@ def airy_beam(theta, freqs, dish_d):
338
346
  {
339
347
  "beam": (
340
348
  ["src", "time", "ant", "freq"],
341
- da.zeros(
349
+ da.zeros( # type: ignore
342
350
  (n_src, n_time, n_ant, n_freq),
343
351
  chunks=(src_chunk, time_chunk, ant_chunk, freq_chunk),
344
352
  ),
@@ -347,7 +355,7 @@ def airy_beam(theta, freqs, dish_d):
347
355
  )
348
356
 
349
357
  def _airy_beam(ds):
350
- beam = delayed(itf.airy_beam)(
358
+ beam = delayed(itf.airy_beam, pure=True)(
351
359
  ds.theta.data, ds.freqs.data, ds.dish_d.data
352
360
  ).compute()
353
361
  ds_out = xr.Dataset({"beam": (["src", "time", "ant", "freq"], beam)})
@@ -376,7 +384,7 @@ def Pv_to_Sv(Pv, d):
376
384
  {
377
385
  "Sv": (
378
386
  ["src", "time", "ant", "freq"],
379
- da.zeros(
387
+ da.zeros( # type: ignore
380
388
  (n_src, n_time, n_ant, n_freq),
381
389
  chunks=(src_chunk, time_chunk, ant_chunk, freq_chunk),
382
390
  ),
@@ -406,7 +414,7 @@ def add_noise(vis: Array, noise_std: float, key: int):
406
414
 
407
415
 
408
416
  def SEFD_to_noise_std(SEFD, chan_width, t_int):
409
- noise_std = SEFD / da.sqrt(chan_width * t_int)
417
+ noise_std = SEFD / da.sqrt(chan_width * t_int) # type: ignore
410
418
  return noise_std
411
419
 
412
420
 
@@ -417,13 +425,13 @@ def SEFD_to_noise_std(SEFD, chan_width, t_int):
417
425
  # return times_fine
418
426
 
419
427
 
420
- def int_sample_times(times, n_int_samples: int, int_time: float = None):
428
+ def int_sample_times(times, n_int_samples: int, int_time: Optional[float] = None):
421
429
 
422
430
  n_time = len(times)
423
431
  time_range = times[-1] - times[0]
424
432
  int_time = time_range / (n_time - 1) if not int_time else int_time
425
433
  n_time_fine = n_time * n_int_samples
426
- times_fine = da.linspace(
434
+ times_fine = da.linspace( # type: ignore
427
435
  -int_time / 2, time_range + int_time / 2, n_time_fine, endpoint=False
428
436
  )
429
437
 
@@ -444,7 +452,7 @@ def generate_gains(
444
452
  times = times[:, None, None] - times[0]
445
453
 
446
454
  # Generate the initial gain values
447
- G0 = G0_mean * da.exp(
455
+ G0 = G0_mean * da.exp( # type: ignore
448
456
  1.0j * rng.uniform(low=-np.pi / 2, high=np.pi / 2, size=(1, n_ant, n_freq))
449
457
  ) + (
450
458
  rng.normal(scale=G0_std, size=(1, n_ant, n_freq))
@@ -455,9 +463,9 @@ def generate_gains(
455
463
  gain_amp = rng.normal(scale=Gt_std_amp, size=(1, n_ant, 1)) * times
456
464
  gain_phase = rng.normal(scale=Gt_std_phase, size=(1, n_ant, 1)) * times
457
465
  # Generate the gain time series
458
- gain_ants = G0 + gain_amp * da.exp(1.0j * gain_phase)
466
+ gain_ants = G0 + gain_amp * da.exp(1.0j * gain_phase) # type: ignore
459
467
  # Set the gain on the last antenna to have zero phase (reference antenna)
460
- gain_ants[:, -1, :] = da.abs(gain_ants[:, -1, :])
468
+ gain_ants[:, -1, :] = da.abs(gain_ants[:, -1, :]) # type: ignore
461
469
 
462
470
  return gain_ants
463
471
 
@@ -479,7 +487,7 @@ def generate_fourier_gains(
479
487
  times = times_jd[None, :, None, None] * 24
480
488
 
481
489
  # Generate the initial gain values
482
- G0 = G0_mean * da.exp(
490
+ G0 = G0_mean * da.exp( # type: ignore
483
491
  1.0j * rng.uniform(low=-np.pi / 2, high=np.pi / 2, size=(1, n_ant, n_freq))
484
492
  ) + (
485
493
  rng.normal(scale=G0_std / 100, size=(1, n_ant, n_freq))
@@ -513,9 +521,9 @@ def generate_fourier_gains(
513
521
  axis=0,
514
522
  ) * np.sqrt(2 * N)
515
523
  # Generate the gain time series
516
- gain_ants = G0 + gain_amp * da.exp(1.0j * gain_phase)
524
+ gain_ants = G0 + gain_amp * da.exp(1.0j * gain_phase) # type: ignore
517
525
  # Set the gain on the last antenna to have zero phase (reference antenna)
518
- gain_ants[:, -1, :] = da.abs(gain_ants[:, -1, :])
526
+ gain_ants[:, -1, :] = da.abs(gain_ants[:, -1, :]) # type: ignore
519
527
 
520
528
  return gain_ants
521
529
 
@@ -545,7 +553,7 @@ def apply_gains(
545
553
  {
546
554
  "vis_obs": (
547
555
  ["time", "bl", "freq"],
548
- da.zeros(
556
+ da.zeros( # type: ignore
549
557
  (n_time, n_bl, n_freq),
550
558
  chunks=(time_chunk, bl_chunk, freq_chunk),
551
559
  dtype=vis_ast.dtype,
@@ -567,6 +575,6 @@ def apply_gains(
567
575
 
568
576
 
569
577
  def time_avg(vis, n_int_samples):
570
- return da.mean(
571
- da.reshape(vis, (-1, n_int_samples, vis.shape[1], vis.shape[2])), axis=1
578
+ return da.mean( # type: ignore
579
+ da.reshape(vis, (-1, n_int_samples, vis.shape[1], vis.shape[2])), axis=1 # type: ignore
572
580
  )