Skip to content

Commit

Permalink
orientation: expose create_north_up_east_left/right (#3308)
Browse files Browse the repository at this point in the history
* expose set_north_up_east_left/right
* add docstring for delete_subsets
* remove set_as_orientation kwarg
  • Loading branch information
kecnry authored Nov 25, 2024
1 parent 33edc03 commit 7f0b3f4
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 34 deletions.
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Cubeviz
Imviz
^^^^^

* Orientation plugin API now exposes create_north_up_east_left and create_north_up_east_right methods. [#3308]

Mosviz
^^^^^^

Expand Down
68 changes: 49 additions & 19 deletions jdaviz/configs/imviz/plugins/orientation/orientation.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,21 @@ class Orientation(PluginTemplateMixin, ViewerSelectMixin):
* :meth:`~jdaviz.core.template_mixin.PluginTemplateMixin.close_in_tray`
* ``align_by`` (`~jdaviz.core.template_mixin.SelectPluginComponent`)
* ``wcs_fast_approximation``
* ``delete_subsets``
* :meth:`delete_subsets`
* ``viewer``
* ``orientation``
* ``rotation_angle``
* ``east_left``
* ``add_orientation``
* :meth:`add_orientation`
* :meth:`set_north_up_east_left`
* :meth:`set_north_up_east_right`
"""
template_file = __file__, "orientation.vue"

# defined as traitlet in addition to global variable above to
# allow access from UI - leave fixed
base_wcs_layer_label = Unicode(base_wcs_layer_label).tag(sync=True)

align_by_items = List().tag(sync=True)
align_by_selected = Unicode().tag(sync=True)
wcs_use_fallback = Bool(True).tag(sync=True)
Expand Down Expand Up @@ -146,7 +152,8 @@ def user_api(self):
expose=(
'align_by', 'link_type', 'wcs_fast_approximation', 'wcs_use_affine',
'delete_subsets', 'viewer', 'orientation',
'rotation_angle', 'east_left', 'add_orientation'
'rotation_angle', 'east_left', 'add_orientation',
'set_north_up_east_left', 'set_north_up_east_right',
)
)

Expand Down Expand Up @@ -283,6 +290,9 @@ def _on_subset_change(self, msg):
self.need_clear_subsets = len(self.app.data_collection.subset_groups) > 0

def delete_subsets(self):
"""
Delete all subsets app-wide. Required before changing ``align_by``.
"""
# subsets will be deleted on changing link type:
for subset_group in self.app.data_collection.subset_groups:
self.app.data_collection.remove_subset_group(subset_group)
Expand Down Expand Up @@ -526,39 +536,59 @@ def _on_viewer_change(self, msg={}):
if ref_data.label in self.orientation.choices:
self.orientation.selected = ref_data.label

def create_north_up_east_left(self, label="North-up, East-left", set_on_create=False,
from_ui=False):
"""
Set the rotation angle and flip to achieve North up and East left
according to the reference image WCS.
"""
def _set_north_up_east_left(self, label="North-up, East-left", set_as_orientation=False,
from_ui=False):
if label not in self.orientation.choices:
degn = self._get_wcs_angles()[-3]
self._add_orientation(rotation_angle=degn, east_left=True,
label=label, set_on_create=set_on_create,
label=label, set_on_create=set_as_orientation,
from_ui=from_ui)
elif set_on_create:
elif set_as_orientation:
self.orientation.selected = label

def create_north_up_east_right(self, label="North-up, East-right", set_on_create=False,
from_ui=False):
def set_north_up_east_left(self, label="North-up, East-left"):
"""
Set the rotation angle and flip to achieve North up and East right
according to the reference image WCS.
Set (and create if necessary) the rotation angle and flip to achieve North up
and East left according to the reference image WCS.
Parameters
----------
label : str
Data label for the orientation layer. If already exists, will be set as the
current orientation layer according to ``set_as_orientation``. Otherwise,
a new layer will be created with this label.
"""
self._set_north_up_east_left(label=label, set_as_orientation=True)

def _set_north_up_east_right(self, label="North-up, East-right", set_as_orientation=False,
from_ui=False):
if label not in self.orientation.choices:
degn = self._get_wcs_angles()[-3]
self._add_orientation(rotation_angle=180 - degn, east_left=False,
label=label, set_on_create=set_on_create,
label=label, set_on_create=set_as_orientation,
from_ui=from_ui)
elif set_on_create:
elif set_as_orientation:
self.orientation.selected = label

def set_north_up_east_right(self, label="North-up, East-right"):
"""
Set (and create, if necessary) the rotation angle and flip to achieve North up
and East right according to the reference image WCS.
Parameters
----------
label : str
Data label for the orientation layer. If already exists, will be set as the
current orientation layer according to ``set_as_orientation``. Otherwise,
a new layer will be created with this label.
"""
self._set_north_up_east_right(label=label, set_as_orientation=True)

def vue_select_north_up_east_left(self, *args, **kwargs):
self.create_north_up_east_left(set_on_create=True, from_ui=True)
self._set_north_up_east_left(set_as_orientation=True, from_ui=True)

def vue_select_north_up_east_right(self, *args, **kwargs):
self.create_north_up_east_right(set_on_create=True, from_ui=True)
self._set_north_up_east_right(set_as_orientation=True, from_ui=True)

def vue_select_default_orientation(self, *args, **kwargs):
self.orientation.selected = base_wcs_layer_label
Expand Down
33 changes: 30 additions & 3 deletions jdaviz/configs/imviz/plugins/orientation/orientation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -128,18 +128,45 @@
<span style="line-height: 36px">Presets:</span>
<!-- NOTE: changes to icons here should be manually reflected in layer_icons in app.py -->
<j-tooltip tooltipcontent="Default orientation">
<v-btn icon @click="select_default_orientation">
<v-btn
:icon="!api_hints_enabled"
:class="api_hints_enabled ? 'api-hint' : null"
@click="select_default_orientation"
>
<v-icon>mdi-image-outline</v-icon>
{{ api_hints_enabled ?
'plg.orientation = \''+base_wcs_layer_label+'\''
:
null
}}
</v-btn>
</j-tooltip>
<j-tooltip tooltipcontent="north up, east left">
<v-btn icon @click="select_north_up_east_left">
<v-btn
:icon="!api_hints_enabled"
:class="api_hints_enabled ? 'api-hint' : null"
@click="select_north_up_east_left"
>
<img :src="icons['nuel']" width="24" class="invert-if-dark" style="opacity: 0.65"/>
{{ api_hints_enabled ?
'plg.set_north_up_east_left()'
:
null
}}
</v-btn>
</j-tooltip>
<j-tooltip tooltipcontent="north up, east right">
<v-btn icon @click="select_north_up_east_right">
<v-btn
:icon="!api_hints_enabled"
:class="api_hints_enabled ? 'api-hint' : null"
@click="select_north_up_east_right"
>
<img :src="icons['nuer']" width="24" class="invert-if-dark" style="opacity: 0.65"/>
{{ api_hints_enabled ?
'plg.set_north_up_east_right()'
:
null
}}
</v-btn>
</j-tooltip>
</v-row>
Expand Down
2 changes: 1 addition & 1 deletion jdaviz/configs/imviz/tests/test_delete_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def test_delete_wcs_layer_with_subset(self):
lc_plugin.align_by = 'WCS'

# Should automatically be applied as reference to first viewer.
lc_plugin._obj.create_north_up_east_left(set_on_create=True)
lc_plugin.set_north_up_east_left()

# Create a rotated ellipse.
reg = EllipsePixelRegion(
Expand Down
4 changes: 2 additions & 2 deletions jdaviz/configs/imviz/tests/test_footprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,8 @@ def test_footprint_updates_on_rotation(imviz_helper):
assert np.concatenate([marks[0].y, marks[1].y]).min() < -3

# now rotate to north-up east-left:
orientation = imviz_helper.plugins['Orientation']._obj
orientation.create_north_up_east_left(set_on_create=True)
orientation = imviz_helper.plugins['Orientation']
orientation.set_north_up_east_left()

# If all footprint orientations have been updated, the lowest
# mark should still be centered low. If the footprint
Expand Down
18 changes: 9 additions & 9 deletions jdaviz/configs/imviz/tests/test_orientation.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,14 @@ def test_N_up_multi_viewer(self):
lc_plugin.align_by = 'WCS'

# Should automatically be applied as reference to first viewer.
lc_plugin._obj.create_north_up_east_left(set_on_create=True)
lc_plugin.set_north_up_east_left()

# This would set a different reference to second viewer.
viewer_2 = self.imviz.create_image_viewer()
self.imviz.app.add_data_to_viewer("imviz-1", "has_wcs_1[SCI,1]")
lc_plugin.viewer = "imviz-1"

lc_plugin._obj.create_north_up_east_right(set_on_create=True)
lc_plugin.set_north_up_east_right()

assert self.viewer.state.reference_data.label == "North-up, East-left"
assert viewer_2.state.reference_data.label == "North-up, East-right"
Expand All @@ -157,8 +157,8 @@ def test_custom_orientation(self):
lc_plugin.viewer = "imviz-0"

lc_plugin.rotation_angle = 42 # Triggers auto-label
lc_plugin._obj.add_orientation(rotation_angle=None, east_left=True, label=None,
set_on_create=True, wrt_data=None)
lc_plugin.add_orientation(rotation_angle=None, east_left=True, label=None,
set_on_create=True, wrt_data=None)
assert self.viewer.state.reference_data.label == "CCW 42.00 deg (E-left)"


Expand All @@ -169,7 +169,7 @@ def test_delete_orientation_multi_viewer(self):
lc_plugin.align_by = 'WCS'

# Should automatically be applied as reference to first viewer.
lc_plugin._obj.create_north_up_east_left(set_on_create=True)
lc_plugin.set_north_up_east_left()

# This would set a different reference to second viewer.
viewer_2 = self.imviz.create_image_viewer()
Expand All @@ -192,15 +192,15 @@ def test_delete_orientation_with_subset(self, klass, angle, sbst_theta):
lc_plugin.align_by = 'WCS'

# Should automatically be applied as reference to first viewer.
lc_plugin._obj.create_north_up_east_left(set_on_create=True)
lc_plugin.set_north_up_east_left()

# Create rotated shape
reg = klass(center=SkyCoord(ra=337.51931488, dec=-20.83187472, unit="deg"),
width=2.4 * u.arcsec, height=1.2 * u.arcsec, angle=angle)
self.imviz.plugins['Subsets'].import_region(reg)

# Switch to N-up E-right
lc_plugin._obj.create_north_up_east_right(set_on_create=True)
lc_plugin.set_north_up_east_right()

self.imviz.app.vue_data_item_remove({"item_name": "North-up, East-left"})

Expand Down Expand Up @@ -234,13 +234,13 @@ def test_create_no_data(self):
lc_plugin.viewer = "imviz-1"

with pytest.raises(ValueError, match="Viewer must have data loaded"):
lc_plugin._obj.create_north_up_east_left(set_on_create=True)
lc_plugin.set_north_up_east_left()

def test_select_no_data(self):
lc_plugin = self.imviz.plugins['Orientation']
lc_plugin.align_by = 'WCS'

lc_plugin._obj.create_north_up_east_left(set_on_create=True)
lc_plugin.set_north_up_east_left()

self.imviz.create_image_viewer()
lc_plugin.viewer = "imviz-1"
Expand Down

0 comments on commit 7f0b3f4

Please sign in to comment.