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

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Wed Sep 7 11:10:14 PDT 2016


12 new commits in yt:

https://bitbucket.org/yt_analysis/yt/commits/053e35273f81/
Changeset:   053e35273f81
Branch:      yt
User:        a_gilbert
Date:        2016-08-14 01:50:24+00:00
Summary:     Updated origin input to accept floats or ints specifying xloc or yloc. Also updated docs accordingly.
Affected #:  2 files

diff -r 56c0b53b459c4cb6c6a3bdf67634e142ec4c0f52 -r 053e35273f81771c2075d9ea012024b72af679bc yt/visualization/base_plot_types.py
--- a/yt/visualization/base_plot_types.py
+++ b/yt/visualization/base_plot_types.py
@@ -357,6 +357,7 @@
         self._toggle_colorbar(True)
         return self
 
+
 def get_multi_plot(nx, ny, colorbar = 'vertical', bw = 4, dpi=300,
                    cbar_padding = 0.4):
     r"""Construct a multiple axes plot object, with or without a colorbar, into
@@ -440,3 +441,5 @@
             ax.clear()
             cbars.append(ax)
     return fig, tr, cbars
+
+

diff -r 56c0b53b459c4cb6c6a3bdf67634e142ec4c0f52 -r 053e35273f81771c2075d9ea012024b72af679bc yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -396,18 +396,20 @@
 
         Parameters
         ----------
-        origin : string or length 1, 2, or 3 sequence of strings
+        origin : string or length 1, 2, or 3 sequence of strings or ints/floats
+                 and strings.
             The location of the origin of the plot coordinate system.  This is
-            represented by '-' separated string or a tuple of strings.  In the
-            first index the y-location is given by 'lower', 'upper', or 'center'.
-            The second index is the x-location, given as 'left', 'right', or
-            'center'.  Finally, the whether the origin is applied in 'domain'
-            space, plot 'window' space or 'native' simulation coordinate system
-            is given. For example, both 'upper-right-domain' and ['upper',
-            'right', 'domain'] place the origin in the upper right hand
-            corner of domain space. If x or y are not given, a value is inferred.
-            For instance, 'left-domain' corresponds to the lower-left hand corner
-            of the simulation domain, 'center-domain' corresponds to the center
+            represented by '-' separated string or a tuple of strings or a mixed
+            tuple.  In the first index the y-location is given by 'lower',
+            'upper', or 'center' or a float or int. The second index is the
+            x-location, given as 'left', 'right', or 'center' or a float or int.
+            Finally, the whether the origin is applied in 'domain' space, plot
+            'window' space or 'native' simulation coordinate system is given.
+            For example, both 'upper-right-domain' and ['upper', 'right',
+            'domain'] place the origin in the upper right hand corner of domain
+            space. If x or y are not given, a value is inferred. For instance,
+            'left-domain' corresponds to the lower-left hand corner of the
+            simulation domain, 'center-domain' corresponds to the center
             of the simulation domain, or 'center-window' for the center of the
             plot window. Further examples:
 
@@ -422,6 +424,7 @@
             ('{xloc}', '{space}')                  ('right', 'domain')
             ('{yloc}', '{space}')                  ('lower', 'window')
             ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
+            (xloc, yloc, coord_sys)                (0.5, 0.5, 'domain')
             ==================================     ============================
 
         """
@@ -650,6 +653,9 @@
     def _setup_origin(self):
         origin = self.origin
         axis_index = self.data_source.axis
+        xc = None
+        yc = None
+
         if isinstance(origin, string_types):
             origin = tuple(origin.split('-'))[:3]
         if 1 == len(origin):
@@ -659,6 +665,9 @@
             origin = (o0map[origin[0]],) + origin
         elif 2 == len(origin) and origin[0] in set(['lower','upper','center']):
             origin = (origin[0], 'center', origin[-1])
+        elif 2 == len(origin) and type(origin[0]) in set([int, float]):
+            xc = origin[0]
+            yc = origin[1]
         assert origin[-1] in ['window', 'domain', 'native']
 
         if origin[2] == 'window':
@@ -677,33 +686,42 @@
         else:
             mylog.warn("origin = {0}".format(origin))
             msg = \
-                ('origin keyword "{0}" not recognized, must declare "domain" '
-                 'or "center" as the last term in origin.').format(self.origin)
+                  ('origin keyword "{0}" not recognized, must declare "domain" '
+                   'or "center" as the last term in origin.').format(self.origin)
             raise RuntimeError(msg)
+        if xc is None and yc is None:
+            if origin[0] == 'lower':
+                yc = yllim
+            elif origin[0] == 'upper':
+                yc = yrlim
+            elif origin[0] == 'center':
+                yc = (yllim + yrlim)/2.0
+            else:
+                mylog.warn("origin = {0}".format(origin))
+                msg = ('origin keyword "{0}" not recognized, must declare "lower" '
+                       '"upper" or "center" as the first term in origin.')
+                msg = msg.format(self.origin)
+                raise RuntimeError(msg)
 
-        if origin[0] == 'lower':
-            yc = yllim
-        elif origin[0] == 'upper':
-            yc = yrlim
-        elif origin[0] == 'center':
-            yc = (yllim + yrlim)/2.0
-        else:
-            mylog.warn("origin = {0}".format(origin))
-            msg = ('origin keyword "{0}" not recognized, must declare "lower" '
-                   '"upper" or "center" as the first term in origin.')
-            msg = msg.format(self.origin)
-            raise RuntimeError(msg)
+            if origin[1] == 'left':
+                xc = xllim
+            elif origin[1] == 'right':
+                xc = xrlim
+            elif origin[1] == 'center':
+                xc = (xllim + xrlim)/2.0
+            else:
+                mylog.warn("origin = {0}".format(origin))
+                msg = ('origin keyword "{0}" not recognized, must declare "left" '
+                       '"right" or "center" as the second term in origin.')
+                msg = msg.format(self.origin)
+                raise RuntimeError(msg)
 
-        if origin[1] == 'left':
-            xc = xllim
-        elif origin[1] == 'right':
-            xc = xrlim
-        elif origin[1] == 'center':
-            xc = (xllim + xrlim)/2.0
-        else:
-            mylog.warn("origin = {0}".format(origin))
-            msg = ('origin keyword "{0}" not recognized, must declare "left" '
-                   '"right" or "center" as the second term in origin.')
+        x_in_bounds = xc >= xllim and xc <= xrlim
+        y_in_bounds = yc >= yllim and yc <= yrlim
+
+        if not x_in_bounds and not y_in_bounds:
+            msg = ('orgin inputs not in bounds of specified coordinate sytem' +
+                   'domain.')
             msg = msg.format(self.origin)
             raise RuntimeError(msg)
 
@@ -807,12 +825,12 @@
                 ia = ImageArray(ia)
             else:
                 ia = image
-            self.plots[f] = WindowPlotMPL(
-                ia, self._field_transform[f].name,
-                self._field_transform[f].func,
-                self._colormaps[f], extent, zlim,
-                self.figure_size, font_size,
-                self.aspect, fig, axes, cax)
+                self.plots[f] = WindowPlotMPL(
+                    ia, self._field_transform[f].name,
+                    self._field_transform[f].func,
+                    self._colormaps[f], extent, zlim,
+                    self.figure_size, font_size,
+                    self.aspect, fig, axes, cax)
 
             if not self._right_handed:
                 ax = self.plots[f].axes
@@ -1195,25 +1213,22 @@
          units are assumed, for example (0.2, 0.3) requests a plot that has an
          x width of 0.2 and a y width of 0.3 in code units.  If units are
          provided the resulting plot axis labels will use the supplied units.
-    axes_unit : A string
-         The name of the unit for the tick labels on the x and y axes.
-         Defaults to None, which automatically picks an appropriate unit.
-         If axes_unit is '1', 'u', or 'unitary', it will not display the
-         units, and only show the axes name.
-    origin : string or length 1, 2, or 3 sequence of strings
+    origin : string or length 1, 2, or 3 sequence of strings or ints/floats
+             and strings.
          The location of the origin of the plot coordinate system.  This is
-         represented by '-' separated string or a tuple of strings.  In the
-         first index the y-location is given by 'lower', 'upper', or 'center'.
-         The second index is the x-location, given as 'left', 'right', or
-         'center'.  Finally, whether the origin is applied in 'domain'
-         space, plot 'window' space or 'native' simulation coordinate system
-         is given. For example, both 'upper-right-domain' and ['upper',
-         'right', 'domain'] place the origin in the upper right hand
-         corner of domain space. If x or y are not given, a value is inferred.
-         For instance, the default location 'center-window' corresponds to
-         the center of the plot window, 'left-domain' corresponds to the
-         lower-left hand corner of the simulation domain, or 'center-domain'
-         for the center of the simulation domain. Further examples:
+         represented by '-' separated string or a tuple of strings or a mixed
+         tuple.  In the first index the y-location is given by 'lower',
+         'upper', or 'center' or a float or int. The second index is the
+         x-location, given as 'left', 'right', or 'center' or a float or int.
+         Finally, the whether the origin is applied in 'domain' space, plot
+         'window' space or 'native' simulation coordinate system is given.
+         For example, both 'upper-right-domain' and ['upper', 'right',
+         'domain'] place the origin in the upper right hand corner of domain
+         space. If x or y are not given, a value is inferred. For instance,
+         'left-domain' corresponds to the lower-left hand corner of the
+         simulation domain, 'center-domain' corresponds to the center
+         of the simulation domain, or 'center-window' for the center of the
+         plot window. Further examples:
 
          ==================================     ============================
          format                                 example
@@ -1226,7 +1241,13 @@
          ('{xloc}', '{space}')                  ('right', 'domain')
          ('{yloc}', '{space}')                  ('lower', 'window')
          ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
+         (xloc, yloc, coord_sys)                (0.5, 0.5, 'domain')
          ==================================     ============================
+    axes_unit : A string
+         The name of the unit for the tick labels on the x and y axes.
+         Defaults to None, which automatically picks an appropriate unit.
+         If axes_unit is '1', 'u', or 'unitary', it will not display the
+         units, and only show the axes name.
     right_handed : boolean
          Whether the implicit east vector for the image generated is set to make a right
          handed coordinate system with a normal vector, the direction of the
@@ -1340,18 +1361,20 @@
          Defaults to None, which automatically picks an appropriate unit.
          If axes_unit is '1', 'u', or 'unitary', it will not display the
          units, and only show the axes name.
-    origin : string or length 1, 2, or 3 sequence of strings
+    origin : string or length 1, 2, or 3 sequence of strings or ints/floats
+             and strings.
          The location of the origin of the plot coordinate system.  This is
-         represented by '-' separated string or a tuple of strings.  In the
-         first index the y-location is given by 'lower', 'upper', or 'center'.
-         The second index is the x-location, given as 'left', 'right', or
-         'center'.  Finally, whether the origin is applied in 'domain'
-         space, plot 'window' space or 'native' simulation coordinate system
-         is given. For example, both 'upper-right-domain' and ['upper',
-         'right', 'domain'] place the origin in the upper right hand
-         corner of domain space. If x or y are not given, a value is inferred.
-         For instance, 'left-domain' corresponds to the lower-left hand corner
-         of the simulation domain, 'center-domain' corresponds to the center
+         represented by '-' separated string or a tuple of strings or a mixed
+         tuple.  In the first index the y-location is given by 'lower',
+         'upper', or 'center' or a float or int. The second index is the
+         x-location, given as 'left', 'right', or 'center' or a float or int.
+         Finally, the whether the origin is applied in 'domain' space, plot
+         'window' space or 'native' simulation coordinate system is given.
+         For example, both 'upper-right-domain' and ['upper', 'right',
+         'domain'] place the origin in the upper right hand corner of domain
+         space. If x or y are not given, a value is inferred. For instance,
+         'left-domain' corresponds to the lower-left hand corner of the
+         simulation domain, 'center-domain' corresponds to the center
          of the simulation domain, or 'center-window' for the center of the
          plot window. Further examples:
 
@@ -1366,6 +1389,7 @@
          ('{xloc}', '{space}')                  ('right', 'domain')
          ('{yloc}', '{space}')                  ('lower', 'window')
          ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
+         (xloc, yloc, coord_sys)                (0.5, 0.5, 'domain')
          ==================================     ============================
     right_handed : boolean
          Whether the implicit east vector for the image generated is set to make a right
@@ -1840,22 +1864,22 @@
          Defaults to None, which automatically picks an appropriate unit.
          If axes_unit is '1', 'u', or 'unitary', it will not display the
          units, and only show the axes name.
-    origin : string or length 1, 2, or 3 sequence of strings
-         The location of the origin of the plot coordinate system for
-         `AxisAlignedSlicePlot` objects; for `OffAxisSlicePlot` objects,
-         this parameter is discarded.  This is represented by '-' separated
-         string or a tuple of strings.  In the first index the y-location is
-         given by 'lower', 'upper', or 'center'.  The second index is the
-         x-location, given as 'left', 'right', or 'center'.  Finally,
-         whether the origin is applied in 'domain' space, plot 'window' space
-         or 'native' simulation coordinate system is given. For example, both
-         'upper-right-domain' and ['upper', 'right', 'domain'] place the
-         origin in the upper right hand corner of domain space. If x or y are
-         not given, a value is inferred.  For instance, 'left-domain'
-         corresponds to the lower-left hand corner of the simulation domain,
-         'center-domain' corresponds to the center of the simulation domain,
-         or 'center-window' for the center of the plot window. Further
-         examples:
+    origin : string or length 1, 2, or 3 sequence of strings or ints/floats
+             and strings.
+         The location of the origin of the plot coordinate system.  This is
+         represented by '-' separated string or a tuple of strings or a mixed
+         tuple.  In the first index the y-location is given by 'lower',
+         'upper', or 'center' or a float or int. The second index is the
+         x-location, given as 'left', 'right', or 'center' or a float or int.
+         Finally, the whether the origin is applied in 'domain' space, plot
+         'window' space or 'native' simulation coordinate system is given.
+         For example, both 'upper-right-domain' and ['upper', 'right',
+         'domain'] place the origin in the upper right hand corner of domain
+         space. If x or y are not given, a value is inferred. For instance,
+         'left-domain' corresponds to the lower-left hand corner of the
+         simulation domain, 'center-domain' corresponds to the center
+         of the simulation domain, or 'center-window' for the center of the
+         plot window. Further examples:
 
          ==================================     ============================
          format                                 example
@@ -1868,6 +1892,7 @@
          ('{xloc}', '{space}')                  ('right', 'domain')
          ('{yloc}', '{space}')                  ('lower', 'window')
          ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
+         (xloc, yloc, coord_sys)                (0.5, 0.5, 'domain')
          ==================================     ============================
     north_vector : a sequence of floats
         A vector defining the 'up' direction in the `OffAxisSlicePlot`; not


https://bitbucket.org/yt_analysis/yt/commits/d0fbd865c310/
Changeset:   d0fbd865c310
Branch:      yt
User:        a_gilbert
Date:        2016-08-14 15:56:28+00:00
Summary:     Updating from comment suggestions.
Affected #:  1 file

diff -r 053e35273f81771c2075d9ea012024b72af679bc -r d0fbd865c310c1e7ed3fc5c77925d0d2c8e1b4a9 yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -665,7 +665,7 @@
             origin = (o0map[origin[0]],) + origin
         elif 2 == len(origin) and origin[0] in set(['lower','upper','center']):
             origin = (origin[0], 'center', origin[-1])
-        elif 2 == len(origin) and type(origin[0]) in set([int, float]):
+        elif 3 == len(origin) and isinstance(origin[0], (int, float)):
             xc = origin[0]
             yc = origin[1]
         assert origin[-1] in ['window', 'domain', 'native']


https://bitbucket.org/yt_analysis/yt/commits/bc35afa585d4/
Changeset:   bc35afa585d4
Branch:      yt
User:        a_gilbert
Date:        2016-08-14 17:38:12+00:00
Summary:     Fixing sloppy errors.
Affected #:  1 file

diff -r d0fbd865c310c1e7ed3fc5c77925d0d2c8e1b4a9 -r bc35afa585d4cb0bffa5d85452efb074280ffa97 yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -825,12 +825,12 @@
                 ia = ImageArray(ia)
             else:
                 ia = image
-                self.plots[f] = WindowPlotMPL(
-                    ia, self._field_transform[f].name,
-                    self._field_transform[f].func,
-                    self._colormaps[f], extent, zlim,
-                    self.figure_size, font_size,
-                    self.aspect, fig, axes, cax)
+            self.plots[f] = WindowPlotMPL(
+                ia, self._field_transform[f].name,
+                self._field_transform[f].func,
+                self._colormaps[f], extent, zlim,
+                self.figure_size, font_size,
+                self.aspect, fig, axes, cax)
 
             if not self._right_handed:
                 ax = self.plots[f].axes


https://bitbucket.org/yt_analysis/yt/commits/d7a290297082/
Changeset:   d7a290297082
Branch:      yt
User:        a_gilbert
Date:        2016-08-16 18:41:12+00:00
Summary:     Updated docs to originals with extra note for new valid input format
Affected #:  1 file

diff -r bc35afa585d4cb0bffa5d85452efb074280ffa97 -r d7a2902970829d2b2085a0f976a5b571bb7216fb yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -396,36 +396,37 @@
 
         Parameters
         ----------
-        origin : string or length 1, 2, or 3 sequence of strings or ints/floats
-                 and strings.
-            The location of the origin of the plot coordinate system.  This is
-            represented by '-' separated string or a tuple of strings or a mixed
-            tuple.  In the first index the y-location is given by 'lower',
-            'upper', or 'center' or a float or int. The second index is the
-            x-location, given as 'left', 'right', or 'center' or a float or int.
-            Finally, the whether the origin is applied in 'domain' space, plot
-            'window' space or 'native' simulation coordinate system is given.
-            For example, both 'upper-right-domain' and ['upper', 'right',
-            'domain'] place the origin in the upper right hand corner of domain
-            space. If x or y are not given, a value is inferred. For instance,
-            'left-domain' corresponds to the lower-left hand corner of the
-            simulation domain, 'center-domain' corresponds to the center
-            of the simulation domain, or 'center-window' for the center of the
-            plot window. Further examples:
+        origin : string or length 1, 2, or 3 sequence of strings.
+             The location of the origin of the plot coordinate system. This
+            is typically represented by a '-' separated string or a tuple of
+            strings. In the first index the y-location is given by 'lower',
+            'upper', or 'center'. The second index is the x-location, given as
+            'left', 'right', or 'center'. Finally, the whether the origin is
+            applied in 'domain' space, plot 'window' space or 'native'
+            simulation coordinate system is given. For example, both
+            'upper-right-domain' and ['upper', 'right', 'domain'] place the
+            origin in the upper right hand corner of domain space. If x or y
+            are not given, a value is inferred. For instance, 'left-domain'
+            corresponds to the lower-left hand corner of the simulation domain,
+            'center-domain' corresponds to the center of the simulation domain,
+            or 'center-window' for the center of the plot window. In the event
+            that none of these options place the origin in a desired location,
+            a sequence of two numeric types and a string specifying the
+            coordinate space can be given.Further examples:
 
