tabsim 0.0.3__tar.gz → 0.0.5__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 (53) hide show
  1. {tabsim-0.0.3 → tabsim-0.0.5}/PKG-INFO +4 -4
  2. {tabsim-0.0.3 → tabsim-0.0.5}/pyproject.toml +5 -4
  3. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/config.py +113 -40
  4. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/dask/observation.py +43 -30
  5. {tabsim-0.0.3/tabsim/data/config_files → tabsim-0.0.5/tabsim/data/config}/sim_config_base.yaml +8 -1
  6. tabsim-0.0.5/tabsim/data/rfi/tles/2023-02-21-navstar.json +1 -0
  7. tabsim-0.0.5/tabsim/data/telescopes/_telescopes.yaml +19 -0
  8. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/jax/coordinates.py +55 -0
  9. tabsim-0.0.5/tabsim/read_ms.py +137 -0
  10. tabsim-0.0.5/tabsim/scripts/write_config_from_ms.py +40 -0
  11. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/tle.py +1 -1
  12. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/write.py +57 -23
  13. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim.egg-info/PKG-INFO +4 -4
  14. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim.egg-info/SOURCES.txt +16 -12
  15. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim.egg-info/entry_points.txt +1 -0
  16. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim.egg-info/requires.txt +2 -2
  17. {tabsim-0.0.3 → tabsim-0.0.5}/LICENSE +0 -0
  18. {tabsim-0.0.3 → tabsim-0.0.5}/README.md +0 -0
  19. {tabsim-0.0.3 → tabsim-0.0.5}/docs/conf.py +0 -0
  20. {tabsim-0.0.3 → tabsim-0.0.5}/setup.cfg +0 -0
  21. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/__init__.py +0 -0
  22. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/dask/__init__.py +0 -0
  23. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/dask/coordinates.py +0 -0
  24. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/dask/extras.py +0 -0
  25. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/dask/interferometry.py +0 -0
  26. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/data/__init__.py +0 -0
  27. {tabsim-0.0.3/tabsim/data/config_files → tabsim-0.0.5/tabsim/data/config}/tab_config_base.yaml +0 -0
  28. {tabsim-0.0.3/tabsim/data/aux_data → tabsim-0.0.5/tabsim/data/rfi}/norad_satellite.rfimodel +0 -0
  29. {tabsim-0.0.3/tabsim/data/aux_data → tabsim-0.0.5/tabsim/data/rfi}/satellite.ole +0 -0
  30. {tabsim-0.0.3/tabsim/data/aux_data → tabsim-0.0.5/tabsim/data/rfi}/satellite.rfimodel +0 -0
  31. {tabsim-0.0.3/tabsim/data/aux_data → tabsim-0.0.5/tabsim/data/rfi}/stationary.loc +0 -0
  32. {tabsim-0.0.3/tabsim/data/aux_data → tabsim-0.0.5/tabsim/data/rfi}/stationary.rfimodel +0 -0
  33. {tabsim-0.0.3/tabsim/data/aux_data → tabsim-0.0.5/tabsim/data/rfi}/tles/2023-02-21-J8HE0T.json +0 -0
  34. {tabsim-0.0.3/tabsim/data/aux_data → tabsim-0.0.5/tabsim/data/sky}/calibrator.skymodel +0 -0
  35. {tabsim-0.0.3/tabsim/data → tabsim-0.0.5/tabsim/data/telescopes}/EDA2.itrf.txt +0 -0
  36. {tabsim-0.0.3/tabsim/data → tabsim-0.0.5/tabsim/data/telescopes}/MWA.itrf.txt +0 -0
  37. {tabsim-0.0.3/tabsim/data → tabsim-0.0.5/tabsim/data/telescopes}/MeerKAT.itrf.txt +0 -0
  38. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/jax/__init__.py +0 -0
  39. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/jax/interferometry.py +0 -0
  40. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/jax/utils.py +0 -0
  41. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/plot.py +0 -0
  42. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/scripts/__init__.py +0 -0
  43. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/scripts/ast_region.py +0 -0
  44. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/scripts/flag_data.py +0 -0
  45. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/scripts/sim_vis.py +0 -0
  46. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/scripts/tle_sat_region.py +0 -0
  47. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/sky.py +0 -0
  48. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim/tools.py +0 -0
  49. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim.egg-info/dependency_links.txt +0 -0
  50. {tabsim-0.0.3 → tabsim-0.0.5}/tabsim.egg-info/top_level.txt +0 -0
  51. {tabsim-0.0.3 → tabsim-0.0.5}/tests/test_basic.py +0 -0
  52. {tabsim-0.0.3 → tabsim-0.0.5}/tests/test_sim-vis.py +0 -0
  53. {tabsim-0.0.3 → tabsim-0.0.5}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tabsim
