[yt-svn] commit/yt: MatthewTurk: Merged in ngoldbaum/yt (pull request #2424)

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Fri Nov 18 08:08:33 PST 2016


1 new commit in yt:

https://bitbucket.org/yt_analysis/yt/commits/76e74bb22aa0/
Changeset:   76e74bb22aa0
Branch:      yt
User:        MatthewTurk
Date:        2016-11-18 16:08:07+00:00
Summary:     Merged in ngoldbaum/yt (pull request #2424)

Implement equivalency keyword argument for PlotWindow.set_unit. Closes #1292
Affected #:  5 files

diff -r 5084dbec0f1d46f3ea3782908daad4890a6adf68 -r 76e74bb22aa019850724f490f23607d18dc628c0 doc/source/visualizing/plots.rst
--- a/doc/source/visualizing/plots.rst
+++ b/doc/source/visualizing/plots.rst
@@ -522,6 +522,33 @@
 The same result could have been accomplished by explicitly setting the ``width``
 to ``(.01, 'Mpc')``.
 
+Set image units
+~~~~~~~~~~~~~~~
+
+:meth:`~yt.visualization.plot_window.AxisAlignedSlicePlot.set_axes_unit` allows
+the customization of the units used for the image and colorbar.
+
+.. python-script::
+
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   slc = yt.SlicePlot(ds, 'z', 'density', width=(10,'kpc'))
+   slc.set_unit('density', 'Msun/pc**3')
+   slc.save()
+
+If the unit you would like to convert to needs an equivalency, this can be
+specified via the ``equivalency`` keyword argument of ``set_unit``. For
+example, let's make a plot of the temperature field, but present it using
+an energy unit instead of a temperature unit:
+
+.. python-script::
+
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   slc = yt.SlicePlot(ds, 'z', 'temperature', width=(10,'kpc'))
+   slc.set_unit('temperature', 'keV', equivalency='thermal')
+   slc.save()
+
 Set the plot center
 ~~~~~~~~~~~~~~~~~~~
 

diff -r 5084dbec0f1d46f3ea3782908daad4890a6adf68 -r 76e74bb22aa019850724f490f23607d18dc628c0 yt/units/yt_array.py
--- a/yt/units/yt_array.py
+++ b/yt/units/yt_array.py
@@ -614,7 +614,7 @@
                 self, conv_unit.dimensions, **kwargs)
             if isinstance(new_arr, tuple):
                 try:
-                    return YTArray(new_arr[0], new_arr[1]).in_units(unit)
+                    return type(self)(new_arr[0], new_arr[1]).in_units(unit)
                 except YTUnitConversionError:
                     raise YTInvalidUnitEquivalence(equiv, self.units, unit)
             else:

diff -r 5084dbec0f1d46f3ea3782908daad4890a6adf68 -r 76e74bb22aa019850724f490f23607d18dc628c0 yt/visualization/fixed_resolution.py
--- a/yt/visualization/fixed_resolution.py
+++ b/yt/visualization/fixed_resolution.py
@@ -282,6 +282,44 @@
         dpy = (self.bounds[3]-self.bounds[2])/self.buff_size[1]
         return distance/dpy
 
+    def set_unit(self, field, unit, equivalency=None, equivalency_kwargs=None):
+        """Sets a new unit for the requested field
+
+        parameters
+        ----------
+        field : string or field tuple
+           The name of the field that is to be changed.
+
+        unit : string or Unit object
+           The name of the new unit.
+
+        equivalency : string, optional
+           If set, the equivalency to use to convert the current units to
+           the new requested unit. If None, the unit conversion will be done
+           without an equivelancy
+
+        equivalency_kwargs : string, optional
+           Keyword arguments to be passed to the equivalency. Only used if
+           ``equivalency`` is set.
+        """
+        if equivalency_kwargs is None:
+            equivalency_kwargs = {}
+        field = self.data_source._determine_fields(field)[0]
+        if equivalency is None:
+            self[field].convert_to_units(unit)
+        else:
+            equiv_array = self[field].to_equivalent(
+                unit, equivalency, **equivalency_kwargs)
+            # equiv_array isn't necessarily an ImageArray. This is an issue
+            # inherent to the way the unit system handles YTArray
+            # sublcasses and I don't see how to modify the unit system to
+            # fix this. Instead, we paper over this issue and hard code
+            # that equiv_array is an ImageArray
+            self[field] = ImageArray(
+                equiv_array, equiv_array.units, equiv_array.units.registry,
+                self[field].info)
+
+
     def export_hdf5(self, filename, fields = None):
         r"""Export a set of fields to a set of HDF5 datasets.
 

diff -r 5084dbec0f1d46f3ea3782908daad4890a6adf68 -r 76e74bb22aa019850724f490f23607d18dc628c0 yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -19,6 +19,7 @@
 import six
 import sys
 
+from collections import defaultdict
 from distutils.version import LooseVersion
 from numbers import Number
 
@@ -189,6 +190,7 @@
         self._periodic = periodic
         self.oblique = oblique
         self._right_handed = right_handed
+        self._equivalencies = defaultdict(lambda: (None, {}))
         self.buff_size = buff_size
         self.antialias = antialias
 
@@ -282,7 +284,11 @@
             # Restore the old fields
             for key, unit in zip(old_fields, old_units):
                 self._frb[key]
-                self._frb[key].convert_to_units(unit)
+                equiv = self._equivalencies[key]
+                if equiv[0] is None:
+                    self._frb[key].convert_to_units(unit)
+                else:
+                    self.frb.set_unit(key, unit, equiv[0], equiv[1])
 
         # Restore the override fields
         for key in self.override_fields:
@@ -365,7 +371,8 @@
         return self
 
     @invalidate_plot
-    def set_unit(self, field, new_unit):
+    def set_unit(self, field, new_unit, equivalency=None,
+                 equivalency_kwargs=None):
         """Sets a new unit for the requested field
 
         parameters
@@ -375,7 +382,18 @@
 
         new_unit : string or Unit object
            The name of the new unit.
+
+        equivalency : string, optional
+           If set, the equivalency to use to convert the current units to
+           the new requested unit. If None, the unit conversion will be done
+           without an equivelancy
+
+        equivalency_kwargs : string, optional
+           Keyword arguments to be passed to the equivalency. Only used if
+           ``equivalency`` is set.
         """
+        if equivalency_kwargs is None:
+            equivalency_kwargs = {}
         field = self.data_source._determine_fields(field)[0]
         field = ensure_list(field)
         new_unit = ensure_list(new_unit)
@@ -384,7 +402,8 @@
                 "Field list {} and unit "
                 "list {} are incompatible".format(field, new_unit))
         for f, u in zip(field, new_unit):
-            self.frb[f].convert_to_units(u)
+            self._equivalencies[f] = (equivalency, equivalency_kwargs)
+            self.frb.set_unit(f, u, equivalency, equivalency_kwargs)
         return self
 
     @invalidate_plot

diff -r 5084dbec0f1d46f3ea3782908daad4890a6adf68 -r 76e74bb22aa019850724f490f23607d18dc628c0 yt/visualization/tests/test_plotwindow.py
--- a/yt/visualization/tests/test_plotwindow.py
+++ b/yt/visualization/tests/test_plotwindow.py
@@ -30,6 +30,7 @@
 from yt.visualization.api import \
     SlicePlot, ProjectionPlot, OffAxisSlicePlot, OffAxisProjectionPlot
 from yt.units.yt_array import YTArray, YTQuantity
+from yt.units import kboltz
 from yt.frontends.stream.api import load_uniform_grid
 from collections import OrderedDict
 
@@ -495,3 +496,38 @@
     slc = SlicePlot(ds, 2, 'density')
     slc.set_buff_size(1200)
     assert_equal(slc.frb['density'].shape, (1200, 1200))
+
+def test_set_unit():
+    ds = fake_random_ds(32, fields=('temperature',), units=('K',))
+    slc = SlicePlot(ds, 2, 'temperature')
+
+    orig_array = slc.frb['gas', 'temperature'].copy()
+
+    slc.set_unit('temperature', 'degF')
+
+    assert str(slc.frb['gas', 'temperature'].units) == 'degF'
+    assert_array_almost_equal(np.array(slc.frb['gas', 'temperature']),
+                              np.array(orig_array)*1.8 - 459.67)
+
+    # test that a plot modifying function that destroys the frb preserves the
+    # new unit
+    slc.set_buff_size(1000)
+
+    assert str(slc.frb['gas', 'temperature'].units) == 'degF'
+
+    slc.set_buff_size(800)
+
+    slc.set_unit('temperature', 'K')
+    assert str(slc.frb['gas', 'temperature'].units) == 'K'
+    assert_array_almost_equal(slc.frb['gas', 'temperature'], orig_array)
+
+    slc.set_unit('temperature', 'keV', equivalency='thermal')
+    assert str(slc.frb['gas', 'temperature'].units) == 'keV'
+    assert_array_almost_equal(slc.frb['gas', 'temperature'],
+                              (orig_array*kboltz).to('keV'))
+
+    # test that a plot modifying function that destroys the frb preserves the
+    # new unit with an equivalency
+    slc.set_buff_size(1000)
+
+    assert str(slc.frb['gas', 'temperature'].units) == 'keV'

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