Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 38 additions & 10 deletions glue_vispy_viewers/volume/colors.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,71 @@
from glue.config import AsinhStretch, LinearStretch, LogStretch, SqrtStretch, DictRegistry
from matplotlib.colors import ListedColormap
from vispy.color import BaseColormap


def create_cmap_template(n):
class GLSLStretchRegistry(DictRegistry):

def add(self, stretch_cls, glsl):
self.members[stretch_cls] = glsl


stretch_glsl = GLSLStretchRegistry()
stretch_glsl.add(LogStretch, "log({stretch.a} * {parameter} + 1.0) / log({stretch.a} + 1.0)")
stretch_glsl.add(SqrtStretch, "sqrt({parameter})")
stretch_glsl.add(AsinhStretch,
"log({parameter} / {stretch.a} + sqrt(pow({parameter} / {stretch.a}, 2) + 1)) / "
"log(1.0 / {stretch.a} + sqrt(pow(1.0 / {stretch.a}, 2) + 1))")
stretch_glsl.add(LinearStretch, "{parameter}")


def create_cmap_template(n, stretch_glsl):
ts = tuple((i + 1) / n for i in range(n-1))
lines = [
"vec4 translucent_colormap(float t) {",
f" float s = {stretch_glsl};"
]
for i in range(n-1):
lines.append(f" if (t <= {(i+1) / n})")
for i, t in enumerate(ts):
lines.append(f" if (s <= {t})")
lines.append(f" {{ return $color_{i}; }}")
lines.append(f" return $color_{n-1};")
lines.append("}")

return "\n".join(lines)


def get_translucent_cmap(r, g, b):
def glsl_for_stretch(stretch, parameter="t"):
template = stretch_glsl.members.get(type(stretch), "{param}")
return template.format(stretch=stretch, parameter=parameter)


def get_translucent_cmap(r, g, b, stretch):

func = glsl_for_stretch(stretch)