3
- Version: 0.0.3
3
+ Version: 0.0.5
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.3"
8
+ version = "0.0.5"
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
@@ -28,14 +27,9 @@ from daskms import xds_from_ms
28
27
  from tqdm import tqdm
29
28
  from importlib.resources import files
30
29
 
31
- config_dir = files("tabsim.data").joinpath("config_files").__str__()
32
30
 
33
- sim_base_config_path = os.path.join(config_dir, "sim_config_base.yaml")
34
- tab_base_config_path = os.path.join(config_dir, "tab_config_base.yaml")
35
- # extract_base_config_path = os.path.join(config_dir, "extract_config_base.yaml")
36
- # pow_spec_base_config_path = os.path.join(
37
- # config_dir, "extract_pow_spec_config_base.yaml"
38
- # )
31
+ sky_dir = files("tabsim.data").joinpath("sky").__str__()
32
+
39
33
 
40
34
  JD0 = 2459997.079914223 # 2023-02-21 13:55:04.589 UTC => GMSA = 0
41
35
  MJD0 = JD0 - 2400000.5
@@ -115,24 +109,67 @@ def load_config(path: str, config_type: str = "sim") -> dict:
115
109
  dict
116
110
  Configuration dictionary.
117
111
  """
112
+ config_dir = files("tabsim.data").joinpath("config").__str__()
113
+
114
+ sim_base_config_path = os.path.join(config_dir, "sim_config_base.yaml")
115
+ tab_base_config_path = os.path.join(config_dir, "tab_config_base.yaml")
116
+ # extract_base_config_path = os.path.join(config_dir, "extract_config_base.yaml")
117
+ # pow_spec_base_config_path = os.path.join(
118
+ # config_dir, "extract_pow_spec_config_base.yaml"
119
+ # )
118
120
 
119
121
  config = yaml_load(path)
120
122
  if config_type == "sim":
121
123
  base_config = yaml_load(sim_base_config_path)
122
124
  elif config_type == "tab":
123
125
  base_config = yaml_load(tab_base_config_path)
124
- elif config_type == "extract":
125
- base_config = yaml_load(extract_base_config_path)
126
- elif config_type == "pow_spec":
127
- base_config = yaml_load(pow_spec_base_config_path)
126
+ # elif config_type == "extract":
127
+ # base_config = yaml_load(extract_base_config_path)
128
+ # elif config_type == "pow_spec":
129
+ # base_config = yaml_load(pow_spec_base_config_path)
128
130
  else:
129
- ValueError(
130
- "A config type must be specified. Options are {sim, tab, extract, pow_spec}."
131
- )
131
+ raise ValueError("A config type must be specified. Options are {sim, tab}.")
132
132
 
133
133
  return deep_update(base_config, config)
134
134
 
135
135
 
136
+ def get_telescope_definitions(tel_name: str):
137
+
138
+ tel_dir = files("tabsim.data").joinpath("telescopes").__str__()
139
+ tel_def = yaml_load(os.path.join(tel_dir, "_telescopes.yaml"))
140
+
141
+ tel_name = tel_name.lower()
142
+ telescope_list = tel_def.keys()
143
+
144
+ if tel_name in telescope_list:
145
+ tel_def = tel_def[tel_name]
146
+ tel_def["itrf_path"] = os.path.join(tel_dir, tel_def["itrf_path"])
147
+ else:
148
+ raise ValueError(
149
+ f"{tel_name} is not a pre-defined telescope within tab-sim. Choose from {telescope_list}"
150
+ )
151
+
152
+ return tel_def
153
+
154
+
155
+ def get_rfi_definitions():
156
+
157
+ rfi_dir = files("tabsim.data").joinpath("rfi").__str__()
158
+
159
+ rfi_def = {
160
+ "tle_satellite": {
161
+ "tle_dir": os.path.join(rfi_dir, "tles"),
162
+ "norad_spec_model": os.path.join(rfi_dir, "norad_satellite.rfimodel"),
163
+ },
164
+ "stationary": {
165
+ "geo_path": os.path.join(rfi_dir, "stationary.loc"),
166
+ "spec_path": os.path.join(rfi_dir, "stationary.rfimodel"),
167
+ },
168
+ }
169
+
170
+ return rfi_def
171
+
172
+
136
173
  def load_sky_model(file_path: str, freqs: Array, src_type: str) -> tuple:
137
174
  """Read in a skymodel file and return parameters to be used in tabascal simulator.
