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

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Fri Oct 16 16:11:00 PDT 2015


1 new commit in yt:

https://bitbucket.org/yt_analysis/yt/commits/6facab7ff325/
Changeset:   6facab7ff325
Branch:      yt
User:        ngoldbaum
Date:        2015-10-16 23:10:51+00:00
Summary:     Merged in chummels/yt (pull request #1808)

[experimental] Modifying scene.render() function to not save to disk and instead requiring sc.save()
Affected #:  17 files

diff -r d0f52cf90877f87528854d9e30dd71dc570050f2 -r 6facab7ff3258b232346caaecd999be9f25ef139 doc/source/cookbook/amrkdtree_downsampling.py
--- a/doc/source/cookbook/amrkdtree_downsampling.py
+++ b/doc/source/cookbook/amrkdtree_downsampling.py
@@ -39,7 +39,8 @@
 
 render_source.set_volume(kd_low_res)
 render_source.set_fields('density')
-sc.render("v1.png")
+sc.render()
+sc.save("v1.png")
 
 # This operation was substantiall faster.  Now lets modify the low resolution
 # rendering until we find something we like.
@@ -48,12 +49,14 @@
 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", sigma_clip=6.0)
+sc.render(sigma_clip=6.0)
+sc.save("v2.png")
 
 # This looks better.  Now let's try turning on opacity.
 
 tf.grey_opacity = True
-sc.render("v3.png", sigma_clip=6.0)
+sc.render(sigma_clip=6.0)
+sc.save("v3.png")
 #
 ## That seemed to pick out som interesting structures.  Now let's bump up the
 ## opacity.
@@ -61,11 +64,13 @@
 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", sigma_clip=6.0)
+sc.render(sigma_clip=6.0)
+sc.save("v4.png")
 #
 ## This looks pretty good, now lets go back to the full resolution AMRKDTree
 #
 render_source.set_volume(kd)
-sc.render("v5.png", sigma_clip=6.0)
+sc.render(sigma_clip=6.0)
+sc.render("v5.png")
 
 # This looks great!

diff -r d0f52cf90877f87528854d9e30dd71dc570050f2 -r 6facab7ff3258b232346caaecd999be9f25ef139 doc/source/cookbook/camera_movement.py
--- a/doc/source/cookbook/camera_movement.py
+++ b/doc/source/cookbook/camera_movement.py
@@ -14,15 +14,18 @@
 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, sigma_clip=8.0)
+    sc.render(sigma_clip=8.0)
+    sc.save('camera_movement_%04i.png' % frame)
     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, sigma_clip=8.0)
+    sc.render(sigma_clip=8.0)
+    sc.save('camera_movement_%04i.png' % frame)
     frame += 1
 
 # Do a rotation over 5 frames
 for _ in cam.iter_rotate(np.pi, 5):
-    sc.render('camera_movement_%04i.png' % frame, sigma_clip=8.0)
+    sc.render(sigma_clip=8.0)
+    sc.save('camera_movement_%04i.png' % frame)
     frame += 1

diff -r d0f52cf90877f87528854d9e30dd71dc570050f2 -r 6facab7ff3258b232346caaecd999be9f25ef139 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
@@ -18,4 +18,5 @@
 
 # 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)
+sc.render(sigma_clip=4)
+sc.save('custom.png')

diff -r d0f52cf90877f87528854d9e30dd71dc570050f2 -r 6facab7ff3258b232346caaecd999be9f25ef139 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
@@ -21,4 +21,4 @@
     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)
+sc.save('new_tf.png')

diff -r d0f52cf90877f87528854d9e30dd71dc570050f2 -r 6facab7ff3258b232346caaecd999be9f25ef139 doc/source/cookbook/opaque_rendering.py
--- a/doc/source/cookbook/opaque_rendering.py
+++ b/doc/source/cookbook/opaque_rendering.py
@@ -12,7 +12,8 @@
 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", sigma_clip=6.0)
