lisainstrument 2.1.0__tar.gz → 2.2.0__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 (92) hide show
  1. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/PKG-INFO +5 -6
  2. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/instru/instru_file_reader.py +28 -3
  3. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/instru/instru_file_reader_v2_0_0.py +28 -3
  4. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/instru/instru_formulas.py +8 -2
  5. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/instru/instru_model.py +6 -0
  6. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/instru/instru_noises.py +11 -0
  7. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/instru/instru_store.py +4 -0
  8. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/instrument.py +27 -10
  9. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/noisy/__init__.py +5 -0
  10. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/noisy/noise_defs.py +212 -25
  11. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/noisy/noise_defs_lisa.py +210 -62
  12. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/pyproject.toml +5 -4
  13. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/LICENSE +0 -0
  14. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/README.md +0 -0
  15. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/__init__.py +0 -0
  16. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/__main__.py +0 -0
  17. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/cli/__init__.py +0 -0
  18. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/cli/run_simulation.py +0 -0
  19. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/freqplan/__init__.py +0 -0
  20. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/freqplan/fplan_file.py +0 -0
  21. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/freqplan/fplan_source.py +0 -0
  22. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/freqplan/fplan_source_interp.py +0 -0
  23. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/glitches/__init__.py +0 -0
  24. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/glitches/glitch_file.py +0 -0
  25. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/glitches/glitch_source.py +0 -0
  26. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/glitches/glitch_source_interp.py +0 -0
  27. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/gwsource/__init__.py +0 -0
  28. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/gwsource/gw_file.py +0 -0
  29. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/gwsource/gw_source.py +0 -0
  30. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/gwsource/hdf5util.py +0 -0
  31. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/instru/__init__.py +0 -0
  32. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/instru/instru_defaults.py +0 -0
  33. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/instru/instru_filter.py +0 -0
  34. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/instru/instru_fplan.py +0 -0
  35. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/instru/instru_glitchsrc.py +0 -0
  36. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/instru/instru_gwsrc.py +0 -0
  37. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/instru/instru_locking.py +0 -0
  38. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/instru/instru_orbsrc.py +0 -0
  39. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/instru/instru_store_v2_0_0.py +0 -0
  40. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/legacy/__init__.py +0 -0
  41. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/legacy/containers.py +0 -0
  42. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/legacy/dsp.py +0 -0
  43. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/legacy/dynamic_delay_dsp.py +0 -0
  44. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/legacy/fixed_shift_dsp.py +0 -0
  45. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/legacy/hexagon.py +0 -0
  46. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/legacy/legacy_plots.py +0 -0
  47. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/legacy/noises.py +0 -0
  48. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/legacy/pyplnoise/LICENSE +0 -0
  49. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/legacy/pyplnoise/__init__.py +0 -0
  50. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/legacy/pyplnoise/pyplnoise.py +0 -0
  51. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/noisy/estimate_psd.py +0 -0
  52. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/noisy/noise_gen_numpy.py +0 -0
  53. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/orbiting/__init__.py +0 -0
  54. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/orbiting/constellation_enums.py +0 -0
  55. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/orbiting/orbit_file.py +0 -0
  56. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/orbiting/orbit_source.py +0 -0
  57. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/orbiting/orbit_source_interp.py +0 -0
  58. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/sigpro/__init__.py +0 -0
  59. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/sigpro/adaptive_delay_numpy.py +0 -0
  60. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/sigpro/chunked_splines.py +0 -0
  61. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/sigpro/dynamic_delay_numpy.py +0 -0
  62. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/sigpro/fir_filters_numpy.py +0 -0
  63. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/sigpro/fixed_shift_numpy.py +0 -0
  64. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/sigpro/iir_filters_numpy.py +0 -0
  65. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/sigpro/regular_interpolators.py +0 -0
  66. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/sigpro/shift_inversion_numpy.py +0 -0
  67. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/sigpro/types_numpy.py +0 -0
  68. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/__init__.py +0 -0
  69. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/analysis.py +0 -0
  70. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/array.py +0 -0
  71. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/delay.py +0 -0
  72. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/derivative.py +0 -0
  73. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/expression.py +0 -0
  74. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/firfilter.py +0 -0
  75. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/graph_util.py +0 -0
  76. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/hdf5_store.py +0 -0
  77. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/iirfilter.py +0 -0
  78. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/integrate.py +0 -0
  79. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/noise.py +0 -0
  80. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/noise_alt.py +0 -0
  81. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/null_store.py +0 -0
  82. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/numpy_store.py +0 -0
  83. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/sampling.py +0 -0
  84. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/scheduler.py +0 -0
  85. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/scheduler_dask.py +0 -0
  86. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/scheduler_serial.py +0 -0
  87. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/segments.py +0 -0
  88. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/shift_inv.py +0 -0
  89. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/store.py +0 -0
  90. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/streams.py +0 -0
  91. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/streams/time.py +0 -0
  92. {lisainstrument-2.1.0 → lisainstrument-2.2.0}/lisainstrument/version.py +0 -0
