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

Time Selector (adapted version of cubeviz's slice) plugin #85

Merged
merged 9 commits into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from 7 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
34 changes: 34 additions & 0 deletions docs/plugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,40 @@ visible when the plugin is opened.
Jdaviz documentation on the Markers plugin.


.. _time-indicator:

Time Selector
==============

The time selector plugin allows defining the time indicated in all light curve viewers
(time and phase viewers) as well as the time at which all image cubes are displayed.


.. admonition:: User API Example
:class: dropdown

See the :class:`~lcviz.plugins.time_selector.time_selector.TimeSelector` user API documentation for more details.

.. code-block:: python

from lcviz import LCviz
lc = search_lightcurve("HAT-P-11", mission="Kepler",
cadence="long", quarter=10).download().flatten()
lcviz = LCviz()
lcviz.load_data(lc)
lcviz.show()

ts = lcviz.plugins['Time Selector']
ts.open_in_tray()


.. seealso::

:ref:`Jdaviz Slice Plugin <jdaviz:slice>`
Jdaviz documentation on the Slice plugin.



.. _flatten:

Flatten
Expand Down
3 changes: 2 additions & 1 deletion lcviz/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ class LCviz(ConfigHelper):
'toolbar': ['g-data-tools', 'g-subset-tools', 'lcviz-coords-info'],
'tray': ['lcviz-metadata-viewer', 'flux-column',
'lcviz-plot-options', 'lcviz-subset-plugin',
'lcviz-markers', 'flatten', 'frequency-analysis', 'ephemeris',
'lcviz-markers', 'time-selector',
'flatten', 'frequency-analysis', 'ephemeris',
'binning', 'lcviz-export-plot'],
'viewer_area': [{'container': 'col',
'children': [{'container': 'row',
Expand Down
12 changes: 11 additions & 1 deletion lcviz/marks.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
from astropy import units as u
import numpy as np

from jdaviz.core.marks import PluginLine, PluginScatter
from jdaviz.core.marks import PluginLine, PluginScatter, SliceIndicatorMarks
from lcviz.viewers import PhaseScatterView

__all__ = ['LivePreviewTrend', 'LivePreviewFlattened', 'LivePreviewBinning']


def _slice_indicator_get_slice_axis(self, data):
if hasattr(data, 'time'):
return data.time.value * u.d
return [] * u.dimensionless_unscaled


SliceIndicatorMarks._get_slice_axis = _slice_indicator_get_slice_axis


class WithoutPhaseSupport:
def update_ty(self, times, y):
self.times = np.asarray(times)
Expand Down
1 change: 1 addition & 0 deletions lcviz/plugins/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from .flux_column.flux_column import * # noqa
from .frequency_analysis.frequency_analysis import * # noqa
from .markers.markers import * # noqa
from .time_selector.time_selector import * # noqa
from .metadata_viewer.metadata_viewer import * # noqa
from .plot_options.plot_options import * # noqa
from .subset_plugin.subset_plugin import * # noqa
1 change: 1 addition & 0 deletions lcviz/plugins/time_selector/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .time_selector import * # noqa
61 changes: 61 additions & 0 deletions lcviz/plugins/time_selector/time_selector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from jdaviz.configs.cubeviz.plugins import Slice
from jdaviz.core.registries import tray_registry

from lcviz.viewers import CubeView

__all__ = ['TimeSelector']


@tray_registry('time-selector', label="Time Selector")
class TimeSelector(Slice):
"""
See the :ref:`Time Selector Plugin Documentation <time-selector>` for more details.

Only the following attributes and methods are available through the
:ref:`public plugin API <plugin-apis>`:

* :meth:`~jdaviz.core.template_mixin.PluginTemplateMixin.show`
* :meth:`~jdaviz.core.template_mixin.PluginTemplateMixin.open_in_tray`
* :meth:`~jdaviz.core.template_mixin.PluginTemplateMixin.close_in_tray`
* ``value`` Time of the indicator. When setting this directly, it will
update automatically to the value corresponding to the nearest slice, if ``snap_to_slice`` is
enabled and a cube is loaded.
* ``show_indicator``
Whether to show indicator in spectral viewer when slice tool is inactive.
* ``show_value``
Whether to show slice value in label to right of indicator.
* ``snap_to_slice``
Whether the indicator (and ``value``) should snap to the value of the nearest slice in the
cube (if one exists).
"""
_cube_viewer_cls = CubeView
_cube_viewer_default_label = 'image'

def __init__(self, *args, **kwargs):
"""

"""
super().__init__(*args, **kwargs)
self.docs_link = f"https://lcviz.readthedocs.io/en/{self.vdocs}/plugins.html#time-selector"
self.docs_description = "Select time to sync across all viewers (as an indicator in all time/phase viewers or to select the active slice in any image/cube viewers). The slice can also be changed interactively in any time viewer by activating the slice tool." # noqa
self.value_label = 'Time'
self.value_unit = 'd'
self.allow_disable_snapping = True

@property
def slice_axis(self):
# global display unit "axis" corresponding to the slice axis
return 'time'

@property
def valid_slice_att_names(self):
return ["time", "dt"]

@property
def user_api(self):
api = super().user_api
# can be removed after deprecated upstream attributes for wavelength/wavelength_value
# are removed in the lowest supported version of jdaviz
api._expose = [e for e in api._expose if e not in ('slice', 'wavelength',
'wavelength_value', 'show_wavelength')]
return api
41 changes: 37 additions & 4 deletions lcviz/viewers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@

from jdaviz.core.events import NewViewerMessage
from jdaviz.core.registries import viewer_registry
from jdaviz.configs.cubeviz.plugins.viewers import CubevizImageView
from jdaviz.configs.cubeviz.plugins.viewers import (CubevizImageView,
WithSliceIndicator, WithSliceSelection)
from jdaviz.configs.default.plugins.viewers import JdavizViewerMixin
from jdaviz.configs.specviz.plugins.viewers import SpecvizProfileView

Expand Down Expand Up @@ -60,13 +61,14 @@ def clone_viewer(self):


@viewer_registry("lcviz-time-viewer", label="flux-vs-time")
class TimeScatterView(JdavizViewerMixin, CloneViewerMixin, BqplotScatterView):
class TimeScatterView(JdavizViewerMixin, CloneViewerMixin, WithSliceIndicator, BqplotScatterView):
# categories: zoom resets, zoom, pan, subset, select tools, shortcuts
tools_nested = [
['jdaviz:homezoom', 'jdaviz:prevzoom'],
['jdaviz:boxzoom', 'jdaviz:xrangezoom', 'jdaviz:yrangezoom'],
['jdaviz:panzoom', 'jdaviz:panzoom_x', 'jdaviz:panzoom_y'],
['bqplot:xrange', 'bqplot:yrange', 'bqplot:rectangle'],
['jdaviz:selectslice'],
['lcviz:viewer_clone', 'jdaviz:sidebar_plot', 'jdaviz:sidebar_export']
]
default_class = LightCurve
Expand All @@ -79,7 +81,7 @@ def __init__(self, *args, **kwargs):

self.display_mask = False
self.time_unit = kwargs.get('time_unit', u.d)
self.initialize_toolbar()
self.initialize_toolbar(default_tool_priority=['jdaviz:selectslice'])
self._subscribe_to_layers_update()
# hack to inherit a small subset of methods from SpecvizProfileView
# TODO: refactor jdaviz so these can be included in some mixin
Expand All @@ -89,6 +91,12 @@ def __init__(self, *args, **kwargs):
self._clean_error = lambda: SpecvizProfileView._clean_error(self)
self.density_map = kwargs.get('density_map', False)

@property
def slice_component_label(self):
# label of the component in the lightcurves corresponding to the slice axis
# calling data_collection_item.get_component(slice_component_label) must work
return 'dt'

def data(self, cls=None):
data = []

Expand Down Expand Up @@ -248,6 +256,15 @@ def apply_roi(self, roi, use_current=False):

@viewer_registry("lcviz-phase-viewer", label="phase-vs-time")
class PhaseScatterView(TimeScatterView):
# categories: zoom resets, zoom, pan, subset, select tools, shortcuts
tools_nested = [
['jdaviz:homezoom', 'jdaviz:prevzoom'],
['jdaviz:boxzoom', 'jdaviz:xrangezoom', 'jdaviz:yrangezoom'],
['jdaviz:panzoom', 'jdaviz:panzoom_x', 'jdaviz:panzoom_y'],
['bqplot:xrange', 'bqplot:yrange', 'bqplot:rectangle'],
['lcviz:viewer_clone', 'jdaviz:sidebar_plot', 'jdaviz:sidebar_export']
]

@property
def ephemeris_component(self):
return self.reference.split('[')[0].split(':')[-1]
Expand All @@ -265,9 +282,13 @@ def times_to_phases(self, times):

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

def _set_slice_indicator_value(self, value):
# NOTE: on first call, this will initialize the indicator itself
self.slice_indicator.value = self.times_to_phases(value)


@viewer_registry("lcviz-cube-viewer", label="cube")
class CubeView(CloneViewerMixin, CubevizImageView):
class CubeView(CloneViewerMixin, CubevizImageView, WithSliceSelection):
# categories: zoom resets, zoom, pan, subset, select tools, shortcuts
tools_nested = [
['jdaviz:homezoom', 'jdaviz:prevzoom'],
Expand Down Expand Up @@ -297,6 +318,18 @@ def __init__(self, *args, **kwargs):
# * _default_flux_viewer_reference_name
# * _default_uncert_viewer_reference_name

@property
def slice_component_label(self):
# label of the component in the cubes corresponding to the slice axis
# calling data_collection_item.get_component(slice_component_label) on any
# input cube-data must work
return 'dt'

@property
def slice_index(self):
# index in viewer.slices corresponding to the slice axis
return 0

def _initial_x_axis(self, *args):
# Make sure that the x_att/y_att is correct on data load
# called via a callback set upstream in CubevizImageView when reference_data is changed
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ classifiers = [
]
dependencies = [
"astropy>=5.2",
"jdaviz==3.8.*",
"jdaviz==3.9.*",
"lightkurve>=2.4.1",
]
dynamic = [
Expand Down
Loading