-            ==================================     ============================
-            format                                 example
-            ==================================     ============================
-            '{space}'                              'domain'
-            '{xloc}-{space}'                       'left-window'
-            '{yloc}-{space}'                       'upper-domain'
-            '{yloc}-{xloc}-{space}'                'lower-right-window'
-            ('{space}',)                           ('window',)
-            ('{xloc}', '{space}')                  ('right', 'domain')
-            ('{yloc}', '{space}')                  ('lower', 'window')
-            ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
-            (xloc, yloc, coord_sys)                (0.5, 0.5, 'domain')
-            ==================================     ============================
+         ==================================     ============================
+         format                                 example
+         ==================================     ============================
+         '{space}'                              'domain'
+         '{xloc}-{space}'                       'left-window'
+         '{yloc}-{space}'                       'upper-domain'
+         '{yloc}-{xloc}-{space}'                'lower-right-window'
+         ('{space}',)                           ('window',)
+         ('{xloc}', '{space}')                  ('right', 'domain')
+         ('{yloc}', '{space}')                  ('lower', 'window')
+         ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
+         (xloc, yloc, coord_sys)                (0.23, 0.5, 'domain')
+         ==================================     ============================
 
         """
         self.origin = origin
@@ -1213,22 +1214,23 @@
          units are assumed, for example (0.2, 0.3) requests a plot that has an
          x width of 0.2 and a y width of 0.3 in code units.  If units are
          provided the resulting plot axis labels will use the supplied units.
-    origin : string or length 1, 2, or 3 sequence of strings or ints/floats
-             and strings.
-         The location of the origin of the plot coordinate system.  This is
-         represented by '-' separated string or a tuple of strings or a mixed
-         tuple.  In the first index the y-location is given by 'lower',
-         'upper', or 'center' or a float or int. The second index is the
-         x-location, given as 'left', 'right', or 'center' or a float or int.
-         Finally, the whether the origin is applied in 'domain' space, plot
-         'window' space or 'native' simulation coordinate system is given.
-         For example, both 'upper-right-domain' and ['upper', 'right',
-         'domain'] place the origin in the upper right hand corner of domain
-         space. If x or y are not given, a value is inferred. For instance,
-         'left-domain' corresponds to the lower-left hand corner of the
-         simulation domain, 'center-domain' corresponds to the center
-         of the simulation domain, or 'center-window' for the center of the
-         plot window. Further examples:
+    origin : string or length 1, 2, or 3 sequence of strings.
+         The location of the origin of the plot coordinate system. This 
+         is typically represented by a '-' separated string or a tuple of 
+         strings. In the first index the y-location is given by 'lower', 
+         'upper', or 'center'. The second index is the x-location, given as 
+         'left', 'right', or 'center'. Finally, the whether the origin is 
+         applied in 'domain' space, plot 'window' space or 'native'
+         simulation coordinate system is given. For example, both
+         'upper-right-domain' and ['upper', 'right', 'domain'] place the origin
+         in the upper right hand corner of domain space. If x or y are not given,
+         a value is inferred. For instance, 'left-domain' corresponds to the
+         lower-left hand corner of the simulation domain, 'center-domain'
+         corresponds to the center of the simulation domain, or 'center-window'
+         for the center of the plot window. In the event that none of these
+         options place the origin in a desired location, a sequence of two
+         numeric types and a string specifying the coordinate space can be 
+         given.Further examples:
 
          ==================================     ============================
          format                                 example
@@ -1241,7 +1243,7 @@
          ('{xloc}', '{space}')                  ('right', 'domain')
          ('{yloc}', '{space}')                  ('lower', 'window')
          ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
-         (xloc, yloc, coord_sys)                (0.5, 0.5, 'domain')
+         (xloc, yloc, coord_sys)                (0.23, 0.5, 'domain')
          ==================================     ============================
     axes_unit : A string
          The name of the unit for the tick labels on the x and y axes.
@@ -1361,22 +1363,23 @@
          Defaults to None, which automatically picks an appropriate unit.
          If axes_unit is '1', 'u', or 'unitary', it will not display the
          units, and only show the axes name.
-    origin : string or length 1, 2, or 3 sequence of strings or ints/floats
-             and strings.
-         The location of the origin of the plot coordinate system.  This is
-         represented by '-' separated string or a tuple of strings or a mixed
-         tuple.  In the first index the y-location is given by 'lower',
-         'upper', or 'center' or a float or int. The second index is the
-         x-location, given as 'left', 'right', or 'center' or a float or int.
-         Finally, the whether the origin is applied in 'domain' space, plot
-         'window' space or 'native' simulation coordinate system is given.
-         For example, both 'upper-right-domain' and ['upper', 'right',
-         'domain'] place the origin in the upper right hand corner of domain
-         space. If x or y are not given, a value is inferred. For instance,
-         'left-domain' corresponds to the lower-left hand corner of the
-         simulation domain, 'center-domain' corresponds to the center
-         of the simulation domain, or 'center-window' for the center of the
-         plot window. Further examples:
+    origin : string or length 1, 2, or 3 sequence of strings.
+         The location of the origin of the plot coordinate system. This 
+         is typically represented by a '-' separated string or a tuple of 
+         strings. In the first index the y-location is given by 'lower', 
+         'upper', or 'center'. The second index is the x-location, given as 
+         'left', 'right', or 'center'. Finally, the whether the origin is 
+         applied in 'domain' space, plot 'window' space or 'native'
+         simulation coordinate system is given. For example, both
+         'upper-right-domain' and ['upper', 'right', 'domain'] place the origin
+         in the upper right hand corner of domain space. If x or y are not given,
+         a value is inferred. For instance, 'left-domain' corresponds to the
+         lower-left hand corner of the simulation domain, 'center-domain'
+         corresponds to the center of the simulation domain, or 'center-window'
+         for the center of the plot window. In the event that none of these
+         options place the origin in a desired location, a sequence of two
+         numeric types and a string specifying the coordinate space can be 
+         given.Further examples:
 
          ==================================     ============================
          format                                 example
@@ -1389,7 +1392,7 @@
          ('{xloc}', '{space}')                  ('right', 'domain')
          ('{yloc}', '{space}')                  ('lower', 'window')
          ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
-         (xloc, yloc, coord_sys)                (0.5, 0.5, 'domain')
+         (xloc, yloc, coord_sys)                (0.23, 0.5, 'domain')
          ==================================     ============================
     right_handed : boolean
          Whether the implicit east vector for the image generated is set to make a right
@@ -1864,22 +1867,24 @@
          Defaults to None, which automatically picks an appropriate unit.
          If axes_unit is '1', 'u', or 'unitary', it will not display the
          units, and only show the axes name.
-    origin : string or length 1, 2, or 3 sequence of strings or ints/floats
-             and strings.
-         The location of the origin of the plot coordinate system.  This is
-         represented by '-' separated string or a tuple of strings or a mixed
-         tuple.  In the first index the y-location is given by 'lower',
-         'upper', or 'center' or a float or int. The second index is the
-         x-location, given as 'left', 'right', or 'center' or a float or int.
-         Finally, the whether the origin is applied in 'domain' space, plot
-         'window' space or 'native' simulation coordinate system is given.
-         For example, both 'upper-right-domain' and ['upper', 'right',
-         'domain'] place the origin in the upper right hand corner of domain
-         space. If x or y are not given, a value is inferred. For instance,
-         'left-domain' corresponds to the lower-left hand corner of the
-         simulation domain, 'center-domain' corresponds to the center
-         of the simulation domain, or 'center-window' for the center of the
-         plot window. Further examples:
+    origin : string or length 1, 2, or 3 sequence of strings.
+         The location of the origin of the plot coordinate system for
+         `AxisAlignedSlicePlot` objects; for `OffAxisSlicePlot` objects this
+         parameter is discarded. This is typically represented by a '-' separated
+         string or a tuple of strings. In the first index the y-location
+         is given by 'lower', 'upper', or 'center'. The second index is the
+         x-location, given as 'left', 'right', or 'center'. Finally, the whether
+         the origin is applied in 'domain' space, plot 'window' space or 'native'
+         simulation coordinate system is given. For example, both
+         'upper-right-domain' and ['upper', 'right', 'domain'] place the origin
+         in the upper right hand corner of domain space. If x or y are not given,
+         a value is inferred. For instance, 'left-domain' corresponds to the
+         lower-left hand corner of the simulation domain, 'center-domain'
+         corresponds to the center of the simulation domain, or 'center-window'
+         for the center of the plot window. In the event that none of these
+         options place the origin in a desired location, a sequence of two
+         numeric types and a string specifying the coordinate space can be given.
+         Further examples:
 
          ==================================     ============================
          format                                 example
@@ -1892,7 +1897,7 @@
          ('{xloc}', '{space}')                  ('right', 'domain')
          ('{yloc}', '{space}')                  ('lower', 'window')
          ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
-         (xloc, yloc, coord_sys)                (0.5, 0.5, 'domain')
+         (xloc, yloc, coord_sys)                (0.23, 0.5, 'domain')
          ==================================     ============================
     north_vector : a sequence of floats
         A vector defining the 'up' direction in the `OffAxisSlicePlot`; not


https://bitbucket.org/yt_analysis/yt/commits/6bff2e984ee3/
Changeset:   6bff2e984ee3
Branch:      yt
User:        a_gilbert
Date:        2016-08-16 22:05:38+00:00
Summary:     Updated docs, added a test for origin parameters.
Affected #:  2 files

diff -r d7a2902970829d2b2085a0f976a5b571bb7216fb -r 6bff2e984ee33d88b567ae6e03364d4c5093e012 yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -425,7 +425,7 @@
          ('{xloc}', '{space}')                  ('right', 'domain')
          ('{yloc}', '{space}')                  ('lower', 'window')
          ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
-         (xloc, yloc, coord_sys)                (0.23, 0.5, 'domain')
+         (xloc, yloc, '{space}')                (0.23, 0.5, 'domain')
          ==================================     ============================
 
         """
@@ -1215,11 +1215,11 @@
          x width of 0.2 and a y width of 0.3 in code units.  If units are
          provided the resulting plot axis labels will use the supplied units.
     origin : string or length 1, 2, or 3 sequence of strings.
-         The location of the origin of the plot coordinate system. This 
-         is typically represented by a '-' separated string or a tuple of 
-         strings. In the first index the y-location is given by 'lower', 
-         'upper', or 'center'. The second index is the x-location, given as 
-         'left', 'right', or 'center'. Finally, the whether the origin is 
+         The location of the origin of the plot coordinate system. This
+         is typically represented by a '-' separated string or a tuple of
+         strings. In the first index the y-location is given by 'lower',
+         'upper', or 'center'. The second index is the x-location, given as
+         'left', 'right', or 'center'. Finally, the whether the origin is
          applied in 'domain' space, plot 'window' space or 'native'
          simulation coordinate system is given. For example, both
          'upper-right-domain' and ['upper', 'right', 'domain'] place the origin
@@ -1229,7 +1229,7 @@
          corresponds to the center of the simulation domain, or 'center-window'
          for the center of the plot window. In the event that none of these
          options place the origin in a desired location, a sequence of two
-         numeric types and a string specifying the coordinate space can be 
+         numeric types and a string specifying the coordinate space can be
          given.Further examples:
 
          ==================================     ============================
@@ -1243,7 +1243,7 @@
          ('{xloc}', '{space}')                  ('right', 'domain')
          ('{yloc}', '{space}')                  ('lower', 'window')
          ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
-         (xloc, yloc, coord_sys)                (0.23, 0.5, 'domain')
+         (xloc, yloc, '{space}')                (0.23, 0.5, 'domain')
          ==================================     ============================
     axes_unit : A string
          The name of the unit for the tick labels on the x and y axes.
@@ -1364,11 +1364,11 @@
          If axes_unit is '1', 'u', or 'unitary', it will not display the
          units, and only show the axes name.
     origin : string or length 1, 2, or 3 sequence of strings.
-         The location of the origin of the plot coordinate system. This 
-         is typically represented by a '-' separated string or a tuple of 
-         strings. In the first index the y-location is given by 'lower', 
-         'upper', or 'center'. The second index is the x-location, given as 
-         'left', 'right', or 'center'. Finally, the whether the origin is 
+         The location of the origin of the plot coordinate system. This
+         is typically represented by a '-' separated string or a tuple of
+         strings. In the first index the y-location is given by 'lower',
+         'upper', or 'center'. The second index is the x-location, given as
+         'left', 'right', or 'center'. Finally, the whether the origin is
          applied in 'domain' space, plot 'window' space or 'native'
          simulation coordinate system is given. For example, both
          'upper-right-domain' and ['upper', 'right', 'domain'] place the origin
@@ -1378,7 +1378,7 @@
          corresponds to the center of the simulation domain, or 'center-window'
          for the center of the plot window. In the event that none of these
          options place the origin in a desired location, a sequence of two
-         numeric types and a string specifying the coordinate space can be 
+         numeric types and a string specifying the coordinate space can be
          given.Further examples:
 
          ==================================     ============================
@@ -1392,7 +1392,7 @@
          ('{xloc}', '{space}')                  ('right', 'domain')
          ('{yloc}', '{space}')                  ('lower', 'window')
          ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
-         (xloc, yloc, coord_sys)                (0.23, 0.5, 'domain')
+         (xloc, yloc, '{space}')                (0.23, 0.5, 'domain')
          ==================================     ============================
     right_handed : boolean
          Whether the implicit east vector for the image generated is set to make a right
@@ -1418,13 +1418,13 @@
 
          "mip" : pick out the maximum value of the field in the line of sight.
 
-         "sum" : This method is the same as integrate, except that it does not 
-         multiply by a path length when performing the integration, and is 
+         "sum" : This method is the same as integrate, except that it does not
+         multiply by a path length when performing the integration, and is
          just a straight summation of the field along the given axis. WARNING:
          This should only be used for uniform resolution grid datasets, as other
          datasets may result in unphysical images.
     proj_style : string
-         The method of projection--same as method keyword.  Deprecated as of 
+         The method of projection--same as method keyword.  Deprecated as of
          version 3.0.2.  Please use method instead.
     window_size : float
          The size of the window in inches. Set to 8 by default.
@@ -1897,7 +1897,7 @@
          ('{xloc}', '{space}')                  ('right', 'domain')
          ('{yloc}', '{space}')                  ('lower', 'window')
          ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
-         (xloc, yloc, coord_sys)                (0.23, 0.5, 'domain')
+         (xloc, yloc, '{space}')                (0.23, 0.5, 'domain')
          ==================================     ============================
     north_vector : a sequence of floats
         A vector defining the 'up' direction in the `OffAxisSlicePlot`; not

diff -r d7a2902970829d2b2085a0f976a5b571bb7216fb -r 6bff2e984ee33d88b567ae6e03364d4c5093e012 yt/visualization/tests/test_plotwindow.py
--- a/yt/visualization/tests/test_plotwindow.py
+++ b/yt/visualization/tests/test_plotwindow.py
@@ -115,7 +115,6 @@
         ((0, 'code_length'), (1, 'code_length')),
         ((0, 'code_length'), (1, 'code_length')),
         ((1, 'code_length'), (1, 'code_length')),
