Skip to content

Commit

Permalink
Merge pull request #12 from bmorris3/lightkurve-parser
Browse files Browse the repository at this point in the history
Adding support for subsets in time
  • Loading branch information
bmorris3 authored May 10, 2023
2 parents 03f449d + 7e12c8f commit 001fb10
Show file tree
Hide file tree
Showing 5 changed files with 315 additions and 67 deletions.
15 changes: 2 additions & 13 deletions lcviz/conftest.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import numpy as np
import pytest
from astropy import units as u
from astropy.utils.masked import Masked
from lightkurve import LightCurve

from lcviz import __version__, LCviz
Expand All @@ -22,7 +21,6 @@ def light_curve_like_kepler_quarter(seed=42):
"""
np.random.seed(seed)
exp_per_day = (30 * u.min).to_value(u.day)
masked_fraction = 0.01

# approx start and stop JD for Kepler Quarter 10:
time = np.arange(2455739, 2455833, exp_per_day)
Expand All @@ -32,19 +30,10 @@ def light_curve_like_kepler_quarter(seed=42):
) * u.dimensionless_unscaled
flux_err = scale * np.ones_like(flux)

# randomly apply mask to fraction of the data:
mask_indices = np.random.randint(
low=0,
high=len(flux),
size=int(masked_fraction * len(flux))
)
mask = np.zeros(len(flux), dtype=bool)
mask[mask_indices] = True
quality = np.zeros(len(time), dtype=np.int32)

flux = Masked(flux, mask)
flux_err = Masked(flux_err, mask)
return LightCurve(
time=time, flux=flux, flux_err=flux_err
time=time, flux=flux, flux_err=flux_err, quality=quality
)


Expand Down
55 changes: 54 additions & 1 deletion lcviz/helper.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,32 @@
import astropy.units as u

from lightkurve import LightCurve

from jdaviz.core.helpers import ConfigHelper

__all__ = ['LCviz']


def _get_range_subset_bounds(self, subset_state, *args, **kwargs):
# Instead of overriding the jdaviz version of this method on jdaviz.Application,
# we could put in jdaviz by (1) checking if helper has a
# _default_time_viewer_reference_name, (2) using the LCviz version if so, and (3)
# using the jdaviz version otherwise.
viewer = self.get_viewer(self._jdaviz_helper._default_time_viewer_reference_name)
reference_time = viewer.state.reference_data.meta['reference_time']
if viewer:
units = u.Unit(viewer.state.x_display_unit)
else:
raise ValueError("Unable to find time axis units")

region = reference_time + u.Quantity([subset_state.lo * units, subset_state.hi * units])

return [{"name": subset_state.__class__.__name__,
"glue_state": subset_state.__class__.__name__,
"region": region,
"subset_state": subset_state}]


class LCviz(ConfigHelper):
_default_configuration = {
'settings': {'configuration': 'lcviz',
Expand All @@ -13,7 +37,10 @@ class LCviz(ConfigHelper):
'dense_toolbar': False,
'context': {'notebook': {'max_height': '600px'}}},
'toolbar': ['g-data-tools', 'g-subset-tools'],
'tray': ['g-metadata-viewer', 'g-plot-options', 'HelloWorldPlugin', 'g-export-plot'],
'tray': [
'g-metadata-viewer', 'g-plot-options', 'g-subset-plugin',
'HelloWorldPlugin', 'g-export-plot'
],
'viewer_area': [{'container': 'col',
'children': [{'container': 'row',
'viewers': [{'name': 'time-viewer',
Expand All @@ -24,6 +51,11 @@ def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._default_time_viewer_reference_name = 'time-viewer'

# override jdaviz behavior to support temporal subsets
self.app._get_range_subset_bounds = (
lambda *args, **kwargs: _get_range_subset_bounds(self.app, *args, **kwargs)
)

def load_data(self, data, data_label=None):
"""
Load data into LCviz.
Expand All @@ -47,3 +79,24 @@ def load_data(self, data, data_label=None):
parser_reference='light_curve_parser',
data_label=data_label
)

def get_data(self, data_label=None, cls=LightCurve, subset_to_apply=None):
"""
Returns data with name equal to data_label of type cls with subsets applied from
subset_to_apply.
Parameters
----------
data_label : str, optional
Provide a label to retrieve a specific data set from data_collection.
cls : light curve class, optional
The type that data will be returned as.
subset_to_apply : str, optional
Subset that is to be applied to data before it is returned.
Returns
-------
data : cls
Data is returned as type cls with subsets applied.
"""
return super()._get_data(data_label=data_label, cls=cls, subset_to_apply=subset_to_apply)
34 changes: 30 additions & 4 deletions lcviz/tests/test_parser.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# import pytest
import numpy as np
from glue.core.roi import XRangeROI
from astropy.time import Time
# from astropy.utils.data import download_file
from lightkurve import LightCurve
# from lightkurve.io import kepler
from gwcs.wcs import WCS
import astropy.units as u

from lcviz.utils import TimeCoordinates

# @pytest.mark.remote_data
# def test_kepler_via_mast_local_file(helper):
Expand All @@ -23,7 +24,7 @@
# flux_unit = u.Unit(data.get_component('flux').units)
# flux = flux_arr * flux_unit
#
# assert isinstance(data.coords, WCS)
# assert isinstance(data.coords, TimeCoordinates)
# assert isinstance(flux, u.Quantity)
# assert flux.unit.is_equivalent(u.electron / u.s)
#
Expand All @@ -43,7 +44,7 @@
# flux_unit = u.Unit(data.get_component('flux').units)
# flux = flux_arr * flux_unit
#
# assert isinstance(data.coords, WCS)
# assert isinstance(data.coords, TimeCoordinates)
# assert isinstance(flux, u.Quantity)
# assert flux.unit.is_equivalent(u.electron / u.s)

Expand All @@ -60,6 +61,31 @@ def test_synthetic_lc(helper):
flux_unit = u.Unit(data.get_component('flux').units)
flux = flux_arr * flux_unit

assert isinstance(data.coords, WCS)
assert isinstance(data.coords, TimeCoordinates)
assert isinstance(flux, u.Quantity)
assert flux.unit.is_equivalent(u.electron / u.s)


def test_apply_xrangerois(helper, light_curve_like_kepler_quarter):
lc = light_curve_like_kepler_quarter
helper.load_data(lc)
viewer = helper.app.get_viewer("time-viewer")
subset_plugin = helper.plugins['Subset Tools']

# the min/max of temporal regions can be defined in two ways:
time_ranges = [
[6, 8], # in same units as the x axis, OR
Time(['2011-07-19', '2011-07-23']) # directly with a Time object
]

for time_range in time_ranges:
subset_plugin._obj.subset_selected = "Create New"
viewer.apply_roi(XRangeROI(*time_range))

subsets = helper.app.get_subsets_from_viewer('time-viewer')

subset_1_bounds_jd = subsets['Subset 1'][0]['region'].jd
subset_2_bounds_jd = subsets['Subset 2'][0]['region'].jd

np.testing.assert_allclose(subset_1_bounds_jd, [2455745., 2455747.])
np.testing.assert_allclose(subset_2_bounds_jd, [2455761.50076602, 2455765.50076602])
Loading

0 comments on commit 001fb10

Please sign in to comment.