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

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Tue Nov 10 08:52:16 PST 2015


4 new commits in yt:

https://bitbucket.org/yt_analysis/yt/commits/02d75eea10a9/
Changeset:   02d75eea10a9
Branch:      yt
User:        jzuhone
Date:        2015-11-09 22:39:12+00:00
Summary:     Make sure we check against all string types and not just str
Affected #:  2 files

diff -r 11079ba03a6dd7c5e0214efe0b06e14667d9366a -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 yt/fields/derived_field.py
--- a/yt/fields/derived_field.py
+++ b/yt/fields/derived_field.py
@@ -14,6 +14,7 @@
 import contextlib
 import inspect
 
+from yt.extern.six import string_types
 from yt.funcs import \
     ensure_list
 from .field_exceptions import \
@@ -99,7 +100,7 @@
         # handle units
         if units is None:
             self.units = ''
-        elif isinstance(units, str):
+        elif isinstance(units, string_types):
             if units.lower() == 'auto':
                 self.units = None
             else:

diff -r 11079ba03a6dd7c5e0214efe0b06e14667d9366a -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 yt/fields/field_info_container.py
--- a/yt/fields/field_info_container.py
+++ b/yt/fields/field_info_container.py
@@ -18,6 +18,7 @@
 import numpy as np
 from numbers import Number as numeric_type
 
+from yt.extern.six import string_types
 from yt.funcs import mylog, only_on_root
 from yt.units.unit_object import Unit
 from .derived_field import \
@@ -179,7 +180,7 @@
             # field *name* is in there, then the field *tuple*.
             units = self.ds.field_units.get(field[1], units)
             units = self.ds.field_units.get(field, units)
-            if not isinstance(units, str) and args[0] != "":
+            if not isinstance(units, string_types) and args[0] != "":
                 units = "((%s)*%s)" % (args[0], units)
             if isinstance(units, (numeric_type, np.number, np.ndarray)) and \
                 args[0] == "" and units != 1.0:


https://bitbucket.org/yt_analysis/yt/commits/9cdfe40778a4/
Changeset:   9cdfe40778a4
Branch:      yt
User:        jzuhone
Date:        2015-11-10 01:52:45+00:00
Summary:     Merge
Affected #:  110 files

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a .hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -32,6 +32,7 @@
 yt/utilities/lib/CICDeposit.c
 yt/utilities/lib/ContourFinding.c
 yt/utilities/lib/DepthFirstOctree.c
+yt/utilities/lib/element_mappings.c
 yt/utilities/lib/FixedInterpolator.c
 yt/utilities/lib/fortran_reader.c
 yt/utilities/lib/freetype_writer.c

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/cookbook/amrkdtree_downsampling.py
--- a/doc/source/cookbook/amrkdtree_downsampling.py
+++ b/doc/source/cookbook/amrkdtree_downsampling.py
@@ -4,6 +4,13 @@
 # In this example we will show how to use the AMRKDTree to take a simulation
 # with 8 levels of refinement and only use levels 0-3 to render the dataset.
 
+# Currently this cookbook is flawed in that the data that is covered by the
+# higher resolution data gets masked during the rendering.  This should be
+# fixed by changing either the data source or the code in
+# yt/utilities/amr_kdtree.py where data is being masked for the partitioned
+# grid.  Right now the quick fix is to create a data_collection, but this
+# will only work for patch based simulations that have ds.index.grids.
+
 # We begin by loading up yt, and importing the AMRKDTree
 import numpy as np
 
@@ -12,58 +19,58 @@
 
 # Load up a dataset and define the kdtree
 ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030')
-kd = AMRKDTree(ds)
+im, sc = yt.volume_render(ds, 'density', fname='v0.png')
+sc.camera.set_width(ds.arr(100, 'kpc'))
+render_source = sc.get_source(0)
+kd=render_source.volume
 
 # Print out specifics of KD Tree
 print("Total volume of all bricks = %i" % kd.count_volume())
 print("Total number of cells = %i" % kd.count_cells())
 
-# Define a camera and take an volume rendering.
-tf = yt.ColorTransferFunction((-30, -22))
-cam = ds.camera([0.5, 0.5, 0.5], [0.2, 0.3, 0.4], 0.10, 256,
-                  tf, volume=kd)
-tf.add_layers(4, 0.01, col_bounds=[-27.5, -25.5], colormap='RdBu_r')
-cam.snapshot("v1.png", clip_ratio=6.0)
-
-# This rendering is okay, but lets say I'd like to improve it, and I don't want
-# to spend the time rendering the high resolution data.  What we can do is
-# generate a low resolution version of the AMRKDTree and pass that in to the
-# camera.  We do this by specifying a maximum refinement level of 6.
-
-kd_low_res = AMRKDTree(ds, max_level=6)
+new_source = ds.all_data()
+new_source.max_level=3
+kd_low_res = AMRKDTree(ds, data_source=new_source)
 print(kd_low_res.count_volume())
 print(kd_low_res.count_cells())
 
 # Now we pass this in as the volume to our camera, and render the snapshot
 # again.
 
-cam.volume = kd_low_res
-cam.snapshot("v4.png", clip_ratio=6.0)
+render_source.set_volume(kd_low_res)
+render_source.set_fields('density')
+sc.render()
+sc.save("v1.png", sigma_clip=6.0)
 
 # This operation was substantiall faster.  Now lets modify the low resolution
 # rendering until we find something we like.
 
+tf = render_source.transfer_function
 tf.clear()
 tf.add_layers(4, 0.01, col_bounds=[-27.5, -25.5],
               alpha=np.ones(4, dtype='float64'), colormap='RdBu_r')
-cam.snapshot("v2.png", clip_ratio=6.0)
+sc.render()
+sc.save("v2.png", sigma_clip=6.0)
 
 # This looks better.  Now let's try turning on opacity.
 
 tf.grey_opacity = True
-cam.snapshot("v4.png", clip_ratio=6.0)
-
-# That seemed to pick out som interesting structures.  Now let's bump up the
-# opacity.
-
+sc.render()
+sc.save("v3.png", sigma_clip=6.0)
+#
+## That seemed to pick out som interesting structures.  Now let's bump up the
+## opacity.
+#
 tf.clear()
 tf.add_layers(4, 0.01, col_bounds=[-27.5, -25.5],
               alpha=10.0 * np.ones(4, dtype='float64'), colormap='RdBu_r')
-cam.snapshot("v3.png", clip_ratio=6.0)
-
-# This looks pretty good, now lets go back to the full resolution AMRKDTree
-
-cam.volume = kd
-cam.snapshot("v4.png", clip_ratio=6.0)
+sc.render()
+sc.save("v4.png", sigma_clip=6.0)
+#
+## This looks pretty good, now lets go back to the full resolution AMRKDTree
+#
+render_source.set_volume(kd)
+sc.render()
+sc.save("v5.png", sigma_clip=6.0)
 
 # This looks great!

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/cookbook/camera_movement.py
--- a/doc/source/cookbook/camera_movement.py
+++ b/doc/source/cookbook/camera_movement.py
@@ -3,40 +3,29 @@
 
 # Follow the simple_volume_rendering cookbook for the first part of this.
 ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")  # load data
-ad = ds.all_data()
-mi, ma = ad.quantities.extrema("density")
-
-# Set up transfer function
-tf = yt.ColorTransferFunction((np.log10(mi), np.log10(ma)))
-tf.add_layers(6, w=0.05)
-
-# Set up camera paramters
-c = [0.5, 0.5, 0.5]  # Center
-L = [1, 1, 1]  # Normal Vector
-W = 1.0  # Width
-Nvec = 512  # Pixels on a side
-
-# Specify a north vector, which helps with rotations.
-north_vector = [0., 0., 1.]
+sc = yt.create_scene(ds)
+cam = sc.camera
+cam.resolution = (512, 512)
+cam.set_width(ds.domain_width/20.0)
 
 # Find the maximum density location, store it in max_c
 v, max_c = ds.find_max('density')
 
-# Initialize the Camera
-cam = ds.camera(c, L, W, (Nvec, Nvec), tf, north_vector=north_vector)
 frame = 0
-
-# Do a rotation over 5 frames
-for i, snapshot in enumerate(cam.rotation(np.pi, 5, clip_ratio=8.0)):
-    snapshot.write_png('camera_movement_%04i.png' % frame)
-    frame += 1
-
 # Move to the maximum density location over 5 frames
-for i, snapshot in enumerate(cam.move_to(max_c, 5, clip_ratio=8.0)):
-    snapshot.write_png('camera_movement_%04i.png' % frame)
+for _ in cam.iter_move(max_c, 5):
+    sc.render()
+    sc.save('camera_movement_%04i.png' % frame, sigma_clip=8.0)
     frame += 1
 
 # Zoom in by a factor of 10 over 5 frames
-for i, snapshot in enumerate(cam.zoomin(10.0, 5, clip_ratio=8.0)):
-    snapshot.write_png('camera_movement_%04i.png' % frame)
+for _ in cam.iter_zoom(10.0, 5):
+    sc.render()
+    sc.save('camera_movement_%04i.png' % frame, sigma_clip=8.0)
     frame += 1
+
+# Do a rotation over 5 frames
+for _ in cam.iter_rotate(np.pi, 5):
+    sc.render()
+    sc.save('camera_movement_%04i.png' % frame, sigma_clip=8.0)
+    frame += 1

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/cookbook/complex_plots.rst
--- a/doc/source/cookbook/complex_plots.rst
+++ b/doc/source/cookbook/complex_plots.rst
@@ -196,10 +196,41 @@
 
 In this recipe, we move a camera through a domain and take multiple volume
 rendering snapshots.
-See :ref:`volume_rendering` for more information.
+See :ref:`camera_movement` for more information.
 
 .. yt_cookbook:: camera_movement.py
 
+Volume Rendering with Custom Camera
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In this recipe we modify the :ref:`cookbook-simple_volume_rendering` recipe to
+use customized camera properties. See :ref:`volume_rendering` for more
+information.
+
+.. yt_cookbook:: custom_camera_volume_rendering.py
+
+.. _cookbook-custom-transfer-function:
+
+Volume Rendering with a Custom Transfer Function
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In this recipe we modify the :ref:`cookbook-simple_volume_rendering` recipe to
+use customized camera properties. See :ref:`volume_rendering` for more
+information.
+
+.. yt_cookbook:: custom_transfer_function_volume_rendering.py
+
+.. _cookbook-sigma_clip:
+
+Volume Rendering with Sigma Clipping
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In this recipe we output several images with different values of sigma_clip
+set in order to change the contrast of the resulting image.  See 
+:ref:`sigma_clip` for more information.
+
+.. yt_cookbook:: sigma_clip.py
+
 Zooming into an Image
 ~~~~~~~~~~~~~~~~~~~~~
 
@@ -212,6 +243,15 @@
 
 .. yt_cookbook:: zoomin_frames.py
 
+.. _cookbook-various_lens:
+
+Various Lens Types for Volume Rendering
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This example illustrates the usage and feature of different lenses for volume rendering.
+
+.. yt_cookbook:: various_lens.py
+
 .. _cookbook-opaque_rendering:
 
 Opaque Volume Rendering
@@ -220,7 +260,7 @@
 This recipe demonstrates how to make semi-opaque volume renderings, but also
 how to step through and try different things to identify the type of volume
 rendering you want.
-See :ref:`volume_rendering` for more information.
+See :ref:`opaque_rendering` for more information.
 
 .. yt_cookbook:: opaque_rendering.py
 
@@ -235,23 +275,27 @@
 
 .. yt_cookbook:: amrkdtree_downsampling.py
 
+.. _cookbook-volume_rendering_annotations:
+
 Volume Rendering with Bounding Box and Overlaid Grids
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 This recipe demonstrates how to overplot a bounding box on a volume rendering
 as well as overplotting grids representing the level of refinement achieved
 in different regions of the code.
-See :ref:`volume_rendering` for more information.
+See :ref:`volume_rendering_annotations` for more information.
 
 .. yt_cookbook:: rendering_with_box_and_grids.py
 
 Volume Rendering with Annotation
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 This recipe demonstrates how to write the simulation time, show an
 axis triad indicating the direction of the coordinate system, and show
-the transfer function on a volume rendering.
-See :ref:`volume_rendering` for more information.
+the transfer function on a volume rendering.  Please note that this 
+recipe relies on the old volume rendering interface.  While one can
+continue to use this interface, it may be incompatible with some of the
+new developments and the infrastructure described in :ref:`volume_rendering`.
 
 .. yt_cookbook:: vol-annotated.py
 

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/cookbook/custom_camera_volume_rendering.py
--- /dev/null
+++ b/doc/source/cookbook/custom_camera_volume_rendering.py
@@ -0,0 +1,22 @@
+import yt
+
+# Load the dataset
+ds = yt.load("Enzo_64/DD0043/data0043")
+
+# Create a volume rendering
+sc = yt.create_scene(ds, field=('gas', 'density'))
+
+# Now increase the resolution
+sc.camera.resolution = (1024, 1024)
+
+# Set the camera focus to a position that is offset from the center of
+# the domain
+sc.camera.focus = ds.arr([0.3, 0.3, 0.3], 'unitary')
+
+# Move the camera position to the other side of the dataset
+sc.camera.position = ds.arr([0, 0, 0], 'unitary')
+
+# save to disk with a custom filename and apply sigma clipping to eliminate
+# very bright pixels, producing an image with better contrast.
+sc.render()
+sc.save('custom.png', sigma_clip=4)

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/cookbook/custom_transfer_function_volume_rendering.py
--- /dev/null
+++ b/doc/source/cookbook/custom_transfer_function_volume_rendering.py
@@ -0,0 +1,24 @@
+import yt
+import numpy as np
+
+# Load the dataset
+ds = yt.load("Enzo_64/DD0043/data0043")
+
+# Create a volume rendering
+sc = yt.create_scene(ds, field=('gas', 'density'))
+
+# Modify the transfer function
+
+# First get the render source, in this case the entire domain, with field ('gas','density')
+render_source = sc.get_source(0)
+
+# Clear the transfer function
+render_source.transfer_function.clear()
+
+# Map a range of density values (in log space) to the Reds_r colormap
+render_source.transfer_function.map_to_colormap(
+    np.log10(ds.quan(5.0e-31, 'g/cm**3')),
+    np.log10(ds.quan(1.0e-29, 'g/cm**3')),
+    scale=30.0, colormap='RdBu_r')
+
+sc.save('new_tf.png')

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/cookbook/image_background_colors.py
--- a/doc/source/cookbook/image_background_colors.py
+++ b/doc/source/cookbook/image_background_colors.py
@@ -2,27 +2,14 @@
 # volume renderings, to pngs with varying backgrounds.
 
 # First we use the simple_volume_rendering.py recipe from above to generate
-# a standard volume rendering.  The only difference is that we use 
-# grey_opacity=True with our TransferFunction, as the colored background 
-# functionality requires images with an opacity between 0 and 1. 
-
-# We have removed all the comments from the volume rendering recipe for 
-# brevity here, but consult the recipe for more details.
+# a standard volume rendering.
 
 import yt
 import numpy as np
 
 ds = yt.load("Enzo_64/DD0043/data0043")
-ad = ds.all_data()
-mi, ma = ad.quantities.extrema("density")
-tf = yt.ColorTransferFunction((np.log10(mi)+1, np.log10(ma)), grey_opacity=True)
-tf.add_layers(5, w=0.02, colormap="spectral")
-c = [0.5, 0.5, 0.5]
-L = [0.5, 0.2, 0.7]
-W = 1.0
-Npixels = 512
-cam = ds.camera(c, L, W, Npixels, tf)
-im = cam.snapshot("original.png" % ds, clip_ratio=8.0)
+im, sc = yt.volume_render(ds, 'density')
+im.write_png("original.png", sigma_clip=8.0)
 
 # Our image array can now be transformed to include different background
 # colors.  By default, the background color is black.  The following
@@ -35,10 +22,10 @@
 # None  (0.,0.,0.,0.) <-- Transparent!
 # any rgba list/array: [r,g,b,a], bounded by 0..1
 
-# We include the clip_ratio=8 keyword here to bring out more contrast between
+# We include the sigma_clip=8 keyword here to bring out more contrast between
 # the background and foreground, but it is entirely optional.
 
-im.write_png('black_bg.png', background='black', clip_ratio=8.0)
-im.write_png('white_bg.png', background='white', clip_ratio=8.0)
-im.write_png('green_bg.png', background=[0.,1.,0.,1.], clip_ratio=8.0)
-im.write_png('transparent_bg.png', background=None, clip_ratio=8.0)
+im.write_png('black_bg.png', background='black', sigma_clip=8.0)
+im.write_png('white_bg.png', background='white', sigma_clip=8.0)
+im.write_png('green_bg.png', background=[0.,1.,0.,1.], sigma_clip=8.0)
+im.write_png('transparent_bg.png', background=None, sigma_clip=8.0)

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/cookbook/index.rst
--- a/doc/source/cookbook/index.rst
+++ b/doc/source/cookbook/index.rst
@@ -44,8 +44,10 @@
    embedded_webm_animation
    gadget_notebook
    owls_notebook
+   ../visualizing/transfer_function_helper
    ../analyzing/analysis_modules/sunyaev_zeldovich
    fits_radio_cubes
    fits_xray_images
    tipsy_notebook
    halo_analysis_example
