[yt-svn] commit/yt: 17 new changesets

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Wed Jun 14 09:23:00 PDT 2017


17 new commits in yt:

https://bitbucket.org/yt_analysis/yt/commits/411ba7b141d8/
Changeset:   411ba7b141d8
User:        ngoldbaum
Date:        2017-05-30 14:31:18+00:00
Summary:     Clamp grid edges to integer multiples of the cell width. Closes #1431
Affected #:  1 file

diff -r 2848c2031acc2b429d4effd45c4abf70d215cc80 -r 411ba7b141d88c3f755b30c0bd1a9bba1deb06b9 yt/geometry/grid_geometry_handler.py
--- a/yt/geometry/grid_geometry_handler.py
+++ b/yt/geometry/grid_geometry_handler.py
@@ -53,6 +53,9 @@
         mylog.debug("Constructing grid objects.")
         self._populate_grid_objects()
 
+        mylog.debug("Adjusting grids")
+        self._clamp_grid_edges()
+
         mylog.debug("Re-examining index")
         self._initialize_level_stats()
 
@@ -105,6 +108,35 @@
         self.grid_levels = np.zeros((self.num_grids,1), 'int32')
         self.grid_particle_count = np.zeros((self.num_grids,1), 'int32')
 
+    def _clamp_grid_edges(self):
+        for g in self.grids:
+            start_index = np.zeros((2, 3))
+            if g.Parent is None:
+                left = g.LeftEdge - self.ds.domain_left_edge
+                start_index[0, :] = left/g.dds
+                right = g.RightEdge - self.ds.domain_left_edge
+                start_index[1, :] = right/g.dds
+            else:
+                pdx = g.Parent.dds
+                start_index[0, :] = (g.LeftEdge - g.Parent.LeftEdge) / pdx
+                start_index[1, :] = (g.RightEdge - g.Parent.LeftEdge) / pdx
+            integer_index = np.rint(start_index)
+            need_adjustment = (start_index != integer_index).any(axis=1)
+            if np.any(need_adjustment):
+                wh = np.where(need_adjustment)[0]
+                for d in wh:
+                    if g.Parent is None:
+                        new_edge = (integer_index[d, :] * g.dds +
+                                    self.ds.domain_left_edge)
+                    else:
+                        new_edge = (integer_index[d, :] * pdx +
+                                    g.Parent.LeftEdge)
+                    if d == 0:
+                        g.LeftEdge = new_edge
+                    elif d == 1:
+                        g.RightEdge = new_edge
+
+
     def clear_all_data(self):
         """
         This routine clears all the data currently being held onto by the grids


https://bitbucket.org/yt_analysis/yt/commits/817021886a06/
Changeset:   817021886a06
User:        ngoldbaum
Date:        2017-05-30 14:31:50+00:00
Summary:     Remove undocumented config option reconstruct_index
Affected #:  2 files

diff -r 411ba7b141d88c3f755b30c0bd1a9bba1deb06b9 -r 817021886a06ca3163fd7749d022fd2166cd7e85 yt/config.py
--- a/yt/config.py
+++ b/yt/config.py
@@ -45,7 +45,6 @@
     pluginfilename = 'my_plugins.py',
     parallel_traceback = 'False',
     pasteboard_repo = '',
-    reconstruct_index = 'False',
     test_storage_dir = '/does/not/exist',
     test_data_dir = '/does/not/exist',
     requires_ds_strict = 'False',

diff -r 411ba7b141d88c3f755b30c0bd1a9bba1deb06b9 -r 817021886a06ca3163fd7749d022fd2166cd7e85 yt/frontends/enzo/data_structures.py
--- a/yt/frontends/enzo/data_structures.py
+++ b/yt/frontends/enzo/data_structures.py
@@ -380,13 +380,10 @@
         mylog.info("Finished rebuilding")
 
     def _populate_grid_objects(self):
-        reconstruct = ytcfg.getboolean("yt","reconstruct_index")
         for g,f in izip(self.grids, self.filenames):
             g._prepare_grid()
             g._setup_dx()
             g.set_filename(f[0])
-            if reconstruct:
-                if g.Parent is not None: g._guess_properties_from_parent()
         del self.filenames # No longer needed.
         self.max_level = self.grid_levels.max()
 


https://bitbucket.org/yt_analysis/yt/commits/1b63354a5a94/
Changeset:   1b63354a5a94
User:        ngoldbaum
Date:        2017-05-30 14:32:29+00:00
Summary:     Remove unused _guess_properties_from_parent function
Affected #:  2 files

diff -r 817021886a06ca3163fd7749d022fd2166cd7e85 -r 1b63354a5a94418db0609015f6a4d9beb496c73d yt/frontends/enzo/data_structures.py
--- a/yt/frontends/enzo/data_structures.py
+++ b/yt/frontends/enzo/data_structures.py
@@ -66,28 +66,6 @@
         self._parent_id = -1
         self.Level = -1
 
-    def _guess_properties_from_parent(self):
-        """
-        We know that our grid boundary occurs on the cell boundary of our
-        parent.  This can be a very expensive process, but it is necessary
-        in some indexs, where yt is unable to generate a completely
-        space-filling tiling of grids, possibly due to the finite accuracy in a
-        standard Enzo index file.
-        """
-        rf = self.ds.refine_by
-        my_ind = self.id - self._id_offset
-        self.dds = self.Parent.dds/rf
-        ParentLeftIndex = np.rint((self.LeftEdge-self.Parent.LeftEdge)/self.Parent.dds)
-        self.start_index = rf*(ParentLeftIndex + self.Parent.get_global_startindex()).astype('int64')
-        self.LeftEdge = self.Parent.LeftEdge + self.Parent.dds * ParentLeftIndex
-        self.RightEdge = self.LeftEdge + self.ActiveDimensions*self.dds
-        self.index.grid_left_edge[my_ind,:] = self.LeftEdge
-        self.index.grid_right_edge[my_ind,:] = self.RightEdge
-        self._child_mask = None
-        self._child_index_mask = None
-        self._child_indices = None
-        self._setup_dx()
-
     def set_filename(self, filename):
         """
         Intelligently set the filename.

diff -r 817021886a06ca3163fd7749d022fd2166cd7e85 -r 1b63354a5a94418db0609015f6a4d9beb496c73d yt/frontends/stream/data_structures.py
--- a/yt/frontends/stream/data_structures.py
+++ b/yt/frontends/stream/data_structures.py
@@ -97,21 +97,6 @@
         self._parent_id = -1
         self.Level = -1
 
