Skip to content

Commit

Permalink
Merge branch 'sim-dmgp' into wbfit
Browse files Browse the repository at this point in the history
  • Loading branch information
abhisrkckl committed Dec 18, 2024
2 parents 8860e67 + f6cbcd5 commit e4fb884
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 49 deletions.
9 changes: 3 additions & 6 deletions CHANGELOG-unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,15 @@ the released changes.
- `add_param` returns the name of the parameter (useful for numbered parameters)
- `introduces_dm_errors` class attribute in `NoiseComponent`s to distinguish DM noise
- Simulate correlated DM noise for wideband TOAs
- Abstract base classes `WhiteNoiseComponent` and `CorrelatedNoiseComponent`
- `get_dm_noise_basis` and `get_wideband_noise_basis` methods in `CorrelatedNoiseComponent`s
- `scaled_wideband_uncertainty`, `noise_model_wideband_designmatrix`, `dm_designmatrix`, `wideband_designmatrix`, `full_designmatrix`, and `full_basis_weight` methods in `TimingModel`
- `get_wideband_errors` method in `TOAs`
- `calc_combined_resids` method in `WidebandTOAResiduals`
- Rerun intermittent failures in CI
- micromamba CI environment for testing macOS-latest, without tox

### Fixed
- Changed WAVE_OM units from 1/d to rad/d.
- When EQUAD is created from TNEQ, has proper TCB->TDB conversion info
- TOA selection masks will work when only TOA is the first one
- Condense code in Glitch model and add test coverage.
- `find_empty_masks` will now search through `CMX` parameters
- Fixed some docstrings for binary models.
### Removed
- macOS 12 CI

43 changes: 27 additions & 16 deletions src/pint/models/binary_bt.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
class BinaryBT(PulsarBinary):
"""Blandford and Teukolsky binary model.
This binary model is described in Blandford and Teukolshy 1976. It is
This binary model is described in Blandford and Teukolsky (1976). It is
a relatively simple parametrized post-Keplerian model that does not
support Shapiro delay calculations.
Expand All @@ -36,12 +36,16 @@ class BinaryBT(PulsarBinary):
Notes
-----
Because PINT's binary models all support specification of multiple orbital
frequency derivatives FBn, this is capable of behaving like the model called
BTX in tempo2. The model called BTX in tempo instead supports multiple
(non-interacting) companions, and that is not supported here. Neither can
PINT accept "BTX" as an alias for this model.
frequency derivatives ``FBn``, this is capable of behaving like the model called
``BTX`` in ``tempo2``. The model called ``BTX`` in ``tempo`` instead supports multiple
(non-interacting) companions, and that is not supported here.
References
----------
- Blandford & Teukolsky 1976, ApJ, 205, 580 [1]_
.. [1] https://ui.adsabs.harvard.edu/abs/1976ApJ...205..580B/abstract
See Blandford & Teukolsky 1976, ApJ, 205, 580.
"""

register = True
Expand Down Expand Up @@ -82,16 +86,23 @@ def validate(self):