+   ../visualizing/volume_rendering_tutorial

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/cookbook/offaxis_projection.py
--- a/doc/source/cookbook/offaxis_projection.py
+++ b/doc/source/cookbook/offaxis_projection.py
@@ -11,7 +11,7 @@
 # objects, you could set it the way you would a cutting plane -- but for this
 # dataset, we'll just choose an off-axis value at random.  This gets normalized
 # automatically.
-L = [0.5, 0.4, 0.7]
+L = [1.0, 0.0, 0.0]
 
 # Our "width" is the width of the image plane as well as the depth.
 # The first element is the left to right width, the second is the
@@ -26,7 +26,7 @@
 # Create the off axis projection.
 # Setting no_ghost to False speeds up the process, but makes a
 # slighly lower quality image.
-image = yt.off_axis_projection(ds, c, L, W, Npixels, "density", no_ghost=False)
+image, sc= yt.off_axis_projection(ds, c, L, W, Npixels, "density", no_ghost=False)
 
 # Write out the final image and give it a name
 # relating to what our dataset is called.

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/cookbook/offaxis_projection_colorbar.py
--- a/doc/source/cookbook/offaxis_projection_colorbar.py
+++ b/doc/source/cookbook/offaxis_projection_colorbar.py
@@ -32,7 +32,7 @@
 # Also note that we set the field which we want to project as "density", but
 # really we could use any arbitrary field like "temperature", "metallicity"
 # or whatever.
-image = yt.off_axis_projection(ds, c, L, W, Npixels, "density", no_ghost=False)
+image, sc = yt.off_axis_projection(ds, c, L, W, Npixels, "density", no_ghost=False)
 
 # Image is now an NxN array representing the intensities of the various pixels.
 # And now, we call our direct image saver.  We save the log of the result.

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/cookbook/opaque_rendering.py
--- a/doc/source/cookbook/opaque_rendering.py
+++ b/doc/source/cookbook/opaque_rendering.py
@@ -3,44 +3,51 @@
 
 ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
 
-# We start by building a transfer function, and initializing a camera.
+# We start by building a default volume rendering scene 
 
-tf = yt.ColorTransferFunction((-30, -22))
-cam = ds.camera([0.5, 0.5, 0.5], [0.2, 0.3, 0.4], 0.10, 256, tf)
+im, sc = yt.volume_render(ds, field=("gas","density"), fname="v0.png", sigma_clip=6.0)
 
-# Now let's add some isocontours, and take a snapshot.
-
-tf.add_layers(4, 0.01, col_bounds = [-27.5,-25.5], colormap = 'RdBu_r')
-cam.snapshot("v1.png", clip_ratio=6.0)
+sc.camera.set_width(ds.arr(0.1,'code_length'))
+tf = sc.get_source(0).transfer_function 
+tf.clear()
+tf.add_layers(4, 0.01, col_bounds = [-27.5,-25.5],
+        alpha=np.logspace(-3,0,4), colormap = 'RdBu_r')
+sc.render()
+sc.save("v1.png", sigma_clip=6.0)
 
 # In this case, the default alphas used (np.logspace(-3,0,Nbins)) does not
 # accentuate the outer regions of the galaxy. Let's start by bringing up the
 # alpha values for each contour to go between 0.1 and 1.0
 
+tf = sc.get_source(0).transfer_function 
 tf.clear()
 tf.add_layers(4, 0.01, col_bounds = [-27.5,-25.5],
         alpha=np.logspace(0,0,4), colormap = 'RdBu_r')
-cam.snapshot("v2.png", clip_ratio=6.0)
+sc.render()
+sc.save("v2.png", sigma_clip=6.0)
 
 # Now let's set the grey_opacity to True.  This should make the inner portions
 # start to be obcured
 
 tf.grey_opacity = True
-cam.snapshot("v3.png", clip_ratio=6.0)
+sc.render()
+sc.save("v3.png", sigma_clip=6.0)
 
 # That looks pretty good, but let's start bumping up the opacity.
 
 tf.clear()
 tf.add_layers(4, 0.01, col_bounds = [-27.5,-25.5],
         alpha=10.0*np.ones(4,dtype='float64'), colormap = 'RdBu_r')
-cam.snapshot("v4.png", clip_ratio=6.0)
+sc.render()
+sc.save("v4.png", sigma_clip=6.0)
 
 # Let's bump up again to see if we can obscure the inner contour.
 
 tf.clear()
 tf.add_layers(4, 0.01, col_bounds = [-27.5,-25.5],
         alpha=30.0*np.ones(4,dtype='float64'), colormap = 'RdBu_r')
-cam.snapshot("v5.png", clip_ratio=6.0)
+sc.render()
+sc.save("v5.png", sigma_clip=6.0)
 
 # Now we are losing sight of everything.  Let's see if we can obscure the next
 # layer
@@ -48,13 +55,15 @@
 tf.clear()
 tf.add_layers(4, 0.01, col_bounds = [-27.5,-25.5],
         alpha=100.0*np.ones(4,dtype='float64'), colormap = 'RdBu_r')
-cam.snapshot("v6.png", clip_ratio=6.0)
+sc.render()
+sc.save("v6.png", sigma_clip=6.0)
 
 # That is very opaque!  Now lets go back and see what it would look like with
 # grey_opacity = False
 
 tf.grey_opacity=False
-cam.snapshot("v7.png", clip_ratio=6.0)
+sc.render()
+sc.save("v7.png", sigma_clip=6.0)
 
 # That looks pretty different, but the main thing is that you can see that the
 # inner contours are somewhat visible again.  

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/cookbook/rendering_with_box_and_grids.py
--- a/doc/source/cookbook/rendering_with_box_and_grids.py
+++ b/doc/source/cookbook/rendering_with_box_and_grids.py
@@ -1,61 +1,22 @@
 import yt
 import numpy as np
+from yt.visualization.volume_rendering.api import BoxSource, CoordinateVectorSource
 
 # Load the dataset.
 ds = yt.load("Enzo_64/DD0043/data0043")
+sc = yt.create_scene(ds, ('gas','density'))
+sc.get_source(0).transfer_function.grey_opacity=True
 
-# Create a data container (like a sphere or region) that
-# represents the entire domain.
-ad = ds.all_data()
+sc.annotate_domain(ds)
+sc.render()
+sc.save("%s_vr_domain.png" % ds)
 
-# Get the minimum and maximum densities.
-mi, ma = ad.quantities.extrema("density")
-
-# Create a transfer function to map field values to colors.
-# We bump up our minimum to cut out some of the background fluid
-tf = yt.ColorTransferFunction((np.log10(mi)+2.0, np.log10(ma)))
-
-# Add three Gaussians, evenly spaced between the min and
-# max specified above with widths of 0.02 and using the
-# gist_stern colormap.
-tf.add_layers(3, w=0.02, colormap="gist_stern")
-
-# Choose a center for the render.
-c = [0.5, 0.5, 0.5]
-
-# Choose a vector representing the viewing direction.
-L = [0.5, 0.2, 0.7]
-
-# Set the width of the image.
-# Decreasing or increasing this value
-# results in a zoom in or out.
-W = 1.0
-
-# The number of pixels along one side of the image.
-# The final image will have Npixel^2 pixels.
-Npixels = 512
-
-# Create a camera object.
-# This object creates the images and
-# can be moved and rotated.
-cam = ds.camera(c, L, W, Npixels, tf)
-
-# Create a snapshot.
-# The return value of this function could also be accepted, modified (or saved
-# for later manipulation) and then put written out using write_bitmap.
-# clip_ratio applies a maximum to the function, which is set to that value
-# times the .std() of the array.
-im = cam.snapshot("%s_volume_rendered.png" % ds, clip_ratio=8.0)
-
-# Add the domain edges, with an alpha blending of 0.3:
-nim = cam.draw_domain(im, alpha=0.3)
-nim.write_png('%s_vr_domain.png' % ds)
-
-# Add the grids, colored by the grid level with the algae colormap
-nim = cam.draw_grids(im, alpha=0.3, cmap='algae')
-nim.write_png('%s_vr_grids.png' % ds)
+sc.annotate_grids(ds)
+sc.render()
+sc.save("%s_vr_grids.png" % ds)
 
 # Here we can draw the coordinate vectors on top of the image by processing
 # it through the camera. Then save it out.
-cam.draw_coordinate_vectors(nim)
-nim.write_png("%s_vr_vectors.png" % ds)
+sc.annotate_axes()
+sc.render()
+sc.save("%s_vr_coords.png" % ds)

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/cookbook/sigma_clip.py
--- /dev/null
+++ b/doc/source/cookbook/sigma_clip.py
@@ -0,0 +1,17 @@
+import yt
+
+# Load the dataset.
+ds = yt.load("enzo_tiny_cosmology/RD0009/RD0009")
+
+# Create a volume rendering, which will determine data bounds, use the first
+# acceptable field in the field_list, and set up a default transfer function.
+
+# Render and save output images with different levels of sigma clipping.
+# Sigma clipping removes the highest intensity pixels in a volume render, 
+# which affects the overall contrast of the image.
+sc = yt.create_scene(ds, field=('gas', 'density'))
+sc.render()
+sc.save('clip_0.png')
+sc.save('clip_2.png', sigma_clip=2)
+sc.save('clip_4.png', sigma_clip=4)
+sc.save('clip_6.png', sigma_clip=6)

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/cookbook/simple_volume_rendering.py
--- a/doc/source/cookbook/simple_volume_rendering.py
+++ b/doc/source/cookbook/simple_volume_rendering.py
@@ -1,48 +1,10 @@
 import yt
-import numpy as np
 
 # Load the dataset.
 ds = yt.load("Enzo_64/DD0043/data0043")
 
-# Create a data container (like a sphere or region) that
-# represents the entire domain.
-ad = ds.all_data()
+# Create a volume rendering, which will determine data bounds, use the first
+# acceptable field in the field_list, and set up a default transfer function.
 
-# Get the minimum and maximum densities.
-mi, ma = ad.quantities.extrema("density")
-
-# Create a transfer function to map field values to colors.
-# We bump up our minimum to cut out some of the background fluid
-tf = yt.ColorTransferFunction((np.log10(mi)+1, np.log10(ma)))
-
-# Add five Gaussians, evenly spaced between the min and
-# max specified above with widths of 0.02 and using the
-# spectral colormap.
-tf.add_layers(5, w=0.02, colormap="spectral")
-
-# Choose a center for the render.
-c = [0.5, 0.5, 0.5]
-
-# Choose a vector representing the viewing direction.
-L = [0.5, 0.2, 0.7]
-
-# Set the width of the image.
-# Decreasing or increasing this value
-# results in a zoom in or out.
-W = 1.0
-
-# The number of pixels along one side of the image.
-# The final image will have Npixel^2 pixels.
-Npixels = 512
-
-# Create a camera object.
-# This object creates the images and
-# can be moved and rotated.
-cam = ds.camera(c, L, W, Npixels, tf)
-
-# Create a snapshot.
-# The return value of this function could also be accepted, modified (or saved
-# for later manipulation) and then put written out using write_bitmap.
-# clip_ratio applies a maximum to the function, which is set to that value
-# times the .std() of the array.
-cam.snapshot("%s_volume_rendered.png" % ds, clip_ratio=8.0)
+# This will save a file named 'data0043_Render_density.png' to disk.
+im, sc = yt.volume_render(ds, field=('gas', 'density'))

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/cookbook/various_lens.py
--- /dev/null
+++ b/doc/source/cookbook/various_lens.py
@@ -0,0 +1,120 @@
+import yt
+from yt.visualization.volume_rendering.api import Scene, Camera, VolumeSource
+import numpy as np
+
+field = ("gas", "density")
+
+# normal_vector points from camera to the center of tbe final projection.
+# Now we look at the positive x direction.
+normal_vector = [1., 0., 0.]
+# north_vector defines the "top" direction of the projection, which is
+# positive z direction here.
+north_vector = [0., 0., 1.]
+
+# Follow the simple_volume_rendering cookbook for the first part of this.
+ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+sc = Scene()
+vol = VolumeSource(ds, field=field)
+tf = vol.transfer_function
+tf.grey_opacity = True
+
+# Plane-parallel lens
+cam = Camera(ds, lens_type='plane-parallel')
+# Set the resolution of tbe final projection.
+cam.resolution = [500, 500]
+# Set the location of the camera to be (x=0.2, y=0.5, z=0.5)
+# For plane-parallel lens, the location info along the normal_vector (here
+# is x=0.2) is ignored. 
+cam.position = ds.arr(np.array([0.2, 0.5, 0.5]), 'code_length')
+# Set the orientation of the camera.
+cam.switch_orientation(normal_vector=normal_vector,
+                       north_vector=north_vector)
+# Set the width of the camera, where width[0] and width[1] specify the length and
+# height of final projection, while width[2] in plane-parallel lens is not used.
+cam.set_width(ds.domain_width * 0.5)
+sc.camera = cam
+sc.add_source(vol)
+sc.render()
+sc.save('lens_plane-parallel.png', sigma_clip=6.0)
+
+# Perspective lens
+cam = Camera(ds, lens_type='perspective')
+cam.resolution = [500, 500]
+# Standing at (x=0.2, y=0.5, z=0.5), we look at the area of x>0.2 (with some open angle
+# specified by camera width) along the positive x direction.
+cam.position = ds.arr([0.2, 0.5, 0.5], 'code_length')
+cam.switch_orientation(normal_vector=normal_vector,
+                       north_vector=north_vector)
+# Set the width of the camera, where width[0] and width[1] specify the length and
+# height of the final projection, while width[2] specifies the distance between the
+# camera and the final image.
+cam.set_width(ds.domain_width * 0.5)
+sc.camera = cam
+sc.add_source(vol)
+sc.render()
+sc.save('lens_perspective.png', sigma_clip=6.0)
+
+# Stereo-perspective lens
+cam = Camera(ds, lens_type='stereo-perspective')
+# Set the size ratio of the final projection to be 2:1, since stereo-perspective lens
+# will generate the final image with both left-eye and right-eye ones jointed together.
+cam.resolution = [1000, 500]
+cam.position = ds.arr([0.2, 0.5, 0.5], 'code_length')
+cam.switch_orientation(normal_vector=normal_vector,
+                       north_vector=north_vector)
+cam.set_width(ds.domain_width*0.5)
+# Set the distance between left-eye and right-eye.
+cam.lens.disparity = ds.domain_width[0] * 1.e-3
+sc.camera = cam
+sc.add_source(vol)
+sc.render()
+sc.save('lens_stereo-perspective.png', sigma_clip=6.0)
+
+# Fisheye lens
+dd = ds.sphere(ds.domain_center, ds.domain_width[0] / 10)
+cam = Camera(dd, lens_type='fisheye')
+cam.resolution = [500, 500]
+v, c = ds.find_max(field)
+cam.set_position(c - 0.0005 * ds.domain_width)
+cam.switch_orientation(normal_vector=normal_vector,
+                       north_vector=north_vector)
+cam.set_width(ds.domain_width)
+cam.lens.fov = 360.0
+sc.camera = cam
+sc.add_source(vol)
+sc.render()
+sc.save('lens_fisheye.png', sigma_clip=6.0)
+
+# Spherical lens
+cam = Camera(ds, lens_type='spherical')
+# Set the size ratio of the final projection to be 2:1, since spherical lens
+# will generate the final image with length of 2*pi and height of pi.
+cam.resolution = [1000, 500]
+# Standing at (x=0.4, y=0.5, z=0.5), we look in all the radial directions
+# from this point in spherical coordinate.
+cam.position = ds.arr([0.4, 0.5, 0.5], 'code_length')
+cam.switch_orientation(normal_vector=normal_vector,
+                       north_vector=north_vector)
+# In (stereo)spherical camera, camera width is not used since the entire volume
+# will be rendered
+sc.camera = cam
+sc.add_source(vol)
+sc.render()
+sc.save('lens_spherical.png', sigma_clip=6.0)
+
+# Stereo-spherical lens
+cam = Camera(ds, lens_type='stereo-spherical')
+# Set the size ratio of the final projection to be 4:1, since spherical-perspective lens
+# will generate the final image with both left-eye and right-eye ones jointed together.
+cam.resolution = [2000, 500]
+cam.position = ds.arr([0.4, 0.5, 0.5], 'code_length')
+cam.switch_orientation(normal_vector=normal_vector,
+                       north_vector=north_vector)
+# In (stereo)spherical camera, camera width is not used since the entire volume
+# will be rendered
+# Set the distance between left-eye and right-eye.
+cam.lens.disparity = ds.domain_width[0] * 1.e-3
+sc.camera = cam
+sc.add_source(vol)
+sc.render()
+sc.save('lens_stereo-spherical.png', sigma_clip=6.0)

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/cookbook/vol-annotated.py
--- a/doc/source/cookbook/vol-annotated.py
+++ b/doc/source/cookbook/vol-annotated.py
@@ -4,7 +4,7 @@
 import pylab
 
 import yt
-import yt.visualization.volume_rendering.api as vr
+import yt.visualization.volume_rendering.old_camera as vr
 
 ds = yt.load("maestro_subCh_plt00248")
 
@@ -17,11 +17,11 @@
 # centered on these with width sigma        
 vals = [-1.e7, -5.e6, -2.5e6, 2.5e6, 5.e6, 1.e7]
 sigma = 2.e5
-        
+
 mi, ma = min(vals), max(vals)
 
 # Instantiate the ColorTransferfunction.
-tf =  vr.ColorTransferFunction((mi, ma))
+tf =  yt.ColorTransferFunction((mi, ma))
 
 for v in vals:
     tf.sample_colormap(v, sigma**2, colormap="coolwarm")