@@ -1,18 +1,17 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: lisainstrument
3
- Version: 2.1.0
3
+ Version: 2.2.0
4
4
  Summary: Simulates the LISA measurement chain (noise and signals) and generates telemetry data
5
5
  Home-page: https://gitlab.in2p3.fr/lisa-simulation/instrument
6
6
  License: BSD 3-Clause
7
7
  Author: Jean-Baptiste Bayle
8
8
  Author-email: j2b.bayle@gmail.com
9
- Maintainer: Jean-Baptiste Bayle
10
- Maintainer-email: j2b.bayle@gmail.com
11
- Requires-Python: >=3.10,<4.0
9
+ Maintainer: Wolfgang Kastaun
10
+ Maintainer-email: wolfgang.kastaun@aei.mpg.de
11
+ Requires-Python: >=3.11,<4.0
12
12
  Classifier: Intended Audience :: Science/Research
13
13
  Classifier: License :: Other/Proprietary License
14
14
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.10
16
15
  Classifier: Programming Language :: Python :: 3.11
17
16
  Classifier: Programming Language :: Python :: 3.12
18
17
  Classifier: Programming Language :: Python :: 3.13
@@ -27,7 +26,7 @@ Requires-Dist: lisaconstants (>=2.0.1,<3.0.0)
27
26
  Requires-Dist: matplotlib (>=3.9.2,<4.0.0)
28
27
  Requires-Dist: numpy (>=2.1.2,<3.0.0)
29
28
  Requires-Dist: pyyaml (>=6.0.2,<7.0.0)
30
- Requires-Dist: scipy (>=1.14.1,<2.0.0)
29
+ Requires-Dist: scipy (>=1.17.1,<2.0.0)
31
30
  Requires-Dist: typing-extensions (>=4.15.0,<5.0.0)
32
31
  Project-URL: Documentation, https://lisa-simulation.pages.in2p3.fr/instrument
33
32
  Project-URL: Download, https://gitlab.in2p3.fr/lisa-simulation/instrument/-/releases
@@ -79,7 +79,7 @@ class SimResultFile:
79
79
  Arguments:
80
80
  path: Path of the a HDF5 file created by store_instru_hdf5
81
81
  """
82
- self._h5f = h5py.File(str(path), "r")
82
+ self._h5f_raw = h5py.File(str(path), "r")
83
83
  self._version: Final = Version(self._h5f.attrs["version_format"])
84
84
 
85
85
  if not SimResultFile.format_specifier().contains(self._version):
@@ -126,9 +126,34 @@ class SimResultFile:
126
126
  i: _unique_index_range(r) for i, r in ranges.items()
127
127
  }
128
128
 
129
+ @property
130
+ def _h5f(self) -> h5py.File:
131
+ if self._h5f_raw is None:
132
+ msg = "SimResultFile used after closing it"
133
+ raise RuntimeError(msg)
134
+ return self._h5f_raw
135
+
136
+ def close(self) -> None:
137
+ """Close file
138
+
139
+ Note the interface provides a context manager, consider using `with`
140
+ mechanism instead
141
+ """
142
+ if self._h5f_raw is not None:
143
+ self._h5f_raw.close()
144
+ self._h5f_raw = None
145
+
129
146
  def __del__(self):
130
- """File is automatically closed"""
131
- self._h5f.close()
147
+ """HDF5 file is automatically closed"""
148
+ self.close()
149
+
150
+ def __enter__(self):
151
+ """Enter context"""
152
+ return self
153
+
154
+ def __exit__(self, exc_type, exc_val, exc_tb):
155
+ """Exit context"""
156
+ self.close()
132
157
 
133
158
  @property
134
159
  def format_version(self) -> Version:
@@ -70,7 +70,7 @@ class SimResultFile:
70
70
  Arguments:
71
71
  path: Path of the a HDF5 file created by store_instru_hdf5
72
72
  """
