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

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Thu Oct 15 10:57:36 PDT 2015


14 new commits in yt:

https://bitbucket.org/yt_analysis/yt/commits/3e4f75c0a81e/
Changeset:   3e4f75c0a81e
Branch:      yt
User:        chummels
Date:        2015-10-14 19:15:10+00:00
Summary:     Adding optional custom message to YTFieldNotFound exception.
Affected #:  1 file

diff -r 52b57ac913dd7e334914c7e8985f35ebb1618346 -r 3e4f75c0a81e6c4db6b92b53c3d8ed43c8d89c35 yt/utilities/exceptions.py
--- a/yt/utilities/exceptions.py
+++ b/yt/utilities/exceptions.py
@@ -60,12 +60,14 @@
         return s
 
 class YTFieldNotFound(YTException):
-    def __init__(self, fname, ds):
+    def __init__(self, fname, ds, custom_msg=None):
         self.fname = fname
         self.ds = ds
+        if custom_msg is None: custom_msg = ""
+        self.custom_msg = custom_msg
 
     def __str__(self):
-        return "Could not find field '%s' in %s." % (self.fname, self.ds)
+        return "Could not find field '%s' in %s. %s" % (self.fname, self.ds, self.custom_msg)
 
 class YTCouldNotGenerateField(YTFieldNotFound):
     def __str__(self):


https://bitbucket.org/yt_analysis/yt/commits/3ce5709d484a/
Changeset:   3ce5709d484a
Branch:      yt
User:        chummels
Date:        2015-10-14 19:18:25+00:00
Summary:     Adding default_field to base dataset objects.  Unless specified in each frontend, it will be ('gas', 'density').
Affected #:  1 file

diff -r 3e4f75c0a81e6c4db6b92b53c3d8ed43c8d89c35 -r 3ce5709d484a1077c38ae476de654cad2542f2d1 yt/data_objects/static_output.py
--- a/yt/data_objects/static_output.py
+++ b/yt/data_objects/static_output.py
@@ -112,6 +112,7 @@
 class Dataset(object):
 
     default_fluid_type = "gas"
+    default_field = ("gas", "density")
     fluid_types = ("gas", "deposit", "index")
     particle_types = ("io",) # By default we have an 'all'
     particle_types_raw = ("io",)


https://bitbucket.org/yt_analysis/yt/commits/f596d0d742ab/
Changeset:   f596d0d742ab
Branch:      yt
User:        chummels
Date:        2015-10-14 19:18:49+00:00
Summary:     Making volume_render() use the frontend's default_field if field not specified.
Affected #:  1 file

diff -r 3ce5709d484a1077c38ae476de654cad2542f2d1 -r f596d0d742ab8b48a44d35c0826f7ff24eea62c7 yt/visualization/volume_rendering/volume_rendering.py
--- a/yt/visualization/volume_rendering/volume_rendering.py
+++ b/yt/visualization/volume_rendering/volume_rendering.py
@@ -17,6 +17,7 @@
 from .render_source import VolumeSource
 from .utils import data_source_or_all
 from yt.funcs import mylog
+from yt.utilities.exceptions import YTFieldNotFound
 
 
 def volume_render(data_source, field=None, fname=None, clip_ratio=None):
@@ -33,11 +34,11 @@
         This is the source to be rendered, which can be any arbitrary yt
         3D object
     field: string, tuple, optional
-        The field to be rendered. By default, this will use the first
-        field in data_source.ds.field_list.  A default transfer function
-        will be built that spans the range of values for that given field,
-        and the field will be logarithmically scaled if the field_info
-        object specifies as such.
+        The field to be rendered. If unspecified, this will use the 
+        default_field for your dataset's frontend--usually ('gas', 'density').
+        A default transfer function will be built that spans the range of 
+        values for that given field, and the field will be logarithmically 
+        scaled if the field_info object specifies as such.
     fname: string, optional
         If specified, the resulting rendering will be saved to this filename
         in png format.
@@ -63,20 +64,11 @@
     data_source = data_source_or_all(data_source)
     sc = Scene()
     if field is None:
-        data_source.ds.index
-        for ftype, f in sorted(data_source.ds.field_list):
-            if ftype == "all":
-                continue
-            if f == 'Density':
-                field = (ftype, f)
-            elif f == 'density':
-                field = (ftype, f)
-            elif ftype != 'index' and 'particle' not in f:
-                field = (ftype, f)
-                break
-        else:
-            raise RuntimeError("Could not find default field." +
-                               " Please set explicitly in volume_render call")
+        field = data_source.ds.default_field
+        if field not in data_source.ds.derived_field_list:
+            raise YTFieldNotFound(field, data_source.ds, 
+                "You must specify a field with volume_render(), since " + \
+                "the default field does not exist in your dataset.")
         mylog.info('Setting default field to %s' % field.__repr__())
 
     vol = VolumeSource(data_source, field=field)


https://bitbucket.org/yt_analysis/yt/commits/a2ca6bbf2b06/
Changeset:   a2ca6bbf2b06
Branch:      yt
User:        chummels
Date:        2015-10-14 21:30:48+00:00
Summary:     Adding create_scene helper class.
Affected #:  3 files

diff -r f596d0d742ab8b48a44d35c0826f7ff24eea62c7 -r a2ca6bbf2b0601f200c7e4a78464235aeda79ede yt/__init__.py
--- a/yt/__init__.py
+++ b/yt/__init__.py
@@ -154,7 +154,7 @@
     ParticleProjectionPlot, ParticleImageBuffer, ParticlePlot
 
 from yt.visualization.volume_rendering.api import \
-    volume_render, ColorTransferFunction, TransferFunction, \
+    volume_render, create_scene, ColorTransferFunction, TransferFunction, \
     off_axis_projection
 import yt.visualization.volume_rendering.api as volume_rendering
 #    TransferFunctionHelper, MultiVariateTransferFunction

diff -r f596d0d742ab8b48a44d35c0826f7ff24eea62c7 -r a2ca6bbf2b0601f200c7e4a78464235aeda79ede yt/visualization/volume_rendering/api.py
--- a/yt/visualization/volume_rendering/api.py
+++ b/yt/visualization/volume_rendering/api.py
@@ -27,7 +27,7 @@
 #    SphericalCamera, StereoSphericalCamera
 from .camera import Camera
 from .transfer_function_helper import TransferFunctionHelper
-from .volume_rendering import volume_render
+from .volume_rendering import volume_render, create_scene
 from .off_axis_projection import off_axis_projection
 from .scene import Scene
 from .render_source import VolumeSource, OpaqueSource, LineSource, \

diff -r f596d0d742ab8b48a44d35c0826f7ff24eea62c7 -r a2ca6bbf2b0601f200c7e4a78464235aeda79ede yt/visualization/volume_rendering/volume_rendering.py
--- a/yt/visualization/volume_rendering/volume_rendering.py
+++ b/yt/visualization/volume_rendering/volume_rendering.py
@@ -20,6 +20,56 @@
 from yt.utilities.exceptions import YTFieldNotFound
 
 
+def create_scene(data_source, field=None):
+    r""" Set up a scene object with sensible defaults for use in volume 
+    rendering.
+
+    A helper function that creates a default camera view, transfer
+    function, and image size. Using these, it returns an instance 
+    of the Scene class, allowing one to further modify their rendering.
+
+    This function is the same as volume_render() except it doesn't render
+    the image.
+
+    Parameters
+    ----------
+    data_source : :class:`yt.data_objects.data_containers.AMR3DData`
+        This is the source to be rendered, which can be any arbitrary yt
+        3D object
+    field: string, tuple, optional
+        The field to be rendered. If unspecified, this will use the 
+        default_field for your dataset's frontend--usually ('gas', 'density').
+        A default transfer function will be built that spans the range of 
+        values for that given field, and the field will be logarithmically 
+        scaled if the field_info object specifies as such.
+
+    Returns
+    -------
+    sc: Scene
+        A :class:`yt.visualization.volume_rendering.scene.Scene` object
+        that was constructed during the rendering. Useful for further
+        modifications, rotations, etc.
+
+    Example:
+    >>> import yt
+    >>> ds = yt.load("Enzo_64/DD0046/DD0046")
+    >>> sc = yt.create_scene(ds)
+    """
+    data_source = data_source_or_all(data_source)
+    sc = Scene()
+    if field is None:
+        field = data_source.ds.default_field
+        if field not in data_source.ds.derived_field_list:
+            raise YTFieldNotFound(field, data_source.ds, 
+                "You must specify a field with volume_render(), since " + \
+                "the default field does not exist in your dataset.")
+        mylog.info('Setting default field to %s' % field.__repr__())
+
+    vol = VolumeSource(data_source, field=field)
+    sc.add_source(vol)
+    sc.camera = Camera(data_source)
+    return sc
+
 def volume_render(data_source, field=None, fname=None, clip_ratio=None):
     r""" Create a simple volume rendering of a data source.
 
@@ -61,18 +111,6 @@
     >>> ds = yt.load("Enzo_64/DD0046/DD0046")
     >>> im, sc = yt.volume_render(ds, fname='test.png', clip_ratio=4.0)
     """