+sc.render(sigma_clip=6.0)
+sc.save("v1.png")
 
 # 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 +23,31 @@
 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", sigma_clip=6.0)
+sc.render(sigma_clip=6.0)
+sc.save("v2.png")
 
 # 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", sigma_clip=6.0)
+sc.render(sigma_clip=6.0)
+sc.save("v3.png")
 
 # 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", sigma_clip=6.0)
+sc.render(sigma_clip=6.0)
+sc.save("v4.png")
 
 # 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", sigma_clip=6.0)
+sc.render(sigma_clip=6.0)
+sc.save("v5.png")
 
 # Now we are losing sight of everything.  Let's see if we can obscure the next
 # layer
@@ -50,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')
-im = sc.render("v6.png", sigma_clip=6.0)
+sc.render(sigma_clip=6.0)
+sc.save("v6.png")
 
 # 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", sigma_clip=6.0)
+sc.render(sigma_clip=6.0)
+sc.save("v7.png")
 
 # That looks pretty different, but the main thing is that you can see that the
 # inner contours are somewhat visible again.  

diff -r d0f52cf90877f87528854d9e30dd71dc570050f2 -r 6facab7ff3258b232346caaecd999be9f25ef139 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
@@ -8,15 +8,15 @@
 sc.get_source(0).transfer_function.grey_opacity=True
 
 sc.annotate_domain(ds)
-im = sc.render()
-im.write_png("%s_vr_domain.png" % ds)
+sc.render()
+sc.save("%s_vr_domain.png" % ds)
 
 sc.annotate_grids(ds)