-    def _guess_properties_from_parent(self):
-        rf = self.ds.refine_by
-        my_ind = self.id - self._id_offset
-        self.dds = self.Parent.dds/rf
-        ParentLeftIndex = np.rint((self.LeftEdge-self.Parent.LeftEdge)/self.Parent.dds)
-        self.start_index = rf*(ParentLeftIndex + self.Parent.get_global_startindex()).astype('int64')
-        self.LeftEdge = self.Parent.LeftEdge + self.Parent.dds * ParentLeftIndex
-        self.RightEdge = self.LeftEdge + self.ActiveDimensions*self.dds
-        self.index.grid_left_edge[my_ind,:] = self.LeftEdge
-        self.index.grid_right_edge[my_ind,:] = self.RightEdge
-        self._child_mask = None
-        self._child_index_mask = None
-        self._child_indices = None
-        self._setup_dx()
-
     def set_filename(self, filename):
         pass
 


https://bitbucket.org/yt_analysis/yt/commits/618da10ecadb/
Changeset:   618da10ecadb
User:        ngoldbaum
Date:        2017-05-30 17:01:50+00:00
Summary:     don't clamp grid edges in new loop over grids
Affected #:  1 file

diff -r 1b63354a5a94418db0609015f6a4d9beb496c73d -r 618da10ecadb789b66e9bc94a024e4017509b344 yt/geometry/grid_geometry_handler.py
--- a/yt/geometry/grid_geometry_handler.py
+++ b/yt/geometry/grid_geometry_handler.py
@@ -53,9 +53,6 @@
         mylog.debug("Constructing grid objects.")
         self._populate_grid_objects()
 
-        mylog.debug("Adjusting grids")
-        self._clamp_grid_edges()
-
         mylog.debug("Re-examining index")
         self._initialize_level_stats()
 
@@ -108,35 +105,6 @@
         self.grid_levels = np.zeros((self.num_grids,1), 'int32')
         self.grid_particle_count = np.zeros((self.num_grids,1), 'int32')
 
