Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simulate correlated noise #1645

Merged
merged 12 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG-unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ the released changes.
- Added radial velocity methods for binary models
- Support for wideband data in `pint.bayesian` (no correlated noise).
- Added `DMWaveX` model (Fourier representation of DM noise)
- Simulate correlated noise using `pint.simulate` functions and the `zima` script.
abhisrkckl marked this conversation as resolved.
Show resolved Hide resolved
### Fixed
- Wave model `validate()` can correctly use PEPOCH to assign WAVEEPOCH parameter
- Fixed RTD by specifying theme explicitly.
Expand Down
2 changes: 1 addition & 1 deletion src/pint/data/examples/B1855+09_NANOGrav_9yv1.gls.par
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ FD3 1.07526915D-04 1 2.50177766D-05
SOLARN0 0.00
EPHEM DE421
ECL IERS2003
CLK TT(BIPM)
CLK TT(BIPM2019)
UNITS TDB
TIMEEPH FB90
#T2CMETHOD TEMPO
Expand Down
12 changes: 11 additions & 1 deletion src/pint/scripts/zima.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ def main(argv=None):
default=False,
help="Actually add in random noise, or just populate the column",
)
parser.add_argument(
"--addcorrnoise",
action="store_true",
default=False,
help="Add in a correlated noise realization if it's present in the model",
)
parser.add_argument(
"--wideband",
action="store_true",
Expand Down Expand Up @@ -127,13 +133,17 @@ def main(argv=None):
freq=np.atleast_1d(args.freq) * u.MHz,
fuzz=args.fuzzdays * u.d,
add_noise=args.addnoise,
add_correlated_noise=args.addcorrnoise,
wideband=args.wideband,
wideband_dm_error=args.dmerror * pint.dmu,
)
else:
log.info(f"Reading initial TOAs from {args.inputtim}")
ts = pint.simulation.make_fake_toas_fromtim(
args.inputtim, model=m, add_noise=args.addnoise
args.inputtim,
model=m,
add_noise=args.addnoise,
add_correlated_noise=args.addcorrnoise,
)

# Write TOAs to a file
Expand Down
47 changes: 42 additions & 5 deletions src/pint/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def get_fake_toa_clock_versions(model, include_bipm=False, include_gps=True):
}


def make_fake_toas(ts, model, add_noise=False, name="fake"):
def make_fake_toas(ts, model, add_noise=False, add_correlated_noise=False, name="fake"):
"""Make toas from an array of times

Can include alternating frequencies if fed an array of frequencies,
Expand All @@ -142,6 +142,8 @@ def make_fake_toas(ts, model, add_noise=False, name="fake"):
current model
add_noise : bool, optional
Add noise to the TOAs (otherwise `error` just populates the column)
add_correlated_noise : bool, optional
Add correlated noise to the TOAs if it's present in the timing mode.
name : str, optional
Name for the TOAs (goes into the flags)

Expand All @@ -156,6 +158,13 @@ def make_fake_toas(ts, model, add_noise=False, name="fake"):
"""
tsim = deepcopy(ts)
zero_residuals(tsim, model)

if add_correlated_noise:
U = model.noise_model_designmatrix(tsim)
b = model.noise_model_basis_weight(tsim)
corrn = (U @ (b**0.5 * np.random.randn(len(b)))) << u.s
tsim.adjust_TOAs(time.TimeDelta(corrn))