-    data_source = data_source_or_all(data_source)
-    sc = Scene()
-    if field is None:
-        field = data_source.ds.default_field
-        if field not in data_source.ds.derived_field_list:
-            raise YTFieldNotFound(field, data_source.ds, 
-                "You must specify a field with volume_render(), since " + \
-                "the default field does not exist in your dataset.")
-        mylog.info('Setting default field to %s' % field.__repr__())
-
-    vol = VolumeSource(data_source, field=field)
-    sc.add_source(vol)
-    sc.camera = Camera(data_source)
+    sc = create_scene(data_source, field=field)
     im = sc.render(fname=fname, clip_ratio=clip_ratio)
     return im, sc


https://bitbucket.org/yt_analysis/yt/commits/f66c29f42a40/
Changeset:   f66c29f42a40
Branch:      yt
User:        chummels
Date:        2015-10-14 21:49:51+00:00
Summary:     Merging.
Affected #:  20 files

diff -r a2ca6bbf2b0601f200c7e4a78464235aeda79ede -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 .hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -31,6 +31,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
@@ -38,6 +39,7 @@
 yt/utilities/lib/image_utilities.c
 yt/utilities/lib/Interpolators.c
 yt/utilities/lib/kdtree.c
+yt/utilities/lib/line_integral_convolution.c
 yt/utilities/lib/mesh_utilities.c
 yt/utilities/lib/misc_utilities.c
 yt/utilities/lib/Octree.c

diff -r a2ca6bbf2b0601f200c7e4a78464235aeda79ede -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 doc/source/cookbook/amrkdtree_downsampling.py
--- a/doc/source/cookbook/amrkdtree_downsampling.py
+++ b/doc/source/cookbook/amrkdtree_downsampling.py
@@ -48,12 +48,12 @@
 tf.clear()
 tf.add_layers(4, 0.01, col_bounds=[-27.5, -25.5],
               alpha=np.ones(4, dtype='float64'), colormap='RdBu_r')
-sc.render("v2.png", clip_ratio=6.0)
+sc.render("v2.png", sigma_clip=6.0)
 
 # This looks better.  Now let's try turning on opacity.
 
 tf.grey_opacity = True
-sc.render("v3.png", clip_ratio=6.0)
+sc.render("v3.png", sigma_clip=6.0)
 #
 ## That seemed to pick out som interesting structures.  Now let's bump up the
 ## opacity.
@@ -61,11 +61,11 @@
 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')