-        None,
     ),
     0.2 : (
         ((0.4, 'code_length'), (0.6, 'code_length')),
@@ -444,3 +443,28 @@
             assert_raises(
                 YTInvalidFieldType, object, ds, normal, field_name_list)
 
+def test_setup_origin():
+    origin_inputs = ('domain', 'left-window', 'center-domain',
+                     'lower-right-window',
+                     ('window',), ('right', 'domain'), ('lower', 'window'),
+                     ('lower', 'right', 'window'), (0.5, 0.5, 'domain'))
+    w=(10, 'cm')
+
+    ds = fake_random_ds(32, length_unit=100.0)
+    generated_limits = []
+    correct_limits = [[(45.0, 50.0), (45.0, 50.0)],
+                      [(0.0, 10.0), (0.0, 10.0)],
+                      [(-5.0, 5.0), (-5.0, 5.0)],
+                      [(-10.0, 0), (0, 10.0)],
+                      [(0.0, 10.0), (0.0, 10.0)],
+                      [(-55.0, -45.0), (-55.0, -45.0)],
+                      [(-5.0, 5.0), (0.0, 10.0)],
+                      [(-10.0, 0), (0, 10.0)],
+                      [(-5.0, 5.0), (-5.0, 5.0)]
+                      ]
+    for o in origin_inputs:
+        slc = SlicePlot(ds, 2, 'density', width=w, origin=o)
+        ax = slc.plots['density'].axes
+        generated_limits.append([ax.get_xlim(), ax.get_ylim()])
+
+    yield assert_equal, generated_limits, correct_limits


https://bitbucket.org/yt_analysis/yt/commits/15192426c13f/
Changeset:   15192426c13f
Branch:      yt
User:        a_gilbert
Date:        2016-08-16 22:59:16+00:00
Summary:     Updating, accidently removed an argument from WIDTH_SPECS
Affected #:  1 file

diff -r 6bff2e984ee33d88b567ae6e03364d4c5093e012 -r 15192426c13fca9fc50c134e08356d8f79e4def0 yt/visualization/tests/test_plotwindow.py
--- a/yt/visualization/tests/test_plotwindow.py
+++ b/yt/visualization/tests/test_plotwindow.py
@@ -115,6 +115,7 @@
         ((0, 'code_length'), (1, 'code_length')),
         ((0, 'code_length'), (1, 'code_length')),
         ((1, 'code_length'), (1, 'code_length')),
+        None
     ),
     0.2 : (
         ((0.4, 'code_length'), (0.6, 'code_length')),


https://bitbucket.org/yt_analysis/yt/commits/22498343c4ca/
Changeset:   22498343c4ca
Branch:      yt
User:        a_gilbert
Date:        2016-08-16 23:09:55+00:00
Summary:     Debugging.
Affected #:  1 file

diff -r 15192426c13fca9fc50c134e08356d8f79e4def0 -r 22498343c4cab8eda5b12f47f63c3c3fa0e3515b yt/visualization/tests/test_plotwindow.py
--- a/yt/visualization/tests/test_plotwindow.py
+++ b/yt/visualization/tests/test_plotwindow.py
@@ -115,7 +115,7 @@
         ((0, 'code_length'), (1, 'code_length')),
         ((0, 'code_length'), (1, 'code_length')),
         ((1, 'code_length'), (1, 'code_length')),
-        None
+        None,
     ),
     0.2 : (
         ((0.4, 'code_length'), (0.6, 'code_length')),


https://bitbucket.org/yt_analysis/yt/commits/49c57c71b73e/
Changeset:   49c57c71b73e
Branch:      yt
User:        a_gilbert
Date:        2016-08-17 03:02:13+00:00
Summary:     Added capacity for tuple of numeric and string unit specifier. Fixed testing.
Affected #:  2 files

diff -r 22498343c4cab8eda5b12f47f63c3c3fa0e3515b -r 49c57c71b73ee727e34b877f2ca5a8d2cdbbe05e yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -156,7 +156,8 @@
     Parameters
     ----------
 
-    data_source : :class:`yt.data_objects.construction_data_containers.YTQuadTreeProj` or :class:`yt.data_objects.selection_data_containers.YTSlice`
+    data_source : :class:`yt.data_objects.construction_data_containers.YTQuadTreeProj`
+    or :class:`yt.data_objects.selection_data_containers.YTSlice`
         This is the source to be pixelized, which can be a projection or a
         slice.  (For cutting planes, see
         `yt.visualization.fixed_resolution.ObliqueFixedResolutionBuffer`.)
@@ -396,8 +397,8 @@
 
         Parameters
         ----------
-        origin : string or length 1, 2, or 3 sequence of strings.
-             The location of the origin of the plot coordinate system. This
+        origin : string or length 1, 2, or 3 sequence.
+            The location of the origin of the plot coordinate system. This
             is typically represented by a '-' separated string or a tuple of
             strings. In the first index the y-location is given by 'lower',
             'upper', or 'center'. The second index is the x-location, given as
@@ -411,22 +412,24 @@
             'center-domain' corresponds to the center of the simulation domain,
             or 'center-window' for the center of the plot window. In the event
             that none of these options place the origin in a desired location,
-            a sequence of two numeric types and a string specifying the
-            coordinate space can be given.Further examples:
+            a sequence of tuples and a string specifying the
+            coordinate space can be given. If plain numeric types are input,
+            units of `code_length` are assumed. Further examples:
 
-         ==================================     ============================
-         format                                 example
-         ==================================     ============================
-         '{space}'                              'domain'
-         '{xloc}-{space}'                       'left-window'
-         '{yloc}-{space}'                       'upper-domain'
-         '{yloc}-{xloc}-{space}'                'lower-right-window'
-         ('{space}',)                           ('window',)
-         ('{xloc}', '{space}')                  ('right', 'domain')
-         ('{yloc}', '{space}')                  ('lower', 'window')
-         ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
-         (xloc, yloc, '{space}')                (0.23, 0.5, 'domain')
-         ==================================     ============================
+         ==================================                ============================
+         format                                            example
+         ==================================                ============================
+         '{space}'                                          'domain'
+         '{xloc}-{space}'                                   'left-window'
+         '{yloc}-{space}'                                   'upper-domain'
+         '{yloc}-{xloc}-{space}'                            'lower-right-window'
+         ('{space}',)                                       ('window',)
+         ('{xloc}', '{space}')                              ('right', 'domain')
+         ('{yloc}', '{space}')                              ('lower', 'window')
+         ('{yloc}', '{xloc}', '{space}')                    ('lower', 'right', 'window')
+         ((yloc, '{unit}'), (xloc, '{unit}'), '{space}')    ((0.5, 'm'), (0.4, 'm'), 'window')
+         (xloc, yloc, '{space}')                            (0.23, 0.5, 'domain')
+         ==================================                 ============================
 
         """
         self.origin = origin
@@ -667,8 +670,12 @@
         elif 2 == len(origin) and origin[0] in set(['lower','upper','center']):
             origin = (origin[0], 'center', origin[-1])
         elif 3 == len(origin) and isinstance(origin[0], (int, float)):
-            xc = origin[0]
-            yc = origin[1]
+            xc = self.ds.quan(origin[0], 'code_length')
+            yc = self.ds.quan(origin[1], 'code_length')
+        elif 3 == len(origin) and isinstance(origin[0], tuple):
+            xc = YTQuantity(origin[0][0], origin[0][1])
+            xc = YTQuantity(origin[1][0], origin[0][1])
+
         assert origin[-1] in ['window', 'domain', 'native']
 
         if origin[2] == 'window':
@@ -1214,7 +1221,7 @@
          units are assumed, for example (0.2, 0.3) requests a plot that has an
          x width of 0.2 and a y width of 0.3 in code units.  If units are
          provided the resulting plot axis labels will use the supplied units.
-    origin : string or length 1, 2, or 3 sequence of strings.
+    origin : string or length 1, 2, or 3 sequence.
          The location of the origin of the plot coordinate system. This
          is typically represented by a '-' separated string or a tuple of
          strings. In the first index the y-location is given by 'lower',
@@ -1222,29 +1229,31 @@
          'left', 'right', or 'center'. Finally, the whether the origin is
          applied in 'domain' space, plot 'window' space or 'native'
          simulation coordinate system is given. For example, both
-         'upper-right-domain' and ['upper', 'right', 'domain'] place the origin
-         in the upper right hand corner of domain space. If x or y are not given,
-         a value is inferred. For instance, 'left-domain' corresponds to the
-         lower-left hand corner of the simulation domain, 'center-domain'
-         corresponds to the center of the simulation domain, or 'center-window'
-         for the center of the plot window. In the event that none of these
-         options place the origin in a desired location, a sequence of two
-         numeric types and a string specifying the coordinate space can be
-         given.Further examples:
+         'upper-right-domain' and ['upper', 'right', 'domain'] place the
+         origin in the upper right hand corner of domain space. If x or y
+         are not given, a value is inferred. For instance, 'left-domain'
+         corresponds to the lower-left hand corner of the simulation domain,
+         'center-domain' corresponds to the center of the simulation domain,
+         or 'center-window' for the center of the plot window. In the event
+         that none of these options place the origin in a desired location,
+         a sequence of tuples and a string specifying the
+         coordinate space can be given. If plain numeric types are input,
+         units of `code_length` are assumed. Further examples:
 
-         ==================================     ============================
-         format                                 example
-         ==================================     ============================
-         '{space}'                              'domain'
-         '{xloc}-{space}'                       'left-window'
-         '{yloc}-{space}'                       'upper-domain'
-         '{yloc}-{xloc}-{space}'                'lower-right-window'
-         ('{space}',)                           ('window',)
-         ('{xloc}', '{space}')                  ('right', 'domain')
-         ('{yloc}', '{space}')                  ('lower', 'window')
-         ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
-         (xloc, yloc, '{space}')                (0.23, 0.5, 'domain')
-         ==================================     ============================
+         ==================================                ============================
+         format                                            example
+         ==================================                ============================
+         '{space}'                                          'domain'
+         '{xloc}-{space}'                                   'left-window'
+         '{yloc}-{space}'                                   'upper-domain'
+         '{yloc}-{xloc}-{space}'                            'lower-right-window'
+         ('{space}',)                                       ('window',)
+         ('{xloc}', '{space}')                              ('right', 'domain')
+         ('{yloc}', '{space}')                              ('lower', 'window')
+         ('{yloc}', '{xloc}', '{space}')                    ('lower', 'right', 'window')
+         ((yloc, '{unit}'), (xloc, '{unit}'), '{space}')    ((0.5, 'm'), (0.4, 'm'), 'window')
+         (xloc, yloc, '{space}')                            (0.23, 0.5, 'domain')
+         ==================================                 ============================
     axes_unit : A string
          The name of the unit for the tick labels on the x and y axes.
          Defaults to None, which automatically picks an appropriate unit.
@@ -1363,7 +1372,7 @@
          Defaults to None, which automatically picks an appropriate unit.
          If axes_unit is '1', 'u', or 'unitary', it will not display the
          units, and only show the axes name.
-    origin : string or length 1, 2, or 3 sequence of strings.
+    origin : string or length 1, 2, or 3 sequence.
          The location of the origin of the plot coordinate system. This
          is typically represented by a '-' separated string or a tuple of
          strings. In the first index the y-location is given by 'lower',
@@ -1371,29 +1380,32 @@
          'left', 'right', or 'center'. Finally, the whether the origin is
          applied in 'domain' space, plot 'window' space or 'native'
          simulation coordinate system is given. For example, both
-         'upper-right-domain' and ['upper', 'right', 'domain'] place the origin
-         in the upper right hand corner of domain space. If x or y are not given,
-         a value is inferred. For instance, 'left-domain' corresponds to the
-         lower-left hand corner of the simulation domain, 'center-domain'
-         corresponds to the center of the simulation domain, or 'center-window'
-         for the center of the plot window. In the event that none of these
-         options place the origin in a desired location, a sequence of two
-         numeric types and a string specifying the coordinate space can be
-         given.Further examples:
+         'upper-right-domain' and ['upper', 'right', 'domain'] place the
+         origin in the upper right hand corner of domain space. If x or y
+         are not given, a value is inferred. For instance, 'left-domain'
+         corresponds to the lower-left hand corner of the simulation domain,
+         'center-domain' corresponds to the center of the simulation domain,
+         or 'center-window' for the center of the plot window. In the event
+         that none of these options place the origin in a desired location,
+         a sequence of tuples and a string specifying the
+         coordinate space can be given. If plain numeric types are input,
+         units of `code_length` are assumed. Further examples:
 
-         ==================================     ============================
-         format                                 example
-         ==================================     ============================
-         '{space}'                              'domain'
-         '{xloc}-{space}'                       'left-window'
-         '{yloc}-{space}'                       'upper-domain'
-         '{yloc}-{xloc}-{space}'                'lower-right-window'
-         ('{space}',)                           ('window',)
-         ('{xloc}', '{space}')                  ('right', 'domain')
-         ('{yloc}', '{space}')                  ('lower', 'window')
-         ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
-         (xloc, yloc, '{space}')                (0.23, 0.5, 'domain')
-         ==================================     ============================
+         ==================================                ============================
+         format                                            example
+         ==================================                ============================
+         '{space}'                                          'domain'
+         '{xloc}-{space}'                                   'left-window'
+         '{yloc}-{space}'                                   'upper-domain'
+         '{yloc}-{xloc}-{space}'                            'lower-right-window'
+         ('{space}',)                                       ('window',)
+         ('{xloc}', '{space}')                              ('right', 'domain')
+         ('{yloc}', '{space}')                              ('lower', 'window')
+         ('{yloc}', '{xloc}', '{space}')                    ('lower', 'right', 'window')
+         ((yloc, '{unit}'), (xloc, '{unit}'), '{space}')    ((0.5, 'm'), (0.4, 'm'), 'window')
+         (xloc, yloc, '{space}')                            (0.23, 0.5, 'domain')
+         ==================================                 ============================
+
     right_handed : boolean
          Whether the implicit east vector for the image generated is set to make a right
          handed coordinate system with the direction of the
@@ -1867,38 +1879,40 @@
          Defaults to None, which automatically picks an appropriate unit.
          If axes_unit is '1', 'u', or 'unitary', it will not display the
          units, and only show the axes name.
-    origin : string or length 1, 2, or 3 sequence of strings.
+    origin : string or length 1, 2, or 3 sequence.
          The location of the origin of the plot coordinate system for
-         `AxisAlignedSlicePlot` objects; for `OffAxisSlicePlot` objects this
-         parameter is discarded. This is typically represented by a '-' separated
-         string or a tuple of strings. In the first index the y-location
-         is given by 'lower', 'upper', or 'center'. The second index is the
-         x-location, given as 'left', 'right', or 'center'. Finally, the whether
-         the origin is applied in 'domain' space, plot 'window' space or 'native'
-         simulation coordinate system is given. For example, both
-         'upper-right-domain' and ['upper', 'right', 'domain'] place the origin
-         in the upper right hand corner of domain space. If x or y are not given,
-         a value is inferred. For instance, 'left-domain' corresponds to the
-         lower-left hand corner of the simulation domain, 'center-domain'
-         corresponds to the center of the simulation domain, or 'center-window'
-         for the center of the plot window. In the event that none of these
-         options place the origin in a desired location, a sequence of two
-         numeric types and a string specifying the coordinate space can be given.
-         Further examples:
+         `AxisAlignedSlicePlot` object; for `OffAxisSlicePlot` objects this
+         parameter is discarded. This is typically represented by a '-'
+         separated string or a tuple of strings. In the first index the
+         y-location is given by 'lower', 'upper', or 'center'. The second index
+         is the x-location, given as 'left', 'right', or 'center'. Finally, the
+         whether the origin is applied in 'domain' space, plot 'window' space or
+         'native' simulation coordinate system is given. For example, both
+         'upper-right-domain' and ['upper', 'right', 'domain'] place the
+         origin in the upper right hand corner of domain space. If x or y
+         are not given, a value is inferred. For instance, 'left-domain'
+         corresponds to the lower-left hand corner of the simulation domain,
+         'center-domain' corresponds to the center of the simulation domain,
+         or 'center-window' for the center of the plot window. In the event
+         that none of these options place the origin in a desired location,
+         a sequence of tuples and a string specifying the
+         coordinate space can be given. If plain numeric types are input,
+         units of `code_length` are assumed. Further examples:
 
-         ==================================     ============================
-         format                                 example
-         ==================================     ============================
-         '{space}'                              'domain'
-         '{xloc}-{space}'                       'left-window'
-         '{yloc}-{space}'                       'upper-domain'
-         '{yloc}-{xloc}-{space}'                'lower-right-window'
-         ('{space}',)                           ('window',)
-         ('{xloc}', '{space}')                  ('right', 'domain')
-         ('{yloc}', '{space}')                  ('lower', 'window')
-         ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
-         (xloc, yloc, '{space}')                (0.23, 0.5, 'domain')
-         ==================================     ============================
+         ==================================                ============================
+         format                                            example
+         ==================================                ============================
+         '{space}'                                          'domain'
+         '{xloc}-{space}'                                   'left-window'
+         '{yloc}-{space}'                                   'upper-domain'
+         '{yloc}-{xloc}-{space}'                            'lower-right-window'
+         ('{space}',)                                       ('window',)
+         ('{xloc}', '{space}')                              ('right', 'domain')
+         ('{yloc}', '{space}')                              ('lower', 'window')
+         ('{yloc}', '{xloc}', '{space}')                    ('lower', 'right', 'window')
+         ((yloc, '{unit}'), (xloc, '{unit}'), '{space}')    ((0.5, 'm'), (0.4, 'm'), 'window')
+         (xloc, yloc, '{space}')                            (0.23, 0.5, 'domain')
+         ==================================                 ============================
     north_vector : a sequence of floats
         A vector defining the 'up' direction in the `OffAxisSlicePlot`; not
         used in `AxisAlignedSlicePlot`.  This option sets the orientation of the

diff -r 22498343c4cab8eda5b12f47f63c3c3fa0e3515b -r 49c57c71b73ee727e34b877f2ca5a8d2cdbbe05e yt/visualization/tests/test_plotwindow.py
--- a/yt/visualization/tests/test_plotwindow.py
+++ b/yt/visualization/tests/test_plotwindow.py
@@ -448,7 +448,8 @@
     origin_inputs = ('domain', 'left-window', 'center-domain',
                      'lower-right-window',
                      ('window',), ('right', 'domain'), ('lower', 'window'),
-                     ('lower', 'right', 'window'), (0.5, 0.5, 'domain'))
+                     ('lower', 'right', 'window'), (0.5, 0.5, 'domain'),
+                     ((50, 'cm'), (50, 'cm'), 'domain'))
     w=(10, 'cm')
 
     ds = fake_random_ds(32, length_unit=100.0)
@@ -462,10 +463,11 @@
                       [(-5.0, 5.0), (0.0, 10.0)],
                       [(-10.0, 0), (0, 10.0)],
                       [(-5.0, 5.0), (-5.0, 5.0)]
+                      [(-5.0, 5.0), (-5.0, 5.0)]
                       ]
     for o in origin_inputs:
         slc = SlicePlot(ds, 2, 'density', width=w, origin=o)
         ax = slc.plots['density'].axes
         generated_limits.append([ax.get_xlim(), ax.get_ylim()])
 
-    yield assert_equal, generated_limits, correct_limits
+    yield assert_array_almost_equal, correct_limits, generated_limits


https://bitbucket.org/yt_analysis/yt/commits/405474784eb3/
Changeset:   405474784eb3
Branch:      yt
User:        a_gilbert
Date:        2016-08-17 22:01:54+00:00
Summary:     Tests are up and running.
Affected #:  2 files

diff -r 49c57c71b73ee727e34b877f2ca5a8d2cdbbe05e -r 405474784eb337baf3aff2acd48b6acc9cbe9281 yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -674,7 +674,7 @@
             yc = self.ds.quan(origin[1], 'code_length')
         elif 3 == len(origin) and isinstance(origin[0], tuple):
             xc = YTQuantity(origin[0][0], origin[0][1])
-            xc = YTQuantity(origin[1][0], origin[0][1])
+            yc = YTQuantity(origin[1][0], origin[0][1])
 
         assert origin[-1] in ['window', 'domain', 'native']
 
@@ -761,7 +761,6 @@
             if self.aspect is None:
                 self.aspect = float((self.ds.quan(1.0, unit_y) /
                                      self.ds.quan(1.0, unit_x)).in_cgs())
-
             extentx = [(self.xlim[i] - xc).in_units(unit_x) for i in (0, 1)]
             extenty = [(self.ylim[i] - yc).in_units(unit_y) for i in (0, 1)]
 

diff -r 49c57c71b73ee727e34b877f2ca5a8d2cdbbe05e -r 405474784eb337baf3aff2acd48b6acc9cbe9281 yt/visualization/tests/test_plotwindow.py
--- a/yt/visualization/tests/test_plotwindow.py
+++ b/yt/visualization/tests/test_plotwindow.py
@@ -445,29 +445,40 @@
                 YTInvalidFieldType, object, ds, normal, field_name_list)
 
 def test_setup_origin():
-    origin_inputs = ('domain', 'left-window', 'center-domain',
+    origin_inputs = ('domain',
+                     'left-window',
+                     'center-domain',
                      'lower-right-window',
-                     ('window',), ('right', 'domain'), ('lower', 'window'),
-                     ('lower', 'right', 'window'), (0.5, 0.5, 'domain'),
+                     ('window',),
+                     ('right', 'domain'),
+                     ('lower', 'window'),
+                     ('lower', 'right', 'window'),
+                     (0.5, 0.5, 'domain'),
                      ((50, 'cm'), (50, 'cm'), 'domain'))
     w=(10, 'cm')
 
     ds = fake_random_ds(32, length_unit=100.0)
     generated_limits = []
-    correct_limits = [[(45.0, 50.0), (45.0, 50.0)],
-                      [(0.0, 10.0), (0.0, 10.0)],
-                      [(-5.0, 5.0), (-5.0, 5.0)],
-                      [(-10.0, 0), (0, 10.0)],
-                      [(0.0, 10.0), (0.0, 10.0)],
-                      [(-55.0, -45.0), (-55.0, -45.0)],
-                      [(-5.0, 5.0), (0.0, 10.0)],
-                      [(-10.0, 0), (0, 10.0)],
-                      [(-5.0, 5.0), (-5.0, 5.0)]
-                      [(-5.0, 5.0), (-5.0, 5.0)]
+    #lower limit -> llim
+    #upper limit -> ulim
+    #                 xllim xulim yllim yulim
+    correct_limits = [45.0, 55.0, 45.0, 55.0,
+                      0.0, 10.0, 0.0, 10.0,
+                      -5.0, 5.0, -5.0, 5.0,
+                      -10.0, 0, 0, 10.0,
+                      0.0, 10.0, 0.0, 10.0,
+                      -55.0, -45.0, -55.0, -45.0,
+                      -5.0, 5.0, 0.0, 10.0,
+                      -10.0, 0, 0, 10.0,
+                      -5.0, 5.0, -5.0, 5.0,
+                      -5.0, 5.0, -5.0, 5.0
                       ]
     for o in origin_inputs:
         slc = SlicePlot(ds, 2, 'density', width=w, origin=o)
         ax = slc.plots['density'].axes
-        generated_limits.append([ax.get_xlim(), ax.get_ylim()])
-
+        xlims = ax.get_xlim()
+        ylims = ax.get_ylim()
+        lims = [xlims[0], xlims[1], ylims[0], ylims[1]]
+        for l in lims:
+            generated_limits.append(l)
     yield assert_array_almost_equal, correct_limits, generated_limits


https://bitbucket.org/yt_analysis/yt/commits/a3465e29e8f8/
Changeset:   a3465e29e8f8
Branch:      yt
User:        ngoldbaum
Date:        2016-08-25 15:51:00+00:00
Summary:     merging with mainline
Affected #:  56 files

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c .hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -23,6 +23,7 @@
 yt/geometry/particle_smooth.c
 yt/geometry/selection_routines.c
 yt/utilities/amr_utils.c
+yt/utilities/lib/autogenerated_element_samplers.c
 yt/utilities/kdtree/forthonf2c.h
 yt/utilities/libconfig_wrapper.c
 yt/utilities/spatial/ckdtree.c

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c MANIFEST.in
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -3,6 +3,7 @@
 include yt/visualization/mapserver/html/leaflet/*.css
 include yt/visualization/mapserver/html/leaflet/*.js
 include yt/visualization/mapserver/html/leaflet/images/*.png
+include yt/utilities/mesh_types.yaml
 exclude scripts/pr_backport.py
 recursive-include yt *.py *.pyx *.pxd *.h README* *.txt LICENSE* *.cu
 recursive-include doc *.rst *.txt *.py *.ipynb *.png *.jpg *.css *.html

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c doc/install_script.sh
--- a/doc/install_script.sh
+++ b/doc/install_script.sh
@@ -1429,25 +1429,24 @@
         YT_DEPS+=('netcdf4')   
     fi
     
-    # Here is our dependency list for yt
-    log_cmd conda update --yes conda
+    log_cmd ${DEST_DIR}/bin/conda update --yes conda
     
     log_cmd echo "DEPENDENCIES" ${YT_DEPS[@]}
     for YT_DEP in "${YT_DEPS[@]}"; do
         echo "Installing $YT_DEP"
-        log_cmd conda install --yes ${YT_DEP}
+        log_cmd ${DEST_DIR}/bin/conda install --yes ${YT_DEP}
     done
 
     if [ $INST_PY3 -eq 1 ]
     then
         echo "Installing mercurial"
-        log_cmd conda create -y -n py27 python=2.7 mercurial
+        log_cmd ${DEST_DIR}/bin/conda create -y -n py27 python=2.7 mercurial
         log_cmd ln -s ${DEST_DIR}/envs/py27/bin/hg ${DEST_DIR}/bin
     fi
 
-    log_cmd pip install python-hglib
+    log_cmd ${DEST_DIR}/bin/pip install python-hglib
 
-    log_cmd hg clone https://bitbucket.org/yt_analysis/yt_conda ${DEST_DIR}/src/yt_conda
+    log_cmd ${DEST_DIR}/bin/hg clone https://bitbucket.org/yt_analysis/yt_conda ${DEST_DIR}/src/yt_conda
     
     if [ $INST_EMBREE -eq 1 ]
     then
@@ -1474,17 +1473,17 @@
         ( ${GETFILE} "$PYEMBREE_URL" 2>&1 ) 1>> ${LOG_FILE} || do_exit
         log_cmd unzip ${DEST_DIR}/src/master.zip
         pushd ${DEST_DIR}/src/pyembree-master &> /dev/null
-        log_cmd python setup.py install build_ext -I${DEST_DIR}/include -L${DEST_DIR}/lib
+        log_cmd ${DEST_DIR}/bin/${PYTHON_EXEC} setup.py install build_ext -I${DEST_DIR}/include -L${DEST_DIR}/lib
         popd &> /dev/null
     fi
 
     if [ $INST_ROCKSTAR -eq 1 ]
     then
         echo "Building Rockstar"
-        ( hg clone http://bitbucket.org/MatthewTurk/rockstar ${DEST_DIR}/src/rockstar/ 2>&1 ) 1>> ${LOG_FILE}
-        ROCKSTAR_PACKAGE=$(conda build ${DEST_DIR}/src/yt_conda/rockstar --output)
-        log_cmd conda build ${DEST_DIR}/src/yt_conda/rockstar
-        log_cmd conda install $ROCKSTAR_PACKAGE
+        ( ${DEST_DIR}/bin/hg clone http://bitbucket.org/MatthewTurk/rockstar ${DEST_DIR}/src/rockstar/ 2>&1 ) 1>> ${LOG_FILE}
+        ROCKSTAR_PACKAGE=$(${DEST_DIR}/bin/conda build ${DEST_DIR}/src/yt_conda/rockstar --output)
+        log_cmd ${DEST_DIR}/bin/conda build ${DEST_DIR}/src/yt_conda/rockstar
+        log_cmd ${DEST_DIR}/bin/conda install $ROCKSTAR_PACKAGE
         ROCKSTAR_DIR=${DEST_DIR}/src/rockstar
     fi
 
@@ -1493,20 +1492,20 @@
     then
         if [ $INST_PY3 -eq 1 ]
         then
-            log_cmd pip install pyx
+            log_cmd ${DEST_DIR}/bin/pip install pyx
         else
-            log_cmd pip install pyx==0.12.1
+            log_cmd ${DEST_DIR}/bin/pip install pyx==0.12.1
         fi
     fi
 
     if [ $INST_YT_SOURCE -eq 0 ]
     then
         echo "Installing yt"
-        log_cmd conda install -c conda-forge --yes yt
+        log_cmd ${DEST_DIR}/bin/conda install -c conda-forge --yes yt
     else
         echo "Building yt from source"
         YT_DIR="${DEST_DIR}/src/yt-hg"
-        log_cmd hg clone -r ${BRANCH} https://bitbucket.org/yt_analysis/yt ${YT_DIR}
+        log_cmd ${DEST_DIR}/bin/hg clone -r ${BRANCH} https://bitbucket.org/yt_analysis/yt ${YT_DIR}
         if [ $INST_EMBREE -eq 1 ]
         then
             echo $DEST_DIR > ${YT_DIR}/embree.cfg
@@ -1517,7 +1516,7 @@
             ROCKSTAR_LIBRARY_PATH=${DEST_DIR}/lib
         fi
         pushd ${YT_DIR} &> /dev/null
-        ( LIBRARY_PATH=$ROCKSTAR_LIBRARY_PATH python setup.py develop 2>&1) 1>> ${LOG_FILE} || do_exit
+        ( LIBRARY_PATH=$ROCKSTAR_LIBRARY_PATH ${DEST_DIR}/bin/${PYTHON_EXEC} setup.py develop 2>&1) 1>> ${LOG_FILE} || do_exit
         popd &> /dev/null
     fi
 

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c doc/source/analyzing/analysis_modules/absorption_spectrum.rst
--- a/doc/source/analyzing/analysis_modules/absorption_spectrum.rst
+++ b/doc/source/analyzing/analysis_modules/absorption_spectrum.rst
@@ -116,7 +116,12 @@
 Continuum features with optical depths that follow a power law can also be
 added.  Like adding lines, you must specify details like the wavelength
 and the field in the dataset and LightRay that is tied to this feature.
-Below, we will add H Lyman continuum.
+The wavelength refers to the location at which the continuum begins to be 
+applied to the dataset, and as it moves to lower wavelength values, the 
+optical depth value decreases according to the defined power law.  The 
+normalization value is the column density of the linked field which results
+in an optical depth of 1 at the defined wavelength.  Below, we add the hydrogen 
+Lyman continuum.
 
 .. code-block:: python
 
@@ -131,7 +136,7 @@
 Making the Spectrum
 ^^^^^^^^^^^^^^^^^^^
 
-Once all the lines and continuum are added, it is time to make a spectrum out
+Once all the lines and continuua are added, it is time to make a spectrum out
 of some light ray data.
 
 .. code-block:: python

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c setup.py
--- a/setup.py
+++ b/setup.py
@@ -114,6 +114,9 @@
               ["yt/utilities/spatial/ckdtree.pyx"],
               include_dirs=["yt/utilities/lib/"],
               libraries=std_libs),
+    Extension("yt.utilities.lib.autogenerated_element_samplers",
+              ["yt/utilities/lib/autogenerated_element_samplers.pyx"],
+              include_dirs=["yt/utilities/lib/"]),
     Extension("yt.utilities.lib.bitarray",
               ["yt/utilities/lib/bitarray.pyx"],
               libraries=std_libs),
@@ -193,7 +196,7 @@
     "particle_mesh_operations", "depth_first_octree", "fortran_reader",
     "interpolators", "misc_utilities", "basic_octree", "image_utilities",
     "points_in_volume", "quad_tree", "ray_integrators", "mesh_utilities",
-    "amr_kdtools", "lenses",
+    "amr_kdtools", "lenses", "distance_queue"
 ]
 for ext_name in lib_exts:
     cython_extensions.append(

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c tests/tests.yaml
--- a/tests/tests.yaml
+++ b/tests/tests.yaml
@@ -67,11 +67,13 @@
   local_ytdata_000:
     - yt/frontends/ytdata
 
-  local_absorption_spectrum_001:
+  local_absorption_spectrum_004:
     - yt/analysis_modules/absorption_spectrum/tests/test_absorption_spectrum.py:test_absorption_spectrum_non_cosmo
+    - yt/analysis_modules/absorption_spectrum/tests/test_absorption_spectrum.py:test_absorption_spectrum_non_cosmo_novpec
     - yt/analysis_modules/absorption_spectrum/tests/test_absorption_spectrum.py:test_absorption_spectrum_cosmo
     - yt/analysis_modules/absorption_spectrum/tests/test_absorption_spectrum.py:test_absorption_spectrum_non_cosmo_sph
     - yt/analysis_modules/absorption_spectrum/tests/test_absorption_spectrum.py:test_absorption_spectrum_cosmo_sph
+    - yt/analysis_modules/absorption_spectrum/tests/test_absorption_spectrum.py:test_absorption_spectrum_with_continuum
 
   local_axialpix_001:
     - yt/geometry/coordinates/tests/test_axial_pixelization.py:test_axial_pixelization

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/analysis_modules/absorption_spectrum/absorption_spectrum.py
--- a/yt/analysis_modules/absorption_spectrum/absorption_spectrum.py
+++ b/yt/analysis_modules/absorption_spectrum/absorption_spectrum.py
@@ -203,6 +203,13 @@
             input_ds = input_file
         field_data = input_ds.all_data()
 
+        # temperature field required to calculate voigt profile widths
+        if ('temperature' not in input_ds.derived_field_list) and \
+           (('gas', 'temperature') not in input_ds.derived_field_list):
+            raise RuntimeError(
+                "('gas', 'temperature') field required to be present in %s "
+                "for AbsorptionSpectrum to function." % input_file)
+
         self.tau_field = np.zeros(self.lambda_field.size)
         self.absorbers_list = []
 
@@ -210,6 +217,7 @@
             comm = _get_comm(())
             njobs = min(comm.size, len(self.line_list))
 
+        mylog.info("Creating spectrum")
         self._add_lines_to_spectrum(field_data, use_peculiar_velocity,
                                     output_absorbers_file,
                                     subgrid_resolution=subgrid_resolution,
@@ -268,47 +276,96 @@
                 redshift_eff = ((1 + redshift) * \
                                 (1 + field_data['redshift_dopp'])) - 1.
 
+        if not use_peculiar_velocity:
+            redshift_eff = redshift
+
         return redshift, redshift_eff
 
     def _add_continua_to_spectrum(self, field_data, use_peculiar_velocity,
                                   observing_redshift=0.):
         """
-        Add continuum features to the spectrum.
+        Add continuum features to the spectrum.  Continuua are recorded as
+        a name, associated field, wavelength, normalization value, and index.
+        Continuua are applied at and below the denoted wavelength, where the
+        optical depth decreases as a power law of desired index.  For positive 
+        index values, this means optical depth is highest at the denoted 
+        wavelength, and it drops with shorter and shorter wavelengths.  
+        Consequently, transmitted flux undergoes a discontinuous cutoff at the 
+        denoted wavelength, and then slowly increases with decreasing wavelength 
+        according to the power law.
         """
         # Change the redshifts of continuum sources to account for the
         # redshift at which the observer sits
         redshift, redshift_eff = self._apply_observing_redshift(field_data,
                                  use_peculiar_velocity, observing_redshift)
 
-        # Only add continuum features down to tau of 1.e-4.
-        min_tau = 1.e-3
+        # min_tau is the minimum optical depth value that warrants 
+        # accounting for an absorber.  for a single absorber, noticeable 
+        # continuum effects begin for tau = 1e-3 (leading to transmitted 
+        # flux of e^-tau ~ 0.999).  but we apply a cutoff to remove
+        # absorbers with insufficient column_density to contribute 
+        # significantly to a continuum (see below).  because lots of 
+        # low column density absorbers can add up to a significant
+        # continuum effect, we normalize min_tau by the n_absorbers.
+        n_absorbers = field_data['dl'].size
+        min_tau = 1.e-3/n_absorbers
 
         for continuum in self.continuum_list:
-            column_density = field_data[continuum['field_name']] * field_data['dl']
+
+            # Normalization is in cm**-2, so column density must be as well
+            column_density = (field_data[continuum['field_name']] * 
+                              field_data['dl']).in_units('cm**-2')
+            if (column_density == 0).all():
+                mylog.info("Not adding continuum %s: insufficient column density" % continuum['label'])
+                continue
 
             # redshift_eff field combines cosmological and velocity redshifts
             if use_peculiar_velocity:
                 delta_lambda = continuum['wavelength'] * redshift_eff
             else:
                 delta_lambda = continuum['wavelength'] * redshift
+
+            # right index of continuum affected area is wavelength itself
             this_wavelength = delta_lambda + continuum['wavelength']
-            right_index = np.digitize(this_wavelength, self.lambda_field).clip(0, self.n_lambda)
+            right_index = np.digitize(this_wavelength, 
+                                      self.lambda_field).clip(0, self.n_lambda)
+            # left index of continuum affected area wavelength at which 
+            # optical depth reaches tau_min
             left_index = np.digitize((this_wavelength *
-                                     np.power((min_tau * continuum['normalization'] /
-                                               column_density), (1. / continuum['index']))),
-                                    self.lambda_field).clip(0, self.n_lambda)
+                              np.power((min_tau * continuum['normalization'] /
+                                        column_density),
+                                       (1. / continuum['index']))),
+                              self.lambda_field).clip(0, self.n_lambda)
 
+            # Only calculate the effects of continuua where normalized 
+            # column_density is greater than min_tau
+            # because lower column will not have significant contribution
             valid_continuua = np.where(((column_density /
                                          continuum['normalization']) > min_tau) &
                                        (right_index - left_index > 1))[0]
+            if valid_continuua.size == 0:
+                mylog.info("Not adding continuum %s: insufficient column density or out of range" %
+                    continuum['label'])
+                continue
+
             pbar = get_pbar("Adding continuum - %s [%f A]: " % \
                                 (continuum['label'], continuum['wavelength']),
                             valid_continuua.size)
+
+            # Tau value is (wavelength / continuum_wavelength)**index / 
+            #              (column_dens / norm)
+            # i.e. a power law decreasing as wavelength decreases
+
+            # Step through the absorber list and add continuum tau for each to
+            # the total optical depth for all wavelengths
             for i, lixel in enumerate(valid_continuua):
-                line_tau = np.power((self.lambda_field[left_index[lixel]:right_index[lixel]] /
-                                     this_wavelength[lixel]), continuum['index']) * \
-                                     column_density[lixel] / continuum['normalization']
-                self.tau_field[left_index[lixel]:right_index[lixel]] += line_tau
+                cont_tau = \
+                    np.power((self.lambda_field[left_index[lixel] :
+                                                right_index[lixel]] /
+                                   this_wavelength[lixel]), \
+                              continuum['index']) * \
+                    (column_density[lixel] / continuum['normalization'])
+                self.tau_field[left_index[lixel]:right_index[lixel]] += cont_tau
                 pbar.update(i)
             pbar.finish()
 
@@ -333,6 +390,9 @@
         # and deposit the lines into the spectrum
         for line in parallel_objects(self.line_list, njobs=njobs):
             column_density = field_data[line['field_name']] * field_data['dl']
+            if (column_density == 0).all():
+                mylog.info("Not adding line %s: insufficient column density" % line['label'])
+                continue
 
             # redshift_eff field combines cosmological and velocity redshifts
             # so delta_lambda gives the offset in angstroms from the rest frame
@@ -376,7 +436,10 @@
             cdens = column_density.in_units("cm**-2").d # cm**-2
             thermb = thermal_b.in_cgs().d  # thermal b coefficient; cm / s
             dlambda = delta_lambda.d  # lambda offset; angstroms
-            vlos = field_data['velocity_los'].in_units("km/s").d # km/s
+            if use_peculiar_velocity:
+                vlos = field_data['velocity_los'].in_units("km/s").d # km/s
+            else:
+                vlos = np.zeros(field_data['temperature'].size)
 
             # When we actually deposit the voigt profile, sometimes we will
             # have underresolved lines (ie lines with smaller widths than
@@ -413,6 +476,12 @@
             # observed spectrum where it occurs and deposit a voigt profile
             for i in parallel_objects(np.arange(n_absorbers), njobs=-1):
 
+                # if there is a ray element with temperature = 0 or column
+                # density = 0, skip it
+                if (thermal_b[i] == 0.) or (cdens[i] == 0.):
+                    pbar.update(i)
+                    continue
+
                 # the virtual window into which the line is deposited initially
                 # spans a region of 2 coarse spectral bins
                 # (one on each side of the center_index) but the window

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/analysis_modules/absorption_spectrum/tests/test_absorption_spectrum.py
--- a/yt/analysis_modules/absorption_spectrum/tests/test_absorption_spectrum.py
+++ b/yt/analysis_modules/absorption_spectrum/tests/test_absorption_spectrum.py
@@ -33,7 +33,8 @@
 COSMO_PLUS_SINGLE = "enzo_cosmology_plus/RD0009/RD0009"
 GIZMO_PLUS = "gizmo_cosmology_plus/N128L16.param"
 GIZMO_PLUS_SINGLE = "gizmo_cosmology_plus/snap_N128L16_151.hdf5"
-
+ISO_GALAXY = "IsolatedGalaxy/galaxy0030/galaxy0030"
+FIRE = "FIRE_M12i_ref11/snapshot_600.hdf5"
 
 @requires_file(COSMO_PLUS)
 @requires_answer_testing()
@@ -145,6 +146,58 @@
     shutil.rmtree(tmpdir)
 
 @requires_file(COSMO_PLUS_SINGLE)
+ at requires_answer_testing()
+def test_absorption_spectrum_non_cosmo_novpec():
+    """
+    This test generates an absorption spectrum from a simple light ray on a
+    grid dataset
+    """
+
+    # Set up in a temp dir
+    tmpdir = tempfile.mkdtemp()
+    curdir = os.getcwd()
+    os.chdir(tmpdir)
+
+    lr = LightRay(COSMO_PLUS_SINGLE)
+
+    ray_start = [0,0,0]
+    ray_end = [1,1,1]
+    lr.make_light_ray(start_position=ray_start, end_position=ray_end,
+                      fields=['temperature', 'density', 'H_number_density'],
+                      data_filename='lightray.h5', use_peculiar_velocity=False)
+
+    sp = AbsorptionSpectrum(1200.0, 1300.0, 10001)
+
+    my_label = 'HI Lya'
+    field = 'H_number_density'
+    wavelength = 1215.6700  # Angstromss
+    f_value = 4.164E-01
+    gamma = 6.265e+08
+    mass = 1.00794
+
+    sp.add_line(my_label, field, wavelength, f_value,
+                gamma, mass, label_threshold=1.e10)
+
+    wavelength, flux = sp.make_spectrum('lightray.h5',
+                                        output_file='spectrum.h5',
+                                        line_list_file='lines.txt',
+                                        use_peculiar_velocity=False)
+
+    # load just-generated hdf5 file of spectral data (for consistency)
+    data = h5.File('spectrum.h5', 'r')
+
+    for key in data.keys():
+        func = lambda x=key: data[x][:]
+        func.__name__ = "{}_non_cosmo_novpec".format(key)
+        test = GenericArrayTest(None, func)
+        test_absorption_spectrum_non_cosmo_novpec.__name__ = test.description
+        yield test
+
+    # clean up
+    os.chdir(curdir)
+    shutil.rmtree(tmpdir)
+
+ at requires_file(COSMO_PLUS_SINGLE)
 def test_equivalent_width_conserved():
     """
     This tests that the equivalent width of the optical depth is conserved 
@@ -360,3 +413,146 @@
     # clean up
     os.chdir(curdir)
     shutil.rmtree(tmpdir)
+
+ at requires_file(ISO_GALAXY)
+ at requires_answer_testing()
+def test_absorption_spectrum_with_continuum():
+    """
+    This test generates an absorption spectrum from a simple light ray on a
+    grid dataset and adds Lyman alpha and Lyman continuum to it
+    """
+
+    # Set up in a temp dir
+    tmpdir = tempfile.mkdtemp()
+    curdir = os.getcwd()
+    os.chdir(tmpdir)
+
+    ds = load(ISO_GALAXY)
+    lr = LightRay(ds)
+
+    ray_start = ds.domain_left_edge
+    ray_end = ds.domain_right_edge
+    lr.make_light_ray(start_position=ray_start, end_position=ray_end,
+                      fields=['temperature', 'density', 'H_number_density'],
+                      data_filename='lightray.h5')
+
+    sp = AbsorptionSpectrum(800.0, 1300.0, 5001)
+
+    my_label = 'HI Lya'
+    field = 'H_number_density'
+    wavelength = 1215.6700  # Angstromss
+    f_value = 4.164E-01
+    gamma = 6.265e+08
+    mass = 1.00794
+
+    sp.add_line(my_label, field, wavelength, f_value,
+                gamma, mass, label_threshold=1.e10)
+
+    my_label = 'Ly C'
+    field = 'H_number_density'
+    wavelength = 912.323660  # Angstroms
+    normalization = 1.6e17
+    index = 3.0
+
+    sp.add_continuum(my_label, field, wavelength, normalization, index)
+
+    wavelength, flux = sp.make_spectrum('lightray.h5',
+                                        output_file='spectrum.h5',
+                                        line_list_file='lines.txt',
+                                        use_peculiar_velocity=True)
+
+    # load just-generated hdf5 file of spectral data (for consistency)
+    data = h5.File('spectrum.h5', 'r')
+    
+    for key in data.keys():
+        func = lambda x=key: data[x][:]
+        func.__name__ = "{}_continuum".format(key)
+        test = GenericArrayTest(None, func)
+        test_absorption_spectrum_with_continuum.__name__ = test.description
+        yield test
+
+    # clean up
+    os.chdir(curdir)
+    shutil.rmtree(tmpdir)
+
+ at requires_file(FIRE)
+def test_absorption_spectrum_with_zero_field():
+    """
+    This test generates an absorption spectrum with some 
+    particle dataset
+    """
+
+    # Set up in a temp dir
+    tmpdir = tempfile.mkdtemp()
+    curdir = os.getcwd()
+    os.chdir(tmpdir)
+
+    ds = load(FIRE)
+    lr = LightRay(ds)
+
+    # Define species and associated parameters to add to continuum
+    # Parameters used for both adding the transition to the spectrum
+    # and for fitting
+    # Note that for single species that produce multiple lines
+    # (as in the OVI doublet), 'numLines' will be equal to the number
+    # of lines, and f,gamma, and wavelength will have multiple values.
+
+    HI_parameters = {
+        'name': 'HI',
+        'field': 'H_number_density',
+        'f': [.4164],
+        'Gamma': [6.265E8],
+        'wavelength': [1215.67],
+        'mass': 1.00794,
+        'numLines': 1,
+        'maxN': 1E22, 'minN': 1E11,
+        'maxb': 300, 'minb': 1,
+        'maxz': 6, 'minz': 0,
+        'init_b': 30,
+        'init_N': 1E14
+    }
+
+    species_dicts = {'HI': HI_parameters}
+
+
+    # Get all fields that need to be added to the light ray
+    fields = [('gas','temperature')]
+    for s, params in species_dicts.items():
+        fields.append(params['field'])
+
+    # With a single dataset, a start_position and
+    # end_position or trajectory must be given.
+    # Trajectory should be given as (r, theta, phi)
+    lr.make_light_ray(
+        start_position=ds.arr([0., 0., 0.], 'unitary'),
+        end_position=ds.arr([1., 1., 1.], 'unitary'),
+        solution_filename='test_lightraysolution.txt',
+        data_filename='test_lightray.h5',
+        fields=fields)
+    
+    # Create an AbsorptionSpectrum object extending from
+    # lambda = 900 to lambda = 1800, with 10000 pixels
+    sp = AbsorptionSpectrum(900.0, 1400.0, 50000)
+    
+    # Iterate over species
+    for s, params in species_dicts.items():
+        # Iterate over transitions for a single species
+        for i in range(params['numLines']):
+            # Add the lines to the spectrum
+            sp.add_line(
+                s, params['field'],
+                params['wavelength'][i], params['f'][i],
+                params['Gamma'][i], params['mass'],
+                label_threshold=1.e10)
+    
+    
+    # Make and save spectrum
+    wavelength, flux = sp.make_spectrum(
+        'test_lightray.h5',
+        output_file='test_spectrum.h5',
+        line_list_file='test_lines.txt',
+        use_peculiar_velocity=True)
+
+    # clean up
+    os.chdir(curdir)
+    shutil.rmtree(tmpdir)

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/analysis_modules/cosmological_observation/light_ray/light_ray.py
--- a/yt/analysis_modules/cosmological_observation/light_ray/light_ray.py
+++ b/yt/analysis_modules/cosmological_observation/light_ray/light_ray.py
@@ -21,8 +21,6 @@
     load
 from yt.frontends.ytdata.utilities import \
     save_as_dataset
-from yt.units.unit_object import \
-    Unit
 from yt.units.yt_array import \
     YTArray
 from yt.utilities.cosmology import \
@@ -391,7 +389,11 @@
 
         # Initialize data structures.
         self._data = {}
+        # temperature field is automatically added to fields
         if fields is None: fields = []
+        if (('gas', 'temperature') not in fields) and \
+           ('temperature' not in fields):
+           fields.append(('gas', 'temperature'))
         data_fields = fields[:]
         all_fields = fields[:]
         all_fields.extend(['dl', 'dredshift', 'redshift'])
@@ -604,19 +606,18 @@
               self.cosmology.t_from_z(ds["current_redshift"])
         extra_attrs = {"data_type": "yt_light_ray"}
         field_types = dict([(field, "grid") for field in data.keys()])
+
         # Only return LightRay elements with non-zero density
-        mask_field_units = ['K', 'cm**-3', 'g/cm**3']
-        mask_field_units = [Unit(u) for u in mask_field_units]
-        for f in data:
-            for u in mask_field_units:
-                if data[f].units.same_dimensions_as(u):
-                    mask = data[f] > 0
-                    if not np.any(mask):
-                        raise RuntimeError(
-                            "No zones along light ray with nonzero %s. "
-                            "Please modify your light ray trajectory." % (f,))
-                    for key in data.keys():
-                        data[key] = data[key][mask]
+        if 'temperature' in data: f = 'temperature'
+        if ('gas', 'temperature') in data: f = ('gas', 'temperature')
+        if 'temperature' in data or ('gas', 'temperature') in data:
+            mask = data[f] > 0
+            if not np.any(mask):
+                raise RuntimeError(
+                    "No zones along light ray with nonzero %s. "
+                    "Please modify your light ray trajectory." % (f,))
+            for key in data.keys():
+                data[key] = data[key][mask]
         save_as_dataset(ds, filename, data, field_types=field_types,
                         extra_attrs=extra_attrs)
 

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/analysis_modules/particle_trajectories/particle_trajectories.py
--- a/yt/analysis_modules/particle_trajectories/particle_trajectories.py
+++ b/yt/analysis_modules/particle_trajectories/particle_trajectories.py
@@ -11,7 +11,7 @@
 # The full license is in the file COPYING.txt, distributed with this software.
 #-----------------------------------------------------------------------------
 
-from yt.data_objects.data_containers import YTFieldData
+from yt.data_objects.field_data import YTFieldData
 from yt.data_objects.time_series import DatasetSeries
 from yt.utilities.lib.particle_mesh_operations import CICSample_3
 from yt.utilities.parallel_tools.parallel_analysis_interface import \

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/data_objects/construction_data_containers.py
--- a/yt/data_objects/construction_data_containers.py
+++ b/yt/data_objects/construction_data_containers.py
@@ -28,7 +28,8 @@
 from yt.data_objects.data_containers import \
     YTSelectionContainer1D, \
     YTSelectionContainer2D, \
-    YTSelectionContainer3D, \
+    YTSelectionContainer3D
+from yt.data_objects.field_data import \
     YTFieldData
 from yt.funcs import \
     ensure_list, \

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -65,6 +65,8 @@
 from yt.geometry.selection_routines import \
     compose_selector
 from yt.extern.six import add_metaclass, string_types
+from yt.data_objects.field_data import YTFieldData
+from yt.data_objects.profiles import create_profile
 
 data_object_registry = {}
 
@@ -91,12 +93,6 @@
         return tr
     return save_state
 
-class YTFieldData(dict):
-    """
-    A Container object for field data, instead of just having it be a dict.
-    """
-    pass
-
 class RegisteredDataContainer(type):
     def __init__(cls, name, b, d):
         type.__init__(cls, name, b, d)
@@ -813,8 +809,77 @@
         ex = self._compute_extrema(field)
         return ex[1] - ex[0]
 
-    def hist(self, field, weight = None, bins = None):
-        raise NotImplementedError
+    def profile(self, bin_fields, fields, n_bins=64,
+                extrema=None, logs=None, units=None,
+                weight_field="cell_mass",
+                accumulation=False, fractional=False,
+                deposition='ngp'):
+        r"""
+        Create a 1, 2, or 3D profile object from this data_source.
+
+        The dimensionality of the profile object is chosen by the number of
+        fields given in the bin_fields argument.  This simply calls
+        :func:`yt.data_objects.profiles.create_profile`.
+
+        Parameters
+        ----------
+        bin_fields : list of strings
+            List of the binning fields for profiling.
+        fields : list of strings
+            The fields to be profiled.
+        n_bins : int or list of ints
+            The number of bins in each dimension.  If None, 64 bins for
+            each bin are used for each bin field.
+            Default: 64.
+        extrema : dict of min, max tuples
+            Minimum and maximum values of the bin_fields for the profiles.
+            The keys correspond to the field names. Defaults to the extrema
+            of the bin_fields of the dataset. If a units dict is provided, extrema
+            are understood to be in the units specified in the dictionary.
+        logs : dict of boolean values
+            Whether or not to log the bin_fields for the profiles.
+            The keys correspond to the field names. Defaults to the take_log
+            attribute of the field.
+        units : dict of strings
+            The units of the fields in the profiles, including the bin_fields.
+        weight_field : str or tuple field identifier
+            The weight field for computing weighted average for the profile
+            values.  If None, the profile values are sums of the data in
+            each bin.
+        accumulation : bool or list of bools
+            If True, the profile values for a bin n are the cumulative sum of
+            all the values from bin 0 to n.  If -True, the sum is reversed so
+            that the value for bin n is the cumulative sum from bin N (total bins)
+            to n.  If the profile is 2D or 3D, a list of values can be given to
+            control the summation in each dimension independently.
+            Default: False.
+        fractional : If True the profile values are divided by the sum of all
+            the profile data such that the profile represents a probability
+            distribution function.
+        deposition : Controls the type of deposition used for ParticlePhasePlots.
+            Valid choices are 'ngp' and 'cic'. Default is 'ngp'. This parameter is
+            ignored the if the input fields are not of particle type.
+
+
+        Examples
+        --------
+
+        Create a 1d profile.  Access bin field from profile.x and field
+        data from profile[<field_name>].
+
+        >>> ds = load("DD0046/DD0046")
+        >>> ad = ds.all_data()
+        >>> profile = ad.profile(ad, [("gas", "density")],
+        ...                          [("gas", "temperature"),
+        ...                          ("gas", "velocity_x")])
+        >>> print (profile.x)
+        >>> print (profile["gas", "temperature"])
+        >>> plot = profile.plot()
+        """
+        p = create_profile(self, bin_fields, fields, n_bins,
+                   extrema, logs, units, weight_field, accumulation,
+                   fractional, deposition)
+        return p
 
     def mean(self, field, axis=None, weight='ones'):
         r"""Compute the mean of a field, optionally along an axis, with a

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/data_objects/field_data.py
--- /dev/null
+++ b/yt/data_objects/field_data.py
@@ -0,0 +1,20 @@
+"""
+The YTFieldData object.
+
+
+
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (c) 2016, yt Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+
+class YTFieldData(dict):
+    """
+    A Container object for field data, instead of just having it be a dict.
+    """
+    pass

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/data_objects/grid_patch.py
--- a/yt/data_objects/grid_patch.py
+++ b/yt/data_objects/grid_patch.py
@@ -17,8 +17,9 @@
 import numpy as np
 
 from yt.data_objects.data_containers import \
-    YTFieldData, \
     YTSelectionContainer
+from yt.data_objects.field_data import \
+    YTFieldData
 from yt.geometry.selection_routines import convert_mask_to_indices
 import yt.geometry.particle_deposit as particle_deposit
 from yt.utilities.exceptions import \

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/data_objects/octree_subset.py
--- a/yt/data_objects/octree_subset.py
+++ b/yt/data_objects/octree_subset.py
@@ -17,8 +17,9 @@
 import numpy as np
 
 from yt.data_objects.data_containers import \
-    YTFieldData, \
     YTSelectionContainer
+from yt.data_objects.field_data import \
+    YTFieldData
 import yt.geometry.particle_deposit as particle_deposit
 import yt.geometry.particle_smooth as particle_smooth
 

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/data_objects/particle_io.py
--- a/yt/data_objects/particle_io.py
+++ b/yt/data_objects/particle_io.py
@@ -21,11 +21,12 @@
     ensure_list, \
     mylog
 from yt.extern.six import add_metaclass
+from yt.data_objects.field_data import \
+    YTFieldData
 
 particle_handler_registry = defaultdict()
 
 def particle_converter(func):
-    from .data_containers import YTFieldData
     def save_state(grid):
         old_params = grid.field_parameters
         old_keys = grid.field_data.keys()

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/data_objects/profiles.py
--- a/yt/data_objects/profiles.py
+++ b/yt/data_objects/profiles.py
@@ -26,7 +26,9 @@
     array_like_field, \
     YTQuantity
 from yt.units.unit_object import Unit
-from yt.data_objects.data_containers import YTFieldData
+from yt.data_objects.field_data import YTFieldData
+from yt.utilities.exceptions import \
+    YTIllDefinedProfile
 from yt.utilities.lib.misc_utilities import \
     new_bin_profile1d, \
     new_bin_profile2d, \
@@ -453,6 +455,14 @@
     def bounds(self):
         return ((self.x_bins[0], self.x_bins[-1]),)
 
+    def plot(self):
+        r"""
+        This returns a :class:~yt.visualization.profile_plotter.ProfilePlot
+        with the fields that have been added to this object.
+        """
+        from yt.visualization.profile_plotter import ProfilePlot
+        return ProfilePlot.from_profiles(self)
+
 class Profile1DFromDataset(ProfileNDFromDataset, Profile1D):
     """
     A 1D profile object loaded from a ytdata dataset.
@@ -572,6 +582,14 @@
         return ((self.x_bins[0], self.x_bins[-1]),
                 (self.y_bins[0], self.y_bins[-1]))
 
+    def plot(self):
+        r"""
+        This returns a :class:~yt.visualization.profile_plotter.PhasePlot with
+        the fields that have been added to this object.
+        """
+        from yt.visualization.profile_plotter import PhasePlot
+        return PhasePlot.from_profile(self)
+
 class Profile2DFromDataset(ProfileNDFromDataset, Profile2D):
     """
     A 2D profile object loaded from a ytdata dataset.
@@ -928,7 +946,7 @@
     data from profile[<field_name>].
 
     >>> ds = load("DD0046/DD0046")
-    >>> ad = ds.h.all_data()
+    >>> ad = ds.all_data()
     >>> profile = create_profile(ad, [("gas", "density")],
     ...                              [("gas", "temperature"),
     ...                               ("gas", "velocity_x")])
@@ -940,10 +958,18 @@
     fields = ensure_list(fields)
     is_pfield = [data_source.ds._get_field_info(f).particle_type
                  for f in bin_fields + fields]
+    wf = None
+    if weight_field is not None:
+        wf = data_source.ds._get_field_info(weight_field)
+        is_pfield.append(wf.particle_type)
+        wf = wf.name
 
-    if len(bin_fields) == 1:
+    if any(is_pfield) and not all(is_pfield):
+        raise YTIllDefinedProfile(
+            bin_fields, data_source._determine_fields(fields), wf, is_pfield)
+    elif len(bin_fields) == 1:
         cls = Profile1D
-    elif len(bin_fields) == 2 and np.all(is_pfield):
+    elif len(bin_fields) == 2 and all(is_pfield):
         # log bin_fields set to False for Particle Profiles.
         # doesn't make much sense for CIC deposition.
         # accumulation and fractional set to False as well.

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/data_objects/static_output.py
--- a/yt/data_objects/static_output.py
+++ b/yt/data_objects/static_output.py
@@ -889,10 +889,12 @@
         return new_unit
 
     def set_code_units(self):
-        self._set_code_unit_attributes()
         # here we override units, if overrides have been provided.
         self._override_code_units()
 
+        # set attributes like ds.length_unit
+        self._set_code_unit_attributes()
+
         self.unit_registry.modify("code_length", self.length_unit)
         self.unit_registry.modify("code_mass", self.mass_unit)
         self.unit_registry.modify("code_time", self.time_unit)
@@ -932,19 +934,22 @@
     def _override_code_units(self):
         if len(self.units_override) == 0:
             return
-        mylog.warning("Overriding code units. This is an experimental and potentially "+
-                      "dangerous option that may yield inconsistent results, and must be used "+
-                      "very carefully, and only if you know what you want from it.")
+        mylog.warning(
+            "Overriding code units. This is an experimental and potentially "
+            "dangerous option that may yield inconsistent results, and must be "
+            "used very carefully, and only if you know what you want from it.")
         for unit, cgs in [("length", "cm"), ("time", "s"), ("mass", "g"),
-                          ("velocity","cm/s"), ("magnetic","gauss"), ("temperature","K")]:
+                          ("velocity","cm/s"), ("magnetic","gauss"), 
+                          ("temperature","K")]:
             val = self.units_override.get("%s_unit" % unit, None)
             if val is not None:
                 if isinstance(val, YTQuantity):
                     val = (val.v, str(val.units))
                 elif not isinstance(val, tuple):
                     val = (val, cgs)
