From a51eb0ef7a1d1625c49ad48d2868a8e587b50690 Mon Sep 17 00:00:00 2001 From: Jennifer Kotler Date: Fri, 9 Dec 2022 16:35:17 -0500 Subject: [PATCH 01/42] Added .ico and .svg files --- docs/logos/cube.ico | Bin 0 -> 432254 bytes docs/logos/cube.svg | 1 + docs/logos/imviz.ico | Bin 0 -> 432254 bytes docs/logos/mos.ico | Bin 0 -> 432254 bytes docs/logos/mos.svg | 1 + docs/logos/specicon.svg | 1 + docs/logos/specviz.ico | Bin 0 -> 432254 bytes docs/logos/specviz2d.ico | Bin 0 -> 432254 bytes 8 files changed, 3 insertions(+) create mode 100644 docs/logos/cube.ico create mode 100644 docs/logos/cube.svg create mode 100644 docs/logos/imviz.ico create mode 100644 docs/logos/mos.ico create mode 100644 docs/logos/mos.svg create mode 100644 docs/logos/specicon.svg create mode 100644 docs/logos/specviz.ico create mode 100644 docs/logos/specviz2d.ico diff --git a/docs/logos/cube.ico b/docs/logos/cube.ico new file mode 100644 index 0000000000000000000000000000000000000000..35c7e0a46a402e2360ed464a1a3b8e6836f997ec GIT binary patch literal 432254 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 l4!_fB$9oYC}NaKSli`Ywbwuk~Gn2NA2> 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 \ No newline at end of file diff --git a/docs/logos/imviz.ico b/docs/logos/imviz.ico new file mode 100644 index 0000000000000000000000000000000000000000..ec2b3ac553185358968fe027abee3e2244b155c5 GIT binary patch literal 432254 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 literal 0 HcmV?d00001 diff --git a/docs/logos/mos.svg b/docs/logos/mos.svg new file mode 100644 index 0000000000..9667f16213 --- /dev/null +++ b/docs/logos/mos.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/logos/specicon.svg b/docs/logos/specicon.svg new file mode 100644 index 0000000000..2deb534e68 --- /dev/null +++ b/docs/logos/specicon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/logos/specviz.ico b/docs/logos/specviz.ico new file mode 100644 index 0000000000000000000000000000000000000000..f051cec174fc71c0bfebc7b55602cfa8cd2aacd2 GIT binary patch literal 432254 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%0A=pGC3bZ(-{{aX4Q{~@LY*aRG!F8wY0l6hXW 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

uZF)VE=9Z<98&H%Z{Ska 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 E0EGJr&;S4c literal 0 HcmV?d00001 diff --git a/docs/logos/specviz2d.ico b/docs/logos/specviz2d.ico new file mode 100644 index 0000000000000000000000000000000000000000..957345236f53acce1eef854e8038bc724429235a GIT binary patch literal 432254 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

Y=X8IvU)1xaz&+Z_yk`rXQtl&mbO z*A{x*<0pKVU&nnG`Mv7BSiT890dlFd)$v+qZpU?=64B=Dhqc zJ&CWgJ8sC>=!Rc{t7EK&+JPG72UZ;czbh`F95vycJQeu2h>xIJ0<8~QN6%8_t*Q@M zE+rd6I0hSF#B+{Q>R$xDIHut_2*Ru9A<@f(?@Dm3bNVd(=%d~tOIdqiT)#)MB1;XWMv^C;)90kOn)^ZY$Q7=cH!UFt zi{w&Em)G$dU54rJb03jhbGEdLP%u>hI%!on;R*PdoGJ ziMDY5i{$FQ$GX`&z%^PPd`m_<-g(h_Qo?`SA_evp1vFdKy0eKm0vUzyoHoT7+BR*p zm2b_lXCJ-QCf=C0F(Z20h~iJ}!XeBd_E+5rwFABBK?I*GKe*t%38^0f9~t#52LD;` zpg5vqU9tdd=)I1)Z-M?)O@VZy^mUebt~~W>T7yP?j?-W-!}lrYElVzQn!1)+bf@&K z@U(02y?UQTzd9Brb6jo&ot~vGCQH6tt~|15@%PE0O@<#A{;8*t>{4Dt4t#64Owe!9 zdB-z)9=TBB8rc=9lhRzBFt0kD48OA)c`}&KL%0X6@m8n&U3#`Q4nEEIuGK;{u3X7k8z6>*e4W_FWCyOZD$U- zg?QplF&ly9ovrAaR^}Ajb}-Mh)|M`Q#h!oSPd536tX(ziG#fgA9t2g#f{CNhzu*MS zdfx%^inH{XsR0WE!Q>$H_7Fx5G9tsssiuWmL**2D9-H!znCq$|FFD%>d6MX3FrN4b zjy>1S!lwEh2y?1el06|@3ZES3b8;*vY%Lp4)}BVQQo zB_p(^g4a`HPlUA0_I`|<}k-$fXFsplU5QKWz=}34(^JOU0}~qTR_xlb!+&j;X1;G1(5p1x>nm1!`XQF>b(rU^ zW`!esa_?!b{6a7$dtdrG=yK^%;a+k<`W5`SE(TX;3xD|X437zNF7e^z$LGO*;cRl~ z7=FA;{x%pE*5$t=XFS)DV~Pb9kOPuWidz)1AJh+_h<%~lNXdr+_Dex=NaRf|GA2Vj zv`&2&iHTqoGS_Vy`N*fc&$z4Yp(ba$E7%Ondps$@b8si*4eVK6dT-r`i>z zpV?^gk4I%sBnSC;)|Tw)F~fT7fC9R;mOPhgWP*BKc&MGf@}kHY8L-r zGD7Ek%@gpPWhmaScwyIL`mE!c6Y#hq*J&@=l1WJ}a8B_%zTbTYY!Br)$Ofq`*FMU2 zNahvt=MeK7NPTS$K796jc3J7icIEJ2+I1s)*?`*P=;6#1KRmVUGMMpU0f&m5V0@H#%-TbKn$jklVGeN=)-r( zkVsH(LeC}a!jH-|ZbNUW&P4J-`ADiaZQen=V8?dWjoV_IKKaBptXpHt-+cocVTwI? z*A+JLy0neG@V9nh<^N<>U@@cEj~wvctqxm zL+O=HOfQA4!JNgQ-ydStr<2z}p8bf-_iRl4Np|`0lkG}+V&8K80BUJVHue6??1gE! z*u0rj?9JDnwM7eN+sZ}rZS~4U^vwRyHg4MFze~2dNLVHfGO-*_;kd-9tRz3H>*VK? zuOoY(k3J+nL!Uhz(?Kq0+pX`*2g=8EJejBQ3*$?qz+O>6{G|D&z<&wfN#BSagWiFQ zWqUH*A=Tc`hig=Gq&(!rV^GY1r~#J}Q-tRejC}ew^|v;GqxEY(u#d?Qr8ts8wOLqHp)iz=5c{cItL3aDKLu?Xz zy`OZ=;P9Ef-cR7zpRPL3ZYP)FUUc_^w_RZOO*r4~pLCH;z2^#gri`;$&rGygGyY6% z#3T0B{OPuQ$sAkz(Yv-|>so%M@^5xyP`^Q+Brd(q&heYrK^%h?>aFQGtH^VJ0^zdy*(Ku0bwZ{>flXR?dd`lfIn`tG2h%BT{Sb*cW1_SziZ;om28Q$Oyg_XBzUx7UA) zTckjwK%_vVK%_vVK%_vVK%_vVK%_vVK%_vVK%_vVK%_vVK%_vVK%_vVK%_vVK%_vV RK%_vVK%_vVzyVKz{{h&uNRj{m literal 0 HcmV?d00001 From 0a398082b5c90ea4d58ad57e8d571433967feaa0 Mon Sep 17 00:00:00 2001 From: "P. L. Lim" <2090236+pllim@users.noreply.github.com> Date: Tue, 4 Apr 2023 13:24:14 -0400 Subject: [PATCH 02/42] app-wide display unit in specviz (#2048) * basic app-wide display unit in specviz (not all plugins are updated yet) * unit-aware select component which maps to glue-supported unit strings * implement use_display_units option for get_data, get_subsets Co-authored-by: Jesse Averbukh Co-authored-by: Kyle Conroy --- CHANGES.rst | 2 + docs/specviz/plugins.rst | 16 +- jdaviz/app.py | 121 ++++-- jdaviz/configs/cubeviz/helper.py | 5 +- .../default/plugins/line_lists/line_lists.py | 7 +- jdaviz/configs/default/plugins/viewers.py | 2 - .../imviz/plugins/coords_info/coords_info.py | 55 +-- jdaviz/configs/mosviz/plugins/parsers.py | 4 +- jdaviz/configs/specviz/helper.py | 6 +- jdaviz/configs/specviz/plugins/parsers.py | 12 - .../tests/test_unit_conversion.py | 333 ++++------------ .../unit_conversion/unit_conversion.py | 367 ++++++------------ .../unit_conversion/unit_conversion.vue | 75 +--- jdaviz/configs/specviz/plugins/viewers.py | 33 +- jdaviz/configs/specviz/tests/test_helper.py | 30 +- .../configs/specviz2d/tests/test_parsers.py | 2 +- jdaviz/core/freezable_state.py | 2 +- jdaviz/core/helpers.py | 29 +- jdaviz/core/template_mixin.py | 106 +++-- jdaviz/core/tests/test_tools.py | 21 +- jdaviz/core/user_api.py | 5 + jdaviz/core/validunits.py | 63 ++- jdaviz/tests/test_subsets.py | 31 +- jdaviz/utils.py | 1 - .../specviz_glue_unit_conversion.ipynb | 293 ++++++++++++++ .../concepts/specviz_unit_conversion.ipynb | 61 --- 26 files changed, 820 insertions(+), 862 deletions(-) create mode 100644 notebooks/concepts/specviz_glue_unit_conversion.ipynb delete mode 100644 notebooks/concepts/specviz_unit_conversion.ipynb diff --git a/CHANGES.rst b/CHANGES.rst index 4a7750a4a5..cfe4ef8495 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -41,6 +41,8 @@ Mosviz Specviz ^^^^^^^ +* Re-enabled unit conversion support. [#2048] + Specviz2d ^^^^^^^^^ diff --git a/docs/specviz/plugins.rst b/docs/specviz/plugins.rst index e6ed909749..4fccafb30c 100644 --- a/docs/specviz/plugins.rst +++ b/docs/specviz/plugins.rst @@ -118,15 +118,8 @@ To export the table into the notebook via the API, call Unit Conversion =============== -.. note:: - - This plugin is temporarily disabled. Effort to improve it is being - tracked at https://github.com/spacetelescope/jdaviz/issues/1972 . - The spectral flux density and spectral axis units can be converted -using the Unit Conversion plugin. The Spectrum1D object to be -converted is the currently selected spectrum in the spectrum viewer :guilabel:`Data` -icon in the viewer toolbar. +using the Unit Conversion plugin. Select the frequency, wavelength, or energy unit in the :guilabel:`New Spectral Axis Unit` pulldown @@ -135,11 +128,8 @@ Select the frequency, wavelength, or energy unit in the Select the flux density unit in the :guilabel:`New Flux Unit` pulldown (e.g., Jansky, W/(Hz/m2), ph/(Angstrom cm2 s)). -The :guilabel:`Apply` button will convert the flux density and/or -spectral axis units and create a new Spectrum1D object that -is automatically switched to in the spectrum viewer. -The name of the new Spectrum1D object is "_units_copy_" plus -the flux and spectral units of the spectrum. +Note that this affects the default units in all viewers and plugins, where applicable, +but does not affect the underlying data. .. _line-lists: diff --git a/jdaviz/app.py b/jdaviz/app.py index 8ab36feb77..0ec4f538d5 100644 --- a/jdaviz/app.py +++ b/jdaviz/app.py @@ -9,9 +9,9 @@ from ipywidgets import widget_serialization import ipyvue +from astropy import units as u from astropy.nddata import CCDData, NDData from astropy.io import fits -from astropy import units as u from astropy.coordinates import Angle from astropy.time import Time from regions import PixCoord, CirclePixelRegion, RectanglePixelRegion, EllipsePixelRegion @@ -28,7 +28,7 @@ from glue.config import colormaps, data_translator from glue.config import settings as glue_settings from glue.core import BaseData, HubListener, Data, DataCollection -from glue.core.link_helpers import LinkSame +from glue.core.link_helpers import LinkSame, LinkSameWithUnits from glue.plugins.wcs_autolinking.wcs_autolinking import WCSLink, IncompatibleWCS from glue.core.message import (DataCollectionAddMessage, DataCollectionDeleteMessage, @@ -39,6 +39,7 @@ from glue.core.subset import (Subset, RangeSubsetState, RoiSubsetState, CompositeSubsetState, InvertState) from glue.core.roi import CircularROI, EllipticalROI, RectangularROI +from glue.core.units import unit_converter from glue_astronomy.spectral_coordinates import SpectralCoordinates from glue_jupyter.app import JupyterApplication from glue_jupyter.common.toolbar_vuetify import read_icon @@ -69,10 +70,51 @@ mask=['mask', 'dq']) +@unit_converter('custom-jdaviz') +class UnitConverterWithSpectral: + + def equivalent_units(self, data, cid, units): + if cid.label == "flux": + eqv = u.spectral_density(1 * u.m) # Value does not matter here. + list_of_units = set(list(map(str, u.Unit(units).find_equivalent_units( + include_prefix_units=True, equivalencies=eqv))) + [ + 'Jy', 'mJy', 'uJy', + 'W / (m2 Hz)', 'W / (Hz m2)', # Order is different in astropy v5.3 + 'eV / (s m2 Hz)', 'eV / (Hz s m2)', + 'erg / (s cm2)', + 'erg / (s cm2 Angstrom)', 'erg / (Angstrom s cm2)', + 'erg / (s cm2 Hz)', 'erg / (Hz s cm2)', + 'ph / (s cm2 Angstrom)', 'ph / (Angstrom s cm2)', + 'ph / (s cm2 Hz)', 'ph / (Hz s cm2)' + ]) + else: # spectral axis + # prefer Hz over Bq and um over micron + exclude = {'Bq', 'micron'} + list_of_units = set(list(map(str, u.Unit(units).find_equivalent_units( + include_prefix_units=True, equivalencies=u.spectral())))) - exclude + return list_of_units + + def to_unit(self, data, cid, values, original_units, target_units): + # Given a glue data object (data), a component ID (cid), the values + # to convert, and the original and target units of the values, this method + # should return the converted values. Note that original_units + # gives the units of the values array, which might not be the same + # as the original native units of the component in the data. + if cid.label == "flux": + spec = data.get_object(cls=Spectrum1D) + eqv = u.spectral_density(spec.spectral_axis) + else: # spectral axis + eqv = u.spectral() + return (values * u.Unit(original_units)).to_value(u.Unit(target_units), equivalencies=eqv) + + # Set default opacity for data layers to 1 instead of 0.8 in # some glue-core versions glue_settings.DATA_ALPHA = 1 +# Enable spectrum unit conversion. +glue_settings.UNIT_CONVERTER = 'custom-jdaviz' + custom_components = {'j-tooltip': 'components/tooltip.vue', 'j-external-link': 'components/external_link.vue', 'j-docs-link': 'components/docs_link.vue', @@ -447,7 +489,7 @@ def _link_new_data(self, reference_data=None, data_to_be_linked=None): if isinstance(linked_data.coords, SpectralCoordinates): wc_old = ref_data.world_component_ids[-1] wc_new = linked_data.world_component_ids[0] - self.data_collection.add_link(LinkSame(wc_old, wc_new)) + self.data_collection.add_link(LinkSameWithUnits(wc_old, wc_new)) return try: @@ -493,8 +535,8 @@ def _link_new_data(self, reference_data=None, data_to_be_linked=None): else: continue - links.append(LinkSame(ref_data.pixel_component_ids[ref_index], - linked_data.pixel_component_ids[linked_index])) + links.append(LinkSameWithUnits(ref_data.pixel_component_ids[ref_index], + linked_data.pixel_component_ids[linked_index])) dc.add_link(links) @@ -833,7 +875,8 @@ def get_subsets_from_viewer(self, viewer_reference, data_label=None, subset_type return regions def get_subsets(self, subset_name=None, spectral_only=False, - spatial_only=False, object_only=False, simplify_spectral=True): + spatial_only=False, object_only=False, simplify_spectral=True, + use_display_units=False): """ Returns all branches of glue subset tree in the form that subset plugin can recognize. @@ -850,6 +893,8 @@ def get_subsets(self, subset_name=None, spectral_only=False, leave out the region class name and glue_state. simplify_spectral : bool Return a composite spectral subset collapsed to a simplified SpectralRegion. + use_display_units: bool, optional + Whether to convert to the display units defined in the plugin. Returns ------- @@ -868,7 +913,8 @@ def get_subsets(self, subset_name=None, spectral_only=False, if isinstance(subset.subset_state, CompositeSubsetState): # Region composed of multiple ROI or Range subset # objects that must be traversed - subset_region = self.get_sub_regions(subset.subset_state, simplify_spectral) + subset_region = self.get_sub_regions(subset.subset_state, + simplify_spectral, use_display_units) elif isinstance(subset.subset_state, RoiSubsetState): # 3D regions represented as a dict including an # AstropyRegion object if possible @@ -876,7 +922,8 @@ def get_subsets(self, subset_name=None, spectral_only=False, elif isinstance(subset.subset_state, RangeSubsetState): # 2D regions represented as SpectralRegion objects subset_region = self._get_range_subset_bounds(subset.subset_state, - simplify_spectral) + simplify_spectral, + use_display_units) else: # subset.subset_state can be an instance of MaskSubsetState # or something else we do not know how to handle @@ -965,17 +1012,24 @@ def _remove_duplicate_bounds(self, spec_regions): regions_no_dups += region return regions_no_dups - def _get_range_subset_bounds(self, subset_state, simplify_spectral=True): + def _get_range_subset_bounds(self, subset_state, + simplify_spectral=True, use_display_units=False): # TODO: Use global display units # units = dc[0].data.coords.spectral_axis.unit viewer = self.get_viewer(self._jdaviz_helper. _default_spectrum_viewer_reference_name) data = viewer.data() - if viewer: - units = u.Unit(viewer.state.x_display_unit) - elif data and len(data) > 0 and isinstance(data[0], Spectrum1D): + if data and len(data) > 0 and isinstance(data[0], Spectrum1D): units = data[0].spectral_axis.unit else: raise ValueError("Unable to find spectral axis units") + if use_display_units: + # converting may result in flipping order (wavelength <-> frequency) + ret_units = self._get_display_unit('spectral') + subset_bounds = [(subset_state.lo * units).to(ret_units, u.spectral()), + (subset_state.hi * units).to(ret_units, u.spectral())] + spec_region = SpectralRegion(min(subset_bounds), max(subset_bounds)) + else: + spec_region = SpectralRegion(subset_state.lo * units, subset_state.hi * units) spec_region = SpectralRegion(subset_state.lo * units, subset_state.hi * units) if not simplify_spectral: @@ -1012,12 +1066,14 @@ def _get_roi_subset_definition(self, subset_state): "region": roi_as_region, "subset_state": subset_state}] - def get_sub_regions(self, subset_state, simplify_spectral=True): + def get_sub_regions(self, subset_state, simplify_spectral=True, use_display_units=False): if isinstance(subset_state, CompositeSubsetState): if subset_state and hasattr(subset_state, "state2") and subset_state.state2: - one = self.get_sub_regions(subset_state.state1, simplify_spectral) - two = self.get_sub_regions(subset_state.state2, simplify_spectral) + one = self.get_sub_regions(subset_state.state1, + simplify_spectral, use_display_units) + two = self.get_sub_regions(subset_state.state2, + simplify_spectral, use_display_units) if isinstance(one, list) and "glue_state" in one[0]: one[0]["glue_state"] = subset_state.__class__.__name__ @@ -1077,7 +1133,8 @@ def get_sub_regions(self, subset_state, simplify_spectral=True): else: # This gets triggered in the InvertState case where state1 # is an object and state2 is None - return self.get_sub_regions(subset_state.state1, simplify_spectral) + return self.get_sub_regions(subset_state.state1, + simplify_spectral, use_display_units) elif subset_state is not None: # This is the leaf node of the glue subset state tree where # a subset_state is either ROI or Range. @@ -1085,7 +1142,17 @@ def get_sub_regions(self, subset_state, simplify_spectral=True): return self._get_roi_subset_definition(subset_state) elif isinstance(subset_state, RangeSubsetState): - return self._get_range_subset_bounds(subset_state, simplify_spectral) + return self._get_range_subset_bounds(subset_state, + simplify_spectral, use_display_units) + + def _get_display_unit(self, axis): + if self._jdaviz_helper is None or self._jdaviz_helper.plugins.get('Unit Conversion') is None: # noqa + raise ValueError("cannot detect unit conversion plugin") + try: + return getattr(self._jdaviz_helper.plugins.get('Unit Conversion')._obj, + f'{axis}_unit_selected') + except AttributeError: + raise ValueError(f"could not find display unit for axis='{axis}'") def add_data(self, data, data_label=None, notify_done=True): """ @@ -1267,19 +1334,6 @@ def add_data_to_viewer(self, viewer_reference, data_label, self.set_data_visibility(viewer_item, data_label, visible=visible, replace=clear_other_data) - def _set_plot_axes_labels(self, viewer_id): - """ - Sets the plot axes labels to be the units of the data to be loaded. - - Parameters - ---------- - viewer_id : str - The UUID associated with the desired viewer item. - """ - viewer = self._viewer_by_id(viewer_id) - - viewer.set_plot_axes() - def remove_data_from_viewer(self, viewer_reference, data_label): """ Removes a data set from the specified viewer. @@ -1655,11 +1709,8 @@ def set_data_visibility(self, viewer_reference, data_label, visible=True, replac # active data. viewer_data_labels = [layer.layer.label for layer in viewer.layers] if len(viewer_data_labels) > 0 and getattr(self._jdaviz_helper, '_in_batch_load', 0) == 0: - active_data = self.data_collection[viewer_data_labels[0]] - if (hasattr(active_data, "_preferred_translation") - and active_data._preferred_translation is not None): - self._set_plot_axes_labels(viewer_id) - + # This "if" is nested on purpose to make parent "if" available + # for other configs in the future, as needed. if self.config == 'imviz': viewer.on_limits_change() # Trigger compass redraw diff --git a/jdaviz/configs/cubeviz/helper.py b/jdaviz/configs/cubeviz/helper.py index dc102af7e0..5ebaf1797b 100644 --- a/jdaviz/configs/cubeviz/helper.py +++ b/jdaviz/configs/cubeviz/helper.py @@ -120,7 +120,8 @@ def specviz(self): self._specviz = Specviz(app=self.app) return self._specviz - def get_data(self, data_label=None, cls=None, subset_to_apply=None, function=None): + def get_data(self, data_label=None, cls=None, subset_to_apply=None, function=None, + use_display_units=False): """ Returns data with name equal to data_label of type cls with subsets applied from subset_to_apply. @@ -151,7 +152,7 @@ def get_data(self, data_label=None, cls=None, subset_to_apply=None, function=Non elif function is False: function = None return self._get_data(data_label=data_label, cls=cls, subset_to_apply=subset_to_apply, - function=function) + function=function, use_display_units=use_display_units) def layer_is_cube_image_data(layer): diff --git a/jdaviz/configs/default/plugins/line_lists/line_lists.py b/jdaviz/configs/default/plugins/line_lists/line_lists.py index f46f8bb0b2..1061ff195d 100644 --- a/jdaviz/configs/default/plugins/line_lists/line_lists.py +++ b/jdaviz/configs/default/plugins/line_lists/line_lists.py @@ -199,7 +199,8 @@ def _on_viewer_data_changed(self, msg=None): self._on_spectrum_viewer_limits_changed() # will also trigger _auto_slider_step # set the choices (and default) for the units for new custom lines - self.custom_unit_choices = create_spectral_equivalencies_list(viewer_data) + self.custom_unit_choices = create_spectral_equivalencies_list( + viewer_data.spectral_axis.unit) self.custom_unit = str(viewer_data.spectral_axis.unit) def _parse_redshift_msg(self, msg): @@ -410,6 +411,10 @@ def vue_slider_reset(self, event): def _on_spectrum_viewer_limits_changed(self, event=None): sv = self.app.get_viewer(self._default_spectrum_viewer_reference_name) + + if sv.state.x_min is None or sv.state.x_max is None: + return + self.spectrum_viewer_min = float(sv.state.x_min) self.spectrum_viewer_max = float(sv.state.x_max) diff --git a/jdaviz/configs/default/plugins/viewers.py b/jdaviz/configs/default/plugins/viewers.py index de2660590f..7023f19671 100644 --- a/jdaviz/configs/default/plugins/viewers.py +++ b/jdaviz/configs/default/plugins/viewers.py @@ -115,8 +115,6 @@ def _get_layer_info(layer): return "mdi-chart-bell-curve", "" return "", suffix - return '', '' - visible_layers = {} for layer in self.state.layers[::-1]: if layer.visible: diff --git a/jdaviz/configs/imviz/plugins/coords_info/coords_info.py b/jdaviz/configs/imviz/plugins/coords_info/coords_info.py index 35a2ff2a1f..982cf6a624 100644 --- a/jdaviz/configs/imviz/plugins/coords_info/coords_info.py +++ b/jdaviz/configs/imviz/plugins/coords_info/coords_info.py @@ -388,13 +388,10 @@ def _image_viewer_update(self, viewer, x, y): def _spectrum_viewer_update(self, viewer, x, y): def _cursor_fallback(): - statistic = getattr(viewer.state, 'function', None) - cache_key = (viewer.state.layers[0].layer.label, statistic) - sp = self.app._get_object_cache.get(cache_key, viewer.data()[0]) self._dict['axes_x'] = x - self._dict['axes_x:unit'] = sp.spectral_axis.unit.to_string() + self._dict['axes_x:unit'] = viewer.state.x_display_unit self._dict['axes_y'] = y - self._dict['axes_y:unit'] = sp.flux.unit.to_string() + self._dict['axes_y:unit'] = viewer.state.y_display_unit self._dict['data_label'] = '' def _copy_axes_to_spectral(): @@ -417,8 +414,6 @@ def _copy_axes_to_spectral(): self.row3_text = '' self.icon = 'mdi-cursor-default' self.marks[viewer._reference_id].visible = False - # get the units from the first layer - # TODO: replace with display units once implemented _cursor_fallback() _copy_axes_to_spectral() return @@ -461,17 +456,22 @@ def _copy_axes_to_spectral(): subset_to_apply=subset_label) self.app._get_object_cache[cache_key] = sp + # Calculations have to happen in the frame of viewer display units. + disp_wave = sp.spectral_axis.to_value(viewer.state.x_display_unit, u.spectral()) + disp_flux = sp.flux.to_value(viewer.state.y_display_unit, + u.spectral_density(sp.spectral_axis)) + # Out of range in spectral axis. if (self.dataset.selected != lyr.layer.label and - (x < sp.spectral_axis.value.min() or x > sp.spectral_axis.value.max())): + (x < disp_wave.min() or x > disp_wave.max())): continue - cur_i = np.argmin(abs(sp.spectral_axis.value - x)) - cur_wave = sp.spectral_axis[cur_i] - cur_flux = sp.flux[cur_i] + cur_i = np.argmin(abs(disp_wave - x)) + cur_wave = disp_wave[cur_i] + cur_flux = disp_flux[cur_i] - dx = cur_wave.value - x - dy = cur_flux.value - y + dx = cur_wave - x + dy = cur_flux - y cur_distance = math.sqrt(dx * dx + dy * dy) if (closest_distance is None) or (cur_distance < closest_distance): closest_distance = cur_distance @@ -496,27 +496,34 @@ def _copy_axes_to_spectral(): return self.row2_title = 'Wave' - self.row2_text = f'{closest_wave.value:10.5e} {closest_wave.unit.to_string()}' - self._dict['axes_x'] = closest_wave.value - self._dict['axes_x:unit'] = closest_wave.unit.to_string() - if closest_wave.unit != u.pix: + self.row2_text = f'{closest_wave:10.5e} {viewer.state.x_display_unit}' + self._dict['axes_x'] = closest_wave + self._dict['axes_x:unit'] = viewer.state.x_display_unit + if viewer.state.x_display_unit != u.pix: self.row2_text += f' ({int(closest_i)} pix)' if self.app.config == 'cubeviz': # float to be compatible with nan self._dict['slice'] = float(closest_i) - self._dict['spectral_axis'] = closest_wave.value - self._dict['spectral_axis:unit'] = closest_wave.unit.to_string() + self._dict['spectral_axis'] = closest_wave + self._dict['spectral_axis:unit'] = viewer.state.x_display_unit else: # float to be compatible with nan self._dict['index'] = float(closest_i) + if viewer.state.y_display_unit is None: + flux_unit = "" + else: + flux_unit = viewer.state.y_display_unit self.row3_title = 'Flux' - self.row3_text = f'{closest_flux.value:10.5e} {closest_flux.unit.to_string()}' - self._dict['axes_y'] = closest_flux.value - self._dict['axes_y:unit'] = closest_flux.unit.to_string() + self.row3_text = f'{closest_flux:10.5e} {flux_unit}' + self._dict['axes_y'] = closest_flux + self._dict['axes_y:unit'] = viewer.state.y_display_unit - self.icon = closest_icon + if closest_icon is not None: + self.icon = closest_icon + else: + self.icon = "" - self.marks[viewer._reference_id].update_xy([closest_wave.value], [closest_flux.value]) # noqa + self.marks[viewer._reference_id].update_xy([closest_wave], [closest_flux]) self.marks[viewer._reference_id].visible = True _copy_axes_to_spectral() diff --git a/jdaviz/configs/mosviz/plugins/parsers.py b/jdaviz/configs/mosviz/plugins/parsers.py index 6b6259cea7..6566de033f 100644 --- a/jdaviz/configs/mosviz/plugins/parsers.py +++ b/jdaviz/configs/mosviz/plugins/parsers.py @@ -9,7 +9,7 @@ from astropy.io.registry import IORegistryError from astropy.wcs import WCS from glue.core.data import Data -from glue.core.link_helpers import LinkSame +from glue.core.link_helpers import LinkSameWithUnits from specutils import Spectrum1D, SpectrumList, SpectrumCollection from specutils.io.default_loaders.jwst_reader import identify_jwst_s2d_multi_fits @@ -140,7 +140,7 @@ def link_data_in_table(app, data_obj=None): wc_spec_1d = app.session.data_collection[spec_1d].world_component_ids wc_spec_2d = app.session.data_collection[spec_2d].world_component_ids - wc_spec_ids.append(LinkSame(wc_spec_1d[0], wc_spec_2d[1])) + wc_spec_ids.append(LinkSameWithUnits(wc_spec_1d[0], wc_spec_2d[1])) app.session.data_collection.add_link(wc_spec_ids) diff --git a/jdaviz/configs/specviz/helper.py b/jdaviz/configs/specviz/helper.py index 04db731d89..7692ec04be 100644 --- a/jdaviz/configs/specviz/helper.py +++ b/jdaviz/configs/specviz/helper.py @@ -271,7 +271,7 @@ def set_spectrum_tick_format(self, fmt, axis=None): self._default_spectrum_viewer_reference_name ).figure.axes[axis].tick_format = fmt - def get_data(self, data_label=None, cls=None, subset_to_apply=None): + def get_data(self, data_label=None, cls=None, subset_to_apply=None, use_display_units=False): """ Returns data with name equal to data_label of type cls with subsets applied from subset_to_apply. @@ -284,6 +284,8 @@ def get_data(self, data_label=None, cls=None, subset_to_apply=None): The type that data will be returned as. subset_to_apply : str, optional Subset that is to be applied to data before it is returned. + use_display_units: bool, optional + Whether to convert to the display units defined in the plugin. Returns ------- @@ -302,4 +304,4 @@ def get_data(self, data_label=None, cls=None, subset_to_apply=None): function = None return self._get_data(data_label=data_label, cls=cls, subset_to_apply=subset_to_apply, - function=function) + function=function, use_display_units=use_display_units) diff --git a/jdaviz/configs/specviz/plugins/parsers.py b/jdaviz/configs/specviz/plugins/parsers.py index a567e65ddc..73c019060b 100644 --- a/jdaviz/configs/specviz/plugins/parsers.py +++ b/jdaviz/configs/specviz/plugins/parsers.py @@ -76,14 +76,6 @@ def specviz_spectrum1d_parser(app, data, data_label=None, format=None, show_in_v raise ValueError(f"Length of data labels list ({len(data_label)}) is different" f" than length of list of data ({len(data)})") - # If there's already visible data in the viewer, convert units if needed - current_unit = None - if spectrum_viewer_reference_name in app.get_viewer_reference_names(): - sv = app.get_viewer(spectrum_viewer_reference_name) - for layer_state in sv.state.layers: - if layer_state.visible: - current_unit = sv.state.x_display_unit - with app.data_collection.delay_link_manager_update(): # these are used to build a combined spectrum with all # input spectra included (taken from https://github.com/spacetelescope/ @@ -98,10 +90,6 @@ def specviz_spectrum1d_parser(app, data, data_label=None, format=None, show_in_v wave_units = spec.spectral_axis.unit flux_units = spec.flux.unit - if current_unit is not None and spec.spectral_axis.unit != current_unit: - spec = Spectrum1D(flux=spec.flux, - spectral_axis=spec.spectral_axis.to(current_unit)) - # Make metadata layout conform with other viz. spec.meta = standardize_metadata(spec.meta) diff --git a/jdaviz/configs/specviz/plugins/unit_conversion/tests/test_unit_conversion.py b/jdaviz/configs/specviz/plugins/unit_conversion/tests/test_unit_conversion.py index cf1af35805..245c19c124 100644 --- a/jdaviz/configs/specviz/plugins/unit_conversion/tests/test_unit_conversion.py +++ b/jdaviz/configs/specviz/plugins/unit_conversion/tests/test_unit_conversion.py @@ -1,272 +1,91 @@ -import numpy as np import pytest from astropy import units as u -from astropy.nddata import UnknownUncertainty -from astropy.tests.helper import assert_quantity_allclose -from glue.core.roi import XRangeROI - -from jdaviz.configs.specviz.plugins.unit_conversion import unit_conversion as uc - -RESULT_SPECTRAL_AXIS = [0.6, 0.62222222, 0.64444444, 0.66666667, - 0.68888889, 0.71111111, 0.73333333, - 0.75555556, 0.77777778, 0.8] * u.micron - -RESULT_FLUX = [1.04067240e-07, 9.52912307e-08, 9.77144651e-08, - 1.00212528e-07, 8.55573341e-08, 8.29285448e-08, - 9.05651431e-08, 8.33870526e-08, 7.47628902e-08, - 7.74896053e-08] * u.Unit("erg / (s cm2 um)") - -RESULT_UNCERTAINTY = [3.85914248e-09, 3.60631495e-09, 1.74661581e-09, - 1.29057072e-08, 1.08965936e-08, 3.33352891e-09, - 5.64618219e-09, 1.65028707e-09, 4.49994292e-09, - 6.61559372e-09] +# On failure, should not crash; essentially a no-op. @pytest.mark.parametrize( - ('new_spectral_axis', 'new_flux'), - [("fail", "erg / (s cm2 um)"), - ("None", "fail"), - ("micron", "fail")]) -def test_value_error_exception(specviz_helper, spectrum1d, new_spectral_axis, new_flux): - label = "Test 1D Spectrum" - specviz_helper.load_spectrum(spectrum1d, data_label=label) - - conv_func = uc.UnitConversion.process_unit_conversion - converted_spectrum = conv_func(specviz_helper.app, spectrum=spectrum1d, - new_flux=new_flux, - new_spectral_axis=new_spectral_axis) - - assert converted_spectrum is None - - -def test_no_spec_no_flux_no_uncert(specviz_helper, spectrum1d): - label = "Test 1D Spectrum" - specviz_helper.load_spectrum(spectrum1d, data_label=label) - - spectrum1d.uncertainty = None - - conv_func = uc.UnitConversion.process_unit_conversion - converted_spectrum = conv_func(specviz_helper.app, spectrum=spectrum1d) - - assert converted_spectrum.flux.unit == spectrum1d.flux.unit - assert converted_spectrum.spectral_axis.unit == spectrum1d.spectral_axis.unit - assert converted_spectrum.uncertainty is None - - # Test that applying and removing Subset disables and enables it, respectively. - conv_plugin = specviz_helper.app.get_tray_item_from_name('g-unit-conversion') - specviz_helper.app.get_viewer("spectrum-viewer").apply_roi(XRangeROI(6000, 6500)) - assert conv_plugin.disabled_msg == 'Please create Subsets only after unit conversion' - specviz_helper.app.data_collection.remove_subset_group( - specviz_helper.app.data_collection.subset_groups[0]) - assert conv_plugin.disabled_msg == '' - - -def test_spec_no_flux_no_uncert(specviz_helper, spectrum1d): - label = "Test 1D Spectrum" - specviz_helper.load_spectrum(spectrum1d, data_label=label) - + ('new_spectral_axis', 'new_flux', 'expected_spectral_axis', 'expected_flux'), + [("fail", "erg / (s cm2 Angstrom)", "Angstrom", "erg / (s cm2 Angstrom)"), + ("None", "fail", "Angstrom", "Jy"), + ("micron", "fail", "micron", "Jy")]) +def test_value_error_exception(specviz_helper, spectrum1d, new_spectral_axis, new_flux, + expected_spectral_axis, expected_flux): + specviz_helper.load_spectrum(spectrum1d, data_label="Test 1D Spectrum") + viewer = specviz_helper.app.get_viewer("spectrum-viewer") + plg = specviz_helper.plugins["Unit Conversion"] + + try: + plg.spectral_unit = new_spectral_axis + except ValueError as e: + if "reverting selection to" not in repr(e): + raise + try: + plg.flux_unit = new_flux + except ValueError as e: + if "reverting selection to" not in repr(e): + raise + + assert len(specviz_helper.app.data_collection) == 1 + assert u.Unit(viewer.state.x_display_unit) == u.Unit(expected_spectral_axis) + assert u.Unit(viewer.state.y_display_unit) == u.Unit(expected_flux) + + +@pytest.mark.parametrize('uncert', (False, True)) +def test_conv_wave_only(specviz_helper, spectrum1d, uncert): + if uncert is False: + spectrum1d.uncertainty = None + specviz_helper.load_spectrum(spectrum1d, data_label="Test 1D Spectrum") + + viewer = specviz_helper.app.get_viewer("spectrum-viewer") + plg = specviz_helper.plugins["Unit Conversion"] new_spectral_axis = "micron" - spectrum1d.uncertainty = None - - conv_func = uc.UnitConversion.process_unit_conversion - converted_spectrum = conv_func(specviz_helper.app, spectrum=spectrum1d, - new_spectral_axis=new_spectral_axis) - - assert_quantity_allclose(converted_spectrum.spectral_axis, - RESULT_SPECTRAL_AXIS, atol=1e-5*u.um) - assert converted_spectrum.flux.unit == spectrum1d.flux.unit - assert converted_spectrum.spectral_axis.unit == new_spectral_axis - assert converted_spectrum.uncertainty is None - + plg.spectral_unit = new_spectral_axis -def test_no_spec_no_flux_uncert(specviz_helper, spectrum1d): - label = "Test 1D Spectrum" - specviz_helper.load_spectrum(spectrum1d, data_label=label) + assert len(specviz_helper.app.data_collection) == 1 + assert u.Unit(viewer.state.x_display_unit) == u.Unit(new_spectral_axis) + assert u.Unit(viewer.state.y_display_unit) == u.Unit('Jy') - conv_func = uc.UnitConversion.process_unit_conversion - converted_spectrum = conv_func(specviz_helper.app, spectrum=spectrum1d) - assert converted_spectrum.flux.unit == spectrum1d.flux.unit +@pytest.mark.parametrize('uncert', (False, True)) +def test_conv_flux_only(specviz_helper, spectrum1d, uncert): + if uncert is False: + spectrum1d.uncertainty = None + specviz_helper.load_spectrum(spectrum1d, data_label="Test 1D Spectrum") + viewer = specviz_helper.app.get_viewer("spectrum-viewer") + plg = specviz_helper.plugins["Unit Conversion"] + new_flux = "erg / (s cm2 Angstrom)" + plg.flux_unit = new_flux -def test_no_spec_no_flux_uncert_unit_exp_none(specviz_helper, spectrum1d): - np.random.seed(42) - label = "Test 1D Spectrum" - specviz_helper.load_spectrum(spectrum1d, data_label=label) + assert len(specviz_helper.app.data_collection) == 1 + assert u.Unit(viewer.state.x_display_unit) == u.Unit('Angstrom') + assert u.Unit(viewer.state.y_display_unit) == u.Unit(new_flux) - spectrum1d.uncertainty = UnknownUncertainty(np.abs( - np.random.randn(len(spectrum1d.spectral_axis)))) - conv_func = uc.UnitConversion.process_unit_conversion - converted_spectrum = conv_func(specviz_helper.app, spectrum=spectrum1d) - - assert converted_spectrum.flux.unit == spectrum1d.flux.unit - assert converted_spectrum.spectral_axis.unit == spectrum1d.spectral_axis.unit - assert converted_spectrum.uncertainty is None - - -def test_no_spec_flux_no_uncert(specviz_helper, spectrum1d): - label = "Test 1D Spectrum" - specviz_helper.load_spectrum(spectrum1d, data_label=label) - - spectrum1d.uncertainty = None - new_flux = "erg / (s cm2 um)" - - conv_func = uc.UnitConversion.process_unit_conversion - converted_spectrum = conv_func(specviz_helper.app, spectrum=spectrum1d, - new_flux=new_flux) - - assert_quantity_allclose(converted_spectrum.flux, - RESULT_FLUX, atol=1e-5*u.Unit(new_flux)) - assert converted_spectrum.spectral_axis.unit == spectrum1d.spectral_axis.unit - assert converted_spectrum.uncertainty is None - - -def test_no_spec_flux_unit_exp_not_none(specviz_helper, spectrum1d): - label = "Test 1D Spectrum" - specviz_helper.load_spectrum(spectrum1d, data_label=label) - - new_flux = "erg / (s cm2 um)" - - conv_func = uc.UnitConversion.process_unit_conversion - converted_spectrum = conv_func(specviz_helper.app, spectrum=spectrum1d, - new_flux=new_flux) - - assert_quantity_allclose(converted_spectrum.flux, - RESULT_FLUX, atol=1e-5*u.Unit(new_flux)) - assert_quantity_allclose(converted_spectrum.uncertainty.quantity.value, - RESULT_UNCERTAINTY, atol=1e-11) - - -def test_spec_flux_no_uncert(specviz_helper, spectrum1d): - label = "Test 1D Spectrum" - specviz_helper.load_spectrum(spectrum1d, data_label=label) +@pytest.mark.parametrize('uncert', (False, True)) +def test_conv_wave_flux(specviz_helper, spectrum1d, uncert): + if uncert is False: + spectrum1d.uncertainty = None + specviz_helper.load_spectrum(spectrum1d, data_label="Test 1D Spectrum") + viewer = specviz_helper.app.get_viewer("spectrum-viewer") + plg = specviz_helper.plugins["Unit Conversion"] new_spectral_axis = "micron" - new_flux = "erg / (s cm2 um)" - - spectrum1d.uncertainty = None - - conv_func = uc.UnitConversion.process_unit_conversion - converted_spectrum = conv_func(specviz_helper.app, spectrum=spectrum1d, - new_flux=new_flux, - new_spectral_axis=new_spectral_axis) - - assert_quantity_allclose(converted_spectrum.flux, - RESULT_FLUX, atol=1e-5*u.Unit(new_flux)) - assert_quantity_allclose(converted_spectrum.spectral_axis, - RESULT_SPECTRAL_AXIS, atol=1e-5*u.um) - assert converted_spectrum.uncertainty is None - - -def test_spec_no_flux_uncert_no_unit_exp(specviz_helper, spectrum1d): - np.random.seed(42) - label = "Test 1D Spectrum" - specviz_helper.load_spectrum(spectrum1d, data_label=label) - - new_spectral_axis = "micron" - - spectrum1d.uncertainty = UnknownUncertainty(np.abs( - np.random.randn(len(spectrum1d.spectral_axis)))) - - conv_func = uc.UnitConversion.process_unit_conversion - converted_spectrum = conv_func(specviz_helper.app, spectrum=spectrum1d, - new_spectral_axis=new_spectral_axis) - - assert converted_spectrum.flux.unit == spectrum1d.flux.unit - assert_quantity_allclose(converted_spectrum.spectral_axis, - RESULT_SPECTRAL_AXIS, atol=1e-5*u.um) - assert converted_spectrum.uncertainty is None - - -def test_no_spec_flux_uncert_no_unit_exp(specviz_helper, spectrum1d): - np.random.seed(42) - label = "Test 1D Spectrum" - specviz_helper.load_spectrum(spectrum1d, data_label=label) - - new_flux = "erg / (s cm2 um)" - - spectrum1d.uncertainty = UnknownUncertainty(np.abs( - np.random.randn(len(spectrum1d.spectral_axis)))) - - conv_func = uc.UnitConversion.process_unit_conversion - converted_spectrum = conv_func(specviz_helper.app, spectrum=spectrum1d, - new_flux=new_flux) - - assert converted_spectrum.spectral_axis.unit == spectrum1d.spectral_axis.unit - assert_quantity_allclose(converted_spectrum.flux, - RESULT_FLUX, atol=1e-5*u.Unit(new_flux)) - assert converted_spectrum.uncertainty is None - - -def test_spec_no_flux_uncert_unit_exp(specviz_helper, spectrum1d): - label = "Test 1D Spectrum" - specviz_helper.load_spectrum(spectrum1d, data_label=label) - - new_spectral_axis = "micron" - - conv_func = uc.UnitConversion.process_unit_conversion - converted_spectrum = conv_func(specviz_helper.app, spectrum=spectrum1d, - new_spectral_axis=new_spectral_axis) - - assert_quantity_allclose(converted_spectrum.spectral_axis, - RESULT_SPECTRAL_AXIS, atol=1e-5*u.um) - - -def test_spec_flux_uncert_no_unit_exp(specviz_helper, spectrum1d): - np.random.seed(42) - label = "Test 1D Spectrum" - specviz_helper.load_spectrum(spectrum1d, data_label=label) - - new_spectral_axis = "micron" - new_flux = "erg / (s cm2 um)" - - spectrum1d.uncertainty = UnknownUncertainty(np.abs( - np.random.randn(len(spectrum1d.spectral_axis)))) - - conv_func = uc.UnitConversion.process_unit_conversion - converted_spectrum = conv_func(specviz_helper.app, spectrum=spectrum1d, - new_flux=new_flux, - new_spectral_axis=new_spectral_axis) - - assert converted_spectrum.uncertainty is None - assert_quantity_allclose(converted_spectrum.spectral_axis, - RESULT_SPECTRAL_AXIS, atol=1e-5*u.um) - assert_quantity_allclose(converted_spectrum.flux, - RESULT_FLUX, atol=1e-5*u.Unit(new_flux)) - - -def test_spec_flux_uncert_unit_exp(specviz_helper, spectrum1d): - label = "Test 1D Spectrum" - specviz_helper.load_spectrum(spectrum1d, data_label=label) - - new_spectral_axis = "micron" - new_flux = "erg / (s cm2 um)" - - conv_func = uc.UnitConversion.process_unit_conversion - converted_spectrum = conv_func(specviz_helper.app, spectrum=spectrum1d, - new_flux=new_flux, - new_spectral_axis=new_spectral_axis) - - assert_quantity_allclose(converted_spectrum.spectral_axis, - RESULT_SPECTRAL_AXIS, atol=1e-5*u.um) - assert_quantity_allclose(converted_spectrum.flux, - RESULT_FLUX, atol=1e-5*u.Unit(new_flux)) - assert_quantity_allclose(converted_spectrum.uncertainty.quantity.value, - RESULT_UNCERTAINTY, atol=1e-11) - - -def test_converted_spec_is_none(specviz_helper, spectrum1d): - label = "Test 1D Spectrum" - specviz_helper.load_spectrum(spectrum1d, data_label=label) - - new_spectral_axis = "feet" - - unit_conversion = specviz_helper.app.get_tray_item_from_name("g-unit-conversion") - unit_conversion.new_spectral_axis_unit = new_spectral_axis - converted_spectrum = unit_conversion.vue_unit_conversion(specviz_helper.app, - spectrum=spectrum1d, - new_flux=None, - new_spectral_axis=new_spectral_axis) - - assert converted_spectrum is None + new_flux = "erg / (s cm2 Angstrom)" + plg.spectral_unit = new_spectral_axis + plg.flux_unit = new_flux + + assert len(specviz_helper.app.data_collection) == 1 + assert u.Unit(viewer.state.x_display_unit) == u.Unit(new_spectral_axis) + assert u.Unit(viewer.state.y_display_unit) == u.Unit(new_flux) + + +def test_conv_no_data(specviz_helper): + """plugin unit selections won't have valid choices yet, preventing + attempting to set display units.""" + plg = specviz_helper.plugins["Unit Conversion"] + with pytest.raises(ValueError, match="no valid unit choices"): + plg.spectral_unit = "micron" + with pytest.raises(ValueError, match="no valid unit choices"): + plg.flux_unit = "erg / (s cm2 Angstrom)" + assert len(specviz_helper.app.data_collection) == 0 diff --git a/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.py b/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.py index acae7e3f26..05d62ddb79 100644 --- a/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.py +++ b/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.py @@ -1,274 +1,133 @@ -from packaging.version import Version - -import specutils +import numpy as np from astropy import units as u -from astropy.nddata import VarianceUncertainty, StdDevUncertainty, InverseVariance -from glue.core.message import SubsetCreateMessage, SubsetDeleteMessage -from traitlets import List, Unicode, Any, observe +from traitlets import List, Unicode, observe -from jdaviz.core.events import SnackbarMessage, RedshiftMessage from jdaviz.core.registries import tray_registry -from jdaviz.core.template_mixin import PluginTemplateMixin, DatasetSelectMixin +from jdaviz.core.template_mixin import PluginTemplateMixin, UnitSelectPluginComponent, PluginUserApi from jdaviz.core.validunits import (create_spectral_equivalencies_list, create_flux_equivalencies_list) -from jdaviz.configs.specviz.helper import _apply_redshift_to_spectra __all__ = ['UnitConversion'] -unit_exponents = {StdDevUncertainty: 1, - InverseVariance: -2, - VarianceUncertainty: 2} -SPECUTILS_GT_1_7_0 = Version(specutils.__version__) > Version('1.7.0') + +def _valid_glue_display_unit(unit_str, sv, axis='x'): + # need to make sure the unit string is formatted according to the list of valid choices + # that glue will accept (may not be the same as the defaults of the installed version of + # astropy) + if not unit_str: + return unit_str + unit_u = u.Unit(unit_str) + choices_str = getattr(sv.state.__class__, f'{axis}_display_unit').get_choices(sv.state) + choices_str = [choice for choice in choices_str if choice is not None] + choices_u = [u.Unit(choice) for choice in choices_str] + if unit_u not in choices_u: + raise ValueError(f"{unit_str} could not find match in valid {axis} display units {choices_str}") # noqa + ind = choices_u.index(unit_u) + return choices_str[ind] @tray_registry('g-unit-conversion', label="Unit Conversion", viewer_requirements='spectrum') -class UnitConversion(PluginTemplateMixin, DatasetSelectMixin): - +class UnitConversion(PluginTemplateMixin): + """ + The Unit Conversion plugin handles global app-wide unit-conversion. + See the :ref:`Unit Conversion Plugin Documentation ` for more details. + + Only the following attributes and methods are available through the + :ref:`public plugin API `: + + * :meth:`~jdaviz.core.template_mixin.PluginTemplateMixin.show` + * :meth:`~jdaviz.core.template_mixin.PluginTemplateMixin.open_in_tray` + * ``spectral_unit`` (:class:`~jdaviz.core.template_mixin.SelectPluginComponent`): + Global unit to use for all spectral axes. + * ``flux_unit`` (:class:`~jdaviz.core.template_mixin.SelectPluginComponent`): + Global unit to use for all flux axes. + """ template_file = __file__, "unit_conversion.vue" - current_flux_unit = Unicode().tag(sync=True) - current_spectral_axis_unit = Unicode().tag(sync=True) - new_flux_unit = Any().tag(sync=True) - new_spectral_axis_unit = Any().tag(sync=True) - - spectral_axis_unit_equivalencies = List([]).tag(sync=True) - flux_unit_equivalencies = List([]).tag(sync=True) + spectral_unit_items = List().tag(sync=True) + spectral_unit_selected = Unicode().tag(sync=True) + flux_unit_items = List().tag(sync=True) + flux_unit_selected = Unicode().tag(sync=True) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.hub.subscribe(self, SubsetCreateMessage, handler=self._on_viewer_subset_changed) - self.hub.subscribe(self, SubsetDeleteMessage, handler=self._on_viewer_subset_changed) - - self._redshift = None - self.app.hub.subscribe(self, RedshiftMessage, handler=self._redshift_listener) - - self._default_spectrum_viewer_reference_name = kwargs.get( - "spectrum_viewer_reference_name", "spectrum-viewer" - ) - - # when accessing the selected data, access the spectrum-viewer version - # TODO: we'll probably want to update unit-conversion to be able to act on cubes directly - # in the future - self.dataset._viewers = [self._default_spectrum_viewer_reference_name] - # require entries to be in spectrum-viewer (not other cubeviz images, etc) - self.dataset.add_filter('layer_in_spectrum_viewer') - - def _on_viewer_subset_changed(self, *args): - if len(self.app.data_collection.subset_groups) == 0: - self.disabled_msg = '' - else: - self.disabled_msg = 'Please create Subsets only after unit conversion' - - def _redshift_listener(self, msg): - '''Save new redshifts (including from the helper itself)''' - if msg.param == "redshift": - self._redshift = msg.value - - @observe('dataset_selected') - def update_ui(self, event=None): - """ - Set up UI to have all values of currently visible spectra. - """ - spectrum = self.dataset.selected_obj - if spectrum is None: + if self.config not in ['specviz']: + # TODO [specviz2d, mosviz] x_display_unit is not implemented in glue for image viewer + # used by spectrum-2d-viewer + # TODO [mosviz]: add to yaml file + # TODO [cubeviz, slice]: slice indicator broken after changing spectral_unit + # TODO: support for multiple viewers and handling of mixed state from glue (or does + # this force all to sync?) + self.disabled_msg = f'This plugin is temporarily disabled in {self.config}. Effort to improve it is being tracked at GitHub Issue 1972.' # noqa + + # TODO [markers]: existing markers need converting + self.spectrum_viewer.state.add_callback('x_display_unit', + self._on_glue_x_display_unit_changed) + self.spectrum_viewer.state.add_callback('y_display_unit', + self._on_glue_y_display_unit_changed) + + self.spectral_unit = UnitSelectPluginComponent(self, + items='spectral_unit_items', + selected='spectral_unit_selected') + self.flux_unit = UnitSelectPluginComponent(self, + items='flux_unit_items', + selected='flux_unit_selected') + + @property + def user_api(self): + return PluginUserApi(self, expose=('spectral_unit', 'flux_unit')) + + def _on_glue_x_display_unit_changed(self, x_unit): + if x_unit is None: return - - # Set UI label to show current flux and spectral axis units. - self.current_flux_unit = spectrum.flux.unit.to_string() - self.current_spectral_axis_unit = spectrum.spectral_axis.unit.to_string() - - # Populate drop down with all valid options for unit conversion. - self.spectral_axis_unit_equivalencies = create_spectral_equivalencies_list(spectrum) - self.flux_unit_equivalencies = create_flux_equivalencies_list(spectrum) - - def vue_unit_conversion(self, *args, **kwargs): - """ - Runs when the ``apply`` button is hit. Tries to change units if ``new`` units are set - and are valid. - """ - if self._redshift is not None: - # apply the global redshift to the new spectrum - spectrum = _apply_redshift_to_spectra(self.dataset.selected_obj, self._redshift) - else: - spectrum = self.dataset.selected_obj - - converted_spec = self.process_unit_conversion(spectrum, - self.new_flux_unit, - self.new_spectral_axis_unit) - if converted_spec is None: + self.spectrum_viewer.set_plot_axes() + if x_unit != self.spectral_unit.selected: + x_unit = _valid_glue_display_unit(x_unit, self.spectrum_viewer, 'x') + x_u = u.Unit(x_unit) + choices = create_spectral_equivalencies_list(x_u) + # ensure that original entry is in the list of choices + if not np.any([x_u == u.Unit(choice) for choice in choices]): + choices = [x_unit] + choices + self.spectral_unit.choices = choices + # in addition to the jdaviz options, allow the user to set any glue-valid unit + # which would then be appended on to the list of choices going forward + self.spectral_unit._addl_unit_strings = self.spectrum_viewer.state.__class__.x_display_unit.get_choices(self.spectrum_viewer.state) # noqa + self.spectral_unit.selected = x_unit + if not len(self.flux_unit.choices): + # in case flux_unit was triggered first (but could not be set because there + # as no spectral_unit to determine valid equivalencies) + self._on_glue_y_display_unit_changed(self.spectrum_viewer.state.y_display_unit) + + def _on_glue_y_display_unit_changed(self, y_unit): + if y_unit is None: return - - label = f"_units_copy_Flux:{converted_spec.flux.unit}_" +\ - f"SpectralAxis:{converted_spec.spectral_axis.unit}" - new_label = "" - - # Finds the '_units_copy_' spectrum and does unit conversions in that copy. - if "_units_copy_" in self.dataset_selected: - - selected_data_label = self.dataset_selected - selected_data_label_split = selected_data_label.split("_units_copy_") - - new_label = selected_data_label_split[0] + label - - original_spectrum = self.data_collection[selected_data_label_split[0]] - original_flux = original_spectrum.get_object().flux.unit - original_spectral_axis = original_spectrum.get_object().spectral_axis.unit - - if new_label in self.data_collection: - # Spectrum with these converted units already exists. - msg = SnackbarMessage( - "Spectrum with these units already exists, please check the data drop down.", - color="warning", - sender=self) - self.hub.broadcast(msg) - return - - elif converted_spec.flux.unit == original_flux and \ - converted_spec.spectral_axis.unit == original_spectral_axis: - # Check if converted units already exist in the original spectrum. - msg = SnackbarMessage( - "These are the units of the original spectrum, please use " - "that spectrum instead.", - color="warning", - sender=self) - self.hub.broadcast(msg) - return - - else: - # Add spectrum with converted units to app. - self.app.add_data(converted_spec, new_label) - self.app.add_data_to_viewer( - self._default_spectrum_viewer_reference_name, - new_label, clear_other_data=True - ) - - else: - new_label = self.dataset_selected + label - - if new_label in self.data_collection: - # Spectrum with these converted units already exists. - msg = SnackbarMessage( - "Spectrum with these units already exists, please check the data drop down.", - color="warning", - sender=self) - self.hub.broadcast(msg) - - return - else: - - # Replace old spectrum with new one with updated units. - self.app.add_data(converted_spec, new_label) - - self.app.add_data_to_viewer( - self._default_spectrum_viewer_reference_name, - new_label, clear_other_data=True - ) - snackbar_message = SnackbarMessage( - f"Data set '{label}' units converted successfully.", - color="success", - sender=self) - self.hub.broadcast(snackbar_message) - - def process_unit_conversion(self, spectrum, new_flux=None, new_spectral_axis=None): - """ - - Parameters - ---------- - spectrum : `specutils.Spectrum1D` - The spectrum that will have its units converted. - new_flux - The flux of spectrum will be converted to these units if they are provided. - new_spectral_axis - The spectral_axis of spectrum will be converted to these units if they are provided. - - Returns - ------- - converted_spectrum : `specutils.Spectrum1D` - A new spectrum with converted units. - """ - set_spectral_axis_unit = spectrum.spectral_axis - set_flux_unit = spectrum.flux - - current_flux_unit = spectrum.flux.unit.to_string() - current_spectral_axis_unit = spectrum.spectral_axis.unit.to_string() - - # Try to set new units if set and are valid. - if new_spectral_axis is not None \ - and new_spectral_axis != "" \ - and new_spectral_axis != current_spectral_axis_unit: - try: - set_spectral_axis_unit = spectrum.spectral_axis.to(u.Unit(new_spectral_axis)) - except ValueError as e: - snackbar_message = SnackbarMessage( - "Unable to convert spectral axis units for selected data. " - f"Try different units: {repr(e)}", - color="error", - sender=self) - self.hub.broadcast(snackbar_message) - - return - - # Try to set new units if set and are valid. - if new_flux is not None \ - and new_flux != "" \ - and new_flux != current_flux_unit: - try: - equivalencies = u.spectral_density(set_spectral_axis_unit) - set_flux_unit = spectrum.flux.to(u.Unit(new_flux), - equivalencies=equivalencies) - except ValueError as e: - snackbar_message = SnackbarMessage( - "Unable to convert flux units for selected data. " - f"Try different units: {repr(e)}", - color="error", - sender=self) - self.hub.broadcast(snackbar_message) - - return - - # Uncertainty converted to new flux units - if spectrum.uncertainty is not None: - unit_exp = unit_exponents.get(spectrum.uncertainty.__class__) - # If uncertainty type not in our lookup, drop the uncertainty - if unit_exp is None: - msg = SnackbarMessage( - "Warning: Unrecognized uncertainty type, cannot guarantee " - "conversion so dropping uncertainty in resulting data", - color="warning", - sender=self) - self.hub.broadcast(msg) - temp_uncertainty = None - else: - try: - # Catch and handle error trying to convert variance uncertainties - # between frequency and wavelength space. - # TODO: simplify this when astropy handles it - temp_uncertainty = spectrum.uncertainty.quantity**(1/unit_exp) - temp_uncertainty = temp_uncertainty.to(u.Unit(set_flux_unit.unit), - equivalencies=u.spectral_density(set_spectral_axis_unit)) # noqa - temp_uncertainty **= unit_exp - temp_uncertainty = spectrum.uncertainty.__class__(temp_uncertainty.value) - except u.UnitConversionError: - msg = SnackbarMessage( - "Warning: Could not convert uncertainty, setting to " - "None in converted data", - color="warning", - sender=self) - self.hub.broadcast(msg) - temp_uncertainty = None - else: - temp_uncertainty = None - - # Create new spectrum with new units. - converted_spectrum = spectrum._copy(flux=set_flux_unit, - wcs=None, - spectral_axis=set_spectral_axis_unit, - unit=set_flux_unit.unit, - uncertainty=temp_uncertainty) - if SPECUTILS_GT_1_7_0: - converted_spectrum.shift_spectrum_to(redshift=spectrum.redshift) - else: - converted_spectrum.redshift = spectrum.redshift - return converted_spectrum + if self.spectral_unit.selected == "": + # no spectral unit set yet, cannot determine equivalencies + # setting the spectral unit will check len(flux_unit.choices) and call this manually + # in the case that that is triggered second. + return + self.spectrum_viewer.set_plot_axes() + if y_unit != self.flux_unit.selected: + x_u = u.Unit(self.spectral_unit.selected) + y_unit = _valid_glue_display_unit(y_unit, self.spectrum_viewer, 'y') + y_u = u.Unit(y_unit) + choices = create_flux_equivalencies_list(y_u, x_u) + # ensure that original entry is in the list of choices + if not np.any([y_u == u.Unit(choice) for choice in choices]): + choices = [y_unit] + choices + self.flux_unit.choices = choices + self.flux_unit.selected = y_unit + + @observe('spectral_unit_selected') + def _on_spectral_unit_changed(self, *args): + xunit = _valid_glue_display_unit(self.spectral_unit.selected, self.spectrum_viewer, 'x') + if self.spectrum_viewer.state.x_display_unit != xunit: + self.spectrum_viewer.state.x_display_unit = xunit + + @observe('flux_unit_selected') + def _on_flux_unit_changed(self, *args): + yunit = _valid_glue_display_unit(self.flux_unit.selected, self.spectrum_viewer, 'y') + if self.spectrum_viewer.state.y_display_unit != yunit: + self.spectrum_viewer.state.y_display_unit = yunit diff --git a/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.vue b/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.vue index fac0a6d9e8..f544f5733f 100644 --- a/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.vue +++ b/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.vue @@ -3,72 +3,31 @@ - - - - + > - - - - - - - - - + > - - - - Apply - - - diff --git a/jdaviz/configs/specviz/plugins/viewers.py b/jdaviz/configs/specviz/plugins/viewers.py index 65c105f4fe..a917fb4578 100644 --- a/jdaviz/configs/specviz/plugins/viewers.py +++ b/jdaviz/configs/specviz/plugins/viewers.py @@ -350,10 +350,21 @@ def add_data(self, data, color=None, alpha=None, **layer_state): result : bool `True` if successful, `False` otherwise. """ + # If this is the first loaded data, set things up for unit conversion. + if len(self.layers) == 0: + reset_plot_axes = True + else: + reset_plot_axes = False + # The base class handles the plotting of the main # trace representing the spectrum itself. result = super().add_data(data, color, alpha, **layer_state) + if reset_plot_axes: + self.state.x_display_unit = data.get_component(self.state.x_att.label).units + self.state.y_display_unit = data.get_component("flux").units + self.set_plot_axes() + self._plot_uncertainties() self._plot_mask() @@ -476,22 +487,20 @@ def _plot_uncertainties(self): self.figure.marks = list(self.figure.marks) + [error_line_mark] def set_plot_axes(self): - # Get data to be used for axes labels - data = self.data()[0] - # Set axes labels for the spectrum viewer - spectral_axis_unit_type = str(data.spectral_axis.unit.physical_type).title() - # flux_unit_type = data.flux.unit.physical_type.title() flux_unit_type = "Flux density" - - if data.spectral_axis.unit.is_equivalent(u.m): + x_unit = u.Unit(self.state.x_display_unit) + if x_unit.is_equivalent(u.m): spectral_axis_unit_type = "Wavelength" - elif data.spectral_axis.unit.is_equivalent(u.pixel): - spectral_axis_unit_type = "pixel" + elif x_unit.is_equivalent(u.Hz): + spectral_axis_unit_type = "Frequency" + elif x_unit.is_equivalent(u.pixel): + spectral_axis_unit_type = "Pixel" + else: + spectral_axis_unit_type = str(x_unit.physical_type).title() - label_0 = f"{spectral_axis_unit_type} [{data.spectral_axis.unit.to_string()}]" - self.figure.axes[0].label = label_0 - self.figure.axes[1].label = f"{flux_unit_type} [{data.flux.unit.to_string()}]" + self.figure.axes[0].label = f"{spectral_axis_unit_type} [{self.state.x_display_unit}]" + self.figure.axes[1].label = f"{flux_unit_type} [{self.state.y_display_unit}]" # Make it so y axis label is not covering tick numbers. self.figure.axes[1].label_offset = "-50" diff --git a/jdaviz/configs/specviz/tests/test_helper.py b/jdaviz/configs/specviz/tests/test_helper.py index 82543695ff..f3041ab734 100644 --- a/jdaviz/configs/specviz/tests/test_helper.py +++ b/jdaviz/configs/specviz/tests/test_helper.py @@ -10,7 +10,6 @@ from astropy.utils.data import download_file from jdaviz.app import Application -from jdaviz.configs.specviz.plugins.unit_conversion import unit_conversion as uc from jdaviz.core.marks import LineUncertainties from jdaviz import Specviz @@ -277,7 +276,7 @@ def test_get_spectral_regions_unit_conversion(specviz_helper, spectrum1d): # If the reference (visible) data changes via unit conversion, # check that the region's units convert too - specviz_helper.load_spectrum(spectrum1d) + specviz_helper.load_spectrum(spectrum1d) # Originally Angstrom # Also check coordinates info panel. # x=0 -> 6000 A, x=1 -> 6222.222 A @@ -293,27 +292,18 @@ def test_get_spectral_regions_unit_conversion(specviz_helper, spectrum1d): assert label_mouseover.as_text() == ('', '', '') assert label_mouseover.icon == '' - # Convert the wavelength axis to microns + # Convert the wavelength axis to micron new_spectral_axis = "micron" - conv_func = uc.UnitConversion.process_unit_conversion - converted_spectrum = conv_func(specviz_helper.app, spectrum=spectrum1d, - new_spectral_axis=new_spectral_axis) - - # Add this new data and clear the other, making the converted spectrum our reference - specviz_helper.app.add_data(converted_spectrum, "Converted Spectrum") - specviz_helper.app.add_data_to_viewer("spectrum-viewer", - "Converted Spectrum", - clear_other_data=True) + spec_viewer.state.x_display_unit = new_spectral_axis + spec_viewer.set_plot_axes() - specviz_helper.app.get_viewer("spectrum-viewer").apply_roi(XRangeROI(0.6, 0.7)) + spec_viewer.apply_roi(XRangeROI(0.6, 0.7)) - # TODO: Is this test still relevant with the upcoming glue unit conversion changes? # Retrieve the Subset - # subsets = specviz_helper.get_spectral_regions() - # reg = subsets.get('Subset 1') - # - # assert reg.lower.unit == u.Unit(new_spectral_axis) - # assert reg.upper.unit == u.Unit(new_spectral_axis) + subsets = specviz_helper.get_spectral_regions() + reg = subsets.get('Subset 1') + assert reg.lower.unit == u.micron + assert reg.upper.unit == u.micron # Coordinates info panel should show new unit label_mouseover._viewer_mouse_event(spec_viewer, @@ -321,7 +311,7 @@ def test_get_spectral_regions_unit_conversion(specviz_helper, spectrum1d): label_mouseover.as_text() == ('Cursor 6.10000e-01, 1.25000e+01', 'Wave 6.00000e-01 micron (0 pix)', 'Flux 1.24967e+01 Jy') - assert label_mouseover.icon == 'b' + assert label_mouseover.icon == 'a' label_mouseover._viewer_mouse_event(spec_viewer, {'event': 'mouseleave'}) assert label_mouseover.as_text() == ('', '', '') diff --git a/jdaviz/configs/specviz2d/tests/test_parsers.py b/jdaviz/configs/specviz2d/tests/test_parsers.py index 1e4fea74b8..78a4096068 100644 --- a/jdaviz/configs/specviz2d/tests/test_parsers.py +++ b/jdaviz/configs/specviz2d/tests/test_parsers.py @@ -81,7 +81,7 @@ def test_2d_parser_no_unit(specviz2d_helper, mos_spectrum2d): label_mouseover._viewer_mouse_event(viewer_1d, {'event': 'mousemove', 'domain': {'x': 6.5, 'y': 3}}) assert label_mouseover.as_text() == ('Cursor 6.50000e+00, 3.00000e+00', - 'Wave 6.00000e+00 pix', + 'Wave 6.00000e+00 pixel', 'Flux -3.59571e+00') assert label_mouseover.icon == 'b' diff --git a/jdaviz/core/freezable_state.py b/jdaviz/core/freezable_state.py index 0d1a14600f..6405bf035b 100644 --- a/jdaviz/core/freezable_state.py +++ b/jdaviz/core/freezable_state.py @@ -8,7 +8,7 @@ __all__ = ['FreezableState', 'FreezableProfileViewerState', 'FreezableBqplotImageViewerState'] -class FreezableState(): +class FreezableState: _frozen_state = [] def __setattr__(self, k, v): diff --git a/jdaviz/core/helpers.py b/jdaviz/core/helpers.py index d9a415768d..25a4c41300 100644 --- a/jdaviz/core/helpers.py +++ b/jdaviz/core/helpers.py @@ -410,7 +410,23 @@ def show_in_new_tab(self, title=None): # pragma: no cover DeprecationWarning) return self.show(loc="sidecar:tab-after", title=title) - def _get_data(self, data_label=None, cls=None, subset_to_apply=None, function=None): + def _get_data(self, data_label=None, cls=None, subset_to_apply=None, function=None, + use_display_units=False): + def _handle_display_units(data, use_display_units): + if use_display_units: + if isinstance(data, Spectrum1D): + spectral_unit = self.app._get_display_unit('spectral') + flux_unit = self.app._get_display_unit('flux') + # TODO: any other attributes (meta, wcs, etc)? + # TODO: implement uncertainty.to upstream + data = Spectrum1D(spectral_axis=data.spectral_axis.to(spectral_unit, + u.spectral()), + flux=data.flux.to(flux_unit), + uncertainty=data.uncertainty.__class__(data.uncertainty.quantity.to(flux_unit))) # noqa + else: # pragma: nocover + raise NotImplementedError(f"converting {data.__class__.__name__} to display units is not supported") # noqa + return data + list_of_valid_function_values = ('minimum', 'maximum', 'mean', 'median', 'sum') if function and function not in list_of_valid_function_values: @@ -457,7 +473,7 @@ def _get_data(self, data_label=None, cls=None, subset_to_apply=None, function=No else: data = data.get_object(cls=cls, **object_kwargs) - return data + return _handle_display_units(data, use_display_units) if not cls and subset_to_apply: raise AttributeError(f"A valid cls must be provided to" @@ -480,9 +496,9 @@ def _get_data(self, data_label=None, cls=None, subset_to_apply=None, function=No warnings.warn(f"Not able to get {data_label} returned with" f" subset {subsets.label} applied of type {cls}." f" Exception: {e}") - return data + return _handle_display_units(data, use_display_units) - def get_data(self, data_label=None, cls=None, subset_to_apply=None): + def get_data(self, data_label=None, cls=None, subset_to_apply=None, use_display_units=False): """ Returns data with name equal to data_label of type cls with subsets applied from subset_to_apply. @@ -495,6 +511,8 @@ def get_data(self, data_label=None, cls=None, subset_to_apply=None): The type that data will be returned as. subset_to_apply : str, optional Subset that is to be applied to data before it is returned. + use_display_units: bool, optional + Whether to convert to the display units defined in the plugin. Returns ------- @@ -502,7 +520,8 @@ def get_data(self, data_label=None, cls=None, subset_to_apply=None): Data is returned as type cls with subsets applied. """ - return self._get_data(data_label=data_label, cls=cls, subset_to_apply=subset_to_apply) + return self._get_data(data_label=data_label, cls=cls, subset_to_apply=subset_to_apply, + use_display_units=use_display_units) class ImageConfigHelper(ConfigHelper): diff --git a/jdaviz/core/template_mixin.py b/jdaviz/core/template_mixin.py index fb094d6f5e..4092724239 100644 --- a/jdaviz/core/template_mixin.py +++ b/jdaviz/core/template_mixin.py @@ -28,7 +28,7 @@ __all__ = ['show_widget', 'TemplateMixin', 'PluginTemplateMixin', - 'BasePluginComponent', 'SelectPluginComponent', + 'BasePluginComponent', 'SelectPluginComponent', 'UnitSelectPluginComponent', 'PluginSubcomponent', 'SubsetSelect', 'SpatialSubsetSelectMixin', 'SpectralSubsetSelectMixin', 'DatasetSpectralSubsetValidMixin', @@ -101,7 +101,32 @@ def _subset_type(subset): return 'spectral' -class TemplateMixin(VuetifyTemplate, HubListener): +class ViewerPropertiesMixin: + # assumes that self.app is defined by the class + @cached_property + def spectrum_viewer(self): + if hasattr(self, '_default_spectrum_viewer_reference_name'): + viewer_reference = self._default_spectrum_viewer_reference_name + else: + viewer_reference = self.app._get_first_viewer_reference_name( + require_spectrum_viewer=True + ) + + return self.app.get_viewer(viewer_reference) + + @cached_property + def spectrum_2d_viewer(self): + if hasattr(self, '_default_spectrum_2d_viewer_reference_name'): + viewer_reference = self._default_spectrum_2d_viewer_reference_name + else: + viewer_reference = self.app._get_first_viewer_reference_name( + require_spectrum_2d_viewer=True + ) + + return self.app.get_viewer(viewer_reference) + + +class TemplateMixin(VuetifyTemplate, HubListener, ViewerPropertiesMixin): config = Unicode("").tag(sync=True) vdocs = Unicode("").tag(sync=True) popout_button = Any().tag(sync=True, **widget_serialization) @@ -293,7 +318,7 @@ def show(self, loc="inline", title=None): # pragma: no cover show_widget(self, loc=loc, title=title) -class BasePluginComponent(HubListener): +class BasePluginComponent(HubListener, ViewerPropertiesMixin): """ This base class handles attaching traitlets from the plugin itself to logic handled within the component, support for caching and clearing caches on properties, @@ -375,28 +400,6 @@ def _dict_from_viewer(viewer, viewer_item): for vid, viewer in self.app._viewer_store.items() if viewer.__class__.__name__ != 'MosvizTableViewer'] - @cached_property - def spectrum_viewer(self): - if hasattr(self, '_default_spectrum_viewer_reference_name'): - viewer_reference = self._default_spectrum_viewer_reference_name - else: - viewer_reference = self.app._get_first_viewer_reference_name( - require_spectrum_viewer=True - ) - - return self._plugin.app.get_viewer(viewer_reference) - - @cached_property - def spectrum_2d_viewer(self): - if hasattr(self, '_default_spectrum_2d_viewer_reference_name'): - viewer_reference = self._default_spectrum_2d_viewer_reference_name - else: - viewer_reference = self.app._get_first_viewer_reference_name( - require_spectrum_2d_viewer=True - ) - - return self._plugin.app.get_viewer(viewer_reference) - class SelectPluginComponent(BasePluginComponent, HasTraits): """ @@ -473,6 +476,10 @@ def __hash__(self): def choices(self): return self.labels + @choices.setter + def choices(self, choices=[]): + self.items = [{'label': choice} for choice in choices] + @property def is_multiselect(self): if not hasattr(self, 'multiselect'): @@ -641,6 +648,48 @@ def _selected_changed(self, event): raise ValueError(f"{event['new']} not one of {self.labels}, reverting selection to {event['old']}") # noqa +class UnitSelectPluginComponent(SelectPluginComponent): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.add_observe('items', lambda _: self._clear_cache('unit_choices')) + self._addl_unit_strings = [] + + @cached_property + def unit_choices(self): + return [u.Unit(lbl) for lbl in self.labels] + + @property + def addl_unit_choices(self): + return [u.Unit(choice) for choice in self._addl_unit_strings] + + def _selected_changed(self, event): + self._clear_cache() + if event['new'] in self.labels + ['']: + # the string is an exact match, no converting necessary + return + elif not len(self.labels): + raise ValueError("no valid unit choices") + try: + new_u = u.Unit(event['new']) + except ValueError: + self.selected = event['old'] + raise ValueError(f"{event['new']} could not be converted to a valid unit, reverting selection to {event['old']}") # noqa + if new_u not in self.unit_choices: + if new_u in self.addl_unit_choices: + # append this one (as the valid string representation) to the list of user-choices + addl_index = self.addl_unit_choices.index(new_u) + self.choices = self.choices + [self._addl_unit_strings[addl_index]] + # clear the cache so we can find the appropriate entry in unit_choices + self._clear_cache('unit_choices') + else: + self.selected = event['old'] + raise ValueError(f"{event['new']} not one of {self.labels}, reverting selection to {event['old']}") # noqa + + # convert to default string representation from the valid choices + ind = self.unit_choices.index(new_u) + self.selected = self.labels[ind] + + class LayerSelect(SelectPluginComponent): """ Plugin select for layers, with support for single or multi-selection. @@ -1483,11 +1532,14 @@ def selected_obj(self): # from the data collection return self.get_object(cls=self.default_data_cls) - def selected_spectrum_for_spatial_subset(self, spatial_subset=SPATIAL_DEFAULT_TEXT): + def selected_spectrum_for_spatial_subset(self, + spatial_subset=SPATIAL_DEFAULT_TEXT, + use_display_units=True): if spatial_subset == SPATIAL_DEFAULT_TEXT: spatial_subset = None return self.plugin._specviz_helper.get_data(data_label=self.selected, - subset_to_apply=spatial_subset) + subset_to_apply=spatial_subset, + use_display_units=use_display_units) def _is_valid_item(self, data): def not_from_plugin(data): diff --git a/jdaviz/core/tests/test_tools.py b/jdaviz/core/tests/test_tools.py index 2785d0bce4..aace5d537c 100644 --- a/jdaviz/core/tests/test_tools.py +++ b/jdaviz/core/tests/test_tools.py @@ -1,24 +1,19 @@ -import numpy as np -from glue.core import Data +from numpy.testing import assert_allclose -def test_boxzoom(cubeviz_helper, spectral_cube_wcs): - data = Data(flux=np.ones((128, 128, 256)), label='Test Flux', coords=spectral_cube_wcs) - cubeviz_helper.app.data_collection.append(data) - - cubeviz_helper.app.add_data_to_viewer('spectrum-viewer', 'Test Flux') - cubeviz_helper.app.add_data_to_viewer('flux-viewer', 'Test Flux') +def test_boxzoom(cubeviz_helper, image_cube_hdu_obj_microns): + cubeviz_helper.load_data(image_cube_hdu_obj_microns, data_label="Test Flux") flux_viewer = cubeviz_helper.app.get_viewer('flux-viewer') assert flux_viewer.state.y_min == -0.5 - assert flux_viewer.state.y_max == 127.5 + assert flux_viewer.state.y_max == 8.5 assert flux_viewer.state.x_min == -0.5 - assert flux_viewer.state.x_max == 127.5 + assert flux_viewer.state.x_max == 9.5 t = flux_viewer.toolbar.tools['jdaviz:boxzoom'] t.activate() - t.interact.selected_x = [10, 20] - t.interact.selected_y = [20, 60] + t.interact.selected_x = [1, 4] + t.interact.selected_y = [2, 6] - assert t.get_x_axis_with_aspect_ratio() == (-5., 35.) + assert_allclose(t.get_x_axis_with_aspect_ratio(), [0.277778, 4.722222], rtol=1e-6) diff --git a/jdaviz/core/user_api.py b/jdaviz/core/user_api.py index 9ef69ed4f6..4a31da9197 100644 --- a/jdaviz/core/user_api.py +++ b/jdaviz/core/user_api.py @@ -1,3 +1,5 @@ +import astropy.units as u + __all__ = ['UserApiWrapper', 'PluginUserApi'] @@ -38,12 +40,15 @@ def __setattr__(self, attr, value): exp_obj = getattr(self._obj, attr) from jdaviz.core.template_mixin import (SelectPluginComponent, + UnitSelectPluginComponent, PlotOptionsSyncState, AddResults, AutoTextField) if isinstance(exp_obj, SelectPluginComponent): # this allows setting the selection directly without needing to access the underlying # .selected traitlet + if isinstance(exp_obj, UnitSelectPluginComponent) and isinstance(value, u.Unit): + value = value.to_string() exp_obj.selected = value return elif isinstance(exp_obj, AddResults): diff --git a/jdaviz/core/validunits.py b/jdaviz/core/validunits.py index 01a939ead0..372a5f2904 100644 --- a/jdaviz/core/validunits.py +++ b/jdaviz/core/validunits.py @@ -1,5 +1,4 @@ -import astropy.units as u -import numpy as np +from astropy import units as u __all__ = ['units_to_strings', 'create_spectral_equivalencies_list', 'create_flux_equivalencies_list'] @@ -19,68 +18,61 @@ def units_to_strings(unit_list): result : list A list of the units with their best (i.e., most readable) string version. """ - return [u.Unit(unit).name - if u.Unit(unit) == u.Unit("Angstrom") - else u.Unit(unit).long_names[0] if ( - hasattr(u.Unit(unit), "long_names") and len(u.Unit(unit).long_names) > 0) - else u.Unit(unit).to_string() - for unit in unit_list] + return [u.Unit(unit).to_string() for unit in unit_list] -def create_spectral_equivalencies_list(spectrum, +def create_spectral_equivalencies_list(spectral_axis_unit, exclude=[u.jupiterRad, u.earthRad, u.solRad, - u.lyr, u.AU, u.pc]): - """Get all possible conversions from current spectral_axis_unit. - """ - if spectrum.spectral_axis.unit == u.pix: + u.lyr, u.AU, u.pc, u.Bq, u.micron, u.lsec]): + """Get all possible conversions from current spectral_axis_unit.""" + if spectral_axis_unit in (u.pix, u.dimensionless_unscaled): return [] # Get unit equivalencies. - curr_spectral_axis_unit_equivalencies = u.Unit( - spectrum.spectral_axis.unit).find_equivalent_units( - equivalencies=u.spectral()) + try: + curr_spectral_axis_unit_equivalencies = spectral_axis_unit.find_equivalent_units( + equivalencies=u.spectral()) + except u.core.UnitConversionError: + return [] # Get local units. - locally_defined_spectral_axis_units = ['angstrom', 'nanometer', - 'micron', 'hertz', 'erg'] + locally_defined_spectral_axis_units = ['Angstrom', 'nm', + 'um', 'Hz', 'erg'] local_units = [u.Unit(unit) for unit in locally_defined_spectral_axis_units] # Remove overlap units. curr_spectral_axis_unit_equivalencies = list(set(curr_spectral_axis_unit_equivalencies) - - set(local_units+exclude)) + - set(local_units + exclude)) # Convert equivalencies into readable versions of the units and sorted alphabetically. spectral_axis_unit_equivalencies_titles = sorted(units_to_strings( curr_spectral_axis_unit_equivalencies)) # Concatenate both lists with the local units coming first. - spectral_axis_unit_equivalencies_titles = sorted(units_to_strings( - local_units)) + spectral_axis_unit_equivalencies_titles - - return spectral_axis_unit_equivalencies_titles + return sorted(units_to_strings(local_units)) + spectral_axis_unit_equivalencies_titles -def create_flux_equivalencies_list(spectrum): - """Get all possible conversions for flux from current flux units. - """ - if ((spectrum.flux.unit == u.count) or (spectrum.spectral_axis.unit == u.pix)): +def create_flux_equivalencies_list(flux_unit, spectral_axis_unit): + """Get all possible conversions for flux from current flux units.""" + if ((flux_unit in (u.count, (u.MJy / u.sr), u.dimensionless_unscaled)) + or (spectral_axis_unit in (u.pix, u.dimensionless_unscaled))): return [] - # Get unit equivalencies. - curr_flux_unit_equivalencies = u.Unit( - spectrum.flux.unit).find_equivalent_units( - equivalencies=u.spectral_density(np.sum(spectrum.spectral_axis)), + # Get unit equivalencies. Value passed into u.spectral_density() is irrelevant. + try: + curr_flux_unit_equivalencies = flux_unit.find_equivalent_units( + equivalencies=u.spectral_density(1 * spectral_axis_unit), include_prefix_units=False) + except u.core.UnitConversionError: + return [] # Get local units. locally_defined_flux_units = ['Jy', 'mJy', 'uJy', 'W / (m2 Hz)', 'eV / (s m2 Hz)', 'erg / (s cm2)', - 'erg / (s cm2 um)', 'erg / (s cm2 Angstrom)', 'erg / (s cm2 Hz)', - 'ph / (s cm2 um)', 'ph / (s cm2 Angstrom)', 'ph / (s cm2 Hz)'] local_units = [u.Unit(unit) for unit in locally_defined_flux_units] @@ -93,7 +85,4 @@ def create_flux_equivalencies_list(spectrum): flux_unit_equivalencies_titles = sorted(units_to_strings(curr_flux_unit_equivalencies)) # Concatenate both lists with the local units coming first. - flux_unit_equivalencies_titles = (sorted(units_to_strings(local_units)) + - flux_unit_equivalencies_titles) - - return flux_unit_equivalencies_titles + return sorted(units_to_strings(local_units)) + flux_unit_equivalencies_titles diff --git a/jdaviz/tests/test_subsets.py b/jdaviz/tests/test_subsets.py index 972231c691..4f25b52bb6 100644 --- a/jdaviz/tests/test_subsets.py +++ b/jdaviz/tests/test_subsets.py @@ -4,12 +4,10 @@ from astropy.tests.helper import assert_quantity_allclose from glue.core import Data from glue.core.roi import CircularROI, EllipticalROI, RectangularROI, XRangeROI - from glue.core.edit_subset_mode import AndMode, AndNotMode, OrMode from regions import PixCoord, CirclePixelRegion, RectanglePixelRegion, EllipsePixelRegion - from numpy.testing import assert_allclose -from specutils import SpectralRegion +from specutils import SpectralRegion, Spectrum1D from jdaviz.core.marks import ShadowSpatialSpectral @@ -135,12 +133,10 @@ def test_region_from_subset_3d(cubeviz_helper): def test_region_from_subset_profile(cubeviz_helper, spectral_cube_wcs): - data = Data(flux=np.ones((128, 128, 256)), label='Test 1D Flux', coords=spectral_cube_wcs) + data = Spectrum1D(flux=np.ones((128, 128, 256)) * u.nJy, wcs=spectral_cube_wcs) subset_plugin = cubeviz_helper.app.get_tray_item_from_name('g-subset-plugin') - cubeviz_helper.app.data_collection.append(data) - - cubeviz_helper.app.add_data_to_viewer('spectrum-viewer', 'Test 1D Flux') + cubeviz_helper.load_data(data, data_label='Test 1D Flux') cubeviz_helper.app.get_viewer("spectrum-viewer").apply_roi(XRangeROI(5, 15.5)) @@ -184,11 +180,8 @@ def test_region_from_subset_profile(cubeviz_helper, spectral_cube_wcs): def test_region_spectral_spatial(cubeviz_helper, spectral_cube_wcs): - data = Data(flux=np.ones((128, 128, 256)), label='Test Flux', coords=spectral_cube_wcs) - cubeviz_helper.app.data_collection.append(data) - - cubeviz_helper.app.add_data_to_viewer('spectrum-viewer', 'Test Flux') - cubeviz_helper.app.add_data_to_viewer('flux-viewer', 'Test Flux') + data = Spectrum1D(flux=np.ones((128, 128, 256)) * u.nJy, wcs=spectral_cube_wcs) + cubeviz_helper.load_data(data, data_label="Test Flux") # use gaussian smooth plugin as a regression test for # https://github.com/spacetelescope/jdaviz/issues/1853 @@ -236,11 +229,8 @@ def test_region_spectral_spatial(cubeviz_helper, spectral_cube_wcs): def test_disjoint_spatial_subset(cubeviz_helper, spectral_cube_wcs): - data = Data(flux=np.ones((128, 128, 256)), label='Test Flux', coords=spectral_cube_wcs) - cubeviz_helper.app.data_collection.append(data) - - cubeviz_helper.app.add_data_to_viewer('spectrum-viewer', 'Test Flux') - cubeviz_helper.app.add_data_to_viewer('flux-viewer', 'Test Flux') + data = Spectrum1D(flux=np.ones((128, 128, 256)) * u.nJy, wcs=spectral_cube_wcs) + cubeviz_helper.load_data(data, data_label="Test Flux") flux_viewer = cubeviz_helper.app.get_viewer("flux-viewer") flux_viewer.apply_roi(CircularROI(xc=3, yc=4, radius=1)) @@ -260,11 +250,8 @@ def test_disjoint_spatial_subset(cubeviz_helper, spectral_cube_wcs): def test_disjoint_spectral_subset(cubeviz_helper, spectral_cube_wcs): subset_plugin = cubeviz_helper.app.get_tray_item_from_name('g-subset-plugin') - data = Data(flux=np.ones((128, 128, 256)), label='Test Flux', coords=spectral_cube_wcs) - cubeviz_helper.app.data_collection.append(data) - - cubeviz_helper.app.add_data_to_viewer('spectrum-viewer', 'Test Flux') - cubeviz_helper.app.add_data_to_viewer('flux-viewer', 'Test Flux') + data = Spectrum1D(flux=np.ones((128, 128, 256)) * u.nJy, wcs=spectral_cube_wcs) + cubeviz_helper.load_data(data, data_label="Test Flux") spec_viewer = cubeviz_helper.app.get_viewer("spectrum-viewer") spec_viewer.apply_roi(XRangeROI(5, 15.5)) diff --git a/jdaviz/utils.py b/jdaviz/utils.py index 3d042d99f0..59ad0cf814 100644 --- a/jdaviz/utils.py +++ b/jdaviz/utils.py @@ -4,7 +4,6 @@ from collections import deque import matplotlib.pyplot as plt - from astropy.io import fits from ipyvue import watch from glue.config import settings diff --git a/notebooks/concepts/specviz_glue_unit_conversion.ipynb b/notebooks/concepts/specviz_glue_unit_conversion.ipynb new file mode 100644 index 0000000000..614d7c46b1 --- /dev/null +++ b/notebooks/concepts/specviz_glue_unit_conversion.ipynb @@ -0,0 +1,293 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "57c41ae5", + "metadata": {}, + "source": [ + "This is a concept notebook to investigate Glue unit conversion behavior integrated into Jdaviz spectrum viewer." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2b3bbfb1", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from astropy import units as u\n", + "from specutils import Spectrum1D\n", + "\n", + "from jdaviz import Specviz" + ] + }, + { + "cell_type": "markdown", + "id": "0d253733", + "metadata": {}, + "source": [ + "First spectrum." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cba69bb7", + "metadata": {}, + "outputs": [], + "source": [ + "wave1 = np.linspace(2, 5, 10) * u.um\n", + "flux1 = [1, 2, 3, 4, 5, 5, 4, 3, 2, 1] * u.Jy\n", + "spec1 = Spectrum1D(flux=flux1, spectral_axis=wave1)\n", + "\n", + "print(wave1)\n", + "print(flux1)" + ] + }, + { + "cell_type": "markdown", + "id": "1e0e7dc5", + "metadata": {}, + "source": [ + "Second spectrum in different units and with slight offsets in spectral axis." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "26bc794d", + "metadata": {}, + "outputs": [], + "source": [ + "wave2 = (wave1 + (0.1 * u.um)).to(u.GHz, u.spectral())\n", + "flux2 = flux1.to(u.mJy)\n", + "spec2 = Spectrum1D(flux=flux2, spectral_axis=wave2)\n", + "\n", + "print(wave2)\n", + "print(wave2.to(u.um, u.spectral()))\n", + "print(flux2)" + ] + }, + { + "cell_type": "markdown", + "id": "2bb4f4ea", + "metadata": {}, + "source": [ + "Fire up Specviz." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "74692a02", + "metadata": {}, + "outputs": [], + "source": [ + "specviz = Specviz()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "efdba701", + "metadata": {}, + "outputs": [], + "source": [ + "specviz.show()" + ] + }, + { + "cell_type": "markdown", + "id": "642fbae1", + "metadata": {}, + "source": [ + "Load the data into Specviz. Desired behavior:\n", + "\n", + "1. \"Jy_um\" would load with Jy in Y-axis and um in X-axis.\n", + "2. \"mJy_GHz\" would load with data automatically converted to Jy and um in the plot. You would see the same shape but slightly offset in X-axis, just slightly." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5ee09160", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "specviz.load_data(spec1, data_label=\"Jy_um\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9655292b", + "metadata": {}, + "outputs": [], + "source": [ + "specviz.load_data(spec2, data_label=\"mJy_GHz\")" + ] + }, + { + "cell_type": "markdown", + "id": "e6012551", + "metadata": {}, + "source": [ + "Change the spectral axis display unit to GHz." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6a4611b3", + "metadata": {}, + "outputs": [], + "source": [ + "viewer = specviz.app.get_viewer(\"spectrum-viewer\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ac319e71", + "metadata": {}, + "outputs": [], + "source": [ + "viewer.state.x_display_unit = \"GHz\"" + ] + }, + { + "cell_type": "markdown", + "id": "b2e84da2", + "metadata": {}, + "source": [ + "Change the flux axis display unit to FLAM." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4892cb38", + "metadata": {}, + "outputs": [], + "source": [ + "FLAM = u.erg / (u.s * u.cm * u.cm * u.AA)\n", + "\n", + "# If astropy can do it, Jdaviz should too.\n", + "spec1.flux.to(FLAM, u.spectral_density(spec1.spectral_axis))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3be87c54", + "metadata": {}, + "outputs": [], + "source": [ + "# this MIGHT fail depending on the version of astropy (since glue harcodes the expected string formatting \n", + "# for units, whereas astropy recently changed the default order of units)\n", + "try:\n", + " viewer.state.y_display_unit = FLAM.to_string()\n", + "except ValueError as e:\n", + " print(\"setting y_display_unit failed: \", repr(e))" + ] + }, + { + "cell_type": "markdown", + "id": "116e5806", + "metadata": {}, + "source": [ + "The plugin select component, however, is unit-aware and will handle mapping to the string formatting expected by glue" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "da5df8d4", + "metadata": {}, + "outputs": [], + "source": [ + "uc = specviz.plugins['Unit Conversion']\n", + "uc.flux_unit.choices" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b74ae8aa", + "metadata": {}, + "outputs": [], + "source": [ + "uc.flux_unit = FLAM.to_string()" + ] + }, + { + "cell_type": "markdown", + "id": "8be218b4", + "metadata": {}, + "source": [ + "Change the spectral axis again, this time to Angstrom via the plugin API." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8f9073f7", + "metadata": {}, + "outputs": [], + "source": [ + "uc.spectral_unit = 'Angstrom'" + ] + }, + { + "cell_type": "markdown", + "id": "fa487529", + "metadata": {}, + "source": [ + "Change everything back to original units." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8c110686", + "metadata": {}, + "outputs": [], + "source": [ + "viewer.state.x_display_unit = \"micron\"\n", + "viewer.state.y_display_unit = \"Jy\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "87642b18", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.15" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/concepts/specviz_unit_conversion.ipynb b/notebooks/concepts/specviz_unit_conversion.ipynb deleted file mode 100644 index 1402e6c56c..0000000000 --- a/notebooks/concepts/specviz_unit_conversion.ipynb +++ /dev/null @@ -1,61 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from jdaviz.configs.specviz.helper import Specviz\n", - "import specutils\n", - "import astropy.units as u\n", - "import numpy as np" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "spec_url = 'https://dr14.sdss.org/optical/spectrum/view/data/format=fits/spec=lite?plateid=1323&mjd=52797&fiberid=12'\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": false - }, - "outputs": [], - "source": [ - "specviz = Specviz()\n", - "spec = specutils.Spectrum1D.read(spec_url)\n", - "specviz.load_spectrum(spec)\n", - "\n", - "specviz.show()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.5" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} From 81bd3c96f053cb99990f021b558b8585ffac95d9 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Wed, 5 Apr 2023 09:27:38 -0400 Subject: [PATCH 03/42] bump glue-core to necessary version for display units --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ebd23f4b9e..7d0acb9155 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,8 +12,8 @@ dependencies = [ "traitlets>=5.0.5", "bqplot>=0.12.37", "bqplot-image-gl>=1.4.11", - "glue-core>=1.6.0,!=1.9.0,!=1.10", - "glue-jupyter>=0.15.0", + "glue-core>=1.10.0", + "glue-jupyter>=0.16.3", "echo>=0.5.0", "ipykernel>=6.19.4", "ipyvue>=1.6", From efc5fd7d5329d49b0911aa3d53fc70e58b829391 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Tue, 4 Apr 2023 13:29:20 -0400 Subject: [PATCH 04/42] change PR number in changelog to main PR --- CHANGES.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index cfe4ef8495..1ec8c85d70 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -41,7 +41,7 @@ Mosviz Specviz ^^^^^^^ -* Re-enabled unit conversion support. [#2048] +* Re-enabled unit conversion support. [#2127] Specviz2d ^^^^^^^^^ From c267347eeae3e6da752fb4f34ca2a9978a7e954c Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Wed, 5 Apr 2023 14:01:42 -0400 Subject: [PATCH 05/42] Display units line analysis (#2128) * emit event when display unit changed * update line analysis for unit changes --- jdaviz/app.py | 1 - .../plugins/line_analysis/line_analysis.py | 23 +++++++++++++------ .../unit_conversion/unit_conversion.py | 7 ++++++ jdaviz/core/events.py | 20 +++++++++++++++- 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/jdaviz/app.py b/jdaviz/app.py index 0ec4f538d5..348b34ef36 100644 --- a/jdaviz/app.py +++ b/jdaviz/app.py @@ -1031,7 +1031,6 @@ def _get_range_subset_bounds(self, subset_state, else: spec_region = SpectralRegion(subset_state.lo * units, subset_state.hi * units) - spec_region = SpectralRegion(subset_state.lo * units, subset_state.hi * units) if not simplify_spectral: return [{"name": subset_state.__class__.__name__, "glue_state": subset_state.__class__.__name__, diff --git a/jdaviz/configs/specviz/plugins/line_analysis/line_analysis.py b/jdaviz/configs/specviz/plugins/line_analysis/line_analysis.py index 134a9b917d..3b179c1639 100644 --- a/jdaviz/configs/specviz/plugins/line_analysis/line_analysis.py +++ b/jdaviz/configs/specviz/plugins/line_analysis/line_analysis.py @@ -15,7 +15,8 @@ RemoveDataMessage, SpectralMarksChangedMessage, LineIdentifyMessage, - RedshiftMessage) + RedshiftMessage, + GlobalDisplayUnitChanged) from jdaviz.core.marks import (LineAnalysisContinuum, LineAnalysisContinuumCenter, LineAnalysisContinuumLeft, @@ -158,6 +159,8 @@ def __init__(self, *args, **kwargs): handler=self._on_plotted_lines_changed) self.hub.subscribe(self, LineIdentifyMessage, handler=self._on_identified_line_changed) + self.hub.subscribe(self, GlobalDisplayUnitChanged, + handler=self._on_global_display_unit_changed) @property def user_api(self): @@ -205,6 +208,10 @@ def _on_viewer_subsets_changed(self, msg): and self.plugin_opened): self._calculate_statistics() + def _on_global_display_unit_changed(self, msg): + if self.plugin_opened: + self._calculate_statistics() + @observe('plugin_opened') def _on_plugin_opened_changed(self, *args): if self.disabled_msg: @@ -314,8 +321,8 @@ def _calculate_statistics(self, *args, **kwargs): # show spinner with overlay self.results_computing = True - - full_spectrum = self.dataset.selected_spectrum_for_spatial_subset(self.spatial_subset_selected) # noqa + full_spectrum = self.dataset.selected_spectrum_for_spatial_subset(self.spatial_subset_selected, # noqa + use_display_units=True) if (full_spectrum is None or self.width == "" or (not self.plugin_opened and not kwargs.get('ignore_plugin_closed'))): @@ -330,13 +337,14 @@ def _calculate_statistics(self, *args, **kwargs): self.update_results(None) return - sr = self.app.get_subsets().get(self.spectral_subset_selected) if self.spectral_subset_selected == "Entire Spectrum": spectrum = full_spectrum else: + sr = self.app.get_subsets(self.spectral_subset_selected, + simplify_spectral=True, use_display_units=True) spectrum = extract_region(full_spectrum, sr, return_single_spectrum=True) - sr_lower = spectrum.spectral_axis[spectrum.spectral_axis.value >= sr.lower.value][0] - sr_upper = spectrum.spectral_axis[spectrum.spectral_axis.value <= sr.upper.value][-1] + sr_lower = np.nanmin(spectrum.spectral_axis[spectrum.spectral_axis.value >= sr.lower.value]) # noqa + sr_upper = np.nanmax(spectrum.spectral_axis[spectrum.spectral_axis.value <= sr.upper.value]) # noqa # compute continuum if self.continuum_subset_selected == "Surrounding" and self.spectral_subset_selected == "Entire Spectrum": # noqa @@ -383,7 +391,8 @@ def _calculate_statistics(self, *args, **kwargs): # cube, but still apply that to the spatially-collapsed spectrum. continuum_mask = ~self._specviz_helper.get_data( self.dataset.selected, - subset_to_apply=self.continuum_subset_selected).mask + subset_to_apply=self.continuum_subset_selected, + use_display_units=False).mask spectral_axis_nanmasked = spectral_axis.value.copy() spectral_axis_nanmasked[~continuum_mask] = np.nan if self.spectral_subset_selected == "Entire Spectrum": diff --git a/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.py b/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.py index 05d62ddb79..d96525c315 100644 --- a/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.py +++ b/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.py @@ -2,6 +2,7 @@ from astropy import units as u from traitlets import List, Unicode, observe +from jdaviz.core.events import GlobalDisplayUnitChanged from jdaviz.core.registries import tray_registry from jdaviz.core.template_mixin import PluginTemplateMixin, UnitSelectPluginComponent, PluginUserApi from jdaviz.core.validunits import (create_spectral_equivalencies_list, @@ -122,12 +123,18 @@ def _on_glue_y_display_unit_changed(self, y_unit): @observe('spectral_unit_selected') def _on_spectral_unit_changed(self, *args): + self.hub.broadcast(GlobalDisplayUnitChanged('spectral', + self.spectral_unit.selected, + sender=self)) xunit = _valid_glue_display_unit(self.spectral_unit.selected, self.spectrum_viewer, 'x') if self.spectrum_viewer.state.x_display_unit != xunit: self.spectrum_viewer.state.x_display_unit = xunit @observe('flux_unit_selected') def _on_flux_unit_changed(self, *args): + self.hub.broadcast(GlobalDisplayUnitChanged('flux', + self.flux_unit.selected, + sender=self)) yunit = _valid_glue_display_unit(self.flux_unit.selected, self.spectrum_viewer, 'y') if self.spectrum_viewer.state.y_display_unit != yunit: self.spectrum_viewer.state.y_display_unit = yunit diff --git a/jdaviz/core/events.py b/jdaviz/core/events.py index 46126bb65e..1bfbb9d9b6 100644 --- a/jdaviz/core/events.py +++ b/jdaviz/core/events.py @@ -1,3 +1,4 @@ +import astropy.units as u from glue.core.message import Message __all__ = ['NewViewerMessage', 'ViewerAddedMessage', 'ViewerRemovedMessage', 'LoadDataMessage', @@ -6,7 +7,8 @@ 'SliceSelectSliceMessage', 'SliceToolStateMessage', 'TableClickMessage', 'LinkUpdatedMessage', 'ExitBatchLoadMessage', - 'MarkersChangedMessage', 'CanvasRotationChangedMessage'] + 'MarkersChangedMessage', 'CanvasRotationChangedMessage', + 'GlobalDisplayUnitChanged'] class NewViewerMessage(Message): @@ -337,3 +339,19 @@ def angle(self): @property def flip_horizontal(self): return self._flip_horizontal + + +class GlobalDisplayUnitChanged(Message): + '''Message generated when the global app-wide display unit is changed''' + def __init__(self, axis, unit, *args, **kwargs): + super().__init__(*args, **kwargs) + self._axis = axis + self._unit = unit + + @property + def axis(self): + return self._axis + + @property + def unit(self): + return u.Unit(self._unit) From 9db4468d798d5667b5bf11f6bdd687ca265ef8f1 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Wed, 5 Apr 2023 09:30:22 -0400 Subject: [PATCH 06/42] cubeviz/slice plugin unit conversion support (we might want to generalize some of this logic more into the mark's _update_data when adding support for spectral lines as well) --- jdaviz/configs/cubeviz/plugins/slice/slice.py | 30 +++++++++++++++---- .../unit_conversion/unit_conversion.py | 2 +- jdaviz/core/helpers.py | 2 ++ jdaviz/core/marks.py | 2 +- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/jdaviz/configs/cubeviz/plugins/slice/slice.py b/jdaviz/configs/cubeviz/plugins/slice/slice.py index c7a94a5adc..57026f9d63 100644 --- a/jdaviz/configs/cubeviz/plugins/slice/slice.py +++ b/jdaviz/configs/cubeviz/plugins/slice/slice.py @@ -3,13 +3,15 @@ import warnings import numpy as np +import astropy.units as u from astropy.units import UnitsWarning from glue_jupyter.bqplot.image import BqplotImageView from glue_jupyter.bqplot.profile import BqplotProfileView from traitlets import Bool, Float, observe, Any, Int from specutils.spectra.spectrum1d import Spectrum1D -from jdaviz.core.events import AddDataMessage, SliceToolStateMessage, SliceSelectSliceMessage +from jdaviz.core.events import (AddDataMessage, SliceToolStateMessage, + SliceSelectSliceMessage, GlobalDisplayUnitChanged) from jdaviz.core.registries import tray_registry from jdaviz.core.template_mixin import PluginTemplateMixin from jdaviz.core.user_api import PluginUserApi @@ -83,11 +85,19 @@ def __init__(self, *args, **kwargs): self.session.hub.subscribe(self, AddDataMessage, handler=self._on_data_added) + # update internal wavelength when x display unit is changed (preserving slice) + self.session.hub.subscribe(self, GlobalDisplayUnitChanged, + handler=self._on_global_display_unit_changed) + @property def user_api(self): return PluginUserApi(self, expose=('slice', 'wavelength', 'show_indicator', 'show_wavelength')) + @property + def slice_indicator(self): + return self.spectrum_viewer.slice_indicator + def _watch_viewer(self, viewer, watch=True): if isinstance(viewer, BqplotImageView): if watch and viewer not in self._watched_viewers: @@ -125,11 +135,7 @@ def _update_reference_data(self, reference_data): self._update_data(reference_data.get_object(cls=Spectrum1D).spectral_axis) def _update_data(self, x_all): - if hasattr(x_all, 'unit'): - self.wavelength_unit = str(x_all.unit) - x_all = x_all.value - - self._x_all = x_all + self._x_all = x_all.value if self.wavelength == -1: if len(x_all): @@ -142,6 +148,9 @@ def _update_data(self, x_all): # force wavelength to update from the current slider value self._on_slider_updated({'new': self.slice}) + # update data held inside slice indicator and force reverting to original active status + self.slice_indicator._update_data(x_all) + def _viewer_slices_changed(self, value): # the slices attribute on the viewer state was changed, # so we'll update the slider to match which will trigger @@ -157,6 +166,15 @@ def _on_select_slice_message(self, msg): warnings.simplefilter('ignore', category=UnitsWarning) self.slice = msg.slice + def _on_global_display_unit_changed(self, msg): + if msg.axis != 'spectral': + return + prev_unit = self.wavelength_unit + self.wavelength_unit = msg.unit.to_string() + if self._x_all is None or prev_unit == '': + return + self._update_data((self._x_all * u.Unit(prev_unit)).to(msg.unit, u.spectral())) + @observe('wavelength') def _on_wavelength_updated(self, event): # convert to float (JS handles stripping any invalid characters) diff --git a/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.py b/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.py index d96525c315..990646f3e0 100644 --- a/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.py +++ b/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.py @@ -54,7 +54,7 @@ class UnitConversion(PluginTemplateMixin): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - if self.config not in ['specviz']: + if self.config not in ['specviz', 'cubeviz']: # TODO [specviz2d, mosviz] x_display_unit is not implemented in glue for image viewer # used by spectrum-2d-viewer # TODO [mosviz]: add to yaml file diff --git a/jdaviz/core/helpers.py b/jdaviz/core/helpers.py index 25a4c41300..60277ee090 100644 --- a/jdaviz/core/helpers.py +++ b/jdaviz/core/helpers.py @@ -416,6 +416,8 @@ def _handle_display_units(data, use_display_units): if use_display_units: if isinstance(data, Spectrum1D): spectral_unit = self.app._get_display_unit('spectral') + if not spectral_unit: + return data flux_unit = self.app._get_display_unit('flux') # TODO: any other attributes (meta, wcs, etc)? # TODO: implement uncertainty.to upstream diff --git a/jdaviz/core/marks.py b/jdaviz/core/marks.py index 2a6590d711..7c2cc5a223 100644 --- a/jdaviz/core/marks.py +++ b/jdaviz/core/marks.py @@ -268,7 +268,7 @@ def _update_colors_opacities(self): self.colors = ["#c75109" if self._active else "#007BA1"] self.opacities = [1.0 if self._active else 0.9] - def _on_change_state(self, msg): + def _on_change_state(self, msg={}): if isinstance(msg, dict): changes = msg else: From 63ddd82251eed6775648aa5414402e6fc547d75c Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Tue, 11 Apr 2023 10:08:47 -0400 Subject: [PATCH 07/42] Display units support for markers plugin (#2130) * update markers plugin for display units * move unit-updating logic to mark itself * LineUncertainties to be unit-aware * fix support for markers in cubeviz --- .../default/plugins/markers/markers.py | 1 - jdaviz/configs/default/plugins/viewers.py | 4 + jdaviz/core/marks.py | 78 ++++++++++++++++++- 3 files changed, 78 insertions(+), 5 deletions(-) diff --git a/jdaviz/configs/default/plugins/markers/markers.py b/jdaviz/configs/default/plugins/markers/markers.py index ed06f00910..754eee5d8c 100644 --- a/jdaviz/configs/default/plugins/markers/markers.py +++ b/jdaviz/configs/default/plugins/markers/markers.py @@ -139,7 +139,6 @@ def _on_viewer_key_event(self, viewer, data): raise ValueError(f'failed to add {row_info} to table: {repr(err)}') x, y = row_info['axes_x'], row_info['axes_y'] - # TODO: will need to test/update when adding support for display units self._get_mark(viewer).append_xy(getattr(x, 'value', x), getattr(y, 'value', y)) def clear_table(self): diff --git a/jdaviz/configs/default/plugins/viewers.py b/jdaviz/configs/default/plugins/viewers.py index 7023f19671..70f33aa657 100644 --- a/jdaviz/configs/default/plugins/viewers.py +++ b/jdaviz/configs/default/plugins/viewers.py @@ -216,6 +216,10 @@ def jdaviz_helper(self): """The Jdaviz configuration helper tied to the viewer.""" return self.jdaviz_app._jdaviz_helper + @property + def hub(self): + return self.session.hub + @property def reference_id(self): return self._reference_id diff --git a/jdaviz/core/marks.py b/jdaviz/core/marks.py index 7c2cc5a223..08ffba76b9 100644 --- a/jdaviz/core/marks.py +++ b/jdaviz/core/marks.py @@ -7,6 +7,7 @@ from glue.core import HubListener from specutils import Spectrum1D +from jdaviz.core.events import GlobalDisplayUnitChanged from jdaviz.core.events import (SliceToolStateMessage, LineIdentifyMessage, SpectralMarksChangedMessage, RedshiftMessage) @@ -485,6 +486,20 @@ def _on_shadowing_changed(self, change): class PluginMark(): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.xunit = None + self.yunit = None + # whether to update existing marks when global display units are changed + self.auto_update_units = True + self.hub.subscribe(self, GlobalDisplayUnitChanged, + handler=self._on_global_display_unit_changed) + self._update_units() + + @property + def hub(self): + return self.viewer.hub + def update_xy(self, x, y): self.x = np.asarray(x) self.y = np.asarray(y) @@ -493,24 +508,79 @@ def append_xy(self, x, y): self.x = np.append(self.x, x) self.y = np.append(self.y, y) + def _update_units(self): + if not self.auto_update_units: + return + if self.xunit is None: + self.set_x_unit() + if self.yunit is None: + self.set_y_unit() + + def set_x_unit(self, unit=None): + if unit is None: + if not hasattr(self.viewer.state, 'x_display_unit'): + return + unit = self.viewer.state.x_display_unit + unit = u.Unit(unit) + if self.xunit is not None: + x = (self.x * self.xunit).to_value(unit, u.spectral()) + self.xunit = unit + self.x = x + self.xunit = unit + + def set_y_unit(self, unit=None): + if unit is None: + if not hasattr(self.viewer.state, 'y_display_unit'): + return + unit = self.viewer.state.y_display_unit + unit = u.Unit(unit) + if self.yunit is not None: + self.y = (self.y * self.yunit).to_value(unit) + self.yunit = unit + + def _on_global_display_unit_changed(self, msg): + if not self.auto_update_units: + return + if self.viewer.__class__.__name__ in ['SpecvizProfileView', 'CubevizProfileView']: + axis_map = {'spectral': 'x', 'flux': 'y'} + elif self.viewer.__class__.__name__ == 'MosvizProfile2DView': + axis_map = {'spectral': 'x'} + else: + return + axis = axis_map.get(msg.axis, None) + if axis is not None: + getattr(self, f'set_{axis}_unit')(msg.unit) + def clear(self): self.update_xy([], []) +class LinesAutoUnit(PluginMark, Lines, HubListener): + def __init__(self, viewer, *args, **kwargs): + self.viewer = viewer + super().__init__(*args, **kwargs) + + class PluginLine(Lines, PluginMark, HubListener): def __init__(self, viewer, x=[], y=[], **kwargs): + self.viewer = viewer # color is same blue as import button super().__init__(x=x, y=y, colors=["#007BA1"], scales=viewer.scales, **kwargs) class PluginScatter(Scatter, PluginMark, HubListener): def __init__(self, viewer, x=[], y=[], **kwargs): + self.viewer = viewer # color is same blue as import button super().__init__(x=x, y=y, colors=["#007BA1"], scales=viewer.scales, **kwargs) class LineAnalysisContinuum(PluginLine): - pass + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + # units do not need to be updated because the plugin itself reruns + # the computation and automatically changes the arrays themselves + self.auto_update_units = False class LineAnalysisContinuumCenter(LineAnalysisContinuum): @@ -529,9 +599,9 @@ class LineAnalysisContinuumRight(LineAnalysisContinuumLeft): pass -class LineUncertainties(Lines): - def __init__(self, **kwargs): - super().__init__(**kwargs) +class LineUncertainties(LinesAutoUnit): + def __init__(self, viewer, *args, **kwargs): + super().__init__(viewer, *args, **kwargs) class ScatterMask(Scatter): From e19b25c3997f0b7f4bb93f0e63fa301b45c0848c Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Thu, 13 Apr 2023 15:22:52 -0400 Subject: [PATCH 08/42] display units: fix failing tests (#2132) * fix error raised when spectrum uncertainty is None * fix RTD build failure because of missing mixin available in import * fix test setting display unit now that um is preferred to micron * add disabled unit conversion plugin to mosviz * avoid unit-conversion error in cubeviz tests * bump versions of glue/glue-jupyter * fix deg intialization in cubeviz slice plugin * add LinesAutoUnit to __all__ so RTD can find it * add use_display_units kwarg to get_spectral_regions * fix setting display units for unitless data * Apply suggestions from code review Co-authored-by: P. L. Lim <2090236+pllim@users.noreply.github.com> --- jdaviz/app.py | 3 ++- jdaviz/configs/cubeviz/plugins/slice/slice.py | 3 ++- jdaviz/configs/mosviz/mosviz.yaml | 1 + jdaviz/configs/specviz/helper.py | 10 ++++++++-- jdaviz/configs/specviz/plugins/viewers.py | 9 ++++++--- jdaviz/configs/specviz/tests/test_helper.py | 16 ++++++++++------ jdaviz/core/helpers.py | 9 ++++++++- jdaviz/core/marks.py | 2 +- jdaviz/core/template_mixin.py | 1 + 9 files changed, 39 insertions(+), 15 deletions(-) diff --git a/jdaviz/app.py b/jdaviz/app.py index 348b34ef36..f607a990dc 100644 --- a/jdaviz/app.py +++ b/jdaviz/app.py @@ -894,7 +894,8 @@ def get_subsets(self, subset_name=None, spectral_only=False, simplify_spectral : bool Return a composite spectral subset collapsed to a simplified SpectralRegion. use_display_units: bool, optional - Whether to convert to the display units defined in the plugin. + Whether to convert to the display units defined in the + :ref:`Unit Conversion ` plugin. Returns ------- diff --git a/jdaviz/configs/cubeviz/plugins/slice/slice.py b/jdaviz/configs/cubeviz/plugins/slice/slice.py index 57026f9d63..04ef23a59e 100644 --- a/jdaviz/configs/cubeviz/plugins/slice/slice.py +++ b/jdaviz/configs/cubeviz/plugins/slice/slice.py @@ -171,7 +171,8 @@ def _on_global_display_unit_changed(self, msg): return prev_unit = self.wavelength_unit self.wavelength_unit = msg.unit.to_string() - if self._x_all is None or prev_unit == '': + # original unit during init can be blank or deg (before axis is set correctly) + if self._x_all is None or prev_unit in ('deg', ''): return self._update_data((self._x_all * u.Unit(prev_unit)).to(msg.unit, u.spectral())) diff --git a/jdaviz/configs/mosviz/mosviz.yaml b/jdaviz/configs/mosviz/mosviz.yaml index b5a846350c..98f842b08b 100644 --- a/jdaviz/configs/mosviz/mosviz.yaml +++ b/jdaviz/configs/mosviz/mosviz.yaml @@ -22,6 +22,7 @@ tray: - g-gaussian-smooth - g-slit-overlay - g-model-fitting + - g-unit-conversion - g-line-list - specviz-line-analysis - g-export-plot diff --git a/jdaviz/configs/specviz/helper.py b/jdaviz/configs/specviz/helper.py index 7692ec04be..e5252ee985 100644 --- a/jdaviz/configs/specviz/helper.py +++ b/jdaviz/configs/specviz/helper.py @@ -128,18 +128,24 @@ def get_spectra(self, data_label=None, subset_to_apply=None, apply_slider_redshi return output_spectra - def get_spectral_regions(self): + def get_spectral_regions(self, use_display_units=False): """ A simple wrapper around the app-level call to retrieve only spectral subsets, which are now returned as SpectralRegions by default. + Parameters + ---------- + use_display_units : bool, optional + Whether to convert to the display units defined in the + :ref:`Unit Conversion ` plugin. + Returns ------- spec_regs : dict Mapping from the names of the subsets to the subsets expressed as `specutils.SpectralRegion` objects. """ - return self.app.get_subsets(spectral_only=True) + return self.app.get_subsets(spectral_only=True, use_display_units=use_display_units) def x_limits(self, x_min=None, x_max=None): """Sets the limits of the x-axis diff --git a/jdaviz/configs/specviz/plugins/viewers.py b/jdaviz/configs/specviz/plugins/viewers.py index a917fb4578..e1de39a615 100644 --- a/jdaviz/configs/specviz/plugins/viewers.py +++ b/jdaviz/configs/specviz/plugins/viewers.py @@ -361,8 +361,10 @@ def add_data(self, data, color=None, alpha=None, **layer_state): result = super().add_data(data, color, alpha, **layer_state) if reset_plot_axes: - self.state.x_display_unit = data.get_component(self.state.x_att.label).units - self.state.y_display_unit = data.get_component("flux").units + x_units = data.get_component(self.state.x_att.label).units + y_units = data.get_component("flux").units + self.state.x_display_unit = x_units if len(x_units) else None + self.state.y_display_unit = y_units if len(y_units) else None self.set_plot_axes() self._plot_uncertainties() @@ -489,7 +491,8 @@ def _plot_uncertainties(self): def set_plot_axes(self): # Set axes labels for the spectrum viewer flux_unit_type = "Flux density" - x_unit = u.Unit(self.state.x_display_unit) + x_disp_unit = self.state.x_display_unit + x_unit = u.Unit(x_disp_unit) if x_disp_unit else u.dimensionless_unscaled if x_unit.is_equivalent(u.m): spectral_axis_unit_type = "Wavelength" elif x_unit.is_equivalent(u.Hz): diff --git a/jdaviz/configs/specviz/tests/test_helper.py b/jdaviz/configs/specviz/tests/test_helper.py index f3041ab734..53e8122dbd 100644 --- a/jdaviz/configs/specviz/tests/test_helper.py +++ b/jdaviz/configs/specviz/tests/test_helper.py @@ -293,17 +293,21 @@ def test_get_spectral_regions_unit_conversion(specviz_helper, spectrum1d): assert label_mouseover.icon == '' # Convert the wavelength axis to micron - new_spectral_axis = "micron" - spec_viewer.state.x_display_unit = new_spectral_axis - spec_viewer.set_plot_axes() + new_spectral_axis = "um" + specviz_helper.plugins['Unit Conversion'].spectral_unit = new_spectral_axis spec_viewer.apply_roi(XRangeROI(0.6, 0.7)) # Retrieve the Subset - subsets = specviz_helper.get_spectral_regions() + subsets = specviz_helper.get_spectral_regions(use_display_units=False) + reg = subsets.get('Subset 1') + assert reg.lower.unit == u.Angstrom + assert reg.upper.unit == u.Angstrom + + subsets = specviz_helper.get_spectral_regions(use_display_units=True) reg = subsets.get('Subset 1') - assert reg.lower.unit == u.micron - assert reg.upper.unit == u.micron + assert reg.lower.unit == u.um + assert reg.upper.unit == u.um # Coordinates info panel should show new unit label_mouseover._viewer_mouse_event(spec_viewer, diff --git a/jdaviz/core/helpers.py b/jdaviz/core/helpers.py index 60277ee090..8939b0d876 100644 --- a/jdaviz/core/helpers.py +++ b/jdaviz/core/helpers.py @@ -418,13 +418,20 @@ def _handle_display_units(data, use_display_units): spectral_unit = self.app._get_display_unit('spectral') if not spectral_unit: return data + if self.app.config == 'cubeviz' and spectral_unit == 'deg': + # this happens before the correct axis is set for the spectrum-viewer + # and would result in a unit-conversion error if attempting to convert + # to the display units. This should only ever be temporary during + # app intialization. + return data flux_unit = self.app._get_display_unit('flux') # TODO: any other attributes (meta, wcs, etc)? # TODO: implement uncertainty.to upstream + new_uncert = data.uncertainty.__class__(data.uncertainty.quantity.to(flux_unit)) if data.uncertainty is not None else None # noqa data = Spectrum1D(spectral_axis=data.spectral_axis.to(spectral_unit, u.spectral()), flux=data.flux.to(flux_unit), - uncertainty=data.uncertainty.__class__(data.uncertainty.quantity.to(flux_unit))) # noqa + uncertainty=new_uncert) else: # pragma: nocover raise NotImplementedError(f"converting {data.__class__.__name__} to display units is not supported") # noqa return data diff --git a/jdaviz/core/marks.py b/jdaviz/core/marks.py index 08ffba76b9..95b29843f0 100644 --- a/jdaviz/core/marks.py +++ b/jdaviz/core/marks.py @@ -14,7 +14,7 @@ __all__ = ['OffscreenLinesMarks', 'BaseSpectrumVerticalLine', 'SpectralLine', 'SliceIndicatorMarks', 'ShadowMixin', 'ShadowLine', 'ShadowLabelFixedY', - 'PluginMark', 'PluginLine', 'PluginScatter', + 'PluginMark', 'LinesAutoUnit', 'PluginLine', 'PluginScatter', 'LineAnalysisContinuum', 'LineAnalysisContinuumCenter', 'LineAnalysisContinuumLeft', 'LineAnalysisContinuumRight', 'LineUncertainties', 'ScatterMask', 'SelectedSpaxel', 'MarkersMark'] diff --git a/jdaviz/core/template_mixin.py b/jdaviz/core/template_mixin.py index 4092724239..ded3170d26 100644 --- a/jdaviz/core/template_mixin.py +++ b/jdaviz/core/template_mixin.py @@ -28,6 +28,7 @@ __all__ = ['show_widget', 'TemplateMixin', 'PluginTemplateMixin', + 'ViewerPropertiesMixin', 'BasePluginComponent', 'SelectPluginComponent', 'UnitSelectPluginComponent', 'PluginSubcomponent', 'SubsetSelect', 'SpatialSubsetSelectMixin', 'SpectralSubsetSelectMixin', From 9e364bc467b2daa5cbfd7a3f824bff14c6e190c9 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Mon, 17 Apr 2023 16:04:25 -0400 Subject: [PATCH 09/42] Display units: line lists (#2148) * BaseSpectrumVerticalLine to inherit unit-support from PluginMark * convert units on internal rest value * code cleanup --- .../plugins/line_analysis/line_analysis.py | 4 +- .../unit_conversion/unit_conversion.py | 3 + jdaviz/core/marks.py | 173 +++++++++--------- 3 files changed, 91 insertions(+), 89 deletions(-) diff --git a/jdaviz/configs/specviz/plugins/line_analysis/line_analysis.py b/jdaviz/configs/specviz/plugins/line_analysis/line_analysis.py index 3b179c1639..f7be264351 100644 --- a/jdaviz/configs/specviz/plugins/line_analysis/line_analysis.py +++ b/jdaviz/configs/specviz/plugins/line_analysis/line_analysis.py @@ -530,8 +530,8 @@ def _uncertainty(result): def _compute_redshift_for_selected_line(self): index = self.line_items.index(self.selected_line) line_mark = self.line_marks[index] - rest_value = (line_mark.rest_value * line_mark._x_unit).to_value(u.AA, - equivalencies=u.spectral()) + rest_value = (line_mark.rest_value * line_mark.xunit).to_value(u.AA, + equivalencies=u.spectral()) return (self.results_centroid - rest_value) / rest_value @observe('sync_identify') diff --git a/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.py b/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.py index 990646f3e0..6e10407ea5 100644 --- a/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.py +++ b/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.py @@ -83,6 +83,9 @@ def user_api(self): def _on_glue_x_display_unit_changed(self, x_unit): if x_unit is None: return + if x_unit == 'deg' and self.app.config == 'cubeviz': + # original unit during init can be deg (before axis is set correctly) + return self.spectrum_viewer.set_plot_axes() if x_unit != self.spectral_unit.selected: x_unit = _valid_glue_display_unit(x_unit, self.spectrum_viewer, 'x') diff --git a/jdaviz/core/marks.py b/jdaviz/core/marks.py index 95b29843f0..8d533d0f44 100644 --- a/jdaviz/core/marks.py +++ b/jdaviz/core/marks.py @@ -59,11 +59,75 @@ def _update_counts(self, *args): self.right.text = [f'{oob_right} \u25b6' if oob_right > 0 else ''] -class BaseSpectrumVerticalLine(Lines, HubListener): +class PluginMark(): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.xunit = None + self.yunit = None + # whether to update existing marks when global display units are changed + self.auto_update_units = True + self.hub.subscribe(self, GlobalDisplayUnitChanged, + handler=self._on_global_display_unit_changed) + + if self.xunit is None: + self.set_x_unit() + if self.yunit is None: + self.set_y_unit() + + @property + def hub(self): + return self.viewer.hub + + def update_xy(self, x, y): + self.x = np.asarray(x) + self.y = np.asarray(y) + + def append_xy(self, x, y): + self.x = np.append(self.x, x) + self.y = np.append(self.y, y) + + def set_x_unit(self, unit=None): + if unit is None: + if not hasattr(self.viewer.state, 'x_display_unit'): + return + unit = self.viewer.state.x_display_unit + unit = u.Unit(unit) + if self.xunit is not None: + x = (self.x * self.xunit).to_value(unit, u.spectral()) + self.xunit = unit + self.x = x + self.xunit = unit + + def set_y_unit(self, unit=None): + if unit is None: + if not hasattr(self.viewer.state, 'y_display_unit'): + return + unit = self.viewer.state.y_display_unit + unit = u.Unit(unit) + if self.yunit is not None: + self.y = (self.y * self.yunit).to_value(unit) + self.yunit = unit + + def _on_global_display_unit_changed(self, msg): + if not self.auto_update_units: + return + if self.viewer.__class__.__name__ in ['SpecvizProfileView', 'CubevizProfileView']: + axis_map = {'spectral': 'x', 'flux': 'y'} + elif self.viewer.__class__.__name__ == 'MosvizProfile2DView': + axis_map = {'spectral': 'x'} + else: + return + axis = axis_map.get(msg.axis, None) + if axis is not None: + getattr(self, f'set_{axis}_unit')(msg.unit) + + def clear(self): + self.update_xy([], []) + + +class BaseSpectrumVerticalLine(Lines, PluginMark, HubListener): def __init__(self, viewer, x, **kwargs): - # we'll store the current units so that we can automatically update the - # positioning on a change to the x-units - self._x_unit = viewer.state.reference_data.get_object(cls=Spectrum1D).spectral_axis.unit + self.viewer = viewer # the location of the marker will need to update automatically if the # underlying data changes (through a unit conversion, for example) @@ -84,14 +148,14 @@ def _update_reference_data(self, reference_data): def _update_data(self, x_all): # the x-units may have changed. We want to convert the internal self.x - # from self._x_unit to the new units (x_all.unit) + # from self.xunit to the new units (x_all.unit) new_unit = x_all.unit - if new_unit == self._x_unit: + if new_unit == self.xunit: return - old_quant = self.x[0]*self._x_unit + old_quant = self.x[0]*self.xunit x = old_quant.to_value(x_all.unit, equivalencies=u.spectral()) self.x = [x, x] - self._x_unit = new_unit + self.xunit = new_unit class SpectralLine(BaseSpectrumVerticalLine): @@ -111,7 +175,7 @@ def __init__(self, viewer, rest_value, redshift=0, name=None, **kwargs): # setting redshift will set self.x and enable the obs_value property, # but to do that we need x_unit set first (would normally be assigned # in the super init) - self._x_unit = viewer.state.reference_data.get_object(cls=Spectrum1D).spectral_axis.unit + self.xunit = u.Unit(viewer.state.x_display_unit) self.redshift = redshift viewer.session.hub.subscribe(self, LineIdentifyMessage, @@ -132,6 +196,11 @@ def rest_value(self): def obs_value(self): return self.x[0] + def set_x_unit(self, unit=None): + prev_unit = self.xunit + super().set_x_unit(unit=unit) + self._rest_value = (self._rest_value * prev_unit).to_value(unit, u.spectral()) + @property def redshift(self): return self._redshift @@ -139,16 +208,16 @@ def redshift(self): @redshift.setter def redshift(self, redshift): self._redshift = redshift - if str(self._x_unit.physical_type) == 'length': + if str(self.xunit.physical_type) == 'length': obs_value = self._rest_value*(1+redshift) - elif str(self._x_unit.physical_type) == 'frequency': + elif str(self.xunit.physical_type) == 'frequency': obs_value = self._rest_value/(1+redshift) else: # catch all for anything else (wavenumber, energy, etc) - rest_angstrom = (self._rest_value*self._x_unit).to_value(u.Angstrom, - equivalencies=u.spectral()) + rest_angstrom = (self._rest_value*self.xunit).to_value(u.Angstrom, + equivalencies=u.spectral()) obs_angstrom = rest_angstrom*(1+redshift) - obs_value = (obs_angstrom*u.Angstrom).to_value(self._x_unit, + obs_value = (obs_angstrom*u.Angstrom).to_value(self.xunit, equivalencies=u.spectral()) self.x = [obs_value, obs_value] @@ -169,14 +238,14 @@ def _process_identify_change(self, msg): def _update_data(self, x_all): new_unit = x_all.unit - if new_unit == self._x_unit: + if new_unit == self.xunit: return - old_quant = self._rest_value*self._x_unit + old_quant = self._rest_value*self.xunit self._rest_value = old_quant.to_value(new_unit, equivalencies=u.spectral()) # re-compute self.x from current redshift (instead of converting that as well) self.redshift = self._redshift - self._x_unit = new_unit + self.xunit = new_unit class SliceIndicatorMarks(BaseSpectrumVerticalLine, HubListener): @@ -485,76 +554,6 @@ def _on_shadowing_changed(self, change): self._update_align() -class PluginMark(): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.xunit = None - self.yunit = None - # whether to update existing marks when global display units are changed - self.auto_update_units = True - self.hub.subscribe(self, GlobalDisplayUnitChanged, - handler=self._on_global_display_unit_changed) - self._update_units() - - @property - def hub(self): - return self.viewer.hub - - def update_xy(self, x, y): - self.x = np.asarray(x) - self.y = np.asarray(y) - - def append_xy(self, x, y): - self.x = np.append(self.x, x) - self.y = np.append(self.y, y) - - def _update_units(self): - if not self.auto_update_units: - return - if self.xunit is None: - self.set_x_unit() - if self.yunit is None: - self.set_y_unit() - - def set_x_unit(self, unit=None): - if unit is None: - if not hasattr(self.viewer.state, 'x_display_unit'): - return - unit = self.viewer.state.x_display_unit - unit = u.Unit(unit) - if self.xunit is not None: - x = (self.x * self.xunit).to_value(unit, u.spectral()) - self.xunit = unit - self.x = x - self.xunit = unit - - def set_y_unit(self, unit=None): - if unit is None: - if not hasattr(self.viewer.state, 'y_display_unit'): - return - unit = self.viewer.state.y_display_unit - unit = u.Unit(unit) - if self.yunit is not None: - self.y = (self.y * self.yunit).to_value(unit) - self.yunit = unit - - def _on_global_display_unit_changed(self, msg): - if not self.auto_update_units: - return - if self.viewer.__class__.__name__ in ['SpecvizProfileView', 'CubevizProfileView']: - axis_map = {'spectral': 'x', 'flux': 'y'} - elif self.viewer.__class__.__name__ == 'MosvizProfile2DView': - axis_map = {'spectral': 'x'} - else: - return - axis = axis_map.get(msg.axis, None) - if axis is not None: - getattr(self, f'set_{axis}_unit')(msg.unit) - - def clear(self): - self.update_xy([], []) - - class LinesAutoUnit(PluginMark, Lines, HubListener): def __init__(self, viewer, *args, **kwargs): self.viewer = viewer From b9de21e712bdc18afc7362579379b1fddeb0a436 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Thu, 4 May 2023 09:19:41 -0400 Subject: [PATCH 10/42] remove unit conversion plugin from all bug specviz * for initial implementation - eventually we'll want to implement across all plugins/viewers --- jdaviz/configs/cubeviz/cubeviz.yaml | 1 - jdaviz/configs/mosviz/mosviz.yaml | 1 - jdaviz/configs/specviz2d/specviz2d.yaml | 1 - 3 files changed, 3 deletions(-) diff --git a/jdaviz/configs/cubeviz/cubeviz.yaml b/jdaviz/configs/cubeviz/cubeviz.yaml index 4903187b53..139e499f04 100644 --- a/jdaviz/configs/cubeviz/cubeviz.yaml +++ b/jdaviz/configs/cubeviz/cubeviz.yaml @@ -25,7 +25,6 @@ tray: - g-gaussian-smooth - g-collapse - g-model-fitting - - g-unit-conversion - g-line-list - specviz-line-analysis - cubeviz-moment-maps diff --git a/jdaviz/configs/mosviz/mosviz.yaml b/jdaviz/configs/mosviz/mosviz.yaml index 98f842b08b..b5a846350c 100644 --- a/jdaviz/configs/mosviz/mosviz.yaml +++ b/jdaviz/configs/mosviz/mosviz.yaml @@ -22,7 +22,6 @@ tray: - g-gaussian-smooth - g-slit-overlay - g-model-fitting - - g-unit-conversion - g-line-list - specviz-line-analysis - g-export-plot diff --git a/jdaviz/configs/specviz2d/specviz2d.yaml b/jdaviz/configs/specviz2d/specviz2d.yaml index d62dac9ed9..6126211888 100644 --- a/jdaviz/configs/specviz2d/specviz2d.yaml +++ b/jdaviz/configs/specviz2d/specviz2d.yaml @@ -21,7 +21,6 @@ tray: - spectral-extraction - g-gaussian-smooth - g-model-fitting - - g-unit-conversion - g-line-list - specviz-line-analysis - g-export-plot From d942d0948f584554f879e884270615019d9301dc Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Thu, 4 May 2023 15:22:32 -0400 Subject: [PATCH 11/42] get_display_unit fallback for configs without unit conversion plugin --- jdaviz/app.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/jdaviz/app.py b/jdaviz/app.py index f607a990dc..69ba093c3d 100644 --- a/jdaviz/app.py +++ b/jdaviz/app.py @@ -1147,7 +1147,15 @@ def get_sub_regions(self, subset_state, simplify_spectral=True, use_display_unit def _get_display_unit(self, axis): if self._jdaviz_helper is None or self._jdaviz_helper.plugins.get('Unit Conversion') is None: # noqa - raise ValueError("cannot detect unit conversion plugin") + # fallback on native units (unit conversion is not enabled) + if axis == 'spectral': + sv = self.get_viewer(self._jdaviz_helper._default_spectrum_viewer_reference_name) + return sv.data()[0].spectral_axis.unit + elif axis == 'flux': + sv = self.get_viewer(self._jdaviz_helper._default_spectrum_viewer_reference_name) + return sv.data()[0].flux.unit + else: + raise ValueError(f"could not find units for axis='{axis}'") try: return getattr(self._jdaviz_helper.plugins.get('Unit Conversion')._obj, f'{axis}_unit_selected') From bff781b158ec866b1273a6d4c8d8cbb88befac5e Mon Sep 17 00:00:00 2001 From: Ricky O'Steen Date: Mon, 15 May 2023 16:12:52 -0400 Subject: [PATCH 12/42] Update glue-core dependency --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7d0acb9155..11508b190a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ dependencies = [ "traitlets>=5.0.5", "bqplot>=0.12.37", "bqplot-image-gl>=1.4.11", - "glue-core>=1.10.0", + "glue-core>=1.10.1", "glue-jupyter>=0.16.3", "echo>=0.5.0", "ipykernel>=6.19.4", From 15e755d4c2b767de17f85f265db80438f4cafe95 Mon Sep 17 00:00:00 2001 From: Ricky O'Steen <39831871+rosteen@users.noreply.github.com> Date: Tue, 16 May 2023 10:29:45 -0400 Subject: [PATCH 13/42] Update Subset Tools plugin to use display units (#2195) * bump glue-core to necessary version for display units * cubeviz/slice plugin unit conversion support (we might want to generalize some of this logic more into the mark's _update_data when adding support for spectral lines as well) * display units: fix failing tests (#2132) * fix error raised when spectrum uncertainty is None * fix RTD build failure because of missing mixin available in import * fix test setting display unit now that um is preferred to micron * add disabled unit conversion plugin to mosviz * avoid unit-conversion error in cubeviz tests * bump versions of glue/glue-jupyter * fix deg intialization in cubeviz slice plugin * add LinesAutoUnit to __all__ so RTD can find it * add use_display_units kwarg to get_spectral_regions * fix setting display units for unitless data * Apply suggestions from code review Co-authored-by: P. L. Lim <2090236+pllim@users.noreply.github.com> * remove unit conversion plugin from all bug specviz * for initial implementation - eventually we'll want to implement across all plugins/viewers * Working on unit conversion handling in subset plugin * Get subset updating working in non-default units * Add changelog * Update jdaviz/configs/default/plugins/subset_plugin/subset_plugin.vue Co-authored-by: Kyle Conroy --------- Co-authored-by: Kyle Conroy Co-authored-by: P. L. Lim <2090236+pllim@users.noreply.github.com> --- CHANGES.rst | 2 + .../plugins/subset_plugin/subset_plugin.py | 37 ++++++++++++++++--- .../plugins/subset_plugin/subset_plugin.vue | 1 + pyproject.toml | 2 +- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 1ec8c85d70..41376347f2 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -14,6 +14,8 @@ New Features - Histogram showing image values in stretch limits section of plot options plugin. [#2153] +- Subset Plugin now respects the chosen display unit after using Unit Conversion. [#2195] + Cubeviz ^^^^^^^ diff --git a/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py b/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py index 3af7db91f5..9bc7364f0d 100644 --- a/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py +++ b/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py @@ -1,4 +1,5 @@ import numpy as np +import astropy.units as u from glue.core.message import EditSubsetMessage, SubsetUpdateMessage from glue.core.edit_subset_mode import (AndMode, AndNotMode, OrMode, ReplaceMode, XorMode) @@ -7,7 +8,7 @@ from glue_jupyter.widgets.subset_mode_vuetify import SelectionModeMenu from traitlets import Any, List, Unicode, Bool, observe -from jdaviz.core.events import SnackbarMessage +from jdaviz.core.events import SnackbarMessage, GlobalDisplayUnitChanged from jdaviz.core.registries import tray_registry from jdaviz.core.template_mixin import PluginTemplateMixin, DatasetSelectMixin, SubsetSelect @@ -52,12 +53,15 @@ def __init__(self, *args, **kwargs): handler=self._sync_selected_from_state) self.session.hub.subscribe(self, SubsetUpdateMessage, handler=self._on_subset_update) + self.session.hub.subscribe(self, GlobalDisplayUnitChanged, + handler=self._on_display_unit_changed) self.subset_select = SubsetSelect(self, 'subset_items', 'subset_selected', default_text="Create New") self.subset_states = [] + self.spectral_display_unit = None def _sync_selected_from_state(self, *args): if not hasattr(self, 'subset_select'): @@ -127,7 +131,8 @@ def _unpack_get_subsets_for_ui(self): ------- """ - subset_information = self.app.get_subsets(self.subset_selected, simplify_spectral=False) + subset_information = self.app.get_subsets(self.subset_selected, simplify_spectral=False, + use_display_units=True) _around_decimals = 6 # Avoid 30 degrees from coming back as 29.999999999999996 if not subset_information: return @@ -175,10 +180,12 @@ def _unpack_get_subsets_for_ui(self): 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}] + lo = spec['region'].lower + hi = spec['region'].upper + subset_definition = [{"name": "Lower bound", "att": "lo", "value": lo.value, + "orig": lo.value, "unit": str(lo.unit)}, + {"name": "Upper bound", "att": "hi", "value": hi.value, + "orig": hi.value, "unit": str(hi.unit)}] subset_type = "Range" if len(subset_definition) > 0: # Note: .append() does not work for List traitlet. @@ -199,6 +206,13 @@ def _get_subset_definition(self, *args): self._unpack_get_subsets_for_ui() + def _on_display_unit_changed(self, msg): + # We only care about the spectral units, since flux units don't affect spectral subsets + if msg.axis == "spectral": + self.spectral_display_unit = msg.unit + if self.subset_selected != self.subset_select.default_text: + self._get_subset_definition(self.subset_selected) + def vue_update_subset(self, *args): for index, sub in enumerate(self.subset_definitions): sub_states = self.subset_states[index] @@ -207,6 +221,17 @@ def vue_update_subset(self, *args): d_val = np.radians(d_att["value"]) else: d_val = float(d_att["value"]) + + # Convert from display unit to original unit if necessary + if self.subset_types[index] == "Range": + if self.spectral_display_unit is not None: + x_att = sub_states.att + base_units = self.app.data_collection[0].get_component(x_att).units + if self.spectral_display_unit != base_units: + d_val = d_val*u.Unit(self.spectral_display_unit) + d_val = d_val.to(u.Unit(base_units)) + d_val = d_val.value + if float(d_att["orig"]) != d_val: if self.subset_types[index] == "Range": setattr(sub_states, d_att["att"], d_val) diff --git a/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.vue b/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.vue index 354c337611..f833ce7644 100644 --- a/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.vue +++ b/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.vue @@ -59,6 +59,7 @@ v-model.number="item.value" type="number" :disabled="!is_editable" + :suffix="item.unit.replace('Angstrom', 'A')" > diff --git a/pyproject.toml b/pyproject.toml index 11508b190a..7d0acb9155 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ dependencies = [ "traitlets>=5.0.5", "bqplot>=0.12.37", "bqplot-image-gl>=1.4.11", - "glue-core>=1.10.1", + "glue-core>=1.10.0", "glue-jupyter>=0.16.3", "echo>=0.5.0", "ipykernel>=6.19.4", From 2b2b6c3467e0feabe9a27378a7bf6786b5bfe4ab Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Fri, 26 May 2023 13:50:38 -0400 Subject: [PATCH 14/42] allow downstream apps to set what classes are considered native marks --- jdaviz/configs/default/plugins/viewers.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/jdaviz/configs/default/plugins/viewers.py b/jdaviz/configs/default/plugins/viewers.py index de2660590f..e51997c901 100644 --- a/jdaviz/configs/default/plugins/viewers.py +++ b/jdaviz/configs/default/plugins/viewers.py @@ -22,6 +22,7 @@ class JdavizViewerMixin: toolbar = None tools_nested = [] _prev_limits = None + _native_mark_classnames = ('Lines', 'LinesGL') def __init__(self, *args, **kwargs): # NOTE: anything here most likely won't be called by viewers because of inheritance order @@ -35,14 +36,16 @@ def native_marks(self): """ Return all marks that are Lines/LinesGL objects (and not subclasses) """ - return [m for m in self.figure.marks if m.__class__.__name__ in ['Lines', 'LinesGL']] + return [m for m in self.figure.marks + if m.__class__.__name__ in self._native_mark_classnames] @property def custom_marks(self): """ Return all marks that are not Lines/LinesGL objects (but can be subclasses) """ - return [m for m in self.figure.marks if m.__class__.__name__ not in ['Lines', 'LinesGL']] + return [m for m in self.figure.marks + if m.__class__.__name__ not in self._native_mark_classnames] def _subscribe_to_layers_update(self): # subscribe to new layers From 2535c8712df648c9c08dbcfcebebd78cd358f17f Mon Sep 17 00:00:00 2001 From: Ricky O'Steen <39831871+rosteen@users.noreply.github.com> Date: Fri, 26 May 2023 13:59:10 -0400 Subject: [PATCH 15/42] Fix unit conversion for PluginMarks and y-limits (#2215) * Fix unit conversion for PluginMarks and y-limits * Only use equivalency if it's a spec viewer * Store wavelength unit on data update * Remove redundant line * Better check in marks --- jdaviz/app.py | 8 +++++++- jdaviz/configs/cubeviz/plugins/slice/slice.py | 4 +++- jdaviz/core/marks.py | 11 ++++++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/jdaviz/app.py b/jdaviz/app.py index 69ba093c3d..f518aa9f1d 100644 --- a/jdaviz/app.py +++ b/jdaviz/app.py @@ -102,9 +102,15 @@ def to_unit(self, data, cid, values, original_units, target_units): # as the original native units of the component in the data. if cid.label == "flux": spec = data.get_object(cls=Spectrum1D) - eqv = u.spectral_density(spec.spectral_axis) + if len(values) == 2: + # Need this for setting the y-limits + spec_limits = [spec.spectral_axis[0].value, spec.spectral_axis[-1].value] + eqv = u.spectral_density(spec_limits*spec.spectral_axis.unit) + else: + eqv = u.spectral_density(spec.spectral_axis) else: # spectral axis eqv = u.spectral() + return (values * u.Unit(original_units)).to_value(u.Unit(target_units), equivalencies=eqv) diff --git a/jdaviz/configs/cubeviz/plugins/slice/slice.py b/jdaviz/configs/cubeviz/plugins/slice/slice.py index 04ef23a59e..9eb559b028 100644 --- a/jdaviz/configs/cubeviz/plugins/slice/slice.py +++ b/jdaviz/configs/cubeviz/plugins/slice/slice.py @@ -145,6 +145,9 @@ def _update_data(self, x_all): # leave in the pre-init state and don't update the wavelength/slice return + # Also update unit when data is updated + self.wavelength_unit = x_all.unit.to_string() + # force wavelength to update from the current slider value self._on_slider_updated({'new': self.slice}) @@ -170,7 +173,6 @@ def _on_global_display_unit_changed(self, msg): if msg.axis != 'spectral': return prev_unit = self.wavelength_unit - self.wavelength_unit = msg.unit.to_string() # original unit during init can be blank or deg (before axis is set correctly) if self._x_all is None or prev_unit in ('deg', ''): return diff --git a/jdaviz/core/marks.py b/jdaviz/core/marks.py index 8d533d0f44..9eb9e8f16c 100644 --- a/jdaviz/core/marks.py +++ b/jdaviz/core/marks.py @@ -104,8 +104,17 @@ def set_y_unit(self, unit=None): return unit = self.viewer.state.y_display_unit unit = u.Unit(unit) + if self.yunit is not None: - self.y = (self.y * self.yunit).to_value(unit) + if self.viewer.default_class is Spectrum1D: + spec = self.viewer.state.reference_data.get_object(cls=Spectrum1D) + eqv = u.spectral_density(spec.spectral_axis) + y = (self.y * self.yunit).to_value(unit, equivalencies=eqv) + else: + y = (self.y * self.yunit).to_value(unit) + self.yunit = unit + self.y = y + self.yunit = unit def _on_global_display_unit_changed(self, msg): From d86fd9a792f8abdb1062fe606fbbb4322f2cbab7 Mon Sep 17 00:00:00 2001 From: Jesse Averbukh Date: Tue, 30 May 2023 11:51:36 -0400 Subject: [PATCH 16/42] Replace subset_to_apply in docs where possible (#2223) --- docs/cubeviz/export_data.rst | 2 +- docs/specviz/export_data.rst | 4 ++-- jdaviz/configs/cubeviz/helper.py | 4 ++-- notebooks/SpecvizExample.ipynb | 30 +++++++++++++++++++++--------- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/docs/cubeviz/export_data.rst b/docs/cubeviz/export_data.rst index 70ebac4c9d..248ad932f4 100644 --- a/docs/cubeviz/export_data.rst +++ b/docs/cubeviz/export_data.rst @@ -29,7 +29,7 @@ An example without accessing Specviz: .. code-block:: python subset1_spec1d = cubeviz.get_data(data_label=flux_data_label, - subset_to_apply="Subset 1", + spatial_subset="Subset 1", function="mean") Note that in the above example, the ``function`` keyword is used to tell Cubeviz diff --git a/docs/specviz/export_data.rst b/docs/specviz/export_data.rst index f87e74fca2..e6d322acb6 100644 --- a/docs/specviz/export_data.rst +++ b/docs/specviz/export_data.rst @@ -33,7 +33,7 @@ To extract a spectrum with a spectral subset applied: .. code-block:: python - specviz.get_data(subset_to_apply='Subset 1') + specviz.get_data(spectral_subset='Subset 1') In this case, the returned `specutils.Spectrum1D` object will have a ``mask`` attribute, where ``True`` corresponds to the region outside the selected subset @@ -42,7 +42,7 @@ spectrum containing only your subset by running: .. code-block:: python - spec = specviz.get_data(subset_to_apply='Subset 1') + spec = specviz.get_data(spectral_subset='Subset 1') subset_spec = Spectrum1D(flux=spec.flux[~spec.mask], spectral_axis=spec.spectral_axis[~spec.mask]) specviz.load_spectrum(subset_spec) diff --git a/jdaviz/configs/cubeviz/helper.py b/jdaviz/configs/cubeviz/helper.py index bb7a23e2e5..bb55df1918 100644 --- a/jdaviz/configs/cubeviz/helper.py +++ b/jdaviz/configs/cubeviz/helper.py @@ -123,8 +123,8 @@ def specviz(self): def get_data(self, data_label=None, spatial_subset=None, spectral_subset=None, function=None, cls=None): """ - Returns data with name equal to data_label of type cls with subsets applied from - subset_to_apply. + Returns data with name equal to ``data_label`` of type ``cls`` with subsets applied from + ``spatial_subset`` and/or ``spectral_subset`` using ``function`` if applicable. Parameters ---------- diff --git a/notebooks/SpecvizExample.ipynb b/notebooks/SpecvizExample.ipynb index 6fd1a9044b..5f671b4864 100644 --- a/notebooks/SpecvizExample.ipynb +++ b/notebooks/SpecvizExample.ipynb @@ -13,7 +13,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ "import warnings\n", @@ -37,7 +39,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ "from jdaviz import Specviz\n", @@ -63,7 +67,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ "specviz.show()" @@ -91,7 +97,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ "data_dir = tempfile.gettempdir()\n", @@ -116,11 +124,13 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ "# Returns a version of the whole spectra, with a mask applied\n", - "specviz.get_spectra(data_label='myfile', subset_to_apply='Subset 1')" + "specviz.get_data(data_label='myfile', spectral_subset='Subset 1')" ] }, { @@ -133,10 +143,12 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ - "specviz.app.get_subsets_from_viewer('spectrum-viewer')" + "specviz.get_spectra()" ] }, { @@ -281,7 +293,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.8" + "version": "3.9.16" } }, "nbformat": 4, From ccbe5468c307c3d1d5b86a697d5dcc1645cad446 Mon Sep 17 00:00:00 2001 From: Jesse Averbukh Date: Tue, 30 May 2023 11:51:36 -0400 Subject: [PATCH 17/42] Replace subset_to_apply in docs where possible (#2223) --- docs/cubeviz/export_data.rst | 2 +- docs/specviz/export_data.rst | 4 ++-- jdaviz/configs/cubeviz/helper.py | 4 ++-- notebooks/SpecvizExample.ipynb | 30 +++++++++++++++++++++--------- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/docs/cubeviz/export_data.rst b/docs/cubeviz/export_data.rst index 70ebac4c9d..248ad932f4 100644 --- a/docs/cubeviz/export_data.rst +++ b/docs/cubeviz/export_data.rst @@ -29,7 +29,7 @@ An example without accessing Specviz: .. code-block:: python subset1_spec1d = cubeviz.get_data(data_label=flux_data_label, - subset_to_apply="Subset 1", + spatial_subset="Subset 1", function="mean") Note that in the above example, the ``function`` keyword is used to tell Cubeviz diff --git a/docs/specviz/export_data.rst b/docs/specviz/export_data.rst index f87e74fca2..e6d322acb6 100644 --- a/docs/specviz/export_data.rst +++ b/docs/specviz/export_data.rst @@ -33,7 +33,7 @@ To extract a spectrum with a spectral subset applied: .. code-block:: python - specviz.get_data(subset_to_apply='Subset 1') + specviz.get_data(spectral_subset='Subset 1') In this case, the returned `specutils.Spectrum1D` object will have a ``mask`` attribute, where ``True`` corresponds to the region outside the selected subset @@ -42,7 +42,7 @@ spectrum containing only your subset by running: .. code-block:: python - spec = specviz.get_data(subset_to_apply='Subset 1') + spec = specviz.get_data(spectral_subset='Subset 1') subset_spec = Spectrum1D(flux=spec.flux[~spec.mask], spectral_axis=spec.spectral_axis[~spec.mask]) specviz.load_spectrum(subset_spec) diff --git a/jdaviz/configs/cubeviz/helper.py b/jdaviz/configs/cubeviz/helper.py index ebffc9d74c..f1d8ac4d8f 100644 --- a/jdaviz/configs/cubeviz/helper.py +++ b/jdaviz/configs/cubeviz/helper.py @@ -123,8 +123,8 @@ def specviz(self): def get_data(self, data_label=None, spatial_subset=None, spectral_subset=None, function=None, cls=None, use_display_units=False): """ - Returns data with name equal to data_label of type cls with subsets applied from - subset_to_apply. + Returns data with name equal to ``data_label`` of type ``cls`` with subsets applied from + ``spatial_subset`` and/or ``spectral_subset`` using ``function`` if applicable. Parameters ---------- diff --git a/notebooks/SpecvizExample.ipynb b/notebooks/SpecvizExample.ipynb index 6fd1a9044b..5f671b4864 100644 --- a/notebooks/SpecvizExample.ipynb +++ b/notebooks/SpecvizExample.ipynb @@ -13,7 +13,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ "import warnings\n", @@ -37,7 +39,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ "from jdaviz import Specviz\n", @@ -63,7 +67,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ "specviz.show()" @@ -91,7 +97,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ "data_dir = tempfile.gettempdir()\n", @@ -116,11 +124,13 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ "# Returns a version of the whole spectra, with a mask applied\n", - "specviz.get_spectra(data_label='myfile', subset_to_apply='Subset 1')" + "specviz.get_data(data_label='myfile', spectral_subset='Subset 1')" ] }, { @@ -133,10 +143,12 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ - "specviz.app.get_subsets_from_viewer('spectrum-viewer')" + "specviz.get_spectra()" ] }, { @@ -281,7 +293,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.8" + "version": "3.9.16" } }, "nbformat": 4, From 75d542e3a33e022fe5150843dc83d63c14603933 Mon Sep 17 00:00:00 2001 From: Ricky O'Steen Date: Tue, 30 May 2023 14:19:22 -0400 Subject: [PATCH 18/42] Avoid trying to convert units of empty marks arrays --- jdaviz/core/marks.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/jdaviz/core/marks.py b/jdaviz/core/marks.py index 9eb9e8f16c..ae2307ec13 100644 --- a/jdaviz/core/marks.py +++ b/jdaviz/core/marks.py @@ -92,7 +92,8 @@ def set_x_unit(self, unit=None): return unit = self.viewer.state.x_display_unit unit = u.Unit(unit) - if self.xunit is not None: + + if self.xunit is not None and not np.all([s == 0 for s in self.x.shape]): x = (self.x * self.xunit).to_value(unit, u.spectral()) self.xunit = unit self.x = x @@ -105,7 +106,7 @@ def set_y_unit(self, unit=None): unit = self.viewer.state.y_display_unit unit = u.Unit(unit) - if self.yunit is not None: + if self.yunit is not None and not np.all([s == 0 for s in self.y.shape]): if self.viewer.default_class is Spectrum1D: spec = self.viewer.state.reference_data.get_object(cls=Spectrum1D) eqv = u.spectral_density(spec.spectral_axis) From a937636f34873372c586ba95b8c42b190bedcf5a Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Fri, 26 May 2023 18:05:23 -0400 Subject: [PATCH 19/42] Add open method to automatically detect config and load data --- jdaviz/__init__.py | 1 + jdaviz/configs/__init__.py | 1 + jdaviz/core/data_formats.py | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/jdaviz/__init__.py b/jdaviz/__init__.py index 716678364f..fdddfd2e84 100644 --- a/jdaviz/__init__.py +++ b/jdaviz/__init__.py @@ -19,6 +19,7 @@ from jdaviz.configs.cubeviz import Cubeviz # noqa: F401 from jdaviz.configs.imviz import Imviz # noqa: F401 from jdaviz.utils import enable_hot_reloading # noqa: F401 +from jdaviz.core.data_formats import open # noqa: F401 # Clean up namespace. del os diff --git a/jdaviz/configs/__init__.py b/jdaviz/configs/__init__.py index 957cbeb45f..eb078d8c5c 100644 --- a/jdaviz/configs/__init__.py +++ b/jdaviz/configs/__init__.py @@ -1,5 +1,6 @@ from .cubeviz import * # noqa from .specviz import * # noqa +from .specviz2d import * # noqa from .default import * # noqa from .mosviz import * # noqa from .imviz import * # noqa diff --git a/jdaviz/core/data_formats.py b/jdaviz/core/data_formats.py index 7caa29253b..495cde7f22 100644 --- a/jdaviz/core/data_formats.py +++ b/jdaviz/core/data_formats.py @@ -11,6 +11,7 @@ from stdatamodels import asdf_in_fits from jdaviz.core.config import list_configurations +from jdaviz import configs as jdaviz_configs __all__ = [ 'guess_dimensionality', @@ -272,3 +273,35 @@ def identify_helper(filename, ext=1): return 'imviz' raise ValueError(f"No helper could be auto-identified for {filename}.") + + +def open(filename, show=True, **kwargs): + ''' + Automatically detect the correct configuration based on a given file, + load the data, and display the configuration + + Parameters + ---------- + filename : str (path-like) + Name for a local data file. + show : bool + Determines whether to immediately show the application + + Returns + ------- + Jdaviz App : jdaviz.app.Application + The application, configured based on the automatic config detection + ''' + helper_str = identify_helper(filename) + viz_class = getattr(jdaviz_configs, helper_str.capitalize()) + + viz_helper = viz_class() + if helper_str == "specviz": + viz_helper.load_spectrum(filename, **kwargs) + else: + viz_helper.load_data(filename, **kwargs) + + if show: + viz_helper.show() + + return viz_helper From cc513b30d8cc128e8150d7f85c6c8b4d444abe8a Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Fri, 26 May 2023 18:05:39 -0400 Subject: [PATCH 20/42] Update demo notebooks --- notebooks/CubevizExample.ipynb | 30 ++++++++----- notebooks/Specviz2dExample.ipynb | 26 ++---------- notebooks/SpecvizExample.ipynb | 73 ++++++++++---------------------- 3 files changed, 45 insertions(+), 84 deletions(-) diff --git a/notebooks/CubevizExample.ipynb b/notebooks/CubevizExample.ipynb index 73ef66238f..48e89d593c 100644 --- a/notebooks/CubevizExample.ipynb +++ b/notebooks/CubevizExample.ipynb @@ -29,14 +29,7 @@ "from photutils.aperture import CircularAperture\n", "from regions import PixCoord, CirclePixelRegion\n", "\n", - "from jdaviz import Cubeviz" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We create a Cubeviz instance and show it." + "import jdaviz" ] }, { @@ -80,9 +73,26 @@ "fn = \"jw02732-o004_t004_miri_ch1-shortmediumlong_s3d.fits\"\n", "result = Observations.download_file(f\"mast:JWST/product/{fn}\", local_path=f'{data_dir}/{fn}')\n", "\n", + "with warnings.catch_warnings():\n", + " warnings.simplefilter('ignore')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can ask Jdaviz to automatically load the data. Jdaviz will automatically detect Cubeviz as the most appropriate configuration" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ "with warnings.catch_warnings():\n", " warnings.simplefilter('ignore')\n", - " cubeviz.load_data(f'{data_dir}/{fn}')" + " cubeviz = jdaviz.open(f'{data_dir}/{fn}')" ] }, { @@ -225,7 +235,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.8" + "version": "3.10.10" } }, "nbformat": 4, diff --git a/notebooks/Specviz2dExample.ipynb b/notebooks/Specviz2dExample.ipynb index 32d7990d1a..69c56c9e60 100644 --- a/notebooks/Specviz2dExample.ipynb +++ b/notebooks/Specviz2dExample.ipynb @@ -28,27 +28,7 @@ "\n", "from astroquery.mast import Observations\n", "\n", - "from jdaviz import Specviz2d\n", - "\n", - "specviz2d = Specviz2d()" - ] - }, - { - "cell_type": "markdown", - "id": "0ed07713", - "metadata": {}, - "source": [ - "## Display Specviz2d" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "45802673", - "metadata": {}, - "outputs": [], - "source": [ - "specviz2d.show()" + "import jdaviz" ] }, { @@ -94,7 +74,7 @@ "metadata": {}, "outputs": [], "source": [ - "specviz2d.load_data(f'{data_dir}/{fn}')" + "jdaviz.open(f'{data_dir}/{fn}')" ] } ], @@ -114,7 +94,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.6" + "version": "3.10.10" } }, "nbformat": 4, diff --git a/notebooks/SpecvizExample.ipynb b/notebooks/SpecvizExample.ipynb index 5f671b4864..c21c221acf 100644 --- a/notebooks/SpecvizExample.ipynb +++ b/notebooks/SpecvizExample.ipynb @@ -26,60 +26,16 @@ "\n", "# Suppress warnings\n", "with warnings.catch_warnings():\n", - " warnings.simplefilter(\"ignore\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Create Specviz via Helper" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "from jdaviz import Specviz\n", - "specviz = Specviz()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Display Specviz\n", + " warnings.simplefilter(\"ignore\")\n", "\n", - "Note: you probably want to pick one of the three options below depending on preference. Also not the latter two will only work in JupyterLab, not the \"classic\" notebook interface." + "import jdaviz" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "This will show Specviz inline in the notebook" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "specviz.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Load a file to Specviz\n", + "## Download Data\n", "\n", "Here we download a JWST spectrum from [MAST](https://masttest.stsci.edu/) using `astroquery`. \n", "By default the downloaded file goes to your temp directory, and thus may eventually be \n", @@ -106,9 +62,24 @@ "#data_dir = \"/User/username/Data/\"\n", "\n", "fn = \"jw02732-o004_t004_miri_ch1-shortmediumlong_x1d.fits\"\n", - "result = Observations.download_file(f\"mast:JWST/product/{fn}\", local_path=f'{data_dir}/{fn}')\n", - "\n", - "specviz.load_spectrum(f'{data_dir}/{fn}', \"myfile\")" + "result = Observations.download_file(f\"mast:JWST/product/{fn}\", local_path=f'{data_dir}/{fn}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Open in Jdaviz\n", + "Jdaviz can automatically detect the correct configuration and load the data by using `jdaviz.open`. By default, jdaviz will display the application automatically. To only return the helper, set `show=False`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "specviz = jdaviz.open(f'{data_dir}/{fn}', show=True, data_label=\"myfile\")" ] }, { @@ -293,7 +264,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.16" + "version": "3.10.10" } }, "nbformat": 4, From 9b4d33562309a46c20adb1486bd20e8f36edd039 Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Fri, 26 May 2023 18:09:45 -0400 Subject: [PATCH 21/42] Codestyle --- jdaviz/core/data_formats.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdaviz/core/data_formats.py b/jdaviz/core/data_formats.py index 495cde7f22..9608aba215 100644 --- a/jdaviz/core/data_formats.py +++ b/jdaviz/core/data_formats.py @@ -300,7 +300,7 @@ def open(filename, show=True, **kwargs): viz_helper.load_spectrum(filename, **kwargs) else: viz_helper.load_data(filename, **kwargs) - + if show: viz_helper.show() From 66c7f1a2f692d418b012a99914c73208e6afcf1f Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Tue, 30 May 2023 17:04:04 -0400 Subject: [PATCH 22/42] Add autoconfig test coverage --- jdaviz/core/tests/test_autoconfig.py | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 jdaviz/core/tests/test_autoconfig.py diff --git a/jdaviz/core/tests/test_autoconfig.py b/jdaviz/core/tests/test_autoconfig.py new file mode 100644 index 0000000000..4e7aba313b --- /dev/null +++ b/jdaviz/core/tests/test_autoconfig.py @@ -0,0 +1,32 @@ +# Tests automatic config detection against our example notebook data + +from pathlib import Path +from tempfile import TemporaryDirectory + +import pytest +from astroquery.mast import Observations + +from jdaviz import open as jdaviz_open +from jdaviz.configs import Specviz, Specviz2d, Cubeviz, Imviz + + +@pytest.mark.remote_data +@pytest.mark.filterwarnings('ignore') +@pytest.mark.parametrize('uris', ( + ("mast:JWST/product/jw02732-o004_t004_miri_ch1-shortmediumlong_x1d.fits", Specviz), + ("mast:JWST/product/jw01538-o160_s00004_nirspec_f170lp-g235h-s1600a1-sub2048_s2d.fits", Specviz2d), # noqa + ("mast:JWST/product/jw02727-o002_t062_nircam_clear-f090w_i2d.fits", Imviz), + ("mast:JWST/product/jw02732-o004_t004_miri_ch1-shortmediumlong_s3d.fits", Cubeviz)) +) +def test_autoconfig(uris): + # Setup temporary directory + with TemporaryDirectory(ignore_cleanup_errors=True) as tempdir: + uri = uris[0] + helper_class = uris[1] + download_path = str(Path(tempdir) / Path(uri).name) + Observations.download_file(uri, local_path=download_path) + + viz_helper = jdaviz_open(download_path, show=False) + + assert type(viz_helper) == helper_class + assert len(viz_helper.app.data_collection) > 0 From 1fb46da33865fe30ef86d3ea789530effbea164a Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Wed, 31 May 2023 11:06:04 -0400 Subject: [PATCH 23/42] Revert "Update demo notebooks" This reverts commit cc513b30d8cc128e8150d7f85c6c8b4d444abe8a. --- notebooks/CubevizExample.ipynb | 30 +++++-------- notebooks/Specviz2dExample.ipynb | 26 ++++++++++-- notebooks/SpecvizExample.ipynb | 73 ++++++++++++++++++++++---------- 3 files changed, 84 insertions(+), 45 deletions(-) diff --git a/notebooks/CubevizExample.ipynb b/notebooks/CubevizExample.ipynb index 48e89d593c..73ef66238f 100644 --- a/notebooks/CubevizExample.ipynb +++ b/notebooks/CubevizExample.ipynb @@ -29,7 +29,14 @@ "from photutils.aperture import CircularAperture\n", "from regions import PixCoord, CirclePixelRegion\n", "\n", - "import jdaviz" + "from jdaviz import Cubeviz" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We create a Cubeviz instance and show it." ] }, { @@ -73,26 +80,9 @@ "fn = \"jw02732-o004_t004_miri_ch1-shortmediumlong_s3d.fits\"\n", "result = Observations.download_file(f\"mast:JWST/product/{fn}\", local_path=f'{data_dir}/{fn}')\n", "\n", - "with warnings.catch_warnings():\n", - " warnings.simplefilter('ignore')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we can ask Jdaviz to automatically load the data. Jdaviz will automatically detect Cubeviz as the most appropriate configuration" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ "with warnings.catch_warnings():\n", " warnings.simplefilter('ignore')\n", - " cubeviz = jdaviz.open(f'{data_dir}/{fn}')" + " cubeviz.load_data(f'{data_dir}/{fn}')" ] }, { @@ -235,7 +225,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.10" + "version": "3.10.8" } }, "nbformat": 4, diff --git a/notebooks/Specviz2dExample.ipynb b/notebooks/Specviz2dExample.ipynb index 69c56c9e60..32d7990d1a 100644 --- a/notebooks/Specviz2dExample.ipynb +++ b/notebooks/Specviz2dExample.ipynb @@ -28,7 +28,27 @@ "\n", "from astroquery.mast import Observations\n", "\n", - "import jdaviz" + "from jdaviz import Specviz2d\n", + "\n", + "specviz2d = Specviz2d()" + ] + }, + { + "cell_type": "markdown", + "id": "0ed07713", + "metadata": {}, + "source": [ + "## Display Specviz2d" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "45802673", + "metadata": {}, + "outputs": [], + "source": [ + "specviz2d.show()" ] }, { @@ -74,7 +94,7 @@ "metadata": {}, "outputs": [], "source": [ - "jdaviz.open(f'{data_dir}/{fn}')" + "specviz2d.load_data(f'{data_dir}/{fn}')" ] } ], @@ -94,7 +114,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.10" + "version": "3.10.6" } }, "nbformat": 4, diff --git a/notebooks/SpecvizExample.ipynb b/notebooks/SpecvizExample.ipynb index c21c221acf..5f671b4864 100644 --- a/notebooks/SpecvizExample.ipynb +++ b/notebooks/SpecvizExample.ipynb @@ -26,16 +26,60 @@ "\n", "# Suppress warnings\n", "with warnings.catch_warnings():\n", - " warnings.simplefilter(\"ignore\")\n", + " warnings.simplefilter(\"ignore\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create Specviz via Helper" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "from jdaviz import Specviz\n", + "specviz = Specviz()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Display Specviz\n", "\n", - "import jdaviz" + "Note: you probably want to pick one of the three options below depending on preference. Also not the latter two will only work in JupyterLab, not the \"classic\" notebook interface." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Download Data\n", + "This will show Specviz inline in the notebook" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "specviz.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load a file to Specviz\n", "\n", "Here we download a JWST spectrum from [MAST](https://masttest.stsci.edu/) using `astroquery`. \n", "By default the downloaded file goes to your temp directory, and thus may eventually be \n", @@ -62,24 +106,9 @@ "#data_dir = \"/User/username/Data/\"\n", "\n", "fn = \"jw02732-o004_t004_miri_ch1-shortmediumlong_x1d.fits\"\n", - "result = Observations.download_file(f\"mast:JWST/product/{fn}\", local_path=f'{data_dir}/{fn}')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Open in Jdaviz\n", - "Jdaviz can automatically detect the correct configuration and load the data by using `jdaviz.open`. By default, jdaviz will display the application automatically. To only return the helper, set `show=False`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "specviz = jdaviz.open(f'{data_dir}/{fn}', show=True, data_label=\"myfile\")" + "result = Observations.download_file(f\"mast:JWST/product/{fn}\", local_path=f'{data_dir}/{fn}')\n", + "\n", + "specviz.load_spectrum(f'{data_dir}/{fn}', \"myfile\")" ] }, { @@ -264,7 +293,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.10" + "version": "3.9.16" } }, "nbformat": 4, From 73163b24258102a2dc1b65bc6748c15887788392 Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Wed, 31 May 2023 11:11:40 -0400 Subject: [PATCH 24/42] Add mention of open to relevant example notebooks --- notebooks/CubevizExample.ipynb | 9 ++++++++- notebooks/ImvizExample.ipynb | 10 +++++++++- notebooks/Specviz2dExample.ipynb | 10 +++++++++- notebooks/SpecvizExample.ipynb | 9 ++++++++- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/notebooks/CubevizExample.ipynb b/notebooks/CubevizExample.ipynb index 73ef66238f..ac78ed88e7 100644 --- a/notebooks/CubevizExample.ipynb +++ b/notebooks/CubevizExample.ipynb @@ -85,6 +85,13 @@ " cubeviz.load_data(f'{data_dir}/{fn}')" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Alternatively, the data and the configuration can be autodetected and loaded simultaneously by calling `jdaviz.open(f'{data_dir}/{fn}')`" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -225,7 +232,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.8" + "version": "3.10.10" } }, "nbformat": 4, diff --git a/notebooks/ImvizExample.ipynb b/notebooks/ImvizExample.ipynb index 3b41256da3..b39014d4c5 100644 --- a/notebooks/ImvizExample.ipynb +++ b/notebooks/ImvizExample.ipynb @@ -152,6 +152,14 @@ "imviz.show()" ] }, + { + "cell_type": "markdown", + "id": "99d4bdef", + "metadata": {}, + "source": [ + "Alternatively, the data and the configuration can be autodetected and loaded simultaneously by calling `jdaviz.open(f'{data_dir}/{fn}')`" + ] + }, { "cell_type": "markdown", "id": "3e78efeb", @@ -720,7 +728,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.6" + "version": "3.10.10" } }, "nbformat": 4, diff --git a/notebooks/Specviz2dExample.ipynb b/notebooks/Specviz2dExample.ipynb index 32d7990d1a..5a8d4c8a8f 100644 --- a/notebooks/Specviz2dExample.ipynb +++ b/notebooks/Specviz2dExample.ipynb @@ -96,6 +96,14 @@ "source": [ "specviz2d.load_data(f'{data_dir}/{fn}')" ] + }, + { + "cell_type": "markdown", + "id": "795bc520", + "metadata": {}, + "source": [ + "Alternatively, the data and the configuration can be autodetected and loaded simultaneously by calling `jdaviz.open(f'{data_dir}/{fn}')`" + ] } ], "metadata": { @@ -114,7 +122,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.6" + "version": "3.10.10" } }, "nbformat": 4, diff --git a/notebooks/SpecvizExample.ipynb b/notebooks/SpecvizExample.ipynb index 5f671b4864..115cb03a1e 100644 --- a/notebooks/SpecvizExample.ipynb +++ b/notebooks/SpecvizExample.ipynb @@ -111,6 +111,13 @@ "specviz.load_spectrum(f'{data_dir}/{fn}', \"myfile\")" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Alternatively, the data and the configuration can be autodetected and loaded simultaneously by calling `jdaviz.open(f'{data_dir}/{fn}')`" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -293,7 +300,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.16" + "version": "3.10.10" } }, "nbformat": 4, From 1bd26f4cdb461f5928abb07e2d24c9ca1d2c4fbb Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Wed, 31 May 2023 15:03:33 -0400 Subject: [PATCH 25/42] Prepare to support open via cli --- jdaviz/cli.py | 4 +++- jdaviz/core/data_formats.py | 10 +++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/jdaviz/cli.py b/jdaviz/cli.py index 2c673da2b2..4f569e7f00 100644 --- a/jdaviz/cli.py +++ b/jdaviz/cli.py @@ -14,10 +14,12 @@ __all__ = ['main'] JDAVIZ_DIR = pathlib.Path(__file__).parent.resolve() +DEFAULT_VERBOSITY = 'warning' +DEFAULT_HISTORY_VERBOSITY = 'info' def main(filepaths=None, layout='default', instrument=None, browser='default', - theme='light', verbosity='warning', history_verbosity='info', + theme='light', verbosity=DEFAULT_VERBOSITY, history_verbosity=DEFAULT_HISTORY_VERBOSITY, hotreload=False): """ Start a Jdaviz application instance with data loaded from FILENAME. diff --git a/jdaviz/core/data_formats.py b/jdaviz/core/data_formats.py index 9608aba215..885bf52dd9 100644 --- a/jdaviz/core/data_formats.py +++ b/jdaviz/core/data_formats.py @@ -12,6 +12,7 @@ from jdaviz.core.config import list_configurations from jdaviz import configs as jdaviz_configs +from jdaviz.cli import DEFAULT_VERBOSITY, DEFAULT_HISTORY_VERBOSITY __all__ = [ 'guess_dimensionality', @@ -292,15 +293,22 @@ def open(filename, show=True, **kwargs): Jdaviz App : jdaviz.app.Application The application, configured based on the automatic config detection ''' + # Identify the correct config helper_str = identify_helper(filename) viz_class = getattr(jdaviz_configs, helper_str.capitalize()) - viz_helper = viz_class() + # Create config instance + verbosity = kwargs.pop('verbosity', DEFAULT_VERBOSITY) + history_verbosity = kwargs.pop('history_verbosity', DEFAULT_HISTORY_VERBOSITY) + viz_helper = viz_class(verbosity=verbosity, history_verbosity=history_verbosity) + + # Load data if helper_str == "specviz": viz_helper.load_spectrum(filename, **kwargs) else: viz_helper.load_data(filename, **kwargs) + # Display app if show: viz_helper.show() From f6ca9e870a1a4749371a413babeca6bc1571f164 Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Wed, 31 May 2023 15:11:22 -0400 Subject: [PATCH 26/42] Remove the need to open file twice for autoconfig detection --- jdaviz/core/data_formats.py | 37 ++++++++++++++++------------ jdaviz/core/tests/test_autoconfig.py | 5 ++-- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/jdaviz/core/data_formats.py b/jdaviz/core/data_formats.py index 885bf52dd9..c0bc16cdb9 100644 --- a/jdaviz/core/data_formats.py +++ b/jdaviz/core/data_formats.py @@ -158,6 +158,9 @@ def identify_helper(filename, ext=1): ------- helper_name : str Name of the best-guess helper for ``filename``. + + Fits HDUList : astropy.io.fits.HDUList + The HDUList of the file opened to identify the helper """ supported_dtypes = [ Spectrum1D, @@ -169,10 +172,11 @@ def identify_helper(filename, ext=1): if filename.lower().endswith('asdf'): # ASDF files are only supported in jdaviz for # Roman WFI 2D images, so suggest imviz: - return 'imviz' + return ('imviz', None) - header = fits.getheader(filename, ext=ext) - data = fits.getdata(filename, ext=ext) + hdul = fits.open(filename) + data = hdul[ext] + header = data.header wcs = _get_wcs(filename, header) has_spectral_axis = 'spectral' in wcs.world_axis_object_classes @@ -203,10 +207,10 @@ def identify_helper(filename, ext=1): # could be 2D spectrum or 2D image. break tie with WCS: if has_spectral_axis: if n_axes > 1: - return 'specviz2d' - return 'specviz' + return ('specviz2d', hdul) + return ('specviz', hdul) elif not isinstance(data, fits.BinTableHDU): - return 'imviz' + return ('imviz', hdul) # Ensure specviz is chosen when ``data`` is a table or recarray # and there's a "known" spectral column name: @@ -232,7 +236,7 @@ def identify_helper(filename, ext=1): # if at least one spectral column is found: if sum(found_spectral_columns): - return 'specviz' + return ('specviz', hdul) # If the data could be spectral: for cls in [Spectrum1D, SpectrumList]: @@ -242,10 +246,10 @@ def identify_helper(filename, ext=1): # first catch known JWST spectrum types: if (n_axes == 3 and recognized_spectrum_format.find('s3d') > -1): - return 'cubeviz' + return ('cubeviz', hdul) elif (n_axes == 2 and recognized_spectrum_format.find('x1d') > -1): - return 'specviz' + return ('specviz', hdul) # we intentionally don't choose specviz2d for # data recognized as 's2d' as we did with the cases above, @@ -255,11 +259,11 @@ def identify_helper(filename, ext=1): # Use WCS to break the tie below: elif n_axes == 2: if has_spectral_axis: - return 'specviz2d' - return 'imviz' + return ('specviz2d', hdul) + return ('imviz', hdul) elif n_axes == 1: - return 'specviz' + return ('specviz', hdul) try: # try using the specutils registry: @@ -271,7 +275,7 @@ def identify_helper(filename, ext=1): if n_axes == 2 and not has_spectral_axis: # at this point, non-spectral 2D data are likely images: - return 'imviz' + return ('imviz', hdul) raise ValueError(f"No helper could be auto-identified for {filename}.") @@ -294,7 +298,7 @@ def open(filename, show=True, **kwargs): The application, configured based on the automatic config detection ''' # Identify the correct config - helper_str = identify_helper(filename) + helper_str, hdul = identify_helper(filename) viz_class = getattr(jdaviz_configs, helper_str.capitalize()) # Create config instance @@ -303,10 +307,11 @@ def open(filename, show=True, **kwargs): viz_helper = viz_class(verbosity=verbosity, history_verbosity=history_verbosity) # Load data + data = hdul if (hdul is not None) else filename if helper_str == "specviz": - viz_helper.load_spectrum(filename, **kwargs) + viz_helper.load_spectrum(data, **kwargs) else: - viz_helper.load_data(filename, **kwargs) + viz_helper.load_data(data, **kwargs) # Display app if show: diff --git a/jdaviz/core/tests/test_autoconfig.py b/jdaviz/core/tests/test_autoconfig.py index 4e7aba313b..8c36663451 100644 --- a/jdaviz/core/tests/test_autoconfig.py +++ b/jdaviz/core/tests/test_autoconfig.py @@ -7,13 +7,14 @@ from astroquery.mast import Observations from jdaviz import open as jdaviz_open -from jdaviz.configs import Specviz, Specviz2d, Cubeviz, Imviz +from jdaviz.configs import Specviz2d, Cubeviz, Imviz # , Specviz @pytest.mark.remote_data @pytest.mark.filterwarnings('ignore') @pytest.mark.parametrize('uris', ( - ("mast:JWST/product/jw02732-o004_t004_miri_ch1-shortmediumlong_x1d.fits", Specviz), + # ("mast:JWST/product/jw02732-o004_t004_miri_ch1-shortmediumlong_x1d.fits", Specviz), + # Specviz check disabled due to https://github.com/spacetelescope/jdaviz/issues/2229 ("mast:JWST/product/jw01538-o160_s00004_nirspec_f170lp-g235h-s1600a1-sub2048_s2d.fits", Specviz2d), # noqa ("mast:JWST/product/jw02727-o002_t062_nircam_clear-f090w_i2d.fits", Imviz), ("mast:JWST/product/jw02732-o004_t004_miri_ch1-shortmediumlong_s3d.fits", Cubeviz)) From c85dbd5a2057ab2e98eee0226bdfc1a115a533ff Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Wed, 31 May 2023 15:14:53 -0400 Subject: [PATCH 27/42] Fix Helper vs App Docstring --- jdaviz/core/data_formats.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jdaviz/core/data_formats.py b/jdaviz/core/data_formats.py index c0bc16cdb9..d31bc3ab40 100644 --- a/jdaviz/core/data_formats.py +++ b/jdaviz/core/data_formats.py @@ -294,8 +294,8 @@ def open(filename, show=True, **kwargs): Returns ------- - Jdaviz App : jdaviz.app.Application - The application, configured based on the automatic config detection + Jdaviz ConfigHelper : jdaviz.core.helpers.ConfigHelper + The autoidentified ConfigHelper for the given data ''' # Identify the correct config helper_str, hdul = identify_helper(filename) From 8169a6d4e9cd200266b714a6f2d12b4d67489e75 Mon Sep 17 00:00:00 2001 From: "P. L. Lim" <2090236+pllim@users.noreply.github.com> Date: Wed, 31 May 2023 21:04:40 -0400 Subject: [PATCH 28/42] TST: Change PIP_EXTRA_INDEX_URL because packages moved where they upload nightly builds. --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 8781af9977..73ddbd9c90 100644 --- a/tox.ini +++ b/tox.ini @@ -15,7 +15,7 @@ isolated_build = true setenv = MPLBACKEND=agg JUPYTER_PLATFORM_DIRS=1 - devdeps: PIP_EXTRA_INDEX_URL = https://pypi.anaconda.org/scipy-wheels-nightly/simple + devdeps: PIP_EXTRA_INDEX_URL = https://pypi.anaconda.org/scientific-python-nightly-wheels/simple # Pass through the following environment variables which may be needed for the CI passenv = HOME,WINDIR,LC_ALL,LC_CTYPE,CC,CI From 7af857ebaaac0e6e9de0b544eab3296d8b33f783 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Thu, 1 Jun 2023 11:42:48 -0400 Subject: [PATCH 29/42] Display units: model fitting (#2216) * model component compatibility based on display units * equation validity based on display units * allow re-estimating model parameters to update compat checks * test coverage * get_data(use_display_units) to pass spectral_density equivalency * handle whitespace in model equation --- jdaviz/components/tooltip.vue | 2 +- .../plugins/model_fitting/model_fitting.py | 89 +++++++++++++++++-- .../plugins/model_fitting/model_fitting.vue | 40 +++++++-- .../model_fitting/tests/test_fitting.py | 53 +++++++++++ jdaviz/core/helpers.py | 3 +- 5 files changed, 172 insertions(+), 15 deletions(-) diff --git a/jdaviz/components/tooltip.vue b/jdaviz/components/tooltip.vue index 1bd8f37c1f..91c81e1e5c 100644 --- a/jdaviz/components/tooltip.vue +++ b/jdaviz/components/tooltip.vue @@ -76,7 +76,7 @@ const tooltips = { 'plugin-plot-options-mixed-state': 'Current values are mixed, click to sync at shown value', 'plugin-model-fitting-add-model': 'Create model component', 'plugin-model-fitting-param-fixed': 'Check the box to freeze parameter value', - 'plugin-model-fitting-reestimate-all': 'Re-estimate initial values based on the current data/subset selection for all free parameters', + 'plugin-model-fitting-reestimate-all': 'Re-estimate initial values based on the current data/subset selection for all free parameters based on current display units', 'plugin-model-fitting-reestimate': 'Re-estimate initial values based on the current data/subset selection for all free parameters in this component', 'plugin-unit-conversion-apply': 'Apply unit conversion', 'plugin-line-lists-load': 'Load list into "Loaded Lines" section of plugin', diff --git a/jdaviz/configs/default/plugins/model_fitting/model_fitting.py b/jdaviz/configs/default/plugins/model_fitting/model_fitting.py index 1620db5df7..e7ccc53395 100644 --- a/jdaviz/configs/default/plugins/model_fitting/model_fitting.py +++ b/jdaviz/configs/default/plugins/model_fitting/model_fitting.py @@ -8,7 +8,7 @@ from traitlets import Bool, List, Unicode, observe from glue.core.data import Data -from jdaviz.core.events import SnackbarMessage +from jdaviz.core.events import SnackbarMessage, GlobalDisplayUnitChanged from jdaviz.core.registries import tray_registry from jdaviz.core.template_mixin import (PluginTemplateMixin, SelectPluginComponent, @@ -60,6 +60,7 @@ class ModelFitting(PluginTemplateMixin, DatasetSelectMixin, * :meth:`create_model_component` * :meth:`remove_model_component` * :meth:`model_components` + * :meth:`valid_model_components` * :meth:`get_model_component` * :meth:`set_model_component` * :meth:`reestimate_model_parameters` @@ -169,13 +170,17 @@ def __init__(self, *args, **kwargs): # set the filter on the viewer options self._update_viewer_filters() + self.hub.subscribe(self, GlobalDisplayUnitChanged, + handler=self._on_global_display_unit_changed) + @property def user_api(self): expose = ['dataset'] if self.config == "cubeviz": expose += ['spatial_subset'] expose += ['spectral_subset', 'model_component', 'poly_order', 'model_component_label', - 'model_components', 'create_model_component', 'remove_model_component', + 'model_components', 'valid_model_components', + 'create_model_component', 'remove_model_component', 'get_model_component', 'set_model_component', 'reestimate_model_parameters', 'equation', 'equation_components', 'add_results', 'residuals_calculate', 'residuals'] @@ -336,6 +341,7 @@ def _dataset_selected_changed(self, event=None): # (won't affect calculations because these locations are masked) selected_spec.flux[np.isnan(selected_spec.flux)] = 0.0 + # TODO: can we simplify this logic? self._units["x"] = str( selected_spec.spectral_axis.unit) self._units["y"] = str( @@ -503,8 +509,38 @@ def _initialize_model_component(self, model_comp, comp_label, poly_order=None): self._initialized_models[comp_label] = initialized_model new_model["Initialized"] = True + new_model["initialized_display_units"] = self._units.copy() + + new_model["compat_display_units"] = True # always compatible at time of creation return new_model + def _check_model_component_compat(self, axes=['x', 'y'], display_units=None): + if display_units is None: + display_units = [u.Unit(self._units[ax]) for ax in axes] + + disp_physical_types = [unit.physical_type for unit in display_units] + + for model_index, comp_model in enumerate(self.component_models): + compat = True + for ax, ax_physical_type in zip(axes, disp_physical_types): + comp_unit = u.Unit(comp_model["initialized_display_units"][ax]) + compat = comp_unit.physical_type == ax_physical_type + if not compat: + break + self.component_models[model_index]["compat_display_units"] = compat + + # length hasn't changed, so we need to force the traitlet to update + self.send_state("component_models") + self._check_model_equation_invalid() + + def _on_global_display_unit_changed(self, msg): + axis = {'spectral': 'x', 'flux': 'y'}.get(msg.axis) + + # update internal tracking of current units + self._units[axis] = str(msg.unit) + + self._check_model_component_compat([axis], [msg.unit]) + def remove_model_component(self, model_component_label): """ Remove an existing model component. @@ -634,6 +670,9 @@ def reestimate_model_parameters(self, model_component_label=None): # length hasn't changed, so we need to force the traitlet to update self.send_state("component_models") + # model units may have changed, need to re-check their compatibility with display units + self._check_model_component_compat() + # return user-friendly info on revised model return self.get_model_component(model_component_label) @@ -644,12 +683,19 @@ def model_components(self): """ return [x["id"] for x in self.component_models] + @property + def valid_model_components(self): + """ + List of the labels of existing valid (due to display units) model components + """ + return [x["id"] for x in self.component_models if x["compat_display_units"]] + @property def equation_components(self): """ List of the labels of model components in the current equation """ - return re.split('[+*/-]', self.equation.value) + return re.split(r'[+*/-]', self.equation.value.replace(' ', '')) def vue_add_model(self, event): self.create_model_component() @@ -658,10 +704,41 @@ def vue_remove_model(self, event): self.remove_model_component(event) @observe('model_equation') - def _model_equation_changed(self, event): + def _check_model_equation_invalid(self, event=None): # Length is a dummy check to test the infrastructure if len(self.model_equation) == 0: - self.model_equation_invalid_msg = 'model equation is required' + self.model_equation_invalid_msg = 'model equation is required.' + return + if '' in self.equation_components: + # includes an operator without a variable (ex: 'C+') + self.model_equation_invalid_msg = 'incomplete equation.' + return + + components_not_existing = [comp for comp in self.equation_components + if comp not in self.model_components] + if len(components_not_existing): + if len(components_not_existing) == 1: + msg = "is not an existing model component." + else: + msg = "are not existing model components." + self.model_equation_invalid_msg = f'{", ".join(components_not_existing)} {msg}' + return + components_not_valid = [comp for comp in self.equation_components + if comp not in self.valid_model_components] + if len(components_not_valid): + if len(components_not_valid) == 1: + msg = ("is currently disabled because it has" + " incompatible units with the current display units." + " Remove the component from the equation," + " re-estimate its free parameters to use the new units" + " or revert the display units.") + else: + msg = ("are currently disabled because they have" + " incompatible units with the current display units." + " Remove the components from the equation," + " re-estimate their free parameters to use the new units" + " or revert the display units.") + self.model_equation_invalid_msg = f'{", ".join(components_not_valid)} {msg}' return self.model_equation_invalid_msg = '' @@ -707,6 +784,8 @@ def calculate_fit(self, add_data=True): if not self.spectral_subset_valid: valid, spec_range, subset_range = self._check_dataset_spectral_subset_valid(return_ranges=True) # noqa raise ValueError(f"spectral subset '{self.spectral_subset.selected}' {subset_range} is outside data range of '{self.dataset.selected}' {spec_range}") # noqa + if len(self.model_equation_invalid_msg): + raise ValueError(f"model equation is invalid: {self.model_equation_invalid_msg}") if self.cube_fit: ret = self._fit_model_to_cube(add_data=add_data) diff --git a/jdaviz/configs/default/plugins/model_fitting/model_fitting.vue b/jdaviz/configs/default/plugins/model_fitting/model_fitting.vue index e42107cf78..8da1c00bc0 100644 --- a/jdaviz/configs/default/plugins/model_fitting/model_fitting.vue +++ b/jdaviz/configs/default/plugins/model_fitting/model_fitting.vue @@ -128,14 +128,38 @@ - - {{ item.id }} model component not in equation + + + {{ item.id }} is inconsistent with the current display units so cannot be used in the model equation. + Create a new model component or re-estimate the free parameters based on the current display units. + + + + mdi-restart + Re-estimate free parameters + + + + + + + + {{ item.id }} model component not in equation + - @@ -290,7 +314,7 @@ }, methods: { componentInEquation(componentId) { - return this.model_equation.split(/[+*\/-]/).indexOf(componentId) !== -1 + return this.model_equation.replace(/\s/g, '').split(/[+*\/-]/).indexOf(componentId) !== -1 }, roundUncertainty(uncertainty) { return uncertainty.toPrecision(2) diff --git a/jdaviz/configs/default/plugins/model_fitting/tests/test_fitting.py b/jdaviz/configs/default/plugins/model_fitting/tests/test_fitting.py index 41d418a0ec..22c059d64a 100644 --- a/jdaviz/configs/default/plugins/model_fitting/tests/test_fitting.py +++ b/jdaviz/configs/default/plugins/model_fitting/tests/test_fitting.py @@ -327,3 +327,56 @@ def test_results_table(specviz_helper, spectrum1d): 'G:mean_1:fixed', 'G:mean_1:std', 'G:stddev_1', 'G:stddev_1:unit', 'G:stddev_1:fixed', 'G:stddev_1:std'] + + +def test_equation_validation(specviz_helper, spectrum1d): + data_label = 'test' + specviz_helper.load_data(spectrum1d, data_label=data_label) + + mf = specviz_helper.plugins['Model Fitting'] + mf.create_model_component('Const1D') + mf.create_model_component('Linear1D') + + assert mf.equation == 'C+L' + assert mf._obj.model_equation_invalid_msg == '' + + mf.equation = 'L+' + assert mf._obj.model_equation_invalid_msg == 'incomplete equation.' + + mf.equation = 'L+C' + assert mf._obj.model_equation_invalid_msg == '' + + mf.equation = 'L+CC' + assert mf._obj.model_equation_invalid_msg == 'CC is not an existing model component.' + + mf.equation = 'L+CC+DD' + assert mf._obj.model_equation_invalid_msg == 'CC, DD are not existing model components.' + + mf.equation = '' + assert mf._obj.model_equation_invalid_msg == 'model equation is required.' + + +@pytest.mark.filterwarnings(r"ignore:Model is linear in parameters.*") +@pytest.mark.filterwarnings(r"ignore:The fit may be unsuccessful.*") +def test_incompatible_units(specviz_helper, spectrum1d): + data_label = 'test' + specviz_helper.load_data(spectrum1d, data_label=data_label) + + mf = specviz_helper.plugins['Model Fitting'] + mf.create_model_component('Linear1D') + + mf.add_results.label = 'model native units' + mf.calculate_fit(add_data=True) + + uc = specviz_helper.plugins['Unit Conversion'] + assert uc.spectral_unit.selected == "Angstrom" + uc.spectral_unit = u.Hz + + assert 'L is currently disabled' in mf._obj.model_equation_invalid_msg + mf.add_results.label = 'frequency units' + with pytest.raises(ValueError, match=r"model equation is invalid.*"): + mf.calculate_fit(add_data=True) + + mf.reestimate_model_parameters() + assert mf._obj.model_equation_invalid_msg == '' + mf.calculate_fit(add_data=True) diff --git a/jdaviz/core/helpers.py b/jdaviz/core/helpers.py index f70e582740..40dbd87740 100644 --- a/jdaviz/core/helpers.py +++ b/jdaviz/core/helpers.py @@ -431,7 +431,8 @@ def _handle_display_units(data, use_display_units): new_uncert = data.uncertainty.__class__(data.uncertainty.quantity.to(flux_unit)) if data.uncertainty is not None else None # noqa data = Spectrum1D(spectral_axis=data.spectral_axis.to(spectral_unit, u.spectral()), - flux=data.flux.to(flux_unit), + flux=data.flux.to(flux_unit, + u.spectral_density(data.spectral_axis)), uncertainty=new_uncert) else: # pragma: nocover raise NotImplementedError(f"converting {data.__class__.__name__} to display units is not supported") # noqa From 3caae359547b3c4ea1173acc302b6759198c45f1 Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Thu, 1 Jun 2023 11:43:22 -0400 Subject: [PATCH 30/42] Add clarity for kwargs --- jdaviz/core/data_formats.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jdaviz/core/data_formats.py b/jdaviz/core/data_formats.py index d31bc3ab40..448a12a26e 100644 --- a/jdaviz/core/data_formats.py +++ b/jdaviz/core/data_formats.py @@ -292,6 +292,9 @@ def open(filename, show=True, **kwargs): show : bool Determines whether to immediately show the application + All other arguments are interpreted as load_data/load_spectrum arguments for + the autoidentified configuration class + Returns ------- Jdaviz ConfigHelper : jdaviz.core.helpers.ConfigHelper From 1c5a8c1c37b596b152ac37a18b8ac32b8d19461b Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Thu, 1 Jun 2023 14:13:56 -0400 Subject: [PATCH 31/42] plugin results: support overwriting when data loaded in multiple viewers (#2222) --- jdaviz/components/plugin_add_results.vue | 26 ++++++++---- jdaviz/core/template_mixin.py | 54 +++++++++++++++--------- 2 files changed, 51 insertions(+), 29 deletions(-) diff --git a/jdaviz/components/plugin_add_results.vue b/jdaviz/components/plugin_add_results.vue index 08451089ae..2660f84d7d 100644 --- a/jdaviz/components/plugin_add_results.vue +++ b/jdaviz/components/plugin_add_results.vue @@ -12,14 +12,24 @@ :hint="label_hint ? label_hint : 'Label for the resulting data item.'" > - +

+ + + +
Date: Fri, 2 Jun 2023 12:35:18 -0400 Subject: [PATCH 32/42] reverts removal of call to set_plot_axes when loading data into viewer (#2235) * fixes a bug in the axes labels on cube viewers in cubeviz as well as setting the correct attributes in lcviz --- jdaviz/app.py | 1 + jdaviz/configs/default/plugins/viewers.py | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/jdaviz/app.py b/jdaviz/app.py index 05a37d1d7f..43611be372 100644 --- a/jdaviz/app.py +++ b/jdaviz/app.py @@ -1728,6 +1728,7 @@ def set_data_visibility(self, viewer_reference, data_label, visible=True, replac [data] = [x for x in self.data_collection if x.label == data_label] viewer.add_data(data, percentile=95, color=viewer.color_cycler()) + viewer.set_plot_axes() add_data_message = AddDataMessage(data, viewer, viewer_id=viewer_id, diff --git a/jdaviz/configs/default/plugins/viewers.py b/jdaviz/configs/default/plugins/viewers.py index 70f33aa657..08e418c881 100644 --- a/jdaviz/configs/default/plugins/viewers.py +++ b/jdaviz/configs/default/plugins/viewers.py @@ -227,3 +227,7 @@ def reference_id(self): @property def reference(self): return self.jdaviz_app._viewer_item_by_id(self.reference_id).get('reference') + + def set_plot_axes(self): + # individual viewers can override to set custom axes labels/ticks/styling + return From 956b9c444cf9bd80c1b51aaa232503bd7d55d5da Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Fri, 2 Jun 2023 15:42:42 -0400 Subject: [PATCH 33/42] Subsume failing identifier test into autoconfig test --- jdaviz/core/data_formats.py | 5 +++-- jdaviz/core/tests/test_autoconfig.py | 16 ++++++++++++---- jdaviz/core/tests/test_data_menu.py | 15 ++------------- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/jdaviz/core/data_formats.py b/jdaviz/core/data_formats.py index 448a12a26e..c26104c663 100644 --- a/jdaviz/core/data_formats.py +++ b/jdaviz/core/data_formats.py @@ -174,7 +174,8 @@ def identify_helper(filename, ext=1): # Roman WFI 2D images, so suggest imviz: return ('imviz', None) - hdul = fits.open(filename) + # Must use memmap=False to force close all handles and allow file overwrite + hdul = fits.open(filename, memmap=False) data = hdul[ext] header = data.header wcs = _get_wcs(filename, header) @@ -268,7 +269,7 @@ def identify_helper(filename, ext=1): try: # try using the specutils registry: valid_format, config = identify_data(filename) - return config + return (config, hdul) except ValueError: # if file type not recognized: pass diff --git a/jdaviz/core/tests/test_autoconfig.py b/jdaviz/core/tests/test_autoconfig.py index 8c36663451..94ac011e6e 100644 --- a/jdaviz/core/tests/test_autoconfig.py +++ b/jdaviz/core/tests/test_autoconfig.py @@ -5,6 +5,7 @@ import pytest from astroquery.mast import Observations +from astropy.utils.data import download_file from jdaviz import open as jdaviz_open from jdaviz.configs import Specviz2d, Cubeviz, Imviz # , Specviz @@ -17,15 +18,22 @@ # Specviz check disabled due to https://github.com/spacetelescope/jdaviz/issues/2229 ("mast:JWST/product/jw01538-o160_s00004_nirspec_f170lp-g235h-s1600a1-sub2048_s2d.fits", Specviz2d), # noqa ("mast:JWST/product/jw02727-o002_t062_nircam_clear-f090w_i2d.fits", Imviz), - ("mast:JWST/product/jw02732-o004_t004_miri_ch1-shortmediumlong_s3d.fits", Cubeviz)) -) + ("mast:JWST/product/jw02732-o004_t004_miri_ch1-shortmediumlong_s3d.fits", Cubeviz), + ("https://stsci.box.com/shared/static/28a88k1qfipo4yxc4p4d40v4axtlal8y.fits", Cubeviz) + # Check that MaNGA cubes go to cubeviz. This file is originally from: + # https://data.sdss.org/sas/dr14/manga/spectro/redux/v2_1_2/7495/stack/manga-7495-12704-LOGCUBE.fits.gz) +)) def test_autoconfig(uris): # Setup temporary directory with TemporaryDirectory(ignore_cleanup_errors=True) as tempdir: uri = uris[0] helper_class = uris[1] - download_path = str(Path(tempdir) / Path(uri).name) - Observations.download_file(uri, local_path=download_path) + + if uri.startswith("mast:"): + download_path = str(Path(tempdir) / Path(uri).name) + Observations.download_file(uri, local_path=download_path) + elif uri.startswith("http"): + download_path = download_file(uri, cache=True, timeout=100) viz_helper = jdaviz_open(download_path, show=False) diff --git a/jdaviz/core/tests/test_data_menu.py b/jdaviz/core/tests/test_data_menu.py index 9c18584630..f092c2994c 100644 --- a/jdaviz/core/tests/test_data_menu.py +++ b/jdaviz/core/tests/test_data_menu.py @@ -110,17 +110,6 @@ def test_visibility_toggle(imviz_helper): def test_auto_config_detection(uri, expected_helper): url = f'https://mast.stsci.edu/api/v0.1/Download/file/?uri={uri}' fn = download_file(url, timeout=100) - helper_name = identify_helper(fn) + helper_name, hdul = identify_helper(fn) + hdul.close() assert helper_name == expected_helper - - -@pytest.mark.remote_data -@pytest.mark.filterwarnings(r"ignore::astropy.wcs.wcs.FITSFixedWarning") -def test_auto_config_manga(): - # Check that MaNGA cubes go to cubeviz. This file is - # originally from - # https://data.sdss.org/sas/dr14/manga/spectro/redux/v2_1_2/7495/stack/manga-7495-12704-LOGCUBE.fits.gz - URL = 'https://stsci.box.com/shared/static/28a88k1qfipo4yxc4p4d40v4axtlal8y.fits' - fn = download_file(URL, cache=True, timeout=100) - helper_name = identify_helper(fn) - assert helper_name == 'cubeviz' From 56fb20e9ea1e56e3b5fcc9a0de427a74a924fa84 Mon Sep 17 00:00:00 2001 From: Jesse Averbukh Date: Fri, 2 Jun 2023 15:54:56 -0400 Subject: [PATCH 34/42] Update subset plugin UI (#2234) * Update subset plugin UI * Apply suggestions from code review Co-authored-by: Kyle Conroy --------- Co-authored-by: Kyle Conroy --- .../plugins/subset_plugin/subset_plugin.py | 12 ++++++ .../plugins/subset_plugin/subset_plugin.vue | 37 ++++++++++++++++--- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py b/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py index 7cae959aa7..0e33a60d8a 100644 --- a/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py +++ b/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py @@ -1,12 +1,18 @@ +import os + import numpy as np + from glue.core.message import EditSubsetMessage, SubsetUpdateMessage from glue.core.edit_subset_mode import (AndMode, AndNotMode, OrMode, ReplaceMode, XorMode) from glue.core.roi import CircularROI, EllipticalROI, RectangularROI from glue.core.subset import RoiSubsetState, RangeSubsetState, CompositeSubsetState +from glue.icons import icon_path from glue_jupyter.widgets.subset_mode_vuetify import SelectionModeMenu +from glue_jupyter.common.toolbar_vuetify import read_icon from traitlets import Any, List, Unicode, Bool, observe + from jdaviz.core.events import SnackbarMessage from jdaviz.core.registries import tray_registry from jdaviz.core.template_mixin import PluginTemplateMixin, DatasetSelectMixin, SubsetSelect @@ -41,6 +47,12 @@ class SubsetPlugin(PluginTemplateMixin, DatasetSelectMixin): is_centerable = Bool(False).tag(sync=True) + icon_replace = Unicode(read_icon(os.path.join(icon_path("glue_replace", icon_format="svg")), 'svg+xml')).tag(sync=True) # noqa + icon_or = Unicode(read_icon(os.path.join(icon_path("glue_or", icon_format="svg")), 'svg+xml')).tag(sync=True) # noqa + icon_and = Unicode(read_icon(os.path.join(icon_path("glue_and", icon_format="svg")), 'svg+xml')).tag(sync=True) # noqa + icon_xor = Unicode(read_icon(os.path.join(icon_path("glue_xor", icon_format="svg")), 'svg+xml')).tag(sync=True) # noqa + icon_andnot = Unicode(read_icon(os.path.join(icon_path("glue_andnot", icon_format="svg")), 'svg+xml')).tag(sync=True) # noqa + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.vue b/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.vue index 286adbce32..03d3d1f73f 100644 --- a/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.vue +++ b/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.vue @@ -47,17 +47,42 @@
- - Subset type: {{ subset_types[index] }} + + Subregion {{ index }} + +
+ {{ subset_types[index] }} applied with +
+
+
+ + replace mode +
+
+ + and mode +
+
+ + add mode +
+
+ + remove mode +
+
+ + xor mode +
+
- - Glue state: {{ glue_state_types[index] }} - - + +
From 61e6ef9a67ee73cf217ab78c4a2819b475505d0e Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Fri, 2 Jun 2023 16:07:49 -0400 Subject: [PATCH 35/42] Changelog --- CHANGES.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 0ec2aeff96..79a9e43eaf 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,8 @@ New Features ------------ +- Introduce jdaviz.open to automatically detect the appropriate config and load data [#2221] + Cubeviz ^^^^^^^ From 2a35e274f972e3cea808ede1618c9ccc2167e88a Mon Sep 17 00:00:00 2001 From: Camilla Pacifici Date: Mon, 5 Jun 2023 08:47:13 -0400 Subject: [PATCH 36/42] Add docs page to explain how to create jdaviz-readable products (#2228) * Add page for data products * Update index * Fix title * Capital letters * Address first review comments * Edit format * Apply suggestions from code review Co-authored-by: P. L. Lim <2090236+pllim@users.noreply.github.com> * Including reference in import_data * Update docs/create_products.rst * Update docs/create_products.rst --------- Co-authored-by: Camilla Pacifici Co-authored-by: P. L. Lim <2090236+pllim@users.noreply.github.com> Co-authored-by: Ricky O'Steen <39831871+rosteen@users.noreply.github.com> --- docs/create_products.rst | 71 ++++++++++++++++++++++++++++++++++ docs/cubeviz/import_data.rst | 1 + docs/index.rst | 1 + docs/mosviz/import_data.rst | 4 +- docs/specviz/import_data.rst | 1 + docs/specviz2d/import_data.rst | 5 ++- 6 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 docs/create_products.rst diff --git a/docs/create_products.rst b/docs/create_products.rst new file mode 100644 index 0000000000..3a78bd6991 --- /dev/null +++ b/docs/create_products.rst @@ -0,0 +1,71 @@ +.. _create_products: + +Creating Jdaviz-readable Products +================================= + +Spectroscopic data products (1D, 2D, and 3D) can be loaded +in the different ``jdaviz`` configurations using +essentially two methods, i.e., loading :class:`~specutils.Spectrum1D` objects or +from FITS files. Here, we list a few ways in which data can be packaged to be easily loaded +into a ``jdaviz`` configuration. + +Data in a database +------------------ + +If the data are stored in a database, we recommend storing a :class:`~specutils.Spectrum1D` object +per entry. This would allow the user to query the data and visualize it in +``jdaviz`` with few lines of code; also see :ref:`create_product_spectrum1d_obj`. + +Data in FITS files +------------------ + +If the data are stored as FITS files, we propose three options: + +* :ref:`create_product_specutils_loader` +* :ref:`create_product_dedicated_loader` +* :ref:`create_product_spectrum1d_obj` + +.. _create_product_specutils_loader: + +Using an available specutils loader +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Available loaders can be listed with the following commands: + +.. code-block:: python + + from specutils import Spectrum1D + Spectrum1D.read.list_formats() + +The majority are fairly specific to missions and instruments. Four formats +are more generic and adaptable: ``ASCII``, ``ECSV``, ``tabular-fits``, and +``wcs1d-fits``. More information on how to create files that are readable by +these loaders can be found on the `specutils GitHub repository +`_. + +.. _create_product_dedicated_loader: + +Creating a dedicated loader +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The `specutils documentation on how to create a custom loader +`_ +is available. We are working on the necessary documentation to prompt +``jdaviz`` to recognize a custom loader developed in ``specutils``. + +.. _create_product_spectrum1d_obj: + +Providing scripts to load the data as Spectrum1D objects +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If none of the above is an acceptable option, the user can create the data +products with their custom format and provide scripts or Jupyter Notebooks +that show how to read the products and create :class:`~specutils.Spectrum1D` objects +that can be read into ``jdaviz``. More about +how to create :class:`~specutils.Spectrum1D` objects for the 1D, 2D, and 3D cases can be +found in the corresponding "Importing data" sections of the various configurations: + +* :ref:`specviz-import-data` +* :ref:`cubeviz-import-data` +* :ref:`specviz2d-import-data` +* :ref:`mosviz-import-api` diff --git a/docs/cubeviz/import_data.rst b/docs/cubeviz/import_data.rst index dee10366da..993ad8969f 100644 --- a/docs/cubeviz/import_data.rst +++ b/docs/cubeviz/import_data.rst @@ -10,6 +10,7 @@ now supports 3D cubes and allows the Python-level interface and parsing tools to be defined in ``specutils`` instead of being duplicated in Jdaviz. :class:`~specutils.Spectrum1D` objects are very flexible in their capabilities, however, and hence should address most astronomical spectrum use cases. +If you are creating your own data products, please read the page :ref:`create_products`. Cubeviz will automatically parse the data into the multiple viewers as described in :ref:`cubeviz-display-cubes`. For the best experience, data loaded into Cubeviz should contain valid WCS diff --git a/docs/index.rst b/docs/index.rst index b87827979d..075a1b26ba 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -192,6 +192,7 @@ Using Jdaviz save_state.rst display.rst sample_notebooks.rst + create_products.rst Reference/API ============= diff --git a/docs/mosviz/import_data.rst b/docs/mosviz/import_data.rst index 74621ca579..ed0f513af2 100644 --- a/docs/mosviz/import_data.rst +++ b/docs/mosviz/import_data.rst @@ -100,7 +100,9 @@ Manual Loading If an automatic parser is not provided yet for your data, Mosviz provides manual loading by specifying which files are which, and the associations between them. This is done by generating three lists containing the filenames for the 1D spectra, -2D spectra, and images in your dataset. These three lists are taken as arguments +2D spectra, and images in your dataset (if you are creating your own data products, +please read the page :ref:`create_products`). +These three lists are taken as arguments by :py:meth:`~jdaviz.configs.mosviz.helper.Mosviz.load_data`. The association between files is assumed to be the order of each list (e.g., the first object consists of the first filename specified in each list, the second target is the second in each list, and so forth). diff --git a/docs/specviz/import_data.rst b/docs/specviz/import_data.rst index c5623ddfbf..e30aa19f02 100644 --- a/docs/specviz/import_data.rst +++ b/docs/specviz/import_data.rst @@ -9,6 +9,7 @@ as that allows the Python-level interface and parsing tools to be defined in ``s instead of being duplicated in Jdaviz. :class:`~specutils.Spectrum1D` objects are very flexible in their capabilities, however, and hence should address most astronomical spectrum use cases. +If you are creating your own data products, please read the page :ref:`create_products`. .. seealso:: diff --git a/docs/specviz2d/import_data.rst b/docs/specviz2d/import_data.rst index 0c9fc6860a..e3501e70a3 100644 --- a/docs/specviz2d/import_data.rst +++ b/docs/specviz2d/import_data.rst @@ -9,6 +9,7 @@ as that allows the Python-level interface and parsing tools to be defined in ``s instead of being duplicated in Jdaviz. :class:`~specutils.Spectrum1D` objects are very flexible in their capabilities, however, and hence should address most astronomical spectrum use cases. +If you are creating your own data products, please read the page :ref:`create_products`. .. seealso:: @@ -56,7 +57,7 @@ notebook can access the Specviz2D helper class API. Using this API, users can load data into the application through code with the :meth:`~jdaviz.configs.specviz2d.helper.Specviz2d.load_data` method, which takes as input a :class:`~specutils.Spectrum1D` object or filename for the -2D spectrum and (optionally) the 1D spectrum. +2D spectrum and (optionally) the 1D spectrum. By default, extension 1 of the 2D file is loaded, but you can specify another extension by providing an integer @@ -66,4 +67,4 @@ the spectrum to be horizontal: .. code-block:: python - specviz2d.load_data(fn, ext=7, transpose=True) \ No newline at end of file + specviz2d.load_data(fn, ext=7, transpose=True) From beb45e061207fe42c0e6f339a875d313e9af8ef5 Mon Sep 17 00:00:00 2001 From: "P. L. Lim" <2090236+pllim@users.noreply.github.com> Date: Fri, 12 May 2023 18:04:38 -0400 Subject: [PATCH 37/42] FEAT: Load annulus from file and allow IMPORT DATA to load reg files. Annulus support provided by glue-viz/glue#2403 and glue-viz/glue-astronomy#92 Add test for exception. Bump minimum requirements for glue-core and glue-astronomy. --- CHANGES.rst | 5 ++ docs/imviz/import_data.rst | 3 + jdaviz/configs/imviz/plugins/parsers.py | 5 ++ .../imviz/tests/data/ds9_annulus_01.reg | 4 ++ jdaviz/configs/imviz/tests/test_regions.py | 55 +++++++++++-------- jdaviz/core/helpers.py | 23 +++++--- jdaviz/core/region_translators.py | 9 ++- pyproject.toml | 4 +- 8 files changed, 74 insertions(+), 34 deletions(-) create mode 100644 jdaviz/configs/imviz/tests/data/ds9_annulus_01.reg diff --git a/CHANGES.rst b/CHANGES.rst index 79a9e43eaf..1da7311aa3 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -12,6 +12,11 @@ Cubeviz Imviz ^^^^^ +- Added the ability to load DS9 region files (``.reg``) using the ``IMPORT DATA`` + button. However, this only works after loading at least one image into Imviz. [#2201] + +- Added support for new ``CircularAnnulusROI`` subset from glue. [#2201] + Mosviz ^^^^^^ diff --git a/docs/imviz/import_data.rst b/docs/imviz/import_data.rst index 82ff507764..6d23609109 100644 --- a/docs/imviz/import_data.rst +++ b/docs/imviz/import_data.rst @@ -43,6 +43,9 @@ application. A notification will appear to let users know if the data import was successful. Afterward, the new data set can be found in the :guilabel:`Data` tab of each viewer's options menu as described in :ref:`cubeviz-selecting-data`. +Once data is loaded, you may use the :guilabel:`Import Data` button again +to load regions from a ``.reg`` file; also see :ref:`imviz-import-regions-api`. + .. _imviz-import-api: Importing data via the API diff --git a/jdaviz/configs/imviz/plugins/parsers.py b/jdaviz/configs/imviz/plugins/parsers.py index 4789830bc1..39b1068528 100644 --- a/jdaviz/configs/imviz/plugins/parsers.py +++ b/jdaviz/configs/imviz/plugins/parsers.py @@ -82,6 +82,11 @@ def parse_data(app, file_obj, ext=None, data_label=None): ) with rdd.open(file_obj) as pf: _parse_image(app, pf, data_label, ext=ext) + + elif file_obj_lower.endswith('.reg'): + # This will load DS9 regions as Subset but only if there is already data. + app._jdaviz_helper.load_regions_from_file(file_obj) + else: # Assume FITS with fits.open(file_obj) as pf: _parse_image(app, pf, data_label, ext=ext) diff --git a/jdaviz/configs/imviz/tests/data/ds9_annulus_01.reg b/jdaviz/configs/imviz/tests/data/ds9_annulus_01.reg new file mode 100644 index 0000000000..b4d5144aa2 --- /dev/null +++ b/jdaviz/configs/imviz/tests/data/ds9_annulus_01.reg @@ -0,0 +1,4 @@ +# Region file format: DS9 version 4.1 +global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 +icrs +annulus(197.8929,-1.36599,1.9820003",3.9640007",5.946001") # color=magenta font="helvetica 10 bold roman" text={Annulus} diff --git a/jdaviz/configs/imviz/tests/test_regions.py b/jdaviz/configs/imviz/tests/test_regions.py index 38a60fbc78..145ed2f1ad 100644 --- a/jdaviz/configs/imviz/tests/test_regions.py +++ b/jdaviz/configs/imviz/tests/test_regions.py @@ -1,9 +1,8 @@ -import glue_astronomy import numpy as np +import pytest from astropy import units as u from astropy.coordinates import SkyCoord, Angle from astropy.utils.data import get_pkg_data_filename -from packaging.version import Version from photutils.aperture import CircularAperture, SkyCircularAperture from regions import (PixCoord, CircleSkyRegion, RectanglePixelRegion, CirclePixelRegion, EllipsePixelRegion, PointSkyRegion, PolygonPixelRegion, @@ -11,8 +10,6 @@ from jdaviz.configs.imviz.tests.utils import BaseImviz_WCS_NoWCS -GLUE_ASTRONOMY_LT_0_7_1 = not (Version(glue_astronomy.__version__) >= Version("0.7.1.dev")) - class BaseRegionHandler: """Test to see if region is loaded. @@ -122,13 +119,15 @@ def test_regions_sky_has_wcs(self): self.imviz._apply_interactive_region('bqplot:circle', (1.5, 2.5), (3.6, 4.6)) sky = SkyCoord(ra=337.5202808, dec=-20.833333059999998, unit='deg') - # This will become indistinguishable from normal Subset. + # These will become indistinguishable from normal Subset. my_reg_sky_1 = CircleSkyRegion(sky, Angle(0.5, u.arcsec)) - # Masked subset. my_reg_sky_2 = CircleAnnulusSkyRegion(center=sky, inner_radius=0.0004 * u.deg, outer_radius=0.0005 * u.deg) - # Add them both. - bad_regions = self.imviz.load_regions([my_reg_sky_1, my_reg_sky_2], return_bad_regions=True) + # Masked subset. + my_reg_sky_3 = PolygonPixelRegion(vertices=PixCoord(x=[1, 1, 3, 3, 1], y=[1, 3, 3, 1, 1])) + # Add them all. + bad_regions = self.imviz.load_regions([my_reg_sky_1, my_reg_sky_2, my_reg_sky_3], + return_bad_regions=True) assert len(bad_regions) == 0 # Mimic interactive regions (after) @@ -139,15 +138,28 @@ def test_regions_sky_has_wcs(self): # that check hopefully is already done in glue-astronomy. # Apparently, static region ate up one number... subsets = self.imviz.get_interactive_regions() - assert list(subsets.keys()) == ['Subset 1', 'Subset 2', 'Subset 4', 'Subset 5'], subsets + assert list(subsets.keys()) == ['Subset 1', 'Subset 2', 'Subset 3', 'Subset 5', 'Subset 6'], subsets # noqa: E501 assert isinstance(subsets['Subset 1'], CirclePixelRegion) assert isinstance(subsets['Subset 2'], CirclePixelRegion) - assert isinstance(subsets['Subset 4'], EllipsePixelRegion) - assert isinstance(subsets['Subset 5'], RectanglePixelRegion) + assert isinstance(subsets['Subset 3'], CircleAnnulusPixelRegion) + assert isinstance(subsets['Subset 5'], EllipsePixelRegion) + assert isinstance(subsets['Subset 6'], RectanglePixelRegion) # Check static region self.verify_region_loaded('MaskedSubset 1') + def test_regions_annulus_from_load_data(self): + # This file actually will load 2 annuli + regfile = get_pkg_data_filename('data/ds9_annulus_01.reg') + self.imviz.load_data(regfile) + assert len(self.imviz.app.data_collection) == 2 # Make sure not loaded as data + + subsets = self.imviz.get_interactive_regions() + subset_names = list(subsets.keys()) + assert subset_names == ['Subset 1', 'Subset 2'] + for n in subset_names: + assert isinstance(subsets[n], CircleAnnulusPixelRegion) + def test_photutils_pixel(self): my_aper = CircularAperture((5, 5), r=2) bad_regions = self.imviz.load_regions([my_aper], return_bad_regions=True) @@ -173,18 +185,21 @@ def setup_class(self): self.raw_regions = Regions.read(self.region_file, format='ds9') def test_ds9_load_all(self, imviz_helper): + with pytest.raises(ValueError, match="Cannot load regions without data"): + imviz_helper.load_data(self.region_file) + self.viewer = imviz_helper.default_viewer imviz_helper.load_data(self.arr, data_label='my_image') bad_regions = imviz_helper.load_regions_from_file(self.region_file, return_bad_regions=True) assert len(bad_regions) == 1 - # Will load 8/9 and 6 of that become ROIs. + # Will load 8/9 and 7 of that become ROIs. subsets = imviz_helper.get_interactive_regions() assert list(subsets.keys()) == ['Subset 1', 'Subset 2', 'Subset 3', - 'Subset 4', 'Subset 5', 'Subset 6'], subsets + 'Subset 4', 'Subset 5', 'Subset 6', 'Subset 7'], subsets - for i in (1, 2): # The other 2 are MaskedSubset - self.verify_region_loaded(f'MaskedSubset {i}', count=1) + # The other 1 is MaskedSubset + self.verify_region_loaded('MaskedSubset 1', count=1) def test_ds9_load_two_good(self, imviz_helper): self.viewer = imviz_helper.default_viewer @@ -234,18 +249,12 @@ def test_annulus(self): new_subset = subset_groups[0].subset_state & ~subset_groups[1].subset_state self.viewer.apply_subset_state(new_subset) - # In older glue-astronomy, annulus is no longer accessible by API - # but also should not crash Imviz. subsets = self.imviz.get_interactive_regions() assert len(self.imviz.app.data_collection.subset_groups) == 3 - if GLUE_ASTRONOMY_LT_0_7_1: - expected_subset_keys = ['Subset 1', 'Subset 2'] - else: - expected_subset_keys = ['Subset 1', 'Subset 2', 'Subset 3'] - assert isinstance(subsets['Subset 3'], CircleAnnulusPixelRegion) - assert list(subsets.keys()) == expected_subset_keys, subsets + assert list(subsets.keys()) == ['Subset 1', 'Subset 2', 'Subset 3'], subsets assert isinstance(subsets['Subset 1'], CirclePixelRegion) assert isinstance(subsets['Subset 2'], CirclePixelRegion) + assert isinstance(subsets['Subset 3'], CircleAnnulusPixelRegion) # Clear the regions for next test. self.imviz._delete_all_regions() diff --git a/jdaviz/core/helpers.py b/jdaviz/core/helpers.py index 7a4c171fcd..c6dc0fb457 100644 --- a/jdaviz/core/helpers.py +++ b/jdaviz/core/helpers.py @@ -658,12 +658,17 @@ def load_regions(self, regions, max_num_regions=None, refdata_label=None, If not requested, return `None`. """ + if len(self.app.data_collection) == 0: + raise ValueError('Cannot load regions without data.') + from photutils.aperture import (CircularAperture, SkyCircularAperture, EllipticalAperture, SkyEllipticalAperture, - RectangularAperture, SkyRectangularAperture) + RectangularAperture, SkyRectangularAperture, + CircularAnnulus, SkyCircularAnnulus) from regions import (Regions, CirclePixelRegion, CircleSkyRegion, EllipsePixelRegion, EllipseSkyRegion, - RectanglePixelRegion, RectangleSkyRegion) + RectanglePixelRegion, RectangleSkyRegion, + CircleAnnulusPixelRegion, CircleAnnulusSkyRegion) from jdaviz.core.region_translators import regions2roi, aperture2regions # If user passes in one region obj instead of list, try to be smart. @@ -688,23 +693,27 @@ def load_regions(self, regions, max_num_regions=None, refdata_label=None, has_wcs = data_has_valid_wcs(data, ndim=2) for region in regions: - if isinstance(region, (SkyCircularAperture, SkyEllipticalAperture, - SkyRectangularAperture, CircleSkyRegion, - EllipseSkyRegion, RectangleSkyRegion)) and not has_wcs: + if (isinstance(region, (SkyCircularAperture, SkyEllipticalAperture, + SkyRectangularAperture, SkyCircularAnnulus, + CircleSkyRegion, EllipseSkyRegion, + RectangleSkyRegion, CircleAnnulusSkyRegion)) + and not has_wcs): bad_regions.append((region, 'Sky region provided but data has no valid WCS')) continue # photutils: Convert to regions shape first if isinstance(region, (CircularAperture, SkyCircularAperture, EllipticalAperture, SkyEllipticalAperture, - RectangularAperture, SkyRectangularAperture)): + RectangularAperture, SkyRectangularAperture, + CircularAnnulus, SkyCircularAnnulus)): region = aperture2regions(region) # regions: Convert to ROI. # NOTE: Out-of-bounds ROI will succeed; this is native glue behavior. if isinstance(region, (CirclePixelRegion, CircleSkyRegion, EllipsePixelRegion, EllipseSkyRegion, - RectanglePixelRegion, RectangleSkyRegion)): + RectanglePixelRegion, RectangleSkyRegion, + CircleAnnulusPixelRegion, CircleAnnulusSkyRegion)): state = regions2roi(region, wcs=data.coords) # TODO: Do we want user to specify viewer? Does it matter? diff --git a/jdaviz/core/region_translators.py b/jdaviz/core/region_translators.py index 17e6d3defe..df1d277fb0 100644 --- a/jdaviz/core/region_translators.py +++ b/jdaviz/core/region_translators.py @@ -3,7 +3,7 @@ """ from astropy import units as u from astropy.coordinates import Angle -from glue.core.roi import CircularROI, EllipticalROI, RectangularROI +from glue.core.roi import CircularROI, EllipticalROI, RectangularROI, CircularAnnulusROI from photutils.aperture import (CircularAperture, SkyCircularAperture, EllipticalAperture, SkyEllipticalAperture, RectangularAperture, SkyRectangularAperture, @@ -115,7 +115,8 @@ def regions2roi(region_shape, wcs=None): """ - if isinstance(region_shape, (CircleSkyRegion, EllipseSkyRegion, RectangleSkyRegion)): + if isinstance(region_shape, (CircleSkyRegion, EllipseSkyRegion, RectangleSkyRegion, + CircleAnnulusSkyRegion)): if wcs is None: raise ValueError(f'WCS must be provided for {region_shape}') @@ -140,6 +141,10 @@ def regions2roi(region_shape, wcs=None): roi = RectangularROI( xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, theta=region_shape.angle.to_value(u.radian)) + elif isinstance(region_shape, CircleAnnulusPixelRegion): + roi = CircularAnnulusROI( + xc=region_shape.center.x, yc=region_shape.center.y, + inner_radius=region_shape.inner_radius, outer_radius=region_shape.outer_radius) else: raise NotImplementedError(f'{region_shape.__class__.__name__} is not supported') diff --git a/pyproject.toml b/pyproject.toml index ebd23f4b9e..f80d3aa37e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ dependencies = [ "traitlets>=5.0.5", "bqplot>=0.12.37", "bqplot-image-gl>=1.4.11", - "glue-core>=1.6.0,!=1.9.0,!=1.10", + "glue-core>=1.11", "glue-jupyter>=0.15.0", "echo>=0.5.0", "ipykernel>=6.19.4", @@ -26,7 +26,7 @@ dependencies = [ "specutils>=1.9", "specreduce>=1.3.0,<1.4.0", "photutils>=1.4", - "glue-astronomy>=0.7", + "glue-astronomy>=0.9", "asteval>=0.9.23", "idna", "vispy>=0.6.5", From e0a1fd68f2e940d2882b459f511f91c2a9fa3726 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Tue, 6 Jun 2023 09:14:25 -0400 Subject: [PATCH 38/42] disallow gaussian smooth output as input --- CHANGES.rst | 3 +++ .../configs/default/plugins/gaussian_smooth/gaussian_smooth.py | 2 ++ .../plugins/gaussian_smooth/tests/test_gaussian_smooth.py | 2 +- jdaviz/core/template_mixin.py | 3 +++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 79a9e43eaf..be79e70cd8 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -60,6 +60,9 @@ Specviz2d Other Changes and Additions --------------------------- +- Gaussian smooth plugin excludes results from the gaussian smooth plugin from the input + dataset dropdown. [#2239] + 3.5.1 (unreleased) ================== diff --git a/jdaviz/configs/default/plugins/gaussian_smooth/gaussian_smooth.py b/jdaviz/configs/default/plugins/gaussian_smooth/gaussian_smooth.py index 09e3b0eb5e..3142843f56 100644 --- a/jdaviz/configs/default/plugins/gaussian_smooth/gaussian_smooth.py +++ b/jdaviz/configs/default/plugins/gaussian_smooth/gaussian_smooth.py @@ -71,6 +71,8 @@ def __init__(self, *args, **kwargs): self.dataset._viewers = [self._default_spectrum_viewer_reference_name] self.dataset._clear_cache() + self.dataset.add_filter('not_from_this_plugin') + self.mode = SelectPluginComponent(self, items='mode_items', selected='mode_selected', diff --git a/jdaviz/configs/default/plugins/gaussian_smooth/tests/test_gaussian_smooth.py b/jdaviz/configs/default/plugins/gaussian_smooth/tests/test_gaussian_smooth.py index 7bed9fcd15..4c6cb0574e 100644 --- a/jdaviz/configs/default/plugins/gaussian_smooth/tests/test_gaussian_smooth.py +++ b/jdaviz/configs/default/plugins/gaussian_smooth/tests/test_gaussian_smooth.py @@ -40,7 +40,7 @@ def test_linking_after_spectral_smooth(cubeviz_helper, spectrum1d_cube): # The data label used to be prepended to the results_label ONLY if there were multiple # smoothed spectra. As of PR#1973, POs requested the data label to always be present. # As a result, label will overwrite here - assert len(gs.dataset_items) == 2 + assert len(gs.dataset_items) == 1 assert gs.dataset_selected == f'{data_label}[FLUX]' assert gs.results_label == f'{data_label}[FLUX] spectral-smooth stddev-3.2' assert gs.results_label_overwrite is True diff --git a/jdaviz/core/template_mixin.py b/jdaviz/core/template_mixin.py index 3f61217d18..c36967ad30 100644 --- a/jdaviz/core/template_mixin.py +++ b/jdaviz/core/template_mixin.py @@ -1496,6 +1496,9 @@ def _is_valid_item(self, data): def not_from_plugin(data): return data.meta.get('Plugin', None) is None + def not_from_this_plugin(data): + return data.meta.get('Plugin', None) != self.plugin.__class__.__name__ + def not_from_plugin_model_fitting(data): return data.meta.get('Plugin', None) != 'ModelFitting' From f530f527be337aa16bf7a35b9336e367b203b264 Mon Sep 17 00:00:00 2001 From: "P. L. Lim" <2090236+pllim@users.noreply.github.com> Date: Wed, 7 Jun 2023 12:27:19 -0400 Subject: [PATCH 39/42] BUG: Fix ellipse translation in app.get_subsets() --- CHANGES.rst | 2 ++ jdaviz/app.py | 2 +- jdaviz/tests/test_subsets.py | 10 +++++----- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index be79e70cd8..379ce4b3bd 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -42,6 +42,8 @@ Specviz2d Bug Fixes --------- +- Fixed wrong elliptical region translation in ``app.get_subsets()``. [#2244] + Cubeviz ^^^^^^^ diff --git a/jdaviz/app.py b/jdaviz/app.py index d2d3d9c217..f7c42c7726 100644 --- a/jdaviz/app.py +++ b/jdaviz/app.py @@ -1006,7 +1006,7 @@ def _get_roi_subset_definition(self, subset_state): rx = roi.radius_x ry = roi.radius_y theta = np.around(np.degrees(roi.theta), decimals=_around_decimals) - roi_as_region = EllipsePixelRegion(PixCoord(xc, yc), rx, ry, Angle(theta, "deg")) + roi_as_region = EllipsePixelRegion(PixCoord(xc, yc), rx * 2, ry * 2, Angle(theta, "deg")) # noqa: E501 return [{"name": subset_state.roi.__class__.__name__, "glue_state": subset_state.__class__.__name__, diff --git a/jdaviz/tests/test_subsets.py b/jdaviz/tests/test_subsets.py index 76e8ef3b1d..bf4f14d976 100644 --- a/jdaviz/tests/test_subsets.py +++ b/jdaviz/tests/test_subsets.py @@ -332,7 +332,7 @@ def test_composite_region_from_subset_3d(cubeviz_helper): viewer.apply_roi(EllipticalROI(30, 30, 3, 6)) reg = cubeviz_helper.app.get_subsets("Subset 1") ellipse1 = EllipsePixelRegion(center=PixCoord(x=30, y=30), - width=3, height=6, angle=0.0 * u.deg) + width=6, height=12, angle=0.0 * u.deg) assert reg[-1] == {'name': 'EllipticalROI', 'glue_state': 'OrState', 'region': ellipse1, 'subset_state': reg[-1]['subset_state']} @@ -384,18 +384,18 @@ def test_composite_region_with_consecutive_and_not_states(cubeviz_helper): viewer.apply_roi(EllipticalROI(30, 30, 3, 6)) reg = cubeviz_helper.app.get_subsets("Subset 1") ellipse1 = EllipsePixelRegion(center=PixCoord(x=30, y=30), - width=3, height=6, angle=0.0 * u.deg) + width=6, height=12, angle=0.0 * u.deg) assert reg[-1] == {'name': 'EllipticalROI', 'glue_state': 'AndNotState', 'region': ellipse1, 'subset_state': reg[-1]['subset_state']} regions_list = cubeviz_helper.app.get_subsets("Subset 1", object_only=True) assert len(regions_list) == 3 - assert regions_list[-1].width == 3 + assert regions_list[-1].width == 6 regions_list = cubeviz_helper.app.get_subsets("Subset 1", spatial_only=True, object_only=True) assert len(regions_list) == 3 - assert regions_list[-1].width == 3 + assert regions_list[-1].width == 6 spatial_list = cubeviz_helper.app.get_subsets("Subset 1", spatial_only=True) assert len(spatial_list) == 3 @@ -446,7 +446,7 @@ def test_composite_region_with_imviz(imviz_helper, image_2d_wcs): viewer.apply_roi(EllipticalROI(3, 3, 3, 6)) reg = imviz_helper.app.get_subsets("Subset 1") ellipse1 = EllipsePixelRegion(center=PixCoord(x=3, y=3), - width=3, height=6, angle=0.0 * u.deg) + width=6, height=12, angle=0.0 * u.deg) assert reg[-1] == {'name': 'EllipticalROI', 'glue_state': 'AndNotState', 'region': ellipse1, 'subset_state': reg[-1]['subset_state']} From ba01f97a58dfd157bff4fb20d5bf66a8dc7da186 Mon Sep 17 00:00:00 2001 From: "P. L. Lim" <2090236+pllim@users.noreply.github.com> Date: Thu, 8 Jun 2023 11:38:43 -0400 Subject: [PATCH 40/42] DOC: Use pydata-sphinx-theme (#2243) * DOC: Use pydata-sphinx-theme that has dark mode, modern design, and mobile friendly DOC: No longer need tomli DOC: Now requires sphinx-astropy 1.9.1 * Add cards to index page with icons * Remove iframe hardcoding so it scales in mobile mode * DOC: Insert small logo next to title instead of a giant logo above the title --- .readthedocs.yaml | 4 +- docs/_static/jdaviz.css | 74 ++++++++++ docs/conf.py | 101 +++++++------ docs/cubeviz/examples.rst | 8 +- docs/cubeviz/index.rst | 11 +- docs/dev/index.rst | 6 +- docs/imviz/examples.rst | 10 +- docs/imviz/index.rst | 10 +- docs/index.rst | 235 +++++++++--------------------- docs/index_citation.rst | 25 ++++ docs/index_jwst_modes.rst | 145 ++++++++++++++++++ docs/index_ref_api.rst | 11 ++ docs/index_using_jdaviz.rst | 21 +++ docs/mosviz/index.rst | 11 +- docs/reference/api.rst | 230 +++-------------------------- docs/reference/api_configs.rst | 22 +++ docs/reference/api_nuts_bolts.rst | 87 +++++++++++ docs/reference/api_parsers.rst | 19 +++ docs/reference/api_plugins.rst | 85 +++++++++++ docs/reference/api_viewers.rst | 19 +++ docs/specviz/examples.rst | 6 +- docs/specviz/index.rst | 10 +- docs/specviz2d/index.rst | 10 +- pyproject.toml | 7 +- 24 files changed, 691 insertions(+), 476 deletions(-) create mode 100644 docs/_static/jdaviz.css create mode 100644 docs/index_citation.rst create mode 100644 docs/index_jwst_modes.rst create mode 100644 docs/index_ref_api.rst create mode 100644 docs/index_using_jdaviz.rst create mode 100644 docs/reference/api_configs.rst create mode 100644 docs/reference/api_nuts_bolts.rst create mode 100644 docs/reference/api_parsers.rst create mode 100644 docs/reference/api_plugins.rst create mode 100644 docs/reference/api_viewers.rst diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 2d4d2bdb88..9c73b7145f 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -1,11 +1,11 @@ version: 2 build: - os: ubuntu-20.04 + os: ubuntu-22.04 apt_packages: - graphviz tools: - python: "3.9" + python: "3.11" jobs: post_checkout: # Use `git log` to check if the latest commit contains "skip rtd" or "rtd skip", diff --git a/docs/_static/jdaviz.css b/docs/_static/jdaviz.css new file mode 100644 index 0000000000..94ff946b6f --- /dev/null +++ b/docs/_static/jdaviz.css @@ -0,0 +1,74 @@ +/* Main page overview cards */ + +.sd-card { + background: #fff; + border-radius: 0; + padding: 30px 10px 20px 10px; + margin: 10px 0px; +} + +.sd-card .sd-card-header { + text-align: center; +} + +.sd-card .sd-card-header .sd-card-text { + margin: 0px; +} + +.sd-card .sd-card-img-top { + height: 52px; + width: 52px; + margin-left: auto; + margin-right: auto; +} + +.sd-card .sd-card-header { + border: none; + background-color: white; + color: #150458 !important; + font-size: var(--pst-font-size-h5); + font-weight: bold; + padding: 2.5rem 0rem 0.5rem 0rem; +} + +.sd-card .sd-card-footer { + border: none; + background-color: white; +} + +.sd-card .sd-card-footer .sd-card-text { + max-width: 220px; + margin-left: auto; + margin-right: auto; +} + +/* Dark theme tweaking */ +html[data-theme=dark] .sd-card img[src*='.svg'] { + filter: invert(0.82) brightness(0.8) contrast(1.2); +} + +/* Main index page overview cards */ +html[data-theme=dark] .sd-card { + background-color:var(--pst-color-background); +} + +html[data-theme=dark] .sd-shadow-sm { + box-shadow: 0 .1rem 1rem rgba(250, 250, 250, .6) !important +} + +html[data-theme=dark] .sd-card .sd-card-header { + background-color:var(--pst-color-background); + color: #150458 !important; +} + +html[data-theme=dark] .sd-card .sd-card-footer { + background-color:var(--pst-color-background); +} + +html[data-theme=dark] h1 { + color: var(--pst-color-primary); +} + +html[data-theme=dark] h3 { + color: #0a6774; +} diff --git a/docs/conf.py b/docs/conf.py index b450ac9fd3..8f06459b9a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -25,34 +25,24 @@ # Thus, any C-extensions that are needed to build the documentation will *not* # be accessible, and the documentation will not build correctly. -import os import sys import datetime -import importlib.metadata as importlib_metadata -from pathlib import Path - -if sys.version_info < (3, 11): - import tomli as tomllib -else: - import tomllib +from jdaviz import __version__ try: - from sphinx_astropy.conf.v1 import * # noqa + from sphinx_astropy.conf.v2 import * # noqa except ImportError: print('ERROR: the documentation requires the sphinx-astropy package to be installed') sys.exit(1) -with open(Path(__file__).parent.parent / "pyproject.toml", "rb") as configuration_file: - metadata = tomllib.load(configuration_file) - # -- General configuration ---------------------------------------------------- # By default, highlight as Python 3. highlight_language = 'python3' # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.2' +# needs_sphinx = '1.2' # To perform a Sphinx version check that needs to be more specific than # major.minor, call `check_sphinx_version("x.y.z")` here. @@ -60,7 +50,7 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns.append('_templates') +exclude_patterns.append('_templates') # noqa: F405 # This is added to the end of RST files - a good place to put substitutions to # be used globally. @@ -134,13 +124,13 @@ .. |icon-viewer-data-select| image:: /img/icons/viewer_data_select.png :scale: 30 :alt: data select icon -""" +""" # noqa: F405 # -- Project information ------------------------------------------------------ # This does not *have* to match the package name, but typically does -project = metadata['project']['name'] -author = metadata['project']['authors'][0]['name'] +project = "jdaviz" +author = "JDADF Developers" copyright = '{0}, {1}'.format( datetime.datetime.now().year, author) @@ -149,15 +139,15 @@ # built documents. # The full version, including alpha/beta/rc tags. -release = importlib_metadata.version(project) +release = __version__ +dev = "dev" in release # The short X.Y version. version = '.'.join(release.split('.')[:2]) -extensions += ['sphinx.ext.extlinks'] +extensions += ['sphinx.ext.extlinks', 'sphinx_design'] # noqa: F405 gh_tag = f'v{release}' if '.dev' not in release else 'main' extlinks = {'gh-tree': (f'https://github.com/spacetelescope/jdaviz/tree/{gh_tag}/%s', '%s'), - 'gh-notebook': (f'https://github.com/spacetelescope/jdaviz/blob/{gh_tag}/notebooks/%s.ipynb', - '%s notebook')} + 'gh-notebook': (f'https://github.com/spacetelescope/jdaviz/blob/{gh_tag}/notebooks/%s.ipynb', '%s notebook')} # noqa: E501 # -- Options for HTML output -------------------------------------------------- @@ -168,33 +158,54 @@ # variables set in the global configuration. The variables set in the # global configuration are listed below, commented out. +html_css_files = ["jdaviz.css"] +html_copy_source = False + +html_theme_options.update( # noqa: F405 + { + "github_url": "https://github.com/spacetelescope/jdaviz", + "external_links": [ + {"name": "Help Desk", "url": "http://jwsthelp.stsci.edu/"}, + ], + "use_edit_page_button": True, + } +) + +html_context = { + "default_mode": "light", + "to_be_indexed": ["stable", "latest"], + "is_development": dev, + "github_user": "spacetelescope", + "github_repo": "jdaviz", + "github_version": "main", + "doc_path": "docs", +} # Add any paths that contain custom themes here, relative to this directory. # To use a different custom theme, add the directory containing the theme. -#html_theme_path = [] +# html_theme_path = [] # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. To override the custom theme, set this to the # name of a builtin theme or the name of a custom theme in html_theme_path. -#html_theme = None -html_theme = "sphinx_rtd_theme" +# html_theme = "sphinx_rtd_theme" # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = '' +html_logo = 'logos/jdaviz.svg' # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = '' +html_favicon = 'logos/specviz2d.ico' # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '' +# html_last_updated_fmt = '' # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". @@ -220,21 +231,6 @@ [author], 1)] -# -- Options for the edit_on_github extension --------------------------------- - -if metadata['tool']['build_sphinx']['edit_on_github']: - - extensions += ['sphinx_astropy.ext.edit_on_github'] - - edit_on_github_project = metadata['tool']['build_sphinx']['github_project'] - edit_on_github_branch = "main" - - edit_on_github_source_root = "" - edit_on_github_doc_root = "docs" - -# -- Resolving issue number to links in changelog ----------------------------- -github_issues_url = 'https://github.com/{0}/issues/'.format(metadata['tool']['build_sphinx']['github_project']) - # -- Turn on nitpicky mode for sphinx (to warn about references not found) ---- nitpicky = True @@ -263,15 +259,16 @@ nitpick_ignore.append((dtype, target)) # Extra intersphinx in addition to what is already in sphinx-astropy -intersphinx_mapping['glue'] = ('http://docs.glueviz.org/en/stable/', None) -intersphinx_mapping['glue_jupyter'] = ('https://glue-jupyter.readthedocs.io/en/stable/', None) -intersphinx_mapping['regions'] = ('https://astropy-regions.readthedocs.io/en/stable/', None) -intersphinx_mapping['skimage'] = ('https://scikit-image.org/docs/stable/', None) -intersphinx_mapping['specutils'] = ('https://specutils.readthedocs.io/en/stable/', None) -intersphinx_mapping['specreduce'] = ('https://specreduce.readthedocs.io/en/stable/', None) -intersphinx_mapping['photutils'] = ('https://photutils.readthedocs.io/en/stable/', None) -intersphinx_mapping['traitlets'] = ('https://traitlets.readthedocs.io/en/stable/', None) -intersphinx_mapping['roman_datamodels'] = ('https://roman-datamodels.readthedocs.io/en/stable/', None) +intersphinx_mapping.update({ # noqa: F405 + 'glue': ('http://docs.glueviz.org/en/stable/', None), + 'glue_jupyter': ('https://glue-jupyter.readthedocs.io/en/stable/', None), + 'photutils': ('https://photutils.readthedocs.io/en/stable/', None), + 'regions': ('https://astropy-regions.readthedocs.io/en/stable/', None), + 'roman_datamodels': ('https://roman-datamodels.readthedocs.io/en/stable/', None), + 'skimage': ('https://scikit-image.org/docs/stable/', None), + 'specreduce': ('https://specreduce.readthedocs.io/en/stable/', None), + 'specutils': ('https://specutils.readthedocs.io/en/stable/', None), + 'traitlets': ('https://traitlets.readthedocs.io/en/stable/', None)}) # Options for linkcheck linkcheck_ignore = ['https://github.com/spacetelescope/jdaviz/settings/branches'] diff --git a/docs/cubeviz/examples.rst b/docs/cubeviz/examples.rst index 21e9119c61..dd029a38ad 100644 --- a/docs/cubeviz/examples.rst +++ b/docs/cubeviz/examples.rst @@ -18,25 +18,25 @@ Open and Explore a Cube .. raw:: html - + Selecting Subsets ================= .. raw:: html - + Model Fitting ============= .. raw:: html - + Line Analysis ============= .. raw:: html - + diff --git a/docs/cubeviz/index.rst b/docs/cubeviz/index.rst index 3683951423..3205126deb 100644 --- a/docs/cubeviz/index.rst +++ b/docs/cubeviz/index.rst @@ -1,12 +1,11 @@ - -.. image:: ../logos/cubeviz.svg - :width: 400 +.. |cubeviz_logo| image:: ../logos/cube.svg + :height: 42px .. _cubeviz: -####### -Cubeviz -####### +###################### +|cubeviz_logo| Cubeviz +###################### .. image:: https://stsci.box.com/shared/static/esod50xtbn07wvls1ia07urnr65tv2bj.gif :alt: Introductory video tour of the Cubeviz configuration and its features diff --git a/docs/dev/index.rst b/docs/dev/index.rst index 0429567a6d..043722ab82 100644 --- a/docs/dev/index.rst +++ b/docs/dev/index.rst @@ -1,6 +1,6 @@ -########## -Developers -########## +############### +Developer Guide +############### Here is some documentation specific for developers. diff --git a/docs/imviz/examples.rst b/docs/imviz/examples.rst index 7bbdf798fd..eca2ef12f4 100644 --- a/docs/imviz/examples.rst +++ b/docs/imviz/examples.rst @@ -18,32 +18,32 @@ Open Image Data .. raw:: html - + Overplotting a Catalog ====================== .. raw:: html - + Aligning Images =============== .. raw:: html - + Exploring the Plugin Toolbar ============================ .. raw:: html - + Aperture Photometry =================== .. raw:: html - + diff --git a/docs/imviz/index.rst b/docs/imviz/index.rst index 147ea78db4..5f0b030639 100644 --- a/docs/imviz/index.rst +++ b/docs/imviz/index.rst @@ -1,11 +1,11 @@ -.. image:: ../logos/imviz.svg - :width: 400 +.. |imviz_logo| image:: ../logos/imviz\ icon.svg + :height: 42px .. _imviz: -##### -Imviz -##### +################## +|imviz_logo| Imviz +################## .. image:: https://stsci.box.com/shared/static/56jhed2cqr3nr2w5a3e5gwwkvytmc00n.gif :alt: Introductory video tour of the Imviz configuration and its features diff --git a/docs/index.rst b/docs/index.rst index 075a1b26ba..af771a7dbf 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -2,8 +2,58 @@ Jdaviz ###### -.. image:: logos/jdaviz.svg - :width: 400 +.. grid:: 3 + :gutter: 1 + + .. grid-item-card:: + :img-top: logos/imviz\ icon.svg + + .. button-ref:: imviz/index + :expand: + :color: primary + :click-parent: + + Jump to Imviz + + .. grid-item-card:: + :img-top: logos/specicon.svg + + .. button-ref:: specviz/index + :expand: + :color: primary + :click-parent: + + Jump to Specviz + + .. grid-item-card:: + :img-top: logos/cube.svg + + .. button-ref:: cubeviz/index + :expand: + :color: primary + :click-parent: + + Jump to Cubeviz + + .. grid-item-card:: + :img-top: logos/specviz2d\ icon.svg + + .. button-ref:: specviz2d/index + :expand: + :color: primary + :click-parent: + + Jump to Specviz2D + + .. grid-item-card:: + :img-top: logos/mos.svg + + .. button-ref:: mosviz/index + :expand: + :color: primary + :click-parent: + + Jump to Mosviz ``jdaviz`` is a package of astronomical data analysis visualization tools based on the Jupyter platform. These GUI-based tools link data @@ -46,181 +96,38 @@ contextual information like on-sky views of the spectrograph slit. under the "Materials and Videos" expandable section. Scroll down to the bottom of that section to find materials from the most recent session (JWebbinar 24, March 2023). -.. _jdaviz_instrument_table: - -JWST Instrument Modes in Jdaviz -=============================== - -This tool is designed with instrument modes from the James Webb Space Telescope (JWST) in mind, but -the tool should be flexible enough to read in data from many astronomical telescopes. The table below -summarizes Jdaviz file support specific to JWST instrument modes. - -.. list-table:: JWST Instrument Modes in Jdaviz - :widths: 25 15 10 15 20 - :header-rows: 1 - - * - Instrument - - Template Mode - - File Type - - Pipeline Level - - Primary Configuration - * - NIRSpec - - MOS - - S2D - - 2b,3 - - Mosviz - * - - - - - X1D - - 2b,3 - - Specviz - * - - - IFU - - S3D - - 2b,3 - - Cubeviz - * - - - - - X1D - - 2b,3 - - Specviz - * - - - FS - - S2D - - 2b,3 - - Specviz2d - * - - - - - X1D - - 2b,3 - - Specviz - * - - - BOTS - - X1DINTS - - -- - - No Support - * - NIRISS - - IMAGING - - I2D - - 2b,3 - - Imviz - * - - - WFSS - - X1D - - 2b - - Specviz - * - - - AMI - - AMINORM - - -- - - No Support - * - - - SOSS - - X1DINTS - - -- - - No Support - * - NIRCam - - Imaging - - I2D - - 2b,3 - - Imviz - * - - - Coronagraphic Imaging - - I2D - - 2b,3 - - Imviz - * - - - WFSS - - X1D - - 2b - - Specviz - * - - - Grism TSO - - X1DINTS - - -- - - No Support - * - MIRI - - Imaging - - I2D - - 2b,3 - - Imviz - * - - - Coronagraphic Imaging - - I2D - - 2b,3 - - Imviz - * - - - LRS-slit - - S2D - - 2b,3 - - Specviz2d - * - - - - - X1D - - 2b,3 - - Specviz - * - - - LRS-slitless - - X1DINTS - - -- - - No Support - * - - - MRS - - S3D - - 2b,3 - - Cubeviz - * - - - - - X1D - - 2b, 3 - - Specviz - - +************ Using Jdaviz -============ +************ .. toctree:: :maxdepth: 2 - installation.rst - imviz/index.rst - specviz/index.rst - cubeviz/index.rst - specviz2d/index.rst - mosviz/index.rst - plugin_api.rst - save_state.rst - display.rst - sample_notebooks.rst - create_products.rst - -Reference/API -============= + index_using_jdaviz + +******************************* +JWST Instrument Modes in Jdaviz +******************************* .. toctree:: - :maxdepth: 2 + :maxdepth: 2 - dev/index.rst - reference/api.rst + index_jwst_modes -Additional documentation -======================== +***************** +Development Guide +***************** .. toctree:: - :maxdepth: 1 + :maxdepth: 2 - known_bugs.rst + index_ref_api +********************* License & Attribution -===================== +********************* -This project is Copyright (c) JDADF Developers and licensed under -the terms of the BSD 3-Clause license. - -This package is based upon -the `Astropy package template `_ -which is licensed under the BSD 3-clause licence. See the -`licenses `_ -folder for more information. +.. toctree:: + :maxdepth: 2 -Cite ``jdaviz`` via our Zenodo record: https://doi.org/10.5281/zenodo.5513927. + index_citation diff --git a/docs/index_citation.rst b/docs/index_citation.rst new file mode 100644 index 0000000000..5a277e10d1 --- /dev/null +++ b/docs/index_citation.rst @@ -0,0 +1,25 @@ +.. _cite-jdaviz: + +******** +Citation +******** + +Cite Us +======= + +If you use ``jdaviz``, please cite us via our Zenodo record: |Zenodo| + +.. |Zenodo| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.5513927.svg + :target: https://doi.org/10.5281/zenodo.5513927 + +License +======= + +This project is Copyright (c) JDADF Developers and licensed under +the terms of the BSD 3-Clause license. + +This package is based upon +the `Astropy package template `_ +which is licensed under the BSD 3-clause licence. See the +`licenses `_ +folder for more information. diff --git a/docs/index_jwst_modes.rst b/docs/index_jwst_modes.rst new file mode 100644 index 0000000000..ff1e901ba3 --- /dev/null +++ b/docs/index_jwst_modes.rst @@ -0,0 +1,145 @@ +.. _jdaviz_instrument_table: + +********** +JWST Modes +********** + +This tool is designed with instrument modes from the James Webb Space Telescope (JWST) in mind, but +the tool should be flexible enough to read in data from many astronomical telescopes. The table below +summarizes Jdaviz file support specific to JWST instrument modes. + +NIRSpec +======= + +.. list-table:: JWST/NIRSpec Instrument Modes in Jdaviz + :widths: 15 10 15 20 + :header-rows: 1 + + * - Template Mode + - File Type + - Pipeline Level + - Primary Configuration + * - MOS + - S2D + - 2b,3 + - Mosviz + * - + - X1D + - 2b,3 + - Specviz + * - IFU + - S3D + - 2b,3 + - Cubeviz + * - + - X1D + - 2b,3 + - Specviz + * - FS + - S2D + - 2b,3 + - Specviz2d + * - + - X1D + - 2b,3 + - Specviz + * - BOTS + - X1DINTS + - -- + - No Support + +NIRISS +====== + +.. list-table:: JWST/NIRISS Instrument Modes in Jdaviz + :widths: 15 10 15 20 + :header-rows: 1 + + * - Template Mode + - File Type + - Pipeline Level + - Primary Configuration + * - IMAGING + - I2D + - 2b,3 + - Imviz + * - WFSS + - X1D + - 2b + - Specviz + * - AMI + - AMINORM + - -- + - No Support + * - SOSS + - X1DINTS + - -- + - No Support + +NIRCam +====== + +.. list-table:: JWST/NIRCam Instrument Modes in Jdaviz + :widths: 15 10 15 20 + :header-rows: 1 + + * - Template Mode + - File Type + - Pipeline Level + - Primary Configuration + * - Imaging + - I2D + - 2b,3 + - Imviz + * - Coronagraphic Imaging + - I2D + - 2b,3 + - Imviz + * - WFSS + - X1D + - 2b + - Specviz + * - Grism TSO + - X1DINTS + - -- + - No Support + +MIRI +==== + +.. list-table:: JWST/MIRI Instrument Modes in Jdaviz + :widths: 15 10 15 20 + :header-rows: 1 + + * - Template Mode + - File Type + - Pipeline Level + - Primary Configuration + * - Imaging + - I2D + - 2b,3 + - Imviz + * - Coronagraphic Imaging + - I2D + - 2b,3 + - Imviz + * - LRS-slit + - S2D + - 2b,3 + - Specviz2d + * - + - X1D + - 2b,3 + - Specviz + * - LRS-slitless + - X1DINTS + - -- + - No Support + * - MRS + - S3D + - 2b,3 + - Cubeviz + * - + - X1D + - 2b, 3 + - Specviz diff --git a/docs/index_ref_api.rst b/docs/index_ref_api.rst new file mode 100644 index 0000000000..b981598b1a --- /dev/null +++ b/docs/index_ref_api.rst @@ -0,0 +1,11 @@ +.. _jdaviz-dev: + +********** +Developers +********** + +.. toctree:: + :maxdepth: 2 + + dev/index + reference/api diff --git a/docs/index_using_jdaviz.rst b/docs/index_using_jdaviz.rst new file mode 100644 index 0000000000..9aa9c9ab9f --- /dev/null +++ b/docs/index_using_jdaviz.rst @@ -0,0 +1,21 @@ +.. _using-jdaviz: + +********** +User Guide +********** + +.. toctree:: + :maxdepth: 2 + + installation + imviz/index + specviz/index + cubeviz/index + specviz2d/index + mosviz/index + plugin_api + save_state + display + sample_notebooks + create_products + known_bugs diff --git a/docs/mosviz/index.rst b/docs/mosviz/index.rst index 211d2ff627..64adb21405 100644 --- a/docs/mosviz/index.rst +++ b/docs/mosviz/index.rst @@ -1,12 +1,11 @@ - -.. image:: ../logos/mosviz.svg - :width: 400 +.. |mosviz_logo| image:: ../logos/mos.svg + :height: 42px .. _mosviz: -###### -Mosviz -###### +#################### +|mosviz_logo| Mosviz +#################### .. image:: https://stsci.box.com/shared/static/sbstzr702zqghc40x49g6zxsik6ayg6u.gif :alt: Introductory video tour of the Mosviz configuration and its features diff --git a/docs/reference/api.rst b/docs/reference/api.rst index 2699a7ca1f..e155ee3b30 100644 --- a/docs/reference/api.rst +++ b/docs/reference/api.rst @@ -1,239 +1,45 @@ .. _jdaviz-api: -### -API -### - -.. _jdaviz-api-configs: +############# +Reference/API +############# Configurations ============== -.. automodapi:: jdaviz.configs.cubeviz.helper - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.imviz.helper - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.mosviz.helper - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.specviz.helper - :no-inheritance-diagram: +.. toctree:: + :maxdepth: 2 -.. automodapi:: jdaviz.configs.specviz2d.helper - :no-inheritance-diagram: - -.. _jdaviz-api-viewers: + api_configs Viewers ======= -.. automodapi:: jdaviz.configs.default.plugins.viewers - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.cubeviz.plugins.viewers - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.imviz.plugins.viewers - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.mosviz.plugins.viewers - :no-inheritance-diagram: +.. toctree:: + :maxdepth: 2 -.. automodapi:: jdaviz.configs.specviz.plugins.viewers - :no-inheritance-diagram: - -.. _jdaviz-api-parsers: + api_viewers Parsers ======= -.. automodapi:: jdaviz.configs.cubeviz.plugins.parsers - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.imviz.plugins.parsers - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.mosviz.plugins.parsers - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.specviz.plugins.parsers - :no-inheritance-diagram: +.. toctree:: + :maxdepth: 2 -.. automodapi:: jdaviz.configs.specviz2d.plugins.parsers - :no-inheritance-diagram: - -.. _jdaviz-api-plugins: + api_parsers Plugins ======= -.. automodapi:: jdaviz.configs.default.plugins.collapse.collapse - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.default.plugins.data_tools.data_tools - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.default.plugins.export_plot.export_plot - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.default.plugins.gaussian_smooth.gaussian_smooth - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.default.plugins.line_lists.line_lists - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.default.plugins.markers.markers - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.default.plugins.metadata_viewer.metadata_viewer - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.default.plugins.model_fitting.model_fitting - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.default.plugins.plot_options.plot_options - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.default.plugins.subset_plugin.subset_plugin - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.default.plugins.subset_tools.subset_tools - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.default.plugins.viewer_creator.viewer_creator - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.cubeviz.plugins.moment_maps.moment_maps - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.cubeviz.plugins.slice.slice - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.imviz.plugins.aper_phot_simple.aper_phot_simple - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.imviz.plugins.catalogs.catalogs - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.imviz.plugins.compass.compass - :no-inheritance-diagram: +.. toctree:: + :maxdepth: 2 -.. automodapi:: jdaviz.configs.imviz.plugins.coords_info.coords_info - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.imviz.plugins.image_viewer_creator.image_viewer_creator - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.imviz.plugins.line_profile_xy.line_profile_xy - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.imviz.plugins.links_control.links_control - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.imviz.plugins.rotate_canvas.rotate_canvas - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.mosviz.plugins.row_lock.row_lock - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.mosviz.plugins.slit_overlay.slit_overlay - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.specviz.plugins.line_analysis.line_analysis - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.specviz.plugins.unit_conversion.unit_conversion - :no-inheritance-diagram: - -.. automodapi:: jdaviz.configs.specviz2d.plugins.spectral_extraction.spectral_extraction - :no-inheritance-diagram: - -.. _jdaviz-api-nuts-bolts: + api_plugins Nuts and Bolts ============== -.. automodapi:: jdaviz.app - :no-inheritance-diagram: - :no-inherited-members: - -.. automodapi:: jdaviz.configs.default.plugins.data_tools.file_chooser - :no-inheritance-diagram: - :no-inherited-members: - -.. automodapi:: jdaviz.configs.default.plugins.line_lists.line_list_mixin - :no-inheritance-diagram: - :no-inherited-members: - -.. automodapi:: jdaviz.configs.default.plugins.model_fitting.fitting_backend - :no-inheritance-diagram: - :no-inherited-members: - -.. automodapi:: jdaviz.configs.default.plugins.model_fitting.initializers - :no-inheritance-diagram: - :no-inherited-members: - -.. automodapi:: jdaviz.configs.imviz.wcs_utils - :no-inheritance-diagram: - :no-inherited-members: - -.. automodapi:: jdaviz.core.astrowidgets_api - :no-inheritance-diagram: - :no-inherited-members: - -.. automodapi:: jdaviz.core.config - :no-inheritance-diagram: - :no-inherited-members: - -.. automodapi:: jdaviz.core.custom_traitlets - :no-inheritance-diagram: - :no-inherited-members: - -.. automodapi:: jdaviz.core.data_formats - :no-inheritance-diagram: - :no-inherited-members: - -.. automodapi:: jdaviz.core.events - :no-inheritance-diagram: - :no-inherited-members: - -.. automodapi:: jdaviz.core.freezable_state - :no-inheritance-diagram: - :no-inherited-members: - -.. automodapi:: jdaviz.core.helpers - :no-inheritance-diagram: - :no-inherited-members: - -.. automodapi:: jdaviz.core.linelists - :no-inheritance-diagram: - :no-inherited-members: - -.. automodapi:: jdaviz.core.marks - :no-inheritance-diagram: - :no-inherited-members: - -.. automodapi:: jdaviz.core.region_translators - :no-inheritance-diagram: - :no-inherited-members: - -.. automodapi:: jdaviz.core.registries - :no-inheritance-diagram: - :no-inherited-members: - -.. automodapi:: jdaviz.core.template_mixin - :no-inheritance-diagram: - :no-inherited-members: - -.. automodapi:: jdaviz.core.validunits - :no-inheritance-diagram: - :no-inherited-members: - -.. automodapi:: jdaviz.models.physical_models - :no-inherited-members: +.. toctree:: + :maxdepth: 2 -.. automodapi:: jdaviz.utils - :no-inheritance-diagram: - :no-inherited-members: + api_nuts_bolts diff --git a/docs/reference/api_configs.rst b/docs/reference/api_configs.rst new file mode 100644 index 0000000000..c5826d2ba4 --- /dev/null +++ b/docs/reference/api_configs.rst @@ -0,0 +1,22 @@ +.. _jdaviz-api-configs: + +Helpers API +=========== + +.. toctree:: + :maxdepth: 1 + +.. automodapi:: jdaviz.configs.cubeviz.helper + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.imviz.helper + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.mosviz.helper + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.specviz.helper + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.specviz2d.helper + :no-inheritance-diagram: diff --git a/docs/reference/api_nuts_bolts.rst b/docs/reference/api_nuts_bolts.rst new file mode 100644 index 0000000000..3e376a7808 --- /dev/null +++ b/docs/reference/api_nuts_bolts.rst @@ -0,0 +1,87 @@ +.. _jdaviz-api-nuts-bolts: + +Utilities API +============= + +.. automodapi:: jdaviz.app + :no-inheritance-diagram: + :no-inherited-members: + +.. automodapi:: jdaviz.configs.default.plugins.data_tools.file_chooser + :no-inheritance-diagram: + :no-inherited-members: + +.. automodapi:: jdaviz.configs.default.plugins.line_lists.line_list_mixin + :no-inheritance-diagram: + :no-inherited-members: + +.. automodapi:: jdaviz.configs.default.plugins.model_fitting.fitting_backend + :no-inheritance-diagram: + :no-inherited-members: + +.. automodapi:: jdaviz.configs.default.plugins.model_fitting.initializers + :no-inheritance-diagram: + :no-inherited-members: + +.. automodapi:: jdaviz.configs.imviz.wcs_utils + :no-inheritance-diagram: + :no-inherited-members: + +.. automodapi:: jdaviz.core.astrowidgets_api + :no-inheritance-diagram: + :no-inherited-members: + +.. automodapi:: jdaviz.core.config + :no-inheritance-diagram: + :no-inherited-members: + +.. automodapi:: jdaviz.core.custom_traitlets + :no-inheritance-diagram: + :no-inherited-members: + +.. automodapi:: jdaviz.core.data_formats + :no-inheritance-diagram: + :no-inherited-members: + +.. automodapi:: jdaviz.core.events + :no-inheritance-diagram: + :no-inherited-members: + +.. automodapi:: jdaviz.core.freezable_state + :no-inheritance-diagram: + :no-inherited-members: + +.. automodapi:: jdaviz.core.helpers + :no-inheritance-diagram: + :no-inherited-members: + +.. automodapi:: jdaviz.core.linelists + :no-inheritance-diagram: + :no-inherited-members: + +.. automodapi:: jdaviz.core.marks + :no-inheritance-diagram: + :no-inherited-members: + +.. automodapi:: jdaviz.core.region_translators + :no-inheritance-diagram: + :no-inherited-members: + +.. automodapi:: jdaviz.core.registries + :no-inheritance-diagram: + :no-inherited-members: + +.. automodapi:: jdaviz.core.template_mixin + :no-inheritance-diagram: + :no-inherited-members: + +.. automodapi:: jdaviz.core.validunits + :no-inheritance-diagram: + :no-inherited-members: + +.. automodapi:: jdaviz.models.physical_models + :no-inherited-members: + +.. automodapi:: jdaviz.utils + :no-inheritance-diagram: + :no-inherited-members: diff --git a/docs/reference/api_parsers.rst b/docs/reference/api_parsers.rst new file mode 100644 index 0000000000..9272aa20c3 --- /dev/null +++ b/docs/reference/api_parsers.rst @@ -0,0 +1,19 @@ +.. _jdaviz-api-parsers: + +Parsers API +=========== + +.. automodapi:: jdaviz.configs.cubeviz.plugins.parsers + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.imviz.plugins.parsers + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.mosviz.plugins.parsers + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.specviz.plugins.parsers + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.specviz2d.plugins.parsers + :no-inheritance-diagram: diff --git a/docs/reference/api_plugins.rst b/docs/reference/api_plugins.rst new file mode 100644 index 0000000000..85c87cb271 --- /dev/null +++ b/docs/reference/api_plugins.rst @@ -0,0 +1,85 @@ +.. _jdaviz-api-plugins: + +Plugins API +=========== + +.. automodapi:: jdaviz.configs.default.plugins.collapse.collapse + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.default.plugins.data_tools.data_tools + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.default.plugins.export_plot.export_plot + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.default.plugins.gaussian_smooth.gaussian_smooth + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.default.plugins.line_lists.line_lists + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.default.plugins.markers.markers + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.default.plugins.metadata_viewer.metadata_viewer + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.default.plugins.model_fitting.model_fitting + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.default.plugins.plot_options.plot_options + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.default.plugins.subset_plugin.subset_plugin + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.default.plugins.subset_tools.subset_tools + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.default.plugins.viewer_creator.viewer_creator + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.cubeviz.plugins.moment_maps.moment_maps + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.cubeviz.plugins.slice.slice + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.imviz.plugins.aper_phot_simple.aper_phot_simple + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.imviz.plugins.catalogs.catalogs + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.imviz.plugins.compass.compass + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.imviz.plugins.coords_info.coords_info + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.imviz.plugins.image_viewer_creator.image_viewer_creator + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.imviz.plugins.line_profile_xy.line_profile_xy + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.imviz.plugins.links_control.links_control + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.imviz.plugins.rotate_canvas.rotate_canvas + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.mosviz.plugins.row_lock.row_lock + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.mosviz.plugins.slit_overlay.slit_overlay + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.specviz.plugins.line_analysis.line_analysis + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.specviz.plugins.unit_conversion.unit_conversion + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.specviz2d.plugins.spectral_extraction.spectral_extraction + :no-inheritance-diagram: diff --git a/docs/reference/api_viewers.rst b/docs/reference/api_viewers.rst new file mode 100644 index 0000000000..5908516f5c --- /dev/null +++ b/docs/reference/api_viewers.rst @@ -0,0 +1,19 @@ +.. _jdaviz-api-viewers: + +Viewers API +=========== + +.. automodapi:: jdaviz.configs.default.plugins.viewers + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.cubeviz.plugins.viewers + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.imviz.plugins.viewers + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.mosviz.plugins.viewers + :no-inheritance-diagram: + +.. automodapi:: jdaviz.configs.specviz.plugins.viewers + :no-inheritance-diagram: diff --git a/docs/specviz/examples.rst b/docs/specviz/examples.rst index 5213109338..f0ac712a37 100644 --- a/docs/specviz/examples.rst +++ b/docs/specviz/examples.rst @@ -18,18 +18,18 @@ Open a Spectrum .. raw:: html - + Model Fitting ============= .. raw:: html - + Line Analysis ============= .. raw:: html - + diff --git a/docs/specviz/index.rst b/docs/specviz/index.rst index 6e6c6212fa..aa656c7b75 100644 --- a/docs/specviz/index.rst +++ b/docs/specviz/index.rst @@ -1,11 +1,11 @@ -.. image:: ../logos/specviz.svg - :width: 400 +.. |specviz_logo| image:: ../logos/specicon.svg + :height: 42px .. _specviz: -####### -Specviz -####### +###################### +|specviz_logo| Specviz +###################### .. image:: https://stsci.box.com/shared/static/qlrlsf12fl9v9wjy321hwrjk8d9jf5h8.gif :alt: Introductory video tour of the Specviz configuration and its features diff --git a/docs/specviz2d/index.rst b/docs/specviz2d/index.rst index 4d5df1f3f8..87789e915e 100644 --- a/docs/specviz2d/index.rst +++ b/docs/specviz2d/index.rst @@ -1,11 +1,11 @@ -.. image:: ../logos/specviz2d.svg - :width: 400 +.. |specviz2d_logo| image:: ../logos/specviz2d\ icon.svg + :height: 42px .. _specviz2d: -######### -Specviz2D -######### +########################## +|specviz2d_logo| Specviz2D +########################## Specviz2d is a tool for visualization and quick-look analysis of 2D astronomical spectra. It incorporates visualization tools with analysis capabilities, diff --git a/pyproject.toml b/pyproject.toml index f80d3aa37e..380533e946 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ name = "jdaviz" description = "Astronomical data analysis development leveraging the Jupyter platform" requires-python = ">=3.8" authors = [ - { name = "JDADF Developers", email = "rosteen@stsci.edu" }, + { name = "JDADF Developers", email = "help@stsci.edu" }, ] dependencies = [ "packaging", @@ -72,9 +72,8 @@ test = [ "pytest-tornasync", ] docs = [ - "sphinx-rtd-theme", - "sphinx-astropy", - "tomli; python_version <\"3.11\"" + "sphinx-astropy[confv2]>=1.9.1", + "sphinx_design" ] roman = [ "roman_datamodels>=0.14.2", From 2093786ca917546e6fb7c459a6903b6df4367885 Mon Sep 17 00:00:00 2001 From: Jesse Averbukh Date: Thu, 8 Jun 2023 12:06:35 -0400 Subject: [PATCH 41/42] Add app method to simplify spectral subset (#2237) * Add app method to simplify spectral subset Add simplify button to subset plugin * Fix xor bug exposed by simplify button * Fix style checks * Remove print statements * Add tooltip to simplify button * Make button appear only if the subset can be simplified * Make simplify button appear only when applicable * Apply suggestions from code review Co-authored-by: P. L. Lim <2090236+pllim@users.noreply.github.com> * Update changes file --------- Co-authored-by: P. L. Lim <2090236+pllim@users.noreply.github.com> --- CHANGES.rst | 3 + jdaviz/app.py | 68 +++++++++++++++++-- .../plugins/subset_plugin/subset_plugin.py | 20 ++++++ .../plugins/subset_plugin/subset_plugin.vue | 3 + jdaviz/tests/test_subsets.py | 23 +++++++ 5 files changed, 111 insertions(+), 6 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 0e859e0347..0d68f25024 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,6 +6,9 @@ New Features - Introduce jdaviz.open to automatically detect the appropriate config and load data [#2221] +- Add Simplify button to subset plugin to make composite spectral subsets more user + friendly. [#2237] + Cubeviz ^^^^^^^ diff --git a/jdaviz/app.py b/jdaviz/app.py index f7c42c7726..b075b28354 100644 --- a/jdaviz/app.py +++ b/jdaviz/app.py @@ -1106,12 +1106,32 @@ def get_sub_regions(self, subset_state, simplify_spectral=True): # (4.0 um, 4.5 um) (5.0 um, 6.0 um) (9.0 um, 12.0 um) if isinstance(two, SpectralRegion): - if one.lower > two.lower: - # If one.lower is less than two.lower, it will be included - # in the two.invert() call. Otherwise, we can add it like this. - return (two.invert(one.lower, one.upper) + - one.invert(two.lower, two.upper)) - return two.invert(one.lower, one.upper) + new_region = None + temp_region = None + for subregion in two: + # Add all subregions that do not intersect with XOR region + # to a new SpectralRegion object + if subregion.lower > one.upper or subregion.upper < one.lower: + if not new_region: + new_region = subregion + else: + new_region += subregion + # All other subregions are added to temp_region + else: + if not temp_region: + temp_region = subregion + else: + temp_region += subregion + # This is the main application of XOR to other regions + if not new_region: + new_region = temp_region.invert(one.lower, one.upper) + else: + new_region = new_region + temp_region.invert(one.lower, one.upper) + # This adds the edge regions that are otherwise not included + if not (one.lower == temp_region.lower and one.upper == temp_region.upper): + new_region = new_region + one.invert(temp_region.lower, + temp_region.upper) + return new_region else: return two + one else: @@ -1127,6 +1147,42 @@ def get_sub_regions(self, subset_state, simplify_spectral=True): elif isinstance(subset_state, RangeSubsetState): return self._get_range_subset_bounds(subset_state, simplify_spectral) + def simplify_spectral_subset(self, subset_name, att, overwrite=False): + """ + Convert a composite spectral subset consisting of And, AndNot, Or, Replace, and Xor + into one consisting of just Range and Or state objects. + + Parameters + ---------- + subset_name : str + Name of subset to simplify. + att : str + Attribute that the subset uses to apply to data. + overwrite : bool + Whether to update the current subset with the simplified state or apply it + to a new subset. + """ + spectral_region = self.get_subsets(subset_name, spectral_only=True) + new_state = None + # Reverse through sub regions so that they are added back + # in the order of lowest values to highest + for index in range(len(spectral_region) - 1, -1, -1): + convert_to_range = RangeSubsetState(spectral_region[index].lower.value, + spectral_region[index].upper.value, + att) + if new_state is None: + new_state = convert_to_range + else: + new_state = new_state | convert_to_range + + dc = self.data_collection + if not overwrite: + dc.new_subset_group(subset_state=new_state) + else: + old_subset = [subsets for subsets in dc.subset_groups + if subsets.label == subset_name][0] + old_subset.subset_state = new_state + def add_data(self, data, data_label=None, notify_done=True): """ Add data to the Glue ``DataCollection``. diff --git a/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py b/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py index 0e33a60d8a..6e17456e5d 100644 --- a/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py +++ b/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py @@ -46,6 +46,7 @@ class SubsetPlugin(PluginTemplateMixin, DatasetSelectMixin): subplugins_opened = Any().tag(sync=True) is_centerable = Bool(False).tag(sync=True) + can_simplify = Bool(False).tag(sync=True) icon_replace = Unicode(read_icon(os.path.join(icon_path("glue_replace", icon_format="svg")), 'svg+xml')).tag(sync=True) # noqa icon_or = Unicode(read_icon(os.path.join(icon_path("glue_or", icon_format="svg")), 'svg+xml')).tag(sync=True) # noqa @@ -199,6 +200,15 @@ def _unpack_get_subsets_for_ui(self): self.glue_state_types = self.glue_state_types + [glue_state] self.subset_states = self.subset_states + [subset_state] + simplifiable_states = set(['AndState', 'XorState', 'AndNotState']) + # Check if the subset has more than one subregion, is a range subset type, and + # uses one of the states that can be simplified. + if (len(self.subset_states) > 1 and isinstance(self.subset_states[0], RangeSubsetState) + and len(simplifiable_states - set(self.glue_state_types)) < 3): + self.can_simplify = True + else: + self.can_simplify = False + def _get_subset_definition(self, *args): """ Retrieve the parameters defining the selected subset, for example the @@ -211,6 +221,16 @@ def _get_subset_definition(self, *args): self._unpack_get_subsets_for_ui() + def vue_simplify_subset(self, *args): + if len(self.subset_states) < 2: + self.hub.broadcast(SnackbarMessage("Cannot simplify spectral subset " + "of length less than 2", color='warning', + sender=self)) + return + att = self.subset_states[0].att + self.app.simplify_spectral_subset(subset_name=self.subset_selected, att=att, + overwrite=True) + def vue_update_subset(self, *args): status, reason = self._check_input() if not status: diff --git a/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.vue b/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.vue index 03d3d1f73f..e35cf51c7c 100644 --- a/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.vue +++ b/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.vue @@ -88,6 +88,9 @@ + + Simplify + Update diff --git a/jdaviz/tests/test_subsets.py b/jdaviz/tests/test_subsets.py index bf4f14d976..5a2fd2b2a1 100644 --- a/jdaviz/tests/test_subsets.py +++ b/jdaviz/tests/test_subsets.py @@ -504,6 +504,9 @@ def test_composite_region_from_subset_2d(specviz_helper, spectrum1d): assert subset_plugin.subset_types == ['Range', 'Range', 'Range', 'Range'] assert subset_plugin.glue_state_types == ['AndState', 'AndNotState', 'OrState', 'AndState'] + subset_plugin.vue_simplify_subset() + assert subset_plugin.glue_state_types == ["RangeSubsetState", "OrState"] + def test_edit_composite_spectral_subset(specviz_helper, spectrum1d): specviz_helper.load_spectrum(spectrum1d) @@ -550,3 +553,23 @@ def test_edit_composite_spectral_subset(specviz_helper, spectrum1d): viewer.apply_roi(XRangeROI(7800, 8000)) with pytest.raises(ValueError, match="AND mode should overlap with existing subset"): specviz_helper.app.get_subsets("Subset 1") + + +def test_edit_composite_spectral_with_xor(specviz_helper, spectrum1d): + specviz_helper.load_spectrum(spectrum1d) + viewer = specviz_helper.app.get_viewer(specviz_helper._default_spectrum_viewer_reference_name) + + viewer.apply_roi(XRangeROI(6400, 6600)) + specviz_helper.app.session.edit_subset_mode.mode = OrMode + viewer.apply_roi(XRangeROI(7200, 7400)) + + viewer.apply_roi(XRangeROI(7600, 7800)) + + specviz_helper.app.session.edit_subset_mode.mode = XorMode + viewer.apply_roi(XRangeROI(6700, 7700)) + reg = specviz_helper.app.get_subsets("Subset 1") + + assert reg[0].lower.value == 6400 and reg[0].upper.value == 6600 + assert reg[1].lower.value == 6700 and reg[1].upper.value == 7200 + assert reg[2].lower.value == 7400 and reg[2].upper.value == 7600 + assert reg[3].lower.value == 7700 and reg[3].upper.value == 7800 From 35dfc58ff158ef6428fb753e5586ef03914a2259 Mon Sep 17 00:00:00 2001 From: Ricky O'Steen Date: Tue, 13 Jun 2023 11:27:30 -0400 Subject: [PATCH 42/42] Fix missed conflict --- jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py b/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py index 92c48941fa..4a505c320f 100644 --- a/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py +++ b/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py @@ -227,7 +227,6 @@ def _get_subset_definition(self, *args): self._unpack_get_subsets_for_ui() -<<<<<<< HEAD def vue_simplify_subset(self, *args): if len(self.subset_states) < 2: self.hub.broadcast(SnackbarMessage("Cannot simplify spectral subset " @@ -237,14 +236,13 @@ def vue_simplify_subset(self, *args): att = self.subset_states[0].att self.app.simplify_spectral_subset(subset_name=self.subset_selected, att=att, overwrite=True) -======= + def _on_display_unit_changed(self, msg): # We only care about the spectral units, since flux units don't affect spectral subsets if msg.axis == "spectral": self.spectral_display_unit = msg.unit if self.subset_selected != self.subset_select.default_text: self._get_subset_definition(self.subset_selected) ->>>>>>> a9151a48acb62b44db69c360245bd46c6c8b7a9a def vue_update_subset(self, *args): status, reason = self._check_input()