Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Discussion PR on SpectrumCollections decorator #471

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions specutils/manipulation/resample.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
from astropy.nddata import StdDevUncertainty, VarianceUncertainty, InverseVariance

from ..spectra import Spectrum1D
from ..spectra.spectrum_collection import runs_on_spectrum_collection

__all__ = ['ResamplerBase', 'FluxConservingResampler',
'LinearInterpolatedResampler', 'SplineInterpolatedResampler']
__all__ = ['ResamplerBase', 'FluxConservingResampler', 'LinearInterpolatedResampler', 'SplineInterpolatedResampler']


class ResamplerBase(ABC):
Expand Down Expand Up @@ -137,6 +137,7 @@ def _resample_matrix(self, orig_lamb, fin_lamb):

# set bins that don't overlap 100% with original bins
# to zero by checking edges, and applying generated mask
# to zero by checking edges, and applying generated mask
left_clip = np.where(fin_edges[:-1] - orig_edges[0] < 0, 0, 1)
right_clip = np.where(orig_edges[-1] - fin_edges[1:] < 0, 0, 1)
keep_overlapping_matrix = left_clip * right_clip
Expand All @@ -145,6 +146,7 @@ def _resample_matrix(self, orig_lamb, fin_lamb):

return resamp_mat

@runs_on_spectrum_collection
def resample1d(self, orig_spectrum, fin_lamb):
"""
Create a re-sampling matrix to be used in re-sampling spectra in a way
Expand Down
32 changes: 32 additions & 0 deletions specutils/spectra/spectrum_collection.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import functools

import astropy.units as u
import numpy as np
Expand Down Expand Up @@ -244,3 +245,34 @@ def __repr__(self):
Uncertainty type: {}""".format(
self.ndim, self.shape, self.flux.unit, self.spectral_axis.unit,
self.uncertainty.uncertainty_type if self.uncertainty is not None else None)


def runs_on_spectrum_collection(func):
"""
Decorator to wrap Spectrum1D manipulation functionality so that it can
run on a SpectrumCollection

For this decorator to work, the first argument in your function/method
should be the Spectrum1D or SpectrumCollection object, although if it's
not it will simply pass the original function.

Another fallout, right now it's expecting this to be attached to a class
method, since it's expecting the first argument to be self, and the second
argument to be the spectrum1D or SpectrumCollection
"""
@functools.wraps(func)

def wrapper(sarg, farg, *args, **kwargs):

if isinstance(farg, SpectrumCollection):
new_spectra = []

for spec in farg:
new_spectra.append(func(sarg, spec, *args, **kwargs))

return SpectrumCollection.from_spectra(new_spectra)

else:
return func(sarg, farg, *args, **kwargs)

return wrapper
19 changes: 18 additions & 1 deletion specutils/tests/test_resample.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from astropy.nddata import InverseVariance, StdDevUncertainty
from astropy.tests.helper import assert_quantity_allclose

from ..spectra.spectrum1d import Spectrum1D
from ..spectra import Spectrum1D, SpectrumCollection
from ..tests.spectral_examples import simulated_spectra
from ..manipulation.resample import FluxConservingResampler, LinearInterpolatedResampler, SplineInterpolatedResampler

Expand Down Expand Up @@ -162,3 +162,20 @@ def test_expanded_grid_interp_spline():
assert_quantity_allclose(results.flux,
np.array([np.nan, 3.98808594, 6.94042969, 6.45869141,
5.89921875, 7.29736328, np.nan, np.nan, np.nan])*u.mJy)


def test_spectrum_collection():
"""
Test if spectrum collection decorator is working with resample
"""

spec = Spectrum1D(spectral_axis=np.linspace(0, 50, 50) * u.AA,
flux = np.random.randn(50) * u.Jy,
uncertainty = StdDevUncertainty(np.random.sample(50), unit='Jy'))
spec1 = Spectrum1D(spectral_axis=np.linspace(20, 60, 50) * u.AA,
flux = np.random.randn(50) * u.Jy,
uncertainty = StdDevUncertainty(np.random.sample(50), unit='Jy'))
spec_coll = SpectrumCollection.from_spectra([spec, spec1])

inst = FluxConservingResampler()
results = inst(spec_coll, np.linspace(20,40,40))