Skip to content

Commit

Permalink
WIP: TPF cube viewer
Browse files Browse the repository at this point in the history
  • Loading branch information
kecnry committed Jan 19, 2024
1 parent 3e9e016 commit 2e23a90
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 44 deletions.
32 changes: 25 additions & 7 deletions lcviz/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ def light_curve_parser(app, file_obj, data_label=None, show_in_viewer=True, **kw

# handle flux_origin default
flux_origin = light_curve.meta.get('FLUX_ORIGIN', None) # i.e. PDCSAP or SAP
if isinstance(light_curve, lightkurve.targetpixelfile.TargetPixelFile):
new_data_label += '[TPF]'
elif flux_origin is not None:
new_data_label += f'[{flux_origin}]'

if flux_origin == 'flux' or (flux_origin is None and 'flux' in getattr(light_curve, 'columns', [])): # noqa
# then make a copy of this column so it won't be lost when changing with the flux_column
# plugin
Expand All @@ -47,14 +52,27 @@ def light_curve_parser(app, file_obj, data_label=None, show_in_viewer=True, **kw
data = _data_with_reftime(app, light_curve)
app.add_data(data, new_data_label)

if show_in_viewer:
app.add_data_to_viewer(time_viewer_reference_name, new_data_label)
if isinstance(light_curve, lightkurve.targetpixelfile.TargetPixelFile):
# ensure a TPF viewer exists
# TODO: move this to an event listener on add_data so that we can also remove when empty?
from jdaviz.core.events import NewViewerMessage
from lcviz.viewers import CubeView
viewer_reference_name = 'tpf'
if viewer_reference_name not in app._viewer_store.keys():
app._on_new_viewer(NewViewerMessage(CubeView, data=None, sender=app),
vid='tpf', name='tpf')
if show_in_viewer:
app.add_data_to_viewer(viewer_reference_name, new_data_label)

else:
if show_in_viewer:
app.add_data_to_viewer(time_viewer_reference_name, new_data_label)

# add to any known phase viewers
ephem_plugin = app._jdaviz_helper.plugins.get('Ephemeris', None)
if ephem_plugin is not None:
for viewer_id in ephem_plugin._obj.phase_viewer_ids:
app.add_data_to_viewer(viewer_id, new_data_label)
# add to any known phase viewers
ephem_plugin = app._jdaviz_helper.plugins.get('Ephemeris', None)
if ephem_plugin is not None:
for viewer_id in ephem_plugin._obj.phase_viewer_ids:
app.add_data_to_viewer(viewer_id, new_data_label)

Check warning on line 75 in lcviz/parsers.py

View check run for this annotation

Codecov / codecov/patch

lcviz/parsers.py#L75

Added line #L75 was not covered by tests


def _data_with_reftime(app, light_curve):
Expand Down
111 changes: 74 additions & 37 deletions lcviz/viewers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from glue.core.subset_group import GroupedSubset

from glue_jupyter.bqplot.scatter import BqplotScatterView
from glue_jupyter.bqplot.image import BqplotImageView

from astropy import units as u
from astropy.time import Time
Expand All @@ -19,12 +20,47 @@

from lightkurve import LightCurve

__all__ = ['TimeScatterView', 'PhaseScatterView', 'CubeView']

__all__ = ['TimeScatterView', 'PhaseScatterView']

class CloneViewerMixin:
def _get_clone_viewer_reference(self):
base_name = self.reference.split("[")[0]
name = base_name
ind = 0
while name in self.jdaviz_helper.viewers.keys():
ind += 1
name = f"{base_name}[{ind}]"
return name

def clone_viewer(self):
name = self._get_clone_viewer_reference()

self.jdaviz_app._on_new_viewer(NewViewerMessage(self.__class__,
data=None,
sender=self.jdaviz_app),
vid=name, name=name)

this_viewer_item = self.jdaviz_app._get_viewer_item(self.reference)
this_state = self.state.as_dict()
for data in self.jdaviz_app.data_collection:
data_id = self.jdaviz_app._data_id_from_label(data.label)
visible = this_viewer_item['selected_data_items'].get(data_id, 'hidden')
self.jdaviz_app.set_data_visibility(name, data.label, visible == 'visible')
# TODO: don't revert color when adding same data to a new viewer
# (same happens when creating a phase-viewer from ephemeris plugin)

new_viewer = self.jdaviz_helper.viewers[name]._obj
for k, v in this_state.items():
if k in ('layers',):
continue
setattr(new_viewer.state, k, v)

return new_viewer.user_api


@viewer_registry("lcviz-time-viewer", label="flux-vs-time")
class TimeScatterView(JdavizViewerMixin, BqplotScatterView):
class TimeScatterView(JdavizViewerMixin, CloneViewerMixin, BqplotScatterView):
# categories: zoom resets, zoom, pan, subset, select tools, shortcuts
tools_nested = [
['jdaviz:homezoom', 'jdaviz:prevzoom'],
Expand All @@ -43,7 +79,6 @@ def __init__(self, *args, **kwargs):

self.display_mask = False
self.time_unit = kwargs.get('time_unit', u.d)
self._subscribe_to_layers_update()
self.initialize_toolbar()
self._subscribe_to_layers_update()
# hack to inherit a small subset of methods from SpecvizProfileView
Expand Down Expand Up @@ -210,40 +245,6 @@ def apply_roi(self, roi, use_current=False):

super().apply_roi(roi, use_current=use_current)

def _get_clone_viewer_reference(self):
base_name = self.reference.split("[")[0]
name = base_name
ind = 0
while name in self.jdaviz_helper.viewers.keys():
ind += 1
name = f"{base_name}[{ind}]"
return name

def clone_viewer(self):
name = self._get_clone_viewer_reference()

self.jdaviz_app._on_new_viewer(NewViewerMessage(self.__class__,
data=None,
sender=self.jdaviz_app),
vid=name, name=name)

this_viewer_item = self.jdaviz_app._get_viewer_item(self.reference)
this_state = self.state.as_dict()
for data in self.jdaviz_app.data_collection:
data_id = self.jdaviz_app._data_id_from_label(data.label)
visible = this_viewer_item['selected_data_items'].get(data_id, 'hidden')
self.jdaviz_app.set_data_visibility(name, data.label, visible == 'visible')
# TODO: don't revert color when adding same data to a new viewer
# (same happens when creating a phase-viewer from ephemeris plugin)

new_viewer = self.jdaviz_helper.viewers[name]._obj
for k, v in this_state.items():
if k in ('layers',):
continue
setattr(new_viewer.state, k, v)

return new_viewer.user_api


@viewer_registry("lcviz-phase-viewer", label="phase-vs-time")
class PhaseScatterView(TimeScatterView):
Expand All @@ -263,3 +264,39 @@ def times_to_phases(self, times):
raise ValueError("must have ephemeris plugin loaded to convert")

return ephem.times_to_phases(times, ephem_component=self.ephemeris_component)


@viewer_registry("lcviz-cube-viewer", label="cube")
class CubeView(JdavizViewerMixin, CloneViewerMixin, BqplotImageView):
# categories: zoom resets, zoom, pan, subset, select tools, shortcuts
tools_nested = [
['jdaviz:homezoom', 'jdaviz:prevzoom'],
['jdaviz:boxzoom'],
['jdaviz:panzoom'],
['bqplot:rectangle'],
['lcviz:viewer_clone', 'jdaviz:sidebar_plot', 'jdaviz:sidebar_export']
]
# default_class = TargetPixelFile # TODO: does this need to use the factory?
# _state_cls = ScatterViewerState

# _native_mark_classnames = ('Image', 'ImageGL', 'Scatter', 'ScatterGL')

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

self.display_mask = False
self.time_unit = kwargs.get('time_unit', u.d)
self.initialize_toolbar()
self._subscribe_to_layers_update()

# Hide axes by default
self.state.show_axes = False

def data(self, cls=None):
# TODO: generalize upstream in jdaviz.
# This method is generalized from
# jdaviz/configs/cubeviz/plugins/viewers.py
return [layer_state.layer

Check warning on line 299 in lcviz/viewers.py

View check run for this annotation

Codecov / codecov/patch

lcviz/viewers.py#L299

Added line #L299 was not covered by tests
for layer_state in self.state.layers
if hasattr(layer_state, 'layer') and
isinstance(layer_state.layer, BaseData)]

0 comments on commit 2e23a90

Please sign in to comment.