[yt-svn] commit/yt: 4 new changesets

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Wed Oct 2 12:32:17 PDT 2013


4 new commits in yt:

https://bitbucket.org/yt_analysis/yt/commits/da308f4c50c7/
Changeset:   da308f4c50c7
Branch:      yt
User:        samskillman
Date:        2013-06-30 00:22:39
Summary:     Add a new TransferFunctionHelper object to help build, plot, and manage a
transfer function.  Adds the capability of overplotting a 1D profile (of say,
CellMass) on the transfer function to help guide choices.
Affected #:  2 files

diff -r 8e8bd5b353df99c1510058a7c982329e5212fcfe -r da308f4c50c7b632169cb3e37036a9651c262864 yt/visualization/volume_rendering/transfer_function_helper.py
--- /dev/null
+++ b/yt/visualization/volume_rendering/transfer_function_helper.py
@@ -0,0 +1,216 @@
+"""
+A helper class to build, display, and modify transfer functions for volume
+rendering.
+
+Author: Samuel Skillman <samskillman at gmail.com>
+Affiliation: DOE CSGF, U. of Colorado at Boulder
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2013 Samuel Skillman.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+from yt.funcs import mylog
+from yt.data_objects.profiles import BinnedProfile1D
+from yt.visualization.volume_rendering.api import ColorTransferFunction
+from yt.visualization._mpl_imports import FigureCanvasAgg
+from matplotlib.figure import Figure
+from IPython.core.display import Image
+import cStringIO
+import numpy as np
+
+
+class TransferFunctionHelper(object):
+
+    profiles = {}
+
+    def __init__(self, pf):
+        r"""A transfer function helper.
+
+        This attempts to help set up a good transfer function by finding
+        bounds, handling linear/log options, and displaying the transfer
+        function combined with 1D profiles of rendering quantity.
+
+        Parameters
+        ----------
+        pf: A StaticOutput instance
+            A static output that is currently being rendered. This is used to
+            help set up data bounds.
+
+        Notes
+        -----
+        """
+        self.pf = pf
+        self.field = None
+        self.log = False
+        self.tf = None
+        self.bounds = None
+        self.grey_opacity = True
+
+    def set_bounds(self, bounds=None):
+        """
+        Set the bounds of the transfer function.
+
+        Parameters
+        ----------
+        bounds: array-like, length 2, optional
+            A length 2 list/array in the form [min, max]. These should be the
+            raw values and not the logarithm of the min and max. If bounds is
+            None, the bounds of the data are calculated from all of the data
+            in the dataset.  This can be slow for very large datasets.
+        """
+        if bounds is None:
+            self.bounds = \
+                self.pf.h.all_data().quantities['Extrema'](self.field)[0]
+
+        # Do some error checking.
+        assert(len(self.bounds) == 2)
+        if self.log:
+            assert(self.bounds[0] > 0.0)
+            assert(self.bounds[1] > 0.0)
+        return
+
+    def set_field(self, field):
+        """
+        Set the field to be rendered
+
+        Parameters
+        ----------
+        field: string
+            The field to be rendered.
+        """
+        self.field = field
+
+    def set_log(self, log):
+        """
+        Set whether or not the transfer function should be in log or linear
+        space. Also modifies the pf.field_info[field].take_log attribute to
+        stay in sync with this setting.
+
+        Parameters
+        ----------
+        log: boolean
+            Sets whether the transfer function should use log or linear space.
+        """
+        self.log = log
+        self.pf.h
+        self.pf.field_info[self.field].take_log = log
+
+    def build_transfer_function(self):
+        """
+        Builds the transfer function according to the current state of the
+        TransferFunctionHelper.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+
+        A ColorTransferFunction object.
+
+        """
+        if self.bounds is None:
+            mylog.info('Calculating data bounds. This may take a while.' +
+                       '  Set the .bounds to avoid this.')
+            self.set_bounds()
+
+        if self.log:
+            mi, ma = np.log10(self.bounds[0]), np.log10(self.bounds[1])
+        else:
+            mi, ma = self.bounds
+        self.tf = ColorTransferFunction((mi, ma),
+                                        grey_opacity=self.grey_opacity,
+                                        nbins=512)
+        return self.tf
+
+    def plot(self, fn=None, profile_field=None, profile_weight=None):
+        """
+        Save the current transfer function to a bitmap, or display
+        it inline.
+
+        Parameters
+        ----------
+        fn: string, optional
+            Filename to save the image to. If None, the returns an image
+            to an IPython session.
+
+        Returns
+        -------
+
+        If fn is None, will return an image to an IPython notebook.
+
+        """
+        if self.tf is None:
+            self.build_transfer_function()
+        tf = self.tf
+        if self.log:
+            xfunc = np.logspace
+            xmi, xma = np.log10(self.bounds[0]), np.log10(self.bounds[1])
+        else:
+            xfunc = np.linspace
+            xmi, xma = self.bounds
+
+        x = xfunc(xmi, xma, tf.nbins)
+        y = tf.funcs[3].y
+        w = np.append(x[1:]-x[:-1], x[-1]-x[-2])
+        colors = np.array([tf.funcs[0].y, tf.funcs[1].y, tf.funcs[2].y,
+                           np.ones_like(x)]).T
+
+        fig = Figure(figsize=[6, 3])
+        canvas = FigureCanvasAgg(fig)
+        ax = fig.add_axes([0.2, 0.2, 0.75, 0.75])
+        ax.bar(x, tf.funcs[3].y, w, edgecolor=[0.0, 0.0, 0.0, 0.0],
+               log=True, color=colors)
+
+        if profile_field is not None:
+            try:
+                prof = self.profiles[self.field]
+            except KeyError:
+                self.setup_profile(profile_field, profile_weight)
+                prof = self.profiles[self.field]
+            ax.plot(prof[self.field], prof[profile_field]*tf.funcs[3].y.max() /
+                    prof[profile_field].max(), color='w', linewidth=3)
+            ax.plot(prof[self.field], prof[profile_field]*tf.funcs[3].y.max() /
+                    prof[profile_field].max(), color='k')
+
+        ax.set_xscale({True: 'log', False: 'linear'}[self.log])
+        ax.set_xlim(x.min(), x.max())
+        ax.set_xlabel(self.pf.field_info[self.field].get_label())
+        ax.set_ylabel(r'$\mathrm{alpha}$')
+        ax.set_ylim(y.max()*1.0e-3, y.max()*2)
+
+        if fn is None:
+            f = cStringIO.StringIO()
+            canvas.print_figure(f)
+            f.seek(0)
+            img = f.read()
+            return Image(img)
+        else:
+            fig.savefig(fn)
+
+    def setup_profile(self, profile_field=None, profile_weight=None):
+        if profile_field is None:
+            profile_field = 'CellVolume'
+        prof = BinnedProfile1D(self.pf.h.all_data(), 128, self.field,
+                               self.bounds[0], self.bounds[1],
+                               log_space=self.log,
+                               lazy_reader=False, end_collect=False)
+        prof.add_fields([profile_field], fractional=False,
+                        weight=profile_weight)
+        self.profiles[self.field] = prof
+        return

diff -r 8e8bd5b353df99c1510058a7c982329e5212fcfe -r da308f4c50c7b632169cb3e37036a9651c262864 yt/visualization/volume_rendering/transfer_functions.py
--- a/yt/visualization/volume_rendering/transfer_functions.py
+++ b/yt/visualization/volume_rendering/transfer_functions.py
@@ -641,6 +641,8 @@
             self.x_bounds[0]))
         rel1 = int(self.nbins*(ma - self.x_bounds[0])/(self.x_bounds[1] -
             self.x_bounds[0]))
+        rel0 = max(rel0, 0)
+        rel1 = min(rel1, self.nbins-1)
         tomap = np.linspace(0.,1.,num=rel1-rel0)
         cmap = get_cmap(colormap)
         cc = cmap(tomap)


https://bitbucket.org/yt_analysis/yt/commits/1fb87198e5e9/
Changeset:   1fb87198e5e9
Branch:      yt
User:        samskillman
Date:        2013-06-30 04:10:52
Summary:     Fix in case a profile is then asked for a different field.
Affected #:  1 file

diff -r da308f4c50c7b632169cb3e37036a9651c262864 -r 1fb87198e5e9d7cdf793da6a8150d4b1d2a07092 yt/visualization/volume_rendering/transfer_function_helper.py
--- a/yt/visualization/volume_rendering/transfer_function_helper.py
+++ b/yt/visualization/volume_rendering/transfer_function_helper.py
@@ -183,6 +183,9 @@
             except KeyError:
                 self.setup_profile(profile_field, profile_weight)
                 prof = self.profiles[self.field]
+            if profile_field not in prof.keys():
+                prof.add_fields([profile_field], fractional=False,
+                                weight=profile_weight)
             ax.plot(prof[self.field], prof[profile_field]*tf.funcs[3].y.max() /
                     prof[profile_field].max(), color='w', linewidth=3)
             ax.plot(prof[self.field], prof[profile_field]*tf.funcs[3].y.max() /


https://bitbucket.org/yt_analysis/yt/commits/a588666af47f/
Changeset:   a588666af47f
Branch:      yt
User:        samskillman
Date:        2013-07-08 22:59:58
Summary:     Fixing up the bounds to be respected, working around a matplotlib bug for
logarithmic bar plots, and initializing the profiles more properly.
Affected #:  1 file

diff -r 1fb87198e5e9d7cdf793da6a8150d4b1d2a07092 -r a588666af47f6e39cd931225df084a8633195e14 yt/visualization/volume_rendering/transfer_function_helper.py
--- a/yt/visualization/volume_rendering/transfer_function_helper.py
+++ b/yt/visualization/volume_rendering/transfer_function_helper.py
@@ -35,7 +35,7 @@
 
 class TransferFunctionHelper(object):
 
-    profiles = {}
+    profiles = None
 
     def __init__(self, pf):
         r"""A transfer function helper.
