utils.py 5.26 KB
Newer Older
Yannick Roehlly's avatar
Yannick Roehlly committed
1
# -*- coding: utf-8 -*-
2
3
# Copyright (C) 2012, 2013 Centre de données Astrophysiques de Marseille
# Licensed under the CeCILL-v2 licence - see Licence_CeCILL_V2-en.txt
Yannick Roehlly's avatar
Yannick Roehlly committed
4
# Authors: Yannick Roehlly, Médéric Boquien
Yannick Roehlly's avatar
Yannick Roehlly committed
5
6
7

import numpy as np
from scipy.constants import c, pi, parsec
8
from .cosmology import cosmology
Yannick Roehlly's avatar
Yannick Roehlly committed
9
10
11
12
13


def lambda_to_nu(wavelength):
    """Convert wavelength (nm) to frequency (Hz)

Yannick Roehlly's avatar
Yannick Roehlly committed
14
    Parameters
Yannick Roehlly's avatar
Yannick Roehlly committed
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    ----------
    wavelength : float or array of floats
        The wavelength(s) in nm.

    Returns
    -------
    nu : float or array of floats
        The frequency(ies) in Hz.

    """
    return c / (wavelength * 1.e-9)


def nu_to_lambda(frequency):
    """Convert frequency (Hz) to wavelength (nm)

Yannick Roehlly's avatar
Yannick Roehlly committed
31
    Parameters
Yannick Roehlly's avatar
Yannick Roehlly committed
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
    ----------
    frequency : float or numpy.array of floats
        The frequency(ies) in Hz.

    Returns
    -------
    wavelength : float or numpy.array of floats
        The wavelength(s) in nm.

    """
    return 1.e-9 * c / frequency


def best_grid(wavelengths1, wavelengths2):
    """
    Return the best wavelength grid to regrid to arrays

Yannick Roehlly's avatar
Yannick Roehlly committed
49
    Considering the two wavelength grids passed in parameters, this function
Yannick Roehlly's avatar
Yannick Roehlly committed
50
51
52
    compute the best new grid that will be used to regrid the two spectra
    before combining them.

Yannick Roehlly's avatar
Yannick Roehlly committed
53
    Parameters
Yannick Roehlly's avatar
Yannick Roehlly committed
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
    ----------
    wavelengths1, wavelengths2 : array of floats
        The wavelength grids to be 'regrided'.

    Returns
    -------
    new_grid : array of floats
        Array containing all the wavelengths found in the input arrays.

    """
    new_grid = np.hstack((wavelengths1, wavelengths2))
    new_grid.sort()
    new_grid = np.unique(new_grid)

    return new_grid


def luminosity_to_flux(luminosity, redshift=0):
    """
    Convert a luminosity (or luminosity density) to a flux (or flux density).

    F = L / (4πDl2)

Yannick Roehlly's avatar
Yannick Roehlly committed
77
    Parameters
Yannick Roehlly's avatar
Yannick Roehlly committed
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
    ----------
    luminosity : float or array of floats
        Luminosity (typically in W) or luminosity density (W/nm or W/Hz).
    redshift :
        Redshift. If redshift is 0 (the default) the flux at a luminosity
        distance of 10 pc is returned.

    Returns
    -------
    flux : float or array of floats
        The flux (typically in W/m²) of flux density (W/m²/nm or W/m²/Hz).

    """
    if redshift == 0:
        dist = 10 * parsec
    else:
94
        dist = cosmology.luminosity_distance(redshift) * 1.e6 * parsec
Yannick Roehlly's avatar
Yannick Roehlly committed
95

96
97
98
99
100
101
102
103
104
    flux = luminosity / (4 * pi * np.square(dist))

    # astropy 0.3 cosmology functions return quantities
    try:
        result = flux.value
    except AttributeError:
        result = flux

    return result
Yannick Roehlly's avatar
Yannick Roehlly committed
105
106


Yannick Roehlly's avatar
Yannick Roehlly committed
107
def lambda_flambda_to_fnu(wavelength, flambda):
Yannick Roehlly's avatar
Yannick Roehlly committed
108
109
110
    """
    Convert a Fλ vs λ spectrum to Fν vs λ

Yannick Roehlly's avatar
Yannick Roehlly committed
111
    Parameters
Yannick Roehlly's avatar
Yannick Roehlly committed
112
    ----------
Yannick Roehlly's avatar
Yannick Roehlly committed
113
114
115
116
    wavelength : list-like of floats
        The wavelengths in nm.
    flambda : list-like of floats
        Fλ flux density in W/m²/nm (or Lλ luminosity density in W/nm).
Yannick Roehlly's avatar
Yannick Roehlly committed
117
118
119

    Returns
    -------
Yannick Roehlly's avatar
Yannick Roehlly committed
120
121
122
    fnu : array of floats
        The Fν flux density in mJy (or the Lν luminosity density in
        1.e-29 W/Hz).
Yannick Roehlly's avatar
Yannick Roehlly committed
123
124

    """
Yannick Roehlly's avatar
Yannick Roehlly committed
125
126
127
128
    wavelength = np.array(wavelength, dtype=float)
    flambda = np.array(flambda, dtype=float)

    # Factor 1e+29 is to switch from W/m²/Hz to mJy