class BinaryBTPiecewise(PulsarBinary):
"""Model implementing the BT model with piecewise orbital parameters A1X and T0X. This model lets the user specify time ranges and fit for a different piecewise orbital parameter in each time range,
This is a PINT pulsar binary BTPiecewise model class, a subclass of PulsarBinary.
It is a wrapper for stand alone BTPiecewise class defined in
./stand_alone_psr_binary/BT_piecewise.py
The aim for this class is to connect the stand alone binary model with the PINT platform.
BTpiecewise special parameters, where xxxx denotes the 4-digit index of the piece:
T0X_xxxx Piecewise T0 values for piece
A1X_xxxx Piecewise A1 values for piece
XR1_xxxx Lower time boundary of piece
XR2_xxxx Upper time boundary of piece
"""BT model with piecewise orbital parameters ``A1X`` and ``T0X``. This model lets the user specify time ranges and fit for a different piecewise orbital parameter in each time range.
``BTpiecewise`` special parameters, where xxxx denotes the 4-digit index of the piece:
- ``T0X_xxxx``: Piecewise ``T0`` values for piece
- ``A1X_xxxx``: Piecewise ``A1`` values for piece
- ``XR1_xxxx``: Lower time boundary of piece
- ``XR2_xxxx``: Upper time boundary of piece
The actual calculations for this are done in
:class:`pint.models.stand_alone_psr_binaries.BT_piecewise.BTpiecewise`
Parameters supported:
.. paramtable::
:class: pint.models.binary_bt.BinaryBTPiecewise
"""

register = True
Expand Down
8 changes: 7 additions & 1 deletion src/pint/models/dispersion_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,10 @@ def validate(self):
r2[j] = getattr(self, f"DMXR2_{index:04d}").quantity.mjd
indices[j] = index
for j, index in enumerate(DMXR1_mapping):
if (r1[j] == r2[j]) and (r1[j] > 0):
log.warning(
f"Start of DMX_{index:04d} ({r1[j]}) equal to end of DMX_{index:04d} ({r2[j]})"
)
if np.any((r1[j] > r1) & (r1[j] < r2)):
k = np.where((r1[j] > r1) & (r1[j] < r2))[0]
for kk in k.flatten():
Expand All @@ -639,6 +643,8 @@ def validate(self):
log.warning(
f"End of DMX_{index:04d} ({r1[j]}-{r2[j]}) overlaps with DMX_{indices[kk]:04d} ({r1[kk]}-{r2[kk]})"
)
if not hasattr(self, "dmx_toas_selector"):
self.dmx_toas_selector = TOASelect(is_range=True)

def validate_toas(self, toas):
DMX_mapping = self.get_prefix_mapping_component("DMX_")
Expand All @@ -651,7 +657,7 @@ def validate_toas(self, toas):
b = self._parent[DMXR1_mapping[k]].quantity.mjd * u.d
e = self._parent[DMXR2_mapping[k]].quantity.mjd * u.d
mjds = toas.get_mjds()
n = np.sum((b <= mjds) & (mjds < e))
n = np.sum((b <= mjds) & (mjds <= e))
if n == 0:
bad_parameters.append(DMX_mapping[k])
if bad_parameters:
Expand Down
5 changes: 5 additions & 0 deletions src/pint/models/model_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,10 @@ def __call__(
if not hasattr(tm, "NoiseComponent_list"):
setattr(tm, "NoiseComponent_list", [])

tm.meta["allow_tcb"] = allow_tcb_
tm.meta["convert_tcb"] = convert_tcb
tm.meta["allow_T2"] = allow_T2

return tm

def _validate_components(self):
Expand Down Expand Up @@ -851,6 +855,7 @@ def get_model(
**kwargs,
)
model.name = parfile
model.meta["original_name"] = parfile

return model

Expand Down
23 changes: 14 additions & 9 deletions src/pint/models/noise_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,9 +499,11 @@ class PLDMNoise(CorrelatedNoiseComponent):
.. paramtable::
:class: pint.models.noise_model.PLDMNoise
Note
----
Ref: Lentati et al. 2014, MNRAS 437(3), 3004-3023
References
----------
- Lentati et al. 2014, MNRAS 437(3), 3004-3023 [1]_
.. [1] https://ui.adsabs.harvard.edu/abs/2014MNRAS.437.3004L/abstract
"""

Expand Down Expand Up @@ -619,9 +621,11 @@ class PLChromNoise(CorrelatedNoiseComponent):
.. paramtable::
:class: pint.models.noise_model.PLChromNoise
Note
----
Ref: Lentati et al. 2014, MNRAS 437(3), 3004-3023
References
----------
- Lentati et al. 2014, MNRAS 437(3), 3004-3023 [1]_
.. [1] https://ui.adsabs.harvard.edu/abs/2014MNRAS.437.3004L/abstract
"""

register = True
Expand Down Expand Up @@ -731,10 +735,11 @@ class PLRedNoise(CorrelatedNoiseComponent):
.. paramtable::
:class: pint.models.noise_model.PLRedNoise
Note
----
Ref: Lentati et al. 2014, MNRAS 437(3), 3004-3023
References
----------
- Lentati et al. 2014, MNRAS 437(3), 3004-3023 [1]_
.. [1] https://ui.adsabs.harvard.edu/abs/2014MNRAS.437.3004L/abstract
"""

register = True
Expand Down
12 changes: 11 additions & 1 deletion src/pint/models/timing_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

import abc
import copy
import datetime
import inspect
import contextlib
from collections import OrderedDict, defaultdict
Expand Down Expand Up @@ -109,6 +110,9 @@

ignore_prefix = {"DMXF1_", "DMXF2_", "DMXEP_"}

# prefixes of parameters that may need to be checked for empty ranges
prefixes = ["DM", "SW", "CM"]