-                u = getattr(self, "%s_unit" % unit)
-                mylog.info("Overriding %s_unit: %g %s -> %g %s.", unit, u.v, u.units, val[0], val[1])
+                u = getattr(self, "%s_unit" % unit, None)
+                mylog.info("Overriding %s_unit: %g -> %g %s.",
+                           unit, u, val[0], val[1])
                 setattr(self, "%s_unit" % unit, self.quan(val[0], val[1]))
 
     _arr = None

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/data_objects/tests/test_profiles.py
--- a/yt/data_objects/tests/test_profiles.py
+++ b/yt/data_objects/tests/test_profiles.py
@@ -8,7 +8,13 @@
 from yt.testing import \
     fake_random_ds, \
     assert_equal, \
+    assert_raises, \
     assert_rel_equal
+from yt.utilities.exceptions import \
+    YTIllDefinedProfile
+from yt.visualization.profile_plotter import \
+    ProfilePlot, \
+    PhasePlot
 
 _fields = ("density", "temperature", "dinosaurs", "tribbles")
 _units = ("g/cm**3", "K", "dyne", "erg")
@@ -158,3 +164,34 @@
                         weight_field = None)
         p3d.add_fields(["particle_ones"])
         yield assert_equal, p3d["particle_ones"].sum(), 32**3