-    def _clamp_grid_edges(self):
-        for g in self.grids:
-            start_index = np.zeros((2, 3))
-            if g.Parent is None:
-                left = g.LeftEdge - self.ds.domain_left_edge
-                start_index[0, :] = left/g.dds
-                right = g.RightEdge - self.ds.domain_left_edge
-                start_index[1, :] = right/g.dds
-            else:
-                pdx = g.Parent.dds
-                start_index[0, :] = (g.LeftEdge - g.Parent.LeftEdge) / pdx
-                start_index[1, :] = (g.RightEdge - g.Parent.LeftEdge) / pdx
-            integer_index = np.rint(start_index)
-            need_adjustment = (start_index != integer_index).any(axis=1)
-            if np.any(need_adjustment):
-                wh = np.where(need_adjustment)[0]
-                for d in wh:
-                    if g.Parent is None:
-                        new_edge = (integer_index[d, :] * g.dds +
-                                    self.ds.domain_left_edge)
-                    else:
-                        new_edge = (integer_index[d, :] * pdx +
-                                    g.Parent.LeftEdge)
-                    if d == 0:
-                        g.LeftEdge = new_edge
-                    elif d == 1:
-                        g.RightEdge = new_edge
-
-
     def clear_all_data(self):
         """
         This routine clears all the data currently being held onto by the grids


https://bitbucket.org/yt_analysis/yt/commits/2a80b4a758ab/
Changeset:   2a80b4a758ab
User:        ngoldbaum
Date:        2017-05-30 17:02:16+00:00
Summary:     fix flake8
Affected #:  1 file

diff -r 618da10ecadb789b66e9bc94a024e4017509b344 -r 2a80b4a758abbaa78895335584d38206a479f7e4 yt/frontends/enzo/data_structures.py
--- a/yt/frontends/enzo/data_structures.py
+++ b/yt/frontends/enzo/data_structures.py
@@ -30,7 +30,6 @@
     ensure_tuple, \
     get_pbar, \
     setdefaultattr
-from yt.config import ytcfg
 from yt.data_objects.grid_patch import \
     AMRGridPatch
 from yt.geometry.grid_geometry_handler import \


https://bitbucket.org/yt_analysis/yt/commits/82c955aaa6ce/
Changeset:   82c955aaa6ce
User:        ngoldbaum
Date:        2017-05-30 17:02:29+00:00
Summary:     add failing test
Affected #:  1 file

diff -r 2a80b4a758abbaa78895335584d38206a479f7e4 -r 82c955aaa6cea681bf2ce2cfaa10c1a25be4f185 yt/frontends/enzo/tests/test_outputs.py
--- a/yt/frontends/enzo/tests/test_outputs.py
+++ b/yt/frontends/enzo/tests/test_outputs.py
@@ -28,6 +28,8 @@
     data_dir_load, \
     AnalyticHaloMassFunctionTest, \
     SimulatedHaloMassFunctionTest
+from yt.visualization.plot_window import \
+    SlicePlot
 from yt.frontends.enzo.api import EnzoDataset
 from yt.frontends.enzo.fields import NODAL_FLAGS
 
@@ -42,6 +44,7 @@
 toro1d = "ToroShockTube/DD0001/data0001"
 kh2d = "EnzoKelvinHelmholtz/DD0011/DD0011"
 mhdctot = "MHDCTOrszagTang/DD0004/data0004"
+dnz = "DeeplyNestedZoom/DD0025/data0025"
 
 def check_color_conservation(ds):
     species_names = ds.field_info.species_names
@@ -191,3 +194,17 @@
     assert (ad['BxF'].sum(axis=-1)/2 == ad['Bx']).all()
     assert (ad['ByF'].sum(axis=-1)/2 == ad['By']).all()
     assert (ad['BzF'].sum(axis=-1)/2 == ad['Bz']).all()
+
+ at requires_file(dnz)
+def test_deeply_nested_zoom():
+    ds = data_dir_load(dnz)
+
+    # carefully chosen to just barely miss a grid in the middle of the image
+    center = [0.4915073260199302, 0.5052605316800006, 0.4905805557500548]
+    
+    plot = SlicePlot(ds, 'z', 'density', width=(0.001, 'pc'),
+                     center=center)
+
+    image = plot.frb['density']
+
+    assert (image > 0).all()


https://bitbucket.org/yt_analysis/yt/commits/5d7f932a0452/
Changeset:   5d7f932a0452
User:        ngoldbaum
Date:        2017-05-30 17:27:15+00:00
Summary:     clamp grid edges while initializing grids
Affected #:  1 file

diff -r 82c955aaa6cea681bf2ce2cfaa10c1a25be4f185 -r 5d7f932a04523c6863c305ccc3b9542ac6457cde yt/data_objects/grid_patch.py
--- a/yt/data_objects/grid_patch.py
+++ b/yt/data_objects/grid_patch.py
@@ -22,6 +22,8 @@
     YTSelectionContainer
 from yt.data_objects.field_data import \
     YTFieldData
+from yt.funcs import \
+    iterable
 from yt.geometry.selection_routines import convert_mask_to_indices
 import yt.geometry.particle_deposit as particle_deposit
 from yt.utilities.exceptions import \
@@ -171,13 +173,32 @@
         h = self.index # cache it
         my_ind = self.id - self._id_offset
         self.ActiveDimensions = h.grid_dimensions[my_ind]
-        self.LeftEdge = h.grid_left_edge[my_ind]
-        self.RightEdge = h.grid_right_edge[my_ind]
+        self.LeftEdge, self.RightEdge = self._clamp_edges(
+            h.grid_left_edge[my_ind], h.grid_right_edge[my_ind])
         h.grid_levels[my_ind, 0] = self.Level
         # This might be needed for streaming formats
         #self.Time = h.gridTimes[my_ind,0]
         self.NumberOfParticles = h.grid_particle_count[my_ind, 0]
 
+    def _clamp_edges(self, left_edge, right_edge):
+        if self.Parent is None or self.Parent == []:
+            return left_edge, right_edge
+        start_index = np.zeros((2, 3))
+        if iterable(self.Parent):
+            p = self.Parent[0]
+        else:
+            p = self.Parent
+        pdx = p.dds
+        start_index[0, :] = (left_edge - p.LeftEdge) / pdx
+        start_index[1, :] = (right_edge - p.LeftEdge) / pdx
+        integer_index = np.rint(start_index)
+        need_adjustment = (start_index != integer_index).any(axis=1)
+        if need_adjustment[0]:
+            left_edge = (integer_index[0, :] * pdx + p.LeftEdge)
+        elif need_adjustment[1]:
+            right_edge = (integer_index[1, :] * pdx + p.LeftEdge)
+        return left_edge, right_edge
+
     def get_position(self, index):
         """ Returns center position of an *index*. """
         pos = (index + 0.5) * self.dds + self.LeftEdge


https://bitbucket.org/yt_analysis/yt/commits/0d9af59d5365/
Changeset:   0d9af59d5365
User:        ngoldbaum
Date:        2017-05-30 18:34:00+00:00
Summary:     implement clamp_edges in cython
Affected #:  2 files

diff -r 5d7f932a04523c6863c305ccc3b9542ac6457cde -r 0d9af59d5365da59a35fc02ba2fd99fdb92b8f4b yt/data_objects/grid_patch.py
--- a/yt/data_objects/grid_patch.py
+++ b/yt/data_objects/grid_patch.py
@@ -22,8 +22,7 @@
     YTSelectionContainer
 from yt.data_objects.field_data import \
     YTFieldData
-from yt.funcs import \
-    iterable
+from yt.funcs import iterable
 from yt.geometry.selection_routines import convert_mask_to_indices
 import yt.geometry.particle_deposit as particle_deposit
 from yt.utilities.exceptions import \
@@ -31,6 +30,8 @@
     YTParticleDepositionNotImplemented
 from yt.utilities.lib.interpolators import \
     ghost_zone_interpolate
+from yt.utilities.lib.mesh_utilities import \
+    clamp_edges
 from yt.utilities.nodal_data_utils import \
     get_nodal_slices
 
@@ -173,32 +174,22 @@
         h = self.index # cache it
         my_ind = self.id - self._id_offset
         self.ActiveDimensions = h.grid_dimensions[my_ind]
-        self.LeftEdge, self.RightEdge = self._clamp_edges(
-            h.grid_left_edge[my_ind], h.grid_right_edge[my_ind])
+        self.LeftEdge = h.grid_left_edge[my_ind]
+        self.RightEdge = h.grid_right_edge[my_ind]
+        if iterable(self.Parent):
+            p = self.Parent[0]
+        else:
+            p = self.Parent
+        if p is not None:
+            self.LeftEdge[:] = clamp_edges(
+                self.LeftEdge.d, p.LeftEdge.d, p.dds.d)
+            self.RightEdge[:] = clamp_edges(
+                self.RightEdge.d, p.LeftEdge.d, p.dds.d)
         h.grid_levels[my_ind, 0] = self.Level
         # This might be needed for streaming formats
         #self.Time = h.gridTimes[my_ind,0]
         self.NumberOfParticles = h.grid_particle_count[my_ind, 0]
 
-    def _clamp_edges(self, left_edge, right_edge):
-        if self.Parent is None or self.Parent == []:
-            return left_edge, right_edge
-        start_index = np.zeros((2, 3))
-        if iterable(self.Parent):
-            p = self.Parent[0]
-        else:
-            p = self.Parent
-        pdx = p.dds
-        start_index[0, :] = (left_edge - p.LeftEdge) / pdx
-        start_index[1, :] = (right_edge - p.LeftEdge) / pdx
-        integer_index = np.rint(start_index)
-        need_adjustment = (start_index != integer_index).any(axis=1)
-        if need_adjustment[0]:
-            left_edge = (integer_index[0, :] * pdx + p.LeftEdge)
-        elif need_adjustment[1]:
-            right_edge = (integer_index[1, :] * pdx + p.LeftEdge)
-        return left_edge, right_edge
-
     def get_position(self, index):
         """ Returns center position of an *index*. """
         pos = (index + 0.5) * self.dds + self.LeftEdge

diff -r 5d7f932a04523c6863c305ccc3b9542ac6457cde -r 0d9af59d5365da59a35fc02ba2fd99fdb92b8f4b yt/utilities/lib/mesh_utilities.pyx
--- a/yt/utilities/lib/mesh_utilities.pyx
+++ b/yt/utilities/lib/mesh_utilities.pyx
@@ -17,6 +17,7 @@
 cimport numpy as np
 cimport cython
 from libc.stdlib cimport malloc, free, abs
+from libc.math cimport rint
 from yt.utilities.lib.fp_utils cimport imax, fmax, imin, fmin, iclip, fclip, i64clip
 
 @cython.boundscheck(False)
@@ -98,3 +99,21 @@
             fwidth = fmin(fwidth, RE[j] - LE[j])
     return fwidth
 
+ at cython.boundscheck(False)
+ at cython.wraparound(False)
+ at cython.cdivision(True)
+cpdef np.float64_t[:] clamp_edges(np.float64_t[:] edge, np.float64_t[:] pleft,
+                                  np.float64_t[:] pdx):
+    cdef np.float64_t start_index
+    cdef np.float64_t integer_index
+    cdef np.intp_t shape = edge.shape[0]
+    cdef np.float64_t[:] ret = np.empty(shape)
+    for i in range(shape):
+        start_index = (edge[i] - pleft[i]) / pdx[i]
+        integer_index = rint(start_index)
+        if start_index != integer_index:
+            ret[i] = integer_index * pdx[i] + pleft[i]
+        else:
+            ret[i] = edge[i]
+    return ret
+


https://bitbucket.org/yt_analysis/yt/commits/98296bbf433f/
Changeset:   98296bbf433f
User:        ngoldbaum
Date:        2017-05-30 19:10:48+00:00
Summary:     attempt to speed up grid generation
Affected #:  1 file

diff -r 0d9af59d5365da59a35fc02ba2fd99fdb92b8f4b -r 98296bbf433f055fce654aebf50c6da9873b4192 yt/data_objects/grid_patch.py
--- a/yt/data_objects/grid_patch.py
+++ b/yt/data_objects/grid_patch.py
@@ -25,6 +25,7 @@
 from yt.funcs import iterable
 from yt.geometry.selection_routines import convert_mask_to_indices
 import yt.geometry.particle_deposit as particle_deposit
+from yt.units.yt_array import YTArray
 from yt.utilities.exceptions import \
     YTFieldTypeNotFound, \
     YTParticleDepositionNotImplemented
@@ -137,19 +138,22 @@
         # So first we figure out what the index is.  We don't assume
         # that dx=dy=dz, at least here.  We probably do elsewhere.
         id = self.id - self._id_offset
+        ds = self.ds
+        index = self.index
         if self.Parent is not None:
             if not hasattr(self.Parent, 'dds'):
                 self.Parent._setup_dx()
-            self.dds = self.Parent.dds.ndarray_view() / self.ds.refine_by
+            self.dds = self.Parent.dds.d / self.ds.refine_by
         else:
-            LE, RE = self.index.grid_left_edge[id,:], \
-                     self.index.grid_right_edge[id,:]
+            LE, RE = (index.grid_left_edge[id, :].d,
+                      index.grid_right_edge[id, :].d)
             self.dds = (RE - LE) / self.ActiveDimensions
-        if self.ds.dimensionality < 2:
-            self.dds[1] = self.ds.domain_right_edge[1] - self.ds.domain_left_edge[1]
         if self.ds.dimensionality < 3:
-            self.dds[2] = self.ds.domain_right_edge[2] - self.ds.domain_left_edge[2]
-        self.dds = self.ds.arr(self.dds, "code_length")
+            self.dds[2] = ds.domain_right_edge[2] - ds.domain_left_edge[2]
+        elif self.ds.dimensionality < 2:
+            self.dds[1] = ds.domain_right_edge[1] - ds.domain_left_edge[1]
+        self.dds = self.dds.view(YTArray)
+        self.dds.units = self.index.grid_left_edge.units
 
     def __repr__(self):
         return "AMRGridPatch_%04i" % (self.id)


https://bitbucket.org/yt_analysis/yt/commits/de4913adcc3a/
Changeset:   de4913adcc3a
User:        ngoldbaum
Date:        2017-05-30 19:11:04+00:00
Summary:     fix failing tests
Affected #:  1 file

diff -r 98296bbf433f055fce654aebf50c6da9873b4192 -r de4913adcc3a2331f6071b7ad01f0ed24d66ddf3 yt/frontends/stream/data_structures.py
--- a/yt/frontends/stream/data_structures.py
+++ b/yt/frontends/stream/data_structures.py
@@ -191,6 +191,7 @@
             if (i%1e4) == 0: mylog.debug("Prepared % 7i / % 7i grids", i, self.num_grids)
             grid.filename = None
             grid._prepare_grid()
+            grid._setup_dx()
             grid.proc_num = self.grid_procs[i]
             temp_grids[i] = grid
         self.grids = temp_grids


https://bitbucket.org/yt_analysis/yt/commits/428430d1a0c6/
Changeset:   428430d1a0c6
User:        ngoldbaum
Date:        2017-05-30 20:10:14+00:00
Summary:     add a configuration option to restore the old behavior
Affected #:  4 files

diff -r de4913adcc3a2331f6071b7ad01f0ed24d66ddf3 -r 428430d1a0c64807b24ca05b17f4f426e3a759e5 doc/source/reference/configuration.rst
--- a/doc/source/reference/configuration.rst
+++ b/doc/source/reference/configuration.rst
@@ -91,6 +91,12 @@
 * ``test_data_dir`` (default: ``'/does/not/exist'``): The default path the
   ``load()`` function searches for datasets when it cannot find a dataset in the
   current directory.
+* ``reconstruct_index`` (default: True): If True, grid edges for patch AMR
+  datasets will be adjusted such that they fall as close as possible to an
+  integer multiple of the local cell width. If you are working with a dataset
+  with a large number of grids, setting this to False can speed up loading
+  your dataset possibly at the cost of grid-aligned artifacts showing up in
+  slice visualizations.
 * ``notebook_password`` (default: empty): If set, this will be fed to the
   IPython notebook created by ``yt notebook``.  Note that this should be an
   sha512 hash, not a plaintext password.  Starting ``yt notebook`` with no

diff -r de4913adcc3a2331f6071b7ad01f0ed24d66ddf3 -r 428430d1a0c64807b24ca05b17f4f426e3a759e5 yt/config.py
--- a/yt/config.py
+++ b/yt/config.py
@@ -45,6 +45,7 @@
     pluginfilename = 'my_plugins.py',
     parallel_traceback = 'False',
     pasteboard_repo = '',
+    reconstruct_index = 'True',
     test_storage_dir = '/does/not/exist',
     test_data_dir = '/does/not/exist',
     requires_ds_strict = 'False',

diff -r de4913adcc3a2331f6071b7ad01f0ed24d66ddf3 -r 428430d1a0c64807b24ca05b17f4f426e3a759e5 yt/data_objects/grid_patch.py
--- a/yt/data_objects/grid_patch.py
+++ b/yt/data_objects/grid_patch.py
@@ -18,6 +18,7 @@
 import numpy as np
 from six import string_types
 
+from yt.config import ytcfg
 from yt.data_objects.data_containers import \
     YTSelectionContainer
 from yt.data_objects.field_data import \
@@ -180,15 +181,20 @@
         self.ActiveDimensions = h.grid_dimensions[my_ind]
         self.LeftEdge = h.grid_left_edge[my_ind]
         self.RightEdge = h.grid_right_edge[my_ind]
-        if iterable(self.Parent):
-            p = self.Parent[0]
-        else:
-            p = self.Parent
-        if p is not None:
-            self.LeftEdge[:] = clamp_edges(
-                self.LeftEdge.d, p.LeftEdge.d, p.dds.d)
-            self.RightEdge[:] = clamp_edges(
-                self.RightEdge.d, p.LeftEdge.d, p.dds.d)
+        # This can be expensive so we allow people to disable this behavior
+        # via a config option
+        if bool(ytcfg.get('yt', 'reconstruct_index')):
+            if iterable(self.Parent):
+                p = self.Parent[0]
+            else:
+                p = self.Parent
+            if p is not None:
+                # clamp grid edges to an integer multiple of the parent cell
+                # width
+                self.LeftEdge.view(np.ndarray)[:] = clamp_edges(
+                    self.LeftEdge, p.LeftEdge, p.dds)
+                self.RightEdge.view(np.ndarray)[:] = clamp_edges(
+                    self.RightEdge, p.LeftEdge, p.dds)
         h.grid_levels[my_ind, 0] = self.Level
         # This might be needed for streaming formats
         #self.Time = h.gridTimes[my_ind,0]

diff -r de4913adcc3a2331f6071b7ad01f0ed24d66ddf3 -r 428430d1a0c64807b24ca05b17f4f426e3a759e5 yt/utilities/lib/mesh_utilities.pyx
--- a/yt/utilities/lib/mesh_utilities.pyx
+++ b/yt/utilities/lib/mesh_utilities.pyx
@@ -19,6 +19,7 @@
 from libc.stdlib cimport malloc, free, abs
 from libc.math cimport rint
 from yt.utilities.lib.fp_utils cimport imax, fmax, imin, fmin, iclip, fclip, i64clip
+from yt.units.yt_array import YTArray
 
 @cython.boundscheck(False)
 @cython.wraparound(False)
@@ -102,8 +103,9 @@
 @cython.boundscheck(False)
 @cython.wraparound(False)
 @cython.cdivision(True)
-cpdef np.float64_t[:] clamp_edges(np.float64_t[:] edge, np.float64_t[:] pleft,
-                                  np.float64_t[:] pdx):
+def clamp_edges(np.float64_t[:] edge, np.float64_t[:] pleft,
+                np.float64_t[:] pdx):
+    """Clamp edge to pleft + pdx*n where n is the closest integer"""
     cdef np.float64_t start_index
     cdef np.float64_t integer_index
     cdef np.intp_t shape = edge.shape[0]
@@ -116,4 +118,3 @@
         else:
             ret[i] = edge[i]
     return ret
-


https://bitbucket.org/yt_analysis/yt/commits/b2f8e779ee77/
Changeset:   b2f8e779ee77
User:        ngoldbaum
Date:        2017-05-30 21:09:24+00:00
Summary:     handle case when Parent is equal to []
Affected #:  1 file

diff -r 428430d1a0c64807b24ca05b17f4f426e3a759e5 -r b2f8e779ee7734c03aa0655c0d4043f902bb9c9b yt/data_objects/grid_patch.py
--- a/yt/data_objects/grid_patch.py
+++ b/yt/data_objects/grid_patch.py
@@ -184,11 +184,11 @@
         # This can be expensive so we allow people to disable this behavior
         # via a config option
         if bool(ytcfg.get('yt', 'reconstruct_index')):
-            if iterable(self.Parent):
+            if iterable(self.Parent) and len(self.Parent) > 0:
                 p = self.Parent[0]
             else:
                 p = self.Parent
-            if p is not None:
+            if p is not None and p != []:
                 # clamp grid edges to an integer multiple of the parent cell
                 # width
                 self.LeftEdge.view(np.ndarray)[:] = clamp_edges(


https://bitbucket.org/yt_analysis/yt/commits/e6ce12c8b294/
Changeset:   e6ce12c8b294
User:        ngoldbaum
Date:        2017-05-31 14:23:25+00:00
Summary:     Update answer numbers for failing tests
Affected #:  1 file

diff -r b2f8e779ee7734c03aa0655c0d4043f902bb9c9b -r e6ce12c8b294c4503dc553ce57844e4f92bed2a9 tests/tests.yaml
--- a/tests/tests.yaml
+++ b/tests/tests.yaml
@@ -17,7 +17,7 @@
   local_fits_001:
     - yt/frontends/fits/tests/test_outputs.py
 
-  local_flash_005:
+  local_flash_006:
     - yt/frontends/flash/tests/test_outputs.py
 
   local_gadget_001:
@@ -42,7 +42,7 @@
   local_owls_001:
     - yt/frontends/owls/tests/test_outputs.py
 
-  local_pw_014:
+  local_pw_015:
     - yt/visualization/tests/test_plotwindow.py:test_attributes
     - yt/visualization/tests/test_plotwindow.py:test_attributes_wt
     - yt/visualization/tests/test_profile_plots.py:test_phase_plot_attributes
@@ -104,7 +104,7 @@
     - yt/analysis_modules/absorption_spectrum/tests/test_absorption_spectrum.py:test_absorption_spectrum_cosmo_sph
     - yt/analysis_modules/absorption_spectrum/tests/test_absorption_spectrum.py:test_absorption_spectrum_with_continuum
 
-  local_axialpix_001:
+  local_axialpix_002:
     - yt/geometry/coordinates/tests/test_axial_pixelization.py:test_axial_pixelization
 
   local_particle_trajectory_000:


https://bitbucket.org/yt_analysis/yt/commits/97b5864680de/
Changeset:   97b5864680de
User:        ngoldbaum
Date:        2017-05-31 19:27:24+00:00
Summary:     cache reconstruct_index
Affected #:  1 file

diff -r e6ce12c8b294c4503dc553ce57844e4f92bed2a9 -r 97b5864680de255a5e053472eb9b4016f9f58e29 yt/data_objects/grid_patch.py
--- a/yt/data_objects/grid_patch.py
+++ b/yt/data_objects/grid_patch.py
@@ -69,6 +69,7 @@
         self._last_selector_id = None
         self._current_particle_type = 'all'
         self._current_fluid_type = self.ds.default_fluid_type
+        self._reconstruct_index = bool(ytcfg.get('yt', 'reconstruct_index'))
 
     def get_global_startindex(self):
         """
