[yt-svn] commit/yt: 3 new changesets
Bitbucket
commits-noreply at bitbucket.org
Mon Oct 8 15:18:40 PDT 2012
3 new commits in yt:
https://bitbucket.org/yt_analysis/yt/changeset/7d4f47ae56b5/
changeset: 7d4f47ae56b5
branch: yt
user: ngoldbaum
date: 2012-10-08 20:55:21
summary: Fixing the way we handle the case when a user passes a full filename to save(). If multiple plots have been created this will write all plots to have the same filename.
affected #: 1 file
diff -r de5451397981bca072e120ea53540e571ff56669 -r 7d4f47ae56b52feb4d1bce1d86437ca5f2a20aca yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -828,11 +828,14 @@
>>> slc.save(mpl_kwargs={'bbox_inches':'tight'})
"""
+ names = []
+ if mpl_kwargs is None: mpl_kwargs = {}
if name == None:
name = str(self.pf)
elif name.endswith('.png'):
- return v.save(name)
- if mpl_kwargs is None: mpl_kwargs = {}
+ for k, v in self.plots.iteritems():
+ names.append(v.save(name,mpl_kwargs))
+ return names
axis = axis_names[self.data_source.axis]
weight = None
if 'Slice' in self.data_source.__class__.__name__:
@@ -842,7 +845,6 @@
weight = self.data_source.weight_field
if 'Cutting' in self.data_source.__class__.__name__:
type = 'OffAxisSlice'
- names = []
for k, v in self.plots.iteritems():
if axis:
n = "%s_%s_%s_%s" % (name, type, axis, k)
https://bitbucket.org/yt_analysis/yt/changeset/bbb6d92725d8/
changeset: bbb6d92725d8
branch: yt
user: ngoldbaum
date: 2012-10-08 20:57:00
summary: Merging.
affected #: 13 files
diff -r 7d4f47ae56b52feb4d1bce1d86437ca5f2a20aca -r bbb6d92725d80fa6b8ed60725524bdaeb8539325 doc/install_script.sh
--- a/doc/install_script.sh
+++ b/doc/install_script.sh
@@ -400,7 +400,7 @@
echo '2c1933ab31246b4f4eba049d3288156e0a72f1730604e3ed7357849967cdd329e4647cf236c9442ecfb06d0aff03e6fc892a7ba2a5c1cf5c011b7ab9c619acec Cython-0.16.tar.gz' > Cython-0.16.tar.gz.sha512
echo '44eea803870a66ff0bab08d13a8b3388b5578ebc1c807d1d9dca0a93e6371e91b15d02917a00b3b20dc67abb5a21dabaf9b6e9257a561f85eeff2147ac73b478 PyX-0.11.1.tar.gz' > PyX-0.11.1.tar.gz.sha512
-echo '1a754d560bfa433f0960ab3b5a62edb5f291be98ec48cf4e5941fa5b84139e200b87a52efbbd6fa4a76d6feeff12439eed3e7a84db4421940d1bbb576f7a684e Python-2.7.2.tgz' > Python-2.7.2.tgz.sha512
+echo 'b981f8464575bb24c297631c87a3b9172312804a0fc14ce1fa7cb41ce2b0d2fd383cd1c816d6e10c36467d18bf9492d6faf557c81c04ff3b22debfa93f30ad0b Python-2.7.3.tgz' > Python-2.7.3.tgz.sha512
echo 'c017d3d59dd324ac91af0edc178c76b60a5f90fbb775cf843e39062f95bd846238f2c53705f8890ed3f34bc0e6e75671a73d13875eb0287d6201cb45f0a2d338 bzip2-1.0.5.tar.gz' > bzip2-1.0.5.tar.gz.sha512
echo 'a296dfcaef7e853e58eed4e24b37c4fa29cfc6ac688def048480f4bb384b9e37ca447faf96eec7b378fd764ba291713f03ac464581d62275e28eb2ec99110ab6 reason-js-20120623.zip' > reason-js-20120623.zip.sha512
echo 'b519218f93946400326e9b656669269ecb3e5232b944e18fbc3eadc4fe2b56244d68aae56d6f69042b4c87c58c881ee2aaa279561ea0f0f48d5842155f4de9de freetype-2.4.4.tar.gz' > freetype-2.4.4.tar.gz.sha512
@@ -429,7 +429,7 @@
[ $INST_0MQ -eq 1 ] && get_ytproject zeromq-2.2.0.tar.gz
[ $INST_0MQ -eq 1 ] && get_ytproject pyzmq-2.1.11.tar.gz
[ $INST_0MQ -eq 1 ] && get_ytproject tornado-2.2.tar.gz
-get_ytproject Python-2.7.2.tgz
+get_ytproject Python-2.7.3.tgz
get_ytproject numpy-1.6.1.tar.gz
get_ytproject matplotlib-1.1.0.tar.gz
get_ytproject mercurial-2.2.2.tar.gz
@@ -554,11 +554,11 @@
fi
fi
-if [ ! -e Python-2.7.2/done ]
+if [ ! -e Python-2.7.3/done ]
then
echo "Installing Python. This may take a while, but don't worry. YT loves you."
- [ ! -e Python-2.7.2 ] && tar xfz Python-2.7.2.tgz
- cd Python-2.7.2
+ [ ! -e Python-2.7.3 ] && tar xfz Python-2.7.3.tgz
+ cd Python-2.7.3
( ./configure --prefix=${DEST_DIR}/ 2>&1 ) 1>> ${LOG_FILE} || do_exit
( make ${MAKE_PROCS} 2>&1 ) 1>> ${LOG_FILE} || do_exit
diff -r 7d4f47ae56b52feb4d1bce1d86437ca5f2a20aca -r bbb6d92725d80fa6b8ed60725524bdaeb8539325 yt/data_objects/api.py
--- a/yt/data_objects/api.py
+++ b/yt/data_objects/api.py
@@ -65,6 +65,9 @@
quantity_info, \
add_quantity
+from image_array import \
+ ImageArray
+
from field_info_container import \
FieldInfoContainer, \
FieldInfo, \
diff -r 7d4f47ae56b52feb4d1bce1d86437ca5f2a20aca -r bbb6d92725d80fa6b8ed60725524bdaeb8539325 yt/data_objects/image_array.py
--- /dev/null
+++ b/yt/data_objects/image_array.py
@@ -0,0 +1,271 @@
+"""
+ImageArray Class
+
+Authors: Samuel Skillman <samskillman at gmail.com>
+Affiliation: University of Colorado at Boulder
+
+Homepage: http://yt-project.org/
+License:
+ Copyright (C) 2012 Samuel Skillman. All Rights Reserved.
+
+ This file is part of yt.
+
+ yt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ """
+
+import numpy as np
+import h5py as h5
+from yt.visualization.image_writer import write_bitmap, write_image
+
+class ImageArray(np.ndarray):
+ r"""A custom Numpy ndarray used for images.
+
+ This differs from ndarray in that you can optionally specify an
+ info dictionary which is used later in saving, and can be accessed with
+ ImageArray.info.
+
+ Parameters
+ ----------
+ input_array: array_like
+ A numpy ndarray, or list.
+
+ Other Parameters
+ ----------------
+ info: dictionary
+ Contains information to be stored with image.
+
+ Returns
+ -------
+ obj: ImageArray object
+
+ Raises
+ ------
+ None
+
+ See Also
+ --------
+ numpy.ndarray : Inherits
+
+ Notes
+ -----
+
+ References
+ ----------
+
+ Examples
+ --------
+ These are written in doctest format, and should illustrate how to
+ use the function. Use the variables 'pf' for the parameter file, 'pc' for
+ a plot collection, 'c' for a center, and 'L' for a vector.
+
+ >>> im = np.zeros([64,128,3])
+ >>> for i in xrange(im.shape[0]):
+ >>> for k in xrange(im.shape[2]):
+ >>> im[i,:,k] = np.linspace(0.,0.3*k, im.shape[1])
+
+ >>> myinfo = {'field':'dinosaurs', 'east_vector':np.array([1.,0.,0.]),
+ >>> 'north_vector':np.array([0.,0.,1.]), 'normal_vector':np.array([0.,1.,0.]),
+ >>> 'width':0.245, 'units':'cm', 'type':'rendering'}
+
+ >>> im_arr = ImageArray(im, info=myinfo)
+ >>> im_arr.save('test_ImageArray')
+
+ Numpy ndarray documentation appended:
+
+ """
+ def __new__(cls, input_array, info=None):
+ # Input array is an already formed ndarray instance
+ # We first cast to be our class type
+ obj = np.asarray(input_array).view(cls)
+ # add the new attribute to the created instance
+ if info is None:
+ info = {}
+ obj.info = info
+ # Finally, we must return the newly created object:
+ return obj
+
+ def __array_finalize__(self, obj):
+ # see InfoArray.__array_finalize__ for comments
+ if obj is None: return
+ self.info = getattr(obj, 'info', None)
+
+ def write_hdf5(self, filename):
+ r"""Writes ImageArray to hdf5 file.
+
+ Parameters
+ ----------
+ filename: string
+ Note filename not be modified.
+
+ Examples
+ --------
+ >>> im = np.zeros([64,128,3])
+ >>> for i in xrange(im.shape[0]):
+ >>> for k in xrange(im.shape[2]):
+ >>> im[i,:,k] = np.linspace(0.,0.3*k, im.shape[1])
+
+ >>> myinfo = {'field':'dinosaurs', 'east_vector':np.array([1.,0.,0.]),
+ >>> 'north_vector':np.array([0.,0.,1.]), 'normal_vector':np.array([0.,1.,0.]),
+ >>> 'width':0.245, 'units':'cm', 'type':'rendering'}
+
+ >>> im_arr = ImageArray(im, info=myinfo)
+ >>> im_arr.write_hdf5('test_ImageArray.h5')
+
+ """
+ array_name = self.info.get("name","image")
+
+ f = h5.File(filename)
+ if array_name in f.keys():
+ del f[array_name]
+ d = f.create_dataset(array_name, data=self)
+ for k, v in self.info.iteritems():
+ d.attrs.create(k, v)
+ f.close()
+
+ def write_png(self, filename, clip_ratio=None):
+ r"""Writes ImageArray to png file.
+
+ Parameters
+ ----------
+ filename: string
+ Note filename not be modified.
+
+ Examples
+ --------
+
+ >>> im = np.zeros([64,128,3])
+ >>> for i in xrange(im.shape[0]):
+ >>> for k in xrange(im.shape[2]):
+ >>> im[i,:,k] = np.linspace(0.,0.3*k, im.shape[1])
+
+ >>> myinfo = {'field':'dinosaurs', 'east_vector':np.array([1.,0.,0.]),
+ >>> 'north_vector':np.array([0.,0.,1.]), 'normal_vector':np.array([0.,1.,0.]),
+ >>> 'width':0.245, 'units':'cm', 'type':'rendering'}
+
+ >>> im_arr = ImageArray(im, info=myinfo)
+ >>> im_arr.write_png('test_ImageArray.png')
+
+ """
+ if filename[-4:] != '.png':
+ filename += '.png'
+
+ if clip_ratio is not None:
+ return write_bitmap(self.swapaxes(0, 1), filename,
+ clip_ratio * self.std())
+ else:
+ return write_bitmap(self.swapaxes(0, 1), filename)
+
+ def write_image(self, filename, color_bounds=None, channel=None, cmap_name="algae", func=lambda x: x):
+ r"""Writes a single channel of the ImageArray to a png file.
+
+ Parameters
+ ----------
+ filename: string
+ Note filename not be modified.
+
+ Other Parameters
+ ----------------
+ channel: int
+ Which channel to write out as an image. Defaults to 0
+ cmap_name: string
+ Name of the colormap to be used.
+ color_bounds : tuple of floats, optional
+ The min and max to scale between. Outlying values will be clipped.
+ cmap_name : string, optional
+ An acceptable colormap. See either yt.visualization.color_maps or
+ http://www.scipy.org/Cookbook/Matplotlib/Show_colormaps .
+ func : function, optional
+ A function to transform the buffer before applying a colormap.
+
+ Returns
+ -------
+ scaled_image : uint8 image that has been saved
+
+ Examples
+ --------
+
+ >>> im = np.zeros([64,128])
+ >>> for i in xrange(im.shape[0]):
+ >>> im[i,:] = np.linspace(0.,0.3*k, im.shape[1])
+
+ >>> myinfo = {'field':'dinosaurs', 'east_vector':np.array([1.,0.,0.]),
+ >>> 'north_vector':np.array([0.,0.,1.]), 'normal_vector':np.array([0.,1.,0.]),
+ >>> 'width':0.245, 'units':'cm', 'type':'rendering'}
+
+ >>> im_arr = ImageArray(im, info=myinfo)
+ >>> im_arr.write_image('test_ImageArray.png')
+
+ """
+ if filename[-4:] != '.png':
+ filename += '.png'
+
+ if channel is None:
+ return write_image(self.swapaxes(0,1), filename,
+ color_bounds=color_bounds, cmap_name=cmap_name,
+ func=func)
+ else:
+ return write_image(self.swapaxes(0,1)[:,:,channel], filename,
+ color_bounds=color_bounds, cmap_name=cmap_name,
+ func=func)
+
+ def save(self, filename, png=True, hdf5=True):
+ """
+ Saves ImageArray.
+
+ Arguments:
+ filename: string
+ This should not contain the extension type (.png, .h5, ...)
+
+ Optional Arguments:
+ png: boolean, default True
+ Save to a png
+
+ hdf5: boolean, default True
+ Save to hdf5 file, including info dictionary as attributes.
+
+ """
+ if png:
+ if len(self.shape) > 2:
+ self.write_png("%s.png" % filename)
+ else:
+ self.write_image("%s.png" % filename)
+ if hdf5:
+ self.write_hdf5("%s.h5" % filename)
+
+ __doc__ += np.ndarray.__doc__
+
+if __name__ == "__main__":
+ im = np.zeros([64,128,3])
+ for i in xrange(im.shape[0]):
+ for k in xrange(im.shape[2]):
+ im[i,:,k] = np.linspace(0.,0.3*k, im.shape[1])
+
+ myinfo = {'field':'dinosaurs', 'east_vector':np.array([1.,0.,0.]),
+ 'north_vector':np.array([0.,0.,1.]), 'normal_vector':np.array([0.,1.,0.]),
+ 'width':0.245, 'units':'cm', 'type':'rendering'}
+
+ im_arr = ImageArray(im, info=myinfo)
+ im_arr.save('test_3d_ImageArray')
+
+ im = np.zeros([64,128])
+ for i in xrange(im.shape[0]):
+ im[i,:] = np.linspace(0.,0.3*k, im.shape[1])
+
+ myinfo = {'field':'dinosaurs', 'east_vector':np.array([1.,0.,0.]),
+ 'north_vector':np.array([0.,0.,1.]), 'normal_vector':np.array([0.,1.,0.]),
+ 'width':0.245, 'units':'cm', 'type':'rendering'}
+
+ im_arr = ImageArray(im, info=myinfo)
+ im_arr.save('test_2d_ImageArray')
+
diff -r 7d4f47ae56b52feb4d1bce1d86437ca5f2a20aca -r bbb6d92725d80fa6b8ed60725524bdaeb8539325 yt/data_objects/universal_fields.py
--- a/yt/data_objects/universal_fields.py
+++ b/yt/data_objects/universal_fields.py
@@ -1002,17 +1002,17 @@
def _BMagnitude(field,data):
"""This assumes that your front end has provided Bx, By, Bz in
units of Gauss. If you use MKS, make sure to write your own
- MagneticEnergy field to deal with non-unitary \mu_0.
+ BMagnitude field to deal with non-unitary \mu_0.
"""
return np.sqrt((data["Bx"]**2 + data["By"]**2 + data["Bz"]**2))
add_field("BMagnitude",
function=_BMagnitude,
- display_name=r"|B|", units="\rm{Gauss}")
+ display_name=r"|B|", units=r"\rm{Gauss}")
def _PlasmaBeta(field,data):
"""This assumes that your front end has provided Bx, By, Bz in
units of Gauss. If you use MKS, make sure to write your own
- MagneticEnergy field to deal with non-unitary \mu_0.
+ PlasmaBeta field to deal with non-unitary \mu_0.
"""
return data['Pressure']/data['MagneticEnergy']
add_field("PlasmaBeta",
diff -r 7d4f47ae56b52feb4d1bce1d86437ca5f2a20aca -r bbb6d92725d80fa6b8ed60725524bdaeb8539325 yt/frontends/flash/fields.py
--- a/yt/frontends/flash/fields.py
+++ b/yt/frontends/flash/fields.py
@@ -98,7 +98,10 @@
if fn1.endswith("_Fraction"):
add_field(fn1.split("_")[0] + "_Density",
function=_get_density(fn1), take_log=True,
- display_name="%s\/Density" % fn1.split("_")[0])
+ display_name="%s\/Density" % fn1.split("_")[0],
+ units = r"\rm{g}/\rm{cm}^3",
+ projected_units = r"\rm{g}/\rm{cm}^2",
+ )
def _get_convert(fname):
def _conv(data):
@@ -107,7 +110,8 @@
add_flash_field("dens", function=NullFunc, take_log=True,
convert_function=_get_convert("dens"),
- units=r"\rm{g}/\rm{cm}^3")
+ units=r"\rm{g}/\rm{cm}^3",
+ projected_units = r"\rm{g}/\rm{cm}^2"),
add_flash_field("velx", function=NullFunc, take_log=False,
convert_function=_get_convert("velx"),
units=r"\rm{cm}/\rm{s}")
@@ -204,6 +208,7 @@
add_field(f, TranslationFunc(v),
take_log=KnownFLASHFields[v].take_log,
units = ff._units, display_name=dname,
+ projected_units = ff._projected_units,
particle_type = pfield)
def _convertParticleMassMsun(data):
diff -r 7d4f47ae56b52feb4d1bce1d86437ca5f2a20aca -r bbb6d92725d80fa6b8ed60725524bdaeb8539325 yt/mods.py
--- a/yt/mods.py
+++ b/yt/mods.py
@@ -62,7 +62,7 @@
ValidateParameter, ValidateDataField, ValidateProperty, \
ValidateSpatial, ValidateGridType, \
TimeSeriesData, AnalysisTask, analysis_task, \
- ParticleTrajectoryCollection
+ ParticleTrajectoryCollection, ImageArray
from yt.data_objects.derived_quantities import \
add_quantity, quantity_info
@@ -122,7 +122,7 @@
get_multi_plot, FixedResolutionBuffer, ObliqueFixedResolutionBuffer, \
callback_registry, write_bitmap, write_image, annotate_image, \
apply_colormap, scale_image, write_projection, write_fits, \
- SlicePlot, OffAxisSlicePlot, ProjectionPlot
+ SlicePlot, OffAxisSlicePlot, ProjectionPlot, OffAxisProjectionPlot
from yt.visualization.volume_rendering.api import \
ColorTransferFunction, PlanckTransferFunction, ProjectionTransferFunction, \
diff -r 7d4f47ae56b52feb4d1bce1d86437ca5f2a20aca -r bbb6d92725d80fa6b8ed60725524bdaeb8539325 yt/utilities/lib/grid_traversal.pyx
--- a/yt/utilities/lib/grid_traversal.pyx
+++ b/yt/utilities/lib/grid_traversal.pyx
@@ -590,7 +590,7 @@
cdef np.float64_t *pointer = <np.float64_t *> star_colors.data
for i in range(pos_x.shape[0]):
kdtree_utils.kd_insert3(self.tree,
- pos_x[i], pos_y[i], pos_z[i], pointer + i*3)
+ pos_x[i], pos_y[i], pos_z[i], <void *> (pointer + i*3))
def __dealloc__(self):
kdtree_utils.kd_free(self.tree)
@@ -616,7 +616,7 @@
cdef np.float64_t slopes[6], dp[3], ds[3]
cdef np.float64_t dt = (exit_t - enter_t) / vri.n_samples
cdef np.float64_t dvs[6], cell_left[3], local_dds[3], pos[3]
- cdef int nstars
+ cdef int nstars, dti, i, j
cdef np.float64_t *colors = NULL, gexp, gaussian, px, py, pz
for i in range(3):
dp[i] = (enter_t + 0.5 * dt) * v_dir[i] + v_pos[i]
@@ -648,6 +648,7 @@
dvs[i] = temp
for dti in range(vri.n_samples):
# Now we add the contribution from stars
+ kdtree_utils.kd_res_rewind(ballq)
for i in range(nstars):
kdtree_utils.kd_res_item3(ballq, &px, &py, &pz)
colors = <np.float64_t *> kdtree_utils.kd_res_item_data(ballq)
@@ -655,20 +656,22 @@
gexp = (px - pos[0])*(px - pos[0]) \
+ (py - pos[1])*(py - pos[1]) \
+ (pz - pos[2])*(pz - pos[2])
- gaussian = vri.star_coeff * expl(-gexp/vri.star_sigma_num)
- for i in range(3): im.rgba[i] += gaussian*dt*colors[i]
+ gaussian = vri.star_coeff * exp(-gexp/vri.star_sigma_num)
+ for j in range(3): im.rgba[j] += gaussian*dt*colors[j]
for i in range(3):
pos[i] += local_dds[i]
FIT_eval_transfer(dt, dvs, im.rgba, vri.n_fits, vri.fits,
vri.field_table_ids, vri.grey_opacity)
for i in range(vc.n_fields):
dvs[i] += slopes[i]
+ kdtree_utils.kd_res_free(ballq)
cdef class VolumeRenderSampler(ImageSampler):
cdef VolumeRenderAccumulator *vra
cdef public object tf_obj
cdef public object my_field_tables
cdef kdtree_utils.kdtree **trees
+ cdef object tree_containers
def __cinit__(self,
np.ndarray vp_pos,
np.ndarray vp_dir,
@@ -709,6 +712,7 @@
self.vra.field_table_ids[i] = tf_obj.field_table_ids[i]
self.supp_data = <void *> self.vra
cdef star_kdtree_container skdc
+ self.tree_containers = star_list
if star_list is None:
self.trees = NULL
else:
@@ -719,10 +723,15 @@
self.trees[i] = skdc.tree
cdef void setup(self, PartitionedGrid pg):
+ cdef star_kdtree_container star_tree
if self.trees == NULL:
self.sampler = volume_render_sampler
else:
+ star_tree = self.tree_containers[pg.parent_grid_id]
self.vra.star_list = self.trees[pg.parent_grid_id]
+ self.vra.star_sigma_num = 2.0*star_tree.sigma**2.0
+ self.vra.star_er = 2.326 * star_tree.sigma
+ self.vra.star_coeff = star_tree.coeff
self.sampler = volume_render_stars_sampler
def __dealloc__(self):
diff -r 7d4f47ae56b52feb4d1bce1d86437ca5f2a20aca -r bbb6d92725d80fa6b8ed60725524bdaeb8539325 yt/visualization/api.py
--- a/yt/visualization/api.py
+++ b/yt/visualization/api.py
@@ -66,6 +66,7 @@
from plot_window import \
SlicePlot, \
OffAxisSlicePlot, \
- ProjectionPlot
+ ProjectionPlot, \
+ OffAxisProjectionPlot
diff -r 7d4f47ae56b52feb4d1bce1d86437ca5f2a20aca -r bbb6d92725d80fa6b8ed60725524bdaeb8539325 yt/visualization/fixed_resolution.py
--- a/yt/visualization/fixed_resolution.py
+++ b/yt/visualization/fixed_resolution.py
@@ -28,6 +28,7 @@
x_dict, \
y_dict, \
axis_names
+from .volume_rendering.api import off_axis_projection
import _MPL
import numpy as np
import weakref
@@ -384,3 +385,28 @@
self.bounds).transpose()
self[item] = buff
return buff
+
+
+class OffAxisProjectionFixedResolutionBuffer(FixedResolutionBuffer):
+ def __init__(self, data_source, bounds, buff_size, antialias = True,
+ periodic = False):
+ self.data = {}
+ FixedResolutionBuffer.__init__(self, data_source, bounds, buff_size, antialias, periodic)
+
+ def __getitem__(self, item):
+ if item in self.data: return self.data[item]
+ mylog.info("Making a fixed resolutuion buffer of (%s) %d by %d" % \
+ (item, self.buff_size[0], self.buff_size[1]))
+ ds = self.data_source
+ width = (self.bounds[1] - self.bounds[0],
+ self.bounds[3] - self.bounds[2],
+ self.bounds[5] - self.bounds[4])
+ buff = off_axis_projection(ds.pf, ds.center, ds.normal_vector,
+ width, ds.resolution, item,
+ weight=ds.weight_field, volume=ds.volume,
+ no_ghost=ds.no_ghost, interpolated=ds.interpolated,
+ north_vector=ds.north_vector)
+ self[item] = buff.swapaxes(0,1)
+ return buff
+
+
diff -r 7d4f47ae56b52feb4d1bce1d86437ca5f2a20aca -r bbb6d92725d80fa6b8ed60725524bdaeb8539325 yt/visualization/image_writer.py
--- a/yt/visualization/image_writer.py
+++ b/yt/visualization/image_writer.py
@@ -116,7 +116,7 @@
image = image.transpose().copy() # Have to make sure it's contiguous
au.write_png(image, fn)
-def write_bitmap(bitmap_array, filename, max_val = None, transpose=True):
+def write_bitmap(bitmap_array, filename, max_val = None, transpose=False):
r"""Write out a bitmapped image directly to a PNG file.
This accepts a three- or four-channel `bitmap_array`. If the image is not
diff -r 7d4f47ae56b52feb4d1bce1d86437ca5f2a20aca -r bbb6d92725d80fa6b8ed60725524bdaeb8539325 yt/visualization/plot_modifications.py
--- a/yt/visualization/plot_modifications.py
+++ b/yt/visualization/plot_modifications.py
@@ -728,9 +728,13 @@
self.plot_args = plot_args
def __call__(self, plot):
+ if len(self.pos) == 3:
+ pos = (self.pos[x_dict[plot.data.axis]],
+ self.pos[y_dict[plot.data.axis]])
+ else: pos = self.pos
from matplotlib.patches import Arrow
# Now convert the pixels to code information
- x, y = self.convert_to_plot(plot, self.pos)
+ x, y = self.convert_to_plot(plot, pos)
dx, dy = self.convert_to_plot(plot, self.code_size, False)
arrow = Arrow(x, y, dx, dy, **self.plot_args)
plot._axes.add_patch(arrow)
@@ -750,12 +754,13 @@
self.text_args = text_args
def __call__(self, plot):
-
-
+ if len(self.pos) == 3:
+ pos = (self.pos[x_dict[plot.data.axis]],
+ self.pos[y_dict[plot.data.axis]])
+ else: pos = self.pos
width,height = plot.image._A.shape
- x,y = self.convert_to_plot(plot, self.pos)
- x,y = x/width,y/height
-
+ x,y = self.convert_to_plot(plot, pos)
+
plot._axes.text(x, y, self.text, **self.text_args)
class MarkerAnnotateCallback(PlotCallback):
diff -r 7d4f47ae56b52feb4d1bce1d86437ca5f2a20aca -r bbb6d92725d80fa6b8ed60725524bdaeb8539325 yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -43,7 +43,8 @@
write_image, apply_colormap
from .fixed_resolution import \
FixedResolutionBuffer, \
- ObliqueFixedResolutionBuffer
+ ObliqueFixedResolutionBuffer, \
+ OffAxisProjectionFixedResolutionBuffer
from .plot_modifications import get_smallest_appropriate_unit, \
callback_registry
from .tick_locators import LogLocator, LinearLocator
@@ -160,7 +161,7 @@
center[y_dict[axis]]+width[1]/2]
return (bounds,center)
-def GetOffAxisBoundsAndCenter(normal, center, width, pf, unit='1'):
+def GetOffAxisBoundsAndCenter(normal, center, width, pf, unit='1',depth=None):
if width == None:
width = (pf.domain_width.min(),
pf.domain_width.min())
@@ -171,6 +172,13 @@
width = (width, width)
Wx, Wy = width
width = np.array((Wx/pf[unit], Wy/pf[unit]))
+ if depth != None:
+ if iterable(depth) and isinstance(depth[1],str):
+ d,unit = depth
+ depth = d/pf[unit]
+ elif iterable(depth):
+ raise RuntimeError("Depth must be a float or a (width,\"unit\") tuple")
+ width = np.append(width,depth)
if isinstance(center,str):
if center.lower() == 'm' or center.lower() == 'max':
v, center = pf.h.find_max("Density")
@@ -179,15 +187,19 @@
else:
raise RuntimeError('center keyword \"%s\" not recognized'%center)
- # Transforming to the cutting plane coordinate system
- center = np.array(center)
- center = (center - pf.domain_left_edge)/pf.domain_width - 0.5
- (normal,perp1,perp2) = ortho_find(normal)
- mat = np.transpose(np.column_stack((perp1,perp2,normal)))
- center = np.dot(mat,center)
+ if width.shape == (2,):
+ # Transforming to the cutting plane coordinate system
+ center = np.array(center)
+ center = (center - pf.domain_left_edge)/pf.domain_width - 0.5
+ (normal,perp1,perp2) = ortho_find(normal)
+ mat = np.transpose(np.column_stack((perp1,perp2,normal)))
+ center = np.dot(mat,center)
+ width = width
+
+ bounds = [-width[0]/2, width[0]/2, -width[1]/2, width[1]/2]
+ else:
+ bounds = [-width[0]/2, width[0]/2, -width[1]/2, width[1]/2, -width[2]/2, width[2]/2]
- bounds = [-width[0]/2, width[0]/2, -width[1]/2, width[1]/2]
-
return (bounds,center)
class PlotWindow(object):
@@ -249,20 +261,14 @@
old_fields = None
if self._frb is not None:
old_fields = self._frb.keys()
- try:
+ if hasattr(self,'zlim'):
+ bounds = self.xlim+self.ylim+self.zlim
+ else:
bounds = self.xlim+self.ylim
- if self.oblique == False:
- self._frb = FixedResolutionBuffer(self.data_source,
- bounds, self.buff_size,
- self.antialias,
- periodic=self._periodic)
- else:
- self._frb = ObliqueFixedResolutionBuffer(self.data_source,
- bounds, self.buff_size,
- self.antialias,
- periodic=self._periodic)
- except:
- raise RuntimeError("Failed to repixelize.")
+ self._frb = self._frb_generator(self.data_source,
+ bounds, self.buff_size,
+ self.antialias,
+ periodic=self._periodic)
if old_fields is None:
self._frb._get_data_source_fields()
else:
@@ -303,6 +309,7 @@
nWx, nWy = Wx/factor, Wy/factor
self.xlim = (centerx - nWx*0.5, centerx + nWx*0.5)
self.ylim = (centery - nWy*0.5, centery + nWy*0.5)
+
@invalidate_data
def pan(self, deltas):
@@ -349,12 +356,16 @@
dy = bounds[3] - bounds[2]
self.xlim = (self.center[0] - dx/2., self.center[0] + dx/2.)
self.ylim = (self.center[1] - dy/2., self.center[1] + dy/2.)
- mylog.info("xlim = %f %f" %self.xlim)
- mylog.info("ylim = %f %f" %self.ylim)
else:
- self.xlim = bounds[0:2]
- self.ylim = bounds[2:]
-
+ self.xlim = tuple(bounds[0:2])
+ self.ylim = tuple(bounds[2:4])
+ if len(bounds) == 6:
+ self.zlim = tuple(bounds[4:6])
+ mylog.info("xlim = %f %f" %self.xlim)
+ mylog.info("ylim = %f %f" %self.ylim)
+ if hasattr(self,'zlim'):
+ mylog.info("zlim = %f %f" %self.zlim)
+
@invalidate_data
def set_width(self, width, unit = '1'):
"""set the width of the plot window
@@ -400,14 +411,20 @@
width = (Wx,Wy)
width = [w / self.pf[unit] for w in width]
- centerx = (self.xlim[1] + self.xlim[0])/2
- centery = (self.ylim[1] + self.ylim[0])/2
+ centerx = (self.xlim[1] + self.xlim[0])/2.
+ centery = (self.ylim[1] + self.ylim[0])/2.
self.xlim = (centerx - width[0]/2.,
centerx + width[0]/2.)
self.ylim = (centery - width[1]/2.,
centery + width[1]/2.)
+ if hasattr(self,'zlim'):
+ centerz = (self.zlim[1] + self.zlim[0])/2.
+ mw = max(width)
+ self.zlim = (centerz - mw/2.,
+ centerz + mw/2.)
+
@invalidate_data
def set_center(self, new_center, unit = '1'):
"""Sets a new center for the plot window
@@ -838,10 +855,8 @@
return names
axis = axis_names[self.data_source.axis]
weight = None
- if 'Slice' in self.data_source.__class__.__name__:
- type = 'Slice'
- if 'Proj' in self.data_source.__class__.__name__:
- type = 'Projection'
+ type = self._plot_type
+ if type in ['Projection','OffAxisProjection']:
weight = self.data_source.weight_field
if 'Cutting' in self.data_source.__class__.__name__:
type = 'OffAxisSlice'
@@ -891,6 +906,9 @@
raise YTNotInsideNotebook
class SlicePlot(PWViewerMPL):
+ _plot_type = 'Slice'
+ _frb_generator = FixedResolutionBuffer
+
def __init__(self, pf, axis, fields, center='c', width=None, axes_unit=None,
origin='center-window'):
r"""Creates a slice plot from a parameter file
@@ -966,6 +984,9 @@
self.set_axes_unit(axes_unit)
class ProjectionPlot(PWViewerMPL):
+ _plot_type = 'Projection'
+ _frb_generator = FixedResolutionBuffer
+
def __init__(self, pf, axis, fields, center='c', width=None, axes_unit=None,
weight_field=None, max_level=None, origin='center-window'):
r"""Creates a projection plot from a parameter file
@@ -1045,6 +1066,9 @@
self.set_axes_unit(axes_unit)
class OffAxisSlicePlot(PWViewerMPL):
+ _plot_type = 'OffAxisSlice'
+ _frb_generator = ObliqueFixedResolutionBuffer
+
def __init__(self, pf, normal, fields, center='c', width=(1,'unitary'),
axes_unit=None, north_vector=None):
r"""Creates an off axis slice plot from a parameter file
@@ -1092,6 +1116,95 @@
PWViewerMPL.__init__(self,cutting,bounds,origin='center-window',periodic=False,oblique=True)
self.set_axes_unit(axes_unit)
+class OffAxisProjectionDummyDataSource(object):
+ _type_name = 'proj'
+ proj_style = 'integrate'
+ _key_fields = []
+ def __init__(self, center, pf, normal_vector, width, fields,
+ interpolated, resolution = (800,800), weight=None,
+ volume=None, no_ghost=False, le=None, re=None,
+ north_vector=None):
+ self.center = center
+ self.pf = pf
+ self.axis = 4 # always true for oblique data objects
+ self.normal_vector = normal_vector
+ self.width = width
+ self.fields = fields
+ self.interpolated = interpolated
+ self.resolution = resolution
+ self.weight_field = weight
+ self.volume = volume
+ self.no_ghost = no_ghost
+ self.le = le
+ self.re = re
+ self.north_vector = north_vector
+
+class OffAxisProjectionPlot(PWViewerMPL):
+ _plot_type = 'OffAxisProjection'
+ _frb_generator = OffAxisProjectionFixedResolutionBuffer
+
+ def __init__(self, pf, normal, fields, center='c', width=(1,'unitary'),
+ depth=(1,'unitary'), axes_unit=None, weight_field=None,
+ max_level=None, north_vector=None, volume=None, no_ghost=False,
+ le=None, re=None, interpolated=False):
+ r"""Creates an off axis projection plot from a parameter file
+
+ Given a pf object, a normal vector to project along, and
+ a field name string, this will return a PWViewrMPL object
+ containing the plot.
+
+ The plot can be updated using one of the many helper functions
+ defined in PlotWindow.
+
+ Parameters
+ ----------
+ pf : :class:`yt.data_objects.api.StaticOutput`
+ This is the parameter file object corresponding to the
+ simulation output to be plotted.
+ normal : a sequence of floats
+ The vector normal to the slicing plane.
+ fields : string
+ The name of the field(s) to be plotted.
+ center : A two or three-element vector of sequence floats, 'c', or 'center'
+ The coordinate of the center of the image. If left blanck,
+ the image centers on the location of the maximum density
+ cell. If set to 'c' or 'center', the plot is centered on
+ the middle of the domain.
+ width : A tuple or a float
+ A tuple containing the width of image and the string key of
+ the unit: (width, 'unit'). If set to a float, code units
+ are assumed
+ depth : A tuple or a float
+ A tuple containing the depth to project thourhg and the string
+ key of the unit: (width, 'unit'). If set to a float, code units
+ are assumed
+ weight_field : string
+ The name of the weighting field. Set to None for no weight.
+ max_level: int
+ The maximum level to project to.
+ axes_unit : A string
+ The name of the unit for the tick labels on the x and y axes.
+ Defaults to None, which automatically picks an appropriate unit.
+ If axes_unit is '1', 'u', or 'unitary', it will not display the
+ units, and only show the axes name.
+ north-vector : a sequence of floats
+ A vector defining the 'up' direction in the plot. This
+ option sets the orientation of the slicing plane. If not
+ set, an arbitrary grid-aligned north-vector is chosen.
+
+ """
+ (bounds,center_rot) = GetOffAxisBoundsAndCenter(normal,center,width,pf,depth=depth)
+ # Hard-coding the resolution for now
+ fields = ensure_list(fields)[:]
+ width = np.array((bounds[1] - bounds[0], bounds[3] - bounds[2], bounds[5] - bounds[4]))
+ OffAxisProj = OffAxisProjectionDummyDataSource(center_rot, pf, normal, width, fields, interpolated,
+ weight=weight_field, volume=volume, no_ghost=no_ghost,
+ le=le, re=re, north_vector=north_vector)
+ # Hard-coding the origin keyword since the other two options
+ # aren't well-defined for off-axis data objects
+ PWViewerMPL.__init__(self,OffAxisProj,bounds,origin='center-window',periodic=False,oblique=True)
+ self.set_axes_unit(axes_unit)
+
_metadata_template = """
%(pf)s<br><br>
diff -r 7d4f47ae56b52feb4d1bce1d86437ca5f2a20aca -r bbb6d92725d80fa6b8ed60725524bdaeb8539325 yt/visualization/volume_rendering/camera.py
--- a/yt/visualization/volume_rendering/camera.py
+++ b/yt/visualization/volume_rendering/camera.py
@@ -37,6 +37,7 @@
arr_ang2pix_nest, arr_fisheye_vectors
from yt.utilities.math_utils import get_rotation_matrix
from yt.utilities.orientation import Orientation
+from yt.data_objects.api import ImageArray
from yt.visualization.image_writer import write_bitmap, write_image
from yt.data_objects.data_containers import data_object_registry
from yt.utilities.parallel_tools.parallel_analysis_interface import \
@@ -301,7 +302,11 @@
np.array(self.width), self.transfer_function, self.sub_samples)
return args
+ star_trees = None
def get_sampler(self, args):
+ kwargs = {}
+ if self.star_trees is not None:
+ kwargs = {'star_list': self.star_trees}
if self.use_light:
if self.light_dir is None:
self.set_default_light_dir()
@@ -312,9 +317,10 @@
if self.light_rgba is None:
self.set_default_light_rgba()
sampler = LightSourceRenderSampler(*args, light_dir=temp_dir,
- light_rgba=self.light_rgba)
+ light_rgba=self.light_rgba, **kwargs)
else:
- sampler = self._sampler_object(*args)
+ sampler = self._sampler_object(*args, **kwargs)
+ print sampler, kwargs
return sampler
def finalize_image(self, image):
@@ -342,15 +348,21 @@
def save_image(self, fn, clip_ratio, image):
if self.comm.rank is 0 and fn is not None:
- if clip_ratio is not None:
- write_bitmap(image, fn, clip_ratio * image.std())
- else:
- write_bitmap(image, fn)
-
+ image.write_png(fn, clip_ratio=clip_ratio)
def initialize_source(self):
return self.volume.initialize_source()
+ def get_information(self):
+ info_dict = {'fields':self.fields,
+ 'type':self.__class__.__name__,
+ 'east_vector':self.orienter.unit_vectors[0],
+ 'north_vector':self.orienter.unit_vectors[1],
+ 'normal_vector':self.orienter.unit_vectors[2],
+ 'width':self.width,
+ 'dataset':self.pf.fullpath}
+ return info_dict
+
def snapshot(self, fn = None, clip_ratio = None, double_check = False,
num_threads = 0):
r"""Ray-cast the camera.
@@ -385,7 +397,9 @@
args = self.get_sampler_args(image)
sampler = self.get_sampler(args)
self.initialize_source()
- image = self._render(double_check, num_threads, image, sampler)
+ image = ImageArray(self._render(double_check, num_threads,
+ image, sampler),
+ info=self.get_information())
self.save_image(fn, clip_ratio, image)
return image
@@ -665,7 +679,7 @@
class PerspectiveCamera(Camera):
expand_factor = 1.0
def __init__(self, *args, **kwargs):
- expand_factor = kwargs.pop('expand_factor', 1.0)
+ self.expand_factor = kwargs.pop('expand_factor', 1.0)
Camera.__init__(self, *args, **kwargs)
def get_sampler_args(self, image):
@@ -704,6 +718,27 @@
self.transfer_function, self.sub_samples)
return args
+ def _render(self, double_check, num_threads, image, sampler):
+ pbar = get_pbar("Ray casting", (self.volume.brick_dimensions + 1).prod(axis=-1).sum())
+ total_cells = 0
+ if double_check:
+ for brick in self.volume.bricks:
+ for data in brick.my_data:
+ if np.any(np.isnan(data)):
+ raise RuntimeError
+
+ view_pos = self.front_center
+ for brick in self.volume.traverse(view_pos, self.front_center, image):
+ sampler(brick, num_threads=num_threads)
+ total_cells += np.prod(brick.my_data[0].shape)
+ pbar.update(total_cells)
+
+ pbar.finish()
+ image = sampler.aimage
+ self.finalize_image(image)
+ return image
+
+
def finalize_image(self, image):
image.shape = self.resolution[0], self.resolution[0], 3
@@ -796,6 +831,15 @@
return image
+ def get_information(self):
+ info_dict = {'fields':self.fields,
+ 'type':self.__class__.__name__,
+ 'center':self.center,
+ 'radius':self.radius,
+ 'dataset':self.pf.fullpath}
+ return info_dict
+
+
def snapshot(self, fn = None, clip_ratio = None, double_check = False,
num_threads = 0, clim = None, label = None):
r"""Ray-cast the camera.
@@ -823,7 +867,9 @@
args = self.get_sampler_args(image)
sampler = self.get_sampler(args)
self.volume.initialize_source()
- image = self._render(double_check, num_threads, image, sampler)
+ image = ImageArray(self._render(double_check, num_threads,
+ image, sampler),
+ info=self.get_information())
self.save_image(fn, clim, image, label = label)
return image
@@ -1259,8 +1305,9 @@
if self.image is not None:
del self.image
+ image = ImageArray(image,
+ info=self.get_information())
self.image = image
-
return image
def save_image(self, fn, clip_ratio=None):
@@ -1665,7 +1712,9 @@
self.initialize_source()
- image = self._render(double_check, num_threads, image, sampler)
+ image = ImageArray(self._render(double_check, num_threads,
+ image, sampler),
+ info=self.get_information())
self.save_image(fn, clip_ratio, image)
@@ -1676,7 +1725,8 @@
def off_axis_projection(pf, center, normal_vector, width, resolution,
field, weight = None,
- volume = None, no_ghost = False, interpolated = False):
+ volume = None, no_ghost = False, interpolated = False,
+ north_vector = None):
r"""Project through a parameter file, off-axis, and return the image plane.
This function will accept the necessary items to integrate through a volume
@@ -1735,8 +1785,9 @@
"""
projcam = ProjectionCamera(center, normal_vector, width, resolution,
- field, weight=weight, pf=pf, volume=volume,
- no_ghost=no_ghost, interpolated=interpolated)
+ field, weight=weight, pf=pf, volume=volume,
+ no_ghost=no_ghost, interpolated=interpolated,
+ north_vector=north_vector)
image = projcam.snapshot()
if weight is not None:
pf.field_info.pop("temp_weightfield")
https://bitbucket.org/yt_analysis/yt/changeset/b5b438054310/
changeset: b5b438054310
branch: yt
user: MatthewTurk
date: 2012-10-09 00:18:38
summary: Merged in ngoldbaum/yt (pull request #292)
affected #: 1 file
diff -r b9838b15dbde418c6f7a8862b1499e67a5d1e6db -r b5b438054310909ce9395a5b359a9bc0caf7326e yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -845,17 +845,21 @@
>>> slc.save(mpl_kwargs={'bbox_inches':'tight'})
"""
+ names = []
+ if mpl_kwargs is None: mpl_kwargs = {}
if name == None:
name = str(self.pf)
elif name.endswith('.png'):
- return v.save(name)
- if mpl_kwargs is None: mpl_kwargs = {}
+ for k, v in self.plots.iteritems():
+ names.append(v.save(name,mpl_kwargs))
+ return names
axis = axis_names[self.data_source.axis]
weight = None
type = self._plot_type
if type in ['Projection','OffAxisProjection']:
weight = self.data_source.weight_field
- names = []
+ if 'Cutting' in self.data_source.__class__.__name__:
+ type = 'OffAxisSlice'
for k, v in self.plots.iteritems():
if axis:
n = "%s_%s_%s_%s" % (name, type, axis, k)
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