-sc.render("v4.png", clip_ratio=6.0)
+sc.render("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("v5.png", clip_ratio=6.0)
+sc.render("v5.png", sigma_clip=6.0)
 
 # This looks great!

diff -r a2ca6bbf2b0601f200c7e4a78464235aeda79ede -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 doc/source/cookbook/camera_movement.py
--- a/doc/source/cookbook/camera_movement.py
+++ b/doc/source/cookbook/camera_movement.py
@@ -14,15 +14,15 @@
 frame = 0
 # Move to the maximum density location over 5 frames
 for _ in cam.iter_move(max_c, 5):
-    sc.render('camera_movement_%04i.png' % frame, clip_ratio=8.0)
+    sc.render('camera_movement_%04i.png' % frame, sigma_clip=8.0)
     frame += 1
 
 # Zoom in by a factor of 10 over 5 frames
 for _ in cam.iter_zoom(10.0, 5):
-    sc.render('camera_movement_%04i.png' % frame, clip_ratio=8.0)
+    sc.render('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('camera_movement_%04i.png' % frame, clip_ratio=8.0)
+    sc.render('camera_movement_%04i.png' % frame, sigma_clip=8.0)
     frame += 1

diff -r a2ca6bbf2b0601f200c7e4a78464235aeda79ede -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 doc/source/cookbook/image_background_colors.py
--- a/doc/source/cookbook/image_background_colors.py
+++ b/doc/source/cookbook/image_background_colors.py
@@ -9,7 +9,7 @@
 
 ds = yt.load("Enzo_64/DD0043/data0043")
 im, sc = yt.volume_render(ds, 'density')
-im.write_png("original.png", clip_ratio=8.0)
+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
@@ -22,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 a2ca6bbf2b0601f200c7e4a78464235aeda79ede -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 doc/source/cookbook/opaque_rendering.py
--- a/doc/source/cookbook/opaque_rendering.py
+++ b/doc/source/cookbook/opaque_rendering.py
@@ -5,14 +5,14 @@
 
 # We start by building a default volume rendering scene 
 
-im, sc = yt.volume_render(ds, field=("gas","density"), fname="v0.png", clip_ratio=6.0)
+im, sc = yt.volume_render(ds, field=("gas","density"), fname="v0.png", sigma_clip=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')
-im = sc.render("v1.png", clip_ratio=6.0)
+im = sc.render("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
@@ -22,27 +22,27 @@
 tf.clear()
 tf.add_layers(4, 0.01, col_bounds = [-27.5,-25.5],
         alpha=np.logspace(0,0,4), colormap = 'RdBu_r')
-im = sc.render("v2.png", clip_ratio=6.0)
+im = sc.render("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
-im = sc.render("v3.png", clip_ratio=6.0)
+im = sc.render("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')
-im = sc.render("v4.png", clip_ratio=6.0)
+im = sc.render("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')
-im = sc.render("v5.png", clip_ratio=6.0)
+im = sc.render("v5.png", sigma_clip=6.0)
 
 # Now we are losing sight of everything.  Let's see if we can obscure the next
 # layer
@@ -50,13 +50,13 @@
 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')
-im = sc.render("v6.png", clip_ratio=6.0)
+im = sc.render("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
-im = sc.render("v7.png", clip_ratio=6.0)
+im = sc.render("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 a2ca6bbf2b0601f200c7e4a78464235aeda79ede -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 doc/source/cookbook/simple_volume_rendering.py
--- a/doc/source/cookbook/simple_volume_rendering.py
+++ b/doc/source/cookbook/simple_volume_rendering.py
@@ -6,14 +6,14 @@
 
 # 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.
-#im, sc = yt.volume_render(ds, fname="%s_volume_rendered.png" % ds, clip_ratio=8.0)
+#im, sc = yt.volume_render(ds, fname="%s_volume_rendered.png" % ds, sigma_clip=8.0)
 
 # You can easily specify a different field
-im, sc = yt.volume_render(ds, field=('gas','density'), fname="%s_density_volume_rendered.png" % ds, clip_ratio=8.0)
+im, sc = yt.volume_render(ds, field=('gas','density'), fname="%s_density_volume_rendered.png" % ds, sigma_clip=8.0)
 
 # Now increase the resolution
 sc.camera.resolution = (512, 512)
-im = sc.render(fname='big.png', clip_ratio=8.0)
+im = sc.render(fname='big.png', sigma_clip=8.0)
 
 # Now modify the transfer function
 # First get the render source, in this case the entire domain, with field ('gas','density')
@@ -25,4 +25,4 @@
         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')
-im = sc.render(fname='new_tf.png', clip_ratio=None)
+im = sc.render(fname='new_tf.png', sigma_clip=None)

diff -r a2ca6bbf2b0601f200c7e4a78464235aeda79ede -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 doc/source/cookbook/various_lens.py
--- a/doc/source/cookbook/various_lens.py
+++ b/doc/source/cookbook/various_lens.py
@@ -34,7 +34,7 @@
 cam.set_width(ds.domain_width * 0.5)
 sc.camera = cam
 sc.add_source(vol)
-sc.render('lens_plane-parallel.png', clip_ratio=6.0)
+sc.render('lens_plane-parallel.png', sigma_clip=6.0)
 
 # Perspective lens
 cam = Camera(ds, lens_type='perspective')
@@ -50,7 +50,7 @@
 cam.set_width(ds.domain_width * 0.5)
 sc.camera = cam
 sc.add_source(vol)
-sc.render('lens_perspective.png', clip_ratio=6.0)
+sc.render('lens_perspective.png', sigma_clip=6.0)
 
 # Stereo-perspective lens
 cam = Camera(ds, lens_type='stereo-perspective')
@@ -65,7 +65,7 @@
 cam.lens.disparity = ds.domain_width[0] * 1.e-3
 sc.camera = cam
 sc.add_source(vol)
-sc.render('lens_stereo-perspective.png', clip_ratio=6.0)
+sc.render('lens_stereo-perspective.png', sigma_clip=6.0)
 
 # Fisheye lens
 dd = ds.sphere(ds.domain_center, ds.domain_width[0] / 10)
@@ -79,7 +79,7 @@
 cam.lens.fov = 360.0
 sc.camera = cam
 sc.add_source(vol)
-sc.render('lens_fisheye.png', clip_ratio=6.0)
+sc.render('lens_fisheye.png', sigma_clip=6.0)
 
 # Spherical lens
 cam = Camera(ds, lens_type='spherical')
@@ -96,7 +96,7 @@
 cam.set_width(ds.domain_width * 0.5)
 sc.camera = cam
 sc.add_source(vol)
-sc.render('lens_spherical.png', clip_ratio=6.0)
+sc.render('lens_spherical.png', sigma_clip=6.0)
 
 # Stereo-spherical lens
 cam = Camera(ds, lens_type='stereo-spherical')
@@ -111,4 +111,4 @@
 cam.lens.disparity = ds.domain_width[0] * 1.e-3
 sc.camera = cam
 sc.add_source(vol)
-sc.render('lens_stereo-spherical.png', clip_ratio=6.0)
\ No newline at end of file
+sc.render('lens_stereo-spherical.png', sigma_clip=6.0)

diff -r a2ca6bbf2b0601f200c7e4a78464235aeda79ede -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 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 a2ca6bbf2b0601f200c7e4a78464235aeda79ede -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 yt/data_objects/image_array.py
--- a/yt/data_objects/image_array.py
+++ b/yt/data_objects/image_array.py
@@ -11,10 +11,12 @@
 # The full license is in the file COPYING.txt, distributed with this software.
 #-----------------------------------------------------------------------------
 
+import warnings
 import numpy as np
 from yt.visualization.image_writer import write_bitmap, write_image
 from yt.units.yt_array import YTArray
 
+
 class ImageArray(YTArray):
     r"""A custom Numpy ndarray used for images.
 
@@ -237,15 +239,15 @@
         np.clip(out, 0.0, 1.0, out)
         return out
 
-    def write_png(self, filename, clip_ratio=None, background='black',
-                  rescale=True):
+    def write_png(self, filename, sigma_clip=None, background='black',
+                  rescale=True, clip_ratio=None):
         r"""Writes ImageArray to png file.
 
         Parameters
         ----------
         filename: string
             Note filename not be modified.
-        clip_ratio: float, optional
+        sigma_clip: float, optional
             Image will be clipped before saving to the standard deviation
             of the image multiplied by this value.  Useful for enhancing
             images. Default: None
@@ -293,9 +295,13 @@
             filename += '.png'
 
         if clip_ratio is not None:
+            warnings.warn("'clip_ratio' keyword is deprecated. Use 'sigma_clip' instead")
+            sigma_clip = clip_ratio
+
+        if sigma_clip is not None:
             nz = out[:, :, :3][out[:, :, :3].nonzero()]
             return write_bitmap(out.swapaxes(0, 1), filename,
-                                nz.mean() + clip_ratio*nz.std())
+                                nz.mean() + sigma_clip * nz.std())
         else:
             return write_bitmap(out.swapaxes(0, 1), filename)
 

diff -r a2ca6bbf2b0601f200c7e4a78464235aeda79ede -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 yt/visualization/volume_rendering/camera.py
--- a/yt/visualization/volume_rendering/camera.py
+++ b/yt/visualization/volume_rendering/camera.py
@@ -70,7 +70,7 @@
         self.normal_vector = None
         self.light = None
         self._resolution = (512, 512)
-        self._width = 1.0
+        self._width = np.array([1.0, 1.0, 1.0])
         self._focus = np.array([0.0]*3)
         self._position = np.array([1.0]*3)
         self.set_lens(lens_type)

diff -r a2ca6bbf2b0601f200c7e4a78464235aeda79ede -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 yt/visualization/volume_rendering/render_source.py
--- a/yt/visualization/volume_rendering/render_source.py
+++ b/yt/visualization/volume_rendering/render_source.py
@@ -513,7 +513,7 @@
 
 
 class GridSource(LineSource):
-    def __init__(self, data_source, alpha=0.3, cmap='alage',
+    def __init__(self, data_source, alpha=0.3, cmap='algae',
                  min_level=None, max_level=None):
         r"""A render source for drawing grids in a scene.
 

diff -r a2ca6bbf2b0601f200c7e4a78464235aeda79ede -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 yt/visualization/volume_rendering/scene.py
--- a/yt/visualization/volume_rendering/scene.py
+++ b/yt/visualization/volume_rendering/scene.py
@@ -90,7 +90,7 @@
 
         return self
 
-    def render(self, fname=None, clip_ratio=None, camera=None):
+    def render(self, fname=None, sigma_clip=None, camera=None):
         r"""Render all sources in the Scene.
 
         Use the current state of the Scene object to render all sources
@@ -101,9 +101,10 @@
         fname: string, optional
             If specified, save the rendering as a bitmap to the file "fname".
             Default: None
-        clip_ratio: float, optional
-            If supplied, the 'max_val' argument to write_bitmap will be handed
-            clip_ratio * image.std()
+        sigma_clip: float, optional
+            Image will be clipped before saving to the standard deviation
+            of the image multiplied by this value.  Useful for enhancing
+            images. Default: None
         camera: :class:`Camera`, optional
             If specified, use a different :class:`Camera` to render the scene.
 
@@ -125,7 +126,7 @@
         self._validate()
         bmp = self.composite(camera=camera)
         if fname is not None:
-            bmp.write_png(fname, clip_ratio=clip_ratio)
+            bmp.write_png(fname, sigma_clip=sigma_clip)
         return bmp
 
     def _validate(self):

diff -r a2ca6bbf2b0601f200c7e4a78464235aeda79ede -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 yt/visualization/volume_rendering/tests/rotation_volume_rendering.py
--- a/yt/visualization/volume_rendering/tests/rotation_volume_rendering.py
+++ b/yt/visualization/volume_rendering/tests/rotation_volume_rendering.py
@@ -21,4 +21,4 @@
 frames = 10
 for i in range(frames):
     sc.camera.yaw(angle/frames)
-    sc.render('test_rot_%04i.png' % i, clip_ratio=6.0)
+    sc.render('test_rot_%04i.png' % i, sigma_clip=6.0)

diff -r a2ca6bbf2b0601f200c7e4a78464235aeda79ede -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 yt/visualization/volume_rendering/tests/simple_volume_rendering.py
--- a/yt/visualization/volume_rendering/tests/simple_volume_rendering.py
+++ b/yt/visualization/volume_rendering/tests/simple_volume_rendering.py
@@ -14,4 +14,4 @@
     fake_random_ds
 
 ds = fake_random_ds(32)
-im, sc = yt.volume_render(ds, fname='test.png', clip_ratio=4.0)
+im, sc = yt.volume_render(ds, fname='test.png', sigma_clip=4.0)

diff -r a2ca6bbf2b0601f200c7e4a78464235aeda79ede -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 yt/visualization/volume_rendering/tests/test_lenses.py
--- a/yt/visualization/volume_rendering/tests/test_lenses.py
+++ b/yt/visualization/volume_rendering/tests/test_lenses.py
@@ -28,7 +28,7 @@
     tf.grey_opacity = True
     sc.camera = cam
     sc.add_source(vol)
-    sc.render('test_perspective_%s.png' % field[1], clip_ratio=6.0)
+    sc.render('test_perspective_%s.png' % field[1], sigma_clip=6.0)
 
 def test_stereoperspective_lens():
     #ds = fake_random_ds(32, fields = field)
@@ -42,7 +42,7 @@
     tf.grey_opacity = True
     sc.camera = cam
     sc.add_source(vol)
-    sc.render('test_stereoperspective_%s.png' % field[1], clip_ratio=6.0)
+    sc.render('test_stereoperspective_%s.png' % field[1], sigma_clip=6.0)
 
 def test_fisheye_lens():
     ds = fake_random_ds(32, fields = field)
@@ -60,7 +60,7 @@
     tf.grey_opacity = True
     sc.camera = cam
     sc.add_source(vol)
-    sc.render('test_fisheye_%s.png' % field[1], clip_ratio=6.0)
+    sc.render('test_fisheye_%s.png' % field[1], sigma_clip=6.0)
 
 def test_plane_lens():
     ds = fake_random_ds(32, fields = field)
@@ -76,7 +76,7 @@
     tf.grey_opacity = True
     sc.camera = cam
     sc.add_source(vol)
-    sc.render('test_plane_%s.png' % field[1], clip_ratio=6.0)
+    sc.render('test_plane_%s.png' % field[1], sigma_clip=6.0)
 
 def test_spherical_lens():
     #ds = fake_random_ds(32, fields = field)
@@ -90,7 +90,7 @@
     tf.grey_opacity = True
     sc.camera = cam
     sc.add_source(vol)
-    sc.render('test_spherical_%s.png' % field[1], clip_ratio=6.0)
+    sc.render('test_spherical_%s.png' % field[1], sigma_clip=6.0)
 
 def test_stereospherical_lens():
     #ds = fake_random_ds(32, fields = field)
@@ -106,5 +106,5 @@
     tf.grey_opacity = True
     sc.camera = cam
     sc.add_source(vol)
-    sc.render('test_stereospherical_%s.png' % field[1], clip_ratio=6.0)
+    sc.render('test_stereospherical_%s.png' % field[1], sigma_clip=6.0)
 

diff -r a2ca6bbf2b0601f200c7e4a78464235aeda79ede -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 yt/visualization/volume_rendering/tests/test_scene.py
--- a/yt/visualization/volume_rendering/tests/test_scene.py
+++ b/yt/visualization/volume_rendering/tests/test_scene.py
@@ -48,9 +48,9 @@
     mi_bound = ((ma-mi)*(0.10))+mi
     ma_bound = ((ma-mi)*(0.90))+mi
     tf.map_to_colormap(mi_bound, ma_bound,  scale=0.01, colormap='Reds_r')
-    sc.render('test_scene.png', clip_ratio=6.0)
+    sc.render('test_scene.png', sigma_clip=6.0)
     
     nrot = 2 
     for i in range(nrot):
         sc.camera.pitch(2*np.pi/nrot)
-        sc.render('test_rot_%04i.png' % i, clip_ratio=6.0)
+        sc.render('test_rot_%04i.png' % i, sigma_clip=6.0)

diff -r a2ca6bbf2b0601f200c7e4a78464235aeda79ede -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 yt/visualization/volume_rendering/tests/test_simple_vr.py
--- a/yt/visualization/volume_rendering/tests/test_simple_vr.py
+++ b/yt/visualization/volume_rendering/tests/test_simple_vr.py
@@ -15,7 +15,7 @@
 
 def test_simple_vr():
     ds = fake_random_ds(32)
-    im, sc = yt.volume_render(ds, fname='test.png', clip_ratio=4.0)
+    im, sc = yt.volume_render(ds, fname='test.png', sigma_clip=4.0)
     print(sc)
     return im, sc
 

diff -r a2ca6bbf2b0601f200c7e4a78464235aeda79ede -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 yt/visualization/volume_rendering/tests/test_zbuff.py
--- a/yt/visualization/volume_rendering/tests/test_zbuff.py
+++ b/yt/visualization/volume_rendering/tests/test_zbuff.py
@@ -10,15 +10,15 @@
 # The full license is in the file COPYING.txt, distributed with this software.
 #-----------------------------------------------------------------------------
 
-import yt
 from yt.testing import fake_random_ds
-from yt.visualization.volume_rendering.api import Scene, Camera, ZBuffer, \
-    VolumeSource, OpaqueSource, LineSource, BoxSource
-from yt.utilities.lib.misc_utilities import lines
-from yt.data_objects.api import ImageArray
+from yt.visualization.volume_rendering.api import \
+    Scene, Camera, ZBuffer, \
+    VolumeSource, OpaqueSource
+from yt.testing import assert_almost_equal
 import numpy as np
 np.random.seed(0)
 
+
 def test_composite_vr():
     ds = fake_random_ds(64)
     dd = ds.sphere(ds.domain_center, 0.45*ds.domain_width[0])
@@ -53,5 +53,55 @@
     im.write_png("composite.png")
     return im
 
+
+def test_nonrectangular_add():
+    rgba1 = np.ones((64, 1, 4))
+    z1 = np.expand_dims(np.arange(64.), 1)
+
+    rgba2 = np.zeros((64, 1, 4))
+    z2 = np.expand_dims(np.arange(63., -1., -1.), 1)
+
+    exact_rgba = np.concatenate((np.ones(32), np.zeros(32)))
+    exact_rgba = np.expand_dims(exact_rgba, 1)
+    exact_rgba = np.dstack((exact_rgba, exact_rgba, exact_rgba, exact_rgba))
+
+    exact_z = np.concatenate((np.arange(32.), np.arange(31.,-1.,-1.)))
+    exact_z = np.expand_dims(exact_z, 1)
+
+    buff1 = ZBuffer(rgba1, z1)
+    buff2 = ZBuffer(rgba2, z2)
+
+    buff = buff1 + buff2
+
+    assert_almost_equal(buff.rgba, exact_rgba)
+    assert_almost_equal(buff.z, exact_z)
+
+
+def test_rectangular_add():
+    rgba1 = np.ones((8, 8, 4))
+    z1 = np.arange(64.)
+    z1 = z1.reshape((8, 8))
+    buff1 = ZBuffer(rgba1, z1)
+
+    rgba2 = np.zeros((8, 8, 4))
+    z2 = np.arange(63., -1., -1.)
+    z2 = z2.reshape((8, 8))
+    buff2 = ZBuffer(rgba2, z2)
+
+    buff = buff1 + buff2
+
+    exact_rgba = np.empty((8, 8, 4), dtype=np.float64)
+    exact_rgba[0:4,0:8,:] = 1.0
+    exact_rgba[4:8,0:8,:] = 0.0
+
+    exact_z = np.concatenate((np.arange(32.), np.arange(31., -1., -1.)))
+    exact_z = np.expand_dims(exact_z, 1)
+    exact_z = exact_z.reshape(8, 8)
+
+    assert_almost_equal(buff.rgba, exact_rgba)
+    assert_almost_equal(buff.z, exact_z)
+
 if __name__ == "__main__":
     im = test_composite_vr()
+    test_nonrectangular_add()
+    test_rectangular_add()

diff -r a2ca6bbf2b0601f200c7e4a78464235aeda79ede -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 yt/visualization/volume_rendering/volume_rendering.py
--- a/yt/visualization/volume_rendering/volume_rendering.py
+++ b/yt/visualization/volume_rendering/volume_rendering.py
@@ -70,7 +70,7 @@
     sc.camera = Camera(data_source)
     return sc
 
-def volume_render(data_source, field=None, fname=None, clip_ratio=None):
+def volume_render(data_source, field=None, fname=None, sigma_clip=None):
     r""" Create a simple volume rendering of a data source.
 
     A helper function that creates a default camera view, transfer
@@ -92,10 +92,11 @@
     fname: string, optional
         If specified, the resulting rendering will be saved to this filename
         in png format.
-    clip_ratio: float, optional
+    sigma_clip: float, optional
         If specified, the resulting image will be clipped before saving,
         using a threshold based on clip_ratio multiplied by the standard
         deviation of the pixel values. Recommended values are between 2 and 6.
+        Default: None
 
     Returns
     -------
@@ -109,7 +110,7 @@
     Example:
     >>> import yt
     >>> ds = yt.load("Enzo_64/DD0046/DD0046")
-    >>> im, sc = yt.volume_render(ds, fname='test.png', clip_ratio=4.0)
+    >>> im, sc = yt.volume_render(ds, fname='test.png', sigma_clip=4.0)
     """
     sc = create_scene(data_source, field=field)
     im = sc.render(fname=fname, clip_ratio=clip_ratio)

diff -r a2ca6bbf2b0601f200c7e4a78464235aeda79ede -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 yt/visualization/volume_rendering/zbuffer_array.py
--- a/yt/visualization/volume_rendering/zbuffer_array.py
+++ b/yt/visualization/volume_rendering/zbuffer_array.py
@@ -28,13 +28,16 @@
 
     def __add__(self, other):
         assert(self.shape == other.shape)
-        f_or_b = self.z < other.z
+        f = self.z < other.z
         if self.z.shape[1] == 1:
             # Non-rectangular
-            rgba = (self.rgba * f_or_b[:,None,:])
-            rgba += (other.rgba * (1.0 - f_or_b)[:,None,:])
+            rgba = (self.rgba * f[:,None,:])
+            rgba += (other.rgba * (1.0 - f)[:,None,:])
         else:
-            rgba = (self.rgba.T * f_or_b).T + (other.rgba.T * (1 - f_or_b)).T
+            b = self.z > other.z
+            rgba = np.empty(self.rgba.shape)
+            rgba[f] = self.rgba[f]
+            rgba[b] = other.rgba[b]
         z = np.min([self.z, other.z], axis=0)
         return ZBuffer(rgba, z)
 


https://bitbucket.org/yt_analysis/yt/commits/3ae4308f713d/
Changeset:   3ae4308f713d
Branch:      yt
User:        chummels
Date:        2015-10-14 22:05:20+00:00
Summary:     One last correction to sigma_clip
Affected #:  1 file

diff -r f66c29f42a40f9034701d82c26aa0d4f8f1e3132 -r 3ae4308f713d05707e9376e603ab93bca40ceb77 yt/visualization/volume_rendering/volume_rendering.py
--- a/yt/visualization/volume_rendering/volume_rendering.py
+++ b/yt/visualization/volume_rendering/volume_rendering.py
@@ -94,7 +94,7 @@
         in png format.
     sigma_clip: float, optional
         If specified, the resulting image will be clipped before saving,
-        using a threshold based on clip_ratio multiplied by the standard
+        using a threshold based on sigma_clip multiplied by the standard
         deviation of the pixel values. Recommended values are between 2 and 6.
         Default: None
 
@@ -113,5 +113,5 @@
     >>> im, sc = yt.volume_render(ds, fname='test.png', sigma_clip=4.0)
     """
     sc = create_scene(data_source, field=field)
-    im = sc.render(fname=fname, clip_ratio=clip_ratio)
+    im = sc.render(fname=fname, sigma_clip=sigma_clip)
     return im, sc


https://bitbucket.org/yt_analysis/yt/commits/7bea431548e2/
Changeset:   7bea431548e2
Branch:      yt
User:        chummels
Date:        2015-10-14 22:52:58+00:00
Summary:     Creating new exception for use in volume_render() and create_scene() as per PR comments.
Affected #:  2 files

diff -r 3ae4308f713d05707e9376e603ab93bca40ceb77 -r 7bea431548e275d91cdff31279d7f06a8a184fb0 yt/utilities/exceptions.py
--- a/yt/utilities/exceptions.py
+++ b/yt/utilities/exceptions.py
@@ -60,15 +60,23 @@
         return s
 
 class YTFieldNotFound(YTException):
-    def __init__(self, fname, ds, custom_msg=None):
+    def __init__(self, fname, ds):
         self.fname = fname
         self.ds = ds
-        if custom_msg is None: custom_msg = ""
+
+    def __str__(self):
+        return "Could not find field '%s' in %s." % (self.fname, self.ds)
+
+class YTFieldNotFoundCustom(YTFieldNotFound):
+    def __init__(self, fname, ds, custom_msg):
+        self.fname = fname
+        self.ds = ds
         self.custom_msg = custom_msg
 
     def __str__(self):
         return "Could not find field '%s' in %s. %s" % (self.fname, self.ds, self.custom_msg)
 
+
 class YTCouldNotGenerateField(YTFieldNotFound):
     def __str__(self):
         return "Could field '%s' in %s could not be generated." % (self.fname, self.ds)

diff -r 3ae4308f713d05707e9376e603ab93bca40ceb77 -r 7bea431548e275d91cdff31279d7f06a8a184fb0 yt/visualization/volume_rendering/volume_rendering.py
--- a/yt/visualization/volume_rendering/volume_rendering.py
+++ b/yt/visualization/volume_rendering/volume_rendering.py
@@ -17,7 +17,7 @@
 from .render_source import VolumeSource
 from .utils import data_source_or_all
 from yt.funcs import mylog
-from yt.utilities.exceptions import YTFieldNotFound
+from yt.utilities.exceptions import YTFieldNotFoundCustom
 
 
 def create_scene(data_source, field=None):
@@ -60,9 +60,8 @@
     if field is None:
         field = data_source.ds.default_field
         if field not in data_source.ds.derived_field_list:
-            raise YTFieldNotFound(field, data_source.ds, 
-                "You must specify a field with volume_render(), since " + \
-                "the default field does not exist in your dataset.")
+            raise YTFieldNotFoundCustom(field, data_source.ds, 
+                "Please specify a field in create_scene()")
         mylog.info('Setting default field to %s' % field.__repr__())
 
     vol = VolumeSource(data_source, field=field)


https://bitbucket.org/yt_analysis/yt/commits/89c2f3b8b660/
Changeset:   89c2f3b8b660
Branch:      yt
User:        chummels
Date:        2015-10-14 23:10:51+00:00
Summary:     Correcting exception for scene field error.
Affected #:  2 files

diff -r 7bea431548e275d91cdff31279d7f06a8a184fb0 -r 89c2f3b8b66052997d95d1a1027b657d0216b160 yt/utilities/exceptions.py
--- a/yt/utilities/exceptions.py
+++ b/yt/utilities/exceptions.py
@@ -67,15 +67,8 @@
     def __str__(self):
         return "Could not find field '%s' in %s." % (self.fname, self.ds)
 
-class YTFieldNotFoundCustom(YTFieldNotFound):
-    def __init__(self, fname, ds, custom_msg):
-        self.fname = fname
-        self.ds = ds
-        self.custom_msg = custom_msg
-
-    def __str__(self):
-        return "Could not find field '%s' in %s. %s" % (self.fname, self.ds, self.custom_msg)
-
+class YTSceneFieldNotFound(YTException):
+    pass
 
 class YTCouldNotGenerateField(YTFieldNotFound):
     def __str__(self):

diff -r 7bea431548e275d91cdff31279d7f06a8a184fb0 -r 89c2f3b8b66052997d95d1a1027b657d0216b160 yt/visualization/volume_rendering/volume_rendering.py
--- a/yt/visualization/volume_rendering/volume_rendering.py
+++ b/yt/visualization/volume_rendering/volume_rendering.py
@@ -17,7 +17,7 @@
 from .render_source import VolumeSource
 from .utils import data_source_or_all
 from yt.funcs import mylog
-from yt.utilities.exceptions import YTFieldNotFoundCustom
+from yt.utilities.exceptions import YTSceneFieldNotFound
 
 
 def create_scene(data_source, field=None):
@@ -60,8 +60,9 @@
     if field is None:
         field = data_source.ds.default_field
         if field not in data_source.ds.derived_field_list:
-            raise YTFieldNotFoundCustom(field, data_source.ds, 
-                "Please specify a field in create_scene()")
+            raise YTSceneFieldNotFound("""Could not find field '%s' in %s. 
+                  Please specify a field in create_scene()""" % \
+                  (field, data_source.ds))
         mylog.info('Setting default field to %s' % field.__repr__())
 
     vol = VolumeSource(data_source, field=field)


https://bitbucket.org/yt_analysis/yt/commits/5479e522312f/
Changeset:   5479e522312f
Branch:      yt
User:        chummels
Date:        2015-10-14 23:15:29+00:00
Summary:     Adding create_scene test
Affected #:  1 file

diff -r 89c2f3b8b66052997d95d1a1027b657d0216b160 -r 5479e522312f504cd5dc879677e8b622ea89049c yt/visualization/volume_rendering/tests/simple_scene_creation.py
--- /dev/null
+++ b/yt/visualization/volume_rendering/tests/simple_scene_creation.py
@@ -0,0 +1,17 @@
+"""
+Create a simple scene object
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (c) 2014, yt Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+import yt
+from yt.testing import \
+    fake_random_ds
+
+ds = fake_random_ds(32)
+sc = yt.create_scene(ds)


https://bitbucket.org/yt_analysis/yt/commits/57e4d9735d43/
Changeset:   57e4d9735d43
Branch:      yt
User:        chummels
Date:        2015-10-14 23:47:48+00:00
Summary:     Merging.
Affected #:  4 files

diff -r 5479e522312f504cd5dc879677e8b622ea89049c -r 57e4d9735d430d885934438d98fdaa0d0e6b1baf doc/source/cookbook/complex_plots.rst
--- a/doc/source/cookbook/complex_plots.rst
+++ b/doc/source/cookbook/complex_plots.rst
@@ -200,6 +200,24 @@
 
 .. 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
+
+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
+
 Zooming into an Image
 ~~~~~~~~~~~~~~~~~~~~~
 
@@ -255,7 +273,7 @@
 .. 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

diff -r 5479e522312f504cd5dc879677e8b622ea89049c -r 57e4d9735d430d885934438d98fdaa0d0e6b1baf 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
+# NOTE: This should use yt.create_scene once that exists
+im, sc = yt.volume_render(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(fname='custom.png', sigma_clip=4)

diff -r 5479e522312f504cd5dc879677e8b622ea89049c -r 57e4d9735d430d885934438d98fdaa0d0e6b1baf doc/source/cookbook/custom_transfer_function_volume_rendering.py
--- /dev/null
+++ b/doc/source/cookbook/custom_transfer_function_volume_rendering.py
@@ -0,0 +1,25 @@
+import yt
+import numpy as np
+
+# Load the dataset
+ds = yt.load("Enzo_64/DD0043/data0043")
+
+# Create a volume rendering
+# NOTE: This should use yt.create_scene once that exists
+im, sc = yt.volume_render(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')
+
+im = sc.render(fname='new_tf.png', sigma_clip=None)

diff -r 5479e522312f504cd5dc879677e8b622ea89049c -r 57e4d9735d430d885934438d98fdaa0d0e6b1baf doc/source/cookbook/simple_volume_rendering.py
--- a/doc/source/cookbook/simple_volume_rendering.py
+++ b/doc/source/cookbook/simple_volume_rendering.py
@@ -1,28 +1,10 @@
 import yt
-import numpy as np
 
 # Load the dataset.
 ds = yt.load("Enzo_64/DD0043/data0043")
 
 # 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.
-#im, sc = yt.volume_render(ds, fname="%s_volume_rendered.png" % ds, sigma_clip=8.0)
 
-# You can easily specify a different field
-im, sc = yt.volume_render(ds, field=('gas','density'), fname="%s_density_volume_rendered.png" % ds, sigma_clip=8.0)
-
-# Now increase the resolution
-sc.camera.resolution = (512, 512)
-im = sc.render(fname='big.png', sigma_clip=8.0)
-
-# Now 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')
-im = sc.render(fname='new_tf.png', sigma_clip=None)
+# This will save a file named 'data0043_density_volume_rendered.png' to disk.
+im, sc = yt.volume_render(ds, field=('gas', 'density'))


https://bitbucket.org/yt_analysis/yt/commits/89d1d2f45299/
Changeset:   89d1d2f45299
Branch:      yt
User:        chummels
Date:        2015-10-15 00:04:08+00:00
Summary:     Updating relevant docs references to include create_scene instead of volume_render.
Affected #:  8 files

diff -r 57e4d9735d430d885934438d98fdaa0d0e6b1baf -r 89d1d2f4529924ba60295cc09c6fb7cc47ac41ca doc/source/cookbook/amrkdtree_downsampling.py
--- a/doc/source/cookbook/amrkdtree_downsampling.py
+++ b/doc/source/cookbook/amrkdtree_downsampling.py
@@ -19,7 +19,7 @@
 
 # Load up a dataset and define the kdtree
 ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030')
-im, sc = yt.volume_render(ds, 'density', fname='v0.png')
+sc = yt.create_scene(ds, 'density', fname='v0.png')
 sc.camera.set_width(ds.arr(100, 'kpc'))
 render_source = sc.get_source(0)
 kd=render_source.volume

diff -r 57e4d9735d430d885934438d98fdaa0d0e6b1baf -r 89d1d2f4529924ba60295cc09c6fb7cc47ac41ca doc/source/cookbook/camera_movement.py
--- a/doc/source/cookbook/camera_movement.py
+++ b/doc/source/cookbook/camera_movement.py
@@ -3,7 +3,7 @@
 
 # Follow the simple_volume_rendering cookbook for the first part of this.
 ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")  # load data
-im, sc = yt.volume_render(ds)
+sc = yt.create_scene(ds)
 cam = sc.camera
 cam.resolution = (512, 512)
 cam.set_width(ds.domain_width/20.0)

diff -r 57e4d9735d430d885934438d98fdaa0d0e6b1baf -r 89d1d2f4529924ba60295cc09c6fb7cc47ac41ca doc/source/cookbook/custom_camera_volume_rendering.py
--- a/doc/source/cookbook/custom_camera_volume_rendering.py
+++ b/doc/source/cookbook/custom_camera_volume_rendering.py
@@ -4,8 +4,7 @@
 ds = yt.load("Enzo_64/DD0043/data0043")
 
 # Create a volume rendering
-# NOTE: This should use yt.create_scene once that exists
-im, sc = yt.volume_render(ds, field=('gas', 'density'))
+sc = yt.create_scene(ds, field=('gas', 'density'))
 
 # Now increase the resolution
 sc.camera.resolution = (1024, 1024)

diff -r 57e4d9735d430d885934438d98fdaa0d0e6b1baf -r 89d1d2f4529924ba60295cc09c6fb7cc47ac41ca doc/source/cookbook/custom_transfer_function_volume_rendering.py
--- a/doc/source/cookbook/custom_transfer_function_volume_rendering.py
+++ b/doc/source/cookbook/custom_transfer_function_volume_rendering.py
@@ -5,8 +5,7 @@
 ds = yt.load("Enzo_64/DD0043/data0043")
 
 # Create a volume rendering
-# NOTE: This should use yt.create_scene once that exists
-im, sc = yt.volume_render(ds, field=('gas', 'density'))
+sc = yt.create_scene(ds, field=('gas', 'density'))
 
 # Modify the transfer function
 

diff -r 57e4d9735d430d885934438d98fdaa0d0e6b1baf -r 89d1d2f4529924ba60295cc09c6fb7cc47ac41ca doc/source/cookbook/opaque_rendering.py
--- a/doc/source/cookbook/opaque_rendering.py
+++ b/doc/source/cookbook/opaque_rendering.py
@@ -5,7 +5,7 @@
 
 # We start by building a default volume rendering scene 
 
-im, sc = yt.volume_render(ds, field=("gas","density"), fname="v0.png", sigma_clip=6.0)
+sc = yt.create_scene(ds, field=("gas","density"), fname="v0.png", sigma_clip=6.0)
 
 sc.camera.set_width(ds.arr(0.1,'code_length'))
 tf = sc.get_source(0).transfer_function 

diff -r 57e4d9735d430d885934438d98fdaa0d0e6b1baf -r 89d1d2f4529924ba60295cc09c6fb7cc47ac41ca 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
@@ -4,7 +4,7 @@
 
 # Load the dataset.
 ds = yt.load("Enzo_64/DD0043/data0043")
-im, sc = yt.volume_render(ds, ('gas','density'))
+sc = yt.create_scene(ds, ('gas','density'))
 sc.get_source(0).transfer_function.grey_opacity=True
 
 sc.annotate_domain(ds)

diff -r 57e4d9735d430d885934438d98fdaa0d0e6b1baf -r 89d1d2f4529924ba60295cc09c6fb7cc47ac41ca doc/source/reference/api/api.rst
--- a/doc/source/reference/api/api.rst
+++ b/doc/source/reference/api/api.rst
@@ -592,6 +592,7 @@
    :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

diff -r 57e4d9735d430d885934438d98fdaa0d0e6b1baf -r 89d1d2f4529924ba60295cc09c6fb7cc47ac41ca doc/source/visualizing/volume_rendering.rst
--- a/doc/source/visualizing/volume_rendering.rst
+++ b/doc/source/visualizing/volume_rendering.rst
@@ -60,6 +60,7 @@
 Here is a working example for rendering the IsolatedGalaxy dataset.
 
 .. python-script::
+
   import yt
   # load the data
   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
@@ -70,10 +71,10 @@
   # sc is an instance of a Scene object, which allows you to further refine
   # your renderings.
 
-When the volume_render function is called, first an empty
-:class:`~yt.visualization.volume_rendering.scene.Scene` object is
-created. Next, a 
-:class:`~yt.visualization.volume_rendering.api.VolumeSource`
+When the :func:`~yt.visualization.volume_rendering.volume_render` function 
+is called, first an empty 
+:class:`~yt.visualization.volume_rendering.scene.Scene` object is created. 
+Next, a :class:`~yt.visualization.volume_rendering.api.VolumeSource`
 object is created, which decomposes the volume elements
 into a tree structure to provide back-to-front rendering of fixed-resolution
 blocks of data.  (If the volume elements are grids, this uses a
@@ -106,6 +107,21 @@
 In this example, we don't add on any non-volume rendering sources; however, if
 such sources are added, they will be integrated as well.
 
+Alternatively, if you don't want to immediately generate an image of your
+volume rendering, and you just want access to the default scene object, 
+you can skip this expensive operation by just running the
+:func:`~yt.visualization.volume_rendering.create_scene` function in lieu of the
+:func:`~yt.visualization.volume_rendering.volume_render` function. Example:
+
+.. python-script::
+
+  import yt
+  # load the data
+  ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+  # volume render the 'density' field 
+  sc = yt.create_scene(ds, 'density')
+
+
 Modifying the Scene
 -------------------
 


https://bitbucket.org/yt_analysis/yt/commits/903124d0180b/
Changeset:   903124d0180b
Branch:      yt
User:        chummels
Date:        2015-10-15 06:24:30+00:00
Summary:     Reverting to old volume_render instead of create_scene in some of the recipes.
Affected #:  2 files

diff -r 89d1d2f4529924ba60295cc09c6fb7cc47ac41ca -r 903124d0180be1a8c9dde901c7d0022ac1fa921b doc/source/cookbook/amrkdtree_downsampling.py
--- a/doc/source/cookbook/amrkdtree_downsampling.py
+++ b/doc/source/cookbook/amrkdtree_downsampling.py
@@ -19,7 +19,7 @@
 
 # Load up a dataset and define the kdtree
 ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030')
-sc = yt.create_scene(ds, 'density', fname='v0.png')
+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

diff -r 89d1d2f4529924ba60295cc09c6fb7cc47ac41ca -r 903124d0180be1a8c9dde901c7d0022ac1fa921b doc/source/cookbook/opaque_rendering.py
--- a/doc/source/cookbook/opaque_rendering.py
+++ b/doc/source/cookbook/opaque_rendering.py
@@ -5,7 +5,7 @@
 
 # We start by building a default volume rendering scene 
 
-sc = yt.create_scene(ds, field=("gas","density"), fname="v0.png", sigma_clip=6.0)
+sc = yt.volume_render(ds, field=("gas","density"), fname="v0.png", sigma_clip=6.0)
 
 sc.camera.set_width(ds.arr(0.1,'code_length'))
 tf = sc.get_source(0).transfer_function 


https://bitbucket.org/yt_analysis/yt/commits/71c822824238/
Changeset:   71c822824238
Branch:      yt
User:        chummels
Date:        2015-10-15 06:25:26+00:00
Summary:     Fixing revert problem in cookbook
Affected #:  2 files

diff -r 903124d0180be1a8c9dde901c7d0022ac1fa921b -r 71c822824238d2e463e10e57a5016f0d236790bd doc/source/cookbook/amrkdtree_downsampling.py
--- a/doc/source/cookbook/amrkdtree_downsampling.py
+++ b/doc/source/cookbook/amrkdtree_downsampling.py
@@ -19,7 +19,7 @@
 
 # Load up a dataset and define the kdtree
 ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030')
-sc = yt.volume_render(ds, 'density', fname='v0.png')
+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

diff -r 903124d0180be1a8c9dde901c7d0022ac1fa921b -r 71c822824238d2e463e10e57a5016f0d236790bd doc/source/cookbook/opaque_rendering.py
--- a/doc/source/cookbook/opaque_rendering.py
+++ b/doc/source/cookbook/opaque_rendering.py
@@ -5,7 +5,7 @@
 
 # We start by building a default volume rendering scene 
 
-sc = yt.volume_render(ds, field=("gas","density"), fname="v0.png", sigma_clip=6.0)
+im, sc = yt.volume_render(ds, field=("gas","density"), fname="v0.png", sigma_clip=6.0)
 
 sc.camera.set_width(ds.arr(0.1,'code_length'))
 tf = sc.get_source(0).transfer_function 


https://bitbucket.org/yt_analysis/yt/commits/562b253b734a/
Changeset:   562b253b734a
Branch:      yt
User:        xarthisius
Date:        2015-10-15 17:57:26+00:00
Summary:     Merged in chummels/yt (pull request #1800)

[experimental] new create_scene() function
Affected #:  14 files

diff -r 3735cc557a7aafa02a3cc69ec65bd3f5c107b136 -r 562b253b734a3abc182b712fb9009034ea3b36c6 doc/source/cookbook/camera_movement.py
--- a/doc/source/cookbook/camera_movement.py
+++ b/doc/source/cookbook/camera_movement.py
@@ -3,7 +3,7 @@
 
 # Follow the simple_volume_rendering cookbook for the first part of this.
 ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")  # load data
-im, sc = yt.volume_render(ds)
+sc = yt.create_scene(ds)
 cam = sc.camera
 cam.resolution = (512, 512)
 cam.set_width(ds.domain_width/20.0)

diff -r 3735cc557a7aafa02a3cc69ec65bd3f5c107b136 -r 562b253b734a3abc182b712fb9009034ea3b36c6 doc/source/cookbook/custom_camera_volume_rendering.py
--- a/doc/source/cookbook/custom_camera_volume_rendering.py
+++ b/doc/source/cookbook/custom_camera_volume_rendering.py
@@ -4,8 +4,7 @@
 ds = yt.load("Enzo_64/DD0043/data0043")
 
 # Create a volume rendering
-# NOTE: This should use yt.create_scene once that exists
-im, sc = yt.volume_render(ds, field=('gas', 'density'))
+sc = yt.create_scene(ds, field=('gas', 'density'))
 
 # Now increase the resolution
 sc.camera.resolution = (1024, 1024)

diff -r 3735cc557a7aafa02a3cc69ec65bd3f5c107b136 -r 562b253b734a3abc182b712fb9009034ea3b36c6 doc/source/cookbook/custom_transfer_function_volume_rendering.py
--- a/doc/source/cookbook/custom_transfer_function_volume_rendering.py
+++ b/doc/source/cookbook/custom_transfer_function_volume_rendering.py
@@ -5,8 +5,7 @@
 ds = yt.load("Enzo_64/DD0043/data0043")
 
 # Create a volume rendering
-# NOTE: This should use yt.create_scene once that exists
-im, sc = yt.volume_render(ds, field=('gas', 'density'))
+sc = yt.create_scene(ds, field=('gas', 'density'))
 
 # Modify the transfer function
 

diff -r 3735cc557a7aafa02a3cc69ec65bd3f5c107b136 -r 562b253b734a3abc182b712fb9009034ea3b36c6 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
@@ -4,7 +4,7 @@
 
 # Load the dataset.
 ds = yt.load("Enzo_64/DD0043/data0043")
-im, sc = yt.volume_render(ds, ('gas','density'))
+sc = yt.create_scene(ds, ('gas','density'))
 sc.get_source(0).transfer_function.grey_opacity=True
 
 sc.annotate_domain(ds)

diff -r 3735cc557a7aafa02a3cc69ec65bd3f5c107b136 -r 562b253b734a3abc182b712fb9009034ea3b36c6 doc/source/reference/api/api.rst
--- a/doc/source/reference/api/api.rst
+++ b/doc/source/reference/api/api.rst
@@ -592,6 +592,7 @@
    :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

diff -r 3735cc557a7aafa02a3cc69ec65bd3f5c107b136 -r 562b253b734a3abc182b712fb9009034ea3b36c6 doc/source/visualizing/volume_rendering.rst
--- a/doc/source/visualizing/volume_rendering.rst
+++ b/doc/source/visualizing/volume_rendering.rst
@@ -60,6 +60,7 @@
 Here is a working example for rendering the IsolatedGalaxy dataset.
 
 .. python-script::
+
   import yt
   # load the data
   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
@@ -70,10 +71,10 @@
   # sc is an instance of a Scene object, which allows you to further refine
   # your renderings.
 
-When the volume_render function is called, first an empty
-:class:`~yt.visualization.volume_rendering.scene.Scene` object is
-created. Next, a 
-:class:`~yt.visualization.volume_rendering.api.VolumeSource`
+When the :func:`~yt.visualization.volume_rendering.volume_render` function 
+is called, first an empty 
+:class:`~yt.visualization.volume_rendering.scene.Scene` object is created. 
+Next, a :class:`~yt.visualization.volume_rendering.api.VolumeSource`
 object is created, which decomposes the volume elements
 into a tree structure to provide back-to-front rendering of fixed-resolution
 blocks of data.  (If the volume elements are grids, this uses a
@@ -106,6 +107,21 @@
 In this example, we don't add on any non-volume rendering sources; however, if
 such sources are added, they will be integrated as well.
 
+Alternatively, if you don't want to immediately generate an image of your
+volume rendering, and you just want access to the default scene object, 
+you can skip this expensive operation by just running the
+:func:`~yt.visualization.volume_rendering.create_scene` function in lieu of the
+:func:`~yt.visualization.volume_rendering.volume_render` function. Example:
+
+.. python-script::
+
+  import yt
+  # load the data
+  ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+  # volume render the 'density' field 
+  sc = yt.create_scene(ds, 'density')
+
+
 Modifying the Scene
 -------------------
 

diff -r 3735cc557a7aafa02a3cc69ec65bd3f5c107b136 -r 562b253b734a3abc182b712fb9009034ea3b36c6 yt/__init__.py
--- a/yt/__init__.py
+++ b/yt/__init__.py
@@ -154,7 +154,7 @@
     ParticleProjectionPlot, ParticleImageBuffer, ParticlePlot
 
 from yt.visualization.volume_rendering.api import \
-    volume_render, ColorTransferFunction, TransferFunction, \
+    volume_render, create_scene, ColorTransferFunction, TransferFunction, \
     off_axis_projection
 import yt.visualization.volume_rendering.api as volume_rendering
 #    TransferFunctionHelper, MultiVariateTransferFunction

diff -r 3735cc557a7aafa02a3cc69ec65bd3f5c107b136 -r 562b253b734a3abc182b712fb9009034ea3b36c6 yt/data_objects/static_output.py
--- a/yt/data_objects/static_output.py
+++ b/yt/data_objects/static_output.py
@@ -112,6 +112,7 @@
 class Dataset(object):
 
     default_fluid_type = "gas"
+    default_field = ("gas", "density")
     fluid_types = ("gas", "deposit", "index")
     particle_types = ("io",) # By default we have an 'all'
     particle_types_raw = ("io",)

diff -r 3735cc557a7aafa02a3cc69ec65bd3f5c107b136 -r 562b253b734a3abc182b712fb9009034ea3b36c6 yt/utilities/exceptions.py
--- a/yt/utilities/exceptions.py
+++ b/yt/utilities/exceptions.py
@@ -67,6 +67,9 @@
     def __str__(self):
         return "Could not find field '%s' in %s." % (self.fname, self.ds)
 
+class YTSceneFieldNotFound(YTException):
+    pass
+
 class YTCouldNotGenerateField(YTFieldNotFound):
     def __str__(self):
         return "Could field '%s' in %s could not be generated." % (self.fname, self.ds)

diff -r 3735cc557a7aafa02a3cc69ec65bd3f5c107b136 -r 562b253b734a3abc182b712fb9009034ea3b36c6 yt/visualization/volume_rendering/api.py
--- a/yt/visualization/volume_rendering/api.py
+++ b/yt/visualization/volume_rendering/api.py
@@ -27,7 +27,7 @@
 #    SphericalCamera, StereoSphericalCamera
 from .camera import Camera
 from .transfer_function_helper import TransferFunctionHelper
-from .volume_rendering import volume_render
+from .volume_rendering import volume_render, create_scene
 from .off_axis_projection import off_axis_projection
 from .scene import Scene
 from .render_source import VolumeSource, OpaqueSource, LineSource, \

diff -r 3735cc557a7aafa02a3cc69ec65bd3f5c107b136 -r 562b253b734a3abc182b712fb9009034ea3b36c6 yt/visualization/volume_rendering/tests/simple_scene_creation.py
--- /dev/null
+++ b/yt/visualization/volume_rendering/tests/simple_scene_creation.py
@@ -0,0 +1,17 @@
+"""
+Create a simple scene object
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (c) 2014, yt Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+import yt
+from yt.testing import \
+    fake_random_ds
+
+ds = fake_random_ds(32)
+sc = yt.create_scene(ds)

diff -r 3735cc557a7aafa02a3cc69ec65bd3f5c107b136 -r 562b253b734a3abc182b712fb9009034ea3b36c6 yt/visualization/volume_rendering/volume_rendering.py
--- a/yt/visualization/volume_rendering/volume_rendering.py
+++ b/yt/visualization/volume_rendering/volume_rendering.py
@@ -17,8 +17,59 @@
 from .render_source import VolumeSource
 from .utils import data_source_or_all
 from yt.funcs import mylog
+from yt.utilities.exceptions import YTSceneFieldNotFound
 
 
+def create_scene(data_source, field=None):
+    r""" Set up a scene object with sensible defaults for use in volume 
+    rendering.
+
+    A helper function that creates a default camera view, transfer
+    function, and image size. Using these, it returns an instance 
+    of the Scene class, allowing one to further modify their rendering.
+
+    This function is the same as volume_render() except it doesn't render
+    the image.
+
+    Parameters
+    ----------
+    data_source : :class:`yt.data_objects.data_containers.AMR3DData`
+        This is the source to be rendered, which can be any arbitrary yt
+        3D object
+    field: string, tuple, optional
+        The field to be rendered. If unspecified, this will use the 
+        default_field for your dataset's frontend--usually ('gas', 'density').
+        A default transfer function will be built that spans the range of 
+        values for that given field, and the field will be logarithmically 
+        scaled if the field_info object specifies as such.
+
+    Returns
+    -------
+    sc: Scene
+        A :class:`yt.visualization.volume_rendering.scene.Scene` object
+        that was constructed during the rendering. Useful for further
+        modifications, rotations, etc.
+
+    Example:
+    >>> import yt
+    >>> ds = yt.load("Enzo_64/DD0046/DD0046")
+    >>> sc = yt.create_scene(ds)
+    """
+    data_source = data_source_or_all(data_source)
+    sc = Scene()
+    if field is None:
+        field = data_source.ds.default_field
+        if field not in data_source.ds.derived_field_list:
+            raise YTSceneFieldNotFound("""Could not find field '%s' in %s. 
+                  Please specify a field in create_scene()""" % \
+                  (field, data_source.ds))
+        mylog.info('Setting default field to %s' % field.__repr__())
+
+    vol = VolumeSource(data_source, field=field)
+    sc.add_source(vol)
+    sc.camera = Camera(data_source)
+    return sc
+
 def volume_render(data_source, field=None, fname=None, sigma_clip=None):
     r""" Create a simple volume rendering of a data source.
 
@@ -33,18 +84,19 @@
         This is the source to be rendered, which can be any arbitrary yt
         3D object
     field: string, tuple, optional
-        The field to be rendered. By default, this will use the first
-        field in data_source.ds.field_list.  A default transfer function
-        will be built that spans the range of values for that given field,
-        and the field will be logarithmically scaled if the field_info
-        object specifies as such.
+        The field to be rendered. If unspecified, this will use the 
+        default_field for your dataset's frontend--usually ('gas', 'density').
+        A default transfer function will be built that spans the range of 
+        values for that given field, and the field will be logarithmically 
+        scaled if the field_info object specifies as such.
     fname: string, optional
         If specified, the resulting rendering will be saved to this filename
         in png format.
-    sigma_clip: float
-        The resulting image will be clipped before saving, using a threshold
-        based on `sigma_clip` multiplied by the standard deviation of the pixel
-        values. Recommended values are between 2 and 6. Default: None
+    sigma_clip: float, optional
+        If specified, the resulting image will be clipped before saving,
+        using a threshold based on sigma_clip multiplied by the standard
+        deviation of the pixel values. Recommended values are between 2 and 6.
+        Default: None
 
     Returns
     -------
@@ -58,29 +110,8 @@
     Example:
     >>> import yt
     >>> ds = yt.load("Enzo_64/DD0046/DD0046")
-    >>> im, sc = yt.volume_render(ds, fname='test.png')
+    >>> im, sc = yt.volume_render(ds, fname='test.png', sigma_clip=4.0)
     """
-    data_source = data_source_or_all(data_source)
-    sc = Scene()
-    if field is None:
-        data_source.ds.index
-        for ftype, f in sorted(data_source.ds.field_list):
-            if ftype == "all":
-                continue
-            if f == 'Density':
-                field = (ftype, f)
-            elif f == 'density':
-                field = (ftype, f)
-            elif ftype != 'index' and 'particle' not in f:
-                field = (ftype, f)
-                break
-        else:
-            raise RuntimeError("Could not find default field." +
-                               " Please set explicitly in volume_render call")
-        mylog.info('Setting default field to %s' % field.__repr__())
-
-    vol = VolumeSource(data_source, field=field)
-    sc.add_source(vol)
-    sc.camera = Camera(data_source)
+    sc = create_scene(data_source, field=field)
     im = sc.render(fname=fname, sigma_clip=sigma_clip)
     return im, sc

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