+
+def test_mixed_particle_mesh_profiles():
+    ds = fake_random_ds(32, particles=10)
+    ad = ds.all_data()
+    assert_raises(
+        YTIllDefinedProfile, ProfilePlot, ad, 'radius', 'particle_mass')
+    assert_raises(
+        YTIllDefinedProfile, ProfilePlot, ad, 'radius',
+        ['particle_mass', 'particle_ones'])
+    assert_raises(
+        YTIllDefinedProfile, ProfilePlot, ad, 'radius',
+        ['particle_mass', 'ones'])
+    assert_raises(
+        YTIllDefinedProfile, ProfilePlot, ad, 'particle_radius', 'particle_mass',
+        'cell_mass')
+    assert_raises(
+        YTIllDefinedProfile, ProfilePlot, ad, 'radius', 'cell_mass',
+        'particle_ones')
+
+    assert_raises(
+        YTIllDefinedProfile, PhasePlot, ad, 'radius', 'particle_mass',
+        'velocity_x')
+    assert_raises(
+        YTIllDefinedProfile, PhasePlot, ad, 'particle_radius', 'particle_mass',
+        'cell_mass')
+    assert_raises(
+        YTIllDefinedProfile, PhasePlot, ad, 'radius', 'cell_mass',
+        'particle_ones')
+    assert_raises(
+        YTIllDefinedProfile, PhasePlot, ad, 'particle_radius', 'particle_mass',
+        'particle_ones')

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/data_objects/unstructured_mesh.py
--- a/yt/data_objects/unstructured_mesh.py
+++ b/yt/data_objects/unstructured_mesh.py
@@ -22,8 +22,9 @@
     fill_fcoords, fill_fwidths
 
 from yt.data_objects.data_containers import \
