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

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