Skip to content

Commit

Permalink
Initial implementation of unit conversion in profile viewer
Browse files Browse the repository at this point in the history
  • Loading branch information
astrofrog committed Apr 28, 2022
1 parent 5797bdc commit 0b2c987
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 53 deletions.
12 changes: 8 additions & 4 deletions glue/core/units.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@


def find_unit_choices(unit_strings):

unit_objects = {}
for unit_string in unit_strings:
equivalent_units = []
for unit_string in sorted(unit_strings):
try:
unit_objects.add(u.Unit(unit_string))
equivalent_units.append(unit_string)
equivalent_units.extend([str(x) for x in u.Unit(unit_string).find_equivalent_units()])
except ValueError:
pass
return equivalent_units


def unit_scaling(original, target):
return u.Unit(original).to(target)
6 changes: 5 additions & 1 deletion glue/viewers/profile/layer_artist.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ def _calculate_profile_postthread(self):

x, y = visible_data

# Convert units
y = y * self.state._y_unit_scale

# Update the data values.
if len(x) > 0:
self.state.update_limits()
Expand Down Expand Up @@ -131,7 +134,8 @@ def _update_profile(self, force=False, **kwargs):
# of updated properties is up to date after this method has been called.
changed = self.pop_changed_properties()

if force or any(prop in changed for prop in ('layer', 'x_att', 'attribute', 'function', 'normalize', 'v_min', 'v_max', 'visible')):
if force or any(prop in changed for prop in ('layer', 'x_att', 'attribute', 'function', 'normalize',
'v_min', 'v_max', 'visible', 'x_display_unit', 'y_display_unit')):
self._calculate_profile(reset=force)
force = True

Expand Down
126 changes: 82 additions & 44 deletions glue/viewers/profile/qt/options_widget.ui
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>269</width>
<width>293</width>
<height>418</height>
</rect>
</property>
Expand Down Expand Up @@ -57,32 +57,26 @@
<property name="verticalSpacing">
<number>5</number>
</property>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>reference</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="combosel_function"/>
</item>
<item row="2" column="1" colspan="2">
<widget class="QComboBox" name="combosel_x_att">
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLength</enum>
</property>
</widget>
</item>
<item row="7" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="font">
Expand Down Expand Up @@ -115,14 +109,7 @@
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="bool_normalize">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="6" column="1" colspan="2">
<item row="7" column="1" colspan="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
Expand All @@ -135,7 +122,7 @@
</property>
</spacer>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QLabel" name="label_7">
<property name="font">
<font>
Expand All @@ -151,7 +138,14 @@
</property>
</widget>
</item>
<item row="5" column="1" colspan="2">
<item row="1" column="1" colspan="2">
<widget class="QComboBox" name="combosel_reference_data">
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLength</enum>
</property>
</widget>
</item>
<item row="6" column="1" colspan="2">
<widget class="QLabel" name="text_warning">
<property name="styleSheet">
<string notr="true">color: rgb(255, 33, 28)</string>
Expand All @@ -167,25 +161,69 @@
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QComboBox" name="combosel_reference_data">
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLength</enum>
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="combosel_function"/>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="bool_normalize">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="6" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
<property name="text">
<string>reference</string>
</property>
</spacer>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>x unit</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_8">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>y_unit</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="QComboBox" name="combosel_y_display_unit"/>
</item>
<item row="3" column="1" colspan="2">
<widget class="QComboBox" name="combosel_x_display_unit"/>
</item>
</layout>
</widget>
Expand Down
18 changes: 15 additions & 3 deletions glue/viewers/profile/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
DeferredDrawSelectionCallbackProperty as DDSCProperty)
from glue.core.data_combo_helper import ManualDataComboHelper, ComponentIDComboHelper
from glue.utils import defer_draw
from glue.core.data import BaseData
from glue.core.link_manager import is_convertible_to_single_pixel_cid
from glue.core.exceptions import IncompatibleDataException
from glue.core.message import SubsetUpdateMessage
from glue.core.units import find_unit_choices
from glue.core.units import find_unit_choices, unit_scaling

__all__ = ['ProfileViewerState', 'ProfileLayerState']

Expand Down Expand Up @@ -61,6 +62,7 @@ def __init__(self, **kwargs):
self.add_callback('layers', self._layers_changed)
self.add_callback('reference_data', self._reference_data_changed, echo_old=True)
self.add_callback('x_att', self._update_att)
self.add_callback('y_display_unit', self._reset_y_limits)
self.add_callback('normalize', self._reset_y_limits)
self.add_callback('function', self._reset_y_limits)

Expand Down Expand Up @@ -138,6 +140,7 @@ def _reset_y_limits(self, *event):
continue
if profile is not None:
x, y = profile
y = y * layer._y_unit_scale
if len(y) > 0:
y_min = min(y_min, np.nanmin(y))
y_max = max(y_max, np.nanmax(y))
Expand Down Expand Up @@ -167,8 +170,8 @@ def _update_y_display_unit_choices(self):
if isinstance(layer_state.layer, BaseData):
component = layer_state.layer.get_component(layer_state.attribute)
if component.units:
component_units.add(component_units)
choices = find_unit_choices(component_units)
component_units.add(component.units)
choices = [''] + find_unit_choices(component_units)
ProfileViewerState.y_display_unit.set_choices(self, choices)

@defer_draw
Expand Down Expand Up @@ -261,6 +264,14 @@ def __init__(self, layer=None, viewer_state=None, **kwargs):

self.update_from_dict(kwargs)

@property
def _y_unit_scale(self):
target_y_units = self.viewer_state.y_display_unit
if target_y_units == '':
return 1
original_y_units = self.layer.get_component(self.attribute).units
return unit_scaling(original_y_units, target_y_units)

def _on_layer_change(self, *args):

if self.layer is not None:
Expand Down Expand Up @@ -313,6 +324,7 @@ def update_profile(self, update_limits=True):

if not self._viewer_callbacks_set:
self.viewer_state.add_callback('x_att', self.reset_cache, priority=100000)
self.viewer_state.add_callback('y_display_unit', self.reset_cache, priority=100000)
self.viewer_state.add_callback('function', self.reset_cache, priority=100000)
if self.is_callback_property('attribute'):
self.add_callback('attribute', self.reset_cache, priority=100000)
Expand Down
6 changes: 5 additions & 1 deletion glue/viewers/profile/viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class MatplotlibProfileMixin(object):
def setup_callbacks(self):
self.state.add_callback('x_att', self._update_axes)
self.state.add_callback('normalize', self._update_axes)
self.state.add_callback('y_display_unit', self._update_axes)

def _update_axes(self, *args):

Expand All @@ -17,7 +18,10 @@ def _update_axes(self, *args):
if self.state.normalize:
self.state.y_axislabel = 'Normalized data values'
else:
self.state.y_axislabel = 'Data values'
if self.state.y_display_unit:
self.state.y_axislabel = f'Data values [{self.state.y_display_unit}]'
else:
self.state.y_axislabel = 'Data values'

self.axes.figure.canvas.draw_idle()

Expand Down

0 comments on commit 0b2c987

Please sign in to comment.