def newView(self, type="scatter", components=[], title="New View", **kwargs): only_subsets = kwargs.get('only_subsets', False) only_view = kwargs.get('only_view', False) if (self.parent is not None): kwargs.setdefault('modal', self.parent.modal) if (self.debug is not None): kwargs.setdefault('debug', self.debug) gp = None mode = "tab-after" if (len(self.active_views.values()) == 0): mode = "split-bottom" kwargs.setdefault('mode', mode) if only_view is False: gp = self.factory.createGluePlot(type, self.data, components, title, **kwargs) else: data = Data(label=self.data.label) for c in components: data.add_component(self.data[c, self.selection], label=c) data.get_component(c).color = self.data.get_component(c).color if (data.size > 0): gp = self.factory.createGluePlot(type, data, components, title, **kwargs) if gp is not None: if only_view is False: gp.setParent(self) key = id(gp.window) self.active_views[key] = gp self.views[key] = { 'type': type, 'components': components, 'title': title, 'kwargs': kwargs } if isinstance(gp.window, Floatview): gp.window.observe( lambda changes: GlueManager.removeViewIfDisposed( self, gp.window), 'uid') self.parent.updateHistory() return gp
def vue_fit_model_to_cube(self, *args, **kwargs): if self._warn_if_no_equation(): return data = self.app.data_collection[self._selected_data_label] # First, ensure that the selected data is cube-like. It is possible # that the user has selected a pre-existing 1d data object. if data.ndim != 3: snackbar_message = SnackbarMessage( f"Selected data {self._selected_data_label} is not cube-like", color='error', sender=self) self.hub.broadcast(snackbar_message) return # Get the primary data component attribute = data.main_components[0] component = data.get_component(attribute) temp_values = data.get_data(attribute) # Transpose the axis order values = np.moveaxis(temp_values, 0, -1) * u.Unit(component.units) # We manually create a Spectrum1D object from the flux information # in the cube we select wcs = data.coords.sub([WCSSUB_SPECTRAL]) spec = Spectrum1D(flux=values, wcs=wcs) # TODO: in vuetify >2.3, timeout should be set to -1 to keep open # indefinitely snackbar_message = SnackbarMessage("Fitting model to cube...", loading=True, timeout=0, sender=self) self.hub.broadcast(snackbar_message) # Retrieve copy of the models with proper "fixed" dictionaries # TODO: figure out why this was causing the parallel fitting to fail #models_to_fit = self._reinitialize_with_fixed() models_to_fit = self._initialized_models.values() fitted_model, fitted_spectrum = fit_model_to_spectrum( spec, models_to_fit, self.model_equation, run_fitter=True) # Save fitted 3D model in a way that the cubeviz # helper can access it. self.app._fitted_3d_model = fitted_model # Transpose the axis order back values = np.moveaxis(fitted_spectrum.flux.value, -1, 0) count = max( map(lambda s: int(next(iter(re.findall("\d$", s)), 0)), self.data_collection.labels)) + 1 label = f"{self.model_label} [Cube] {count}" # Create new glue data object output_cube = Data(label=label, coords=data.coords) output_cube['flux'] = values output_cube.get_component('flux').units = \ fitted_spectrum.flux.unit.to_string() # Add to data collection self.app.data_collection.append(output_cube) snackbar_message = SnackbarMessage("Finished cube fitting", color='success', loading=False, sender=self) self.hub.broadcast(snackbar_message)
def vue_fit_model_to_cube(self, *args, **kwargs): if self._warn_if_no_equation(): return if self.selected_data in self.app.data_collection.labels: data = self.app.data_collection[self.selected_data] else: # User selected some subset from spectrum viewer, just use original cube data = self.app.data_collection[0] # First, ensure that the selected data is cube-like. It is possible # that the user has selected a pre-existing 1d data object. if data.ndim != 3: snackbar_message = SnackbarMessage( f"Selected data {self.selected_data} is not cube-like", color='error', sender=self) self.hub.broadcast(snackbar_message) return # Get the primary data component attribute = data.main_components[0] component = data.get_component(attribute) temp_values = data.get_data(attribute) # Transpose the axis order values = np.moveaxis(temp_values, 0, -1) * u.Unit(component.units) # We manually create a Spectrum1D object from the flux information # in the cube we select wcs = data.coords.sub([WCSSUB_SPECTRAL]) spec = Spectrum1D(flux=values, wcs=wcs) # TODO: in vuetify >2.3, timeout should be set to -1 to keep open # indefinitely snackbar_message = SnackbarMessage("Fitting model to cube...", loading=True, timeout=0, sender=self) self.hub.broadcast(snackbar_message) # Retrieve copy of the models with proper "fixed" dictionaries models_to_fit = self._reinitialize_with_fixed() try: fitted_model, fitted_spectrum = fit_model_to_spectrum( spec, models_to_fit, self.model_equation, run_fitter=True, window=self._window) except ValueError: snackbar_message = SnackbarMessage("Cube fitting failed", color='error', loading=False, sender=self) self.hub.broadcast(snackbar_message) raise # Save fitted 3D model in a way that the cubeviz # helper can access it. for m in fitted_model: temp_label = "{} ({}, {})".format(self.model_label, m["x"], m["y"]) self.app.fitted_models[temp_label] = m["model"] # Transpose the axis order back values = np.moveaxis(fitted_spectrum.flux.value, -1, 0) count = max( map(lambda s: int(next(iter(re.findall(r"\d$", s)), 0)), self.data_collection.labels)) + 1 label = f"{self.model_label} [Cube] {count}" # Create new glue data object output_cube = Data(label=label, coords=data.coords) output_cube['flux'] = values output_cube.get_component('flux').units = \ fitted_spectrum.flux.unit.to_string() # Add to data collection self.app.add_data(output_cube, label) if self.selected_viewer != 'None': # replace the contents in the selected viewer with the results from this plugin self.app.add_data_to_viewer(self.viewer_to_id.get( self.selected_viewer), label, clear_other_data=True) snackbar_message = SnackbarMessage("Finished cube fitting", color='success', loading=False, sender=self) self.hub.broadcast(snackbar_message)
def vue_fit_model_to_cube(self, *args, **kwargs): if self._warn_if_no_equation(): return if self._selected_data_label in self.app.data_collection.labels: data = self.app.data_collection[self._selected_data_label] else: # User selected some subset from spectrum viewer, just use original cube data = self.app.data_collection[0] # First, ensure that the selected data is cube-like. It is possible # that the user has selected a pre-existing 1d data object. if data.ndim != 3: snackbar_message = SnackbarMessage( f"Selected data {self._selected_data_label} is not cube-like", color='error', sender=self) self.hub.broadcast(snackbar_message) return # Get the primary data component attribute = data.main_components[0] component = data.get_component(attribute) temp_values = data.get_data(attribute) # Transpose the axis order values = np.moveaxis(temp_values, 0, -1) * u.Unit(component.units) # We manually create a Spectrum1D object from the flux information # in the cube we select wcs = data.coords.sub([WCSSUB_SPECTRAL]) spec = Spectrum1D(flux=values, wcs=wcs) # TODO: in vuetify >2.3, timeout should be set to -1 to keep open # indefinitely snackbar_message = SnackbarMessage("Fitting model to cube...", loading=True, timeout=0, sender=self) self.hub.broadcast(snackbar_message) # Retrieve copy of the models with proper "fixed" dictionaries # TODO: figure out why this was causing the parallel fitting to fail # models_to_fit = self._reinitialize_with_fixed() models_to_fit = list(self._initialized_models.values()) # Remove units to work around current specutils/astropy modeling limitations # TODO: Keep units once astropy/specutils can handle them for all models removed_units = {} unitless_models = [] for m in models_to_fit: removed_units[m.name] = {} if type(m) == models.Polynomial1D: temp_model = m.__class__(name=m.name, degree=m.degree) else: temp_model = m.__class__(name=m.name) for pname in m.param_names: p = getattr(m, pname) removed_units[m.name][pname] = p.unit setattr(temp_model, pname, p.value) unitless_models.append(temp_model) models_to_fit = unitless_models try: fitted_model, fitted_spectrum = fit_model_to_spectrum( spec, models_to_fit, self.model_equation, run_fitter=True, window=self._window) except ValueError: snackbar_message = SnackbarMessage("Cube fitting failed", color='error', loading=False, sender=self) self.hub.broadcast(snackbar_message) raise # Save fitted 3D model in a way that the cubeviz # helper can access it. for m in fitted_model: temp_label = "{} ({}, {})".format(self.model_label, m["x"], m["y"]) self.app.fitted_models[temp_label] = m["model"] # Transpose the axis order back values = np.moveaxis(fitted_spectrum.flux.value, -1, 0) count = max( map(lambda s: int(next(iter(re.findall(r"\d$", s)), 0)), self.data_collection.labels)) + 1 label = f"{self.model_label} [Cube] {count}" # Create new glue data object output_cube = Data(label=label, coords=data.coords) output_cube['flux'] = values output_cube.get_component('flux').units = \ fitted_spectrum.flux.unit.to_string() # Add to data collection self.app.data_collection.append(output_cube) snackbar_message = SnackbarMessage("Finished cube fitting", color='success', loading=False, sender=self) self.hub.broadcast(snackbar_message)