@@ -69,7 +69,7 @@
 
 # tell the camera to use our figure
 cam._render_figure = f
-    
+
 # save annotated -- this added the transfer function values, 
 # and the clear_fig=False ensures it writes onto our existing figure.
 cam.save_annotated("vol_annotated.png", nim, dpi=145, clear_fig=False)

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/examining/loading_data.rst
--- a/doc/source/examining/loading_data.rst
+++ b/doc/source/examining/loading_data.rst
@@ -1026,6 +1026,60 @@
 * Some functions may behave oddly or not work at all.
 * Data must already reside in memory.
 
+Unstructured Grid Data
+----------------------
+
+See :ref:`loading-numpy-array`,
+:func:`~yt.frontends.stream.data_structures.load_unstructured_mesh` for
+more detail.
+
+In addition to the above grid types, you can also load data stored on
+unstructured meshes. This type of mesh is used, for example, in many
+finite element calculations. Currently, hexahedral, tetrahedral, and
+wedge-shaped mesh element are supported.
+
+To load an unstructured mesh, you need to specify the following. First,
+you need to have a coordinates array, which should be an (L, 3) array
+that stores the (x, y, z) positions of all of the vertices in the mesh.
+Second, you need to specify a connectivity array, which describes how
+those vertices are connected into mesh elements. The connectivity array
+should be (N, M), where N is the number of elements and M is the
+connectivity length, i.e. the number of vertices per element. Finally,
+you must also specify a data dictionary, where the keys should be
+the names of the fields and the values should be numpy arrays that
+contain the field data. These arrays can either supply the cell-averaged
+data for each element, in which case they would be (N, 1), or they
+can have node-centered data, in which case they would also be (N, M).
+
+Here is an example of how to load an in-memory, unstructured mesh dataset:
+
+.. code-block:: python
+
+   import yt
+   import numpy
+   from yt.utilities.exodusII_reader import get_data
+
+   coords, connectivity, data = get_data("MOOSE_sample_data/out.e-s010")
+
+This uses a publically available `MOOSE <http://mooseframework.org/>` 
+dataset along with the get_data function to parse the coords, connectivity, 
+and data. Then, these can be loaded as an in-memory dataset as follows:
+
+.. code-block:: python
+
+    mesh_id = 0
+    ds = yt.load_unstructured_mesh(data[mesh_id], connectivity[mesh_id], coords[mesh_id])
+
+Note that load_unstructured_mesh can take either a single or a list of meshes.
+Here, we have selected only the first mesh to load.
+
+.. rubric:: Caveats
+
+* Units will be incorrect unless the data has already been converted to cgs.
+* Integration is not implemented.
+* Some functions may behave oddly or not work at all.
+* Data must already reside in memory.
+
 Generic Particle Data
 ---------------------
 

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/quickstart/6)_Volume_Rendering.ipynb
--- a/doc/source/quickstart/6)_Volume_Rendering.ipynb
+++ b/doc/source/quickstart/6)_Volume_Rendering.ipynb
@@ -56,14 +56,14 @@
      "cell_type": "markdown",
      "metadata": {},
      "source": [
-      "If we want to apply a clipping, we can specify the `clip_ratio`.  This will clip the upper bounds to this value times the standard deviation of the values in the image array."
+      "If we want to apply a clipping, we can specify the `sigma_clip`.  This will clip the upper bounds to this value times the standard deviation of the values in the image array."
      ]
     },
     {
      "cell_type": "code",
      "collapsed": false,
      "input": [
-      "cam.show(clip_ratio=4)"
+      "cam.show(sigma_clip=4)"
      ],
      "language": "python",
      "metadata": {},
@@ -83,7 +83,7 @@
       "tf = yt.ColorTransferFunction((-28, -25))\n",
       "tf.add_layers(4, w=0.03)\n",
       "cam = ds.camera([0.5, 0.5, 0.5], [1.0, 1.0, 1.0], (20.0, 'kpc'), 512, tf, no_ghost=False)\n",
-      "cam.show(clip_ratio=4.0)"
+      "cam.show(sigma_clip=4.0)"
      ],
      "language": "python",
      "metadata": {},
@@ -93,4 +93,4 @@
    "metadata": {}
   }
  ]
-}
\ No newline at end of file
+}

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/reference/api/api.rst
--- a/doc/source/reference/api/api.rst
+++ b/doc/source/reference/api/api.rst
@@ -418,6 +418,7 @@
    ~yt.frontends.stream.data_structures.load_amr_grids
    ~yt.frontends.stream.data_structures.load_particles
    ~yt.frontends.stream.data_structures.load_hexahedral_mesh
+   ~yt.frontends.stream.data_structures.load_unstructured_mesh
 
 Derived Datatypes
 -----------------
@@ -606,36 +607,57 @@
 
 See also :ref:`volume_rendering`.
 
-Here are the primary entry points:
+Here are the primary entry points and the main classes involved in the 
+Scene infrastructure:
 
 .. autosummary::
    :toctree: generated/
 
+   ~yt.visualization.volume_rendering.volume_rendering.volume_render
+   ~yt.visualization.volume_rendering.volume_rendering.create_scene
+   ~yt.visualization.volume_rendering.off_axis_projection.off_axis_projection
+   ~yt.visualization.volume_rendering.scene.Scene
    ~yt.visualization.volume_rendering.camera.Camera
-   ~yt.visualization.volume_rendering.camera.off_axis_projection
-   ~yt.visualization.volume_rendering.camera.allsky_projection
+   ~yt.utilities.amr_kdtree.amr_kdtree.AMRKDTree
 
-These objects set up the way the image looks:
+The different kinds of sources:
 
 .. autosummary::
    :toctree: generated/
 
-   ~yt.visualization.volume_rendering.transfer_functions.ColorTransferFunction
-   ~yt.visualization.volume_rendering.transfer_functions.MultiVariateTransferFunction
-   ~yt.visualization.volume_rendering.transfer_functions.PlanckTransferFunction
-   ~yt.visualization.volume_rendering.transfer_functions.ProjectionTransferFunction
-   ~yt.visualization.volume_rendering.transfer_functions.TransferFunction
+   ~yt.visualization.volume_rendering.render_source.RenderSource
+   ~yt.visualization.volume_rendering.render_source.VolumeSource
+   ~yt.visualization.volume_rendering.render_source.PointSource
+   ~yt.visualization.volume_rendering.render_source.LineSource
+   ~yt.visualization.volume_rendering.render_source.BoxSource
+   ~yt.visualization.volume_rendering.render_source.GridSource
+   ~yt.visualization.volume_rendering.render_source.CoordinateVectorSource
+   ~yt.visualization.volume_rendering.render_source.MeshSource
 
-There are also advanced objects for particular use cases:
+The different kinds of transfer functions:
 
 .. autosummary::
    :toctree: generated/
 