@@ -183,7 +184,7 @@
         self.RightEdge = h.grid_right_edge[my_ind]
         # This can be expensive so we allow people to disable this behavior
         # via a config option
-        if bool(ytcfg.get('yt', 'reconstruct_index')):
+        if self._reconstruct_index:
             if iterable(self.Parent) and len(self.Parent) > 0:
                 p = self.Parent[0]
             else:


https://bitbucket.org/yt_analysis/yt/commits/e5efa42c0301/
Changeset:   e5efa42c0301
User:        ngoldbaum
Date:        2017-05-31 19:45:26+00:00
Summary:     really cache the config option
Affected #:  1 file

diff -r 97b5864680de255a5e053472eb9b4016f9f58e29 -r e5efa42c0301dbad10a05eec272a1359016e90a5 yt/data_objects/grid_patch.py
--- a/yt/data_objects/grid_patch.py
+++ b/yt/data_objects/grid_patch.py
@@ -37,6 +37,8 @@
 from yt.utilities.nodal_data_utils import \
     get_nodal_slices
 
+RECONSTRUCT_INDEX = bool(ytcfg.get('yt', 'reconstruct_index'))
+
 class AMRGridPatch(YTSelectionContainer):
     _spatial = True
     _num_ghost_zones = 0
@@ -69,7 +71,6 @@
         self._last_selector_id = None
         self._current_particle_type = 'all'
         self._current_fluid_type = self.ds.default_fluid_type
