Source code for baseband_tasks.dm

# Licensed under the GPLv3 - see LICENSE

import numpy as np
import astropy.units as u


[docs]class DispersionMeasure(u.SpecificTypeQuantity): """Dispersion measure quantity. Quantity for electron column density, normally with units of pc / cm**3, with additional methods to help correct for dispersion delays: `time_delay`, `phase_delay`, and `phase_factor`. Parameters ---------- dm : `~astropy.units.Quantity` or float Dispersion measure value. If a `~astropy.units.Quantity` is passed, it must have units equivalent to pc/cm**3. If a float is passed, units may be passed to ``unit``, or will otherwise be assumed to be pc/cm**3. unit : `~astropy.units.UnitBase` or None Units of ``dm``. If `None` (default), will be set either to the units of ``dm`` if ``dm`` is an `~astropy.units.Quantity`, or pc/cm**3 otherwise. If ``dm`` is a `~astropy.units.Quantity` and ``unit`` is also passed, will try to convert ``dm`` to ``unit``. *args, **kwargs As for `~astropy.units.Quantity`. Notes ----- The constant relating dispersion measure to delay is hardcoded to match that of Tempo. See `Taylor, Manchester, & Lyne (1993) <http://adsabs.harvard.edu/abs/1993ApJS...88..529T>`_. It is accessible as the `dispersion_delay_constant` attribute. """ # Constant hardcoded to match assumption made by tempo. dispersion_delay_constant = u.s / 2.41e-4 * u.MHz**2 * u.cm**3 / u.pc """Dispersion delay constant, hardcoded to match that for Tempo.""" _equivalent_unit = _default_unit = u.pc / u.cm**3
[docs] def time_delay(self, freq, ref_freq=None): r"""Time delay due to dispersion. Parameters ---------- freq : `~astropy.units.Quantity` Frequency at which to evaluate the dispersion delay. ref_freq : `~astropy.units.Quantity`, optional Reference frequency relative to which the dispersion delay is evaluated. If not given, infinite frequency is assumed. Notes ----- Given the dispersion measure :math:`\mathrm{DM}`, frequency :math:`f` and reference frequency :math:`f_\mathrm{ref}`, calculates the time delay (Eqn. 4.7, Lorimer & Kramer's Handbook of Pulsar Astronomy): .. math:: \Delta t = \frac{e^2}{2\pi m_ec} \mathrm{DM}\left(\frac{1} {f_\mathrm{ref}^2} - \frac{1}{f^2}\right) where the dispersion delay constant is taken to be exactly (inverse of Eqn. 6 of Taylor, Manchester, & Lyne 1993): .. math:: \frac{e^2}{2\pi m_ec} = \frac{1}{2.410} \times 10^4\, \mathrm{MHz}^2\,\mathrm{pc}^{-1} \,\mathrm{cm}^3\,\mathrm{s}. """ d = self.dispersion_delay_constant * self ref_freq_inv2 = 0. if ref_freq is None else 1. / ref_freq**2 return d * (1. / freq**2 - ref_freq_inv2)
[docs] def phase_delay(self, freq, ref_freq=None): r"""Phase delay due to dispersion. Parameters ---------- freq : `~astropy.units.Quantity` Frequency at which to evaluate the dispersion delay. ref_freq : `~astropy.units.Quantity`, optional Reference frequency relative to which the dispersion delay is evaluated. If not given, infinite frequency is assumed. Notes ----- Given the dispersion measure :math:`\mathrm{DM}`, frequency :math:`f` and reference frequency :math:`f_\mathrm{ref}`, calculates the phase amplitude of the transfer function (Eqn. 5.21, Lorimer & Kramer's Handbook of Pulsar Astronomy, rewritten to use absolute frequency): .. math:: \Delta \phi = \frac{e^2\mathrm{DM}}{m_ec} f \left(\frac{1} {f_\mathrm{ref}} - \frac{1}{f}\right)^2 """ # Eqn. 5.13 of Lorimer & Kramer integrated along line of sight. d = self.dispersion_delay_constant * u.cycle * self ref_freq_inv = 0. if ref_freq is None else 1. / ref_freq return d * freq * (ref_freq_inv - 1. / freq)**2
[docs] def phase_factor(self, freq, ref_freq=None): """Complex exponential factor due to dispersion. This is just ``exp(1j * phase_delay)``. Parameters ---------- freq : `~astropy.units.Quantity` Frequency at which to evaluate the dispersion delay. ref_freq : `~astropy.units.Quantity`, optional Reference frequency relative to which the dispersion delay is evaluated. If not given, infinite frequency is assumed. """ return np.exp(self.phase_delay(freq, ref_freq).to_value(u.rad) * 1j)