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

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Mon Jan 12 13:09:50 PST 2015


33 new commits in yt:

https://bitbucket.org/yt_analysis/yt/commits/4fe1f8b3247a/
Changeset:   4fe1f8b3247a
Branch:      yt
User:        cosmosquark
Date:        2014-11-18 01:33:11+00:00
Summary:     particle_io.py edited online to fix the disk handler for radius and height
Affected #:  1 file

diff -r 6b9ada3a86ad7c86171132650c032e4d157f8f79 -r 4fe1f8b3247abeeb347e4b0521904793658d7734 yt/data_objects/particle_io.py
--- a/yt/data_objects/particle_io.py
+++ b/yt/data_objects/particle_io.py
@@ -134,8 +134,8 @@
     def __init__(self, ds, source):
         self.center = source.center
         self.normal = source._norm_vec
-        self.radius = source._radius
-        self.height = source._height
+        self.radius = source.radius
+        self.height = source.height
         ParticleIOHandler.__init__(self, ds, source)
     
     def _get_args(self):


https://bitbucket.org/yt_analysis/yt/commits/233add1e382a/
Changeset:   233add1e382a
Branch:      yt
User:        cosmosquark
Date:        2014-11-18 01:36:48+00:00
Summary:     particle_fields.py edited online with Bitbucket
Affected #:  1 file

diff -r 4fe1f8b3247abeeb347e4b0521904793658d7734 -r 233add1e382a8b0c60f01915c1f0e398f280f49a yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -521,6 +521,28 @@
               particle_type=True, units="cm/s",
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
+                          
+    def _particle_cylindrical_r(field, data):
+        normal = data.get_field_parameter("normal")
+        return get_cyl_r((data["particle_position"].T, normal), "code_length").in_cgs()
+
+    registry.add_field((ptype, "particle_cylindrical_r"),
+              function=_particle_cylindrical_r,
+              validators=[ValidateParameter("normal")],
+                          display_name = "Particle Cylindrical R",
+              units="cm", particle_type = True)
+
+    def _particle_cylindrical_z(field, data):
+        normal = data.get_field_parameter("normal")
+        return get_cyl_z((data["particle_position"].T,normal), "code_length").in_cgs()
+
+    registry.add_field((ptype, "particle_cylindrical_z"),
+              function=_particle_cylindrical_z,
+              validators=[ValidateParameter("center"),
+                          ValidateParameter("normal")],
+                          display_name = "Particle Cylindrical Z",
+              units="cm", particle_type = True)
+
 
 def add_particle_average(registry, ptype, field_name, 
                          weight = "particle_mass",


https://bitbucket.org/yt_analysis/yt/commits/1461447a5f80/
Changeset:   1461447a5f80
Branch:      yt
User:        cosmosquark
Date:        2014-11-18 01:53:58+00:00
Summary:     particle_fields.py edited online with Bitbucket
Affected #:  1 file

diff -r 233add1e382a8b0c60f01915c1f0e398f280f49a -r 1461447a5f80c7d03daf452ef906596e060ce0ec yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -522,9 +522,10 @@
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
                           
+
     def _particle_cylindrical_r(field, data):
         normal = data.get_field_parameter("normal")
-        return get_cyl_r((data["particle_position"].T, normal), "code_length").in_cgs()
+        return get_cyl_r(data["particle_position"].T, normal)
 
     registry.add_field((ptype, "particle_cylindrical_r"),
               function=_particle_cylindrical_r,
@@ -534,7 +535,7 @@
 
     def _particle_cylindrical_z(field, data):
         normal = data.get_field_parameter("normal")
-        return get_cyl_z((data["particle_position"].T,normal), "code_length").in_cgs()
+        return get_cyl_z(data["particle_position"].T,normal)
 
     registry.add_field((ptype, "particle_cylindrical_z"),
               function=_particle_cylindrical_z,
@@ -544,6 +545,7 @@
               units="cm", particle_type = True)
 
 
+
 def add_particle_average(registry, ptype, field_name, 
                          weight = "particle_mass",
                          density = True):


https://bitbucket.org/yt_analysis/yt/commits/07be288b76ff/
Changeset:   07be288b76ff
Branch:      yt
User:        cosmosquark
Date:        2014-11-18 02:37:35+00:00
Summary:     cylindrical_r and cylindrical_z now works for particles
Affected #:  1 file

diff -r 1461447a5f80c7d03daf452ef906596e060ce0ec -r 07be288b76ff31dddec933962b06ab7710619cce yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -525,7 +525,8 @@
 
     def _particle_cylindrical_r(field, data):
         normal = data.get_field_parameter("normal")
-        return get_cyl_r(data["particle_position"].T, normal)
+        return data.ds.arr(get_cyl_r(data["particle_position"].T, normal),
+                           'code_length')
 
     registry.add_field((ptype, "particle_cylindrical_r"),
               function=_particle_cylindrical_r,
@@ -535,7 +536,8 @@
 
     def _particle_cylindrical_z(field, data):
         normal = data.get_field_parameter("normal")
-        return get_cyl_z(data["particle_position"].T,normal)
+        return data.ds.arr(get_cyl_z(data["particle_position"].T, normal),
+                           'code_length')
 
     registry.add_field((ptype, "particle_cylindrical_z"),
               function=_particle_cylindrical_z,
@@ -546,6 +548,7 @@
 
 
 
+
 def add_particle_average(registry, ptype, field_name, 
                          weight = "particle_mass",
                          density = True):


https://bitbucket.org/yt_analysis/yt/commits/7af1e4675957/
Changeset:   7af1e4675957
Branch:      yt
User:        cosmosquark
Date:        2014-11-18 03:09:37+00:00
Summary:     positions should now be relative to the centre of each data object,
Affected #:  1 file

diff -r 07be288b76ff31dddec933962b06ab7710619cce -r 7af1e467595765cffb93d57709a8ffe27d94b6ce yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -525,9 +525,12 @@
 
     def _particle_cylindrical_r(field, data):
         normal = data.get_field_parameter("normal")
-        return data.ds.arr(get_cyl_r(data["particle_position"].T, normal),
+        center = data.get_field_parameter('center')
+        pos = YTArray([data[ptype, spos % ax] for ax in "xyz"])
+        pos = pos - np.reshape(center, (3, 1))
+        return data.ds.arr(get_cyl_r(pos, normal),
                            'code_length')
-
+                           
     registry.add_field((ptype, "particle_cylindrical_r"),
               function=_particle_cylindrical_r,
               validators=[ValidateParameter("normal")],
@@ -536,9 +539,13 @@
 
     def _particle_cylindrical_z(field, data):
         normal = data.get_field_parameter("normal")
-        return data.ds.arr(get_cyl_z(data["particle_position"].T, normal),
+        center = data.get_field_parameter('center')
+        pos = YTArray([data[ptype, spos % ax] for ax in "xyz"])
+        pos = pos - np.reshape(center, (3, 1))
+        return data.ds.arr(get_cyl_z(pos,normal),
                            'code_length')
 
+
     registry.add_field((ptype, "particle_cylindrical_z"),
               function=_particle_cylindrical_z,
               validators=[ValidateParameter("center"),


https://bitbucket.org/yt_analysis/yt/commits/ff1845163637/
Changeset:   ff1845163637
Branch:      yt
User:        cosmosquark
Date:        2014-12-03 00:35:08+00:00
Summary:     Merged yt_analysis/yt into yt
Affected #:  53 files

diff -r 7af1e467595765cffb93d57709a8ffe27d94b6ce -r ff1845163637262a67025ea82fd77361bb7854a5 .hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -9,6 +9,7 @@
 yt/frontends/artio/_artio_caller.c
 yt/analysis_modules/halo_finding/rockstar/rockstar_groupies.c
 yt/analysis_modules/halo_finding/rockstar/rockstar_interface.c
+yt/analysis_modules/ppv_cube/ppv_utils.c
 yt/frontends/ramses/_ramses_reader.cpp
 yt/frontends/sph/smoothing_kernel.c
 yt/geometry/fake_octree.c

diff -r 7af1e467595765cffb93d57709a8ffe27d94b6ce -r ff1845163637262a67025ea82fd77361bb7854a5 CREDITS
--- a/CREDITS
+++ b/CREDITS
@@ -16,12 +16,14 @@
                 Sam Geen (samgeen at gmail.com)
                 Nathan Goldbaum (goldbaum at ucolick.org)
                 Markus Haider (markus.haider at uibk.ac.at)
+                Eric Hallman (hallman13 at gmail.com)
                 Cameron Hummels (chummels at gmail.com)
                 Christian Karch (chiffre at posteo.de)
                 Ben W. Keller (kellerbw at mcmaster.ca)
                 Ji-hoon Kim (me at jihoonkim.org)
                 Steffen Klemer (sklemer at phys.uni-goettingen.de)
                 Kacper Kowalik (xarthisius.kk at gmail.com)
+                Mark Krumholz (mkrumhol at ucsc.edu)
                 Michael Kuhlen (mqk at astro.berkeley.edu)
                 Eve Lee (elee at cita.utoronto.ca)
                 Sam Leitner (sam.leitner at gmail.com)
@@ -38,6 +40,7 @@
                 Brian O'Shea (bwoshea at gmail.com)
                 Jean-Claude Passy (jcpassy at uvic.ca)
                 John Regan (john.regan at helsinki.fi)
+                Sherwood Richers (srichers at tapir.caltech.edu)
                 Mark Richardson (Mark.L.Richardson at asu.edu)
                 Thomas Robitaille (thomas.robitaille at gmail.com)
                 Anna Rosen (rosen at ucolick.org)
@@ -48,10 +51,14 @@
                 Devin Silvia (devin.silvia at gmail.com)
                 Sam Skillman (samskillman at gmail.com)
                 Stephen Skory (s at skory.us)
+                Aaron Smith (asmith at astro.as.utexas.edu)
                 Britton Smith (brittonsmith at gmail.com)
                 Geoffrey So (gsiisg at gmail.com)
                 Casey Stark (caseywstark at gmail.com)
+                Antoine Strugarek (strugarek at astro.umontreal.ca)
+                Ji Suoqing (jisuoqing at gmail.com)
                 Elizabeth Tasker (tasker at astro1.sci.hokudai.ac.jp)
+                Benjamin Thompson (bthompson2090 at gmail.com)
                 Stephanie Tonnesen (stonnes at gmail.com)
                 Matthew Turk (matthewturk at gmail.com)
                 Rich Wagner (rwagner at physics.ucsd.edu)

diff -r 7af1e467595765cffb93d57709a8ffe27d94b6ce -r ff1845163637262a67025ea82fd77361bb7854a5 doc/helper_scripts/show_fields.py
--- a/doc/helper_scripts/show_fields.py
+++ b/doc/helper_scripts/show_fields.py
@@ -38,7 +38,7 @@
 np.random.seed(int(0x4d3d3d3))
 units = [base_ds._get_field_info(*f).units for f in fields]
 fields = [_strip_ftype(f) for f in fields]
-ds = fake_random_ds(16, fields = fields, units = units)
+ds = fake_random_ds(16, fields=fields, units=units, particles=True)
 ds.parameters["HydroMethod"] = "streaming"
 ds.parameters["EOSType"] = 1.0
 ds.parameters["EOSSoundSpeed"] = 1.0
@@ -163,22 +163,25 @@
 ds.index
 print_all_fields(ds.field_info)
 
-def print_frontend_field(ftype, field, ptype):
-    name = field[0]
-    units = field[1][0]
-    aliases = ["``%s``" % f for f in field[1][1]]
-    if ftype is not "particle_type":
-        ftype = "'"+ftype+"'"
-    s = "(%s, '%s')" % (ftype, name)
-    print s
-    print "^" * len(s)
-    print
-    if len(units) > 0:
-        print "   * Units: :math:`\mathrm{%s}`" % fix_units(units)
-    if len(aliases) > 0:
-        print "   * Aliased to: %s" % " ".join(aliases)
-    print "   * Particle Type: %s" % (ptype)
-    print
+
+class FieldInfo:
+    """ a simple container to hold the information about fields """
+    def __init__(self, ftype, field, ptype):
+        name = field[0]
+        self.units = ""
+        u = field[1][0]
+        if len(u) > 0:
+            self.units = ":math:`\mathrm{%s}`" % fix_units(u)
+        a = ["``%s``" % f for f in field[1][1]]
+        self.aliases = " ".join(a)
+        self.dname = ""
+        if field[1][2] is not None:
+            self.dname = ":math:`{}`".format(field[1][2])
+
+        if ftype is not "particle_type":
+            ftype = "'"+ftype+"'"
+        self.name = "(%s, '%s')" % (ftype, name)
+        self.ptype = ptype
 
 current_frontends = [f for f in _frontends if f not in ["stream"]]
 
@@ -187,9 +190,11 @@
     field_info_names = [fi for fi in dir(this_f) if "FieldInfo" in fi]
     dataset_names = [dset for dset in dir(this_f) if "Dataset" in dset]
 
-    if frontend == "sph":
-        field_info_names = \
-          ['TipsyFieldInfo' if 'Tipsy' in d else 'SPHFieldInfo' for d in dataset_names]
+    if frontend == "gadget":
+        # Drop duplicate entry for GadgetHDF5, add special case for FieldInfo
+        # entry
+        dataset_names = ['GadgetDataset']
+        field_info_names = ['SPHFieldInfo']
     elif frontend == "boxlib":
         field_info_names = []
         for d in dataset_names:
@@ -220,12 +225,51 @@
             h = "%s-Specific Fields" % dset_name.replace("Dataset", "")
             print h
             print "-" * len(h) + "\n"
+
+            field_stuff = []
             for field in known_other_fields:
-                print_frontend_field(frontend, field, False)
+                field_stuff.append(FieldInfo(frontend, field, False))
             for field in known_particle_fields:
                 if frontend in ["sph", "halo_catalogs", "sdf"]:
-                    print_frontend_field("particle_type", field, True)
+                    field_stuff.append(FieldInfo("particle_type", field, True))
                 else:
-                    print_frontend_field("io", field, True)
+                    field_stuff.append(FieldInfo("io", field, True))
+
+            # output
+            len_name = 10
+            len_units = 5
+            len_aliases = 7
+            len_part = 9
+            len_disp = 12
+            for f in field_stuff:
+                len_name = max(len_name, len(f.name))
+                len_aliases = max(len_aliases, len(f.aliases))
+                len_units = max(len_units, len(f.units))
+                len_disp = max(len_disp, len(f.dname))
+
+            fstr = "{nm:{nw}}  {un:{uw}}  {al:{aw}}  {pt:{pw}}  {dp:{dw}}"
+            header = fstr.format(nm="field name", nw=len_name,
+                                 un="units", uw=len_units,
+                                 al="aliases", aw=len_aliases,
+                                 pt="particle?", pw=len_part,
+                                 dp="display name", dw=len_disp)
+
+            div = fstr.format(nm="="*len_name, nw=len_name,
+                              un="="*len_units, uw=len_units,
+                              al="="*len_aliases, aw=len_aliases,
+                              pt="="*len_part, pw=len_part,
+                              dp="="*len_disp, dw=len_disp)
+            print div
+            print header
+            print div
+
+            for f in field_stuff:
+                print fstr.format(nm=f.name, nw=len_name,
+                                  un=f.units, uw=len_units,
+                                  al=f.aliases, aw=len_aliases,
+                                  pt=f.ptype, pw=len_part,
+                                  dp=f.dname, dw=len_disp)
+                
+            print div
 
 print footer

diff -r 7af1e467595765cffb93d57709a8ffe27d94b6ce -r ff1845163637262a67025ea82fd77361bb7854a5 doc/source/analyzing/analysis_modules/_images/dsquared.png
Binary file doc/source/analyzing/analysis_modules/_images/dsquared.png has changed

diff -r 7af1e467595765cffb93d57709a8ffe27d94b6ce -r ff1845163637262a67025ea82fd77361bb7854a5 doc/source/analyzing/analysis_modules/photon_simulator.rst
--- a/doc/source/analyzing/analysis_modules/photon_simulator.rst
+++ b/doc/source/analyzing/analysis_modules/photon_simulator.rst
@@ -46,17 +46,23 @@
 .. code:: python
 
     import yt
+    #yt.enable_parallelism() # If you want to run in parallel this should go here!
     from yt.analysis_modules.photon_simulator.api import *
     from yt.utilities.cosmology import Cosmology
 
+.. note::
+
+    For parallel runs using ``mpi4py``, the call to ``yt.enable_parallelism`` should go *before*
+    the import of the ``photon_simulator`` module, as shown above.
+
 We're going to load up an Athena dataset of a galaxy cluster core:
 
 .. code:: python
 
     ds = yt.load("MHDSloshing/virgo_low_res.0054.vtk",
-                 parameters={"time_unit":(1.0,"Myr"),
-                            "length_unit":(1.0,"Mpc"),
-                            "mass_unit":(1.0e14,"Msun")}) 
+                 units_override={"time_unit":(1.0,"Myr"),
+                                 "length_unit":(1.0,"Mpc"),
+                                 "mass_unit":(1.0e14,"Msun")})
 
 First, to get a sense of what the resulting image will look like, let's
 make a new yt field called ``"density_squared"``, since the X-ray
@@ -67,7 +73,7 @@
 
     def _density_squared(field, data):
         return data["density"]**2
-    add_field("density_squared", function=_density_squared)
+    ds.add_field("density_squared", function=_density_squared, units="g**2/cm**6")
 
 Then we'll project this field along the z-axis.
 
@@ -141,7 +147,8 @@
 
 .. code:: python
 
-    thermal_model = ThermalPhotonModel(apec_model, X_H=0.75, Zmet=0.3)
+    thermal_model = ThermalPhotonModel(apec_model, X_H=0.75, Zmet=0.3,
+                                       photons_per_chunk=100000000)
 
 Where we pass in the ``SpectralModel``, and can optionally set values for
 the hydrogen mass fraction ``X_H`` and metallicity ``Z_met``. If
@@ -150,6 +157,14 @@
 assume that is the name of the metallicity field (which may be spatially
 varying).
 
+The ``ThermalPhotonModel`` iterates over "chunks" of the supplied data source
+to generate the photons, to reduce memory usage and make parallelization more
+efficient. For each chunk, memory is set aside for the photon energies that will
+be generated. ``photons_per_chunk`` is an optional keyword argument which controls
+the size of this array. For large numbers of photons, you may find that
+this parameter needs to be set higher, or if you are looking to decrease memory
+usage, you might set this parameter lower.
+
 Next, we need to specify "fiducial" values for the telescope collecting
 area, exposure time, and cosmological redshift. Remember, the initial
 photon generation will act as a source for Monte-Carlo sampling for more
@@ -294,11 +309,11 @@
             187.49897546,  187.47307048]) degree, 
      'ysky': YTArray([ 12.33519996,  12.3544496 ,  12.32750903, ...,  12.34907707,
             12.33327653,  12.32955225]) degree, 
-     'ypix': YTArray([ 133.85374195,  180.68583074,  115.14110561, ...,  167.61447493,
-            129.17278711,  120.11508562]) (dimensionless), 
+     'ypix': array([ 133.85374195,  180.68583074,  115.14110561, ...,  167.61447493,
+            129.17278711,  120.11508562]), 
      'PI': array([ 27,  15,  25, ..., 609, 611, 672]), 
-     'xpix': YTArray([  86.26331108,  155.15934197,  111.06337043, ...,  114.39586907,
-            130.93509652,  192.50639633]) (dimensionless)}
+     'xpix': array([  86.26331108,  155.15934197,  111.06337043, ...,  114.39586907,
+            130.93509652,  192.50639633])}
 
 
 We can bin up the events into an image and save it to a FITS file. The
@@ -368,14 +383,23 @@
    files in subtle ways that we haven't been able to identify. Please email
    jzuhone at gmail.com if you find any bugs!
 
-Two ``EventList`` instances can be joined togther like this:
+Two ``EventList`` instances can be added together, which is useful if they were
+created using different data sources:
 
 .. code:: python
 
-    events3 = EventList.join_events(events1, events2)
+    events3 = events1+events2
 
-**WARNING**: This doesn't check for parameter consistency between the
-two lists!
+.. warning:: This only works if the two event lists were generated using
+    the same parameters!
+
+Finally, a new ``EventList`` can be created from a subset of an existing ``EventList``,
+defined by a ds9 region (this functionality requires the
+`pyregion <http://pyregion.readthedocs.org>`_ package to be installed):
+
+.. code:: python
+
+    circle_events = events.filter_events("circle.reg")
 
 Creating a X-ray observation from an in-memory dataset
 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -434,11 +458,11 @@
 .. code:: python
 
    data = {}
-   data["density"] = dens
-   data["temperature"] = temp
-   data["velocity_x"] = np.zeros(ddims)
-   data["velocity_y"] = np.zeros(ddims)
-   data["velocity_z"] = np.zeros(ddims)
+   data["density"] = (dens, "g/cm**3")
+   data["temperature"] = (temp, "K")
+   data["velocity_x"] = (np.zeros(ddims), "cm/s")
+   data["velocity_y"] = (np.zeros(ddims), "cm/s")
+   data["velocity_z"] = (np.zeros(ddims), "cm/s")
 
    bbox = np.array([[-0.5,0.5],[-0.5,0.5],[-0.5,0.5]])
 
@@ -451,7 +475,7 @@
 
 .. code:: python
 
-   sphere = ds.sphere(ds.domain_center, (1.0,"Mpc"))
+   sphere = ds.sphere("c", (1.0,"Mpc"))
        
    A = 6000.
    exp_time = 2.0e5

diff -r 7af1e467595765cffb93d57709a8ffe27d94b6ce -r ff1845163637262a67025ea82fd77361bb7854a5 doc/source/analyzing/filtering.rst
--- a/doc/source/analyzing/filtering.rst
+++ b/doc/source/analyzing/filtering.rst
@@ -193,7 +193,15 @@
     center = [0.20, 0.50, 0.10]
 
     sp = ds.sphere(center, (10, 'Mpc'))
-    prj = yt.ProjectionPlot(ds, "x", "density", center=center, width=(50, "Mpc"), data_source=sp)
+    prj = yt.ProjectionPlot(ds, "x", "density", center=center, width=(50, "Mpc"),
+                            data_source=sp)
 
     # Mark the center with a big X
     prj.annotate_marker(center, 'x', plot_args={'s':100})
+
+    prj.show()
+
+    slc = yt.SlicePlot(ds, "x", "density", center=c, width=(50, "Mpc"),
+                       data_source=sp)
+
+    slc.show()

diff -r 7af1e467595765cffb93d57709a8ffe27d94b6ce -r ff1845163637262a67025ea82fd77361bb7854a5 doc/source/analyzing/mesh_filter.ipynb
--- a/doc/source/analyzing/mesh_filter.ipynb
+++ b/doc/source/analyzing/mesh_filter.ipynb
@@ -1,7 +1,16 @@
 {
  "metadata": {
+  "kernelspec": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 2
+   },
+   "display_name": "IPython (Python 2)",
+   "language": "python",
+   "name": "python2"
+  },
   "name": "",
-  "signature": "sha256:9e2b7844e9b6e998eafb1c8a2aacaa8419e6e544aacee754449ad4b0dfea1d85"
+  "signature": "sha256:e7a3de4de9be6a2c653bc45ed2c7ef5fa19da15aafca165d331a3125befe4d6c"
  },
  "nbformat": 3,
  "nbformat_minor": 0,
@@ -41,7 +50,10 @@
      "input": [
       "ad = ds.all_data()\n",
       "hot_ad = ad.cut_region([\"obj['temperature'] > 1e6\"])\n",
-      "dense_ad = ad.cut_region(['obj[\"density\"] > 1e-29'])\n",
+      "dense_ad = ad.cut_region(['obj[\"density\"] > 5e-30'])\n",
+      "\n",
+      "# you can chain cut regions in two ways:\n",
+      "dense_and_cool_ad = dense_ad.cut_region([\"obj['temperature'] < 1e5\"])\n",
       "overpressure_and_fast_ad = ad.cut_region(['(obj[\"pressure\"] > 1e-14) & (obj[\"velocity_magnitude\"].in_units(\"km/s\") > 1e2)'])"
      ],
      "language": "python",
@@ -59,8 +71,19 @@
      "cell_type": "code",
      "collapsed": false,
      "input": [
-      "print 'Temperature of all data: ad[\"temperature\"] = \\n%s' % ad[\"temperature\"] \n",
-      "print 'Temperature of \"hot\" data: hot_ad[\"temperature\"] = \\n%s' % hot_ad['temperature']"
+      "print \"Temperature of all cells:\\n ad['temperature'] = \\n%s\\n\" % ad[\"temperature\"] \n",
+      "print \"Temperatures of all \\\"hot\\\" cells:\\n hot_ad['temperature'] = \\n%s\" % hot_ad['temperature']"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "print \"Density of dense, cool material:\\n dense_and_cool_ad['density'] = \\n%s\\n\" % dense_and_cool_ad['density']\n",
+      "print \"Temperature of dense, cool material:\\n dense_and_cool_ad['temperature'] = \\n%s\" % dense_and_cool_ad['temperature']"
      ],
      "language": "python",
      "metadata": {},
@@ -70,16 +93,52 @@
      "cell_type": "markdown",
      "metadata": {},
      "source": [
-      "However, now we can use this cut_region object as a data source in generated Projections or Profiles or any other number of tasks.  Let's look at a density projection of the densest material, or the material which is overpressure and hot."
+      "Now that we've constructed a `cut_region`, we can use it as a data source for further analysis. To create a plot based on a `cut_region`, use the `data_source` keyword argument provided by yt's plotting objects.\n",
+      "\n",
+      "Here's an example using projections:"
      ]
     },
     {
      "cell_type": "code",
      "collapsed": false,
      "input": [
-      "proj = yt.ProjectionPlot(ds, 'x', \"density\", weight_field=\"density\")\n",
-      "proj.annotate_title('All Data, No Cuts')\n",
-      "proj.show()"
+      "proj1 = yt.ProjectionPlot(ds, 'x', \"density\", weight_field=\"density\")\n",
+      "proj1.annotate_title('No Cuts')\n",
+      "proj1.set_figure_size(5)\n",
+      "proj1.show()\n",
+      "\n",
+      "proj2 = yt.ProjectionPlot(ds, 'x', \"density\", weight_field=\"density\", data_source=hot_ad)\n",
+      "proj2.annotate_title('Hot Gas')\n",
+      "proj2.set_zlim(\"density\", 3e-31, 3e-27)\n",
+      "proj2.set_figure_size(5)\n",
+      "proj2.show()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "The `data_source` keyword argument is also accepted by `SlicePlot`, `ProfilePlot` and `PhasePlot`:"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "slc1 = yt.SlicePlot(ds, 'x', \"density\", center='m')\n",
+      "slc1.set_zlim('density', 3e-31, 3e-27)\n",
+      "slc1.annotate_title('No Cuts')\n",
+      "slc1.set_figure_size(5)\n",
+      "slc1.show()\n",
+      "\n",
+      "slc2 = yt.SlicePlot(ds, 'x', \"density\", center='m', data_source=dense_ad)\n",
+      "slc2.set_zlim('density', 3e-31, 3e-27)\n",
+      "slc2.annotate_title('Dense Gas')\n",
+      "slc2.set_figure_size(5)\n",
+      "slc2.show()"
      ],
      "language": "python",
      "metadata": {},
@@ -89,23 +148,17 @@
      "cell_type": "code",
      "collapsed": false,
      "input": [
-      "proj = yt.ProjectionPlot(ds, 'x', \"density\", weight_field=\"density\", data_source=dense_ad)\n",
-      "proj.annotate_title('Only Dense Material')\n",
-      "proj.set_zlim(\"density\", 3e-31, 3e-27)\n",
-      "proj.show()"
-     ],
-     "language": "python",
-     "metadata": {},
-     "outputs": []
-    },
-    {
-     "cell_type": "code",
-     "collapsed": false,
-     "input": [
-      "proj = yt.ProjectionPlot(ds, 'x', \"density\", weight_field=\"density\", data_source=overpressure_and_fast_ad)\n",
-      "proj.annotate_title('Only Overpressure and Fast Material')\n",
-      "proj.set_zlim(\"density\", 3e-31, 3e-27)\n",
-      "proj.show()"
+      "ph1 = yt.PhasePlot(ad, 'density', 'temperature', 'cell_mass', weight_field=None)\n",
+      "ph1.set_xlim(3e-31, 3e-27)\n",
+      "ph1.set_title('cell_mass', 'No Cuts')\n",
+      "ph1.set_figure_size(5)\n",
+      "ph1.show()\n",
+      "\n",
+      "ph1 = yt.PhasePlot(dense_ad, 'density', 'temperature', 'cell_mass', weight_field=None)\n",
+      "ph1.set_xlim(3e-31, 3e-27)\n",
+      "ph1.set_title('cell_mass', 'Dense Gas')\n",
+      "ph1.set_figure_size(5)\n",
+      "ph1.show()"
      ],
      "language": "python",
      "metadata": {},

diff -r 7af1e467595765cffb93d57709a8ffe27d94b6ce -r ff1845163637262a67025ea82fd77361bb7854a5 doc/source/analyzing/units/unit_equivalencies.rst
--- a/doc/source/analyzing/units/unit_equivalencies.rst
+++ b/doc/source/analyzing/units/unit_equivalencies.rst
@@ -1,7 +1,7 @@
-.. _symbolic_units:
+.. _unit_equivalencies:
 
-Symbolic units: :code:`yt.units`
-================================
+Unit Equivalencies
+==================
 
 .. notebook:: 6)_Unit_Equivalencies.ipynb
    :skip_exceptions:

diff -r 7af1e467595765cffb93d57709a8ffe27d94b6ce -r ff1845163637262a67025ea82fd77361bb7854a5 doc/source/cookbook/Halo_Analysis.ipynb
--- a/doc/source/cookbook/Halo_Analysis.ipynb
+++ b/doc/source/cookbook/Halo_Analysis.ipynb
@@ -1,7 +1,7 @@
 {
  "metadata": {
   "name": "",
-  "signature": "sha256:c423bcb9e3370a4581cbaaa8e764b95ec13e665aa3b46d452891d76cc79d7acf"
+  "signature": "sha256:083fded18194cc4b6d9ebf6d04e24a7f1d90cf57831ff0155e99868c0ace73b7"
  },
  "nbformat": 3,
  "nbformat_minor": 0,
@@ -151,10 +151,10 @@
      "collapsed": false,
      "input": [
       "# use the sphere to calculate radial profiles of gas density weighted by cell volume in terms of the virial radius\n",
-      "hc.add_callback(\"profile\", x_field=\"radius\",\n",
-      "                y_fields=[(\"gas\", \"overdensity\")],\n",
+      "hc.add_callback(\"profile\", [\"radius\"],\n",
+      "                [(\"gas\", \"overdensity\")],\n",
       "                weight_field=\"cell_volume\", \n",
-      "                accumulation=False,\n",
+      "                accumulation=True,\n",
       "                storage=\"virial_quantities_profiles\")"
      ],
      "language": "python",

diff -r 7af1e467595765cffb93d57709a8ffe27d94b6ce -r ff1845163637262a67025ea82fd77361bb7854a5 doc/source/cookbook/halo_profiler.py
--- a/doc/source/cookbook/halo_profiler.py
+++ b/doc/source/cookbook/halo_profiler.py
@@ -21,7 +21,7 @@
 hc.add_callback("profile", ["radius"],
                 [("gas", "overdensity")],
                 weight_field="cell_volume",
-                accumulation=False,
+                accumulation=True,
                 storage="virial_quantities_profiles")
 
 

diff -r 7af1e467595765cffb93d57709a8ffe27d94b6ce -r ff1845163637262a67025ea82fd77361bb7854a5 doc/source/examining/loading_data.rst
--- a/doc/source/examining/loading_data.rst
+++ b/doc/source/examining/loading_data.rst
@@ -131,6 +131,22 @@
 ``("athena","density")``, ``("athena","velocity_x")``, ``("athena","cell_centered_B_x")``, will be
 in code units.
 
+Some 3D Athena outputs may have large grids (especially parallel datasets subsequently joined with
+the `join_vtk` script), and may benefit from being subdivided into "virtual grids". For this purpose,
+one can pass in the `nprocs` parameter:
+
+.. code-block:: python
+
+   import yt
+
+   ds = yt.load("sloshing.0000.vtk", nprocs=8)
+
+which will subdivide each original grid into `nprocs` grids.
+
+.. note::
+
+    Virtual grids are only supported (and really only necessary) for 3D data.
+
 Alternative values for the following simulation parameters may be specified using a ``parameters``
 dict, accepting the following keys:
 

diff -r 7af1e467595765cffb93d57709a8ffe27d94b6ce -r ff1845163637262a67025ea82fd77361bb7854a5 doc/source/reference/api/api.rst
--- a/doc/source/reference/api/api.rst
+++ b/doc/source/reference/api/api.rst
@@ -283,19 +283,19 @@
 .. autosummary::
    :toctree: generated/
 
-   ~yt.frontends.halo_catalogs.halo_catalog.data_structures.HaloCatalogHDF5File
-   ~yt.frontends.halo_catalogs.halo_catalog.data_structures.HaloCatalogDataset
-   ~yt.frontends.halo_catalogs.halo_catalog.fields.HaloCatalogFieldInfo
-   ~yt.frontends.halo_catalogs.halo_catalog.io.IOHandlerHaloCatalogHDF5
-   ~yt.frontends.halo_catalogs.owls_subfind.data_structures.OWLSSubfindParticleIndex
-   ~yt.frontends.halo_catalogs.owls_subfind.data_structures.OWLSSubfindHDF5File
-   ~yt.frontends.halo_catalogs.owls_subfind.data_structures.OWLSSubfindDataset
-   ~yt.frontends.halo_catalogs.owls_subfind.fields.OWLSSubfindFieldInfo
-   ~yt.frontends.halo_catalogs.owls_subfind.io.IOHandlerOWLSSubfindHDF5
-   ~yt.frontends.halo_catalogs.rockstar.data_structures.RockstarBinaryFile
-   ~yt.frontends.halo_catalogs.rockstar.data_structures.RockstarDataset
-   ~yt.frontends.halo_catalogs.rockstar.fields.RockstarFieldInfo
-   ~yt.frontends.halo_catalogs.rockstar.io.IOHandlerRockstarBinary
+   ~yt.frontends.halo_catalog.data_structures.HaloCatalogHDF5File
+   ~yt.frontends.halo_catalog.data_structures.HaloCatalogDataset
+   ~yt.frontends.halo_catalog.fields.HaloCatalogFieldInfo
+   ~yt.frontends.halo_catalog.io.IOHandlerHaloCatalogHDF5
+   ~yt.frontends.owls_subfind.data_structures.OWLSSubfindParticleIndex
+   ~yt.frontends.owls_subfind.data_structures.OWLSSubfindHDF5File
+   ~yt.frontends.owls_subfind.data_structures.OWLSSubfindDataset
+   ~yt.frontends.owls_subfind.fields.OWLSSubfindFieldInfo
+   ~yt.frontends.owls_subfind.io.IOHandlerOWLSSubfindHDF5
+   ~yt.frontends.rockstar.data_structures.RockstarBinaryFile
+   ~yt.frontends.rockstar.data_structures.RockstarDataset
+   ~yt.frontends.rockstar.fields.RockstarFieldInfo
+   ~yt.frontends.rockstar.io.IOHandlerRockstarBinary
 
 MOAB
 ^^^^
@@ -331,21 +331,21 @@
 .. autosummary::
    :toctree: generated/
 
-   ~yt.frontends.sph.data_structures.GadgetBinaryFile
-   ~yt.frontends.sph.data_structures.GadgetHDF5Dataset
-   ~yt.frontends.sph.data_structures.GadgetDataset
-   ~yt.frontends.sph.data_structures.HTTPParticleFile
-   ~yt.frontends.sph.data_structures.HTTPStreamDataset
-   ~yt.frontends.sph.data_structures.OWLSDataset
+   ~yt.frontends.gadget.data_structures.GadgetBinaryFile
+   ~yt.frontends.gadget.data_structures.GadgetHDF5Dataset
+   ~yt.frontends.gadget.data_structures.GadgetDataset
+   ~yt.frontends.http_stream.data_structures.HTTPParticleFile
+   ~yt.frontends.http_stream.data_structures.HTTPStreamDataset
+   ~yt.frontends.owls.data_structures.OWLSDataset
    ~yt.frontends.sph.data_structures.ParticleDataset
-   ~yt.frontends.sph.data_structures.TipsyFile
-   ~yt.frontends.sph.data_structures.TipsyDataset
+   ~yt.frontends.tipsy.data_structures.TipsyFile
+   ~yt.frontends.tipsy.data_structures.TipsyDataset
    ~yt.frontends.sph.fields.SPHFieldInfo
-   ~yt.frontends.sph.io.IOHandlerGadgetBinary
-   ~yt.frontends.sph.io.IOHandlerGadgetHDF5
-   ~yt.frontends.sph.io.IOHandlerHTTPStream
-   ~yt.frontends.sph.io.IOHandlerOWLS
-   ~yt.frontends.sph.io.IOHandlerTipsyBinary
+   ~yt.frontends.gadget.io.IOHandlerGadgetBinary
+   ~yt.frontends.gadget.io.IOHandlerGadgetHDF5
+   ~yt.frontends.http_stream.io.IOHandlerHTTPStream
+   ~yt.frontends.owls.io.IOHandlerOWLS
+   ~yt.frontends.tipsy.io.IOHandlerTipsyBinary
 
 Stream
 ^^^^^^

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

https://bitbucket.org/yt_analysis/yt/commits/c15c6d014a86/
Changeset:   c15c6d014a86
Branch:      yt
User:        cosmosquark
Date:        2014-12-03 01:01:32+00:00
Summary:     Updated particle fields to include fields with respect to the normal and the centre (basically particle_shape_radius can never be negative but particle_shape_position_radius can be... likewise particle_cylindrical_z can not be negative but particle_cylindrical_position_z can be ).. all of which are with respect to the direction of the normal vector that you assign to the disk or sphere (inc the velocities which are always in a coordinate systemin with respect to the direction of the normal vector)
Affected #:  1 file

diff -r ff1845163637262a67025ea82fd77361bb7854a5 -r c15c6d014a8645f89aa26eb0ddba6f8994ca367d yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -43,6 +43,11 @@
 
 from .vector_operations import \
      create_magnitude_field
+     
+from .field_functions import \
+    get_radius, \
+    get_periodic_rvec
+
     
 def _field_concat(fname):
     def _AllFields(field, data):
@@ -369,6 +374,7 @@
               units="cm", particle_type = True,
               display_name = "Particle Radius")
 
+
     def _particle_spherical_position_radius(field, data):
         """
         Radial component of the particles' position vectors in spherical coords
@@ -392,6 +398,14 @@
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
+    # this is just particle radius but add it for ease of use
+    registry.add_field((ptype, "particle_spherical_radius"),
+              function=_particle_radius,
+              particle_type=True, units="cm",
+              validators=[ValidateParameter("normal"),
+                          ValidateParameter("center")])
+
+
     def _particle_spherical_position_theta(field, data):
         """
         Theta component of the particles' position vectors in spherical coords
@@ -415,6 +429,19 @@
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
+    def _particle_cylindrical_theta(field,data)
+        normal = data.get_field_parameter("normal")
+        coords = get_periodic_rvec(data)
+        return get_sph_theta(coords, normal)
+
+    registry.add_field((ptype, "particle_spherical_theta"),
+             function=_particle_cylindrical_theta,
+             validators=[ValidateParameter("center"),
+                         ValidateParameter("normal")],
+             units = "")
+
+
+
     def _particle_spherical_position_phi(field, data):
         """
         Phi component of the particles' position vectors in spherical coords
@@ -438,6 +465,20 @@
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
+
+   def _particle_spherical_phi(field,data)
+        normal = data.get_field_parameter("normal")
+        coords = get_periodic_rvec(data)
+        return get_sph_phi(coords, normal)
+
+    registry.add_field((ptype, "particle_spherical_phi"),
+             function=_particle_spherical_phi,
+             validators=[ValidateParameter("center"),
+                         ValidateParameter("normal")],
+             units = "")
+
+
+    
     def _particle_spherical_velocity_radius(field, data):
         """
         Radial component of the particles' velocity vectors in spherical coords
@@ -494,7 +535,7 @@
 
     registry.add_field((ptype, "particle_spherical_velocity_theta"),
               function=_particle_spherical_velocity_theta,
-              particle_type=True, units="cm/s",
+              particle_type=True, units="/s",
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
@@ -521,40 +562,194 @@
               particle_type=True, units="cm/s",
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
-                          
+    
+    def _particle_cylindrical_position_radius(field, data):
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        bv = data.get_field_parameter("bulk_velocity")
+	    pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        theta = get_cyl_theta(pos, center)
+        z = get_cyl_z(pos, center)
+        pos = pos - np.reshape(center, (3, 1))
+        cylr = get_cyl_r_component(pos, theta, normal)
+        return cylr
 
-    def _particle_cylindrical_r(field, data):
-        normal = data.get_field_parameter("normal")
-        center = data.get_field_parameter('center')
-        pos = YTArray([data[ptype, spos % ax] for ax in "xyz"])
-        pos = pos - np.reshape(center, (3, 1))
-        return data.ds.arr(get_cyl_r(pos, normal),
-                           'code_length')
-                           
-    registry.add_field((ptype, "particle_cylindrical_r"),
-              function=_particle_cylindrical_r,
-              validators=[ValidateParameter("normal")],
-                          display_name = "Particle Cylindrical R",
+
+    registry.add_field((ptype, "particle_cylindrical_position_radius"),
+              function=_particle_cylindrical_position_radius,
+              validators=[ValidateParameter("normal"), ValidateParameter("center")],
               units="cm", particle_type = True)
 
-    def _particle_cylindrical_z(field, data):
+
+
+    def _particle_cylindrical_radius(field, data):
         normal = data.get_field_parameter("normal")
-        center = data.get_field_parameter('center')
-        pos = YTArray([data[ptype, spos % ax] for ax in "xyz"])
-        pos = pos - np.reshape(center, (3, 1))
-        return data.ds.arr(get_cyl_z(pos,normal),
+	    coords = get_periodic_rvec(data)
+        return data.ds.arr(get_cyl_r(coords, normal),
                            'code_length')
 
 
+    registry.add_field((ptype, "particle_cylindrical_radius"),
+              function=_particle_cylindrical_radius,
+              validators=[ValidateParameter("normal"), ValidateParameter("center")],
+              units="cm", particle_type = True)
+
+
+
+    
+    def _particle_cylindrical_position_theta(field, data):
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        bv = data.get_field_parameter("bulk_velocity")
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        theta = get_cyl_theta(pos, center)
+        z = get_cyl_z(pos, center)
+        pos = pos - np.reshape(center, (3, 1))
+        cylt = get_cyl_theta_component(pos, theta, normal)
+        return cylt
+        
+    registry.add_field((ptype, "particle_cylindrical_position_theta"),
+              function=_particle_cylindrical_position_theta,
+              validators=[ValidateParameter("center"),
+                          ValidateParameter("normal")],
+              units="cm", particle_type = True)        
+
+    def _particle_cylindrical_theta(field,data)
+        normal = data.get_field_parameter("normal")
+        coords = get_periodic_rvec(data)
+        return get_cyl_theta(coords, normal)
+        
+    registry.add_field((ptype, "particle_cylindrical_theta"),
+             function=_particle_cylindrical_theta,
+             validators=[ValidateParameter("center"),
+                         ValidateParameter("normal")],
+             units = "")
+
+    def _particle_cylindrical_position_z(field, data):	
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        bv = data.get_field_parameter("bulk_velocity")
+	    pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        theta = get_cyl_theta(pos, center)
+        z = get_cyl_z(pos, center)
+        pos = pos - np.reshape(center, (3, 1))
+        cylz = get_cyl_z_component(pos, normal)
+        return cylz
+
+
+
+    registry.add_field((ptype, "particle_cylindrical_position_z"),
+              function=_particle_cylindrical_position_z,
+              validators=[ValidateParameter("center"),
+                          ValidateParameter("normal")],
+              units="cm", particle_type = True)
+   
+
+    def _particle_cylindrical_z(field,data):
+        normal = data.get_field_parameter("normal")
+        coords = get_periodic_rvec(data)
+        return data.ds.arr(get_cyl_z(coords,normal),
+                          'code_length')
+
     registry.add_field((ptype, "particle_cylindrical_z"),
               function=_particle_cylindrical_z,
-              validators=[ValidateParameter("center"),
-                          ValidateParameter("normal")],
-                          display_name = "Particle Cylindrical Z",
+              validators=[ValidateParameter("normal"), ValidateParameter("center")],
               units="cm", particle_type = True)
 
 
 
+    def _particle_cylindrical_velocity_radius(field, data):
+        """
+        Radial component of the particles' velocity vectors in cylindrical coords
+        based on the provided field parameters for 'normal', 'center', and 
+        'bulk_velocity', 
+        """
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        bv = data.get_field_parameter("bulk_velocity")
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        vel = svel
+        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
+        theta = get_cyl_theta(pos, center)
+        z = get_cyl_z(pos, center)
+        pos = pos - np.reshape(center, (3, 1))
+        vel = vel - np.reshape(bv, (3, 1))
+        cylr = get_cyl_r_component(vel, theta, normal)
+        return cylr
+
+    registry.add_field((ptype, "particle_cylindrical_velocity_radius"),
+              function=_particle_spherical_velocity_radius,
+              particle_type=True, units="cm/s",
+              validators=[ValidateParameter("normal"), 
+                          ValidateParameter("center")])
+
+    # This is simply aliased to "particle_cylindrical_velocity_radius"
+    # for ease of use.
+    registry.add_field((ptype, "particle_cylindrical_velocity"),
+              function=_particle_cylindrical_velocity_radius,
+              particle_type=True, units="cm/s",
+              validators=[ValidateParameter("normal"), 
+                          ValidateParameter("center")])
+
+    def _particle_cylindrical_velocity_theta(field, data):
+        """
+        Theta component of the particles' velocity vectors in cylindrical coords
+        based on the provided field parameters for 'normal', 'center', and 
+        'bulk_velocity', 
+        """
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        bv = data.get_field_parameter("bulk_velocity")
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        vel = svel
+        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
+        theta = get_cyl_theta(pos, center)
+	    z = get_cyl_z(pos, center)
+        pos = pos - np.reshape(center, (3, 1))
+        vel = vel - np.reshape(bv, (3, 1))
+        cylt = get_cyl_theta_component(vel, theta, normal)
+        return cylt
+
+    registry.add_field((ptype, "particle_cylindrical_velocity_theta"),
+              function=_particle_cylindrical_velocity_theta,
+              particle_type=True, units="cm/s",
+              validators=[ValidateParameter("normal"), 
+                          ValidateParameter("center")])
+
+    def _particle_cylindrical_velocity_z(field, data):
+        """
+        z component of the particles' velocity vectors in cylindrical coords
+        based on the provided field parameters for 'normal', 'center', and 
+        'bulk_velocity', 
+        """
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        bv = data.get_field_parameter("bulk_velocity")
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        vel = svel
+        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
+        theta = get_cyl_theta(pos, center)
+	    z = get_cyl_z(pos, center)
+        pos = pos - np.reshape(center, (3, 1))
+        vel = vel - np.reshape(bv, (3, 1))
+        cylz = get_cyl_z_component(vel, normal)
+        return cylz
+
+    registry.add_field((ptype, "particle_cylindrical_velocity_z"),
+              function=_particle_cylindrical_velocity_z,
+              particle_type=True, units="cm/s",
+              validators=[ValidateParameter("normal"), 
+                          ValidateParameter("center")])
+
+
+
+
 
 def add_particle_average(registry, ptype, field_name, 
                          weight = "particle_mass",


https://bitbucket.org/yt_analysis/yt/commits/4e6a7b2f36dc/
Changeset:   4e6a7b2f36dc
Branch:      yt
User:        cosmosquark
Date:        2014-12-03 11:10:41+00:00
Summary:     updated to add the missing ":"
Affected #:  1 file

diff -r c15c6d014a8645f89aa26eb0ddba6f8994ca367d -r 4e6a7b2f36dcf291bf30584159691bb51a24c561 yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -429,7 +429,7 @@
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
-    def _particle_cylindrical_theta(field,data)
+    def _particle_cylindrical_theta(field,data):
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
         return get_sph_theta(coords, normal)
@@ -466,7 +466,7 @@
                           ValidateParameter("center")])
 
 
-   def _particle_spherical_phi(field,data)
+   def _particle_spherical_phi(field,data):
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
         return get_sph_phi(coords, normal)
@@ -616,7 +616,7 @@
                           ValidateParameter("normal")],
               units="cm", particle_type = True)        
 
-    def _particle_cylindrical_theta(field,data)
+    def _particle_cylindrical_theta(field,data):
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
         return get_cyl_theta(coords, normal)


https://bitbucket.org/yt_analysis/yt/commits/9b6cdd46c5e5/
Changeset:   9b6cdd46c5e5
Branch:      yt
User:        cosmosquark
Date:        2014-12-03 11:45:01+00:00
Summary:     fixing indentation on line 469
Affected #:  1 file

diff -r 4e6a7b2f36dcf291bf30584159691bb51a24c561 -r 9b6cdd46c5e51fb3305e7e377a76f202023b9d72 yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -466,7 +466,7 @@
                           ValidateParameter("center")])
 
 
-   def _particle_spherical_phi(field,data):
+    def _particle_spherical_phi(field,data):
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
         return get_sph_phi(coords, normal)


https://bitbucket.org/yt_analysis/yt/commits/5a332f898c27/
Changeset:   5a332f898c27
Branch:      yt
User:        cosmosquark
Date:        2014-12-03 11:45:59+00:00
Summary:     particle_fields.py edited online with Bitbucket
Affected #:  1 file

diff -r 9b6cdd46c5e51fb3305e7e377a76f202023b9d72 -r 5a332f898c271f18167812782b727f3ebfb164ba yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -567,7 +567,7 @@
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
         bv = data.get_field_parameter("bulk_velocity")
-	    pos = spos
+        pos = spos
         pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
         theta = get_cyl_theta(pos, center)
         z = get_cyl_z(pos, center)


https://bitbucket.org/yt_analysis/yt/commits/b0bd33df4b7d/
Changeset:   b0bd33df4b7d
Branch:      yt
User:        cosmosquark
Date:        2014-12-03 11:50:06+00:00
Summary:     fixing indentation
Affected #:  1 file

diff -r 5a332f898c271f18167812782b727f3ebfb164ba -r b0bd33df4b7de2b74617fb3c6a7de8f507b0d44a yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -585,7 +585,7 @@
 
     def _particle_cylindrical_radius(field, data):
         normal = data.get_field_parameter("normal")
-	    coords = get_periodic_rvec(data)
+        coords = get_periodic_rvec(data)
         return data.ds.arr(get_cyl_r(coords, normal),
                            'code_length')
 
@@ -631,7 +631,7 @@
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
         bv = data.get_field_parameter("bulk_velocity")
-	    pos = spos
+        pos = spos
         pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
         theta = get_cyl_theta(pos, center)
         z = get_cyl_z(pos, center)
@@ -709,7 +709,7 @@
         vel = svel
         vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
         theta = get_cyl_theta(pos, center)
-	    z = get_cyl_z(pos, center)
+        z = get_cyl_z(pos, center)
         pos = pos - np.reshape(center, (3, 1))
         vel = vel - np.reshape(bv, (3, 1))
         cylt = get_cyl_theta_component(vel, theta, normal)
@@ -735,7 +735,7 @@
         vel = svel
         vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
         theta = get_cyl_theta(pos, center)
-	    z = get_cyl_z(pos, center)
+        z = get_cyl_z(pos, center)
         pos = pos - np.reshape(center, (3, 1))
         vel = vel - np.reshape(bv, (3, 1))
         cylz = get_cyl_z_component(vel, normal)


https://bitbucket.org/yt_analysis/yt/commits/a1604d4eb04f/
Changeset:   a1604d4eb04f
Branch:      yt
User:        cosmosquark
Date:        2014-12-04 17:39:29+00:00
Summary:     particle_fields.py edited online with Bitbucket
Affected #:  1 file

diff -r b0bd33df4b7de2b74617fb3c6a7de8f507b0d44a -r a1604d4eb04fefe3be0597a946eca3528d10d5c2 yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -840,3 +840,4 @@
                        units = "g/cm**3")
     return [field_name]
 
+


https://bitbucket.org/yt_analysis/yt/commits/5bc5f35b07a2/
Changeset:   5bc5f35b07a2
Branch:      yt
User:        cosmosquark
Date:        2014-12-08 17:27:25+00:00
Summary:     updated cylindrical fields and added in relative fields too
Affected #:  1 file

diff -r a1604d4eb04fefe3be0597a946eca3528d10d5c2 -r 5bc5f35b07a245efb9dc4eb5cf435982b2707261 yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -39,7 +39,8 @@
     get_cyl_r, get_cyl_theta, \
     get_cyl_z, get_sph_r, \
     get_sph_theta, get_sph_phi, \
-    periodic_dist, euclidean_dist
+    periodic_dist, euclidean_dist, \
+    modify_reference_frame
 
 from .vector_operations import \
      create_magnitude_field
@@ -375,10 +376,206 @@
               display_name = "Particle Radius")
 
 
+    def _particle_relative_position(field, data):
+        """
+        Compute the position in a rotated  reference frame relative to
+        normal vector which is set to be in the direction of z and a center
+        """
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        bv = data.get_field_parameter("bulk_velocity")
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        vel = svel
+        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
+	pos = pos.T
+	vel = vel.T
+        L, pos, vel = modify_reference_frame(center, normal, pos, vel)
+        return pos
+
+    registry.add_field((ptype, "particle_relative_position"),
+              function=_particle_relative_position,
+              particle_type=True, units="cm",
+              validators=[ValidateParameter("normal"),
+                          ValidateParameter("center")])
+
+
+    def _particle_relative_position_x(field, data):
+        """
+        Compute the value of x in a rotated reference frame relative to
+        normal vector which is set to be in the direction of z and a center
+        """
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        bv = data.get_field_parameter("bulk_velocity")
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        vel = svel
+        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
+        pos = pos.T
+        vel = vel.T
+        L, pos, vel = modify_reference_frame(center, normal, pos, vel)
+	pos = pos.T
+        return pos[0]
+
+    registry.add_field((ptype, "particle_relative_position_x"),
+              function=_particle_relative_position_x,
+              particle_type=True, units="cm",
+              validators=[ValidateParameter("normal"),
+                          ValidateParameter("center")])
+
+    def _particle_relative_position_y(field, data):
+        """
+        Compute the value of y in a rotated reference frame relative to
+        normal vector which is set to be in the direction of z and a center
+        """
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        bv = data.get_field_parameter("bulk_velocity")
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        vel = svel
+        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
+        pos = pos.T
+        vel = vel.T
+        L, pos, vel = modify_reference_frame(center, normal, pos, vel)
+	pos = pos.T
+        return pos[1]
+
+    registry.add_field((ptype, "particle_relative_position_y"),
+              function=_particle_relative_position_y,
+              particle_type=True, units="cm",
+              validators=[ValidateParameter("normal"),
+                          ValidateParameter("center")])
+
+
+    def _particle_relative_position_z(field, data):
+        """
+        Compute the value of z in a rotated reference frame relative to
+        normal vector which is set to be in the direction of z and a center
+        """
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        bv = data.get_field_parameter("bulk_velocity")
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        vel = svel
+        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
+        pos = pos.T
+        vel = vel.T
+        L, pos, vel = modify_reference_frame(center, normal, pos, vel)
+        pos = pos.T
+        return pos[2]
+
+    registry.add_field((ptype, "particle_relative_position_z"),
+              function=_particle_relative_position_z,
+              particle_type=True, units="cm",
+              validators=[ValidateParameter("normal"),
+                          ValidateParameter("center")])
+
+
+
+    def _particle_relative_velocity(field, data):
+        """
+        Compute the value of x in a rotated  reference frame relative to
+        normal vector which is set to be in the direction of z and a center
+        """
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        bv = data.get_field_parameter("bulk_velocity")
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        vel = svel
+        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
+        pos = pos.T
+        vel = vel.T
+        L, pos, vel = modify_reference_frame(center, normal, pos, vel)
+        return vel
+
+    registry.add_field((ptype, "particle_relative_velocity"),
+              function=_particle_relative_velocity,
+              particle_type=True, units="cm/s",
+              validators=[ValidateParameter("normal"),
+                          ValidateParameter("center")])
+
+
+    def _particle_relative_velocity_x(field, data):
+        """
+        Compute the value of vx in a rotated reference frame relative to
+        normal vector which is set to be in the direction of z and a center
+        """
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        bv = data.get_field_parameter("bulk_velocity")
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        vel = svel
+        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
+        pos = pos.T
+        vel = vel.T
+        L, pos, vel = modify_reference_frame(center, normal, pos, vel)
+        vel = vel.T
+        return vel[0]
+
+    registry.add_field((ptype, "particle_relative_velocity_x"),
+              function=_particle_relative_velocity_x,
+              particle_type=True, units="cm/s",
+              validators=[ValidateParameter("normal"),
+                          ValidateParameter("center")])
+
+    def _particle_relative_velocity_y(field, data):
+        """
+        Compute the value of vy in a rotated reference frame relative to
+        normal vector which is set to be in the direction of z and a center
+        """
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        bv = data.get_field_parameter("bulk_velocity")
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        vel = svel
+        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
+        pos = pos.T
+        vel = vel.T
+        L, pos, vel = modify_reference_frame(center, normal, pos, vel)
+        vel = vel.T
+        return vel[1]
+
+    registry.add_field((ptype, "particle_relative_velocity_y"),
+              function=_particle_relative_velocity_y,
+              particle_type=True, units="cm/s",
+              validators=[ValidateParameter("normal"),
+                          ValidateParameter("center")])
+
+    def _particle_relative_velocity_z(field, data):
+        """
+        Compute the value of vz in a rotated reference frame relative to
+        normal vector which is set to be in the direction of z and a center
+        """
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        bv = data.get_field_parameter("bulk_velocity")
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        vel = svel
+        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
+        pos = pos.T
+        vel = vel.T
+        L, pos, vel = modify_reference_frame(center, normal, pos, vel)
+        vel = vel.T
+        return vel[2]
+
+
+    registry.add_field((ptype, "particle_relative_velocity_z"),
+              function=_particle_relative_velocity_z,
+              particle_type=True, units="cm/s",
+              validators=[ValidateParameter("normal"),
+                          ValidateParameter("center")])
+
     def _particle_spherical_position_radius(field, data):
         """
         Radial component of the particles' position vectors in spherical coords
-        on the provided field parameters for 'normal', 'center', and 
+        on the provided field parameters for 'normal', 'center', 
         'bulk_velocity', 
         """
         normal = data.get_field_parameter('normal')
@@ -535,7 +732,7 @@
 
     registry.add_field((ptype, "particle_spherical_velocity_theta"),
               function=_particle_spherical_velocity_theta,
-              particle_type=True, units="/s",
+              particle_type=True, units="cm/s",
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
@@ -585,8 +782,10 @@
 
     def _particle_cylindrical_radius(field, data):
         normal = data.get_field_parameter("normal")
-        coords = get_periodic_rvec(data)
-        return data.ds.arr(get_cyl_r(coords, normal),
+        center = data.get_field_parameter('center')
+        pos = YTArray([data[ptype, spos % ax] for ax in "xyz"])
+        pos = pos - np.reshape(center, (3, 1))
+        return data.ds.arr(get_cyl_r(pos, normal),
                            'code_length')
 
 
@@ -650,9 +849,12 @@
 
     def _particle_cylindrical_z(field,data):
         normal = data.get_field_parameter("normal")
-        coords = get_periodic_rvec(data)
-        return data.ds.arr(get_cyl_z(coords,normal),
-                          'code_length')
+        center = data.get_field_parameter('center')
+        pos = YTArray([data[ptype, spos % ax] for ax in "xyz"])
+        pos = pos - np.reshape(center, (3, 1))
+        return data.ds.arr(get_cyl_z(pos, normal),
+                           'code_length')
+
 
     registry.add_field((ptype, "particle_cylindrical_z"),
               function=_particle_cylindrical_z,
@@ -840,4 +1042,3 @@
                        units = "g/cm**3")
     return [field_name]
 
-


https://bitbucket.org/yt_analysis/yt/commits/178f28cb7705/
Changeset:   178f28cb7705
Branch:      yt
User:        cosmosquark
Date:        2014-12-15 19:52:20+00:00
Summary:     updating units in particle_cylindrical_theta, particle_spherical_theta and particle_spherical_phi
Affected #:  1 file

diff -r 5bc5f35b07a245efb9dc4eb5cf435982b2707261 -r 178f28cb7705584b8e378fb2c991429c76be7fcb yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -626,16 +626,16 @@
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
-    def _particle_cylindrical_theta(field,data):
+    def _particle_spherical_theta(field,data):
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
         return get_sph_theta(coords, normal)
 
     registry.add_field((ptype, "particle_spherical_theta"),
-             function=_particle_cylindrical_theta,
+             function=_particle_spherical_theta,
              validators=[ValidateParameter("center"),
                          ValidateParameter("normal")],
-             units = "")
+             units = "dimensionless")
 
 
 
@@ -672,7 +672,7 @@
              function=_particle_spherical_phi,
              validators=[ValidateParameter("center"),
                          ValidateParameter("normal")],
-             units = "")
+             units = "dimensionless")
 
 
     
@@ -824,7 +824,7 @@
              function=_particle_cylindrical_theta,
              validators=[ValidateParameter("center"),
                          ValidateParameter("normal")],
-             units = "")
+             units = "dimensionless")
 
     def _particle_cylindrical_position_z(field, data):	
         normal = data.get_field_parameter('normal')


https://bitbucket.org/yt_analysis/yt/commits/3977574cd58e/
Changeset:   3977574cd58e
Branch:      yt
User:        cosmosquark
Date:        2014-12-15 19:57:52+00:00
Summary:     particle_fields.py edited online with Bitbucket
Affected #:  1 file

diff -r 178f28cb7705584b8e378fb2c991429c76be7fcb -r 3977574cd58eaac4b59e9b769225a7753d10a18b yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -629,13 +629,13 @@
     def _particle_spherical_theta(field,data):
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
-        return get_sph_theta(coords, normal)
+        return data.ds.arr(get_sph_theta(coords, normal),"radians")
 
     registry.add_field((ptype, "particle_spherical_theta"),
              function=_particle_spherical_theta,
              validators=[ValidateParameter("center"),
                          ValidateParameter("normal")],
-             units = "dimensionless")
+             units = "radians")
 
 
 
@@ -666,13 +666,13 @@
     def _particle_spherical_phi(field,data):
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
-        return get_sph_phi(coords, normal)
+        return data.ds.arr(get_sph_phi(coords, normal),"radians")
 
     registry.add_field((ptype, "particle_spherical_phi"),
              function=_particle_spherical_phi,
              validators=[ValidateParameter("center"),
                          ValidateParameter("normal")],
-             units = "dimensionless")
+             units = "radians")
 
 
     
@@ -818,13 +818,13 @@
     def _particle_cylindrical_theta(field,data):
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
-        return get_cyl_theta(coords, normal)
+        return data.ds.array(get_cyl_theta(coords, normal),"radians")
         
     registry.add_field((ptype, "particle_cylindrical_theta"),
              function=_particle_cylindrical_theta,
              validators=[ValidateParameter("center"),
                          ValidateParameter("normal")],
-             units = "dimensionless")
+             units = "radians")
 
     def _particle_cylindrical_position_z(field, data):	
         normal = data.get_field_parameter('normal')


https://bitbucket.org/yt_analysis/yt/commits/d2cc48aa779c/
Changeset:   d2cc48aa779c
Branch:      yt
User:        cosmosquark
Date:        2014-12-18 11:44:29+00:00
Summary:     particle_fields.py edited online with Bitbucket
Affected #:  1 file

diff -r 3977574cd58eaac4b59e9b769225a7753d10a18b -r d2cc48aa779c69e24a468aaedd42f311f96d940a yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -388,8 +388,8 @@
         pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
         vel = svel
         vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
-	pos = pos.T
-	vel = vel.T
+        pos = pos.T
+        vel = vel.T
         L, pos, vel = modify_reference_frame(center, normal, pos, vel)
         return pos
 
@@ -439,7 +439,7 @@
         pos = pos.T
         vel = vel.T
         L, pos, vel = modify_reference_frame(center, normal, pos, vel)
-	pos = pos.T
+        pos = pos.T
         return pos[1]
 
     registry.add_field((ptype, "particle_relative_position_y"),


https://bitbucket.org/yt_analysis/yt/commits/e7ef30f301ff/
Changeset:   e7ef30f301ff
Branch:      yt
User:        cosmosquark
Date:        2014-12-18 21:09:08+00:00
Summary:     changed radians to radian
Affected #:  1 file

diff -r d2cc48aa779c69e24a468aaedd42f311f96d940a -r e7ef30f301ff5163d540c6a1c02a3a8723505d3b yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -629,13 +629,13 @@
     def _particle_spherical_theta(field,data):
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
-        return data.ds.arr(get_sph_theta(coords, normal),"radians")
+        return data.ds.arr(get_sph_theta(coords, normal),"radian")
 
     registry.add_field((ptype, "particle_spherical_theta"),
              function=_particle_spherical_theta,
              validators=[ValidateParameter("center"),
                          ValidateParameter("normal")],
-             units = "radians")
+             units = "radian")
 
 
 
@@ -666,13 +666,13 @@
     def _particle_spherical_phi(field,data):
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
-        return data.ds.arr(get_sph_phi(coords, normal),"radians")
+        return data.ds.arr(get_sph_phi(coords, normal),"radian")
 
     registry.add_field((ptype, "particle_spherical_phi"),
              function=_particle_spherical_phi,
              validators=[ValidateParameter("center"),
                          ValidateParameter("normal")],
-             units = "radians")
+             units = "radian")
 
 
     
@@ -818,13 +818,13 @@
     def _particle_cylindrical_theta(field,data):
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
-        return data.ds.array(get_cyl_theta(coords, normal),"radians")
+        return data.ds.array(get_cyl_theta(coords, normal),"radian")
         
     registry.add_field((ptype, "particle_cylindrical_theta"),
              function=_particle_cylindrical_theta,
              validators=[ValidateParameter("center"),
                          ValidateParameter("normal")],
-             units = "radians")
+             units = "radian")
 
     def _particle_cylindrical_position_z(field, data):	
         normal = data.get_field_parameter('normal')


https://bitbucket.org/yt_analysis/yt/commits/a0b1e07bad1f/
Changeset:   a0b1e07bad1f
Branch:      yt
User:        cosmosquark
Date:        2014-12-19 01:20:03+00:00
Summary:     added in particle_type = True
Affected #:  1 file

diff -r e7ef30f301ff5163d540c6a1c02a3a8723505d3b -r a0b1e07bad1f12dc2937e3d75f32b11bf52738d6 yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -633,9 +633,9 @@
 
     registry.add_field((ptype, "particle_spherical_theta"),
              function=_particle_spherical_theta,
+             particle_type=True, units = "radian",
              validators=[ValidateParameter("center"),
-                         ValidateParameter("normal")],
-             units = "radian")
+                         ValidateParameter("normal")])
 
 
 
@@ -671,8 +671,7 @@
     registry.add_field((ptype, "particle_spherical_phi"),
              function=_particle_spherical_phi,
              validators=[ValidateParameter("center"),
-                         ValidateParameter("normal")],
-             units = "radian")
+                         ValidateParameter("normal")])
 
 
     
@@ -699,6 +698,7 @@
     registry.add_field((ptype, "particle_spherical_velocity_radius"),
               function=_particle_spherical_velocity_radius,
               particle_type=True, units="cm/s",
+              particle_type=True, units = "radian",
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
@@ -822,9 +822,9 @@
         
     registry.add_field((ptype, "particle_cylindrical_theta"),
              function=_particle_cylindrical_theta,
+             particle_type=True, units = "radian",
              validators=[ValidateParameter("center"),
-                         ValidateParameter("normal")],
-             units = "radian")
+                         ValidateParameter("normal")])
 
     def _particle_cylindrical_position_z(field, data):	
         normal = data.get_field_parameter('normal')


https://bitbucket.org/yt_analysis/yt/commits/c6857556edde/
Changeset:   c6857556edde
Branch:      yt
User:        cosmosquark
Date:        2014-12-19 01:25:57+00:00
Summary:     particle_fields.py edited online with Bitbucket
Affected #:  1 file

diff -r a0b1e07bad1f12dc2937e3d75f32b11bf52738d6 -r c6857556edde2d7fa8dcfc15fdf1af3bf52079e6 yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -670,6 +670,7 @@
 
     registry.add_field((ptype, "particle_spherical_phi"),
              function=_particle_spherical_phi,
+             particle_type=True, units = "radian",
              validators=[ValidateParameter("center"),
                          ValidateParameter("normal")])
 


https://bitbucket.org/yt_analysis/yt/commits/29f87b643131/
Changeset:   29f87b643131
Branch:      yt
User:        cosmosquark
Date:        2014-12-19 11:49:02+00:00
Summary:     particle_fields.py edited online with Bitbucket
Affected #:  1 file

diff -r c6857556edde2d7fa8dcfc15fdf1af3bf52079e6 -r 29f87b6431318be4b99cfe8b7aabb705cd1fded7 yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -699,7 +699,6 @@
     registry.add_field((ptype, "particle_spherical_velocity_radius"),
               function=_particle_spherical_velocity_radius,
               particle_type=True, units="cm/s",
-              particle_type=True, units = "radian",
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 


https://bitbucket.org/yt_analysis/yt/commits/b5fc4cb4b1eb/
Changeset:   b5fc4cb4b1eb
Branch:      yt
User:        cosmosquark
Date:        2014-12-20 20:11:30+00:00
Summary:     particle_fields.py edited online with Bitbucket
Affected #:  1 file

diff -r 29f87b6431318be4b99cfe8b7aabb705cd1fded7 -r b5fc4cb4b1eb9a037c2b2cc828210bb7c1d6a7c0 yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -415,7 +415,7 @@
         pos = pos.T
         vel = vel.T
         L, pos, vel = modify_reference_frame(center, normal, pos, vel)
-	pos = pos.T
+        pos = pos.T
         return pos[0]
 
     registry.add_field((ptype, "particle_relative_position_x"),


https://bitbucket.org/yt_analysis/yt/commits/23391f5133ef/
Changeset:   23391f5133ef
Branch:      yt
User:        cosmosquark
Date:        2014-12-23 00:03:11+00:00
Summary:     particle_fields.py edited online with Bitbucket
Affected #:  1 file

diff -r b5fc4cb4b1eb9a037c2b2cc828210bb7c1d6a7c0 -r 23391f5133eff98a81b6b15703937602f4e03827 yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -477,7 +477,7 @@
 
     def _particle_relative_velocity(field, data):
         """
-        Compute the value of x in a rotated  reference frame relative to
+        Compute the value of the velocity turple in a rotated reference frame relative to
         normal vector which is set to be in the direction of z and a center
         """
         normal = data.get_field_parameter('normal')
@@ -759,25 +759,6 @@
               particle_type=True, units="cm/s",
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
-    
-    def _particle_cylindrical_position_radius(field, data):
-        normal = data.get_field_parameter('normal')
-        center = data.get_field_parameter('center')
-        bv = data.get_field_parameter("bulk_velocity")
-        pos = spos
-        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
-        theta = get_cyl_theta(pos, center)
-        z = get_cyl_z(pos, center)
-        pos = pos - np.reshape(center, (3, 1))
-        cylr = get_cyl_r_component(pos, theta, normal)
-        return cylr
-
-
-    registry.add_field((ptype, "particle_cylindrical_position_radius"),
-              function=_particle_cylindrical_position_radius,
-              validators=[ValidateParameter("normal"), ValidateParameter("center")],
-              units="cm", particle_type = True)
-
 
 
     def _particle_cylindrical_radius(field, data):
@@ -795,26 +776,6 @@
               units="cm", particle_type = True)
 
 
-
-    
-    def _particle_cylindrical_position_theta(field, data):
-        normal = data.get_field_parameter('normal')
-        center = data.get_field_parameter('center')
-        bv = data.get_field_parameter("bulk_velocity")
-        pos = spos
-        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
-        theta = get_cyl_theta(pos, center)
-        z = get_cyl_z(pos, center)
-        pos = pos - np.reshape(center, (3, 1))
-        cylt = get_cyl_theta_component(pos, theta, normal)
-        return cylt
-        
-    registry.add_field((ptype, "particle_cylindrical_position_theta"),
-              function=_particle_cylindrical_position_theta,
-              validators=[ValidateParameter("center"),
-                          ValidateParameter("normal")],
-              units="cm", particle_type = True)        
-
     def _particle_cylindrical_theta(field,data):
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
@@ -826,26 +787,6 @@
              validators=[ValidateParameter("center"),
                          ValidateParameter("normal")])
 
-    def _particle_cylindrical_position_z(field, data):	
-        normal = data.get_field_parameter('normal')
-        center = data.get_field_parameter('center')
-        bv = data.get_field_parameter("bulk_velocity")
-        pos = spos
-        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
-        theta = get_cyl_theta(pos, center)
-        z = get_cyl_z(pos, center)
-        pos = pos - np.reshape(center, (3, 1))
-        cylz = get_cyl_z_component(pos, normal)
-        return cylz
-
-
-
-    registry.add_field((ptype, "particle_cylindrical_position_z"),
-              function=_particle_cylindrical_position_z,
-              validators=[ValidateParameter("center"),
-                          ValidateParameter("normal")],
-              units="cm", particle_type = True)
-   
 
     def _particle_cylindrical_z(field,data):
         normal = data.get_field_parameter("normal")


https://bitbucket.org/yt_analysis/yt/commits/b68776d078fa/
Changeset:   b68776d078fa
Branch:      yt
User:        cosmosquark
Date:        2014-12-23 00:18:23+00:00
Summary:     Correcting ds.array with the correctly spelt ds.arr and correcting the spelling of tuple in the docstring for particle_relative_velocity
Affected #:  1 file

diff -r 23391f5133eff98a81b6b15703937602f4e03827 -r b68776d078fa4455aa2c650c1ccf0c61c726e2df yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -477,7 +477,7 @@
 
     def _particle_relative_velocity(field, data):
         """
-        Compute the value of the velocity turple in a rotated reference frame relative to
+        Compute the value of the velocity tuple in a rotated reference frame relative to
         normal vector which is set to be in the direction of z and a center
         """
         normal = data.get_field_parameter('normal')
@@ -779,7 +779,7 @@
     def _particle_cylindrical_theta(field,data):
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
-        return data.ds.array(get_cyl_theta(coords, normal),"radian")
+        return data.ds.arr(get_cyl_theta(coords, normal),"radian")
         
     registry.add_field((ptype, "particle_cylindrical_theta"),
              function=_particle_cylindrical_theta,


https://bitbucket.org/yt_analysis/yt/commits/996bc5a04b09/
Changeset:   996bc5a04b09
Branch:      yt
User:        ngoldbaum
Date:        2014-12-23 06:13:30+00:00
Summary:     Updating, clarifying, and debugging fields in particle_fields.py
Affected #:  2 files

diff -r b68776d078fa4455aa2c650c1ccf0c61c726e2df -r 996bc5a04b09668415711c22c278b04163fa5c46 yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -21,10 +21,6 @@
 from yt.fields.derived_field import \
     ValidateParameter, \
     ValidateSpatial
-from yt.utilities.physical_constants import \
-    mass_hydrogen_cgs, \
-    mass_sun_cgs, \
-    mh
 
 from yt.units.yt_array import \
     uconcatenate
@@ -37,17 +33,15 @@
     get_cyl_z_component, \
     get_cyl_theta_component, \
     get_cyl_r, get_cyl_theta, \
-    get_cyl_z, get_sph_r, \
+    get_cyl_z, \
     get_sph_theta, get_sph_phi, \
-    periodic_dist, euclidean_dist, \
     modify_reference_frame
 
 from .vector_operations import \
-     create_magnitude_field
+    create_magnitude_field
      
 from .field_functions import \
-    get_radius, \
-    get_periodic_rvec
+    get_radius
 
     
 def _field_concat(fname):
@@ -101,7 +95,7 @@
              validators = [ValidateSpatial()],
              display_name = "\\mathrm{%s Mass}" % ptype_dn,
              units = "g")
-             
+
     def particle_density(field, data):
         pos = data[ptype, coord_name]
         mass = data[ptype, mass_name]
@@ -363,82 +357,79 @@
 
     create_magnitude_field(registry, "particle_angular_momentum",
                            "g*cm**2/s", ftype=ptype, particle_type=True)
-    
-    from .field_functions import \
-        get_radius
 
     def _particle_radius(field, data):
+        """The spherical radial component of the particle positions
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
+        """        
         return get_radius(data, "particle_position_")
-    registry.add_field((ptype, "particle_radius"),
-              function=_particle_radius,
-              validators=[ValidateParameter("center")],
-              units="cm", particle_type = True,
-              display_name = "Particle Radius")
 
+    registry.add_field(
+        (ptype, "particle_radius"),
+        function=_particle_radius,
+        units="cm",
+        particle_type=True,
+        validators=[ValidateParameter("center")])
 
     def _particle_relative_position(field, data):
-        """
-        Compute the position in a rotated  reference frame relative to
-        normal vector which is set to be in the direction of z and a center
+        """The cartesian particle positions in a rotated reference frame
+
+        Relative to the coordinate system defined by the *normal* vector and
+        *center* field parameters.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
-        bv = data.get_field_parameter("bulk_velocity")
         pos = spos
         pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
-        vel = svel
-        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
         pos = pos.T
-        vel = vel.T
-        L, pos, vel = modify_reference_frame(center, normal, pos, vel)
+        L, pos = modify_reference_frame(center, normal, P=pos)
         return pos
 
-    registry.add_field((ptype, "particle_relative_position"),
-              function=_particle_relative_position,
-              particle_type=True, units="cm",
-              validators=[ValidateParameter("normal"),
-                          ValidateParameter("center")])
-
+    registry.add_field(
+        (ptype, "particle_relative_position"),
+        function=_particle_relative_position,
+        particle_type=True,
+        units="cm",
+        validators=[ValidateParameter("normal"), ValidateParameter("center")])
 
     def _particle_relative_position_x(field, data):
-        """
-        Compute the value of x in a rotated reference frame relative to
-        normal vector which is set to be in the direction of z and a center
+        """The x component of the  particle positions in a rotated reference
+        frame
+
+        Relative to the coordinate system defined by the *normal* vector and
+        *center* field parameters.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
-        bv = data.get_field_parameter("bulk_velocity")
         pos = spos
         pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
-        vel = svel
-        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
         pos = pos.T
-        vel = vel.T
-        L, pos, vel = modify_reference_frame(center, normal, pos, vel)
+        L, pos, = modify_reference_frame(center, normal, P=pos)
         pos = pos.T
         return pos[0]
 
-    registry.add_field((ptype, "particle_relative_position_x"),
-              function=_particle_relative_position_x,
-              particle_type=True, units="cm",
-              validators=[ValidateParameter("normal"),
-                          ValidateParameter("center")])
+    registry.add_field(
+        (ptype, "particle_relative_position_x"),
+        function=_particle_relative_position_x,
+        particle_type=True,
+        units="cm",
+        validators=[ValidateParameter("normal"), ValidateParameter("center")])
 
     def _particle_relative_position_y(field, data):
-        """
-        Compute the value of y in a rotated reference frame relative to
-        normal vector which is set to be in the direction of z and a center
+        """The y component of the  particle positions in a rotated reference
+        frame
+
+        Relative to the coordinate system defined by the *normal* vector and
+        *center* field parameters.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
-        bv = data.get_field_parameter("bulk_velocity")
         pos = spos
         pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
-        vel = svel
-        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
         pos = pos.T
-        vel = vel.T
-        L, pos, vel = modify_reference_frame(center, normal, pos, vel)
+        L, pos = modify_reference_frame(center, normal, P=pos)
         pos = pos.T
         return pos[1]
 
@@ -450,20 +441,19 @@
 
 
     def _particle_relative_position_z(field, data):
-        """
-        Compute the value of z in a rotated reference frame relative to
-        normal vector which is set to be in the direction of z and a center
+        """The z component of the  particle positions in a rotated reference
+        frame
+
+        Relative to the coordinate system defined by the *normal* vector and
+        *center* field parameters.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
-        bv = data.get_field_parameter("bulk_velocity")
+
         pos = spos
         pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
-        vel = svel
-        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
         pos = pos.T
-        vel = vel.T
-        L, pos, vel = modify_reference_frame(center, normal, pos, vel)
+        L, pos = modify_reference_frame(center, normal, P=pos)
         pos = pos.T
         return pos[2]
 
@@ -473,23 +463,20 @@
               validators=[ValidateParameter("normal"),
                           ValidateParameter("center")])
 
+    def _particle_relative_velocity(field, data):
+        """The vector particle velocities in an arbitrary coordinate system
 
-
-    def _particle_relative_velocity(field, data):
-        """
-        Compute the value of the velocity tuple in a rotated reference frame relative to
-        normal vector which is set to be in the direction of z and a center
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
         bv = data.get_field_parameter("bulk_velocity")
-        pos = spos
-        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
         vel = svel
         vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
-        pos = pos.T
+        vel = vel - np.reshape(bv, (3, 1))
         vel = vel.T
-        L, pos, vel = modify_reference_frame(center, normal, pos, vel)
+        L, vel = modify_reference_frame(center, normal, V=vel)
         return vel
 
     registry.add_field((ptype, "particle_relative_velocity"),
@@ -498,22 +485,21 @@
               validators=[ValidateParameter("normal"),
                           ValidateParameter("center")])
 
+    def _particle_relative_velocity_x(field, data):
+        """The x component of the particle velocities in an arbitrary coordinate
+        system
 
-    def _particle_relative_velocity_x(field, data):
-        """
-        Compute the value of vx in a rotated reference frame relative to
-        normal vector which is set to be in the direction of z and a center
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
         bv = data.get_field_parameter("bulk_velocity")
-        pos = spos
-        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
         vel = svel
         vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
-        pos = pos.T
+        vel = vel - np.reshape(bv, (3, 1))
         vel = vel.T
-        L, pos, vel = modify_reference_frame(center, normal, pos, vel)
+        L, vel = modify_reference_frame(center, normal, V=vel)
         vel = vel.T
         return vel[0]
 
@@ -524,20 +510,20 @@
                           ValidateParameter("center")])
 
     def _particle_relative_velocity_y(field, data):
-        """
-        Compute the value of vy in a rotated reference frame relative to
-        normal vector which is set to be in the direction of z and a center
+        """The y component of the particle velocities in an arbitrary coordinate
+        system
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
-        bv = data.get_field_parameter("bulk_velocity")
-        pos = spos
-        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        bv = data.get_field_parameter('bulk_velocity')
         vel = svel
         vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
-        pos = pos.T
+        vel = vel - np.reshape(bv, (3, 1))
         vel = vel.T
-        L, pos, vel = modify_reference_frame(center, normal, pos, vel)
+        L, vel = modify_reference_frame(center, normal, V=vel)
         vel = vel.T
         return vel[1]
 
@@ -548,46 +534,40 @@
                           ValidateParameter("center")])
 
     def _particle_relative_velocity_z(field, data):
-        """
-        Compute the value of vz in a rotated reference frame relative to
-        normal vector which is set to be in the direction of z and a center
+        """The z component of the particle velocities in an arbitrary coordinate
+        system
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
         bv = data.get_field_parameter("bulk_velocity")
-        pos = spos
-        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
         vel = svel
         vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
-        pos = pos.T
+        bv = vel = np.reshape(bv, (3, 1))
         vel = vel.T
-        L, pos, vel = modify_reference_frame(center, normal, pos, vel)
+        L, vel = modify_reference_frame(center, normal, V=vel)
         vel = vel.T
         return vel[2]
 
-
     registry.add_field((ptype, "particle_relative_velocity_z"),
               function=_particle_relative_velocity_z,
               particle_type=True, units="cm/s",
               validators=[ValidateParameter("normal"),
                           ValidateParameter("center")])
 
+    # this is just particle radius but we add it with an alias for the sake of
+    # consistent naming
+    registry.add_field((ptype, "particle_position_spherical_radius"),
+              function=_particle_radius,
+              particle_type=True, units="cm",
+              validators=[ValidateParameter("normal"),
+                          ValidateParameter("center")])
+
     def _particle_spherical_position_radius(field, data):
-        """
-        Radial component of the particles' position vectors in spherical coords
-        on the provided field parameters for 'normal', 'center', 
-        'bulk_velocity', 
-        """
-        normal = data.get_field_parameter('normal')
-        center = data.get_field_parameter('center')
-        bv = data.get_field_parameter("bulk_velocity")
-        pos = spos
-        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
-        theta = get_sph_theta(pos, center)
-        phi = get_sph_phi(pos, center)
-        pos = pos - np.reshape(center, (3, 1))
-        sphr = get_sph_r_component(pos, theta, phi, normal)
-        return sphr
+        """This field is deprecated and will be removed in a future release"""
+        return data[ptype, 'particle_position_spherical_radius']
 
     registry.add_field((ptype, "particle_spherical_position_radius"),
               function=_particle_spherical_position_radius,
@@ -595,30 +575,29 @@
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
-    # this is just particle radius but add it for ease of use
-    registry.add_field((ptype, "particle_spherical_radius"),
-              function=_particle_radius,
-              particle_type=True, units="cm",
-              validators=[ValidateParameter("normal"),
-                          ValidateParameter("center")])
+    def _particle_position_spherical_theta(field, data):
+        """The spherical theta coordinate of the particle positions.
 
+        Relative to the coordinate system defined by the *normal* vector
+        and *center* field parameters.
+        """
+        normal = data.get_field_parameter("normal")
+        center = data.get_field_parameter("center")
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        pos = pos - np.reshape(center, (3, 1))
+        return data.ds.arr(get_sph_theta(pos, normal), "radian")
+
+    registry.add_field(
+        (ptype, "particle_position_spherical_theta"),
+        function=_particle_position_spherical_theta,
+        particle_type=True,
+        units="radian",
+        validators=[ValidateParameter("center"), ValidateParameter("normal")])
 
     def _particle_spherical_position_theta(field, data):
-        """
-        Theta component of the particles' position vectors in spherical coords
-        on the provided field parameters for 'normal', 'center', and 
-        'bulk_velocity', 
-        """
-        normal = data.get_field_parameter('normal')
-        center = data.get_field_parameter('center')
-        bv = data.get_field_parameter("bulk_velocity")
-        pos = spos
-        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
-        theta = get_sph_theta(pos, center)
-        phi = get_sph_phi(pos, center)
-        pos = pos - np.reshape(center, (3, 1))
-        spht = get_sph_theta_component(pos, theta, phi, normal)
-        return spht
+        """This field is deprecated and will be removed in a future release"""
+        return data[ptype, 'particle_position_spherical_theta']
 
     registry.add_field((ptype, "particle_spherical_position_theta"),
               function=_particle_spherical_position_theta,
@@ -626,61 +605,42 @@
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
-    def _particle_spherical_theta(field,data):
+    def _particle_position_spherical_phi(field, data):
+        """The spherical phi component of the particle positions
+
+        Relative to the coordinate system defined by the *normal* vector
+        and *center* field parameters.
+        """
         normal = data.get_field_parameter("normal")
-        coords = get_periodic_rvec(data)
-        return data.ds.arr(get_sph_theta(coords, normal),"radian")
+        center = data.get_field_parameter("center")
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        pos = pos - np.reshape(center, (3, 1))
+        return data.ds.arr(get_sph_phi(pos, normal), "radian")
 
-    registry.add_field((ptype, "particle_spherical_theta"),
-             function=_particle_spherical_theta,
-             particle_type=True, units = "radian",
+    registry.add_field(
+        (ptype, "particle_position_spherical_phi"),
+        function=_particle_position_spherical_phi,
+        particle_type=True,
+        units="radian",
+        validators=[ValidateParameter("normal"), ValidateParameter("center")])
+
+    def _particle_spherical_position_phi(field, data):
+        """This field is deprecated and will be removed in a future release"""
+        return data[ptype, 'particle_position_spherical_phi']
+
+    registry.add_field((ptype, "particle_spherical_position_phi"),
+             function=_particle_spherical_position_phi,
+             particle_type=True, units="radian",
              validators=[ValidateParameter("center"),
                          ValidateParameter("normal")])
 
+    def _particle_velocity_spherical_radius(field, data):
+        """The spherical radius component of the particle velocities in an
+         arbitrary coordinate system
 
-
-    def _particle_spherical_position_phi(field, data):
-        """
-        Phi component of the particles' position vectors in spherical coords
-        on the provided field parameters for 'normal', 'center', and 
-        'bulk_velocity', 
-        """
-        normal = data.get_field_parameter('normal')
-        center = data.get_field_parameter('center')
-        bv = data.get_field_parameter("bulk_velocity")
-        pos = spos
-        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
-        theta = get_sph_theta(pos, center)
-        phi = get_sph_phi(pos, center)
-        pos = pos - np.reshape(center, (3, 1))
-        sphp = get_sph_phi_component(pos, phi, normal)
-        return sphp
-
-    registry.add_field((ptype, "particle_spherical_position_phi"),
-              function=_particle_spherical_position_phi,
-              particle_type=True, units="cm",
-              validators=[ValidateParameter("normal"), 
-                          ValidateParameter("center")])
-
-
-    def _particle_spherical_phi(field,data):
-        normal = data.get_field_parameter("normal")
-        coords = get_periodic_rvec(data)
-        return data.ds.arr(get_sph_phi(coords, normal),"radian")
-
-    registry.add_field((ptype, "particle_spherical_phi"),
-             function=_particle_spherical_phi,
-             particle_type=True, units = "radian",
-             validators=[ValidateParameter("center"),
-                         ValidateParameter("normal")])
-
-
-    
-    def _particle_spherical_velocity_radius(field, data):
-        """
-        Radial component of the particles' velocity vectors in spherical coords
-        based on the provided field parameters for 'normal', 'center', and 
-        'bulk_velocity', 
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
@@ -696,25 +656,36 @@
         sphr = get_sph_r_component(vel, theta, phi, normal)
         return sphr
 
+    registry.add_field((ptype, "particle_velocity_spherical_radius"),
+              function=_particle_velocity_spherical_radius,
+              particle_type=True, units="cm/s",
+              validators=[ValidateParameter("normal"), 
+                          ValidateParameter("center")])
+
+    def _particle_spherical_velocity_radius(field, data):
+        """This field is deprecated and will be removed in a future release"""
+        return data[ptype, 'particle_velocity_spherical_radius']
+
     registry.add_field((ptype, "particle_spherical_velocity_radius"),
               function=_particle_spherical_velocity_radius,
               particle_type=True, units="cm/s",
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
-    # This is simply aliased to "particle_spherical_velocity_radius"
-    # for ease of use.
+    # particel_velocity_spherical_radius is simply aliased to
+    # "particle_radial_velocity" for convenience
     registry.add_field((ptype, "particle_radial_velocity"),
               function=_particle_spherical_velocity_radius,
               particle_type=True, units="cm/s",
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
-    def _particle_spherical_velocity_theta(field, data):
-        """
-        Theta component of the particles' velocity vectors in spherical coords
-        based on the provided field parameters for 'normal', 'center', and 
-        'bulk_velocity', 
+    def _particle_velocity_spherical_theta(field, data):
+        """The spherical theta component of the particle velocities in an
+         arbitrary coordinate system
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
@@ -730,38 +701,63 @@
         spht = get_sph_theta_component(vel, theta, phi, normal)
         return spht
 
+    registry.add_field(
+        (ptype, "particle_velocity_spherical_theta"),
+        function=_particle_velocity_spherical_theta,
+        particle_type=True,
+        units="cm/s",
+        validators=[ValidateParameter("normal"), ValidateParameter("center")])
+
+    def _particle_spherical_velocity_theta(field, data):
+        """This field is deprecated and will be removed in a future release"""
+        return data[ptype, 'particle_velocity_spherical_theta']
+
     registry.add_field((ptype, "particle_spherical_velocity_theta"),
               function=_particle_spherical_velocity_theta,
               particle_type=True, units="cm/s",
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
-    def _particle_spherical_velocity_phi(field, data):
-        """
-        Phi component of the particles' velocity vectors in spherical coords
-        based on the provided field parameters for 'normal', 'center', and 
-        'bulk_velocity', 
+    def _particle_velocity_spherical_phi(field, data):
+        """The cylindrical radial component of the particles velocities
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
         bv = data.get_field_parameter("bulk_velocity")
         pos = YTArray([data[ptype, spos % ax] for ax in "xyz"])
         vel = YTArray([data[ptype, svel % ax] for ax in "xyz"])
-        theta = get_sph_theta(pos, center)
         phi = get_sph_phi(pos, center)
         pos = pos - np.reshape(center, (3, 1))
         vel = vel - np.reshape(bv, (3, 1))
         sphp = get_sph_phi_component(vel, phi, normal)
         return sphp
 
+    registry.add_field(
+        (ptype, "particle_spherical_velocity_phi"),
+        function=_particle_velocity_spherical_phi,
+        particle_type=True,
+        units="cm/s",
+        validators=[ValidateParameter("normal"), ValidateParameter("center")])
+
+    def _particle_spherical_velocity_phi(field, data):
+        """This field is deprecated and will be removed in a future release"""
+        return data[ptype, 'particle_spherical_velocity_theta']
+
     registry.add_field((ptype, "particle_spherical_velocity_phi"),
               function=_particle_spherical_velocity_phi,
               particle_type=True, units="cm/s",
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
+    def _particle_position_cylindrical_radius(field, data):
+        """The cylindrical radius component of the particle positions
 
-    def _particle_cylindrical_radius(field, data):
+        Relative to the coordinate system defined by the *normal* vector
+        and *center* field parameters.
+        """
         normal = data.get_field_parameter("normal")
         center = data.get_field_parameter('center')
         pos = YTArray([data[ptype, spos % ax] for ax in "xyz"])
@@ -769,26 +765,38 @@
         return data.ds.arr(get_cyl_r(pos, normal),
                            'code_length')
 
+    registry.add_field(
+        (ptype, "particle_position_cylindrical_radius"),
+        function=_particle_position_cylindrical_radius,
+        units="cm",
+        particle_type=True,
+        validators=[ValidateParameter("normal"), ValidateParameter("center")])
 
-    registry.add_field((ptype, "particle_cylindrical_radius"),
-              function=_particle_cylindrical_radius,
-              validators=[ValidateParameter("normal"), ValidateParameter("center")],
-              units="cm", particle_type = True)
+    def _particle_position_cylindrical_theta(field,data):
+        """The cylindrical theta component of the particle positions
 
+        Relative to the coordinate system defined by the *normal* vector
+        and *center* field parameters.
+        """
+        normal = data.get_field_parameter("normal")
+        center = data.get_field_parameter('center')
+        pos = YTArray([data[ptype, spos % ax] for ax in "xyz"])
+        pos = pos - np.reshape(center, (3, 1))
+        return data.ds.arr(get_cyl_theta(pos, normal), "radian")
 
-    def _particle_cylindrical_theta(field,data):
-        normal = data.get_field_parameter("normal")
-        coords = get_periodic_rvec(data)
-        return data.ds.arr(get_cyl_theta(coords, normal),"radian")
-        
-    registry.add_field((ptype, "particle_cylindrical_theta"),
-             function=_particle_cylindrical_theta,
-             particle_type=True, units = "radian",
-             validators=[ValidateParameter("center"),
-                         ValidateParameter("normal")])
+    registry.add_field(
+        (ptype, "particle_position_cylindrical_theta"),
+        function=_particle_position_cylindrical_theta,
+        particle_type=True,
+        units="radian",
+        validators=[ValidateParameter("center"), ValidateParameter("normal")])
 
+    def _particle_position_cylindrical_z(field,data):
+        """The cylindrical z component of the particle positions
 
-    def _particle_cylindrical_z(field,data):
+        Relative to the coordinate system defined by the *normal* vector
+        and *center* field parameters.
+        """
         normal = data.get_field_parameter("normal")
         center = data.get_field_parameter('center')
         pos = YTArray([data[ptype, spos % ax] for ax in "xyz"])
@@ -796,19 +804,18 @@
         return data.ds.arr(get_cyl_z(pos, normal),
                            'code_length')
 
+    registry.add_field(
+        (ptype, "particle_position_cylindrical_z"),
+        function=_particle_position_cylindrical_z,
+        units="cm",
+        particle_type=True,
+        validators=[ValidateParameter("normal"), ValidateParameter("center")])
 
-    registry.add_field((ptype, "particle_cylindrical_z"),
-              function=_particle_cylindrical_z,
-              validators=[ValidateParameter("normal"), ValidateParameter("center")],
-              units="cm", particle_type = True)
+    def _particle_velocity_cylindrical_radius(field, data):
+        """The cylindrical radial component of the particles velocities
 
-
-
-    def _particle_cylindrical_velocity_radius(field, data):
-        """
-        Radial component of the particles' velocity vectors in cylindrical coords
-        based on the provided field parameters for 'normal', 'center', and 
-        'bulk_velocity', 
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
@@ -818,31 +825,23 @@
         vel = svel
         vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
         theta = get_cyl_theta(pos, center)
-        z = get_cyl_z(pos, center)
         pos = pos - np.reshape(center, (3, 1))
         vel = vel - np.reshape(bv, (3, 1))
         cylr = get_cyl_r_component(vel, theta, normal)
         return cylr
 
-    registry.add_field((ptype, "particle_cylindrical_velocity_radius"),
-              function=_particle_spherical_velocity_radius,
-              particle_type=True, units="cm/s",
-              validators=[ValidateParameter("normal"), 
-                          ValidateParameter("center")])
+    registry.add_field(
+        (ptype, "particle_velocity_cylindrical_radius"),
+        function=_particle_velocity_spherical_radius,
+        particle_type=True,
+        units="cm/s",
+        validators=[ValidateParameter("normal"), ValidateParameter("center")])
 
-    # This is simply aliased to "particle_cylindrical_velocity_radius"
-    # for ease of use.
-    registry.add_field((ptype, "particle_cylindrical_velocity"),
-              function=_particle_cylindrical_velocity_radius,
-              particle_type=True, units="cm/s",
-              validators=[ValidateParameter("normal"), 
-                          ValidateParameter("center")])
+    def _particle_velocity_cylindrical_theta(field, data):
+        """The cylindrical theta component of the particles velocities
 
-    def _particle_cylindrical_velocity_theta(field, data):
-        """
-        Theta component of the particles' velocity vectors in cylindrical coords
-        based on the provided field parameters for 'normal', 'center', and 
-        'bulk_velocity', 
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
@@ -852,23 +851,33 @@
         vel = svel
         vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
         theta = get_cyl_theta(pos, center)
-        z = get_cyl_z(pos, center)
         pos = pos - np.reshape(center, (3, 1))
         vel = vel - np.reshape(bv, (3, 1))
         cylt = get_cyl_theta_component(vel, theta, normal)
         return cylt
 
+    registry.add_field(
+        (ptype, "particle_velocity_cylindrical_theta"),
+        function=_particle_velocity_cylindrical_theta,
+        particle_type=True,
+        units="cm/s",
+        validators=[ValidateParameter("normal"), ValidateParameter("center")])
+
+    def _particle_cylindrical_velocity_theta(field, data):
+        """This field is deprecated and will be removed in a future release"""
+        return data[ptype, 'particle_velocity_cylindrical_theta']
+
     registry.add_field((ptype, "particle_cylindrical_velocity_theta"),
               function=_particle_cylindrical_velocity_theta,
               particle_type=True, units="cm/s",
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
-    def _particle_cylindrical_velocity_z(field, data):
-        """
-        z component of the particles' velocity vectors in cylindrical coords
-        based on the provided field parameters for 'normal', 'center', and 
-        'bulk_velocity', 
+    def _particle_velocity_cylindrical_z(field, data):
+        """The cylindrical z component of the particles velocities
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
@@ -877,13 +886,22 @@
         pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
         vel = svel
         vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
-        theta = get_cyl_theta(pos, center)
-        z = get_cyl_z(pos, center)
         pos = pos - np.reshape(center, (3, 1))
         vel = vel - np.reshape(bv, (3, 1))
         cylz = get_cyl_z_component(vel, normal)
         return cylz
 
+    registry.add_field(
+        (ptype, "particle_velocity_cylindrical_z"),
+        function=_particle_velocity_cylindrical_z,
+        particle_type=True,
+        units="cm/s",
+        validators=[ValidateParameter("normal"), ValidateParameter("center")])
+
+    def _particle_cylindrical_velocity_z(field, data):
+        """This field is deprecated and will be removed in a future release"""
+        return data[ptype, "particle_velocity_cylindrical_z"]
+
     registry.add_field((ptype, "particle_cylindrical_velocity_z"),
               function=_particle_cylindrical_velocity_z,
               particle_type=True, units="cm/s",
@@ -891,9 +909,6 @@
                           ValidateParameter("center")])
 
 
-
-
-
 def add_particle_average(registry, ptype, field_name, 
                          weight = "particle_mass",
                          density = True):

diff -r b68776d078fa4455aa2c650c1ccf0c61c726e2df -r 996bc5a04b09668415711c22c278b04163fa5c46 yt/utilities/math_utils.py
--- a/yt/utilities/math_utils.py
+++ b/yt/utilities/math_utils.py
@@ -238,7 +238,7 @@
         return np.dot(R, a.T).T
     
 
-def modify_reference_frame(CoM, L, P, V):
+def modify_reference_frame(CoM, L, P=None, V=None):
     r"""Rotates and translates data into a new reference frame to make
     calculations easier.
     
@@ -258,10 +258,13 @@
     L : array
         The angular momentum vector.
     
+    Optional
+    --------
+        
     P : array
         The positions of the data to be modified (i.e. particle or grid cell
         postions). The array should be Nx3.
-    
+
     V : array
         The velocities of the data to be modified (i.e. particle or grid cell
         velocities). The array should be Nx3.
@@ -272,10 +275,10 @@
         The angular momentum vector equal to [0, 0, 1] modulo machine error.
     
     P : array
-        The modified positional data.
+        The modified positional data. Only returned if P is not None
     
     V : array
-        The modified velocity data.
+        The modified velocity data. Only returned if V is not None
     
     Examples
     --------
@@ -300,9 +303,15 @@
     """
     if (L == np.array([0, 0, 1.])).all():
         # Whew! Nothing to do!
-        return L, P, V
+        if V is None:
+            return L, P
+        if P is None:
+            return L, V
+        else:
+            return L, P, V
     # First translate the positions to center of mass reference frame.
-    P = P - CoM
+    if P is not None:
+        P = P - CoM
     # Now find the angle between modified L and the x-axis.
     LL = L.copy()
     LL[2] = 0.
@@ -311,16 +320,25 @@
         theta = -theta
     # Now rotate all the position, velocity, and L vectors by this much around
     # the z axis.
-    P = rotate_vector_3D(P, 2, theta)
-    V = rotate_vector_3D(V, 2, theta)
+    if P is not None:
+        P = rotate_vector_3D(P, 2, theta)
+    if V is not None:
+        V = rotate_vector_3D(V, 2, theta)
     L = rotate_vector_3D(L, 2, theta)
     # Now find the angle between L and the z-axis.
     theta = np.arccos(np.inner(L, [0,0,1])/np.inner(L,L)**.5)
     # This time we rotate around the y axis.
-    P = rotate_vector_3D(P, 1, theta)
-    V = rotate_vector_3D(V, 1, theta)
+    if P is not None:
+        P = rotate_vector_3D(P, 1, theta)
+    if V is not None:
+        V = rotate_vector_3D(V, 1, theta)
     L = rotate_vector_3D(L, 1, theta)
-    return L, P, V
+    if V is None:
+        return L, P
+    if P is None:
+        return L, V
+    else:
+        return L, P, V
 
 def compute_rotational_velocity(CoM, L, P, V):
     r"""Computes the rotational velocity for some data around an axis.


https://bitbucket.org/yt_analysis/yt/commits/d3e2457b53bb/
Changeset:   d3e2457b53bb
Branch:      yt
User:        ngoldbaum
Date:        2014-12-23 18:11:18+00:00
Summary:     Merging with tip.
Affected #:  108 files

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 distribute_setup.py
--- a/distribute_setup.py
+++ b/distribute_setup.py
@@ -269,7 +269,7 @@
 
 def _remove_flat_installation(placeholder):
     if not os.path.isdir(placeholder):
-        log.warn('Unkown installation at %s', placeholder)
+        log.warn('Unknown installation at %s', placeholder)
         return False
     found = False
     for file in os.listdir(placeholder):

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/extensions/notebook_sphinxext.py
--- a/doc/extensions/notebook_sphinxext.py
+++ b/doc/extensions/notebook_sphinxext.py
@@ -1,9 +1,16 @@
-import os, shutil, string, glob, re
+import errno
+import os
+import shutil
+import string
+import re
+import tempfile
+import uuid
 from sphinx.util.compat import Directive
 from docutils import nodes
 from docutils.parsers.rst import directives
+from IPython.config import Config
 from IPython.nbconvert import html, python
-from IPython.nbformat.current import read, write
+from IPython.nbformat import current as nbformat
 from runipy.notebook_runner import NotebookRunner, NotebookError
 
 class NotebookDirective(Directive):
@@ -14,7 +21,7 @@
     """
     required_arguments = 1
     optional_arguments = 1
-    option_spec = {'skip_exceptions' : directives.flag}
+    option_spec = {'skip_exceptions': directives.flag}
     final_argument_whitespace = True
 
     def run(self): # check if there are spaces in the notebook name
@@ -26,9 +33,11 @@
         if not self.state.document.settings.raw_enabled:
             raise self.warning('"%s" directive disabled.' % self.name)
 
+        cwd = os.getcwd()
+        tmpdir = tempfile.mkdtemp()
+        os.chdir(tmpdir)
+
         # get path to notebook
-        source_dir = os.path.dirname(
-            os.path.abspath(self.state.document.current_source))
         nb_filename = self.arguments[0]
         nb_basename = os.path.basename(nb_filename)
         rst_file = self.state_machine.document.attributes['source']
@@ -37,26 +46,24 @@
 
         # Move files around.
         rel_dir = os.path.relpath(rst_dir, setup.confdir)
-        rel_path = os.path.join(rel_dir, nb_basename)
         dest_dir = os.path.join(setup.app.builder.outdir, rel_dir)
         dest_path = os.path.join(dest_dir, nb_basename)
 
-        if not os.path.exists(dest_dir):
-            os.makedirs(dest_dir)
+        image_dir, image_rel_dir = make_image_dir(setup, rst_dir)
 
-        # Copy unevaluated script
-        try:
-            shutil.copyfile(nb_abs_path, dest_path)
-        except IOError:
-            raise RuntimeError("Unable to copy notebook to build destination.")
+        # Ensure desination build directory exists
+        thread_safe_mkdir(os.path.dirname(dest_path))
 
+        # Copy unevaluated notebook
+        shutil.copyfile(nb_abs_path, dest_path)
+
+        # Construct paths to versions getting copied over
         dest_path_eval = string.replace(dest_path, '.ipynb', '_evaluated.ipynb')
         dest_path_script = string.replace(dest_path, '.ipynb', '.py')
         rel_path_eval = string.replace(nb_basename, '.ipynb', '_evaluated.ipynb')
         rel_path_script = string.replace(nb_basename, '.ipynb', '.py')
 
         # Create python script vesion
-        unevaluated_text = nb_to_html(nb_abs_path)
         script_text = nb_to_python(nb_abs_path)
         f = open(dest_path_script, 'w')
         f.write(script_text.encode('utf8'))
@@ -64,8 +71,11 @@
 
         skip_exceptions = 'skip_exceptions' in self.options
 
-        evaluated_text = evaluate_notebook(nb_abs_path, dest_path_eval,
-                                           skip_exceptions=skip_exceptions)
+        evaluated_text, resources = evaluate_notebook(
+            nb_abs_path, dest_path_eval, skip_exceptions=skip_exceptions)
+
+        evaluated_text = write_notebook_output(
+            resources, image_dir, image_rel_dir, evaluated_text)
 
         # Create link to notebook and script files
         link_rst = "(" + \
@@ -85,12 +95,9 @@
         # add dependency
         self.state.document.settings.record_dependencies.add(nb_abs_path)
 
-        # clean up png files left behind by notebooks.
-        png_files = glob.glob("*.png")
-        fits_files = glob.glob("*.fits")
-        h5_files = glob.glob("*.h5")
-        for file in png_files:
-            os.remove(file)
+        # clean up
+        os.chdir(cwd)
+        shutil.rmtree(tmpdir, True)
 
         return [nb_node]
 
@@ -106,14 +113,18 @@
 
 def nb_to_html(nb_path):
     """convert notebook to html"""
-    exporter = html.HTMLExporter(template_file='full')
-    output, resources = exporter.from_filename(nb_path)
+    c = Config({'ExtractOutputPreprocessor':{'enabled':True}})
+
+    exporter = html.HTMLExporter(template_file='full', config=c)
+    notebook = nbformat.read(open(nb_path), 'json')
+    output, resources = exporter.from_notebook_node(notebook)
     header = output.split('<head>', 1)[1].split('</head>',1)[0]
     body = output.split('<body>', 1)[1].split('</body>',1)[0]
 
     # http://imgur.com/eR9bMRH
     header = header.replace('<style', '<style scoped="scoped"')
-    header = header.replace('body {\n  overflow: visible;\n  padding: 8px;\n}\n', '')
+    header = header.replace('body {\n  overflow: visible;\n  padding: 8px;\n}\n',
+                            '')
     header = header.replace("code,pre{", "code{")
 
     # Filter out styles that conflict with the sphinx theme.
@@ -124,17 +135,19 @@
         'uneditable-input{',
         'collapse{',
     ]
+
     filter_strings.extend(['h%s{' % (i+1) for i in range(6)])
 
-    line_begin_strings = [
+    line_begin = [
         'pre{',
         'p{margin'
-        ]
+    ]
 
-    header_lines = filter(
-        lambda x: not any([s in x for s in filter_strings]), header.split('\n'))
-    header_lines = filter(
-        lambda x: not any([x.startswith(s) for s in line_begin_strings]), header_lines)
+    filterfunc = lambda x: not any([s in x for s in filter_strings])
+    header_lines = filter(filterfunc, header.split('\n'))
+
+    filterfunc = lambda x: not any([x.startswith(s) for s in line_begin])
+    header_lines = filter(filterfunc, header_lines)
 
     header = '\n'.join(header_lines)
 
@@ -143,13 +156,11 @@
     lines.append(header)
     lines.append(body)
     lines.append('</div>')
-    return '\n'.join(lines)
+    return '\n'.join(lines), resources
 
 def evaluate_notebook(nb_path, dest_path=None, skip_exceptions=False):
     # Create evaluated version and save it to the dest path.
-    # Always use --pylab so figures appear inline
-    # perhaps this is questionable?
-    notebook = read(open(nb_path), 'json')
+    notebook = nbformat.read(open(nb_path), 'json')
     nb_runner = NotebookRunner(notebook, pylab=False)
     try:
         nb_runner.run_notebook(skip_exceptions=skip_exceptions)
@@ -158,11 +169,14 @@
         print e
         # Return the traceback, filtering out ANSI color codes.
         # http://stackoverflow.com/questions/13506033/filtering-out-ansi-escape-sequences
-        return 'Notebook conversion failed with the following traceback: \n%s' % \
-            re.sub(r'\\033[\[\]]([0-9]{1,2}([;@][0-9]{0,2})*)*[mKP]?', '', str(e))
+        return "Notebook conversion failed with the " \
+               "following traceback: \n%s" % \
+            re.sub(r'\\033[\[\]]([0-9]{1,2}([;@][0-9]{0,2})*)*[mKP]?', '',
+                   str(e))
+
     if dest_path is None:
         dest_path = 'temp_evaluated.ipynb'
-    write(nb_runner.nb, open(dest_path, 'w'), 'json')
+    nbformat.write(nb_runner.nb, open(dest_path, 'w'), 'json')
     ret = nb_to_html(dest_path)
     if dest_path is 'temp_evaluated.ipynb':
         os.remove(dest_path)
@@ -186,3 +200,37 @@
                  html=(visit_notebook_node, depart_notebook_node))
 
     app.add_directive('notebook', NotebookDirective)
+
+    retdict = dict(
+        version='0.1',
+        parallel_read_safe=True,
+        parallel_write_safe=True
+    )
+
+    return retdict
+
+def make_image_dir(setup, rst_dir):
+    image_dir = setup.app.builder.outdir + os.path.sep + '_images'
+    rel_dir = os.path.relpath(setup.confdir, rst_dir)
+    image_rel_dir = rel_dir + os.path.sep + '_images'
+    thread_safe_mkdir(image_dir)
+    return image_dir, image_rel_dir
+
+def write_notebook_output(resources, image_dir, image_rel_dir, evaluated_text):
+    my_uuid = uuid.uuid4().hex
+
+    for output in resources['outputs']:
+        new_name = image_dir + os.path.sep + my_uuid + output
+        new_relative_name = image_rel_dir + os.path.sep + my_uuid + output
+        evaluated_text = evaluated_text.replace(output, new_relative_name)
+        with open(new_name, 'wb') as f:
+            f.write(resources['outputs'][output])
+    return evaluated_text
+
+def thread_safe_mkdir(dirname):
+    try:
+        os.makedirs(dirname)
+    except OSError as e:
+        if e.errno != errno.EEXIST:
+            raise
+        pass

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/extensions/notebookcell_sphinxext.py
--- a/doc/extensions/notebookcell_sphinxext.py
+++ b/doc/extensions/notebookcell_sphinxext.py
@@ -1,14 +1,14 @@
-import os, shutil, string, glob, io
+import os
+import shutil
+import io
+import tempfile
 from sphinx.util.compat import Directive
 from docutils.parsers.rst import directives
-from IPython.nbconvert import html, python
 from IPython.nbformat import current
-from runipy.notebook_runner import NotebookRunner
-from jinja2 import FileSystemLoader
 from notebook_sphinxext import \
-    notebook_node, nb_to_html, nb_to_python, \
-    visit_notebook_node, depart_notebook_node, \
-    evaluate_notebook
+    notebook_node, visit_notebook_node, depart_notebook_node, \
+    evaluate_notebook, make_image_dir, write_notebook_output
+
 
 class NotebookCellDirective(Directive):
     """Insert an evaluated notebook cell into a document
@@ -19,13 +19,22 @@
     required_arguments = 0
     optional_arguments = 1
     has_content = True
-    option_spec = {'skip_exceptions' : directives.flag}
+    option_spec = {'skip_exceptions': directives.flag}
 
     def run(self):
         # check if raw html is supported
         if not self.state.document.settings.raw_enabled:
             raise self.warning('"%s" directive disabled.' % self.name)
 
+        cwd = os.getcwd()
+        tmpdir = tempfile.mkdtemp()
+        os.chdir(tmpdir)
+
+        rst_file = self.state_machine.document.attributes['source']
+        rst_dir = os.path.abspath(os.path.dirname(rst_file))
+
+        image_dir, image_rel_dir = make_image_dir(setup, rst_dir)
+
         # Construct notebook from cell content
         content = "\n".join(self.content)
         with open("temp.py", "w") as f:
@@ -35,7 +44,11 @@
 
         skip_exceptions = 'skip_exceptions' in self.options
 
-        evaluated_text = evaluate_notebook('temp.ipynb', skip_exceptions=skip_exceptions)
+        evaluated_text, resources = evaluate_notebook(
+            'temp.ipynb', skip_exceptions=skip_exceptions)
+
+        evaluated_text = write_notebook_output(
+            resources, image_dir, image_rel_dir, evaluated_text)
 
         # create notebook node
         attributes = {'format': 'html', 'source': 'nb_path'}
@@ -44,9 +57,8 @@
             self.state_machine.get_source_and_line(self.lineno)
 
         # clean up
-        files = glob.glob("*.png") + ['temp.py', 'temp.ipynb']
-        for file in files:
-            os.remove(file)
+        os.chdir(cwd)
+        shutil.rmtree(tmpdir, True)
 
         return [nb_node]
 
@@ -60,6 +72,14 @@
 
     app.add_directive('notebook-cell', NotebookCellDirective)
 
+    retdict = dict(
+        version='0.1',
+        parallel_read_safe=True,
+        parallel_write_safe=True
+    )
+
+    return retdict
+
 def convert_to_ipynb(py_file, ipynb_file):
     with io.open(py_file, 'r', encoding='utf-8') as f:
         notebook = current.reads(f.read(), format='py')

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/extensions/numpydocmod/numpydoc.py
--- a/doc/extensions/numpydocmod/numpydoc.py
+++ b/doc/extensions/numpydocmod/numpydoc.py
@@ -99,6 +99,15 @@
     app.add_domain(NumpyPythonDomain)
     app.add_domain(NumpyCDomain)
 
+    retdict = dict(
+        version='0.1',
+        parallel_read_safe=True,
+        parallel_write_safe=True
+    )
+
+    return retdict
+
+
 #------------------------------------------------------------------------------
 # Docstring-mangling domains
 #------------------------------------------------------------------------------

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/extensions/pythonscript_sphinxext.py
--- a/doc/extensions/pythonscript_sphinxext.py
+++ b/doc/extensions/pythonscript_sphinxext.py
@@ -1,8 +1,13 @@
+import tempfile
+import os
+import glob
+import shutil
+import subprocess
+import uuid
 from sphinx.util.compat import Directive
-from subprocess import Popen,PIPE
-from docutils.parsers.rst import directives
 from docutils import nodes
-import os, glob, base64
+from notebook_sphinxext import make_image_dir
+
 
 class PythonScriptDirective(Directive):
     """Execute an inline python script and display images.
@@ -17,6 +22,15 @@
     has_content = True
 
     def run(self):
+        cwd = os.getcwd()
+        tmpdir = tempfile.mkdtemp()
+        os.chdir(tmpdir)
+
+        rst_file = self.state_machine.document.attributes['source']
+        rst_dir = os.path.abspath(os.path.dirname(rst_file))
+
+        image_dir, image_rel_dir = make_image_dir(setup, rst_dir)
+
         # Construct script from cell content
         content = "\n".join(self.content)
         with open("temp.py", "w") as f:
@@ -27,35 +41,44 @@
         print content
         print ""
 
-        codeproc = Popen(['python', 'temp.py'], stdout=PIPE)
-        out = codeproc.stdout.read()
+        subprocess.call(['python', 'temp.py'])
 
-        images = sorted(glob.glob("*.png"))
-        fns = []
         text = ''
-        for im in images:
-            text += get_image_tag(im)
-            os.remove(im)
-            
-        os.remove("temp.py")
+        for im in sorted(glob.glob("*.png")):
+            text += get_image_tag(im, image_dir, image_rel_dir)
 
         code = content
 
-        literal = nodes.literal_block(code,code)
+        literal = nodes.literal_block(code, code)
         literal['language'] = 'python'
 
         attributes = {'format': 'html'}
         img_node = nodes.raw('', text, **attributes)
-        
+
+        # clean up
+        os.chdir(cwd)
+        shutil.rmtree(tmpdir, True)
+
         return [literal, img_node]
 
+
 def setup(app):
     app.add_directive('python-script', PythonScriptDirective)
     setup.app = app
     setup.config = app.config
     setup.confdir = app.confdir
 
-def get_image_tag(filename):
-    with open(filename, "rb") as image_file:
-        encoded_string = base64.b64encode(image_file.read())
-        return '<img src="data:image/png;base64,%s" width="600"><br>' % encoded_string
+    retdict = dict(
+        version='0.1',
+        parallel_read_safe=True,
+        parallel_write_safe=True
+    )
+
+    return retdict
+
+
+def get_image_tag(filename, image_dir, image_rel_dir):
+    my_uuid = uuid.uuid4().hex
+    shutil.move(filename, image_dir + os.path.sep + my_uuid + filename)
+    relative_filename = image_rel_dir + os.path.sep + my_uuid + filename
+    return '<img src="%s" width="600"><br>' % relative_filename

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/extensions/youtube.py
--- a/doc/extensions/youtube.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# http://countergram.com/youtube-in-rst
-
-from docutils import nodes
-from docutils.parsers.rst import directives
-
-CODE = """\
-<object type="application/x-shockwave-flash"
-        width="%(width)s"
-        height="%(height)s"
-        class="youtube-embed"
-        data="http://www.youtube.com/v/%(yid)s">
-    <param name="movie" value="http://www.youtube.com/v/%(yid)s"></param>
-    <param name="wmode" value="transparent"></param>%(extra)s
-</object>
-"""
-
-PARAM = """\n    <param name="%s" value="%s"></param>"""
-
-def youtube(name, args, options, content, lineno,
-            contentOffset, blockText, state, stateMachine):
-    """ Restructured text extension for inserting youtube embedded videos """
-    if len(content) == 0:
-        return
-    string_vars = {
-        'yid': content[0],
-        'width': 425,
-        'height': 344,
-        'extra': ''
-        }
-    extra_args = content[1:] # Because content[0] is ID
-    extra_args = [ea.strip().split("=") for ea in extra_args] # key=value
-    extra_args = [ea for ea in extra_args if len(ea) == 2] # drop bad lines
-    extra_args = dict(extra_args)
-    if 'width' in extra_args:
-        string_vars['width'] = extra_args.pop('width')
-    if 'height' in extra_args:
-        string_vars['height'] = extra_args.pop('height')
-    if extra_args:
-        params = [PARAM % (key, extra_args[key]) for key in extra_args]
-        string_vars['extra'] = "".join(params)
-    return [nodes.raw('', CODE % (string_vars), format='html')]
-youtube.content = True
-directives.register_directive('youtube', youtube)

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/extensions/yt_colormaps.py
--- a/doc/extensions/yt_colormaps.py
+++ b/doc/extensions/yt_colormaps.py
@@ -15,6 +15,14 @@
     setup.config = app.config
     setup.confdir = app.confdir
 
+    retdict = dict(
+        version='0.1',
+        parallel_read_safe=True,
+        parallel_write_safe=True
+    )
+
+    return retdict
+
 class ColormapScript(Directive):
     required_arguments = 1
     optional_arguments = 0

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/extensions/yt_cookbook.py
--- a/doc/extensions/yt_cookbook.py
+++ b/doc/extensions/yt_cookbook.py
@@ -15,6 +15,14 @@
     setup.config = app.config
     setup.confdir = app.confdir
 
+    retdict = dict(
+        version='0.1',
+        parallel_read_safe=True,
+        parallel_write_safe=True
+    )
+
+    return retdict
+
 data_patterns = ["*.h5", "*.out", "*.dat"]
 
 class CookbookScript(Directive):

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/helper_scripts/show_fields.py
--- a/doc/helper_scripts/show_fields.py
+++ b/doc/helper_scripts/show_fields.py
@@ -126,7 +126,7 @@
     if in_cgs:
         unit_object = unit_object.get_cgs_equivalent()
     latex = unit_object.latex_representation()
-    return latex.replace('\/','~')
+    return latex.replace('\/', '~')
 
 def print_all_fields(fl):
     for fn in sorted(fl):
@@ -204,6 +204,10 @@
                 field_info_names.append("CastroFieldInfo")
             else: 
                 field_info_names.append("BoxlibFieldInfo")
+    elif frontend == "chombo":
+        # remove low dimensional field info containters for ChomboPIC
+        field_info_names = [f for f in field_info_names if '1D' not in f
+                            and '2D' not in f]
 
     for dset_name, fi_name in zip(dataset_names, field_info_names):
         fi = getattr(this_f, fi_name)
@@ -271,5 +275,6 @@
                                   dp=f.dname, dw=len_disp)
                 
             print div
+            print ""
 
 print footer

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/how_to_develop_yt.txt
--- a/doc/how_to_develop_yt.txt
+++ /dev/null
@@ -1,157 +0,0 @@
-How To Develop yt
-=================
-
-We are very happy to accept patches, features, and bugfixes from any member of
-the community!  yt is developed using mercurial, primarily because it enables
-very easy and straightforward submission of changesets.  We're eager to hear
-from you, and if you are developing yt, we encourage you to subscribe to the
-developer mailing list:
-
-http://lists.spacepope.org/listinfo.cgi/yt-dev-spacepope.org
-
-Please feel free to hack around, commit changes, and send them upstream.  If
-you're new to Mercurial, these three resources are pretty great for learning
-the ins and outs:
-
-   * http://hginit.com
-   * http://hgbook.red-bean.com/read/
-   * http://mercurial.selenic.com/
-
-Keep in touch, and happy hacking!  We also provide doc/coding_styleguide.txt
-and an example of a fiducial docstring in doc/docstring_example.txt.  Please
-read them before hacking on the codebase, and feel free to email any of the
-mailing lists for help with the codebase.
-
-Licenses
---------
-
-All code in yt should be under the BSD 3-clause license.
-
-How To Get The Source Code
---------------------------
-
-yt is hosted on BitBucket, and you can see all of the yt repositories at
-http://hg.yt-project.org/ .  With the yt installation script you should have a
-copy of Mercurial.  You can clone the repository like so:
-
-   $ hg clone http://hg.yt-project.org/yt/
-
-You can update to any branch or revision by executing the command:
-
-   $ hg up -C some_revision_specifier
-
-Specifying a branch name in the revspec will update to the latest revision on
-that branch.  If you ran the installation script, you can tell Python to use a
-different version of the library by executing:
-
-   $ python2.6 setup.py develop
-
-This will rebuild all C modules as well.
-
-How To Submit Changes
----------------------
-
-You can submit changes a couple different ways, but the easiest is to use the
-"fork" mechanism on BitBucket.  Just go here:
-
-http://hg.yt-project.org/yt/fork
-
-and you're all set, ready to go.  You'll have to either clone a new copy of the
-repository or edit .hg/hgrc to point to the location of your new fork, first,
-though.
-
-When you're ready to submit them to the main repository, simply go to:
-
-http://hg.yt-project.org/yt/fork
-
-Make sure you notify "yt_analysis" and put in a little description.  That'll
-notify the core developers that you've got something ready to submit, and we
-will review it an (hopefully!) merge it in.  If it goes well, you may end up
-with push access to the main repository.
-
-How To Read The Source Code
----------------------------
-
-yt is organized into several sub-packages, each of which governs a different
-conceptual regime.
-
-   frontends
-      This is where interfaces to codes are created.  Within each subdirectory of
-      yt/frontends/ there must exist the following files, even if empty:
-
-      * data_structures.py, where subclasses of AMRGridPatch, Dataset and
-        GridIndex are defined.
-      * io.py, where a subclass of IOHandler is defined.
-      * misc.py, where any miscellaneous functions or classes are defined.
-      * definitions.py, where any definitions specific to the frontend are
-        defined.  (i.e., header formats, etc.)
-
-   visualization
-      This is where all visualization modules are stored.  This includes plot
-      collections, the volume rendering interface, and pixelization frontends.
-
-   data_objects
-      All objects that handle data, processed or unprocessed, not explicitly
-      defined as visualization are located in here.  This includes the base
-      classes for data regions, covering grids, time series, and so on.  This
-      also includes derived fields and derived quantities.
-
-   astro_objects
-      This is where all objects that represent astrophysical objects should
-      live -- for instance, galaxies, halos, disks, clusters and so on.  These
-      can be expressive, provide astrophysical analysis functionality and will
-      in general be more user-modifiable, user-tweakable, and much less of a
-      black box that data_objects.
-
-   analysis_modules
-      This is where all mechanisms for processing data live.  This includes
-      things like clump finding, halo profiling, halo finding, and so on.  This
-      is something of a catchall, but it serves as a level of greater
-      abstraction that simply data selection and modification.
-
-   gui
-      This is where all GUI components go.  Typically this will be some small
-      tool used for one or two things, which contains a launching mechanism on
-      the command line.
-
-   utilities
-      All broadly useful code that doesn't clearly fit in one of the other
-      categories goes here.
-
-How To Use Branching
---------------------
-
-If you are planning on making a large change to the code base that may not be
-ready for many commits, or if you are planning on breaking some functionality
-and rewriting it, you are encouraged to create a new named branch.  You can
-mark the current repository as a new named branch by executing:
-
-   $ hg branch new_feature_name
-
-The next commit and all subsequent commits will be contained within that named
-branch.  At this point, add your branch here:
-
-http://yt-project.org/wiki/ExistingBranches
-
-To merge changes in from another branch, you would execute:
-
-   $ hg merge some_other_branch
-
-Note also that you can use revision specifiers instead of "some_other_branch".
-When you are ready to merge back into the main branch, execute this process:
-
-   $ hg merge name_of_main_branch
-   $ hg commit --close-branch
-   $ hg up -C name_of_main_branch
-   $ hg merge name_of_feature_branch
-   $ hg commit
-
-When you execute the merge you may have to resolve conflicts.  Once you resolve
-conflicts in a file, you can mark it as resolved by doing:
-
-   $ hg resolve -m path/to/conflicting/file.py
-
-Please be careful when resolving conflicts in files.
-
-Once your branch has been merged in, mark it as closed on the wiki page.
-

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/install_script.sh
--- a/doc/install_script.sh
+++ b/doc/install_script.sh
@@ -264,8 +264,8 @@
         echo "Alternatively, download the Xcode command line tools from"
         echo "the Apple developer tools website."
         echo
-	echo "OS X 10.8.4 and 10.9: download Xcode 5.02 from the mac app store."
-	echo "(search for Xcode)."
+	echo "OS X 10.8.4, 10.9, and 10.10: download the appropriate version of"
+	echo "Xcode from the mac app store (search for Xcode)."
     echo
 	echo "Additionally, you will have to manually install the Xcode"
 	echo "command line tools."
@@ -273,7 +273,7 @@
     echo "For OS X 10.8, see:"
    	echo "http://stackoverflow.com/questions/9353444"
 	echo
-    echo "For OS X 10.9, the command line tools can be installed"
+    echo "For OS X 10.9 and 10.10, the command line tools can be installed"
     echo "with the following command:"
     echo "    xcode-select --install"
     echo

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/_static/custom.css
--- a/doc/source/_static/custom.css
+++ b/doc/source/_static/custom.css
@@ -99,3 +99,13 @@
   height: 45px; 
   visibility: hidden; 
 }
+
+/*
+
+Make tables span only half the page. 
+
+*/
+
+.table {
+    width: 50%
+}

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/about/index.rst
--- /dev/null
+++ b/doc/source/about/index.rst
@@ -0,0 +1,88 @@
+.. _aboutyt:
+
+About yt
+========
+
+.. contents::
+   :depth: 1
+   :local:
+   :backlinks: none
+
+What is yt?
+-----------
+
+yt is a toolkit for analyzing and visualizing quantitative data.  Originally
+written to analyze 3D grid-based astrophysical simulation data, 
+it has grown to handle any kind of data represented in a 2D or 3D volume.
+yt is an Python-based open source project and is open for anyone to use or 
+contribute code.  The entire source code and history is available to all 
+at https://bitbucket.org/yt_analysis/yt .
+
+.. _who-is-yt:
+
+Who is yt?
+----------
+
+As an open-source project, yt has a large number of user-developers.  
+In September of 2014, the yt developer community collectively decided to endow 
+the title of *member* on individuals who had contributed in a significant way 
+to the project.  For a list of those members and a description of their 
+contributions to the code, see 
+`our members website. <http://yt-project.org/members.html>`_
+
+For an up-to-date list of everyone who has contributed to the yt codebase, 
+see the current `CREDITS <http://hg.yt-project.org/yt/src/yt/CREDITS>`_ file.  
+For a more detailed breakup of contributions made by individual users, see out 
+`Open HUB page <https://www.openhub.net/p/yt_amr/contributors?query=&sort=commits>`_.
+
+History of yt
+-------------
+
+yt was originally begun by Matthew Turk in 2007 in the course of his graduate
+studies in computational astrophysics.  The code was developed
+as a simple data-reader and exporter for grid-based hydrodynamical simulation 
+data outputs from the *Enzo* code.  Over the next few years, he invited 
+collaborators and friends to contribute and use yt.  As the community grew,
+so did the capabilities of yt.  It is now a community-developed project with 
+contributions from many people, the hospitality of several institutions, and 
+benefiting from numerous grants.  With this community-driven approach 
+and contributions from a sizeable population of developers, it has evolved 
+into a fully-featured toolkit for analysis and visualization of 
+multidimensional data.  It relies on no proprietary software -- although it 
+can be and has been extended to interface with proprietary software and 
+libraries -- and has been designed from the ground up to enable users to be 
+as immersed in the data as they desire.
+
+How do I contact yt?
+--------------------
+
+If you have any questions about the code, please contact the `yt users email
+list <http://lists.spacepope.org/listinfo.cgi/yt-users-spacepope.org>`_.  If
+you're having other problems, please follow the steps in 
+:ref:`asking-for-help`.
+
+How do I cite yt?
+-----------------
+
+If you use yt in a publication, we'd very much appreciate a citation!  You
+should feel free to cite the `ApJS paper
+<http://adsabs.harvard.edu/abs/2011ApJS..192....9T>`_ with the following BibTeX
+entry: ::
+
+   @ARTICLE{2011ApJS..192....9T,
+      author = {{Turk}, M.~J. and {Smith}, B.~D. and {Oishi}, J.~S. and {Skory}, S. and 
+   	{Skillman}, S.~W. and {Abel}, T. and {Norman}, M.~L.},
+       title = "{yt: A Multi-code Analysis Toolkit for Astrophysical Simulation Data}",
+     journal = {\apjs},
+   archivePrefix = "arXiv",
+      eprint = {1011.3514},
+    primaryClass = "astro-ph.IM",
+    keywords = {cosmology: theory, methods: data analysis, methods: numerical },
+        year = 2011,
+       month = jan,
+      volume = 192,
+       pages = {9-+},
+         doi = {10.1088/0067-0049/192/1/9},
+      adsurl = {http://adsabs.harvard.edu/abs/2011ApJS..192....9T},
+     adsnote = {Provided by the SAO/NASA Astrophysics Data System}
+   }

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/analyzing/analysis_modules/PPVCube.ipynb
--- a/doc/source/analyzing/analysis_modules/PPVCube.ipynb
+++ b/doc/source/analyzing/analysis_modules/PPVCube.ipynb
@@ -1,7 +1,7 @@
 {
  "metadata": {
   "name": "",
-  "signature": "sha256:b83e125278c2e58da4d99ac9d2ca2a136d01f1094e1b83497925e0f9b9b056c2"
+  "signature": "sha256:7ba601e381023e5b7c00a585ccaa55996316d2dfe7f8c96284b4539e1ee5b846"
  },
  "nbformat": 3,
  "nbformat_minor": 0,
@@ -193,7 +193,7 @@
      "cell_type": "code",
      "collapsed": false,
      "input": [
-      "cube = PPVCube(ds, L, \"density\", dims=(200,100,50), velocity_bounds=(-150.,150.,\"km/s\"))"
+      "cube = PPVCube(ds, L, \"density\", dims=(200,100,50), velocity_bounds=(-150.,150.,\"km/s\"), method=\"sum\")"
      ],
      "language": "python",
      "metadata": {},
@@ -335,7 +335,7 @@
      "collapsed": false,
      "input": [
       "cube2 = PPVCube(ds, L, \"density\", dims=(200,100,50), velocity_bounds=(-150,150,\"km/s\"), thermal_broad=True, \n",
-      "                atomic_weight=12.0)\n",
+      "                atomic_weight=12.0, method=\"sum\")\n",
       "cube2.write_fits(\"cube2.fits\", clobber=True, length_unit=\"kpc\")"
      ],
      "language": "python",

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/analyzing/analysis_modules/halo_finders.rst
--- a/doc/source/analyzing/analysis_modules/halo_finders.rst
+++ b/doc/source/analyzing/analysis_modules/halo_finders.rst
@@ -68,15 +68,17 @@
 but also `separately available <http://code.google.com/p/rockstar>`_. The lead 
 developer is Peter Behroozi, and the methods are described in `Behroozi
 et al. 2011 <http://rockstar.googlecode.com/files/rockstar_ap101911.pdf>`_. 
+In order to run the Rockstar halo finder in yt, make sure you've 
+:ref:`installed it so that it can integrate with yt <rockstar-installation>`.
 
-.. note:: At the moment, Rockstar does not support multiple particle masses, 
-  instead using a fixed particle mass. This will not affect most dark matter 
-  simulations, but does make it less useful for finding halos from the stellar
-  mass. In simulations where the highest-resolution particles all have the 
-  same mass (ie: zoom-in grid based simulations), one can set up a particle
-  filter to select the lowest mass particles and perform the halo finding
-  only on those.  See the this cookbook recipe for an example: 
-  :ref:`cookbook-rockstar-nested-grid`.
+At the moment, Rockstar does not support multiple particle masses, 
+instead using a fixed particle mass. This will not affect most dark matter 
+simulations, but does make it less useful for finding halos from the stellar
+mass. In simulations where the highest-resolution particles all have the 
+same mass (ie: zoom-in grid based simulations), one can set up a particle
+filter to select the lowest mass particles and perform the halo finding
+only on those.  See the this cookbook recipe for an example: 
+:ref:`cookbook-rockstar-nested-grid`.
 
 To run the Rockstar Halo finding, you must launch python with MPI and 
 parallelization enabled. While Rockstar itself does not require MPI to run, 
@@ -201,11 +203,29 @@
 halo finder at a few paddings to find the right amount, especially 
 if you're analyzing many similar datasets.
 
+.. _rockstar-installation:
+
 Rockstar Installation
 ---------------------
 
-The Rockstar is slightly patched and modified to run as a library inside of 
-yt. By default it will be built with yt using the ``install_script.sh``.
-If it wasn't installed, please make sure that the installation setting
-``INST_ROCKSTAR=1`` is defined in the ``install_script.sh`` and re-run
-the installation script.
+Because of changes in the Rockstar API over time, yt only currently works with
+a slightly older version of Rockstar.  This version of Rockstar has been 
+slightly patched and modified to run as a library inside of yt. By default it 
+is not installed with yt, but installation is very easy.  The 
+:ref:`install-script` used to install yt from source has a line: 
+``INST_ROCKSTAR=0`` that must be changed to ``INST_ROCKSTAR=1``.  You can
+rerun this installer script over the top of an existing installation, and
+it will only install components missing from the existing installation.  
+You can do this as follows.  Put your freshly modified install_script in
+the parent directory of the yt installation directory (e.g. the parent of 
+``$YT_DEST``, ``yt-x86_64``, ``yt-i386``, etc.), and rerun the installer:
+
+.. code-block:: bash
+
+    cd $YT_DEST
+    cd ..
+    vi install_script.sh  // or your favorite editor to change INST_ROCKSTAR=1
+    bash < install_script.sh
+
+This will download Rockstar and install it as a library in yt.  You should now
+be able to use Rockstar and yt together.

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/analyzing/analysis_modules/radmc3d_export.rst
--- a/doc/source/analyzing/analysis_modules/radmc3d_export.rst
+++ b/doc/source/analyzing/analysis_modules/radmc3d_export.rst
@@ -6,17 +6,11 @@
 .. sectionauthor:: Andrew Myers <atmyers2 at gmail.com>
 .. versionadded:: 2.6
 
-.. note:: 
-
-    As of :code:`yt-3.0`, the radial column density analysis module is not
-    currently functional.  This functionality is still available in
-    :code:`yt-2.x`.  If you would like to use these features in :code:`yt-3.x`,
-    help is needed to port them over.  Contact the yt-users mailing list if you
-    are interested in doing this.
-
 `RADMC-3D
-<http://www.ita.uni-heidelberg.de/~dullemond/software/radmc-3d/>`_ is a three-dimensional Monte-Carlo radiative transfer code
-that is capable of handling both line and continuum emission. The :class:`~yt.analysis_modules.radmc3d_export.RadMC3DInterface.RadMC3DWriter`
+<http://www.ita.uni-heidelberg.de/~dullemond/software/radmc-3d/>`_ is a 
+three-dimensional Monte-Carlo radiative transfer code that is capable of 
+handling both line and continuum emission. The 
+:class:`~yt.analysis_modules.radmc3d_export.RadMC3DInterface.RadMC3DWriter`
 class saves AMR data to disk in an ACSII format that RADMC-3D can read. 
 In principle, this allows one to use RADMC-3D to make synthetic observations 
 from any simulation data format that yt recognizes.
@@ -31,74 +25,77 @@
 
 .. code-block:: python
 
-    from yt.mods import *
-    from yt.analysis_modules.radmc3d_export.api import *
+    import yt
+    from yt.analysis_modules.radmc3d_export.api import RadMC3DWriter
 
-Then, define a field that calculates the dust density in each cell. Here, we assume
-a constant dust-to-gas mass ratio of 0.01:
+Then, define a field that calculates the dust density in each cell. Here, we 
+assume a constant dust-to-gas mass ratio of 0.01:
 
 .. code-block:: python
 
     dust_to_gas = 0.01
     def _DustDensity(field, data):
-        return dust_to_gas*data["density"]
-    add_field("DustDensity", function=_DustDensity)
+        return dust_to_gas * data["density"]
+    yt.add_field(("gas", "dust_density"), function=_DustDensity, units="g/cm**3")
 
 Now load up a dataset and call the
 :class:`~yt.analysis_modules.radmc3d_export.RadMC3DInterface.RadMC3DWriter`:
 
 .. code-block:: python
 
-    ds = load("galaxy0030/galaxy0030")
+    ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
     writer = RadMC3DWriter(ds)
     
     writer.write_amr_grid()
-    writer.write_dust_file("DustDensity", "dust_density.inp")
+    writer.write_dust_file(("gas", "dust_density"), "dust_density.inp")
 
-The method write_amr_grid() creates an "amr_grid.inp" file that tells RADMC-3D how
-to interpret the rest of the data, while "dust_density.inp" contains the actual data field. 
+The method write_amr_grid() creates an "amr_grid.inp" file that tells RADMC-3D 
+how to interpret the rest of the data, while "dust_density.inp" contains the 
+actual data field. 
 
-We can also supply temperature information. The following code creates a "DustTemperature"
-field that is constant at 10 K, and saves it into a file called "dust_temperature.inp"
+We can also supply temperature information. The following code creates a 
+"dust_temperature" field that is constant at 10 K, and saves it into a file 
+called "dust_temperature.inp"
 
 .. code-block:: python
 
     def _DustTemperature(field, data):
-        return 10.0*data["Ones"]
-    add_field("DustTemperature", function=_DustTemperature)
+        return 0. * data["temperature"] + data.ds.quan(10, 'K')
+    yt.add_field(("gas", "dust_temperature"), function=_DustTemperature, units="K")
     
-    writer.write_dust_file("DustTemperature", "dust_temperature.inp")
+    writer.write_dust_file(("gas", "dust_temperature"), "dust_temperature.inp")
 
-With the "amr_grid.inp", "dust_density.inp", and "dust_temperature.inp" files, RADMC-3D
-has everything it needs to compute the thermal dust emission (you may also have to include
-the location and spectra of any sources, which currently must be done manually). 
-The result is something that looks like this:
+With the "amr_grid.inp", "dust_density.inp", and "dust_temperature.inp" files, 
+RADMC-3D has everything it needs to compute the thermal dust emission (you may 
+also have to include the location and spectra of any sources, which currently 
+must be done manually).  The result is something that looks like this:
 
 .. image:: _images/31micron.png
 
 Line Emission
 -------------
 
-The file format required for line emission is slightly different. The following script will generate 
-two files, one called "numderdens_co.inp", which contains the number density of CO molecules
-for every cell in the index, and another called "gas-velocity.inp", which is useful if you want 
-to include doppler broadening.
+The file format required for line emission is slightly different. The 
+following script will generate two files, one called "numderdens_co.inp", 
+which contains the number density of CO molecules for every cell in the index, 
+and another called "gas-velocity.inp", which is useful if you want to include 
+doppler broadening.
 
 .. code-block:: python
 
-    from yt.mods import *
-    from yt.analysis_modules.radmc3d_export.api import *
+    import yt
+    from yt.analysis_modules.radmc3d_export.api import RadMC3DWriter
 
     x_co = 1.0e-4
     mu_h = 2.34e-24
     def _NumberDensityCO(field, data):
         return (x_co/mu_h)*data["density"]
-    add_field("NumberDensityCO", function=_NumberDensityCO)
+    yt.add_field(("gas", "number_density_CO"), function=_NumberDensityCO, units="cm**-3")
     
-    ds = load("galaxy0030/galaxy0030")
+    ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
     writer = RadMC3DWriter(ds)
     
     writer.write_amr_grid()
-    writer.write_line_file("NumberDensityCO", "numberdens_co.inp")
+    writer.write_line_file(("gas", "number_density_CO"), "numberdens_co.inp")
     velocity_fields = ["velocity_x", "velocity_y", "velocity_z"]
     writer.write_line_file(velocity_fields, "gas_velocity.inp") 

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/analyzing/analysis_modules/sunyaev_zeldovich.rst
--- a/doc/source/analyzing/analysis_modules/sunyaev_zeldovich.rst
+++ b/doc/source/analyzing/analysis_modules/sunyaev_zeldovich.rst
@@ -1,3 +1,5 @@
+.. _sunyaev-zeldovich:
+
 Mock Observations of the Sunyaev-Zeldovich Effect
 -------------------------------------------------
 

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/analyzing/analysis_modules/synthetic_observation.rst
--- a/doc/source/analyzing/analysis_modules/synthetic_observation.rst
+++ b/doc/source/analyzing/analysis_modules/synthetic_observation.rst
@@ -1,3 +1,5 @@
+.. _synthetic-observations:
+
 Synthetic Observation
 =====================
 

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/analyzing/external_analysis.rst
--- a/doc/source/analyzing/external_analysis.rst
+++ /dev/null
@@ -1,411 +0,0 @@
-Using yt with External Analysis Tools
-=====================================
-
-yt can be used as a ``glue`` code between simulation data and other methods of
-analyzing data.  Its facilities for understanding units, disk IO and data
-selection set it up ideally to use other mechanisms for analyzing, processing
-and visualizing data.
-
-Calling External Python Codes
------------------------------
-
-Calling external Python codes very straightforward.  For instance, if you had a
-Python code that accepted a set of structured meshes and then post-processed
-them to apply radiative feedback, one could imagine calling it directly:
-
-.. code-block:: python
-
-   import yt
-   import radtrans
-
-   ds = yt.load("DD0010/DD0010")
-   rt_grids = []
-
-   for grid in ds.index.grids:
-       rt_grid = radtrans.RegularBox(
-            grid.LeftEdge, grid.RightEdge,
-            grid["density"], grid["temperature"], grid["metallicity"])
-       rt_grids.append(rt_grid)
-       grid.clear_data()
-
-   radtrans.process(rt_grids)
-
-Or if you wanted to run a population synthesis module on a set of star
-particles (and you could fit them all into memory) it might look something like
-this:
-
-.. code-block:: python
-
-   import yt
-   import pop_synthesis
-
-   ds = yt.load("DD0010/DD0010")
-   ad = ds.all_data()
-   star_masses = ad["StarMassMsun"]
-   star_metals = ad["StarMetals"]
-
-   pop_synthesis.CalculateSED(star_masses, star_metals)
-
-If you have a code that's written in Python that you are having trouble getting
-data into from yt, please feel encouraged to email the users list and we'll
-help out.
-
-Calling Non-Python External Codes
----------------------------------
-
-Independent of its ability to process, analyze and visualize data, yt can also
-serve as a mechanism for reading and selecting simulation data.  In this way,
-it can be used to supply data to an external analysis routine written in
-Fortran, C or C++.  This document describes how to supply that data, using the
-example of a simple code that calculates the best axes that describe a
-distribution of particles as a starting point.  (The underlying method is left
-as an exercise for the reader; we're only currently interested in the function
-specification and structs.)
-
-If you have written a piece of code that performs some analysis function, and
-you would like to include it in the base distribution of yt, we would be happy
-to do so; drop us a line or see :ref:`contributing-code` for more information.
-
-To accomplish the process of linking Python with our external code, we will be
-using a language called `Cython <http://www.cython.org/>`_, which is
-essentially a superset of Python that compiles down to C.  It is aware of NumPy
-arrays, and it is able to massage data between the interpreted language Python
-and C, Fortran or C++.  It will be much easier to utilize routines and analysis
-code that have been separated into subroutines that accept data structures, so
-we will assume that our halo axis calculator accepts a set of structs.
-
-Our Example Code
-++++++++++++++++
-
-Here is the ``axes.h`` file in our imaginary code, which we will then wrap:
-
-.. code-block:: c
-
-   typedef struct structParticleCollection {
-        long npart;
-        double *xpos;
-        double *ypos;
-        double *zpos;
-   } ParticleCollection;
-   
-   void calculate_axes(ParticleCollection *part, 
-            double *ax1, double *ax2, double *ax3);
-
-There are several components to this analysis routine which we will have to
-wrap.
-
-#. We have to wrap the creation of an instance of ``ParticleCollection``.
-#. We have to transform a set of NumPy arrays into pointers to doubles.
-#. We have to create a set of doubles into which ``calculate_axes`` will be
-   placing the values of the axes it calculates.
-#. We have to turn the return values back into Python objects.
-
-Each of these steps can be handled in turn, and we'll be doing it using Cython
-as our interface code.
-
-Setting Up and Building Our Wrapper
-+++++++++++++++++++++++++++++++++++
-
-To get started, we'll need to create two files:
-
-.. code-block:: bash
-
-   axes_calculator.pyx
-   axes_calculator_setup.py
-
-These can go anywhere, but it might be useful to put them in their own
-directory.  The contents of ``axes_calculator.pyx`` will be left for the next
-section, but we will need to put some boilerplate code into
-``axes_calculator_setup.pyx``.  As a quick sidenote, you should call these
-whatever is most appropriate for the external code you are wrapping;
-``axes_calculator`` is probably not the best bet.
-
-Here's a rough outline of what should go in ``axes_calculator_setup.py``:
-
-.. code-block:: python
-
-   NAME = "axes_calculator"
-   EXT_SOURCES = []
-   EXT_LIBRARIES = ["axes_utils", "m"]
-   EXT_LIBRARY_DIRS = ["/home/rincewind/axes_calculator/"]
-   EXT_INCLUDE_DIRS = []
-   DEFINES = []
-
-   from distutils.core import setup
-   from distutils.extension import Extension
-   from Cython.Distutils import build_ext
-
-   ext_modules = [Extension(NAME,
-                    [NAME+".pyx"] + EXT_SOURCES,
-                    libraries = EXT_LIBRARIES,
-                    library_dirs = EXT_LIBRARY_DIRS,
-                    include_dirs = EXT_INCLUDE_DIRS,
-                    define_macros = DEFINES)
-   ]
-
-   setup(
-     name = NAME,
-     cmdclass = {'build_ext': build_ext},
-     ext_modules = ext_modules
-   )
-
-The only variables you should have to change in this are the first six, and
-possibly only the first one.  We'll go through these variables one at a time.  
-
-``NAME``
-   This is the name of our source file, minus the ``.pyx``.  We're also
-   mandating that it be the name of the module we import.  You're free to
-   modify this.
-``EXT_SOURCES``
-   Any additional sources can be listed here.  For instance, if you are only
-   linking against a single ``.c`` file, you could list it here -- if our axes
-   calculator were fully contained within a file called ``calculate_my_axes.c``
-   we could link against it using this variable, and then we would not have to
-   specify any libraries.  This is usually the simplest way to do things, and in
-   fact, yt makes use of this itself for things like HEALPix and interpolation
-   functions.
-``EXT_LIBRARIES``
-   Any libraries that will need to be linked against (like ``m``!) should be
-   listed here.  Note that these are the name of the library minus the leading
-   ``lib`` and without the trailing ``.so``.  So ``libm.so`` would become ``m``
-   and ``libluggage.so`` would become ``luggage``.
-``EXT_LIBRARY_DIRS``
-   If the libraries listed in ``EXT_LIBRARIES`` reside in some other directory
-   or directories, those directories should be listed here.  For instance,
-   ``["/usr/local/lib", "/home/rincewind/luggage/"]`` .
-``EXT_INCLUDE_DIRS``
-   If any header files have been included that live in external directories,
-   those directories should be included here.
-``DEFINES``
-   Any define macros that should be passed to the C compiler should be listed
-   here; if they just need to be defined, then they should be specified to be
-   defined as "None."  For instance, if you wanted to pass ``-DTWOFLOWER``, you
-   would set this to equal: ``[("TWOFLOWER", None)]``.
-
-To build our extension, we would run:
-
-.. code-block:: bash
-
-   $ python2.7 axes_calculator_setup.py build_ext -i
-
-Note that since we don't yet have an ``axes_calculator.pyx``, this will fail.
-But once we have it, it ought to run.
-
-Writing and Calling our Wrapper
-+++++++++++++++++++++++++++++++
-
-Now we begin the tricky part, of writing our wrapper code.  We've already
-figured out how to build it, which is halfway to being able to test that it
-works, and we now need to start writing Cython code.
-
-For a more detailed introduction to Cython, see the Cython documentation at
-http://docs.cython.org/ .  We'll cover a few of the basics for wrapping code
-however.
-
-To start out with, we need to open up and edit our file,
-``axes_calculator.pyx``.  Open this in your favorite version of vi (mine is
-vim) and we will get started by declaring the struct we need to pass in.  But
-first, we need to include some header information:
-
-.. code-block:: cython
-
-   import numpy as np
-   cimport numpy as np
-   cimport cython
-   from stdlib cimport malloc, free
-
-These lines simply import and "Cython import" some common routines.  For more
-information about what is already available, see the Cython documentation.  For
-now, we need to start translating our data.
-
-To do so, we tell Cython both where the struct should come from, and then we
-describe the struct itself.  One fun thing to note is that if you don't need to
-set or access all the values in a struct, and it just needs to be passed around
-opaquely, you don't have to include them in the definition.  For an example of
-this, see the ``png_writer.pyx`` file in the yt repository.  Here's the syntax
-for pulling in (from a file called ``axes_calculator.h``) a struct like the one
-described above:
-
-.. code-block:: cython
-
-   cdef extern from "axes_calculator.h":
-       ctypedef struct ParticleCollection:
-           long npart
-           double *xpos
-           double *ypos
-           double *zpos
-
-So far, pretty easy!  We've basically just translated the declaration from the
-``.h`` file.  Now that we have done so, any other Cython code can create and
-manipulate these ``ParticleCollection`` structs -- which we'll do shortly.
-Next up, we need to declare the function we're going to call, which looks
-nearly exactly like the one in the ``.h`` file.  (One common problem is that
-Cython doesn't know what ``const`` means, so just remove it wherever you see
-it.)  Declare it like so:
-
-.. code-block:: cython
-
-       void calculate_axes(ParticleCollection *part,
-                double *ax1, double *ax2, double *ax3)
-
-Note that this is indented one level, to indicate that it, too, comes from
-``axes_calculator.h``.  The next step is to create a function that accepts
-arrays and converts them to the format the struct likes.  We declare our
-function just like we would a normal Python function, using ``def``.  You can
-also use ``cdef`` if you only want to call a function from within Cython.  We
-want to call it from Python, too, so we just use ``def``.  Note that we don't
-here specify types for the various arguments.  In a moment we'll refine this to
-have better argument types.
-
-.. code-block:: cython
-
-   def examine_axes(xpos, ypos, zpos):
-       cdef double ax1[3], ax2[3], ax3[3]
-       cdef ParticleCollection particles
-       cdef int i
-
-       particles.npart = len(xpos)
-       particles.xpos = <double *> malloc(particles.npart * sizeof(double))
-       particles.ypos = <double *> malloc(particles.npart * sizeof(double))
-       particles.zpos = <double *> malloc(particles.npart * sizeof(double))
-
-       for i in range(particles.npart):
-           particles.xpos[i] = xpos[i]
-           particles.ypos[i] = ypos[i]
-           particles.zpos[i] = zpos[i]
-
-       calculate_axes(&particles, ax1, ax2, ax3)
-
-       free(particles.xpos)
-       free(particles.ypos)
-       free(particles.zpos)
-
-       return ( (ax1[0], ax1[1], ax1[2]),
-                (ax2[0], ax2[1], ax2[2]),
-                (ax3[0], ax3[1], ax3[2]) )
-
-This does the rest.  Note that we've weaved in C-type declarations (ax1, ax2,
-ax3) and Python access to the variables fed in.  This function will probably be
-quite slow -- because it doesn't know anything about the variables xpos, ypos,
-zpos, it won't be able to speed up access to them.  Now we will see what we can
-do by declaring them to be of array-type before we start handling them at all.
-We can do that by annotating in the function argument list.  But first, let's
-test that it works.  From the directory in which you placed these files, run:
-
-.. code-block:: bash
-
-   $ python2.6 setup.py build_ext -i
-
-Now, create a sample file that feeds in the particles:
-
-.. code-block:: python
-
-    import axes_calculator
-    axes_calculator.examine_axes(xpos, ypos, zpos)
-
-Most of the time in that function is spent in converting the data.  So now we
-can go back and we'll try again, rewriting our converter function to believe
-that its being fed arrays from NumPy:
-
-.. code-block:: cython
-
-   def examine_axes(np.ndarray[np.float64_t, ndim=1] xpos,
-                    np.ndarray[np.float64_t, ndim=1] ypos,
-                    np.ndarray[np.float64_t, ndim=1] zpos):
-       cdef double ax1[3], ax2[3], ax3[3]
-       cdef ParticleCollection particles
-       cdef int i
-
-       particles.npart = len(xpos)
-       particles.xpos = <double *> malloc(particles.npart * sizeof(double))
-       particles.ypos = <double *> malloc(particles.npart * sizeof(double))
-       particles.zpos = <double *> malloc(particles.npart * sizeof(double))
-
-       for i in range(particles.npart):
-           particles.xpos[i] = xpos[i]
-           particles.ypos[i] = ypos[i]
-           particles.zpos[i] = zpos[i]
-
-       calculate_axes(&particles, ax1, ax2, ax3)
-
-       free(particles.xpos)
-       free(particles.ypos)
-       free(particles.zpos)
-
-       return ( (ax1[0], ax1[1], ax1[2]),
-                (ax2[0], ax2[1], ax2[2]),
-                (ax3[0], ax3[1], ax3[2]) )
-
-This should be substantially faster, assuming you feed it arrays.
-
-Now, there's one last thing we can try.  If we know our function won't modify
-our arrays, and they are C-Contiguous, we can simply grab pointers to the data:
-
-.. code-block:: cython
-
-   def examine_axes(np.ndarray[np.float64_t, ndim=1] xpos,
-                    np.ndarray[np.float64_t, ndim=1] ypos,
-                    np.ndarray[np.float64_t, ndim=1] zpos):
-       cdef double ax1[3], ax2[3], ax3[3]
-       cdef ParticleCollection particles
-       cdef int i
-
-       particles.npart = len(xpos)
-       particles.xpos = <double *> xpos.data
-       particles.ypos = <double *> ypos.data
-       particles.zpos = <double *> zpos.data
-
-       for i in range(particles.npart):
-           particles.xpos[i] = xpos[i]
-           particles.ypos[i] = ypos[i]
-           particles.zpos[i] = zpos[i]
-
-       calculate_axes(&particles, ax1, ax2, ax3)
-
-       return ( (ax1[0], ax1[1], ax1[2]),
-                (ax2[0], ax2[1], ax2[2]),
-                (ax3[0], ax3[1], ax3[2]) )
-
-But note!  This will break or do weird things if you feed it arrays that are
-non-contiguous.
-
-At this point, you should have a mostly working piece of wrapper code.  And it
-was pretty easy!  Let us know if you run into any problems, or if you are
-interested in distributing your code with yt.
-
-A complete set of files is available with this documentation.  These are
-slightly different, so that the whole thing will simply compile, but they
-provide a useful example.
-
- * `axes.c <../_static/axes.c>`_
- * `axes.h <../_static/axes.h>`_
- * `axes_calculator.pyx <../_static/axes_calculator.pyx>`_
- * `axes_calculator_setup.py <../_static/axes_calculator_setup.txt>`_
-
-Exporting Data from yt
-----------------------
-
-yt is installed alongside h5py.  If you need to export your data from yt, to
-share it with people or to use it inside another code, h5py is a good way to do
-so.  You can write out complete datasets with just a few commands.  You have to
-import, and then save things out into a file.
-
-.. code-block:: python
-
-   import h5py
-   f = h5py.File("some_file.h5")
-   f.create_dataset("/data", data=some_data)
-
-This will create ``some_file.h5`` if necessary and add a new dataset
-(``/data``) to it.  Writing out in ASCII should be relatively straightforward.
-For instance:
-
-.. code-block:: python
-
-   f = open("my_file.txt", "w")
-   for halo in halos:
-       x, y, z = halo.center_of_mass()
-       f.write("%0.2f %0.2f %0.2f\n", x, y, z)
-   f.close()
-
-This example could be extended to work with any data object's fields, as well.

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/analyzing/filtering.rst
--- a/doc/source/analyzing/filtering.rst
+++ b/doc/source/analyzing/filtering.rst
@@ -201,7 +201,7 @@
 
     prj.show()
 
-    slc = yt.SlicePlot(ds, "x", "density", center=c, width=(50, "Mpc"),
+    slc = yt.SlicePlot(ds, "x", "density", center=center, width=(50, "Mpc"),
                        data_source=sp)
 
     slc.show()

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/analyzing/index.rst
--- a/doc/source/analyzing/index.rst
+++ b/doc/source/analyzing/index.rst
@@ -1,7 +1,15 @@
 .. _analyzing:
 
-Analyzing Data
-==============
+General Data Analysis
+=====================
+
+This documentation describes much of the yt infrastructure for manipulating
+one's data to extract the relevant information.  Fields, data objects, and 
+units are at the heart of how yt represents data.  Beyond this, we provide
+a full description for how to filter your datasets based on specific criteria,
+how to analyze chronological datasets from the same underlying simulation or
+source (i.e. time series analysis), and how to run yt in parallel on 
+multiple processors to accomplish tasks faster.
 
 .. toctree::
    :maxdepth: 2
@@ -14,4 +22,3 @@
    time_series_analysis
    parallel_computation
    analysis_modules/index
-   external_analysis

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/analyzing/objects.rst
--- a/doc/source/analyzing/objects.rst
+++ b/doc/source/analyzing/objects.rst
@@ -83,6 +83,8 @@
 If you want to create your own custom data object type, see 
 :ref:`creating-objects`.
 
+.. _geometric-objects:
+
 Geometric Objects
 ^^^^^^^^^^^^^^^^^
 
@@ -107,12 +109,15 @@
     | Usage: ``ortho_ray(axis, coord, ds=None, field_parameters=None, data_source=None)``
     | A line (of data cells) stretching through the full domain 
       aligned with one of the x,y,z axes.  Defined by an axis and a point
-      to be intersected.
+      to be intersected.  Please see this 
+      :ref:`note about ray data value ordering <ray-data-ordering>`.
 
 **Ray (Arbitrarily-Aligned)** 
     | Class :class:`~yt.data_objects.selection_data_containers.YTRayBase`
     | Usage: ``ray(start_coord, end_coord, ds=None, field_parameters=None, data_source=None)``
     | A line (of data cells) defined by arbitrary start and end coordinates. 
+      Please see this 
+      :ref:`note about ray data value ordering <ray-data-ordering>`.
 
 2D Objects
 """"""""""
@@ -170,6 +175,7 @@
     | Usage: ``sphere(center, radius, ds=None, field_parameters=None, data_source=None)``
     | A sphere defined by a central coordinate and a radius.
 
+.. _collection-objects:
 
 Filtering and Collection Objects
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -202,6 +208,8 @@
     | A ``data_collection`` is a list of data objects that can be 
       sampled and processed as a whole in a single data object.
 
+.. _construction-objects:
+
 Construction Objects
 ^^^^^^^^^^^^^^^^^^^^
 

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/analyzing/parallel_computation.rst
--- a/doc/source/analyzing/parallel_computation.rst
+++ b/doc/source/analyzing/parallel_computation.rst
@@ -105,6 +105,14 @@
    If you run into problems, the you can use :ref:`remote-debugging` to examine
    what went wrong.
 
+How do I run my yt job on a subset of available processes
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+You can set the ``communicator`` keyword in the 
+:func:`~yt.utilities.parallel_tools.parallel_analysis_interface.enable_parallelism` 
+call to a specific MPI communicator to specify a subset of availble MPI 
+processes.  If none is specified, it defaults to ``COMM_WORLD``.
+
 Creating Parallel and Serial Sections in a Script
 +++++++++++++++++++++++++++++++++++++++++++++++++
 

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/analyzing/units/comoving_units_and_code_units.rst
--- a/doc/source/analyzing/units/comoving_units_and_code_units.rst
+++ b/doc/source/analyzing/units/comoving_units_and_code_units.rst
@@ -4,3 +4,33 @@
 =============================
 
 .. notebook:: 3)_Comoving_units_and_code_units.ipynb
+
+.. _cosmological-units:
+
+Units for Cosmological Datasets
+-------------------------------
+
+yt has additional capabilities to handle the comoving coordinate system used
+internally in cosmological simulations. Simulations that use comoving
+coordinates, all length units have three other counterparts correspoding to
+comoving units, scaled comoving units, and scaled proper units. In all cases
+'scaled' units refer to scaling by the reduced Hubble parameter - i.e. the length
+unit is what it would be in a universe where Hubble's parameter is 100 km/s/Mpc.
+
+To access these different units, yt has a common naming system. Scaled units are denoted by
+dividing by the scaled Hubble parameter ``h`` (which is in itself a unit). Comoving
+units are denoted by appending ``cm`` to the end of the unit name.
+
+Using the parsec as an example,
+
+``pc``
+    Proper parsecs, :math:`\rm{pc}`.
+
+``pccm``
+    Comoving parsecs, :math:`\rm{pc}/(1+z)`.
+
+``pccm/h``
+    Comoving parsecs normalized by the scaled hubble constant, :math:`\rm{pc}/h/(1+z)`.
+
+``pc/h``
+    Proper parsecs, normalized by the scaled hubble constant, :math:`\rm{pc}/h`.

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/conf.py
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -31,7 +31,7 @@
 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
 extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx',
               'sphinx.ext.pngmath', 'sphinx.ext.viewcode',
-              'numpydocmod', 'youtube', 'yt_cookbook', 'yt_colormaps']
+              'numpydocmod', 'yt_cookbook', 'yt_colormaps']
 
 if not on_rtd:
     extensions.append('sphinx.ext.autosummary')

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/cookbook/Halo_Analysis.ipynb
--- a/doc/source/cookbook/Halo_Analysis.ipynb
+++ b/doc/source/cookbook/Halo_Analysis.ipynb
@@ -1,7 +1,7 @@
 {
  "metadata": {
   "name": "",
-  "signature": "sha256:083fded18194cc4b6d9ebf6d04e24a7f1d90cf57831ff0155e99868c0ace73b7"
+  "signature": "sha256:cb4a8114d92def67d5f948ec8326e8af0b20a5340dc8fd54d8d583e9c646886e"
  },
  "nbformat": 3,
  "nbformat_minor": 0,
@@ -226,7 +226,7 @@
      "cell_type": "code",
      "collapsed": false,
      "input": [
-      "hc.add_callback('profile', 'virial_radius', [('gas','temperature')],\n",
+      "hc.add_callback('profile', 'virial_radius_fraction', [('gas','temperature')],\n",
       "                storage='virial_profiles',\n",
       "                weight_field='cell_mass', \n",
       "                accumulation=False, output_dir='profiles')\n"
@@ -368,7 +368,7 @@
      "input": [
       "halo = hc_reloaded.halo_list[0]\n",
       "\n",
-      "radius = halo.virial_profiles['virial_radius']\n",
+      "radius = halo.virial_profiles[u\"('index', 'virial_radius_fraction')\"]\n",
       "temperature = halo.virial_profiles[u\"('gas', 'temperature')\"]\n",
       "\n",
       "# Remove output files, that are no longer needed\n",

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/cookbook/cosmological_analysis.rst
--- a/doc/source/cookbook/cosmological_analysis.rst
+++ b/doc/source/cookbook/cosmological_analysis.rst
@@ -25,7 +25,7 @@
 zoom datasets.  This recipe uses Rockstar in two different ways to generate a 
 HaloCatalog from the highest resolution dark matter particles (the ones 
 inside the zoom region).  It then overlays some of those halos on a projection
-as a demonstration.  See :ref:`halo-analysis` and :ref:`annotate-halos` for
+as a demonstration.  See :ref:`rockstar` and :ref:`annotate-halos` for
 more information.
 
 .. yt_cookbook:: rockstar_nest.py

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/cookbook/fits_xray_images.ipynb
--- a/doc/source/cookbook/fits_xray_images.ipynb
+++ b/doc/source/cookbook/fits_xray_images.ipynb
@@ -1,7 +1,7 @@
 {
  "metadata": {
   "name": "",
-  "signature": "sha256:650e3fc7f66951a5fcdb18332bbc625f6f6e449fc919acd01da01e1fbbf92ee1"
+  "signature": "sha256:73eb48af6c5628619b5cab88840f6ac2b3eb278ae057c34d567f4a127181b8fb"
  },
  "nbformat": 3,
  "nbformat_minor": 0,
@@ -74,15 +74,15 @@
       "def _counts(field, data):\n",
       "    exposure_time = data.get_field_parameter(\"exposure_time\")\n",
       "    return data[\"flux\"]*data[\"pixel\"]*exposure_time\n",
-      "ds.add_field(name=\"counts\", function=_counts, units=\"counts\", take_log=False)\n",
+      "ds.add_field((\"gas\",\"counts\"), function=_counts, units=\"counts\", take_log=False)\n",
       "\n",
       "def _pp(field, data):\n",
       "    return np.sqrt(data[\"counts\"])*data[\"projected_temperature\"]\n",
-      "ds.add_field(name=\"pseudo_pressure\", function=_pp, units=\"sqrt(counts)*keV\", take_log=False)\n",
+      "ds.add_field((\"gas\",\"pseudo_pressure\"), function=_pp, units=\"sqrt(counts)*keV\", take_log=False)\n",
       "\n",
       "def _pe(field, data):\n",
       "    return data[\"projected_temperature\"]*data[\"counts\"]**(-1./3.)\n",
-      "ds.add_field(name=\"pseudo_entropy\", function=_pe, units=\"keV*(counts)**(-1/3)\", take_log=False)"
+      "ds.add_field((\"gas\",\"pseudo_entropy\"), function=_pe, units=\"keV*(counts)**(-1/3)\", take_log=False)"
      ],
      "language": "python",
      "metadata": {},
@@ -180,10 +180,11 @@
      "input": [
       "radial_profile = yt.ProfilePlot(my_sphere, \"radius\", \n",
       "                                [\"counts\",\"pseudo_pressure\",\"pseudo_entropy\"], \n",
-      "                                n_bins=50, weight_field=\"ones\")\n",
+      "                                n_bins=30, weight_field=\"ones\")\n",
       "radial_profile.set_log(\"counts\", True)\n",
       "radial_profile.set_log(\"pseudo_pressure\", True)\n",
       "radial_profile.set_log(\"pseudo_entropy\", True)\n",
+      "radial_profile.set_xlim(3,100.)\n",
       "radial_profile.show()"
      ],
      "language": "python",
@@ -401,4 +402,4 @@
    "metadata": {}
   }
  ]
-}
+}
\ No newline at end of file

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/cookbook/index.rst
--- a/doc/source/cookbook/index.rst
+++ b/doc/source/cookbook/index.rst
@@ -32,6 +32,8 @@
    cosmological_analysis
    constructing_data_objects
 
+.. _example-notebooks:
+
 Example Notebooks
 -----------------
 .. toctree::
@@ -41,6 +43,7 @@
    custom_colorbar_tickmarks
    embedded_javascript_animation
    embedded_webm_animation
+   gadget_notebook
    ../analyzing/analysis_modules/sunyaev_zeldovich
    fits_radio_cubes
    fits_xray_images

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/developing/building_the_docs.rst
--- a/doc/source/developing/building_the_docs.rst
+++ b/doc/source/developing/building_the_docs.rst
@@ -26,15 +26,17 @@
 
 * Visualizing
 * Analyzing
+* Analysis Modules
 * Examining
 * Cookbook
 * Quickstart
 * Developing
 * Reference
+* FAQ
 * Help
 
 You will have to figure out where your new/modified doc fits into this, but
-browsing through the pre-built documentation is a good way to sort that out.
+browsing through the existing documentation is a good way to sort that out.
 
 All the source for the documentation is written in
 `Sphinx <http://sphinx-doc.org/>`_, which uses ReST for markup.  ReST is very
@@ -83,6 +85,14 @@
 build time by sphinx.  We also use sphinx to run code snippets (e.g. the 
 cookbook and the notebooks) and embed resulting images and example data.
 
+You will want to make sure you have both Sphinx and the sphinx bootstrap theme
+installed.  This installation is easily performed by running this at the 
+command line:
+
+.. code-block:: bash
+
+   pip install sphinx sphinx_bootstrap_theme
+
 Quick versus Full Documentation Builds
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/developing/creating_derived_fields.rst
--- a/doc/source/developing/creating_derived_fields.rst
+++ b/doc/source/developing/creating_derived_fields.rst
@@ -36,20 +36,27 @@
 number of fairly specific parameters that can be passed in, but here we'll only
 look at the most basic ones needed for a simple scalar baryon field.
 
+.. note::
+
+    There are two different :func:`add_field` functions.  For the differences, 
+    see :ref:`faq-add-field-diffs`.
+
 .. code-block:: python
 
    yt.add_field("pressure", function=_pressure, units="dyne/cm**2")
 
 We feed it the name of the field, the name of the function, and the
-units.  Note that the units parameter is a "raw" string, in the format that yt uses
-in its `symbolic units implementation <units>`_ (e.g., employing only unit names, numbers,
-and mathematical operators in the string, and using ``"**"`` for exponentiation). We suggest
-that you name the function that creates a derived field with the intended field name prefixed
-by a single underscore, as in the ``_pressure`` example above.
+units.  Note that the units parameter is a "raw" string, in the format that yt 
+uses in its `symbolic units implementation <units>`_ (e.g., employing only 
+unit names, numbers, and mathematical operators in the string, and using 
+``"**"`` for exponentiation). For cosmological datasets and fields, see 
+:ref:`cosmological-units`.  We suggest that you name the function that creates 
+a derived field with the intended field name prefixed by a single underscore, 
+as in the ``_pressure`` example above.
 
-:func:`add_field` can be invoked in two other ways. The first is by the function
-decorator :func:`derived_field`. The following code is equivalent to the previous
-example:
+:func:`add_field` can be invoked in two other ways. The first is by the 
+function decorator :func:`derived_field`. The following code is equivalent to 
+the previous example:
 
 .. code-block:: python
 
@@ -60,15 +67,16 @@
        return (data.ds.gamma - 1.0) * \
               data["density"] * data["thermal_energy"]
 
-The :func:`derived_field` decorator takes the same arguments as :func:`add_field`,
-and is often a more convenient shorthand in cases where you want to quickly set up
-a new field.
+The :func:`derived_field` decorator takes the same arguments as 
+:func:`add_field`, and is often a more convenient shorthand in cases where 
+you want to quickly set up a new field.
 
-Defining derived fields in the above fashion must be done before a dataset is loaded,
-in order for the dataset to recognize it. If you want to set up a derived field after you
-have loaded a dataset, or if you only want to set up a derived field for a particular
-dataset, there is an :func:`~yt.data_objects.static_output.Dataset.add_field` 
-method that hangs off dataset objects. The calling syntax is the same:
+Defining derived fields in the above fashion must be done before a dataset is 
+loaded, in order for the dataset to recognize it. If you want to set up a 
+derived field after you have loaded a dataset, or if you only want to set up 
+a derived field for a particular dataset, there is an 
+:func:`~yt.data_objects.static_output.Dataset.add_field` method that hangs off 
+dataset objects. The calling syntax is the same:
 
 .. code-block:: python
 
@@ -210,33 +218,3 @@
 
 And now, when that derived field is actually used, you will be placed into a
 debugger.
-
-Units for Cosmological Datasets
--------------------------------
-
-yt has additional capabilities to handle the comoving coordinate system used
-internally in cosmological simulations. Simulations that use comoving
-coordinates, all length units have three other counterparts correspoding to
-comoving units, scaled comoving units, and scaled proper units. In all cases
-'scaled' units refer to scaling by the reduced Hubble parameter - i.e. the length
-unit is what it would be in a universe where Hubble's parameter is 100 km/s/Mpc.
-
-To access these different units, yt has a common naming system. Scaled units are denoted by
-dividing by the scaled Hubble parameter ``h`` (which is in itself a unit). Comoving
-units are denoted by appending ``cm`` to the end of the unit name.
-
-Using the parsec as an example,
-
-``pc``
-    Proper parsecs, :math:`\rm{pc}`.
-
-``pccm``
-    Comoving parsecs, :math:`\rm{pc}/(1+z)`.
-
-``pccm/h``
-    Comoving parsecs normalized by the scaled hubble constant, :math:`\rm{pc}/h/(1+z)`.
-
-``pc/h``
-    Proper parsecs, normalized by the scaled hubble constant, :math:`\rm{pc}/h`.
-
-Further examples of this functionality are shown in :ref:`comoving_units_and_code_units`.

diff -r 996bc5a04b09668415711c22c278b04163fa5c46 -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 doc/source/developing/developing.rst
--- a/doc/source/developing/developing.rst
+++ b/doc/source/developing/developing.rst
@@ -220,6 +220,12 @@
 #. Commit these changes, using ``hg commit``.  This can take an argument
    which is a series of filenames, if you have some changes you do not want
    to commit.
+#. Remember that this is a large development effort and to keep the code 
+   accessible to everyone, good documentation is a must.  Add in source code 
+   comments for what you are doing.  Add in docstrings
+   if you are adding a new function or class or keyword to a function.  
+   Add documentation to the appropriate section of the online docs so that
+   people other than yourself know how to use your new code.  
 #. If your changes include new functionality or cover an untested area of the
    code, add a test.  (See :ref:`testing` for more information.)  Commit
    these changes as well.
@@ -244,6 +250,9 @@
 
 #. Issue a pull request at
    https://bitbucket.org/YourUsername/yt/pull-request/new
+   A pull request is essentially just asking people to review and accept the 
+   modifications you have made to your personal version of the code.
+
 
 During the course of your pull request you may be asked to make changes.  These
 changes may be related to style issues, correctness issues, or even requesting
@@ -253,7 +262,7 @@
 #. Make requested changes, or leave a comment indicating why you don't think
    they should be made.
 #. Commit those changes to your local repository.
-#. Push the changes to your fork::
+#. Push the changes to your fork:
 
       hg push https://bitbucket.org/YourUsername/yt/
 

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

https://bitbucket.org/yt_analysis/yt/commits/10acf6968eda/
Changeset:   10acf6968eda
Branch:      yt
User:        ngoldbaum
Date:        2014-12-23 19:06:06+00:00
Summary:     Replacing relative_<vector_field> with <vector_field>_relative
Affected #:  1 file

diff -r d3e2457b53bb8554af253d2e0f23fbb4c9237fc8 -r 10acf6968eda3f15d76eed2387a21c51b3afc7a2 yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -362,7 +362,7 @@
         """The spherical radial component of the particle positions
 
         Relative to the coordinate system defined by the *normal* vector,
-        *bulk_velocity* vector and *center* field parameters.
+        and *center* field parameters.
         """        
         return get_radius(data, "particle_position_")
 
@@ -373,7 +373,7 @@
         particle_type=True,
         validators=[ValidateParameter("center")])
 
-    def _particle_relative_position(field, data):
+    def _particle_position_relative(field, data):
         """The cartesian particle positions in a rotated reference frame
 
         Relative to the coordinate system defined by the *normal* vector and
@@ -388,13 +388,13 @@
         return pos
 
     registry.add_field(
-        (ptype, "particle_relative_position"),
-        function=_particle_relative_position,
+        (ptype, "particle_position_relative"),
+        function=_particle_position_relative,
         particle_type=True,
         units="cm",
         validators=[ValidateParameter("normal"), ValidateParameter("center")])
 
-    def _particle_relative_position_x(field, data):
+    def _particle_position_relative_x(field, data):
         """The x component of the  particle positions in a rotated reference
         frame
 
@@ -411,13 +411,13 @@
         return pos[0]
 
     registry.add_field(
-        (ptype, "particle_relative_position_x"),
-        function=_particle_relative_position_x,
+        (ptype, "particle_position_relative_x"),
+        function=_particle_position_relative_x,
         particle_type=True,
         units="cm",
         validators=[ValidateParameter("normal"), ValidateParameter("center")])
 
-    def _particle_relative_position_y(field, data):
+    def _particle_position_relative_y(field, data):
         """The y component of the  particle positions in a rotated reference
         frame
 
@@ -433,14 +433,14 @@
         pos = pos.T
         return pos[1]
 
-    registry.add_field((ptype, "particle_relative_position_y"),
-              function=_particle_relative_position_y,
+    registry.add_field((ptype, "particle_position_relative_y"),
+              function=_particle_position_relative_y,
               particle_type=True, units="cm",
               validators=[ValidateParameter("normal"),
                           ValidateParameter("center")])
 
 
-    def _particle_relative_position_z(field, data):
+    def _particle_position_relative_z(field, data):
         """The z component of the  particle positions in a rotated reference
         frame
 
@@ -457,13 +457,13 @@
         pos = pos.T
         return pos[2]
 
-    registry.add_field((ptype, "particle_relative_position_z"),
-              function=_particle_relative_position_z,
+    registry.add_field((ptype, "particle_position_relative_z"),
+              function=_particle_position_relative_z,
               particle_type=True, units="cm",
               validators=[ValidateParameter("normal"),
                           ValidateParameter("center")])
 
-    def _particle_relative_velocity(field, data):
+    def _particle_velocity_relative(field, data):
         """The vector particle velocities in an arbitrary coordinate system
 
         Relative to the coordinate system defined by the *normal* vector,
@@ -479,13 +479,13 @@
         L, vel = modify_reference_frame(center, normal, V=vel)
         return vel
 
-    registry.add_field((ptype, "particle_relative_velocity"),
-              function=_particle_relative_velocity,
+    registry.add_field((ptype, "particle_velocity_relative"),
+              function=_particle_velocity_relative,
               particle_type=True, units="cm/s",
               validators=[ValidateParameter("normal"),
                           ValidateParameter("center")])
 
-    def _particle_relative_velocity_x(field, data):
+    def _particle_velocity_relative_x(field, data):
         """The x component of the particle velocities in an arbitrary coordinate
         system
 
@@ -503,13 +503,13 @@
         vel = vel.T
         return vel[0]
 
-    registry.add_field((ptype, "particle_relative_velocity_x"),
-              function=_particle_relative_velocity_x,
+    registry.add_field((ptype, "particle_velocity_relative_x"),
+              function=_particle_velocity_relative_x,
               particle_type=True, units="cm/s",
               validators=[ValidateParameter("normal"),
                           ValidateParameter("center")])
 
-    def _particle_relative_velocity_y(field, data):
+    def _particle_velocity_relative_y(field, data):
         """The y component of the particle velocities in an arbitrary coordinate
         system
 
@@ -527,13 +527,13 @@
         vel = vel.T
         return vel[1]
 
-    registry.add_field((ptype, "particle_relative_velocity_y"),
-              function=_particle_relative_velocity_y,
+    registry.add_field((ptype, "particle_velocity_relative_y"),
+              function=_particle_velocity_relative_y,
               particle_type=True, units="cm/s",
               validators=[ValidateParameter("normal"),
                           ValidateParameter("center")])
 
-    def _particle_relative_velocity_z(field, data):
+    def _particle_velocity_relative_z(field, data):
         """The z component of the particle velocities in an arbitrary coordinate
         system
 
@@ -551,8 +551,8 @@
         vel = vel.T
         return vel[2]
 
-    registry.add_field((ptype, "particle_relative_velocity_z"),
-              function=_particle_relative_velocity_z,
+    registry.add_field((ptype, "particle_velocity_relative_z"),
+              function=_particle_velocity_relative_z,
               particle_type=True, units="cm/s",
               validators=[ValidateParameter("normal"),
                           ValidateParameter("center")])


https://bitbucket.org/yt_analysis/yt/commits/8b6a5a6061b6/
Changeset:   8b6a5a6061b6
Branch:      yt
User:        ngoldbaum
Date:        2014-12-23 19:14:08+00:00
Summary:     Adding a note that the rotation of the xy plane is arbitrary for these fields
Affected #:  1 file

diff -r 10acf6968eda3f15d76eed2387a21c51b3afc7a2 -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -363,7 +363,7 @@
 
         Relative to the coordinate system defined by the *normal* vector,
         and *center* field parameters.
-        """        
+        """
         return get_radius(data, "particle_position_")
 
     registry.add_field(
@@ -378,6 +378,8 @@
 
         Relative to the coordinate system defined by the *normal* vector and
         *center* field parameters.
+
+        Note that the orientation of the x and y axes are arbitrary.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
@@ -400,6 +402,8 @@
 
         Relative to the coordinate system defined by the *normal* vector and
         *center* field parameters.
+
+        Note that the orientation of the x and y axes are arbitrary.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
@@ -423,6 +427,8 @@
 
         Relative to the coordinate system defined by the *normal* vector and
         *center* field parameters.
+
+        Note that the orientation of the x and y axes are arbitrary.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
@@ -446,6 +452,8 @@
 
         Relative to the coordinate system defined by the *normal* vector and
         *center* field parameters.
+
+        Note that the orientation of the x and y axes are arbitrary.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
@@ -468,6 +476,8 @@
 
         Relative to the coordinate system defined by the *normal* vector,
         *bulk_velocity* vector and *center* field parameters.
+
+        Note that the orientation of the x and y axes are arbitrary.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
@@ -491,6 +501,8 @@
 
         Relative to the coordinate system defined by the *normal* vector,
         *bulk_velocity* vector and *center* field parameters.
+
+        Note that the orientation of the x and y axes are arbitrary.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
@@ -515,6 +527,8 @@
 
         Relative to the coordinate system defined by the *normal* vector,
         *bulk_velocity* vector and *center* field parameters.
+
+        Note that the orientation of the x and y axes are arbitrary.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
@@ -539,6 +553,8 @@
 
         Relative to the coordinate system defined by the *normal* vector,
         *bulk_velocity* vector and *center* field parameters.
+
+        Note that the orientation of the x and y axes are arbitrary.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')


https://bitbucket.org/yt_analysis/yt/commits/77c9d1d6387b/
Changeset:   77c9d1d6387b
Branch:      yt
User:        ngoldbaum
Date:        2015-01-05 01:00:34+00:00
Summary:     Merging with mainline.
Affected #:  55 files

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 doc/extensions/notebook_sphinxext.py
--- a/doc/extensions/notebook_sphinxext.py
+++ b/doc/extensions/notebook_sphinxext.py
@@ -71,11 +71,16 @@
 
         skip_exceptions = 'skip_exceptions' in self.options
 
-        evaluated_text, resources = evaluate_notebook(
+        ret = evaluate_notebook(
             nb_abs_path, dest_path_eval, skip_exceptions=skip_exceptions)
 
-        evaluated_text = write_notebook_output(
-            resources, image_dir, image_rel_dir, evaluated_text)
+        try:
+            evaluated_text, resources = ret
+            evaluated_text = write_notebook_output(
+                resources, image_dir, image_rel_dir, evaluated_text)
+        except ValueError:
+            # This happens when a notebook raises an unhandled exception
+            evaluated_text = ret
 
         # Create link to notebook and script files
         link_rst = "(" + \

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 doc/source/analyzing/analysis_modules/PPVCube.ipynb
--- a/doc/source/analyzing/analysis_modules/PPVCube.ipynb
+++ b/doc/source/analyzing/analysis_modules/PPVCube.ipynb
@@ -1,7 +1,7 @@
 {
  "metadata": {
   "name": "",
-  "signature": "sha256:7ba601e381023e5b7c00a585ccaa55996316d2dfe7f8c96284b4539e1ee5b846"
+  "signature": "sha256:794e861818b8a105bc91b537e8359801c8d28d5a13a32787fb386b0578109a66"
  },
  "nbformat": 3,
  "nbformat_minor": 0,
@@ -19,10 +19,13 @@
      "cell_type": "code",
      "collapsed": false,
      "input": [
+      "from yt.config import ytcfg\n",
+      "ytcfg[\"yt\",\"loglevel\"] = 30\n",
+      "\n",
       "import yt\n",
       "import numpy as np\n",
-      "\n",
-      "from yt.analysis_modules.ppv_cube.api import PPVCube"
+      "from yt.analysis_modules.ppv_cube.api import PPVCube\n",
+      "import yt.units as u"
      ],
      "language": "python",
      "metadata": {},
@@ -168,7 +171,7 @@
      "cell_type": "markdown",
      "metadata": {},
      "source": [
-      "Which shows a rotating disk with a specific density and velocity profile. Now, suppose we wanted to look at this disk galaxy from a certain orientation angle, and simulate a 3D FITS data cube where we can see the gas that is emitting at different velocities along the line of sight. We can do this using the `PPVCube` class. First, let's assume we rotate our viewing angle 60 degrees from face-on, from along the z-axis into the y-axis. We'll create a normal vector:"
+      "Which shows a rotating disk with a specific density and velocity profile. Now, suppose we wanted to look at this disk galaxy from a certain orientation angle, and simulate a 3D FITS data cube where we can see the gas that is emitting at different velocities along the line of sight. We can do this using the `PPVCube` class. First, let's assume we rotate our viewing angle 60 degrees from face-on, from along the z-axis into the x-axis. We'll create a normal vector:"
      ]
     },
     {
@@ -176,7 +179,7 @@
      "collapsed": false,
      "input": [
       "i = 60.*np.pi/180.\n",
-      "L = [0.0,np.sin(i),np.sin(i)]"
+      "L = [np.sin(i),0.0,np.cos(i)]"
      ],
      "language": "python",
      "metadata": {},
@@ -193,7 +196,7 @@
      "cell_type": "code",
      "collapsed": false,
      "input": [
-      "cube = PPVCube(ds, L, \"density\", dims=(200,100,50), velocity_bounds=(-150.,150.,\"km/s\"), method=\"sum\")"
+      "cube = PPVCube(ds, L, \"density\", dims=(200,50), velocity_bounds=(-150.,150.,\"km/s\"), method=\"sum\")"
      ],
      "language": "python",
      "metadata": {},
@@ -268,7 +271,6 @@
      "cell_type": "code",
      "collapsed": false,
      "input": [
-      "import yt.units as u\n",
       "# Picking different velocities for the slices\n",
       "new_center = ds_cube.domain_center\n",
       "new_center[2] = ds_cube.spec2pixel(-100.*u.km/u.s)\n",
@@ -334,7 +336,7 @@
      "cell_type": "code",
      "collapsed": false,
      "input": [
-      "cube2 = PPVCube(ds, L, \"density\", dims=(200,100,50), velocity_bounds=(-150,150,\"km/s\"), thermal_broad=True, \n",
+      "cube2 = PPVCube(ds, L, \"density\", dims=(200,50), velocity_bounds=(-150,150,\"km/s\"), thermal_broad=True, \n",
       "                atomic_weight=12.0, method=\"sum\")\n",
       "cube2.write_fits(\"cube2.fits\", clobber=True, length_unit=\"kpc\")"
      ],

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 doc/source/analyzing/analysis_modules/_images/dust_continuum.png
Binary file doc/source/analyzing/analysis_modules/_images/dust_continuum.png has changed

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 doc/source/analyzing/analysis_modules/index.rst
--- a/doc/source/analyzing/analysis_modules/index.rst
+++ b/doc/source/analyzing/analysis_modules/index.rst
@@ -1,12 +1,13 @@
 .. _analysis-modules:
 
-Analysis Modules
-================
+Topic-Specific Analysis Modules
+===============================
 
-These are "canned" analysis modules that can operate on datasets, performing a
-sequence of operations that result in a final result.  This functionality 
-interoperates with yt, but one needs to import the functions associated
-with each specific analysis module into python before using them.
+These semi-autonomous analysis modules are unique to specific subject matter
+like tracking halos, generating synthetic observations, exporting output to
+external visualization routines, and more.  Because they are somewhat 
+specialized, they exist in their own corners of yt, and they do not get loaded
+by default when you "import yt".  Read up on these advanced tools below.
 
 .. toctree::
    :maxdepth: 2

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 doc/source/analyzing/analysis_modules/radmc3d_export.rst
--- a/doc/source/analyzing/analysis_modules/radmc3d_export.rst
+++ b/doc/source/analyzing/analysis_modules/radmc3d_export.rst
@@ -6,29 +6,54 @@
 .. sectionauthor:: Andrew Myers <atmyers2 at gmail.com>
 .. versionadded:: 2.6
 
+.. figure:: _images/31micron.png
+
+    Above: a sample image showing the continuum dust emission image around a massive protostar
+    made using RADMC-3D and plotted with pyplot.
+
 `RADMC-3D
 <http://www.ita.uni-heidelberg.de/~dullemond/software/radmc-3d/>`_ is a 
 three-dimensional Monte-Carlo radiative transfer code that is capable of 
-handling both line and continuum emission. The 
+handling both line and continuum emission. yt comes equipped with a  
 :class:`~yt.analysis_modules.radmc3d_export.RadMC3DInterface.RadMC3DWriter`
-class saves AMR data to disk in an ACSII format that RADMC-3D can read. 
+class that exports AMR data to a format that RADMC-3D can read. Currently, only
+the ASCII-style data format is supported.  
 In principle, this allows one to use RADMC-3D to make synthetic observations 
 from any simulation data format that yt recognizes.
 
 Continuum Emission
 ------------------
 
-To compute thermal emission intensities, RADMC-3D needs a file called
-"dust_density.inp" that specifies the density of dust for every cell in the AMR
-index. To generate this file, first import the RADMC-3D exporter, which 
-is not loaded into your environment by default:
+To compute thermal emission intensities, RADMC-3D needs several inputs files that
+describe the spatial distribution of the dust and photon sources. To create these
+files, first import the RADMC-3D exporter, which is not loaded into your environment 
+by default:
 
 .. code-block:: python
 
     import yt
-    from yt.analysis_modules.radmc3d_export.api import RadMC3DWriter
+    import numpy as np
+    from yt.analysis_modules.radmc3d_export.api import RadMC3DWriter, RadMC3DSource
 
-Then, define a field that calculates the dust density in each cell. Here, we 
+Next, load up a dataset and instantiate the :class:`~yt.analysis_modules.radmc3d_export.RadMC3DInterface.RadMC3DWriter`.
+For this example, we'll use the "StarParticle" dataset,
+available `here
+<http://yt-project.org/data/>`_. 
+
+.. code-block:: python
+
+    ds = yt.load("StarParticles/plrd01000/")
+    writer = RadMC3DWriter(ds)
+
+The first data file to create is the "amr_grid.inp" file, which describes the structure 
+of the AMR index. To create this file, simply call:
+
+.. code-block:: python
+
+    writer.write_amr_grid()
+
+Next, we must give RADMC-3D information about the dust density. To do this, we
+define a field that calculates the dust density in each cell. We 
 assume a constant dust-to-gas mass ratio of 0.01:
 
 .. code-block:: python
@@ -36,41 +61,118 @@
     dust_to_gas = 0.01
     def _DustDensity(field, data):
         return dust_to_gas * data["density"]
-    yt.add_field(("gas", "dust_density"), function=_DustDensity, units="g/cm**3")
+    ds.add_field(("gas", "dust_density"), function=_DustDensity, units="g/cm**3")
 
-Now load up a dataset and call the
-:class:`~yt.analysis_modules.radmc3d_export.RadMC3DInterface.RadMC3DWriter`:
+We save this information into a file called "dust_density.inp".
 
 .. code-block:: python
 
-    ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
-    writer = RadMC3DWriter(ds)
-    
-    writer.write_amr_grid()
     writer.write_dust_file(("gas", "dust_density"), "dust_density.inp")
 
-The method write_amr_grid() creates an "amr_grid.inp" file that tells RADMC-3D 
-how to interpret the rest of the data, while "dust_density.inp" contains the 
-actual data field. 
-
-We can also supply temperature information. The following code creates a 
-"dust_temperature" field that is constant at 10 K, and saves it into a file 
-called "dust_temperature.inp"
+Finally, we must give RADMC-3D information about any stellar sources that are
+present. To do this, we have provided the 
+:class:`~yt.analysis_modules.radmc3d_export.RadMC3DInterface.RadMC3DSource`
+class. For this example, we place a single source with temperature 5780 K
+at the center of the domain:
 
 .. code-block:: python
 
-    def _DustTemperature(field, data):
-        return 0. * data["temperature"] + data.ds.quan(10, 'K')
-    yt.add_field(("gas", "dust_temperature"), function=_DustTemperature, units="K")
-    
-    writer.write_dust_file(("gas", "dust_temperature"), "dust_temperature.inp")
+    radius_cm = 6.96e10
+    mass_g = 1.989e33
+    position_cm = [0.0, 0.0, 0.0]
+    temperature_K = 5780.0
+    star = RadMC3DSource(radius_cm, mass_g, position_cm, temperature_K)
 
-With the "amr_grid.inp", "dust_density.inp", and "dust_temperature.inp" files, 
-RADMC-3D has everything it needs to compute the thermal dust emission (you may 
-also have to include the location and spectra of any sources, which currently 
-must be done manually).  The result is something that looks like this:
+    sources_list = [star]
+    wavelengths_micron = np.logspace(-1.0, 4.0, 1000)
 
-.. image:: _images/31micron.png
+    writer.write_source_files(sources_list, wavelengths_micron)
+
+The last line creates the files "stars.inp" and "wavelength_micron.inp",
+which describe the locations and spectra of the stellar sources as well
+as the wavelengths RADMC-3D will use in it's calculations.  
+
+If everything goes correctly, after executing the above code, you should have
+the files "amr_grid.inp", "dust_density.inp", "stars.inp", and "wavelength_micron.inp"
+sitting in your working directory. RADMC-3D needs a few more configuration files to 
+compute the thermal dust emission. In particular, you need an opacity file, like the 
+"dustkappa_silicate.inp" file included in RADMC-3D, a main "radmc3d.inp" file that sets
+some runtime parameters, and a "dustopac.inp" that describes the assumed composition of the dust.
+yt cannot make these files for you; in the example that follows, we used a 
+"radmc3d.inp" file that looked like:
+
+::
+
+    nphot = 1000000
+    nphot_scat = 1000000
+
+which basically tells RADMC-3D to use 1,000,000 photon packets instead of the default 100,000. The 
+"dustopac.inp" file looked like:
+
+::
+
+    2
+    1
+    -----------------------------
+    1
+    0
+    silicate
+    -----------------------------   
+
+To get RADMC-3D to compute the dust temperature, run the command:
+
+::
+
+   ./radmc3D mctherm 
+
+in the directory that contains your "amr_grid.inp", "dust_density.inp", "stars.inp", "wavelength_micron.inp",
+"radmc3d.inp", "dustkappa_silicate.inp", and "dustopac.inp" files. If everything goes correctly, you should
+get a "dust_temperature.dat" file in your working directory. Once that file is generated, you can use
+RADMC-3D to generate SEDs, images, and so forth. For example, to create an image at 31 microns, do the command:
+
+::
+
+   ./radmc3d image lambda 31 sizeau 30000 npix 800
+
+which should create a file called "image.out". You can view this image using pyplot or whatever other
+plotting package you want. To facilitate this, we provide helper functions
+that parse the image.out file, returning a header dictionary with some useful metadata
+and an np.array containing the image values. To plot this image in pyplot, you could do something like:
+
+.. code-block:: python
+
+   import matplotlib.pyplot as plt
+   import numpy as np
+   from yt.analysis_modules.radmc3d_export.api import read_radmc3d_image
+   header, image = read_radmc3d_image("image.out")
+
+   Nx = header['Nx']
+   Ny = header['Ny']
+
+   x_hi = 0.5*header["pixel_size_cm_x"]*Nx
+   x_lo = -x_hi
+   y_hi = 0.5*header["pixel_size_cm_y"]*Ny
+   y_lo = -y_hi
+   
+   X = np.linspace(x_lo, x_hi, Nx) 
+   Y = np.linspace(y_lo, y_hi, Ny) 
+
+   plt.pcolormesh(X, Y, np.log10(image), cmap='hot')
+   cbar = plt.colorbar()
+   plt.axis((x_lo, x_hi, y_lo, y_hi))
+   ax = plt.gca()
+   ax.set_xlabel(r"$x$ (cm)")
+   ax.set_ylabel(r"$y$ (cm)")
+   cbar.set_label(r"Log Intensity (erg cm$^{-2}$ s$^{-1}$ Hz$^{-1}$ ster$^{-1}$)")
+   plt.savefig('dust_continuum.png')
+
+The resulting image should look like:
+
+.. image:: _images/dust_continuum.png
+
+This barely scratches the surface of what you can do with RADMC-3D. Our goal here is
+just to describe how to use yt to export the data it knows about (densities, stellar
+sources, etc.) into a format that RADMC-3D can recognize.
 
 Line Emission
 -------------
@@ -87,7 +189,7 @@
     from yt.analysis_modules.radmc3d_export.api import RadMC3DWriter
 
     x_co = 1.0e-4
-    mu_h = 2.34e-24
+    mu_h = yt.YTQuantity(2.34e-24, 'g')
     def _NumberDensityCO(field, data):
         return (x_co/mu_h)*data["density"]
     yt.add_field(("gas", "number_density_CO"), function=_NumberDensityCO, units="cm**-3")

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 doc/source/analyzing/index.rst
--- a/doc/source/analyzing/index.rst
+++ b/doc/source/analyzing/index.rst
@@ -21,4 +21,3 @@
    generating_processed_data
    time_series_analysis
    parallel_computation
-   analysis_modules/index

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 doc/source/cookbook/index.rst
--- a/doc/source/cookbook/index.rst
+++ b/doc/source/cookbook/index.rst
@@ -44,6 +44,7 @@
    embedded_javascript_animation
    embedded_webm_animation
    gadget_notebook
+   owls_notebook
    ../analyzing/analysis_modules/sunyaev_zeldovich
    fits_radio_cubes
    fits_xray_images

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 doc/source/cookbook/owls_notebook.rst
--- /dev/null
+++ b/doc/source/cookbook/owls_notebook.rst
@@ -0,0 +1,7 @@
+.. _owls-notebook:
+
+Using yt to view and analyze Gadget-OWLS outputs
+++++++++++++++++++++++++++++++++++++++++++++++++
+
+.. notebook:: yt_gadget_owls_analysis.ipynb
+

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 doc/source/cookbook/yt_gadget_owls_analysis.ipynb
--- /dev/null
+++ b/doc/source/cookbook/yt_gadget_owls_analysis.ipynb
@@ -0,0 +1,269 @@
+{
+ "metadata": {
+  "name": ""
+ },
+ "nbformat": 3,
+ "nbformat_minor": 0,
+ "worksheets": [
+  {
+   "cells": [
+    {
+     "cell_type": "heading",
+     "level": 1,
+     "metadata": {},
+     "source": [
+      "OWLS Examples"
+     ]
+    },
+    {
+     "cell_type": "heading",
+     "level": 2,
+     "metadata": {},
+     "source": [
+      "Setup"
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "The first thing you will need to run these examples is a working installation of yt.  The author or these examples followed the instructions under \"Get yt: from source\" at http://yt-project.org/ to install an up to date development version of yt.\n",
+      "\n",
+      "Next you should set the default ``test_data_dir`` in the ``.yt/config`` file in your home directory.  Note that you may have to create the directory and file if it doesn't exist already.\n",
+      "\n",
+      "> [yt]\n",
+      "\n",
+      "> test_data_dir=/home/galtay/yt-data\n",
+      "\n",
+      "Now you should create the directory referenced above (in this case ``/home/galtay/yt-data``).  The first time you request ion fields from yt it will download a supplementary data file to this directory. \n",
+      "\n",
+      "Next we will get an example OWLS snapshot.  There is a snapshot available on the yt data site, http://yt-project.org/data/snapshot_033.tar.gz (269 MB).  Save this tar.gz file in the same directory as this notebook, then unzip and untar it.  "
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Now we will tell the notebook that we want figures produced inline. "
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "%matplotlib inline"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "heading",
+     "level": 2,
+     "metadata": {},
+     "source": [
+      "Loading"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "import yt"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Now we will load the snapshot.  See the docs (http://yt-project.org/docs/dev/examining/loading_data.html#indexing-criteria) for a description of ``n_ref`` and ``over_refine_factor``."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "fname = 'snapshot_033/snap_033.0.hdf5'\n",
+      "ds = yt.load(fname, n_ref=64, over_refine_factor=1)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Set a ``YTRegion`` that contains all the data."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "ad = ds.all_data()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "heading",
+     "level": 2,
+     "metadata": {},
+     "source": [
+      "Inspecting "
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "The dataset can tell us what fields it knows about, "
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "ds.field_list"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "ds.derived_field_list"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Note that the ion fields follow the naming convention described in YTEP-0003 http://ytep.readthedocs.org/en/latest/YTEPs/YTEP-0003.html#molecular-and-atomic-species-names"
+     ]
+    },
+    {
+     "cell_type": "heading",
+     "level": 2,
+     "metadata": {},
+     "source": [
+      "Accessing Particle Data"
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "The raw particle data can be accessed using the particle types.  This corresponds directly with what is in the hdf5 snapshots. "
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "ad['PartType0', 'Coordinates']"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "ad['PartType4', 'IronFromSNIa']"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "ad['PartType1', 'ParticleIDs']"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "ad['PartType0', 'Hydrogen']"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "heading",
+     "level": 2,
+     "metadata": {},
+     "source": [
+      "Projection Plots"
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "The projection plots make use of derived fields that store the smoothed particle data (particles smoothed onto an oct-tree).  Below we make a projection of all hydrogen gas followed by only the neutral hydrogen gas. "
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "pz = yt.ProjectionPlot(ds, 'z', ('gas', 'H_density'))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "pz.show()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "pz = yt.ProjectionPlot(ds, 'z', ('gas', 'H_p0_density'))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "pz.show()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    }
+   ],
+   "metadata": {}
+  }
+ ]
+}
\ No newline at end of file

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 doc/source/examining/loading_data.rst
--- a/doc/source/examining/loading_data.rst
+++ b/doc/source/examining/loading_data.rst
@@ -11,32 +11,46 @@
 ART Data
 --------
 
-ART data enjoys preliminary support and has been supported in the past by
-Christopher Moody.  Please contact the ``yt-dev`` mailing list if you are
-interested in using yt for ART data, or if you are interested in assisting with
-development of yt to work with ART data.
+ART data has been supported in the past by Christopher Moody and is currently
+cared for by Kenza Arraki.  Please contact the ``yt-dev`` mailing list if you
+are interested in using yt for ART data, or if you are interested in assisting
+with development of yt to work with ART data.
 
 To load an ART dataset you can use the ``yt.load`` command and provide it the
 gas mesh file. It will search for and attempt to find the complementary dark
 matter and stellar particle header and data files. However, your simulations may
 not follow the same naming convention.
 
-So for example, a single snapshot might have a series of files looking like
-this:
+.. code-block:: python
+    
+   import yt
+
+   ds = yt.load("D9p_500/10MpcBox_HartGal_csf_a0.500.d")
+
+
+It will search for and attempt to find the complementary dark matter and stellar
+particle header and data files. However, your simulations may not follow the
+same naming convention.
+
+For example, the single snapshot given in the sample data has a series of files
+that look like this:
 
 .. code-block:: none
 
-   10MpcBox_csf512_a0.300.d    #Gas mesh
-   PMcrda0.300.DAT             #Particle header
-   PMcrs0a0.300.DAT            #Particle data (positions,velocities)
-   stars_a0.300.dat            #Stellar data (metallicities, ages, etc.)
+   10MpcBox_HartGal_csf_a0.500.d  #Gas mesh
+   PMcrda0.500.DAT                #Particle header
+   PMcrs0a0.500.DAT               #Particle data (positions,velocities)
+   stars_a0.500.dat               #Stellar data (metallicities, ages, etc.)
 
-The ART frontend tries to find the associated files matching the above, but
-if that fails you can specify ``file_particle_data``,``file_particle_data``,
-``file_star_data`` in addition to the specifying the gas mesh. You also have 
-the option of gridding particles, and assigning them onto the meshes.
-This process is in beta, and for the time being it's probably  best to leave
-``do_grid_particles=False`` as the default.
+The ART frontend tries to find the associated files matching the
+above, but if that fails you can specify ``file_particle_header``,
+``file_particle_data``, and ``file_particle_stars``, in addition to
+specifying the gas mesh. Note that the ``pta0.500.dat`` or ``pt.dat``
+file containing particle time steps is not loaded by yt.
+
+You also have the option of gridding particles and assigning them onto the
+meshes.  This process is in beta, and for the time being it's probably best to
+leave ``do_grid_particles=False`` as the default.
 
 To speed up the loading of an ART file, you have a few options. You can turn 
 off the particles entirely by setting ``discover_particles=False``. You can
@@ -46,13 +60,22 @@
 Finally, when stellar ages are computed we 'spread' the ages evenly within a
 smoothing window. By default this is turned on and set to 10Myr. To turn this 
 off you can set ``spread=False``, and you can tweak the age smoothing window
-by specifying the window in seconds, ``spread=1.0e7*265*24*3600``. 
+by specifying the window in seconds, ``spread=1.0e7*365*24*3600``. 
+
+There is currently preliminary support for dark matter only ART data. To load a
+dataset use the ``yt.load`` command and provide it the particle data file. It
+will search for the complementary particle header file.
 
 .. code-block:: python
     
    import yt
 
-   ds = yt.load("SFG1/10MpcBox_csf512_a0.460.d")
+   ds = yt.load("PMcrs0a0.500.DAT")
+
+Important: This should not be used for loading just the dark matter
+data for a 'regular' hydrodynamical data set as the units and IO are
+different!
+
 
 .. _loading-artio-data:
 
@@ -602,7 +625,8 @@
 can apply smoothing kernels to the data to produce both quantitative analysis
 and visualization. See :ref:`loading-sph-data` for more details and
 :ref:`gadget-notebook` for a detailed example of loading, analyzing, and
-visualizing a Gadget dataset.
+visualizing a Gadget dataset.  An example which makes use of a Gadget snapshot
+from the OWLS project can be found at :ref:`owls-notebook`.  
 
 Gadget data in HDF5 format can be loaded with the ``load`` command:
 

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 doc/source/index.rst
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -91,16 +91,26 @@
      <tr valign="top"><td width="25%"><p>
-           <a href="analyzing/index.html">Analyzing Data</a>
+           <a href="analyzing/index.html">General Data Analysis</a></p></td><td width="75%">
-         <p class="linkdescr">Use analysis  tools to extract results from your data</p>
+         <p class="linkdescr">The nuts and bolts of manipulating yt datasets</p></td></tr><tr valign="top"><td width="25%"><p>
+           <a href="analyzing/analysis_modules/index.html">Topic-Specific Analysis Modules</a>
+         </p>
+       </td>
+       <td width="75%">
+         <p class="linkdescr">Track halos, make synthetic observations, find clumps, and more</p>
+       </td>
+     </tr>
+      <tr valign="top">
+       <td width="25%">
+         <p><a href="developing/index.html">Developer Guide</a></p></td>
@@ -159,6 +169,7 @@
    cookbook/index
    visualizing/index
    analyzing/index
+   analyzing/analysis_modules/index
    examining/index
    developing/index
    reference/index

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 yt/analysis_modules/photon_simulator/photon_models.py
--- a/yt/analysis_modules/photon_simulator/photon_models.py
+++ b/yt/analysis_modules/photon_simulator/photon_models.py
@@ -217,7 +217,8 @@
             photons["dx"].append(chunk["dx"][idxs].in_units("kpc"))
 
         for key in photons:
-            photons[key] = uconcatenate(photons[key])
+            if len(photons[key]) > 0:
+                photons[key] = uconcatenate(photons[key])
 
         return photons
 

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 yt/analysis_modules/ppv_cube/ppv_cube.py
--- a/yt/analysis_modules/ppv_cube/ppv_cube.py
+++ b/yt/analysis_modules/ppv_cube/ppv_cube.py
@@ -51,8 +51,9 @@
 
 class PPVCube(object):
     def __init__(self, ds, normal, field, center="c", width=(1.0,"unitary"),
-                 dims=(100,100,100), velocity_bounds=None, thermal_broad=False,
-                 atomic_weight=56., method="integrate", no_shifting=False):
+                 dims=(100,100), velocity_bounds=None, thermal_broad=False,
+                 atomic_weight=56., method="integrate", no_shifting=False,
+                 north_vector=None):
         r""" Initialize a PPVCube object.
 
         Parameters
@@ -62,7 +63,7 @@
         normal : array_like or string
             The normal vector along with to make the projections. If an array, it
             will be normalized. If a string, it will be assumed to be along one of the
-            principal axes of the domain ("x","y", or "z").
+            principal axes of the domain ("x", "y", or "z").
         field : string
             The field to project.
         center : A sequence of floats, a string, or a tuple.
@@ -78,9 +79,11 @@
         width : float, tuple, or YTQuantity.
             The width of the projection. A float will assume the width is in code units.
             A (value, unit) tuple or YTQuantity allows for the units of the width to be
-            specified.
+            specified. Implies width = height, e.g. the aspect ratio of the PPVCube's 
+            spatial dimensions is 1. 
         dims : tuple, optional
-            A 3-tuple of dimensions (nx,ny,nv) for the cube.
+            A 2-tuple of dimensions (nx,nv) for the cube. Implies nx = ny, e.g. the aspect
+            ratio of the PPVCube's spatial dimensions is 1. 
         velocity_bounds : tuple, optional
             A 3-tuple of (vmin, vmax, units) for the velocity bounds to
             integrate over. If None, the largest velocity of the
@@ -95,6 +98,10 @@
         no_shifting : boolean, optional
             If set, no shifting due to velocity will occur but only thermal broadening.
             Should not be set when *thermal_broad* is False, otherwise nothing happens!
+        north_vector : a sequence of floats
+            A vector defining the 'up' direction. This option sets the orientation of 
+            the plane of projection. If not set, an arbitrary grid-aligned north_vector 
+            is chosen. Ignored in the case of on-axis plots.
 
         Examples
         --------
@@ -117,8 +124,8 @@
         self.center = ds.coordinates.sanitize_center(center, normal)[0]
 
         self.nx = dims[0]
-        self.ny = dims[1]
-        self.nv = dims[2]
+        self.ny = dims[0]
+        self.nv = dims[1]
 
         if method not in ["integrate","sum"]:
             raise RuntimeError("Only the 'integrate' and 'sum' projection +"
@@ -167,7 +174,8 @@
             else:
                 buf = off_axis_projection(ds, self.center, normal, width,
                                           (self.nx, self.ny), "intensity",
-                                          no_ghost=True, method=method)[::-1]
+                                          north_vector=north_vector,
+                                          no_ghost=True, method=method).swapaxes(0,1)
             sto.result_id = i
             sto.result = buf
             pbar.update(i)
@@ -176,7 +184,7 @@
         self.data = ds.arr(np.zeros((self.nx,self.ny,self.nv)), self.proj_units)
         if is_root():
             for i, buf in sorted(storage.items()):
-                self.data[:,:,i] = buf[:,:]
+                self.data[:,:,i] = buf.transpose()
 
         self.axis_type = "velocity"
 
@@ -197,8 +205,8 @@
             T = data["temperature"].v
             w = ppv_utils.compute_weight(self.thermal_broad, self.dv_cgs,
                                          self.particle_mass, v.flatten(), T.flatten())
-            w[np.isnan(w)] = 0.0                                                                                                                        
-            return data[self.field]*w.reshape(v.shape)                                                                                                  
+            w[np.isnan(w)] = 0.0
+            return data[self.field]*w.reshape(v.shape)
         return _intensity
 
     def transform_spectral_axis(self, rest_value, units):
@@ -283,7 +291,7 @@
         if sky_scale is not None and sky_center is not None:
             w = create_sky_wcs(w, sky_center, sky_scale)
 
-        fib = FITSImageBuffer(self.data.transpose(2,0,1), fields=self.field, wcs=w)
+        fib = FITSImageBuffer(self.data.transpose(), fields=self.field, wcs=w)
         fib[0].header["bunit"] = re.sub('()', '', str(self.proj_units))
         fib[0].header["btype"] = self.field
 

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 yt/analysis_modules/ppv_cube/tests/test_ppv.py
--- a/yt/analysis_modules/ppv_cube/tests/test_ppv.py
+++ b/yt/analysis_modules/ppv_cube/tests/test_ppv.py
@@ -38,7 +38,7 @@
 
     ds = load_uniform_grid(data, dims)
 
-    cube = PPVCube(ds, "z", "density", dims=dims,
+    cube = PPVCube(ds, "z", "density", dims=(8,1024),
                    velocity_bounds=(-300., 300., "km/s"),
                    thermal_broad=True)
 

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 yt/analysis_modules/radmc3d_export/RadMC3DImageUtilities.py
--- /dev/null
+++ b/yt/analysis_modules/radmc3d_export/RadMC3DImageUtilities.py
@@ -0,0 +1,93 @@
+'''
+
+Functions for dealing with the image.out files created by RADMC-3D
+
+'''
+
+#-----------------------------------------------------------------------------
+# Copyright (c) 2013, 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.
+#-----------------------------------------------------------------------------
+
+import numpy as np
+
+
+def parse_radmc3d_image_header(lines):
+    '''
+
+    Parses the header lines from the image.out file.
+    Returns a dictionary containing the image parameters.
+
+    '''
+
+    header_data = {}
+
+    # an integer flag describing the image format.
+    # this function only works for images made in
+    # "observer at infinity" mode, i.e. iformat is 1
+    iformat = np.int64(lines[0].strip())
+    assert(iformat == 1)
+    header_data["iformat"] = iformat
+
+    # The number of pixels in the x and y-directions
+    Nx, Ny = [np.int64(Npix) for Npix in lines[1].strip().split()]
+    header_data["Nx"] = Nx
+    header_data["Ny"] = Ny
+
+    # You can produce images at multiple wavelenths in a single
+    # pass. This function assumes that there is only 1.
+    num_wavelengths = np.int64(lines[2].strip())
+    assert(num_wavelengths == 1)
+    header_data["num_wavelengths"] = num_wavelengths
+
+    # The size of pixel in each direction. Note that
+    # this only makes sense if iformat is 1
+    pixel_size_cm_x, pixel_size_cm_y = \
+        [np.float64(Npix) for Npix in lines[3].strip().split()]
+    header_data["pixel_size_cm_x"] = pixel_size_cm_x
+    header_data["pixel_size_cm_y"] = pixel_size_cm_y
+
+    # The wavelength at which the image was produced.
+    # We assume there is only 1 image here.
+    wavelength_microns = np.float64(lines[4].strip())  # assume 1 wavelength
+    header_data["wavelength_microns"] = wavelength_microns
+
+    return header_data
+
+
+def read_radmc3d_image(filename):
+    '''
+
+    Loads the image.out file created by radmc-3d.
+    Returns an np.array that contains the image data
+    as well as a dictionary with some useful metadata.
+
+    '''
+
+    fileh = open(filename, 'r')
+    lines = fileh.readlines()
+    fileh.close()
+
+    # The header should always be 5 lines long,
+    # as per the radmc-3d manual
+    header_lines = lines[0:6]
+    header = parse_radmc3d_image_header(header_lines)
+
+    Nx = header["Nx"]
+    Ny = header["Ny"]
+
+    # The rest of the lines are the image data, with the
+    # possible exception of a newline at the end
+    image_lines = lines[6:]
+    image = np.array([np.float64(line.strip()) for line in image_lines
+                      if not line.isspace()])
+
+    # This had better be true
+    assert(image.size == Nx*Ny)
+
+    image = image.reshape(header["Nx"], header["Ny"])
+
+    return header, image

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 yt/analysis_modules/radmc3d_export/RadMC3DInterface.py
--- a/yt/analysis_modules/radmc3d_export/RadMC3DInterface.py
+++ b/yt/analysis_modules/radmc3d_export/RadMC3DInterface.py
@@ -13,18 +13,18 @@
 # The full license is in the file COPYING.txt, distributed with this software.
 #-----------------------------------------------------------------------------
 
-import yt
 import numpy as np
 from yt.utilities.lib.write_array import \
     write_3D_array, write_3D_vector_array
 
+
 class RadMC3DLayer:
     '''
 
     This class represents an AMR "layer" of the style described in
     the radmc3d manual. Unlike yt grids, layers may not have more
     than one parent, so level L grids will need to be split up
-    if they straddle two or more level L - 1 grids. 
+    if they straddle two or more level L - 1 grids.
 
     '''
     def __init__(self, level, parent, unique_id, LE, RE, dim):
@@ -51,7 +51,7 @@
         '''
 
         Returns whether or not this layer overlaps a given grid
-        
+
         '''
         LE, RE = self.get_overlap_with(grid)
         if np.any(RE <= LE):
@@ -59,6 +59,7 @@
         else:
             return True
 
+
 class RadMC3DWriter:
     '''
 
@@ -78,14 +79,13 @@
         An int corresponding to the maximum number of levels of refinement
         to include in the output. Often, this does not need to be very large
         as information on very high levels is frequently unobservable.
-        Default = 2. 
+        Default = 2.
 
     Examples
     --------
 
     This will create a field called "DustDensity" and write it out to the
-    file "dust_density.inp" in a form readable by radmc3d. It will also write
-    a "dust_temperature.inp" file with everything set to 10.0 K: 
+    file "dust_density.inp" in a form readable by RadMC3D.
 
     >>> import yt
     >>> from yt.analysis_modules.radmc3d_export.api import RadMC3DWriter
@@ -95,21 +95,16 @@
     ...     return dust_to_gas*data["Density"]
     >>> yt.add_field("DustDensity", function=_DustDensity)
 
-    >>> def _DustTemperature(field, data):
-    ...     return 10.0*data["Ones"]
-    >>> yt.add_field("DustTemperature", function=_DustTemperature)
-    
     >>> ds = yt.load("galaxy0030/galaxy0030")
+
     >>> writer = RadMC3DWriter(ds)
-    
     >>> writer.write_amr_grid()
     >>> writer.write_dust_file("DustDensity", "dust_density.inp")
-    >>> writer.write_dust_file("DustTemperature", "dust_temperature.inp")
 
     ---
 
-    This example will create a field called "NumberDensityCO" and write it out to
-    the file "numberdens_co.inp". It will also write out information about
+    This example will create a field called "NumberDensityCO" and write it out
+    to the file "numberdens_co.inp". It will also write out information about
     the gas velocity to "gas_velocity.inp" so that this broadening may be
     included in the radiative transfer calculation by radmc3d:
 
@@ -117,34 +112,34 @@
     >>> from yt.analysis_modules.radmc3d_export.api import RadMC3DWriter
 
     >>> x_co = 1.0e-4
-    >>> mu_h = 2.34e-24
+    >>> mu_h = yt.Quantity(2.34e-24, 'g')
     >>> def _NumberDensityCO(field, data):
     ...     return (x_co/mu_h)*data["Density"]
     >>> yt.add_field("NumberDensityCO", function=_NumberDensityCO)
-    
+
     >>> ds = yt.load("galaxy0030/galaxy0030")
     >>> writer = RadMC3DWriter(ds)
-    
+
     >>> writer.write_amr_grid()
     >>> writer.write_line_file("NumberDensityCO", "numberdens_co.inp")
     >>> velocity_fields = ["velocity_x", "velocity_y", "velocity_z"]
-    >>> writer.write_line_file(velocity_fields, "gas_velocity.inp") 
+    >>> writer.write_line_file(velocity_fields, "gas_velocity.inp")
 
     '''
 
     def __init__(self, ds, max_level=2):
         self.max_level = max_level
-        self.cell_count = 0 
+        self.cell_count = 0
         self.layers = []
         self.domain_dimensions = ds.domain_dimensions
-        self.domain_left_edge  = ds.domain_left_edge
+        self.domain_left_edge = ds.domain_left_edge
         self.domain_right_edge = ds.domain_right_edge
         self.grid_filename = "amr_grid.inp"
         self.ds = ds
 
-        base_layer = RadMC3DLayer(0, None, 0, \
-                                  self.domain_left_edge, \
-                                  self.domain_right_edge, \
+        base_layer = RadMC3DLayer(0, None, 0,
+                                  self.domain_left_edge,
+                                  self.domain_right_edge,
                                   self.domain_dimensions)
 
         self.layers.append(base_layer)
@@ -156,7 +151,7 @@
                 self._add_grid_to_layers(grid)
 
     def _get_parents(self, grid):
-        parents = []  
+        parents = []
         for potential_parent in self.layers:
             if potential_parent.level == grid.Level - 1:
                 if potential_parent.overlaps(grid):
@@ -169,12 +164,12 @@
             LE, RE = parent.get_overlap_with(grid)
             N = (RE - LE) / grid.dds
             N = np.array([int(n + 0.5) for n in N])
-            new_layer = RadMC3DLayer(grid.Level, parent.id, \
-                                     len(self.layers), \
+            new_layer = RadMC3DLayer(grid.Level, parent.id,
+                                     len(self.layers),
                                      LE, RE, N)
             self.layers.append(new_layer)
             self.cell_count += np.product(N)
-            
+
     def write_amr_grid(self):
         '''
         This routine writes the "amr_grid.inp" file that describes the mesh
@@ -182,12 +177,12 @@
 
         '''
         dims = self.domain_dimensions
-        LE   = self.domain_left_edge
-        RE   = self.domain_right_edge
+        LE = self.domain_left_edge
+        RE = self.domain_right_edge
 
-        # Radmc3D wants the cell wall positions in cgs. Convert here:
-        LE_cgs = LE.in_units('cm')
-        RE_cgs = RE.in_units('cm')
+        # RadMC-3D wants the cell wall positions in cgs. Convert here:
+        LE_cgs = LE.in_units('cm').d  # don't write the units, though
+        RE_cgs = RE.in_units('cm').d
 
         # calculate cell wall positions
         xs = [str(x) for x in np.linspace(LE_cgs[0], RE_cgs[0], dims[0]+1)]
@@ -196,14 +191,14 @@
 
         # writer file header
         grid_file = open(self.grid_filename, 'w')
-        grid_file.write('1 \n') # iformat is always 1
+        grid_file.write('1 \n')  # iformat is always 1
         if self.max_level == 0:
             grid_file.write('0 \n')
         else:
-            grid_file.write('10 \n') # only layer-style AMR files are supported
-        grid_file.write('1 \n') # only cartesian coordinates are supported
-        grid_file.write('0 \n') 
-        grid_file.write('{}    {}    {} \n'.format(1, 1, 1)) # assume 3D
+            grid_file.write('10 \n')  # only layer-style files are supported
+        grid_file.write('1 \n')  # only cartesian coordinates are supported
+        grid_file.write('0 \n')
+        grid_file.write('{}    {}    {} \n'.format(1, 1, 1))  # assume 3D
         grid_file.write('{}    {}    {} \n'.format(dims[0], dims[1], dims[2]))
         if self.max_level != 0:
             s = str(self.max_level) + '    ' + str(len(self.layers)-1) + '\n'
@@ -234,9 +229,9 @@
                     if potential_parent.id == p:
                         parent_LE = potential_parent.LeftEdge
                 ind = (layer.LeftEdge - parent_LE) / (2.0*dds) + 1
-            ix  = int(ind[0]+0.5)
-            iy  = int(ind[1]+0.5)
-            iz  = int(ind[2]+0.5)
+            ix = int(ind[0]+0.5)
+            iy = int(ind[1]+0.5)
+            iz = int(ind[2]+0.5)
             nx, ny, nz = layer.ActiveDimensions / 2
             s = '{}    {}    {}    {}    {}    {}    {} \n'
             s = s.format(p, ix, iy, iz, nx, ny, nz)
@@ -284,13 +279,13 @@
             lev = layer.level
             if lev == 0:
                 LE = self.domain_left_edge
-                N  = self.domain_dimensions
+                N = self.domain_dimensions
             else:
                 LE = layer.LeftEdge
-                N  = layer.ActiveDimensions
+                N = layer.ActiveDimensions
 
             self._write_layer_data_to_file(fhandle, field, lev, LE, N)
-            
+
         fhandle.close()
 
     def write_line_file(self, field, filename):
@@ -321,11 +316,108 @@
             lev = layer.level
             if lev == 0:
                 LE = self.domain_left_edge
-                N  = self.domain_dimensions
+                N = self.domain_dimensions
             else:
                 LE = layer.LeftEdge
-                N  = layer.ActiveDimensions
+                N = layer.ActiveDimensions
 
             self._write_layer_data_to_file(fhandle, field, lev, LE, N)
 
         fhandle.close()
+
+    def write_source_files(self, sources, wavelengths):
+        '''
+
+        This function creates the stars.inp and wavelength_micron.inp
+        files that RadMC3D uses for its dust continuum calculations.
+
+        Parameters
+        ----------
+
+        sources: a list of RadMC3DSource objects
+            A list that contains all the sources you would like yt
+            to create
+        wavelengths: np.array of float values
+            An array listing the wavelength points you would like to
+            use the radiative transfer calculation
+
+        '''
+
+        nstars = len(sources)
+        nlam = len(wavelengths)
+
+        filename = 'stars.inp'
+        fhandle = open(filename, 'w')
+
+        # write header
+        fhandle.write('2 \n')  # a format flag that should always be 2
+        fhandle.write('%d    %d \n' % (nstars, nlam))
+
+        # write source information
+        for source in sources:
+            fhandle.write(str(source.radius) + ' ')
+            fhandle.write(str(source.mass) + ' ')
+            fhandle.write('%f %f %f' %(source.position[0], \
+                                       source.position[1], \
+                                       source.position[2]))
+            fhandle.write('\n')
+
+        # write wavelength informaton
+        for wavelength in wavelengths:
+            fhandle.write('%f \n' % wavelength)
+
+        # finally write blackbody temperature for each source
+        for source in sources:
+            # the negative sign is a flag used internally
+            # by RadMC3D to indicate that this is a blackbody
+            # source
+            fhandle.write('%f \n' % -source.temperature)
+
+        # done with stars.inp
+        fhandle.close()
+
+        # now do the wavelength_micron.inp file
+        filename = 'wavelength_micron.inp'
+        fhandle = open(filename, 'w')
+
+        fhandle.write('%d \n' % nlam)
+        for wavelength in wavelengths:
+            fhandle.write('%f \n' % wavelength)
+
+        # done with both
+        fhandle.close()
+
+
+class RadMC3DSource:
+    '''
+
+    A class that contains the data associated with a single RadMC3D photon source.
+    This is designed to help export data about the stars in a dataset into a format 
+    that can be read in by RadMC3D. Although RadMC3D can handle non-blackbody 
+    sources, here we assume that the source is a blackbody with a given temperature.
+
+    Parameters
+    ----------
+
+    radius: float
+        The size of the source in cm
+    mass: float 
+        The mass of the source in g
+    position: list of floats
+        The x, y, and z coordinates of the source, in cm
+    temperature: float
+        The blackbody temperature of the source, in K
+
+    '''
+
+    def __init__(self, radius, mass, position, temperature):
+        self.radius = radius
+        self.mass = mass
+        self.position = position
+        self.temperature = temperature
+
+        # some basic sanity checks
+        assert(self.radius > 0.0)
+        assert(self.mass > 0.0)
+        assert(self.temperature > 0)
+        assert(len(self.position) == 3)  # 3D only, please

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 yt/analysis_modules/radmc3d_export/api.py
--- a/yt/analysis_modules/radmc3d_export/api.py
+++ b/yt/analysis_modules/radmc3d_export/api.py
@@ -14,4 +14,8 @@
 #-----------------------------------------------------------------------------
 
 from .RadMC3DInterface import \
-    RadMC3DWriter
+    RadMC3DWriter, \
+    RadMC3DSource
+
+from .RadMC3DImageUtilities import \
+    read_radmc3d_image

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 yt/analysis_modules/radmc3d_export/tests/test_radmc3d_exporter.py
--- a/yt/analysis_modules/radmc3d_export/tests/test_radmc3d_exporter.py
+++ b/yt/analysis_modules/radmc3d_export/tests/test_radmc3d_exporter.py
@@ -13,14 +13,71 @@
 import yt
 from yt.testing import *
 from yt.analysis_modules.radmc3d_export.api import RadMC3DWriter
+from yt.utilities.answer_testing.framework import \
+    AnswerTestingTest, \
+    requires_ds
 from yt.config import ytcfg
 import tempfile
 import os
 import shutil
 
+
+class RadMC3DValuesTest(AnswerTestingTest):
+    '''
+
+    This test writes out a "dust_density.inp" file, 
+    reads it back in, and checks the sum of the 
+    values for degradation.
+
+    '''
+    _type_name = "RadMC3DValuesTest"
+    _attrs = ("field", )
+
+    def __init__(self, ds_fn, field, decimals=10):
+        super(RadMC3DValuesTest, self).__init__(ds_fn)
+        self.field = field
+        self.decimals = decimals
+
+    def run(self):
+
+        # Set up in a temp dir
+        tmpdir = tempfile.mkdtemp()
+        curdir = os.getcwd()
+        os.chdir(tmpdir)
+
+        # try to write the output files
+        writer = RadMC3DWriter(self.ds)
+        writer.write_amr_grid()
+        writer.write_dust_file(self.field, "dust_density.inp")
+
+        # compute the sum of the values in the resulting file
+        total = 0.0
+        with open('dust_density.inp', 'r') as f:
+            for i, line in enumerate(f):
+
+                # skip header
+                if i < 3:
+                    continue
+
+                line = line.rstrip()
+                total += np.float64(line)
+
+        # clean up
+        os.chdir(curdir)
+        shutil.rmtree(tmpdir)
+
+        return total
+
+    def compare(self, new_result, old_result):
+        err_msg = "Total value for %s not equal." % (self.field,)
+        assert_allclose(new_result, old_result, 10.**(-self.decimals),
+                        err_msg=err_msg, verbose=True)
+
+
 ISO_GAL = "IsolatedGalaxy/galaxy0030/galaxy0030"
 
- at requires_file(ISO_GAL)
+
+ at requires_ds(ISO_GAL)
 def test_radmc3d_exporter_continuum():
     """
     This test is simply following the description in the docs for how to
@@ -28,29 +85,12 @@
     dust for one of our sample datasets.
     """
 
-    # Set up in a temp dir
-    tmpdir = tempfile.mkdtemp()
-    curdir = os.getcwd()
-    os.chdir(tmpdir)
+    ds = yt.load(ISO_GAL)
 
     # Make up a dust density field where dust density is 1% of gas density
     dust_to_gas = 0.01
     def _DustDensity(field, data):
         return dust_to_gas * data["density"]
-    
-    # Make up a dust temperature field where temp = 10K everywhere
-    def _DustTemperature(field, data):
-        return 0.*data["temperature"] + data.ds.quan(10,'K')
-    
-    ds = yt.load(ISO_GAL)
     ds.add_field(("gas", "dust_density"), function=_DustDensity, units="g/cm**3")
-    ds.add_field(("gas", "dust_temperature"), function=_DustTemperature, units="K")
-    writer = RadMC3DWriter(ds)
-    
-    writer.write_amr_grid()
-    writer.write_dust_file(("gas", "dust_density"), "dust_density.inp")
-    writer.write_dust_file(("gas", "dust_temperature"), "dust_temperature.inp")
 
-    # clean up
-    os.chdir(curdir)
-    shutil.rmtree(tmpdir)
+    yield RadMC3DValuesTest(ds, ("gas", "dust_density"))

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 yt/analysis_modules/star_analysis/sfr_spectrum.py
--- a/yt/analysis_modules/star_analysis/sfr_spectrum.py
+++ b/yt/analysis_modules/star_analysis/sfr_spectrum.py
@@ -47,6 +47,9 @@
         The comoving volume of the region for the specified list of stars.
     bins : Integer
         The number of time bins used for binning the stars. Default = 300.
+    star_filter : A user-defined filtering rule for stars. 
+        See: http://yt-project.org/docs/dev/analyzing/filtering.html
+        Default: ct>0
     
     Examples
     --------
@@ -56,9 +59,10 @@
     >>> sfr = StarFormationRate(ds, sp)
     """
     def __init__(self, ds, data_source=None, star_mass=None,
-            star_creation_time=None, volume=None, bins=300):
+            star_creation_time=None, volume=None, bins=300,star_filter=None):
         self._ds = ds
         self._data_source = data_source
+        self._filter = star_filter
         self.star_mass = np.array(star_mass)
         self.star_creation_time = np.array(star_creation_time)
         self.volume = volume
@@ -78,14 +82,15 @@
             self.mode = 'provided'
         else:
             self.mode = 'data_source'
+        if filter is not None:
+            self.filter = 'provided'
         # Set up for time conversion.
         self.cosm = Cosmology(
              hubble_constant = self._ds.hubble_constant,
              omega_matter = self._ds.omega_matter,
              omega_lambda = self._ds.omega_lambda)
         # Find the time right now.
-        self.time_now = self.cosm.t_from_z(
-            self._ds.current_redshift) # seconds
+        self.time_now = self._ds.current_time.in_units('s') # seconds
         # Build the distribution.
         self.build_dist()
         # Attach some convenience arrays.
@@ -96,14 +101,19 @@
         Build the data for plotting.
         """
         # Pick out the stars.
-        if self.mode == 'data_source':
-            ct = self._data_source["stars","particle_age"]
+        if self.filter == 'provided':
+          ct = self._filter['creation_time']
+          mass_stars = self._data_source[self._filter, "particle_mass"] 
+        else:
+          if self.mode == 'data_source':
+            ct = self._data_source['creation_time']
             if ct == None :
                 print 'data source must have particle_age!'
                 sys.exit(1)
-            ct_stars = ct[ct > 0]
-            mass_stars = self._data_source["stars", "ParticleMassMsun"][ct > 0]
-        elif self.mode == 'provided':
+            #type = self._data_source['particle_type']
+            ct_stars = ct[ct>0]
+            mass_stars = self._data_source['particle_mass'][ct_stars].in_units('Msun')
+          elif self.mode == 'provided':
             ct_stars = self.star_creation_time
             mass_stars = self.star_mass
         # Find the oldest stars in units of code time.
@@ -116,7 +126,7 @@
         # Sum up the stars created in each time bin.
         self.mass_bins = np.zeros(self.bin_count + 1, dtype='float64')
         for index in np.unique(inds):
-            self.mass_bins[index] += sum(mass_stars[inds == index])
+            self.mass_bins[index] += sum(mass_stars[inds == index].tolist())
         # Calculate the cumulative mass sum over time by forward adding.
         self.cum_mass_bins = self.mass_bins.copy()
         for index in xrange(self.bin_count):
@@ -130,15 +140,15 @@
         """
         if self.mode == 'data_source':
             try:
-                vol = self._data_source.volume('mpccm')
+                vol = self._data_source['cell_volume'].in_units('Mpccm**3').sum()
             except AttributeError:
                 # If we're here, this is probably a HOPHalo object, and we
                 # can get the volume this way.
                 ds = self._data_source.get_sphere()
-                vol = ds.volume('mpccm')
+                vol = ds['cell_volume'].in_units('Mpccm**3').sum()
         elif self.mode == 'provided':
-            vol = self.volume('mpccm')
-        tc = self._ds["Time"]
+            vol = self['cell_volume'].in_units('Mpccm**3').sum()
+        #tc = self._ds["Time"] # code time to seconds conversion factor
         self.time = []
         self.lookback_time = []
         self.redshift = []
@@ -146,16 +156,17 @@
         self.Msol_yr_vol = []
         self.Msol = []
         self.Msol_cumulative = []
+        co = Cosmology() 
         # Use the center of the time_bin, not the left edge.
         for i, time in enumerate((self.time_bins[1:] + self.time_bins[:-1])/2.):
-            self.time.append(time * tc / YEAR)
-            self.lookback_time.append((self.time_now - time * tc)/YEAR)
-            self.redshift.append(self.cosm.z_from_t(time * tc))
+            self.time.append(time.in_units('yr'))
+            self.lookback_time.append(self.time_now.in_units('yr') - time.in_units('yr'))
+            self.redshift.append(co.z_from_t(time.in_units('s')))
             self.Msol_yr.append(self.mass_bins[i] / \
-                (self.time_bins_dt[i] * tc / YEAR))
+                (self.time_bins_dt[i].in_units('yr')))
             # changed vol from mpc to mpccm used in literature
             self.Msol_yr_vol.append(self.mass_bins[i] / \
-                (self.time_bins_dt[i] * tc / YEAR) / vol)
+                (self.time_bins_dt[i].in_units('yr')) / vol)
             self.Msol.append(self.mass_bins[i])
             self.Msol_cumulative.append(self.cum_mass_bins[i])
         self.time = np.array(self.time)
@@ -173,7 +184,7 @@
         The columns in the output file are:
            1. Time (yrs)
            2. Look-back time (yrs)
-           3. Redshift
+           #3. Redshift
            4. Star formation rate in this bin per year (Msol/yr)
            5. Star formation rate in this bin per year per Mpc**3 (Msol/yr/Mpc**3)
            6. Stars formed in this time bin (Msol)
@@ -193,8 +204,8 @@
         for i, time in enumerate(self.time):
             line = "%1.5e %1.5e %1.5e %1.5e %1.5e %1.5e %1.5e\n" % \
             (time, # Time
-            self.lookback_time[i], # Lookback time
-            self.redshift[i], # Redshift
+            self.lookback_time[i], # Lookback time 
+            self.redshift[i], # Redshift 
             self.Msol_yr[i], # Msol/yr
             self.Msol_yr_vol[i], # Msol/yr/vol
             self.Msol[i], # Msol in bin
@@ -261,10 +272,12 @@
     >>> ds = load("RedshiftOutput0000")
     >>> spec = SpectrumBuilder(ds, "/home/user/bc/", model="salpeter")
     """
-    def __init__(self, ds, bcdir="", model="chabrier", time_now=None):
+    def __init__(self, ds, bcdir="", model="chabrier", time_now=None, star_filter = None):
         self._ds = ds
         self.bcdir = bcdir
-        
+        self._filter = star_filter
+        if star_filter is not None:
+            self.filter = 'provided'
         if model == "chabrier":
             self.model = CHABRIER
         elif model == "salpeter":
@@ -277,8 +290,7 @@
         # Find the time right now.
         
         if time_now is None:
-            self.time_now = self.cosm.t_from_z(
-                self._ds.current_redshift) # seconds
+            self.time_now = self._ds.current_time.in_units('s') # seconds
         else:
             self.time_now = time_now
         
@@ -373,18 +385,27 @@
                 self.star_metal = star_metallicity_fraction
         else:
             # Get the data we need.
-            ct = self._data_source["creation_time"]
-            self.star_creation_time = ct[ct > 0]
-            self.star_mass = self._data_source["ParticleMassMsun"][ct > 0]
-            if star_metallicity_constant is not None:
+            if self.filter == 'provided':
+             ct = self._filter['creation_time']
+             mass_stars = self._data_source[self._filter, "particle_mass"] 
+             if star_metallicity_constant is not None:
                 self.star_metal = np.ones(self.star_mass.size, dtype='float64') * \
                     star_metallicity_constant
+             else:
+                self.star_metal = self._data_source[self._filter, "metallicity_fraction"].in_units('Zsun')
             else:
-                self.star_metal = self._data_source["metallicity_fraction"][ct > 0]
-        # Fix metallicity to units of Zsun.
-        self.star_metal /= Zsun
+              ct = self._data_source["creation_time"]
+              #type = self._data_source['particle_type']
+              ct_stars = ct[ct>0]
+              self.star_creation_time = ct_stars
+              self.star_mass = self._data_source['particle_mass'][ct_stars].in_units('Msun')
+              if star_metallicity_constant is not None:
+                self.star_metal = np.ones(self.star_mass.size, dtype='float64') * \
+                    star_metallicity_constant
+              else:
+                self.star_metal = self._data_source["metallicity_fraction"][ct_stars].in_units('Zsun')
         # Age of star in years.
-        dt = (self.time_now - self.star_creation_time * self._ds['Time']) / YEAR
+        dt = (self.time_now - self.star_creation_time).in_units('yr').tolist() 
         dt = np.maximum(dt, 0.0)
         # Remove young stars
         sub = dt >= self.min_age
@@ -428,10 +449,13 @@
         pbar.finish()    
         
         # Normalize.
-        self.total_mass = np.sum(self.star_mass)
-        self.avg_mass = np.mean(self.star_mass)
-        tot_metal = sum(self.star_metal * self.star_mass)
-        self.avg_metal = math.log10(tot_metal / self.total_mass / Zsun)
+        self.total_mass = self.star_mass.sum()
+        self.avg_mass = self.star_mass.mean()
+        tot_metal = (self.star_metal * self.star_mass).sum()
+        if total_metal > 0:
+          self.avg_metal = math.log10((tot_metal / self.total_mass).in_units('Zsun'))
+        else:
+          self.avg_metal = -99 
 
         # Below is an attempt to do the loop using vectors and matrices,
         # however it doesn't appear to be much faster, probably due to all

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 yt/data_objects/construction_data_containers.py
--- a/yt/data_objects/construction_data_containers.py
+++ b/yt/data_objects/construction_data_containers.py
@@ -42,7 +42,7 @@
 from yt.utilities.minimal_representation import \
     MinimalProjectionData
 from yt.utilities.parallel_tools.parallel_analysis_interface import \
-    parallel_objects, parallel_root_only 
+    parallel_objects, parallel_root_only, communication_system
 from yt.units.unit_object import Unit
 import yt.geometry.particle_deposit as particle_deposit
 from yt.utilities.grid_data_format.writer import write_to_gdf
@@ -236,6 +236,7 @@
         else:
             raise NotImplementedError(self.method)
         self._set_center(center)
+        self._projected_units = {}
         if data_source is None: data_source = self.ds.all_data()
         for k, v in data_source.field_parameters.items():
             if k not in self.field_parameters or \
@@ -284,10 +285,11 @@
         if self.weight_field is not None:
             chunk_fields.append(self.weight_field)
         tree = self._get_tree(len(fields))
-        # We do this once
-        for chunk in self.data_source.chunks([], "io", local_only = False):
-            self._initialize_chunk(chunk, tree)
-        # This needs to be parallel_objects-ified
+        # This only needs to be done if we are in parallel; otherwise, we can
+        # safely build the mesh as we go.
+        if communication_system.communicators[-1].size > 1:
+            for chunk in self.data_source.chunks([], "io", local_only = False):
+                self._initialize_chunk(chunk, tree)
         with self.data_source._field_parameter_state(self.field_parameters):
             for chunk in parallel_objects(self.data_source.chunks(
                                           chunk_fields, "io", local_only = True)): 
@@ -327,7 +329,6 @@
                 np.divide(nvals, nwvals[:,None], nvals)
         # We now convert to half-widths and center-points
         data = {}
-        #non_nan = ~np.any(np.isnan(nvals), axis=-1)
         code_length = self.ds.domain_width.units
         data['px'] = self.ds.arr(px, code_length)
         data['py'] = self.ds.arr(py, code_length)
@@ -341,30 +342,8 @@
         for fi, field in enumerate(fields):
             finfo = self.ds._get_field_info(*field)
             mylog.debug("Setting field %s", field)
-            units = finfo.units
-            # add length units to "projected units" if non-weighted 
-            # integral projection
-            if self.weight_field is None and not self._sum_only and \
-               self.method == 'integrate':
-                # See _handle_chunk where we mandate cm
-                if units == '':
-                    input_units = "cm"
-                else:
-                    input_units = "(%s) * cm" % units
-            else:
-                input_units = units
-            # Don't forget [non_nan] somewhere here.
-            self[field] = YTArray(field_data[fi].ravel(),
-                                  input_units=input_units,
-                                  registry=self.ds.unit_registry)
-            # convert units if non-weighted integral projection
-            if self.weight_field is None and not self._sum_only and \
-               self.method == 'integrate':
-                u_obj = Unit(units, registry=self.ds.unit_registry)
-                if ((u_obj.is_code_unit or self.ds.no_cgs_equiv_length) and
-                    not u_obj.is_dimensionless) and input_units != units:
-                    final_unit = "(%s) * code_length" % units
-                    self[field].convert_to_units(final_unit)
+            input_units = self._projected_units[field].units
+            self[field] = self.ds.arr(field_data[fi].ravel(), input_units)
         for i in data.keys(): self[i] = data.pop(i)
         mylog.info("Projection completed")
 
@@ -379,18 +358,34 @@
 
     def _handle_chunk(self, chunk, fields, tree):
         if self.method == "mip" or self._sum_only:
-            dl = 1.0
+            dl = self.ds.quan(1.0, "")
         else:
             # This gets explicitly converted to cm
-            dl = chunk.fwidth[:, self.axis]
-            dl.convert_to_units("cm")
+            ax_name = self.ds.coordinates.axis_name[self.axis]
+            dl = chunk["index", "path_element_%s" % (ax_name)]
+            # This is done for cases where our path element does not have a CGS
+            # equivalent.  Once "preferred units" have been implemented, this
+            # will not be necessary at all, as the final conversion will occur
+            # at the display layer.
+            if not dl.units.is_dimensionless:
+                dl.convert_to_units("cm")
         v = np.empty((chunk.ires.size, len(fields)), dtype="float64")
-        for i in range(len(fields)):
-            v[:,i] = chunk[fields[i]] * dl
+        for i, field in enumerate(fields):
+            d = chunk[field] * dl
+            v[:,i] = d
+            self._projected_units[field] = d.uq
         if self.weight_field is not None:
             w = chunk[self.weight_field]
             np.multiply(v, w[:,None], v)
             np.multiply(w, dl, w)
+            for field in fields:
+                # Note that this removes the dl integration, which is
+                # *correct*, but we are not fully self-consistently carrying it
+                # all through.  So if interrupted, the process will have
+                # incorrect units assigned in the projected units.  This should
+                # not be a problem, since the weight division occurs
+                # self-consistently with unitfree arrays.
+                self._projected_units[field] /= dl.uq
         else:
             w = np.ones(chunk.ires.size, dtype="float64")
         icoords = chunk.icoords
@@ -468,7 +463,7 @@
         self.domain_width = np.rint((self.ds.domain_right_edge -
                     self.ds.domain_left_edge)/self.dds).astype('int64')
         self._setup_data_source()
-                
+
     @property
     def icoords(self):
         ic = np.indices(self.ActiveDimensions).astype("int64")
@@ -948,14 +943,18 @@
         mylog.info("Extracting (sampling: %s)" % (fields,))
         verts = []
         samples = []
-        for block, mask in parallel_objects(self.data_source.blocks):
-            my_verts = self._extract_isocontours_from_grid(
-                            block, self.surface_field, self.field_value,
-                            mask, fields, sample_type)
-            if fields is not None:
-                my_verts, svals = my_verts
-                samples.append(svals)
-            verts.append(my_verts)
+        deps = self._determine_fields(self.surface_field)
+        deps = self._identify_dependencies(deps, spatial=True)
+        for io_chunk in parallel_objects(self.data_source.chunks(deps, "io",
+                                         preload_fields = deps)):
+            for block, mask in self.data_source.blocks:
+                my_verts = self._extract_isocontours_from_grid(
+                                block, self.surface_field, self.field_value,
+                                mask, fields, sample_type)
+                if fields is not None:
+                    my_verts, svals = my_verts
+                    samples.append(svals)
+                verts.append(my_verts)
         verts = np.concatenate(verts).transpose()
         verts = self.comm.par_combine_object(verts, op='cat', datatype='array')
         self.vertices = verts
@@ -1038,21 +1037,27 @@
         """
         flux = 0.0
         mylog.info("Fluxing %s", fluxing_field)
-        for block, mask in parallel_objects(self.data_source.blocks):
-            flux += self._calculate_flux_in_grid(block, mask,
-                    field_x, field_y, field_z, fluxing_field)
+        deps = [field_x, field_y, field_z]
+        if fluxing_field is not None: deps.append(fluxing_field)
+        deps = self._determine_fields(deps)
+        deps = self._identify_dependencies(deps)
+        for io_chunk in parallel_objects(self.data_source.chunks(deps, "io",
+                                preload_fields = deps)):
+            for block, mask in self.data_source.blocks:
+                flux += self._calculate_flux_in_grid(block, mask,
+                        field_x, field_y, field_z, fluxing_field)
         flux = self.comm.mpi_allreduce(flux, op="sum")
         return flux
 
     def _calculate_flux_in_grid(self, grid, mask,
-                    field_x, field_y, field_z, fluxing_field = None):
+            field_x, field_y, field_z, fluxing_field = None):
         vals = grid.get_vertex_centered_data(self.surface_field)
         if fluxing_field is None:
             ff = np.ones(vals.shape, dtype="float64")
         else:
             ff = grid.get_vertex_centered_data(fluxing_field)
-        xv, yv, zv = [grid.get_vertex_centered_data(f) for f in 
-                     [field_x, field_y, field_z]]
+        xv, yv, zv = [grid.get_vertex_centered_data(f)
+                      for f in [field_x, field_y, field_z]]
         return march_cubes_grid_flux(self.field_value, vals, xv, yv, zv,
                     ff, mask, grid.LeftEdge, grid.dds)
 

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -1019,16 +1019,13 @@
         """
         verts = []
         samples = []
-        pb = get_pbar("Extracting ", len(list(self._get_grid_objs())))
-        for i, g in enumerate(self._get_grid_objs()):
-            pb.update(i)
+        for block, mask in self.blocks:
             my_verts = self._extract_isocontours_from_grid(
-                            g, field, value, sample_values)
+                block, mask, field, value, sample_values)
             if sample_values is not None:
                 my_verts, svals = my_verts
                 samples.append(svals)
             verts.append(my_verts)
-        pb.finish()
         verts = np.concatenate(verts).transpose()
         verts = self.comm.par_combine_object(verts, op='cat', datatype='array')
         verts = verts.transpose()
@@ -1052,11 +1049,9 @@
             return verts, samples
         return verts
 
-
-    def _extract_isocontours_from_grid(self, grid, field, value,
-                                       sample_values = None):
-        mask = self._get_cut_mask(grid) * grid.child_mask
-        vals = grid.get_vertex_centered_data(field, no_ghost = False)
+    def _extract_isocontours_from_grid(self, grid, mask, field, value,
+                                       sample_values=None):
+        vals = grid.get_vertex_centered_data(field, no_ghost=False)
         if sample_values is not None:
             svals = grid.get_vertex_centered_data(sample_values)
         else:
@@ -1130,15 +1125,14 @@
         ...     "velocity_x", "velocity_y", "velocity_z", "Metal_Density")
         """
         flux = 0.0
-        for g in self._get_grid_objs():
-            flux += self._calculate_flux_in_grid(g, field, value,
-                    field_x, field_y, field_z, fluxing_field)
+        for block, mask in self.blocks:
+            flux += self._calculate_flux_in_grid(block, mask, field, value, field_x,
+                                                 field_y, field_z, fluxing_field)
         flux = self.comm.mpi_allreduce(flux, op="sum")
         return flux
 
-    def _calculate_flux_in_grid(self, grid, field, value,
+    def _calculate_flux_in_grid(self, grid, mask, field, value,
                     field_x, field_y, field_z, fluxing_field = None):
-        mask = self._get_cut_mask(grid) * grid.child_mask
         vals = grid.get_vertex_centered_data(field)
         if fluxing_field is None:
             ff = np.ones(vals.shape, dtype="float64")

diff -r 8b6a5a6061b6b0f6cff13663e23bfce80ea975ac -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 yt/fields/field_detector.py
--- a/yt/fields/field_detector.py
+++ b/yt/fields/field_detector.py
@@ -190,6 +190,8 @@
         self.requested_parameters.append(param)
         if param in ['bulk_velocity', 'center', 'normal']:
             return self.ds.arr(np.random.random(3) * 1e-2, self.fp_units[param])
+        elif param in ['surface_height']:
+            return self.ds.quan(0.0, 'code_length')
         elif param in ['axis']:
             return 0
         elif param.startswith("cp_"):

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

https://bitbucket.org/yt_analysis/yt/commits/44d8da51fabf/
Changeset:   44d8da51fabf
Branch:      yt
User:        ngoldbaum
Date:        2015-01-05 04:21:04+00:00
Summary:     Fix issues with particle fields noticed during PR review.
Affected #:  1 file

diff -r 77c9d1d6387b327b84cdde02b34c5b79ed66e2c6 -r 44d8da51fabf8799018943429398bf9fa2a485e1 yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -359,7 +359,7 @@
                            "g*cm**2/s", ftype=ptype, particle_type=True)
 
     def _particle_radius(field, data):
-        """The spherical radial component of the particle positions
+        """The spherical radius component of the particle positions
 
         Relative to the coordinate system defined by the *normal* vector,
         and *center* field parameters.
@@ -735,7 +735,7 @@
                           ValidateParameter("center")])
 
     def _particle_velocity_spherical_phi(field, data):
-        """The cylindrical radial component of the particles velocities
+        """The spherical phi component of the particle velocities
 
         Relative to the coordinate system defined by the *normal* vector,
         *bulk_velocity* vector and *center* field parameters.
@@ -752,7 +752,7 @@
         return sphp
 
     registry.add_field(
-        (ptype, "particle_spherical_velocity_phi"),
+        (ptype, "particle_velocity_spherical_phi"),
         function=_particle_velocity_spherical_phi,
         particle_type=True,
         units="cm/s",
@@ -828,7 +828,7 @@
         validators=[ValidateParameter("normal"), ValidateParameter("center")])
 
     def _particle_velocity_cylindrical_radius(field, data):
-        """The cylindrical radial component of the particles velocities
+        """The cylindrical radius component of the particle velocities
 
         Relative to the coordinate system defined by the *normal* vector,
         *bulk_velocity* vector and *center* field parameters.
@@ -854,7 +854,7 @@
         validators=[ValidateParameter("normal"), ValidateParameter("center")])
 
     def _particle_velocity_cylindrical_theta(field, data):
-        """The cylindrical theta component of the particles velocities
+        """The cylindrical theta component of the particle velocities
 
         Relative to the coordinate system defined by the *normal* vector,
         *bulk_velocity* vector and *center* field parameters.
@@ -890,7 +890,7 @@
                           ValidateParameter("center")])
 
     def _particle_velocity_cylindrical_z(field, data):
-        """The cylindrical z component of the particles velocities
+        """The cylindrical z component of the particle velocities
 
         Relative to the coordinate system defined by the *normal* vector,
         *bulk_velocity* vector and *center* field parameters.


https://bitbucket.org/yt_analysis/yt/commits/e05ae4338a02/
Changeset:   e05ae4338a02
Branch:      yt
User:        ngoldbaum
Date:        2015-01-05 05:04:44+00:00
Summary:     reorganizing and commenting geometric fields.
Affected #:  1 file

diff -r 44d8da51fabf8799018943429398bf9fa2a485e1 -r e05ae4338a022f55c864c571675bbd147eb984b9 yt/fields/geometric_fields.py
--- a/yt/fields/geometric_fields.py
+++ b/yt/fields/geometric_fields.py
@@ -22,162 +22,224 @@
     ValidateSpatial
 
 from .field_functions import \
-     get_periodic_rvec, \
-     get_radius
+    get_periodic_rvec, \
+    get_radius
 
 from .field_plugin_registry import \
     register_field_plugin
 
 from yt.utilities.math_utils import \
-    get_sph_r_component, \
-    get_sph_theta_component, \
-    get_sph_phi_component, \
-    get_cyl_r_component, \
-    get_cyl_z_component, \
-    get_cyl_theta_component, \
     get_cyl_r, get_cyl_theta, \
     get_cyl_z, get_sph_r, \
-    get_sph_theta, get_sph_phi, \
-    periodic_dist, euclidean_dist
+    get_sph_theta, get_sph_phi
 
 @register_field_plugin
-def setup_geometric_fields(registry, ftype = "gas", slice_info = None):
+def setup_geometric_fields(registry, ftype="gas", slice_info=None):
 
     def _radius(field, data):
+        """The spherical radius component of the mesh cells.
+
+        Relative to the coordinate system defined by the *center* field
+        parameter.
+        """
         return get_radius(data, "")
 
-    registry.add_field(("index", "radius"), function=_radius,
-              validators=[ValidateParameter("center")],
-              units="cm")
+    registry.add_field(("index", "radius"),
+                       function=_radius,
+                       validators=[ValidateParameter("center")],
+                       units="cm")
 
     def _grid_level(field, data):
+        """The AMR refinement level"""
         return np.ones(data.ActiveDimensions)*(data.Level)
+
     registry.add_field(("index", "grid_level"),
-              function=_grid_level, units = "",
-              validators=[ValidateGridType(),
-                          ValidateSpatial(0)])
+                       function=_grid_level,
+                       units="",
+                       validators=[ValidateGridType(), ValidateSpatial(0)])
 
     def _grid_indices(field, data):
+        """The index of the leaf grid the mesh cells exist on"""
         return np.ones(data["index", "ones"].shape)*(data.id-data._id_offset)
+
     registry.add_field(("index", "grid_indices"),
-              function=_grid_indices, units = "",
-              validators=[ValidateGridType(),
-                          ValidateSpatial(0)], take_log=False)
+                       function=_grid_indices,
+                       units="",
+                       validators=[ValidateGridType(), ValidateSpatial(0)],
+                       take_log=False)
+
     def _ones_over_dx(field, data):
+        """The inverse of the local cell spacing"""
         return np.ones(data["index", "ones"].shape,
                        dtype="float64")/data["index", "dx"]
-    registry.add_field(("index", "ones_over_dx"), function=_ones_over_dx,
-              units = "1 / cm",
-              display_field=False)
+
+    registry.add_field(("index", "ones_over_dx"),
+                       function=_ones_over_dx,
+                       units="1 / cm",
+                       display_field=False)
 
     def _zeros(field, data):
+        """Returns zero for all cells"""
         arr = np.zeros(data["index", "ones"].shape, dtype='float64')
         return data.apply_units(arr, field.units)
 
-    registry.add_field(("index", "zeros"), function=_zeros,
-              units = "",
-              display_field=False)
+    registry.add_field(("index", "zeros"),
+                       function=_zeros,
+                       units="",
+                       display_field=False)
 
     def _ones(field, data):
+        """Returns one for all cells"""
         arr = np.ones(data.ires.shape, dtype="float64")
         if data._spatial:
             return data._reshape_vals(arr)
         return data.apply_units(arr, field.units)
 
-    registry.add_field(("index", "ones"), function=_ones,
-              units = "",
-              display_field=False)
+    registry.add_field(("index", "ones"),
+                       function=_ones,
+                       units="",
+                       display_field=False)
 
-    ### spherical coordinates: r (radius)
-    def _spherical_r(field, data):
+    def _spherical_radius(field, data):
+        """The spherical radius component of the positions of the mesh cells.
+
+        Relative to the coordinate system defined by the *center* field
+        parameter.
+        """
         coords = get_periodic_rvec(data)
         return data.ds.arr(get_sph_r(coords), "code_length").in_cgs()
 
+    registry.add_field(("index", "spherical_radius"),
+                       function=_spherical_radius,
+                       validators=[ValidateParameter("center")],
+                       units="cm")
+
+    def _spherical_r(field, data):
+        """This field is deprecated and will be removed in a future release"""
+        return data['index', 'spherical_radius']
+
     registry.add_field(("index", "spherical_r"),
-             function=_spherical_r,
-             validators=[ValidateParameter("center")],
-             units="cm")
+                       function=_spherical_r,
+                       validators=[ValidateParameter("center")],
+                       units="cm")
 
-    ### spherical coordinates: theta (angle with respect to normal)
     def _spherical_theta(field, data):
+        """The spherical theta component of the positions of the mesh cells.
+
+        theta is the poloidal position angle in the plane parallel to the
+        *normal* vector
+
+        Relative to the coordinate system defined by the *center* and *normal*
+        field parameters.
+        """
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
         return get_sph_theta(coords, normal)
 
     registry.add_field(("index", "spherical_theta"),
-             function=_spherical_theta,
-             validators=[ValidateParameter("center"),
-                         ValidateParameter("normal")])
+                       function=_spherical_theta,
+                       validators=[ValidateParameter("center"),
+                                   ValidateParameter("normal")],
+                       units='')
 
-    ### spherical coordinates: phi (angle in the plane perpendicular to the normal)
     def _spherical_phi(field, data):
+        """The spherical phi component of the positions of the mesh cells.
+
+        phi is the azimuthal position angle in the plane perpendicular to the
+        *normal* vector
+
+        Relative to the coordinate system defined by the *center* and *normal*
+        field parameters.
+        """
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
         return get_sph_phi(coords, normal)
 
     registry.add_field(("index", "spherical_phi"),
-             function=_spherical_phi,
-             validators=[ValidateParameter("center"),
-             ValidateParameter("normal")])
+                       function=_spherical_phi,
+                       validators=[ValidateParameter("center"),
+                                   ValidateParameter("normal")],
+                       units='')
 
-    ### cylindrical coordinates: R (radius in the cylinder's plane)
-    def _cylindrical_r(field, data):
+    def _cylindrical_radius(field, data):
+        """The cylindrical radius component of the positions of the mesh cells.
+
+        Relative to the coordinate system defined by the *normal* vector and
+        *center* field parameters.
+        """
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
         return data.ds.arr(get_cyl_r(coords, normal), "code_length").in_cgs()
 
+    registry.add_field(("index", "cylindrical_radius"),
+                       function=_cylindrical_radius,
+                       validators=[ValidateParameter("center"),
+                                   ValidateParameter("normal")],
+                       units="cm")
+
+    def _cylindrical_r(field, data):
+        """This field is deprecated and will be removed in a future release"""
+        return data['index', 'cylindrical_radius']
+
     registry.add_field(("index", "cylindrical_r"),
-             function=_cylindrical_r,
-             validators=[ValidateParameter("center"),
-                         ValidateParameter("normal")],
-             units="cm")
+                       function=_cylindrical_r,
+                       validators=[ValidateParameter("center")],
+                       units="cm")
 
-    ### cylindrical coordinates: z (height above the cylinder's plane)
     def _cylindrical_z(field, data):
+        """The cylindrical z component of the positions of the mesh cells.
+
+        Relative to the coordinate system defined by the *normal* vector and
+        *center* field parameters.
+        """
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
         return data.ds.arr(get_cyl_z(coords, normal), "code_length").in_cgs()
 
     registry.add_field(("index", "cylindrical_z"),
-             function=_cylindrical_z,
-             validators=[ValidateParameter("center"),
-                         ValidateParameter("normal")],
-             units="cm")
+                       function=_cylindrical_z,
+                       validators=[ValidateParameter("center"),
+                                   ValidateParameter("normal")],
+                       units="cm")
 
-    ### cylindrical coordinates: theta (angle in the cylinder's plane)
     def _cylindrical_theta(field, data):
+        """The cylindrical z component of the positions of the mesh cells.
+
+        theta is the azimuthal position angle in the plane perpendicular to the
+        *normal* vector.
+
+        Relative to the coordinate system defined by the *normal* vector and
+        *center* field parameters.
+        """
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
         return get_cyl_theta(coords, normal)
 
     registry.add_field(("index", "cylindrical_theta"),
-             function=_cylindrical_theta,
-             validators=[ValidateParameter("center"),
-                         ValidateParameter("normal")],
-             units = "")
+                       function=_cylindrical_theta,
+                       validators=[ValidateParameter("center"),
+                                   ValidateParameter("normal")],
+                       units="")
 
-    ### The old field DiskAngle is the same as the spherical coordinates'
-    ### 'theta' angle. I'm keeping DiskAngle for backwards compatibility.
-    # @todo: remove in 3.0?
     def _disk_angle(field, data):
+        """This field is dprecated and will be removed in a future release"""
         return data["index", "spherical_theta"]
 
     registry.add_field(("index", "disk_angle"),
-              function=_disk_angle, take_log=False,
-              validators=[ValidateParameter("center"),
-                          ValidateParameter("normal")],
-              display_field=False,
-              units = "")
+                       function=_disk_angle,
+                       take_log=False,
+                       display_field=False,
+                       validators=[ValidateParameter("center"),
+                                   ValidateParameter("normal")],
+                       units="")
 
-    ### The old field Height is the same as the cylindrical coordinates' z
-    ### field. I'm keeping Height for backwards compatibility.
-    # @todo: remove in 3.0?
     def _height(field, data):
+        """This field is deprecated and will be removed in a future release"""
         return data["index", "cylindrical_z"]
 
-    registry.add_field(("index", "height"), function=_height, 
-             validators=[ValidateParameter("center"),
-                         ValidateParameter("normal")],
-             units="cm",
-             display_field=False)
-
+    registry.add_field(("index", "height"),
+                       function=_height,
+                       validators=[ValidateParameter("center"),
+                                   ValidateParameter("normal")],
+                       units="cm",
+                       display_field=False)


https://bitbucket.org/yt_analysis/yt/commits/ce4a810afb4f/
Changeset:   ce4a810afb4f
Branch:      yt
User:        ngoldbaum
Date:        2015-01-05 05:05:05+00:00
Summary:     reorganizing and commenting vector velocity fields.
Affected #:  1 file

diff -r e05ae4338a022f55c864c571675bbd147eb984b9 -r ce4a810afb4f985cdc819f3cc01a454841cc9b67 yt/fields/vector_operations.py
--- a/yt/fields/vector_operations.py
+++ b/yt/fields/vector_operations.py
@@ -13,15 +13,10 @@
 
 import numpy as np
 
-from yt.units.yt_array import YTArray
-
 from .derived_field import \
     ValidateParameter, \
     ValidateSpatial
 
-from .field_plugin_registry import \
-    register_field_plugin
-
 from yt.utilities.math_utils import \
     get_sph_r_component, \
     get_sph_theta_component, \
@@ -29,19 +24,15 @@
     get_cyl_r_component, \
     get_cyl_z_component, \
     get_cyl_theta_component, \
-    get_cyl_r, get_cyl_theta, \
-    get_cyl_z, get_sph_r, \
-    get_sph_theta, get_sph_phi, \
-    periodic_dist, euclidean_dist, \
     resize_vector
 
 from yt.funcs import just_one
 
-from yt.utilities.lib.misc_utilities import obtain_rvec, obtain_rv_vec
+from yt.utilities.lib.misc_utilities import obtain_rv_vec
 
 def create_magnitude_field(registry, basename, field_units,
-                           ftype = "gas", slice_info = None,
-                           validators = None, particle_type=False):
+                           ftype="gas", slice_info=None,
+                           validators=None, particle_type=False):
 
     field_components = [(ftype, "%s_%s" % (basename, ax)) for ax in 'xyz']
 
@@ -54,29 +45,29 @@
         return np.sqrt(mag)
 
     registry.add_field((ftype, "%s_magnitude" % basename),
-                       function = _magnitude, units = field_units,
-                       validators = validators, particle_type = particle_type)
+                       function=_magnitude, units=field_units,
+                       validators=validators, particle_type=particle_type)
 
 def create_squared_field(registry, basename, field_units,
-                         ftype = "gas", slice_info = None,
-                         validators = None, particle_type=False):
+                         ftype="gas", slice_info=None,
+                         validators=None, particle_type=False):
 
     field_components = [(ftype, "%s_%s" % (basename, ax)) for ax in 'xyz']
 
     def _squared(field, data):
         fn = field_components[0]
-        squared  = data[fn] * data[fn]
+        squared = data[fn] * data[fn]
         for idim in range(1, registry.ds.dimensionality):
             fn = field_components[idim]
             squared += data[fn] * data[fn]
         return squared
 
     registry.add_field((ftype, "%s_squared" % basename),
-                       function = _squared, units = field_units,
-                       validators = validators, particle_type = particle_type)
+                       function=_squared, units=field_units,
+                       validators=validators, particle_type=particle_type)
 
 def create_vector_fields(registry, basename, field_units,
-                         ftype = "gas", slice_info = None):
+                         ftype="gas", slice_info=None):
     # slice_info would be the left, the right, and the factor.
     # For example, with the old Enzo-ZEUS fields, this would be:
     # slice(None, -2, None)
@@ -89,7 +80,6 @@
         div_fac = 2.0
     else:
         sl_left, sl_right, div_fac = slice_info
-    sl_center = slice(1, -1, None)
 
     xn, yn, zn = [(ftype, "%s_%s" % (basename, ax)) for ax in 'xyz']
 
@@ -101,50 +91,113 @@
 
     create_magnitude_field(registry, basename, field_units,
                            ftype=ftype, slice_info=slice_info)
-        
-    def _radial(field, data):
+
+    def _spherical_radius_component(field, data):
+        """The spherical radius component of the vector field
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *center*, and *bulk_* field parameters.
+        """
         normal = data.get_field_parameter("normal")
         vectors = obtain_rv_vec(data, (xn, yn, zn),
                                 "bulk_%s" % basename)
         theta = data['index', 'spherical_theta']
-        phi   = data['index', 'spherical_phi']
+        phi = data['index', 'spherical_phi']
         rv = get_sph_r_component(vectors, theta, phi, normal)
         # Now, anywhere that radius is in fact zero, we want to zero out our
         # return values.
         rv[np.isnan(theta)] = 0.0
         return rv
+
+    registry.add_field((ftype, "%s_spherical_radius" % basename),
+                       function=_spherical_radius_component,
+                       units=field_units,
+                       validators=[ValidateParameter("normal"),
+                                   ValidateParameter("center"),
+                                   ValidateParameter("bulk_%s" % basename)])
+
+    def _radial(field, data):
+        return data[ftype, "%s_spherical_radius" % basename]
+
     def _radial_absolute(field, data):
-        return np.abs(data[ftype, "radial_%s" % basename])
+        return np.abs(data[ftype, "%s_spherical_radius" % basename])
 
     def _tangential(field, data):
-        return np.sqrt(data[ftype, "%s_magnitude" % basename]**2.0
-                     - data[ftype, "radial_%s" % basename]**2.0)
+        return np.sqrt(data[ftype, "%s_magnitude" % basename]**2.0 -
+                       data[ftype, "%s_spherical_radius" % basename]**2.0)
 
     registry.add_field((ftype, "radial_%s" % basename),
-                       function = _radial, units = field_units,
+                       function=_radial,
+                       units=field_units,
                        validators=[ValidateParameter("normal"),
                                    ValidateParameter("center")])
+
     registry.add_field((ftype, "radial_%s_absolute" % basename),
-                       function = _radial_absolute, units = field_units)
+                       function=_radial_absolute,
+                       units=field_units)
+
     registry.add_field((ftype, "tangential_%s" % basename),
-                       function=_tangential, units = field_units)
+                       function=_tangential,
+                       units=field_units)
+
+    def _spherical_theta_component(field, data):
+        """The spherical theta component of the vector field
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *center*, and *bulk_* field parameters.
+        """
+        normal = data.get_field_parameter("normal")
+        vectors = obtain_rv_vec(data, (xn, yn, zn),
+                                "bulk_%s" % basename)
+        theta = resize_vector(data["index", "spherical_theta"], vectors)
+        phi = resize_vector(data["index", "spherical_phi"], vectors)
+        return get_sph_theta_component(vectors, theta, phi, normal)
+
+    registry.add_field((ftype, "%s_spherical_theta" % basename),
+                       function=_spherical_theta_component,
+                       units=field_units,
+                       validators=[ValidateParameter("normal"),
+                                   ValidateParameter("center"),
+                                   ValidateParameter("bulk_%s" % basename)])
+
+    def _spherical_phi_component(field, data):
+        """The spherical phi component of the vector field
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *center*, and *bulk_* field parameters.
+        """
+        normal = data.get_field_parameter("normal")
+        vectors = obtain_rv_vec(data, (xn, yn, zn),
+                                "bulk_%s" % basename)
+        phi = resize_vector(data["index", "spherical_phi"], vectors)
+        return get_sph_phi_component(vectors, phi, normal)
+
+    registry.add_field((ftype, "%s_spherical_phi" % basename),
+                       function=_spherical_phi_component,
+                       units=field_units,
+                       validators=[ValidateParameter("normal"),
+                                   ValidateParameter("center"),
+                                   ValidateParameter("bulk_%s" % basename)])
 
     def _cp_vectors(ax):
         def _cp_val(field, data):
             vec = data.get_field_parameter("cp_%s_vec" % (ax))
             bv = data.get_field_parameter("bulk_%s" % basename)
-            if bv == None: bv = np.zeros(3)
+            if bv is None: bv = np.zeros(3)
             tr  = (data[xn] - bv[0]) * vec[0]
             tr += (data[yn] - bv[1]) * vec[1]
             tr += (data[zn] - bv[2]) * vec[2]
             return tr
         return _cp_val
     registry.add_field((ftype, "cutting_plane_%s_x" % basename),
-                       function = _cp_vectors('x'), units = field_units)
+                       function=_cp_vectors('x'),
+                       units=field_units)
     registry.add_field((ftype, "cutting_plane_%s_y" % basename),
-                       function = _cp_vectors('y'), units = field_units)
+                       function=_cp_vectors('y'),
+                       units=field_units)
     registry.add_field((ftype, "cutting_plane_%s_z" % basename),
-                       function = _cp_vectors('z'), units = field_units)
+                       function=_cp_vectors('z'),
+                       units=field_units)
 
     def _divergence(field, data):
         ds = div_fac * just_one(data["index", "dx"])
@@ -160,14 +213,18 @@
                                 f.units)        
         new_field[1:-1,1:-1,1:-1] = f
         return new_field
+
     def _divergence_abs(field, data):
         return np.abs(data[ftype, "%s_divergence" % basename])
 
     registry.add_field((ftype, "%s_divergence" % basename),
-                       function = _divergence, units = "1/s",
-                       validators = [ValidateSpatial(1)])
+                       function=_divergence,
+                       units="1/s",
+                       validators=[ValidateSpatial(1)])
+    
     registry.add_field((ftype, "%s_divergence_absolute" % basename),
-                       function = _divergence_abs, units = "1/s")
+                       function=_divergence_abs,
+                       units="1/s")
 
     def _tangential_over_magnitude(field, data):
         tr = data[ftype, "tangential_%s" % basename] / \
@@ -177,26 +234,46 @@
              function=_tangential_over_magnitude,
              take_log=False)
 
-    def _cylindrical_radial(field, data):
+    def _cylindrical_radius_component(field, data):
+        """The cylindrical radius component of the vector field
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *center*, and *bulk_* field parameters.
+        """
         normal = data.get_field_parameter("normal")
         vectors = obtain_rv_vec(data, (xn, yn, zn),
                                 "bulk_%s" % basename)
         theta = resize_vector(data["index", 'cylindrical_theta'], vectors)
         return get_cyl_r_component(vectors, theta, normal)
 
-    def _cylindrical_radial_absolute(field, data):
-        return np.abs(_cylindrical_radial(field, data))
+    registry.add_field((ftype, "%s_cylindrical_radius" % basename),
+                       function=_cylindrical_radius_component,
+                       units=field_units,
+                       validators=[ValidateParameter("normal")])
+
+    def _cylindrical_radial(field, data):
+        """This field is deprecated and will be removed in a future version"""
+        return data[ftype, '%s_cylindrical_radius' % basename]
 
     registry.add_field((ftype, "cylindrical_radial_%s" % basename),
-             function=_cylindrical_radial,
-             units=field_units,
-             validators=[ValidateParameter("normal")])
+                       function=_cylindrical_radial,
+                       units=field_units)
+
+    def _cylindrical_radial_absolute(field, data):
+        """This field is deprecated and will be removed in a future version"""
+        return np.abs(data[ftype, '%s_cylindrical_radius' % basename])
+
     registry.add_field((ftype, "cylindrical_radial_%s_absolute" % basename),
-             function=_cylindrical_radial_absolute,
-             units=field_units,
-             validators=[ValidateParameter("normal")])
+                       function=_cylindrical_radial_absolute,
+                       units=field_units,
+                       validators=[ValidateParameter("normal")])
 
-    def _cylindrical_tangential(field, data):
+    def _cylindrical_theta_component(field, data):
+        """The cylindrical theta component of the vector field
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *center*, and *bulk_* field parameters.
+        """
         normal = data.get_field_parameter("normal")
         vectors = obtain_rv_vec(data, (xn, yn, zn),
                                 "bulk_%s" % basename)
@@ -204,24 +281,49 @@
         theta = np.tile(theta, (3,) + (1,)*len(theta.shape))
         return get_cyl_theta_component(vectors, theta, normal)
 
+    registry.add_field((ftype, "%s_cylindrical_theta" % basename),
+                       function=_cylindrical_theta_component,
+                       units=field_units,
+                       validators=[ValidateParameter("normal"),
+                                   ValidateParameter("center"),
+                                   ValidateParameter("bulk_%s" % basename)])
+
+    def _cylindrical_tangential(field, data):
+        """This field is deprecated and will be removed in a future release"""
+        return data["%s_cylindrical_theta" % basename]
+
     def _cylindrical_tangential_absolute(field, data):
-        return np.abs(_cylindrical_tangential(field, data))
+        """This field is deprecated and will be removed in a future release"""
+        return np.abs(data['cylindrical_tangential_%s' % basename])
 
-    registry.add_field(
-             (ftype, "cylindrical_tangential_%s" % basename),
-             function=_cylindrical_tangential,
-             units=field_units,
-             validators=[ValidateParameter("normal")])
-    registry.add_field(
-             (ftype, "cylindrical_tangential_%s_absolute" % basename),
-             function=_cylindrical_tangential_absolute,
-             units=field_units,
-             validators=[ValidateParameter("normal")])
+    registry.add_field((ftype, "cylindrical_tangential_%s" % basename),
+                       function=_cylindrical_tangential,
+                       units=field_units)
 
-def create_averaged_field(registry, basename, field_units,
-                          ftype = "gas", slice_info = None,
-                          validators = None,
-                          weight = "cell_mass"):
+    registry.add_field((ftype, "cylindrical_tangential_%s_absolute" % basename),
+                       function=_cylindrical_tangential_absolute,
+                       units=field_units)
+
+    def _cylindrical_z_component(field, data):
+        """The cylindrical z component of the vector field
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *center*, and *bulk_* field parameters.
+        """
+        normal = data.get_field_parameter("normal")
+        vectors = obtain_rv_vec(data, (xn, yn, zn), "bulk_%s" % basename)
+        return get_cyl_z_component(vectors, normal)
+
+    registry.add_field((ftype, "%s_cylindrical_z" % basename),
+                       function=_cylindrical_z_component,
+                       units=field_units,
+                       validators=[ValidateParameter("normal"),
+                                   ValidateParameter("center"),
+                                   ValidateParameter("bulk_%s" % basename)])
+
+
+def create_averaged_field(registry, basename, field_units, ftype="gas",
+                          slice_info=None, validators=None, weight="cell_mass"):
 
     if validators is None:
         validators = []
@@ -232,14 +334,14 @@
         new_field = data.ds.arr(np.zeros((nx-2, ny-2, nz-2), dtype=np.float64),
                                 (just_one(data[(ftype, basename)]) *
                                  just_one(data[(ftype, weight)])).units)
-        weight_field = data.ds.arr(np.zeros((nx-2, ny-2, nz-2), dtype=np.float64),
+        weight_field = data.ds.arr(np.zeros((nx-2, ny-2, nz-2),
+                                            dtype=np.float64),
                                    data[(ftype, weight)].units)
         i_i, j_i, k_i = np.mgrid[0:3, 0:3, 0:3]
 
         for i, j, k in zip(i_i.ravel(), j_i.ravel(), k_i.ravel()):
             sl = [slice(i, nx-(2-i)), slice(j, ny-(2-j)), slice(k, nz-(2-k))]
-            new_field += data[(ftype, basename)][sl] * \
-              data[(ftype, weight)][sl]
+            new_field += data[(ftype, basename)][sl] * data[(ftype, weight)][sl]
             weight_field += data[(ftype, weight)][sl]
 
         # Now some fancy footwork


https://bitbucket.org/yt_analysis/yt/commits/5db9af2d0957/
Changeset:   5db9af2d0957
Branch:      yt
User:        ngoldbaum
Date:        2015-01-05 05:05:37+00:00
Summary:     use dimensionless units rather than radians, sidestepping possible issues.
Affected #:  1 file

diff -r ce4a810afb4f985cdc819f3cc01a454841cc9b67 -r 5db9af2d0957947454ebc57083fe91e539d52c23 yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -602,13 +602,13 @@
         pos = spos
         pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
         pos = pos - np.reshape(center, (3, 1))
-        return data.ds.arr(get_sph_theta(pos, normal), "radian")
+        return data.ds.arr(get_sph_theta(pos, normal), "")
 
     registry.add_field(
         (ptype, "particle_position_spherical_theta"),
         function=_particle_position_spherical_theta,
         particle_type=True,
-        units="radian",
+        units="",
         validators=[ValidateParameter("center"), ValidateParameter("normal")])
 
     def _particle_spherical_position_theta(field, data):
@@ -632,13 +632,13 @@
         pos = spos
         pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
         pos = pos - np.reshape(center, (3, 1))
-        return data.ds.arr(get_sph_phi(pos, normal), "radian")
+        return data.ds.arr(get_sph_phi(pos, normal), "")
 
     registry.add_field(
         (ptype, "particle_position_spherical_phi"),
         function=_particle_position_spherical_phi,
         particle_type=True,
-        units="radian",
+        units="",
         validators=[ValidateParameter("normal"), ValidateParameter("center")])
 
     def _particle_spherical_position_phi(field, data):
@@ -647,7 +647,7 @@
 
     registry.add_field((ptype, "particle_spherical_position_phi"),
              function=_particle_spherical_position_phi,
-             particle_type=True, units="radian",
+             particle_type=True, units="",
              validators=[ValidateParameter("center"),
                          ValidateParameter("normal")])
 
@@ -798,13 +798,13 @@
         center = data.get_field_parameter('center')
         pos = YTArray([data[ptype, spos % ax] for ax in "xyz"])
         pos = pos - np.reshape(center, (3, 1))
-        return data.ds.arr(get_cyl_theta(pos, normal), "radian")
+        return data.ds.arr(get_cyl_theta(pos, normal), "")
 
     registry.add_field(
         (ptype, "particle_position_cylindrical_theta"),
         function=_particle_position_cylindrical_theta,
         particle_type=True,
-        units="radian",
+        units="",
         validators=[ValidateParameter("center"), ValidateParameter("normal")])
 
     def _particle_position_cylindrical_z(field,data):


https://bitbucket.org/yt_analysis/yt/commits/def04a244759/
Changeset:   def04a244759
Branch:      yt
User:        MatthewTurk
Date:        2015-01-12 21:09:41+00:00
Summary:     Merged in ngoldbaum/yt (pull request #1381)

positions and velocities for various coordinate systems. Fixes #966
Affected #:  5 files

diff -r b7feb560aa19a08d480d85185fe7beeb6bb9e243 -r def04a2447592b5737a71a244df44fc45a9a5fc3 yt/data_objects/particle_io.py
--- a/yt/data_objects/particle_io.py
+++ b/yt/data_objects/particle_io.py
@@ -134,8 +134,8 @@
     def __init__(self, ds, source):
         self.center = source.center
         self.normal = source._norm_vec
-        self.radius = source._radius
-        self.height = source._height
+        self.radius = source.radius
+        self.height = source.height
         ParticleIOHandler.__init__(self, ds, source)
     
     def _get_args(self):

diff -r b7feb560aa19a08d480d85185fe7beeb6bb9e243 -r def04a2447592b5737a71a244df44fc45a9a5fc3 yt/fields/geometric_fields.py
--- a/yt/fields/geometric_fields.py
+++ b/yt/fields/geometric_fields.py
@@ -22,162 +22,224 @@
     ValidateSpatial
 
 from .field_functions import \
-     get_periodic_rvec, \
-     get_radius
+    get_periodic_rvec, \
+    get_radius
 
 from .field_plugin_registry import \
     register_field_plugin
 
 from yt.utilities.math_utils import \
-    get_sph_r_component, \
-    get_sph_theta_component, \
-    get_sph_phi_component, \
-    get_cyl_r_component, \
-    get_cyl_z_component, \
-    get_cyl_theta_component, \
     get_cyl_r, get_cyl_theta, \
     get_cyl_z, get_sph_r, \
-    get_sph_theta, get_sph_phi, \
-    periodic_dist, euclidean_dist
+    get_sph_theta, get_sph_phi
 
 @register_field_plugin
-def setup_geometric_fields(registry, ftype = "gas", slice_info = None):
+def setup_geometric_fields(registry, ftype="gas", slice_info=None):
 
     def _radius(field, data):
+        """The spherical radius component of the mesh cells.
+
+        Relative to the coordinate system defined by the *center* field
+        parameter.
+        """
         return get_radius(data, "")
 
-    registry.add_field(("index", "radius"), function=_radius,
-              validators=[ValidateParameter("center")],
-              units="cm")
+    registry.add_field(("index", "radius"),
+                       function=_radius,
+                       validators=[ValidateParameter("center")],
+                       units="cm")
 
     def _grid_level(field, data):
+        """The AMR refinement level"""
         return np.ones(data.ActiveDimensions)*(data.Level)
+
     registry.add_field(("index", "grid_level"),
-              function=_grid_level, units = "",
-              validators=[ValidateGridType(),
-                          ValidateSpatial(0)])
+                       function=_grid_level,
+                       units="",
+                       validators=[ValidateGridType(), ValidateSpatial(0)])
 
     def _grid_indices(field, data):
+        """The index of the leaf grid the mesh cells exist on"""
         return np.ones(data["index", "ones"].shape)*(data.id-data._id_offset)
+
     registry.add_field(("index", "grid_indices"),
-              function=_grid_indices, units = "",
-              validators=[ValidateGridType(),
-                          ValidateSpatial(0)], take_log=False)
+                       function=_grid_indices,
+                       units="",
+                       validators=[ValidateGridType(), ValidateSpatial(0)],
+                       take_log=False)
+
     def _ones_over_dx(field, data):
+        """The inverse of the local cell spacing"""
         return np.ones(data["index", "ones"].shape,
                        dtype="float64")/data["index", "dx"]
-    registry.add_field(("index", "ones_over_dx"), function=_ones_over_dx,
-              units = "1 / cm",
-              display_field=False)
+
+    registry.add_field(("index", "ones_over_dx"),
+                       function=_ones_over_dx,
+                       units="1 / cm",
+                       display_field=False)
 
     def _zeros(field, data):
+        """Returns zero for all cells"""
         arr = np.zeros(data["index", "ones"].shape, dtype='float64')
         return data.apply_units(arr, field.units)
 
-    registry.add_field(("index", "zeros"), function=_zeros,
-              units = "",
-              display_field=False)
+    registry.add_field(("index", "zeros"),
+                       function=_zeros,
+                       units="",
+                       display_field=False)
 
     def _ones(field, data):
+        """Returns one for all cells"""
         arr = np.ones(data.ires.shape, dtype="float64")
         if data._spatial:
             return data._reshape_vals(arr)
         return data.apply_units(arr, field.units)
 
-    registry.add_field(("index", "ones"), function=_ones,
-              units = "",
-              display_field=False)
+    registry.add_field(("index", "ones"),
+                       function=_ones,
+                       units="",
+                       display_field=False)
 
-    ### spherical coordinates: r (radius)
-    def _spherical_r(field, data):
+    def _spherical_radius(field, data):
+        """The spherical radius component of the positions of the mesh cells.
+
+        Relative to the coordinate system defined by the *center* field
+        parameter.
+        """
         coords = get_periodic_rvec(data)
         return data.ds.arr(get_sph_r(coords), "code_length").in_cgs()
 
+    registry.add_field(("index", "spherical_radius"),
+                       function=_spherical_radius,
+                       validators=[ValidateParameter("center")],
+                       units="cm")
+
+    def _spherical_r(field, data):
+        """This field is deprecated and will be removed in a future release"""
+        return data['index', 'spherical_radius']
+
     registry.add_field(("index", "spherical_r"),
-             function=_spherical_r,
-             validators=[ValidateParameter("center")],
-             units="cm")
+                       function=_spherical_r,
+                       validators=[ValidateParameter("center")],
+                       units="cm")
 
-    ### spherical coordinates: theta (angle with respect to normal)
     def _spherical_theta(field, data):
+        """The spherical theta component of the positions of the mesh cells.
+
+        theta is the poloidal position angle in the plane parallel to the
+        *normal* vector
+
+        Relative to the coordinate system defined by the *center* and *normal*
+        field parameters.
+        """
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
         return get_sph_theta(coords, normal)
 
     registry.add_field(("index", "spherical_theta"),
-             function=_spherical_theta,
-             validators=[ValidateParameter("center"),
-                         ValidateParameter("normal")])
+                       function=_spherical_theta,
+                       validators=[ValidateParameter("center"),
+                                   ValidateParameter("normal")],
+                       units='')
 
-    ### spherical coordinates: phi (angle in the plane perpendicular to the normal)
     def _spherical_phi(field, data):
+        """The spherical phi component of the positions of the mesh cells.
+
+        phi is the azimuthal position angle in the plane perpendicular to the
+        *normal* vector
+
+        Relative to the coordinate system defined by the *center* and *normal*
+        field parameters.
+        """
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
         return get_sph_phi(coords, normal)
 
     registry.add_field(("index", "spherical_phi"),
-             function=_spherical_phi,
-             validators=[ValidateParameter("center"),
-             ValidateParameter("normal")])
+                       function=_spherical_phi,
+                       validators=[ValidateParameter("center"),
+                                   ValidateParameter("normal")],
+                       units='')
 
-    ### cylindrical coordinates: R (radius in the cylinder's plane)
-    def _cylindrical_r(field, data):
+    def _cylindrical_radius(field, data):
+        """The cylindrical radius component of the positions of the mesh cells.
+
+        Relative to the coordinate system defined by the *normal* vector and
+        *center* field parameters.
+        """
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
         return data.ds.arr(get_cyl_r(coords, normal), "code_length").in_cgs()
 
+    registry.add_field(("index", "cylindrical_radius"),
+                       function=_cylindrical_radius,
+                       validators=[ValidateParameter("center"),
+                                   ValidateParameter("normal")],
+                       units="cm")
+
+    def _cylindrical_r(field, data):
+        """This field is deprecated and will be removed in a future release"""
+        return data['index', 'cylindrical_radius']
+
     registry.add_field(("index", "cylindrical_r"),
-             function=_cylindrical_r,
-             validators=[ValidateParameter("center"),
-                         ValidateParameter("normal")],
-             units="cm")
+                       function=_cylindrical_r,
+                       validators=[ValidateParameter("center")],
+                       units="cm")
 
-    ### cylindrical coordinates: z (height above the cylinder's plane)
     def _cylindrical_z(field, data):
+        """The cylindrical z component of the positions of the mesh cells.
+
+        Relative to the coordinate system defined by the *normal* vector and
+        *center* field parameters.
+        """
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
         return data.ds.arr(get_cyl_z(coords, normal), "code_length").in_cgs()
 
     registry.add_field(("index", "cylindrical_z"),
-             function=_cylindrical_z,
-             validators=[ValidateParameter("center"),
-                         ValidateParameter("normal")],
-             units="cm")
+                       function=_cylindrical_z,
+                       validators=[ValidateParameter("center"),
+                                   ValidateParameter("normal")],
+                       units="cm")
 
-    ### cylindrical coordinates: theta (angle in the cylinder's plane)
     def _cylindrical_theta(field, data):
+        """The cylindrical z component of the positions of the mesh cells.
+
+        theta is the azimuthal position angle in the plane perpendicular to the
+        *normal* vector.
+
+        Relative to the coordinate system defined by the *normal* vector and
+        *center* field parameters.
+        """
         normal = data.get_field_parameter("normal")
         coords = get_periodic_rvec(data)
         return get_cyl_theta(coords, normal)
 
     registry.add_field(("index", "cylindrical_theta"),
-             function=_cylindrical_theta,
-             validators=[ValidateParameter("center"),
-                         ValidateParameter("normal")],
-             units = "")
+                       function=_cylindrical_theta,
+                       validators=[ValidateParameter("center"),
+                                   ValidateParameter("normal")],
+                       units="")
 
-    ### The old field DiskAngle is the same as the spherical coordinates'
-    ### 'theta' angle. I'm keeping DiskAngle for backwards compatibility.
-    # @todo: remove in 3.0?
     def _disk_angle(field, data):
+        """This field is dprecated and will be removed in a future release"""
         return data["index", "spherical_theta"]
 
     registry.add_field(("index", "disk_angle"),
-              function=_disk_angle, take_log=False,
-              validators=[ValidateParameter("center"),
-                          ValidateParameter("normal")],
-              display_field=False,
-              units = "")
+                       function=_disk_angle,
+                       take_log=False,
+                       display_field=False,
+                       validators=[ValidateParameter("center"),
+                                   ValidateParameter("normal")],
+                       units="")
 
-    ### The old field Height is the same as the cylindrical coordinates' z
-    ### field. I'm keeping Height for backwards compatibility.
-    # @todo: remove in 3.0?
     def _height(field, data):
+        """This field is deprecated and will be removed in a future release"""
         return data["index", "cylindrical_z"]
 
-    registry.add_field(("index", "height"), function=_height, 
-             validators=[ValidateParameter("center"),
-                         ValidateParameter("normal")],
-             units="cm",
-             display_field=False)
-
+    registry.add_field(("index", "height"),
+                       function=_height,
+                       validators=[ValidateParameter("center"),
+                                   ValidateParameter("normal")],
+                       units="cm",
+                       display_field=False)

diff -r b7feb560aa19a08d480d85185fe7beeb6bb9e243 -r def04a2447592b5737a71a244df44fc45a9a5fc3 yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -21,10 +21,6 @@
 from yt.fields.derived_field import \
     ValidateParameter, \
     ValidateSpatial
-from yt.utilities.physical_constants import \
-    mass_hydrogen_cgs, \
-    mass_sun_cgs, \
-    mh
 
 from yt.units.yt_array import \
     uconcatenate
@@ -37,12 +33,16 @@
     get_cyl_z_component, \
     get_cyl_theta_component, \
     get_cyl_r, get_cyl_theta, \
-    get_cyl_z, get_sph_r, \
+    get_cyl_z, \
     get_sph_theta, get_sph_phi, \
-    periodic_dist, euclidean_dist
+    modify_reference_frame
 
 from .vector_operations import \
-     create_magnitude_field
+    create_magnitude_field
+     
+from .field_functions import \
+    get_radius
+
     
 def _field_concat(fname):
     def _AllFields(field, data):
@@ -95,7 +95,7 @@
              validators = [ValidateSpatial()],
              display_name = "\\mathrm{%s Mass}" % ptype_dn,
              units = "g")
-             
+
     def particle_density(field, data):
         pos = data[ptype, coord_name]
         mass = data[ptype, mass_name]
@@ -357,34 +357,233 @@
 
     create_magnitude_field(registry, "particle_angular_momentum",
                            "g*cm**2/s", ftype=ptype, particle_type=True)
-    
-    from .field_functions import \
-        get_radius
 
     def _particle_radius(field, data):
+        """The spherical radius component of the particle positions
+
+        Relative to the coordinate system defined by the *normal* vector,
+        and *center* field parameters.
+        """
         return get_radius(data, "particle_position_")
-    registry.add_field((ptype, "particle_radius"),
-              function=_particle_radius,
-              validators=[ValidateParameter("center")],
-              units="cm", particle_type = True,
-              display_name = "Particle Radius")
 
-    def _particle_spherical_position_radius(field, data):
+    registry.add_field(
+        (ptype, "particle_radius"),
+        function=_particle_radius,
+        units="cm",
+        particle_type=True,
+        validators=[ValidateParameter("center")])
+
+    def _particle_position_relative(field, data):
+        """The cartesian particle positions in a rotated reference frame
+
+        Relative to the coordinate system defined by the *normal* vector and
+        *center* field parameters.
+
+        Note that the orientation of the x and y axes are arbitrary.
         """
-        Radial component of the particles' position vectors in spherical coords
-        on the provided field parameters for 'normal', 'center', and 
-        'bulk_velocity', 
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        pos = pos.T
+        L, pos = modify_reference_frame(center, normal, P=pos)
+        return pos
+
+    registry.add_field(
+        (ptype, "particle_position_relative"),
+        function=_particle_position_relative,
+        particle_type=True,
+        units="cm",
+        validators=[ValidateParameter("normal"), ValidateParameter("center")])
+
+    def _particle_position_relative_x(field, data):
+        """The x component of the  particle positions in a rotated reference
+        frame
+
+        Relative to the coordinate system defined by the *normal* vector and
+        *center* field parameters.
+
+        Note that the orientation of the x and y axes are arbitrary.
+        """
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        pos = pos.T
+        L, pos, = modify_reference_frame(center, normal, P=pos)
+        pos = pos.T
+        return pos[0]
+
+    registry.add_field(
+        (ptype, "particle_position_relative_x"),
+        function=_particle_position_relative_x,
+        particle_type=True,
+        units="cm",
+        validators=[ValidateParameter("normal"), ValidateParameter("center")])
+
+    def _particle_position_relative_y(field, data):
+        """The y component of the  particle positions in a rotated reference
+        frame
+
+        Relative to the coordinate system defined by the *normal* vector and
+        *center* field parameters.
+
+        Note that the orientation of the x and y axes are arbitrary.
+        """
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        pos = pos.T
+        L, pos = modify_reference_frame(center, normal, P=pos)
+        pos = pos.T
+        return pos[1]
+
+    registry.add_field((ptype, "particle_position_relative_y"),
+              function=_particle_position_relative_y,
+              particle_type=True, units="cm",
+              validators=[ValidateParameter("normal"),
+                          ValidateParameter("center")])
+
+
+    def _particle_position_relative_z(field, data):
+        """The z component of the  particle positions in a rotated reference
+        frame
+
+        Relative to the coordinate system defined by the *normal* vector and
+        *center* field parameters.
+
+        Note that the orientation of the x and y axes are arbitrary.
+        """
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        pos = pos.T
+        L, pos = modify_reference_frame(center, normal, P=pos)
+        pos = pos.T
+        return pos[2]
+
+    registry.add_field((ptype, "particle_position_relative_z"),
+              function=_particle_position_relative_z,
+              particle_type=True, units="cm",
+              validators=[ValidateParameter("normal"),
+                          ValidateParameter("center")])
+
+    def _particle_velocity_relative(field, data):
+        """The vector particle velocities in an arbitrary coordinate system
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
+
+        Note that the orientation of the x and y axes are arbitrary.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
         bv = data.get_field_parameter("bulk_velocity")
-        pos = spos
-        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
-        theta = get_sph_theta(pos, center)
-        phi = get_sph_phi(pos, center)
-        pos = pos - np.reshape(center, (3, 1))
-        sphr = get_sph_r_component(pos, theta, phi, normal)
-        return sphr
+        vel = svel
+        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
+        vel = vel - np.reshape(bv, (3, 1))
+        vel = vel.T
+        L, vel = modify_reference_frame(center, normal, V=vel)
+        return vel
+
+    registry.add_field((ptype, "particle_velocity_relative"),
+              function=_particle_velocity_relative,
+              particle_type=True, units="cm/s",
+              validators=[ValidateParameter("normal"),
+                          ValidateParameter("center")])
+
+    def _particle_velocity_relative_x(field, data):
+        """The x component of the particle velocities in an arbitrary coordinate
+        system
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
+
+        Note that the orientation of the x and y axes are arbitrary.
+        """
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        bv = data.get_field_parameter("bulk_velocity")
+        vel = svel
+        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
+        vel = vel - np.reshape(bv, (3, 1))
+        vel = vel.T
+        L, vel = modify_reference_frame(center, normal, V=vel)
+        vel = vel.T
+        return vel[0]
+
+    registry.add_field((ptype, "particle_velocity_relative_x"),
+              function=_particle_velocity_relative_x,
+              particle_type=True, units="cm/s",
+              validators=[ValidateParameter("normal"),
+                          ValidateParameter("center")])
+
+    def _particle_velocity_relative_y(field, data):
+        """The y component of the particle velocities in an arbitrary coordinate
+        system
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
+
+        Note that the orientation of the x and y axes are arbitrary.
+        """
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        bv = data.get_field_parameter('bulk_velocity')
+        vel = svel
+        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
+        vel = vel - np.reshape(bv, (3, 1))
+        vel = vel.T
+        L, vel = modify_reference_frame(center, normal, V=vel)
+        vel = vel.T
+        return vel[1]
+
+    registry.add_field((ptype, "particle_velocity_relative_y"),
+              function=_particle_velocity_relative_y,
+              particle_type=True, units="cm/s",
+              validators=[ValidateParameter("normal"),
+                          ValidateParameter("center")])
+
+    def _particle_velocity_relative_z(field, data):
+        """The z component of the particle velocities in an arbitrary coordinate
+        system
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
+
+        Note that the orientation of the x and y axes are arbitrary.
+        """
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        bv = data.get_field_parameter("bulk_velocity")
+        vel = svel
+        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
+        bv = vel = np.reshape(bv, (3, 1))
+        vel = vel.T
+        L, vel = modify_reference_frame(center, normal, V=vel)
+        vel = vel.T
+        return vel[2]
+
+    registry.add_field((ptype, "particle_velocity_relative_z"),
+              function=_particle_velocity_relative_z,
+              particle_type=True, units="cm/s",
+              validators=[ValidateParameter("normal"),
+                          ValidateParameter("center")])
+
+    # this is just particle radius but we add it with an alias for the sake of
+    # consistent naming
+    registry.add_field((ptype, "particle_position_spherical_radius"),
+              function=_particle_radius,
+              particle_type=True, units="cm",
+              validators=[ValidateParameter("normal"),
+                          ValidateParameter("center")])
+
+    def _particle_spherical_position_radius(field, data):
+        """This field is deprecated and will be removed in a future release"""
+        return data[ptype, 'particle_position_spherical_radius']
 
     registry.add_field((ptype, "particle_spherical_position_radius"),
               function=_particle_spherical_position_radius,
@@ -392,22 +591,29 @@
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
-    def _particle_spherical_position_theta(field, data):
+    def _particle_position_spherical_theta(field, data):
+        """The spherical theta coordinate of the particle positions.
+
+        Relative to the coordinate system defined by the *normal* vector
+        and *center* field parameters.
         """
-        Theta component of the particles' position vectors in spherical coords
-        on the provided field parameters for 'normal', 'center', and 
-        'bulk_velocity', 
-        """
-        normal = data.get_field_parameter('normal')
-        center = data.get_field_parameter('center')
-        bv = data.get_field_parameter("bulk_velocity")
+        normal = data.get_field_parameter("normal")
+        center = data.get_field_parameter("center")
         pos = spos
         pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
-        theta = get_sph_theta(pos, center)
-        phi = get_sph_phi(pos, center)
         pos = pos - np.reshape(center, (3, 1))
-        spht = get_sph_theta_component(pos, theta, phi, normal)
-        return spht
+        return data.ds.arr(get_sph_theta(pos, normal), "")
+
+    registry.add_field(
+        (ptype, "particle_position_spherical_theta"),
+        function=_particle_position_spherical_theta,
+        particle_type=True,
+        units="",
+        validators=[ValidateParameter("center"), ValidateParameter("normal")])
+
+    def _particle_spherical_position_theta(field, data):
+        """This field is deprecated and will be removed in a future release"""
+        return data[ptype, 'particle_position_spherical_theta']
 
     registry.add_field((ptype, "particle_spherical_position_theta"),
               function=_particle_spherical_position_theta,
@@ -415,34 +621,42 @@
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
-    def _particle_spherical_position_phi(field, data):
+    def _particle_position_spherical_phi(field, data):
+        """The spherical phi component of the particle positions
+
+        Relative to the coordinate system defined by the *normal* vector
+        and *center* field parameters.
         """
-        Phi component of the particles' position vectors in spherical coords
-        on the provided field parameters for 'normal', 'center', and 
-        'bulk_velocity', 
-        """
-        normal = data.get_field_parameter('normal')
-        center = data.get_field_parameter('center')
-        bv = data.get_field_parameter("bulk_velocity")
+        normal = data.get_field_parameter("normal")
+        center = data.get_field_parameter("center")
         pos = spos
         pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
-        theta = get_sph_theta(pos, center)
-        phi = get_sph_phi(pos, center)
         pos = pos - np.reshape(center, (3, 1))
-        sphp = get_sph_phi_component(pos, phi, normal)
-        return sphp
+        return data.ds.arr(get_sph_phi(pos, normal), "")
+
+    registry.add_field(
+        (ptype, "particle_position_spherical_phi"),
+        function=_particle_position_spherical_phi,
+        particle_type=True,
+        units="",
+        validators=[ValidateParameter("normal"), ValidateParameter("center")])
+
+    def _particle_spherical_position_phi(field, data):
+        """This field is deprecated and will be removed in a future release"""
+        return data[ptype, 'particle_position_spherical_phi']
 
     registry.add_field((ptype, "particle_spherical_position_phi"),
-              function=_particle_spherical_position_phi,
-              particle_type=True, units="cm",
-              validators=[ValidateParameter("normal"), 
-                          ValidateParameter("center")])
+             function=_particle_spherical_position_phi,
+             particle_type=True, units="",
+             validators=[ValidateParameter("center"),
+                         ValidateParameter("normal")])
 
-    def _particle_spherical_velocity_radius(field, data):
-        """
-        Radial component of the particles' velocity vectors in spherical coords
-        based on the provided field parameters for 'normal', 'center', and 
-        'bulk_velocity', 
+    def _particle_velocity_spherical_radius(field, data):
+        """The spherical radius component of the particle velocities in an
+         arbitrary coordinate system
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
@@ -458,25 +672,36 @@
         sphr = get_sph_r_component(vel, theta, phi, normal)
         return sphr
 
+    registry.add_field((ptype, "particle_velocity_spherical_radius"),
+              function=_particle_velocity_spherical_radius,
+              particle_type=True, units="cm/s",
+              validators=[ValidateParameter("normal"), 
+                          ValidateParameter("center")])
+
+    def _particle_spherical_velocity_radius(field, data):
+        """This field is deprecated and will be removed in a future release"""
+        return data[ptype, 'particle_velocity_spherical_radius']
+
     registry.add_field((ptype, "particle_spherical_velocity_radius"),
               function=_particle_spherical_velocity_radius,
               particle_type=True, units="cm/s",
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
-    # This is simply aliased to "particle_spherical_velocity_radius"
-    # for ease of use.
+    # particel_velocity_spherical_radius is simply aliased to
+    # "particle_radial_velocity" for convenience
     registry.add_field((ptype, "particle_radial_velocity"),
               function=_particle_spherical_velocity_radius,
               particle_type=True, units="cm/s",
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
-    def _particle_spherical_velocity_theta(field, data):
-        """
-        Theta component of the particles' velocity vectors in spherical coords
-        based on the provided field parameters for 'normal', 'center', and 
-        'bulk_velocity', 
+    def _particle_velocity_spherical_theta(field, data):
+        """The spherical theta component of the particle velocities in an
+         arbitrary coordinate system
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
@@ -492,36 +717,214 @@
         spht = get_sph_theta_component(vel, theta, phi, normal)
         return spht
 
+    registry.add_field(
+        (ptype, "particle_velocity_spherical_theta"),
+        function=_particle_velocity_spherical_theta,
+        particle_type=True,
+        units="cm/s",
+        validators=[ValidateParameter("normal"), ValidateParameter("center")])
+
+    def _particle_spherical_velocity_theta(field, data):
+        """This field is deprecated and will be removed in a future release"""
+        return data[ptype, 'particle_velocity_spherical_theta']
+
     registry.add_field((ptype, "particle_spherical_velocity_theta"),
               function=_particle_spherical_velocity_theta,
               particle_type=True, units="cm/s",
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
-    def _particle_spherical_velocity_phi(field, data):
-        """
-        Phi component of the particles' velocity vectors in spherical coords
-        based on the provided field parameters for 'normal', 'center', and 
-        'bulk_velocity', 
+    def _particle_velocity_spherical_phi(field, data):
+        """The spherical phi component of the particle velocities
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
         """
         normal = data.get_field_parameter('normal')
         center = data.get_field_parameter('center')
         bv = data.get_field_parameter("bulk_velocity")
         pos = YTArray([data[ptype, spos % ax] for ax in "xyz"])
         vel = YTArray([data[ptype, svel % ax] for ax in "xyz"])
-        theta = get_sph_theta(pos, center)
         phi = get_sph_phi(pos, center)
         pos = pos - np.reshape(center, (3, 1))
         vel = vel - np.reshape(bv, (3, 1))
         sphp = get_sph_phi_component(vel, phi, normal)
         return sphp
 
+    registry.add_field(
+        (ptype, "particle_velocity_spherical_phi"),
+        function=_particle_velocity_spherical_phi,
+        particle_type=True,
+        units="cm/s",
+        validators=[ValidateParameter("normal"), ValidateParameter("center")])
+
+    def _particle_spherical_velocity_phi(field, data):
+        """This field is deprecated and will be removed in a future release"""
+        return data[ptype, 'particle_spherical_velocity_theta']
+
     registry.add_field((ptype, "particle_spherical_velocity_phi"),
               function=_particle_spherical_velocity_phi,
               particle_type=True, units="cm/s",
               validators=[ValidateParameter("normal"), 
                           ValidateParameter("center")])
 
+    def _particle_position_cylindrical_radius(field, data):
+        """The cylindrical radius component of the particle positions
+
+        Relative to the coordinate system defined by the *normal* vector
+        and *center* field parameters.
+        """
+        normal = data.get_field_parameter("normal")
+        center = data.get_field_parameter('center')
+        pos = YTArray([data[ptype, spos % ax] for ax in "xyz"])
+        pos = pos - np.reshape(center, (3, 1))
+        return data.ds.arr(get_cyl_r(pos, normal),
+                           'code_length')
+
+    registry.add_field(
+        (ptype, "particle_position_cylindrical_radius"),
+        function=_particle_position_cylindrical_radius,
+        units="cm",
+        particle_type=True,
+        validators=[ValidateParameter("normal"), ValidateParameter("center")])
+
+    def _particle_position_cylindrical_theta(field,data):
+        """The cylindrical theta component of the particle positions
+
+        Relative to the coordinate system defined by the *normal* vector
+        and *center* field parameters.
+        """
+        normal = data.get_field_parameter("normal")
+        center = data.get_field_parameter('center')
+        pos = YTArray([data[ptype, spos % ax] for ax in "xyz"])
+        pos = pos - np.reshape(center, (3, 1))
+        return data.ds.arr(get_cyl_theta(pos, normal), "")
+
+    registry.add_field(
+        (ptype, "particle_position_cylindrical_theta"),
+        function=_particle_position_cylindrical_theta,
+        particle_type=True,
+        units="",
+        validators=[ValidateParameter("center"), ValidateParameter("normal")])
+
+    def _particle_position_cylindrical_z(field,data):
+        """The cylindrical z component of the particle positions
+
+        Relative to the coordinate system defined by the *normal* vector
+        and *center* field parameters.
+        """
+        normal = data.get_field_parameter("normal")
+        center = data.get_field_parameter('center')
+        pos = YTArray([data[ptype, spos % ax] for ax in "xyz"])
+        pos = pos - np.reshape(center, (3, 1))
+        return data.ds.arr(get_cyl_z(pos, normal),
+                           'code_length')
+
+    registry.add_field(
+        (ptype, "particle_position_cylindrical_z"),
+        function=_particle_position_cylindrical_z,
+        units="cm",
+        particle_type=True,
+        validators=[ValidateParameter("normal"), ValidateParameter("center")])
+
+    def _particle_velocity_cylindrical_radius(field, data):
+        """The cylindrical radius component of the particle velocities
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
+        """
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        bv = data.get_field_parameter("bulk_velocity")
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        vel = svel
+        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
+        theta = get_cyl_theta(pos, center)
+        pos = pos - np.reshape(center, (3, 1))
+        vel = vel - np.reshape(bv, (3, 1))
+        cylr = get_cyl_r_component(vel, theta, normal)
+        return cylr
+
+    registry.add_field(
+        (ptype, "particle_velocity_cylindrical_radius"),
+        function=_particle_velocity_spherical_radius,
+        particle_type=True,
+        units="cm/s",
+        validators=[ValidateParameter("normal"), ValidateParameter("center")])
+
+    def _particle_velocity_cylindrical_theta(field, data):
+        """The cylindrical theta component of the particle velocities
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
+        """
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        bv = data.get_field_parameter("bulk_velocity")
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        vel = svel
+        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
+        theta = get_cyl_theta(pos, center)
+        pos = pos - np.reshape(center, (3, 1))
+        vel = vel - np.reshape(bv, (3, 1))
+        cylt = get_cyl_theta_component(vel, theta, normal)
+        return cylt
+
+    registry.add_field(
+        (ptype, "particle_velocity_cylindrical_theta"),
+        function=_particle_velocity_cylindrical_theta,
+        particle_type=True,
+        units="cm/s",
+        validators=[ValidateParameter("normal"), ValidateParameter("center")])
+
+    def _particle_cylindrical_velocity_theta(field, data):
+        """This field is deprecated and will be removed in a future release"""
+        return data[ptype, 'particle_velocity_cylindrical_theta']
+
+    registry.add_field((ptype, "particle_cylindrical_velocity_theta"),
+              function=_particle_cylindrical_velocity_theta,
+              particle_type=True, units="cm/s",
+              validators=[ValidateParameter("normal"), 
+                          ValidateParameter("center")])
+
+    def _particle_velocity_cylindrical_z(field, data):
+        """The cylindrical z component of the particle velocities
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *bulk_velocity* vector and *center* field parameters.
+        """
+        normal = data.get_field_parameter('normal')
+        center = data.get_field_parameter('center')
+        bv = data.get_field_parameter("bulk_velocity")
+        pos = spos
+        pos = YTArray([data[ptype, pos % ax] for ax in "xyz"])
+        vel = svel
+        vel = YTArray([data[ptype, vel % ax] for ax in "xyz"])
+        pos = pos - np.reshape(center, (3, 1))
+        vel = vel - np.reshape(bv, (3, 1))
+        cylz = get_cyl_z_component(vel, normal)
+        return cylz
+
+    registry.add_field(
+        (ptype, "particle_velocity_cylindrical_z"),
+        function=_particle_velocity_cylindrical_z,
+        particle_type=True,
+        units="cm/s",
+        validators=[ValidateParameter("normal"), ValidateParameter("center")])
+
+    def _particle_cylindrical_velocity_z(field, data):
+        """This field is deprecated and will be removed in a future release"""
+        return data[ptype, "particle_velocity_cylindrical_z"]
+
+    registry.add_field((ptype, "particle_cylindrical_velocity_z"),
+              function=_particle_cylindrical_velocity_z,
+              particle_type=True, units="cm/s",
+              validators=[ValidateParameter("normal"), 
+                          ValidateParameter("center")])
+
+
 def add_particle_average(registry, ptype, field_name, 
                          weight = "particle_mass",
                          density = True):

diff -r b7feb560aa19a08d480d85185fe7beeb6bb9e243 -r def04a2447592b5737a71a244df44fc45a9a5fc3 yt/fields/vector_operations.py
--- a/yt/fields/vector_operations.py
+++ b/yt/fields/vector_operations.py
@@ -13,15 +13,10 @@
 
 import numpy as np
 
-from yt.units.yt_array import YTArray
-
 from .derived_field import \
     ValidateParameter, \
     ValidateSpatial
 
-from .field_plugin_registry import \
-    register_field_plugin
-
 from yt.utilities.math_utils import \
     get_sph_r_component, \
     get_sph_theta_component, \
@@ -29,19 +24,15 @@
     get_cyl_r_component, \
     get_cyl_z_component, \
     get_cyl_theta_component, \
-    get_cyl_r, get_cyl_theta, \
-    get_cyl_z, get_sph_r, \
-    get_sph_theta, get_sph_phi, \
-    periodic_dist, euclidean_dist, \
     resize_vector
 
 from yt.funcs import just_one
 
-from yt.utilities.lib.misc_utilities import obtain_rvec, obtain_rv_vec
+from yt.utilities.lib.misc_utilities import obtain_rv_vec
 
 def create_magnitude_field(registry, basename, field_units,
-                           ftype = "gas", slice_info = None,
-                           validators = None, particle_type=False):
+                           ftype="gas", slice_info=None,
+                           validators=None, particle_type=False):
 
     field_components = [(ftype, "%s_%s" % (basename, ax)) for ax in 'xyz']
 
@@ -54,29 +45,29 @@
         return np.sqrt(mag)
 
     registry.add_field((ftype, "%s_magnitude" % basename),
-                       function = _magnitude, units = field_units,
-                       validators = validators, particle_type = particle_type)
+                       function=_magnitude, units=field_units,
+                       validators=validators, particle_type=particle_type)
 
 def create_squared_field(registry, basename, field_units,
-                         ftype = "gas", slice_info = None,
-                         validators = None, particle_type=False):
+                         ftype="gas", slice_info=None,
+                         validators=None, particle_type=False):
 
     field_components = [(ftype, "%s_%s" % (basename, ax)) for ax in 'xyz']
 
     def _squared(field, data):
         fn = field_components[0]
-        squared  = data[fn] * data[fn]
+        squared = data[fn] * data[fn]
         for idim in range(1, registry.ds.dimensionality):
             fn = field_components[idim]
             squared += data[fn] * data[fn]
         return squared
 
     registry.add_field((ftype, "%s_squared" % basename),
-                       function = _squared, units = field_units,
-                       validators = validators, particle_type = particle_type)
+                       function=_squared, units=field_units,
+                       validators=validators, particle_type=particle_type)
 
 def create_vector_fields(registry, basename, field_units,
-                         ftype = "gas", slice_info = None):
+                         ftype="gas", slice_info=None):
     # slice_info would be the left, the right, and the factor.
     # For example, with the old Enzo-ZEUS fields, this would be:
     # slice(None, -2, None)
@@ -89,7 +80,6 @@
         div_fac = 2.0
     else:
         sl_left, sl_right, div_fac = slice_info
-    sl_center = slice(1, -1, None)
 
     xn, yn, zn = [(ftype, "%s_%s" % (basename, ax)) for ax in 'xyz']
 
@@ -101,50 +91,113 @@
 
     create_magnitude_field(registry, basename, field_units,
                            ftype=ftype, slice_info=slice_info)
-        
-    def _radial(field, data):
+
+    def _spherical_radius_component(field, data):
+        """The spherical radius component of the vector field
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *center*, and *bulk_* field parameters.
+        """
         normal = data.get_field_parameter("normal")
         vectors = obtain_rv_vec(data, (xn, yn, zn),
                                 "bulk_%s" % basename)
         theta = data['index', 'spherical_theta']
-        phi   = data['index', 'spherical_phi']
+        phi = data['index', 'spherical_phi']
         rv = get_sph_r_component(vectors, theta, phi, normal)
         # Now, anywhere that radius is in fact zero, we want to zero out our
         # return values.
         rv[np.isnan(theta)] = 0.0
         return rv
+
+    registry.add_field((ftype, "%s_spherical_radius" % basename),
+                       function=_spherical_radius_component,
+                       units=field_units,
+                       validators=[ValidateParameter("normal"),
+                                   ValidateParameter("center"),
+                                   ValidateParameter("bulk_%s" % basename)])
+
+    def _radial(field, data):
+        return data[ftype, "%s_spherical_radius" % basename]
+
     def _radial_absolute(field, data):
-        return np.abs(data[ftype, "radial_%s" % basename])
+        return np.abs(data[ftype, "%s_spherical_radius" % basename])
 
     def _tangential(field, data):
-        return np.sqrt(data[ftype, "%s_magnitude" % basename]**2.0
-                     - data[ftype, "radial_%s" % basename]**2.0)
+        return np.sqrt(data[ftype, "%s_magnitude" % basename]**2.0 -
+                       data[ftype, "%s_spherical_radius" % basename]**2.0)
 
     registry.add_field((ftype, "radial_%s" % basename),
-                       function = _radial, units = field_units,
+                       function=_radial,
+                       units=field_units,
                        validators=[ValidateParameter("normal"),
                                    ValidateParameter("center")])
+
     registry.add_field((ftype, "radial_%s_absolute" % basename),
-                       function = _radial_absolute, units = field_units)
+                       function=_radial_absolute,
+                       units=field_units)
+
     registry.add_field((ftype, "tangential_%s" % basename),
-                       function=_tangential, units = field_units)
+                       function=_tangential,
+                       units=field_units)
+
+    def _spherical_theta_component(field, data):
+        """The spherical theta component of the vector field
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *center*, and *bulk_* field parameters.
+        """
+        normal = data.get_field_parameter("normal")
+        vectors = obtain_rv_vec(data, (xn, yn, zn),
+                                "bulk_%s" % basename)
+        theta = resize_vector(data["index", "spherical_theta"], vectors)
+        phi = resize_vector(data["index", "spherical_phi"], vectors)
+        return get_sph_theta_component(vectors, theta, phi, normal)
+
+    registry.add_field((ftype, "%s_spherical_theta" % basename),
+                       function=_spherical_theta_component,
+                       units=field_units,
+                       validators=[ValidateParameter("normal"),
+                                   ValidateParameter("center"),
+                                   ValidateParameter("bulk_%s" % basename)])
+
+    def _spherical_phi_component(field, data):
+        """The spherical phi component of the vector field
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *center*, and *bulk_* field parameters.
+        """
+        normal = data.get_field_parameter("normal")
+        vectors = obtain_rv_vec(data, (xn, yn, zn),
+                                "bulk_%s" % basename)
+        phi = resize_vector(data["index", "spherical_phi"], vectors)
+        return get_sph_phi_component(vectors, phi, normal)
+
+    registry.add_field((ftype, "%s_spherical_phi" % basename),
+                       function=_spherical_phi_component,
+                       units=field_units,
+                       validators=[ValidateParameter("normal"),
+                                   ValidateParameter("center"),
+                                   ValidateParameter("bulk_%s" % basename)])
 
     def _cp_vectors(ax):
         def _cp_val(field, data):
             vec = data.get_field_parameter("cp_%s_vec" % (ax))
             bv = data.get_field_parameter("bulk_%s" % basename)
-            if bv == None: bv = np.zeros(3)
+            if bv is None: bv = np.zeros(3)
             tr  = (data[xn] - bv[0]) * vec[0]
             tr += (data[yn] - bv[1]) * vec[1]
             tr += (data[zn] - bv[2]) * vec[2]
             return tr
         return _cp_val
     registry.add_field((ftype, "cutting_plane_%s_x" % basename),
-                       function = _cp_vectors('x'), units = field_units)
+                       function=_cp_vectors('x'),
+                       units=field_units)
     registry.add_field((ftype, "cutting_plane_%s_y" % basename),
-                       function = _cp_vectors('y'), units = field_units)
+                       function=_cp_vectors('y'),
+                       units=field_units)
     registry.add_field((ftype, "cutting_plane_%s_z" % basename),
-                       function = _cp_vectors('z'), units = field_units)
+                       function=_cp_vectors('z'),
+                       units=field_units)
 
     def _divergence(field, data):
         ds = div_fac * just_one(data["index", "dx"])
@@ -160,14 +213,18 @@
                                 f.units)        
         new_field[1:-1,1:-1,1:-1] = f
         return new_field
+
     def _divergence_abs(field, data):
         return np.abs(data[ftype, "%s_divergence" % basename])
 
     registry.add_field((ftype, "%s_divergence" % basename),
-                       function = _divergence, units = "1/s",
-                       validators = [ValidateSpatial(1)])
+                       function=_divergence,
+                       units="1/s",
+                       validators=[ValidateSpatial(1)])
+    
     registry.add_field((ftype, "%s_divergence_absolute" % basename),
-                       function = _divergence_abs, units = "1/s")
+                       function=_divergence_abs,
+                       units="1/s")
 
     def _tangential_over_magnitude(field, data):
         tr = data[ftype, "tangential_%s" % basename] / \
@@ -177,26 +234,46 @@
              function=_tangential_over_magnitude,
              take_log=False)
 
-    def _cylindrical_radial(field, data):
+    def _cylindrical_radius_component(field, data):
+        """The cylindrical radius component of the vector field
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *center*, and *bulk_* field parameters.
+        """
         normal = data.get_field_parameter("normal")
         vectors = obtain_rv_vec(data, (xn, yn, zn),
                                 "bulk_%s" % basename)
         theta = resize_vector(data["index", 'cylindrical_theta'], vectors)
         return get_cyl_r_component(vectors, theta, normal)
 
-    def _cylindrical_radial_absolute(field, data):
-        return np.abs(_cylindrical_radial(field, data))
+    registry.add_field((ftype, "%s_cylindrical_radius" % basename),
+                       function=_cylindrical_radius_component,
+                       units=field_units,
+                       validators=[ValidateParameter("normal")])
+
+    def _cylindrical_radial(field, data):
+        """This field is deprecated and will be removed in a future version"""
+        return data[ftype, '%s_cylindrical_radius' % basename]
 
     registry.add_field((ftype, "cylindrical_radial_%s" % basename),
-             function=_cylindrical_radial,
-             units=field_units,
-             validators=[ValidateParameter("normal")])
+                       function=_cylindrical_radial,
+                       units=field_units)
+
+    def _cylindrical_radial_absolute(field, data):
+        """This field is deprecated and will be removed in a future version"""
+        return np.abs(data[ftype, '%s_cylindrical_radius' % basename])
+
     registry.add_field((ftype, "cylindrical_radial_%s_absolute" % basename),
-             function=_cylindrical_radial_absolute,
-             units=field_units,
-             validators=[ValidateParameter("normal")])
+                       function=_cylindrical_radial_absolute,
+                       units=field_units,
+                       validators=[ValidateParameter("normal")])
 
-    def _cylindrical_tangential(field, data):
+    def _cylindrical_theta_component(field, data):
+        """The cylindrical theta component of the vector field
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *center*, and *bulk_* field parameters.
+        """
         normal = data.get_field_parameter("normal")
         vectors = obtain_rv_vec(data, (xn, yn, zn),
                                 "bulk_%s" % basename)
@@ -204,24 +281,49 @@
         theta = np.tile(theta, (3,) + (1,)*len(theta.shape))
         return get_cyl_theta_component(vectors, theta, normal)
 
+    registry.add_field((ftype, "%s_cylindrical_theta" % basename),
+                       function=_cylindrical_theta_component,
+                       units=field_units,
+                       validators=[ValidateParameter("normal"),
+                                   ValidateParameter("center"),
+                                   ValidateParameter("bulk_%s" % basename)])
+
+    def _cylindrical_tangential(field, data):
+        """This field is deprecated and will be removed in a future release"""
+        return data["%s_cylindrical_theta" % basename]
+
     def _cylindrical_tangential_absolute(field, data):
-        return np.abs(_cylindrical_tangential(field, data))
+        """This field is deprecated and will be removed in a future release"""
+        return np.abs(data['cylindrical_tangential_%s' % basename])
 
-    registry.add_field(
-             (ftype, "cylindrical_tangential_%s" % basename),
-             function=_cylindrical_tangential,
-             units=field_units,
-             validators=[ValidateParameter("normal")])
-    registry.add_field(
-             (ftype, "cylindrical_tangential_%s_absolute" % basename),
-             function=_cylindrical_tangential_absolute,
-             units=field_units,
-             validators=[ValidateParameter("normal")])
+    registry.add_field((ftype, "cylindrical_tangential_%s" % basename),
+                       function=_cylindrical_tangential,
+                       units=field_units)
 
-def create_averaged_field(registry, basename, field_units,
-                          ftype = "gas", slice_info = None,
-                          validators = None,
-                          weight = "cell_mass"):
+    registry.add_field((ftype, "cylindrical_tangential_%s_absolute" % basename),
+                       function=_cylindrical_tangential_absolute,
+                       units=field_units)
+
+    def _cylindrical_z_component(field, data):
+        """The cylindrical z component of the vector field
+
+        Relative to the coordinate system defined by the *normal* vector,
+        *center*, and *bulk_* field parameters.
+        """
+        normal = data.get_field_parameter("normal")
+        vectors = obtain_rv_vec(data, (xn, yn, zn), "bulk_%s" % basename)
+        return get_cyl_z_component(vectors, normal)
+
+    registry.add_field((ftype, "%s_cylindrical_z" % basename),
+                       function=_cylindrical_z_component,
+                       units=field_units,
+                       validators=[ValidateParameter("normal"),
+                                   ValidateParameter("center"),
+                                   ValidateParameter("bulk_%s" % basename)])
+
+
+def create_averaged_field(registry, basename, field_units, ftype="gas",
+                          slice_info=None, validators=None, weight="cell_mass"):
 
     if validators is None:
         validators = []
@@ -232,14 +334,14 @@
         new_field = data.ds.arr(np.zeros((nx-2, ny-2, nz-2), dtype=np.float64),
                                 (just_one(data[(ftype, basename)]) *
                                  just_one(data[(ftype, weight)])).units)
-        weight_field = data.ds.arr(np.zeros((nx-2, ny-2, nz-2), dtype=np.float64),
+        weight_field = data.ds.arr(np.zeros((nx-2, ny-2, nz-2),
+                                            dtype=np.float64),
                                    data[(ftype, weight)].units)
         i_i, j_i, k_i = np.mgrid[0:3, 0:3, 0:3]
 
         for i, j, k in zip(i_i.ravel(), j_i.ravel(), k_i.ravel()):
             sl = [slice(i, nx-(2-i)), slice(j, ny-(2-j)), slice(k, nz-(2-k))]
-            new_field += data[(ftype, basename)][sl] * \
-              data[(ftype, weight)][sl]
+            new_field += data[(ftype, basename)][sl] * data[(ftype, weight)][sl]
             weight_field += data[(ftype, weight)][sl]
 
         # Now some fancy footwork

diff -r b7feb560aa19a08d480d85185fe7beeb6bb9e243 -r def04a2447592b5737a71a244df44fc45a9a5fc3 yt/utilities/math_utils.py
--- a/yt/utilities/math_utils.py
+++ b/yt/utilities/math_utils.py
@@ -238,7 +238,7 @@
         return np.dot(R, a.T).T
     
 
-def modify_reference_frame(CoM, L, P, V):
+def modify_reference_frame(CoM, L, P=None, V=None):
     r"""Rotates and translates data into a new reference frame to make
     calculations easier.
     
@@ -258,10 +258,13 @@
     L : array
         The angular momentum vector.
     
+    Optional
+    --------
+        
     P : array
         The positions of the data to be modified (i.e. particle or grid cell
         postions). The array should be Nx3.
-    
+
     V : array
         The velocities of the data to be modified (i.e. particle or grid cell
         velocities). The array should be Nx3.
@@ -272,10 +275,10 @@
         The angular momentum vector equal to [0, 0, 1] modulo machine error.
     
     P : array
-        The modified positional data.
+        The modified positional data. Only returned if P is not None
     
     V : array
-        The modified velocity data.
+        The modified velocity data. Only returned if V is not None
     
     Examples
     --------
@@ -300,9 +303,15 @@
     """
     if (L == np.array([0, 0, 1.])).all():
         # Whew! Nothing to do!
-        return L, P, V
+        if V is None:
+            return L, P
+        if P is None:
+            return L, V
+        else:
+            return L, P, V
     # First translate the positions to center of mass reference frame.
-    P = P - CoM
+    if P is not None:
+        P = P - CoM
     # Now find the angle between modified L and the x-axis.
     LL = L.copy()
     LL[2] = 0.
@@ -311,16 +320,25 @@
         theta = -theta
     # Now rotate all the position, velocity, and L vectors by this much around
     # the z axis.
-    P = rotate_vector_3D(P, 2, theta)
-    V = rotate_vector_3D(V, 2, theta)
+    if P is not None:
+        P = rotate_vector_3D(P, 2, theta)
+    if V is not None:
+        V = rotate_vector_3D(V, 2, theta)
     L = rotate_vector_3D(L, 2, theta)
     # Now find the angle between L and the z-axis.
     theta = np.arccos(np.inner(L, [0,0,1])/np.inner(L,L)**.5)
     # This time we rotate around the y axis.
-    P = rotate_vector_3D(P, 1, theta)
-    V = rotate_vector_3D(V, 1, theta)
+    if P is not None:
+        P = rotate_vector_3D(P, 1, theta)
+    if V is not None:
+        V = rotate_vector_3D(V, 1, theta)
     L = rotate_vector_3D(L, 1, theta)
-    return L, P, V
+    if V is None:
+        return L, P
+    if P is None:
+        return L, V
+    else:
+        return L, P, V
 
 def compute_rotational_velocity(CoM, L, P, V):
     r"""Computes the rotational velocity for some data around an axis.

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