<html><body>
<p>12 new commits in yt:</p>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/02c5536607fd/">https://bitbucket.org/yt_analysis/yt/commits/02c5536607fd/</a> Changeset:   02c5536607fd Branch:      yt User:        chummels Date:        2015-12-05 19:25:41+00:00 Summary:     Adding width and starting_pos kwargs to annotate_arrow() callback Affected #:  1 file</p>
<p>diff -r 315acc8b8296a1655efbc5fa6dfc9c88fab44b62 -r 02c5536607fd7a9e07c2522ecfd26aa362cabb56 yt/visualization/plot_modifications.py --- a/yt/visualization/plot_modifications.py +++ b/yt/visualization/plot_modifications.py @@ -901,11 +901,13 @@</p>
<pre>class ArrowCallback(PlotCallback):
    """</pre>
<ul><li><p>annotate_arrow(pos, length=0.03, coord_system='data', plot_args=None):</p></li></ul>
<p>+    annotate_arrow(pos, length=0.03, width=0.06, starting_pos=None, +                   coord_system='data', plot_args=None):</p>
<pre>Overplot an arrow pointing at a position for highlighting a specific
feature.  Arrow points from lower left to the designated position with</pre>
<ul><li><p>arrow length “length”.</p></li></ul>
<p>+    arrow length “length” unless starting_pos is set to specify tail location +    of arrow.</p>
<pre>Parameters
----------</pre>
<p>@@ -914,6 +916,15 @@</p>
<pre>length : float, optional
    The length, in axis units, of the arrow.</pre>
<p>+        Default: 0.03 + +    width : float, optional +        The width, in axis units, of the arrow. +        Default: 0.06 + +    starting_pos : 2- or 3-element tuple, list, or array, optional +        These are the coordinates from which the arrow starts towards its +        point.  Not compatible with ‘length’ kwarg.</p>
<pre>coord_system : string, optional
    This string defines the coordinate system of the coordinates of pos</pre>
<p>@@ -948,18 +959,20 @@</p>
<pre>>>> import yt
>>> ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030')
>>> s = yt.SlicePlot(ds, 'z', 'density')</pre>
<ul><li><blockquote><blockquote><blockquote><p>s.annotate_arrow([0.1, -0.1, length=0.06, coord_system='plot',</p></blockquote></blockquote></blockquote></li></ul>
<p>+    >>> s.annotate_arrow([0.1, -0.1], length=0.06, coord_system='plot',</p>
<pre>    ...                  plot_args={'color':'red'})
    >>> s.save()

    """
    _type_name = "arrow"</pre>
<ul><li><p>def __init__(self, pos, code_size=None, length=0.03, coord_system='data',</p></li>
<li><p>plot_args=None):</p></li></ul>
<p>+    def __init__(self, pos, code_size=None, length=0.03, width=0.06, +                 starting_pos=None, coord_system='data', plot_args=None):</p>
<pre>def_plot_args = {'color':'white', 'linewidth':2}
self.pos = pos
self.code_size = code_size
self.length = length</pre>
<p>+        self.width = width +        self.starting_pos = starting_pos</p>
<pre>self.coord_system = coord_system
self.transform = None
if plot_args is None: plot_args = def_plot_args</pre>
<p>@@ -981,11 +994,20 @@</p>
<pre>self.code_size = self.code_size * self.pixel_scale(plot)[0]
dx = dy = self.code_size
         else:</pre>