DEFAULT_ORDER = [
"astrometry",
"jump_delay",
Expand Down Expand Up @@ -225,6 +229,8 @@ class TimingModel:
----------
name : str
The name of the timing model
meta : dict
A dictionary of metadata
component_types : list
A list of the distinct categories of component. For example,
delay components will be register as 'DelayComponent'.
Expand All @@ -239,6 +245,9 @@ def __init__(self, name="", components=[]):
"First parameter should be the model name, was {!r}".format(name)
)
self.name = name
self.meta = {
"read_time": f"{datetime.datetime.now().isoformat()}",
}
self.component_types = []
self.top_level_params = []
self.add_param_from_top(
Expand Down Expand Up @@ -2870,6 +2879,7 @@ def as_parfile(
if include_info:
info_string = pint.utils.info_string(prefix_string="# ", comment=comment)
info_string += f"\n# Format: {format.lower()}"
info_string += "".join([f"\n# {x}: {self.meta[x]}" for x in self.meta])
result_begin = info_string + "\n"
else:
result_begin = ""
Expand Down Expand Up @@ -3008,7 +3018,7 @@ def find_empty_masks(self, toas, freeze=False):
if freeze:
log.info(f"'{maskpar}' has no TOAs so freezing")
getattr(self, maskpar).frozen = True
for prefix in ["DM", "SW"]:
for prefix in prefixes:
mapping = pint.utils.xxxselections(self, toas, prefix=prefix)
for k in mapping:
if len(mapping[k]) == 0:
Expand Down
39 changes: 23 additions & 16 deletions src/pint/models/wavex.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@

class WaveX(DelayComponent):
"""
Implementation of the wave model as a delay correction
Delays are expressed as a sum of sinusoids.
Implementation of the wave model as a delay correction, with delays are expressed as a sum of sinusoids.
Used for decomposition of timing noise into a series of sine/cosine components with the amplitudes as fitted parameters.
Expand All @@ -23,25 +21,34 @@ class WaveX(DelayComponent):
.. paramtable::
:class: pint.models.wavex.WaveX
This is an extension of the L13 method described in Lentati et al., 2013 doi: 10.1103/PhysRevD.87.104021
This model is similar to the TEMPO2 WAVE model parameters and users can convert a `TimingModel` with a Wave model
to a WaveX model and produce the same results. The main differences are that the WaveX frequencies are explicitly stated,
This is an extension of the method described in Lentati et al. (2013).
This model is similar to the TEMPO2 WAVE model parameters and users can convert a :class:`~pint.models/timing_model.TimingModel`
with a :class:`~pint.models.wave.Wave` model to a ``WaveX`` model and produce the same results.
The main differences are that the ``WaveX`` frequencies are explicitly stated,
they do not necessarily need to be harmonics of some base frequency, the wave amplitudes are fittable parameters, and the
sine and cosine amplutides are reported as separate `prefixParameter`s rather than as a single `pairParameter`.
sine and cosine amplutides are reported as separate :class:`~pint.models.parameter.prefixParameter` rather than as a
single :class:`pint.models.parameter.pairParameter`.
Analogous parameters in both models have the same units:
WAVEEPOCH is the same as WXEPOCH
WAVEOM and WXFREQ_000N have units of 1/d
WAVEN and WXSIN_000N/WXCOS_000N have units of seconds
The `pint.utils` functions `translate_wave_to_wavex()` and `translate_wavex_to_wave()` can be used to go back and forth between
two model.
- ``WAVEEPOCH`` is the same as ``WXEPOCH``
- ``WAVEOM`` and ``WXFREQ_000N`` have units of 1/d
- ``WAVEN`` and ``WXSIN_000N/WXCOS_000N`` have units of seconds
The :mod:`pint.utils` functions :func:`~pint.utils.translate_wave_to_wavex` and :func:`~pint.utils.translate_wavex_to_wave`
can be used to go back and forth between two model.
WARNING: If the choice of ``WaveX`` frequencies in a :class:`~pint.models/timing_model.TimingModel` doesn't correspond to harmonics of some base
freqeuncy, it will not be possible to convert it to a :class:`~pint.models.wave.Wave` model.
To set up a ``WaveX`` model, users can use the :mod:`pint.utils` function :func:`~pint.utils.wavex_setup` with either a list of frequencies or a choice
of harmonics of a base frequency determined by ``2 * pi /Timespan``
WARNING: If the choice of WaveX frequencies in a `TimingModel` doesn't correspond to harmonics of some base
freqeuncy, it will not be possible to convert it to a Wave model.
References
----------
- Lentati et al. (2013), PRD, 87, 104021 [1]_
To set up a WaveX model, users can use the `pint.utils` function `wavex_setup()` with either a list of frequencies or a choice
of harmonics of a base frequency determined by 2 * pi /Timespan
.. [1] https://ui.adsabs.harvard.edu/abs/2013PhRvD..87j4021L/abstract
"""

register = True
Expand Down

0 comments on commit e4fb884

Please sign in to comment.