Source code for dsigma.helpers

"""Convenience functions for the dsigma pipeline."""

import numpy as np
from scipy.interpolate import make_interp_spline

from astropy import units as u

__all__ = ['interpolate_over_redshift', 'in_degrees', 'spherical_to_cartesian']


[docs] def interpolate_over_redshift(f, z, *args, **kwargs): """Interpolate a function over redshift. For many cosmological calculations such as comoving distances performing the precise calculation for all objects in the catalog would be very expensive. Instead, we can perform the calculation on a grid in redshift and then interpolate. For most calculations, this is extremely accurate and much faster. Parameters ---------- f : callable Function to evaluate over redshift. z : numpy.ndarray Redshifts to evaluate. *args Additional arguments passed to `f`. **kwargs Extra keyword arguments passed to `f`. Returns ------- f_of_z : numpy.ndarray or astropy.units.quantity.Quantity Interpolated values. """ z_min, z_max = np.amin(z), np.amax(z) if z_min == z_max: return np.repeat(f(z[0], *args, **kwargs), len(z)) a_support = np.linspace(1.0 / (1 + z_max), 1.0 / (1 + z_min), 10000) y_support = f(1 / a_support - 1, *args, **kwargs) # Interpolating the sorted array is faster. idx = np.argsort(z) y = make_interp_spline(a_support, y_support)(1.0 / (1 + z[idx])) y[idx] = y if isinstance(y_support, u.Quantity): y = y * y_support.unit return y
[docs] def in_degrees(angle): """Add a degree unit to an angle if it doesn't have a unit, yet. Parameters ---------- angle : astropy.units.quantity.Quantity Angle with or without units. Returns ------- angle : astropy.units.quantity.Quantity Angle with units. """ if angle.unit == u.Unit(''): angle = u.Quantity(angle.value, u.deg, copy=False) return angle.to(u.deg)
[docs] def spherical_to_cartesian(ra, dec): """Convert spherical coordinates to Cartesian coordinates on a unit sphere. Parameters ---------- ra : astropy.units.quantity.Quantity Right ascension. dec : astropy.units.quantity.Quantity Declination. Returns ------- x, y, z : float or numpy.ndarray Cartesian coordinates. """ x = np.cos(ra) * np.cos(dec) y = np.sin(ra) * np.cos(dec) z = np.sin(dec) return x, y, z