-        self._reconstruct_index = bool(ytcfg.get('yt', 'reconstruct_index'))
 
     def get_global_startindex(self):
         """
@@ -184,7 +185,7 @@
         self.RightEdge = h.grid_right_edge[my_ind]
         # This can be expensive so we allow people to disable this behavior
         # via a config option
-        if self._reconstruct_index:
+        if RECONSTRUCT_INDEX:
             if iterable(self.Parent) and len(self.Parent) > 0:
                 p = self.Parent[0]
             else:


https://bitbucket.org/yt_analysis/yt/commits/f94f023b7a68/
Changeset:   f94f023b7a68
User:        ngoldbaum
Date:        2017-05-31 21:42:02+00:00
Summary:     modify edge in-place, this saves a bunch of time
Affected #:  2 files

diff -r e5efa42c0301dbad10a05eec272a1359016e90a5 -r f94f023b7a68174e8113b1239041b0e0ccd06f03 yt/data_objects/grid_patch.py
--- a/yt/data_objects/grid_patch.py
+++ b/yt/data_objects/grid_patch.py
@@ -193,10 +193,8 @@
             if p is not None and p != []:
                 # clamp grid edges to an integer multiple of the parent cell
                 # width
-                self.LeftEdge.view(np.ndarray)[:] = clamp_edges(
-                    self.LeftEdge, p.LeftEdge, p.dds)
-                self.RightEdge.view(np.ndarray)[:] = clamp_edges(
-                    self.RightEdge, p.LeftEdge, p.dds)
+                clamp_edges(self.LeftEdge, p.LeftEdge, p.dds)
+                clamp_edges(self.RightEdge, p.LeftEdge, p.dds)
         h.grid_levels[my_ind, 0] = self.Level
         # This might be needed for streaming formats
         #self.Time = h.gridTimes[my_ind,0]

diff -r e5efa42c0301dbad10a05eec272a1359016e90a5 -r f94f023b7a68174e8113b1239041b0e0ccd06f03 yt/utilities/lib/mesh_utilities.pyx
--- a/yt/utilities/lib/mesh_utilities.pyx
+++ b/yt/utilities/lib/mesh_utilities.pyx
@@ -105,16 +105,14 @@
 @cython.cdivision(True)
 def clamp_edges(np.float64_t[:] edge, np.float64_t[:] pleft,
                 np.float64_t[:] pdx):
-    """Clamp edge to pleft + pdx*n where n is the closest integer"""
+    """Clamp edge to pleft + pdx*n where n is the closest integer
+
+    Note that edge is modified in-place.
+    """
     cdef np.float64_t start_index
     cdef np.float64_t integer_index
     cdef np.intp_t shape = edge.shape[0]
-    cdef np.float64_t[:] ret = np.empty(shape)
     for i in range(shape):
         start_index = (edge[i] - pleft[i]) / pdx[i]
         integer_index = rint(start_index)
-        if start_index != integer_index:
-            ret[i] = integer_index * pdx[i] + pleft[i]
-        else:
-            ret[i] = edge[i]
-    return ret
+        edge[i] = integer_index * pdx[i] + pleft[i]


https://bitbucket.org/yt_analysis/yt/commits/fc8b883d884e/
Changeset:   fc8b883d884e
User:        jzuhone
Date:        2017-06-14 16:22:45+00:00
Summary:     Merge pull request #1433 from ngoldbaum/child-mask-fix

Ensure grid edges are consistent with edges computed by masks
Affected #:  9 files

diff -r 3534461f76f1c27948ee3ae5690925e7e6167974 -r fc8b883d884e901840c0eb707db889c4ac8bddc7 doc/source/reference/configuration.rst
--- a/doc/source/reference/configuration.rst
+++ b/doc/source/reference/configuration.rst
@@ -91,6 +91,12 @@
 * ``test_data_dir`` (default: ``'/does/not/exist'``): The default path the
   ``load()`` function searches for datasets when it cannot find a dataset in the
   current directory.
+* ``reconstruct_index`` (default: True): If True, grid edges for patch AMR
+  datasets will be adjusted such that they fall as close as possible to an
+  integer multiple of the local cell width. If you are working with a dataset
+  with a large number of grids, setting this to False can speed up loading
+  your dataset possibly at the cost of grid-aligned artifacts showing up in
+  slice visualizations.
 * ``notebook_password`` (default: empty): If set, this will be fed to the
   IPython notebook created by ``yt notebook``.  Note that this should be an
   sha512 hash, not a plaintext password.  Starting ``yt notebook`` with no

diff -r 3534461f76f1c27948ee3ae5690925e7e6167974 -r fc8b883d884e901840c0eb707db889c4ac8bddc7 tests/tests.yaml
--- a/tests/tests.yaml
+++ b/tests/tests.yaml
@@ -17,7 +17,7 @@
   local_fits_001:
     - yt/frontends/fits/tests/test_outputs.py
 
-  local_flash_005:
+  local_flash_006:
     - yt/frontends/flash/tests/test_outputs.py
 
   local_gadget_001:
@@ -42,7 +42,7 @@
   local_owls_001:
     - yt/frontends/owls/tests/test_outputs.py
 
-  local_pw_014:
+  local_pw_015:
     - yt/visualization/tests/test_plotwindow.py:test_attributes
     - yt/visualization/tests/test_plotwindow.py:test_attributes_wt
     - yt/visualization/tests/test_profile_plots.py:test_phase_plot_attributes
@@ -104,7 +104,7 @@
     - yt/analysis_modules/absorption_spectrum/tests/test_absorption_spectrum.py:test_absorption_spectrum_cosmo_sph
     - yt/analysis_modules/absorption_spectrum/tests/test_absorption_spectrum.py:test_absorption_spectrum_with_continuum
 
-  local_axialpix_001:
+  local_axialpix_002:
     - yt/geometry/coordinates/tests/test_axial_pixelization.py:test_axial_pixelization
 
   local_particle_trajectory_000:

diff -r 3534461f76f1c27948ee3ae5690925e7e6167974 -r fc8b883d884e901840c0eb707db889c4ac8bddc7 yt/config.py
--- a/yt/config.py
+++ b/yt/config.py
@@ -45,7 +45,7 @@
     pluginfilename = 'my_plugins.py',
     parallel_traceback = 'False',
     pasteboard_repo = '',
-    reconstruct_index = 'False',
+    reconstruct_index = 'True',
     test_storage_dir = '/does/not/exist',
     test_data_dir = '/does/not/exist',
     requires_ds_strict = 'False',

diff -r 3534461f76f1c27948ee3ae5690925e7e6167974 -r fc8b883d884e901840c0eb707db889c4ac8bddc7 yt/data_objects/grid_patch.py
--- a/yt/data_objects/grid_patch.py
+++ b/yt/data_objects/grid_patch.py
@@ -18,20 +18,27 @@
 import numpy as np
 from six import string_types
 
+from yt.config import ytcfg
 from yt.data_objects.data_containers import \
     YTSelectionContainer
 from yt.data_objects.field_data import \
     YTFieldData
+from yt.funcs import iterable
 from yt.geometry.selection_routines import convert_mask_to_indices
 import yt.geometry.particle_deposit as particle_deposit
+from yt.units.yt_array import YTArray
 from yt.utilities.exceptions import \
     YTFieldTypeNotFound, \
     YTParticleDepositionNotImplemented
 from yt.utilities.lib.interpolators import \
     ghost_zone_interpolate
+from yt.utilities.lib.mesh_utilities import \
+    clamp_edges
 from yt.utilities.nodal_data_utils import \
     get_nodal_slices
 
+RECONSTRUCT_INDEX = bool(ytcfg.get('yt', 'reconstruct_index'))
+
 class AMRGridPatch(YTSelectionContainer):
     _spatial = True
     _num_ghost_zones = 0
@@ -134,19 +141,22 @@
         # So first we figure out what the index is.  We don't assume
         # that dx=dy=dz, at least here.  We probably do elsewhere.
         id = self.id - self._id_offset
+        ds = self.ds
+        index = self.index
         if self.Parent is not None:
             if not hasattr(self.Parent, 'dds'):
                 self.Parent._setup_dx()
-            self.dds = self.Parent.dds.ndarray_view() / self.ds.refine_by
+            self.dds = self.Parent.dds.d / self.ds.refine_by
         else:
-            LE, RE = self.index.grid_left_edge[id,:], \
-                     self.index.grid_right_edge[id,:]
+            LE, RE = (index.grid_left_edge[id, :].d,
+                      index.grid_right_edge[id, :].d)
             self.dds = (RE - LE) / self.ActiveDimensions
-        if self.ds.dimensionality < 2:
-            self.dds[1] = self.ds.domain_right_edge[1] - self.ds.domain_left_edge[1]
         if self.ds.dimensionality < 3:
-            self.dds[2] = self.ds.domain_right_edge[2] - self.ds.domain_left_edge[2]
-        self.dds = self.ds.arr(self.dds, "code_length")
+            self.dds[2] = ds.domain_right_edge[2] - ds.domain_left_edge[2]
+        elif self.ds.dimensionality < 2:
+            self.dds[1] = ds.domain_right_edge[1] - ds.domain_left_edge[1]
+        self.dds = self.dds.view(YTArray)
+        self.dds.units = self.index.grid_left_edge.units
 
     def __repr__(self):
         return "AMRGridPatch_%04i" % (self.id)
@@ -173,6 +183,18 @@
         self.ActiveDimensions = h.grid_dimensions[my_ind]
         self.LeftEdge = h.grid_left_edge[my_ind]
         self.RightEdge = h.grid_right_edge[my_ind]
+        # This can be expensive so we allow people to disable this behavior
+        # via a config option
+        if RECONSTRUCT_INDEX:
+            if iterable(self.Parent) and len(self.Parent) > 0:
+                p = self.Parent[0]
+            else:
+                p = self.Parent
+            if p is not None and p != []:
+                # clamp grid edges to an integer multiple of the parent cell
+                # width
+                clamp_edges(self.LeftEdge, p.LeftEdge, p.dds)
+                clamp_edges(self.RightEdge, p.LeftEdge, p.dds)
         h.grid_levels[my_ind, 0] = self.Level
         # This might be needed for streaming formats
         #self.Time = h.gridTimes[my_ind,0]

diff -r 3534461f76f1c27948ee3ae5690925e7e6167974 -r fc8b883d884e901840c0eb707db889c4ac8bddc7 yt/frontends/enzo/data_structures.py
--- a/yt/frontends/enzo/data_structures.py
+++ b/yt/frontends/enzo/data_structures.py
@@ -30,7 +30,6 @@
     ensure_tuple, \
     get_pbar, \
     setdefaultattr
-from yt.config import ytcfg
 from yt.data_objects.grid_patch import \
     AMRGridPatch
 from yt.geometry.grid_geometry_handler import \
@@ -66,28 +65,6 @@
         self._parent_id = -1
         self.Level = -1
 
-    def _guess_properties_from_parent(self):
-        """
-        We know that our grid boundary occurs on the cell boundary of our
-        parent.  This can be a very expensive process, but it is necessary
-        in some indexs, where yt is unable to generate a completely
-        space-filling tiling of grids, possibly due to the finite accuracy in a
-        standard Enzo index file.
-        """
-        rf = self.ds.refine_by
-        my_ind = self.id - self._id_offset
-        self.dds = self.Parent.dds/rf
-        ParentLeftIndex = np.rint((self.LeftEdge-self.Parent.LeftEdge)/self.Parent.dds)
-        self.start_index = rf*(ParentLeftIndex + self.Parent.get_global_startindex()).astype('int64')
-        self.LeftEdge = self.Parent.LeftEdge + self.Parent.dds * ParentLeftIndex
-        self.RightEdge = self.LeftEdge + self.ActiveDimensions*self.dds
-        self.index.grid_left_edge[my_ind,:] = self.LeftEdge
-        self.index.grid_right_edge[my_ind,:] = self.RightEdge
-        self._child_mask = None
-        self._child_index_mask = None
-        self._child_indices = None
-        self._setup_dx()
-
     def set_filename(self, filename):
         """
         Intelligently set the filename.