@@ -59,6 +59,7 @@
         self.tf = None
         self.bounds = None
         self.grey_opacity = True
+        self.profiles = {}
 
     def set_bounds(self, bounds=None):
         """
@@ -73,8 +74,8 @@
             in the dataset.  This can be slow for very large datasets.
         """
         if bounds is None:
-            self.bounds = \
-                self.pf.h.all_data().quantities['Extrema'](self.field)[0]
+            bounds = self.pf.h.all_data().quantities['Extrema'](self.field)[0]
+        self.bounds = bounds
 
         # Do some error checking.
         assert(len(self.bounds) == 2)
@@ -175,7 +176,7 @@
         canvas = FigureCanvasAgg(fig)
         ax = fig.add_axes([0.2, 0.2, 0.75, 0.75])
         ax.bar(x, tf.funcs[3].y, w, edgecolor=[0.0, 0.0, 0.0, 0.0],
-               log=True, color=colors)
+               log=True, color=colors, bottom=[0])
 
         if profile_field is not None:
             try:


https://bitbucket.org/yt_analysis/yt/commits/51157128e185/
Changeset:   51157128e185
Branch:      yt
User:        MatthewTurk
Date:        2013-10-02 21:32:13
Summary:     Merged in samskillman/yt (pull request #538)

Transfer Function Helper
Affected #:  1 file

diff -r 824ba0b66e9229d070e9323032301e061e57a916 -r 51157128e18557c82dc00a9f5853b6bcd361e63a yt/visualization/volume_rendering/transfer_function_helper.py
--- /dev/null
+++ b/yt/visualization/volume_rendering/transfer_function_helper.py
@@ -0,0 +1,220 @@
+"""
+A helper class to build, display, and modify transfer functions for volume
+rendering.
+
+Author: Samuel Skillman <samskillman at gmail.com>
+Affiliation: DOE CSGF, U. of Colorado at Boulder
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2013 Samuel Skillman.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+from yt.funcs import mylog
+from yt.data_objects.profiles import BinnedProfile1D
+from yt.visualization.volume_rendering.api import ColorTransferFunction
+from yt.visualization._mpl_imports import FigureCanvasAgg
+from matplotlib.figure import Figure
+from IPython.core.display import Image
+import cStringIO
+import numpy as np
+
+
+class TransferFunctionHelper(object):
+
+    profiles = None
+
+    def __init__(self, pf):
+        r"""A transfer function helper.
+
+        This attempts to help set up a good transfer function by finding
+        bounds, handling linear/log options, and displaying the transfer
+        function combined with 1D profiles of rendering quantity.
+
+        Parameters
+        ----------
+        pf: A StaticOutput instance
+            A static output that is currently being rendered. This is used to
+            help set up data bounds.
+
+        Notes
+        -----
+        """
+        self.pf = pf
+        self.field = None
+        self.log = False
+        self.tf = None
+        self.bounds = None
+        self.grey_opacity = True
+        self.profiles = {}
+
+    def set_bounds(self, bounds=None):
+        """
+        Set the bounds of the transfer function.
+
+        Parameters
+        ----------
+        bounds: array-like, length 2, optional
+            A length 2 list/array in the form [min, max]. These should be the
+            raw values and not the logarithm of the min and max. If bounds is
+            None, the bounds of the data are calculated from all of the data
+            in the dataset.  This can be slow for very large datasets.
+        """
+        if bounds is None:
+            bounds = self.pf.h.all_data().quantities['Extrema'](self.field)[0]
+        self.bounds = bounds
+
+        # Do some error checking.
+        assert(len(self.bounds) == 2)
+        if self.log:
+            assert(self.bounds[0] > 0.0)
+            assert(self.bounds[1] > 0.0)
+        return
+
+    def set_field(self, field):
+        """
+        Set the field to be rendered
+
+        Parameters
+        ----------
+        field: string
+            The field to be rendered.
+        """
+        self.field = field
+
+    def set_log(self, log):
+        """
+        Set whether or not the transfer function should be in log or linear
+        space. Also modifies the pf.field_info[field].take_log attribute to
+        stay in sync with this setting.
+
+        Parameters
+        ----------
+        log: boolean
+            Sets whether the transfer function should use log or linear space.
+        """
+        self.log = log
+        self.pf.h
+        self.pf.field_info[self.field].take_log = log
+
+    def build_transfer_function(self):
+        """
+        Builds the transfer function according to the current state of the
+        TransferFunctionHelper.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+
+        A ColorTransferFunction object.
+
+        """
+        if self.bounds is None:
+            mylog.info('Calculating data bounds. This may take a while.' +
+                       '  Set the .bounds to avoid this.')
+            self.set_bounds()
+
+        if self.log:
+            mi, ma = np.log10(self.bounds[0]), np.log10(self.bounds[1])
+        else:
+            mi, ma = self.bounds
+        self.tf = ColorTransferFunction((mi, ma),
+                                        grey_opacity=self.grey_opacity,
+                                        nbins=512)
+        return self.tf
+
+    def plot(self, fn=None, profile_field=None, profile_weight=None):
+        """
+        Save the current transfer function to a bitmap, or display
+        it inline.
+
+        Parameters
+        ----------
+        fn: string, optional
+            Filename to save the image to. If None, the returns an image
+            to an IPython session.
+
+        Returns
+        -------
+
+        If fn is None, will return an image to an IPython notebook.
+
+        """
+        if self.tf is None:
+            self.build_transfer_function()
+        tf = self.tf
+        if self.log:
+            xfunc = np.logspace
+            xmi, xma = np.log10(self.bounds[0]), np.log10(self.bounds[1])
+        else:
+            xfunc = np.linspace
+            xmi, xma = self.bounds
+
+        x = xfunc(xmi, xma, tf.nbins)
+        y = tf.funcs[3].y
+        w = np.append(x[1:]-x[:-1], x[-1]-x[-2])
+        colors = np.array([tf.funcs[0].y, tf.funcs[1].y, tf.funcs[2].y,
+                           np.ones_like(x)]).T
+
+        fig = Figure(figsize=[6, 3])
+        canvas = FigureCanvasAgg(fig)
+        ax = fig.add_axes([0.2, 0.2, 0.75, 0.75])
+        ax.bar(x, tf.funcs[3].y, w, edgecolor=[0.0, 0.0, 0.0, 0.0],
+               log=True, color=colors, bottom=[0])
+
+        if profile_field is not None:
+            try:
+                prof = self.profiles[self.field]
+            except KeyError:
+                self.setup_profile(profile_field, profile_weight)
+                prof = self.profiles[self.field]
+            if profile_field not in prof.keys():
+                prof.add_fields([profile_field], fractional=False,
+                                weight=profile_weight)
+            ax.plot(prof[self.field], prof[profile_field]*tf.funcs[3].y.max() /
+                    prof[profile_field].max(), color='w', linewidth=3)
+            ax.plot(prof[self.field], prof[profile_field]*tf.funcs[3].y.max() /
+                    prof[profile_field].max(), color='k')
+
+        ax.set_xscale({True: 'log', False: 'linear'}[self.log])
+        ax.set_xlim(x.min(), x.max())
+        ax.set_xlabel(self.pf.field_info[self.field].get_label())
+        ax.set_ylabel(r'$\mathrm{alpha}$')
+        ax.set_ylim(y.max()*1.0e-3, y.max()*2)
+
+        if fn is None:
+            f = cStringIO.StringIO()
+            canvas.print_figure(f)
+            f.seek(0)
+            img = f.read()
+            return Image(img)
+        else:
+            fig.savefig(fn)
+
+    def setup_profile(self, profile_field=None, profile_weight=None):
+        if profile_field is None:
+            profile_field = 'CellVolume'
+        prof = BinnedProfile1D(self.pf.h.all_data(), 128, self.field,
+                               self.bounds[0], self.bounds[1],
+                               log_space=self.log,
+                               lazy_reader=False, end_collect=False)
+        prof.add_fields([profile_field], fractional=False,
+                        weight=profile_weight)
+        self.profiles[self.field] = prof
+        return

Repository URL: https://bitbucket.org/yt_analysis/yt/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.



More information about the yt-svn mailing list