Skip to content
New issue

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

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

Already on GitHub? # to your account

Export plugin filters #2780

Merged
merged 6 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
2 changes: 1 addition & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ New Features

- "Export Plot" plugin is now replaced with the more general "Export" plugin. [#2722]

- "Export" plugin supports exporting plugin tables, data and non-composite spatial subsets.[#2755, #2760, #2772, #2770]
- "Export" plugin supports exporting plugin tables, data and non-composite spatial subsets.[#2755, #2760, #2772, #2770, #2780]

- Opening a plugin in the tray (from the API or the toolbar buttons) now scrolls to that plugin.
[#2768]
Expand Down
10 changes: 10 additions & 0 deletions jdaviz/configs/default/plugins/export/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ class Export(PluginTemplateMixin, ViewerSelectMixin, SubsetSelectMixin,
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

# NOTE: if adding export support for non-plugin products, also update the language
# in the UI as well as in _set_dataset_not_supported_msg
self.dataset.filters = ['is_not_wcs_only', 'not_child_layer',
'from_plugin']

# NOTE: if/when adding support for spectral subsets, update the languange in the UI
self.subset.filters = ['is_spatial']

self.plot = SelectPluginComponent(self,
items='plot_items',
selected='plot_selected',
Expand Down Expand Up @@ -237,6 +245,8 @@ def _set_subset_not_supported_msg(self, msg=None):
def _set_dataset_not_supported_msg(self, msg=None):
if self.dataset.selected_obj is not None:
if self.dataset.selected_obj.meta.get("Plugin", None) is None:
# NOTE: should not be a valid choice due to dataset filters, but we'll include
# another check here.
self.data_invalid_msg = "Data export is only available for plugin generated data."
elif not isinstance(self.dataset.selected_obj, (Spectrum1D, CCDData)):
self.data_invalid_msg = "Export is not implemented for this type of data"
Expand Down
8 changes: 7 additions & 1 deletion jdaviz/configs/default/plugins/export/export.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
></j-multiselect-toggle>

<j-plugin-section-header style="margin-top: 12px">Viewers</j-plugin-section-header>
<v-row>
<span class="v-messages v-messages__message text--secondary">Export viewer plot as an image.</span>
</v-row>
Comment on lines +16 to +18
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you missed the Tables section, I think that should also have a caption like this for consistency. Other than that, this PR looks good.

<plugin-inline-select
:items="viewer_items"
:selected.sync="viewer_selected"
Expand Down Expand Up @@ -86,6 +89,9 @@

<div v-if="dataset_items.length > 0">
<j-plugin-section-header style="margin-top: 12px">Data</j-plugin-section-header>
<v-row>
<span class="v-messages v-messages__message text--secondary">Export data generated by plugins.</span>
</v-row>
<plugin-inline-select
:items="dataset_items"
:selected.sync="dataset_selected"
Expand Down Expand Up @@ -115,7 +121,7 @@
<div v-if="subset_items.length > 0">
<j-plugin-section-header style="margin-top: 12px">Subsets</j-plugin-section-header>
<v-row>
<span class="v-messages v-messages__message text--secondary"> Save subset as astropy region. </span>
<span class="v-messages v-messages__message text--secondary">Export spatial subset as astropy region.</span>
</v-row>
<plugin-inline-select
:items="subset_items"
Expand Down
23 changes: 3 additions & 20 deletions jdaviz/configs/default/plugins/export/tests/test_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,7 @@ def test_not_implemented(self, cubeviz_helper, spectral_cube_wcs):

cubeviz_helper.app.session.edit_subset_mode.mode = NewMode
cubeviz_helper.app.get_viewer("spectrum-viewer").apply_roi(XRangeROI(5, 15.5))
export_plugin.subset.selected = 'Subset 2'

assert export_plugin.subset_invalid_msg == 'Export for spectral subsets not supported.'
assert 'Subset 2' not in export_plugin.subset.choices

def test_export_subsets_wcs(self, tmp_path, imviz_helper, spectral_cube_wcs):

Expand Down Expand Up @@ -186,18 +184,6 @@ def test_basic_export_subsets_cubeviz(self, tmp_path, cubeviz_helper, spectral_c


def test_export_data(cubeviz_helper, spectrum1d_cube):
cubeviz_helper.load_data(spectrum1d_cube, data_label="test")
export_plugin = cubeviz_helper.plugins["Export"]._obj
export_plugin.dataset_selected = 'test[FLUX]'
assert export_plugin.dataset_format.selected == 'fits'
assert 'test[FLUX]' in cubeviz_helper.app.data_collection.labels
with pytest.raises(NotImplementedError,
match='Data can not be exported'):
export_plugin.export()
assert export_plugin.data_invalid_msg == 'Data export is only available for plugin generated data.' # noqa


def test_disable_export_for_non_plugin_generated_data(cubeviz_helper, spectrum1d_cube):
cubeviz_helper.load_data(spectrum1d_cube, data_label='test')
mm = cubeviz_helper.plugins["Moment Maps"]
mm.dataset = 'test[FLUX]'
Expand All @@ -209,13 +195,10 @@ def test_disable_export_for_non_plugin_generated_data(cubeviz_helper, spectrum1d
cubeviz_helper._default_flux_viewer_reference_name, 'moment 0'
)
ep = cubeviz_helper.plugins["Export"]._obj
ep.dataset_selected = 'test[FLUX]'
with pytest.raises(NotImplementedError,
match='Data can not be exported'):
ep.export()
assert ep.data_invalid_msg == 'Data export is only available for plugin generated data.'
assert 'test[FLUX]' not in ep.dataset.choices

ep.dataset_selected = 'moment 0'
assert ep.dataset_format.selected == 'fits'
ep.export()
assert os.path.isfile("cubeviz_export.fits")
assert ep.data_invalid_msg == ''
30 changes: 17 additions & 13 deletions jdaviz/core/template_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -1339,6 +1339,7 @@
multiselect=None,
default_text=None, manual_options=[],
default_mode='first',
filters=['not_child_layer'],
only_wcs_layers=False):
"""
Parameters
Expand Down Expand Up @@ -1392,12 +1393,6 @@
self._update_layer_items()
self.update_wcs_only_filter(only_wcs_layers)

# ignore layers that are children in associations:
def is_parent(data):
return self.app._get_assoc_data_parent(data.label) is None

self.add_filter(is_parent)

def _get_viewer(self, viewer):
# newer will likely be the viewer name in most cases, but viewer id in the case
# of additional viewers in imviz.
Expand All @@ -1413,6 +1408,13 @@
viewer_names = [viewer_names]
return [self._get_viewer(viewer) for viewer in viewer_names]

def _is_valid_item(self, lyr):
def not_child_layer(lyr):
# ignore layers that are children in associations:
return self.app._get_assoc_data_parent(lyr.label) is None

Check warning on line 1414 in jdaviz/core/template_mixin.py

View check run for this annotation

Codecov / codecov/patch

jdaviz/core/template_mixin.py#L1414

Added line #L1414 was not covered by tests

return super()._is_valid_item(lyr, locals())

def _layer_to_dict(self, layer_label):
is_subset = None
colors = []
Expand Down Expand Up @@ -3033,7 +3035,8 @@

def __init__(self, plugin, items, selected,
multiselect=None,
filters=['not_from_plugin_model_fitting', 'layer_in_viewers', 'is_not_wcs_only'],
filters=['not_from_plugin_model_fitting', 'layer_in_viewers',
'is_not_wcs_only', 'not_child_layer'],
default_text=None, manual_options=[],
default_mode='first'):
"""
Expand Down Expand Up @@ -3072,12 +3075,6 @@
# initialize items from original viewers
self._on_data_changed()

# ignore layers that are children in associations:
def is_parent(data):
return self.app._get_assoc_data_parent(data.label) is None

self.add_filter(is_parent)

def _cubeviz_include_spatial_subsets(self):
"""
Call this method to prepend spatial subsets to the list of datasets (and listen for newly
Expand Down Expand Up @@ -3151,6 +3148,9 @@
use_display_units=use_display_units)

def _is_valid_item(self, data):
def from_plugin(data):
return data.meta.get('Plugin', None) is not None

def not_from_plugin(data):
return data.meta.get('Plugin', None) is None

Expand Down Expand Up @@ -3199,6 +3199,10 @@
def is_not_wcs_only(data):
return not data.meta.get(_wcs_only_label, False)

def not_child_layer(data):
# ignore layers that are children in associations:
return self.app._get_assoc_data_parent(data.label) is None

return super()._is_valid_item(data, locals())

@observe('filters')
Expand Down