@@ -380,13 +357,10 @@
         mylog.info("Finished rebuilding")
 
     def _populate_grid_objects(self):
-        reconstruct = ytcfg.getboolean("yt","reconstruct_index")
         for g,f in izip(self.grids, self.filenames):
             g._prepare_grid()
             g._setup_dx()
             g.set_filename(f[0])
-            if reconstruct:
-                if g.Parent is not None: g._guess_properties_from_parent()
         del self.filenames # No longer needed.
         self.max_level = self.grid_levels.max()
 

diff -r 3534461f76f1c27948ee3ae5690925e7e6167974 -r fc8b883d884e901840c0eb707db889c4ac8bddc7 yt/frontends/enzo/tests/test_outputs.py
--- a/yt/frontends/enzo/tests/test_outputs.py
+++ b/yt/frontends/enzo/tests/test_outputs.py
@@ -28,6 +28,8 @@
     data_dir_load, \
     AnalyticHaloMassFunctionTest, \
     SimulatedHaloMassFunctionTest
+from yt.visualization.plot_window import \
+    SlicePlot
 from yt.frontends.enzo.api import EnzoDataset
 from yt.frontends.enzo.fields import NODAL_FLAGS
 
@@ -42,6 +44,7 @@
 toro1d = "ToroShockTube/DD0001/data0001"
 kh2d = "EnzoKelvinHelmholtz/DD0011/DD0011"
 mhdctot = "MHDCTOrszagTang/DD0004/data0004"