-    YTFieldData, \
     YTSelectionContainer
+from yt.data_objects.field_data import \
+    YTFieldData
 import yt.geometry.particle_deposit as particle_deposit
 
 class UnstructuredMesh(YTSelectionContainer):

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/frontends/art/data_structures.py
--- a/yt/frontends/art/data_structures.py
+++ b/yt/frontends/art/data_structures.py
@@ -25,7 +25,8 @@
 from yt.data_objects.octree_subset import \
     OctreeSubset
 from yt.funcs import \
-    mylog
+    mylog, \
+    setdefaultattr
 from yt.geometry.oct_container import \
     ARTOctreeContainer
 from yt.frontends.art.definitions import \
@@ -243,10 +244,10 @@
         mass = aM0 * 1.98892e33
 
         self.cosmological_simulation = True
-        self.mass_unit = self.quan(mass, "g*%s" % ng**3)
-        self.length_unit = self.quan(box_proper, "Mpc")
-        self.velocity_unit = self.quan(velocity, "cm/s")
-        self.time_unit = self.length_unit / self.velocity_unit
+        setdefaultattr(self, 'mass_unit', self.quan(mass, "g*%s" % ng**3))
+        setdefaultattr(self, 'length_unit', self.quan(box_proper, "Mpc"))
+        setdefaultattr(self, 'velocity_unit', self.quan(velocity, "cm/s"))
+        setdefaultattr(self, 'time_unit', self.length_unit / self.velocity_unit)
 
     def _parse_parameter_file(self):
         """

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/frontends/artio/data_structures.py
--- a/yt/frontends/artio/data_structures.py
+++ b/yt/frontends/artio/data_structures.py
@@ -30,7 +30,8 @@
     ARTIOFieldInfo
 
 from yt.funcs import \
-    mylog
+    mylog, \
+    setdefaultattr
 from yt.geometry.geometry_handler import \
     Index, \
     YTDataChunk
@@ -39,7 +40,7 @@
     Dataset
 from yt.data_objects.octree_subset import \
     OctreeSubset
-from yt.data_objects.data_containers import \
+from yt.data_objects.field_data import \
     YTFieldData
 from yt.utilities.exceptions import \
     YTParticleDepositionNotImplemented
@@ -354,10 +355,13 @@
         self.storage_filename = storage_filename
 
     def _set_code_unit_attributes(self):
-        self.mass_unit = self.quan(self.parameters["unit_m"], "g")
-        self.length_unit = self.quan(self.parameters["unit_l"], "cm")
-        self.time_unit = self.quan(self.parameters["unit_t"], "s")
-        self.velocity_unit = self.length_unit / self.time_unit
+        setdefaultattr(
+            self, 'mass_unit', self.quan(self.parameters["unit_m"], "g"))
+        setdefaultattr(
+            self, 'length_unit', self.quan(self.parameters["unit_l"], "cm"))
+        setdefaultattr(
+            self, 'time_unit', self.quan(self.parameters["unit_t"], "s"))
+        setdefaultattr(self, 'velocity_unit', self.length_unit / self.time_unit)
 
     def _parse_parameter_file(self):
         # hard-coded -- not provided by headers

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/frontends/athena/data_structures.py
--- a/yt/frontends/athena/data_structures.py
+++ b/yt/frontends/athena/data_structures.py
@@ -471,12 +471,15 @@
 
     def _set_code_unit_attributes(self):
         """
-        Generates the conversion to various physical _units based on the parameter file
+        Generates the conversion to various physical _units based on the
+        parameter file
         """
         if "length_unit" not in self.units_override:
             self.no_cgs_equiv_length = True
         for unit, cgs in [("length", "cm"), ("time", "s"), ("mass", "g")]:
-            # We set these to cgs for now, but they may be overridden later.
+            # We set these to cgs for now, but they may have been overriden
+            if getattr(self, unit+'_unit', None) is not None:
+                continue
             mylog.warning("Assuming 1.0 = 1.0 %s", cgs)
             setattr(self, "%s_unit" % unit, self.quan(1.0, cgs))
         self.magnetic_unit = np.sqrt(4*np.pi * self.mass_unit /

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/frontends/athena/tests/test_outputs.py
--- a/yt/frontends/athena/tests/test_outputs.py
+++ b/yt/frontends/athena/tests/test_outputs.py
@@ -49,6 +49,20 @@
         test_blast.__name__ = test.description
         yield test
 
+uo_blast = {
+    'length_unit': (1.0, 'pc'),
+    'mass_unit': (2.38858753789e-24, 'g/cm**3*pc**3'),
+    'time_unit': (1.0, 's*pc/km'),
+}
+
+ at requires_file(blast)
+def test_blast_override():
+    # verify that overriding units causes derived unit values to be updated.
+    # see issue #1259
+    ds = load(blast, units_override=uo_blast)
+    assert_equal(float(ds.magnetic_unit.in_units('gauss')),
+                 5.478674679698131e-07)
+
 uo_stripping = {"time_unit":3.086e14,
                 "length_unit":8.0236e22,
                 "mass_unit":9.999e-30*8.0236e22**3}

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/frontends/boxlib/data_structures.py
--- a/yt/frontends/boxlib/data_structures.py
+++ b/yt/frontends/boxlib/data_structures.py
@@ -22,8 +22,9 @@
 import numpy as np
 
 from yt.funcs import \
+    ensure_tuple, \
     mylog, \
-    ensure_tuple
+    setdefaultattr
 from yt.data_objects.grid_patch import AMRGridPatch
 from yt.extern.six.moves import zip as izip
 from yt.geometry.grid_geometry_handler import GridIndex
@@ -608,10 +609,10 @@
             self._setup2d()
 
     def _set_code_unit_attributes(self):
-        self.length_unit = self.quan(1.0, "cm")
-        self.mass_unit = self.quan(1.0, "g")
-        self.time_unit = self.quan(1.0, "s")
-        self.velocity_unit = self.quan(1.0, "cm/s")
+        setdefaultattr(self, 'length_unit', self.quan(1.0, "cm"))
+        setdefaultattr(self, 'mass_unit', self.quan(1.0, "g"))
+        setdefaultattr(self, 'time_unit', self.quan(1.0, "s"))
+        setdefaultattr(self, 'velocity_unit', self.quan(1.0, "cm/s"))
 
     def _setup1d(self):
         # self._index_class = BoxlibHierarchy1D
@@ -1016,10 +1017,11 @@
             self.particle_types_raw = self.particle_types
 
     def _set_code_unit_attributes(self):
-        self.mass_unit = self.quan(1.0, "Msun")
-        self.time_unit = self.quan(1.0 / 3.08568025e19, "s")
-        self.length_unit = self.quan(1.0 / (1 + self.current_redshift), "Mpc")
-        self.velocity_unit = self.length_unit / self.time_unit
+        setdefaultattr(self, 'mass_unit', self.quan(1.0, "Msun"))
+        setdefaultattr(self, 'time_unit', self.quan(1.0 / 3.08568025e19, "s"))
+        setdefaultattr(self, 'length_unit',
+                       self.quan(1.0 / (1 + self.current_redshift), "Mpc"))
+        setdefaultattr(self, 'velocity_unit', self.length_unit / self.time_unit)
 
 def _guess_pcast(vals):
     # Now we guess some things about the parameter and its type

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/frontends/chombo/data_structures.py
--- a/yt/frontends/chombo/data_structures.py
+++ b/yt/frontends/chombo/data_structures.py
@@ -23,7 +23,9 @@
 from stat import \
     ST_CTIME
 
-from yt.funcs import mylog
+from yt.funcs import \
+    mylog, \
+    setdefaultattr
 from yt.data_objects.grid_patch import \
     AMRGridPatch
 from yt.extern import six
@@ -275,14 +277,19 @@
         self.parameters["EOSType"] = -1 # default
 
     def _set_code_unit_attributes(self):
-        mylog.warning("Setting code length to be 1.0 cm")
-        mylog.warning("Setting code mass to be 1.0 g")
-        mylog.warning("Setting code time to be 1.0 s")
-        self.length_unit = self.quan(1.0, "cm")
-        self.mass_unit = self.quan(1.0, "g")
-        self.time_unit = self.quan(1.0, "s")
-        self.magnetic_unit = self.quan(np.sqrt(4.*np.pi), "gauss")
-        self.velocity_unit = self.length_unit / self.time_unit
+        if not hasattr(self, 'length_unit'):
+            mylog.warning("Setting code length unit to be 1.0 cm")
+        if not hasattr(self, 'mass_unit'):
+            mylog.warning("Setting code mass unit to be 1.0 g")
+        if not hasattr(self, 'time_unit'):
+            mylog.warning("Setting code time unit to be 1.0 s")
+        setdefaultattr(self, 'length_unit', self.quan(1.0, "cm"))
+        setdefaultattr(self, 'mass_unit', self.quan(1.0, "g"))
+        setdefaultattr(self, 'time_unit', self.quan(1.0, "s"))
+        setdefaultattr(self, 'magnetic_unit',
+                       self.quan(np.sqrt(4.*np.pi), "gauss"))
+        setdefaultattr(self, 'velocity_unit',
+                       self.length_unit / self.time_unit)
 
     def _localize(self, f, default):
         if f is None:

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/frontends/enzo/data_structures.py
--- a/yt/frontends/enzo/data_structures.py
+++ b/yt/frontends/enzo/data_structures.py
@@ -28,7 +28,8 @@
 from yt.funcs import \
     ensure_list, \
     ensure_tuple, \
-    get_pbar
+    get_pbar, \
+    setdefaultattr
 from yt.config import ytcfg
 from yt.data_objects.grid_patch import \
     AMRGridPatch
@@ -917,11 +918,12 @@
             if box_size is None:
                 box_size = self.parameters["Physics"]["Cosmology"]\
                     ["CosmologyComovingBoxSize"]
-            self.length_unit = self.quan(box_size, "Mpccm/h")
-            self.mass_unit = \
-                self.quan(k['urho'], 'g/cm**3') * (self.length_unit.in_cgs())**3
-            self.time_unit = self.quan(k['utim'], 's')
-            self.velocity_unit = self.quan(k['uvel'], 'cm/s')
+            setdefaultattr(self, 'length_unit', self.quan(box_size, "Mpccm/h"))
+            setdefaultattr(
+                self, 'mass_unit',
+                self.quan(k['urho'], 'g/cm**3') * (self.length_unit.in_cgs())**3)
+            setdefaultattr(self, 'time_unit', self.quan(k['utim'], 's'))
+            setdefaultattr(self, 'velocity_unit', self.quan(k['uvel'], 'cm/s'))
         else:
             if "LengthUnits" in self.parameters:
                 length_unit = self.parameters["LengthUnits"]
@@ -937,15 +939,16 @@
                 mylog.warning("Setting 1.0 in code units to be 1.0 s")
                 length_unit = mass_unit = time_unit = 1.0
 
-            self.length_unit = self.quan(length_unit, "cm")
-            self.mass_unit = self.quan(mass_unit, "g")
-            self.time_unit = self.quan(time_unit, "s")
-            self.velocity_unit = self.length_unit / self.time_unit
+            setdefaultattr(self, 'length_unit', self.quan(length_unit, "cm"))
+            setdefaultattr(self, 'mass_unit', self.quan(mass_unit, "g"))
+            setdefaultattr(self, 'time_unit', self.quan(time_unit, "s"))
+            setdefaultattr(
+                self, 'velocity_unit', self.length_unit / self.time_unit)
 
         magnetic_unit = np.sqrt(4*np.pi * self.mass_unit /
                                 (self.time_unit**2 * self.length_unit))
         magnetic_unit = np.float64(magnetic_unit.in_cgs())
-        self.magnetic_unit = self.quan(magnetic_unit, "gauss")
+        setdefaultattr(self, 'magnetic_unit', self.quan(magnetic_unit, "gauss"))
 
     def cosmology_get_units(self):
         """

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/frontends/exodus_ii/data_structures.py
--- a/yt/frontends/exodus_ii/data_structures.py
+++ b/yt/frontends/exodus_ii/data_structures.py
@@ -14,6 +14,8 @@
 #-----------------------------------------------------------------------------
 import numpy as np
 
+from yt.funcs import \
+    setdefaultattr
 from yt.geometry.unstructured_mesh_handler import \
     UnstructuredIndex
 from yt.data_objects.unstructured_mesh import \
@@ -163,9 +165,9 @@
         # should be set, along with examples of how to set them to standard
         # values.
         #
-        self.length_unit = self.quan(1.0, "cm")
-        self.mass_unit = self.quan(1.0, "g")
-        self.time_unit = self.quan(1.0, "s")
+        setdefaultattr(self, 'length_unit', self.quan(1.0, "cm"))
+        setdefaultattr(self, 'mass_unit', self.quan(1.0, "g"))
+        setdefaultattr(self, 'time_unit', self.quan(1.0, "s"))
         #
         # These can also be set:
         # self.velocity_unit = self.quan(1.0, "cm/s")

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/frontends/fits/data_structures.py
--- a/yt/frontends/fits/data_structures.py
+++ b/yt/frontends/fits/data_structures.py
@@ -25,8 +25,9 @@
 
 from yt.config import ytcfg
 from yt.funcs import \
+    ensure_list, \
     mylog, \
-    ensure_list
+    setdefaultattr
 from yt.data_objects.grid_patch import \
     AMRGridPatch
 from yt.geometry.grid_geometry_handler import \
@@ -447,10 +448,10 @@
             mylog.warning("No length conversion provided. Assuming 1 = 1 cm.")
             length_factor = 1.0
             length_unit = "cm"
-        self.length_unit = self.quan(length_factor,length_unit)
-        self.mass_unit = self.quan(1.0, "g")
-        self.time_unit = self.quan(1.0, "s")
-        self.velocity_unit = self.quan(1.0, "cm/s")
+        setdefaultattr(self, 'length_unit', self.quan(length_factor,length_unit))
+        setdefaultattr(self, 'mass_unit', self.quan(1.0, "g"))
+        setdefaultattr(self, 'time_unit', self.quan(1.0, "s"))
+        setdefaultattr(self, 'velocity_unit', self.quan(1.0, "cm/s"))
         if "beam_size" in self.specified_parameters:
             beam_size = self.specified_parameters["beam_size"]
             beam_size = self.quan(beam_size[0], beam_size[1]).in_cgs().value

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/frontends/flash/data_structures.py
--- a/yt/frontends/flash/data_structures.py
+++ b/yt/frontends/flash/data_structures.py
@@ -22,7 +22,9 @@
     AMRGridPatch
 from yt.data_objects.static_output import \
     Dataset, ParticleFile
-from yt.funcs import mylog
+from yt.funcs import \
+    mylog, \
+    setdefaultattr
 from yt.geometry.grid_geometry_handler import \
     GridIndex
 from yt.geometry.particle_geometry_handler import \
@@ -246,13 +248,14 @@
         else:
             length_factor = 1.0
             temperature_factor = 1.0
-        self.magnetic_unit = self.quan(b_factor, "gauss")
 
-        self.length_unit = self.quan(length_factor, "cm")
-        self.mass_unit = self.quan(1.0, "g")
-        self.time_unit = self.quan(1.0, "s")
-        self.velocity_unit = self.quan(1.0, "cm/s")
-        self.temperature_unit = self.quan(temperature_factor, "K")
+        setdefaultattr(self, 'magnetic_unit', self.quan(b_factor, "gauss"))
+        setdefaultattr(self, 'length_unit', self.quan(length_factor, "cm"))
+        setdefaultattr(self, 'mass_unit', self.quan(1.0, "g"))
+        setdefaultattr(self, 'time_unit', self.quan(1.0, "s"))
+        setdefaultattr(self, 'velocity_unit', self.quan(1.0, "cm/s"))
+        setdefaultattr(
+            self, 'temperature_unit', self.quan(temperature_factor, "K"))
 
     def set_code_units(self):
         super(FLASHDataset, self).set_code_units()

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/frontends/gadget_fof/data_structures.py
--- a/yt/frontends/gadget_fof/data_structures.py
+++ b/yt/frontends/gadget_fof/data_structures.py
@@ -33,7 +33,8 @@
     GadgetFOFFieldInfo, \
     GadgetFOFHaloFieldInfo
 from yt.funcs import \
-    only_on_root
+    only_on_root, \
+    setdefaultattr
 from yt.geometry.particle_geometry_handler import \
     ParticleIndex
 from yt.utilities.cosmology import \
@@ -232,7 +233,8 @@
         else:
             raise RuntimeError
         length_unit = _fix_unit_ordering(length_unit)
-        self.length_unit = self.quan(length_unit[0], length_unit[1])
+        setdefaultattr(self, 'length_unit',
+                       self.quan(length_unit[0], length_unit[1]))
         
         if "velocity" in unit_base:
             velocity_unit = unit_base["velocity"]
@@ -244,7 +246,8 @@
             else:
                 velocity_unit = (1e5, "cmcm/s")
         velocity_unit = _fix_unit_ordering(velocity_unit)
-        self.velocity_unit = self.quan(velocity_unit[0], velocity_unit[1])
+        setdefaultattr(self, 'velocity_unit',
+                       self.quan(velocity_unit[0], velocity_unit[1]))
 
         # We set hubble_constant = 1.0 for non-cosmology, so this is safe.
         # Default to 1e10 Msun/h if mass is not specified.
@@ -259,7 +262,7 @@
             # Sane default
             mass_unit = (1.0, "1e10*Msun/h")
         mass_unit = _fix_unit_ordering(mass_unit)
-        self.mass_unit = self.quan(mass_unit[0], mass_unit[1])
+        setdefaultattr(self, 'mass_unit', self.quan(mass_unit[0], mass_unit[1]))
 
         if "time" in unit_base:
             time_unit = unit_base["time"]
@@ -267,7 +270,7 @@
             time_unit = (unit_base["UnitTime_in_s"], "s")
         else:
             time_unit = (1., "s")        
-        self.time_unit = self.quan(time_unit[0], time_unit[1])
+        setdefaultattr(self, 'time_unit', self.quan(time_unit[0], time_unit[1]))
 
     def __repr__(self):
         return self.basename.split(".", 1)[0]

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/frontends/gamer/data_structures.py
--- a/yt/frontends/gamer/data_structures.py
+++ b/yt/frontends/gamer/data_structures.py
@@ -18,7 +18,9 @@
 import numpy as np
 import weakref
 
-from yt.funcs import mylog
+from yt.funcs import \
+    mylog, \
+    setdefaultattr
 from yt.data_objects.grid_patch import \
     AMRGridPatch
 from yt.geometry.grid_geometry_handler import \
@@ -205,7 +207,7 @@
                           "Use units_override to specify the units")
 
         for unit, cgs in [("length", "cm"), ("time", "s"), ("mass", "g")]:
-            setattr(self, "%s_unit"%unit, self.quan(1.0, cgs))
+            setdefaultattr(self, "%s_unit"%unit, self.quan(1.0, cgs))
 
             if len(self.units_override) == 0:
                 mylog.warning("Assuming 1.0 = 1.0 %s", cgs)

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/frontends/gdf/data_structures.py
--- a/yt/frontends/gdf/data_structures.py
+++ b/yt/frontends/gdf/data_structures.py
@@ -19,7 +19,9 @@
 import os
 from yt.extern.six import string_types
 from yt.funcs import \
-    just_one, ensure_tuple
+    ensure_tuple, \
+    just_one, \
+    setdefaultattr
 from yt.data_objects.grid_patch import \
     AMRGridPatch
 from yt.geometry.grid_geometry_handler import \