73
- self._h5f = h5py.File(str(path), "r")
73
+ self._h5f_raw = h5py.File(str(path), "r")
74
74
  self._version: Final = Version(self._h5f.attrs["version_format"])
75
75
 
76
76
  if not SimResultFile.format_specifier().contains(self._version):
@@ -117,9 +117,34 @@ class SimResultFile:
117
117
  i: _unique_index_range(r) for i, r in ranges.items()
118
118
  }
119
119
 
120
+ @property
121
+ def _h5f(self) -> h5py.File:
122
+ if self._h5f_raw is None:
123
+ msg = "SimResultFile used after closing it"
124
+ raise RuntimeError(msg)
125
+ return self._h5f_raw
126
+
127
+ def close(self) -> None:
128
+ """Close file
129
+
130
+ Note the interface provides a context manager, consider using `with`
131
+ mechanism instead
132
+ """
133
+ if self._h5f_raw is not None:
134
+ self._h5f_raw.close()
135
+ self._h5f_raw = None
136
+
120
137
  def __del__(self):
121
- """File is automatically closed"""
122
- self._h5f.close()
138
+ """HDF5 file is automatically closed"""
139
+ self.close()
140
+
141
+ def __enter__(self):
142
+ """Enter context"""
143
+ return self
144
+
145
+ def __exit__(self, exc_type, exc_val, exc_tb):
146
+ """Exit context"""
147
+ self.close()
123
148
 
124
149
  @property
125
150
  def format_version(self) -> Version:
@@ -245,22 +245,28 @@ def scet_wrt_tps_distant(
245
245
  def adjacent_carrier_fluctuations(
246
246
  local_carrier_fluctuations_: np.ndarray | float,
247
247
  backlink_noises_: np.ndarray | float,
248
+ reciprocal_backlink_noises_: np.ndarray | float,
248
249
  *,
249
250
  central_freq: float,
250
251
  ) -> np.ndarray | float:
251
252
  """Compute adjacent_carrier_fluctuations"""
252
- return local_carrier_fluctuations_ + central_freq * backlink_noises_
253
+ return local_carrier_fluctuations_ + central_freq * (
254
+ backlink_noises_ + reciprocal_backlink_noises_
255
+ )
253
256
 
254
257
 
255
258
  @stream_expression(np.float64)
256
259
  def adjacent_usb_fluctuations(
257
260
  adjacent_usb_fluctuations_: np.ndarray | float,
258
261
  backlink_noises_: np.ndarray | float,
262
+ reciprocal_backlink_noises_: np.ndarray | float,
259
263
  *,
260
264
  central_freq: float,
261
265
  ) -> np.ndarray | float:
262
266
  """Compute adjacent_usb_fluctuations"""
263
- return adjacent_usb_fluctuations_ + central_freq * backlink_noises_
267
+ return adjacent_usb_fluctuations_ + central_freq * (
268
+ backlink_noises_ + reciprocal_backlink_noises_
269
+ )
264
270
 
265
271
 
266
272
  @for_each_mosa
@@ -456,6 +456,7 @@ class ModelConstellation: # pylint: disable = too-few-public-methods
456
456
  mosa.value: compute.adjacent_usb_fluctuations(
457
457
  self.local_usb_fluctuations[mosa.adjacent.value],
458
458
  self.backlink_noises[mosa.value],
459
+ self.reciprocal_backlink_noises[mosa.sat.value],
459
460
  central_freq=cfg.central_freq,
460
461
  )
461
462
  for mosa in MosaID
@@ -1511,6 +1512,9 @@ class ModelConstellation: # pylint: disable = too-few-public-methods
1511
1512
  ## Backlink noise
1512
1513
 
1513
1514
  self.backlink_noises = self._generate_noise_mosas(noises.noise_def_backlink)
1515
+ self.reciprocal_backlink_noises = self._generate_noise_sats(
1516
+ noises.noise_def_reciprocal_backlink
1517
+ )
1514
1518
 
1515
1519
  ## Test-mass acceleration noise
1516
1520
 
@@ -1704,6 +1708,7 @@ class ModelConstellation: # pylint: disable = too-few-public-methods
1704
1708
  compute.adjacent_carrier_fluctuations(
1705
1709
  results.local_carrier_fluctuations[mosa.adjacent],
1706
1710
  self.backlink_noises[mosa.value],
1711
+ self.reciprocal_backlink_noises[mosa.sat.value],
1707
1712
  central_freq=cfg.central_freq,
1708
1713
  )
1709
1714
  )