+dnz = "DeeplyNestedZoom/DD0025/data0025"
 
 def check_color_conservation(ds):
     species_names = ds.field_info.species_names
@@ -191,3 +194,17 @@
     assert (ad['BxF'].sum(axis=-1)/2 == ad['Bx']).all()
     assert (ad['ByF'].sum(axis=-1)/2 == ad['By']).all()
     assert (ad['BzF'].sum(axis=-1)/2 == ad['Bz']).all()
+
+ at requires_file(dnz)
+def test_deeply_nested_zoom():
+    ds = data_dir_load(dnz)
+
+    # carefully chosen to just barely miss a grid in the middle of the image
+    center = [0.4915073260199302, 0.5052605316800006, 0.4905805557500548]
+    
+    plot = SlicePlot(ds, 'z', 'density', width=(0.001, 'pc'),
+                     center=center)
+
+    image = plot.frb['density']
+
+    assert (image > 0).all()

diff -r 3534461f76f1c27948ee3ae5690925e7e6167974 -r fc8b883d884e901840c0eb707db889c4ac8bddc7 yt/frontends/stream/data_structures.py
--- a/yt/frontends/stream/data_structures.py
+++ b/yt/frontends/stream/data_structures.py
@@ -102,21 +102,6 @@
         self._parent_id = -1
         self.Level = -1
 
