jdaviz icon indicating copy to clipboard operation
jdaviz copied to clipboard

[BUG] Mosviz: Model Fitting doesn't work in Mosviz

Open PatrickOgle opened this issue 3 years ago • 7 comments

Describe the bug All attempts to fit a model using the Model Fitting plugin in Mosviz fail, for even the simplest model (Constant1D), to either the full Dataset or a Subset. The following traceback is generated:

IndexError                                Traceback (most recent call last)
~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/ipyvue/VueTemplateWidget.py in _handle_event(self, _, content, buffers)
     55                 getattr(self, 'vue_' + event)(data, buffers)
     56             else:
---> 57                 getattr(self, 'vue_' + event)(data)
     58 
     59 

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/jdaviz/configs/default/plugins/model_fitting/model_fitting.py in vue_model_fitting(self, *args, **kwargs)
    359         self._fitted_spectrum = fitted_spectrum
    360 
--> 361         self.vue_register_spectrum({"spectrum": fitted_spectrum})
    362         self.app.fitted_models[self.model_label] = fitted_model
    363 

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/jdaviz/configs/default/plugins/model_fitting/model_fitting.py in vue_register_spectrum(self, event)
    498             # Remove the actual Glue data object from the data_collection
    499             self.data_collection.remove(self.data_collection[label])
--> 500         self.data_collection[label] = spectrum
    501 
    502         self.app.add_data_to_viewer('spectrum-viewer', label)

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/data_collection.py in __setitem__(self, key, data)
    391                 self.remove(existing_data)
    392 
--> 393         self.append(data)
    394 
    395     def __iter__(self):

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/data_collection.py in append(self, data)
     80                 s.register()
     81             msg = DataCollectionAddMessage(self, data)
---> 82             self.hub.broadcast(msg)
     83 
     84         self._sync_link_manager()

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/hub.py in broadcast(self, message)
    213             logging.getLogger(__name__).info("Broadcasting %s", message)
    214             for subscriber, handler in self._find_handlers(message):
--> 215                 handler(message)
    216 
    217     def __getstate__(self):

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/jdaviz/app.py in _on_data_added(self, msg)
   1022             the new data.
   1023         """
-> 1024         self._link_new_data()
   1025         data_item = self._create_data_item(msg.data.label)
   1026         self.state.data_items.append(data_item)

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/jdaviz/app.py in _link_new_data(self)
    257                 continue
    258             else:
--> 259                 self.data_collection.add_link(LinkSame(wc_old[0], wc_new[0]))
    260                 break
    261 

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/data_collection.py in add_link(self, links)
    160            instances, or a :class:`~glue.core.link_helpers.LinkCollection`
    161         """
--> 162         self._link_manager.add_link(links)
    163 
    164     def remove_link(self, links):

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/link_manager.py in add_link(self, link, update_external)
    187                 self._external_links.append(link)
    188                 if update_external:
--> 189                     self.update_externally_derivable_components()
    190 
    191     @contract(link=ComponentLink)

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/link_manager.py in update_externally_derivable_components(self, data)
    240                 d = DerivedComponent(data, link)
    241                 comps[cid] = d
--> 242             data._set_externally_derivable_components(comps)
    243 
    244         # Now update information about pixel-aligned data

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/data.py in _set_externally_derivable_components(self, derivable_components)
   1028         if self.hub:
   1029             msg = ExternallyDerivableComponentsChangedMessage(self)
-> 1030             self.hub.broadcast(msg)
   1031 
   1032     def _set_pixel_aligned_data(self, pixel_aligned_data):

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/hub.py in broadcast(self, message)
    213             logging.getLogger(__name__).info("Broadcasting %s", message)
    214             for subscriber, handler in self._find_handlers(message):
--> 215                 handler(message)
    216 
    217     def __getstate__(self):

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/viewers/common/viewer.py in _update_data(self, message)
    271                 else:
    272                     if layer_artist.layer is message.data:
--> 273                         layer_artist.update()
    274 
    275     def _update_subset(self, message):

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue_jupyter/table/viewer.py in update(self)
    157 
    158     def update(self):
--> 159         self._refresh()
    160 
    161     def clear(self):

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue_jupyter/table/viewer.py in _refresh(self)
    151 
    152     def _refresh(self):
--> 153         self._table_viewer.redraw()
    154 
    155     def redraw(self):

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue_jupyter/table/viewer.py in redraw(self)
    204             self.widget_table.selections = [subset.label for subset in subsets]
    205             self.widget_table.selection_colors = [subset.style.color for subset in subsets]
--> 206         self.widget_table._update()
    207 
    208     def apply_filter(self):

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue_jupyter/table/viewer.py in _update(self)
     29     def _update(self):
     30         self._update_columns()
---> 31         self._update_items()
     32         self.total_length = len(self)
     33         self.options = {**self.options, 'totalItems': self.total_length}

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue_jupyter/table/viewer.py in _update_items(self)
     68 
     69     def _update_items(self):
---> 70         self.items = self._get_items()
     71 
     72     @traitlets.default('items')

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue_jupyter/table/viewer.py in _get_items(self)
    127 
    128         view = slice(i1, i2)
--> 129         masks = {k.label: k.to_mask(view) for k in self.data.subsets}
    130 
    131         items = []

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue_jupyter/table/viewer.py in <dictcomp>(.0)
    127 
    128         view = slice(i1, i2)