@@ -1863,6 +1868,7 @@ class ModelConstellation: # pylint: disable = too-few-public-methods
1863
1868
  compute.adjacent_carrier_fluctuations(
1864
1869
  results.local_carrier_fluctuations[mosa.adjacent],
1865
1870
  self.backlink_noises[mosa.value],
1871
+ self.reciprocal_backlink_noises[mosa.sat.value],
1866
1872
  central_freq=cfg.central_freq,
1867
1873
  )
1868
1874
  )
@@ -22,6 +22,7 @@ from lisainstrument.noisy import (
22
22
  NoiseDefModulation,
23
23
  NoiseDefOMS,
24
24
  NoiseDefRanging,
25
+ NoiseDefReciprocalBacklink,
25
26
  NoiseDefTestMass,
26
27
  TestMassNoiseShape,
27
28
  )
@@ -40,6 +41,7 @@ class InstruNoisesConfig:
40
41
  modulation_asds: dict[MosaID, float]
41
42
  ranging_asds: dict[MosaID, float]
42
43
  backlink_asds: dict[MosaID, float]
44
+ reciprocal_backlink_asds: dict[SatID, float]
43
45
  backlink_fknees: dict[MosaID, float]
44
46
  testmass_asds: dict[MosaID, float]
45
47
  testmass_fknees: dict[MosaID, float]
@@ -133,6 +135,15 @@ class InstruNoises: # pylint: disable = too-many-public-methods
133
135
  name=f"backlink_{mosa.value}",
134
136
  )
135
137
 
138
+ def noise_def_reciprocal_backlink(self, sc: SatID) -> NoiseDefBase:
139
+ """Definition of reciprocal backlink noise used for given SC"""
140
+ cfg = self._config
141
+ return NoiseDefReciprocalBacklink(
142
+ displacement_asd_onesided=cfg.reciprocal_backlink_asds[sc],
143
+ f_sample=cfg.physics_fs,
144
+ name=f"reciprocal_backlink_sc_{sc.value}",
145
+ )
146
+
136
147
  def noise_def_testmass(self, mosa: MosaID) -> NoiseDefBase:
137
148
  """Definition of testmass noise used for given MOSA"""
138
149
  cfg = self._config
@@ -518,6 +518,9 @@ class SimMoreDatasetsSat:
518
518
  scet_wrt_tcb_withinitial: SamplesSatsType = _dataset(
519
519
  False, False, IdxSpace.PHYSICS_EXT
520
520
  )
521
+ reciprocal_backlink_noises: SamplesSatsType = _dataset(
522
+ False, False, IdxSpace.PHYSICS
523
+ )
521
524
 
522
525
 
523
526
  @dataclass(kw_only=True, frozen=True)
@@ -644,6 +647,7 @@ class SimMetaData:
644
647
  ranging_asds: dict[str, float]
645
648
  prn_ambiguity: float | None
646
649
  backlink_asds: dict[str, float]
650
+ reciprocal_backlink_asds: dict[str, float]
647
651
  backlink_fknees: dict[str, float]
648
652
  testmass_asds: dict[str, float]
649
653
  testmass_fknees: dict[str, float]
@@ -95,7 +95,8 @@ class Instrument:
95
95
  fplan: path to frequency-plan file, dictionary of locking beatnote frequencies [Hz],
96
96
  or 'static' for a default set of constant locking beatnote frequencies
97
97
  laser_asds: dictionary of amplitude spectral densities for laser noise [Hz/sqrt(Hz)]
98
- laser_shape: laser noise spectral shape, either 'white' or 'white+infrared'
98
+ laser_shape: laser noise spectral shape, choices are 'white', 'white+infrared',
99
+ 'white+infrared_stationary'
99
100
  central_freq: laser central frequency from which all offsets are computed [Hz]
