tabsim 0.0.5__tar.gz → 0.0.7__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.5 → tabsim-0.0.7}/PKG-INFO +1 -1
  2. {tabsim-0.0.5 → tabsim-0.0.7}/pyproject.toml +1 -1
  3. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/dask/coordinates.py +50 -26
  4. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/dask/interferometry.py +35 -27
  5. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/dask/observation.py +43 -26
  6. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/jax/coordinates.py +7 -37
  7. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/jax/interferometry.py +10 -38
  8. tabsim-0.0.7/tabsim/jax/utils.py +11 -0
  9. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/scripts/sim_vis.py +4 -0
  10. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim.egg-info/PKG-INFO +1 -1
  11. tabsim-0.0.5/tabsim/jax/utils.py +0 -90
  12. {tabsim-0.0.5 → tabsim-0.0.7}/LICENSE +0 -0
  13. {tabsim-0.0.5 → tabsim-0.0.7}/README.md +0 -0
  14. {tabsim-0.0.5 → tabsim-0.0.7}/docs/conf.py +0 -0
  15. {tabsim-0.0.5 → tabsim-0.0.7}/setup.cfg +0 -0
  16. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/__init__.py +0 -0
  17. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/config.py +0 -0
  18. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/dask/__init__.py +0 -0
  19. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/dask/extras.py +0 -0
  20. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/data/__init__.py +0 -0
  21. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/data/config/sim_config_base.yaml +0 -0
  22. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/data/config/tab_config_base.yaml +0 -0
  23. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/data/rfi/norad_satellite.rfimodel +0 -0
  24. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/data/rfi/satellite.ole +0 -0
  25. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/data/rfi/satellite.rfimodel +0 -0
  26. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/data/rfi/stationary.loc +0 -0
  27. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/data/rfi/stationary.rfimodel +0 -0
  28. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/data/rfi/tles/2023-02-21-J8HE0T.json +0 -0
  29. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/data/rfi/tles/2023-02-21-navstar.json +0 -0
  30. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/data/sky/calibrator.skymodel +0 -0
  31. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/data/telescopes/EDA2.itrf.txt +0 -0
  32. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/data/telescopes/MWA.itrf.txt +0 -0
  33. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/data/telescopes/MeerKAT.itrf.txt +0 -0
  34. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/data/telescopes/_telescopes.yaml +0 -0
  35. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/jax/__init__.py +0 -0
  36. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/plot.py +0 -0
  37. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/read_ms.py +0 -0
  38. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/scripts/__init__.py +0 -0
  39. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/scripts/ast_region.py +0 -0
  40. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/scripts/flag_data.py +0 -0
  41. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/scripts/tle_sat_region.py +0 -0
  42. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/scripts/write_config_from_ms.py +0 -0
  43. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/sky.py +0 -0
  44. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/tle.py +0 -0
  45. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/tools.py +0 -0
  46. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim/write.py +0 -0
  47. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim.egg-info/SOURCES.txt +0 -0
  48. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim.egg-info/dependency_links.txt +0 -0
  49. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim.egg-info/entry_points.txt +0 -0
  50. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim.egg-info/requires.txt +0 -0
  51. {tabsim-0.0.5 → tabsim-0.0.7}/tabsim.egg-info/top_level.txt +0 -0
  52. {tabsim-0.0.5 → tabsim-0.0.7}/tests/test_basic.py +0 -0
  53. {tabsim-0.0.5 → tabsim-0.0.7}/tests/test_sim-vis.py +0 -0
  54. {tabsim-0.0.5 → tabsim-0.0.7}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tabsim
3
- Version: 0.0.5
3
+ Version: 0.0.7
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>
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "tabsim"
8
- version = "0.0.5"
8
+ version = "0.0.7"
9
9
  license = {file = "LICENSE"}
10
10
  readme = "README.md"
11
11
  # dynamic = ["version", "readme"]
@@ -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)})
@@ -237,6 +243,22 @@ def GEO_to_XYZ_vmap1(geo: Array, times: Array) -> Array:
237
243
 
238
244
  GEO_to_XYZ_vmap1.__doc__ = coord.GEO_to_XYZ_vmap1.__doc__
