Repository: spacetelescope/jdaviz

Issue:
Subset Tools plugin incorrect after using "remove selection" mode
**Reporter: Jesse Averbukh**

In specviz example notebook, create a spectral subset then use the "remove selection" mode at the top to remove a chunk out of the middle. The Subset Tools plugin shows incorrect values for the range of the subset.

 --- 

 DISCLAIMER: This issue was autocreated by the Jdaviz Issue Creation Bot on behalf of the reporter. If any information is incorrect, please contact [Duy Nguyen](https://github.com/duytnguyendtn)

Discussion:
javerbukh: As far as I can tell, the behavior mentioned here:

>  Stop the plugin refreshing multiple times

exists in `main` although it is more noticeable in this branch (although none of my debug statements triggered so maybe I need to optimize the `.vue` file somehow?). The easiest way to replicate the behavior is to create a spectral selection in cubeviz, then using the `remove` subset mode, remove a section from the subset. Before you complete you selection however, click and drag one end of the selection brush and wait, then continue that action until a considerable delay appears.
pllim: `KeyError: 'ComponentID not found or not unique: DATA'` means loading failed for one reason or another. I'll have to see if it is related or not, probably not but I cannot prove that right now.
pllim: You can ignore the dev failure: #2165
codecov[bot]: ## [Codecov](https://codecov.io/gh/spacetelescope/jdaviz/pull/2157?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spacetelescope) Report
Patch coverage: **`96.96`**% and project coverage change: **`-0.01`** :warning:
> Comparison is base [(`c0e2ed5`)](https://codecov.io/gh/spacetelescope/jdaviz/commit/c0e2ed563391d31d078c7fd1ddac7032aa1f3b1f?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spacetelescope) 91.50% compared to head [(`6f484dd`)](https://codecov.io/gh/spacetelescope/jdaviz/pull/2157?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spacetelescope) 91.49%.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #2157      +/-   ##
==========================================
- Coverage   91.50%   91.49%   -0.01%     
==========================================
  Files         147      147              
  Lines       16142    16151       +9     
==========================================
+ Hits        14771    14778       +7     
- Misses       1371     1373       +2     
```


| [Impacted Files](https://codecov.io/gh/spacetelescope/jdaviz/pull/2157?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spacetelescope) | Coverage Δ | |
|---|---|---|
| [...igs/default/plugins/subset\_plugin/subset\_plugin.py](https://codecov.io/gh/spacetelescope/jdaviz/pull/2157?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spacetelescope#diff-amRhdml6L2NvbmZpZ3MvZGVmYXVsdC9wbHVnaW5zL3N1YnNldF9wbHVnaW4vc3Vic2V0X3BsdWdpbi5weQ==) | `97.12% <96.66%> (-1.42%)` | :arrow_down: |
| [.../plugins/subset\_plugin/tests/test\_subset\_plugin.py](https://codecov.io/gh/spacetelescope/jdaviz/pull/2157?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spacetelescope#diff-amRhdml6L2NvbmZpZ3MvZGVmYXVsdC9wbHVnaW5zL3N1YnNldF9wbHVnaW4vdGVzdHMvdGVzdF9zdWJzZXRfcGx1Z2luLnB5) | `100.00% <100.00%> (ø)` | |

... and [1 file with indirect coverage changes](https://codecov.io/gh/spacetelescope/jdaviz/pull/2157/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spacetelescope)

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spacetelescope). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spacetelescope)

</details>

[:umbrella: View full report in Codecov by Sentry](https://codecov.io/gh/spacetelescope/jdaviz/pull/2157?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spacetelescope).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spacetelescope).

javerbukh: @kecnry I could see the subset definition being moved to `get_subsets` but afaik there isn't a great reason for that. So far, only the Subset Plugin uses the front-end-friendly subset definition. Were there other sections you had in mind?

Live updating will most likely not be possible with this implementation considering the only way to update composite subsets (from what I've experimented with so far) is to create a copy with the updated values and then overwrite the subset with that copy. I plan on working on updating composite subsets as the follow-up work for this. I can absolutely give live updating a try in the next PR but I am not optimistic about it working with how subsets behave currently.
javerbukh: Here is what the layout looks like now:

![image](https://user-images.githubusercontent.com/7179333/236252288-1f0ee663-e323-46d1-a7cc-308e3c193738.png)

javerbukh: Thank you for the reviews! Merging now.

Patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index 3683a6d7..d2a31ae2 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -10,6 +10,8 @@ New Features
 
 - Exact-text filtering for metadata plugin. [#2147]
 
+- Update Subset Plugin to utilize ``get_subsets()``. [#2157]
+
 Cubeviz
 ^^^^^^^
 
diff --git a/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py b/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py
index 76f8e91d..3af7db91 100644
--- a/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py
+++ b/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py
@@ -15,10 +15,12 @@ __all__ = ['SubsetPlugin']
 
 SUBSET_MODES = {
     'replace': ReplaceMode,
-    'add': OrMode,
-    'and': AndMode,
-    'xor': XorMode,
-    'remove': AndNotMode
+    'OrState': OrMode,
+    'AndState': AndMode,
+    'XorState': XorMode,
+    'AndNotState': AndNotMode,
+    'RangeSubsetState': RangeSubsetState,
+    'RoiSubsetState': RoiSubsetState
 }
 
 
@@ -32,6 +34,7 @@ class SubsetPlugin(PluginTemplateMixin, DatasetSelectMixin):
     show_region_info = Bool(True).tag(sync=True)
     subset_types = List([]).tag(sync=True)
     subset_definitions = List([]).tag(sync=True)
+    glue_state_types = List([]).tag(sync=True)
     has_subset_details = Bool(False).tag(sync=True)
 
     subplugins_opened = Any().tag(sync=True)
@@ -54,6 +57,7 @@ class SubsetPlugin(PluginTemplateMixin, DatasetSelectMixin):
                                           'subset_items',
                                           'subset_selected',
                                           default_text="Create New")
+        self.subset_states = []
 
     def _sync_selected_from_state(self, *args):
         if not hasattr(self, 'subset_select'):
@@ -91,6 +95,7 @@ class SubsetPlugin(PluginTemplateMixin, DatasetSelectMixin):
     def _sync_selected_from_ui(self, change):
         self.subset_definitions = []
         self.subset_types = []
+        self.glue_state_types = []
         self.is_editable = False
 
         if not hasattr(self, 'subset_select'):
@@ -113,78 +118,74 @@ class SubsetPlugin(PluginTemplateMixin, DatasetSelectMixin):
             self.session.edit_subset_mode = self.mode_selected
     '''
 
-    def _unpack_nested_subset(self, subset_state):
-        '''
-        Navigate through the tree of subset states for composite
-        subsets made up of multiple regions.
-        '''
-        if isinstance(subset_state, CompositeSubsetState):
-            self._unpack_nested_subset(subset_state.state1)
-            self._unpack_nested_subset(subset_state.state2)
-            self.is_editable = False
-        else:
-            if subset_state is not None:
-                self._get_subset_subregion_definition(subset_state)
-
-    def _get_subset_subregion_definition(self, subset_state):
-        """
-        Get the type and parameters for a single region in the subset. Note that
-        the string type and operation (if in a composite subset) need to be stored
-        separately from the float parameters for display reasons.
+    def _unpack_get_subsets_for_ui(self):
         """
-        subset_type = ''
-        subset_definition = []
-        self.is_editable = False
-        _around_decimals = 6  # Avoid 30 degrees from coming back as 29.999999999999996
+        Convert what app.get_subsets returns into something the UI of this plugin
+        can display.
 
-        if isinstance(subset_state, RoiSubsetState):
-            if isinstance(subset_state.roi, CircularROI):
-                x, y = subset_state.roi.get_center()
-                r = subset_state.roi.radius
-                subset_definition = [{"name": "X Center", "att": "xc", "value": x, "orig": x},
-                                     {"name": "Y Center", "att": "yc", "value": y, "orig": y},
-                                     {"name": "Radius", "att": "radius", "value": r, "orig": r}]
-                self.is_editable = True
-
-            elif isinstance(subset_state.roi, RectangularROI):
-                for att in ("Xmin", "Xmax", "Ymin", "Ymax"):
-                    real_att = att.lower()
-                    val = getattr(subset_state.roi, real_att)
-                    subset_definition.append(
-                        {"name": att, "att": real_att, "value": val, "orig": val})
-                theta = np.around(np.degrees(subset_state.roi.theta), decimals=_around_decimals)
-                subset_definition.append(
-                    {"name": "Angle", "att": "theta", "value": theta, "orig": theta})
-                self.is_editable = True
-
-            elif isinstance(subset_state.roi, EllipticalROI):
-                xc = subset_state.roi.xc
-                yc = subset_state.roi.yc
-                rx = subset_state.roi.radius_x
-                ry = subset_state.roi.radius_y
-                theta = np.around(np.degrees(subset_state.roi.theta), decimals=_around_decimals)
-                subset_definition = [
-                    {"name": "X Center", "att": "xc", "value": xc, "orig": xc},
-                    {"name": "Y Center", "att": "yc", "value": yc, "orig": yc},
-                    {"name": "X Radius", "att": "radius_x", "value": rx, "orig": rx},
-                    {"name": "Y Radius", "att": "radius_y", "value": ry, "orig": ry},
-                    {"name": "Angle", "att": "theta", "value": theta, "orig": theta}]
-                self.is_editable = True
-
-            subset_type = subset_state.roi.__class__.__name__
+        Returns
+        -------
 
-        elif isinstance(subset_state, RangeSubsetState):
-            lo = subset_state.lo
-            hi = subset_state.hi
-            subset_definition = [{"name": "Lower bound", "att": "lo", "value": lo, "orig": lo},
-                                 {"name": "Upper bound", "att": "hi", "value": hi, "orig": hi}]
+        """
+        subset_information = self.app.get_subsets(self.subset_selected, simplify_spectral=False)
+        _around_decimals = 6  # Avoid 30 degrees from coming back as 29.999999999999996
+        if not subset_information:
+            return
+        if len(subset_information) == 1:
             self.is_editable = True
-            subset_type = "Range"
+        else:
+            self.is_editable = False
 
-        if len(subset_definition) > 0 and subset_definition not in self.subset_definitions:
-            # Note: .append() does not work for List traitlet.
-            self.subset_definitions = self.subset_definitions + [subset_definition]
-            self.subset_types = self.subset_types + [subset_type]
+        for spec in subset_information:
+            subset_definition = []
+            subset_type = ''
+            subset_state = spec["subset_state"]
+            glue_state = spec["glue_state"]
+            if isinstance(subset_state, RoiSubsetState):
+                if isinstance(subset_state.roi, CircularROI):
+                    x, y = subset_state.roi.get_center()
+                    r = subset_state.roi.radius
+                    subset_definition = [{"name": "X Center", "att": "xc", "value": x, "orig": x},
+                                         {"name": "Y Center", "att": "yc", "value": y, "orig": y},
+                                         {"name": "Radius", "att": "radius", "value": r, "orig": r}]
+
+                elif isinstance(subset_state.roi, RectangularROI):
+                    for att in ("Xmin", "Xmax", "Ymin", "Ymax"):
+                        real_att = att.lower()
+                        val = getattr(subset_state.roi, real_att)
+                        subset_definition.append(
+                            {"name": att, "att": real_att, "value": val, "orig": val})
+                    theta = np.around(np.degrees(subset_state.roi.theta), decimals=_around_decimals)
+                    subset_definition.append(
+                        {"name": "Angle", "att": "theta", "value": theta, "orig": theta})
+
+                elif isinstance(subset_state.roi, EllipticalROI):
+                    xc = subset_state.roi.xc
+                    yc = subset_state.roi.yc
+                    rx = subset_state.roi.radius_x
+                    ry = subset_state.roi.radius_y
+                    theta = np.around(np.degrees(subset_state.roi.theta), decimals=_around_decimals)
+                    subset_definition = [
+                        {"name": "X Center", "att": "xc", "value": xc, "orig": xc},
+                        {"name": "Y Center", "att": "yc", "value": yc, "orig": yc},
+                        {"name": "X Radius", "att": "radius_x", "value": rx, "orig": rx},
+                        {"name": "Y Radius", "att": "radius_y", "value": ry, "orig": ry},
+                        {"name": "Angle", "att": "theta", "value": theta, "orig": theta}]
+
+                subset_type = subset_state.roi.__class__.__name__
+
+            elif isinstance(subset_state, RangeSubsetState):
+                lo = subset_state.lo
+                hi = subset_state.hi
+                subset_definition = [{"name": "Lower bound", "att": "lo", "value": lo, "orig": lo},
+                                     {"name": "Upper bound", "att": "hi", "value": hi, "orig": hi}]
+                subset_type = "Range"
+            if len(subset_definition) > 0:
+                # Note: .append() does not work for List traitlet.
+                self.subset_definitions = self.subset_definitions + [subset_definition]
+                self.subset_types = self.subset_types + [subset_type]
+                self.glue_state_types = self.glue_state_types + [glue_state]
+                self.subset_states = self.subset_states + [subset_state]
 
     def _get_subset_definition(self, *args):
         """
@@ -193,40 +194,35 @@ class SubsetPlugin(PluginTemplateMixin, DatasetSelectMixin):
         """
         self.subset_definitions = []
         self.subset_types = []
+        self.glue_state_types = []
+        self.subset_states = []
 
-        self._unpack_nested_subset(self.subset_select.selected_subset_state)
+        self._unpack_get_subsets_for_ui()
 
     def vue_update_subset(self, *args):
-        if not self.is_editable:  # no-op
-            return
-
-        subset_state = self.subset_select.selected_subset_state
-
-        # Composite region cannot be edited, so just grab first element.
-        subset_type = self.subset_types[0]
-        subset_definition = self.subset_definitions[0]
-
-        try:
-            if subset_type == "Range":
-                sbst_obj = subset_state
-            else:
-                sbst_obj = subset_state.roi
-
-            for d_att in subset_definition:
+        for index, sub in enumerate(self.subset_definitions):
+            sub_states = self.subset_states[index]
+            for d_att in sub:
                 if d_att["att"] == 'theta':  # Humans use degrees but glue uses radians
                     d_val = np.radians(d_att["value"])
                 else:
-                    d_val = d_att["value"]
-
-                setattr(sbst_obj, d_att["att"], d_val)
-
-            # Force glue to update the Subset. This is the same call used in
-            # glue.core.edit_subset_mode.EditSubsetMode.update() but we do not
-            # want to deal with all the contract stuff tied to the update() method.
-            self.session.edit_subset_mode._combine_data(subset_state, override_mode=ReplaceMode)
-        except Exception as err:  # pragma: no cover
-            self.hub.broadcast(SnackbarMessage(
-                f"Failed to update Subset: {repr(err)}", color='error', sender=self))
+                    d_val = float(d_att["value"])
+                if float(d_att["orig"]) != d_val:
+                    if self.subset_types[index] == "Range":
+                        setattr(sub_states, d_att["att"], d_val)
+                    else:
+                        setattr(sub_states.roi, d_att["att"], d_val)
+            try:
+                # TODO: This commented out section is "more correct" because it
+                #  adds the changed subregion to the data_collection.subset_groups
+                #  tree. However, it still needs improvement and the section below
+                #  allows updating similar to `main`.
+                # self.session.edit_subset_mode._combine_data(sub_states,
+                # override_mode=SUBSET_MODES[self.glue_state_types[index]])
+                self.session.edit_subset_mode._combine_data(sub_states, override_mode=ReplaceMode)
+            except Exception as err:  # pragma: no cover
+                self.hub.broadcast(SnackbarMessage(
+                    f"Failed to update Subset: {repr(err)}", color='error', sender=self))
 
     def vue_recenter_subset(self, *args):
         # Composite region cannot be edited. This only works for Imviz.
@@ -296,6 +292,9 @@ class SubsetPlugin(PluginTemplateMixin, DatasetSelectMixin):
         elif isinstance(subset_state, RangeSubsetState):
             cen = (subset_state.hi - subset_state.lo) * 0.5 + subset_state.lo
 
+        elif isinstance(subset_state, CompositeSubsetState):
+            cen = None
+
         else:  # pragma: no cover
             raise NotImplementedError(
                 f'Getting center of {subset_state.__class__} is not supported')
diff --git a/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.vue b/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.vue
index 895f798f..354c3376 100644
--- a/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.vue
+++ b/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.vue
@@ -45,44 +45,26 @@
       </v-expansion-panels>
     </v-row>
 
-    <!-- Composite region cannot be edited, so just grab first element. -->
-    <div v-if="is_editable">
-      <v-row v-for="(item, index2) in subset_definitions[0]"
-       class="pt-0 pb-0 mt-0 mb-0">
+    <!-- Show all subregions of a subset, including Glue state and subset type. -->
+    <div v-for="(region, index) in subset_definitions">
+      <v-row no-gutters>
+          <v-col>Subset type: {{ subset_types[index] }}</v-col>
+      </v-row>
+      <v-row no-gutters>
+          <v-col>Glue state: {{ glue_state_types[index] }}</v-col>
+      </v-row>
+      <v-row v-for="(item, index2) in region">
         <v-text-field
           :label="item.name"
           v-model.number="item.value"
           type="number"
+          :disabled="!is_editable"
         ></v-text-field>
       </v-row>
+    </div>
 
       <v-row justify="end" no-gutters>
-        <v-btn color="primary" text @click="update_subset">Update</v-btn>
+        <v-btn color="primary" text @click="update_subset" :disabled="!is_editable">Update</v-btn>
       </v-row>
-    </div>
-
-    <div v-if="show_region_info">
-      <j-plugin-section-header>Subset Region Definition</j-plugin-section-header>
-      <div v-if="subset_definitions.length">
-        <v-row v-for="(subset_definition, index) in subset_definitions" no-gutters>
-          <v-col>
-            <v-row class="pt-0 pb-0 mt-0 mb-0">
-              <v-col>Subset type:</v-col>
-              <v-col>{{ subset_types[index] }}</v-col>
-            </v-row>
-            <v-row v-for="(item, index2) in subset_definition"
-             class="pt-0 pb-0 mt-0 mb-0" no-gutters>
-              <v-col>{{ item.name }}:</v-col>
-              <v-col>
-                <j-number-uncertainty
-                  :value="item.orig"
-                  :defaultDigs="6"
-                ></j-number-uncertainty>
-              </v-col>
-            </v-row>
-          </v-col>
-        </v-row>
-      </div>
-    </div>
   </j-tray-plugin>
 </template>


Test patch:
diff --git a/jdaviz/configs/default/plugins/subset_plugin/tests/test_subset_plugin.py b/jdaviz/configs/default/plugins/subset_plugin/tests/test_subset_plugin.py
index 423adccb..b867e624 100644
--- a/jdaviz/configs/default/plugins/subset_plugin/tests/test_subset_plugin.py
+++ b/jdaviz/configs/default/plugins/subset_plugin/tests/test_subset_plugin.py
@@ -1,4 +1,6 @@
+import warnings
 import pytest
+
 from glue.core.roi import XRangeROI
 
 
@@ -16,3 +18,10 @@ def test_plugin(specviz_helper, spectrum1d):
     po = specviz_helper.plugins['Plot Options']
     po.layer = 'Subset 1'
     po.line_color = 'green'
+
+
+def test_subset_definition_with_composite_subset(cubeviz_helper, spectrum1d_cube):
+    with warnings.catch_warnings():
+        warnings.simplefilter('ignore')
+        cubeviz_helper.load_data(spectrum1d_cube)
+    cubeviz_helper.app.get_tray_item_from_name('g-subset-plugin')
diff --git a/jdaviz/tests/test_subsets.py b/jdaviz/tests/test_subsets.py
index 28f5fbeb..972231c6 100644
--- a/jdaviz/tests/test_subsets.py
+++ b/jdaviz/tests/test_subsets.py
@@ -62,8 +62,8 @@ def test_region_from_subset_3d(cubeviz_helper):
 
     cubeviz_helper.app.get_viewer('flux-viewer').apply_roi(RectangularROI(1, 3.5, -0.2, 3.3))
 
-    subsets = cubeviz_helper.app.get_subsets_from_viewer('flux-viewer')
-    reg = subsets.get('Subset 1')
+    subsets = cubeviz_helper.app.get_subsets()
+    reg = cubeviz_helper.app.get_subsets('Subset 1', object_only=True)[0]
 
     assert len(subsets) == 1
     assert isinstance(reg, RectanglePixelRegion)
@@ -273,8 +273,7 @@ def test_disjoint_spectral_subset(cubeviz_helper, spectral_cube_wcs):
     cubeviz_helper.app.session.edit_subset_mode.mode = OrMode
     spec_viewer.apply_roi(XRangeROI(30, 35))
 
-    subsets = cubeviz_helper.app.get_subsets_from_viewer('spectrum-viewer')
-    reg = subsets.get('Subset 1')
+    reg = cubeviz_helper.app.get_subsets('Subset 1')
 
     assert len(reg) == 2
     assert isinstance(reg, SpectralRegion)
@@ -285,31 +284,32 @@ def test_disjoint_spectral_subset(cubeviz_helper, spectral_cube_wcs):
 
     assert subset_plugin.subset_selected == "Subset 1"
     assert subset_plugin.subset_types == ["Range", "Range"]
-    assert not subset_plugin.is_editable
+    assert subset_plugin.glue_state_types == ["RangeSubsetState", "OrState"]
+    # assert not subset_plugin.is_editable
     assert subset_plugin.get_center() is None
-    subset_plugin.set_center(99, update=True)   # This is no-op
+    # TODO: Should this be changed to something else?
+    # subset_plugin.set_center(99, update=True)   # This is no-op
     for key in ("orig", "value"):
-        assert subset_plugin._get_value_from_subset_definition(0, "Lower bound", key) == 30
-        assert subset_plugin._get_value_from_subset_definition(0, "Upper bound", key) == 35
-        assert subset_plugin._get_value_from_subset_definition(1, "Lower bound", key) == 5
-        assert subset_plugin._get_value_from_subset_definition(1, "Upper bound", key) == 15.5
+        assert subset_plugin._get_value_from_subset_definition(1, "Lower bound", key) == 30
+        assert subset_plugin._get_value_from_subset_definition(1, "Upper bound", key) == 35
+        assert subset_plugin._get_value_from_subset_definition(0, "Lower bound", key) == 5
+        assert subset_plugin._get_value_from_subset_definition(0, "Upper bound", key) == 15.5
 
     # This should not be possible via GUI but here we change
     # something to make sure no-op is really no-op.
     subset_plugin._set_value_in_subset_definition(0, "Lower bound", "value", 25)
-    subset_plugin.vue_update_subset()
+    # subset_plugin.vue_update_subset()
     # "value" here does not matter. It is going to get overwritten next time Subset is processed.
     assert subset_plugin._get_value_from_subset_definition(0, "Lower bound", "value") == 25
-    assert subset_plugin._get_value_from_subset_definition(0, "Lower bound", "orig") == 30
+    assert subset_plugin._get_value_from_subset_definition(0, "Lower bound", "orig") == 5
 
-    subsets = cubeviz_helper.app.get_subsets_from_viewer('spectrum-viewer')
-    reg = subsets.get('Subset 1')
+    reg = cubeviz_helper.app.get_subsets('Subset 1')
     assert_quantity_allclose(reg[1].lower, 30.0*u.Hz)  # Still the old value
 
     # See, never happened.
     subset_plugin.subset_selected = "Create New"
     subset_plugin.subset_selected = "Subset 1"
-    assert subset_plugin._get_value_from_subset_definition(0, "Lower bound", "value") == 30
+    assert subset_plugin._get_value_from_subset_definition(0, "Lower bound", "value") == 5
 
 
 def test_composite_region_from_subset_3d(cubeviz_helper):
@@ -356,6 +356,13 @@ def test_composite_region_from_subset_3d(cubeviz_helper):
     assert reg[-1] == {'name': 'CircularROI', 'glue_state': 'AndNotState', 'region': circle2,
                        'subset_state': reg[-1]['subset_state']}
 
+    subset_plugin = cubeviz_helper.app.get_tray_item_from_name('g-subset-plugin')
+    assert subset_plugin.subset_selected == "Subset 1"
+    assert subset_plugin.subset_types == ['CircularROI', 'RectangularROI', 'EllipticalROI',
+                                          'RectangularROI', 'CircularROI']
+    assert subset_plugin.glue_state_types == ['AndState', 'AndNotState',
+                                              'OrState', 'AndState', 'AndNotState']
+
 
 def test_composite_region_with_consecutive_and_not_states(cubeviz_helper):
     data = Data(flux=np.ones((128, 128, 10)), label='Test 3D Flux')
@@ -398,6 +405,11 @@ def test_composite_region_with_consecutive_and_not_states(cubeviz_helper):
     spatial_list = cubeviz_helper.app.get_subsets("Subset 1", spatial_only=True)
     assert len(spatial_list) == 3
 
+    subset_plugin = cubeviz_helper.app.get_tray_item_from_name('g-subset-plugin')
+    assert subset_plugin.subset_selected == "Subset 1"
+    assert subset_plugin.subset_types == ['CircularROI', 'RectangularROI', 'EllipticalROI']
+    assert subset_plugin.glue_state_types == ['AndState', 'AndNotState', 'AndNotState']
+
 
 def test_composite_region_with_imviz(imviz_helper, image_2d_wcs):
     arr = np.ones((10, 10))
@@ -427,6 +439,11 @@ def test_composite_region_with_imviz(imviz_helper, image_2d_wcs):
     assert reg[-1] == {'name': 'EllipticalROI', 'glue_state': 'AndNotState', 'region': ellipse1,
                        'subset_state': reg[-1]['subset_state']}
 
+    subset_plugin = imviz_helper.app.get_tray_item_from_name('g-subset-plugin')
+    assert subset_plugin.subset_selected == "Subset 1"
+    assert subset_plugin.subset_types == ['CircularROI', 'RectangularROI', 'EllipticalROI']
+    assert subset_plugin.glue_state_types == ['AndState', 'AndNotState', 'AndNotState']
+
 
 def test_with_invalid_subset_name(cubeviz_helper):
     subset_name = "Test"
@@ -470,3 +487,8 @@ def test_composite_region_from_subset_2d(specviz_helper, spectrum1d):
                              7500 * spectrum1d.spectral_axis.unit)
     assert reg[-1]['region'].lower == subset1.lower and reg[-1]['region'].upper == subset1.upper
     assert reg[-1]['glue_state'] == 'AndState'
+
+    subset_plugin = specviz_helper.app.get_tray_item_from_name('g-subset-plugin')
+    assert subset_plugin.subset_selected == "Subset 1"
+    assert subset_plugin.subset_types == ['Range', 'Range', 'Range', 'Range']
+    assert subset_plugin.glue_state_types == ['AndState', 'AndNotState', 'OrState', 'AndState']