100
101
  offset_freqs: dictionary of laser frequency offsets for unlocked lasers [Hz],
101
102
  defined with respect to :attr:`lisainstrument.Instrument.central_freq`,
@@ -116,10 +117,13 @@ class Instrument:
116
117
  clockinv_maxiter: maximum number of iterations for clock noise inversion
117
118
  backlink_asds: dictionary of amplitude spectral densities for backlink noise [m/sqrt(Hz)]
118
119
  backlink_fknees: dictionary of cutoff frequencied for backlink noise [Hz]
120
+ reciprocal_backlink_asds: dictionary of amplitude spectral densities
121
+ for reciprocal backlink noise [m/sqrt(Hz)]
119
122
  testmass_asds: dictionary of amplitude spectral densities for test-mass noise [ms^(-2)/sqrt(Hz)]
120
123
  testmass_fknees: dictionary of low-frequency cutoff frequencies for test-mass noise [Hz]
121
124
  testmass_fbreak: dictionary of high-frequency break frequencies for test-mass noise [Hz]
122
- testmass_shape: test-mass noise spectral shape, either 'original' or 'lowfreq-relax'
125
+ testmass_shape: test-mass noise spectral shape, choices are 'original', 'original-stationary',
126
+ 'lowfreq-relax', 'lowfreq-relax-stationary'
123
127
  testmass_frelax: dictionary of low-frequency relaxation frequencies for test-mass noise [Hz]
124
128
  oms_asds: tuple of dictionaries of amplitude spectral densities for OMS noise [m/sqrt(Hz)],
125
129
  ordered as (sci_carrier, sci_usb, tmi_carrier, tmi_usb, ref_carrier, ref_usb)
@@ -197,7 +201,7 @@ class Instrument:
197
201
  lock: str | dict[str, str] = "N1-12",
198
202
  fplan: str | float | dict[str, float] | np.ndarray = "static",
199
203
  laser_asds: float | dict[str, float] = 30.0,
200
- laser_shape: str = "white+infrared",
204
+ laser_shape: str = "white+infrared_stationary",
201
205
  central_freq: float = 2.816e14,
202
206
  offset_freqs="default",
203
207
  # Laser phase modulation
@@ -216,11 +220,12 @@ class Instrument:
216
220
  # Backlink noises
217
221
  backlink_asds: float | dict[str, float] = 3e-12,
218
222
  backlink_fknees: float | dict[str, float] = 2e-3,
223
+ reciprocal_backlink_asds: float | dict[str, float] = 1.7e-9,
219
224
  # Test-mass noise
220
225
  testmass_asds: float | dict[str, float] = 2.4e-15,
221
226
  testmass_fknees: float | dict[str, float] = 0.4e-3,
222
227
  testmass_fbreak: float | dict[str, float] = 8e-3,
223
- testmass_shape: str = "original",
228
+ testmass_shape: str = "original-stationary",
224
229
  testmass_frelax: float | dict[str, float] = 0.8e-4,
225
230
  # OMS noise
226
231
  oms_asds: tuple[float | dict[str, float], ...] = (
@@ -469,9 +474,9 @@ class Instrument:
469
474
  laser_asds, "laser_asds"
470
475
  )
471
476
 
472
- if laser_shape not in ["white", "white+infrared"]:
477
+ if laser_shape not in {e.value for e in LaserNoiseShape}:
473
478
  raise ValueError(f"invalid laser noise spectral shape '{laser_shape}'")
474
- self.laser_shape = laser_shape
479
+ self.laser_shape: Final[str] = str(laser_shape)
475
480
 
476
481
  match modulation_asds:
477
482
  case "default":
@@ -621,6 +626,10 @@ class Instrument:
621
626
  backlink_fknees, "backlink_fknees"
622
627
  )
623
628
 
629
+ self.reciprocal_backlink_asds: Final[SatDictFloat] = param_sat_dict_float(
630
+ reciprocal_backlink_asds, "reciprocal_backlink_asds"
631
+ )
632
+
624
633
  match oms_asds:
625
634
  case (sci_carrier, sci_usb, tmi_carrier, tmi_usb, ref_carrier, ref_usb):
626
635
  self.oms_sci_carrier_asds: Final[MosaDictFloat] = param_mosa_dict_float(
@@ -650,11 +659,11 @@ class Instrument:
650
659
  )