239
245
 
246
+ from skyfield.api import Distance, load
247
+ from skyfield.toposlib import ITRSPosition
248
+ import numpy as np
249
+ from numpy.typing import NDArray
250
+
251
+ def itrs_to_gcrs_sf(pos_itrs: NDArray, times_jd: NDArray) -> NDArray:
252
+
253
+ ts = load.timescale()
254
+ t_sf = ts.ut1_jd(np.array(times_jd))
255
+
256
+ pos_gcrs = np.stack(
257
+ [ITRSPosition(Distance(m=pos)).at(t_sf).position.m.T for pos in pos_itrs], axis=1
258
+ )
259
+
260
+ return pos_gcrs
261
+
240
262
 
241
263
  def ITRF_to_XYZ(itrf: Array, gsa: Array) -> Array:
242
264
  n_time = gsa.shape[0]
@@ -255,7 +277,7 @@ def ITRF_to_XYZ(itrf: Array, gsa: Array) -> Array:
255
277
  {
256
278
  "xyz": (
257
279
  ["time", "ant", "space"],
258
- da.zeros(
280
+ da.zeros( # type: ignore
259
281
  shape=(n_time, n_ant, 3),
260
282
  chunks=(time_chunk, ant_chunk, 3),
261
283
  dtype=float,
@@ -265,7 +287,9 @@ def ITRF_to_XYZ(itrf: Array, gsa: Array) -> Array:
265
287
  )
266
288
 
267
289
  def _ITRF_to_XYZ(ds):
268
- XYZ = delayed(coord.itrf_to_xyz, pure=True)(ds.itrf.data, ds.gsa.data).compute()
290
+ XYZ = delayed(jit(coord.itrf_to_xyz), pure=True)(
291
+ ds.itrf.data, ds.gsa.data
292
+ ).compute()
269
293
  ds_out = xr.Dataset({"xyz": (["time", "ant", "space"], XYZ)})
270
294
  return ds_out
271
295
 
@@ -294,7 +318,7 @@ def ENU_to_ITRF(ENU: Array, lat: Array, lon: Array, el: Array) -> Array:
294
318
  {
295
319
  "ITRF": (
296
320
  ["ant", "space"],
297
- da.zeros(
321
+ da.zeros( # type: ignore
298
322
  shape=(n_ant, 3),
299
323
  chunks=(ant_chunk, 3),
300
324
  dtype=float,
@@ -304,7 +328,7 @@ def ENU_to_ITRF(ENU: Array, lat: Array, lon: Array, el: Array) -> Array:
304
328
  )
305
329
 
306
330
  def _ENU_to_ITRF(ds):
307
- ITRF = delayed(coord.enu_to_itrf, pure=True)(
331
+ ITRF = delayed(jit(coord.enu_to_itrf), pure=True)(
308
332
  ds.ENU.data,
309
333
  ds.lat.data,
310
334
  ds.lon.data,
@@ -335,8 +359,8 @@ def ITRF_to_UVW(
335
359
  input = xr.Dataset(
336
360
  {
337
361
  "itrf": (["ant", "space"], itrf),
338
- "h0": (["time"], da.atleast_1d(h0)),
339
- "dec": (["cel_space_1"], da.atleast_1d(dec)),
362
+ "h0": (["time"], da.atleast_1d(h0)), # type: ignore
363
+ "dec": (["cel_space_1"], da.atleast_1d(dec)), # type: ignore
340
364
  }
341
365
  )
342
366
 
@@ -344,7 +368,7 @@ def ITRF_to_UVW(
344
368
  {
345
369
  "uvw": (
346
370
  ["time", "ant", "space"],
347
- da.zeros(
371
+ da.zeros( # type: ignore
348
372
  shape=(n_time, n_ant, 3),
349
373
  chunks=(time_chunk, ant_chunk, 3),
350
374
  dtype=float,
@@ -354,7 +378,7 @@ def ITRF_to_UVW(
354
378
  )
355
379
 
356
380
  def _ITRF_to_UVW(ds):
357
- uvw = delayed(coord.itrf_to_uvw, pure=True)(
381
+ uvw = delayed(jit(coord.itrf_to_uvw), pure=True)(
358
382
  ds.itrf.data,
359
383
  ds.h0.data,
360
384
  ds.dec.data,
@@ -381,8 +405,8 @@ def angular_separation(rfi_xyz: Array, ants_xyz: Array, ra: Array, dec: Array) -
381
405
  {
382
406
  "rfi_xyz": (["src", "time", "space"], rfi_xyz),
383
407
  "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])),
408
+ "ra": (["cel_space_0"], da.from_array([ra])), # type: ignore
409
+ "dec": (["cel_space_1"], da.from_array([dec])), # type: ignore
386
410
  }
387
411
  )
388
412
 
@@ -390,7 +414,7 @@ def angular_separation(rfi_xyz: Array, ants_xyz: Array, ra: Array, dec: Array) -
390
414
  {
391
415
  "sep": (
392
416
  ["src", "time", "ant"],
393
- da.zeros(
417
+ da.zeros( # type: ignore
394
418
  shape=(n_src, n_time, n_ant),
395
419
  chunks=(src_chunk, time_chunk, ant_chunk),
396
420
  dtype=float,
@@ -400,7 +424,7 @@ def angular_separation(rfi_xyz: Array, ants_xyz: Array, ra: Array, dec: Array) -
400
424
  )
401
425
 
402
426
  def _angular_separation(ds):
403
- sep = delayed(coord.angular_separation, pure=True)(
427
+ sep = delayed(jit(coord.angular_separation), pure=True)(
404
428
  ds.rfi_xyz.data, ds.ants_xyz.data, ds.ra.data, ds.dec.data
405
429
  ).compute()
406
430
  ds_out = xr.Dataset({"sep": (["src", "time", "ant"], sep)})
@@ -441,7 +465,7 @@ def orbit_vmap(
441
465
  {
442
466
  "orbit": (
443
467
  ["src", "time", "space"],
444
- da.zeros(
468
+ da.zeros( # type: ignore
445
469
  shape=(n_src, n_time, 3),
446
470
  chunks=(src_chunk, time_chunk, 3),
447
471
  dtype=float,
@@ -451,7 +475,7 @@ def orbit_vmap(
451
475
  )
452
476
 
453
477
  def _orbit_vmap(ds):
454
- orbit = delayed(coord.orbit_vmap, pure=True)(
478
+ orbit = delayed(jit(coord.orbit_vmap), pure=True)(
455
479
  ds.times.data,
456
480
  ds.elevation.data,
457
481
  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
  )
@@ -1,4 +1,4 @@
1
- from jax import config, Array
1
+ from jax import Array
2
2
 
3
3
  import dask.array as da
4
4
  import numpy as np
@@ -11,6 +11,7 @@ from tabsim.dask.coordinates import (
11
11
  ENU_to_GEO,
12
12
  GEO_to_XYZ_vmap0,
13
13
  ITRF_to_XYZ,
14
+ itrs_to_gcrs_sf,
14
15
  orbit_vmap,
15
16
  radec_to_lmn,
16
17
  angular_separation,
@@ -44,8 +45,6 @@ from tabsim.write import construct_observation_ds, write_ms
44
45
  from tabsim.dask.extras import get_chunksizes
45
46
  from tabsim.tle import get_satellite_positions, ants_pos, sat_distance
46
47
 
47
- config.update("jax_enable_x64", True)
48
-
49
48
  from astropy.time import Time
50
49
 
51
50
 
@@ -83,23 +82,24 @@ class Telescope(object):
83
82
  n_ant: Optional[int] = None,
84
83
  ):
85
84
  self.tel_name = tel_name
86
- self.latitude = da.asarray(latitude)
87
- self.longitude = da.asarray(longitude)
88
- self.elevation = da.asarray(elevation)
89
- self.GEO = da.asarray([latitude, longitude, elevation])
85
+ self.latitude = da.asarray(latitude) # type: ignore
86
+ self.longitude = da.asarray(longitude) # type: ignore
87
+ self.elevation = da.asarray(elevation) # type: ignore
88
+ self.GEO = da.asarray([latitude, longitude, elevation]) # type: ignore
90
89
  self.ITRF = None
91
90
  self.ENU = None
92
91
  self.n_ant = n_ant
93
92
 
94
- if ENU_array is not None or ENU_path is not None:
93
+ if ENU_array or ENU_path:
95
94
  self.createArrayENU(ENU_array, ENU_path)
96
- if ITRF_array is not None or ITRF_path is not None:
95
+ if ITRF_array or ITRF_path:
97
96
  self.createArrayITRF(ITRF_array, ITRF_path)
98
97
  if self.ITRF is None and self.ENU is None:
99
98
  raise ValueError(
100
- "One of ('ENU_array', 'ENU_path', 'ITRF_array', 'ITRF_path') must be provided to create a Telescope object."
99
+ "One of 'ENU_path' or 'ITRF_path' must be provided to create a Telescope object."
101
100
  )
102
- self.n_ant = len(self.ITRF)
101
+ else:
102
+ self.n_ant = len(self.ITRF)
103
103
 
104
104
  def __str__(self):
105
105
  msg = """\nTelescope Location
@@ -126,7 +126,7 @@ Elevation : {elevation}\n"""
126
126
  array or as a csv like file."""
127
127
  print(msg)
128
128
  return
129
- self.ENU = da.asarray(self.ENU)
129
+ self.ENU = da.asarray(self.ENU) # type: ignore
130
130
  self.ENU_path = ENU_path
131
131
  self.GEO_ants = ENU_to_GEO(self.GEO, self.ENU)
132
132
  self.ITRF = ENU_to_ITRF(self.ENU, self.latitude, self.longitude, self.elevation)
@@ -142,8 +142,8 @@ Elevation : {elevation}\n"""
142
142
  array or as a csv like file."""
143
143
  raise ValueError(msg)
144
144
 
145
- self.ITRF = da.asarray(self.ITRF)
146
- self.GEO_ants = da.asarray(itrf_to_geo(self.ITRF.compute()))
145
+ self.ITRF = da.asarray(self.ITRF) # type: ignore
146
+ self.GEO_ants = da.asarray(itrf_to_geo(self.ITRF.compute())) # type: ignore
147
147
 
148
148
 
149
149
  class Observation(Telescope):
@@ -330,7 +330,8 @@ class Observation(Telescope):
330
330
  self.mag_uvw = da.linalg.norm(self.bl_uvw[0], axis=-1)
331
331
  self.syn_bw = beam_size(self.mag_uvw.max().compute(), freqs.max())
332
332
 
333
- self.ants_xyz = ITRF_to_XYZ(self.ITRF, self.gsa)
333
+ # self.ants_xyz = ITRF_to_XYZ(self.ITRF, self.gsa)
334
+ self.ants_xyz = da.asarray(itrs_to_gcrs_sf(np.asarray(self.ITRF), np.asarray(mjd_to_jd(self.times_mjd_fine.compute()))))
334
335
  self.vis_rfi = da.zeros(
335
336
  shape=(self.n_time, self.n_bl, self.n_freq),
336
337
  chunks=(self.time_chunk, self.bl_chunk, self.freq_chunk),
@@ -474,7 +475,7 @@ Number of stationary RFI : {n_stat}"""
474
475
  dec: array (n_src,)
475
476
  Declination of the sources in degrees.
476
477
  """
477
- I = da.atleast_2d(I)
478
+ I = da.atleast_2d(I) # type: ignore
478
479
  if I.ndim == 2:
479
480
  I = da.expand_dims(I, axis=0)
480
481
  I = I * da.ones(
@@ -530,7 +531,7 @@ Number of stationary RFI : {n_stat}"""
530
531
  dec: Array (n_src,)
531
532
  Declination of the sources in degrees.
532
533
  """
533
- I = da.atleast_2d(I)
534
+ I = da.atleast_2d(I) # type: ignore
534
535
  if I.ndim == 2:
535
536
  I = da.expand_dims(I, axis=0)
536
537
  I = I * da.ones(
@@ -718,7 +719,7 @@ Number of stationary RFI : {n_stat}"""
718
719
  tles: Array (n_src, 2)
719
720
  TLEs of the satellites corresponding to the NORAD IDs.
720
721
  """
721
- Pv = da.atleast_2d(Pv)
722
+ Pv = da.atleast_2d(Pv) # type: ignore
722
723
  if Pv.ndim == 2:
723
724
  Pv = da.expand_dims(Pv, axis=0)
724
725
  Pv = (
@@ -728,10 +729,11 @@ Number of stationary RFI : {n_stat}"""
728
729
  )
729
730
  ).rechunk((-1, self.time_fine_chunk, self.freq_chunk))
730
731
  norad_ids = da.asarray(da.atleast_1d(norad_ids), chunks=(-1,))
732
+ n_src = len(norad_ids)
731
733
 
732
734
  rfi_xyz = da.asarray(
733
735
  get_satellite_positions(tles, mjd_to_jd(self.times_mjd_fine.compute())),
734
- chunks=(-1, self.time_fine_chunk, 3),
736
+ chunks=(n_src, self.time_fine_chunk, 3),
735
737
  )
736
738
  # from tabsim.jax.coordinates import kepler_orbit_many
737
739
  # from tabsim.tle import
@@ -743,7 +745,7 @@ Number of stationary RFI : {n_stat}"""
743
745
  # self.ants_xyz is shape (n_time_fine,n_ant,3)
744
746
  distances = da.linalg.norm(
745
747
  self.ants_xyz[None, :, :, :] - rfi_xyz[:, :, None, :], axis=-1
746
- )
748
+ ) # .rechunk(n_src, self.time_chunk, self.n_int_samples, self.n_ant)
747
749
  # distances = da.asarray(da.linalg.norm(
748
750
  # ants_pos(self.ITRF.compute(), mjd_to_jd(self.times_mjd_fine.compute()))[None, :, :, :] - rfi_xyz[:, :, None, :], axis=-1
749
751
  # ), chunks=(-1, self.time_fine_chunk, self.n_ant))
@@ -751,24 +753,39 @@ Number of stationary RFI : {n_stat}"""
751
753
  I = Pv_to_Sv(Pv, distances)
752
754
  # I is shape (n_src,n_time_fine,n_ant,n_freq)
753
755
 
756
+ c_distances = (
757
+ (distances + self.ants_uvw[None, :, :, -1])
758
+ .reshape((n_src, self.n_time, self.n_int_samples, self.n_ant))
759
+ .rechunk((n_src, self.time_chunk, self.n_int_samples, self.ant_chunk))
760
+ )
761
+
754
762
  angular_seps = angular_separation(rfi_xyz, self.ants_xyz, self.ra, self.dec)
755
763
 
756
764
  # angular_seps is shape (n_src,n_time_fine,n_ant)
757
765
  rfi_A_app = da.sqrt(da.abs(I)) * airy_beam(
758
766
  angular_seps, self.freqs, self.dish_d
759
767
  )
768
+
769
+ rfi_A = rfi_A_app.reshape(
770
+ (n_src, self.n_time, self.n_int_samples, self.n_ant, self.n_freq)
771
+ ).rechunk(
772
+ (
773
+ n_src,
774
+ self.time_chunk,
775
+ self.n_int_samples,
776
+ self.ant_chunk,
777
+ self.freq_chunk,
778
+ )
779
+ )
780
+
760
781
  # rfi_A_app = da.ones((Pv.shape[0], self.n_time_fine, self.n_ant, self.n_freq), chunks=(-1, self.time_fine_chunk, self.n_ant, self.freq_chunk))
761
782
  # self.rfi_A_app is shape (n_src,n_time_fine,n_ant,n_freqs)
762
783
  # distances is shape (n_src,n_time_fine,n_ant)
763
784
  # self.ants_uvw is shape (n_time_fine,n_ant,3)
764
785
 
765
786
  vis_rfi = rfi_vis(
766
- rfi_A_app.reshape(
767
- (-1, self.n_time, self.n_int_samples, self.n_ant, self.n_freq)
768
- ),
769
- (distances + self.ants_uvw[None, :, :, -1]).reshape(
770
- (-1, self.n_time, self.n_int_samples, self.n_ant)
771
- ),
787
+ rfi_A,
788
+ c_distances,
772
789
  self.freqs,
773
790
  self.a1,
774
791
  self.a2,