[yt-svn] commit/yt: 6 new changesets
Bitbucket
commits-noreply at bitbucket.org
Wed Oct 24 04:45:22 PDT 2012
6 new commits in yt:
https://bitbucket.org/yt_analysis/yt/changeset/814a93ee3207/
changeset: 814a93ee3207
branch: yt
user: scopatz
date: 2012-10-23 21:33:27
summary: added ray trace stuff.
affected #: 4 files
diff -r 76ab79a5ae9af5a5b062b49907bf85fc95e6bf0c -r 814a93ee320766d02a677b07a441cbc3dcc660a5 yt/data_objects/tests/test_profiles.py
--- /dev/null
+++ b/yt/data_objects/tests/test_profiles.py
@@ -0,0 +1,74 @@
+from yt.testing import *
+from yt.data_objects.profiles import \
+ BinnedProfile1D, BinnedProfile2D, BinnedProfile3D
+
+_fields = ("Density", "Temperature", "Dinosaurs", "Tribbles")
+
+def test_profiles():
+ pf = fake_random_pf(64, nprocs = 8, fields = _fields)
+ nv = pf.domain_dimensions.prod()
+ dd = pf.h.all_data()
+ (rmi, rma), (tmi, tma), (dmi, dma) = dd.quantities["Extrema"](
+ ["Density", "Temperature", "Dinosaurs"])
+ rt, tt, dt = dd.quantities["TotalQuantity"](
+ ["Density", "Temperature", "Dinosaurs"])
+ # First we look at the
+ for nb in [8, 16, 32, 64]:
+ for lr in [True, False]:
+ # We log all the fields or don't log 'em all. No need to do them
+ # individually.
+ for lf in [True, False]:
+ # We have the min and the max, but to avoid cutting them off
+ # since we aren't doing end-collect, we cut a bit off the edges
+ for ec, e1, e2 in [(False, 0.9, 1.1), (True, 1.0, 1.0)]:
+ p1d = BinnedProfile1D(dd,
+ nb, "Density", rmi*e1, rma*e2, lf,
+ lr, end_collect=ec)
+ p1d.add_fields(["Ones", "Temperature"], weight=None)
+ yield assert_equal, p1d["Ones"].sum(), nv
+ yield assert_rel_equal, tt, p1d["Temperature"].sum(), 7
+
+ p2d = BinnedProfile2D(dd,
+ nb, "Density", rmi*e1, rma*e2, lf,
+ nb, "Temperature", tmi*e1, tma*e2, lf,
+ lr, end_collect=ec)
+ p2d.add_fields(["Ones", "Temperature"], weight=None)
+ yield assert_equal, p2d["Ones"].sum(), nv
+ yield assert_rel_equal, tt, p2d["Temperature"].sum(), 7
+
+ p3d = BinnedProfile3D(dd,
+ nb, "Density", rmi*e1, rma*e2, lf,
+ nb, "Temperature", tmi*e1, tma*e2, lf,
+ nb, "Dinosaurs", dmi*e1, dma*e2, lf,
+ lr, end_collect=ec)
+ p3d.add_fields(["Ones", "Temperature"], weight=None)
+ yield assert_equal, p3d["Ones"].sum(), nv
+ yield assert_rel_equal, tt, p3d["Temperature"].sum(), 7
+
+ p1d = BinnedProfile1D(dd, nb, "x", 0.0, 1.0, log_space=False)
+ p1d.add_fields("Ones", weight=None)
+ av = nv / nb
+ yield assert_equal, p1d["Ones"][:-1], np.ones(nb)*av
+ # We re-bin ones with a weight now
+ p1d.add_fields(["Ones"], weight="Temperature")
+ yield assert_equal, p1d["Ones"][:-1], np.ones(nb)
+
+ p2d = BinnedProfile2D(dd, nb, "x", 0.0, 1.0, False,
+ nb, "y", 0.0, 1.0, False)
+ p2d.add_fields("Ones", weight=None)
+ av = nv / nb**2
+ yield assert_equal, p2d["Ones"][:-1,:-1], np.ones((nb, nb))*av
+ # We re-bin ones with a weight now
+ p2d.add_fields(["Ones"], weight="Temperature")
+ yield assert_equal, p2d["Ones"][:-1,:-1], np.ones((nb, nb))
+
+ p3d = BinnedProfile3D(dd, nb, "x", 0.0, 1.0, False,
+ nb, "y", 0.0, 1.0, False,
+ nb, "z", 0.0, 1.0, False)
+ p3d.add_fields("Ones", weight=None)
+ av = nv / nb**3
+ yield assert_equal, p3d["Ones"][:-1,:-1,:-1], np.ones((nb, nb, nb))*av
+ # We re-bin ones with a weight now
+ p3d.add_fields(["Ones"], weight="Temperature")
+ yield assert_equal, p3d["Ones"][:-1,:-1,:-1], np.ones((nb,nb,nb))
+
diff -r 76ab79a5ae9af5a5b062b49907bf85fc95e6bf0c -r 814a93ee320766d02a677b07a441cbc3dcc660a5 yt/data_objects/tests/test_projection.py
--- /dev/null
+++ b/yt/data_objects/tests/test_projection.py
@@ -0,0 +1,35 @@
+from yt.testing import *
+from yt.data_objects.profiles import \
+ BinnedProfile1D, BinnedProfile2D, BinnedProfile3D
+
+def test_projection():
+ for nprocs in [8, 1]:
+ # We want to test both 1 proc and 8 procs, to make sure that
+ # parallelism isn't broken
+ pf = fake_random_pf(64, nprocs = 1)
+ dims = pf.domain_dimensions
+ xn, yn, zn = pf.domain_dimensions
+ xi, yi, zi = pf.domain_left_edge + 1.0/(pf.domain_dimensions * 2)
+ xf, yf, zf = pf.domain_right_edge - 1.0/(pf.domain_dimensions * 2)
+ dd = pf.h.all_data()
+ rho_tot = dd.quantities["TotalQuantity"]("Density")[0]
+ coords = np.mgrid[xi:xf:xn*1j, yi:yf:yn*1j, zi:zf:zn*1j]
+ uc = [np.unique(c) for c in coords]
+ # Some simple projection tests with single grids
+ for ax, an in enumerate("xyz"):
+ xax = x_dict[ax]
+ yax = y_dict[ax]
+ for wf in ["Density", None]:
+ proj = pf.h.proj(ax, ["Ones", "Density"], weight_field = wf)
+ yield assert_equal, proj["Ones"].sum(), proj["Ones"].size
+ yield assert_equal, proj["Ones"].min(), 1.0
+ yield assert_equal, proj["Ones"].max(), 1.0
+ yield assert_equal, np.unique(proj["px"]), uc[xax]
+ yield assert_equal, np.unique(proj["py"]), uc[yax]
+ yield assert_equal, np.unique(proj["pdx"]), 1.0/(dims[xax]*2.0)
+ yield assert_equal, np.unique(proj["pdy"]), 1.0/(dims[yax]*2.0)
+ # wf == None
+ yield assert_equal, wf, None
+ v1 = proj["Density"].sum()
+ v2 = (dd["Density"] * dd["d%s" % an]).sum()
+ yield assert_rel_equal, v1, v2, 10
diff -r 76ab79a5ae9af5a5b062b49907bf85fc95e6bf0c -r 814a93ee320766d02a677b07a441cbc3dcc660a5 yt/testing.py
--- a/yt/testing.py
+++ b/yt/testing.py
@@ -24,7 +24,10 @@
import numpy as np
from yt.funcs import *
-from numpy.testing import assert_array_equal
+from numpy.testing import assert_array_equal, assert_equal, assert_almost_equal
+
+def assert_rel_equal(a1, a2, decimels):
+ return assert_almost_equal(a1/a2, 1.0, decimels)
def amrspace(extent, levels=7, cells=8):
"""Creates two numpy arrays representing the left and right bounds of
@@ -127,7 +130,8 @@
return left, right, level
-def fake_random_pf(ndims, peak_value = 1.0, fields = ("Density",), negative = False):
+def fake_random_pf(ndims, peak_value = 1.0, fields = ("Density",),
+ negative = False, nprocs = 1):
from yt.frontends.stream.api import load_uniform_grid
if not iterable(ndims):
ndims = [ndims, ndims, ndims]
@@ -139,5 +143,5 @@
offset = 0.0
data = dict((field, (np.random.random(ndims) - offset) * peak_value)
for field in fields)
- ug = load_uniform_grid(data, ndims, 1.0)
+ ug = load_uniform_grid(data, ndims, 1.0, nprocs = nprocs)
return ug
diff -r 76ab79a5ae9af5a5b062b49907bf85fc95e6bf0c -r 814a93ee320766d02a677b07a441cbc3dcc660a5 yt/visualization/plot_modifications.py
--- a/yt/visualization/plot_modifications.py
+++ b/yt/visualization/plot_modifications.py
@@ -7,6 +7,8 @@
Affiliation: UC Berkeley
Author: Stephen Skory <s at skory.us>
Affiliation: UC San Diego
+Author: Anthony Scopatz <scopatz at gmail.com>
+Affiliation: The University of Chicago
Homepage: http://yt-project.org/
License:
Copyright (C) 2008-2011 Matthew Turk, JS Oishi, Stephen Skory. All Rights Reserved.
@@ -1124,3 +1126,152 @@
def __call__(self,plot):
plot._axes.set_title(self.title)
+class FlashRayDataCallback(PlotCallback):
+ _type_name = "flash_ray_data"
+ def __init__(self, cmap_name='bone', sample=None):
+ """
+ annotate_flash_ray_data(cmap_name='bone', sample=None)
+
+ Adds ray trace data to the plot. *cmap_name* is the name of the color map
+ ('bone', 'jet', 'hot', etc). *sample* dictates the amount of down sampling
+ to do to prevent all of the rays from being plotted. This may be None
+ (plot all rays, default), an integer (step size), or a slice object.
+ """
+ self.cmap_name = cmap_name
+ self.sample = sample if isinstance(sample, slice) else slice(None, None, sample)
+
+ def __call__(self, plot):
+ ray_data = plot.data.pf._handle["RayData"][:]
+ idx = ray_data[:,0].argsort(kind="mergesort")
+ ray_data = ray_data[idx]
+
+ tags = ray_data[:,0]
+ coords = ray_data[:,1:3]
+ power = ray_data[:,4]
+ power /= power.max()
+ cx, cy = self.convert_to_plot(plot, coords.T)
+ coords[:,0], coords[:,1] = cx, cy
+ splitidx = np.argwhere(0 < (tags[1:] - tags[:-1])) + 1
+ coords = np.split(coords, splitidx.flat)[self.sample]
+ power = np.split(power, splitidx.flat)[self.sample]
+ cmap = matplotlib.cm.get_cmap(self.cmap_name)
+
+ plot._axes.hold(True)
+ colors = [cmap(p.max()) for p in power]
+ lc = matplotlib.collections.LineCollection(coords, colors=colors)
+ plot._axes.add_collection(lc)
+ plot._axes.hold(False)
+
+
+class TimestampCallback(PlotCallback):
+ _type_name = "timestamp"
+ _time_conv = {
+ 'as': 1e-18,
+ 'attosec': 1e-18,
+ 'attosecond': 1e-18,
+ 'attoseconds': 1e-18,
+ 'fs': 1e-15,
+ 'femtosec': 1e-15,
+ 'femtosecond': 1e-15,
+ 'femtoseconds': 1e-15,
+ 'ps': 1e-12,
+ 'picosec': 1e-12,
+ 'picosecond': 1e-12,
+ 'picoseconds': 1e-12,
+ 'ns': 1e-9,
+ 'nanosec': 1e-9,
+ 'nanosecond':1e-9,
+ 'nanoseconds' : 1e-9,
+ 'us': 1e-6,
+ 'microsec': 1e-6,
+ 'microsecond': 1e-6,
+ 'microseconds': 1e-6,
+ 'ms': 1e-3,
+ 'millisec': 1e-3,
+ 'millisecond': 1e-3,
+ 'milliseconds': 1e-3,
+ 's': 1.0,
+ 'sec': 1.0,
+ 'second':1.0,
+ 'seconds': 1.0,
+ 'm': 60.0,
+ 'min': 60.0,
+ 'minute': 60.0,
+ 'minutes': 60.0,
+ 'h': 3600.0,
+ 'hour': 3600.0,
+ 'hours': 3600.0,
+ 'd': 86400.0,
+ 'day': 86400.0,
+ 'days': 86400.0,
+ 'y': 86400.0*365.25,
+ 'year': 86400.0*365.25,
+ 'years': 86400.0*365.25,
+ 'ev': 1e-9 * 7.6e-8 / 6.03,
+ 'kev': 1e-12 * 7.6e-8 / 6.03,
+ 'mev': 1e-15 * 7.6e-8 / 6.03,
+ }
+
+ def __init__(self, x, y, units=None, format="{time:.3G} {units}", **kwargs):
+ """
+ annotate_timestamp(x, y, units=None, format="{time:.3G} {units}", **kwargs)
+
+ Adds the current time to the plot at point given by *x* and *y*. If *units*
+ is given ('s', 'ms', 'ns', etc), it will covert the time to this basis. If
+ *units* is None, it will attempt to figure out the correct value by which to
+ scale. The *format* keyword is a template string that will be evaluated and
+ displayed on the plot. All other *kwargs* will be passed to the text()
+ method on the plot axes. See matplotlib's text() functions for more
+ information.
+ """
+ self.x = x
+ self.y = y
+ self.format = format
+ self.units = units
+ self.kwargs = {'color': 'w'}
+ self.kwargs.update(kwargs)
+
+ def __call__(self, plot):
+ if self.units is None:
+ t = plot.data.pf.current_time
+ scale_keys = ['as', 'fs', 'ps', 'ns', 'us', 'ms', 's']
+ self.units = 's'
+ for k in scale_keys:
+ if t < self._time_conv[k]:
+ break
+ self.units = k
+ t = plot.data.pf.current_time / self._time_conv[self.units.lower()]
+ if self.units == 'us':
+ self.units = '$\\mu s$'
+ s = self.format.format(time=t, units=self.units)
+ plot._axes.hold(True)
+ plot._axes.text(self.x, self.y, s, **self.kwargs)
+ plot._axes.hold(False)
+
+
+class MaterialBoundaryCallback(ContourCallback):
+ _type_name = "material_boundary"
+ def __init__(self, field='targ', ncont=1, factor=4, clim=(0.9, 1.0), **kwargs):
+ """
+ annotate_material_boundary(self, field='targ', ncont=1, factor=4,
+ clim=(0.9, 1.0), **kwargs):
+
+ Add the limiting contours of *field* to the plot. Nominally, *field* is
+ the target material but may be any other field present in the hierarchy.
+ The number of contours generated is given by *ncount*, *factor* governs
+ the number of points used in the interpolation, and *clim* gives the
+ (upper, lower) limits for contouring. For this to truly be the boundary
+ *clim* should be close to the edge. For example the default is (0.9, 1.0)
+ for 'targ' which is defined on the range [0.0, 1.0]. All other *kwargs*
+ will be passed to the contour() method on the plot axes. See matplotlib
+ for more information.
+ """
+ plot_args = {'colors': 'w'}
+ plot_args.update(kwargs)
+ super(MaterialBoundaryCallback, self).__init__(field=field, ncont=ncont,
+ factor=factor, clim=clim,
+ plot_args=plot_args)
+
+ def __call__(self, plot):
+ super(MaterialBoundaryCallback, self).__call__(plot)
+
https://bitbucket.org/yt_analysis/yt/changeset/df3c48e34cc9/
changeset: df3c48e34cc9
branch: yt
user: scopatz
date: 2012-10-23 21:35:34
summary: merge commit
affected #: 36 files
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 MANIFEST.in
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,3 +1,3 @@
-include distribute_setup.py
+include distribute_setup.py README* CREDITS FUNDING LICENSE.txt
recursive-include yt/gui/reason/html *.html *.png *.ico *.js
-recursive-include yt *.pyx *.pxd *.hh *.h README*
+recursive-include yt *.pyx *.pxd *.hh *.h README*
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 nose.cfg
--- /dev/null
+++ b/nose.cfg
@@ -0,0 +1,4 @@
+[nosetests]
+detailed-errors=1
+where=yt
+exclude=answer_testing
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 setup.cfg
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,3 +1,9 @@
[egg_info]
#tag_build = .dev
#tag_svn_revision = 1
+
+[nosetests]
+detailed-errors=1
+where=yt
+exclude=answer_testing
+with-xunit=1
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/analysis_modules/halo_finding/parallel_hop/parallel_hop_interface.py
--- a/yt/analysis_modules/halo_finding/parallel_hop/parallel_hop_interface.py
+++ b/yt/analysis_modules/halo_finding/parallel_hop/parallel_hop_interface.py
@@ -31,7 +31,7 @@
from yt.funcs import *
from yt.utilities.performance_counters import yt_counters, time_function
try:
- from yt.utilities.kdtree import \
+ from yt.utilities.kdtree.api import \
chainHOP_tags_dens, \
create_tree, fKD, find_nn_nearest_neighbors, \
free_tree, find_chunk_nearest_neighbors
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/analysis_modules/halo_profiler/multi_halo_profiler.py
--- a/yt/analysis_modules/halo_profiler/multi_halo_profiler.py
+++ b/yt/analysis_modules/halo_profiler/multi_halo_profiler.py
@@ -606,6 +606,7 @@
if newProfile:
mylog.info("Writing halo %d" % halo['id'])
+ if os.path.exists(filename): os.remove(filename)
if filename.endswith('.h5'):
profile.write_out_h5(filename)
else:
@@ -717,7 +718,9 @@
Default=True.
njobs : int
The number of jobs over which to split the projections. Set
- to -1 so that each halo is done by a single processor.
+ to -1 so that each halo is done by a single processor. Halo
+ projections do not currently work in parallel, so this must
+ be set to -1.
Default: -1.
dynamic : bool
If True, distribute halos using a task queue. If False,
@@ -731,6 +734,12 @@
"""
+ # Halo projections cannot run in parallel because they are done by
+ # giving a data source to the projection object.
+ if njobs > 0:
+ mylog.warn("Halo projections cannot use more than one processor per halo, setting njobs to -1.")
+ njobs = -1
+
# Get list of halos for projecting.
if halo_list == 'filtered':
halo_projection_list = self.filtered_halos
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/analysis_modules/two_point_functions/two_point_functions.py
--- a/yt/analysis_modules/two_point_functions/two_point_functions.py
+++ b/yt/analysis_modules/two_point_functions/two_point_functions.py
@@ -30,7 +30,7 @@
from yt.utilities.parallel_tools.parallel_analysis_interface import ParallelAnalysisInterface, parallel_blocking_call, parallel_root_only
try:
- from yt.utilities.kdtree import *
+ from yt.utilities.kdtree.api import *
except ImportError:
mylog.debug("The Fortran kD-Tree did not import correctly.")
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/config.py
--- a/yt/config.py
+++ b/yt/config.py
@@ -38,6 +38,7 @@
inline = 'False',
numthreads = '-1',
__withinreason = 'False',
+ __withintesting = 'False',
__parallel = 'False',
__global_parallel_rank = '0',
__global_parallel_size = '1',
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -237,6 +237,7 @@
def __set_default_field_parameters(self):
self.set_field_parameter("center",np.zeros(3,dtype='float64'))
self.set_field_parameter("bulk_velocity",np.zeros(3,dtype='float64'))
+ self.set_field_parameter("normal",np.array([0,0,1],dtype='float64'))
def _set_center(self, center):
if center is None:
@@ -3658,7 +3659,7 @@
class AMRCoveringGridBase(AMR3DData):
_spatial = True
_type_name = "covering_grid"
- _con_args = ('level', 'left_edge', 'right_edge', 'ActiveDimensions')
+ _con_args = ('level', 'left_edge', 'ActiveDimensions')
def __init__(self, level, left_edge, dims, fields = None,
pf = None, num_ghost_zones = 0, use_pbar = True, **kwargs):
"""A 3D region with all data extracted to a single, specified
@@ -3685,8 +3686,9 @@
fields=fields, pf=pf, **kwargs)
self.left_edge = np.array(left_edge)
self.level = level
- self.dds = self.pf.h.select_grids(self.level)[0].dds.copy()
- self.ActiveDimensions = np.array(dims,dtype='int32')
+ rdx = self.pf.domain_dimensions*self.pf.refine_by**level
+ self.dds = self.pf.domain_width/rdx.astype("float64")
+ self.ActiveDimensions = np.array(dims, dtype='int32')
self.right_edge = self.left_edge + self.ActiveDimensions*self.dds
self._num_ghost_zones = num_ghost_zones
self._use_pbar = use_pbar
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/data_objects/derived_quantities.py
--- a/yt/data_objects/derived_quantities.py
+++ b/yt/data_objects/derived_quantities.py
@@ -598,16 +598,16 @@
continue
else:
nz_filter = None
- mins.append(data[field][nz_filter].min())
- maxs.append(data[field][nz_filter].max())
+ mins.append(np.nanmin(data[field][nz_filter]))
+ maxs.append(np.nanmax(data[field][nz_filter]))
else:
if this_filter.any():
if non_zero:
nz_filter = ((this_filter) &
(data[field][this_filter] > 0.0))
else: nz_filter = this_filter
- mins.append(data[field][nz_filter].min())
- maxs.append(data[field][nz_filter].max())
+ mins.append(np.nanmin(data[field][nz_filter]))
+ maxs.append(np.nanmax(data[field][nz_filter]))
else:
mins.append(1e90)
maxs.append(-1e90)
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/data_objects/field_info_container.py
--- a/yt/data_objects/field_info_container.py
+++ b/yt/data_objects/field_info_container.py
@@ -160,7 +160,8 @@
# required attrs
pf = fake_parameter_file(lambda: 1)
pf.current_redshift = pf.omega_lambda = pf.omega_matter = \
- pf.hubble_constant = pf.cosmological_simulation = 0.0
+ pf.cosmological_simulation = 0.0
+ pf.hubble_constant = 0.7
pf.domain_left_edge = np.zeros(3, 'float64')
pf.domain_right_edge = np.ones(3, 'float64')
pf.dimensionality = 3
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/data_objects/tests/test_covering_grid.py
--- /dev/null
+++ b/yt/data_objects/tests/test_covering_grid.py
@@ -0,0 +1,27 @@
+from yt.testing import *
+from yt.data_objects.profiles import \
+ BinnedProfile1D, BinnedProfile2D, BinnedProfile3D
+
+def setup():
+ from yt.config import ytcfg
+ ytcfg["yt","__withintesting"] = "True"
+
+def test_covering_grid():
+ # We decompose in different ways
+ for level in [0, 1, 2]:
+ for nprocs in [1, 2, 4, 8]:
+ pf = fake_random_pf(16, nprocs = nprocs)
+ dn = pf.refine_by**level
+ cg = pf.h.covering_grid(level, [0.0, 0.0, 0.0],
+ dn * pf.domain_dimensions)
+ yield assert_equal, cg["Ones"].max(), 1.0
+ yield assert_equal, cg["Ones"].min(), 1.0
+ yield assert_equal, cg["CellVolume"].sum(), pf.domain_width.prod()
+ for g in pf.h.grids:
+ di = g.get_global_startindex()
+ dd = g.ActiveDimensions
+ for i in range(dn):
+ f = cg["Density"][dn*di[0]+i:dn*(di[0]+dd[0])+i:dn,
+ dn*di[1]+i:dn*(di[1]+dd[1])+i:dn,
+ dn*di[2]+i:dn*(di[2]+dd[2])+i:dn]
+ yield assert_equal, f, g["Density"]
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/data_objects/tests/test_derived_quantities.py
--- /dev/null
+++ b/yt/data_objects/tests/test_derived_quantities.py
@@ -0,0 +1,24 @@
+from yt.testing import *
+import numpy as np
+
+def setup():
+ from yt.config import ytcfg
+ ytcfg["yt","__withintesting"] = "True"
+
+def test_extrema():
+ for nprocs in [1, 2, 4, 8]:
+ pf = fake_random_pf(16, nprocs = nprocs, fields = ("Density",
+ "x-velocity", "y-velocity", "z-velocity"))
+ sp = pf.h.sphere("c", (0.25, '1'))
+ (mi, ma), = sp.quantities["Extrema"]("Density")
+ yield assert_equal, mi, np.nanmin(sp["Density"])
+ yield assert_equal, ma, np.nanmax(sp["Density"])
+ dd = pf.h.all_data()
+ (mi, ma), = dd.quantities["Extrema"]("Density")
+ yield assert_equal, mi, np.nanmin(dd["Density"])
+ yield assert_equal, ma, np.nanmax(dd["Density"])
+ sp = pf.h.sphere("max", (0.25, '1'))
+ yield assert_equal, np.any(np.isnan(sp["RadialVelocity"])), True
+ (mi, ma), = dd.quantities["Extrema"]("RadialVelocity")
+ yield assert_equal, mi, np.nanmin(dd["RadialVelocity"])
+ yield assert_equal, ma, np.nanmax(dd["RadialVelocity"])
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/data_objects/tests/test_extract_regions.py
--- /dev/null
+++ b/yt/data_objects/tests/test_extract_regions.py
@@ -0,0 +1,53 @@
+from yt.testing import *
+
+def setup():
+ from yt.config import ytcfg
+ ytcfg["yt","__withintesting"] = "True"
+
+def test_cut_region():
+ # We decompose in different ways
+ for nprocs in [1, 2, 4, 8]:
+ pf = fake_random_pf(64, nprocs = nprocs,
+ fields = ("Density", "Temperature", "x-velocity"))
+ # We'll test two objects
+ dd = pf.h.all_data()
+ r = dd.cut_region( [ "grid['Temperature'] > 0.5",
+ "grid['Density'] < 0.75",
+ "grid['x-velocity'] > 0.25" ])
+ t = ( (dd["Temperature"] > 0.5 )
+ & (dd["Density"] < 0.75 )
+ & (dd["x-velocity"] > 0.25 ) )
+ yield assert_equal, np.all(r["Temperature"] > 0.5), True
+ yield assert_equal, np.all(r["Density"] < 0.75), True
+ yield assert_equal, np.all(r["x-velocity"] > 0.25), True
+ yield assert_equal, np.sort(dd["Density"][t]), np.sort(r["Density"])
+ yield assert_equal, np.sort(dd["x"][t]), np.sort(r["x"])
+ r2 = r.cut_region( [ "grid['Temperature'] < 0.75" ] )
+ t2 = (r["Temperature"] < 0.75)
+ yield assert_equal, np.sort(r2["Temperature"]), np.sort(r["Temperature"][t2])
+ yield assert_equal, np.all(r2["Temperature"] < 0.75), True
+
+def test_extract_region():
+ # We decompose in different ways
+ for nprocs in [1, 2, 4, 8]:
+ pf = fake_random_pf(64, nprocs = nprocs,
+ fields = ("Density", "Temperature", "x-velocity"))
+ # We'll test two objects
+ dd = pf.h.all_data()
+ t = ( (dd["Temperature"] > 0.5 )
+ & (dd["Density"] < 0.75 )
+ & (dd["x-velocity"] > 0.25 ) )
+ r = dd.extract_region(t)
+ yield assert_equal, np.all(r["Temperature"] > 0.5), True
+ yield assert_equal, np.all(r["Density"] < 0.75), True
+ yield assert_equal, np.all(r["x-velocity"] > 0.25), True
+ yield assert_equal, np.sort(dd["Density"][t]), np.sort(r["Density"])
+ yield assert_equal, np.sort(dd["x"][t]), np.sort(r["x"])
+ t2 = (r["Temperature"] < 0.75)
+ r2 = r.cut_region( [ "grid['Temperature'] < 0.75" ] )
+ yield assert_equal, np.sort(r2["Temperature"]), np.sort(r["Temperature"][t2])
+ yield assert_equal, np.all(r2["Temperature"] < 0.75), True
+ t3 = (r["Temperature"] < 0.75)
+ r3 = r.extract_region( t3 )
+ yield assert_equal, np.sort(r3["Temperature"]), np.sort(r["Temperature"][t3])
+ yield assert_equal, np.all(r3["Temperature"] < 0.75), True
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/data_objects/tests/test_fields.py
--- /dev/null
+++ b/yt/data_objects/tests/test_fields.py
@@ -0,0 +1,91 @@
+from yt.testing import *
+import numpy as np
+from yt.data_objects.field_info_container import \
+ FieldInfo
+import yt.data_objects.universal_fields
+from yt.utilities.definitions import \
+ mpc_conversion, sec_conversion
+
+def setup():
+ from yt.config import ytcfg
+ ytcfg["yt","__withintesting"] = "True"
+ np.seterr(all = 'ignore')
+
+_sample_parameters = dict(
+ axis = 0,
+ center = np.array((0.0, 0.0, 0.0)),
+ bulk_velocity = np.array((0.0, 0.0, 0.0)),
+ normal = np.array((0.0, 0.0, 1.0)),
+ cp_x_vec = np.array((1.0, 0.0, 0.0)),
+ cp_y_vec = np.array((0.0, 1.0, 0.0)),
+ cp_z_vec = np.array((0.0, 0.0, 1.0)),
+)
+
+_base_fields = ["Density", "x-velocity", "y-velocity", "z-velocity"]
+
+def realistic_pf(fields, nprocs):
+ pf = fake_random_pf(16, fields = fields, nprocs = nprocs)
+ pf.parameters["HydroMethod"] = "streaming"
+ pf.parameters["Gamma"] = 5.0/3.0
+ pf.parameters["EOSType"] = 1.0
+ pf.parameters["EOSSoundSpeed"] = 1.0
+ pf.conversion_factors["Time"] = 1.0
+ pf.conversion_factors.update( dict((f, 1.0) for f in fields) )
+ pf.current_redshift = 0.0001
+ pf.hubble_constant = 0.7
+ for unit in mpc_conversion:
+ pf.units[unit+'h'] = pf.units[unit]
+ pf.units[unit+'cm'] = pf.units[unit]
+ pf.units[unit+'hcm'] = pf.units[unit]
+ return pf
+
+class TestFieldAccess(object):
+ description = None
+
+ def __init__(self, field_name, nproc):
+ # Note this should be a field name
+ self.field_name = field_name
+ self.description = "Accessing_%s_%s" % (field_name, nproc)
+ self.nproc = nproc
+
+ def __call__(self):
+ field = FieldInfo[self.field_name]
+ deps = field.get_dependencies()
+ fields = deps.requested + _base_fields
+ skip_grids = False
+ needs_spatial = False
+ for v in field.validators:
+ f = getattr(v, "fields", None)
+ if f: fields += f
+ if getattr(v, "ghost_zones", 0) > 0:
+ skip_grids = True
+ if hasattr(v, "ghost_zones"):
+ needs_spatial = True
+ pf = realistic_pf(fields, self.nproc)
+ # This gives unequal sized grids as well as subgrids
+ dd1 = pf.h.all_data()
+ dd2 = pf.h.all_data()
+ dd1.field_parameters.update(_sample_parameters)
+ dd2.field_parameters.update(_sample_parameters)
+ v1 = dd1[self.field_name]
+ conv = field._convert_function(dd1) or 1.0
+ if not needs_spatial:
+ assert_equal(v1, conv*field._function(field, dd2))
+ if not skip_grids:
+ for g in pf.h.grids:
+ g.field_parameters.update(_sample_parameters)
+ conv = field._convert_function(g) or 1.0
+ v1 = g[self.field_name]
+ g.clear_data()
+ g.field_parameters.update(_sample_parameters)
+ assert_equal(v1, conv*field._function(field, g))
+
+def test_all_fields():
+ for field in FieldInfo:
+ if field.startswith("CuttingPlane"): continue
+ if field.startswith("particle"): continue
+ if field.startswith("CIC"): continue
+ if field.startswith("WeakLensingConvergence"): continue
+ if FieldInfo[field].particle_type: continue
+ for nproc in [1, 4, 8]:
+ yield TestFieldAccess(field, nproc)
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/data_objects/tests/test_ortho_rays.py
--- /dev/null
+++ b/yt/data_objects/tests/test_ortho_rays.py
@@ -0,0 +1,25 @@
+from yt.testing import *
+
+def test_ortho_ray():
+ pf = fake_random_pf(64, nprocs=8)
+ dx = (pf.domain_right_edge - pf.domain_left_edge) / \
+ pf.domain_dimensions
+
+ axes = ['x', 'y', 'z']
+ for ax, an in enumerate(axes):
+ ocoord = np.random.random(2)
+
+ my_oray = pf.h.ortho_ray(ax, ocoord)
+
+ my_axes = range(3)
+ del my_axes[ax]
+
+ # find the cells intersected by the ortho ray
+ my_all = pf.h.all_data()
+ my_cells = (np.abs(my_all[axes[my_axes[0]]] - ocoord[0]) <=
+ 0.5 * dx[my_axes[0]]) & \
+ (np.abs(my_all[axes[my_axes[1]]] - ocoord[1]) <=
+ 0.5 * dx[my_axes[1]])
+
+ assert_equal(my_oray['Density'].sum(),
+ my_all['Density'][my_cells].sum())
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/data_objects/tests/test_projection.py
--- a/yt/data_objects/tests/test_projection.py
+++ b/yt/data_objects/tests/test_projection.py
@@ -2,11 +2,15 @@
from yt.data_objects.profiles import \
BinnedProfile1D, BinnedProfile2D, BinnedProfile3D
+def setup():
+ from yt.config import ytcfg
+ ytcfg["yt","__withintesting"] = "True"
+
def test_projection():
for nprocs in [8, 1]:
# We want to test both 1 proc and 8 procs, to make sure that
# parallelism isn't broken
- pf = fake_random_pf(64, nprocs = 1)
+ pf = fake_random_pf(64, nprocs = nprocs)
dims = pf.domain_dimensions
xn, yn, zn = pf.domain_dimensions
xi, yi, zi = pf.domain_left_edge + 1.0/(pf.domain_dimensions * 2)
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/data_objects/tests/test_rays.py
--- /dev/null
+++ b/yt/data_objects/tests/test_rays.py
@@ -0,0 +1,31 @@
+from yt.testing import *
+
+def test_ray():
+ pf = fake_random_pf(64, nprocs=8)
+ dx = (pf.domain_right_edge - pf.domain_left_edge) / \
+ pf.domain_dimensions
+
+ p1 = np.random.random(3)
+ p2 = np.random.random(3)
+
+ my_ray = pf.h.ray(p1, p2)
+ assert_rel_equal(my_ray['dts'].sum(), 1.0, 14)
+ ray_cells = my_ray['dts'] > 0
+
+ # find cells intersected by the ray
+ my_all = pf.h.all_data()
+
+ dt = np.abs(dx / (p2 - p1))
+ tin = np.concatenate([[(my_all['x'] - p1[0]) / (p2 - p1)[0] - 0.5 * dt[0]],
+ [(my_all['y'] - p1[1]) / (p2 - p1)[1] - 0.5 * dt[1]],
+ [(my_all['z'] - p1[2]) / (p2 - p1)[2] - 0.5 * dt[2]]])
+ tout = np.concatenate([[(my_all['x'] - p1[0]) / (p2 - p1)[0] + 0.5 * dt[0]],
+ [(my_all['y'] - p1[1]) / (p2 - p1)[1] + 0.5 * dt[1]],
+ [(my_all['z'] - p1[2]) / (p2 - p1)[2] + 0.5 * dt[2]]])
+ tin = tin.max(axis=0)
+ tout = tout.min(axis=0)
+ my_cells = (tin < tout) & (tin < 1) & (tout > 0)
+
+ assert_rel_equal(ray_cells.sum(), my_cells.sum(), 14)
+ assert_rel_equal(my_ray['Density'][ray_cells].sum(),
+ my_all['Density'][my_cells].sum(), 14)
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/data_objects/time_series.py
--- a/yt/data_objects/time_series.py
+++ b/yt/data_objects/time_series.py
@@ -258,8 +258,11 @@
"""
if isinstance(filenames, types.StringTypes):
+ pattern = filenames
filenames = glob.glob(filenames)
filenames.sort()
+ if len(filenames) == 0:
+ raise YTNoFilenamesMatchPattern(pattern)
obj = cls(filenames[:], parallel = parallel)
return obj
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/data_objects/universal_fields.py
--- a/yt/data_objects/universal_fields.py
+++ b/yt/data_objects/universal_fields.py
@@ -32,7 +32,7 @@
from yt.funcs import *
-from yt.utilities.lib import CICDeposit_3, obtain_rvec
+from yt.utilities.lib import CICDeposit_3, obtain_rvec, obtain_rv_vec
from yt.utilities.cosmology import Cosmology
from field_info_container import \
add_field, \
@@ -54,7 +54,19 @@
kboltz, \
G, \
rho_crit_now, \
- speed_of_light_cgs
+ speed_of_light_cgs, \
+ km_per_cm
+
+from yt.utilities.math_utils import \
+ get_sph_r_component, \
+ get_sph_theta_component, \
+ get_sph_phi_component, \
+ get_cyl_r_component, \
+ get_cyl_z_component, \
+ get_cyl_theta_component, \
+ get_cyl_r, get_cyl_theta, \
+ get_cyl_z, get_sph_r, \
+ get_sph_theta, get_sph_phi
# Note that, despite my newfound efforts to comply with PEP-8,
# I violate it here in order to keep the name/func_name relationship
@@ -179,12 +191,8 @@
def _VelocityMagnitude(field, data):
"""M{|v|}"""
- bulk_velocity = data.get_field_parameter("bulk_velocity")
- if bulk_velocity == None:
- bulk_velocity = np.zeros(3)
- return ( (data["x-velocity"]-bulk_velocity[0])**2.0 + \
- (data["y-velocity"]-bulk_velocity[1])**2.0 + \
- (data["z-velocity"]-bulk_velocity[2])**2.0 )**(1.0/2.0)
+ velocities = obtain_rv_vec(data)
+ return np.sqrt(np.sum(velocities**2,axis=0))
add_field("VelocityMagnitude", function=_VelocityMagnitude,
take_log=False, units=r"\rm{cm}/\rm{s}")
@@ -194,13 +202,6 @@
function=_TangentialOverVelocityMagnitude,
take_log=False)
-def _TangentialVelocity(field, data):
- return np.sqrt(data["VelocityMagnitude"]**2.0
- - data["RadialVelocity"]**2.0)
-add_field("TangentialVelocity",
- function=_TangentialVelocity,
- take_log=False, units=r"\rm{cm}/\rm{s}")
-
def _Pressure(field, data):
"""M{(Gamma-1.0)*rho*E}"""
return (data.pf["Gamma"] - 1.0) * \
@@ -223,14 +224,9 @@
def _sph_r(field, data):
center = data.get_field_parameter("center")
- coords = np.array([data['x'] - center[0],
- data['y'] - center[1],
- data['z'] - center[2]]).transpose()
+ coords = obtain_rvec(data)
- ## The spherical coordinates radius is simply the magnitude of the
- ## coords vector.
-
- return np.sqrt(np.sum(coords**2,axis=-1))
+ return get_sph_r(coords)
def _Convert_sph_r_CGS(data):
return data.convert("cm")
@@ -245,20 +241,9 @@
center = data.get_field_parameter("center")
normal = data.get_field_parameter("normal")
- coords = np.array([data['x'] - center[0],
- data['y'] - center[1],
- data['z'] - center[2]]).transpose()
+ coords = obtain_rvec(data)
- ## The angle (theta) with respect to the normal (J), is the arccos
- ## of the dot product of the normal with the normalized coords
- ## vector.
-
- tile_shape = list(coords.shape)[:-1] + [1]
- J = np.tile(normal,tile_shape)
-
- JdotCoords = np.sum(J*coords,axis=-1)
-
- return np.arccos( JdotCoords / np.sqrt(np.sum(coords**2,axis=-1)) )
+ return get_sph_theta(coords, normal)
add_field("sph_theta", function=_sph_theta,
validators=[ValidateParameter("center"),ValidateParameter("normal")])
@@ -269,54 +254,21 @@
center = data.get_field_parameter("center")
normal = data.get_field_parameter("normal")
- coords = np.array([data['x'] - center[0],
- data['y'] - center[1],
- data['z'] - center[2]]).transpose()
-
- ## We have freedom with respect to what axis (xprime) to define
- ## the disk angle. Here I've chosen to use the axis that is
- ## perpendicular to the normal and the y-axis. When normal ==
- ## y-hat, then set xprime = z-hat. With this definition, when
- ## normal == z-hat (as is typical), then xprime == x-hat.
- ##
- ## The angle is then given by the arctan of the ratio of the
- ## yprime-component and the xprime-component of the coords vector.
+ coords = obtain_rvec(data)
- xprime = np.cross([0.0,1.0,0.0],normal)
- if np.sum(xprime) == 0: xprime = np.array([0.0, 0.0, 1.0])
- yprime = np.cross(normal,xprime)
-
- tile_shape = list(coords.shape)[:-1] + [1]
- Jx = np.tile(xprime,tile_shape)
- Jy = np.tile(yprime,tile_shape)
-
- Px = np.sum(Jx*coords,axis=-1)
- Py = np.sum(Jy*coords,axis=-1)
-
- return np.arctan2(Py,Px)
+ return get_sph_phi(coords, normal)
add_field("sph_phi", function=_sph_phi,
validators=[ValidateParameter("center"),ValidateParameter("normal")])
-
-
### cylindrical coordinates: R (radius in the cylinder's plane)
def _cyl_R(field, data):
center = data.get_field_parameter("center")
normal = data.get_field_parameter("normal")
- coords = np.array([data['x'] - center[0],
- data['y'] - center[1],
- data['z'] - center[2]]).transpose()
+ coords = obtain_rvec(data)
- ## The cross product of the normal (J) with the coords vector
- ## gives a vector of magnitude equal to the cylindrical radius.
-
- tile_shape = list(coords.shape)[:-1] + [1]
- J = np.tile(normal,tile_shape)
-
- JcrossCoords = np.cross(J,coords)
- return np.sqrt(np.sum(JcrossCoords**2,axis=-1))
+ return get_cyl_r(coords, normal)
def _Convert_cyl_R_CGS(data):
return data.convert("cm")
@@ -324,6 +276,9 @@
add_field("cyl_R", function=_cyl_R,
validators=[ValidateParameter("center"),ValidateParameter("normal")],
convert_function = _Convert_cyl_R_CGS, units=r"\rm{cm}")
+add_field("cyl_RCode", function=_cyl_R,
+ validators=[ValidateParameter("center"),ValidateParameter("normal")],
+ units=r"Radius (code)")
### cylindrical coordinates: z (height above the cylinder's plane)
@@ -331,17 +286,9 @@
center = data.get_field_parameter("center")
normal = data.get_field_parameter("normal")
- coords = np.array([data['x'] - center[0],
- data['y'] - center[1],
- data['z'] - center[2]]).transpose()
+ coords = obtain_rvec(data)
- ## The dot product of the normal (J) with the coords vector gives
- ## the cylindrical height.
-
- tile_shape = list(coords.shape)[:-1] + [1]
- J = np.tile(normal,tile_shape)
-
- return np.sum(J*coords,axis=-1)
+ return get_cyl_z(coords, normal)
def _Convert_cyl_z_CGS(data):
return data.convert("cm")
@@ -352,14 +299,17 @@
### cylindrical coordinates: theta (angle in the cylinder's plane)
-### [This is identical to the spherical coordinate's 'phi' angle.]
def _cyl_theta(field, data):
- return data['sph_phi']
+ center = data.get_field_parameter("center")
+ normal = data.get_field_parameter("normal")
+
+ coords = obtain_rvec(data)
+
+ return get_cyl_theta(coords, normal)
add_field("cyl_theta", function=_cyl_theta,
validators=[ValidateParameter("center"),ValidateParameter("normal")])
-
### The old field DiskAngle is the same as the spherical coordinates'
### 'theta' angle. I'm keeping DiskAngle for backwards compatibility.
def _DiskAngle(field, data):
@@ -392,6 +342,54 @@
ValidateParameter("normal")],
units=r"AU", display_field=False)
+def _cyl_RadialVelocity(field, data):
+ normal = data.get_field_parameter("normal")
+ velocities = obtain_rv_vec(data)
+
+ theta = data['cyl_theta']
+
+ return get_cyl_r_component(velocities, theta, normal)
+
+def _cyl_RadialVelocityABS(field, data):
+ return np.abs(_cyl_RadialVelocity(field, data))
+def _Convert_cyl_RadialVelocityKMS(data):
+ return km_per_cm
+add_field("cyl_RadialVelocity", function=_cyl_RadialVelocity,
+ units=r"\rm{cm}/\rm{s}",
+ validators=[ValidateParameter("normal")])
+add_field("cyl_RadialVelocityABS", function=_cyl_RadialVelocityABS,
+ units=r"\rm{cm}/\rm{s}",
+ validators=[ValidateParameter("normal")])
+add_field("cyl_RadialVelocityKMS", function=_cyl_RadialVelocity,
+ convert_function=_Convert_cyl_RadialVelocityKMS, units=r"\rm{km}/\rm{s}",
+ validators=[ValidateParameter("normal")])
+add_field("cyl_RadialVelocityKMSABS", function=_cyl_RadialVelocityABS,
+ convert_function=_Convert_cyl_RadialVelocityKMS, units=r"\rm{km}/\rm{s}",
+ validators=[ValidateParameter("normal")])
+
+def _cyl_TangentialVelocity(field, data):
+ normal = data.get_field_parameter("normal")
+ velocities = obtain_rv_vec(data)
+ theta = data['cyl_theta']
+
+ return get_cyl_theta_component(velocities, theta, normal)
+
+def _cyl_TangentialVelocityABS(field, data):
+ return np.abs(_cyl_TangentialVelocity(field, data))
+def _Convert_cyl_TangentialVelocityKMS(data):
+ return km_per_cm
+add_field("cyl_TangentialVelocity", function=_cyl_TangentialVelocity,
+ units=r"\rm{cm}/\rm{s}",
+ validators=[ValidateParameter("normal")])
+add_field("cyl_TangentialVelocityABS", function=_cyl_TangentialVelocityABS,
+ units=r"\rm{cm}/\rm{s}",
+ validators=[ValidateParameter("normal")])
+add_field("cyl_TangentialVelocityKMS", function=_cyl_TangentialVelocity,
+ convert_function=_Convert_cyl_TangentialVelocityKMS, units=r"\rm{km}/\rm{s}",
+ validators=[ValidateParameter("normal")])
+add_field("cyl_TangentialVelocityKMSABS", function=_cyl_TangentialVelocityABS,
+ convert_function=_Convert_cyl_TangentialVelocityKMS, units=r"\rm{km}/\rm{s}",
+ validators=[ValidateParameter("normal")])
def _DynamicalTime(field, data):
"""
@@ -450,7 +448,7 @@
# This is rho_total / rho_cr(z).
def _Convert_Overdensity(data):
- return 1 / (rho_crit_now * data.pf.hubble_constant**2 *
+ return 1.0 / (rho_crit_now * data.pf.hubble_constant**2 *
(1+data.pf.current_redshift)**3)
add_field("Overdensity",function=_Matter_Density,
convert_function=_Convert_Overdensity, units=r"")
@@ -470,8 +468,8 @@
else:
omega_baryon_now = 0.0441
return data['Density'] / (omega_baryon_now * rho_crit_now *
- (data.pf['CosmologyHubbleConstantNow']**2) *
- ((1+data.pf['CosmologyCurrentRedshift'])**3))
+ (data.pf.hubble_constant**2) *
+ ((1+data.pf.current_redshift)**3))
add_field("Baryon_Overdensity", function=_Baryon_Overdensity,
units=r"")
@@ -640,13 +638,7 @@
take_log=False, display_field=False)
def obtain_velocities(data):
- if data.has_field_parameter("bulk_velocity"):
- bv = data.get_field_parameter("bulk_velocity")
- else: bv = np.zeros(3, dtype='float64')
- xv = data["x-velocity"] - bv[0]
- yv = data["y-velocity"] - bv[1]
- zv = data["z-velocity"] - bv[2]
- return xv, yv, zv
+ return obtain_rv_vec(data)
def _convertSpecificAngularMomentum(data):
return data.convert("cm")
@@ -711,7 +703,7 @@
# convert_function=_convertSpecificAngularMomentum, vector_field=True,
# units=r"\rm{cm}^2/\rm{s}", validators=[ValidateParameter('center')])
def _convertSpecificAngularMomentumKMSMPC(data):
- return data.convert("mpc")/1e5
+ return km_per_cm*data.convert("mpc")
#add_field("ParticleSpecificAngularMomentumKMSMPC",
# function=_ParticleSpecificAngularMomentum, particle_type=True,
# convert_function=_convertSpecificAngularMomentumKMSMPC, vector_field=True,
@@ -883,33 +875,32 @@
display_name = "Radius (code)")
def _RadialVelocity(field, data):
- center = data.get_field_parameter("center")
- bulk_velocity = data.get_field_parameter("bulk_velocity")
- if bulk_velocity == None:
- bulk_velocity = np.zeros(3)
- new_field = ( (data['x']-center[0])*(data["x-velocity"]-bulk_velocity[0])
- + (data['y']-center[1])*(data["y-velocity"]-bulk_velocity[1])
- + (data['z']-center[2])*(data["z-velocity"]-bulk_velocity[2])
- )/data["RadiusCode"]
- if np.any(np.isnan(new_field)): # to fix center = point
- new_field[np.isnan(new_field)] = 0.0
- return new_field
+ normal = data.get_field_parameter("normal")
+ velocities = obtain_rv_vec(data)
+ theta = data['sph_theta']
+ phi = data['sph_phi']
+
+ return get_sph_r_component(velocities, theta, phi, normal)
+
def _RadialVelocityABS(field, data):
return np.abs(_RadialVelocity(field, data))
def _ConvertRadialVelocityKMS(data):
- return 1e-5
+ return km_per_cm
add_field("RadialVelocity", function=_RadialVelocity,
- units=r"\rm{cm}/\rm{s}",
- validators=[ValidateParameter("center")])
+ units=r"\rm{cm}/\rm{s}")
add_field("RadialVelocityABS", function=_RadialVelocityABS,
- units=r"\rm{cm}/\rm{s}",
- validators=[ValidateParameter("center")])
+ units=r"\rm{cm}/\rm{s}")
add_field("RadialVelocityKMS", function=_RadialVelocity,
- convert_function=_ConvertRadialVelocityKMS, units=r"\rm{km}/\rm{s}",
- validators=[ValidateParameter("center")])
+ convert_function=_ConvertRadialVelocityKMS, units=r"\rm{km}/\rm{s}")
add_field("RadialVelocityKMSABS", function=_RadialVelocityABS,
- convert_function=_ConvertRadialVelocityKMS, units=r"\rm{km}/\rm{s}",
- validators=[ValidateParameter("center")])
+ convert_function=_ConvertRadialVelocityKMS, units=r"\rm{km}/\rm{s}")
+
+def _TangentialVelocity(field, data):
+ return np.sqrt(data["VelocityMagnitude"]**2.0
+ - data["RadialVelocity"]**2.0)
+add_field("TangentialVelocity",
+ function=_TangentialVelocity,
+ take_log=False, units=r"\rm{cm}/\rm{s}")
def _CuttingPlaneVelocityX(field, data):
x_vec, y_vec, z_vec = [data.get_field_parameter("cp_%s_vec" % (ax))
@@ -1026,6 +1017,47 @@
display_name=r"\rm{Magnetic}\/\rm{Energy}",
units="\rm{ergs}\/\rm{cm}^{-3}")
+def _BPoloidal(field,data):
+ normal = data.get_field_parameter("normal")
+
+ Bfields = np.array([data['Bx'], data['By'], data['Bz']])
+
+ theta = data['sph_theta']
+ phi = data['sph_phi']
+
+ return get_sph_theta_component(Bfields, theta, phi, normal)
+
+add_field("BPoloidal", function=_BPoloidal,
+ units=r"\rm{Gauss}",
+ validators=[ValidateParameter("normal")])
+
+def _BToroidal(field,data):
+ normal = data.get_field_parameter("normal")
+
+ Bfields = np.array([data['Bx'], data['By'], data['Bz']])
+
+ phi = data['sph_phi']
+
+ return get_sph_phi_component(Bfields, phi, normal)
+
+add_field("BToroidal", function=_BToroidal,
+ units=r"\rm{Gauss}",
+ validators=[ValidateParameter("normal")])
+
+def _BRadial(field,data):
+ normal = data.get_field_parameter("normal")
+
+ Bfields = np.array([data['Bx'], data['By'], data['Bz']])
+
+ theta = data['sph_theta']
+ phi = data['sph_phi']
+
+ return get_sph_r_component(Bfields, theta, phi, normal)
+
+add_field("BRadial", function=_BPoloidal,
+ units=r"\rm{Gauss}",
+ validators=[ValidateParameter("normal")])
+
def _VorticitySquared(field, data):
mylog.debug("Generating vorticity on %s", data)
# We need to set up stencils
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/frontends/stream/data_structures.py
--- a/yt/frontends/stream/data_structures.py
+++ b/yt/frontends/stream/data_structures.py
@@ -353,7 +353,8 @@
psize = get_psize(np.array(data[key].shape), nprocs)
grid_left_edges, grid_right_edges, temp[key] = \
decompose_array(data[key], psize, bbox)
- grid_dimensions = np.array([grid.shape for grid in temp[key]])
+ grid_dimensions = np.array([grid.shape for grid in temp[key]],
+ dtype="int32")
for gid in range(nprocs):
new_data[gid] = {}
for key in temp.keys():
@@ -364,7 +365,7 @@
sfh.update({0:data})
grid_left_edges = domain_left_edge
grid_right_edges = domain_right_edge
- grid_dimensions = domain_dimensions.reshape(nprocs,3)
+ grid_dimensions = domain_dimensions.reshape(nprocs,3).astype("int32")
handler = StreamHandler(
grid_left_edges,
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/funcs.py
--- a/yt/funcs.py
+++ b/yt/funcs.py
@@ -310,7 +310,8 @@
maxval = max(maxval, 1)
from yt.config import ytcfg
if ytcfg.getboolean("yt", "suppressStreamLogging") or \
- ytcfg.getboolean("yt", "ipython_notebook"):
+ ytcfg.getboolean("yt", "ipython_notebook") or \
+ ytcfg.getboolean("yt", "__withintesting"):
return DummyProgressBar()
elif ytcfg.getboolean("yt", "__withinreason"):
from yt.gui.reason.extdirect_repl import ExtProgressBar
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/utilities/decompose.py
--- a/yt/utilities/decompose.py
+++ b/yt/utilities/decompose.py
@@ -68,9 +68,12 @@
def evaluate_domain_decomposition(n_d, pieces, ldom):
""" Evaluate longest to shortest edge ratio
BEWARE: lot's of magic here """
- ideal_bsize = 3.0 * (pieces * np.product(n_d) ** 2) ** (1.0 / 3.0)
- bsize = int(np.sum(
- ldom / np.array(n_d, dtype=np.float64) * np.product(n_d)))
+ eff_dim = (n_d > 1).sum()
+ ideal_bsize = eff_dim * (pieces * np.product(n_d) ** (eff_dim - 1)
+ ) ** (1.0 / eff_dim)
+ mask = np.where(n_d > 1)
+ nd_arr = np.array(n_d, dtype=np.float64)[mask]
+ bsize = int(np.sum(ldom[mask] / nd_arr * np.product(nd_arr)))
load_balance = float(np.product(n_d)) / \
(float(pieces) * np.product((n_d - 1) / ldom + 1))
@@ -134,23 +137,15 @@
def split_array(tab, psize):
- """ Split array into px*py*pz subarrays using internal numpy routine. """
- temp = [np.array_split(array, psize[1], axis=1)
- for array in np.array_split(tab, psize[2], axis=2)]
- temp = [item for sublist in temp for item in sublist]
- temp = [np.array_split(array, psize[0], axis=0) for array in temp]
- temp = [item for sublist in temp for item in sublist]
- return temp
-
-
-if __name__ == "__main__":
-
- NPROC = 12
- ARRAY = np.zeros((128, 128, 129))
- BBOX = np.array([[0., 1.0], [-1.5, 1.5], [1.0, 2.5]])
-
- PROCS = get_psize(np.array(ARRAY.shape), NPROC)
- LE, RE, DATA = decompose_array(ARRAY, PROCS, BBOX)
-
- for idx in range(NPROC):
- print LE[idx, :], RE[idx, :], DATA[idx].shape
+ """ Split array into px*py*pz subarrays. """
+ n_d = np.array(tab.shape, dtype=np.int64)
+ slices = []
+ for i in range(psize[0]):
+ for j in range(psize[1]):
+ for k in range(psize[2]):
+ piece = np.array((i, j, k), dtype=np.int64)
+ lei = n_d * piece / psize
+ rei = n_d * (piece + np.ones(3, dtype=np.int64)) / psize
+ slices.append(np.s_[lei[0]:rei[0], lei[1]:
+ rei[1], lei[2]:rei[2]])
+ return [tab[slc] for slc in slices]
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/utilities/exceptions.py
--- a/yt/utilities/exceptions.py
+++ b/yt/utilities/exceptions.py
@@ -146,3 +146,11 @@
def __str__(self):
return "You must create an API key before uploading. See " + \
"https://data.yt-project.org/getting_started.html"
+
+class YTNoFilenamesMatchPattern(YTException):
+ def __init__(self, pattern):
+ self.pattern = pattern
+
+ def __str__(self):
+ return "No filenames were found to match the pattern: " + \
+ "'%s'" % (self.pattern)
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/utilities/kdtree/__init__.py
--- a/yt/utilities/kdtree/__init__.py
+++ b/yt/utilities/kdtree/__init__.py
@@ -1,1 +0,0 @@
-from fKDpy import *
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/utilities/kdtree/api.py
--- /dev/null
+++ b/yt/utilities/kdtree/api.py
@@ -0,0 +1,9 @@
+from fKDpy import \
+ chainHOP_tags_dens, \
+ create_tree, \
+ fKD, \
+ find_nn_nearest_neighbors, \
+ free_tree, \
+ find_chunk_nearest_neighbors
+
+
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/utilities/kdtree/test.py
--- a/yt/utilities/kdtree/test.py
+++ /dev/null
@@ -1,58 +0,0 @@
-from Forthon import *
-from fKDpy import *
-import numpy,random
-
-n = 32768
-
-
-fKD.tags = fzeros((64),'i')
-fKD.dist = fzeros((64),'d')
-fKD.pos = fzeros((3,n),'d')
-fKD.nn = 64
-fKD.nparts = n
-fKD.sort = True
-fKD.rearrange = True
-fKD.qv = numpy.array([16./32, 16./32, 16./32])
-
-fp = open('parts.txt','r')
-xpos = []
-ypos = []
-zpos = []
-line = fp.readline()
-while line:
- line = line.split()
- xpos.append(float(line[0]))
- ypos.append(float(line[1]))
- zpos.append(float(line[2]))
- line= fp.readline()
-
-fp.close()
-
-
-for k in range(32):
- for j in range(32):
- for i in range(32):
- fKD.pos[0][i + j*32 + k*1024] = float(i)/32 + 1./64 + 0.0001*random.random()
- fKD.pos[1][i + j*32 + k*1024] = float(j)/32 + 1./64 + 0.0001*random.random()
- fKD.pos[2][i + j*32 + k*1024] = float(k)/32 + 1./64 + 0.0001*random.random()
-
-
-
-#print fKD.pos[0][0],fKD.pos[1][0],fKD.pos[2][0]
-
-create_tree()
-
-
-find_nn_nearest_neighbors()
-
-#print 'next'
-
-#fKD.qv = numpy.array([0., 0., 0.])
-
-#find_nn_nearest_neighbors()
-
-
-#print (fKD.tags - 1)
-#print fKD.dist
-
-free_tree()
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/utilities/lib/geometry_utils.pyx
--- a/yt/utilities/lib/geometry_utils.pyx
+++ b/yt/utilities/lib/geometry_utils.pyx
@@ -338,3 +338,47 @@
rg[2,i,j,k] = zg[i,j,k] - c[2]
return rg
+ at cython.boundscheck(False)
+ at cython.wraparound(False)
+ at cython.cdivision(True)
+def obtain_rv_vec(data):
+ # This is just to let the pointers exist and whatnot. We can't cdef them
+ # inside conditionals.
+ cdef np.ndarray[np.float64_t, ndim=1] vxf
+ cdef np.ndarray[np.float64_t, ndim=1] vyf
+ cdef np.ndarray[np.float64_t, ndim=1] vzf
+ cdef np.ndarray[np.float64_t, ndim=2] rvf
+ cdef np.ndarray[np.float64_t, ndim=3] vxg
+ cdef np.ndarray[np.float64_t, ndim=3] vyg
+ cdef np.ndarray[np.float64_t, ndim=3] vzg
+ cdef np.ndarray[np.float64_t, ndim=4] rvg
+ cdef np.float64_t bv[3]
+ cdef int i, j, k
+ bulk_velocity = data.get_field_parameter("bulk_velocity")
+ if bulk_velocity == None:
+ bulk_velocity = np.zeros(3)
+ bv[0] = bulk_velocity[0]; bv[1] = bulk_velocity[1]; bv[2] = bulk_velocity[2]
+ if len(data['x-velocity'].shape) == 1:
+ # One dimensional data
+ vxf = data['x-velocity'].astype("float64")
+ vyf = data['y-velocity'].astype("float64")
+ vzf = data['z-velocity'].astype("float64")
+ rvf = np.empty((3, vxf.shape[0]), 'float64')
+ for i in range(vxf.shape[0]):
+ rvf[0, i] = vxf[i] - bv[0]
+ rvf[1, i] = vyf[i] - bv[1]
+ rvf[2, i] = vzf[i] - bv[2]
+ return rvf
+ else:
+ # Three dimensional data
+ vxg = data['x-velocity'].astype("float64")
+ vyg = data['y-velocity'].astype("float64")
+ vzg = data['z-velocity'].astype("float64")
+ rvg = np.empty((3, vxg.shape[0], vxg.shape[1], vxg.shape[2]), 'float64')
+ for i in range(vxg.shape[0]):
+ for j in range(vxg.shape[1]):
+ for k in range(vxg.shape[2]):
+ rvg[0,i,j,k] = vxg[i,j,k] - bv[0]
+ rvg[1,i,j,k] = vyg[i,j,k] - bv[1]
+ rvg[2,i,j,k] = vzg[i,j,k] - bv[2]
+ return rvg
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/utilities/lib/misc_utilities.pyx
--- a/yt/utilities/lib/misc_utilities.pyx
+++ b/yt/utilities/lib/misc_utilities.pyx
@@ -233,49 +233,6 @@
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
-def obtain_rvec(data):
- # This is just to let the pointers exist and whatnot. We can't cdef them
- # inside conditionals.
- cdef np.ndarray[np.float64_t, ndim=1] xf
- cdef np.ndarray[np.float64_t, ndim=1] yf
- cdef np.ndarray[np.float64_t, ndim=1] zf
- cdef np.ndarray[np.float64_t, ndim=2] rf
- cdef np.ndarray[np.float64_t, ndim=3] xg
- cdef np.ndarray[np.float64_t, ndim=3] yg
- cdef np.ndarray[np.float64_t, ndim=3] zg
- cdef np.ndarray[np.float64_t, ndim=4] rg
- cdef np.float64_t c[3]
- cdef int i, j, k
- center = data.get_field_parameter("center")
- c[0] = center[0]; c[1] = center[1]; c[2] = center[2]
- if len(data['x'].shape) == 1:
- # One dimensional data
- xf = data['x']
- yf = data['y']
- zf = data['z']
- rf = np.empty((3, xf.shape[0]), 'float64')
- for i in range(xf.shape[0]):
- rf[0, i] = xf[i] - c[0]
- rf[1, i] = yf[i] - c[1]
- rf[2, i] = zf[i] - c[2]
- return rf
- else:
- # Three dimensional data
- xg = data['x']
- yg = data['y']
- zg = data['z']
- rg = np.empty((3, xg.shape[0], xg.shape[1], xg.shape[2]), 'float64')
- for i in range(xg.shape[0]):
- for j in range(xg.shape[1]):
- for k in range(xg.shape[2]):
- rg[0,i,j,k] = xg[i,j,k] - c[0]
- rg[1,i,j,k] = yg[i,j,k] - c[1]
- rg[2,i,j,k] = zg[i,j,k] - c[2]
- return rg
-
- at cython.boundscheck(False)
- at cython.wraparound(False)
- at cython.cdivision(True)
def kdtree_get_choices(np.ndarray[np.float64_t, ndim=3] data,
np.ndarray[np.float64_t, ndim=1] l_corner,
np.ndarray[np.float64_t, ndim=1] r_corner):
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/utilities/lib/tests/test_geometry_utils.py
--- /dev/null
+++ b/yt/utilities/lib/tests/test_geometry_utils.py
@@ -0,0 +1,30 @@
+from yt.testing import *
+from yt.utilities.lib import obtain_rvec, obtain_rv_vec
+
+_fields = ("Density", "x-velocity", "y-velocity", "z-velocity")
+
+def test_obtain_rvec():
+ pf = fake_random_pf(64, nprocs=8, fields=_fields,
+ negative = [False, True, True, True])
+
+ dd = pf.h.sphere((0.5,0.5,0.5), 0.2)
+
+ coords = obtain_rvec(dd)
+
+ r = np.sqrt(np.sum(coords*coords,axis=0))
+
+ assert_array_less(r.max(), 0.2)
+
+ assert_array_less(0.0, r.min())
+
+def test_obtain_rv_vec():
+ pf = fake_random_pf(64, nprocs=8, fields=_fields,
+ negative = [False, True, True, True])
+
+ dd = pf.h.all_data()
+
+ vels = obtain_rv_vec(dd)
+
+ assert_array_equal(vels[0,:], dd['x-velocity'])
+ assert_array_equal(vels[1,:], dd['y-velocity'])
+ assert_array_equal(vels[2,:], dd['z-velocity'])
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/utilities/math_utils.py
--- a/yt/utilities/math_utils.py
+++ b/yt/utilities/math_utils.py
@@ -674,3 +674,191 @@
[uz*ux*(1-cost)-uy*sint, uz*uy*(1-cost)+ux*sint, cost+uz**2*(1-cost)]])
return R
+
+def get_ortho_basis(normal):
+ xprime = np.cross([0.0,1.0,0.0],normal)
+ if np.sum(xprime) == 0: xprime = np.array([0.0, 0.0, 1.0])
+ yprime = np.cross(normal,xprime)
+ zprime = normal
+ return (xprime, yprime, zprime)
+
+def get_sph_r(coords):
+ # The spherical coordinates radius is simply the magnitude of the
+ # coordinate vector.
+
+ return np.sqrt(np.sum(coords**2, axis=0))
+
+def resize_vector(vector,vector_array):
+ if len(vector_array.shape) == 4:
+ res_vector = np.resize(vector,(3,1,1,1))
+ else:
+ res_vector = np.resize(vector,(3,1))
+ return res_vector
+
+def get_sph_theta(coords, normal):
+ # The angle (theta) with respect to the normal (J), is the arccos
+ # of the dot product of the normal with the normalized coordinate
+ # vector.
+
+ res_normal = resize_vector(normal, coords)
+
+ tile_shape = [1] + list(coords.shape)[1:]
+
+ J = np.tile(res_normal,tile_shape)
+
+ JdotCoords = np.sum(J*coords,axis=0)
+
+ return np.arccos( JdotCoords / np.sqrt(np.sum(coords**2,axis=0)) )
+
+def get_sph_phi(coords, normal):
+ # We have freedom with respect to what axis (xprime) to define
+ # the disk angle. Here I've chosen to use the axis that is
+ # perpendicular to the normal and the y-axis. When normal ==
+ # y-hat, then set xprime = z-hat. With this definition, when
+ # normal == z-hat (as is typical), then xprime == x-hat.
+ #
+ # The angle is then given by the arctan of the ratio of the
+ # yprime-component and the xprime-component of the coordinate
+ # vector.
+
+ (xprime, yprime, zprime) = get_ortho_basis(normal)
+
+ res_xprime = resize_vector(xprime, coords)
+ res_yprime = resize_vector(yprime, coords)
+
+ tile_shape = [1] + list(coords.shape)[1:]
+ Jx = np.tile(res_xprime,tile_shape)
+ Jy = np.tile(res_yprime,tile_shape)
+
+ Px = np.sum(Jx*coords,axis=0)
+ Py = np.sum(Jy*coords,axis=0)
+
+ return np.arctan2(Py,Px)
+
+def get_cyl_r(coords, normal):
+ # The cross product of the normal (J) with a coordinate vector
+ # gives a vector of magnitude equal to the cylindrical radius.
+
+ res_normal = resize_vector(normal, coords)
+
+ tile_shape = [1] + list(coords.shape)[1:]
+ J = np.tile(res_normal, tile_shape)
+
+ JcrossCoords = np.cross(J, coords, axisa=0, axisb=0, axisc=0)
+ return np.sqrt(np.sum(JcrossCoords**2, axis=0))
+
+def get_cyl_z(coords, normal):
+ # The dot product of the normal (J) with the coordinate vector
+ # gives the cylindrical height.
+
+ res_normal = resize_vector(normal, coords)
+
+ tile_shape = [1] + list(coords.shape)[1:]
+ J = np.tile(res_normal, tile_shape)
+
+ return np.sum(J*coords, axis=0)
+
+def get_cyl_theta(coords, normal):
+ # This is identical to the spherical phi component
+
+ return get_sph_phi(coords, normal)
+
+
+def get_cyl_r_component(vectors, theta, normal):
+ # The r of a vector is the vector dotted with rhat
+
+ (xprime, yprime, zprime) = get_ortho_basis(normal)
+
+ res_xprime = resize_vector(xprime, vectors)
+ res_yprime = resize_vector(yprime, vectors)
+
+ tile_shape = [1] + list(vectors.shape)[1:]
+ Jx = np.tile(res_xprime,tile_shape)
+ Jy = np.tile(res_yprime,tile_shape)
+
+ rhat = Jx*np.cos(theta) + Jy*np.sin(theta)
+
+ return np.sum(vectors*rhat,axis=0)
+
+def get_cyl_theta_component(vectors, theta, normal):
+ # The theta component of a vector is the vector dotted with thetahat
+
+ (xprime, yprime, zprime) = get_ortho_basis(normal)
+
+ res_xprime = resize_vector(xprime, vectors)
+ res_yprime = resize_vector(yprime, vectors)
+
+ tile_shape = [1] + list(vectors.shape)[1:]
+ Jx = np.tile(res_xprime,tile_shape)
+ Jy = np.tile(res_yprime,tile_shape)
+
+ thetahat = -Jx*np.sin(theta) + Jy*np.cos(theta)
+
+ return np.sum(vectors*thetahat, axis=0)
+
+def get_cyl_z_component(vectors, normal):
+ # The z component of a vector is the vector dotted with zhat
+ (xprime, yprime, zprime) = get_ortho_basis(normal)
+
+ res_zprime = resize_vector(zprime, vectors)
+
+ tile_shape = [1] + list(vectors.shape)[1:]
+ zhat = np.tile(res_zprime, tile_shape)
+
+ return np.sum(vectors*zhat, axis=0)
+
+def get_sph_r_component(vectors, theta, phi, normal):
+ # The r component of a vector is the vector dotted with rhat
+
+ (xprime, yprime, zprime) = get_ortho_basis(normal)
+
+ res_xprime = resize_vector(xprime, vectors)
+ res_yprime = resize_vector(yprime, vectors)
+ res_zprime = resize_vector(zprime, vectors)
+
+ tile_shape = [1] + list(vectors.shape)[1:]
+ Jx = np.tile(res_xprime,tile_shape)
+ Jy = np.tile(res_yprime,tile_shape)
+ Jz = np.tile(res_zprime,tile_shape)
+
+ rhat = Jx*np.sin(theta)*np.cos(phi) + \
+ Jy*np.sin(theta)*np.sin(phi) + \
+ Jz*np.cos(theta)
+
+ return np.sum(vectors*rhat, axis=0)
+
+def get_sph_phi_component(vectors, phi, normal):
+ # The phi component of a vector is the vector dotted with phihat
+
+ (xprime, yprime, zprime) = get_ortho_basis(normal)
+
+ res_xprime = resize_vector(xprime, vectors)
+ res_yprime = resize_vector(yprime, vectors)
+
+ tile_shape = [1] + list(vectors.shape)[1:]
+ Jx = np.tile(res_xprime,tile_shape)
+ Jy = np.tile(res_yprime,tile_shape)
+
+ phihat = -Jx*np.sin(phi) + Jy*np.cos(phi)
+
+ return np.sum(vectors*phihat, axis=0)
+
+def get_sph_theta_component(vectors, theta, phi, normal):
+ # The theta component of a vector is the vector dotted with thetahat
+
+ (xprime, yprime, zprime) = get_ortho_basis(normal)
+
+ res_xprime = resize_vector(xprime, vectors)
+ res_yprime = resize_vector(yprime, vectors)
+ res_zprime = resize_vector(zprime, vectors)
+
+ tile_shape = [1] + list(vectors.shape)[1:]
+ Jx = np.tile(res_xprime,tile_shape)
+ Jy = np.tile(res_yprime,tile_shape)
+ Jz = np.tile(res_zprime,tile_shape)
+
+ thetahat = Jx*np.cos(theta)*np.cos(phi) + \
+ Jy*np.cos(theta)*np.sin(phi) - \
+ Jz*np.sin(theta)
+
+ return np.sum(vectors*thetahat, axis=0)
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/utilities/tests/test_coordinate_conversions.py
--- /dev/null
+++ b/yt/utilities/tests/test_coordinate_conversions.py
@@ -0,0 +1,125 @@
+from yt.testing import *
+from yt.utilities.math_utils import \
+ get_sph_r_component, \
+ get_sph_theta_component, \
+ get_sph_phi_component, \
+ get_cyl_r_component, \
+ get_cyl_z_component, \
+ get_cyl_theta_component, \
+ get_cyl_r, get_cyl_theta, \
+ get_cyl_z, get_sph_r, \
+ get_sph_theta, get_sph_phi
+
+# Randomly generated coordinates in the domain [[-1,1],[-1,1],-1,1]]
+coords = np.array([[-0.41503037, -0.22102472, -0.55774212],
+ [ 0.73828247, -0.17913899, 0.64076921],
+ [ 0.08922066, -0.94254844, -0.61774511],
+ [ 0.10173242, -0.95789145, 0.16294352],
+ [ 0.73186508, -0.3109153 , 0.75728738],
+ [ 0.8757989 , -0.41475119, -0.57039201],
+ [ 0.58040762, 0.81969082, 0.46759728],
+ [-0.89983356, -0.9853683 , -0.38355343]]).T
+
+def test_spherical_coordinate_conversion():
+ normal = [0, 0, 1]
+ real_r = [ 0.72950559, 0.99384957, 1.13047198, 0.97696269,
+ 1.09807968, 1.12445067, 1.10788685, 1.38843954]
+ real_theta = [ 2.44113629, 0.87012028, 2.14891444, 1.4032274 ,
+ 0.80979483, 2.10280198, 1.13507735, 1.85068416]
+ real_phi = [-2.65224483, -0.23804243, -1.47641858, -1.46498842,
+ -0.40172325, -0.4422801 , 0.95466734, -2.31085392]
+
+ calc_r = get_sph_r(coords)
+ calc_theta = get_sph_theta(coords, normal)
+ calc_phi = get_sph_phi(coords, normal)
+
+ assert_array_almost_equal(calc_r, real_r)
+ assert_array_almost_equal(calc_theta, real_theta)
+ assert_array_almost_equal(calc_phi, real_phi)
+
+ normal = [1, 0, 0]
+ real_theta = [ 2.17598842, 0.73347681, 1.49179079, 1.46647589,
+ 0.8412984 , 0.67793705, 1.0193883 , 2.27586987]
+ real_phi = [-0.37729951, -2.86898397, -0.99063518, -1.73928995,
+ -2.75201227,-0.62870527, 2.08920872, -1.19959244]
+
+ calc_theta = get_sph_theta(coords, normal)
+ calc_phi = get_sph_phi(coords, normal)
+
+ assert_array_almost_equal(calc_theta, real_theta)
+ assert_array_almost_equal(calc_phi, real_phi)
+
+def test_cylindrical_coordiante_conversion():
+ normal = [0, 0, 1]
+ real_r = [ 0.47021498, 0.75970506, 0.94676179, 0.96327853,
+ 0.79516968, 0.96904193, 1.00437346, 1.3344104 ]
+ real_theta = [-2.65224483, -0.23804243, -1.47641858, -1.46498842,
+ -0.40172325, -0.4422801 , 0.95466734, -2.31085392]
+ real_z = [-0.55774212, 0.64076921, -0.61774511, 0.16294352,
+ 0.75728738, -0.57039201, 0.46759728, -0.38355343]
+
+ calc_r = get_cyl_r(coords, normal)
+ calc_theta = get_cyl_theta(coords, normal)
+ calc_z = get_cyl_z(coords, normal)
+
+ assert_array_almost_equal(calc_r, real_r)
+ assert_array_almost_equal(calc_theta, real_theta)
+ assert_array_almost_equal(calc_z, real_z)
+
+ normal = [1, 0, 0]
+ real_r = [ 0.59994016, 0.66533898, 1.12694569, 0.97165149,
+ 0.81862843, 0.70524152, 0.94368441, 1.05738542]
+ real_theta = [-0.37729951, -2.86898397, -0.99063518, -1.73928995,
+ -2.75201227, -0.62870527, 2.08920872, -1.19959244]
+ real_z = [-0.41503037, 0.73828247, 0.08922066, 0.10173242,
+ 0.73186508, 0.8757989 , 0.58040762, -0.89983356]
+
+ calc_r = get_cyl_r(coords, normal)
+ calc_theta = get_cyl_theta(coords, normal)
+ calc_z = get_cyl_z(coords, normal)
+
+ assert_array_almost_equal(calc_r, real_r)
+ assert_array_almost_equal(calc_theta, real_theta)
+ assert_array_almost_equal(calc_z, real_z)
+
+def test_spherical_coordinate_projections():
+ normal = [0, 0, 1]
+ theta = get_sph_theta(coords, normal)
+ phi = get_sph_phi(coords, normal)
+ zero = np.tile(0,coords.shape[1])
+
+ # Purely radial field
+ vecs = np.array([np.sin(theta)*np.cos(phi), np.sin(theta)*np.sin(phi), np.cos(theta)])
+ assert_array_almost_equal(zero, get_sph_theta_component(vecs, theta, phi, normal))
+ assert_array_almost_equal(zero, get_sph_phi_component(vecs, phi, normal))
+
+ # Purely toroidal field
+ vecs = np.array([-np.sin(phi), np.cos(phi), zero])
+ assert_array_almost_equal(zero, get_sph_theta_component(vecs, theta, phi, normal))
+ assert_array_almost_equal(zero, get_sph_r_component(vecs, theta, phi, normal))
+
+ # Purely poloidal field
+ vecs = np.array([np.cos(theta)*np.cos(phi), np.cos(theta)*np.sin(phi), -np.sin(theta)])
+ assert_array_almost_equal(zero, get_sph_phi_component(vecs, phi, normal))
+ assert_array_almost_equal(zero, get_sph_r_component(vecs, theta, phi, normal))
+
+def test_cylindrical_coordinate_projections():
+ normal = [0, 0, 1]
+ theta = get_cyl_theta(coords, normal)
+ z = get_cyl_z(coords, normal)
+ zero = np.tile(0, coords.shape[1])
+
+ # Purely radial field
+ vecs = np.array([np.cos(theta), np.sin(theta), zero])
+ assert_array_almost_equal(zero, get_cyl_theta_component(vecs, theta, normal))
+ assert_array_almost_equal(zero, get_cyl_z_component(vecs, normal))
+
+ # Purely toroidal field
+ vecs = np.array([-np.sin(theta), np.cos(theta), zero])
+ assert_array_almost_equal(zero, get_cyl_z_component(vecs, normal))
+ assert_array_almost_equal(zero, get_cyl_r_component(vecs, theta, normal))
+
+ # Purely z field
+ vecs = np.array([zero, zero, z])
+ assert_array_almost_equal(zero, get_cyl_theta_component(vecs, theta, normal))
+ assert_array_almost_equal(zero, get_cyl_r_component(vecs, theta, normal))
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/utilities/tests/test_decompose.py
--- /dev/null
+++ b/yt/utilities/tests/test_decompose.py
@@ -0,0 +1,96 @@
+"""
+Test suite for cartesian domain decomposition.
+
+Author: Kacper Kowalik <xarthisius.kk at gmail.com>
+Affiliation: CA UMK
+Homepage: http://yt-project.org/
+License:
+ Copyright (C) 2012 Kacper Kowalik. 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/>.
+"""
+
+from yt.testing import assert_array_equal, assert_almost_equal
+import numpy as np
+import yt.utilities.decompose as dec
+
+
+def setup():
+ pass
+
+
+def test_psize_2d():
+ procs = dec.get_psize(np.array([5, 1, 7]), 6)
+ assert_array_equal(procs, np.array([3, 1, 2]))
+ procs = dec.get_psize(np.array([1, 7, 5]), 6)
+ assert_array_equal(procs, np.array([1, 2, 3]))
+ procs = dec.get_psize(np.array([7, 5, 1]), 6)
+ assert_array_equal(procs, np.array([2, 3, 1]))
+
+
+def test_psize_3d():
+ procs = dec.get_psize(np.array([33, 35, 37]), 12)
+ assert_array_equal(procs, np.array([3, 2, 2]))
+
+
+def test_decomposition_2d():
+ array = np.ones((7, 5, 1))
+ bbox = np.array([[-0.7, 0.0], [1.5, 2.0], [0.0, 0.7]])
+ ledge, redge, data = dec.decompose_array(array, np.array([2, 3, 1]), bbox)
+
+ assert_array_equal(data[1].shape, np.array([3, 2, 1]))
+
+ gold_le = np.array([
+ [-0.7, 1.5, 0.0], [-0.7, 1.6, 0.0],
+ [-0.7, 1.8, 0.0], [-0.4, 1.5, 0.0],
+ [-0.4, 1.6, 0.0], [-0.4, 1.8, 0.0]
+ ])
+ assert_almost_equal(ledge, gold_le, 8)
+
+ gold_re = np.array(
+ [[-0.4, 1.6, 0.7], [-0.4, 1.8, 0.7],
+ [-0.4, 2.0, 0.7], [0.0, 1.6, 0.7],
+ [0.0, 1.8, 0.7], [0.0, 2.0, 0.7]]
+ )
+ assert_almost_equal(redge, gold_re, 8)
+
+
+def test_decomposition_3d():
+ array = np.ones((33, 35, 37))
+ bbox = np.array([[0., 1.0], [-1.5, 1.5], [1.0, 2.5]])
+
+ ledge, redge, data = dec.decompose_array(array, np.array([3, 2, 2]), bbox)
+ assert_array_equal(data[0].shape, np.array([11, 17, 18]))
+
+ gold_le = np.array(
+ [[0.00000, -1.50000, 1.00000], [0.00000, -1.50000, 1.72973],
+ [0.00000, -0.04286, 1.00000], [0.00000, -0.04286, 1.72973],
+ [0.33333, -1.50000, 1.00000], [0.33333, -1.50000, 1.72973],
+ [0.33333, -0.04286, 1.00000], [0.33333, -0.04286, 1.72973],
+ [0.66667, -1.50000, 1.00000], [0.66667, -1.50000, 1.72973],
+ [0.66667, -0.04286, 1.00000], [0.66667, -0.04286, 1.72973]]
+ )
+ assert_almost_equal(ledge, gold_le, 5)
+
+ gold_re = np.array(
+ [[0.33333, -0.04286, 1.72973], [0.33333, -0.04286, 2.50000],
+ [0.33333, 1.50000, 1.72973], [0.33333, 1.50000, 2.50000],
+ [0.66667, -0.04286, 1.72973], [0.66667, -0.04286, 2.50000],
+ [0.66667, 1.50000, 1.72973], [0.66667, 1.50000, 2.50000],
+ [1.00000, -0.04286, 1.72973], [1.00000, -0.04286, 2.50000],
+ [1.00000, 1.50000, 1.72973], [1.00000, 1.50000, 2.50000]]
+ )
+ assert_almost_equal(redge, gold_re, 5)
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/utilities/tests/test_kdtrees.py
--- a/yt/utilities/tests/test_kdtrees.py
+++ b/yt/utilities/tests/test_kdtrees.py
@@ -26,10 +26,7 @@
from yt.testing import *
try:
- from yt.utilities.kdtree import \
- chainHOP_tags_dens, \
- create_tree, fKD, find_nn_nearest_neighbors, \
- free_tree, find_chunk_nearest_neighbors
+ from yt.utilities.kdtree.api import *
except ImportError:
mylog.debug("The Fortran kD-Tree did not import correctly.")
@@ -39,10 +36,14 @@
pass
def test_fortran_tree():
- # This test makes sure that the fortran kdtree is finding the correct
- # nearest neighbors.
+ r"""This test makes sure that the fortran kdtree is finding the correct
+ nearest neighbors.
+ """
# Four points.
- fKD.pos = np.empty((3, 4), dtype='float64', order='F')
+ try:
+ fKD.pos = np.empty((3, 4), dtype='float64', order='F')
+ except NameError:
+ return
# Make four points by hand that, in particular, will allow us to test
# the periodicity of the kdtree.
points = np.array([0.01, 0.5, 0.98, 0.99])
@@ -70,8 +71,9 @@
assert_array_equal(fKD.tags, tags)
def test_cython_tree():
- # This test makes sure that the cython kdtree is finding the correct
- # nearest neighbors.
+ r"""This test makes sure that the cython kdtree is finding the correct
+ nearest neighbors.
+ """
# Four points.
pos = np.empty((4, 3), dtype='float64')
# Make four points by hand that, in particular, will allow us to test
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/visualization/plot_modifications.py
--- a/yt/visualization/plot_modifications.py
+++ b/yt/visualization/plot_modifications.py
@@ -213,7 +213,7 @@
class ContourCallback(PlotCallback):
_type_name = "contour"
def __init__(self, field, ncont=5, factor=4, clim=None,
- plot_args = None):
+ plot_args = None, label = False, label_args = None):
"""
annotate_contour(self, field, ncont=5, factor=4, take_log=False, clim=None,
plot_args = None):
@@ -232,6 +232,10 @@
self.clim = clim
if plot_args is None: plot_args = {'colors':'k'}
self.plot_args = plot_args
+ self.label = label
+ if label_args is None:
+ label_args = {}
+ self.label_args = label_args
def __call__(self, plot):
x0, x1 = plot.xlim
@@ -292,10 +296,14 @@
if self.clim is not None:
self.ncont = np.linspace(self.clim[0], self.clim[1], ncont)
- plot._axes.contour(xi,yi,zi,self.ncont, **self.plot_args)
+ cset = plot._axes.contour(xi,yi,zi,self.ncont, **self.plot_args)
plot._axes.set_xlim(xx0,xx1)
plot._axes.set_ylim(yy0,yy1)
plot._axes.hold(False)
+
+ if self.label:
+ plot._axes.clabel(cset, **self.label_args)
+
class GridBoundaryCallback(PlotCallback):
_type_name = "grids"
@@ -366,39 +374,30 @@
class StreamlineCallback(PlotCallback):
_type_name = "streamlines"
- def __init__(self, field_x, field_y, factor=6.0, nx=16, ny=16,
- xstart=(0,1), ystart=(0,1), nsample=256,
- start_at_xedge=False, start_at_yedge=False,
- plot_args=None):
+ def __init__(self, field_x, field_y, factor = 16,
+ density = 1, arrowsize = 1, arrowstyle = None,
+ color = None, normalize = False):
"""
- annotate_streamlines(field_x, field_y, factor=6.0, nx=16, ny=16,
- xstart=(0,1), ystart=(0,1), nsample=256,
- start_at_xedge=False, start_at_yedge=False,
- plot_args=None):
+ annotate_streamlines(field_x, field_y, factor = 16, density = 1,
+ arrowsize = 1, arrowstyle = None,
+ color = None, normalize = False):
Add streamlines to any plot, using the *field_x* and *field_y*
- from the associated data, using *nx* and *ny* starting points
- that are bounded by *xstart* and *ystart*. To begin
- streamlines from the left edge of the plot, set
- *start_at_xedge* to True; for the bottom edge, use
- *start_at_yedge*. A line with the qmean vector magnitude will
- cover 1.0/*factor* of the image.
+ from the associated data, skipping every *factor* datapoints like
+ 'quiver'. *density* is the index of the amount of the streamlines.
"""
PlotCallback.__init__(self)
self.field_x = field_x
self.field_y = field_y
- self.xstart = xstart
- self.ystart = ystart
- self.nsample = nsample
+ self.bv_x = self.bv_y = 0
self.factor = factor
- if start_at_xedge:
- self.data_size = (1,ny)
- elif start_at_yedge:
- self.data_size = (nx,1)
- else:
- self.data_size = (nx,ny)
- if plot_args is None: plot_args = {'color':'k', 'linestyle':'-'}
- self.plot_args = plot_args
+ self.dens = density
+ self.arrowsize = arrowsize
+ if arrowstyle is None : arrowstyle='-|>'
+ self.arrowstyle = arrowstyle
+ if color is None : color = "#000000"
+ self.color = color
+ self.normalize = normalize
def __call__(self, plot):
x0, x1 = plot.xlim
@@ -406,43 +405,31 @@
xx0, xx1 = plot._axes.get_xlim()
yy0, yy1 = plot._axes.get_ylim()
plot._axes.hold(True)
- nx = plot.image._A.shape[0]
- ny = plot.image._A.shape[1]
+ nx = plot.image._A.shape[0] / self.factor
+ ny = plot.image._A.shape[1] / self.factor
pixX = _MPL.Pixelize(plot.data['px'],
plot.data['py'],
plot.data['pdx'],
plot.data['pdy'],
- plot.data[self.field_x],
+ plot.data[self.field_x] - self.bv_x,
int(nx), int(ny),
- (x0, x1, y0, y1),)
+ (x0, x1, y0, y1),).transpose()
pixY = _MPL.Pixelize(plot.data['px'],
plot.data['py'],
plot.data['pdx'],
plot.data['pdy'],
- plot.data[self.field_y],
+ plot.data[self.field_y] - self.bv_y,
int(nx), int(ny),
- (x0, x1, y0, y1),)
- r0 = np.mgrid[self.xstart[0]*nx:self.xstart[1]*nx:self.data_size[0]*1j,
- self.ystart[0]*ny:self.ystart[1]*ny:self.data_size[1]*1j]
- lines = np.zeros((self.nsample, 2, self.data_size[0], self.data_size[1]))
- lines[0,:,:,:] = r0
- mag = np.sqrt(pixX**2 + pixY**2)
- scale = np.sqrt(nx*ny) / (self.factor * mag.mean())
- dt = 1.0 / (self.nsample-1)
- for i in range(1,self.nsample):
- xt = lines[i-1,0,:,:]
- yt = lines[i-1,1,:,:]
- ix = np.maximum(np.minimum((xt).astype('int'), nx-1), 0)
- iy = np.maximum(np.minimum((yt).astype('int'), ny-1), 0)
- lines[i,0,:,:] = xt + dt * pixX[ix,iy] * scale
- lines[i,1,:,:] = yt + dt * pixY[ix,iy] * scale
- # scale into data units
- lines[:,0,:,:] = lines[:,0,:,:] * (xx1 - xx0) / nx + xx0
- lines[:,1,:,:] = lines[:,1,:,:] * (yy1 - yy0) / ny + yy0
- for i in range(self.data_size[0]):
- for j in range(self.data_size[1]):
- plot._axes.plot(lines[:,0,i,j], lines[:,1,i,j],
- **self.plot_args)
+ (x0, x1, y0, y1),).transpose()
+ X,Y = (na.linspace(xx0,xx1,nx,endpoint=True),
+ na.linspace(yy0,yy1,ny,endpoint=True))
+ if self.normalize:
+ nn = na.sqrt(pixX**2 + pixY**2)
+ pixX /= nn
+ pixY /= nn
+ plot._axes.streamplot(X,Y, pixX, pixY, density=self.dens,
+ arrowsize=self.arrowsize, arrowstyle=self.arrowstyle,
+ color=self.color, norm=self.normalize)
plot._axes.set_xlim(xx0,xx1)
plot._axes.set_ylim(yy0,yy1)
plot._axes.hold(False)
diff -r 814a93ee320766d02a677b07a441cbc3dcc660a5 -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 yt/visualization/streamlines.py
--- a/yt/visualization/streamlines.py
+++ b/yt/visualization/streamlines.py
@@ -146,7 +146,8 @@
@parallel_passthrough
def _finalize_parallel(self,data):
self.streamlines = self.comm.mpi_allreduce(self.streamlines, op='sum')
- self.magnitudes = self.comm.mpi_allreduce(self.magnitudes, op='sum')
+ if self.get_magnitude:
+ self.magnitudes = self.comm.mpi_allreduce(self.magnitudes, op='sum')
def _integrate_through_brick(self, node, stream, step,
periodic=False, mag=None):
https://bitbucket.org/yt_analysis/yt/changeset/c88a92f30151/
changeset: c88a92f30151
branch: yt
user: scopatz
date: 2012-10-23 21:55:26
summary: bugfix for contour annotations.
affected #: 1 file
diff -r df3c48e34cc922e10cf3d1ed4b95bc126b70d193 -r c88a92f30151a943cd52feebdcf5485fda5ed3fa yt/visualization/plot_modifications.py
--- a/yt/visualization/plot_modifications.py
+++ b/yt/visualization/plot_modifications.py
@@ -294,7 +294,7 @@
self.clim = (np.log10(self.clim[0]), np.log10(self.clim[1]))
if self.clim is not None:
- self.ncont = np.linspace(self.clim[0], self.clim[1], ncont)
+ self.ncont = np.linspace(self.clim[0], self.clim[1], self.ncont)
cset = plot._axes.contour(xi,yi,zi,self.ncont, **self.plot_args)
plot._axes.set_xlim(xx0,xx1)
https://bitbucket.org/yt_analysis/yt/changeset/6f48556cbe09/
changeset: 6f48556cbe09
branch: yt
user: scopatz
date: 2012-10-23 23:20:47
summary: fixed yt/testing.py issue.
affected #: 1 file
diff -r c88a92f30151a943cd52feebdcf5485fda5ed3fa -r 6f48556cbe09a22d1d200de4b36985d660441f18 yt/testing.py
--- a/yt/testing.py
+++ b/yt/testing.py
@@ -24,10 +24,12 @@
import numpy as np
from yt.funcs import *
-from numpy.testing import assert_array_equal, assert_equal, assert_almost_equal
+from numpy.testing import assert_array_equal, assert_almost_equal, \
+ assert_approx_equal, assert_array_almost_equal, assert_equal, \
+ assert_array_less, assert_string_equal, assert_array_almost_equal_nulp
-def assert_rel_equal(a1, a2, decimels):
- return assert_almost_equal(a1/a2, 1.0, decimels)
+def assert_rel_equal(a1, a2, decimals):
+ return assert_almost_equal(a1/a2, 1.0, decimals)
def amrspace(extent, levels=7, cells=8):
"""Creates two numpy arrays representing the left and right bounds of
@@ -137,11 +139,16 @@
ndims = [ndims, ndims, ndims]
else:
assert(len(ndims) == 3)
- if negative:
- offset = 0.5
- else:
- offset = 0.0
+ if not iterable(negative):
+ negative = [negative for f in fields]
+ assert(len(fields) == len(negative))
+ offsets = []
+ for n in negative:
+ if n:
+ offsets.append(0.5)
+ else:
+ offsets.append(0.0)
data = dict((field, (np.random.random(ndims) - offset) * peak_value)
- for field in fields)
+ for field,offset in zip(fields,offsets))
ug = load_uniform_grid(data, ndims, 1.0, nprocs = nprocs)
return ug
https://bitbucket.org/yt_analysis/yt/changeset/5f5bfa8f287f/
changeset: 5f5bfa8f287f
branch: yt
user: scopatz
date: 2012-10-24 02:52:54
summary: rm TimeCallback under Nathan's suggestion.
affected #: 1 file
diff -r 6f48556cbe09a22d1d200de4b36985d660441f18 -r 5f5bfa8f287f61321911b9e3ee2727aa692d89a8 yt/visualization/plot_modifications.py
--- a/yt/visualization/plot_modifications.py
+++ b/yt/visualization/plot_modifications.py
@@ -450,30 +450,6 @@
plot._axes.set_xlabel(self.label)
plot._axes.set_ylabel(self.label)
-class TimeCallback(PlotCallback):
- _type_name = "time"
- def __init__(self, format_code='10.7e'):
- """
- This annotates the plot with the current simulation time.
- For now, the time is displayed in seconds.
- *format_code* can be optionally set, allowing a custom
- c-style format code for the time display.
- """
- self.format_code = format_code
- PlotCallback.__init__(self)
-
- def __call__(self, plot):
- current_time = plot.pf.current_time/plot.pf['Time']
- timestring = format(current_time,self.format_code)
- base = timestring[:timestring.find('e')]
- exponent = timestring[timestring.find('e')+1:]
- if exponent[0] == '+':
- exponent = exponent[1:]
- timestring = r'$t\/=\/'+base+''+r'\times\,10^{'+exponent+r'}\, \rm{s}$'
- from mpl_toolkits.axes_grid1.anchored_artists import AnchoredText
- at = AnchoredText(timestring, prop=dict(size=12), frameon=True, loc=4)
- plot._axes.add_artist(at)
-
def get_smallest_appropriate_unit(v, pf):
max_nu = 1e30
good_u = None
https://bitbucket.org/yt_analysis/yt/changeset/981d0cf55bb1/
changeset: 981d0cf55bb1
branch: yt
user: MatthewTurk
date: 2012-10-24 13:45:20
summary: Merged in scopatz/yt (pull request #313)
affected #: 2 files
diff -r 221b5163bffa2e478a2b65d80090adf1be45bb2e -r 981d0cf55bb18724b63a29decb21fbd8d5d4af67 yt/visualization/plot_modifications.py
--- a/yt/visualization/plot_modifications.py
+++ b/yt/visualization/plot_modifications.py
@@ -7,6 +7,8 @@
Affiliation: UC Berkeley
Author: Stephen Skory <s at skory.us>
Affiliation: UC San Diego
+Author: Anthony Scopatz <scopatz at gmail.com>
+Affiliation: The University of Chicago
Homepage: http://yt-project.org/
License:
Copyright (C) 2008-2011 Matthew Turk, JS Oishi, Stephen Skory. All Rights Reserved.
@@ -292,7 +294,7 @@
self.clim = (np.log10(self.clim[0]), np.log10(self.clim[1]))
if self.clim is not None:
- self.ncont = np.linspace(self.clim[0], self.clim[1], ncont)
+ self.ncont = np.linspace(self.clim[0], self.clim[1], self.ncont)
cset = plot._axes.contour(xi,yi,zi,self.ncont, **self.plot_args)
plot._axes.set_xlim(xx0,xx1)
@@ -448,30 +450,6 @@
plot._axes.set_xlabel(self.label)
plot._axes.set_ylabel(self.label)
-class TimeCallback(PlotCallback):
- _type_name = "time"
- def __init__(self, format_code='10.7e'):
- """
- This annotates the plot with the current simulation time.
- For now, the time is displayed in seconds.
- *format_code* can be optionally set, allowing a custom
- c-style format code for the time display.
- """
- self.format_code = format_code
- PlotCallback.__init__(self)
-
- def __call__(self, plot):
- current_time = plot.pf.current_time/plot.pf['Time']
- timestring = format(current_time,self.format_code)
- base = timestring[:timestring.find('e')]
- exponent = timestring[timestring.find('e')+1:]
- if exponent[0] == '+':
- exponent = exponent[1:]
- timestring = r'$t\/=\/'+base+''+r'\times\,10^{'+exponent+r'}\, \rm{s}$'
- from mpl_toolkits.axes_grid1.anchored_artists import AnchoredText
- at = AnchoredText(timestring, prop=dict(size=12), frameon=True, loc=4)
- plot._axes.add_artist(at)
-
def get_smallest_appropriate_unit(v, pf):
max_nu = 1e30
good_u = None
@@ -1111,3 +1089,152 @@
def __call__(self,plot):
plot._axes.set_title(self.title)
+class FlashRayDataCallback(PlotCallback):
+ _type_name = "flash_ray_data"
+ def __init__(self, cmap_name='bone', sample=None):
+ """
+ annotate_flash_ray_data(cmap_name='bone', sample=None)
+
+ Adds ray trace data to the plot. *cmap_name* is the name of the color map
+ ('bone', 'jet', 'hot', etc). *sample* dictates the amount of down sampling
+ to do to prevent all of the rays from being plotted. This may be None
+ (plot all rays, default), an integer (step size), or a slice object.
+ """
+ self.cmap_name = cmap_name
+ self.sample = sample if isinstance(sample, slice) else slice(None, None, sample)
+
+ def __call__(self, plot):
+ ray_data = plot.data.pf._handle["RayData"][:]
+ idx = ray_data[:,0].argsort(kind="mergesort")
+ ray_data = ray_data[idx]
+
+ tags = ray_data[:,0]
+ coords = ray_data[:,1:3]
+ power = ray_data[:,4]
+ power /= power.max()
+ cx, cy = self.convert_to_plot(plot, coords.T)
+ coords[:,0], coords[:,1] = cx, cy
+ splitidx = np.argwhere(0 < (tags[1:] - tags[:-1])) + 1
+ coords = np.split(coords, splitidx.flat)[self.sample]
+ power = np.split(power, splitidx.flat)[self.sample]
+ cmap = matplotlib.cm.get_cmap(self.cmap_name)
+
+ plot._axes.hold(True)
+ colors = [cmap(p.max()) for p in power]
+ lc = matplotlib.collections.LineCollection(coords, colors=colors)
+ plot._axes.add_collection(lc)
+ plot._axes.hold(False)
+
+
+class TimestampCallback(PlotCallback):
+ _type_name = "timestamp"
+ _time_conv = {
+ 'as': 1e-18,
+ 'attosec': 1e-18,
+ 'attosecond': 1e-18,
+ 'attoseconds': 1e-18,
+ 'fs': 1e-15,
+ 'femtosec': 1e-15,
+ 'femtosecond': 1e-15,
+ 'femtoseconds': 1e-15,
+ 'ps': 1e-12,
+ 'picosec': 1e-12,
+ 'picosecond': 1e-12,
+ 'picoseconds': 1e-12,
+ 'ns': 1e-9,
+ 'nanosec': 1e-9,
+ 'nanosecond':1e-9,
+ 'nanoseconds' : 1e-9,
+ 'us': 1e-6,
+ 'microsec': 1e-6,
+ 'microsecond': 1e-6,
+ 'microseconds': 1e-6,
+ 'ms': 1e-3,
+ 'millisec': 1e-3,
+ 'millisecond': 1e-3,
+ 'milliseconds': 1e-3,
+ 's': 1.0,
+ 'sec': 1.0,
+ 'second':1.0,
+ 'seconds': 1.0,
+ 'm': 60.0,
+ 'min': 60.0,
+ 'minute': 60.0,
+ 'minutes': 60.0,
+ 'h': 3600.0,
+ 'hour': 3600.0,
+ 'hours': 3600.0,
+ 'd': 86400.0,
+ 'day': 86400.0,
+ 'days': 86400.0,
+ 'y': 86400.0*365.25,
+ 'year': 86400.0*365.25,
+ 'years': 86400.0*365.25,
+ 'ev': 1e-9 * 7.6e-8 / 6.03,
+ 'kev': 1e-12 * 7.6e-8 / 6.03,
+ 'mev': 1e-15 * 7.6e-8 / 6.03,
+ }
+
+ def __init__(self, x, y, units=None, format="{time:.3G} {units}", **kwargs):
+ """
+ annotate_timestamp(x, y, units=None, format="{time:.3G} {units}", **kwargs)
+
+ Adds the current time to the plot at point given by *x* and *y*. If *units*
+ is given ('s', 'ms', 'ns', etc), it will covert the time to this basis. If
+ *units* is None, it will attempt to figure out the correct value by which to
+ scale. The *format* keyword is a template string that will be evaluated and
+ displayed on the plot. All other *kwargs* will be passed to the text()
+ method on the plot axes. See matplotlib's text() functions for more
+ information.
+ """
+ self.x = x
+ self.y = y
+ self.format = format
+ self.units = units
+ self.kwargs = {'color': 'w'}
+ self.kwargs.update(kwargs)
+
+ def __call__(self, plot):
+ if self.units is None:
+ t = plot.data.pf.current_time
+ scale_keys = ['as', 'fs', 'ps', 'ns', 'us', 'ms', 's']
+ self.units = 's'
+ for k in scale_keys:
+ if t < self._time_conv[k]:
+ break
+ self.units = k
+ t = plot.data.pf.current_time / self._time_conv[self.units.lower()]
+ if self.units == 'us':
+ self.units = '$\\mu s$'
+ s = self.format.format(time=t, units=self.units)
+ plot._axes.hold(True)
+ plot._axes.text(self.x, self.y, s, **self.kwargs)
+ plot._axes.hold(False)
+
+
+class MaterialBoundaryCallback(ContourCallback):
+ _type_name = "material_boundary"
+ def __init__(self, field='targ', ncont=1, factor=4, clim=(0.9, 1.0), **kwargs):
+ """
+ annotate_material_boundary(self, field='targ', ncont=1, factor=4,
+ clim=(0.9, 1.0), **kwargs):
+
+ Add the limiting contours of *field* to the plot. Nominally, *field* is
+ the target material but may be any other field present in the hierarchy.
+ The number of contours generated is given by *ncount*, *factor* governs
+ the number of points used in the interpolation, and *clim* gives the
+ (upper, lower) limits for contouring. For this to truly be the boundary
+ *clim* should be close to the edge. For example the default is (0.9, 1.0)
+ for 'targ' which is defined on the range [0.0, 1.0]. All other *kwargs*
+ will be passed to the contour() method on the plot axes. See matplotlib
+ for more information.
+ """
+ plot_args = {'colors': 'w'}
+ plot_args.update(kwargs)
+ super(MaterialBoundaryCallback, self).__init__(field=field, ncont=ncont,
+ factor=factor, clim=clim,
+ plot_args=plot_args)
+
+ def __call__(self, plot):
+ super(MaterialBoundaryCallback, self).__call__(plot)
+
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