Yannick Roehlly's avatar
Yannick Roehlly committed
129
    # Factor 1e-9 is to switch from nm to m (only one because the other nm
Yannick Roehlly's avatar
Yannick Roehlly committed
130
131
    # wavelength goes with the Fλ in W/m²/nm).
    fnu = 1e+29 * 1e-9 * flambda * wavelength * wavelength / c
Yannick Roehlly's avatar
Yannick Roehlly committed
132

Yannick Roehlly's avatar
Yannick Roehlly committed
133
    return fnu
Yannick Roehlly's avatar
Yannick Roehlly committed
134
135


Yannick Roehlly's avatar
Yannick Roehlly committed
136
def lambda_fnu_to_flambda(wavelength, fnu):
Yannick Roehlly's avatar
Yannick Roehlly committed
137
138
139
    """
    Convert a Fν vs λ spectrum to Fλ vs λ

Yannick Roehlly's avatar
Yannick Roehlly committed
140
    Parameters
Yannick Roehlly's avatar
Yannick Roehlly committed
141
    ----------
Yannick Roehlly's avatar
Yannick Roehlly committed
142
143
144
145
146
    wavelength : list-like of floats
        The wavelengths in nm.
    fnu : list-like of floats
        The Fν flux density in mJy (of the  Lν luminosity density in
        1.e-29 W/Hz).
Yannick Roehlly's avatar
Yannick Roehlly committed
147
148
149

    Returns
    -------
Yannick Roehlly's avatar
Yannick Roehlly committed
150
151
    flambda : array of floats
        Fλ flux density in W/m²/nm (or Lλ luminosity density in W/nm).
Yannick Roehlly's avatar
Yannick Roehlly committed
152
153

    """
Yannick Roehlly's avatar
Yannick Roehlly committed
154
155
    wavelength = np.array(wavelength, dtype=float)
    fnu = np.array(fnu, dtype=float)
Yannick Roehlly's avatar
Yannick Roehlly committed
156

Yannick Roehlly's avatar
Yannick Roehlly committed
157
158
159
    # Factor 1e-29 is to switch from Jy to W/m²/Hz
    # Factor 1e+9 is to switch from m to nm
    flambda = 1e-29 * 1e+9 * fnu / (wavelength * wavelength) * c
Yannick Roehlly's avatar
Yannick Roehlly committed
160

Yannick Roehlly's avatar
Yannick Roehlly committed
161
    return flambda
Yannick Roehlly's avatar
Yannick Roehlly committed
162
163


Yannick Roehlly's avatar
Yannick Roehlly committed
164
165
def redshift_spectrum(wavelength, flux, redshift, is_fnu=False):
    """Redshit a spectrum
Yannick Roehlly's avatar
Yannick Roehlly committed
166

Yannick Roehlly's avatar
Yannick Roehlly committed
167
    Parameters
Yannick Roehlly's avatar
Yannick Roehlly committed
168
    ----------
Yannick Roehlly's avatar
Yannick Roehlly committed
169
170
171
172
173
174
    wavelength : array like of floats
        The wavelength in nm.
    flux : array like of floats
        The flux or luminosity density.
    redshift : float
        The redshift.
Yannick Roehlly's avatar
Yannick Roehlly committed
175
    is_fnu : boolean
Yannick Roehlly's avatar
Yannick Roehlly committed
176
177
178
        If false (default) the flux is a Fλ density in W/m²/nm (or a Lλ
        luminosity density in W/nm). If true, the flux is a Fν density in mJy
        (or a Lν luminosity density in 1.e-29 W/Hz).
Yannick Roehlly's avatar
Yannick Roehlly committed
179
180
181

    Results
    -------
Yannick Roehlly's avatar
Yannick Roehlly committed
182
183
184
    wavelength, flux : tuple of numpy arrays of floats
        The redshifted spectrum with the same kind of flux (or luminosity)
        density as the input.
Yannick Roehlly's avatar
Yannick Roehlly committed
185
186

    """
Yannick Roehlly's avatar
Yannick Roehlly committed
187
188
189
    wavelength = np.array(wavelength, dtype=float)
    flux = np.array(flux, dtype=float)
    redshift = float(redshift)
Yannick Roehlly's avatar
Yannick Roehlly committed
190

Yannick Roehlly's avatar
Yannick Roehlly committed
191
192
193
194
    if redshift < 0:
        redshift_factor = 1. / (1. - redshift)
    else:
        redshift_factor = 1. + redshift
Yannick Roehlly's avatar
Yannick Roehlly committed
195

Yannick Roehlly's avatar
Yannick Roehlly committed
196
197
198
    if is_fnu:
        # Switch to Fλ
        flux = lambda_fnu_to_flambda(wavelength, flux)
Yannick Roehlly's avatar
Yannick Roehlly committed
199

Yannick Roehlly's avatar
Yannick Roehlly committed
200
201
    wavelength *= redshift_factor
    flux /= redshift_factor
Yannick Roehlly's avatar
Yannick Roehlly committed
202

Yannick Roehlly's avatar
Yannick Roehlly committed
203
204
205
    if is_fnu:
        # Switch back to Fλ
        flux = lambda_flambda_to_fnu(wavelength, flux)
Yannick Roehlly's avatar
Yannick Roehlly committed
206

Yannick Roehlly's avatar
Yannick Roehlly committed
207
    return wavelength, flux