<ul><li><p>dx = (xx1-xx0) * self.length</p></li>
<li><p>dy = (yy1-yy0) * self.length</p></li></ul>
<p>+            if self.starting_pos is not None: +                start_x,start_y = self.sanitize_coord_system(plot, \ +                                       self.starting_pos, \ +                                       coord_system=self.coord_system) +                dx = x – start_x +                dy = y – start_y +            else: +                dx = (xx1-xx0) * 2**(0.5) * self.length +                dy = (yy1-yy0) * 2**(0.5) * self.length</p>
<pre>plot._axes.hold(True)
from matplotlib.patches import Arrow</pre>
<ul><li><p>arrow = Arrow(x-dx, y-dy, dx, dy, width=dx,</p></li></ul>
<p>+        print “length = %f” % self.length +        print “width = %f” % self.width +        arrow = Arrow(x-dx, y-dy, dx, dy, width=self.width,</p>
<pre>transform=self.transform, **self.plot_args)
         plot._axes.add_patch(arrow)
         plot._axes.set_xlim(xx0,xx1)</pre>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/a5b85b78c5a0/">https://bitbucket.org/yt_analysis/yt/commits/a5b85b78c5a0/</a> Changeset:   a5b85b78c5a0 Branch:      yt User:        chummels Date:        2015-12-05 19:45:18+00:00 Summary:     Removing print statements. Affected #:  1 file</p>
<p>diff -r 02c5536607fd7a9e07c2522ecfd26aa362cabb56 -r a5b85b78c5a0f9508f7808ce51c716386f878db9 yt/visualization/plot_modifications.py --- a/yt/visualization/plot_modifications.py +++ b/yt/visualization/plot_modifications.py @@ -901,7 +901,7 @@</p>
<pre>class ArrowCallback(PlotCallback):
    """</pre>
<ul><li><p>annotate_arrow(pos, length=0.03, width=0.06, starting_pos=None,</p></li></ul>
<p>+    annotate_arrow(pos, length=0.03, width=0.03, starting_pos=None,</p>
<pre>                   coord_system='data', plot_args=None):

    Overplot an arrow pointing at a position for highlighting a specific</pre>
<p>@@ -920,7 +920,7 @@</p>
<pre>width : float, optional
    The width, in axis units, of the arrow.</pre>
<ul><li><p>Default: 0.06</p></li></ul>
<p>+        Default: 0.03</p>
<pre>starting_pos : 2- or 3-element tuple, list, or array, optional
    These are the coordinates from which the arrow starts towards its</pre>
<p>@@ -965,7 +965,7 @@</p>
<pre>"""
_type_name = "arrow"</pre>
<ul><li><p>def __init__(self, pos, code_size=None, length=0.03, width=0.06,</p></li></ul>
<p>+    def __init__(self, pos, code_size=None, length=0.03, width=0.03,</p>
<pre>starting_pos=None, coord_system='data', plot_args=None):
         def_plot_args = {'color':'white', 'linewidth':2}
         self.pos = pos</pre>
<p>@@ -1005,8 +1005,6 @@</p>
<pre>dy = (yy1-yy0) * 2**(0.5) * self.length
         plot._axes.hold(True)
         from matplotlib.patches import Arrow</pre>
<ul><li><p>print “length = %f” % self.length</p></li>
<li><p>print “width = %f” % self.width arrow = Arrow(x-dx, y-dy, dx, dy, width=self.width,</p>
<pre>transform=self.transform, **self.plot_args)</pre>
<p>plot._axes.add_patch(arrow)</p></li></ul>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/027833076b4c/">https://bitbucket.org/yt_analysis/yt/commits/027833076b4c/</a> Changeset:   027833076b4c Branch:      yt User:        chummels Date:        2015-12-05 20:25:36+00:00 Summary:     Updating annotate_arrow to use pyplot arrow instead of patches arrow. Affected #:  1 file</p>
<p>diff -r a5b85b78c5a0f9508f7808ce51c716386f878db9 -r 027833076b4c117e5f537e16e2f7fb7d54e88d3b yt/visualization/plot_modifications.py --- a/yt/visualization/plot_modifications.py +++ b/yt/visualization/plot_modifications.py @@ -901,7 +901,8 @@</p>
<pre>class ArrowCallback(PlotCallback):
    """</pre>
<ul><li><p>annotate_arrow(pos, length=0.03, width=0.03, starting_pos=None,</p></li></ul>
<p>+    annotate_arrow(pos, length=0.03, width=0.003, head_length=None, +                   head_width=0.02, starting_pos=None,</p>
<pre>                   coord_system='data', plot_args=None):

    Overplot an arrow pointing at a position for highlighting a specific</pre>
<p>@@ -919,8 +920,17 @@</p>
<pre>        Default: 0.03

    width : float, optional</pre>
<ul><li><p>The width, in axis units, of the arrow.</p></li>
<li><p>Default: 0.03</p></li></ul>
<p>+        The width, in axis units, of the tail line of the arrow. +        Default: 0.003 + +    head_length : float, optional +        The length, in axis units, of the head of the arrow.  If set +        to None, use 1.5*head_width +        Default: None + +    head_width : float, optional +        The width, in axis units, of the head of the arrow. +        Default: 0.02</p>
<pre>starting_pos : 2- or 3-element tuple, list, or array, optional
    These are the coordinates from which the arrow starts towards its</pre>
<p>@@ -942,7 +952,7 @@</p>
<pre>plot_args : dictionary, optional
    This dictionary is passed to the MPL arrow function for generating</pre>
<ul><li><p>the arrow.  By default, it is: {'color':'white', 'linewidth':2}</p></li></ul>
<p>+        the arrow.  By default, it is: {'color':'white'}</p>
<pre>Examples
--------</pre>
<p>@@ -965,13 +975,16 @@</p>
<pre>"""
_type_name = "arrow"</pre>
<ul><li><p>def __init__(self, pos, code_size=None, length=0.03, width=0.03,</p></li></ul>
<p>+    def __init__(self, pos, code_size=None, length=0.03, width=0.003, +                 head_width=0.02, head_length=None,</p>
<pre>starting_pos=None, coord_system='data', plot_args=None):</pre>
<ul><li><p>def_plot_args = {'color':'white', 'linewidth':2}</p></li></ul>
<p>+        def_plot_args = {'color':'white'}</p>
<pre>self.pos = pos
self.code_size = code_size
self.length = length
self.width = width</pre>
<p>+        self.head_width = head_width +        self.head_length = head_length</p>
<pre>self.starting_pos = starting_pos
self.coord_system = coord_system
self.transform = None</pre>
<p>@@ -1003,11 +1016,16 @@</p>
<pre>else:
    dx = (xx1-xx0) * 2**(0.5) * self.length
    dy = (yy1-yy0) * 2**(0.5) * self.length</pre>
<p>+        # If the arrow is 0 length +        if dx == dy == 0: +            warnings.warn("The arrow has zero length.  Not annotating.") +            return</p>
<pre>plot._axes.hold(True)</pre>
<ul><li><p>from matplotlib.patches import Arrow</p></li>
<li><p>arrow = Arrow(x-dx, y-dy, dx, dy, width=self.width,</p></li>
<li><p>transform=self.transform, **self.plot_args)</p></li>
<li><p>plot._axes.add_patch(arrow)</p></li></ul>
<p>+        plot._axes.arrow(x-dx, y-dy, dx, dy, width=self.width, +                         head_width=self.head_width, +                         head_length=self.head_length, +                         transform=self.transform, +                         length_includes_head=True, **self.plot_args)</p>
<pre>plot._axes.set_xlim(xx0,xx1)
plot._axes.set_ylim(yy0,yy1)
plot._axes.hold(False)</pre>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/eef6d0b77712/">https://bitbucket.org/yt_analysis/yt/commits/eef6d0b77712/</a> Changeset:   eef6d0b77712 Branch:      yt User:        chummels Date:        2015-12-05 20:48:54+00:00 Summary:     Updating annotate_ray to allow rays to be plotted as arrows if desired. Affected #:  1 file</p>
<p>diff -r 027833076b4c117e5f537e16e2f7fb7d54e88d3b -r eef6d0b777127b3940061d0834c76bb612004db5 yt/visualization/plot_modifications.py --- a/yt/visualization/plot_modifications.py +++ b/yt/visualization/plot_modifications.py @@ -1992,6 +1992,9 @@</p>
<pre>Adds a line representing the projected path of a ray across the plot.
The ray can be either a YTOrthoRay, YTRay, or a LightRay object.
annotate_ray() will properly account for periodic rays across the volume.</pre>
<p>+    If arrow is set to True, uses the MPL.pyplot.arrow function, otherwise +    uses the MPL.pyplot.plot function to plot a normal line.  Adjust +    plot_args accordingly.</p>
<pre>Parameters
----------</pre>
<p>@@ -2003,6 +2006,11 @@</p>
<pre>        object, it will only plot the segment of the LightRay that intersects
        the dataset currently displayed.
</pre>
<p>+    arrow : boolean, optional +        Whether or not to place an arrowhead on the front of the ray as it +        traverses the box. +        Default: False +</p>
<pre>plot_args : dictionary, optional
    A dictionary of any arbitrary parameters to be passed to the Matplotlib
    line object.  Defaults: {'color':'white', 'linewidth':2}.</pre>
<p>@@ -2033,10 +2041,11 @@</p>
<pre>"""
_type_name = "ray"</pre>
<ul><li><p>def __init__(self, ray, plot_args=None):</p></li></ul>
<p>+    def __init__(self, ray, arrow=False, plot_args=None):</p>
<pre>PlotCallback.__init__(self)
def_plot_args = {'color':'white', 'linewidth':2}
self.ray = ray</pre>
<p>+        self.arrow = arrow</p>
<pre>        if plot_args is None: plot_args = def_plot_args
        self.plot_args = plot_args
</pre>
<p>@@ -2107,10 +2116,16 @@</p>
<pre>            segments = [[start_coord, end_coord]]

        for segment in segments:</pre>
<ul><li><p>lcb = LinePlotCallback(segment[0], segment[1],</p></li></ul>
<p>+            if self.arrow: +                #import pdb; pdb.set_trace() +                cb = ArrowCallback(segment[1], starting_pos=segment[0],</p>
<pre>coord_system='data',
plot_args=self.plot_args)</pre>
<ul><li><p>lcb(plot)</p></li></ul>
<p>+            else: +                cb = LinePlotCallback(segment[0], segment[1], +                                   coord_system='data', +                                   plot_args=self.plot_args) +            cb(plot)</p>
<pre>        return plot
</pre>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/6907a36bd0a6/">https://bitbucket.org/yt_analysis/yt/commits/6907a36bd0a6/</a> Changeset:   6907a36bd0a6 Branch:      yt User:        chummels Date:        2015-12-05 21:46:53+00:00 Summary:     Making sanitize_coord_system actually return a tuple of floats for coordinates instead of a tuple of ndarrays. Affected #:  1 file</p>
<p>diff -r eef6d0b777127b3940061d0834c76bb612004db5 -r 6907a36bd0a609cc8013f8cd2a7b7fa256381adf yt/visualization/plot_modifications.py --- a/yt/visualization/plot_modifications.py +++ b/yt/visualization/plot_modifications.py @@ -156,6 +156,9 @@</p>
<pre>                      "need to be in 3D")
coord = self.project_coords(plot, coord)
coord = self.convert_to_plot(plot, coord)</pre>
<p>+            # Convert coordinates from a tuple of ndarray to a tuple of floats +            # since not all callbacks are OK with ndarrays as coords (eg arrow) +            coord = (coord[0][0], coord[1][0])</p>
<pre>         # if in plot coords, define the transform correctly
         if coord_system == "data" or coord_system == "plot":
self.transform = plot._axes.transData</pre>
<p>@@ -2117,7 +2120,6 @@</p>
<pre>         for segment in segments:
if self.arrow:</pre>
<ul><li><p>#import pdb; pdb.set_trace() cb = ArrowCallback(segment[1], starting_pos=segment[0],</p>
<pre>coord_system='data',
plot_args=self.plot_args)</pre></li></ul>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/8973f6081f8b/">https://bitbucket.org/yt_analysis/yt/commits/8973f6081f8b/</a> Changeset:   8973f6081f8b Branch:      yt User:        chummels Date:        2015-12-06 08:48:51+00:00 Summary:     Normaling arrow heads to current plot.  Assuring only final ray segment gets arrow head. Affected #:  1 file</p>
<p>diff -r 6907a36bd0a609cc8013f8cd2a7b7fa256381adf -r 8973f6081f8b504029a5d0be3939d3718da587c1 yt/visualization/plot_modifications.py --- a/yt/visualization/plot_modifications.py +++ b/yt/visualization/plot_modifications.py @@ -978,8 +978,8 @@</p>
<pre>"""
_type_name = "arrow"</pre>
<ul><li><p>def __init__(self, pos, code_size=None, length=0.03, width=0.003,</p></li>
<li><p>head_width=0.02, head_length=None,</p></li></ul>
<p>+    def __init__(self, pos, code_size=None, length=0.03, width=0.0001, +                 head_width=0.01, head_length=0.01,</p>
<pre>starting_pos=None, coord_system='data', plot_args=None):
         def_plot_args = {'color':'white'}
         self.pos = pos</pre>
<p>@@ -999,7 +999,13 @@</p>
<pre>coord_system=self.coord_system)
         xx0, xx1 = plot._axes.get_xlim()
         yy0, yy1 = plot._axes.get_ylim()</pre>
<p>– +        # normalize all of the kwarg lengths to the plot size +        plot_diag = ((yy1-yy0)**2 + (xx1-xx0)**2)**(0.5) +        self.length *= plot_diag +        self.width *= plot_diag +        self.head_width *= plot_diag +        if self.head_length is not None: +            self.head_length *= plot_diag</p>
<pre>         if self.code_size is not None:
warnings.warn("The code_size keyword is deprecated.  Please use "
              "the length keyword in 'axis' units instead. "</pre>
<p>@@ -2118,17 +2124,24 @@</p>
<pre>        else:
            segments = [[start_coord, end_coord]]
</pre>
<ul><li><p>for segment in segments:</p></li>
<li><p>if self.arrow:</p></li>
<li><p>cb = ArrowCallback(segment[1], starting_pos=segment[0],</p></li>
<li><p>coord_system='data',</p></li>
<li><p>plot_args=self.plot_args)</p></li>
<li><p>else:</p></li>
<li><p>cb = LinePlotCallback(segment[0], segment[1],</p></li>
<li><p>coord_system='data',</p></li>
<li><p>plot_args=self.plot_args)</p></li></ul>
<p>+        # To assure that the last ray segment has an arrow if so desired +        # and all other ray segments are lines +        for segment in segments[:-1]: +            cb = LinePlotCallback(segment[0], segment[1], +                                  coord_system='data', +                                  plot_args=self.plot_args)</p>
<pre>cb(plot)</pre>
<p>– +        segment = segments[-1] +        if self.arrow: +            cb = ArrowCallback(segment[1], starting_pos=segment[0], +                               coord_system='data', +                               plot_args=self.plot_args) +        else: +           cb = LinePlotCallback(segment[0], segment[1], +                               coord_system='data', +                               plot_args=self.plot_args) +        cb(plot) +</p>
<pre>        return plot

class LineIntegralConvolutionCallback(PlotCallback):</pre>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/7574d2271d1f/">https://bitbucket.org/yt_analysis/yt/commits/7574d2271d1f/</a> Changeset:   7574d2271d1f Branch:      yt User:        chummels Date:        2016-03-15 23:28:47+00:00 Summary:     Cleaning up docs for annotate_ray. Affected #:  1 file</p>
<p>diff -r 8973f6081f8b504029a5d0be3939d3718da587c1 -r 7574d2271d1f4e16bf4fda604f1cf41680377051 yt/visualization/plot_modifications.py --- a/yt/visualization/plot_modifications.py +++ b/yt/visualization/plot_modifications.py @@ -904,13 +904,13 @@</p>
<pre>class ArrowCallback(PlotCallback):
    """</pre>
<ul><li><p>annotate_arrow(pos, length=0.03, width=0.003, head_length=None,</p></li>
<li><p>head_width=0.02, starting_pos=None,</p></li></ul>
<p>+    annotate_arrow(pos, length=0.03, width=0.003, head_length=None, +                   head_width=0.02, starting_pos=None,</p>
<pre>                   coord_system='data', plot_args=None):

    Overplot an arrow pointing at a position for highlighting a specific
    feature.  Arrow points from lower left to the designated position with</pre>
<ul><li><p>arrow length “length” unless starting_pos is set to specify tail location</p></li></ul>
<p>+    arrow length “length” unless starting_pos is set to specify tail location</p>
<pre>    of arrow.

    Parameters</pre>
<p>@@ -978,7 +978,7 @@</p>
<pre>"""
_type_name = "arrow"</pre>
<ul><li><p>def __init__(self, pos, code_size=None, length=0.03, width=0.0001,</p></li></ul>
<p>+    def __init__(self, pos, code_size=None, length=0.03, width=0.0001,</p>
<pre>head_width=0.01, head_length=0.01,
starting_pos=None, coord_system='data', plot_args=None):
         def_plot_args = {'color':'white'}</pre>
<p>@@ -1030,10 +1030,10 @@</p>
<pre>warnings.warn("The arrow has zero length.  Not annotating.")
return
         plot._axes.hold(True)</pre>
<ul><li><p>plot._axes.arrow(x-dx, y-dy, dx, dy, width=self.width,</p></li>
<li><p>head_width=self.head_width,</p></li>
<li><p>head_length=self.head_length,</p></li>
<li><p>transform=self.transform,</p></li></ul>
<p>+        plot._axes.arrow(x-dx, y-dy, dx, dy, width=self.width, +                         head_width=self.head_width, +                         head_length=self.head_length, +                         transform=self.transform,</p>
<pre>length_includes_head=True, **self.plot_args)
         plot._axes.set_xlim(xx0,xx1)
         plot._axes.set_ylim(yy0,yy1)</pre>
<p>@@ -1796,8 +1796,8 @@</p>
<pre>axis length.  Additional customization of the scale bar is possible by
adjusting the text_args and size_bar_args dictionaries.  The text_args
dictionary accepts matplotlib's font_properties arguments to override</pre>
<ul><li><p>the default font_properties for the current plot.  The size_bar_args</p></li>
<li><p>dictionary accepts keyword arguments for the AnchoredSizeBar class in</p></li></ul>
<p>+    the default font_properties for the current plot.  The size_bar_args +    dictionary accepts keyword arguments for the AnchoredSizeBar class in</p>
<pre>    matplotlib's axes_grid toolkit.

    Parameters</pre>
<p>@@ -1877,7 +1877,7 @@</p>
<pre>     _type_name = "scale"
     def __init__(self, corner='lower_right', coeff=None, unit=None, pos=None,
max_frac=0.16, min_frac=0.015, coord_system='axis',</pre>
<ul><li><p>text_args=None, size_bar_args=None, draw_inset_box=False,</p></li></ul>
<p>+                 text_args=None, size_bar_args=None, draw_inset_box=False,</p>
<pre>                 inset_box_args=None):

        def_size_bar_args = {</pre>
<p>@@ -1970,7 +1970,7 @@</p>
<pre>         # FontProperties instances use set_<property>() setter functions
         for key, val in self.text_args.items():
setter_func = "set_"+key</pre>
<ul><li><p>try:</p></li></ul>
<p>+            try:</p>
<pre>    getattr(fontproperties, setter_func)(val)
except AttributeError:
    raise AttributeError("Cannot set text_args keyword " \</pre>
<p>@@ -2002,7 +2002,7 @@</p>
<pre>The ray can be either a YTOrthoRay, YTRay, or a LightRay object.
annotate_ray() will properly account for periodic rays across the volume.
If arrow is set to True, uses the MPL.pyplot.arrow function, otherwise</pre>
<ul><li><p>uses the MPL.pyplot.plot function to plot a normal line.  Adjust</p></li></ul>
<p>+    uses the MPL.pyplot.plot function to plot a normal line.  Adjust</p>
<pre>    plot_args accordingly.

    Parameters</pre>
<p>@@ -2016,8 +2016,8 @@</p>
<pre>        the dataset currently displayed.

    arrow : boolean, optional</pre>
<ul><li><p>Whether or not to place an arrowhead on the front of the ray as it</p></li>
<li><p>traverses the box.</p></li></ul>
<p>+        Whether or not to place an arrowhead on the front of the ray to denote +        direction</p>
<pre>        Default: False

    plot_args : dictionary, optional</pre>
<p>@@ -2133,7 +2133,7 @@</p>
<pre>cb(plot)
         segment = segments[-1]
         if self.arrow:</pre>
<ul><li><p>cb = ArrowCallback(segment[1], starting_pos=segment[0],</p></li></ul>
<p>+            cb = ArrowCallback(segment[1], starting_pos=segment[0],</p>
<pre>coord_system='data',
plot_args=self.plot_args)
         else:</pre>
<p>@@ -2141,7 +2141,6 @@</p>
<pre>coord_system='data',
plot_args=self.plot_args)
         cb(plot)</pre>
<p>–</p>
<pre>        return plot

class LineIntegralConvolutionCallback(PlotCallback):</pre>
<p>@@ -2151,7 +2150,7 @@</p>
<pre>                                       cmap='binary', alpha=0.8,
                                       const_alpha=False):
</pre>
<ul><li><p>Add the line integral convolution to the plot for vector fields</p></li></ul>
<p>+    Add the line integral convolution to the plot for vector fields</p>
<pre>    visualization. Two component of vector fields needed to be provided
    (i.e., velocity_x and velocity_y, magentic_field_x and magnetic_field_y).
</pre>
<p>@@ -2248,7 +2247,7 @@</p>
<pre>        lic_data_clip = np.clip(lic_data,self.lim[0],self.lim[1])

        if self.const_alpha:</pre>
<ul><li><p>plot._axes.imshow(lic_data_clip, extent=extent, cmap=self.cmap,</p></li></ul>
<p>+            plot._axes.imshow(lic_data_clip, extent=extent, cmap=self.cmap,</p>
<pre>                  alpha=self.alpha)
         else:
lic_data_rgba = cm.ScalarMappable(norm=None, cmap=self.cmap).\</pre>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/52b7292e3caf/">https://bitbucket.org/yt_analysis/yt/commits/52b7292e3caf/</a> Changeset:   52b7292e3caf Branch:      yt User:        chummels Date:        2016-03-16 18:54:59+00:00 Summary:     Merging with tip. Affected #:  457 files</p>
<p>diff -r 7574d2271d1f4e16bf4fda604f1cf41680377051 -r 52b7292e3caf231d622322be093b39bc35029222 .hgchurn --- a/.hgchurn +++ b/.hgchurn @@ -22,4 +22,21 @@</p>
<pre>ngoldbau@ucsc.edu = goldbaum@ucolick.org
biondo@wisc.edu = Biondo@wisc.edu
samgeen@googlemail.com = samgeen@gmail.com</pre>
<p>-fbogert = fbogert@ucsc.edu \ No newline at end of file +fbogert = fbogert@ucsc.edu +bwoshea = oshea@msu.edu +mornkr@slac.stanford.edu = me@jihoonkim.org +kbarrow = kssbarrow@gatech.edu +kssbarrow@gmail.com = kssbarrow@gatech.edu +kassbarrow@gmail.com = kssbarrow@gatech.edu +antoine.strugarek@cea.fr = strugarek@astro.umontreal.ca +rosen@ucolick.org = alrosen@ucsc.edu +jzuhone = jzuhone@gmail.com +karraki@nmsu.edu = karraki@gmail.com +hckr@eml.cc = astrohckr@gmail.com +julian3@illinois.edu = astrohckr@gmail.com +cosmosquark = bthompson2090@gmail.com +chris.m.malone@lanl.gov = chris.m.malone@gmail.com +jnaiman@ucolick.org = jnaiman +migueld.deval = miguel@archlinux.net +slevy@ncsa.illinois.edu = salevy@illinois.edu +malzraa@gmail.com = kellerbw@mcmaster.ca \ No newline at end of file</p>
<p>diff -r 7574d2271d1f4e16bf4fda604f1cf41680377051 -r 52b7292e3caf231d622322be093b39bc35029222 .hgignore --- a/.hgignore +++ b/.hgignore @@ -28,31 +28,34 @@</p>
<pre>yt/utilities/spatial/ckdtree.c
yt/utilities/lib/alt_ray_tracers.c
yt/utilities/lib/amr_kdtools.c</pre>
<p>+yt/utilities/lib/basic_octree.c</p>
<pre>yt/utilities/lib/bitarray.c</pre>
<p>-yt/utilities/lib/CICDeposit.c -yt/utilities/lib/ContourFinding.c -yt/utilities/lib/DepthFirstOctree.c +yt/utilities/lib/bounding_volume_hierarchy.c +yt/utilities/lib/contour_finding.c +yt/utilities/lib/depth_first_octree.c</p>
<pre>yt/utilities/lib/element_mappings.c</pre>
<p>-yt/utilities/lib/FixedInterpolator.c</p>
<pre>yt/utilities/lib/fortran_reader.c
yt/utilities/lib/freetype_writer.c
yt/utilities/lib/geometry_utils.c
yt/utilities/lib/image_utilities.c</pre>
<p>-yt/utilities/lib/Interpolators.c +yt/utilities/lib/interpolators.c</p>
<pre>yt/utilities/lib/kdtree.c
yt/utilities/lib/line_integral_convolution.c</pre>
<p>+yt/utilities/lib/mesh_construction.cpp +yt/utilities/lib/mesh_intersection.cpp +yt/utilities/lib/mesh_samplers.cpp +yt/utilities/lib/mesh_traversal.cpp</p>
<pre>yt/utilities/lib/mesh_utilities.c
yt/utilities/lib/misc_utilities.c</pre>
<p>-yt/utilities/lib/Octree.c -yt/utilities/lib/GridTree.c +yt/utilities/lib/particle_mesh_operations.c</p>
<pre>yt/utilities/lib/origami.c</pre>
<p>+yt/utilities/lib/particle_mesh_operations.c</p>
<pre>yt/utilities/lib/pixelization_routines.c
yt/utilities/lib/png_writer.c</pre>
<p>-yt/utilities/lib/PointsInVolume.c -yt/utilities/lib/QuadTree.c -yt/utilities/lib/RayIntegrators.c +yt/utilities/lib/points_in_volume.c +yt/utilities/lib/quad_tree.c +yt/utilities/lib/ray_integrators.c</p>
<pre>yt/utilities/lib/ragged_arrays.c</pre>
<p>-yt/utilities/lib/VolumeIntegrator.c</p>
<pre>yt/utilities/lib/grid_traversal.c
yt/utilities/lib/marching_cubes.c
yt/utilities/lib/png_writer.h</pre>
<p>diff -r 7574d2271d1f4e16bf4fda604f1cf41680377051 -r 52b7292e3caf231d622322be093b39bc35029222 CONTRIBUTING.rst --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -795,8 +795,8 @@</p>
<pre>  rather than explicitly. Ex: ``super(SpecialGridSubclass, self).__init__()``
  rather than ``SpecialGrid.__init__()``.
* Docstrings should describe input, output, behavior, and any state changes</pre>
<ul><li><p>that occur on an object.  See the file ``doc/docstring_example.txt`` for a</p></li>
<li><p>fiducial example of a docstring.</p></li></ul>
<p>+   that occur on an object.  See :ref:`docstrings` below for a fiducial example +   of a docstring.</p>
<pre>* Use only one top-level import per line. Unless there is a good reason not to,
  imports should happen at the top of the file, after the copyright blurb.
* Never compare with ``True`` or ``False`` using ``==`` or ``!=``, always use</pre>
<p>@@ -843,7 +843,7 @@</p>
<pre>   be avoided, they must be explained, even if they are only to be passed on to
   a nested function.
</pre>
<p>-.. _docstrings +.. _docstrings:</p>
<pre>Docstrings
----------</pre>
<p>diff -r 7574d2271d1f4e16bf4fda604f1cf41680377051 -r 52b7292e3caf231d622322be093b39bc35029222 CREDITS --- a/CREDITS +++ b/CREDITS @@ -4,20 +4,30 @@</p>
<pre>Tom Abel (tabel@stanford.edu)
Gabriel Altay (gabriel.altay@gmail.com)
Kenza Arraki (karraki@gmail.com)</pre>
<p>+                Kirk Barrow (kssbarrow@gatech.edu) +                Ricarda Beckmann (Ricarda.Beckmann@astro.ox.ac.uk)</p>
<pre>Elliott Biondo (biondo@wisc.edu)
Alex Bogert (fbogert@ucsc.edu)</pre>
<p>+                André-Patrick Bubel (code@andre-bubel.de)</p>
<pre>Pengfei Chen (madcpf@gmail.com)
David Collins (dcollins4096@gmail.com)
Brian Crosby (crosby.bd@gmail.com)
Andrew Cunningham (ajcunn@gmail.com)
Miguel de Val-Borro (miguel.deval@gmail.com)</pre>
<p>+                Bili Dong (qobilidop@gmail.com) +                Nicholas Earl (nchlsearl@gmail.com)</p>
<pre>Hilary Egan (hilaryye@gmail.com)</pre>
<p>+                Daniel Fenn (df11c@my.fsu.edu)</p>
<pre>John Forces (jforbes@ucolick.org)</pre>
<p>+                Adam Ginsburg (keflavich@gmail.com)</p>
<pre>Sam Geen (samgeen@gmail.com)
Nathan Goldbaum (goldbaum@ucolick.org)</pre>
<p>+                William Gray (graywilliamj@gmail.com)</p>
<pre>Markus Haider (markus.haider@uibk.ac.at)
Eric Hallman (hallman13@gmail.com)
Cameron Hummels (chummels@gmail.com)</pre>
<p>+                Anni Järvenpää (anni.jarvenpaa@gmail.com) +                Allyson Julian (astrohckr@gmail.com)</p>
<pre>Christian Karch (chiffre@posteo.de)
Ben W. Keller (kellerbw@mcmaster.ca)
Ji-hoon Kim (me@jihoonkim.org)</pre>
<p>@@ -25,11 +35,15 @@</p>
<pre>Kacper Kowalik (xarthisius.kk@gmail.com)
Mark Krumholz (mkrumhol@ucsc.edu)
Michael Kuhlen (mqk@astro.berkeley.edu)</pre>
<p>+                Meagan Lang (langmm.astro@gmail.com) +                Doris Lee (dorislee@berkeley.edu)</p>
<pre>Eve Lee (elee@cita.utoronto.ca)
Sam Leitner (sam.leitner@gmail.com)</pre>
<p>+                Stuart Levy (salevy@illinois.edu)</p>
<pre>Yuan Li (yuan@astro.columbia.edu)
Chris Malone (chris.m.malone@gmail.com)
Josh Maloney (joshua.moloney@colorado.edu)</pre>
<p>+                Jonah Miller (jonah.maxwell.miller@gmail.com)</p>
<pre>Chris Moody (cemoody@ucsc.edu)
Stuart Mumford (stuart@mumford.me.uk)
Andrew Myers (atmyers@astro.berkeley.edu)</pre>
<p>@@ -44,6 +58,7 @@</p>
<pre>Mark Richardson (Mark.L.Richardson@asu.edu)
Thomas Robitaille (thomas.robitaille@gmail.com)
Anna Rosen (rosen@ucolick.org)</pre>
<p>+                Chuck Rozhon (rozhon2@illinois.edu)</p>
<pre>Douglas Rudd (drudd@uchicago.edu)
Anthony Scopatz (scopatz@gmail.com)
Noel Scudder (noel.scudder@stonybrook.edu)</pre>
<p>@@ -59,6 +74,7 @@</p>
<pre>Ji Suoqing (jisuoqing@gmail.com)
Elizabeth Tasker (tasker@astro1.sci.hokudai.ac.jp)
Benjamin Thompson (bthompson2090@gmail.com)</pre>
<p>+                Robert Thompson (rthompsonj@gmail.com)</p>
<pre>Stephanie Tonnesen (stonnes@gmail.com)
Matthew Turk (matthewturk@gmail.com)
Rich Wagner (rwagner@physics.ucsd.edu)</pre>
<p>diff -r 7574d2271d1f4e16bf4fda604f1cf41680377051 -r 52b7292e3caf231d622322be093b39bc35029222 MANIFEST.in --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,4 @@ -include README* CREDITS COPYING.txt CITATION requirements.txt optional-requirements.txt +include README* CREDITS COPYING.txt CITATION requirements.txt optional-requirements.txt setupext.py</p>
<pre>include yt/visualization/mapserver/html/map_index.html
include yt/visualization/mapserver/html/leaflet/*.css
include yt/visualization/mapserver/html/leaflet/*.js</pre>
<p>diff -r 7574d2271d1f4e16bf4fda604f1cf41680377051 -r 52b7292e3caf231d622322be093b39bc35029222 clean.sh --- a/clean.sh +++ b/clean.sh @@ -1,4 +1,1 @@ -find . -name “*.so” -exec rm -v {} \; -find . -name “*.pyc” -exec rm -v {} \; -find . -name “__config__.py” -exec rm -v {} \; -rm -rvf build dist +hg --config extensions.purge= purge --all yt</p>
<p>diff -r 7574d2271d1f4e16bf4fda604f1cf41680377051 -r 52b7292e3caf231d622322be093b39bc35029222 doc/extensions/notebook_sphinxext.py --- a/doc/extensions/notebook_sphinxext.py +++ /dev/null @@ -1,241 +0,0 @@ -import errno -import os -import shutil -import string -import re -import tempfile -import uuid -from sphinx.util.compat import Directive -from docutils import nodes -from docutils.parsers.rst import directives -from IPython.config import Config -from IPython.nbconvert import html, python -from IPython.nbformat import current as nbformat -from runipy.notebook_runner import NotebookRunner, NotebookError – -class NotebookDirective(Directive):</p>
<ul><li><p>"""Insert an evaluated notebook into a document</p></li></ul>
<p>–</p>
<ul><li><p>This uses runipy and nbconvert to transform a path to an unevaluated notebook</p></li>
<li><p>into html suitable for embedding in a Sphinx document.</p></li>
<li><p>"""</p></li>
<li><p>required_arguments = 1</p></li>
<li><p>optional_arguments = 1</p></li>
<li><p>option_spec = {'skip_exceptions': directives.flag}</p></li>
<li><p>final_argument_whitespace = True</p></li></ul>
<p>–</p>
<ul><li><p>def run(self): # check if there are spaces in the notebook name</p></li>
<li><p>nb_path = self.arguments[0]</p></li>
<li><p>if ' ' in nb_path: raise ValueError(</p></li>
<li><p>"Due to issues with docutils stripping spaces from links, white "</p></li>
<li><p>"space is not allowed in notebook filenames '{0}'".format(nb_path))</p></li>
<li><p># check if raw html is supported</p></li>
<li><p>if not self.state.document.settings.raw_enabled:</p></li>
<li><p>raise self.warning('"%s" directive disabled.' % self.name)</p></li></ul>
<p>–</p>
<ul><li><p>cwd = os.getcwd()</p></li>
<li><p>tmpdir = tempfile.mkdtemp()</p></li>
<li><p>os.chdir(tmpdir)</p></li></ul>
<p>–</p>
<ul><li><p># get path to notebook</p></li>
<li><p>nb_filename = self.arguments[0]</p></li>
<li><p>nb_basename = os.path.basename(nb_filename)</p></li>
<li><p>rst_file = self.state_machine.document.attributes['source']</p></li>
<li><p>rst_dir = os.path.abspath(os.path.dirname(rst_file))</p></li>
<li><p>nb_abs_path = os.path.abspath(os.path.join(rst_dir, nb_filename))</p></li></ul>
<p>–</p>
<ul><li><p># Move files around.</p></li>
<li><p>rel_dir = os.path.relpath(rst_dir, setup.confdir)</p></li>
<li><p>dest_dir = os.path.join(setup.app.builder.outdir, rel_dir)</p></li>
<li><p>dest_path = os.path.join(dest_dir, nb_basename)</p></li></ul>
<p>–</p>
<ul><li><p>image_dir, image_rel_dir = make_image_dir(setup, rst_dir)</p></li></ul>
<p>–</p>
<ul><li><p># Ensure desination build directory exists</p></li>
<li><p>thread_safe_mkdir(os.path.dirname(dest_path))</p></li></ul>
<p>–</p>
<ul><li><p># Copy unevaluated notebook</p></li>
<li><p>shutil.copyfile(nb_abs_path, dest_path)</p></li></ul>
<p>–</p>
<ul><li><p># Construct paths to versions getting copied over</p></li>
<li><p>dest_path_eval = string.replace(dest_path, ‘.ipynb’, ‘_evaluated.ipynb’)</p></li>
<li><p>dest_path_script = string.replace(dest_path, ‘.ipynb’, ‘.py’)</p></li>
<li><p>rel_path_eval = string.replace(nb_basename, ‘.ipynb’, ‘_evaluated.ipynb’)</p></li>
<li><p>rel_path_script = string.replace(nb_basename, ‘.ipynb’, ‘.py’)</p></li></ul>
<p>–</p>
<ul><li><p># Create python script vesion</p></li>
<li><p>script_text = nb_to_python(nb_abs_path)</p></li>
<li><p>f = open(dest_path_script, ‘w’)</p></li>
<li><p>f.write(script_text.encode('utf8'))</p></li>
<li><p>f.close()</p></li></ul>
<p>–</p>
<ul><li><p>skip_exceptions = ‘skip_exceptions’ in self.options</p></li></ul>
<p>–</p>
<ul><li><p>ret = evaluate_notebook(</p></li>
<li><p>nb_abs_path, dest_path_eval, skip_exceptions=skip_exceptions)</p></li></ul>
<p>–</p>
<ul><li><p>try:</p></li>
<li><p>evaluated_text, resources = ret</p></li>
<li><p>evaluated_text = write_notebook_output(</p></li>
<li><p>resources, image_dir, image_rel_dir, evaluated_text)</p></li>
<li><p>except ValueError:</p></li>
<li><p># This happens when a notebook raises an unhandled exception</p></li>
<li><p>evaluated_text = ret</p></li></ul>
<p>–</p>
<ul><li><p># Create link to notebook and script files</p></li>
<li><p>link_rst = “(” + \</p></li>
<li><p>formatted_link(nb_basename) + "; " + \</p></li>
<li><p>formatted_link(rel_path_eval) + "; " + \</p></li>
<li><p>formatted_link(rel_path_script) + \</p></li>
<li><p>“)”</p></li></ul>
<p>–</p>
<ul><li><p>self.state_machine.insert_input([link_rst], rst_file)</p></li></ul>
<p>–</p>
<ul><li><p># create notebook node</p></li>
<li><p>attributes = {'format': ‘html’, ‘source’: ‘nb_path’}</p></li>
<li><p>nb_node = notebook_node('', evaluated_text, **attributes)</p></li>
<li><p>(nb_node.source, nb_node.line) = \</p></li>
<li><p>self.state_machine.get_source_and_line(self.lineno)</p></li></ul>
<p>–</p>
<ul><li><p># add dependency</p></li>
<li><p>self.state.document.settings.record_dependencies.add(nb_abs_path)</p></li></ul>
<p>–</p>
<ul><li><p># clean up</p></li>
<li><p>os.chdir(cwd)</p></li>
<li><p>shutil.rmtree(tmpdir, True)</p></li></ul>
<p>–</p>
<ul><li><p>return [nb_node]</p></li></ul>
<p>– – -class notebook_node(nodes.raw):</p>
<ul><li><p>pass</p></li></ul>
<p>– -def nb_to_python(nb_path):</p>
<ul><li><p>"""convert notebook to python script"""</p></li>
<li><p>exporter = python.PythonExporter()</p></li>
<li><p>output, resources = exporter.from_filename(nb_path)</p></li>
<li><p>return output</p></li></ul>
<p>– -def nb_to_html(nb_path):</p>
<ul><li><p>"""convert notebook to html"""</p></li>
<li><p>c = Config({'ExtractOutputPreprocessor':{'enabled':True}})</p></li></ul>
<p>–</p>
<ul><li><p>exporter = html.HTMLExporter(template_file='full', config=c)</p></li>
<li><p>notebook = nbformat.read(open(nb_path), ‘json’)</p></li>
<li><p>output, resources = exporter.from_notebook_node(notebook)</p></li>
<li><p>header = output.split('<head>', 1)[1].split('</head>',1)[0]</p></li>
<li><p>body = output.split('<body>', 1)[1].split('</body>',1)[0]</p></li></ul>
<p>–</p>
<ul><li><p># <a href="http://imgur.com/eR9bMRH">http://imgur.com/eR9bMRH</a></p></li>
<li><p>header = header.replace('<style', ‘<style scoped="scoped"’)</p></li>
<li><p>header = header.replace('body {\n  overflow: visible;\n  padding: 8px;\n}\n',</p></li>
<li><p>'')</p></li>
<li><p>header = header.replace("code,pre{", “code{”)</p></li></ul>
<p>–</p>
<ul><li><p># Filter out styles that conflict with the sphinx theme.</p></li>
<li><p>filter_strings = [</p></li>
<li><p>‘navbar’,</p></li>
<li><p>‘body{’,</p></li>
<li><p>‘alert{’,</p></li>
<li><p>‘uneditable-input{’,</p></li>
<li><p>‘collapse{’,</p></li>
<li><p>]</p></li></ul>
<p>–</p>
<ul><li><p>filter_strings.extend(['h%s{' % (i+1) for i in range(6)])</p></li></ul>
<p>–</p>
<ul><li><p>line_begin = [</p></li>
<li><p>‘pre{’,</p></li>
<li><p>‘p{margin’</p></li>
<li><p>]</p></li></ul>
<p>–</p>
<ul><li><p>filterfunc = lambda x: not any([s in x for s in filter_strings])</p></li>
<li><p>header_lines = filter(filterfunc, header.split('\n'))</p></li></ul>
<p>–</p>
<ul><li><p>filterfunc = lambda x: not any([x.startswith(s) for s in line_begin])</p></li>
<li><p>header_lines = filter(filterfunc, header_lines)</p></li></ul>
<p>–</p>
<ul><li><p>header = '\n'.join(header_lines)</p></li></ul>
<p>–</p>
<ul><li><p># concatenate raw html lines</p></li>
<li><p>lines = ['<div class="ipynotebook">']</p></li>
<li><p>lines.append(header)</p></li>
<li><p>lines.append(body)</p></li>
<li><p>lines.append('</div>')</p></li>
<li><p>return '\n'.join(lines), resources</p></li></ul>
<p>– -def evaluate_notebook(nb_path, dest_path=None, skip_exceptions=False):</p>
<ul><li><p># Create evaluated version and save it to the dest path.</p></li>
<li><p>notebook = nbformat.read(open(nb_path), ‘json’)</p></li>
<li><p>nb_runner = NotebookRunner(notebook, pylab=False)</p></li>
<li><p>try:</p></li>
<li><p>nb_runner.run_notebook(skip_exceptions=skip_exceptions)</p></li>
<li><p>except NotebookError as e:</p></li>
<li><p>print('')</p></li>
<li><p>print(e)</p></li>
<li><p># Return the traceback, filtering out ANSI color codes.</p></li>
<li><p># <a href="http://stackoverflow.com/questions/13506033/filtering-out-ansi-escape-sequences">http://stackoverflow.com/questions/13506033/filtering-out-ansi-escape-sequences</a></p></li>
<li><p>return "Notebook conversion failed with the " \</p></li>
<li><p>“following traceback: \n%s” % \</p></li>
<li><p>re.sub(r'\\033[\[\]]([0-9]{1,2}([;@][0-9]{0,2})*)*[mKP]?', '',</p></li>
<li><p>str(e))</p></li></ul>
<p>–</p>
<ul><li><p>if dest_path is None:</p></li>
<li><p>dest_path = ‘temp_evaluated.ipynb’</p></li>
<li><p>nbformat.write(nb_runner.nb, open(dest_path, ‘w'), 'json’)</p></li>
<li><p>ret = nb_to_html(dest_path)</p></li>
<li><p>if dest_path is ‘temp_evaluated.ipynb’:</p></li>
<li><p>os.remove(dest_path)</p></li>
<li><p>return ret</p></li></ul>
<p>– -def formatted_link(path):</p>
<ul><li><p>return “`%s <%s>`__” % (os.path.basename(path), path)</p></li></ul>
<p>– -def visit_notebook_node(self, node):</p>
<ul><li><p>self.visit_raw(node)</p></li></ul>
<p>– -def depart_notebook_node(self, node):</p>
<ul><li><p>self.depart_raw(node)</p></li></ul>
<p>– -def setup(app):</p>
<ul><li><p>setup.app = app</p></li>
<li><p>setup.config = app.config</p></li>
<li><p>setup.confdir = app.confdir</p></li></ul>
<p>–</p>
<ul><li><p>app.add_node(notebook_node,</p></li>
<li><p>html=(visit_notebook_node, depart_notebook_node))</p></li></ul>
<p>–</p>
<ul><li><p>app.add_directive('notebook', NotebookDirective)</p></li></ul>
<p>–</p>
<ul><li><p>retdict = dict(</p></li>
<li><p>version='0.1',</p></li>
<li><p>parallel_read_safe=True,</p></li>
<li><p>parallel_write_safe=True</p></li>
<li><p>)</p></li></ul>
<p>–</p>
<ul><li><p>return retdict</p></li></ul>
<p>– -def make_image_dir(setup, rst_dir):</p>
<ul><li><p>image_dir = setup.app.builder.outdir + os.path.sep + ‘_images’</p></li>
<li><p>rel_dir = os.path.relpath(setup.confdir, rst_dir)</p></li>
<li><p>image_rel_dir = rel_dir + os.path.sep + ‘_images’</p></li>
<li><p>thread_safe_mkdir(image_dir)</p></li>
<li><p>return image_dir, image_rel_dir</p></li></ul>
<p>– -def write_notebook_output(resources, image_dir, image_rel_dir, evaluated_text):</p>
<ul><li><p>my_uuid = uuid.uuid4().hex</p></li></ul>
<p>–</p>
<ul><li><p>for output in resources['outputs']:</p></li>
<li><p>new_name = image_dir + os.path.sep + my_uuid + output</p></li>
<li><p>new_relative_name = image_rel_dir + os.path.sep + my_uuid + output</p></li>
<li><p>evaluated_text = evaluated_text.replace(output, new_relative_name)</p></li>
<li><p>with open(new_name, ‘wb’) as f:</p></li>
<li><p>f.write(resources['outputs'][output])</p></li>
<li><p>return evaluated_text</p></li></ul>
<p>– -def thread_safe_mkdir(dirname):</p>
<ul><li><p>try:</p></li>
<li><p>os.makedirs(dirname)</p></li>
<li><p>except OSError as e:</p></li>
<li><p>if e.errno != errno.EEXIST:</p></li>
<li><p>raise</p></li>
<li><p>pass</p></li></ul>
<p>diff -r 7574d2271d1f4e16bf4fda604f1cf41680377051 -r 52b7292e3caf231d622322be093b39bc35029222 doc/extensions/notebookcell_sphinxext.py --- a/doc/extensions/notebookcell_sphinxext.py +++ /dev/null @@ -1,87 +0,0 @@ -import os -import shutil -import io -import tempfile -from sphinx.util.compat import Directive -from docutils.parsers.rst import directives -from IPython.nbformat import current -from notebook_sphinxext import \</p>
<ul><li><p>notebook_node, visit_notebook_node, depart_notebook_node, \</p></li>
<li><p>evaluate_notebook, make_image_dir, write_notebook_output</p></li></ul>
<p>– – -class NotebookCellDirective(Directive):</p>
<ul><li><p>"""Insert an evaluated notebook cell into a document</p></li></ul>
<p>–</p>
<ul><li><p>This uses runipy and nbconvert to transform an inline python</p></li>
<li><p>script into html suitable for embedding in a Sphinx document.</p></li>
<li><p>"""</p></li>
<li><p>required_arguments = 0</p></li>
<li><p>optional_arguments = 1</p></li>
<li><p>has_content = True</p></li>
<li><p>option_spec = {'skip_exceptions': directives.flag}</p></li></ul>
<p>–</p>
<ul><li><p>def run(self):</p></li>
<li><p># check if raw html is supported</p></li>
<li><p>if not self.state.document.settings.raw_enabled:</p></li>
<li><p>raise self.warning('"%s" directive disabled.' % self.name)</p></li></ul>
<p>–</p>
<ul><li><p>cwd = os.getcwd()</p></li>
<li><p>tmpdir = tempfile.mkdtemp()</p></li>
<li><p>os.chdir(tmpdir)</p></li></ul>
<p>–</p>
<ul><li><p>rst_file = self.state_machine.document.attributes['source']</p></li>
<li><p>rst_dir = os.path.abspath(os.path.dirname(rst_file))</p></li></ul>
<p>–</p>
<ul><li><p>image_dir, image_rel_dir = make_image_dir(setup, rst_dir)</p></li></ul>
<p>–</p>
<ul><li><p># Construct notebook from cell content</p></li>
<li><p>content = "\n".join(self.content)</p></li>
<li><p>with open("temp.py", “w”) as f:</p></li>
<li><p>f.write(content)</p></li></ul>
<p>–</p>
<ul><li><p>convert_to_ipynb('temp.py', ‘temp.ipynb’)</p></li></ul>
<p>–</p>
<ul><li><p>skip_exceptions = ‘skip_exceptions’ in self.options</p></li></ul>
<p>–</p>
<ul><li><p>evaluated_text, resources = evaluate_notebook(</p></li>
<li><p>‘temp.ipynb’, skip_exceptions=skip_exceptions)</p></li></ul>
<p>–</p>
<ul><li><p>evaluated_text = write_notebook_output(</p></li>
<li><p>resources, image_dir, image_rel_dir, evaluated_text)</p></li></ul>
<p>–</p>
<ul><li><p># create notebook node</p></li>
<li><p>attributes = {'format': ‘html’, ‘source’: ‘nb_path’}</p></li>
<li><p>nb_node = notebook_node('', evaluated_text, **attributes)</p></li>
<li><p>(nb_node.source, nb_node.line) = \</p></li>
<li><p>self.state_machine.get_source_and_line(self.lineno)</p></li></ul>
<p>–</p>
<ul><li><p># clean up</p></li>
<li><p>os.chdir(cwd)</p></li>
<li><p>shutil.rmtree(tmpdir, True)</p></li></ul>
<p>–</p>
<ul><li><p>return [nb_node]</p></li></ul>
<p>– -def setup(app):</p>
<ul><li><p>setup.app = app</p></li>
<li><p>setup.config = app.config</p></li>
<li><p>setup.confdir = app.confdir</p></li></ul>
<p>–</p>
<ul><li><p>app.add_node(notebook_node,</p></li>
<li><p>html=(visit_notebook_node, depart_notebook_node))</p></li></ul>
<p>–</p>
<ul><li><p>app.add_directive('notebook-cell', NotebookCellDirective)</p></li></ul>
<p>–</p>
<ul><li><p>retdict = dict(</p></li>
<li><p>version='0.1',</p></li>
<li><p>parallel_read_safe=True,</p></li>
<li><p>parallel_write_safe=True</p></li>
<li><p>)</p></li></ul>
<p>–</p>
<ul><li><p>return retdict</p></li></ul>
<p>– -def convert_to_ipynb(py_file, ipynb_file):</p>
<ul><li><p>with io.open(py_file, ‘r’, encoding='utf-8') as f:</p></li>
<li><p>notebook = current.reads(f.read(), format='py')</p></li>
<li><p>with io.open(ipynb_file, ‘w’, encoding='utf-8') as f:</p></li>
<li><p>current.write(notebook, f, format='ipynb')</p></li></ul>
<p>diff -r 7574d2271d1f4e16bf4fda604f1cf41680377051 -r 52b7292e3caf231d622322be093b39bc35029222 doc/extensions/numpydocmod/__init__.py --- a/doc/extensions/numpydocmod/__init__.py +++ /dev/null @@ -1,1 +0,0 @@ -from numpydoc import setup</p>
<p>diff -r 7574d2271d1f4e16bf4fda604f1cf41680377051 -r 52b7292e3caf231d622322be093b39bc35029222 doc/extensions/numpydocmod/comment_eater.py --- a/doc/extensions/numpydocmod/comment_eater.py +++ /dev/null @@ -1,158 +0,0 @@ -from cStringIO import StringIO -import compiler -import inspect -import textwrap -import tokenize – -from compiler_unparse import unparse – – -class Comment(object):</p>
<ul><li><p>""" A comment block.</p></li>
<li><p>"""</p></li>
<li><p>is_comment = True</p></li>
<li><p>def __init__(self, start_lineno, end_lineno, text):</p></li>
<li><p># int : The first line number in the block. 1-indexed.</p></li>
<li><p>self.start_lineno = start_lineno</p></li>
<li><p># int : The last line number. Inclusive!</p></li>
<li><p>self.end_lineno = end_lineno</p></li>
<li><p># str : The text block including ‘#’ character but not any leading spaces.</p></li>
<li><p>self.text = text</p></li></ul>
<p>–</p>
<ul><li><p>def add(self, string, start, end, line):</p></li>
<li><p>""" Add a new comment line.</p></li>
<li><p>"""</p></li>
<li><p>self.start_lineno = min(self.start_lineno, start[0])</p></li>
<li><p>self.end_lineno = max(self.end_lineno, end[0])</p></li>
<li><p>self.text += string</p></li></ul>
<p>–</p>
<ul><li><p>def __repr__(self):</p></li>
<li><p>return ‘%s(%r, %r, %r)’ % (self.__class__.__name__, self.start_lineno,</p></li>
<li><p>self.end_lineno, self.text)</p></li></ul>
<p>– – -class NonComment(object):</p>
<ul><li><p>""" A non-comment block of code.</p></li>
<li><p>"""</p></li>
<li><p>is_comment = False</p></li>
<li><p>def __init__(self, start_lineno, end_lineno):</p></li>
<li><p>self.start_lineno = start_lineno</p></li>
<li><p>self.end_lineno = end_lineno</p></li></ul>
<p>–</p>
<ul><li><p>def add(self, string, start, end, line):</p></li>
<li><p>""" Add lines to the block.</p></li>
<li><p>"""</p></li>
<li><p>if string.strip():</p></li>
<li><p># Only add if not entirely whitespace.</p></li>
<li><p>self.start_lineno = min(self.start_lineno, start[0])</p></li>
<li><p>self.end_lineno = max(self.end_lineno, end[0])</p></li></ul>
<p>–</p>
<ul><li><p>def __repr__(self):</p></li>
<li><p>return ‘%s(%r, %r)’ % (self.__class__.__name__, self.start_lineno,</p></li>
<li><p>self.end_lineno)</p></li></ul>
<p>– – -class CommentBlocker(object):</p>
<ul><li><p>""" Pull out contiguous comment blocks.</p></li>
<li><p>"""</p></li>
<li><p>def __init__(self):</p></li>
<li><p># Start with a dummy.</p></li>
<li><p>self.current_block = NonComment(0, 0)</p></li></ul>
<p>–</p>
<ul><li><p># All of the blocks seen so far.</p></li>
<li><p>self.blocks = []</p></li></ul>
<p>–</p>
<ul><li><p># The index mapping lines of code to their associated comment blocks.</p></li>
<li><p>self.index = {}</p></li></ul>
<p>–</p>
<ul><li><p>def process_file(self, file):</p></li>
<li><p>""" Process a file object.</p></li>
<li><p>"""</p></li>
<li><p>for token in tokenize.generate_tokens(file.next):</p></li>
<li><p>self.process_token(*token)</p></li>
<li><p>self.make_index()</p></li></ul>
<p>–</p>
<ul><li><p>def process_token(self, kind, string, start, end, line):</p></li>
<li><p>""" Process a single token.</p></li>
<li><p>"""</p></li>
<li><p>if self.current_block.is_comment:</p></li>
<li><p>if kind == tokenize.COMMENT:</p></li>
<li><p>self.current_block.add(string, start, end, line)</p></li>
<li><p>else:</p></li>
<li><p>self.new_noncomment(start[0], end[0])</p></li>
<li><p>else:</p></li>
<li><p>if kind == tokenize.COMMENT:</p></li>
<li><p>self.new_comment(string, start, end, line)</p></li>
<li><p>else:</p></li>
<li><p>self.current_block.add(string, start, end, line)</p></li></ul>
<p>–</p>
<ul><li><p>def new_noncomment(self, start_lineno, end_lineno):</p></li>
<li><p>""" We are transitioning from a noncomment to a comment.</p></li>
<li><p>"""</p></li>
<li><p>block = NonComment(start_lineno, end_lineno)</p></li>
<li><p>self.blocks.append(block)</p></li>
<li><p>self.current_block = block</p></li></ul>
<p>–</p>
<ul><li><p>def new_comment(self, string, start, end, line):</p></li>
<li><p>""" Possibly add a new comment.</p></li></ul>
<p>–</p>
<ul><li><p>Only adds a new comment if this comment is the only thing on the line.</p></li>
<li><p>Otherwise, it extends the noncomment block.</p></li>
<li><p>"""</p></li>
<li><p>prefix = line[:start[1]]</p></li>
<li><p>if prefix.strip():</p></li>
<li><p># Oops! Trailing comment, not a comment block.</p></li>
<li><p>self.current_block.add(string, start, end, line)</p></li>
<li><p>else:</p></li>
<li><p># A comment block.</p></li>
<li><p>block = Comment(start[0], end[0], string)</p></li>
<li><p>self.blocks.append(block)</p></li>
<li><p>self.current_block = block</p></li></ul>
<p>–</p>
<ul><li><p>def make_index(self):</p></li>
<li><p>""" Make the index mapping lines of actual code to their associated</p></li>
<li><p>prefix comments.</p></li>
<li><p>"""</p></li>
<li><p>for prev, block in zip(self.blocks[:-1], self.blocks[1:]):</p></li>
<li><p>if not block.is_comment:</p></li>
<li><p>self.index[block.start_lineno] = prev</p></li></ul>
<p>–</p>
<ul><li><p>def search_for_comment(self, lineno, default=None):</p></li>
<li><p>""" Find the comment block just before the given line number.</p></li></ul>
<p>–</p>
<ul><li><p>Returns None (or the specified default) if there is no such block.</p></li>
<li><p>"""</p></li>
<li><p>if not self.index:</p></li>
<li><p>self.make_index()</p></li>
<li><p>block = self.index.get(lineno, None)</p></li>
<li><p>text = getattr(block, ‘text’, default)</p></li>
<li><p>return text</p></li></ul>
<p>– – -def strip_comment_marker(text):</p>
<ul><li><p>""" Strip # markers at the front of a block of comment text.</p></li>
<li><p>"""</p></li>
<li><p>lines = []</p></li>
<li><p>for line in text.splitlines():</p></li>
<li><p>lines.append(line.lstrip('#'))</p></li>
<li><p>text = textwrap.dedent('\n'.join(lines))</p></li>
<li><p>return text</p></li></ul>
<p>– – -def get_class_traits(klass):</p>
<ul><li><p>""" Yield all of the documentation for trait definitions on a class object.</p></li>
<li><p>"""</p></li>
<li><p># FIXME: gracefully handle errors here or in the caller?</p></li>
<li><p>source = inspect.getsource(klass)</p></li>
<li><p>cb = CommentBlocker()</p></li>
<li><p>cb.process_file(StringIO(source))</p></li>
<li><p>mod_ast = compiler.parse(source)</p></li>
<li><p>class_ast = mod_ast.node.nodes[0]</p></li>
<li><p>for node in class_ast.code.nodes:</p></li>
<li><p># FIXME: handle other kinds of assignments?</p></li>
<li><p>if isinstance(node, compiler.ast.Assign):</p></li>
<li><p>name = node.nodes[0].name</p></li>
<li><p>rhs = unparse(node.expr).strip()</p></li>
<li><p>doc = strip_comment_marker(cb.search_for_comment(node.lineno, default=''))</p></li>
<li><p>yield name, rhs, doc</p></li></ul>
<p>–</p>
<p>diff -r 7574d2271d1f4e16bf4fda604f1cf41680377051 -r 52b7292e3caf231d622322be093b39bc35029222 doc/extensions/numpydocmod/compiler_unparse.py --- a/doc/extensions/numpydocmod/compiler_unparse.py +++ /dev/null @@ -1,860 +0,0 @@ -""" Turn compiler.ast structures back into executable python code. –</p>
<ul><li><p>The unparse method takes a compiler.ast tree and transforms it back into</p></li>
<li><p>valid python code.  It is incomplete and currently only works for</p></li>
<li><p>import statements, function calls, function definitions, assignments, and</p></li>
<li><p>basic expressions.</p></li></ul>
<p>–</p>
<ul><li><p>Inspired by python-2.5-svn/Demo/parser/unparse.py</p></li></ul>
<p>–</p>
<ul><li><p>fixme: We may want to move to using _ast trees because the compiler for</p></li>
<li><p>them is about 6 times faster than compiler.compile.</p></li></ul>
<p>-""" – -import sys -import cStringIO -from compiler.ast import Const, Name, Tuple, Div, Mul, Sub, Add – -def unparse(ast, single_line_functions=False):</p>
<ul><li><p>s = cStringIO.StringIO()</p></li>
<li><p>UnparseCompilerAst(ast, s, single_line_functions)</p></li>
<li><p>return s.getvalue().lstrip()</p></li></ul>
<p>– -op_precedence = { 'compiler.ast.Power':3, 'compiler.ast.Mul':2, 'compiler.ast.Div':2,</p>
<ul><li><p>'compiler.ast.Add':1, 'compiler.ast.Sub':1 }</p></li></ul>
<p>– -class UnparseCompilerAst:</p>
<ul><li><p>""" Methods in this class recursively traverse an AST and</p></li>
<li><p>output source code for the abstract syntax; original formatting</p></li>
<li><p>is disregarged.</p></li>
<li><p>"""</p></li></ul>
<p>–</p>
<ul><li><p>#########################################################################</p></li>
<li><p># object interface.</p></li>
<li><p>#########################################################################</p></li></ul>
<p>–</p>
<ul><li><p>def __init__(self, tree, file = sys.stdout, single_line_functions=False):</p></li>
<li><p>""" Unparser(tree, file=sys.stdout) -> None.</p></li></ul>
<p>–</p>
<ul><li><p>Print the source for tree to file.</p></li>
<li><p>"""</p></li>
<li><p>self.f = file</p></li>
<li><p>self._single_func = single_line_functions</p></li>
<li><p>self._do_indent = True</p></li>
<li><p>self._indent = 0</p></li>
<li><p>self._dispatch(tree)</p></li>
<li><p>self._write("\n")</p></li>
<li><p>self.f.flush()</p></li></ul>
<p>–</p>
<ul><li><p>#########################################################################</p></li>
<li><p># Unparser private interface.</p></li>
<li><p>#########################################################################</p></li></ul>
<p>–</p>
<ul><li><p>### format, output, and dispatch methods ################################</p></li></ul>
<p>–</p>
<ul><li><p>def _fill(self, text = ""):</p></li>
<li><p>“Indent a piece of text, according to the current indentation level”</p></li>
<li><p>if self._do_indent:</p></li>
<li><p>self._write("\n"+"    "*self._indent + text)</p></li>
<li><p>else:</p></li>
<li><p>self._write(text)</p></li></ul>
<p>–</p>
<ul><li><p>def _write(self, text):</p></li>
<li><p>“Append a piece of text to the current line.”</p></li>
<li><p>self.f.write(text)</p></li></ul>
<p>–</p>
<ul><li><p>def _enter(self):</p></li>
<li><p>“Print ‘:’, and increase the indentation.”</p></li>
<li><p>self._write(": ")</p></li>
<li><p>self._indent += 1</p></li></ul>
<p>–</p>
<ul><li><p>def _leave(self):</p></li>
<li><p>“Decrease the indentation level.”</p></li>
<li><p>self._indent -= 1</p></li></ul>
<p>–</p>
<ul><li><p>def _dispatch(self, tree):</p></li>
<li><p>“_dispatcher function, _dispatching tree type T to method _T.”</p></li>
<li><p>if isinstance(tree, list):</p></li>
<li><p>for t in tree:</p></li>
<li><p>self._dispatch(t)</p></li>
<li><p>return</p></li>
<li><p>meth = getattr(self, "_"+tree.__class__.__name__)</p></li>
<li><p>if tree.__class__.__name__ == ‘NoneType’ and not self._do_indent:</p></li>
<li><p>return</p></li>
<li><p>meth(tree)</p></li></ul>
<p>– –</p>
<ul><li><p>#########################################################################</p></li>
<li><p># compiler.ast unparsing methods.</p></li>
<li><p>#</p></li>
<li><p># There should be one method per concrete grammar type. They are</p></li>
<li><p># organized in alphabetical order.</p></li>
<li><p>#########################################################################</p></li></ul>
<p>–</p>
<ul><li><p>def _Add(self, t):</p></li>
<li><p>self.__binary_op(t, ‘+’)</p></li></ul>
<p>–</p>
<ul><li><p>def _And(self, t):</p></li>
<li><p>self._write(" (")</p></li>
<li><p>for i, node in enumerate(t.nodes):</p></li>
<li><p>self._dispatch(node)</p></li>
<li><p>if i != len(t.nodes)-1:</p></li>
<li><p>self._write(") and (")</p></li>
<li><p>self._write(")")</p></li></ul>
<p>–</p>
<ul><li><p>def _AssAttr(self, t):</p></li>
<li><p>""" Handle assigning an attribute of an object</p></li>
<li><p>"""</p></li>
<li><p>self._dispatch(t.expr)</p></li>
<li><p>self._write('.'+t.attrname)</p></li></ul>
<p>–</p>
<ul><li><p>def _Assign(self, t):</p></li>
<li><p>""" Expression Assignment such as “a = 1”.</p></li></ul>
<p>–</p>
<ul><li><p>This only handles assignment in expressions.  Keyword assignment</p></li>
<li><p>is handled separately.</p></li>
<li><p>"""</p></li>
<li><p>self._fill()</p></li>
<li><p>for target in t.nodes:</p></li>
<li><p>self._dispatch(target)</p></li>
<li><p>self._write(" = ")</p></li>
<li><p>self._dispatch(t.expr)</p></li>
<li><p>if not self._do_indent:</p></li>
<li><p>self._write('; ')</p></li></ul>
<p>–</p>
<ul><li><p>def _AssName(self, t):</p></li>
<li><p>""" Name on left hand side of expression.</p></li></ul>
<p>–</p>
<ul><li><p>Treat just like a name on the right side of an expression.</p></li>
<li><p>"""</p></li>
<li><p>self._Name(t)</p></li></ul>
<p>–</p>
<ul><li><p>def _AssTuple(self, t):</p></li>
<li><p>""" Tuple on left hand side of an expression.</p></li>
<li><p>"""</p></li></ul>
<p>–</p>
<ul><li><p># _write each elements, separated by a comma.</p></li>
<li><p>for element in t.nodes[:-1]:</p></li>
<li><p>self._dispatch(element)</p></li>
<li><p>self._write(", ")</p></li></ul>
<p>–</p>
<ul><li><p># Handle the last one without writing comma</p></li>
<li><p>last_element = t.nodes[-1]</p></li>
<li><p>self._dispatch(last_element)</p></li></ul>
<p>–</p>
<ul><li><p>def _AugAssign(self, t):</p></li>
<li><p>""" +=,-=,*=,/=,**=, etc. operations</p></li>
<li><p>"""</p></li></ul>
<p>–</p>
<ul><li><p>self._fill()</p></li>
<li><p>self._dispatch(t.node)</p></li>
<li><p>self._write(' ‘+t.op+’ ')</p></li>
<li><p>self._dispatch(t.expr)</p></li>
<li><p>if not self._do_indent:</p></li>
<li><p>self._write(';')</p></li></ul>
<p>–</p>
<ul><li><p>def _Bitand(self, t):</p></li>
<li><p>""" Bit and operation.</p></li>
<li><p>"""</p></li></ul>
<p>–</p>
<ul><li><p>for i, node in enumerate(t.nodes):</p></li>
<li><p>self._write("(")</p></li>
<li><p>self._dispatch(node)</p></li>
<li><p>self._write(")")</p></li>
<li><p>if i != len(t.nodes)-1:</p></li>
<li><p>self._write(" & ")</p></li></ul>
<p>–</p>
<ul><li><p>def _Bitor(self, t):</p></li>
<li><p>""" Bit or operation</p></li>
<li><p>"""</p></li></ul>
<p>–</p>
<ul><li><p>for i, node in enumerate(t.nodes):</p></li>
<li><p>self._write("(")</p></li>
<li><p>self._dispatch(node)</p></li>
<li><p>self._write(")")</p></li>
<li><p>if i != len(t.nodes)-1:</p></li>
<li><p>self._write(" | ")</p></li></ul>
<p>–</p>
<ul><li><p>def _CallFunc(self, t):</p></li>
<li><p>""" Function call.</p></li>
<li><p>"""</p></li>
<li><p>self._dispatch(t.node)</p></li>
<li><p>self._write("(")</p></li>
<li><p>comma = False</p></li>
<li><p>for e in t.args:</p></li>
<li><p>if comma: self._write(", ")</p></li>
<li><p>else: comma = True</p></li>
<li><p>self._dispatch(e)</p></li>
<li><p>if t.star_args:</p></li>
<li><p>if comma: self._write(", ")</p></li>
<li><p>else: comma = True</p></li>
<li><p>self._write("*")</p></li>
<li><p>self._dispatch(t.star_args)</p></li>
<li><p>if t.dstar_args:</p></li>
<li><p>if comma: self._write(", ")</p></li>
<li><p>else: comma = True</p></li>
<li><p>self._write("**")</p></li>
<li><p>self._dispatch(t.dstar_args)</p></li>
<li><p>self._write(")")</p></li></ul>
<p>–</p>
<ul><li><p>def _Compare(self, t):</p></li>
<li><p>self._dispatch(t.expr)</p></li>
<li><p>for op, expr in t.ops:</p></li>
<li><p>self._write(" " + op + " ")</p></li>
<li><p>self._dispatch(expr)</p></li></ul>
<p>–</p>
<ul><li><p>def _Const(self, t):</p></li>
<li><p>""" A constant value such as an integer value, 3, or a string, “hello”.</p></li>
<li><p>"""</p></li>
<li><p>self._dispatch(t.value)</p></li></ul>
<p>–</p>
<ul><li><p>def _Decorators(self, t):</p></li>
<li><p>""" Handle function decorators (eg. @has_units)</p></li>
<li><p>"""</p></li>
<li><p>for node in t.nodes:</p></li>
<li><p>self._dispatch(node)</p></li></ul>
<p>–</p>
<ul><li><p>def _Dict(self, t):</p></li>
<li><p>self._write("{")</p></li>
<li><p>for  i, (k, v) in enumerate(t.items):</p></li>
<li><p>self._dispatch(k)</p></li>
<li><p>self._write(": ")</p></li>
<li><p>self._dispatch(v)</p></li>
<li><p>if i < len(t.items)-1:</p></li>
<li><p>self._write(", ")</p></li>
<li><p>self._write("}")</p></li></ul>
<p>–</p>
<ul><li><p>def _Discard(self, t):</p></li>
<li><p>""" Node for when return value is ignored such as in “foo(a)”.</p></li>
<li><p>"""</p></li>
<li><p>self._fill()</p></li>
<li><p>self._dispatch(t.expr)</p></li></ul>
<p>–</p>
<ul><li><p>def _Div(self, t):</p></li>
<li><p>self.__binary_op(t, ‘/’)</p></li></ul>
<p>–</p>
<ul><li><p>def _Ellipsis(self, t):</p></li>
<li><p>self._write("…")</p></li></ul>
<p>–</p>
<ul><li><p>def _From(self, t):</p></li>
<li><p>""" Handle “from xyz import foo, bar as baz”.</p></li>
<li><p>"""</p></li>
<li><p># fixme: Are From and ImportFrom handled differently?</p></li>
<li><p>self._fill("from ")</p></li>
<li><p>self._write(t.modname)</p></li>
<li><p>self._write(" import ")</p></li>
<li><p>for i, (name,asname) in enumerate(t.names):</p></li>
<li><p>if i != 0:</p></li>
<li><p>self._write(", ")</p></li>
<li><p>self._write(name)</p></li>
<li><p>if asname is not None:</p></li>
<li><p>self._write(" as "+asname)</p></li></ul>
<p>–</p>
<ul><li><p>def _Function(self, t):</p></li>
<li><p>""" Handle function definitions</p></li>
<li><p>"""</p></li>
<li><p>if t.decorators is not None:</p></li>
<li><p>self._fill("@")</p></li>
<li><p>self._dispatch(t.decorators)</p></li>
<li><p>self._fill("def “+t.name + "(”)</p></li>
<li><p>defaults = [None] * (len(t.argnames) – len(t.defaults)) + list(t.defaults)</p></li>
<li><p>for i, arg in enumerate(zip(t.argnames, defaults)):</p></li>
<li><p>self._write(arg[0])</p></li>
<li><p>if arg[1] is not None:</p></li>
<li><p>self._write('=')</p></li>
<li><p>self._dispatch(arg[1])</p></li>
<li><p>if i < len(t.argnames)-1:</p></li>
<li><p>self._write(', ')</p></li>
<li><p>self._write(")")</p></li>
<li><p>if self._single_func:</p></li>
<li><p>self._do_indent = False</p></li>
<li><p>self._enter()</p></li>
<li><p>self._dispatch(t.code)</p></li>
<li><p>self._leave()</p></li>
<li><p>self._do_indent = True</p></li></ul>
<p>–</p>
<ul><li><p>def _Getattr(self, t):</p></li>
<li><p>""" Handle getting an attribute of an object</p></li>
<li><p>"""</p></li>
<li><p>if isinstance(t.expr, (Div, Mul, Sub, Add)):</p></li>
<li><p>self._write('(')</p></li>
<li><p>self._dispatch(t.expr)</p></li>
<li><p>self._write(')')</p></li>
<li><p>else:</p></li>
<li><p>self._dispatch(t.expr)</p></li></ul>
<p>–</p>
<ul><li><p>self._write('.'+t.attrname)</p></li></ul>
<p>–</p>
<ul><li><p>def _If(self, t):</p></li>
<li><p>self._fill()</p></li></ul>
<p>–</p>
<ul><li><p>for i, (compare,code) in enumerate(t.tests):</p></li>
<li><p>if i == 0:</p></li>
<li><p>self._write("if ")</p></li>
<li><p>else:</p></li>
<li><p>self._write("elif ")</p></li>
<li><p>self._dispatch(compare)</p></li>
<li><p>self._enter()</p></li>
<li><p>self._fill()</p></li>
<li><p>self._dispatch(code)</p></li>
<li><p>self._leave()</p></li>
<li><p>self._write("\n")</p></li></ul>
<p>–</p>
<ul><li><p>if t.else_ is not None:</p></li>
<li><p>self._write("else")</p></li>
<li><p>self._enter()</p></li>
<li><p>self._fill()</p></li>
<li><p>self._dispatch(t.else_)</p></li>
<li><p>self._leave()</p></li>
<li><p>self._write("\n")</p></li></ul>
<p>–</p>
<ul><li><p>def _IfExp(self, t):</p></li>
<li><p>self._dispatch(t.then)</p></li>
<li><p>self._write(" if ")</p></li>
<li><p>self._dispatch(t.test)</p></li></ul>
<p>–</p>
<ul><li><p>if t.else_ is not None:</p></li>
<li><p>self._write(" else (")</p></li>
<li><p>self._dispatch(t.else_)</p></li>
<li><p>self._write(")")</p></li></ul>
<p>–</p>
<ul><li><p>def _Import(self, t):</p></li>
<li><p>""" Handle “import xyz.foo”.</p></li>
<li><p>"""</p></li>
<li><p>self._fill("import ")</p></li></ul>
<p>–</p>
<ul><li><p>for i, (name,asname) in enumerate(t.names):</p></li>
<li><p>if i != 0:</p></li>
<li><p>self._write(", ")</p></li>
<li><p>self._write(name)</p></li>
<li><p>if asname is not None:</p></li>
<li><p>self._write(" as "+asname)</p></li></ul>
<p>–</p>
<ul><li><p>def _Keyword(self, t):</p></li>
<li><p>""" Keyword value assignment within function calls and definitions.</p></li>
<li><p>"""</p></li>
<li><p>self._write(t.name)</p></li>
<li><p>self._write("=")</p></li>
<li><p>self._dispatch(t.expr)</p></li></ul>
<p>–</p>
<ul><li><p>def _List(self, t):</p></li>
<li><p>self._write("[")</p></li>
<li><p>for  i,node in enumerate(t.nodes):</p></li>
<li><p>self._dispatch(node)</p></li>
<li><p>if i < len(t.nodes)-1:</p></li>
<li><p>self._write(", ")</p></li>
<li><p>self._write("]")</p></li></ul>
<p>–</p>
<ul><li><p>def _Module(self, t):</p></li>
<li><p>if t.doc is not None:</p></li>
<li><p>self._dispatch(t.doc)</p></li>
<li><p>self._dispatch(t.node)</p></li></ul>
<p>–</p>
<ul><li><p>def _Mul(self, t):</p></li>
<li><p>self.__binary_op(t, ‘*’)</p></li></ul>
<p>–</p>
<ul><li><p>def _Name(self, t):</p></li>
<li><p>self._write(t.name)</p></li></ul>
<p>–</p>
<ul><li><p>def _NoneType(self, t):</p></li>
<li><p>self._write("None")</p></li></ul>
<p>–</p>
<ul><li><p>def _Not(self, t):</p></li>
<li><p>self._write('not (')</p></li>
<li><p>self._dispatch(t.expr)</p></li>
<li><p>self._write(')')</p></li></ul>
<p>–</p>
<ul><li><p>def _Or(self, t):</p></li>
<li><p>self._write(" (")</p></li>
<li><p>for i, node in enumerate(t.nodes):</p></li>
<li><p>self._dispatch(node)</p></li>
<li><p>if i != len(t.nodes)-1:</p></li>
<li><p>self._write(") or (")</p></li>
<li><p>self._write(")")</p></li></ul>
<p>–</p>
<ul><li><p>def _Pass(self, t):</p></li>
<li><p>self._write("pass\n")</p></li></ul>
<p>–</p>
<ul><li><p>def _Printnl(self, t):</p></li>
<li><p>self._fill("print ")</p></li>
<li><p>if t.dest:</p></li>
<li><p>self._write(">> ")</p></li>
<li><p>self._dispatch(t.dest)</p></li>
<li><p>self._write(", ")</p></li>
<li><p>comma = False</p></li>
<li><p>for node in t.nodes:</p></li>
<li><p>if comma: self._write(', ')</p></li>
<li><p>else: comma = True</p></li>
<li><p>self._dispatch(node)</p></li></ul>
<p>–</p>
<ul><li><p>def _Power(self, t):</p></li>
<li><p>self.__binary_op(t, ‘**’)</p></li></ul>
<p>–</p>
<ul><li><p>def _Return(self, t):</p></li>
<li><p>self._fill("return ")</p></li>
<li><p>if t.value:</p></li>
<li><p>if isinstance(t.value, Tuple):</p></li>
<li><p>text = ', '.join([ name.name for name in t.value.asList() ])</p></li>
<li><p>self._write(text)</p></li>
<li><p>else:</p></li>
<li><p>self._dispatch(t.value)</p></li>
<li><p>if not self._do_indent:</p></li>
<li><p>self._write('; ')</p></li></ul>
<p>–</p>
<ul><li><p>def _Slice(self, t):</p></li>
<li><p>self._dispatch(t.expr)</p></li>
<li><p>self._write("[")</p></li>
<li><p>if t.lower:</p></li>
<li><p>self._dispatch(t.lower)</p></li>
<li><p>self._write(":")</p></li>
<li><p>if t.upper:</p></li>
<li><p>self._dispatch(t.upper)</p></li>
<li><p>#if t.step:</p></li>
<li><p>#    self._write(":")</p></li>
<li><p>#    self._dispatch(t.step)</p></li>
<li><p>self._write("]")</p></li></ul>
<p>–</p>
<ul><li><p>def _Sliceobj(self, t):</p></li>
<li><p>for i, node in enumerate(t.nodes):</p></li>
<li><p>if i != 0:</p></li>
<li><p>self._write(":")</p></li>
<li><p>if not (isinstance(node, Const) and node.value is None):</p></li>
<li><p>self._dispatch(node)</p></li></ul>
<p>–</p>
<ul><li><p>def _Stmt(self, tree):</p></li>
<li><p>for node in tree.nodes:</p></li>
<li><p>self._dispatch(node)</p></li></ul>
<p>–</p>
<ul><li><p>def _Sub(self, t):</p></li>
<li><p>self.__binary_op(t, ‘-’)</p></li></ul>
<p>–</p>
<ul><li><p>def _Subscript(self, t):</p></li>
<li><p>self._dispatch(t.expr)</p></li>
<li><p>self._write("[")</p></li>
<li><p>for i, value in enumerate(t.subs):</p></li>
<li><p>if i != 0:</p></li>
<li><p>self._write(",")</p></li>
<li><p>self._dispatch(value)</p></li>
<li><p>self._write("]")</p></li></ul>
<p>–</p>
<ul><li><p>def _TryExcept(self, t):</p></li>
<li><p>self._fill("try")</p></li>
<li><p>self._enter()</p></li>
<li><p>self._dispatch(t.body)</p></li>
<li><p>self._leave()</p></li></ul>
<p>–</p>
<ul><li><p>for handler in t.handlers:</p></li>
<li><p>self._fill('except ')</p></li>
<li><p>self._dispatch(handler[0])</p></li>
<li><p>if handler[1] is not None:</p></li>
<li><p>self._write(', ')</p></li>
<li><p>self._dispatch(handler[1])</p></li>
<li><p>self._enter()</p></li>
<li><p>self._dispatch(handler[2])</p></li>
<li><p>self._leave()</p></li></ul>
<p>–</p>
<ul><li><p>if t.else_:</p></li>
<li><p>self._fill("else")</p></li>
<li><p>self._enter()</p></li>
<li><p>self._dispatch(t.else_)</p></li>
<li><p>self._leave()</p></li></ul>
<p>–</p>
<ul><li><p>def _Tuple(self, t):</p></li></ul>
<p>–</p>
<ul><li><p>if not t.nodes:</p></li>
<li><p># Empty tuple.</p></li>
<li><p>self._write("()")</p></li>
<li><p>else:</p></li>
<li><p>self._write("(")</p></li></ul>
<p>–</p>
<ul><li><p># _write each elements, separated by a comma.</p></li>
<li><p>for element in t.nodes[:-1]:</p></li>
<li><p>self._dispatch(element)</p></li>
<li><p>self._write(", ")</p></li></ul>
<p>–</p>
<ul><li><p># Handle the last one without writing comma</p></li>
<li><p>last_element = t.nodes[-1]</p></li>
<li><p>self._dispatch(last_element)</p></li></ul>
<p>–</p>
<ul><li><p>self._write(")")</p></li></ul>
<p>–</p>
<ul><li><p>def _UnaryAdd(self, t):</p></li>
<li><p>self._write("+")</p></li>
<li><p>self._dispatch(t.expr)</p></li></ul>
<p>–</p>
<ul><li><p>def _UnarySub(self, t):</p></li>
<li><p>self._write("-")</p></li>
<li><p>self._dispatch(t.expr)</p></li></ul>
<p>–</p>
<ul><li><p>def _With(self, t):</p></li>
<li><p>self._fill('with ')</p></li>
<li><p>self._dispatch(t.expr)</p></li>
<li><p>if t.vars:</p></li>
<li><p>self._write(' as ')</p></li>
<li><p>self._dispatch(t.vars.name)</p></li>
<li><p>self._enter()</p></li>
<li><p>self._dispatch(t.body)</p></li>
<li><p>self._leave()</p></li>
<li><p>self._write('\n')</p></li></ul>
<p>–</p>
<ul><li><p>def _int(self, t):</p></li>
<li><p>self._write(repr(t))</p></li></ul>
<p>–</p>
<ul><li><p>def __binary_op(self, t, symbol):</p></li>
<li><p># Check if parenthesis are needed on left side and then dispatch</p></li>
<li><p>has_paren = False</p></li>
<li><p>left_class = str(t.left.__class__)</p></li>
<li><p>if (left_class in op_precedence.keys() and</p></li>
<li><p>op_precedence[left_class] < op_precedence[str(t.__class__)]):</p></li>
<li><p>has_paren = True</p></li>
<li><p>if has_paren:</p></li>
<li><p>self._write('(')</p></li>
<li><p>self._dispatch(t.left)</p></li>
<li><p>if has_paren:</p></li>
<li><p>self._write(')')</p></li>
<li><p># Write the appropriate symbol for operator</p></li>
<li><p>self._write(symbol)</p></li>
<li><p># Check if parenthesis are needed on the right side and then dispatch</p></li>
<li><p>has_paren = False</p></li>
<li><p>right_class = str(t.right.__class__)</p></li>
<li><p>if (right_class in op_precedence.keys() and</p></li>
<li><p>op_precedence[right_class] < op_precedence[str(t.__class__)]):</p></li>
<li><p>has_paren = True</p></li>
<li><p>if has_paren:</p></li>
<li><p>self._write('(')</p></li>
<li><p>self._dispatch(t.right)</p></li>
<li><p>if has_paren:</p></li>
<li><p>self._write(')')</p></li></ul>
<p>–</p>
<ul><li><p>def _float(self, t):</p></li>
<li><p># if t is 0.1, str(t)->'0.1' while repr(t)->'0.1000000000001'</p></li>
<li><p># We prefer str here.</p></li>
<li><p>self._write(str(t))</p></li></ul>
<p>–</p>
<ul><li><p>def _str(self, t):</p></li>
<li><p>self._write(repr(t))</p></li></ul>
<p>–</p>
<ul><li><p>def _tuple(self, t):</p></li>
<li><p>self._write(str(t))</p></li></ul>
<p>–</p>
<ul><li><p>#########################################################################</p></li>
<li><p># These are the methods from the _ast modules unparse.</p></li>
<li><p>#</p></li>
<li><p># As our needs to handle more advanced code increase, we may want to</p></li>
<li><p># modify some of the methods below so that they work for compiler.ast.</p></li>
<li><p>#########################################################################</p></li></ul>
<p>– -#    # stmt -#    def <em>Expr(self, tree): -#        self._fill() -#        self._dispatch(tree.value) -# -#    def <em>Import(self, t): -#        self._fill("import “) -#        first = True -#        for a in t.names: -#            if first: -#                first = False -#            else: -#                self._write(”, “) -#            self._write(a.name) -#            if a.asname: -#                self._write(” as “+a.asname) -# -##    def _ImportFrom(self, t): -##        self._fill("from “) -##        self._write(t.module) -##        self._write(” import “) -##        for i, a in enumerate(t.names): -##            if i == 0: -##                self._write(”, “) -##            self._write(a.name) -##            if a.asname: -##                self._write(” as “+a.asname) -##        # XXX(jpe) what is level for? -## -# -#    def _Break(self, t): -#        self._fill("break”) -# -#    def _Continue(self, t): -#        self._fill("continue”) -# -#    def _Delete(self, t): -#        self._fill("del “) -#        self._dispatch(t.targets) -# -#    def _Assert(self, t): -#        self._fill("assert “) -#        self._dispatch(t.test) -#        if t.msg: -#            self._write(”, “) -#            self._dispatch(t.msg) -# -#    def _Exec(self, t): -#        self._fill("exec “) -#        self._dispatch(t.body) -#        if t.globals: -#            self._write(” in “) -#            self._dispatch(t.globals) -#        if t.locals: -#            self._write(”, “) -#            self._dispatch(t.locals) -# -#    def _Print(self, t): -#        self._fill("print “) -#        do_comma = False -#        if t.dest: -#            self._write(">>”) -#            self._dispatch(t.dest) -#            do_comma = True -#        for e in t.values: -#            if do_comma:self._write(”, “) -#            else:do_comma=True -#            self._dispatch(e) -#        if not t.nl: -#            self._write(",”) -# -#    def _Global(self, t): -#        self._fill("global”) -#        for i, n in enumerate(t.names): -#            if i != 0: -#                self._write(",”) -#            self._write(" " + n) -# -#    def _Yield(self, t): -#        self._fill("yield") -#        if t.value: -#            self._write(" (") -#            self._dispatch(t.value) -#            self._write(")") -# -#    def _Raise(self, t): -#        self._fill('raise ‘) -#        if t.type: -#            self._dispatch(t.type) -#        if t.inst: -#            self._write(", “) -#            self._dispatch(t.inst) -#        if t.tback: -#            self._write(”, “) -#            self._dispatch(t.tback) -# -# -#    def _TryFinally(self, t): -#        self._fill("try”) -#        self._enter() -#        self._dispatch(t.body) -#        self._leave() -# -#        self._fill("finally") -#        self._enter() -#        self._dispatch(t.finalbody) -#        self._leave() -# -#    def _excepthandler(self, t): -#        self._fill("except “) -#        if t.type: -#            self._dispatch(t.type) -#        if t.name: -#            self._write(”, “) -#            self._dispatch(t.name) -#        self._enter() -#        self._dispatch(t.body) -#        self._leave() -# -#    def _ClassDef(self, t): -#        self._write("\n”) -#        self._fill("class “+t.name) -#        if t.bases: -#            self._write("(”) -#            for a in t.bases: -#                self._dispatch(a) -#                self._write(", “) -#            self._write(")”) -#        self._enter() -#        self._dispatch(t.body) -#        self._leave() -# -#    def _FunctionDef(self, t): -#        self._write("\n") -#        for deco in t.decorators: -#            self._fill("@") -#            self._dispatch(deco) -#        self._fill("def “+t.name + “(”) -#        self._dispatch(t.args) -#        self._write(")”) -#        self._enter() -#        self._dispatch(t.body) -#        self._leave() -# -#    def _For(self, t): -#        self._fill("for “) -#        self._dispatch(t.target) -#        self._write(” in “) -#        self._dispatch(t.iter) -#        self._enter() -#        self._dispatch(t.body) -#        self._leave() -#        if t.orelse: -#            self._fill("else”) -#            self._enter() -#            self._dispatch(t.orelse) -#            self._leave -# -#    def _While(self, t): -#        self._fill("while “) -#        self._dispatch(t.test) -#        self._enter() -#        self._dispatch(t.body) -#        self._leave() -#        if t.orelse: -#            self._fill("else”) -#            self._enter() -#            self._dispatch(t.orelse) -#            self._leave -# -#    # expr -#    def _Str(self, tree): -#        self._write(repr(tree.s)) -## -#    def _Repr(self, t): -#        self._write("`") -#        self._dispatch(t.value) -#        self._write("`") -# -#    def _Num(self, t): -#        self._write(repr(t.n)) -# -#    def _ListComp(self, t): -#        self._write("[") -#        self._dispatch(t.elt) -#        for gen in t.generators: -#            self._dispatch(gen) -#        self._write("]") -# -#    def _GeneratorExp(self, t): -#        self._write("(") -#        self._dispatch(t.elt) -#        for gen in t.generators: -#            self._dispatch(gen) -#        self._write(")") -# -#    def _comprehension(self, t): -#        self._write(" for “) -#        self._dispatch(t.target) -#        self._write(” in “) -#        self._dispatch(t.iter) -#        for if_clause in t.ifs: -#            self._write(” if “) -#            self._dispatch(if_clause) -# -#    def _IfExp(self, t): -#        self._dispatch(t.body) -#        self._write(” if “) -#        self._dispatch(t.test) -#        if t.orelse: -#            self._write(” else “) -#            self._dispatch(t.orelse) -# -#    unop = {"Invert":"~”, “Not”: “not”, “UAdd":"+”, “USub":"-”} -#    def _UnaryOp(self, t): -#        self._write(self.unop[t.op.__class__.__name__]) -#        self._write("(") -#        self._dispatch(t.operand) -#        self._write(")") -# -#    binop = { “Add":"+”, “Sub":"-”, “Mult":"*”, “Div":"/”, “Mod":"%”, -#                    “LShift":">>”, “RShift":"<<”, “BitOr":"|”, “BitXor":"^”, “BitAnd":"&”, -#                    “FloorDiv":"//”, “Pow”: “**”} -#    def _BinOp(self, t): -#        self._write("(") -#        self._dispatch(t.left) -#        self._write(")" + self.binop[t.op.__class__.__name</em></em>] + “(”) -#        self._dispatch(t.right) -#        self._write(")") -# -#    boolops = {_ast.And: ‘and’, _ast.Or: ‘or’} -#    def _BoolOp(self, t): -#        self._write("(") -#        self._dispatch(t.values[0]) -#        for v in t.values[1:]: -#            self._write(" %s " % self.boolops[t.op.__class__]) -#            self._dispatch(v) -#        self._write(")") -# -#    def _Attribute(self,t): -#        self._dispatch(t.value) -#        self._write(".") -#        self._write(t.attr) -# -##    def _Call(self, t): -##        self._dispatch(t.func) -##        self._write("(") -##        comma = False -##        for e in t.args: -##            if comma: self._write(", “) -##            else: comma = True -##            self._dispatch(e) -##        for e in t.keywords: -##            if comma: self._write(”, “) -##            else: comma = True -##            self._dispatch(e) -##        if t.starargs: -##            if comma: self._write(”, “) -##            else: comma = True -##            self._write("*”) -##            self._dispatch(t.starargs) -##        if t.kwargs: -##            if comma: self._write(", “) -##            else: comma = True -##            self._write("**”) -##            self._dispatch(t.kwargs) -##        self._write(")") -# -#    # slice -#    def _Index(self, t): -#        self._dispatch(t.value) -# -#    def _ExtSlice(self, t): -#        for i, d in enumerate(t.dims): -#            if i != 0: -#                self._write(’: ') -#            self._dispatch(d) -# -#    # others -#    def _arguments(self, t): -#        first = True -#        nonDef = len(t.args)-len(t.defaults) -#        for a in t.args[0:nonDef]: -#            if first:first = False -#            else: self._write(", “) -#            self._dispatch(a) -#        for a,d in zip(t.args[nonDef:], t.defaults): -#            if first:first = False -#            else: self._write(”, “) -#            self._dispatch(a), -#            self._write("=”) -#            self._dispatch(d) -#        if t.vararg: -#            if first:first = False -#            else: self._write(", “) -#            self._write("*"+t.vararg) -#        if t.kwarg: -#            if first:first = False -#            else: self._write(”, “) -#            self._write("**"+t.kwarg) -# -##    def _keyword(self, t): -##        self._write(t.arg) -##        self._write("=”) -##        self._dispatch(t.value) -# -#    def _Lambda(self, t): -#        self._write("lambda “) -#        self._dispatch(t.args) -#        self._write(”: ") -#        self._dispatch(t.body) – – –</p>
<p>This diff is so big that we needed to truncate the remainder.</p>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/8919b2de7e36/">https://bitbucket.org/yt_analysis/yt/commits/8919b2de7e36/</a> Changeset:   8919b2de7e36 Branch:      yt User:        chummels Date:        2016-03-16 19:11:39+00:00 Summary:     Clarifying documentation on annotate_arrow callback. Affected #:  1 file</p>
<p>diff -r 52b7292e3caf231d622322be093b39bc35029222 -r 8919b2de7e36e1a39879cf2a6d42276273073272 yt/visualization/plot_modifications.py --- a/yt/visualization/plot_modifications.py +++ b/yt/visualization/plot_modifications.py @@ -913,9 +913,16 @@</p>
<pre>                   coord_system='data', plot_args=None):

    Overplot an arrow pointing at a position for highlighting a specific</pre>
<ul><li><p>feature.  Arrow points from lower left to the designated position with</p></li>
<li><p>arrow length “length” unless starting_pos is set to specify tail location</p></li>
<li><p>of arrow.</p></li></ul>
<p>+    feature.  By default, wrrow points from lower left to the designated +    position with arrow length “length” unless starting_pos is set to specify +    tail location of arrow. + +    coord_system keyword refers to positions set in pos arg and starting_pos +    keyword, which by default are in data coordinates. + +    length, width, head_length, and head_width keywords for the arrow are all +    in axis units, ie relative to the size of the plot axes as 1, even if +    the position of the arrow is set relative to another coordinate system.</p>
<pre>Parameters
----------</pre>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/7730a2abd258/">https://bitbucket.org/yt_analysis/yt/commits/7730a2abd258/</a> Changeset:   7730a2abd258 Branch:      yt User:        chummels Date:        2016-03-16 19:12:57+00:00 Summary:     Correcting typo in docstrings for annotate_arrow() Affected #:  1 file</p>
<p>diff -r 8919b2de7e36e1a39879cf2a6d42276273073272 -r 7730a2abd2588614480cf3e881d814b7e739e17b yt/visualization/plot_modifications.py --- a/yt/visualization/plot_modifications.py +++ b/yt/visualization/plot_modifications.py @@ -913,7 +913,7 @@</p>
<pre>                   coord_system='data', plot_args=None):

    Overplot an arrow pointing at a position for highlighting a specific</pre>
<ul><li><p>feature.  By default, wrrow points from lower left to the designated</p></li></ul>
<p>+    feature.  By default, arrow points from lower left to the designated</p>
<pre>    position with arrow length "length" unless starting_pos is set to specify
    tail location of arrow.
</pre>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/4dfcc6bdf74a/">https://bitbucket.org/yt_analysis/yt/commits/4dfcc6bdf74a/</a> Changeset:   4dfcc6bdf74a Branch:      yt User:        chummels Date:        2016-03-16 19:31:52+00:00 Summary:     Clarifying docstrings for annotate_arrow Affected #:  1 file</p>
<p>diff -r 7730a2abd2588614480cf3e881d814b7e739e17b -r 4dfcc6bdf74a117625634ced4f64bd52b74c2f2e yt/visualization/plot_modifications.py --- a/yt/visualization/plot_modifications.py +++ b/yt/visualization/plot_modifications.py @@ -913,16 +913,18 @@</p>
<pre>                   coord_system='data', plot_args=None):

    Overplot an arrow pointing at a position for highlighting a specific</pre>
<ul><li><p>feature.  By default, arrow points from lower left to the designated</p></li>
<li><p>position with arrow length “length” unless starting_pos is set to specify</p></li>
<li><p>tail location of arrow.</p></li></ul>
<p>+    feature.  By default, arrow points from lower left to the designated +    position “pos” with arrow length “length”.  Alternatively, if +    “starting_pos” is set, arrow will stretch from “starting_pos” to “pos” +    and “length” will be disregarded.</p>
<ul><li><p>coord_system keyword refers to positions set in pos arg and starting_pos</p></li>
<li><p>keyword, which by default are in data coordinates.</p></li></ul>
<p>+    “coord_system” keyword refers to positions set in “pos” arg and +    “starting_pos” keyword, which by default are in data coordinates.</p>
<ul><li><p>length, width, head_length, and head_width keywords for the arrow are all</p></li>
<li><p>in axis units, ie relative to the size of the plot axes as 1, even if</p></li>
<li><p>the position of the arrow is set relative to another coordinate system.</p></li></ul>
<p>+    “length”, “width”, “head_length”, and “head_width” keywords for the arrow +    are all in axis units, ie relative to the size of the plot axes as 1, +    even if the position of the arrow is set relative to another coordinate +    system.</p>
<pre>Parameters
----------</pre>
<p>@@ -1028,8 +1030,8 @@</p>
<pre>dx = dy = self.code_size
         else:
if self.starting_pos is not None:</pre>
<ul><li><p>start_x,start_y = self.sanitize_coord_system(plot, \</p></li>
<li><p>self.starting_pos, \</p></li></ul>
<p>+                start_x,start_y = self.sanitize_coord_system(plot, +                                       self.starting_pos,</p>
<pre>                       coord_system=self.coord_system)
dx = x - start_x
dy = y - start_y</pre>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/bba384360818/">https://bitbucket.org/yt_analysis/yt/commits/bba384360818/</a> Changeset:   bba384360818 Branch:      yt User:        brittonsmith Date:        2016-03-28 08:42:09+00:00 Summary:     Merged in chummels/yt (pull request #2043)</p>
<p>Enhancing annotate_ray and annotate_arrow callbacks Affected #:  1 file</p>
<p>diff -r be993079427c300e09b4b6430e3c8d90af0c3500 -r bba3843608189ecf29b8ad109ae02546bbd272af yt/visualization/plot_modifications.py --- a/yt/visualization/plot_modifications.py +++ b/yt/visualization/plot_modifications.py @@ -158,6 +158,9 @@</p>
<pre>                      "need to be in 3D")
coord = self.project_coords(plot, coord)
coord = self.convert_to_plot(plot, coord)</pre>
<p>+            # Convert coordinates from a tuple of ndarray to a tuple of floats +            # since not all callbacks are OK with ndarrays as coords (eg arrow) +            coord = (coord[0][0], coord[1][0])</p>
<pre>         # if in plot coords, define the transform correctly
         if coord_system == "data" or coord_system == "plot":
self.transform = plot._axes.transData</pre>
<p>@@ -905,11 +908,23 @@</p>
<pre>class ArrowCallback(PlotCallback):
    """</pre>
<ul><li><p>annotate_arrow(pos, length=0.03, coord_system='data', plot_args=None):</p></li></ul>
<p>+    annotate_arrow(pos, length=0.03, width=0.003, head_length=None, +                   head_width=0.02, starting_pos=None, +                   coord_system='data', plot_args=None):</p>
<pre>Overplot an arrow pointing at a position for highlighting a specific</pre>
<ul><li><p>feature.  Arrow points from lower left to the designated position with</p></li>
<li><p>arrow length “length”.</p></li></ul>
<p>+    feature.  By default, arrow points from lower left to the designated +    position “pos” with arrow length “length”.  Alternatively, if +    “starting_pos” is set, arrow will stretch from “starting_pos” to “pos” +    and “length” will be disregarded. + +    “coord_system” keyword refers to positions set in “pos” arg and +    “starting_pos” keyword, which by default are in data coordinates. + +    “length”, “width”, “head_length”, and “head_width” keywords for the arrow +    are all in axis units, ie relative to the size of the plot axes as 1, +    even if the position of the arrow is set relative to another coordinate +    system.</p>
<pre>Parameters
----------</pre>
<p>@@ -918,6 +933,24 @@</p>
<pre>length : float, optional
    The length, in axis units, of the arrow.</pre>
<p>+        Default: 0.03 + +    width : float, optional +        The width, in axis units, of the tail line of the arrow. +        Default: 0.003 + +    head_length : float, optional +        The length, in axis units, of the head of the arrow.  If set +        to None, use 1.5*head_width +        Default: None + +    head_width : float, optional +        The width, in axis units, of the head of the arrow. +        Default: 0.02 + +    starting_pos : 2- or 3-element tuple, list, or array, optional +        These are the coordinates from which the arrow starts towards its +        point.  Not compatible with ‘length’ kwarg.</p>
<pre>coord_system : string, optional
    This string defines the coordinate system of the coordinates of pos</pre>
<p>@@ -935,7 +968,7 @@</p>
<pre>plot_args : dictionary, optional
    This dictionary is passed to the MPL arrow function for generating</pre>
<ul><li><p>the arrow.  By default, it is: {'color':'white', 'linewidth':2}</p></li></ul>
<p>+        the arrow.  By default, it is: {'color':'white'}</p>
<pre>Examples
--------</pre>
<p>@@ -952,18 +985,23 @@</p>
<pre>>>> import yt
>>> ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030')
>>> s = yt.SlicePlot(ds, 'z', 'density')</pre>
<ul><li><blockquote><blockquote><blockquote><p>s.annotate_arrow([0.1, -0.1, length=0.06, coord_system='plot',</p></blockquote></blockquote></blockquote></li></ul>
<p>+    >>> s.annotate_arrow([0.1, -0.1], length=0.06, coord_system='plot',</p>
<pre>    ...                  plot_args={'color':'red'})
    >>> s.save()

    """
    _type_name = "arrow"</pre>
<ul><li><p>def __init__(self, pos, code_size=None, length=0.03, coord_system='data',</p></li>
<li><p>plot_args=None):</p></li>
<li><p>def_plot_args = {'color':'white', 'linewidth':2}</p></li></ul>
<p>+    def __init__(self, pos, code_size=None, length=0.03, width=0.0001, +                 head_width=0.01, head_length=0.01, +                 starting_pos=None, coord_system='data', plot_args=None): +        def_plot_args = {'color':'white'}</p>
<pre>self.pos = pos
self.code_size = code_size
self.length = length</pre>
<p>+        self.width = width +        self.head_width = head_width +        self.head_length = head_length +        self.starting_pos = starting_pos</p>
<pre>self.coord_system = coord_system
self.transform = None
if plot_args is None: plot_args = def_plot_args</pre>
<p>@@ -974,7 +1012,13 @@</p>
<pre>coord_system=self.coord_system)
         xx0, xx1 = plot._axes.get_xlim()
         yy0, yy1 = plot._axes.get_ylim()</pre>
<p>– +        # normalize all of the kwarg lengths to the plot size +        plot_diag = ((yy1-yy0)**2 + (xx1-xx0)**2)**(0.5) +        self.length *= plot_diag +        self.width *= plot_diag +        self.head_width *= plot_diag +        if self.head_length is not None: +            self.head_length *= plot_diag</p>
<pre>         if self.code_size is not None:
warnings.warn("The code_size keyword is deprecated.  Please use "
              "the length keyword in 'axis' units instead. "</pre>
<p>@@ -985,13 +1029,25 @@</p>
<pre>self.code_size = self.code_size * self.pixel_scale(plot)[0]
dx = dy = self.code_size
         else:</pre>
<ul><li><p>dx = (xx1-xx0) * self.length</p></li>
<li><p>dy = (yy1-yy0) * self.length</p></li></ul>
<p>+            if self.starting_pos is not None: +                start_x,start_y = self.sanitize_coord_system(plot, +                                       self.starting_pos, +                                       coord_system=self.coord_system) +                dx = x – start_x +                dy = y – start_y +            else: +                dx = (xx1-xx0) * 2**(0.5) * self.length +                dy = (yy1-yy0) * 2**(0.5) * self.length +        # If the arrow is 0 length +        if dx == dy == 0: +            warnings.warn("The arrow has zero length.  Not annotating.") +            return</p>
<pre>plot._axes.hold(True)</pre>
<ul><li><p>from matplotlib.patches import Arrow</p></li>
<li><p>arrow = Arrow(x-dx, y-dy, dx, dy, width=dx,</p></li>
<li><p>transform=self.transform, **self.plot_args)</p></li>
<li><p>plot._axes.add_patch(arrow)</p></li></ul>
<p>+        plot._axes.arrow(x-dx, y-dy, dx, dy, width=self.width, +                         head_width=self.head_width, +                         head_length=self.head_length, +                         transform=self.transform, +                         length_includes_head=True, **self.plot_args)</p>
<pre>plot._axes.set_xlim(xx0,xx1)
plot._axes.set_ylim(yy0,yy1)
plot._axes.hold(False)</pre>
<p>@@ -1837,8 +1893,8 @@</p>
<pre>axis length.  Additional customization of the scale bar is possible by
adjusting the text_args and size_bar_args dictionaries.  The text_args
dictionary accepts matplotlib's font_properties arguments to override</pre>
<ul><li><p>the default font_properties for the current plot.  The size_bar_args</p></li>
<li><p>dictionary accepts keyword arguments for the AnchoredSizeBar class in</p></li></ul>
<p>+    the default font_properties for the current plot.  The size_bar_args +    dictionary accepts keyword arguments for the AnchoredSizeBar class in</p>
<pre>    matplotlib's axes_grid toolkit.

    Parameters</pre>
<p>@@ -1918,7 +1974,7 @@</p>
<pre>     _type_name = "scale"
     def __init__(self, corner='lower_right', coeff=None, unit=None, pos=None,
max_frac=0.16, min_frac=0.015, coord_system='axis',</pre>
<ul><li><p>text_args=None, size_bar_args=None, draw_inset_box=False,</p></li></ul>
<p>+                 text_args=None, size_bar_args=None, draw_inset_box=False,</p>
<pre>                 inset_box_args=None):

        def_size_bar_args = {</pre>
<p>@@ -2011,7 +2067,7 @@</p>
<pre>         # FontProperties instances use set_<property>() setter functions
         for key, val in self.text_args.items():
setter_func = "set_"+key</pre>
<ul><li><p>try:</p></li></ul>
<p>+            try:</p>
<pre>    getattr(fontproperties, setter_func)(val)
except AttributeError:
    raise AttributeError("Cannot set text_args keyword " \</pre>
<p>@@ -2042,6 +2098,9 @@</p>
<pre>Adds a line representing the projected path of a ray across the plot.
The ray can be either a YTOrthoRay, YTRay, or a LightRay object.
annotate_ray() will properly account for periodic rays across the volume.</pre>
<p>+    If arrow is set to True, uses the MPL.pyplot.arrow function, otherwise +    uses the MPL.pyplot.plot function to plot a normal line.  Adjust +    plot_args accordingly.</p>
<pre>Parameters
----------</pre>
<p>@@ -2053,6 +2112,11 @@</p>
<pre>        object, it will only plot the segment of the LightRay that intersects
        the dataset currently displayed.
</pre>
<p>+    arrow : boolean, optional +        Whether or not to place an arrowhead on the front of the ray to denote +        direction +        Default: False +</p>
<pre>plot_args : dictionary, optional
    A dictionary of any arbitrary parameters to be passed to the Matplotlib
    line object.  Defaults: {'color':'white', 'linewidth':2}.</pre>
<p>@@ -2083,10 +2147,11 @@</p>
<pre>"""
_type_name = "ray"</pre>
<ul><li><p>def __init__(self, ray, plot_args=None):</p></li></ul>
<p>+    def __init__(self, ray, arrow=False, plot_args=None):</p>
<pre>PlotCallback.__init__(self)
def_plot_args = {'color':'white', 'linewidth':2}
self.ray = ray</pre>
<p>+        self.arrow = arrow</p>
<pre>        if plot_args is None: plot_args = def_plot_args
        self.plot_args = plot_args
</pre>
<p>@@ -2156,12 +2221,23 @@</p>
<pre>        else:
            segments = [[start_coord, end_coord]]
</pre>
<ul><li><p>for segment in segments:</p></li>
<li><p>lcb = LinePlotCallback(segment[0], segment[1],</p></li>
<li><p>coord_system='data',</p></li>
<li><p>plot_args=self.plot_args)</p></li>
<li><p>lcb(plot)</p></li></ul>
<p>– +        # To assure that the last ray segment has an arrow if so desired +        # and all other ray segments are lines +        for segment in segments[:-1]: +            cb = LinePlotCallback(segment[0], segment[1], +                                  coord_system='data', +                                  plot_args=self.plot_args) +            cb(plot) +        segment = segments[-1] +        if self.arrow: +            cb = ArrowCallback(segment[1], starting_pos=segment[0], +                               coord_system='data', +                               plot_args=self.plot_args) +        else: +           cb = LinePlotCallback(segment[0], segment[1], +                               coord_system='data', +                               plot_args=self.plot_args) +        cb(plot)</p>
<pre>        return plot

class LineIntegralConvolutionCallback(PlotCallback):</pre>
<p>@@ -2171,7 +2247,7 @@</p>
<pre>                                       cmap='binary', alpha=0.8,
                                       const_alpha=False):
</pre>
<ul><li><p>Add the line integral convolution to the plot for vector fields</p></li></ul>
<p>+    Add the line integral convolution to the plot for vector fields</p>
<pre>    visualization. Two component of vector fields needed to be provided
    (i.e., velocity_x and velocity_y, magentic_field_x and magnetic_field_y).
</pre>
<p>@@ -2268,7 +2344,7 @@</p>
<pre>        lic_data_clip = np.clip(lic_data,self.lim[0],self.lim[1])

        if self.const_alpha:</pre>
<ul><li><p>plot._axes.imshow(lic_data_clip, extent=extent, cmap=self.cmap,</p></li></ul>
<p>+            plot._axes.imshow(lic_data_clip, extent=extent, cmap=self.cmap,</p>
<pre>                  alpha=self.alpha)
         else:
lic_data_rgba = cm.ScalarMappable(norm=None, cmap=self.cmap).\</pre>
<p>Repository URL: <a href="https://bitbucket.org/yt_analysis/yt/">https://bitbucket.org/yt_analysis/yt/</a></p>
<p>—</p>
<p>This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.</p>

<img src="http://link.bitbucket.org/wf/open?upn=ll4ctv0L-2ByeRZFC1LslHcg6aJmnQ70VruLbmeLQr27DrLg6r8twFMifpScE1u2gipFmhhlIQ78tG-2FnzpdY2Ag3n7rKEt5pVRClrw14jWO2umukZzNCszANPtIPXrP9-2BzlPt0-2F-2FvvaTQZUNoakanPNZ57vTmIM9wsbU8IOrCXVZJim1sNEh-2F8pF8fRU8mhUaWzVtaqGqKCQ-2FoeBbU2GvlQIdrbL6Bd9S-2FevUsVmN2sOU-3D" alt="" width="1" height="1" border="0" style="height:1px !important;width:1px !important;border-width:0 !important;margin-top:0 !important;margin-bottom:0 !important;margin-right:0 !important;margin-left:0 !important;padding-top:0 !important;padding-bottom:0 !important;padding-right:0 !important;padding-left:0 !important;"/>
</body></html>