-   ~yt.visualization.volume_rendering.camera.FisheyeCamera
-   ~yt.visualization.volume_rendering.camera.MosaicCamera
-   ~yt.visualization.volume_rendering.camera.PerspectiveCamera
-   ~yt.utilities.amr_kdtree.amr_kdtree.AMRKDTree
-   ~yt.visualization.volume_rendering.camera.StereoPairCamera
+   ~yt.visualization.volume_rendering.transfer_functions.TransferFunction
+   ~yt.visualization.volume_rendering.transfer_functions.ColorTransferFunction
+   ~yt.visualization.volume_rendering.transfer_functions.ProjectionTransferFunction
+   ~yt.visualization.volume_rendering.transfer_functions.PlanckTransferFunction
+   ~yt.visualization.volume_rendering.transfer_functions.MultiVariateTransferFunction
+   ~yt.visualization.volume_rendering.transfer_function_helper.TransferFunctionHelper
+ 
+The different kinds of lenses:
+
+.. autosummary::
+   :toctree: generated/
+
+   ~yt.visualization.volume_rendering.lens.Lens
+   ~yt.visualization.volume_rendering.lens.PlaneParallelLens
+   ~yt.visualization.volume_rendering.lens.PerspectiveLens
+   ~yt.visualization.volume_rendering.lens.StereoPerspectiveLens
+   ~yt.visualization.volume_rendering.lens.FisheyeLens
+   ~yt.visualization.volume_rendering.lens.SphericalLens
+   ~yt.visualization.volume_rendering.lens.StereoSphericalLens
 
 Streamlining
 ^^^^^^^^^^^^

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/visualizing/TransferFunctionHelper_Tutorial.ipynb
--- a/doc/source/visualizing/TransferFunctionHelper_Tutorial.ipynb
+++ b/doc/source/visualizing/TransferFunctionHelper_Tutorial.ipynb
@@ -1,7 +1,7 @@
 {
  "metadata": {
   "name": "",
-  "signature": "sha256:5a1547973517987ff047f1b2405277a0e98392e8fd5ffe04521cb2dc372d32d3"
+  "signature": "sha256:ed09405c56bab51abd351d107a4354726709d289b965f274106f4451b387f5ba"
  },
  "nbformat": 3,
  "nbformat_minor": 0,
@@ -25,6 +25,8 @@
       "import numpy as np\n",
       "from IPython.core.display import Image\n",
       "from yt.visualization.volume_rendering.transfer_function_helper import TransferFunctionHelper\n",
+      "from yt.visualization.volume_rendering.render_source import VolumeSource\n",
+      "from yt.visualization.volume_rendering.camera import Camera\n",
       "\n",
       "def showme(im):\n",
       "    # screen out NaNs\n",
@@ -66,7 +68,7 @@
      "cell_type": "code",
      "collapsed": false,
      "input": [
-      "tfh = yt.TransferFunctionHelper(ds)"
+      "tfh = TransferFunctionHelper(ds)"
      ],
      "language": "python",
      "metadata": {},
@@ -84,7 +86,7 @@
      "collapsed": false,
      "input": [
       "# Build a transfer function that is a multivariate gaussian in temperature\n",
-      "tfh = yt.TransferFunctionHelper(ds)\n",
+      "tfh = TransferFunctionHelper(ds)\n",
       "tfh.set_field('temperature')\n",
       "tfh.set_log(True)\n",
       "tfh.set_bounds()\n",
@@ -124,7 +126,7 @@
      "cell_type": "code",
      "collapsed": false,
      "input": [
-      "tfh = yt.TransferFunctionHelper(ds)\n",
+      "tfh = TransferFunctionHelper(ds)\n",
       "tfh.set_field('temperature')\n",
       "tfh.set_bounds()\n",
       "tfh.set_log(True)\n",
@@ -143,27 +145,20 @@
      "cell_type": "markdown",
      "metadata": {},
      "source": [
-      "Finally, let's take a look at the volume rendering."
+      "Finally, let's take a look at the volume rendering. First use the helper function to create a default rendering, then we override this with the transfer function we just created."
      ]
     },
     {
      "cell_type": "code",
      "collapsed": false,
      "input": [
-      "L = [-0.1, -1.0, -0.1]\n",
-      "c = ds.domain_center\n",
-      "W = 1.5*ds.domain_width\n",
-      "Npixels = 512 \n",
-      "cam = ds.camera(c, L, W, Npixels, tfh.tf, fields=['temperature'],\n",
-      "                  north_vector=[1.,0.,0.], steady_north=True, \n",
-      "                  sub_samples=5, no_ghost=False)\n",
+      "im, sc = yt.volume_render(ds, ['temperature'])\n",
       "\n",
-      "# Here we substitute the TransferFunction we constructed earlier.\n",
-      "cam.transfer_function = tfh.tf\n",
+      "source = sc.get_source(0)\n",
+      "source.set_transfer_function(tfh.tf)\n",
+      "im2 = sc.render()\n",
       "\n",
-      "\n",
-      "im = cam.snapshot()\n",
-      "showme(im[:,:,:3])"
+      "showme(im2[:,:,:3])"
      ],
      "language": "python",
      "metadata": {},

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/visualizing/Volume_Rendering_Tutorial.ipynb
--- /dev/null
+++ b/doc/source/visualizing/Volume_Rendering_Tutorial.ipynb
@@ -0,0 +1,272 @@
+{
+ "metadata": {
+  "name": "",
+  "signature": "sha256:16b0b0137841594b135cb8e07f6029e0cd646630816929435e584cbbf10555b4"
+ },
+ "nbformat": 3,
+ "nbformat_minor": 0,
+ "worksheets": [
+  {
+   "cells": [
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "This notebook shows how to use the new (in version 3.3) Scene interface to create custom volume renderings. To begin, we load up a dataset and use the yt.create_scene method to set up a basic Scene. We store the Scene in a variable called 'sc' and render the default ('gas', 'density') field."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "import yt\n",
+      "import numpy as np\n",
+      "from yt.visualization.volume_rendering.transfer_function_helper import TransferFunctionHelper\n",
+      "from yt.visualization.volume_rendering.api import Scene, Camera, VolumeSource\n",
+      "\n",
+      "ds = yt.load(\"IsolatedGalaxy/galaxy0030/galaxy0030\")\n",
+      "sc = yt.create_scene(ds)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Now we can look at some information about the Scene we just created using the python print keyword:"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "print sc"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "This prints out information about the Sources, Camera, and Lens associated with this Scene. Each of these can also be printed individually. For example, to print only the information about the first (and currently, only) Source, we can do:"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "print sc.get_source(0)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "We can see that the yt.create_source has created a VolumeSource with default values for the center, bounds, and transfer function. Now, let's see what this Scene looks like. In the notebook, we can do this by calling sc.show(). "
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "sc.show()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "That looks okay, but it's a little too zoomed-out. To fix this, let's modify the Camera associated with our Scene. This next bit of code will zoom in the camera (i.e. decrease the width of the view) by a factor of 3."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "sc.camera.zoom(3.0)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Now when we print the Scene, we see that the Camera width has decreased by a factor of 3:"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "print sc"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "To see what this looks like, we re-render the image and display the scene again. Note that we don't actually have to call sc.show() here - we can just have Ipython evaluate the Scene and that will display it automatically."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "sc.render()\n",
+      "sc"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "That's better! The image looks a little washed-out though, so we use the sigma_clip argument to sc.show() to improve the contrast:"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "sc.show(sigma_clip=4.0)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Next, we demonstrate how to change the mapping between the field values and the colors in the image. We use the TransferFunctionHelper to create a new transfer function using the \"gist_rainbow\" colormap, and then re-create the image as follows:"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "# Set up a custom transfer function using the TransferFunctionHelper. \n",
+      "# We use 10 Gaussians evenly spaced logarithmically between the min and max\n",
+      "# field values.\n",
+      "tfh = TransferFunctionHelper(ds)\n",
+      "tfh.set_field('density')\n",
+      "tfh.set_log(True)\n",
+      "tfh.set_bounds()\n",
+      "tfh.build_transfer_function()\n",
+      "tfh.tf.add_layers(10, colormap='gist_rainbow')\n",
+      "\n",
+      "# Grab the first render source and set it to use the new transfer function\n",
+      "render_source = sc.get_source(0)\n",
+      "render_source.transfer_function = tfh.tf\n",
+      "\n",
+      "sc.render()\n",
+      "sc.show(sigma_clip=4.0)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Now, let's try using a different lens type. We can give a sense of depth to the image by using the perspective lens. To do, we create a new Camera below. We also demonstrate how to switch the camera to a new position and orientation."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "cam = Camera(ds, lens_type='perspective')\n",
+      "\n",
+      "# Standing at (x=0.05, y=0.5, z=0.5), we look at the area of x>0.05 (with some open angle\n",
+      "# specified by camera width) along the positive x direction.\n",
+      "cam.position = ds.arr([0.05, 0.5, 0.5], 'code_length')\n",
+      "\n",
+      "normal_vector = [1., 0., 0.]\n",
+      "north_vector = [0., 0., 1.]\n",
+      "cam.switch_orientation(normal_vector=normal_vector,\n",
+      "                       north_vector=north_vector)\n",
+      "\n",
+      "# The width determines the opening angle\n",
+      "cam.set_width(ds.domain_width * 0.5)\n",
+      "\n",
+      "sc.camera = cam\n",
+      "print sc.camera"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "The resulting image looks like:"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "sc.render()\n",
+      "sc.show(sigma_clip=4.0)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Finally, the next cell restores the lens and the transfer function to the defaults, moves the camera, and adds an opaque source  that shows the axes of the simulation coordinate system."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "# set the lens type back to plane-parallel\n",
+      "sc.camera.set_lens('plane-parallel')\n",
+      "\n",
+      "# move the camera to the left edge of the domain\n",
+      "sc.camera.set_position(ds.domain_left_edge)\n",
+      "sc.camera.switch_orientation()\n",
+      "\n",
+      "# reset the transfer function to the default\n",
+      "render_source = sc.get_source(0)\n",
+      "render_source.build_default_transfer_function()\n",
+      "\n",
+      "# add an opaque source to the scene\n",
+      "sc.annotate_axes()\n",
+      "\n",
+      "sc.render()\n",
+      "sc.show(sigma_clip=4.0)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    }
+   ],
+   "metadata": {}
+  }
+ ]
+}
\ No newline at end of file

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/visualizing/_images/scene_diagram.svg
--- /dev/null
+++ b/doc/source/visualizing/_images/scene_diagram.svg
@@ -0,0 +1,512 @@
+<?xml version="1.0" standalone="yes"?>
+
+<svg version="1.1" viewBox="0.0 0.0 710.0 462.0" fill="none" stroke="none"
+stroke-linecap="square" stroke-miterlimit="10"
+xmlns="http://www.w3.org/2000/svg"
+xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0
+0l710.0 0l0 462.0l-710.0 0l0 -462.0z" clip-rule="nonzero"></path></clipPath><g
+clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l710.4252
+0l0 462.4462l-710.4252 0z" fill-rule="nonzero"></path><path fill="#000000"
+fill-opacity="0.0" d="m50.425198 121.13386l489.73227 0l0 289.6063l-489.73227
+0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0"
+d="m540.1575 121.13386l96.53546 -96.53543l0 289.6063l-96.53546 96.53543z"
+fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0"
+d="m50.425198 121.13386l96.53543 -96.53543l489.7323 0l-96.53546 96.53543z"
+fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0"
+d="m50.425198 121.13386l96.53543 -96.53543l489.7323 0l0 289.6063l-96.53546
+96.53543l-489.73227 0zm0 0l489.73227 0l96.53546 -96.53543m-96.53546 96.53543l0
+289.6063" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.2"
+d="m540.1575 121.13386l96.53546 -96.53543l0 289.6063l-96.53546 96.53543z"
+fill-rule="nonzero"></path><path fill="#ffffff" fill-opacity="0.2"
+d="m50.425198 121.13386l96.53543 -96.53543l489.7323 0l-96.53546 96.53543z"
+fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0"
+stroke-linejoin="round" stroke-linecap="butt" d="m50.425198 121.13386l96.53543
+-96.53543l489.7323 0l0 289.6063l-96.53546 96.53543l-489.73227 0zm0 0l489.73227
+0l96.53546 -96.53543m-96.53546 96.53543l0 289.6063"
+fill-rule="nonzero"></path><path fill="#cccccc" d="m399.52493 268.74014l0 0c0
+-6.521576 14.789307 -11.80838 33.032806 -11.80838c18.24353 0 33.032806 5.286804
+33.032806 11.80838l0 47.233612c0 6.5216064 -14.789276 11.808411 -33.032806
+11.808411c-18.2435 0 -33.032806 -5.286804 -33.032806 -11.808411z"
+fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0"
+d="m465.59055 268.74014l0 0c0 6.5216064 -14.789276 11.808411 -33.032806
+11.808411c-18.2435 0 -33.032806 -5.286804 -33.032806 -11.808411"
+fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0"
+d="m399.52493 268.74014l0 0c0 -6.521576 14.789307 -11.80838 33.032806
+-11.80838c18.24353 0 33.032806 5.286804 33.032806 11.80838l0 47.233612c0
+6.5216064 -14.789276 11.808411 -33.032806 11.808411c-18.2435 0 -33.032806
+-5.286804 -33.032806 -11.808411z" fill-rule="nonzero"></path><path
+stroke="#000000" stroke-width="2.0" stroke-linejoin="round"
+stroke-linecap="butt" d="m465.59055 268.74014l0 0c0 6.5216064 -14.789276
+11.808411 -33.032806 11.808411c-18.2435 0 -33.032806 -5.286804 -33.032806
+-11.808411" fill-rule="nonzero"></path><path stroke="#000000"
+stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m399.52493
+268.74014l0 0c0 -6.521576 14.789307 -11.80838 33.032806 -11.80838c18.24353 0
+33.032806 5.286804 33.032806 11.80838l0 47.233612c0 6.5216064 -14.789276
+11.808411 -33.032806 11.808411c-18.2435 0 -33.032806 -5.286804 -33.032806
+-11.808411z" fill-rule="nonzero"></path><path fill="#cccccc" d="m333.45938
+255.11298l20.896912 1.2207031E-4l6.457367 -18.286331l6.457367
+18.286331l20.896881 -1.2207031E-4l-16.906006 11.301453l6.457611
+18.286224l-16.905853 -11.301636l-16.905884 11.301636l6.4576416 -18.286224z"
+fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0"
+stroke-linejoin="round" stroke-linecap="butt" d="m333.45938 255.11298l20.896912
+1.2207031E-4l6.457367 -18.286331l6.457367 18.286331l20.896881
+-1.2207031E-4l-16.906006 11.301453l6.457611 18.286224l-16.905853
+-11.301636l-16.905884 11.301636l6.4576416 -18.286224z"
+fill-rule="nonzero"></path><path fill="#cccccc" d="m408.14435
+214.56168l38.53543 0l0 22.251968l-38.53543 0z" fill-rule="nonzero"></path><path
+fill="#a3a3a3" d="m446.67978 214.56168l7.417328 -7.4173126l0
+22.251968l-7.417328 7.4173126z" fill-rule="nonzero"></path><path fill="#d6d6d6"
+d="m408.14435 214.56168l7.417328 -7.4173126l38.53543 0l-7.417328 7.4173126z"
+fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0"
+d="m408.14435 214.56168l7.417328 -7.4173126l38.53543 0l0 22.251968l-7.417328
+7.4173126l-38.53543 0zm0 0l38.53543 0l7.417328 -7.4173126m-7.417328 7.4173126l0
+22.251968" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0"
+stroke-linejoin="round" stroke-linecap="butt" d="m408.14435 214.56168l7.417328
+-7.4173126l38.53543 0l0 22.251968l-7.417328 7.4173126l-38.53543 0zm0 0l38.53543
+0l7.417328 -7.4173126m-7.417328 7.4173126l0 22.251968"
+fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0"
+d="m329.62204 327.78217l135.9685 0l0 54.582672l-135.9685 0z"
+fill-rule="nonzero"></path><path fill="#000000" d="m354.4149 362.55652q-0.15625
+0.0625 -0.375 0.0625q-0.234375 0 -0.5 -0.140625q-2.796875 -3.015625 -3.734375
+-7.765625q-0.328125 -1.640625 -0.328125 -3.40625q0 -3.375 1.203125
+-6.4375q1.046875 -2.703125 2.859375 -4.671875q0.125 -0.109375 0.515625
+-0.109375q0.375 0 0.640625 0.25q0.265625 0.25 0.265625 0.5625q-2.4375 4.171875
+-2.859375 7.734375q-0.140625 1.25 -0.140625 2.625q-0.015625 0.0625 -0.015625
+0.109375q0 1.34375 0.15625 2.5625q0.140625 1.25 0.5 2.515625q0.6875 2.453125
+2.359375 5.328125q0 0.515625 -0.546875 0.78125zm5.5 -4.3125l1.34375 0q1.625 0
+2.1875 -0.984375q0.171875 -0.3125 0.171875 -0.671875q0 -0.359375 -0.171875
+-0.625q-0.171875 -0.265625 -0.53125 -0.484375q-0.5625 -0.34375 -1.84375
+-0.734375q-1.28125 -0.390625 -1.953125 -0.671875q-0.65625 -0.296875 -1.15625
+-0.703125q-1.0 -0.84375 -1.0 -2.3125q0 -2.171875 2.421875 -2.921875q0.90625
+-0.28125 1.796875 -0.28125q0.890625 0 1.640625 0.125q0.765625 0.109375 1.375
+0.390625q1.390625 0.640625 1.390625 1.84375l0 0.0625q0 0.65625 -0.453125
+1.109375q-0.4375 0.4375 -1.140625 0.453125q-1.109375 0 -1.5 -0.953125q-0.125
+-0.296875 -0.125 -0.484375q0 -0.1875 0.140625 -0.890625l-1.15625 0q-0.953125 0
+-1.40625 0.328125q-0.828125 0.578125 -0.828125 1.265625q0 0.90625 1.640625
+1.46875l0.890625 0.3125q2.25 0.75 2.890625 1.28125q0.65625 0.515625 0.9375
+1.140625q0.296875 0.625 0.296875 1.421875q0 0.8125 -0.3125 1.390625q-0.296875
+0.59375 -0.859375 1.015625q-1.21875 0.921875 -3.140625 0.921875q-1.71875 0
+-3.078125 -0.515625q-1.0 -0.375 -1.421875 -1.078125q-0.21875 -0.359375 -0.21875
+-0.765625q0 -0.390625 0.125 -0.6875q0.140625 -0.3125 0.34375 -0.515625q0.453125
+-0.453125 1.15625 -0.453125q0.671875 0 1.140625 0.46875q0.46875 0.4375 0.46875
+1.0l0 0.015625q-0.015625 0.578125 -0.0625 0.71875zm12.8515625 1.8125q-1.25 0
+-2.203125 -0.46875q-0.953125 -0.46875 -1.609375 -1.3125q-1.3125 -1.703125
+-1.3125 -4.453125q0 -2.890625 1.78125 -4.5q1.625 -1.46875 4.078125
+-1.46875l0.03125 0q2.296875 0 3.703125 1.75q1.328125 1.65625 1.328125 4.3125q0
+2.953125 -1.640625 4.59375q-1.546875 1.546875 -4.15625 1.546875zm-1.703125
+-9.578125q-0.4375 0.46875 -0.734375 1.28125q-0.28125 0.8125 -0.28125 2.0q0
+1.203125 0.21875 2.03125q0.234375 0.8125 0.640625 1.359375q0.796875 1.09375
+2.234375 1.09375q1.46875 0 2.28125 -1.28125q0.734375 -1.171875 0.734375
+-3.078125q0 -3.171875 -1.859375 -3.984375q-0.5625 -0.234375 -1.140625
+-0.234375q-0.578125 0 -1.109375 0.171875q-0.53125 0.171875 -0.984375
+0.640625zm18.230469 8.21875q-1.875 1.359375 -3.375 1.359375q-2.953125 0
+-3.796875 -2.375q-0.28125 -0.78125 -0.28125 -1.828125l0 -5.953125l-1.640625
+0q-0.4375 0 -0.4375 -0.890625q0 -0.59375 0.234375 -0.65625q1.96875 -0.5 3.59375
+-0.5q0.515625 0 0.546875 0.9375l0 6.21875q0 2.28125 1.171875 2.71875q0.34375
+0.140625 0.875 0.140625q0.515625 0 0.984375 -0.109375q0.484375 -0.125 0.859375
+-0.28125q0.34375 -0.171875 0.625 -0.375l0.5 -0.375l0 -6.828125l-1.59375
+0q-0.484375 0 -0.484375 -0.875q0 -0.546875 0.3125 -0.671875q0.3125 -0.125 0.75
+-0.21875q0.453125 -0.078125 0.921875 -0.15625q0.921875 -0.109375 1.46875
+-0.125l0.03125 0q0.515625 0 0.625 0.125q0.140625 0.125 0.1875 0.328125q0.078125
+0.296875 0.078125 1.03125l0 8.828125l1.96875 0q0.3125 0 0.3125 0.765625q0
+0.8125 -0.484375 0.890625q-1.1875 0.1875 -2.125 0.1875q-0.9375 0 -1.109375
+-0.09375q-0.15625 -0.09375 -0.28125 -0.265625q-0.1875 -0.25 -0.4375
+-0.953125zm9.6328125 -9.96875l0 0.46875q0 0.140625 -0.015625 0.28125q0 0.140625
+0 0.25q1.375 -1.25 2.75 -1.71875q0.453125 -0.140625 0.921875 -0.15625l0.03125
+0q0.453125 0 0.8125 0.171875q0.375 0.1875 0.609375 0.453125q0.390625 0.46875
+0.390625 0.96875q0 0.515625 -0.125 0.8125q-0.125 0.296875 -0.359375 0.5q-0.5
+0.453125 -0.984375 0.453125q-0.484375 0 -0.75 -0.125q-0.25 -0.140625 -0.453125
+-0.34375q-0.421875 -0.453125 -0.421875 -1.0q-0.671875 0.3125 -1.03125
+0.71875q-0.34375 0.421875 -0.578125 0.765625l-0.515625 0.796875l0
+6.140625l2.84375 0q0.265625 0 0.265625 0.71875q0 0.578125 -0.171875
+0.765625q-0.171875 0.171875 -0.3125 0.171875l-6.8125 0q-0.328125 0 -0.328125
+-0.734375q0.015625 -0.546875 0.3125 -0.84375q0.09375 -0.078125 0.40625
+-0.078125q0.328125 0 0.65625 -0.03125q0.328125 -0.03125 0.515625
+-0.078125q0.328125 -0.109375 0.328125 -0.390625l0 -7.71875l-2.0625 0q-0.453125
+0 -0.453125 -0.921875q0 -0.578125 0.296875 -0.703125q0.296875 -0.140625 0.78125
+-0.21875q0.5 -0.09375 1.015625 -0.140625q0.984375 -0.09375 1.546875
+-0.109375l0.09375 0q0.484375 0 0.578125 0.0625q0.125 0.046875 0.171875
+0.15625q0.046875 0.125 0.046875 0.515625l0 0.140625zm13.277344
+0.78125l-1.078125 0q-1.21875 0 -2.109375 0.921875q-1.125 1.1875 -1.125
+3.40625q0 3.265625 1.828125 4.125q0.5625 0.28125 1.171875 0.28125q0.59375 0
+1.0625 -0.125q0.484375 -0.125 0.953125 -0.34375q0.46875 -0.1875 0.890625
+-0.453125l0.828125 -0.5q0.046875 -0.03125 0.15625 -0.03125q0.109375 0 0.265625
+0.140625q0.171875 0.125 0.3125 0.3125q0.3125 0.4375 0.3125 0.734375q0 0.296875
+-0.140625 0.40625q-2.234375 1.671875 -4.875 1.671875q-2.4375 0 -3.828125
+-1.703125q-1.328125 -1.640625 -1.328125 -4.515625q0 -2.8125 1.6875
+-4.453125q1.59375 -1.515625 4.078125 -1.53125q2.640625 0.015625 3.65625
+1.15625q0.390625 0.453125 0.390625 0.953125q0 0.5 -0.109375 0.796875q-0.140625
+0.296875 -0.359375 0.5q-0.46875 0.46875 -1.140625 0.46875q-0.65625 0 -1.125
+-0.46875q-0.46875 -0.4375 -0.46875 -0.890625q0 -0.4375 0.09375
+-0.859375zm5.046875 4.28125q0 -1.453125 0.484375 -2.578125q0.46875 -1.09375
+1.265625 -1.84375q1.609375 -1.5 3.984375 -1.515625l0.046875 0q2.171875 0
+3.359375 1.375q1.1875 1.359375 1.1875 3.921875q0 0.546875 -0.515625
+0.953125q-0.484375 0.390625 -1.234375 0.390625l-6.171875 0q0.203125 2.734375
+1.90625 3.515625q0.53125 0.234375 1.140625 0.234375q0.59375 0 1.0625
+-0.125q0.46875 -0.140625 0.890625 -0.34375q0.4375 -0.203125 0.859375
+-0.46875q0.84375 -0.53125 1.0 -0.53125q0.140625 0.015625 0.3125
+0.140625q0.140625 0.140625 0.28125 0.328125q0.296875 0.4375 0.3125 0.75l0
+0.015625q0 0.28125 -0.125 0.375q-2.15625 1.671875 -4.875 1.671875q-2.453125 0
+-3.828125 -1.71875q-1.34375 -1.65625 -1.34375 -4.546875zm7.921875 -1.0625l0
+-0.046875q0 -2.3125 -1.34375 -2.859375q-0.421875 -0.15625 -0.9375
+-0.15625q-0.515625 0 -1.078125 0.1875q-0.5625 0.1875 -1.03125 0.5625q-1.046875
+0.859375 -1.125 2.3125l5.515625 0zm7.3867188 5.515625l1.34375 0q1.625 0 2.1875
+-0.984375q0.171875 -0.3125 0.171875 -0.671875q0 -0.359375 -0.171875
+-0.625q-0.171875 -0.265625 -0.53125 -0.484375q-0.5625 -0.34375 -1.84375
+-0.734375q-1.28125 -0.390625 -1.953125 -0.671875q-0.65625 -0.296875 -1.15625
+-0.703125q-1.0 -0.84375 -1.0 -2.3125q0 -2.171875 2.421875 -2.921875q0.90625
+-0.28125 1.796875 -0.28125q0.890625 0 1.640625 0.125q0.765625 0.109375 1.375
+0.390625q1.390625 0.640625 1.390625 1.84375l0 0.0625q0 0.65625 -0.453125
+1.109375q-0.4375 0.4375 -1.140625 0.453125q-1.109375 0 -1.5 -0.953125q-0.125
+-0.296875 -0.125 -0.484375q0 -0.1875 0.140625 -0.890625l-1.15625 0q-0.953125 0
+-1.40625 0.328125q-0.828125 0.578125 -0.828125 1.265625q0 0.90625 1.640625
+1.46875l0.890625 0.3125q2.25 0.75 2.890625 1.28125q0.65625 0.515625 0.9375
+1.140625q0.296875 0.625 0.296875 1.421875q0 0.8125 -0.3125 1.390625q-0.296875
+0.59375 -0.859375 1.015625q-1.21875 0.921875 -3.140625 0.921875q-1.71875 0
+-3.078125 -0.515625q-1.0 -0.375 -1.421875 -1.078125q-0.21875 -0.359375 -0.21875
+-0.765625q0 -0.390625 0.125 -0.6875q0.140625 -0.3125 0.34375 -0.515625q0.453125
+-0.453125 1.15625 -0.453125q0.671875 0 1.140625 0.46875q0.46875 0.4375 0.46875
+1.0l0 0.015625q-0.015625 0.578125 -0.0625 0.71875zm9.1015625 4.234375q-0.265625
+0.140625 -0.484375 0.140625q-0.234375 0 -0.390625 -0.0625q-0.140625 -0.0625
+-0.265625 -0.171875q-0.28125 -0.25 -0.28125 -0.609375q2.4375 -4.140625 2.859375
+-7.84375q0.140625 -1.265625 0.15625 -2.671875l0 -0.09375q0 -1.328125 -0.140625
+-2.53125q-0.15625 -1.25 -0.5 -2.484375q-0.6875 -2.390625 -2.375 -5.25q0 -0.3125
+0.265625 -0.5625q0.28125 -0.25 0.5625 -0.25q0.46875 0 0.59375 0.109375q2.828125
+3.046875 3.734375 7.6875q0.328125 1.625 0.328125 3.421875q0 5.0625 -2.5
+9.109375q-0.734375 1.1875 -1.5625 2.0625z" fill-rule="nonzero"></path><path
+fill="#000000" fill-opacity="0.0" d="m147.41995 24.598425l135.9685 0l0
+54.582672l-135.9685 0z" fill-rule="nonzero"></path><path fill="#000000"
+d="m187.11708 54.654053q0.75 0.40625 1.875 0.40625q1.125 0 1.8125
+-0.203125q0.671875 -0.1875 1.15625 -0.5625q1.03125 -0.78125 1.046875
+-2.078125l0 -0.015625q0 -1.46875 -2.40625 -2.859375q-0.671875 -0.390625
+-1.46875 -0.78125l-1.6875 -0.859375q-3.1875 -1.6875 -3.1875 -4.5q0 -2.171875
+1.75 -3.375q1.578125 -1.0625 4.0 -1.0625l0.109375 0q1.796875 0 3.34375
+0.8125q1.859375 0.953125 1.859375 2.515625q0 0.75 -0.515625 1.296875q-0.515625
+0.515625 -1.28125 0.515625q-0.765625 0 -1.28125 -0.515625q-0.53125 -0.53125
+-0.53125 -1.296875q0 -0.625 0.34375 -1.09375q-0.6875 -0.421875 -1.65625
+-0.421875q-0.96875 0 -1.59375 0.171875q-0.640625 0.15625 -1.109375
+0.484375q-0.953125 0.671875 -0.96875 1.921875l0 0.015625q0 0.921875 1.015625
+1.65625q0.5 0.375 1.21875 0.75l1.578125 0.8125q2.59375 1.296875 3.640625
+2.390625q1.296875 1.34375 1.296875 3.234375q0 2.15625 -1.6875 3.515625q-1.6875
+1.34375 -4.28125 1.34375q-1.984375 0 -3.6875 -0.828125q-1.984375 -0.984375
+-1.984375 -2.453125q0 -0.78125 0.53125 -1.296875q0.53125 -0.53125 1.28125
+-0.53125q0.765625 0 1.28125 0.53125q0.515625 0.53125 0.515625 1.15625q0 0.625
+-0.328125 1.203125zm17.214844 -8.328125l-1.078125 0q-1.21875 0 -2.109375
+0.921875q-1.125 1.1875 -1.125 3.40625q0 3.265625 1.828125 4.125q0.5625 0.28125
+1.171875 0.28125q0.59375 0 1.0625 -0.125q0.484375 -0.125 0.953125
+-0.34375q0.46875 -0.1875 0.890625 -0.453125l0.828125 -0.5q0.046875 -0.03125
+0.15625 -0.03125q0.109375 0 0.265625 0.140625q0.171875 0.125 0.3125
+0.3125q0.3125 0.4375 0.3125 0.734375q0 0.296875 -0.140625 0.40625q-2.234375
+1.671875 -4.875 1.671875q-2.4375 0 -3.828125 -1.703125q-1.328125 -1.640625
+-1.328125 -4.515625q0 -2.8125 1.6875 -4.453125q1.59375 -1.515625 4.078125
+-1.53125q2.640625 0.015625 3.65625 1.15625q0.390625 0.453125 0.390625
+0.953125q0 0.5 -0.109375 0.796875q-0.140625 0.296875 -0.359375 0.5q-0.46875
+0.46875 -1.140625 0.46875q-0.65625 0 -1.125 -0.46875q-0.46875 -0.4375 -0.46875
+-0.890625q0 -0.4375 0.09375 -0.859375zm5.046875 4.28125q0 -1.453125 0.484375
+-2.578125q0.46875 -1.09375 1.265625 -1.84375q1.6093903 -1.5 3.9843903
+-1.515625l0.046875 0q2.171875 0 3.359375 1.375q1.1875 1.359375 1.1875
+3.921875q0 0.546875 -0.515625 0.953125q-0.484375 0.390625 -1.234375
+0.390625l-6.171875 0q0.203125 2.734375 1.90625 3.515625q0.53125 0.234375
+1.140625 0.234375q0.59375 0 1.0625 -0.125q0.46875 -0.140625 0.890625
+-0.34375q0.4375 -0.203125 0.859375 -0.46875q0.84375 -0.53125 1.0
+-0.53125q0.140625 0.015625 0.3125 0.140625q0.140625 0.140625 0.28125
+0.328125q0.296875 0.4375 0.3125 0.75l0 0.015625q0 0.28125 -0.125 0.375q-2.15625
+1.671875 -4.875 1.671875q-2.453125 0 -3.8281403 -1.71875q-1.34375 -1.65625
+-1.34375 -4.546875zm7.9218903 -1.0625l0 -0.046875q0 -2.3125 -1.34375
+-2.859375q-0.421875 -0.15625 -0.9375 -0.15625q-0.515625 0 -1.078125
+0.1875q-0.5625 0.1875 -1.03125 0.5625q-1.046875 0.859375 -1.125 2.3125l5.515625
+0zm12.386719 7.09375q-0.3125 0 -0.3125 -0.71875q0 -0.5625 0.171875 -0.75q0.1875
+-0.1875 0.3125 -0.1875q1.21875 0 1.21875 -0.5l0 -3.484375q0 -2.265625 -0.265625
+-2.96875q-0.25 -0.71875 -0.65625 -1.015625q-0.40625 -0.296875 -1.09375
+-0.296875q-1.296875 0 -3.203125 1.5l0 6.765625l1.96875 0q0.296875 0 0.296875
+0.71875q0 0.5625 -0.171875 0.75q-0.171875 0.1875 -0.3125 0.1875l-5.96875
+0q-0.3125 0 -0.3125 -0.71875q0 -0.5625 0.171875 -0.75q0.1875 -0.1875 0.3125
+-0.1875l0.125 0q1.34375 0 1.53125 -0.265625q0.0625 -0.09375 0.0625 -0.234375l0
+-7.765625l-2.0625 0q-0.359375 -0.015625 -0.453125 -0.578125q-0.015625 -0.171875
+-0.015625 -0.34375q0 -0.53125 0.296875 -0.65625q0.3125 -0.125 0.796875
+-0.21875q0.484375 -0.09375 1.015625 -0.140625q1.046875 -0.125 1.578125
+-0.125l0.046875 0q0.515625 0.015625 0.625 0.125q0.109375 0.109375 0.15625
+0.296875q0.0625 0.203125 0.0625 0.84375l0 0.21875q1.765625 -0.984375 3.21875
+-1.34375q0.46875 -0.125 1.203125 -0.125q0.703125 0 1.421875 0.3125q0.734375
+0.3125 1.15625 0.890625q0.75 1.03125 0.75 3.28125l0 5.828125l1.828125 0q0.3125
+0 0.3125 0.71875q0 0.5625 -0.1875 0.75q-0.171875 0.1875 -0.296875
+0.1875l-5.328125 0zm7.0078125 -6.03125q0 -1.453125 0.484375 -2.578125q0.46875
+-1.09375 1.265625 -1.84375q1.609375 -1.5 3.984375 -1.515625l0.046875 0q2.171875
+0 3.359375 1.375q1.1875 1.359375 1.1875 3.921875q0 0.546875 -0.515625
+0.953125q-0.484375 0.390625 -1.234375 0.390625l-6.171875 0q0.203125 2.734375
+1.90625 3.515625q0.53125 0.234375 1.140625 0.234375q0.59375 0 1.0625
+-0.125q0.46875 -0.140625 0.890625 -0.34375q0.4375 -0.203125 0.859375
+-0.46875q0.84375 -0.53125 1.0 -0.53125q0.140625 0.015625 0.3125
+0.140625q0.140625 0.140625 0.28125 0.328125q0.296875 0.4375 0.3125 0.75l0
+0.015625q0 0.28125 -0.125 0.375q-2.15625 1.671875 -4.875 1.671875q-2.453125 0
+-3.828125 -1.71875q-1.34375 -1.65625 -1.34375 -4.546875zm7.921875 -1.0625l0
+-0.046875q0 -2.3125 -1.34375 -2.859375q-0.421875 -0.15625 -0.9375
+-0.15625q-0.515625 0 -1.078125 0.1875q-0.5625 0.1875 -1.03125 0.5625q-1.046875
+0.859375 -1.125 2.3125l5.515625 0z" fill-rule="nonzero"></path><path
+fill="#000000" fill-opacity="0.0" d="m133.71216 260.5739l55.118057
+-122.19269l60.047882 27.08609l-12.547058 67.867874l-42.571 54.324814z"
+fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0"
+stroke-linejoin="round" stroke-linecap="butt" d="m133.71216 260.5739l55.118057
+-122.19269l60.047882 27.08609l-12.547058 67.867874l-42.571 54.324814z"
+fill-rule="nonzero"></path><path fill="#000000" d="m171.84547
+238.87013q-0.6672516 0.4532318 -1.1298218 1.4787292q-0.4625702 1.0254974
+-0.43501282 2.066391q0.033996582 1.0266571 0.52685547 1.9860382q1.046875
+2.0491943 3.6611786 3.2455902q5.4123535 2.4413757 7.995346 0.40112305q0.8348236
+-0.63475037 1.2331543 -1.5178223q0.00642395 -0.01423645 -0.0078125
+-0.0206604q0.3983307 -0.8830719 0.5014343 -1.4536438q0.09527588 -0.59124756
+0.0821991 -1.0942383q-0.013092041 -0.5029907 -0.07897949 -0.9269562q-0.15101624
+-0.80519104 -0.08035278 -0.961853q0.07067871 -0.15667725 0.24887085
+-0.24771118q0.18461609 -0.105285645 0.41334534 -0.15637207q0.5130615
+-0.11138916 0.78367615 0.010681152q0.28486633 0.12849426 0.38008118
+0.41140747q0.080963135 0.27650452 0.16526794 0.811615q0.09072876 0.520874
+0.07725525 1.234726q-0.0713501 1.7162018 -0.7523651 3.2259674q-0.68743896
+1.5240021 -1.6971283 2.5084076q-1.023941 0.97798157 -2.4385529
+1.4540405q-3.0437317 1.0096588 -7.003296 -0.7763977q-4.1162415 -1.8567352
+-5.4350586 -4.9370728q-1.2121582 -2.8608093 0.22697449 -6.0512543l0.0128479
+-0.02848816q0.7581177 -1.6806793 2.199585 -2.7102814q1.5976105 -1.1477356
+2.9222107 -0.5502472q0.6836548 0.30838013 0.9701538 1.0032654q0.25801086
+0.68203735 -0.05680847 1.3799438q-0.31480408 0.6979065 -0.99684143
+0.95591736q-0.70269775 0.26582336 -1.3578796 -0.029708862q-0.64094543
+-0.28910828 -0.93052673 -0.71113586zm8.361542 -5.578766q0.32844543
+-0.0061187744 0.6845093 0.1545105q0.3560791 0.16061401 0.5753021
+0.3966217q0.19854736 0.24383545 0.31443787 0.51893616q0.21247864 0.5929413
+-0.05595398 1.226059q-0.44973755 0.9970093 -1.4791718 0.96118164q-0.32202148
+-0.008117676 -0.7208252 -0.1880188q-0.384552 -0.17346191 -0.6235962
+-0.555542q-0.23904419 -0.38208008 -0.32055664 -0.8473816q-0.0750885 -0.47953796
+-0.005508423 -1.013794q0.055343628 -0.5406952 0.18190002 -1.0492706q0.22880554
+-0.9252472 0.6785431 -1.9222565q0.4497223 -0.99702454 1.1049652
+-1.5756531q0.6474304 -0.59928894 1.3814087 -0.7824402q1.2819519 -0.2959442
+3.0195923 0.48786926l5.526306 2.4927673l0.8095093 -1.7946167q0.13491821
+-0.29910278 0.76161194 -0.016418457q0.28485107 0.12849426 0.5040741
+0.36450195q0.22564697 0.22177124 0.17982483 0.47535706q-0.09892273 0.6753082
+-0.6000366 1.7862701q-0.5075531 1.1251984 -0.6081085 1.2341156q-0.08630371
+0.11532593 -0.23098755 0.1700592q-0.28152466 0.13012695 -0.9269409
+0.07896423q0.3696289 1.7265778 -0.45915222 3.563919q-0.7452698 1.6521912
+-2.052353 2.1939087q-1.2101898 0.51686096 -2.5205536 -0.07420349l-0.02848816
+-0.0128479q-1.6379395 -0.7388458 -2.0034027 -2.3606873q-0.33642578 -1.4201813
+0.37670898 -3.0011597l1.1885681 -2.634964q-1.7946167 -0.8095093 -2.4422913
+-0.7416992q-0.64123535 0.05357361 -1.0269623 0.37667847q-0.38571167 0.32310486
+-0.6940918 1.0067749l-0.48828125 1.0824585zm8.212418 3.0359192q0.6039276
+-1.3388367 0.11392212 -3.1025696l-2.079483 -0.93800354l-1.047226
+2.3216248q-0.3854828 0.8545685 -0.28694153 1.3961182q0.17866516 0.9719238
+0.8623352 1.280304q1.2533875 0.5653839 2.0563965 -0.34083557q0.22680664
+-0.27479553 0.3809967 -0.6166382zm11.960602 -26.70578q0.13491821 -0.29910278
+0.889801 0.041412354q0.7548828 0.34049988 0.57499695 0.73931885l-2.2100983
+4.899597q-0.12849426 0.28486633 -0.78367615 -0.010681152q-0.5269928 -0.23770142
+-0.66770935 -0.60972595q-0.039093018 -0.10333252 -5.493164E-4
+-0.188797l0.0128479 -0.02848816q0.50112915 -1.1109467 0.04534912
+-1.3165436l-3.1761932 -1.4327087q-2.0652466 -0.9315796 -2.8153992
+-0.97854614q-0.75798035 -0.06765747 -1.1956329 0.18060303q-0.43766785
+0.24824524 -0.7203522 0.87493896q-0.5332489 1.1821747 0.04385376
+3.5508423l6.1672363 2.7818756l0.75167847 -1.6664276q0.12849426 -0.28486633
+0.8833771 0.055648804q0.7548828 0.34049988 0.5557251 0.7820282l-2.1908264
+4.856888q-0.12849426 0.28486633 -0.755188 0.002166748l-0.04272461
+-0.01927185q-0.49850464 -0.22485352 -0.64704895 -0.61753845q-0.039093018
+-0.10334778 -5.493164E-4 -0.188797l0.00642395 -0.014251709q0.50112915
+-1.1109619 0.04534912 -1.3165436l-3.1761932 -1.4327087q-2.0652466 -0.9315796
+-2.8153992 -0.97854614q-0.75798035 -0.06765747 -1.1956329
+0.18060303q-0.43766785 0.24824524 -0.7203522 0.87493896q-0.5332489 1.1821747
+0.05027771 3.5365906l6.1672363 2.7818909l0.8095093 -1.794632q0.12207031
+-0.27061462 0.74876404 0.012069702q0.5269928 0.23771667 0.63505554
+0.49215698q0.100234985 0.23376465 0.048843384 0.34770203l-2.4477997
+5.426605q-0.13491821 0.29910278 -0.7473755 0.022842407q-0.55548096 -0.25056458
+-0.65571594 -0.48432922q-0.093826294 -0.24801636 -0.042434692
+-0.36195374l0.05140686 -0.11395264q0.55252075 -1.2248993 0.3874817
+-1.5050354q-0.059753418 -0.09552002 -0.1879425 -0.15333557l-7.0787964
+-3.1930695l-0.848053 1.8800812q-0.14915466 0.29267883 -0.7417908
+0.16249084q-0.14886475 -0.05001831 -0.27703857 -0.10783386q-0.4985199
+-0.22486877 -0.49038696 -0.546875q0.014541626 -0.33625793 0.12825012
+-0.8163452q0.113708496 -0.48008728 0.2894287 -0.98361206q0.3164978 -1.0056915
+0.5349426 -1.4899445l0.01927185 -0.04273987q0.22625732 -0.46359253 0.3709259
+-0.5183258q0.14468384 -0.054718018 0.33486938 -0.020355225q0.2108612
+0.026550293 0.7948303 0.28996277l0.19940186 0.08995056q-0.17132568 -2.0142212
+0.09857178 -3.4866028q0.07879639 -0.47868347 0.20729065 -0.76353455q0.8930359
+-1.9797821 2.7947083 -2.1676025q-0.2232666 -2.0890656 0.07040405
+-3.8421173q0.08381653 -0.5278473 0.38578796 -1.1972656q0.30195618 -0.66941833
+0.88235474 -1.196106q0.58680725 -0.54093933 1.2872772 -0.6877899q1.2484283
+-0.2596283 3.2994232 0.66552734l5.3126526 2.396408l0.7452545
+-1.6522064zm-3.3632507 -3.1840363q-1.3246002 -0.59750366 -2.1509247
+-1.5016022q-0.8042755 -0.8770294 -1.1602936 -1.9118042q-0.70558167 -2.0838013
+0.25672913 -4.2551727l0.01927185 -0.04272461q0.8930359 -1.9797821 2.6346893
+-2.4968872q1.727417 -0.5235138 4.063278 0.5301361q0.49850464 0.22485352
+0.6568146 0.8619232q0.15690613 0.60214233 -0.151474 1.2858124l-2.5377502
+5.626007q2.5760498 0.93914795 3.9884949 -0.292099q0.43208313 -0.38789368
+0.6826477 -0.94337463q0.24414062 -0.5412445 0.322937 -1.019928q0.06454468
+-0.48510742 0.052856445 -0.9532013q-0.005264282 -0.48231506 -0.07392883
+-0.97610474q-0.1373291 -0.9875641 -0.0730896 -1.1299896q0.07206726 -0.12176514
+0.25668335 -0.22703552q0.18600464 -0.070373535 0.41474915 -0.12145996q0.520874
+-0.09072876 0.8121643 0.023529053l0.01423645 0.00642395q0.25637817 0.11564636
+0.2904358 0.26812744q0.6374054 2.6529846 -0.48049927 5.1312714q-1.008667
+2.2361603 -3.1407776 2.782837q-2.0622864 0.5438843 -4.6972504
+-0.64468384zm2.2887878 -7.6580963l-0.04272461 -0.01927185q-2.1079712 -0.9508667
+-3.1589966 0.049179077q-0.3159027 0.3203125 -0.5279083 0.790329q-0.21202087
+0.47003174 -0.2723999 1.0598755q-0.06036377 0.58984375 0.08872986
+1.1713257q0.35290527 1.3076477 1.6453857 1.9763489l2.2679138
+-5.0277863zm-0.24273682 -9.189972l0.42729187 0.19273376q0.12817383 0.05783081
+0.24993896 0.12989807q0.12818909 0.05781555 0.22789001 0.10279846q-0.57406616
+-1.7673645 -0.43598938 -3.213501q0.058135986 -0.47087097 0.2366333
+-0.9045868l0.0128479 -0.02848816q0.18630981 -0.41304016 0.49075317
+-0.6699524q0.32510376 -0.26474 0.66360474 -0.36917114q0.5879059 -0.16333008
+1.0436859 0.042251587q0.47003174 0.21202087 0.6892395 0.44802856q0.21922302
+0.23602295 0.30801392 0.53318787q0.2074585 0.64208984 0.008300781
+1.0836182q-0.19917297 0.44154358 -0.42233276 0.63227844q-0.23098755 0.1700592
+-0.4996643 0.271698q-0.58651733 0.19824219 -1.085022 -0.026611328q0.008605957
+0.7409363 0.2311554 1.2355652q0.24320984 0.4868164 0.46018982
+0.84181213l0.51438904 0.79766846l5.5975037 2.5249023l1.1692963
+-2.5922241q0.10922241 -0.24214172 0.7644043 0.053390503q0.5269928 0.23771667
+0.6272278 0.47148132q0.085998535 0.22735596 0.028182983 0.35554504l-2.8011627
+6.209961q-0.13491821 0.29910278 -0.80433655 -0.0028533936q-0.4920807
+-0.23910522 -0.640625 -0.6318054q-0.032669067 -0.11756897 0.095825195
+-0.4024353q0.13491821 -0.29910278 0.24134827 -0.61105347q0.10643005 -0.31195068
+0.14079285 -0.5021515q0.035217285 -0.34407043 -0.22116089 -0.4597168l-7.0360565
+-3.1737976l-0.848053 1.8800812q-0.18632507 0.41305542 -1.0266571
+0.033996582q-0.5269928 -0.23771667 -0.5188751 -0.5597229q-0.0061035156
+-0.32844543 0.12184143 -0.8020935q0.12013245 -0.494339 0.28941345
+-0.9836273q0.31929016 -0.93585205 0.53634644 -1.4550323l0.0385437
+-0.08546448q0.19917297 -0.44152832 0.294693 -0.50128174q0.09411621 -0.094680786
+0.21308899 -0.092437744q0.13322449 0.008666992 0.4893036 0.16929626l0.12818909
+0.05781555zm4.841614 -8.833481q0.32843018 -0.0061187744 0.6845093
+0.15449524q0.3560791 0.16062927 0.5753021 0.39663696q0.19854736 0.24383545
+0.3144226 0.51893616q0.2124939 0.5929413 -0.05593872 1.226059q-0.44973755
+0.9970093 -1.4791718 0.96118164q-0.32202148 -0.008117676 -0.7208252
+-0.1880188q-0.38456726 -0.17346191 -0.6235962 -0.555542q-0.23904419 -0.38208008
+-0.32055664 -0.8473816q-0.0750885 -0.47953796 -0.005508423
+-1.0138092q0.055343628 -0.54067993 0.18190002 -1.0492554q0.22880554 -0.9252472
+0.67852783 -1.9222717q0.44973755 -0.9970093 1.1049805 -1.5756378q0.6474304
+-0.59928894 1.3814087 -0.7824402q1.2819366 -0.2959442 3.0195923
+0.48786926l5.526291 2.4927673l0.8095093 -1.7946167q0.13491821 -0.29910278
+0.76161194 -0.016418457q0.28486633 0.12849426 0.50408936 0.36450195q0.22564697
+0.22177124 0.17982483 0.47535706q-0.09892273 0.6753082 -0.6000519
+1.7862701q-0.5075531 1.1251984 -0.60809326 1.2341156q-0.08631897 0.11532593
+-0.23098755 0.1700592q-0.28152466 0.13012695 -0.9269562 0.07896423q0.36964417
+1.7265778 -0.45913696 3.563919q-0.7452698 1.6521912 -2.0523682
+2.1939087q-1.2101746 0.51686096 -2.5205383 -0.07421875l-0.02848816
+-0.0128479q-1.6379547 -0.73883057 -2.0034027 -2.360672q-0.33642578 -1.4201965
+0.37670898 -3.0011597l1.1885681 -2.634964q-1.794632 -0.8095093 -2.4422913
+-0.7416992q-0.6412506 0.05357361 -1.0269623 0.37667847q-0.38571167 0.32310486
+-0.69410706 1.0067596l-0.488266 1.0824738zm8.212418 3.0359192q0.60391235
+-1.3388519 0.11390686 -3.1025696l-2.079483 -0.93800354l-1.047226
+2.3216095q-0.38546753 0.85458374 -0.28692627 1.3961334q0.17866516 0.9719238
+0.8623352 1.280304q1.2533875 0.56536865 2.0563965 -0.34083557q0.22680664
+-0.2748108 0.3809967 -0.6166382z" fill-rule="nonzero"></path><path
+fill="#f3f3f3" d="m276.30206 161.02286l24.433777 11.021454l0 0c13.494385
+6.0869904 9.273712 44.63011 -9.427124 86.0885c-18.700836 41.458374 -44.800217
+70.13254 -58.294617 64.04556l-24.433746 -11.021454z"
+fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0"
+stroke-linejoin="round" stroke-linecap="butt" d="m276.30206 161.02286l24.433777
+11.021454l0 0c13.494385 6.0869904 9.273712 44.63011 -9.427124
+86.0885c-18.700836 41.458374 -44.800217 70.13254 -58.294617 64.04556l-24.433746
+-11.021454z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0"
+d="m213.59521 297.66257l55.910248 -123.94888l49.75757 22.444397l-55.910248
+123.94888z" fill-rule="nonzero"></path><path fill="#000000" d="m247.30704
+257.94562q0.12207031 -0.27062988 0.8769531 0.069885254q0.7548828 0.34051514
+0.5878296 0.7108154l-0.8673248 1.922821l12.918442 5.827179l2.2614746
+-5.01355l-1.2147522 -1.5249939q-0.16226196 -0.21029663 -0.02734375
+-0.5093994q0.12850952 -0.2848816 0.24188232 -0.42227173q0.10559082 -0.15808105
+0.22039795 -0.26055908q0.26309204 -0.24127197 0.4482727 -0.15774536q0.0569458
+0.0256958 0.06478882 0.0463562l2.484314 2.3204956l-4.6514587
+10.311951q-0.1156311 0.25637817 -0.7423401 -0.026306152l-0.04272461
+-0.019256592q-0.47003174 -0.21203613 -0.6342163 -0.6460571q-0.046905518
+-0.12399292 0.0687561 -0.3803711l0.0128479 -0.028503418q0.0335083 -0.0362854
+0.0592041 -0.09326172q0.10922241 -0.24212646 0.19638062 -0.51135254q0.112854004
+-0.3262024 0.1472168 -0.51638794q0.035217285 -0.3440857 -0.22116089
+-0.4597168l-12.434158 -5.6087646q-0.1709137 -0.0770874 -0.23516846
+0.065338135l-0.7838135 1.7376709q-0.13491821 0.29910278 -0.77027893
+0.14962769q-0.14884949 -0.05001831 -0.27703857 -0.1078186q-0.03491211
+0.001373291 -0.06340027 -0.011474609q-0.09970093 -0.044952393 -0.1787262
+-0.0977478q-0.09327698 -0.05923462 -0.16589355 -0.12625122q-0.1750946
+-0.18182373 -0.1315155 -0.31643677l2.8525543 -6.3239136zm13.346802
+-1.3545227q-1.3246155 -0.59750366 -2.15094 -1.5016174q-0.80426025 -0.87701416
+-1.1602783 -1.9118042q-0.7055969 -2.0838013 0.25671387 -4.2551575l0.01928711
+-0.04273987q0.8930054 -1.9797821 2.634674 -2.496872q1.727417 -0.52352905
+4.0632935 0.53012085q0.49850464 0.22486877 0.6567993 0.8619232q0.15692139
+0.6021576 -0.15145874 1.2858124l-2.5377502 5.626007q2.5760498 0.9391632
+3.9884949 -0.292099q0.43206787 -0.38789368 0.6826477 -0.94337463q0.24414062
+-0.54122925 0.322937 -1.019928q0.06454468 -0.48510742 0.052856445
+-0.95318604q-0.005279541 -0.48233032 -0.07394409 -0.97610474q-0.1373291
+-0.9875641 -0.0730896 -1.1300049q0.07208252 -0.12176514 0.25668335
+-0.22703552q0.18600464 -0.07035828 0.4147644 -0.12145996q0.520874 -0.09072876
+0.8121338 0.023529053l0.014251709 0.00642395q0.25637817 0.11564636 0.2904358
+0.2681427q0.63739014 2.6529694 -0.48049927 5.131256q-1.008667 2.2361603
+-3.1407776 2.7828217q-2.0622864 0.5439148 -4.697235 -0.6446533zm2.2887878
+-7.6581116l-0.04272461 -0.01927185q-2.1079712 -0.95085144 -3.1589966
+0.049179077q-0.31591797 0.32032776 -0.5279236 0.79034424q-0.21200562 0.47001648
+-0.2723999 1.0598602q-0.06036377 0.58984375 0.08874512 1.1713257q0.35290527
+1.3076477 1.6453857 1.9763489l2.2679138 -5.0277863zm11.559509
+-8.374359q-0.12850952 0.28485107 -0.7836914 -0.010681152q-0.51275635
+-0.23129272 -0.6129761 -0.46505737q-0.09384155 -0.24801636 -0.04244995
+-0.36195374q0.50112915 -1.1109619 0.04534912 -1.3165436l-3.176178
+-1.4327087q-2.0652466 -0.9315796 -2.8153992 -0.9785614q-0.7579651 -0.06764221
+-1.1956482 0.18060303q-0.4376526 0.2482605 -0.7203369 0.8749542q-0.53323364
+1.1821747 0.05026245 3.5365906l6.1672363 2.7818756l0.8095093
+-1.7946167q0.12207031 -0.27061462 0.7772522 0.024917603q0.51275635 0.23129272
+0.6130066 0.46505737q0.100250244 0.23376465 0.042419434 0.36195374l-2.4542236
+5.4408417q-0.12850952 0.28486633 -0.7836914 -0.010665894q-0.51272583
+-0.23129272 -0.6129761 -0.46505737q-0.09384155 -0.24801636 -0.042419434
+-0.361969l0.0513916 -0.11393738q0.55252075 -1.2248993 0.3874817
+-1.5050354q-0.059753418 -0.09552002 -0.18795776 -0.15335083l-7.078766
+-3.1930542l-0.8480835 1.8800812q-0.1619873 0.321167 -0.71328735
+0.17532349q-0.16311646 -0.056427002 -0.31976318 -0.12709045q-0.48428345
+-0.21844482 -0.47616577 -0.54045105q0.014556885 -0.33625793 0.12826538
+-0.8163452q0.113708496 -0.48008728 0.2894287 -0.9836273q0.3164978 -1.0056763
+0.5349426 -1.4899445l0.019256592 -0.04272461q0.22625732 -0.46359253 0.37094116
+-0.5183258q0.14468384 -0.054718018 0.33486938 -0.020355225q0.21084595
+0.026550293 0.7948303 0.28996277l0.19940186 0.0899353q-0.17132568 -2.014206
+0.09857178 -3.4865875q0.07879639 -0.47868347 0.38076782 -1.1481018q0.28909302
+-0.64094543 0.86950684 -1.167633q0.5868225 -0.5409241 1.287262
+-0.68777466q1.2484436 -0.2596283 3.2994385 0.6655121l5.3126526
+2.396408l0.75167847 -1.6664276q0.12850952 -0.28486633 0.7836609
+0.010665894q0.51275635 0.23129272 0.6065979 0.47930908q0.10021973 0.23376465
+0.048828125 0.3477173l-2.190796 4.8568726zm2.721405 -9.871262l0.55252075
+-1.2248993q0.6681824 -1.4812775 0.002166748 -2.3987885q-0.21420288 -0.28515625
+-0.54177856 -0.43293762q-0.3276062 -0.14776611 -0.6404114
+-0.10031128q-0.31280518 0.047454834 -0.65997314 0.28511047q-0.5446167
+0.37139893 -1.4275208 1.3787079q-0.88290405 1.007309 -1.4155273
+1.5041199q-0.5404663 0.47613525 -1.1163635 0.7648773q-1.1803284 0.564621
+-2.519165 -0.03929138q-1.9797668 -0.8930359 -1.667633 -3.4090881q0.11627197
+-0.94174194 0.4824829 -1.7536011q0.36621094 -0.8118439 0.7885437
+-1.4441223q0.41448975 -0.65293884 0.92144775 -1.0927734q1.1557617 -1.0042114
+2.252472 -0.5095062l0.05697632 0.0256958q0.59820557 0.26983643 0.82492065
+0.86920166q0.2189331 0.5786896 -0.05593872 1.226059q-0.45617676 1.0112457
+-1.4855957 0.9754181q-0.32202148 -0.008117676 -0.49295044
+-0.08522034q-0.17089844 -0.0770874 -0.7540283 -0.49438477l-0.47543335
+1.0539703q-0.39187622 0.86883545 -0.27911377 1.4167938q0.18649292 0.9925995
+0.8132019 1.2752838q0.8260803 0.3726349 2.0134277 -0.89160156l0.651062
+-0.6833496q1.6088257 -1.7426147 2.3565063 -2.108139q0.73983765 -0.38619995
+1.4252014 -0.3855896q0.691803 -0.013626099 1.4181824 0.31402588q0.7406616
+0.3340912 1.1391602 0.85665894q0.41915894 0.51475525 0.5724182
+1.2009735q0.3392334 1.4900208 -0.4510193 3.2419128q-0.70669556 1.5667267
+-1.7356567 2.5938568q-0.75302124 0.75737 -1.5674438 0.8528137q-0.417511
+0.051635742 -0.7878418 -0.11540222q-0.3560791 -0.16061401 -0.57528687
+-0.39663696q-0.22705078 -0.25668335 -0.32867432 -0.5253601q-0.2267456
+-0.59936523 0.06237793 -1.2402954q0.27624512 -0.6124573 0.89627075
+-0.8470001q0.59155273 -0.247406 1.1043091 -0.016113281l0.014251709
+0.00642395q0.52056885 0.25195312 0.62945557 0.35250854z"
+fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0"
+d="m125.19179 263.8607l33.637787 -74.55118" fill-rule="nonzero"></path><path
+stroke="#434343" stroke-width="1.0" stroke-linejoin="round"
+stroke-linecap="butt" d="m125.19179 263.8607l32.228317 -71.42735"
+fill-rule="evenodd"></path><path fill="#434343" stroke="#434343"
+stroke-width="1.0" stroke-linecap="butt" d="m157.4201 192.43333l0.5625458
+1.4875793l0.24568176 -3.2788696l-2.2958221 2.353836z"
+fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0"
+d="m125.190956 262.63293l74.56457 33.634216" fill-rule="nonzero"></path><path
+stroke="#434343" stroke-width="1.0" stroke-linejoin="round"
+stroke-linecap="butt" d="m125.190956 262.63293l71.440605 32.225098"
+fill-rule="evenodd"></path><path fill="#434343" stroke="#434343"
+stroke-width="1.0" stroke-linecap="butt" d="m196.63156 294.858l-1.4875183
+0.5627136l3.278885 0.24533081l-2.3540802 -2.2955627z"
+fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0"
+d="m129.13316 262.30618l-61.102364 6.1102295" fill-rule="nonzero"></path><path
+stroke="#434343" stroke-width="1.0" stroke-linejoin="round"
+stroke-linecap="butt" d="m125.36197 262.6833l-53.92109 5.3921204"
+fill-rule="evenodd"></path><path fill="#434343" stroke="#434343"
+stroke-width="1.0" stroke-linecap="butt" d="m128.63564 262.35593c0.090408325
+0.9040222 -0.56915283 1.710144 -1.4731445 1.8005371c-0.9039993 0.09039307
+-1.7101212 -0.56915283 -1.8005219 -1.473175c-0.090400696 -0.9039917 0.56915283
+-1.7101135 1.4731522 -1.8005066c0.9039993 -0.09039307 1.7101212 0.56915283
+1.8005142 1.4731445z" fill-rule="nonzero"></path><path fill="#434343"
+stroke="#434343" stroke-width="1.0" stroke-linecap="butt" d="m71.44088
+268.0754l1.007103 -1.230896l-2.9625397 1.4264526l3.1863403 0.81155396z"
+fill-rule="evenodd"></path></g></svg>
+

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/visualizing/index.rst
--- a/doc/source/visualizing/index.rst
+++ b/doc/source/visualizing/index.rst
@@ -15,6 +15,8 @@
    callbacks
    manual_plotting
    volume_rendering
+   unstructured_mesh_rendering
+   hardware_volume_rendering
    sketchfab
    mapserver
    streamlines

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/visualizing/plots.rst
--- a/doc/source/visualizing/plots.rst
+++ b/doc/source/visualizing/plots.rst
@@ -311,7 +311,8 @@
 .. _off-axis-projection-function:
 
 To avoid manually creating a camera and setting the transfer
-function, yt provides the :func:`~yt.visualization.volume_rendering.camera.off_axis_projection`
+function, yt provides the
+:func:`~yt.visualization.volume_rendering.off_axis_projection.off_axis_projection`
 function, which wraps the camera interface to create an off axis
 projection image buffer.  These images can be saved to disk or
 used in custom plots.  This snippet creates an off axis
@@ -327,7 +328,7 @@
    W = [0.02, 0.02, 0.02]
    c = [0.5, 0.5, 0.5]
    N = 512
-   image = yt.off_axis_projection(ds, c, L, W, N, "density")
+   image, sc = yt.off_axis_projection(ds, c, L, W, N, "density")
    yt.write_image(np.log10(image), "%s_offaxis_projection.png" % ds)
 
 Here, ``W`` is the width of the projection in the x, y, *and* z

diff -r 02d75eea10a9fc81e2d10e9e11038dcc52ec4bf4 -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a doc/source/visualizing/transfer_function_helper.rst
--- /dev/null
+++ b/doc/source/visualizing/transfer_function_helper.rst
@@ -0,0 +1,6 @@
+.. _transfer-function-helper-tutorial:
+
+Transfer Function Helper Tutorial
+=================================
+
+.. notebook:: TransferFunctionHelper_Tutorial.ipynb

This diff is so big that we needed to truncate the remainder.

https://bitbucket.org/yt_analysis/yt/commits/ef61ac627761/
Changeset:   ef61ac627761
Branch:      yt
User:        jzuhone
Date:        2015-11-10 02:14:22+00:00
Summary:     Don't check if is instance of str, but only string_types
Affected #:  16 files

diff -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a -r ef61ac62776108d71261fd0e74b4be12d1fc4ec1 yt/analysis_modules/absorption_spectrum/absorption_spectrum.py
--- a/yt/analysis_modules/absorption_spectrum/absorption_spectrum.py
+++ b/yt/analysis_modules/absorption_spectrum/absorption_spectrum.py
@@ -20,6 +20,7 @@
 
 from .absorption_line import tau_profile
 
+from yt.extern.six import string_types
 from yt.convenience import load
 from yt.funcs import get_pbar, mylog
 from yt.units.yt_array import YTArray, YTQuantity
@@ -167,7 +168,7 @@
                 input_fields.append(feature['field_name'])
                 field_units[feature["field_name"]] = "cm**-3"
 
-        if isinstance(input_file, str):
+        if isinstance(input_file, string_types):
             input_ds = load(input_file)
         else:
             input_ds = input_file

diff -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a -r ef61ac62776108d71261fd0e74b4be12d1fc4ec1 yt/convenience.py
--- a/yt/convenience.py
+++ b/yt/convenience.py
@@ -16,6 +16,7 @@
 import os, os.path, types
 
 # Named imports
+from yt.extern.six import string_types
 from yt.funcs import *
 from yt.config import ytcfg
 from yt.utilities.parameter_file_storage import \
@@ -33,11 +34,11 @@
     :class:`yt.data_objects.api.Dataset` subclass.
     """
     candidates = []
-    args = [os.path.expanduser(arg) if isinstance(arg, str)
+    args = [os.path.expanduser(arg) if isinstance(arg, string_types)
             else arg for arg in args]
     valid_file = []
     for argno, arg in enumerate(args):
-        if isinstance(arg, str):
+        if isinstance(arg, string_types):
             if os.path.exists(arg):
                 valid_file.append(True)
             elif arg.startswith("http"):
@@ -73,7 +74,7 @@
     if len(candidates) == 0:
         if ytcfg.get("yt", "enzo_db") != '' \
            and len(args) == 1 \
-           and isinstance(args[0], str):
+           and isinstance(args[0], string_types):
             erdb = EnzoRunDatabase()
             fn = erdb.find_uuid(args[0])
             n = "EnzoDataset"

diff -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a -r ef61ac62776108d71261fd0e74b4be12d1fc4ec1 yt/data_objects/static_output.py
--- a/yt/data_objects/static_output.py
+++ b/yt/data_objects/static_output.py
@@ -18,7 +18,7 @@
 import functools
 
 from yt.funcs import *
-from yt.extern.six import add_metaclass
+from yt.extern.six import add_metaclass, string_types
 
 from yt.config import ytcfg
 from yt.utilities.cosmology import \
@@ -131,7 +131,7 @@
 
     def __new__(cls, filename=None, *args, **kwargs):
         from yt.frontends.stream.data_structures import StreamHandler
-        if not isinstance(filename, str):
+        if not isinstance(filename, string_types):
             obj = object.__new__(cls)
             # The Stream frontend uses a StreamHandler object to pass metadata
             # to __init__.
@@ -458,7 +458,7 @@
         # concatenation fields.
         n = getattr(filter, "name", filter)
         self.known_filters[n] = None
-        if isinstance(filter, str):
+        if isinstance(filter, string_types):
             used = False
             for f in filter_registry[filter]:
                 used = self._setup_filtered_type(f)

diff -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a -r ef61ac62776108d71261fd0e74b4be12d1fc4ec1 yt/frontends/gadget/data_structures.py
--- a/yt/frontends/gadget/data_structures.py
+++ b/yt/frontends/gadget/data_structures.py
@@ -15,6 +15,7 @@
 # The full license is in the file COPYING.txt, distributed with this software.
 #-----------------------------------------------------------------------------
 
+from yt.extern.six import string_types
 from yt.utilities.on_demand_imports import _h5py as h5py
 import numpy as np
 import stat
@@ -41,7 +42,7 @@
     GadgetFieldInfo
 
 def _fix_unit_ordering(unit):
-    if isinstance(unit[0], str):
+    if isinstance(unit[0], string_types):
         unit = unit[1], unit[0]
     return unit
 

diff -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a -r ef61ac62776108d71261fd0e74b4be12d1fc4ec1 yt/frontends/gadget/io.py
--- a/yt/frontends/gadget/io.py
+++ b/yt/frontends/gadget/io.py
@@ -18,6 +18,7 @@
 import numpy as np
 import os
 
+from yt.extern.six import string_types
 from yt.frontends.owls.io import \
     IOHandlerOWLS
 from yt.utilities.io_handler import \
@@ -167,7 +168,7 @@
         fs = self._field_size
         offsets = {}
         for field in self._fields:
-            if not isinstance(field, str):
+            if not isinstance(field, string_types):
                 field = field[0]
             if not any( (ptype, field) in field_list
                         for ptype in self._ptypes):

diff -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a -r ef61ac62776108d71261fd0e74b4be12d1fc4ec1 yt/frontends/gdf/data_structures.py
--- a/yt/frontends/gdf/data_structures.py
+++ b/yt/frontends/gdf/data_structures.py
@@ -17,6 +17,7 @@
 import numpy as np
 import weakref
 import os
+from yt.extern.six import string_types
 from yt.funcs import \
     just_one, ensure_tuple
 from yt.data_objects.grid_patch import \
@@ -195,7 +196,7 @@
                 self.field_units[field_name] = just_one(field_conv)
             elif 'field_units' in current_field.attrs:
                 field_units = current_field.attrs['field_units']
-                if isinstance(field_units, str):
+                if isinstance(field_units, string_types):
                     current_field_units = current_field.attrs['field_units']
                 else:
                     current_field_units = \

diff -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a -r ef61ac62776108d71261fd0e74b4be12d1fc4ec1 yt/frontends/ramses/data_structures.py
--- a/yt/frontends/ramses/data_structures.py
+++ b/yt/frontends/ramses/data_structures.py
@@ -21,6 +21,7 @@
 import weakref
 from io import BytesIO
 
+from yt.extern.six import string_types
 from yt.funcs import \
     mylog
 from yt.geometry.oct_geometry_handler import \
@@ -521,7 +522,7 @@
                  fields = None, storage_filename = None,
                  units_override=None):
         # Here we want to initiate a traceback, if the reader is not built.
-        if isinstance(fields, str):
+        if isinstance(fields, string_types):
             fields = field_aliases[fields]
         '''
         fields: An array of hydro variable fields in order of position in the hydro_XXXXX.outYYYYY file

diff -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a -r ef61ac62776108d71261fd0e74b4be12d1fc4ec1 yt/frontends/ytdata/data_structures.py
--- a/yt/frontends/ytdata/data_structures.py
+++ b/yt/frontends/ytdata/data_structures.py
@@ -241,7 +241,7 @@
     def _parse_parameter_file(self):
         super(YTSpatialPlotDataset, self)._parse_parameter_file()
         if self.parameters["container_type"] == "proj":
-            if isinstance(self.parameters["weight_field"], str) and \
+            if isinstance(self.parameters["weight_field"], string_types) and \
               self.parameters["weight_field"] == "None":
                 self.parameters["weight_field"] = None
             elif isinstance(self.parameters["weight_field"], np.ndarray):
@@ -605,7 +605,7 @@
     def _parse_parameter_file(self):
         super(YTGridDataset, self)._parse_parameter_file()
 
-        if isinstance(self.parameters["weight_field"], str) and \
+        if isinstance(self.parameters["weight_field"], string_types) and \
           self.parameters["weight_field"] == "None":
             self.parameters["weight_field"] = None
         elif isinstance(self.parameters["weight_field"], np.ndarray):
@@ -639,7 +639,7 @@
                              self.parameters[range_name+"_units"]))
 
             bin_field = "%s_field" % ax
-            if isinstance(self.parameters[bin_field], str) and \
+            if isinstance(self.parameters[bin_field], string_types) and \
               self.parameters[bin_field] == "None":
                 self.parameters[bin_field] = None
             elif isinstance(self.parameters[bin_field], np.ndarray):

diff -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a -r ef61ac62776108d71261fd0e74b4be12d1fc4ec1 yt/funcs.py
--- a/yt/funcs.py
+++ b/yt/funcs.py
@@ -626,7 +626,7 @@
     if isinstance(length, numeric_type):
         return YTArray(length, 'code_length', registry=registry)
     length_valid_tuple = isinstance(length, (list, tuple)) and len(length) == 2
-    unit_is_string = isinstance(length[1], str)
+    unit_is_string = isinstance(length[1], string_types)
     if length_valid_tuple and unit_is_string:
         return YTArray(*length, registry=registry)
     else:

diff -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a -r ef61ac62776108d71261fd0e74b4be12d1fc4ec1 yt/testing.py
--- a/yt/testing.py
+++ b/yt/testing.py
@@ -14,6 +14,7 @@
 #-----------------------------------------------------------------------------
 
 import hashlib
+from yt.extern.six import string_types
 from yt.extern.six.moves import cPickle
 import itertools as it
 import numpy as np
@@ -329,7 +330,7 @@
         # Determine the maximum number of values any of the keywords has
         num_lists = 0
         for val in keywords.values():
-            if isinstance(val, str):
+            if isinstance(val, string_types):
                 num_lists = max(1.0, num_lists)
             else:
                 num_lists = max(len(val), num_lists)
@@ -346,7 +347,7 @@
             list_of_kwarg_dicts[i] = {}
             for key in keywords.keys():
                 # if it's a string, use it (there's only one)
-                if isinstance(keywords[key], str):
+                if isinstance(keywords[key], string_types):
                     list_of_kwarg_dicts[i][key] = keywords[key]
                 # if there are more options, use the i'th val
                 elif i < len(keywords[key]):

diff -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a -r ef61ac62776108d71261fd0e74b4be12d1fc4ec1 yt/utilities/answer_testing/output_tests.py
--- a/yt/utilities/answer_testing/output_tests.py
+++ b/yt/utilities/answer_testing/output_tests.py
@@ -14,6 +14,7 @@
 #-----------------------------------------------------------------------------
 
 import matplotlib
+from yt.extern.six import string_types
 from yt.mods import *
 
 # We first create our dictionary of tests to run.  This starts out empty, and
@@ -150,7 +151,7 @@
         self.io_log = io_log
 
     def __iter__(self):
-        if isinstance(self.io_log, str):
+        if isinstance(self.io_log, string_types):
             for line in open(self.io_log):
                 yield line[len(self.io_log_header):].split()[0].strip()
         elif isinstance(self.io_log, list):

diff -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a -r ef61ac62776108d71261fd0e74b4be12d1fc4ec1 yt/utilities/command_line.py
--- a/yt/utilities/command_line.py
+++ b/yt/utilities/command_line.py
@@ -20,7 +20,7 @@
 from yt.startup_tasks import parser, subparsers
 from yt.mods import *
 from yt.funcs import *
-from yt.extern.six import add_metaclass
+from yt.extern.six import add_metaclass, string_types
 from yt.extern.six.moves import urllib
 from yt.utilities.minimal_representation import MinimalProjectDescription
 import argparse, os, os.path, math, sys, time, subprocess, getpass, tempfile
@@ -40,7 +40,7 @@
     return ds
 
 def _add_arg(sc, arg):
-    if isinstance(arg, str):
+    if isinstance(arg, string_types):
         arg = _common_options[arg].copy()
     argc = dict(arg.items())
     argnames = []

diff -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a -r ef61ac62776108d71261fd0e74b4be12d1fc4ec1 yt/utilities/operator_registry.py
--- a/yt/utilities/operator_registry.py
+++ b/yt/utilities/operator_registry.py
@@ -15,10 +15,11 @@
 
 import copy
 import types
+from yt.extern.six import string_types
 
 class OperatorRegistry(dict):
     def find(self, op, *args, **kwargs):
-        if isinstance(op, str):
+        if isinstance(op, string_types):
             # Lookup, assuming string or hashable object
             op = copy.deepcopy(self[op])
             op.args = args

diff -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a -r ef61ac62776108d71261fd0e74b4be12d1fc4ec1 yt/utilities/periodic_table.py
--- a/yt/utilities/periodic_table.py
+++ b/yt/utilities/periodic_table.py
@@ -16,6 +16,7 @@
 import numpy as np
 import numbers
 import types
+from yt.extern.six import string_types
 
 _elements = (
     (1, 1.0079400000, "Hydrogen", "H"),
@@ -164,7 +165,7 @@
     def __getitem__(self, key):
         if isinstance(key, (np.number, numbers.Number)):
             d = self.elements_by_number
-        elif isinstance(key, str):
+        elif isinstance(key, string_types):
             if len(key) <= 2:
                 d = self.elements_by_symbol
             elif len(key) == 3 and key[0] == "U":

diff -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a -r ef61ac62776108d71261fd0e74b4be12d1fc4ec1 yt/visualization/color_maps.py
--- a/yt/visualization/color_maps.py
+++ b/yt/visualization/color_maps.py
@@ -16,6 +16,7 @@
 import matplotlib.colors as cc
 import matplotlib.cm as mcm
 from . import _colormap_data as _cm
+from yt.extern.six import string_types
 
 def is_colormap(cmap):
     return isinstance(cmap,cc.Colormap)
@@ -365,7 +366,7 @@
     # Figure out how many intervals there are total.
     rolling_index = 0
     for i, (color, interval) in enumerate(ctuple_list):
-        if isinstance(color, str):
+        if isinstance(color, string_types):
             ctuple_list[i] = (color_dict[color], interval)
         rolling_index += interval
     scale = 256./rolling_index

diff -r 9cdfe40778a48bc0ecd02faa34b9d9120c1d202a -r ef61ac62776108d71261fd0e74b4be12d1fc4ec1 yt/visualization/volume_rendering/camera.py
--- a/yt/visualization/volume_rendering/camera.py
+++ b/yt/visualization/volume_rendering/camera.py
@@ -16,6 +16,7 @@
 from yt.units.yt_array import YTArray
 from yt.units.unit_registry import UnitParseError
 from yt.utilities.math_utils import get_rotation_matrix
+from yt.extern.six import string_types
 from .utils import data_source_or_all
 from .lens import lenses
 import numpy as np
@@ -231,7 +232,7 @@
                         (zma - zmi) ** 2)
         focus = data_source.get_field_parameter('center')
 
-        if iterable(width) and len(width) > 1 and isinstance(width[1], str):
+        if iterable(width) and len(width) > 1 and isinstance(width[1], string_types):
             width = data_source.ds.quan(width[0], input_units=width[1])
             # Now convert back to code length for subsequent manipulation
             width = width.in_units("code_length")  # .value


https://bitbucket.org/yt_analysis/yt/commits/652f3058834c/
Changeset:   652f3058834c
Branch:      yt
User:        ngoldbaum
Date:        2015-11-10 16:52:05+00:00
Summary:     Merged in jzuhone/yt (pull request #1852)

[bugfix] Check against string_types not str
Affected #:  18 files

diff -r 6bb90c5fb64093ed15937d5cc1d9d82123112c07 -r 652f3058834c94de92fb59bfde799736182ee8b7 yt/analysis_modules/absorption_spectrum/absorption_spectrum.py
--- a/yt/analysis_modules/absorption_spectrum/absorption_spectrum.py
+++ b/yt/analysis_modules/absorption_spectrum/absorption_spectrum.py
@@ -20,6 +20,7 @@
 
 from .absorption_line import tau_profile
 
+from yt.extern.six import string_types
 from yt.convenience import load
 from yt.funcs import get_pbar, mylog
 from yt.units.yt_array import YTArray, YTQuantity
@@ -167,7 +168,7 @@
                 input_fields.append(feature['field_name'])
                 field_units[feature["field_name"]] = "cm**-3"
 
-        if isinstance(input_file, str):
+        if isinstance(input_file, string_types):
             input_ds = load(input_file)
         else:
             input_ds = input_file

diff -r 6bb90c5fb64093ed15937d5cc1d9d82123112c07 -r 652f3058834c94de92fb59bfde799736182ee8b7 yt/convenience.py
--- a/yt/convenience.py
+++ b/yt/convenience.py
@@ -16,6 +16,7 @@
 import os, os.path, types
 
 # Named imports
+from yt.extern.six import string_types
 from yt.funcs import *
 from yt.config import ytcfg
 from yt.utilities.parameter_file_storage import \
@@ -33,11 +34,11 @@
     :class:`yt.data_objects.api.Dataset` subclass.
     """
     candidates = []
-    args = [os.path.expanduser(arg) if isinstance(arg, str)
+    args = [os.path.expanduser(arg) if isinstance(arg, string_types)
             else arg for arg in args]
     valid_file = []
     for argno, arg in enumerate(args):
-        if isinstance(arg, str):
+        if isinstance(arg, string_types):
             if os.path.exists(arg):
                 valid_file.append(True)
             elif arg.startswith("http"):
@@ -73,7 +74,7 @@
     if len(candidates) == 0:
         if ytcfg.get("yt", "enzo_db") != '' \
            and len(args) == 1 \
-           and isinstance(args[0], str):
+           and isinstance(args[0], string_types):
             erdb = EnzoRunDatabase()
             fn = erdb.find_uuid(args[0])
             n = "EnzoDataset"

diff -r 6bb90c5fb64093ed15937d5cc1d9d82123112c07 -r 652f3058834c94de92fb59bfde799736182ee8b7 yt/data_objects/static_output.py
--- a/yt/data_objects/static_output.py
+++ b/yt/data_objects/static_output.py
@@ -18,7 +18,7 @@
 import functools
 
 from yt.funcs import *
-from yt.extern.six import add_metaclass
+from yt.extern.six import add_metaclass, string_types
 
 from yt.config import ytcfg
 from yt.utilities.cosmology import \
@@ -131,7 +131,7 @@
 
     def __new__(cls, filename=None, *args, **kwargs):
         from yt.frontends.stream.data_structures import StreamHandler
-        if not isinstance(filename, str):
+        if not isinstance(filename, string_types):
             obj = object.__new__(cls)
             # The Stream frontend uses a StreamHandler object to pass metadata
             # to __init__.
@@ -458,7 +458,7 @@
         # concatenation fields.
         n = getattr(filter, "name", filter)
         self.known_filters[n] = None
-        if isinstance(filter, str):
+        if isinstance(filter, string_types):
             used = False
             for f in filter_registry[filter]:
                 used = self._setup_filtered_type(f)

diff -r 6bb90c5fb64093ed15937d5cc1d9d82123112c07 -r 652f3058834c94de92fb59bfde799736182ee8b7 yt/fields/derived_field.py
--- a/yt/fields/derived_field.py
+++ b/yt/fields/derived_field.py
@@ -14,6 +14,7 @@
 import contextlib
 import inspect
 
+from yt.extern.six import string_types
 from yt.funcs import \
     ensure_list
 from .field_exceptions import \
@@ -99,7 +100,7 @@
         # handle units
         if units is None:
             self.units = ''
-        elif isinstance(units, str):
+        elif isinstance(units, string_types):
             if units.lower() == 'auto':
                 self.units = None
             else:

diff -r 6bb90c5fb64093ed15937d5cc1d9d82123112c07 -r 652f3058834c94de92fb59bfde799736182ee8b7 yt/fields/field_info_container.py
--- a/yt/fields/field_info_container.py
+++ b/yt/fields/field_info_container.py
@@ -18,6 +18,7 @@
 import numpy as np
 from numbers import Number as numeric_type
 
+from yt.extern.six import string_types
 from yt.funcs import mylog, only_on_root
 from yt.units.unit_object import Unit
 from .derived_field import \
@@ -179,7 +180,7 @@
             # field *name* is in there, then the field *tuple*.
             units = self.ds.field_units.get(field[1], units)
             units = self.ds.field_units.get(field, units)
-            if not isinstance(units, str) and args[0] != "":
+            if not isinstance(units, string_types) and args[0] != "":
                 units = "((%s)*%s)" % (args[0], units)
             if isinstance(units, (numeric_type, np.number, np.ndarray)) and \
                 args[0] == "" and units != 1.0:

diff -r 6bb90c5fb64093ed15937d5cc1d9d82123112c07 -r 652f3058834c94de92fb59bfde799736182ee8b7 yt/frontends/gadget/data_structures.py
--- a/yt/frontends/gadget/data_structures.py
+++ b/yt/frontends/gadget/data_structures.py
@@ -15,6 +15,7 @@
 # The full license is in the file COPYING.txt, distributed with this software.
 #-----------------------------------------------------------------------------
 
+from yt.extern.six import string_types
 from yt.utilities.on_demand_imports import _h5py as h5py
 import numpy as np
 import stat
@@ -41,7 +42,7 @@
     GadgetFieldInfo
 
 def _fix_unit_ordering(unit):
-    if isinstance(unit[0], str):
+    if isinstance(unit[0], string_types):
         unit = unit[1], unit[0]
     return unit
 

diff -r 6bb90c5fb64093ed15937d5cc1d9d82123112c07 -r 652f3058834c94de92fb59bfde799736182ee8b7 yt/frontends/gadget/io.py
--- a/yt/frontends/gadget/io.py
+++ b/yt/frontends/gadget/io.py
@@ -18,6 +18,7 @@
 import numpy as np
 import os
 
+from yt.extern.six import string_types
 from yt.frontends.owls.io import \
     IOHandlerOWLS
 from yt.utilities.io_handler import \
@@ -167,7 +168,7 @@
         fs = self._field_size
         offsets = {}
         for field in self._fields:
-            if not isinstance(field, str):
+            if not isinstance(field, string_types):
                 field = field[0]
             if not any( (ptype, field) in field_list
                         for ptype in self._ptypes):

diff -r 6bb90c5fb64093ed15937d5cc1d9d82123112c07 -r 652f3058834c94de92fb59bfde799736182ee8b7 yt/frontends/gdf/data_structures.py
--- a/yt/frontends/gdf/data_structures.py
+++ b/yt/frontends/gdf/data_structures.py
@@ -17,6 +17,7 @@
 import numpy as np
 import weakref
 import os
+from yt.extern.six import string_types
 from yt.funcs import \
     just_one, ensure_tuple
 from yt.data_objects.grid_patch import \
@@ -195,7 +196,7 @@
                 self.field_units[field_name] = just_one(field_conv)
             elif 'field_units' in current_field.attrs:
                 field_units = current_field.attrs['field_units']
-                if isinstance(field_units, str):
+                if isinstance(field_units, string_types):
                     current_field_units = current_field.attrs['field_units']
                 else:
                     current_field_units = \

diff -r 6bb90c5fb64093ed15937d5cc1d9d82123112c07 -r 652f3058834c94de92fb59bfde799736182ee8b7 yt/frontends/ramses/data_structures.py
--- a/yt/frontends/ramses/data_structures.py
+++ b/yt/frontends/ramses/data_structures.py
@@ -21,6 +21,7 @@
 import weakref
 from io import BytesIO
 
+from yt.extern.six import string_types
 from yt.funcs import \
     mylog
 from yt.geometry.oct_geometry_handler import \
@@ -521,7 +522,7 @@
                  fields = None, storage_filename = None,
                  units_override=None):
         # Here we want to initiate a traceback, if the reader is not built.
-        if isinstance(fields, str):
+        if isinstance(fields, string_types):
             fields = field_aliases[fields]
         '''
         fields: An array of hydro variable fields in order of position in the hydro_XXXXX.outYYYYY file

diff -r 6bb90c5fb64093ed15937d5cc1d9d82123112c07 -r 652f3058834c94de92fb59bfde799736182ee8b7 yt/frontends/ytdata/data_structures.py
--- a/yt/frontends/ytdata/data_structures.py
+++ b/yt/frontends/ytdata/data_structures.py
@@ -241,7 +241,7 @@
     def _parse_parameter_file(self):
         super(YTSpatialPlotDataset, self)._parse_parameter_file()
         if self.parameters["container_type"] == "proj":
-            if isinstance(self.parameters["weight_field"], str) and \
+            if isinstance(self.parameters["weight_field"], string_types) and \
               self.parameters["weight_field"] == "None":
                 self.parameters["weight_field"] = None
             elif isinstance(self.parameters["weight_field"], np.ndarray):
@@ -605,7 +605,7 @@
     def _parse_parameter_file(self):
         super(YTGridDataset, self)._parse_parameter_file()
 
-        if isinstance(self.parameters["weight_field"], str) and \
+        if isinstance(self.parameters["weight_field"], string_types) and \
           self.parameters["weight_field"] == "None":
             self.parameters["weight_field"] = None
         elif isinstance(self.parameters["weight_field"], np.ndarray):
@@ -639,7 +639,7 @@
                              self.parameters[range_name+"_units"]))
 
             bin_field = "%s_field" % ax
-            if isinstance(self.parameters[bin_field], str) and \
+            if isinstance(self.parameters[bin_field], string_types) and \
               self.parameters[bin_field] == "None":
                 self.parameters[bin_field] = None
             elif isinstance(self.parameters[bin_field], np.ndarray):

diff -r 6bb90c5fb64093ed15937d5cc1d9d82123112c07 -r 652f3058834c94de92fb59bfde799736182ee8b7 yt/funcs.py
--- a/yt/funcs.py
+++ b/yt/funcs.py
@@ -626,7 +626,7 @@
     if isinstance(length, numeric_type):
         return YTArray(length, 'code_length', registry=registry)
     length_valid_tuple = isinstance(length, (list, tuple)) and len(length) == 2
-    unit_is_string = isinstance(length[1], str)
+    unit_is_string = isinstance(length[1], string_types)
     if length_valid_tuple and unit_is_string:
         return YTArray(*length, registry=registry)
     else:

diff -r 6bb90c5fb64093ed15937d5cc1d9d82123112c07 -r 652f3058834c94de92fb59bfde799736182ee8b7 yt/testing.py
--- a/yt/testing.py
+++ b/yt/testing.py
@@ -14,6 +14,7 @@
 #-----------------------------------------------------------------------------
 
 import hashlib
+from yt.extern.six import string_types
 from yt.extern.six.moves import cPickle
 import itertools as it
 import numpy as np
@@ -329,7 +330,7 @@
         # Determine the maximum number of values any of the keywords has
         num_lists = 0
         for val in keywords.values():
-            if isinstance(val, str):
+            if isinstance(val, string_types):
                 num_lists = max(1.0, num_lists)
             else:
                 num_lists = max(len(val), num_lists)
@@ -346,7 +347,7 @@
             list_of_kwarg_dicts[i] = {}
             for key in keywords.keys():
                 # if it's a string, use it (there's only one)
-                if isinstance(keywords[key], str):
+                if isinstance(keywords[key], string_types):
                     list_of_kwarg_dicts[i][key] = keywords[key]
                 # if there are more options, use the i'th val
                 elif i < len(keywords[key]):

diff -r 6bb90c5fb64093ed15937d5cc1d9d82123112c07 -r 652f3058834c94de92fb59bfde799736182ee8b7 yt/utilities/answer_testing/output_tests.py
--- a/yt/utilities/answer_testing/output_tests.py
+++ b/yt/utilities/answer_testing/output_tests.py
@@ -14,6 +14,7 @@
 #-----------------------------------------------------------------------------
 
 import matplotlib
+from yt.extern.six import string_types
 from yt.mods import *
 
 # We first create our dictionary of tests to run.  This starts out empty, and
@@ -150,7 +151,7 @@
         self.io_log = io_log
 
     def __iter__(self):
-        if isinstance(self.io_log, str):
+        if isinstance(self.io_log, string_types):
             for line in open(self.io_log):
                 yield line[len(self.io_log_header):].split()[0].strip()
         elif isinstance(self.io_log, list):

diff -r 6bb90c5fb64093ed15937d5cc1d9d82123112c07 -r 652f3058834c94de92fb59bfde799736182ee8b7 yt/utilities/command_line.py
--- a/yt/utilities/command_line.py
+++ b/yt/utilities/command_line.py
@@ -20,7 +20,7 @@
 from yt.startup_tasks import parser, subparsers
 from yt.mods import *
 from yt.funcs import *
-from yt.extern.six import add_metaclass
+from yt.extern.six import add_metaclass, string_types
 from yt.extern.six.moves import urllib
 from yt.utilities.minimal_representation import MinimalProjectDescription
 import argparse, os, os.path, math, sys, time, subprocess, getpass, tempfile
@@ -40,7 +40,7 @@
     return ds
 
 def _add_arg(sc, arg):
-    if isinstance(arg, str):
+    if isinstance(arg, string_types):
         arg = _common_options[arg].copy()
     argc = dict(arg.items())
     argnames = []

diff -r 6bb90c5fb64093ed15937d5cc1d9d82123112c07 -r 652f3058834c94de92fb59bfde799736182ee8b7 yt/utilities/operator_registry.py
--- a/yt/utilities/operator_registry.py
+++ b/yt/utilities/operator_registry.py
@@ -15,10 +15,11 @@
 
 import copy
 import types
+from yt.extern.six import string_types
 
 class OperatorRegistry(dict):
     def find(self, op, *args, **kwargs):
-        if isinstance(op, str):
+        if isinstance(op, string_types):
             # Lookup, assuming string or hashable object
             op = copy.deepcopy(self[op])
             op.args = args

diff -r 6bb90c5fb64093ed15937d5cc1d9d82123112c07 -r 652f3058834c94de92fb59bfde799736182ee8b7 yt/utilities/periodic_table.py
--- a/yt/utilities/periodic_table.py
+++ b/yt/utilities/periodic_table.py
@@ -16,6 +16,7 @@
 import numpy as np
 import numbers
 import types
+from yt.extern.six import string_types
 
 _elements = (
     (1, 1.0079400000, "Hydrogen", "H"),
@@ -164,7 +165,7 @@
     def __getitem__(self, key):
         if isinstance(key, (np.number, numbers.Number)):
             d = self.elements_by_number
-        elif isinstance(key, str):
+        elif isinstance(key, string_types):
             if len(key) <= 2:
                 d = self.elements_by_symbol
             elif len(key) == 3 and key[0] == "U":

diff -r 6bb90c5fb64093ed15937d5cc1d9d82123112c07 -r 652f3058834c94de92fb59bfde799736182ee8b7 yt/visualization/color_maps.py
--- a/yt/visualization/color_maps.py
+++ b/yt/visualization/color_maps.py
@@ -16,6 +16,7 @@
 import matplotlib.colors as cc
 import matplotlib.cm as mcm
 from . import _colormap_data as _cm
+from yt.extern.six import string_types
 
 def is_colormap(cmap):
     return isinstance(cmap,cc.Colormap)
@@ -365,7 +366,7 @@
     # Figure out how many intervals there are total.
     rolling_index = 0
     for i, (color, interval) in enumerate(ctuple_list):
-        if isinstance(color, str):
+        if isinstance(color, string_types):
             ctuple_list[i] = (color_dict[color], interval)
         rolling_index += interval
     scale = 256./rolling_index

diff -r 6bb90c5fb64093ed15937d5cc1d9d82123112c07 -r 652f3058834c94de92fb59bfde799736182ee8b7 yt/visualization/volume_rendering/camera.py
--- a/yt/visualization/volume_rendering/camera.py
+++ b/yt/visualization/volume_rendering/camera.py
@@ -16,6 +16,7 @@
 from yt.units.yt_array import YTArray
 from yt.units.unit_registry import UnitParseError
 from yt.utilities.math_utils import get_rotation_matrix
+from yt.extern.six import string_types
 from .utils import data_source_or_all
 from .lens import lenses
 import numpy as np
@@ -231,7 +232,7 @@
                         (zma - zmi) ** 2)
         focus = data_source.get_field_parameter('center')
 
-        if iterable(width) and len(width) > 1 and isinstance(width[1], str):
+        if iterable(width) and len(width) > 1 and isinstance(width[1], string_types):
             width = data_source.ds.quan(width[0], input_units=width[1])
             # Now convert back to code length for subsequent manipulation
             width = width.in_units("code_length")  # .value

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