[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