138
175
  A skymodel file is a csv file with the following columns:
@@ -218,9 +255,7 @@ def load_obs(obs_spec: dict) -> Observation:
218
255
  start_time_mjd = jd_to_mjd(obs_["start_time_jd"])
219
256
  elif obs_["start_time_isot"]:
220
257
 
221
- start_time_mjd = jd_to_mjd(
222
- Time(obs_["start_time_isot"], format="isot", scale="ut1").jd
223
- )
258
+ start_time_mjd = jd_to_mjd(Time(obs_["start_time_isot"], format="isot").jd)
224
259
  elif obs_["start_time_lha"] is not None:
225
260
  gsa = obs_["start_time_lha"] - tel_["longitude"] + obs_["ra"]
226
261
  start_time_mjd = MJD0 + (gsa / 360)
@@ -630,6 +665,8 @@ def add_gains(obs: Observation, obs_spec: dict) -> None:
630
665
 
631
666
  def plot_diagnostics(obs: Observation, obs_spec: dict, save_path: str) -> None:
632
667
 
668
+ from tabsim.plot import plot_uv, plot_src_alt, plot_angular_seps
669
+
633
670
  diag_ = obs_spec["diagnostics"]
634
671
 
635
672
  if diag_["src_alt"]:
@@ -729,20 +766,7 @@ def save_inputs(obs: Observation, obs_spec: dict, save_path: str) -> None:
729
766
  if path is not None:
730
767
  shutil.copy(path, save_path)
731
768
 
732
- key = (
733
- 2
734
- * [
735
- "tle_satellite",
736
- ]
737
- + 2
738
- * [
739
- "satellite",
740
- ]
741
- + 2
742
- * [
743
- "stationary",
744
- ]
745
- )
769
+ key = 2 * ["tle_satellite"] + 2 * ["satellite"] + 2 * ["stationary"]
746
770
  subkey = [
747
771
  "norad_ids_path",
748
772
  "norad_spec_model",
@@ -783,11 +807,14 @@ def print_fringe_freq_sat(obs: Observation):
783
807
  for i in range(obs.n_rfi_satellite)
784
808
  ]
785
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
786
813
  f_sample = (
787
814
  np.pi
788
815
  * np.max(np.abs(fringe_freq))
789
816
  * np.max(obs.rfi_satellite_A_app)
790
- / np.sqrt(6 * obs.noise_std.mean()).compute()
817
+ / np.sqrt(6 * noise_std)
791
818
  )
792
819
  n_int = int(np.ceil(obs.int_time * f_sample))
793
820
 
@@ -818,11 +845,14 @@ def print_fringe_freq_tle_sat(obs: Observation):
818
845
  for i in range(obs.n_rfi_tle_satellite)
819
846
  ]
820
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
821
851
  f_sample = (
822
852
  np.pi
823
853
  * np.max(np.abs(fringe_freq))
824
854
  * np.max(obs.rfi_tle_satellite_A_app)
825
- / np.sqrt(6 * obs.noise_std.mean()).compute()
855
+ / np.sqrt(6 * noise_std)
826
856
  )
827
857
  n_int = int(np.ceil(obs.int_time * f_sample))
828
858
 
@@ -835,6 +865,20 @@ def print_fringe_freq_tle_sat(obs: Observation):
835
865
  print(f"Recommended n_int is >= : {n_int:.0f} ({obs.n_int_samples} used)")
836
866
 
837
867
 
