Skip to content

Commit 27ac01c

Browse files
authored
Merge pull request #81 from paranoya/feature/spectra-interpolation
New spectra interpolation methods
2 parents d11fecd + f664816 commit 27ac01c

5 files changed

Lines changed: 607 additions & 42 deletions

File tree

src/pst/SSP.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from astropy import units as u
1010
from astropy import units
1111

12-
from pst.utils import check_unit
12+
from pst.utils import check_unit, flux_conserving_interpolation
1313

1414
class SSPBase(object):
1515
"""Base class that represents a model of Simple Stellar Populations.
@@ -223,32 +223,35 @@ def cut_wavelength(self, wl_min=None, wl_max=None, verbose=True):
223223
if verbose:
224224
print('[SSP] Models cut between {} {}'.format(wl_min, wl_max))
225225

226-
def interpolate_sed(self, new_wl_edges, verbose=True):
226+
def interpolate_sed(self, new_wl, verbose=True, log=False, **interp_kwargs):
227227
"""Flux-conserving interpolation.
228228
229229
Parameters
230230
----------
231-
- new_wl_edges: bin edges of the new interpolated points.
231+
- new_wl: bin centers of the new interpolated points.
232232
"""
233-
if not isinstance(new_wl_edges, units.Quantity):
234-
new_wl_edges *= self.wavelength.unit
233+
if not isinstance(new_wl, units.Quantity):
234+
new_wl = new_wl << self.wavelength.unit
235235

236-
new_wl = (new_wl_edges[1:] + new_wl_edges[:-1]) / 2
237-
dwl = np.diff(new_wl_edges)
238-
ori_dwl = np.hstack((np.diff(self.wavelength),
239-
self.wavelength[-1] - self.wavelength[-2]))
240236
if verbose:
241237
print('[SSP] Interpolating SSP SEDs')
238+
239+
if log:
240+
target_wl = np.log(new_wl.to_value(self.wavelength.unit))
241+
ref_wl = np.log(self.wavelength.value)
242+
else:
243+
target_wl = new_wl
244+
ref_wl = self.wavelength
245+
242246
new_l_lambda = np.empty(
243247
shape=(self.metallicities.size, self.ages.size,
244248
new_wl.size), dtype=np.float32) * self.L_lambda.unit
245249

246250
for i in range(self.L_lambda.shape[0]):
247251
for j in range(self.L_lambda.shape[1]):
248-
f = np.interp(new_wl_edges, self.wavelength,
249-
np.cumsum(self.L_lambda[i, j] * ori_dwl))
250-
new_flux = np.diff(f) / dwl
251-
new_l_lambda[i, j] = new_flux
252+
new_l_lambda[i, j] = flux_conserving_interpolation(
253+
target_wl, ref_wl, self.L_lambda[i, j],
254+
**interp_kwargs)
252255

253256
self.L_lambda = new_l_lambda
254257
self.wavelength = new_wl

src/pst/models.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ def interpolate_ssp_masses(self, ssp: SSPBase, t_obs: u.Gyr,
130130
Stellar masses corresponding to each SSP age and metallicity, in units
131131
of solar masses.
132132
"""
133-
134133
# define age bins from 0 to t_obs
135134
age_bins = np.hstack(
136135
[0 << u.yr, np.sqrt(ssp.ages[1:] * ssp.ages[:-1]), 1e12 << u.yr])
@@ -645,11 +644,12 @@ def stellar_mass_formed(self, times: u.Gyr):
645644
"""
646645
interpolator = interpolate.PchipInterpolator(
647646
self.table_t, self.table_mass)
648-
integral = interpolator(times) << self.table_mass.unit
647+
integral = interpolator(times.to_value(self.table_t.unit)
648+
) << self.table_mass.unit
649649
integral[times > self.table_t[-1]] = self.table_mass[-1]
650650
integral[times < self.table_t[0]] = 0
651651
return integral
652-
652+
653653
@u.quantity_input
654654
def ism_metallicity(self, times: u.Gyr):
655655
"""Evaluate the integral of the SFR over a given set of times.

0 commit comments

Comments
 (0)