651
660
 
652
661
  # Test-mass noise
653
- if testmass_shape not in ["original", "lowfreq-relax"]:
662
+ if testmass_shape not in {e.value for e in TestMassNoiseShape}:
654
663
  raise ValueError(
655
664
  f"invalid test-mass noise spectral shape '{testmass_shape}'"
656
665
  )
657
- self.testmass_shape: Final[str] = testmass_shape
666
+ self.testmass_shape: Final[str] = str(testmass_shape)
658
667
 
659
668
  self.testmass_asds: Final[MosaDictFloat] = param_mosa_dict_float(
660
669
  testmass_asds, "testmass_asds"
@@ -857,6 +866,7 @@ class Instrument:
857
866
  ranging_asds=make_mosa_id_dict(self.ranging_asds),
858
867
  backlink_asds=make_mosa_id_dict(self.backlink_asds),
859
868
  backlink_fknees=make_mosa_id_dict(self.backlink_fknees),
869
+ reciprocal_backlink_asds=make_sat_id_dict(self.reciprocal_backlink_asds),
860
870
  testmass_asds=make_mosa_id_dict(self.testmass_asds),
861
871
  testmass_fknees=make_mosa_id_dict(self.testmass_fknees),
862
872
  testmass_fbreak=make_mosa_id_dict(self.testmass_fbreak),
@@ -943,8 +953,9 @@ class Instrument:
943
953
 
944
954
  Args:
945
955
  excluding: noises to keep on, to be chosen in ('laser', 'modulation',
946
- 'clock', 'test-mass', 'backlink', 'oms', 'ranging', 'angular-jitters', 'dws',
947
- 'moc-time-correlation', 'longitudinal-jitters')
956
+ 'clock', 'test-mass', 'backlink', 'reciprocal_backlink', 'oms',
957
+ 'ranging', 'angular-jitters', 'dws', 'moc-time-correlation',
958
+ 'longitudinal-jitters')
948
959
  """
949
960
 
950
961
  valid_noises = {
@@ -953,6 +964,7 @@ class Instrument:
953
964
  "clock": self.disable_clock_noise,
954
965
  "test-mass": self.disable_testmass_noise,
955
966
  "backlink": self.disable_backlink_noise,
967
+ "reciprocal_backlink": self.disable_reciprocal_backlink_noise,
956
968
  "oms": self.disable_oms_noise,
957
969
  "ranging": self.disable_ranging_noises,
958
970
  "angular-jitters": self.disable_angular_jitters,
@@ -1007,6 +1019,11 @@ class Instrument:
1007
1019
  logger.info("disable backlink noise")
1008
1020
  self.backlink_asds = make_mosa_dict_const(0.0)
1009
1021
 
1022
+ def disable_reciprocal_backlink_noise(self):
1023
+ """Turn off reciprocal backlink noise."""
1024
+ logger.info("disable reciprocal backlink noise")
1025
+ self.reciprocal_backlink_asds = make_sat_dict_const(0.0)
1026
+
1010
1027
  def disable_oms_noise(self):
1011
1028
  """Turn off OMS noise in all interferometers."""
1012
1029
  logger.info("disable oms noise")
@@ -16,13 +16,17 @@ from .noise_defs import (
16
16
  NoiseDefBase,
17
17
  NoiseDefCumSum,
18
18
  NoiseDefFalloff6,
19
+ NoiseDefFalloff6Stat,
19
20
  NoiseDefFalloff8,
21
+ NoiseDefFalloff8Stat,
20
22
  NoiseDefFiltered,
21
23
  NoiseDefGradient,
22
24
  NoiseDefInfraRed,
25
+ NoiseDefInfraRedStat,
23
26
  NoiseDefPink,
24
27
  NoiseDefPowerLaw,
25
28
  NoiseDefRed,
29
+ NoiseDefRedPow,
26
30
  NoiseDefScaled,
27
31
  NoiseDefSum,
28
32
  NoiseDefViolet,
@@ -45,6 +49,7 @@ from .noise_defs_lisa import (
45
49
  NoiseDefModulation,
46
50
  NoiseDefOMS,
47
51
  NoiseDefRanging,
52
+ NoiseDefReciprocalBacklink,
48
53
  NoiseDefTestMass,
49
54
  TestMassNoiseShape,
50
55
  )