-im = sc.render()
-im.write_png("%s_vr_grids.png" % 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.
 sc.annotate_axes()
-im = sc.render()
-im.write_png("%s_vr_coords.png" % ds)
+sc.render()
+sc.save("%s_vr_coords.png" % ds)

diff -r d0f52cf90877f87528854d9e30dd71dc570050f2 -r 6facab7ff3258b232346caaecd999be9f25ef139 doc/source/cookbook/various_lens.py
--- a/doc/source/cookbook/various_lens.py
+++ b/doc/source/cookbook/various_lens.py
@@ -34,7 +34,8 @@
 cam.set_width(ds.domain_width * 0.5)
 sc.camera = cam
 sc.add_source(vol)
-sc.render('lens_plane-parallel.png', sigma_clip=6.0)
+sc.render(sigma_clip=6.0)
+sc.save('lens_plane-parallel.png')
 
 # Perspective lens
 cam = Camera(ds, lens_type='perspective')
@@ -50,7 +51,8 @@
 cam.set_width(ds.domain_width * 0.5)
 sc.camera = cam
 sc.add_source(vol)
-sc.render('lens_perspective.png', sigma_clip=6.0)
+sc.render(sigma_clip=6.0)
+sc.save('lens_perspective.png')
 
 # Stereo-perspective lens
 cam = Camera(ds, lens_type='stereo-perspective')
@@ -65,7 +67,8 @@
 cam.lens.disparity = ds.domain_width[0] * 1.e-3
 sc.camera = cam
 sc.add_source(vol)
-sc.render('lens_stereo-perspective.png', sigma_clip=6.0)
+sc.render(sigma_clip=6.0)
+sc.save('lens_stereo-perspective.png')
 
 # Fisheye lens
 dd = ds.sphere(ds.domain_center, ds.domain_width[0] / 10)
@@ -79,7 +82,8 @@
 cam.lens.fov = 360.0
 sc.camera = cam
 sc.add_source(vol)
-sc.render('lens_fisheye.png', sigma_clip=6.0)
+sc.render(sigma_clip=6.0)
+sc.save('lens_fisheye.png')
 
 # Spherical lens
 cam = Camera(ds, lens_type='spherical')
@@ -96,7 +100,8 @@
 cam.set_width(ds.domain_width * 0.5)
 sc.camera = cam
 sc.add_source(vol)
-sc.render('lens_spherical.png', sigma_clip=6.0)
+sc.render(sigma_clip=6.0)
+sc.save('lens_spherical.png')
 
 # Stereo-spherical lens
 cam = Camera(ds, lens_type='stereo-spherical')
@@ -111,4 +116,5 @@
 cam.lens.disparity = ds.domain_width[0] * 1.e-3
 sc.camera = cam
 sc.add_source(vol)
-sc.render('lens_stereo-spherical.png', sigma_clip=6.0)
+sc.render(sigma_clip=6.0)
+sc.save('lens_stereo-spherical.png')

diff -r d0f52cf90877f87528854d9e30dd71dc570050f2 -r 6facab7ff3258b232346caaecd999be9f25ef139 doc/source/visualizing/volume_rendering.rst
--- a/doc/source/visualizing/volume_rendering.rst
+++ b/doc/source/visualizing/volume_rendering.rst
@@ -31,11 +31,11 @@
    :align: center
    :alt: Diagram of a 3D Scene
 
-In versions of yt prior to 3.2, the only volume rendering interface accessible
+In versions of yt prior to 3.3, the only volume rendering interface accessible
 was through the "camera" object.  This presented a number of problems,
 principle of which was the inability to describe new scene elements or to
 develop complex visualizations that were independent of the specific elements
-being rendered.  The new "scene" based interface present in yt 3.2 and beyond
+being rendered.  The new "scene" based interface present in yt 3.3 and beyond
 enables both more complex visualizations to be constructed as well as a new,
 more intuitive interface for very simple 3D visualizations.
 
@@ -65,14 +65,15 @@
   # load the data
   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
   # volume render the 'density' field, and save the resulting image
-  im, sc = yt.volume_render(ds, 'density', fname='test_rendering.png')
+  im, sc = yt.volume_render(ds, 'density', fname='rendering.png')
 
-  # im is the image that was generated.
+  # im is the image array generated. it is also saved to 'rendering.png'.
   # sc is an instance of a Scene object, which allows you to further refine
-  # your renderings.
+  # your renderings, and later save them.
 
-When the :func:`~yt.visualization.volume_rendering.volume_render` function 
-is called, first an empty 
+When the 
+:func:`~yt.visualization.volume_rendering.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
@@ -96,9 +97,10 @@
 lenses can be swapped in and out.  For example, this might include a fisheye
 lens, a spherical lens, or some other method of describing the direction and
 origin of rays for rendering. Once the camera is added to the scene object, we
-call the main method of the
+call the main methods of the
 :class:`~yt.visualization.volume_rendering.scene.Scene` class,
-:meth:`~yt.visualization.volume_rendering.scene.Scene.render`.  When called,
+:meth:`~yt.visualization.volume_rendering.scene.Scene.render` and 
+:meth:`~yt.visualization.volume_rendering.scene.Scene.save`.  When called,
 the scene will loop through all of the
 :class:`~yt.visualization.volume_rendering.render_source.RenderSource` objects
 that have been added and integrate the radiative transfer equation through the
@@ -110,20 +112,17 @@
 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:
+:func:`~yt.visualization.volume_rendering.volume_rendering.create_scene` function in lieu of the
+:func:`~yt.visualization.volume_rendering.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
--------------------
+Modifying and Saving the Scene
+------------------------------
 
 Once a basic scene has been created with default render sources and
 camera operations, deeper modifications are possible. These
@@ -133,6 +132,56 @@
 present in the scene.  Below, we describe a few of the aspects of tuning a
 scene to create a visualization that is communicative and pleasing.
 
+.. _rendering_scene:
+
+Rendering and Saving
+++++++++++++++++++++
+
+Whenever you want a rendering of your current scene configuration, use the
+:meth:`~yt.visualization.volume_rendering.scene.Scene.render` method to
+trigger the scene to actually do the ray-tracing step.  After that, you can
+use the :meth:`~yt.visualization.volume_rendering.scene.Scene.save` method
+to save it to disk.  Alternatively, 
+:meth:`~yt.visualization.volume_rendering.scene.Scene.render` will return an 
+:class:`~yt.data_objects.image_array.ImageArray` object if you want to further 
+process it in Python (potentially writing it out with 
+:meth:`~yt.data_objects.image_array.ImageArray.write_png`).  You can continue 
+modifying your :class:`~yt.visualization.volume_rendering.scene.Scene` object,
+and render it as you make changes to see how those changes affect the resulting
+image.  
+
+.. python-script::
+
+  import yt
+  ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+  sc = yt.create_scene(ds, 'density')
+  sc.render() 
+  sc.save()
+  <make changes to scene>
+  sc.render()
+  sc.save('changes.png')
+
+.. _sigma_clip:
+
+Improving Image Contrast with Sigma Clipping
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If your images appear to be too dark, you can try using the ``sigma_clip``
+keyword in the :meth:`~yt.visualization.volume_rendering.scene.Scene.render` 
+or :func:`~yt.visualization.volume_rendering.volume_rendering.volume_render` functions.  
+Because the brightness range in an image is scaled to match the range of 
+emissivity values of underlying rendering, if you have a few really 
+high-emissivity points, they will scale the rest of your image to be quite 
+dark.  ``sigma_clip = N`` can address this by removing values that are more
+than ``N`` standard deviations brighter than the mean of your image.  
+Typically, a choice of 4 to 6 will help dramatically with your resulting image.
+
+.. python-script::
+
+  sc = yt.create_scene(ds, 'density')
+  sc.render(sigma_clip=4)
+  sc.save()
+
 .. _transfer_functions:
 
 Transfer Functions
@@ -329,7 +378,8 @@
 .. python-script::
 
    for i in sc.camera.zoomin(100, 5):
-       sc.render("frame_%03i.png" % i)
+       sc.render()
+       sc.save("frame_%03i.png" % i)
 
 The variable ``i`` is the frame number in the particular loop being called.  In
 this case, this will zoom in by a factor of 100 over the course of 5 frames.

diff -r d0f52cf90877f87528854d9e30dd71dc570050f2 -r 6facab7ff3258b232346caaecd999be9f25ef139 yt/visualization/volume_rendering/camera.py
--- a/yt/visualization/volume_rendering/camera.py
+++ b/yt/visualization/volume_rendering/camera.py
@@ -447,7 +447,8 @@
         --------
 
         >>> for i in cam.iter_rotate(np.pi, 10):
-        ...     im = sc.render("rotation_%04i.png" % i)
+        ...     im = sc.render()
+        ...     sc.save('rotation_%04i.png' % i)
         """
 
         dtheta = (1.0*theta)/n_steps
@@ -475,7 +476,8 @@
         --------
 
         >>> for i in cam.iter_move([0.2,0.3,0.6], 10):
-        ...     sc.render("move_%04i.png" % i)
+        ...     sc.render()
+        ...     sc.save("move_%04i.png" % i)
         """
         assert isinstance(final, YTArray)
         if exponential:
@@ -523,7 +525,8 @@
         --------
 
         >>> for i in cam.iter_zoom(100.0, 10):
-        ...     sc.render("zoom_%04i.png" % i)
+        ...     sc.render()
+        ...     sc.save("zoom_%04i.png" % i)
         """
         f = final**(1.0/n_steps)
         for i in xrange(n_steps):

diff -r d0f52cf90877f87528854d9e30dd71dc570050f2 -r 6facab7ff3258b232346caaecd999be9f25ef139 yt/visualization/volume_rendering/render_source.py
--- a/yt/visualization/volume_rendering/render_source.py
+++ b/yt/visualization/volume_rendering/render_source.py
@@ -70,7 +70,6 @@
     def set_zbuffer(self, zbuffer):
         self.zbuffer = zbuffer
 
-
 class VolumeSource(RenderSource):
     """A class for rendering data from a volumetric data source
 
@@ -94,8 +93,8 @@
     Examples
     --------
     >>> source = VolumeSource(ds.all_data(), 'density')
+    """
 
-    """
     _image = None
     data_source = None
 
@@ -124,7 +123,9 @@
 
     def build_defaults(self):
         """Sets a default volume and transfer function"""
+        mylog.info("Creating default volume")
         self.build_default_volume()
+        mylog.info("Creating default transfer function")
         self.build_default_transfer_function()
 
     def set_transfer_function(self, transfer_function):
@@ -265,12 +266,11 @@
             Whether or not this is being called from a higher level in the VR
             interface. Used to set the correct orientation.
         """
-        image = self.volume.reduce_tree_images(image,
-                                               camera.lens.viewpoint)
+        image = self.volume.reduce_tree_images(image, camera.lens.viewpoint)
         image.shape = camera.resolution[0], camera.resolution[1], 4
         # If the call is from VR, the image is rotated by 180 to get correct
-        # up dirirection
-        if call_from_VR is True:
+        # up direction
+        if call_from_VR is True: 
             image = np.rot90(image, k=2)
         if self.transfer_function.grey_opacity is False:
             image[:, :, 3] = 1.0
@@ -365,6 +365,7 @@
         the rendered image.
 
         """
+ 
         self.sampler = new_mesh_sampler(camera, self)
 
         mylog.debug("Casting rays")
@@ -404,6 +405,7 @@
 
     """
 
+
     _image = None
     data_source = None
 
@@ -455,7 +457,7 @@
         return zbuffer
 
     def __repr__(self):
-        disp = "<Points Source>"
+        disp = "<Point Source>"
         return disp
 
 
@@ -553,7 +555,6 @@
 
 class BoxSource(LineSource):
     r"""A render source for a box drawn with line segments.
-
     This render source will draw a box, with transparent faces, in data
     space coordinates.  This is useful for annotations.
 
@@ -677,8 +678,8 @@
     Examples
     --------
     >>> source = CoordinateVectorSource()
+    """
 
-    """
     def __init__(self, colors=None, alpha=1.0):
         super(CoordinateVectorSource, self).__init__()
         # If colors aren't individually set, make black with full opacity

diff -r d0f52cf90877f87528854d9e30dd71dc570050f2 -r 6facab7ff3258b232346caaecd999be9f25ef139 yt/visualization/volume_rendering/scene.py
--- a/yt/visualization/volume_rendering/scene.py
+++ b/yt/visualization/volume_rendering/scene.py
@@ -14,11 +14,11 @@
 
 import numpy as np
 from collections import OrderedDict
-from yt.funcs import mylog
+from yt.funcs import mylog, get_image_suffix
 from yt.extern.six import iteritems, itervalues
 from .camera import Camera
 from .render_source import OpaqueSource, BoxSource, CoordinateVectorSource, \
-    GridSource
+    GridSource, RenderSource
 from .zbuffer_array import ZBuffer
 
 
@@ -53,6 +53,8 @@
         super(Scene, self).__init__()
         self.sources = OrderedDict()
         self.camera = None
+        # An image array containing the last rendered image of the scene
+        self.last_render = None
 
     def get_source(self, source_num):
         """Returns the volume rendering source indexed by ``source_num``"""
@@ -98,22 +100,20 @@
 
         return self
 
-    def render(self, fname=None, sigma_clip=None, camera=None):
+    def render(self, sigma_clip=None, camera=None):
         r"""Render all sources in the Scene.
 
         Use the current state of the Scene object to render all sources
-        currently in the scene.
+        currently in the scene.  Returns the image array.  If you want to
+        save the output to a file, call the save() function.
 
         Parameters
         ----------
-        fname: string, optional
-            If specified, save the rendering as a bitmap to the file "fname".
-            Default: None
         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:`yt.visualization.volume_rendering.camera.Camera`, optional
+        camera: :class:`Camera`, optional
             If specified, use a different :class:`Camera` to render the scene.
 
         Returns
@@ -125,20 +125,80 @@
         --------
         >>> sc = Scene()
         >>> # Add sources/camera/etc
-        >>> im = sc.render('rendering.png')
+        >>> im = sc.render(sigma_clip=4)
+        >>> sc.save()
 
         """
+        mylog.info("Rendering scene (Can take a while).")
         if camera is None:
             camera = self.camera
         assert(camera is not None)
         self._validate()
         bmp = self.composite(camera=camera)
-        if fname is not None:
-            bmp.write_png(fname, sigma_clip=sigma_clip)
+        self.last_render = bmp
         return bmp
 
+    def save(self, fname=None):
+        r"""Saves the most recently rendered image of the Scene to disk.
+
+        Once you have created a scene and rendered that scene to an image 
+        array, this saves that image array to disk with an optional filename.
+        If an image has not yet been rendered for the current scene object,
+        it forces one and writes it out.
+
+        Parameters
+        ----------
+        fname: string, optional
+            If specified, save the rendering as a bitmap to the file "fname".
+            If unspecified, it creates a default based on the dataset filename.
+            Default: None
+
+        Returns
+        -------
+            Nothing
+
+        Examples
+        --------
+        >>> sc = yt.create_scene(ds)
+        >>> # Add sources/camera/etc
+        >>> sc.render()
+        >>> sc.save('test.png')
+
+        # Or alternatively
+        >>> sc = yt.create_scene(ds)
+        >>> # Add sources/camera/etc
+        >>> sc.save('test.png')
+
+        """
+        if fname is None:
+            sources = list(itervalues(self.sources))
+            rensources = [s for s in sources if isinstance(s, RenderSource)]
+            # if a volume source present, use its affiliated ds for fname
+            if len(rensources) > 0:
+                rs = rensources[0]
+                basename = rs.data_source.ds.basename
+                if isinstance(rs.field, basestring):
+                    field = rs.field
+                else:
+                    field = rs.field[-1]
+                fname = "%s_Render_%s.png" % (basename, field)
+            # if no volume source present, use a default filename
+            else:
+                fname = "Render_opaque.png"   
+        suffix = get_image_suffix(fname)
+        if suffix == '':
+            suffix = '.png'
+            fname = '%s%s' % (fname, suffix)
+
+        if self.last_render is None:
+            self.render()
+
+        mylog.info("Saving render %s", fname)
+        self.last_render.write_png(fname)
+ 
     def _validate(self):
         r"""Validate the current state of the scene."""
+
         for k, source in iteritems(self.sources):
             source._validate()
         return

diff -r d0f52cf90877f87528854d9e30dd71dc570050f2 -r 6facab7ff3258b232346caaecd999be9f25ef139 yt/visualization/volume_rendering/tests/modify_transfer_function.py
--- a/yt/visualization/volume_rendering/tests/modify_transfer_function.py
+++ b/yt/visualization/volume_rendering/tests/modify_transfer_function.py
@@ -22,5 +22,5 @@
 tf.clear()
 tf.grey_opacity=True
 tf.add_layers(3, colormap='RdBu')
-sc.render("new_tf.png")
-
+sc.render()
+sc.save("new_tf.png")

diff -r d0f52cf90877f87528854d9e30dd71dc570050f2 -r 6facab7ff3258b232346caaecd999be9f25ef139 yt/visualization/volume_rendering/tests/multiple_fields.py
--- a/yt/visualization/volume_rendering/tests/multiple_fields.py
+++ b/yt/visualization/volume_rendering/tests/multiple_fields.py
@@ -20,5 +20,6 @@
 volume_source = sc.get_source(0)
 volume_source.set_field(('gas','velocity_x'))
 volume_source.build_default_transfer_function()
-sc.render("render_x.png")
+sc.render()
+sc.save("render_x.png")
 

diff -r d0f52cf90877f87528854d9e30dd71dc570050f2 -r 6facab7ff3258b232346caaecd999be9f25ef139 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,5 @@
 frames = 10
 for i in range(frames):
     sc.camera.yaw(angle/frames)
-    sc.render('test_rot_%04i.png' % i, sigma_clip=6.0)
+    sc.render(sigma_clip=6.0)
+    sc.save('test_rot_%04i.png' % i)

diff -r d0f52cf90877f87528854d9e30dd71dc570050f2 -r 6facab7ff3258b232346caaecd999be9f25ef139 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
@@ -55,7 +55,8 @@
         tf.grey_opacity = True
         sc.camera = cam
         sc.add_source(vol)
-        sc.render('test_perspective_%s.png' % self.field[1], sigma_clip=6.0)
+        sc.render(sigma_clip=6.0)
+        sc.save('test_perspective_%s.png' % self.field[1])
 
     def test_stereoperspective_lens(self):
         sc = Scene()
@@ -67,8 +68,8 @@
         tf.grey_opacity = True
         sc.camera = cam
         sc.add_source(vol)
-        sc.render('test_stereoperspective_%s.png' % self.field[1],
-                  sigma_clip=6.0)
+        sc.render(sigma_clip=6.0)
+        sc.save('test_stereoperspective_%s.png' % self.field[1])
 
     def test_fisheye_lens(self):
         dd = self.ds.sphere(self.ds.domain_center,
@@ -85,8 +86,8 @@
         tf.grey_opacity = True
         sc.camera = cam
         sc.add_source(vol)
-        sc.render('test_fisheye_%s.png' % self.field[1],
-                  sigma_clip=6.0)
+        sc.render(sigma_clip=6.0)
+        sc.save('test_fisheye_%s.png' % self.field[1])
 
     def test_plane_lens(self):
         dd = self.ds.sphere(self.ds.domain_center,
@@ -101,8 +102,8 @@
         tf.grey_opacity = True
         sc.camera = cam
         sc.add_source(vol)
-        sc.render('test_plane_%s.png' % self.field[1],
-                  sigma_clip=6.0)
+        sc.render(sigma_clip=6.0)
+        sc.save('test_plane_%s.png' % self.field[1])
 
     def test_spherical_lens(self):
         sc = Scene()
@@ -114,8 +115,8 @@
         tf.grey_opacity = True
         sc.camera = cam
         sc.add_source(vol)
-        sc.render('test_spherical_%s.png' % self.field[1],
-                  sigma_clip=6.0)
+        sc.render(sigma_clip=6.0)
+        sc.save('test_spherical_%s.png' % self.field[1])
 
     def test_stereospherical_lens(self):
         w = (self.ds.domain_width).in_units('code_length')
@@ -129,5 +130,5 @@
         tf.grey_opacity = True
         sc.camera = cam
         sc.add_source(vol)
-        sc.render('test_stereospherical_%s.png' % self.field[1],
-                  sigma_clip=6.0)
+        sc.render(sigma_clip=6.0)
+        sc.save('test_stereospherical_%s.png' % self.field[1])

diff -r d0f52cf90877f87528854d9e30dd71dc570050f2 -r 6facab7ff3258b232346caaecd999be9f25ef139 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
@@ -76,9 +76,11 @@
         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', sigma_clip=6.0)
+        sc.render(sigma_clip=6.0)
+        sc.save('test_scene.png')
 
         nrot = 2 
         for i in range(nrot):
             sc.camera.pitch(2*np.pi/nrot)
-            sc.render('test_rot_%04i.png' % i, sigma_clip=6.0)
+            sc.render(sigma_clip=6.0)
+            sc.save('test_rot_%04i.png' % i)

diff -r d0f52cf90877f87528854d9e30dd71dc570050f2 -r 6facab7ff3258b232346caaecd999be9f25ef139 yt/visualization/volume_rendering/volume_rendering.py
--- a/yt/visualization/volume_rendering/volume_rendering.py
+++ b/yt/visualization/volume_rendering/volume_rendering.py
@@ -113,5 +113,6 @@
     >>> 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, sigma_clip=sigma_clip)
+    im = sc.render(sigma_clip=sigma_clip)
+    sc.save(fname=fname)
     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