-    def _guess_properties_from_parent(self):
-        rf = self.ds.refine_by
-        my_ind = self.id - self._id_offset
-        self.dds = self.Parent.dds/rf
-        ParentLeftIndex = np.rint((self.LeftEdge-self.Parent.LeftEdge)/self.Parent.dds)
-        self.start_index = rf*(ParentLeftIndex + self.Parent.get_global_startindex()).astype('int64')
-        self.LeftEdge = self.Parent.LeftEdge + self.Parent.dds * ParentLeftIndex
-        self.RightEdge = self.LeftEdge + self.ActiveDimensions*self.dds
-        self.index.grid_left_edge[my_ind,:] = self.LeftEdge
-        self.index.grid_right_edge[my_ind,:] = self.RightEdge
-        self._child_mask = None
-        self._child_index_mask = None
-        self._child_indices = None
-        self._setup_dx()
-
     def set_filename(self, filename):
         pass
 
@@ -211,6 +196,7 @@
             if (i%1e4) == 0: mylog.debug("Prepared % 7i / % 7i grids", i, self.num_grids)
             grid.filename = None
             grid._prepare_grid()
+            grid._setup_dx()
             grid.proc_num = self.grid_procs[i]
             temp_grids[i] = grid
         self.grids = temp_grids

diff -r 3534461f76f1c27948ee3ae5690925e7e6167974 -r fc8b883d884e901840c0eb707db889c4ac8bddc7 yt/utilities/lib/mesh_utilities.pyx
--- a/yt/utilities/lib/mesh_utilities.pyx
+++ b/yt/utilities/lib/mesh_utilities.pyx
@@ -17,7 +17,9 @@
 cimport numpy as np
 cimport cython
 from libc.stdlib cimport malloc, free, abs
+from libc.math cimport rint
 from yt.utilities.lib.fp_utils cimport imax, fmax, imin, fmin, iclip, fclip, i64clip
+from yt.units.yt_array import YTArray
 
 @cython.boundscheck(False)
 @cython.wraparound(False)
@@ -98,3 +100,19 @@
             fwidth = fmin(fwidth, RE[j] - LE[j])
     return fwidth
 
+ at cython.boundscheck(False)
+ at cython.wraparound(False)
+ at cython.cdivision(True)
+def clamp_edges(np.float64_t[:] edge, np.float64_t[:] pleft,
+                np.float64_t[:] pdx):
+    """Clamp edge to pleft + pdx*n where n is the closest integer
+
+    Note that edge is modified in-place.
+    """
+    cdef np.float64_t start_index
+    cdef np.float64_t integer_index
+    cdef np.intp_t shape = edge.shape[0]
+    for i in range(shape):
+        start_index = (edge[i] - pleft[i]) / pdx[i]
+        integer_index = rint(start_index)
+        edge[i] = integer_index * pdx[i] + pleft[i]

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