if add_noise:
# this function will include EFAC and EQUAD
err = model.scaled_toa_uncertainty(tsim) * np.random.normal(size=len(tsim))
Expand Down Expand Up @@ -198,6 +207,7 @@ def make_fake_toas_uniform(
obs="GBT",
error=1 * u.us,
add_noise=False,
add_correlated_noise=False,
wideband=False,
wideband_dm_error=1e-4 * pint.dmu,
name="fake",
Expand Down Expand Up @@ -229,6 +239,8 @@ def make_fake_toas_uniform(
uncertainty to attach to each TOA
add_noise : bool, optional
Add noise to the TOAs (otherwise `error` just populates the column)
add_correlated_noise : bool, optional
Add correlated noise to the TOAs if it's present in the timing mode.
wideband : bool, optional
Whether to include wideband DM information with each TOA; default is
not to include any wideband DM information. If True, the DM associated
Expand Down Expand Up @@ -301,7 +313,13 @@ def make_fake_toas_uniform(
if wideband:
ts = update_fake_dms(model, ts, wideband_dm_error, add_noise)

return make_fake_toas(ts, model=model, add_noise=add_noise, name=name)
return make_fake_toas(
ts,
model=model,
add_noise=add_noise,
add_correlated_noise=add_correlated_noise,
name=name,
)


def make_fake_toas_fromMJDs(
Expand All @@ -311,6 +329,7 @@ def make_fake_toas_fromMJDs(
obs="GBT",
error=1 * u.us,
add_noise=False,
add_correlated_noise=False,
wideband=False,
wideband_dm_error=1e-4 * pint.dmu,
name="fake",
Expand All @@ -336,6 +355,8 @@ def make_fake_toas_fromMJDs(
uncertainty to attach to each TOA
add_noise : bool, optional
Add noise to the TOAs (otherwise `error` just populates the column)
add_correlated_noise : bool, optional
Add correlated noise to the TOAs if it's present in the timing mode.
wideband : astropy.units.Quantity, optional
Whether to include wideband DM values with each TOA; default is
not to include any DM information
Expand Down Expand Up @@ -396,10 +417,18 @@ def make_fake_toas_fromMJDs(
if wideband:
ts = update_fake_dms(model, ts, wideband_dm_error, add_noise)

return make_fake_toas(ts, model=model, add_noise=add_noise, name=name)
return make_fake_toas(
ts,
model=model,
add_noise=add_noise,
add_correlated_noise=add_correlated_noise,
name=name,
)


def make_fake_toas_fromtim(timfile, model, add_noise=False, name="fake"):
def make_fake_toas_fromtim(
timfile, model, add_noise=False, add_correlated_noise=False, name="fake"
):
"""Make fake toas with the same times as an input tim file

Can include alternating frequencies if fed an array of frequencies,
Expand All @@ -413,6 +442,8 @@ def make_fake_toas_fromtim(timfile, model, add_noise=False, name="fake"):
current model
add_noise : bool, optional
Add noise to the TOAs (otherwise `error` just populates the column)
add_correlated_noise : bool, optional
Add correlated noise to the TOAs if it's present in the timing mode.
name : str, optional
Name for the TOAs (goes into the flags)

Expand All @@ -432,7 +463,13 @@ def make_fake_toas_fromtim(timfile, model, add_noise=False, name="fake"):
dm_errors = input_ts.get_dm_errors()
ts = update_fake_dms(model, ts, dm_errors, add_noise)

return make_fake_toas(input_ts, model=model, add_noise=add_noise, name=name)
return make_fake_toas(
input_ts,
model=model,
add_noise=add_noise,
add_correlated_noise=add_correlated_noise,
name=name,
)


def calculate_random_models(
Expand Down
2 changes: 2 additions & 0 deletions tests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.ipynb
chains/*
abhisrkckl marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 1 addition & 1 deletion tests/datafile/B1855+09_NANOGrav_9yv1.gls.par
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ FD3 1.07526915D-04 1 2.50177766D-05
SOLARN0 0.00
EPHEM DE421
ECL IERS2003
CLK TT(BIPM)
CLK TT(BIPM2019)
UNITS TDB
TIMEEPH FB90
#T2CMETHOD TEMPO
Expand Down
8 changes: 8 additions & 0 deletions tests/test_zima.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,11 @@ def test_zima_fuzzdays(tmp_path):
lines = sys.stdout.getvalue()
finally:
sys.stdout = saved_stdout


def test_zima_corrnoise(tmp_path):
parfile = datadir / "B1855+09_NANOGrav_9yv1.gls.par"
output_timfile = tmp_path / "fake_testzima.tim"
cmd = f"--addnoise --addcorrnoise {parfile} {output_timfile}"
zima.main(cmd.split())
assert os.path.isfile(output_timfile)
Loading