@@ -223,17 +225,17 @@
                     un = unit_name[:-5]
                     un = un.replace('magnetic', 'magnetic_field', 1)
                     unit = self.unit_system[un]
-                    setattr(self, unit_name, self.quan(value, unit))
-                setattr(self, unit_name, self.quan(value, unit))
+                    setdefaultattr(self, unit_name, self.quan(value, unit))
+                setdefaultattr(self, unit_name, self.quan(value, unit))
                 if unit_name in h5f["/field_types"]:
                     if unit_name in self.field_units:
                         mylog.warning("'field_units' was overridden by 'dataset_units/%s'"
                                       % (unit_name))
                     self.field_units[unit_name] = str(unit)
         else:
-            self.length_unit = self.quan(1.0, "cm")
-            self.mass_unit = self.quan(1.0, "g")
-            self.time_unit = self.quan(1.0, "s")
+            setdefaultattr(self, 'length_unit', self.quan(1.0, "cm"))
+            setdefaultattr(self, 'mass_unit', self.quan(1.0, "g"))
+            setdefaultattr(self, 'time_unit', self.quan(1.0, "s"))
 
         h5f.close()
 

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/frontends/halo_catalog/data_structures.py
--- a/yt/frontends/halo_catalog/data_structures.py
+++ b/yt/frontends/halo_catalog/data_structures.py
@@ -23,6 +23,8 @@
 from .fields import \
     HaloCatalogFieldInfo
 
+from yt.funcs import \
+    setdefaultattr
 from yt.geometry.particle_geometry_handler import \
     ParticleIndex
 from yt.data_objects.static_output import \
@@ -76,10 +78,10 @@
         self.parameters.update(hvals)
 
     def _set_code_unit_attributes(self):
-        self.length_unit = self.quan(1.0, "cm")
-        self.mass_unit = self.quan(1.0, "g")
-        self.velocity_unit = self.quan(1.0, "cm / s")
-        self.time_unit = self.quan(1.0, "s")
+        setdefaultattr(self, 'length_unit', self.quan(1.0, "cm"))
+        setdefaultattr(self, 'mass_unit', self.quan(1.0, "g"))
+        setdefaultattr(self, 'velocity_unit', self.quan(1.0, "cm / s"))
+        setdefaultattr(self, 'time_unit', self.quan(1.0, "s"))
 
     @classmethod
     def _is_valid(self, *args, **kwargs):

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/frontends/moab/data_structures.py
--- a/yt/frontends/moab/data_structures.py
+++ b/yt/frontends/moab/data_structures.py
@@ -19,6 +19,8 @@
 import weakref
 from yt.data_objects.unstructured_mesh import \
     SemiStructuredMesh
+from yt.funcs import \
+    setdefaultattr
 from yt.geometry.unstructured_mesh_handler import \
     UnstructuredIndex
 from yt.data_objects.static_output import \
@@ -78,9 +80,9 @@
     def _set_code_unit_attributes(self):
         # Almost everything is regarded as dimensionless in MOAB, so these will
         # not be used very much or at all.
-        self.length_unit = self.quan(1.0, "cm")
-        self.time_unit = self.quan(1.0, "s")
-        self.mass_unit = self.quan(1.0, "g")
+        setdefaultattr(self, 'length_unit', self.quan(1.0, "cm"))
+        setdefaultattr(self, 'time_unit', self.quan(1.0, "s"))
+        setdefaultattr(self, 'mass_unit', self.quan(1.0, "g"))
 
     def _parse_parameter_file(self):
         self._handle = h5py.File(self.parameter_filename, "r")
@@ -161,9 +163,9 @@
     def _set_code_unit_attributes(self):
         # Almost everything is regarded as dimensionless in MOAB, so these will
         # not be used very much or at all.
-        self.length_unit = self.quan(1.0, "cm")
-        self.time_unit = self.quan(1.0, "s")
-        self.mass_unit = self.quan(1.0, "g")
+        setdefaultattr(self, 'length_unit', self.quan(1.0, "cm"))
+        setdefaultattr(self, 'time_unit', self.quan(1.0, "s"))
+        setdefaultattr(self, 'mass_unit', self.quan(1.0, "g"))
 
     def _parse_parameter_file(self):
         #  not sure if this import has side-effects so I'm not deleting it

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/frontends/owls_subfind/data_structures.py
--- a/yt/frontends/owls_subfind/data_structures.py
+++ b/yt/frontends/owls_subfind/data_structures.py
@@ -24,7 +24,9 @@
 from .fields import \
     OWLSSubfindFieldInfo
 
-from yt.funcs import only_on_root
+from yt.funcs import \
+    only_on_root, \
+    setdefaultattr
 from yt.utilities.exceptions import \
     YTException
 from yt.utilities.logger import ytLogger as \
@@ -176,7 +178,8 @@
         else:
             raise RuntimeError
         length_unit = _fix_unit_ordering(length_unit)
-        self.length_unit = self.quan(length_unit[0], length_unit[1])
+        setdefaultattr(self, 'length_unit',
+                       self.quan(length_unit[0], length_unit[1]))
 
         if "velocity" in unit_base:
             velocity_unit = unit_base["velocity"]
@@ -185,7 +188,8 @@
         else:
             velocity_unit = (1e5, "cm/s")
         velocity_unit = _fix_unit_ordering(velocity_unit)
-        self.velocity_unit = self.quan(velocity_unit[0], velocity_unit[1])
+        setdefaultattr(self, 'velocity_unit',
+                       self.quan(velocity_unit[0], velocity_unit[1]))
 
         # We set hubble_constant = 1.0 for non-cosmology, so this is safe.
         # Default to 1e10 Msun/h if mass is not specified.
@@ -200,7 +204,7 @@
             # Sane default
             mass_unit = (1.0, "1e10*Msun/h")
         mass_unit = _fix_unit_ordering(mass_unit)
-        self.mass_unit = self.quan(mass_unit[0], mass_unit[1])
+        setdefaultattr(self, 'mass_unit', self.quan(mass_unit[0], mass_unit[1]))
 
         if "time" in unit_base:
             time_unit = unit_base["time"]
@@ -208,7 +212,7 @@
             time_unit = (unit_base["UnitTime_in_s"], "s")
         else:
             time_unit = (1., "s")        
-        self.time_unit = self.quan(time_unit[0], time_unit[1])
+        setdefaultattr(self, 'time_unit', self.quan(time_unit[0], time_unit[1]))
 
     @classmethod
     def _is_valid(self, *args, **kwargs):

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/frontends/ramses/data_structures.py
--- a/yt/frontends/ramses/data_structures.py
+++ b/yt/frontends/ramses/data_structures.py
@@ -23,7 +23,8 @@
 
 from yt.extern.six import string_types
 from yt.funcs import \
-    mylog
+    mylog, \
+    setdefaultattr
 from yt.geometry.oct_geometry_handler import \
     OctreeIndex
 from yt.geometry.geometry_handler import \
@@ -565,17 +566,21 @@
         # For now assume an atomic ideal gas with cosmic abundances (x_H = 0.76)
         mean_molecular_weight_factor = _X**-1
 
-        self.density_unit = self.quan(density_unit, 'g/cm**3')
-        self.magnetic_unit = self.quan(magnetic_unit, "gauss")
-        self.pressure_unit = self.quan(pressure_unit, 'dyne/cm**2')
-        self.time_unit = self.quan(time_unit, "s")
-        self.mass_unit = self.quan(mass_unit, "g")
-        self.velocity_unit = self.quan(length_unit, 'cm') / self.time_unit
-        self.temperature_unit = (self.velocity_unit**2*mp* 
-                                 mean_molecular_weight_factor/kb).in_units('K')
+        setdefaultattr(self, 'density_unit', self.quan(density_unit, 'g/cm**3'))
+        setdefaultattr(self, 'magnetic_unit', self.quan(magnetic_unit, "gauss"))
+        setdefaultattr(self, 'pressure_unit',
+                       self.quan(pressure_unit, 'dyne/cm**2'))
+        setdefaultattr(self, 'time_unit', self.quan(time_unit, "s"))
+        setdefaultattr(self, 'mass_unit', self.quan(mass_unit, "g"))
+        setdefaultattr(self, 'velocity_unit',
+                       self.quan(length_unit, 'cm') / self.time_unit)
+        temperature_unit = (
+            self.velocity_unit**2*mp*mean_molecular_weight_factor/kb)
+        setdefaultattr(self, 'temperature_unit', temperature_unit.in_units('K'))
 
         # Only the length unit get scales by a factor of boxlen
-        self.length_unit = self.quan(length_unit * boxlen, "cm")
+        setdefaultattr(self, 'length_unit',
+                       self.quan(length_unit * boxlen, "cm"))
 
     def _parse_parameter_file(self):
         # hardcoded for now

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/frontends/rockstar/data_structures.py
--- a/yt/frontends/rockstar/data_structures.py
+++ b/yt/frontends/rockstar/data_structures.py
@@ -22,12 +22,14 @@
 from .fields import \
     RockstarFieldInfo
 
-from yt.utilities.cosmology import Cosmology
-from yt.geometry.particle_geometry_handler import \
-    ParticleIndex
 from yt.data_objects.static_output import \
     Dataset, \
     ParticleFile
+from yt.funcs import \
+    setdefaultattr
+from yt.geometry.particle_geometry_handler import \
+    ParticleIndex
+from yt.utilities.cosmology import Cosmology
 import yt.utilities.fortran_utils as fpu
 
 from .definitions import \
@@ -92,10 +94,10 @@
 
     def _set_code_unit_attributes(self):
         z = self.current_redshift
-        self.length_unit = self.quan(1.0 / (1.0+z), "Mpc / h")
-        self.mass_unit = self.quan(1.0, "Msun / h")
-        self.velocity_unit = self.quan(1.0, "km / s")
-        self.time_unit = self.length_unit / self.velocity_unit
+        setdefaultattr(self, 'length_unit', self.quan(1.0 / (1.0+z), "Mpc / h"))
+        setdefaultattr(self, 'mass_unit', self.quan(1.0, "Msun / h"))
+        setdefaultattr(self, 'velocity_unit', self.quan(1.0, "km / s"))
+        setdefaultattr(self, 'time_unit', self.length_unit / self.velocity_unit)
 
     @classmethod
     def _is_valid(self, *args, **kwargs):

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/frontends/sdf/data_structures.py
--- a/yt/frontends/sdf/data_structures.py
+++ b/yt/frontends/sdf/data_structures.py
@@ -28,7 +28,8 @@
 from yt.data_objects.static_output import \
     Dataset, ParticleFile
 from yt.funcs import \
-    get_requests
+    get_requests, \
+    setdefaultattr
 from .fields import \
     SDFFieldInfo
 from yt.utilities.sdf import \
@@ -177,16 +178,22 @@
         return self._midx
 
     def _set_code_unit_attributes(self):
-        self.length_unit = self.quan(1.0, self.parameters.get("length_unit", 'kpc'))
-        self.velocity_unit = self.quan(1.0, self.parameters.get("velocity_unit", 'kpc/Gyr'))
-        self.time_unit = self.quan(1.0, self.parameters.get("time_unit", 'Gyr'))
+        setdefaultattr(
+            self, 'length_unit',
+            self.quan(1.0, self.parameters.get("length_unit", 'kpc')))
+        setdefaultattr(
+            self, 'velocity_unit',
+            self.quan(1.0, self.parameters.get("velocity_unit", 'kpc/Gyr')))
+        setdefaultattr(
+            self, 'time_unit',
+            self.quan(1.0, self.parameters.get("time_unit", 'Gyr')))
         mass_unit = self.parameters.get("mass_unit", '1e10 Msun')
         if ' ' in mass_unit:
             factor, unit = mass_unit.split(' ')
         else:
             factor = 1.0
             unit = mass_unit
-        self.mass_unit = self.quan(float(factor), unit)
+        setdefaultattr(self, 'mass_unit', self.quan(float(factor), unit))
 
     @classmethod
     def _is_valid(cls, *args, **kwargs):

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/frontends/stream/data_structures.py
--- a/yt/frontends/stream/data_structures.py
+++ b/yt/frontends/stream/data_structures.py
@@ -26,7 +26,7 @@
     iterable, \
     ensure_list
 from yt.utilities.io_handler import io_registry
-from yt.data_objects.data_containers import \
+from yt.data_objects.field_data import \
     YTFieldData
 from yt.data_objects.particle_unions import \
     ParticleUnion

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/funcs.py
--- a/yt/funcs.py
+++ b/yt/funcs.py
@@ -1004,3 +1004,12 @@
 
 def get_interactivity():
     return interactivity
+
+def setdefaultattr(obj, name, value):
+    """Set attribute with *name* on *obj* with *value* if it doesn't exist yet
+
+    Analogous to dict.setdefault
+    """
+    if not hasattr(obj, name):
+        setattr(obj, name, value)
+    return getattr(obj, name)

diff -r 405474784eb337baf3aff2acd48b6acc9cbe9281 -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c yt/geometry/particle_smooth.pxd
--- a/yt/geometry/particle_smooth.pxd
+++ b/yt/geometry/particle_smooth.pxd
@@ -23,15 +23,12 @@
 from yt.utilities.lib.fp_utils cimport *
 from oct_container cimport Oct, OctAllocationContainer, OctreeContainer
 from .particle_deposit cimport kernel_func, get_kernel_func, gind
+from yt.utilities.lib.distance_queue cimport NeighborList, Neighbor_compare, \
+    r2dist, DistanceQueue
 
 cdef extern from "platform_dep.h":
     void *alloca(int)
 
-cdef struct NeighborList
-cdef struct NeighborList:
-    np.int64_t pn       # Particle number
-    np.float64_t r2     # radius**2
-
 cdef class ParticleSmoothOperation:
     # We assume each will allocate and define their own temporary storage
     cdef kernel_func sph_kernel
@@ -39,10 +36,8 @@
     cdef np.float64_t DW[3]
     cdef int nfields
     cdef int maxn
-    cdef int curn
     cdef bint periodicity[3]
     # Note that we are preallocating here, so this is *not* threadsafe.
-    cdef NeighborList *neighbors
     cdef void (*pos_setup)(np.float64_t ipos[3], np.float64_t opos[3])
     cdef void neighbor_process(self, int dim[3], np.float64_t left_edge[3],
                                np.float64_t dds[3], np.float64_t[:,:] ppos,
@@ -52,7 +47,7 @@
                                np.int64_t offset, np.float64_t **index_fields,
                                OctreeContainer octree, np.int64_t domain_id,
                                int *nsize, np.float64_t[:,:] oct_left_edges,
-                               np.float64_t[:,:] oct_dds)
+                               np.float64_t[:,:] oct_dds, DistanceQueue dq)
     cdef int neighbor_search(self, np.float64_t pos[3], OctreeContainer octree,
                              np.int64_t **nind, int *nsize, 
                              np.int64_t nneighbors, np.int64_t domain_id, 
@@ -65,10 +60,7 @@
                                np.int64_t offset,
                                np.float64_t **index_fields,
                                OctreeContainer octree, np.int64_t domain_id,
-                               int *nsize)
-    cdef void neighbor_eval(self, np.int64_t pn, np.float64_t ppos[3],
-                            np.float64_t cpos[3])
-    cdef void neighbor_reset(self)
+                               int *nsize, DistanceQueue dq)
     cdef void neighbor_find(self,
                             np.int64_t nneighbors,
                             np.int64_t *nind,
@@ -78,7 +70,7 @@
                             np.float64_t[:,:] ppos,
                             np.float64_t cpos[3],
                             np.float64_t[:,:] oct_left_edges,
-                            np.float64_t[:,:] oct_dds)
+                            np.float64_t[:,:] oct_dds, DistanceQueue dq)
     cdef void process(self, np.int64_t offset, int i, int j, int k,
                       int dim[3], np.float64_t cpos[3], np.float64_t **fields,
-                      np.float64_t **index_fields)
+                      np.float64_t **index_fields, DistanceQueue dq)

This diff is so big that we needed to truncate the remainder.

https://bitbucket.org/yt_analysis/yt/commits/9a37f70cce9d/
Changeset:   9a37f70cce9d
Branch:      yt
User:        ngoldbaum
Date:        2016-08-25 15:51:32+00:00
Summary:     remove yield assert
Affected #:  1 file

diff -r a3465e29e8f821b8e7109ce3b3cfa5534d2cd55c -r 9a37f70cce9dfdab3d8da8f6362c75a9c7e02e36 yt/visualization/tests/test_plotwindow.py
--- a/yt/visualization/tests/test_plotwindow.py
+++ b/yt/visualization/tests/test_plotwindow.py
@@ -481,7 +481,7 @@
         lims = [xlims[0], xlims[1], ylims[0], ylims[1]]
         for l in lims:
             generated_limits.append(l)
-    yield assert_array_almost_equal, correct_limits, generated_limits
+    assert_array_almost_equal(correct_limits, generated_limits)
 
 def test_frb_regen():
     ds = fake_random_ds(32)