class TranslucentCmap(BaseColormap):
glsl_map = """
vec4 translucent_fire(float t) {{
return vec4({0}, {1}, {2}, t);
return vec4({0}, {1}, {2}, {3});
}}
""".format(r, g, b)
""".format(r, g, b, func)

return TranslucentCmap()


def get_mpl_cmap(cmap):
def get_mpl_cmap(cmap, stretch):

if isinstance(cmap, ListedColormap):
colors = cmap.colors
n_colors = len(colors)
colors = [color + [index / n_colors] for index, color in enumerate(colors)]
ts = stretch([index / n_colors for index in range(len(colors))])
colors = [color + [t] for t, color in zip(ts, colors)]
else:
n_colors = 256
colors = [cmap(index / n_colors)[:3] + (index / n_colors,) for index in range(n_colors)]
ts = stretch([index / n_colors for index in range(n_colors)])
colors = [cmap(t)[:3] + (t,) for t in ts]

template = create_cmap_template(n_colors)
stretch_glsl = glsl_for_stretch(stretch)
template = create_cmap_template(n_colors, stretch_glsl)

class MatplotlibCmap(BaseColormap):
glsl_map = template
Expand Down
6 changes: 6 additions & 0 deletions glue_vispy_viewers/volume/jupyter/layer_state_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ class Volume3DLayerStateWidget(v.VuetifyTemplate):

cmap_items = traitlets.List().tag(sync=True)

# Stretch

stretch_items = traitlets.List().tag(sync=True)
stretch_selected = traitlets.Int(allow_none=True).tag(sync=True)

subset = traitlets.Bool().tag(sync=True)

def __init__(self, layer_state):
Expand All @@ -37,6 +42,7 @@ def __init__(self, layer_state):
self.subset = isinstance(layer_state.layer, Subset)

link_glue_choices(self, layer_state, "attribute")
link_glue_choices(self, layer_state, "stretch")
link_glue_choices(self, layer_state, "color_mode")

self.cmap_items = [
Expand Down
3 changes: 3 additions & 0 deletions glue_vispy_viewers/volume/jupyter/layer_state_widget.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
<v-select label="color" :items="color_mode_items" v-model="color_mode_selected" hide-details />
</div>
</template>
<div>
<v-select label="stretch" :items="stretch_items" v-model="stretch_selected" hide-details />
</div>
<div>
<v-subheader class="pl-0 slider-label">opacity</v-subheader>
<glue-throttled-slider wait="300" max="1" step="0.01" :value.sync="glue_state.alpha" hide-details />
Expand Down
7 changes: 4 additions & 3 deletions glue_vispy_viewers/volume/layer_artist.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from ..common.layer_artist import VispyLayerArtist


COLOR_PROPERTIES = set(['cmap', 'color', 'color_mode'])
COLOR_PROPERTIES = set(['cmap', 'color', 'color_mode', 'stretch', 'stretch_parameters'])


class DataProxy(object):
Expand Down Expand Up @@ -160,9 +160,10 @@

def _update_cmap(self):
if self.state.color_mode == "Fixed":
cmap = get_translucent_cmap(*ColorConverter().to_rgb(self.state.color))
cmap = get_translucent_cmap(*ColorConverter().to_rgb(self.state.color),
self.state.stretch_object)
else:
cmap = get_mpl_cmap(self.state.cmap)
cmap = get_mpl_cmap(self.state.cmap, self.state.stretch_object)

Check warning on line 166 in glue_vispy_viewers/volume/layer_artist.py

View check run for this annotation

Codecov / codecov/patch

glue_vispy_viewers/volume/layer_artist.py#L166

Added line #L166 was not covered by tests

self._multivol.set_cmap(self.id, cmap)
self.redraw()
Expand Down
5 changes: 4 additions & 1 deletion glue_vispy_viewers/volume/layer_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
delay_callback)
from glue.core.state_objects import StateAttributeLimitsHelper
from glue.core.data_combo_helper import ComponentIDComboHelper
from glue.viewers.common.stretch_state_mixin import StretchStateMixin
from ..common.layer_state import VispyLayerState

__all__ = ['VolumeLayerState']


class VolumeLayerState(VispyLayerState):
class VolumeLayerState(VispyLayerState, StretchStateMixin):
"""
A state object for volume layers
"""
Expand Down Expand Up @@ -39,6 +40,8 @@ def __init__(self, layer=None, **kwargs):

VolumeLayerState.color_mode.set_choices(self, ['Fixed', 'Linear'])

self.setup_stretch_callback()

self.add_callback('layer', self._on_layer_change)
if layer is not None:
self._on_layer_change()
Expand Down
151 changes: 74 additions & 77 deletions glue_vispy_viewers/volume/qt/layer_style_widget.ui
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>292</width>
<height>214</height>
<height>246</height>
</rect>
</property>
<property name="windowTitle">
Expand All @@ -17,30 +17,48 @@
<property name="verticalSpacing">
<number>5</number>
</property>
<item row="9" column="2">
<widget class="QRadioButton" name="radio_subset_outline">
<property name="text">
<string>Outline</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QComboBox" name="combotext_color_mode">
<property name="currentText">
<string>Fixed</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>Fixed</string>
</property>
</item>
<item>
<property name="text">
<string>Linear</string>
</property>
</item>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_color">
<property name="text">
<string>Color:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_color_mode">
<item row="0" column="0">
<widget class="QLabel" name="label_att">
<property name="text">
<string>Color mode:</string>
<string>Attribute:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="valuetext_vmin"/>
</item>
<item row="1" column="3" alignment="Qt::AlignLeft">
<widget class="QLineEdit" name="valuetext_vmax"/>
</item>
<item row="5" column="1" colspan="3">
<widget class="QColormapCombo" name="combodata_cmap"/>
</item>
<item row="8" column="0" colspan="4">
<item row="8" column="0" colspan="3">
<widget class="QSlider" name="value_alpha">
<property name="maximum">
<number>100</number>
Expand All @@ -50,54 +68,24 @@
</property>
</widget>
</item>
<item row="4" column="1" colspan="3">
<widget class="QColorBox" name="color_color">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="1" colspan="3">
<widget class="QComboBox" name="combosel_attribute">
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_subset_mode">
<property name="text">
<string>Subset:</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_att">
<item row="9" column="1">
<widget class="QRadioButton" name="radio_subset_data">
<property name="text">
<string>Attribute:</string>
<string>Data</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_color_mode"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_limits">
<property name="text">
<string>Limits:</string>
</property>
</widget>
</item>
<item row="9" column="3">
<widget class="QRadioButton" name="radio_subset_outline">
<item row="9" column="0">
<widget class="QLabel" name="label_subset_mode">
<property name="text">
<string>Outline</string>
<string>Subset:</string>
</property>
</widget>
</item>
Expand All @@ -108,42 +96,34 @@
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QRadioButton" name="radio_subset_data">
<item row="3" column="0">
<widget class="QLabel" name="label_color_mode">
<property name="text">
<string>Data</string>
<string>Color mode:</string>
</property>
</widget>
</item>
<item row="1" column="2" alignment="Qt::AlignHCenter">
<widget class="QToolButton" name="button_flip_limits">
<property name="styleSheet">
<string notr="true">padding: 0px</string>
<item row="6" column="1" colspan="2">
<widget class="QComboBox" name="combosel_stretch"/>
</item>
<item row="4" column="1" colspan="2">
<widget class="QColorBox" name="color_color">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>⇄</string>
<string/>
</property>
</widget>
</item>
<item row="3" column="1" colspan="3">
<widget class="QComboBox" name="combotext_color_mode">
<property name="currentText">
<string>Fixed</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>Fixed</string>
</property>
</item>
<item>
<property name="text">
<string>Linear</string>
</property>
</item>
</widget>
<item row="1" column="1">
<widget class="QLineEdit" name="valuetext_vmin"/>
</item>
<item row="5" column="1" colspan="2">
<widget class="QColormapCombo" name="combodata_cmap"/>
</item>
<item row="10" column="1">
<spacer name="verticalSpacer">
Expand All @@ -158,6 +138,23 @@
</property>
</spacer>
</item>
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="combosel_attribute">
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_stretch">
<property name="text">
<string>Stretch</string>
</property>
</widget>
</item>
<item row="1" column="2" alignment="Qt::AlignLeft">
<widget class="QLineEdit" name="valuetext_vmax"/>
</item>
</layout>
</widget>
<customwidgets>
Expand Down
Loading