--> 129         masks = {k.label: k.to_mask(view) for k in self.data.subsets}
    130 
    131         items = []

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/subset.py in to_mask(self, view)
    180 
    181         """
--> 182         return self.data.get_mask(self.subset_state, view=view)
    183 
    184     @contract(value=bool)

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/data.py in get_mask(self, subset_state, view)
   1383     def get_mask(self, subset_state, view=None):
   1384         try:
-> 1385             return subset_state.to_mask(self, view=view)
   1386         except IncompatibleAttribute:
   1387             return get_mask_with_key_joins(self, self._key_joins, subset_state, view=view)

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/subset.py in to_mask(self, data, view)
    771     @contract(data='isinstance(Data)', view='array_view')
    772     def to_mask(self, data, view=None):
--> 773         x = data[self.att, view]
    774         result = (x >= self.lo) & (x <= self.hi)
    775         return result

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/data.py in __getitem__(self, key)
    569                 raise IncompatibleAttribute(_k)
    570 
--> 571         return self.get_data(key, view=view)
    572 
    573     def _ipython_key_completions_(self):

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/data.py in get_data(self, cid, view)
   1362 
   1363         if view is not None:
-> 1364             result = comp[view]
   1365         else:
   1366             result = comp.data

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/component.py in __getitem__(self, key)
    196 
    197     def __getitem__(self, key):
--> 198         return self._link.compute(self._data, key)
    199 
    200 

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/component_link.py in compute(self, data, view)
    164 
    165         # First we get the values of all the 'from' components.
--> 166         args = [data[join_component_view(f, view)] for f in self._from]
    167 
    168         # We keep track of the original shape of the arguments

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/component_link.py in <listcomp>(.0)
    164 
    165         # First we get the values of all the 'from' components.
--> 166         args = [data[join_component_view(f, view)] for f in self._from]
    167 
    168         # We keep track of the original shape of the arguments

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/data.py in __getitem__(self, key)
    569                 raise IncompatibleAttribute(_k)
    570 
--> 571         return self.get_data(key, view=view)
    572 
    573     def _ipython_key_completions_(self):

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/data.py in get_data(self, cid, view)
   1362 
   1363         if view is not None:
-> 1364             result = comp[view]
   1365         else:
   1366             result = comp.data

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/component.py in __getitem__(self, key)
    196 
    197     def __getitem__(self, key):
--> 198         return self._link.compute(self._data, key)
    199 
    200 

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/component_link.py in compute(self, data, view)
    164 
    165         # First we get the values of all the 'from' components.
--> 166         args = [data[join_component_view(f, view)] for f in self._from]
    167 
    168         # We keep track of the original shape of the arguments

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/component_link.py in <listcomp>(.0)
    164 
    165         # First we get the values of all the 'from' components.
--> 166         args = [data[join_component_view(f, view)] for f in self._from]
    167 
    168         # We keep track of the original shape of the arguments

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/data.py in __getitem__(self, key)
    569                 raise IncompatibleAttribute(_k)
    570 
--> 571         return self.get_data(key, view=view)
    572 
    573     def _ipython_key_completions_(self):

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/data.py in get_data(self, cid, view)
   1362 
   1363         if view is not None:
-> 1364             result = comp[view]
   1365         else:
   1366             result = comp.data

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/component.py in __getitem__(self, key)
    196 
    197     def __getitem__(self, key):
--> 198         return self._link.compute(self._data, key)
    199 
    200 

~/miniconda3/envs/jwebbinar7/lib/python3.8/site-packages/glue/core/component_link.py in compute(self, data, view)
    167 
    168         # We keep track of the original shape of the arguments
--> 169         original_shape = args[0].shape
    170         logger.debug("shape of first argument: %s", original_shape)
    171 

IndexError: list index out of range

To Reproduce Steps to reproduce the behavior:

  1. Go to Model Fitting
  2. Click on 1DSpectrum (or Subset)
  3. Add a constant model component 'C'
  4. Enter 'C' in the Model Equation Editor
  5. Press 'Fit'

Expected behavior The model should be fitted and plotted in the spectrum viewer

Screenshots N/A Desktop (please complete the following information):

  • OS: OSX 10.15.7
  • Browser: safari
  • Jupyter: [run "jupyter --version"] jupyter core : 4.7.1 jupyter-notebook : 6.4.0 qtconsole : 5.1.1 ipython : 7.25.0 ipykernel : 6.0.3 jupyter client : 6.1.12 jupyter lab : not installed nbconvert : 6.1.0 ipywidgets : 7.6.3 nbformat : 5.1.3 traitlets : 5.0.5

Package versions (please complete the following information):

macOS-10.15.7-x86_64-i386-64bit Python 3.8.10 | packaged by conda-forge | (default, May 10 2021, 22:58:09) [Clang 11.1.0 ] Numpy 1.21.1 astropy 4.3 specutils 1.3 spectral-cube 0.5.0 pyyaml 5.4.1 click 8.0.1 asteval 0.9.25 idna 2.10 traitlets 5.0.5 bqplot 0.12.30 bqplot-image-gl 1.4.3 glue-core 1.0.1 glue-jupyter 0.7 glue-astronomy 0.2 echo 0.5 ipyvue 1.5.0 ipyvuetify 1.8.0 ipysplitpanes 0.2.0 ipygoldenlayout 0.4.0 voila 0.2.10 vispy 0.7.3 Jdaviz 1.2.dev365+ge29b827

Additional context (e.g. data files) ERS NIRSpec MOS PRISM dataset with cutouts, jwst 1.1.0-processed

Model fitting works in Specviz and Cubeviz, but has never been attempted for an x1d in Mosviz.

🐱

PatrickOgle avatar Jul 30 '21 18:07 PatrickOgle