868
+ def check_telescope_defintion(tel_def: dict):
869
+
870
+ dish_d = tel_def["dish_d"]
871
+
872
+ if tel_def["itrf_path"] and dish_d:
873
+ return True
874
+ elif (
875
+ tel_def["longitude"] and tel_def["latitude"] and tel_def["enu_path"] and dish_d
876
+ ):
877
+ return True
878
+ else:
879
+ return False
880
+
881
+
838
882
  def run_sim_config(
839
883
  obs_spec: Optional[dict] = None,
840
884
  config_path: Optional[str] = None,
@@ -843,7 +887,6 @@ def run_sim_config(
843
887
 
844
888
  from tabsim.tle import id_generator
845
889
 
846
-
847
890
  log_path = f"log_sim_{id_generator()}.txt"
848
891
  log = open(log_path, "w")
849
892
  backup = sys.stdout
@@ -852,11 +895,17 @@ def run_sim_config(
852
895
  start = datetime.now()
853
896
  print(datetime.now())
854
897
 
855
- if config_path is not None:
898
+ if config_path:
856
899
  obs_spec = load_config(config_path, config_type="sim")
857
900
  elif obs_spec is None:
858
- print("obs_spec or path must be defined.")
859
- return None
901
+ raise ValueError("obs_spec or config_path must be defined.")
902
+
903
+ rfi_def = get_rfi_definitions()
904
+ obs_spec["rfi_sources"] = deep_update(obs_spec["rfi_sources"], rfi_def)
905
+
906
+ if not check_telescope_defintion(obs_spec["telescope"]):
907
+ tel_def = get_telescope_definitions(obs_spec["telescope"]["name"])
908
+ obs_spec["telescope"] = deep_update(obs_spec["telescope"], tel_def)
860
909
 
861
910
  obs = load_obs(obs_spec)
862
911
  add_astro_sources(obs, obs_spec)
@@ -889,9 +938,26 @@ def run_sim_config(
889
938
  print()
890
939
  print(f"Writing data to : {save_path}")
891
940
 
892
- 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
+
893
953
  save_data(obs, obs_spec, zarr_path, ms_path)
894
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
+
895
961
  end = datetime.now()
896
962
  print()
897
963
  print(f"Total simulation time : {end - start}")
@@ -903,4 +969,11 @@ def run_sim_config(
903
969
  os.remove(log_path)
904
970
  sys.stdout = backup
905
971
 
906
- 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,9 +1,9 @@
1
- import jax.numpy as jnp
2
1
  from jax import config, Array
3
2
 
4
3
  import dask.array as da
5
4
  import numpy as np
6
5
  import xarray as xr
6
+ from typing import Optional
7
7
 
8
8
  from tabsim.dask.coordinates import (
9
9
  ENU_to_ITRF,
@@ -75,12 +75,12 @@ class Telescope(object):
75
75
  latitude: float,
76
76
  longitude: float,
77
77
  elevation: float = 0.0,
78
- ENU_array: Array = None,
79
- ENU_path: str = None,
80
- ITRF_array: Array = None,
81
- ITRF_path: str = None,
82
- tel_name: str = None,
83
- n_ant: int = None,
78
+ ENU_array: Optional[Array] = None,
79
+ ENU_path: Optional[str] = None,
80
+ ITRF_array: Optional[Array] = None,
81
+ ITRF_path: Optional[str] = None,
82
+ tel_name: Optional[str] = None,
83
+ n_ant: Optional[int] = None,
84
84
  ):
85
85
  self.tel_name = tel_name
86
86
  self.latitude = da.asarray(latitude)
@@ -132,16 +132,16 @@ Elevation : {elevation}\n"""
132
132
  self.ITRF = ENU_to_ITRF(self.ENU, self.latitude, self.longitude, self.elevation)
133
133
 
134
134
  def createArrayITRF(self, ITRF_array, ITRF_path):
135
+
135
136
  if ITRF_array is not None:
136
137
  self.ITRF = ITRF_array
137
138
  elif ITRF_path is not None:
138
139
  self.ITRF = np.loadtxt(ITRF_path, usecols=(0, 1, 2), max_rows=self.n_ant)
139
140
  else:
140
- self.ITRF = None
141
- msg = """Error : ITRF antenna coordinates are needed either in an
141
+ msg = """ITRF antenna coordinates are needed either in an
142
142
  array or as a csv like file."""
143
- print(msg)
144
- return
143
+ raise ValueError(msg)
144
+
145
145
  self.ITRF = da.asarray(self.ITRF)
146
146
  self.GEO_ants = da.asarray(itrf_to_geo(self.ITRF.compute()))
147
147
 
@@ -205,11 +205,11 @@ class Observation(Telescope):
205
205
  times_mjd: Array,
206
206
  int_time: float = 2.0,
207
207
  chan_width: float = 209e3,
208
- ENU_array: Array = None,
209
- ENU_path: str = None,
210
- ITRF_array: Array = None,
211
- ITRF_path: str = None,
212
- n_ant: int = None,
208
+ ENU_array: Optional[Array] = None,
209
+ ENU_path: Optional[str] = None,
210
+ ITRF_array: Optional[Array] = None,
211
+ ITRF_path: Optional[str] = None,
212
+ n_ant: Optional[int] = None,
213
213
  dish_d: float = 13.5,
214
214
  random_seed: int = 0,
215
215
  auto_corrs: bool = False,
@@ -242,7 +242,7 @@ class Observation(Telescope):
242
242
  self.target_name = target_name
243
243
  self.auto_corrs = auto_corrs
244
244
 
245
- a1, a2 = jnp.triu_indices(self.n_ant, 0 if auto_corrs else 1)
245
+ a1, a2 = np.triu_indices(self.n_ant, 0 if auto_corrs else 1)
246
246
  self.n_bl = len(a1)
247
247
 
248
248
  self.ant_chunk = self.n_ant
@@ -290,11 +290,17 @@ class Observation(Telescope):
290
290
  self.n_int_samples // 2, self.n_time_fine, self.n_int_samples
291
291
  ).rechunk(self.time_chunk)
292
292
 
293
+ # self.gsa = da.asarray(
294
+ # Time(self.times_mjd_fine.compute(), format="mjd")
295
+ # .sidereal_time("mean", "greenwich")
296
+ # .hour
297
+ # * 15,
298
+ # chunks=(self.time_fine_chunk,),
299
+ # )
300
+ from tabsim.jax.coordinates import mjd_to_gast
301
+
293
302
  self.gsa = da.asarray(
294
- Time(self.times_mjd_fine.compute(), format="mjd")
295
- .sidereal_time("mean", "greenwich")
296
- .hour
297
- * 15,
303
+ mjd_to_gast(self.times_mjd_fine.compute()),
298
304
  chunks=(self.time_fine_chunk,),
299
305
  )
300
306
  self.gha = (self.gsa - self.ra) % 360
@@ -313,7 +319,9 @@ class Observation(Telescope):
313
319
  self.dish_d = da.asarray(dish_d)
314
320
  self.fov = beam_size(dish_d, freqs.max(), fwhp=False)
315
321
 
316
- self.ants_uvw = ITRF_to_UVW(self.ITRF, self.gha, self.dec)
322
+ self.ants_uvw = da.asarray(
323
+ np.array(ITRF_to_UVW(self.ITRF, self.gha, self.dec).compute())
324
+ )
317
325
 
318
326
  if no_w:
319
327
  self.ants_uvw[:, :, -1] = 0.0
@@ -326,17 +334,17 @@ class Observation(Telescope):
326
334
  self.vis_rfi = da.zeros(
327
335
  shape=(self.n_time, self.n_bl, self.n_freq),
328
336
  chunks=(self.time_chunk, self.bl_chunk, self.freq_chunk),
329
- dtype=jnp.complex128,
337
+ dtype=np.complex128,
330
338
  )
331
339
  self.vis_ast = da.zeros(
332
340
  shape=(self.n_time, self.n_bl, self.n_freq),
333
341
  chunks=(self.time_chunk, self.bl_chunk, self.freq_chunk),
334
- dtype=jnp.complex128,
342
+ dtype=np.complex128,
335
343
  )
336
344
  self.gains_ants = da.ones(
337
345
  shape=(self.n_time, self.n_ant, self.n_freq),
338
346
  chunks=(self.time_chunk, self.ant_chunk, self.freq_chunk),
339
- dtype=jnp.complex128,
347
+ dtype=np.complex128,
340
348
  )
341
349
  self.random_seed = random_seed
342
350
 
@@ -486,7 +494,7 @@ Number of stationary RFI : {n_stat}"""
486
494
 
487
495
  self.ast_p_I.append(I)
488
496
  self.ast_p_lmn.append(lmn)
489
- self.ast_p_radec.append(jnp.array([ra, dec]))
497
+ self.ast_p_radec.append(np.array([ra, dec]))
490
498
  self.n_p_ast += len(I)
491
499
  self.n_ast += len(I)
492
500
 
@@ -550,7 +558,7 @@ Number of stationary RFI : {n_stat}"""
550
558
  self.ast_g_pos_angle.append(pos_angle)
551
559
  self.ast_g_I.append(I)
552
560
  self.ast_g_lmn.append(lmn)
553
- self.ast_g_radec.append(jnp.array([ra, dec]))
561
+ self.ast_g_radec.append(np.array([ra, dec]))
554
562
  self.n_g_ast += len(I)
555
563
  self.n_ast += len(I)
556
564
 
@@ -596,7 +604,7 @@ Number of stationary RFI : {n_stat}"""
596
604
  self.ast_e_major.append(shape)
597
605
  self.ast_e_I.append(I)
598
606
  self.ast_e_lmn.append(lmn)
599
- self.ast_e_radec.append(jnp.array([ra, dec]))
607
+ self.ast_e_radec.append(np.array([ra, dec]))
600
608
  self.n_e_ast += len(I)
601
609
  self.n_ast += len(I)
602
610
 
@@ -725,6 +733,11 @@ Number of stationary RFI : {n_stat}"""
725
733
  get_satellite_positions(tles, mjd_to_jd(self.times_mjd_fine.compute())),
726
734
  chunks=(-1, self.time_fine_chunk, 3),
727
735
  )
736
+ # from tabsim.jax.coordinates import kepler_orbit_many
737
+ # from tabsim.tle import
738
+ # rfi_xyz = da.asarray(
739
+ # kepler_orbit_many(mjd_to_jd(self.times_mjd_fine.compute()), )
740
+ # )
728
741
  tles = da.asarray(da.atleast_2d(tles), chunks=(-1,))
729
742
  # rfi_xyz is shape (n_src,n_time_fine,3)
730
743
  # self.ants_xyz is shape (n_time_fine,n_ant,3)
@@ -938,7 +951,7 @@ Number of stationary RFI : {n_stat}"""
938
951
  else:
939
952
  self.flags = (
940
953
  da.abs(self.vis_cal - self.vis_ast)
941
- > 3.0 * da.std(self.vis_model, axis=0)[None, ...]
954
+ > 3.0 * da.std(self.vis_ast, axis=0)[None, ...]
942
955
  )
943
956
  else:
944
957
  self.flags = da.zeros(shape=self.vis_cal.shape, dtype=bool)
@@ -959,7 +972,7 @@ Number of stationary RFI : {n_stat}"""
959
972
  self,
960
973
  path: str = "Observation.ms",
961
974
  overwrite: bool = False,
962
- ds: xr.Dataset = None,
975
+ ds: Optional[xr.Dataset] = None,
963
976
  ):
964
977
  """
965
978
  Write the visibilities to disk using Measurement Set format.
@@ -2,6 +2,8 @@
2
2
  # This is base simulation config that is loaded and then updated with your provided config.
3
3
  # Populated parameters here are the default values used if none are specified in your config.
4
4
  ###############################################################################################
5
+ # Astronomical Sources
6
+ #######################
5
7
  ast_sources:
6
8
  ##########################################
7
9
  # Exponential shaped astronomical sources
@@ -120,11 +122,16 @@ observation:
120
122
  output:
121
123
  zarr: True # Optional - Whether to save the output to a zarr file. This contains almost all inputs ot the simulation
122
124
  ms: True # Optional - Whether to save the output to a Measurement Set file
125
+ accumulate_ms: null # Optional - Whether to add the RFI visibilities to a provided MS file. This should be the MS file path to add to.
126
+ keep_sim: True # Optional - Whether to keep the simulation files generated by tabsim after adding to RFI visibilities to accumulate_ms. This includes all data including generated MS files.
123
127
  flag_data: True # Optional - Whether to apply ideal 3sigma flags
124
128
  overwrite: False # Optional - Whether to overwrite a previous simulation with the same name
125
129
  path: ./ # Optional - Path to where the simulation should be saved
126
130
  prefix: null # Optional - Prefix used in the simulation file name
127
131
  suffix: null # Optional - Suffix used in the simulation file name
132
+ ##############
133
+ # RFI sources
134
+ ##############
128
135
  rfi_sources:
129
136
  #######################################
130
137
  # Circular trajectory based satellites
@@ -164,7 +171,7 @@ rfi_sources:
164
171
  telescope:
165
172
  latitude: null # Required - Latitude of the telescope location in decimal degrees. North is +ve
166
173
  longitude: null # Required - Longitude of the telescope in decimal degrees. East from Greenwich meridian
167
- elevation: null # Required - Elevation of the telescope above the WGS84 Earth ellipsoid model in metres.
174
+ elevation: 0 # Required - Elevation of the telescope above the WGS84 Earth ellipsoid model in metres.
168
175
  dish_d: null # Required - Dish diameter in metres
169
176
  enu_path: null # Required if itrf_path is null - Path to the csv file of the antennas in East, North, Up frame, in metres, relative to the telescope location
170
177
  itrf_path: null # Required if enu_path is null - Path to the csv file contaning the antenna positions in International Terrestrial Reference Frame in metres.