Source code for madcubapy.utils.spectral

import astropy.constants as const
import astropy.units as u
from astropy.units import Quantity
import numpy as np

__all__ = [
    'create_spectral_array',
    'obs_to_rest',
    'rest_to_obs',
    'obs_to_vel',
    'vel_to_obs',
    'rest_to_vel',
    'vel_to_rest',
]

[docs] def create_spectral_array(nchan, cdelt, crpix, crval): """ Create a spectral axis array. Parameters ---------- nchan : `~int` Number of channels in the spectrum. cdelt : `~float` or `~astropy.units.Quantity` Width of a channel. crpix : `~float` Reference channel of the spectrum. crval : `~float` Value of the reference channel. Returns ------- spectral_array : `~numpy.ndarray` or `~astropy.units.Quantity` Returned spectral axis array with units if cdelt is a quantity. """ # if cdelt has units if isinstance(cdelt, Quantity): first_chan = crval - (cdelt.value * crpix) last_chan = crval + (cdelt.value * (nchan-1 - crpix)) spectral_array = np.linspace(first_chan, last_chan, nchan) * cdelt.unit # if cdelt is adimensional else: first_chan = crval - (cdelt * crpix) last_chan = crval + (cdelt * (nchan-1 - crpix)) spectral_array = np.linspace(first_chan, last_chan, nchan) return spectral_array
[docs] def obs_to_rest(obs_freq, radial_velocity, doppler_convention="radio"): """ Convert observed frequency to rest frequency. Parameters ---------- obs_freq : `~astropy.units.Quantity` Observed frequency. radial_velocity : `~astropy.units.Quantity` Radial velocity of the source relative to the observer. doppler_convention : {"radio" (default), "relativistic"} The Doppler convention to use. Returns ------- rest_freq : `~astropy.units.Quantity` Rest frequency. """ if not isinstance(obs_freq, u.Quantity): raise TypeError("obs_freq must be an astropy Quantity.") if not isinstance(radial_velocity, u.Quantity): raise TypeError("vel must be an astropy Quantity.") if doppler_convention == "radio": rest_freq = _obs_to_rest_radio(obs_freq, radial_velocity) elif doppler_convention == "relativistic": rest_freq = _obs_to_rest_rel(obs_freq, radial_velocity) else: raise ValueError( "Doppler convention can only be radio or relativistic.") return rest_freq
[docs] def rest_to_obs(rest_freq, radial_velocity, doppler_convention="radio"): """ Convert rest frequency to observed frequency. Parameters ---------- rest_freq : `~astropy.units.Quantity` Rest frequency. radial_velocity : `~astropy.units.Quantity` Radial velocity of the source relative to the observer. doppler_convention : {"radio" (default), "relativistic"} The Doppler convention to use. Returns ------- obs_freq : `~astropy.units.Quantity` Observed frequency. """ if not isinstance(rest_freq, u.Quantity): raise TypeError("rest_freq must be an astropy Quantity.") if not isinstance(radial_velocity, u.Quantity): raise TypeError("vel must be an astropy Quantity.") if doppler_convention == "radio": obs_freq = _rest_to_obs_radio(rest_freq, radial_velocity) elif doppler_convention == "relativistic": obs_freq = _rest_to_obs_rel(rest_freq, radial_velocity) else: raise ValueError( "Doppler convention can only be radio or relativistic.") return obs_freq
[docs] def obs_to_vel(obs_freq, doppler_rest, doppler_convention="radio"): """ Convert observed frequency to velocity. Parameters ---------- obs_freq : `~astropy.units.Quantity` Observed frequency. doppler_rest : `~astropy.units.Quantity` Rest frequency of the line. doppler_convention : {"radio" (default), "relativistic"} The Doppler convention to use. Returns ------- vel : `~astropy.units.Quantity` Velocity. """ if not isinstance(obs_freq, u.Quantity): raise TypeError("obs_freq must be an astropy Quantity.") if not isinstance(doppler_rest, u.Quantity): raise TypeError("doppler_rest must be an astropy Quantity.") if doppler_convention == "radio": vel = _obs_to_vel_radio(obs_freq, doppler_rest) elif doppler_convention == "relativistic": vel = _obs_to_vel_rel(obs_freq, doppler_rest) else: raise ValueError( "Doppler convention can only be radio or relativistic.") return vel
[docs] def vel_to_obs(vel, doppler_rest, doppler_convention="radio"): """ Convert velocity to observed frequency. Parameters ---------- vel : `~astropy.units.Quantity` Velocity. doppler_rest : `~astropy.units.Quantity` Rest frequency of the line. doppler_convention : {"radio" (default), "relativistic"} The Doppler convention to use. Returns ------- obs_freq : `~astropy.units.Quantity` Observed frequency. """ if not isinstance(vel, u.Quantity): raise TypeError("vel must be an astropy Quantity.") if not isinstance(doppler_rest, u.Quantity): raise TypeError("doppler_rest must be an astropy Quantity.") if doppler_convention == "radio": obs_freq = _vel_to_obs_radio(vel, doppler_rest) elif doppler_convention == "relativistic": obs_freq = _vel_to_obs_rel(vel, doppler_rest) else: raise ValueError( "Doppler convention can only be radio or relativistic.") return obs_freq
[docs] def rest_to_vel(rest_freq, radial_velocity, doppler_rest, doppler_convention="radio"): """ Convert rest frequency to velocity. Parameters ---------- rest_freq : `~astropy.units.Quantity` Observed frequency. radial_velocity : `~astropy.units.Quantity` Radial velocity of the source relative to the observer. doppler_rest : `~astropy.units.Quantity` Rest frequency of the line. doppler_convention : {"radio" (default), "relativistic"} The Doppler convention to use. Returns ------- vel : `~astropy.units.Quantity` Velocity. """ if not isinstance(rest_freq, u.Quantity): raise TypeError("rest_freq must be an astropy Quantity.") if not isinstance(radial_velocity, u.Quantity): raise TypeError("radial_velocity must be an astropy Quantity.") if not isinstance(doppler_rest, u.Quantity): raise TypeError("doppler_rest must be an astropy Quantity.") if doppler_convention not in ["radio", "relativistic"]: raise ValueError( "Doppler convention can only be radio or relativistic.") obs_freq = rest_to_obs(rest_freq, radial_velocity, doppler_convention) vel = obs_to_vel(obs_freq, doppler_rest, doppler_convention) return vel
[docs] def vel_to_rest(vel, radial_velocity, doppler_rest, doppler_convention="radio"): """ Convert velocty to rest frequency. Parameters ---------- vel : `~astropy.units.Quantity` Velocity. radial_velocity : `~astropy.units.Quantity` Radial velocity of the source relative to the observer. doppler_rest : `~astropy.units.Quantity` Rest frequency of the line. doppler_convention : {"radio" (default), "relativistic"} The Doppler convention to use. Returns ------- rest_freq : `~astropy.units.Quantity` Rest frequency. """ if not isinstance(vel, u.Quantity): raise TypeError("vel must be an astropy Quantity.") if not isinstance(radial_velocity, u.Quantity): raise TypeError("radial_velocity must be an astropy Quantity.") if not isinstance(doppler_rest, u.Quantity): raise TypeError("doppler_rest must be an astropy Quantity.") if doppler_convention not in ["radio", "relativistic"]: raise ValueError( "Doppler convention can only be radio or relativistic.") obs_freq = vel_to_obs(vel, doppler_rest, doppler_convention) rest_freq = obs_to_rest(obs_freq, radial_velocity, doppler_convention) return rest_freq
def _obs_to_rest_radio(obs_freq, vel): return obs_freq / (1 - vel / const.c) def _obs_to_rest_rel(obs_freq, vel): beta = vel / const.c return obs_freq * np.sqrt((1 + beta) / (1 - beta)) def _rest_to_obs_radio(rest_freq, vel): return rest_freq * (1 - vel / const.c) def _rest_to_obs_rel(rest_freq, vel): beta = vel / const.c return rest_freq * ((1 - beta) / (1 + beta))**0.5 def _obs_to_vel_radio(obs_freq, rest_freq): return const.c * ((rest_freq - obs_freq) / rest_freq) def _obs_to_vel_rel(obs_freq, rest_freq): R = obs_freq / rest_freq beta = (1 - R**2) / (1 + R**2) return beta * const.c def _vel_to_obs_radio(vel, rest_freq): return rest_freq * (1 - vel / const.c) def _vel_to_obs_rel(vel, rest_freq): beta = (vel / const.c) return rest_freq * ((1 - beta) / (1 + beta))**0.5