[yt-svn] commit/yt: 16 new changesets
commits-noreply at bitbucket.org
commits-noreply at bitbucket.org
Tue Jun 20 08:25:35 PDT 2017
16 new commits in yt:
https://bitbucket.org/yt_analysis/yt/commits/7f9138467af0/
Changeset: 7f9138467af0
User: jzuhone
Date: 2017-06-09 13:40:15+00:00
Summary: First crack at implementing 0 and 1-dimensional results for region expressions
Affected #: 1 file
diff -r 46ddbe0ff60d4384ed866781ff78d117e2bc2607 -r 7f9138467af0074687e0407fd395533e431f03a5 yt/data_objects/region_expression.py
--- a/yt/data_objects/region_expression.py
+++ b/yt/data_objects/region_expression.py
@@ -56,7 +56,12 @@
# OK, now we need to look at our slices. How many are a specific
# coordinate?
- if not all(isinstance(v, slice) for v in item):
+ nslices = sum([isinstance(v, slice) for v in item])
+ if nslices == 0:
+ return self._create_point(item)
+ elif nslices == 1:
+ return self._create_ray(item)
+ elif nslices == 2:
return self._create_slice(item)
else:
if all(s.start is s.stop is s.step is None for s in item):
@@ -133,3 +138,24 @@
if all(d is not None for d in dims):
return self.ds.arbitrary_grid(left_edge, right_edge, dims)
return self.ds.region(center, left_edge, right_edge)
+
+ def _create_point(self, point_tuple):
+ coord = [self._spec_to_value(p) for p in point_tuple]
+ return self.ds.point(coord)
+
+ def _create_ray(self, ray_tuple):
+ axis = None
+ new_slice = []
+ coord = []
+ for ax, v in enumerate(ray_tuple):
+ if not isinstance(v, slice):
+ coord.append(self._spec_to_value(v))
+ new_slice.append(slice(None, None, None))
+ else:
+ if axis is not None: raise RuntimeError
+ axis = ax
+ new_slice.append(v)
+ if axis == 1: coord = [coord[1], coord[0]]
+ source = self._create_region(new_slice)
+ ray = self.ds.ortho_ray(axis, coord, data_source=source)
+ return ray
\ No newline at end of file
https://bitbucket.org/yt_analysis/yt/commits/45bbec4dc9a5/
Changeset: 45bbec4dc9a5
User: jzuhone
Date: 2017-06-10 02:06:13+00:00
Summary: Raise a NotImplementedError for now on steps along rays
Affected #: 1 file
diff -r 7f9138467af0074687e0407fd395533e431f03a5 -r 45bbec4dc9a56c5dd94226c2d6a4912b1a991aef yt/data_objects/region_expression.py
--- a/yt/data_objects/region_expression.py
+++ b/yt/data_objects/region_expression.py
@@ -158,4 +158,6 @@
if axis == 1: coord = [coord[1], coord[0]]
source = self._create_region(new_slice)
ray = self.ds.ortho_ray(axis, coord, data_source=source)
+ if getattr(new_slice[axis].step, "imag", 0.0) != 0.0:
+ raise NotImplementedError
return ray
\ No newline at end of file
https://bitbucket.org/yt_analysis/yt/commits/74d8fb65b011/
Changeset: 74d8fb65b011
User: jzuhone
Date: 2017-06-12 14:00:21+00:00
Summary: Convert coordinates to code_length in ortho_ray
Affected #: 1 file
diff -r 45bbec4dc9a56c5dd94226c2d6a4912b1a991aef -r 74d8fb65b01117bcaaa111a9ab8ac750819fb167 yt/data_objects/selection_data_containers.py
--- a/yt/data_objects/selection_data_containers.py
+++ b/yt/data_objects/selection_data_containers.py
@@ -137,7 +137,9 @@
# Even though we may not be using x,y,z we use them here.
self.px_dx = 'd%s'%('xyz'[self.px_ax])
self.py_dx = 'd%s'%('xyz'[self.py_ax])
- self.px, self.py = coords
+ # Convert coordinates to code length.
+ self.px = self.ds.quan(coords[0], "code_length")
+ self.py = self.ds.quan(coords[1], "code_length")
self.sort_by = 'xyz'[self.axis]
@property
https://bitbucket.org/yt_analysis/yt/commits/6597fd87c6cb/
Changeset: 6597fd87c6cb
User: jzuhone
Date: 2017-06-12 14:04:06+00:00
Summary: Always convert the coordinate to code length
Affected #: 1 file
diff -r 74d8fb65b01117bcaaa111a9ab8ac750819fb167 -r 6597fd87c6cb7e48cb3a08fe0dcf07bcbc674905 yt/data_objects/region_expression.py
--- a/yt/data_objects/region_expression.py
+++ b/yt/data_objects/region_expression.py
@@ -71,9 +71,10 @@
def _spec_to_value(self, input_tuple):
if not isinstance(input_tuple, tuple):
# We now assume that it's in code_length
- return self.ds.quan(input_tuple, 'code_length')
- v, u = input_tuple
- value = self.ds.quan(v, u)
+ value = self.ds.quan(input_tuple, 'code_length')
+ else:
+ v, u = input_tuple
+ value = self.ds.quan(v, u).in_units("code_length")
return value
def _create_slice(self, slice_tuple):
https://bitbucket.org/yt_analysis/yt/commits/cd00e879b0ae/
Changeset: cd00e879b0ae
User: jzuhone
Date: 2017-06-12 14:25:45+00:00
Summary: ortho_ray should take characters as axes as well as ints
Affected #: 1 file
diff -r 6597fd87c6cb7e48cb3a08fe0dcf07bcbc674905 -r cd00e879b0ae3f8910049258d4752effcb08eb91 yt/data_objects/selection_data_containers.py
--- a/yt/data_objects/selection_data_containers.py
+++ b/yt/data_objects/selection_data_containers.py
@@ -23,7 +23,8 @@
ensure_list, \
iterable, \
validate_width_tuple, \
- fix_length
+ fix_length, \
+ fix_axis
from yt.geometry.selection_routines import \
points_in_cells
from yt.units.yt_array import \
@@ -88,8 +89,8 @@
Parameters
----------
- axis : int
- The axis along which to cast the ray. Can be 0, 1, or 2 for x, y, z.
+ axis : int or char
+ The axis along which to slice. Can be 0, 1, or 2 for x, y, z.
coords : tuple of floats
The (plane_x, plane_y) coordinates at which to cast the ray. Note
that this is in the plane coordinates: so if you are casting along
@@ -129,7 +130,7 @@
def __init__(self, axis, coords, ds=None,
field_parameters=None, data_source=None):
super(YTOrthoRay, self).__init__(ds, field_parameters, data_source)
- self.axis = axis
+ self.axis = fix_axis(axis, self.ds)
xax = self.ds.coordinates.x_axis[self.axis]
yax = self.ds.coordinates.y_axis[self.axis]
self.px_ax = xax
https://bitbucket.org/yt_analysis/yt/commits/b2eec238d068/
Changeset: b2eec238d068
User: jzuhone
Date: 2017-06-12 14:26:02+00:00
Summary: Tests for new functionality
Affected #: 1 file
diff -r cd00e879b0ae3f8910049258d4752effcb08eb91 -r b2eec238d0681f5612f99766d81f396799efb78f yt/data_objects/tests/test_dataset_access.py
--- a/yt/data_objects/tests/test_dataset_access.py
+++ b/yt/data_objects/tests/test_dataset_access.py
@@ -76,6 +76,40 @@
frb2 = ds.r[0.5, ::1024j, ::512j]
assert_equal(frb1["density"], frb2["density"])
+ # Test slice which doesn't cover the whole domain
+ box = ds.box([0.0, 0.25, 0.25], [1.0, 0.75, 0.75])
+
+ sl3 = ds.r[0.5, 0.25:0.75, 0.25:0.75]
+ sl4 = ds.slice("x", 0.5, data_source=box)
+ assert_equal(sl3["density"], sl4["density"])
+
+ frb3 = sl3.to_frb(width = 0.5, height = 0.5, resolution = (1024, 512))
+ frb4 = ds.r[0.5, 0.25:0.75:1024j, 0.25:0.75:512j]
+ assert_equal(frb3["density"], frb4["density"])
+
+def test_point_from_r():
+ ds = fake_amr_ds(fields = ["density"])
+ pt1 = ds.r[0.5,0.3,0.1]
+ pt2 = ds.point([0.5,0.3,0.1])
+ assert_equal(pt1["density"], pt2["density"])
+
+def test_ortho_ray_from_r():
+ ds = fake_amr_ds(fields = ["density"])
+ ray1 = ds.r[:,0.3,0.2]
+ ray2 = ds.ortho_ray("x",[0.3, 0.2])
+ assert_equal(ray1["density"], ray2["density"])
+
+ # the y-coord is funny so test it too
+ ray3 = ds.r[0.3,:,0.2]
+ ray4 = ds.ortho_ray("y", [0.2, 0.3])
+ assert_equal(ray3["density"], ray4["density"])
+
+ # Test ray which doesn't cover the whole domain
+ box = ds.box([0.25, 0.0, 0.0], [0.75, 1.0, 1.0])
+ ray5 = ds.r[0.25:0.75,0.3,0.2]
+ ray6 = ds.ortho_ray("x", [0.3, 0.2], data_source=box)
+ assert_equal(ray5["density"], ray6["density"])
+
def test_particle_counts():
ds = fake_random_ds(16, particles=100)
assert ds.particle_type_counts == {'io': 100}
https://bitbucket.org/yt_analysis/yt/commits/8d4aada253c6/
Changeset: 8d4aada253c6
User: jzuhone
Date: 2017-06-12 15:26:17+00:00
Summary: adding in ability to create non-ortho ray
Affected #: 2 files
diff -r b2eec238d0681f5612f99766d81f396799efb78f -r 8d4aada253c65bd98bf6e51bc441fb9212a35d35 yt/data_objects/region_expression.py
--- a/yt/data_objects/region_expression.py
+++ b/yt/data_objects/region_expression.py
@@ -14,6 +14,7 @@
import weakref
from yt.extern.six import string_types
+from yt.funcs import iterable
from yt.utilities.exceptions import YTDimensionalityError
class RegionExpression(object):
@@ -38,12 +39,19 @@
if isinstance(item, tuple) and isinstance(item[1], string_types):
return self.all_data[item]
if isinstance(item, slice):
- # This is for the case where we give a slice as an index; one
- # possible use case of this would be where we supply something
- # like ds.r[::256j] . This would be expanded, implicitly into
- # ds.r[::256j, ::256j, ::256j]. Other cases would be if we do
- # ds.r[0.1:0.9] where it will be expanded along three dimensions.
- item = (item, item, item)
+ if iterable(item.start) and len(item.start) == 3 and \
+ iterable(item.stop) and len(item.stop) == 3:
+ # This is for a ray that is not orthogonal to an axis.
+ # it's straightforward to do this, so we create a ray
+ # and drop out here.
+ return self._create_ray(item)
+ else:
+ # This is for the case where we give a slice as an index; one
+ # possible use case of this would be where we supply something
+ # like ds.r[::256j] . This would be expanded, implicitly into
+ # ds.r[::256j, ::256j, ::256j]. Other cases would be if we do
+ # ds.r[0.1:0.9] where it will be expanded along three dimensions.
+ item = (item, item, item)
if len(item) != self.ds.dimensionality:
# Not the right specification, and we don't want to do anything
# implicitly. Note that this happens *after* the implicit expansion
@@ -60,7 +68,7 @@
if nslices == 0:
return self._create_point(item)
elif nslices == 1:
- return self._create_ray(item)
+ return self._create_ortho_ray(item)
elif nslices == 2:
return self._create_slice(item)
else:
@@ -144,7 +152,12 @@
coord = [self._spec_to_value(p) for p in point_tuple]
return self.ds.point(coord)
- def _create_ray(self, ray_tuple):
+ def _create_ray(self, ray_slice):
+ start_point = [self._spec_to_value(v) for v in ray_slice.start]
+ end_point = [self._spec_to_value(v) for v in ray_slice.stop]
+ return self.ds.ray(start_point, end_point)
+
+ def _create_ortho_ray(self, ray_tuple):
axis = None
new_slice = []
coord = []
diff -r b2eec238d0681f5612f99766d81f396799efb78f -r 8d4aada253c65bd98bf6e51bc441fb9212a35d35 yt/data_objects/tests/test_dataset_access.py
--- a/yt/data_objects/tests/test_dataset_access.py
+++ b/yt/data_objects/tests/test_dataset_access.py
@@ -93,6 +93,24 @@
pt2 = ds.point([0.5,0.3,0.1])
assert_equal(pt1["density"], pt2["density"])
+def test_ray_from_r():
+ ds = fake_amr_ds(fields = ["density"])
+ ray1 = ds.r[(0.1,0.2,0.3):(0.4,0.5,0.6)]
+ ray2 = ds.ray((0.1,0.2,0.3), (0.4,0.5,0.6))
+ assert_equal(ray1["density"], ray2["density"])
+
+ ray3 = ds.r[0.5*ds.domain_left_edge:0.5*ds.domain_right_edge]
+ ray4 = ds.ray(0.5*ds.domain_left_edge, 0.5*ds.domain_right_edge)
+ assert_equal(ray3["density"], ray4["density"])
+
+ start = [(0.1,"cm"), 0.2, (0.3,"cm")]
+ end = [(0.5,"cm"), (0.4,"cm"), 0.6]
+ ray5 = ds.r[start:end]
+ start_arr = [ds.quan(0.1,"cm"), 0.2, ds.quan(0.3,"cm")]
+ end_arr = [ds.quan(0.5,"cm"), ds.quan(0.4,"cm"), 0.6]
+ ray6 = ds.ray(start_arr, end_arr)
+ assert_equal(ray5["density"], ray6["density"])
+
def test_ortho_ray_from_r():
ds = fake_amr_ds(fields = ["density"])
ray1 = ds.r[:,0.3,0.2]
https://bitbucket.org/yt_analysis/yt/commits/ac82e2480971/
Changeset: ac82e2480971
User: jzuhone
Date: 2017-06-12 15:31:58+00:00
Summary: Add docs
Affected #: 1 file
diff -r 8d4aada253c65bd98bf6e51bc441fb9212a35d35 -r ac82e24809716fb0ddf2c03c0cd0571091176030 doc/source/analyzing/objects.rst
--- a/doc/source/analyzing/objects.rst
+++ b/doc/source/analyzing/objects.rst
@@ -197,7 +197,6 @@
(900.1, 'm')]
sl.plot()
-.. _available-objects:
Making Image Buffers
^^^^^^^^^^^^^^^^^^^^
@@ -214,6 +213,34 @@
This `frb` object then can be queried like a normal fixed resolution buffer,
and it will return arrays of shape (1024, 1024).
+Making Rays
+^^^^^^^^^^^
+
+The slicing syntax can also be used select 1D rays of points, whether along
+an axis or off-axis. To create a ray along an axis:::
+
+ ortho_ray = ds.r[(500.0, "kpc"), (200, "kpc"):(300.0, "kpc"), (-2.0, "Mpc")]
+
+To create a ray off-axis, use a single slice between the start and end points
+of the ray:::
+
+ start = ((500.0, "kpc"), (0.2, "Mpc"), (100.0, "kpc"))
+ end = ((1.0, "Mpc"), (300.0, "kpc"), (0.0, "kpc"))
+ ray = ds.r[start:end]
+
+Selecting Points
+^^^^^^^^^^^^^^^^
+
+Finally, you can quickly select a single point within the domain by providing
+a single coordinate for every axis:::
+
+ pt = ds.r[(10.0, 'km'), (200, 'm'), (1.0,'km')]
+
+Querying this object for fields will give you the value of the field at that
+point.
+
+.. _available-objects:
+
Available Objects
-----------------
https://bitbucket.org/yt_analysis/yt/commits/b89e4d0e0eca/
Changeset: b89e4d0e0eca
User: jzuhone
Date: 2017-06-12 17:37:39+00:00
Summary: Make sure this works with YTQuantity inputs
Affected #: 1 file
diff -r ac82e24809716fb0ddf2c03c0cd0571091176030 -r b89e4d0e0ecae82fae57047cf3ee765d9e660294 yt/data_objects/region_expression.py
--- a/yt/data_objects/region_expression.py
+++ b/yt/data_objects/region_expression.py
@@ -15,6 +15,7 @@
from yt.extern.six import string_types
from yt.funcs import iterable
+from yt.units.yt_array import YTQuantity
from yt.utilities.exceptions import YTDimensionalityError
class RegionExpression(object):
@@ -76,14 +77,14 @@
return self.all_data
return self._create_region(item)
- def _spec_to_value(self, input_tuple):
- if not isinstance(input_tuple, tuple):
- # We now assume that it's in code_length
- value = self.ds.quan(input_tuple, 'code_length')
+ def _spec_to_value(self, input):
+ if isinstance(input, tuple):
+ v = self.ds.quan(input[0], input[1]).to("code_length")
+ elif isinstance(input, YTQuantity):
+ v = self.ds.quan(input.value, input.units).to('code_length')
else:
- v, u = input_tuple
- value = self.ds.quan(v, u).in_units("code_length")
- return value
+ v = self.ds.quan(input, "code_length")
+ return v
def _create_slice(self, slice_tuple):
# This is somewhat more complex because we want to allow for slicing
https://bitbucket.org/yt_analysis/yt/commits/752959d57e8b/
Changeset: 752959d57e8b
User: jzuhone
Date: 2017-06-13 10:46:45+00:00
Summary: Simplify this with a new function, "obj_length"
Affected #: 2 files
diff -r b89e4d0e0ecae82fae57047cf3ee765d9e660294 -r 752959d57e8b0d7e0eb366c3c058c32b0108e29e yt/data_objects/region_expression.py
--- a/yt/data_objects/region_expression.py
+++ b/yt/data_objects/region_expression.py
@@ -14,7 +14,7 @@
import weakref
from yt.extern.six import string_types
-from yt.funcs import iterable
+from yt.funcs import iterable, obj_length
from yt.units.yt_array import YTQuantity
from yt.utilities.exceptions import YTDimensionalityError
@@ -40,8 +40,7 @@
if isinstance(item, tuple) and isinstance(item[1], string_types):
return self.all_data[item]
if isinstance(item, slice):
- if iterable(item.start) and len(item.start) == 3 and \
- iterable(item.stop) and len(item.stop) == 3:
+ if obj_length(item.start) == 3 and obj_length(item.stop) == 3:
# This is for a ray that is not orthogonal to an axis.
# it's straightforward to do this, so we create a ray
# and drop out here.
diff -r b89e4d0e0ecae82fae57047cf3ee765d9e660294 -r 752959d57e8b0d7e0eb366c3c058c32b0108e29e yt/funcs.py
--- a/yt/funcs.py
+++ b/yt/funcs.py
@@ -1141,3 +1141,9 @@
def issue_deprecation_warning(msg):
from numpy import VisibleDeprecationWarning
warnings.warn(msg, VisibleDeprecationWarning, stacklevel=3)
+
+def obj_length(v):
+ if iterable(v):
+ return len(v)
+ else:
+ return 0
\ No newline at end of file
https://bitbucket.org/yt_analysis/yt/commits/c28a83865294/
Changeset: c28a83865294
User: jzuhone
Date: 2017-06-13 10:51:06+00:00
Summary: Make this documentation a bit clearer
Affected #: 1 file
diff -r 752959d57e8b0d7e0eb366c3c058c32b0108e29e -r c28a83865294babd88a5ae73c880855cf18f8892 doc/source/analyzing/objects.rst
--- a/doc/source/analyzing/objects.rst
+++ b/doc/source/analyzing/objects.rst
@@ -224,6 +224,13 @@
To create a ray off-axis, use a single slice between the start and end points
of the ray:::
+ start = [0.1, 0.2, 0.3]
+ end = [0.4, 0.5, 0.6]
+ ray = ds.r[start:end]
+
+As for the other slicing options, combinations of unitful quantities with even
+different units can be used. Here's a somewhat convoluted (yet working) example:::
+
start = ((500.0, "kpc"), (0.2, "Mpc"), (100.0, "kpc"))
end = ((1.0, "Mpc"), (300.0, "kpc"), (0.0, "kpc"))
ray = ds.r[start:end]
https://bitbucket.org/yt_analysis/yt/commits/41165c8eacda/
Changeset: 41165c8eacda
User: jzuhone
Date: 2017-06-13 10:57:16+00:00
Summary: Making sure converting to code_length works property in a couple of places
Affected #: 2 files
diff -r c28a83865294babd88a5ae73c880855cf18f8892 -r 41165c8eacda24a94bd8b89a8d9770320186fe09 yt/data_objects/region_expression.py
--- a/yt/data_objects/region_expression.py
+++ b/yt/data_objects/region_expression.py
@@ -80,7 +80,7 @@
if isinstance(input, tuple):
v = self.ds.quan(input[0], input[1]).to("code_length")
elif isinstance(input, YTQuantity):
- v = self.ds.quan(input.value, input.units).to('code_length')
+ v = self.ds.quan(input).to('code_length')
else:
v = self.ds.quan(input, "code_length")
return v
diff -r c28a83865294babd88a5ae73c880855cf18f8892 -r 41165c8eacda24a94bd8b89a8d9770320186fe09 yt/data_objects/selection_data_containers.py
--- a/yt/data_objects/selection_data_containers.py
+++ b/yt/data_objects/selection_data_containers.py
@@ -28,7 +28,8 @@
from yt.geometry.selection_routines import \
points_in_cells
from yt.units.yt_array import \
- YTArray
+ YTArray, \
+ YTQuantity
from yt.utilities.exceptions import \
YTSphereTooSmall, \
YTIllDefinedCutRegion, \
@@ -138,9 +139,15 @@
# Even though we may not be using x,y,z we use them here.
self.px_dx = 'd%s'%('xyz'[self.px_ax])
self.py_dx = 'd%s'%('xyz'[self.py_ax])
- # Convert coordinates to code length.
- self.px = self.ds.quan(coords[0], "code_length")
- self.py = self.ds.quan(coords[1], "code_length")
+ # Convert coordinates to code length.
+ if isinstance(coords[0], YTQuantity):
+ self.px = self.ds.quan(coords[0]).to("code_length")
+ else:
+ self.px = self.ds.quan(coords[0], "code_length")
+ if isinstance(coords[1], YTQuantity):
+ self.py = self.ds.quan(coords[1]).to("code_length")
+ else:
+ self.py = self.ds.quan(coords[1], "code_length")
self.sort_by = 'xyz'[self.axis]
@property
https://bitbucket.org/yt_analysis/yt/commits/8f006e500d32/
Changeset: 8f006e500d32
User: jzuhone
Date: 2017-06-13 14:04:53+00:00
Summary: note about code length
Affected #: 1 file
diff -r 41165c8eacda24a94bd8b89a8d9770320186fe09 -r 8f006e500d323cdc8bafd4c44a814aa4811c6da3 doc/source/analyzing/objects.rst
--- a/doc/source/analyzing/objects.rst
+++ b/doc/source/analyzing/objects.rst
@@ -224,8 +224,8 @@
To create a ray off-axis, use a single slice between the start and end points
of the ray:::
- start = [0.1, 0.2, 0.3]
- end = [0.4, 0.5, 0.6]
+ start = [0.1, 0.2, 0.3] # interpreted in code_length
+ end = [0.4, 0.5, 0.6] # interpreted in code_length
ray = ds.r[start:end]
As for the other slicing options, combinations of unitful quantities with even
https://bitbucket.org/yt_analysis/yt/commits/9e1cc9917aee/
Changeset: 9e1cc9917aee
User: jzuhone
Date: 2017-06-13 20:03:45+00:00
Summary: Don't use iterable here
Affected #: 1 file
diff -r 8f006e500d323cdc8bafd4c44a814aa4811c6da3 -r 9e1cc9917aeeae5e385657ec7b093c3d3e52374f yt/data_objects/region_expression.py
--- a/yt/data_objects/region_expression.py
+++ b/yt/data_objects/region_expression.py
@@ -14,7 +14,7 @@
import weakref
from yt.extern.six import string_types
-from yt.funcs import iterable, obj_length
+from yt.funcs import obj_length
from yt.units.yt_array import YTQuantity
from yt.utilities.exceptions import YTDimensionalityError
https://bitbucket.org/yt_analysis/yt/commits/d1bb34510e2c/
Changeset: d1bb34510e2c
User: jzuhone
Date: 2017-06-20 01:57:33+00:00
Summary: Responding to Matt's comments
Affected #: 2 files
diff -r 9e1cc9917aeeae5e385657ec7b093c3d3e52374f -r d1bb34510e2c37eefba9a3ff3e68720117230450 yt/data_objects/region_expression.py
--- a/yt/data_objects/region_expression.py
+++ b/yt/data_objects/region_expression.py
@@ -64,7 +64,7 @@
# OK, now we need to look at our slices. How many are a specific
# coordinate?
- nslices = sum([isinstance(v, slice) for v in item])
+ nslices = sum(isinstance(v, slice) for v in item)
if nslices == 0:
return self._create_point(item)
elif nslices == 1:
diff -r 9e1cc9917aeeae5e385657ec7b093c3d3e52374f -r d1bb34510e2c37eefba9a3ff3e68720117230450 yt/funcs.py
--- a/yt/funcs.py
+++ b/yt/funcs.py
@@ -1146,4 +1146,6 @@
if iterable(v):
return len(v)
else:
+ # If something isn't iterable, we return 0
+ # to signify zero length (aka a scalar).
return 0
\ No newline at end of file
https://bitbucket.org/yt_analysis/yt/commits/edf23011658c/
Changeset: edf23011658c
User: MatthewTurk
Date: 2017-06-20 15:25:13+00:00
Summary: Merge pull request #1446 from jzuhone/point_ray
Extend region expression to return points and rays
Affected #: 5 files
diff -r 4dd3b6fa631d77671ddbe2f975dd8300785857c6 -r edf23011658c556b1d6d4adc9c0177d08d08ace1 doc/source/analyzing/objects.rst
--- a/doc/source/analyzing/objects.rst
+++ b/doc/source/analyzing/objects.rst
@@ -197,7 +197,6 @@
(900.1, 'm')]
sl.plot()
-.. _available-objects:
Making Image Buffers
^^^^^^^^^^^^^^^^^^^^
@@ -214,6 +213,41 @@
This `frb` object then can be queried like a normal fixed resolution buffer,
and it will return arrays of shape (1024, 1024).
+Making Rays
+^^^^^^^^^^^
+
+The slicing syntax can also be used select 1D rays of points, whether along
+an axis or off-axis. To create a ray along an axis:::
+
+ ortho_ray = ds.r[(500.0, "kpc"), (200, "kpc"):(300.0, "kpc"), (-2.0, "Mpc")]
+
+To create a ray off-axis, use a single slice between the start and end points
+of the ray:::
+
+ start = [0.1, 0.2, 0.3] # interpreted in code_length
+ end = [0.4, 0.5, 0.6] # interpreted in code_length
+ ray = ds.r[start:end]
+
+As for the other slicing options, combinations of unitful quantities with even
+different units can be used. Here's a somewhat convoluted (yet working) example:::
+
+ start = ((500.0, "kpc"), (0.2, "Mpc"), (100.0, "kpc"))
+ end = ((1.0, "Mpc"), (300.0, "kpc"), (0.0, "kpc"))
+ ray = ds.r[start:end]
+
+Selecting Points
+^^^^^^^^^^^^^^^^
+
+Finally, you can quickly select a single point within the domain by providing
+a single coordinate for every axis:::
+
+ pt = ds.r[(10.0, 'km'), (200, 'm'), (1.0,'km')]
+
+Querying this object for fields will give you the value of the field at that
+point.
+
+.. _available-objects:
+
Available Objects
-----------------
diff -r 4dd3b6fa631d77671ddbe2f975dd8300785857c6 -r edf23011658c556b1d6d4adc9c0177d08d08ace1 yt/data_objects/region_expression.py
--- a/yt/data_objects/region_expression.py
+++ b/yt/data_objects/region_expression.py
@@ -14,6 +14,8 @@
import weakref
from yt.extern.six import string_types
+from yt.funcs import obj_length
+from yt.units.yt_array import YTQuantity
from yt.utilities.exceptions import YTDimensionalityError
class RegionExpression(object):
@@ -38,12 +40,18 @@
if isinstance(item, tuple) and isinstance(item[1], string_types):
return self.all_data[item]
if isinstance(item, slice):
- # This is for the case where we give a slice as an index; one
- # possible use case of this would be where we supply something
- # like ds.r[::256j] . This would be expanded, implicitly into
- # ds.r[::256j, ::256j, ::256j]. Other cases would be if we do
- # ds.r[0.1:0.9] where it will be expanded along three dimensions.
- item = (item, item, item)
+ if obj_length(item.start) == 3 and obj_length(item.stop) == 3:
+ # This is for a ray that is not orthogonal to an axis.
+ # it's straightforward to do this, so we create a ray
+ # and drop out here.
+ return self._create_ray(item)
+ else:
+ # This is for the case where we give a slice as an index; one
+ # possible use case of this would be where we supply something
+ # like ds.r[::256j] . This would be expanded, implicitly into
+ # ds.r[::256j, ::256j, ::256j]. Other cases would be if we do
+ # ds.r[0.1:0.9] where it will be expanded along three dimensions.
+ item = (item, item, item)
if len(item) != self.ds.dimensionality:
# Not the right specification, and we don't want to do anything
# implicitly. Note that this happens *after* the implicit expansion
@@ -56,20 +64,26 @@
# OK, now we need to look at our slices. How many are a specific
# coordinate?
- if not all(isinstance(v, slice) for v in item):
+ nslices = sum(isinstance(v, slice) for v in item)
+ if nslices == 0:
+ return self._create_point(item)
+ elif nslices == 1:
+ return self._create_ortho_ray(item)
+ elif nslices == 2:
return self._create_slice(item)
else:
if all(s.start is s.stop is s.step is None for s in item):
return self.all_data
return self._create_region(item)
- def _spec_to_value(self, input_tuple):
- if not isinstance(input_tuple, tuple):
- # We now assume that it's in code_length
- return self.ds.quan(input_tuple, 'code_length')
- v, u = input_tuple
- value = self.ds.quan(v, u)
- return value
+ def _spec_to_value(self, input):
+ if isinstance(input, tuple):
+ v = self.ds.quan(input[0], input[1]).to("code_length")
+ elif isinstance(input, YTQuantity):
+ v = self.ds.quan(input).to('code_length')
+ else:
+ v = self.ds.quan(input, "code_length")
+ return v
def _create_slice(self, slice_tuple):
# This is somewhat more complex because we want to allow for slicing
@@ -133,3 +147,31 @@
if all(d is not None for d in dims):
return self.ds.arbitrary_grid(left_edge, right_edge, dims)
return self.ds.region(center, left_edge, right_edge)
+
+ def _create_point(self, point_tuple):
+ coord = [self._spec_to_value(p) for p in point_tuple]
+ return self.ds.point(coord)
+
+ def _create_ray(self, ray_slice):
+ start_point = [self._spec_to_value(v) for v in ray_slice.start]
+ end_point = [self._spec_to_value(v) for v in ray_slice.stop]
+ return self.ds.ray(start_point, end_point)
+
+ def _create_ortho_ray(self, ray_tuple):
+ axis = None
+ new_slice = []
+ coord = []
+ for ax, v in enumerate(ray_tuple):
+ if not isinstance(v, slice):
+ coord.append(self._spec_to_value(v))
+ new_slice.append(slice(None, None, None))
+ else:
+ if axis is not None: raise RuntimeError
+ axis = ax
+ new_slice.append(v)
+ if axis == 1: coord = [coord[1], coord[0]]
+ source = self._create_region(new_slice)
+ ray = self.ds.ortho_ray(axis, coord, data_source=source)
+ if getattr(new_slice[axis].step, "imag", 0.0) != 0.0:
+ raise NotImplementedError
+ return ray
\ No newline at end of file
diff -r 4dd3b6fa631d77671ddbe2f975dd8300785857c6 -r edf23011658c556b1d6d4adc9c0177d08d08ace1 yt/data_objects/selection_data_containers.py
--- a/yt/data_objects/selection_data_containers.py
+++ b/yt/data_objects/selection_data_containers.py
@@ -23,11 +23,13 @@
ensure_list, \
iterable, \
validate_width_tuple, \
- fix_length
+ fix_length, \
+ fix_axis
from yt.geometry.selection_routines import \
points_in_cells
from yt.units.yt_array import \
- YTArray
+ YTArray, \
+ YTQuantity
from yt.utilities.exceptions import \
YTSphereTooSmall, \
YTIllDefinedCutRegion, \
@@ -88,8 +90,8 @@
Parameters
----------
- axis : int
- The axis along which to cast the ray. Can be 0, 1, or 2 for x, y, z.
+ axis : int or char
+ The axis along which to slice. Can be 0, 1, or 2 for x, y, z.
coords : tuple of floats
The (plane_x, plane_y) coordinates at which to cast the ray. Note
that this is in the plane coordinates: so if you are casting along
@@ -129,7 +131,7 @@
def __init__(self, axis, coords, ds=None,
field_parameters=None, data_source=None):
super(YTOrthoRay, self).__init__(ds, field_parameters, data_source)
- self.axis = axis
+ self.axis = fix_axis(axis, self.ds)
xax = self.ds.coordinates.x_axis[self.axis]
yax = self.ds.coordinates.y_axis[self.axis]
self.px_ax = xax
@@ -137,7 +139,15 @@
# Even though we may not be using x,y,z we use them here.
self.px_dx = 'd%s'%('xyz'[self.px_ax])
self.py_dx = 'd%s'%('xyz'[self.py_ax])
- self.px, self.py = coords
+ # Convert coordinates to code length.
+ if isinstance(coords[0], YTQuantity):
+ self.px = self.ds.quan(coords[0]).to("code_length")
+ else:
+ self.px = self.ds.quan(coords[0], "code_length")
+ if isinstance(coords[1], YTQuantity):
+ self.py = self.ds.quan(coords[1]).to("code_length")
+ else:
+ self.py = self.ds.quan(coords[1], "code_length")
self.sort_by = 'xyz'[self.axis]
@property
diff -r 4dd3b6fa631d77671ddbe2f975dd8300785857c6 -r edf23011658c556b1d6d4adc9c0177d08d08ace1 yt/data_objects/tests/test_dataset_access.py
--- a/yt/data_objects/tests/test_dataset_access.py
+++ b/yt/data_objects/tests/test_dataset_access.py
@@ -76,6 +76,58 @@
frb2 = ds.r[0.5, ::1024j, ::512j]
assert_equal(frb1["density"], frb2["density"])
+ # Test slice which doesn't cover the whole domain
+ box = ds.box([0.0, 0.25, 0.25], [1.0, 0.75, 0.75])
+
+ sl3 = ds.r[0.5, 0.25:0.75, 0.25:0.75]
+ sl4 = ds.slice("x", 0.5, data_source=box)
+ assert_equal(sl3["density"], sl4["density"])
+
+ frb3 = sl3.to_frb(width = 0.5, height = 0.5, resolution = (1024, 512))
+ frb4 = ds.r[0.5, 0.25:0.75:1024j, 0.25:0.75:512j]
+ assert_equal(frb3["density"], frb4["density"])
+
+def test_point_from_r():
+ ds = fake_amr_ds(fields = ["density"])
+ pt1 = ds.r[0.5,0.3,0.1]
+ pt2 = ds.point([0.5,0.3,0.1])
+ assert_equal(pt1["density"], pt2["density"])
+
+def test_ray_from_r():
+ ds = fake_amr_ds(fields = ["density"])
+ ray1 = ds.r[(0.1,0.2,0.3):(0.4,0.5,0.6)]
+ ray2 = ds.ray((0.1,0.2,0.3), (0.4,0.5,0.6))
+ assert_equal(ray1["density"], ray2["density"])
+
+ ray3 = ds.r[0.5*ds.domain_left_edge:0.5*ds.domain_right_edge]
+ ray4 = ds.ray(0.5*ds.domain_left_edge, 0.5*ds.domain_right_edge)
+ assert_equal(ray3["density"], ray4["density"])
+
+ start = [(0.1,"cm"), 0.2, (0.3,"cm")]
+ end = [(0.5,"cm"), (0.4,"cm"), 0.6]
+ ray5 = ds.r[start:end]
+ start_arr = [ds.quan(0.1,"cm"), 0.2, ds.quan(0.3,"cm")]
+ end_arr = [ds.quan(0.5,"cm"), ds.quan(0.4,"cm"), 0.6]
+ ray6 = ds.ray(start_arr, end_arr)
+ assert_equal(ray5["density"], ray6["density"])
+
+def test_ortho_ray_from_r():
+ ds = fake_amr_ds(fields = ["density"])
+ ray1 = ds.r[:,0.3,0.2]
+ ray2 = ds.ortho_ray("x",[0.3, 0.2])
+ assert_equal(ray1["density"], ray2["density"])
+
+ # the y-coord is funny so test it too
+ ray3 = ds.r[0.3,:,0.2]
+ ray4 = ds.ortho_ray("y", [0.2, 0.3])
+ assert_equal(ray3["density"], ray4["density"])
+
+ # Test ray which doesn't cover the whole domain
+ box = ds.box([0.25, 0.0, 0.0], [0.75, 1.0, 1.0])
+ ray5 = ds.r[0.25:0.75,0.3,0.2]
+ ray6 = ds.ortho_ray("x", [0.3, 0.2], data_source=box)
+ assert_equal(ray5["density"], ray6["density"])
+
def test_particle_counts():
ds = fake_random_ds(16, particles=100)
assert ds.particle_type_counts == {'io': 100}
diff -r 4dd3b6fa631d77671ddbe2f975dd8300785857c6 -r edf23011658c556b1d6d4adc9c0177d08d08ace1 yt/funcs.py
--- a/yt/funcs.py
+++ b/yt/funcs.py
@@ -1141,3 +1141,11 @@
def issue_deprecation_warning(msg):
from numpy import VisibleDeprecationWarning
warnings.warn(msg, VisibleDeprecationWarning, stacklevel=3)
+
+def obj_length(v):
+ if iterable(v):
+ return len(v)
+ else:
+ # If something isn't iterable, we return 0
+ # to signify zero length (aka a scalar).
+ return 0
\ No newline at end of file
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