https://bitbucket.org/yt_analysis/yt/commits/7e7c3fdd9cc7/
Changeset:   7e7c3fdd9cc7
Branch:      yt
User:        ngoldbaum
Date:        2016-09-07 18:09:46+00:00
Summary:     Merged in a_gilbert/yt (pull request #2340)

Closing Issue #1247: updated origin input to accept floats or ints specifying xloc or yloc.
Affected #:  3 files

diff -r 4bc8ace93fda81e800a2e90c052c431c2d48a01b -r 7e7c3fdd9cc79e65a179d277ae64b345dc30411f yt/visualization/base_plot_types.py
--- a/yt/visualization/base_plot_types.py
+++ b/yt/visualization/base_plot_types.py
@@ -357,6 +357,7 @@
         self._toggle_colorbar(True)
         return self
 
+
 def get_multi_plot(nx, ny, colorbar = 'vertical', bw = 4, dpi=300,
                    cbar_padding = 0.4):
     r"""Construct a multiple axes plot object, with or without a colorbar, into
@@ -440,3 +441,5 @@
             ax.clear()
             cbars.append(ax)
     return fig, tr, cbars
+
+

diff -r 4bc8ace93fda81e800a2e90c052c431c2d48a01b -r 7e7c3fdd9cc79e65a179d277ae64b345dc30411f yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -156,7 +156,8 @@
     Parameters
     ----------
 
-    data_source : :class:`yt.data_objects.construction_data_containers.YTQuadTreeProj` or :class:`yt.data_objects.selection_data_containers.YTSlice`
+    data_source : :class:`yt.data_objects.construction_data_containers.YTQuadTreeProj`
+    or :class:`yt.data_objects.selection_data_containers.YTSlice`
         This is the source to be pixelized, which can be a projection or a
         slice.  (For cutting planes, see
         `yt.visualization.fixed_resolution.ObliqueFixedResolutionBuffer`.)
@@ -397,33 +398,39 @@
 
         Parameters
         ----------
-        origin : string or length 1, 2, or 3 sequence of strings
-            The location of the origin of the plot coordinate system.  This is
-            represented by '-' separated string or a tuple of strings.  In the
-            first index the y-location is given by 'lower', 'upper', or 'center'.
-            The second index is the x-location, given as 'left', 'right', or
-            'center'.  Finally, the whether the origin is applied in 'domain'
-            space, plot 'window' space or 'native' simulation coordinate system
-            is given. For example, both 'upper-right-domain' and ['upper',
-            'right', 'domain'] place the origin in the upper right hand
-            corner of domain space. If x or y are not given, a value is inferred.
-            For instance, 'left-domain' corresponds to the lower-left hand corner
-            of the simulation domain, 'center-domain' corresponds to the center
-            of the simulation domain, or 'center-window' for the center of the
-            plot window. Further examples:
+        origin : string or length 1, 2, or 3 sequence.
+            The location of the origin of the plot coordinate system. This
+            is typically represented by a '-' separated string or a tuple of
+            strings. In the first index the y-location is given by 'lower',
+            'upper', or 'center'. The second index is the x-location, given as
+            'left', 'right', or 'center'. Finally, the whether the origin is
+            applied in 'domain' space, plot 'window' space or 'native'
+            simulation coordinate system is given. For example, both
+            'upper-right-domain' and ['upper', 'right', 'domain'] place the
+            origin in the upper right hand corner of domain space. If x or y
+            are not given, a value is inferred. For instance, 'left-domain'
+            corresponds to the lower-left hand corner of the simulation domain,
+            'center-domain' corresponds to the center of the simulation domain,
+            or 'center-window' for the center of the plot window. In the event
+            that none of these options place the origin in a desired location,
+            a sequence of tuples and a string specifying the
+            coordinate space can be given. If plain numeric types are input,
+            units of `code_length` are assumed. Further examples:
 
-            ==================================     ============================
-            format                                 example
-            ==================================     ============================
-            '{space}'                              'domain'
-            '{xloc}-{space}'                       'left-window'
-            '{yloc}-{space}'                       'upper-domain'
-            '{yloc}-{xloc}-{space}'                'lower-right-window'
-            ('{space}',)                           ('window',)
-            ('{xloc}', '{space}')                  ('right', 'domain')
-            ('{yloc}', '{space}')                  ('lower', 'window')
-            ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
-            ==================================     ============================
+         ==================================                ============================
+         format                                            example
+         ==================================                ============================
+         '{space}'                                          'domain'
+         '{xloc}-{space}'                                   'left-window'
+         '{yloc}-{space}'                                   'upper-domain'
+         '{yloc}-{xloc}-{space}'                            'lower-right-window'
+         ('{space}',)                                       ('window',)
+         ('{xloc}', '{space}')                              ('right', 'domain')
+         ('{yloc}', '{space}')                              ('lower', 'window')
+         ('{yloc}', '{xloc}', '{space}')                    ('lower', 'right', 'window')
+         ((yloc, '{unit}'), (xloc, '{unit}'), '{space}')    ((0.5, 'm'), (0.4, 'm'), 'window')
+         (xloc, yloc, '{space}')                            (0.23, 0.5, 'domain')
+         ==================================                 ============================
 
         """
         self.origin = origin
@@ -651,6 +658,9 @@
     def _setup_origin(self):
         origin = self.origin
         axis_index = self.data_source.axis
+        xc = None
+        yc = None
+
         if isinstance(origin, string_types):
             origin = tuple(origin.split('-'))[:3]
         if 1 == len(origin):
@@ -660,6 +670,13 @@
             origin = (o0map[origin[0]],) + origin
         elif 2 == len(origin) and origin[0] in set(['lower','upper','center']):
             origin = (origin[0], 'center', origin[-1])
+        elif 3 == len(origin) and isinstance(origin[0], (int, float)):
+            xc = self.ds.quan(origin[0], 'code_length')
+            yc = self.ds.quan(origin[1], 'code_length')
+        elif 3 == len(origin) and isinstance(origin[0], tuple):
+            xc = YTQuantity(origin[0][0], origin[0][1])
+            yc = YTQuantity(origin[1][0], origin[0][1])
+
         assert origin[-1] in ['window', 'domain', 'native']
 
         if origin[2] == 'window':
@@ -678,33 +695,42 @@
         else:
             mylog.warn("origin = {0}".format(origin))
             msg = \
-                ('origin keyword "{0}" not recognized, must declare "domain" '
-                 'or "center" as the last term in origin.').format(self.origin)
+                  ('origin keyword "{0}" not recognized, must declare "domain" '
+                   'or "center" as the last term in origin.').format(self.origin)
             raise RuntimeError(msg)
+        if xc is None and yc is None:
+            if origin[0] == 'lower':
+                yc = yllim
+            elif origin[0] == 'upper':
+                yc = yrlim
+            elif origin[0] == 'center':
+                yc = (yllim + yrlim)/2.0
+            else:
+                mylog.warn("origin = {0}".format(origin))
+                msg = ('origin keyword "{0}" not recognized, must declare "lower" '
+                       '"upper" or "center" as the first term in origin.')
+                msg = msg.format(self.origin)
+                raise RuntimeError(msg)
 
-        if origin[0] == 'lower':
-            yc = yllim
-        elif origin[0] == 'upper':
-            yc = yrlim
-        elif origin[0] == 'center':
-            yc = (yllim + yrlim)/2.0
-        else:
-            mylog.warn("origin = {0}".format(origin))
-            msg = ('origin keyword "{0}" not recognized, must declare "lower" '
-                   '"upper" or "center" as the first term in origin.')
-            msg = msg.format(self.origin)
-            raise RuntimeError(msg)
+            if origin[1] == 'left':
+                xc = xllim
+            elif origin[1] == 'right':
+                xc = xrlim
+            elif origin[1] == 'center':
+                xc = (xllim + xrlim)/2.0
+            else:
+                mylog.warn("origin = {0}".format(origin))
+                msg = ('origin keyword "{0}" not recognized, must declare "left" '
+                       '"right" or "center" as the second term in origin.')
+                msg = msg.format(self.origin)
+                raise RuntimeError(msg)
 
-        if origin[1] == 'left':
-            xc = xllim
-        elif origin[1] == 'right':
-            xc = xrlim
-        elif origin[1] == 'center':
-            xc = (xllim + xrlim)/2.0
-        else:
-            mylog.warn("origin = {0}".format(origin))
-            msg = ('origin keyword "{0}" not recognized, must declare "left" '
-                   '"right" or "center" as the second term in origin.')
+        x_in_bounds = xc >= xllim and xc <= xrlim
+        y_in_bounds = yc >= yllim and yc <= yrlim
+
+        if not x_in_bounds and not y_in_bounds:
+            msg = ('orgin inputs not in bounds of specified coordinate sytem' +
+                   'domain.')
             msg = msg.format(self.origin)
             raise RuntimeError(msg)
 
@@ -736,7 +762,6 @@
             if self.aspect is None:
                 self.aspect = float((self.ds.quan(1.0, unit_y) /
                                      self.ds.quan(1.0, unit_x)).in_cgs())
-
             extentx = [(self.xlim[i] - xc).in_units(unit_x) for i in (0, 1)]
             extenty = [(self.ylim[i] - yc).in_units(unit_y) for i in (0, 1)]
 
@@ -1196,38 +1221,44 @@
          units are assumed, for example (0.2, 0.3) requests a plot that has an
          x width of 0.2 and a y width of 0.3 in code units.  If units are
          provided the resulting plot axis labels will use the supplied units.
+    origin : string or length 1, 2, or 3 sequence.
+         The location of the origin of the plot coordinate system. This
+         is typically represented by a '-' separated string or a tuple of
+         strings. In the first index the y-location is given by 'lower',
+         'upper', or 'center'. The second index is the x-location, given as
+         'left', 'right', or 'center'. Finally, the whether the origin is
+         applied in 'domain' space, plot 'window' space or 'native'
+         simulation coordinate system is given. For example, both
+         'upper-right-domain' and ['upper', 'right', 'domain'] place the
+         origin in the upper right hand corner of domain space. If x or y
+         are not given, a value is inferred. For instance, 'left-domain'
+         corresponds to the lower-left hand corner of the simulation domain,
+         'center-domain' corresponds to the center of the simulation domain,
+         or 'center-window' for the center of the plot window. In the event
+         that none of these options place the origin in a desired location,
+         a sequence of tuples and a string specifying the
+         coordinate space can be given. If plain numeric types are input,
+         units of `code_length` are assumed. Further examples:
+
+         ==================================                ============================
+         format                                            example
+         ==================================                ============================
+         '{space}'                                          'domain'
+         '{xloc}-{space}'                                   'left-window'
+         '{yloc}-{space}'                                   'upper-domain'
+         '{yloc}-{xloc}-{space}'                            'lower-right-window'
+         ('{space}',)                                       ('window',)
+         ('{xloc}', '{space}')                              ('right', 'domain')
+         ('{yloc}', '{space}')                              ('lower', 'window')
+         ('{yloc}', '{xloc}', '{space}')                    ('lower', 'right', 'window')
+         ((yloc, '{unit}'), (xloc, '{unit}'), '{space}')    ((0.5, 'm'), (0.4, 'm'), 'window')
+         (xloc, yloc, '{space}')                            (0.23, 0.5, 'domain')
+         ==================================                 ============================
     axes_unit : A string
          The name of the unit for the tick labels on the x and y axes.
          Defaults to None, which automatically picks an appropriate unit.
          If axes_unit is '1', 'u', or 'unitary', it will not display the
          units, and only show the axes name.
-    origin : string or length 1, 2, or 3 sequence of strings
-         The location of the origin of the plot coordinate system.  This is
-         represented by '-' separated string or a tuple of strings.  In the
-         first index the y-location is given by 'lower', 'upper', or 'center'.
-         The second index is the x-location, given as 'left', 'right', or
-         'center'.  Finally, whether the origin is applied in 'domain'
-         space, plot 'window' space or 'native' simulation coordinate system
-         is given. For example, both 'upper-right-domain' and ['upper',
-         'right', 'domain'] place the origin in the upper right hand
-         corner of domain space. If x or y are not given, a value is inferred.
-         For instance, the default location 'center-window' corresponds to
-         the center of the plot window, 'left-domain' corresponds to the
-         lower-left hand corner of the simulation domain, or 'center-domain'
-         for the center of the simulation domain. Further examples:
-
-         ==================================     ============================
-         format                                 example
-         ==================================     ============================
-         '{space}'                              'domain'
-         '{xloc}-{space}'                       'left-window'
-         '{yloc}-{space}'                       'upper-domain'
-         '{yloc}-{xloc}-{space}'                'lower-right-window'
-         ('{space}',)                           ('window',)
-         ('{xloc}', '{space}')                  ('right', 'domain')
-         ('{yloc}', '{space}')                  ('lower', 'window')
-         ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
-         ==================================     ============================
     right_handed : boolean
          Whether the implicit east vector for the image generated is set to make a right
          handed coordinate system with a normal vector, the direction of the
@@ -1341,33 +1372,40 @@
          Defaults to None, which automatically picks an appropriate unit.
          If axes_unit is '1', 'u', or 'unitary', it will not display the
          units, and only show the axes name.
-    origin : string or length 1, 2, or 3 sequence of strings
-         The location of the origin of the plot coordinate system.  This is
-         represented by '-' separated string or a tuple of strings.  In the
-         first index the y-location is given by 'lower', 'upper', or 'center'.
-         The second index is the x-location, given as 'left', 'right', or
-         'center'.  Finally, whether the origin is applied in 'domain'
-         space, plot 'window' space or 'native' simulation coordinate system
-         is given. For example, both 'upper-right-domain' and ['upper',
-         'right', 'domain'] place the origin in the upper right hand
-         corner of domain space. If x or y are not given, a value is inferred.
-         For instance, 'left-domain' corresponds to the lower-left hand corner
-         of the simulation domain, 'center-domain' corresponds to the center
-         of the simulation domain, or 'center-window' for the center of the
-         plot window. Further examples:
+    origin : string or length 1, 2, or 3 sequence.
+         The location of the origin of the plot coordinate system. This
+         is typically represented by a '-' separated string or a tuple of
+         strings. In the first index the y-location is given by 'lower',
+         'upper', or 'center'. The second index is the x-location, given as
+         'left', 'right', or 'center'. Finally, the whether the origin is
+         applied in 'domain' space, plot 'window' space or 'native'
+         simulation coordinate system is given. For example, both
+         'upper-right-domain' and ['upper', 'right', 'domain'] place the
+         origin in the upper right hand corner of domain space. If x or y
+         are not given, a value is inferred. For instance, 'left-domain'
+         corresponds to the lower-left hand corner of the simulation domain,
+         'center-domain' corresponds to the center of the simulation domain,
+         or 'center-window' for the center of the plot window. In the event
+         that none of these options place the origin in a desired location,
+         a sequence of tuples and a string specifying the
+         coordinate space can be given. If plain numeric types are input,
+         units of `code_length` are assumed. Further examples:
 
-         ==================================     ============================
-         format                                 example
-         ==================================     ============================
-         '{space}'                              'domain'
-         '{xloc}-{space}'                       'left-window'
-         '{yloc}-{space}'                       'upper-domain'
-         '{yloc}-{xloc}-{space}'                'lower-right-window'
-         ('{space}',)                           ('window',)
-         ('{xloc}', '{space}')                  ('right', 'domain')
-         ('{yloc}', '{space}')                  ('lower', 'window')
-         ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
-         ==================================     ============================
+         ==================================                ============================
+         format                                            example
+         ==================================                ============================
+         '{space}'                                          'domain'
+         '{xloc}-{space}'                                   'left-window'
+         '{yloc}-{space}'                                   'upper-domain'
+         '{yloc}-{xloc}-{space}'                            'lower-right-window'
+         ('{space}',)                                       ('window',)
+         ('{xloc}', '{space}')                              ('right', 'domain')
+         ('{yloc}', '{space}')                              ('lower', 'window')
+         ('{yloc}', '{xloc}', '{space}')                    ('lower', 'right', 'window')
+         ((yloc, '{unit}'), (xloc, '{unit}'), '{space}')    ((0.5, 'm'), (0.4, 'm'), 'window')
+         (xloc, yloc, '{space}')                            (0.23, 0.5, 'domain')
+         ==================================                 ============================
+
     right_handed : boolean
          Whether the implicit east vector for the image generated is set to make a right
          handed coordinate system with the direction of the
@@ -1392,13 +1430,13 @@
 
          "mip" : pick out the maximum value of the field in the line of sight.
 
-         "sum" : This method is the same as integrate, except that it does not 
-         multiply by a path length when performing the integration, and is 
+         "sum" : This method is the same as integrate, except that it does not
+         multiply by a path length when performing the integration, and is
          just a straight summation of the field along the given axis. WARNING:
          This should only be used for uniform resolution grid datasets, as other
          datasets may result in unphysical images.
     proj_style : string
-         The method of projection--same as method keyword.  Deprecated as of 
+         The method of projection--same as method keyword.  Deprecated as of
          version 3.0.2.  Please use method instead.
     window_size : float
          The size of the window in inches. Set to 8 by default.
@@ -1841,35 +1879,40 @@
          Defaults to None, which automatically picks an appropriate unit.
          If axes_unit is '1', 'u', or 'unitary', it will not display the
          units, and only show the axes name.
-    origin : string or length 1, 2, or 3 sequence of strings
+    origin : string or length 1, 2, or 3 sequence.
          The location of the origin of the plot coordinate system for
-         `AxisAlignedSlicePlot` objects; for `OffAxisSlicePlot` objects,
-         this parameter is discarded.  This is represented by '-' separated
-         string or a tuple of strings.  In the first index the y-location is
-         given by 'lower', 'upper', or 'center'.  The second index is the
-         x-location, given as 'left', 'right', or 'center'.  Finally,
-         whether the origin is applied in 'domain' space, plot 'window' space
-         or 'native' simulation coordinate system is given. For example, both
+         `AxisAlignedSlicePlot` object; for `OffAxisSlicePlot` objects this
+         parameter is discarded. This is typically represented by a '-'
+         separated string or a tuple of strings. In the first index the
+         y-location is given by 'lower', 'upper', or 'center'. The second index
+         is the x-location, given as 'left', 'right', or 'center'. Finally, the
+         whether the origin is applied in 'domain' space, plot 'window' space or
+         'native' simulation coordinate system is given. For example, both
          'upper-right-domain' and ['upper', 'right', 'domain'] place the
-         origin in the upper right hand corner of domain space. If x or y are
-         not given, a value is inferred.  For instance, 'left-domain'
+         origin in the upper right hand corner of domain space. If x or y
+         are not given, a value is inferred. For instance, 'left-domain'
          corresponds to the lower-left hand corner of the simulation domain,
          'center-domain' corresponds to the center of the simulation domain,
-         or 'center-window' for the center of the plot window. Further
-         examples:
+         or 'center-window' for the center of the plot window. In the event
+         that none of these options place the origin in a desired location,
+         a sequence of tuples and a string specifying the
+         coordinate space can be given. If plain numeric types are input,
+         units of `code_length` are assumed. Further examples:
 
-         ==================================     ============================
-         format                                 example
-         ==================================     ============================
-         '{space}'                              'domain'
-         '{xloc}-{space}'                       'left-window'
-         '{yloc}-{space}'                       'upper-domain'
-         '{yloc}-{xloc}-{space}'                'lower-right-window'
-         ('{space}',)                           ('window',)
-         ('{xloc}', '{space}')                  ('right', 'domain')
-         ('{yloc}', '{space}')                  ('lower', 'window')
-         ('{yloc}', '{xloc}', '{space}')        ('lower', 'right', 'window')
-         ==================================     ============================
+         ==================================                ============================
+         format                                            example
+         ==================================                ============================
+         '{space}'                                          'domain'
+         '{xloc}-{space}'                                   'left-window'
+         '{yloc}-{space}'                                   'upper-domain'
+         '{yloc}-{xloc}-{space}'                            'lower-right-window'
+         ('{space}',)                                       ('window',)
+         ('{xloc}', '{space}')                              ('right', 'domain')
+         ('{yloc}', '{space}')                              ('lower', 'window')
+         ('{yloc}', '{xloc}', '{space}')                    ('lower', 'right', 'window')
+         ((yloc, '{unit}'), (xloc, '{unit}'), '{space}')    ((0.5, 'm'), (0.4, 'm'), 'window')
+         (xloc, yloc, '{space}')                            (0.23, 0.5, 'domain')
+         ==================================                 ============================
     north_vector : a sequence of floats
         A vector defining the 'up' direction in the `OffAxisSlicePlot`; not
         used in `AxisAlignedSlicePlot`.  This option sets the orientation of the

diff -r 4bc8ace93fda81e800a2e90c052c431c2d48a01b -r 7e7c3fdd9cc79e65a179d277ae64b345dc30411f yt/visualization/tests/test_plotwindow.py
--- a/yt/visualization/tests/test_plotwindow.py
+++ b/yt/visualization/tests/test_plotwindow.py
@@ -444,6 +444,44 @@
             assert_raises(
                 YTInvalidFieldType, object, ds, normal, field_name_list)
 
+def test_setup_origin():
+    origin_inputs = ('domain',
+                     'left-window',
+                     'center-domain',
+                     'lower-right-window',
+                     ('window',),
+                     ('right', 'domain'),
+                     ('lower', 'window'),
+                     ('lower', 'right', 'window'),
+                     (0.5, 0.5, 'domain'),
+                     ((50, 'cm'), (50, 'cm'), 'domain'))
+    w=(10, 'cm')
+
+    ds = fake_random_ds(32, length_unit=100.0)
+    generated_limits = []
+    #lower limit -> llim
+    #upper limit -> ulim
+    #                 xllim xulim yllim yulim
+    correct_limits = [45.0, 55.0, 45.0, 55.0,
+                      0.0, 10.0, 0.0, 10.0,
+                      -5.0, 5.0, -5.0, 5.0,
+                      -10.0, 0, 0, 10.0,
+                      0.0, 10.0, 0.0, 10.0,
+                      -55.0, -45.0, -55.0, -45.0,
+                      -5.0, 5.0, 0.0, 10.0,
+                      -10.0, 0, 0, 10.0,
+                      -5.0, 5.0, -5.0, 5.0,
+                      -5.0, 5.0, -5.0, 5.0
+                      ]
+    for o in origin_inputs:
+        slc = SlicePlot(ds, 2, 'density', width=w, origin=o)
+        ax = slc.plots['density'].axes
+        xlims = ax.get_xlim()
+        ylims = ax.get_ylim()
+        lims = [xlims[0], xlims[1], ylims[0], ylims[1]]
+        for l in lims:
+            generated_limits.append(l)
+    assert_array_almost_equal(correct_limits, generated_limits)
 
 def test_frb_regen():
     ds = fake_random_ds(32)

Repository URL: https://bitbucket.org/yt_analysis/yt/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.



More information about the yt-svn mailing list