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

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Sat May 11 08:13:25 PDT 2013


28 new commits in yt:

https://bitbucket.org/yt_analysis/yt/commits/3b0ab6c3816b/
Changeset:   3b0ab6c3816b
Branch:      yt
User:        jzuhone
Date:        2012-12-11 17:18:50
Summary:     Merging
Affected #:  1 file

diff -r 380f62e5f4f2cd4cfa2627dfd988bebf253af05b -r 3b0ab6c3816b7a73f38528859acc85fdbbe97980 yt/frontends/athena/fields.py
--- a/yt/frontends/athena/fields.py
+++ b/yt/frontends/athena/fields.py
@@ -43,11 +43,7 @@
 
 log_translation_dict = {}
 
-translation_dict = {"Density": "density",
-                    "Pressure": "pressure",
-                    "x-velocity": "velocity_x",
-                    "y-velocity": "velocity_y",
-                    "z-velocity": "velocity_z"}
+translation_dict = {"Density": "density"}
 
 AthenaFieldInfo = FieldInfoContainer.create_with_fallback(FieldInfo)
 add_field = AthenaFieldInfo.add_field
@@ -56,29 +52,37 @@
 add_athena_field = KnownAthenaFields.add_field
 
 add_athena_field("density", function=NullFunc, take_log=False,
-          units=r"",
-          projected_units =r"")
+                 units=r"", projected_units =r"")
 
 add_athena_field("pressure", function=NullFunc, take_log=False,
-          units=r"")
+                 units=r"")
 
 add_athena_field("velocity_x", function=NullFunc, take_log=False,
-          units=r"")
+                 units=r"")
 
 add_athena_field("velocity_y", function=NullFunc, take_log=False,
-          units=r"")
+                 units=r"")
 
 add_athena_field("velocity_z", function=NullFunc, take_log=False,
-          units=r"")
+                 units=r"")
+
+add_athena_field("momentum_x", function=NullFunc, take_log=False,
+                 units=r"")
+
+add_athena_field("momentum_y", function=NullFunc, take_log=False,
+                 units=r"")
+
+add_athena_field("momentum_z", function=NullFunc, take_log=False,
+                 units=r"")
 
 add_athena_field("cell_centered_B_x", function=NullFunc, take_log=False,
-          units=r"", display_name=r"$\rm{cell\ centered\ B_x}$")
+                 units=r"", display_name=r"$\rm{cell\ centered\ B_x}$")
 
 add_athena_field("cell_centered_B_y", function=NullFunc, take_log=False,
-          units=r"", display_name=r"$\rm{cell\ centered\ B_y}$")
+                 units=r"", display_name=r"$\rm{cell\ centered\ B_y}$")
 
 add_athena_field("cell_centered_B_z", function=NullFunc, take_log=False,
-          units=r"", display_name=r"$\rm{cell\ centered\ B_z}$")
+                 units=r"", display_name=r"$\rm{cell\ centered\ B_z}$")
 
 for f,v in log_translation_dict.items():
     add_field(f, TranslationFunc(v), take_log=True)
@@ -86,7 +90,39 @@
 for f,v in translation_dict.items():
     add_field(f, TranslationFunc(v), take_log=False)
 
-def _Temperature(fields, data):
+# In Athena, conservative or primitive variables may be written out.
+# By default, yt concerns itself with primitive variables. The following
+# field definitions allow for conversions to primitive variables in the
+# case that the file contains the conservative ones.
+
+def _xvelocity(field, data) :
+    try:
+        xvel = data["velocity_x"]
+    except:
+        xvel = data["momentum_x"]/data["Density"]
+    return xvel
+add_field("x-velocity", function=_xvelocity, take_log=False,
+          units=r"")
+
+def _yvelocity(field, data) :
+    try:
+        yvel = data["velocity_y"]
+    except:
+        yvel = data["momentum_y"]/data["Density"]
+    return yvel
+add_field("y-velocity", function=_yvelocity, take_log=False,
+          units=r"")
+
+def _zvelocity(field, data) :
+    try:
+        zvel = data["velocity_z"]
+    except:
+        zvel = data["momentum_z"]/data["Density"]
+    return zvel
+add_field("z-velocity", function=_zvelocity, take_log=False,
+          units=r"")
+
+def _Temperature(field, data):
     if data.has_field_parameter("mu") :
         mu = data.get_field_parameter("mu")
     else:
@@ -95,19 +131,19 @@
 add_field("Temperature", function=_Temperature, take_log=False,
           units=r"\rm{K}")
 
-def _Bx(fields, data):
+def _Bx(field, data):
     factor = np.sqrt(4.*np.pi)
     return data['cell_centered_B_x']*factor
 add_field("Bx", function=_Bx, take_log=False,
           units=r"\rm{Gauss}", display_name=r"B_x")
 
-def _By(fields, data):
+def _By(field, data):
     factor = np.sqrt(4.*np.pi)
     return data['cell_centered_B_y']*factor
 add_field("By", function=_By, take_log=False,
           units=r"\rm{Gauss}", display_name=r"B_y")
 
-def _Bz(fields, data):
+def _Bz(field, data):
     factor = np.sqrt(4.*np.pi)
     return data['cell_centered_B_z']*factor
 add_field("Bz", function=_Bz, take_log=False,


https://bitbucket.org/yt_analysis/yt/commits/18607c558f38/
Changeset:   18607c558f38
Branch:      yt
User:        jzuhone
Date:        2012-12-11 17:23:39
Summary:     Merging
Affected #:  2 files

diff -r 3b0ab6c3816b7a73f38528859acc85fdbbe97980 -r 18607c558f38ff5486530de13fe216c07426cc30 yt/utilities/particle_generator.py
--- a/yt/utilities/particle_generator.py
+++ b/yt/utilities/particle_generator.py
@@ -330,7 +330,8 @@
         ParticleGenerator.__init__(self, pf, num_particles, field_list)
 
         num_cells = len(data_source["x"].flat)
-        max_density = data_source[density_field].max()
+        max_mass = (data_source[density_field]*
+                    data_source["CellVolume"]).max()
         num_particles_left = num_particles
         all_x = []
         all_y = []
@@ -341,12 +342,13 @@
         
         while num_particles_left > 0:
 
-            rho = np.random.uniform(high=1.01*max_density,
-                                    size=num_particles_left)
+            m = np.random.uniform(high=1.01*max_mass,
+                                  size=num_particles_left)
             idxs = np.random.random_integers(low=0, high=num_cells-1,
                                              size=num_particles_left)
-            rho_true = data_source[density_field].flat[idxs]
-            accept = rho <= rho_true
+            m_true = (data_source[density_field]*
+                      data_source["CellVolume"]).flat[idxs]
+            accept = m <= m_true
             num_accepted = accept.sum()
             accepted_idxs = idxs[accept]
             

diff -r 3b0ab6c3816b7a73f38528859acc85fdbbe97980 -r 18607c558f38ff5486530de13fe216c07426cc30 yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -1059,7 +1059,7 @@
         (bounds, center, units) = GetWindowParameters(axis, center, width, pf)
         if axes_unit is None and units != ('1', '1'):
             axes_unit = units
-        slc = pf.h.slice(axis, center[axis], fields=fields)
+        slc = pf.h.slice(axis, center[axis], center=center, fields=fields)
         PWViewerMPL.__init__(self, slc, bounds, origin=origin)
         self.set_axes_unit(axes_unit)
 


https://bitbucket.org/yt_analysis/yt/commits/bea5473873e8/
Changeset:   bea5473873e8
Branch:      yt
User:        jzuhone
Date:        2012-12-20 23:27:17
Summary:     Merging
Affected #:  23 files

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 distribute_setup.py
--- a/distribute_setup.py
+++ b/distribute_setup.py
@@ -14,11 +14,14 @@
 This file can also be run as a script to install or upgrade setuptools.
 """
 import os
+import shutil
 import sys
 import time
 import fnmatch
 import tempfile
 import tarfile
+import optparse
+
 from distutils import log
 
 try:
@@ -46,7 +49,7 @@
             args = [quote(arg) for arg in args]
         return os.spawnl(os.P_WAIT, sys.executable, *args) == 0
 
-DEFAULT_VERSION = "0.6.21"
+DEFAULT_VERSION = "0.6.32"
 DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/"
 SETUPTOOLS_FAKED_VERSION = "0.6c11"
 
@@ -63,7 +66,7 @@
 """ % SETUPTOOLS_FAKED_VERSION
 
 
-def _install(tarball):
+def _install(tarball, install_args=()):
     # extracting the tarball
     tmpdir = tempfile.mkdtemp()
     log.warn('Extracting in %s', tmpdir)
@@ -81,11 +84,14 @@
 
         # installing
         log.warn('Installing Distribute')
-        if not _python_cmd('setup.py', 'install'):
+        if not _python_cmd('setup.py', 'install', *install_args):
             log.warn('Something went wrong during the installation.')
             log.warn('See the error message above.')
+            # exitcode will be 2
+            return 2
     finally:
         os.chdir(old_wd)
+        shutil.rmtree(tmpdir)
 
 
 def _build_egg(egg, tarball, to_dir):
@@ -110,6 +116,7 @@
 
     finally:
         os.chdir(old_wd)
+        shutil.rmtree(tmpdir)
     # returning the result
     log.warn(egg)
     if not os.path.exists(egg):
@@ -144,7 +151,7 @@
         except ImportError:
             return _do_download(version, download_base, to_dir, download_delay)
         try:
-            pkg_resources.require("distribute>="+version)
+            pkg_resources.require("distribute>=" + version)
             return
         except pkg_resources.VersionConflict:
             e = sys.exc_info()[1]
@@ -167,6 +174,7 @@
         if not no_fake:
             _create_fake_setuptools_pkg_info(to_dir)
 
+
 def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
                         to_dir=os.curdir, delay=15):
     """Download distribute from a specified location and return its filename
@@ -203,6 +211,7 @@
                 dst.close()
     return os.path.realpath(saveto)
 
+
 def _no_sandbox(function):
     def __no_sandbox(*args, **kw):
         try:
@@ -227,6 +236,7 @@
 
     return __no_sandbox
 
+
 def _patch_file(path, content):
     """Will backup the file then patch it"""
     existing_content = open(path).read()
@@ -245,15 +255,18 @@
 
 _patch_file = _no_sandbox(_patch_file)
 
+
 def _same_content(path, content):
     return open(path).read() == content
 
+
 def _rename_path(path):
     new_name = path + '.OLD.%s' % time.time()
-    log.warn('Renaming %s into %s', path, new_name)
+    log.warn('Renaming %s to %s', path, new_name)
     os.rename(path, new_name)
     return new_name
 
+
 def _remove_flat_installation(placeholder):
     if not os.path.isdir(placeholder):
         log.warn('Unkown installation at %s', placeholder)
@@ -267,7 +280,7 @@
         log.warn('Could not locate setuptools*.egg-info')
         return
 
-    log.warn('Removing elements out of the way...')
+    log.warn('Moving elements out of the way...')
     pkg_info = os.path.join(placeholder, file)
     if os.path.isdir(pkg_info):
         patched = _patch_egg_dir(pkg_info)
@@ -289,11 +302,13 @@
 
 _remove_flat_installation = _no_sandbox(_remove_flat_installation)
 
+
 def _after_install(dist):
     log.warn('After install bootstrap.')
     placeholder = dist.get_command_obj('install').install_purelib
     _create_fake_setuptools_pkg_info(placeholder)
 
+
 def _create_fake_setuptools_pkg_info(placeholder):
     if not placeholder or not os.path.exists(placeholder):
         log.warn('Could not find the install location')
@@ -307,7 +322,11 @@
         return
 
     log.warn('Creating %s', pkg_info)
-    f = open(pkg_info, 'w')
+    try:
+        f = open(pkg_info, 'w')
+    except EnvironmentError:
+        log.warn("Don't have permissions to write %s, skipping", pkg_info)
+        return
     try:
         f.write(SETUPTOOLS_PKG_INFO)
     finally:
@@ -321,7 +340,10 @@
     finally:
         f.close()
 
-_create_fake_setuptools_pkg_info = _no_sandbox(_create_fake_setuptools_pkg_info)
+_create_fake_setuptools_pkg_info = _no_sandbox(
+    _create_fake_setuptools_pkg_info
+)
+
 
 def _patch_egg_dir(path):
     # let's check if it's already patched
@@ -343,6 +365,7 @@
 
 _patch_egg_dir = _no_sandbox(_patch_egg_dir)
 
+
 def _before_install():
     log.warn('Before install bootstrap.')
     _fake_setuptools()
@@ -351,7 +374,7 @@
 def _under_prefix(location):
     if 'install' not in sys.argv:
         return True
-    args = sys.argv[sys.argv.index('install')+1:]
+    args = sys.argv[sys.argv.index('install') + 1:]
     for index, arg in enumerate(args):
         for option in ('--root', '--prefix'):
             if arg.startswith('%s=' % option):
@@ -359,7 +382,7 @@
                 return location.startswith(top_dir)
             elif arg == option:
                 if len(args) > index:
-                    top_dir = args[index+1]
+                    top_dir = args[index + 1]
                     return location.startswith(top_dir)
         if arg == '--user' and USER_SITE is not None:
             return location.startswith(USER_SITE)
@@ -376,11 +399,14 @@
         return
     ws = pkg_resources.working_set
     try:
-        setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools',
-                                  replacement=False))
+        setuptools_dist = ws.find(
+            pkg_resources.Requirement.parse('setuptools', replacement=False)
+            )
     except TypeError:
         # old distribute API
-        setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools'))
+        setuptools_dist = ws.find(
+            pkg_resources.Requirement.parse('setuptools')
+        )
 
     if setuptools_dist is None:
         log.warn('No setuptools distribution found')
@@ -414,7 +440,7 @@
         res = _patch_egg_dir(setuptools_location)
         if not res:
             return
-    log.warn('Patched done.')
+    log.warn('Patching complete.')
     _relaunch()
 
 
@@ -422,7 +448,9 @@
     log.warn('Relaunching...')
     # we have to relaunch the process
     # pip marker to avoid a relaunch bug
-    if sys.argv[:3] == ['-c', 'install', '--single-version-externally-managed']:
+    _cmd1 = ['-c', 'install', '--single-version-externally-managed']
+    _cmd2 = ['-c', 'install', '--record']
+    if sys.argv[:3] == _cmd1 or sys.argv[:3] == _cmd2:
         sys.argv[0] = 'setup.py'
     args = [sys.executable] + sys.argv
     sys.exit(subprocess.call(args))
@@ -448,7 +476,7 @@
             # Extract directories with a safe mode.
             directories.append(tarinfo)
             tarinfo = copy.copy(tarinfo)
-            tarinfo.mode = 448 # decimal for oct 0700
+            tarinfo.mode = 448  # decimal for oct 0700
         self.extract(tarinfo, path)
 
     # Reverse sort directories.
@@ -475,11 +503,39 @@
                 self._dbg(1, "tarfile: %s" % e)
 
 
-def main(argv, version=DEFAULT_VERSION):
+def _build_install_args(options):
+    """
+    Build the arguments to 'python setup.py install' on the distribute package
+    """
+    install_args = []
+    if options.user_install:
+        if sys.version_info < (2, 6):
+            log.warn("--user requires Python 2.6 or later")
+            raise SystemExit(1)
+        install_args.append('--user')
+    return install_args
+
+def _parse_args():
+    """
+    Parse the command line for options
+    """
+    parser = optparse.OptionParser()
+    parser.add_option(
+        '--user', dest='user_install', action='store_true', default=False,
+        help='install in user site package (requires Python 2.6 or later)')
+    parser.add_option(
+        '--download-base', dest='download_base', metavar="URL",
+        default=DEFAULT_URL,
+        help='alternative URL from where to download the distribute package')
+    options, args = parser.parse_args()
+    # positional arguments are ignored
+    return options
+
+def main(version=DEFAULT_VERSION):
     """Install or upgrade setuptools and EasyInstall"""
-    tarball = download_setuptools()
-    _install(tarball)
-
+    options = _parse_args()
+    tarball = download_setuptools(download_base=options.download_base)
+    return _install(tarball, _build_install_args(options))
 
 if __name__ == '__main__':
-    main(sys.argv[1:])
+    sys.exit(main())

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 doc/install_script.sh
--- a/doc/install_script.sh
+++ b/doc/install_script.sh
@@ -399,6 +399,14 @@
     ( ${SHASUM} -c $1.sha512 2>&1 ) 1>> ${LOG_FILE} || do_exit
 }
 
+function get_ytdata
+{
+    echo "Downloading $1 from yt-project.org"
+    [ -e $1 ] && return
+    ${GETFILE} "http://yt-project.org/data/$1" || do_exit
+    ( ${SHASUM} -c $1.sha512 2>&1 ) 1>> ${LOG_FILE} || do_exit
+}
+
 ORIG_PWD=`pwd`
 
 if [ -z "${DEST_DIR}" ]
@@ -407,6 +415,13 @@
     exit 1
 fi
 
+# Get supplemental data.
+
+mkdir -p ${DEST_DIR}/data
+cd ${DEST_DIR}/data
+echo 'de6d8c6ea849f0206d219303329a0276b3cce7c051eec34377d42aacbe0a4f47ac5145eb08966a338ecddd2b83c8f787ca9956508ad5c39ee2088ad875166410  xray_emissivity.h5' > xray_emissivity.h5.sha512
+get_ytdata xray_emissivity.h5
+
 mkdir -p ${DEST_DIR}/src
 cd ${DEST_DIR}/src
 
@@ -706,7 +721,7 @@
 then
     if [ ! -e Rockstar/done ]
     then
-        [ ! -e Rockstar] && tar xfz rockstar-0.99.6.tar.gz
+        [ ! -e Rockstar ] && tar xfz rockstar-0.99.6.tar.gz
         echo "Building Rockstar"
         cd Rockstar
         ( make lib 2>&1 ) 1>> ${LOG_FILE} || do_exit

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 yt/analysis_modules/spectral_integrator/api.py
--- a/yt/analysis_modules/spectral_integrator/api.py
+++ b/yt/analysis_modules/spectral_integrator/api.py
@@ -30,4 +30,8 @@
 
 from .spectral_frequency_integrator import \
     SpectralFrequencyIntegrator, \
-    create_table_from_textfiles
+    create_table_from_textfiles, \
+    EmissivityIntegrator, \
+    add_xray_emissivity_field, \
+    add_xray_luminosity_field, \
+    add_xray_photon_emissivity_field

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 yt/analysis_modules/spectral_integrator/spectral_frequency_integrator.py
--- a/yt/analysis_modules/spectral_integrator/spectral_frequency_integrator.py
+++ b/yt/analysis_modules/spectral_integrator/spectral_frequency_integrator.py
@@ -4,9 +4,11 @@
 
 Author: Matthew Turk <matthewturk at gmail.com>
 Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittons at origins.colorado.edu>
+Affiliation: Michigan State University
 Homepage: http://yt-project.org/
 License:
-  Copyright (C) 2007-2011 Matthew Turk.  All Rights Reserved.
+  Copyright (C) 2007-2012 Matthew Turk.  All Rights Reserved.
 
   This file is part of yt.
 
@@ -24,16 +26,20 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 
+from exceptions import IOError
+import h5py
 import numpy as np
+import os
 
 from yt.funcs import *
 
 from yt.data_objects.field_info_container import add_field
+from yt.utilities.exceptions import YTException
 from yt.utilities.linear_interpolators import \
-    UnilinearFieldInterpolator, \
-    BilinearFieldInterpolator, \
-    TrilinearFieldInterpolator
+    BilinearFieldInterpolator
 
+xray_data_version = 1
+    
 class SpectralFrequencyIntegrator(object):
     def __init__(self, table, field_names,
                  bounds, ev_bounds):
@@ -80,8 +86,8 @@
             return 10**interp(dd)
         add_field(name, function=frequency_bin_field,
                         projection_conversion="cm",
-                        units=r"\rm{ergs}\/\rm{cm}^{-3}\/\rm{s}^{-1}",
-                        projected_units=r"\rm{ergs}\/\rm{cm}^{-2}\/\rm{s}^{-1}")
+                        units=r"\rm{ergs}\ \rm{cm}^{-3}\ \rm{s}^{-1}",
+                        projected_units=r"\rm{ergs}\ \rm{cm}^{-2}\ \rm{s}^{-1}")
         return name
 
 def create_table_from_textfiles(pattern, rho_spec, e_spec, T_spec):
@@ -100,3 +106,304 @@
         table[ri,:,ei] = [float(l.split()[-1]) for l in open(pattern%(i+1)) if l[0] != "#"]
     return table
 
+class EnergyBoundsException(YTException):
+    def __init__(self, lower, upper):
+        self.lower = lower
+        self.upper = upper
+
+    def __str__(self):
+        return "Energy bounds are %e to %e keV." % \
+          (self.lower, self.upper)
+
+class ObsoleteDataException(YTException):
+    def __str__(self):
+        return "X-ray emissivity data is out of data.\nDownload the latest data from http://yt-project.org/data/xray_emissivity.h5 and move it to %s." % \
+          os.path.join(os.environ["YT_DEST"], "data", "xray_emissivity.h5")
+          
+class EmissivityIntegrator(object):
+    r"""Class for making X-ray emissivity fields with hdf5 data tables 
+    from Cloudy.
+    """
+    def __init__(self, filename=None):
+        r"""Initialize an EmissivityIntegrator object.
+
+        Keyword Parameters
+        ------------------
+        filename: string
+            Path to data file containing emissivity values.  If None,
+            a file called xray_emissivity.h5 is used.  This file contains 
+            emissivity tables for primordial elements and for metals at 
+            solar metallicity for the energy range 0.1 to 100 keV.
+            Default: None.
+            
+        """
+
+        default_filename = False
+        if filename is None:
+            filename = os.path.join(os.environ["YT_DEST"], 
+                                    "data", "xray_emissivity.h5")
+            default_filename = True
+
+        if not os.path.exists(filename):
+            raise IOError("File does not exist: %s." % filename)
+        only_on_root(mylog.info, "Loading emissivity data from %s." % filename)
+        in_file = h5py.File(filename, "r")
+        if "info" in in_file.attrs:
+            only_on_root(mylog.info, in_file.attrs["info"])
+        if default_filename and \
+          in_file.attrs["version"] < xray_data_version:
+            raise ObsoleteDataException()
+        else:
+            only_on_root(mylog.info, "X-ray emissivity data version: %s." % \
+                         in_file.attrs["version"])
+
+        for field in ["emissivity_primordial", "emissivity_metals",
+                      "log_nH", "log_T", "log_E"]:
+            setattr(self, field, in_file[field][:])
+        in_file.close()
+
+        E_diff = np.diff(self.log_E)
+        self.E_bins = \
+                  np.power(10, np.concatenate([self.log_E[:-1] - 0.5 * E_diff,
+                                               [self.log_E[-1] - 0.5 * E_diff[-1],
+                                                self.log_E[-1] + 0.5 * E_diff[-1]]]))
+        self.dnu = 2.41799e17 * np.diff(self.E_bins)
+
+    def _get_interpolator(self, data, e_min, e_max):
+        r"""Create an interpolator for total emissivity in a 
+        given energy range.
+
+        Parameters
+        ----------
+        e_min: float
+            the minimum energy in keV for the energy band.
+        e_min: float
+            the maximum energy in keV for the energy band.
+
+        """
+        if (e_min - self.E_bins[0]) / e_min < -1e-3 or \
+          (e_max - self.E_bins[-1]) / e_max > 1e-3:
+            raise EnergyBoundsException(np.power(10, self.E_bins[0]),
+                                        np.power(10, self.E_bins[-1]))
+        e_is, e_ie = np.digitize([e_min, e_max], self.E_bins)
+        e_is = np.clip(e_is - 1, 0, self.E_bins.size - 1)
+        e_ie = np.clip(e_ie, 0, self.E_bins.size - 1)
+
+        my_dnu = np.copy(self.dnu[e_is: e_ie])
+        # clip edge bins if the requested range is smaller
+        my_dnu[0] -= e_min - self.E_bins[e_is]
+        my_dnu[-1] -= self.E_bins[e_ie] - e_max
+
+        interp_data = (data[..., e_is:e_ie] * my_dnu).sum(axis=-1)
+        return BilinearFieldInterpolator(np.log10(interp_data),
+                                         [self.log_nH[0], self.log_nH[-1],
+                                          self.log_T[0],  self.log_T[-1]],
+                                         ["log_nH", "log_T"], truncate=True)
+
+def add_xray_emissivity_field(e_min, e_max, filename=None,
+                              with_metals=True,
+                              constant_metallicity=None):
+    r"""Create an X-ray emissivity field for a given energy range.
+
+    Parameters
+    ----------
+    e_min: float
+        the minimum energy in keV for the energy band.
+    e_min: float
+        the maximum energy in keV for the energy band.
+
+    Keyword Parameters
+    ------------------
+    filename: string
+        Path to data file containing emissivity values.  If None,
+        a file called xray_emissivity.h5 is used.  This file contains 
+        emissivity tables for primordial elements and for metals at 
+        solar metallicity for the energy range 0.1 to 100 keV.
+        Default: None.
+    with_metals: bool
+        If True, use the metallicity field to add the contribution from 
+        metals.  If False, only the emission from H/He is considered.
+        Default: True.
+    constant_metallicity: float
+        If specified, assume a constant metallicity for the emission 
+        from metals.  The *with_metals* keyword must be set to False 
+        to use this.
+        Default: None.
+
+    This will create a field named "Xray_Emissivity_{e_min}_{e_max}keV".
+    The units of the field are erg s^-1 cm^-3.
+
+    Examples
+    --------
+
+    >>> from yt.mods import *
+    >>> from yt.analysis_modules.spectral_integrator.api import *
+    >>> add_xray_emissivity_field(0.5, 2)
+    >>> pf = load(dataset)
+    >>> p = ProjectionPlot(pf, 'x', "Xray_Emissivity_0.5_2keV")
+    >>> p.save()
+
+    """
+
+    my_si = EmissivityIntegrator(filename=filename)
+
+    em_0 = my_si._get_interpolator(my_si.emissivity_primordial, e_min, e_max)
+    em_Z = None
+    if with_metals or constant_metallicity is not None:
+        em_Z = my_si._get_interpolator(my_si.emissivity_metals, e_min, e_max)
+
+    def _emissivity_field(field, data):
+        dd = {"log_nH" : np.log10(data["H_NumberDensity"]),
+              "log_T"   : np.log10(data["Temperature"])}
+
+        my_emissivity = np.power(10, em_0(dd))
+        if em_Z is not None:
+            if with_metals:
+                my_Z = data["Metallicity"]
+            elif constant_metallicity is not None:
+                my_Z = constant_metallicity
+            my_emissivity += my_Z * np.power(10, em_Z(dd))
+
+        return data["H_NumberDensity"]**2 * my_emissivity
+
+    field_name = "Xray_Emissivity_%s_%skeV" % (e_min, e_max)
+    add_field(field_name, function=_emissivity_field,
+              projection_conversion="cm",
+              display_name=r"\epsilon_{X}\ (%s-%s\ keV)" % (e_min, e_max),
+              units=r"\rm{erg}\ \rm{cm}^{-3}\ \rm{s}^{-1}",
+              projected_units=r"\rm{erg}\ \rm{cm}^{-2}\ \rm{s}^{-1}")
+    return field_name
+
+def add_xray_luminosity_field(e_min, e_max, filename=None,
+                              with_metals=True,
+                              constant_metallicity=None):
+    r"""Create an X-ray luminosity field for a given energy range.
+
+    Parameters
+    ----------
+    e_min: float
+        the minimum energy in keV for the energy band.
+    e_min: float
+        the maximum energy in keV for the energy band.
+
+    Keyword Parameters
+    ------------------
+    filename: string
+        Path to data file containing emissivity values.  If None,
+        a file called xray_emissivity.h5 is used.  This file contains 
+        emissivity tables for primordial elements and for metals at 
+        solar metallicity for the energy range 0.1 to 100 keV.
+        Default: None.
+    with_metals: bool
+        If True, use the metallicity field to add the contribution from 
+        metals.  If False, only the emission from H/He is considered.
+        Default: True.
+    constant_metallicity: float
+        If specified, assume a constant metallicity for the emission 
+        from metals.  The *with_metals* keyword must be set to False 
+        to use this.
+        Default: None.
+
+    This will create a field named "Xray_Luminosity_{e_min}_{e_max}keV".
+    The units of the field are erg s^-1.
+
+    Examples
+    --------
+
+    >>> from yt.mods import *
+    >>> from yt.analysis_modules.spectral_integrator.api import *
+    >>> add_xray_luminosity_field(0.5, 2)
+    >>> pf = load(dataset)
+    >>> sp = pf.h.sphere('max', (2., 'mpc'))
+    >>> print sp.quantities['TotalQuantity']('Xray_Luminosity_0.5_2keV')
+    
+    """
+
+    em_field = add_xray_emissivity_field(e_min, e_max, filename=filename,
+                                         with_metals=with_metals,
+                                         constant_metallicity=constant_metallicity)
+
+    def _luminosity_field(field, data):
+        return data[em_field] * data["CellVolume"]
+    field_name = "Xray_Luminosity_%s_%skeV" % (e_min, e_max)
+    add_field(field_name, function=_luminosity_field,
+              display_name=r"\rm{L}_{X}\ (%s-%s\ keV)" % (e_min, e_max),
+              units=r"\rm{erg}\ \rm{s}^{-1}")
+    return field_name
+
+def add_xray_photon_emissivity_field(e_min, e_max, filename=None,
+                                     with_metals=True,
+                                     constant_metallicity=None):
+    r"""Create an X-ray photon emissivity field for a given energy range.
+
+    Parameters
+    ----------
+    e_min: float
+        the minimum energy in keV for the energy band.
+    e_min: float
+        the maximum energy in keV for the energy band.
+
+    Keyword Parameters
+    ------------------
+    filename: string
+        Path to data file containing emissivity values.  If None,
+        a file called xray_emissivity.h5 is used.  This file contains 
+        emissivity tables for primordial elements and for metals at 
+        solar metallicity for the energy range 0.1 to 100 keV.
+        Default: None.
+    with_metals: bool
+        If True, use the metallicity field to add the contribution from 
+        metals.  If False, only the emission from H/He is considered.
+        Default: True.
+    constant_metallicity: float
+        If specified, assume a constant metallicity for the emission 
+        from metals.  The *with_metals* keyword must be set to False 
+        to use this.
+        Default: None.
+
+    This will create a field named "Xray_Photon_Emissivity_{e_min}_{e_max}keV".
+    The units of the field are photons s^-1 cm^-3.
+
+    Examples
+    --------
+
+    >>> from yt.mods import *
+    >>> from yt.analysis_modules.spectral_integrator.api import *
+    >>> add_xray_emissivity_field(0.5, 2)
+    >>> pf = load(dataset)
+    >>> p = ProjectionPlot(pf, 'x', "Xray_Emissivity_0.5_2keV")
+    >>> p.save()
+
+    """
+
+    my_si = EmissivityIntegrator(filename=filename)
+    energy_erg = np.power(10, my_si.log_E) * 1.60217646e-9
+
+    em_0 = my_si._get_interpolator((my_si.emissivity_primordial[..., :] / energy_erg),
+                                   e_min, e_max)
+    em_Z = None
+    if with_metals or constant_metallicity is not None:
+        em_Z = my_si._get_interpolator((my_si.emissivity_metals[..., :] / energy_erg),
+                                       e_min, e_max)
+
+    def _emissivity_field(field, data):
+        dd = {"log_nH" : np.log10(data["H_NumberDensity"]),
+              "log_T"   : np.log10(data["Temperature"])}
+
+        my_emissivity = np.power(10, em_0(dd))
+        if em_Z is not None:
+            if with_metals:
+                my_Z = data["Metallicity"]
+            elif constant_metallicity is not None:
+                my_Z = constant_metallicity
+            my_emissivity += my_Z * np.power(10, em_Z(dd))
+
+        return data["H_NumberDensity"]**2 * my_emissivity
+
+    field_name = "Xray_Photon_Emissivity_%s_%skeV" % (e_min, e_max)
+    add_field(field_name, function=_emissivity_field,
+              projection_conversion="cm",
+              display_name=r"\epsilon_{X}\ (%s-%s\ keV)" % (e_min, e_max),
+              units=r"\rm{photons}\ \rm{cm}^{-3}\ \rm{s}^{-1}",
+              projected_units=r"\rm{photons}\ \rm{cm}^{-2}\ \rm{s}^{-1}")
+    return field_name

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 yt/config.py
--- a/yt/config.py
+++ b/yt/config.py
@@ -59,9 +59,10 @@
     hub_url = 'https://hub.yt-project.org/upload',
     hub_api_key = '',
     ipython_notebook = 'False',
+    notebook_password = '',
     answer_testing_tolerance = '3',
     answer_testing_bitwise = 'False',
-    gold_standard_filename = 'gold004',
+    gold_standard_filename = 'gold005',
     local_standard_filename = 'local001',
     sketchfab_api_key = 'None'
     )

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -1781,10 +1781,16 @@
             self._okay_to_serialize = True
 
     def _get_tree(self, nvals):
-        xd = self.pf.domain_dimensions[x_dict[self.axis]]
-        yd = self.pf.domain_dimensions[y_dict[self.axis]]
+        xax = x_dict[self.axis]
+        yax = y_dict[self.axis]
+        xd = self.pf.domain_dimensions[xax]
+        yd = self.pf.domain_dimensions[yax]
+        bounds = (self.pf.domain_left_edge[xax],
+                  self.pf.domain_right_edge[yax],
+                  self.pf.domain_left_edge[xax],
+                  self.pf.domain_right_edge[yax])
         return QuadTree(np.array([xd,yd], dtype='int64'), nvals,
-                        style = self.proj_style)
+                        bounds, style = self.proj_style)
 
     def _get_dls(self, grid, fields):
         # Place holder for a time when maybe we will not be doing just

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 yt/data_objects/field_info_container.py
--- a/yt/data_objects/field_info_container.py
+++ b/yt/data_objects/field_info_container.py
@@ -280,7 +280,7 @@
             return np.ones(self.NumberOfParticles)
         return defaultdict.__missing__(self, field_name)
 
-    def get_field_parameter(self, param):
+    def get_field_parameter(self, param, default = None):
         self.requested_parameters.append(param)
         if param in ['bulk_velocity', 'center', 'normal']:
             return np.random.random(3) * 1e-2

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 yt/data_objects/time_series.py
--- a/yt/data_objects/time_series.py
+++ b/yt/data_objects/time_series.py
@@ -258,9 +258,12 @@
         ...     SlicePlot(pf, "x", "Density").save()
 
         """
+        
         if isinstance(filenames, types.StringTypes):
             filenames = glob.glob(filenames)
             filenames.sort()
+        if len(filenames) == 0:
+            raise YTOutputNotIdentified(filenames, {})
         obj = cls(filenames[:], parallel = parallel, **kwargs)
         return obj
 

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 yt/data_objects/universal_fields.py
--- a/yt/data_objects/universal_fields.py
+++ b/yt/data_objects/universal_fields.py
@@ -506,11 +506,11 @@
 def _CellVolume(field, data):
     if data['dx'].size == 1:
         try:
-            return data['dx']*data['dy']*data['dx']*\
+            return data['dx'] * data['dy'] * data['dz'] * \
                 np.ones(data.ActiveDimensions, dtype='float64')
         except AttributeError:
-            return data['dx']*data['dy']*data['dx']
-    return data["dx"]*data["dy"]*data["dz"]
+            return data['dx'] * data['dy'] * data['dz']
+    return data["dx"] * data["dy"] * data["dz"]
 def _ConvertCellVolumeMpc(data):
     return data.convert("mpc")**3.0
 def _ConvertCellVolumeCGS(data):

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 yt/frontends/chombo/data_structures.py
--- a/yt/frontends/chombo/data_structures.py
+++ b/yt/frontends/chombo/data_structures.py
@@ -106,7 +106,7 @@
         # for now, the hierarchy file is the parameter file!
         self.hierarchy_filename = self.parameter_file.parameter_filename
         self.hierarchy = os.path.abspath(self.hierarchy_filename)
-        self.directory = os.path.dirname(self.hierarchy_filename)
+        self.directory = pf.fullpath
         self._fhandle = h5py.File(self.hierarchy_filename, 'r')
 
         self.float_type = self._fhandle['/level_0']['data:datatype=0'].dtype.name
@@ -143,9 +143,6 @@
                     self.grid_particle_count[ind] += 1
                     self.grids[ind].NumberOfParticles += 1
 
-    def _initialize_data_storage(self):
-        pass
-
     def _detect_fields(self):
         ncomp = int(self._fhandle['/'].attrs['num_components'])
         self.field_list = [c[1] for c in self._fhandle['/'].attrs.items()[-ncomp:]]

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 yt/funcs.py
--- a/yt/funcs.py
+++ b/yt/funcs.py
@@ -185,7 +185,7 @@
 
     .. code-block:: python
 
-       @rootonly
+       @deprecate
        def some_really_old_function(...):
 
     """
@@ -205,7 +205,7 @@
 
     .. code-block:: python
 
-       @rootonly
+       @pdb_run
        def some_function_to_debug(...):
 
     """
@@ -574,5 +574,5 @@
     return inv_axis_names.get(axis, axis)
 
 def get_image_suffix(name):
-    suffix = os.path.splitext(name)[1]
+    suffix = os.path.splitext(name)[1].lstrip('.')
     return suffix if suffix in ['png', 'eps', 'ps', 'pdf'] else ''

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 yt/imods.py
--- /dev/null
+++ b/yt/imods.py
@@ -0,0 +1,17 @@
+# This custom importer for yt will set up some IPython notebook-specific
+# helpers.  For instance, it will eventually add items to the menubar.
+
+import __builtin__
+if "__IPYTHON__" not in dir(__builtin__):
+    raise ImportError
+
+from IPython.core.interactiveshell import InteractiveShell
+from IPython.core.display import display, display_html
+inst = InteractiveShell.instance()
+ip = inst.get_ipython()
+ip.enable_pylab("inline", import_all=False)
+
+from yt.config import ytcfg
+ytcfg["yt", "ipython_notebook"] = "True"
+
+from yt.mods import *

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 yt/utilities/command_line.py
--- a/yt/utilities/command_line.py
+++ b/yt/utilities/command_line.py
@@ -30,7 +30,7 @@
 from yt.funcs import *
 from yt.utilities.minimal_representation import MinimalProjectDescription
 import argparse, os, os.path, math, sys, time, subprocess, getpass, tempfile
-import urllib, urllib2, base64
+import urllib, urllib2, base64, os
 
 def _fix_pf(arg):
     if os.path.isdir("%s" % arg) and \
@@ -591,19 +591,6 @@
             print
             loki = raw_input("Press enter to go on, Ctrl-C to exit.")
             cedit.config.setoption(uu, hgrc_path, "bb.username=%s" % bbusername)
-        bb_fp = "81:2b:08:90:dc:d3:71:ee:e0:7c:b4:75:ce:9b:6c:48:94:56:a1:fe"
-        if uu.config("hostfingerprints", "bitbucket.org", None) is None:
-            print "Let's also add bitbucket.org to the known hosts, so hg"
-            print "doesn't warn us about bitbucket."
-            print "We will add this:"
-            print
-            print "   [hostfingerprints]"
-            print "   bitbucket.org = %s" % (bb_fp)
-            print
-            loki = raw_input("Press enter to go on, Ctrl-C to exit.")
-            cedit.config.setoption(uu, hgrc_path,
-                                   "hostfingerprints.bitbucket.org=%s" % bb_fp)
-
         # We now reload the UI's config file so that it catches the [bb]
         # section changes.
         uu.readconfig(hgrc_path[0])
@@ -1398,6 +1385,67 @@
         import rpdb
         rpdb.run_rpdb(int(args.task))
 
+class YTNotebookCmd(YTCommand):
+    name = ["notebook"]
+    args = (
+            dict(short="-o", long="--open-browser", action="store_true",
+                 default = False, dest='open_browser',
+                 help="Open a web browser."),
+            dict(short="-p", long="--port", action="store",
+                 default = 0, dest='port',
+                 help="Port to listen on; defaults to auto-detection."),
+            dict(short="-n", long="--no-password", action="store_true",
+                 default = False, dest='no_password',
+                 help="If set, do not prompt or use a password."),
+            )
+    description = \
+        """
+        Run the IPython Notebook
+        """
+    def __call__(self, args):
+        kwargs = {}
+        from IPython.frontend.html.notebook.notebookapp import NotebookApp
+        pw = ytcfg.get("yt", "notebook_password")
+        if len(pw) == 0 and not args.no_password:
+            import IPython.lib
+            pw = IPython.lib.passwd()
+            print "If you would like to use this password in the future,"
+            print "place a line like this inside the [yt] section in your"
+            print "yt configuration file at ~/.yt/config"
+            print
+            print "notebook_password = %s" % pw
+            print
+        elif args.no_password:
+            pw = None
+        if args.port != 0:
+            kwargs['port'] = int(args.port)
+        if pw is not None:
+            kwargs['password'] = pw
+        app = NotebookApp(open_browser=args.open_browser,
+                          **kwargs)
+        app.initialize(argv=[])
+        print
+        print "***************************************************************"
+        print
+        print "The notebook is now live at:"
+        print
+        print "     http://127.0.0.1:%s/" % app.port
+        print
+        print "Recall you can create a new SSH tunnel dynamically by pressing"
+        print "~C and then typing -L%s:localhost:%s" % (app.port, app.port)
+        print
+        print "Additionally, while in the notebook, we recommend you start by"
+        print "replacing 'yt.mods' with 'yt.imods' like so:"
+        print
+        print "    from yt.imods import *"
+        print
+        print "This will enable some IPython-specific extensions to yt."
+        print
+        print "***************************************************************"
+        print
+        app.start()
+
+
 class YTGUICmd(YTCommand):
     name = ["serve", "reason"]
     args = (

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 yt/utilities/grid_data_format/tests/test_writer.py
--- /dev/null
+++ b/yt/utilities/grid_data_format/tests/test_writer.py
@@ -0,0 +1,66 @@
+"""
+Testsuite for writing yt data to GDF
+
+Author: Kacper Kowalik <xarthisius.kk at gmail.com>
+Affiliation: Torun Center for Astronomy, NCU
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2012 Kacper Kowalik.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+import tempfile
+import shutil
+import os
+import h5py as h5
+from yt.testing import \
+    fake_random_pf, assert_equal
+from yt.utilities.grid_data_format.writer import \
+    write_to_gdf
+from yt.frontends.gdf.data_structures import \
+    GDFStaticOutput
+from yt.mods import \
+    load
+
+TEST_AUTHOR = "yt test runner"
+TEST_COMMENT = "Testing write_to_gdf"
+
+
+def setup():
+    """Test specific setup."""
+    from yt.config import ytcfg
+    ytcfg["yt", "__withintesting"] = "True"
+
+
+def test_write_gdf():
+    """Main test suite for write_gdf"""
+    tmpdir = tempfile.mkdtemp()
+    tmpfile = os.path.join(tmpdir, 'test_gdf.h5')
+
+    test_pf = fake_random_pf(64)
+    write_to_gdf(test_pf, tmpfile, data_author=TEST_AUTHOR,
+                 data_comment=TEST_COMMENT)
+    del test_pf
+
+    assert isinstance(load(tmpfile), GDFStaticOutput)
+
+    h5f = h5.File(tmpfile, 'r')
+    gdf = h5f['gridded_data_format'].attrs
+    assert_equal(gdf['data_author'], TEST_AUTHOR)
+    assert_equal(gdf['data_comment'], TEST_COMMENT)
+    h5f.close()
+
+    shutil.rmtree(tmpdir)

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 yt/utilities/lib/QuadTree.pyx
--- a/yt/utilities/lib/QuadTree.pyx
+++ b/yt/utilities/lib/QuadTree.pyx
@@ -115,9 +115,11 @@
     cdef int merged
     cdef int num_cells
     cdef QTN_combine *combine
+    cdef np.float64_t bounds[4]
+    cdef np.float64_t dds[2]
 
     def __cinit__(self, np.ndarray[np.int64_t, ndim=1] top_grid_dims,
-                  int nvals, style = "integrate"):
+                  int nvals, bounds, style = "integrate"):
         if style == "integrate":
             self.combine = QTN_add_value
         elif style == "mip":
@@ -133,9 +135,13 @@
         cdef np.float64_t weight_val = 0.0
         self.nvals = nvals
         for i in range(nvals): vals[i] = 0.0
+        for i in range(4):
+            self.bounds[i] = bounds[i]
 
         self.top_grid_dims[0] = top_grid_dims[0]
         self.top_grid_dims[1] = top_grid_dims[1]
+        self.dds[0] = (self.bounds[1] - self.bounds[0])/self.top_grid_dims[0]
+        self.dds[1] = (self.bounds[3] - self.bounds[2])/self.top_grid_dims[1]
 
         # This wouldn't be necessary if we did bitshifting...
         for i in range(80):
@@ -404,6 +410,58 @@
             wtoadd -= node.weight_val
         return added
 
+    @cython.boundscheck(False)
+    @cython.wraparound(False)
+    @cython.cdivision(True)
+    def fill_image(self, np.ndarray[np.float64_t, ndim=2] buffer, _bounds,
+                   int val_index = 0):
+        cdef np.float64_t dds[2], pos[2]
+        cdef int nn[2], i, j
+        cdef np.float64_t bounds[4]
+        for i in range(4):
+            bounds[i] = _bounds[i]
+        for i in range(2):
+            nn[i] = buffer.shape[i]
+            dds[i] = (bounds[i*2 + 1] - bounds[i*2])/nn[i]
+        cdef QuadTreeNode *node
+        pos[0] = bounds[0]
+        for i in range(nn[0]):
+            pos[1] = bounds[2]
+            for j in range(nn[1]):
+                # We start at level zero.  In the future we could optimize by
+                # retaining oct information from previous cells.
+                node = self.find_node_at_pos(pos)
+                buffer[i,j] = node.val[val_index]
+                pos[1] += dds[1]
+            pos[0] += dds[0]
+
+    @cython.boundscheck(False)
+    @cython.wraparound(False)
+    @cython.cdivision(True)
+    cdef QuadTreeNode *find_node_at_pos(self, np.float64_t pos[2]):
+        cdef np.int64_t ind[2]
+        cdef np.float64_t cp[2]
+        cdef np.float64_t dds[2]
+        cdef QuadTreeNode *cur
+        for i in range(2):
+            ind[i] = <np.int64_t> (pos[i]/self.dds[i])
+            cp[i] = (ind[i] + 0.5) * self.dds[i]
+            dds[i] = self.dds[i]
+        cur = self.root_nodes[ind[0]][ind[1]]
+        while cur.children[0][0] != NULL:
+            for i in range(2):
+                # Note that below offset by half a dx for center, after
+                # updating to the next level
+                dds[i] = dds[i] / 2.0
+                if cp[i] < pos[i]:
+                    ind[i] = 0
+                    cp[i] -= dds[i] / 2.0 
+                else:
+                    ind[i] = 1
+                    cp[i] += dds[i] / 2.0
+            cur = cur.children[ind[0]][ind[1]]
+        return cur
+
     def __dealloc__(self):
         cdef int i, j
         for i in range(self.top_grid_dims[0]):

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 yt/utilities/parallel_tools/parallel_analysis_interface.py
--- a/yt/utilities/parallel_tools/parallel_analysis_interface.py
+++ b/yt/utilities/parallel_tools/parallel_analysis_interface.py
@@ -799,7 +799,7 @@
                 if target < size:
                     #print "RECEIVING FROM %02i on %02i" % (target, rank)
                     buf = self.recv_quadtree(target, tgd, args)
-                    qto = QuadTree(tgd, args[2])
+                    qto = QuadTree(tgd, args[2], qt.bounds)
                     qto.frombuffer(buf[0], buf[1], buf[2], merge_style)
                     merge_quadtrees(qt, qto, style = merge_style)
                     del qto
@@ -819,7 +819,7 @@
         self.comm.Bcast([buf[2], MPI.DOUBLE], root=0)
         self.refined = buf[0]
         if rank != 0:
-            qt = QuadTree(tgd, args[2])
+            qt = QuadTree(tgd, args[2], qt.bounds)
             qt.frombuffer(buf[0], buf[1], buf[2], merge_style)
         return qt
 

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 yt/utilities/physical_constants.py
--- a/yt/utilities/physical_constants.py
+++ b/yt/utilities/physical_constants.py
@@ -1,26 +1,31 @@
 #
 # Physical Constants and Units Conversion Factors
 #
+# Values for these constants are drawn from IAU and IUPAC data 
+# unless otherwise noted:
+# http://maia.usno.navy.mil/NSFA/IAU2009_consts.html
+# http://goldbook.iupac.org/list_goldbook_phys_constants_defs.html
 
 # Masses
-mass_hydrogen_cgs = 1.67e-24  # g
-mass_electron_cgs = 9.11e-28  # g
-amu_cgs           = 1.66053886e-24  # g
-mass_sun_cgs = 1.9891e33  # g
+mass_hydrogen_cgs = 1.674534e-24  # g
+mass_electron_cgs = 9.1093898e-28  # g
+amu_cgs           = 1.6605402e-24  # g
+mass_sun_cgs = 1.98841586e33  # g
 # Velocities
 speed_of_light_cgs = 2.99792458e10  # cm/s, exact
 
 # Cross Sections
-cross_section_thompson_cgs = 6.65e-25  # cm^2
+# 8*pi/3 (alpha*hbar*c/(2*pi))**2
+cross_section_thompson_cgs = 6.65245854533e-25  # cm^2
 
 # Charge
-charge_proton_cgs = 4.803e-10  # esu = 1.602e-19  Coulombs
+charge_proton_cgs = 4.8032056e-10  # esu = 1.602176487e-19  Coulombs
 
 # Physical Constants
 boltzmann_constant_cgs = 1.3806504e-16  # erg K^-1
 gravitational_constant_cgs  = 6.67428e-8  # cm^3 g^-1 s^-2
 planck_constant_cgs   = 6.62606896e-27  # erg s
-stefan_boltzmann_constant_cgs = 5.670373e-5 # erg cm^-2 s^-1 K^-4
+stefan_boltzmann_constant_cgs = 5.67051e-5 # erg cm^-2 s^-1 K^-4
 rho_crit_now = 1.8788e-29  # g times h^2 (critical mass for closure, Cosmology)
 
 # Misc. Approximations
@@ -32,16 +37,16 @@
 mpc_per_mpc   = 1e0
 mpc_per_kpc   = 1e-3
 mpc_per_pc    = 1e-6
-mpc_per_au    = 4.847e-12
-mpc_per_rsun  = 2.253e-14
-mpc_per_miles = 5.216e-20
-mpc_per_cm    = 3.24e-25
+mpc_per_au    = 4.84813682e-12
+mpc_per_rsun  = 2.253962e-14
+mpc_per_miles = 5.21552871e-20
+mpc_per_cm    = 3.24077929e-25
 km_per_pc     = 1.3806504e13
 km_per_m      = 1e-3
 km_per_cm     = 1e-5
-pc_per_cm     = 3.24e-19
+pc_per_cm     = 3.24077929e-19
 
-m_per_fpc     = 0.0324077649
+m_per_fpc     = 0.0324077929
 
 kpc_per_mpc   = 1.0 / mpc_per_kpc
 pc_per_mpc    = 1.0 / mpc_per_pc

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 yt/visualization/base_plot_types.py
--- /dev/null
+++ b/yt/visualization/base_plot_types.py
@@ -0,0 +1,84 @@
+"""
+This is a place for base classes of the various plot types.
+
+Author: Nathan Goldbaum <goldbaum at ucolick.org>
+Affiliation: UCSC Astronomy
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2010-2012 Nathan Goldbaum.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+import matplotlib
+from ._mpl_imports import \
+    FigureCanvasAgg, FigureCanvasPdf, FigureCanvasPS
+from yt.funcs import \
+    get_image_suffix, mylog
+
+
+class PlotMPL(object):
+    """A base class for all yt plots made using matplotlib.
+
+    """
+    def __init__(self, fsize, axrect):
+        """Initialize PlotMPL class"""
+        self._plot_valid = True
+        self.figure = matplotlib.figure.Figure(figsize=fsize,
+                                               frameon=True)
+        self.axes = self.figure.add_axes(axrect)
+
+    def save(self, name, mpl_kwargs, canvas=None):
+        """Choose backend and save image to disk"""
+        suffix = get_image_suffix(name)
+        if suffix == '':
+            suffix = '.png'
+            name = "%s%s" % (name, suffix)
+
+        mylog.info("Saving plot %s", name)
+
+        if suffix == ".png":
+            canvas = FigureCanvasAgg(self.figure)
+        elif suffix == ".pdf":
+            canvas = FigureCanvasPdf(self.figure)
+        elif suffix in (".eps", ".ps"):
+            canvas = FigureCanvasPS(self.figure)
+        else:
+            mylog.warning("Unknown suffix %s, defaulting to Agg", suffix)
+            canvas = FigureCanvasAgg(self.figure)
+
+        canvas.print_figure(name, **mpl_kwargs)
+        return name
+
+
+class ImagePlotMPL(PlotMPL):
+    """A base class for yt plots made using imshow
+
+    """
+    def __init__(self, fsize, axrect, caxrect, zlim):
+        """Initialize ImagePlotMPL class object"""
+        PlotMPL.__init__(self, fsize, axrect)
+        self.zmin, self.zmax = zlim
+        self.cax = self.figure.add_axes(caxrect)
+
+    def _init_image(self, data, cbnorm, cmap, extent, aspect=None):
+        """Store output of imshow in image variable"""
+        if (cbnorm == 'log10'):
+            norm = matplotlib.colors.LogNorm()
+        elif (cbnorm == 'linear'):
+            norm = matplotlib.colors.Normalize()
+        self.image = self.axes.imshow(data, origin='lower', extent=extent,
+                                      norm=norm, vmin=self.zmin, aspect=aspect,
+                                      vmax=self.zmax, cmap=cmap)

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 yt/visualization/fixed_resolution.py
--- a/yt/visualization/fixed_resolution.py
+++ b/yt/visualization/fixed_resolution.py
@@ -159,14 +159,27 @@
         info['projected_units'] = \
                 self.data_source.pf.field_info[item].get_projected_units()
         info['center'] = self.data_source.center
+        
         try:
             info['coord'] = self.data_source.coord
         except AttributeError:
             pass
+        
         try:
             info['weight_field'] = self.data_source.weight_field
         except AttributeError:
             pass
+        
+        info['label'] = self.data_source.pf.field_info[item].display_name
+        if info['label'] is None:
+            info['label'] = r'$\rm{'+item+r'}$'
+        elif info['label'].find('$') == -1:
+            info['label'] = r'$\rm{'+info['label']+r'}$'
+        if info['units'] is None or info['units'] == '':
+            pass
+        else:
+            info['label'] += r'$\/\/('+info['units']+r')$'
+        
         return info
 
     def convert_to_pixel(self, coords):

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 yt/visualization/plot_modifications.py
--- a/yt/visualization/plot_modifications.py
+++ b/yt/visualization/plot_modifications.py
@@ -658,24 +658,25 @@
 
         xf = axis_names[px_index]
         yf = axis_names[py_index]
+        dxf = "d%s" % xf
+        dyf = "d%s" % yf
 
         DomainRight = plot.data.pf.domain_right_edge
         DomainLeft = plot.data.pf.domain_left_edge
         DomainWidth = DomainRight - DomainLeft
-        
+
         nx, ny = plot.image._A.shape
         buff = np.zeros((nx,ny),dtype='float64')
         for i,clump in enumerate(reversed(self.clumps)):
             mylog.debug("Pixelizing contour %s", i)
 
-
             xf_copy = clump[xf].copy()
             yf_copy = clump[yf].copy()
-            
-            temp = _MPL.Pixelize(xf_copy, yf_copy, 
-                                 clump['dx']/2.0,
-                                 clump['dy']/2.0,
-                                 clump['dx']*0.0+i+1, # inits inside Pixelize
+
+            temp = _MPL.Pixelize(xf_copy, yf_copy,
+                                 clump[dxf]/2.0,
+                                 clump[dyf]/2.0,
+                                 clump[dxf]*0.0+i+1, # inits inside Pixelize
                                  int(nx), int(ny),
                              (x0, x1, y0, y1), 0).transpose()
             buff = np.maximum(temp, buff)

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -25,29 +25,18 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 import base64
-import matplotlib.figure
-from matplotlib.mathtext import MathTextParser
-from distutils import version
+import numpy as np
 import matplotlib
-
-# Some magic for dealing with pyparsing being included or not
-# included in matplotlib (not in gentoo, yes in everything else)
-# Also accounting for the fact that in 1.2.0, pyparsing got renamed.
-try:
-    if version.LooseVersion(matplotlib.__version__) < version.LooseVersion("1.2.0"):
-        from matplotlib.pyparsing import ParseFatalException
-    else:
-        from matplotlib.pyparsing_py2 import ParseFatalException
-except ImportError:
-    from pyparsing import ParseFatalException
-
 import cStringIO
 import types
 import __builtin__
+
+from matplotlib.mathtext import MathTextParser
+from distutils import version
 from functools import wraps
 
-import numpy as np
-from ._mpl_imports import *
+from ._mpl_imports import \
+    FigureCanvasAgg, FigureCanvasPdf, FigureCanvasPS
 from .color_maps import yt_colormaps, is_colormap
 from .image_writer import \
     write_image, apply_colormap
@@ -58,10 +47,13 @@
 from .plot_modifications import get_smallest_appropriate_unit, \
     callback_registry
 from .tick_locators import LogLocator, LinearLocator
+from .base_plot_types import ImagePlotMPL
+
 from yt.utilities.delaunay.triangulate import Triangulation as triang
 from yt.config import ytcfg
-
-from yt.funcs import *
+from yt.funcs import \
+    mylog, defaultdict, iterable, ensure_list, \
+    fix_axis, get_image_suffix
 from yt.utilities.lib import write_png_to_string
 from yt.utilities.definitions import \
     x_dict, x_names, \
@@ -75,6 +67,17 @@
 from yt.data_objects.time_series import \
     TimeSeriesData
 
+# Some magic for dealing with pyparsing being included or not
+# included in matplotlib (not in gentoo, yes in everything else)
+# Also accounting for the fact that in 1.2.0, pyparsing got renamed.
+try:
+    if version.LooseVersion(matplotlib.__version__) < version.LooseVersion("1.2.0"):
+        from matplotlib.pyparsing import ParseFatalException
+    else:
+        from matplotlib.pyparsing_py2 import ParseFatalException
+except ImportError:
+    from pyparsing import ParseFatalException
+
 def invalidate_data(f):
     @wraps(f)
     def newfunc(*args, **kwargs):
@@ -763,7 +766,6 @@
             fields = self._frb.keys()
         self._colorbar_valid = True
         for f in self.fields:
-            md = self.get_metadata(f, strip_mathml = False, return_string = False)
             axis_index = self.data_source.axis
 
             if self.origin == 'center-window':
@@ -781,7 +783,11 @@
                 raise RuntimeError(
                     'origin keyword: \"%(k)s\" not recognized' % {'k': self.origin})
 
-            (unit_x, unit_y) = md['axes_unit_names']
+            if self._axes_unit_names is None:
+                unit = get_smallest_appropriate_unit(self.xlim[1] - self.xlim[0], self.pf)
+                (unit_x, unit_y) = (unit, unit)
+            else:
+                (unit_x, unit_y) = self._axes_unit_names
 
             extentx = [(self.xlim[i] - xc) * self.pf[unit_x] for i in (0,1)]
             extenty = [(self.ylim[i] - yc) * self.pf[unit_y] for i in (0,1)]
@@ -807,8 +813,11 @@
             # Correct the aspect ratio in case unit_x and unit_y are different
             aspect = self.pf[unit_x]/self.pf[unit_y]
             
-            self.plots[f] = WindowPlotMPL(self._frb[f], extent, aspect, self._field_transform[f], 
-                                          self._colormaps[f], size, zlim)
+            image = self._frb[f]
+
+            self.plots[f] = WindowPlotMPL(image, self._field_transform[f].name, 
+                                          self._colormaps[f], extent, aspect, 
+                                          zlim, size)
 
             self.plots[f].cb = self.plots[f].figure.colorbar(
                 self.plots[f].image, cax = self.plots[f].cax)
@@ -830,29 +839,15 @@
 
             self.plots[f].axes.tick_params(labelsize=self.fontsize)
 
-            field_name = self.data_source.pf.field_info[f].display_name
+            colorbar_label = image.info['label']
 
-            if field_name is None:
-                field_name = r'$\rm{'+f+r'}$'
-            elif field_name.find('$') == -1:
-                field_name = r'$\rm{'+field_name+r'}$'
-            
             parser = MathTextParser('Agg')
             try:
-                parser.parse(field_name)
+                parser.parse(colorbar_label)
             except ParseFatalException, err:
-                raise YTCannotParseFieldDisplayName(f,field_name,str(err))
-
-            if md['colorbar_unit'] is None or md['colorbar_unit'] == '':
-                label = field_name
-            else:
-                try:
-                    parser.parse(r'$'+md['colorbar_unit']+r'$')
-                except ParseFatalException, err:
-                    raise YTCannotParseUnitDisplayName(f, md['colorbar_unit'],str(err))
-                label = field_name+r'$\/\/('+md['colorbar_unit']+r')$'
-
-            self.plots[f].cb.set_label(label,fontsize=self.fontsize)
+                raise YTCannotParseUnitDisplayName(f, colorbar_label, str(err))
+                
+            self.plots[f].cb.set_label(colorbar_label, fontsize=self.fontsize)
 
             self.plots[f].cb.ax.tick_params(labelsize=self.fontsize)
 
@@ -1468,51 +1463,19 @@
         else:
             self._field_transform[field] = linear_transform
 
-class PlotMPL(object):
-    """A base class for all yt plots made using matplotlib.
-
-    """
-    datalabel = None
-    figure = None
-    def __init__(self, field, size):
-        self._plot_valid = True
+class WindowPlotMPL(ImagePlotMPL):
+    def __init__(self, data, cbname, cmap, extent, aspect, zlim, size):
         fsize, axrect, caxrect = self._get_best_layout(size)
-        
         if np.any(np.array(axrect) < 0):
-            self.figure = matplotlib.figure.Figure(figsize = size, 
-                                                   frameon = True)
-            self.axes = self.figure.add_axes((.07,.10,.8,.8))
-            self.cax = self.figure.add_axes((.87,.10,.04,.8))
             mylog.warning('The axis ratio of the requested plot is very narrow.  '
                           'There is a good chance the plot will not look very good, '
                           'consider making the plot manually using FixedResolutionBuffer '
                           'and matplotlib.')
-        else:
-            self.figure = matplotlib.figure.Figure(figsize = fsize, 
-                                                   frameon = True)
-            self.axes = self.figure.add_axes(axrect)
-            self.cax = self.figure.add_axes(caxrect)
-            
-    def save(self, name, mpl_kwargs, canvas = None):
-        suffix = get_image_suffix(name)
-        
-        if suffix == '':
-            suffix = '.png'
-            name = "%s%s" % (name, suffix)
-        mylog.info("Saving plot %s", name)
-        if suffix == ".png":
-            canvas = FigureCanvasAgg(self.figure)
-        elif suffix == ".pdf":
-            canvas = FigureCanvasPdf(self.figure)
-        elif suffix in (".eps", ".ps"):
-            canvas = FigureCanvasPS(self.figure)
-        else:
-            mylog.warning("Unknown suffix %s, defaulting to Agg", suffix)
-            canvas = FigureCanvasAgg(self.figure)
-
-
-        canvas.print_figure(name,**mpl_kwargs)
-        return name
+            axrect  = (0.07, 0.10, 0.80, 0.80)
+            caxrect = (0.87, 0.10, 0.04, 0.80)
+        ImagePlotMPL.__init__(self, fsize, axrect, caxrect, zlim)
+        self._init_image(data, cbname, cmap, extent, aspect)
+        self.image.axes.ticklabel_format(scilimits=(-2,3))
 
     def _get_best_layout(self, size):
         aspect = 1.0*size[0]/size[1]
@@ -1551,26 +1514,3 @@
         axrect = (text_buffx, text_bottomy, xfrac, yfrac )
         caxrect = (text_buffx+xfrac, text_bottomy, cbar_frac/4., yfrac )
         return newsize, axrect, caxrect
-
-    def _repr_png_(self):
-        canvas = FigureCanvasAgg(self.figure)
-        f = cStringIO.StringIO()
-        canvas.print_figure(f)
-        f.seek(0)
-        return f.read()
-
-class WindowPlotMPL(PlotMPL):
-    def __init__(self, data, extent, aspect, field_transform, cmap, size, zlim):
-        self.zmin, self.zmax = zlim
-        PlotMPL.__init__(self, data, size)
-        self.__init_image(data, extent, aspect, field_transform, cmap)
-
-    def __init_image(self, data, extent, aspect, field_transform, cmap):
-        if (field_transform.name == 'log10'):
-            norm = matplotlib.colors.LogNorm()
-        elif (field_transform.name == 'linear'):
-            norm = matplotlib.colors.Normalize()
-        self.image = self.axes.imshow(data, origin='lower', extent=extent,
-                                      norm=norm, vmin=self.zmin, aspect=aspect, 
-                                      vmax=self.zmax, cmap=cmap)
-        self.image.axes.ticklabel_format(scilimits=(-2,3))

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r bea5473873e824088584621372b1f3a6a70dbdc0 yt/visualization/tests/test_plotwindow.py
--- a/yt/visualization/tests/test_plotwindow.py
+++ b/yt/visualization/tests/test_plotwindow.py
@@ -1,28 +1,97 @@
-from yt.testing import *
-from yt.mods import SlicePlot, ProjectionPlot, \
-    OffAxisSlicePlot, OffAxisProjectionPlot
+"""
+Testsuite for PlotWindow class
+
+Author: Nathan Goldbaum <goldbaum at ucolick.org>
+Affiliation: UCSC Astronomy
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2012 Nathan Goldbaum.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
 import os
+import sys
+import tempfile
+import shutil
+from yt.testing import \
+    fake_random_pf
+from yt.mods import \
+    SlicePlot, ProjectionPlot, OffAxisSlicePlot, OffAxisProjectionPlot
+
+
+EXT_TO_TYPE = {
+    '.ps': 'PostScript document text conforming DSC level 3.0',
+    '.eps': 'PostScript document text conforming DSC level 3.0, type EPS',
+    '.pdf': 'PDF document, version 1.4',
+    '.png': 'PNG image data, 1070 x 1000, 8-bit/color RGBA, non-interlaced'
+}
+
 
 def setup():
+    """Test specific setup."""
     from yt.config import ytcfg
-    ytcfg["yt","__withintesting"] = "True"
+    ytcfg["yt", "__withintesting"] = "True"
 
-def teardown_func(fns):
-    for fn in fns:
-        os.remove(fn)
+
+def assert_fname(fname):
+    """Function that checks file type using libmagic"""
+    if fname is None:
+        return
+
+    try:
+        import magic
+    except ImportError:
+        # OS X doesn't come with libmagic
+        pass
+
+    if 'magic' in sys.modules:
+        ext = os.path.splitext(fname)[1]
+        mds = magic.open(magic.MAGIC_NONE)
+        mds.load()
+        magic_text = mds.file(fname)
+        mds.close()
+        assert magic_text == EXT_TO_TYPE[ext]
+
 
 def test_plotwindow():
-    pf = fake_random_pf(64)
-    fns = []
-    for dim in [0,1,2]:
-        slc = SlicePlot(pf, dim, 'Density')
-        fns.append(slc.save()[0])
-        prj = ProjectionPlot(pf, dim, 'Density')
-        fns.append(prj.save()[0])
-    normal = [1,1,1]
-    oaslc = OffAxisSlicePlot(pf, normal, 'Density')
-    fns.append(oaslc.save()[0])
-    oaprj = OffAxisProjectionPlot(pf, normal, 'Density')
-    fns.append(oaprj.save()[0])
-    teardown_func(fns)
-    
+    """Main test suite for PlotWindow."""
+    # Perform I/O in safe place instead of yt main dir
+    tmpdir = tempfile.mkdtemp()
+    curdir = os.getcwd()
+    os.chdir(tmpdir)
+
+    normal = [1, 1, 1]
+
+    test_pf = fake_random_pf(64)
+    test_flnms = [None, 'test.png', 'test.eps',
+                  'test.ps', 'test.pdf']
+    for fname in test_flnms:
+        for dim in [0, 1, 2]:
+            obj = SlicePlot(test_pf, dim, 'Density')
+            assert_fname(obj.save(fname)[0])
+
+            obj = ProjectionPlot(test_pf, dim, 'Density')
+            assert_fname(obj.save(fname)[0])
+
+        obj = OffAxisSlicePlot(test_pf, normal, 'Density')
+        assert_fname(obj.save(fname)[0])
+
+        obj = OffAxisProjectionPlot(test_pf, normal, 'Density')
+        assert_fname(obj.save(fname)[0])
+
+    os.chdir(curdir)
+    # clean up
+    shutil.rmtree(tmpdir)


https://bitbucket.org/yt_analysis/yt/commits/b90af0249db1/
Changeset:   b90af0249db1
Branch:      yt
User:        jzuhone
Date:        2013-01-12 16:28:32
Summary:     Merging
Affected #:  5 files

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r b90af0249db1f1fef85913ba2f58719ac8ff88f0 doc/install_script.sh
--- a/doc/install_script.sh
+++ b/doc/install_script.sh
@@ -399,6 +399,14 @@
     ( ${SHASUM} -c $1.sha512 2>&1 ) 1>> ${LOG_FILE} || do_exit
 }
 
+function get_ytdata
+{
+    echo "Downloading $1 from yt-project.org"
+    [ -e $1 ] && return
+    ${GETFILE} "http://yt-project.org/data/$1" || do_exit
+    ( ${SHASUM} -c $1.sha512 2>&1 ) 1>> ${LOG_FILE} || do_exit
+}
+
 ORIG_PWD=`pwd`
 
 if [ -z "${DEST_DIR}" ]
@@ -407,6 +415,13 @@
     exit 1
 fi
 
+# Get supplemental data.
+
+mkdir -p ${DEST_DIR}/data
+cd ${DEST_DIR}/data
+echo 'de6d8c6ea849f0206d219303329a0276b3cce7c051eec34377d42aacbe0a4f47ac5145eb08966a338ecddd2b83c8f787ca9956508ad5c39ee2088ad875166410  xray_emissivity.h5' > xray_emissivity.h5.sha512
+get_ytdata xray_emissivity.h5
+
 mkdir -p ${DEST_DIR}/src
 cd ${DEST_DIR}/src
 

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r b90af0249db1f1fef85913ba2f58719ac8ff88f0 yt/analysis_modules/spectral_integrator/api.py
--- a/yt/analysis_modules/spectral_integrator/api.py
+++ b/yt/analysis_modules/spectral_integrator/api.py
@@ -30,4 +30,8 @@
 
 from .spectral_frequency_integrator import \
     SpectralFrequencyIntegrator, \
-    create_table_from_textfiles
+    create_table_from_textfiles, \
+    EmissivityIntegrator, \
+    add_xray_emissivity_field, \
+    add_xray_luminosity_field, \
+    add_xray_photon_emissivity_field

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r b90af0249db1f1fef85913ba2f58719ac8ff88f0 yt/analysis_modules/spectral_integrator/spectral_frequency_integrator.py
--- a/yt/analysis_modules/spectral_integrator/spectral_frequency_integrator.py
+++ b/yt/analysis_modules/spectral_integrator/spectral_frequency_integrator.py
@@ -4,9 +4,11 @@
 
 Author: Matthew Turk <matthewturk at gmail.com>
 Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittons at origins.colorado.edu>
+Affiliation: Michigan State University
 Homepage: http://yt-project.org/
 License:
-  Copyright (C) 2007-2011 Matthew Turk.  All Rights Reserved.
+  Copyright (C) 2007-2012 Matthew Turk.  All Rights Reserved.
 
   This file is part of yt.
 
@@ -24,16 +26,20 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 
+from exceptions import IOError
+import h5py
 import numpy as np
+import os
 
 from yt.funcs import *
 
 from yt.data_objects.field_info_container import add_field
+from yt.utilities.exceptions import YTException
 from yt.utilities.linear_interpolators import \
-    UnilinearFieldInterpolator, \
-    BilinearFieldInterpolator, \
-    TrilinearFieldInterpolator
+    BilinearFieldInterpolator
 
+xray_data_version = 1
+    
 class SpectralFrequencyIntegrator(object):
     def __init__(self, table, field_names,
                  bounds, ev_bounds):
@@ -80,8 +86,8 @@
             return 10**interp(dd)
         add_field(name, function=frequency_bin_field,
                         projection_conversion="cm",
-                        units=r"\rm{ergs}\/\rm{cm}^{-3}\/\rm{s}^{-1}",
-                        projected_units=r"\rm{ergs}\/\rm{cm}^{-2}\/\rm{s}^{-1}")
+                        units=r"\rm{ergs}\ \rm{cm}^{-3}\ \rm{s}^{-1}",
+                        projected_units=r"\rm{ergs}\ \rm{cm}^{-2}\ \rm{s}^{-1}")
         return name
 
 def create_table_from_textfiles(pattern, rho_spec, e_spec, T_spec):
@@ -100,3 +106,304 @@
         table[ri,:,ei] = [float(l.split()[-1]) for l in open(pattern%(i+1)) if l[0] != "#"]
     return table
 
+class EnergyBoundsException(YTException):
+    def __init__(self, lower, upper):
+        self.lower = lower
+        self.upper = upper
+
+    def __str__(self):
+        return "Energy bounds are %e to %e keV." % \
+          (self.lower, self.upper)
+
+class ObsoleteDataException(YTException):
+    def __str__(self):
+        return "X-ray emissivity data is out of data.\nDownload the latest data from http://yt-project.org/data/xray_emissivity.h5 and move it to %s." % \
+          os.path.join(os.environ["YT_DEST"], "data", "xray_emissivity.h5")
+          
+class EmissivityIntegrator(object):
+    r"""Class for making X-ray emissivity fields with hdf5 data tables 
+    from Cloudy.
+    """
+    def __init__(self, filename=None):
+        r"""Initialize an EmissivityIntegrator object.
+
+        Keyword Parameters
+        ------------------
+        filename: string
+            Path to data file containing emissivity values.  If None,
+            a file called xray_emissivity.h5 is used.  This file contains 
+            emissivity tables for primordial elements and for metals at 
+            solar metallicity for the energy range 0.1 to 100 keV.
+            Default: None.
+            
+        """
+
+        default_filename = False
+        if filename is None:
+            filename = os.path.join(os.environ["YT_DEST"], 
+                                    "data", "xray_emissivity.h5")
+            default_filename = True
+
+        if not os.path.exists(filename):
+            raise IOError("File does not exist: %s." % filename)
+        only_on_root(mylog.info, "Loading emissivity data from %s." % filename)
+        in_file = h5py.File(filename, "r")
+        if "info" in in_file.attrs:
+            only_on_root(mylog.info, in_file.attrs["info"])
+        if default_filename and \
+          in_file.attrs["version"] < xray_data_version:
+            raise ObsoleteDataException()
+        else:
+            only_on_root(mylog.info, "X-ray emissivity data version: %s." % \
+                         in_file.attrs["version"])
+
+        for field in ["emissivity_primordial", "emissivity_metals",
+                      "log_nH", "log_T", "log_E"]:
+            setattr(self, field, in_file[field][:])
+        in_file.close()
+
+        E_diff = np.diff(self.log_E)
+        self.E_bins = \
+                  np.power(10, np.concatenate([self.log_E[:-1] - 0.5 * E_diff,
+                                               [self.log_E[-1] - 0.5 * E_diff[-1],
+                                                self.log_E[-1] + 0.5 * E_diff[-1]]]))
+        self.dnu = 2.41799e17 * np.diff(self.E_bins)
+
+    def _get_interpolator(self, data, e_min, e_max):
+        r"""Create an interpolator for total emissivity in a 
+        given energy range.
+
+        Parameters
+        ----------
+        e_min: float
+            the minimum energy in keV for the energy band.
+        e_min: float
+            the maximum energy in keV for the energy band.
+
+        """
+        if (e_min - self.E_bins[0]) / e_min < -1e-3 or \
+          (e_max - self.E_bins[-1]) / e_max > 1e-3:
+            raise EnergyBoundsException(np.power(10, self.E_bins[0]),
+                                        np.power(10, self.E_bins[-1]))
+        e_is, e_ie = np.digitize([e_min, e_max], self.E_bins)
+        e_is = np.clip(e_is - 1, 0, self.E_bins.size - 1)
+        e_ie = np.clip(e_ie, 0, self.E_bins.size - 1)
+
+        my_dnu = np.copy(self.dnu[e_is: e_ie])
+        # clip edge bins if the requested range is smaller
+        my_dnu[0] -= e_min - self.E_bins[e_is]
+        my_dnu[-1] -= self.E_bins[e_ie] - e_max
+
+        interp_data = (data[..., e_is:e_ie] * my_dnu).sum(axis=-1)
+        return BilinearFieldInterpolator(np.log10(interp_data),
+                                         [self.log_nH[0], self.log_nH[-1],
+                                          self.log_T[0],  self.log_T[-1]],
+                                         ["log_nH", "log_T"], truncate=True)
+
+def add_xray_emissivity_field(e_min, e_max, filename=None,
+                              with_metals=True,
+                              constant_metallicity=None):
+    r"""Create an X-ray emissivity field for a given energy range.
+
+    Parameters
+    ----------
+    e_min: float
+        the minimum energy in keV for the energy band.
+    e_min: float
+        the maximum energy in keV for the energy band.
+
+    Keyword Parameters
+    ------------------
+    filename: string
+        Path to data file containing emissivity values.  If None,
+        a file called xray_emissivity.h5 is used.  This file contains 
+        emissivity tables for primordial elements and for metals at 
+        solar metallicity for the energy range 0.1 to 100 keV.
+        Default: None.
+    with_metals: bool
+        If True, use the metallicity field to add the contribution from 
+        metals.  If False, only the emission from H/He is considered.
+        Default: True.
+    constant_metallicity: float
+        If specified, assume a constant metallicity for the emission 
+        from metals.  The *with_metals* keyword must be set to False 
+        to use this.
+        Default: None.
+
+    This will create a field named "Xray_Emissivity_{e_min}_{e_max}keV".
+    The units of the field are erg s^-1 cm^-3.
+
+    Examples
+    --------
+
+    >>> from yt.mods import *
+    >>> from yt.analysis_modules.spectral_integrator.api import *
+    >>> add_xray_emissivity_field(0.5, 2)
+    >>> pf = load(dataset)
+    >>> p = ProjectionPlot(pf, 'x', "Xray_Emissivity_0.5_2keV")
+    >>> p.save()
+
+    """
+
+    my_si = EmissivityIntegrator(filename=filename)
+
+    em_0 = my_si._get_interpolator(my_si.emissivity_primordial, e_min, e_max)
+    em_Z = None
+    if with_metals or constant_metallicity is not None:
+        em_Z = my_si._get_interpolator(my_si.emissivity_metals, e_min, e_max)
+
+    def _emissivity_field(field, data):
+        dd = {"log_nH" : np.log10(data["H_NumberDensity"]),
+              "log_T"   : np.log10(data["Temperature"])}
+
+        my_emissivity = np.power(10, em_0(dd))
+        if em_Z is not None:
+            if with_metals:
+                my_Z = data["Metallicity"]
+            elif constant_metallicity is not None:
+                my_Z = constant_metallicity
+            my_emissivity += my_Z * np.power(10, em_Z(dd))
+
+        return data["H_NumberDensity"]**2 * my_emissivity
+
+    field_name = "Xray_Emissivity_%s_%skeV" % (e_min, e_max)
+    add_field(field_name, function=_emissivity_field,
+              projection_conversion="cm",
+              display_name=r"\epsilon_{X}\ (%s-%s\ keV)" % (e_min, e_max),
+              units=r"\rm{erg}\ \rm{cm}^{-3}\ \rm{s}^{-1}",
+              projected_units=r"\rm{erg}\ \rm{cm}^{-2}\ \rm{s}^{-1}")
+    return field_name
+
+def add_xray_luminosity_field(e_min, e_max, filename=None,
+                              with_metals=True,
+                              constant_metallicity=None):
+    r"""Create an X-ray luminosity field for a given energy range.
+
+    Parameters
+    ----------
+    e_min: float
+        the minimum energy in keV for the energy band.
+    e_min: float
+        the maximum energy in keV for the energy band.
+
+    Keyword Parameters
+    ------------------
+    filename: string
+        Path to data file containing emissivity values.  If None,
+        a file called xray_emissivity.h5 is used.  This file contains 
+        emissivity tables for primordial elements and for metals at 
+        solar metallicity for the energy range 0.1 to 100 keV.
+        Default: None.
+    with_metals: bool
+        If True, use the metallicity field to add the contribution from 
+        metals.  If False, only the emission from H/He is considered.
+        Default: True.
+    constant_metallicity: float
+        If specified, assume a constant metallicity for the emission 
+        from metals.  The *with_metals* keyword must be set to False 
+        to use this.
+        Default: None.
+
+    This will create a field named "Xray_Luminosity_{e_min}_{e_max}keV".
+    The units of the field are erg s^-1.
+
+    Examples
+    --------
+
+    >>> from yt.mods import *
+    >>> from yt.analysis_modules.spectral_integrator.api import *
+    >>> add_xray_luminosity_field(0.5, 2)
+    >>> pf = load(dataset)
+    >>> sp = pf.h.sphere('max', (2., 'mpc'))
+    >>> print sp.quantities['TotalQuantity']('Xray_Luminosity_0.5_2keV')
+    
+    """
+
+    em_field = add_xray_emissivity_field(e_min, e_max, filename=filename,
+                                         with_metals=with_metals,
+                                         constant_metallicity=constant_metallicity)
+
+    def _luminosity_field(field, data):
+        return data[em_field] * data["CellVolume"]
+    field_name = "Xray_Luminosity_%s_%skeV" % (e_min, e_max)
+    add_field(field_name, function=_luminosity_field,
+              display_name=r"\rm{L}_{X}\ (%s-%s\ keV)" % (e_min, e_max),
+              units=r"\rm{erg}\ \rm{s}^{-1}")
+    return field_name
+
+def add_xray_photon_emissivity_field(e_min, e_max, filename=None,
+                                     with_metals=True,
+                                     constant_metallicity=None):
+    r"""Create an X-ray photon emissivity field for a given energy range.
+
+    Parameters
+    ----------
+    e_min: float
+        the minimum energy in keV for the energy band.
+    e_min: float
+        the maximum energy in keV for the energy band.
+
+    Keyword Parameters
+    ------------------
+    filename: string
+        Path to data file containing emissivity values.  If None,
+        a file called xray_emissivity.h5 is used.  This file contains 
+        emissivity tables for primordial elements and for metals at 
+        solar metallicity for the energy range 0.1 to 100 keV.
+        Default: None.
+    with_metals: bool
+        If True, use the metallicity field to add the contribution from 
+        metals.  If False, only the emission from H/He is considered.
+        Default: True.
+    constant_metallicity: float
+        If specified, assume a constant metallicity for the emission 
+        from metals.  The *with_metals* keyword must be set to False 
+        to use this.
+        Default: None.
+
+    This will create a field named "Xray_Photon_Emissivity_{e_min}_{e_max}keV".
+    The units of the field are photons s^-1 cm^-3.
+
+    Examples
+    --------
+
+    >>> from yt.mods import *
+    >>> from yt.analysis_modules.spectral_integrator.api import *
+    >>> add_xray_emissivity_field(0.5, 2)
+    >>> pf = load(dataset)
+    >>> p = ProjectionPlot(pf, 'x', "Xray_Emissivity_0.5_2keV")
+    >>> p.save()
+
+    """
+
+    my_si = EmissivityIntegrator(filename=filename)
+    energy_erg = np.power(10, my_si.log_E) * 1.60217646e-9
+
+    em_0 = my_si._get_interpolator((my_si.emissivity_primordial[..., :] / energy_erg),
+                                   e_min, e_max)
+    em_Z = None
+    if with_metals or constant_metallicity is not None:
+        em_Z = my_si._get_interpolator((my_si.emissivity_metals[..., :] / energy_erg),
+                                       e_min, e_max)
+
+    def _emissivity_field(field, data):
+        dd = {"log_nH" : np.log10(data["H_NumberDensity"]),
+              "log_T"   : np.log10(data["Temperature"])}
+
+        my_emissivity = np.power(10, em_0(dd))
+        if em_Z is not None:
+            if with_metals:
+                my_Z = data["Metallicity"]
+            elif constant_metallicity is not None:
+                my_Z = constant_metallicity
+            my_emissivity += my_Z * np.power(10, em_Z(dd))
+
+        return data["H_NumberDensity"]**2 * my_emissivity
+
+    field_name = "Xray_Photon_Emissivity_%s_%skeV" % (e_min, e_max)
+    add_field(field_name, function=_emissivity_field,
+              projection_conversion="cm",
+              display_name=r"\epsilon_{X}\ (%s-%s\ keV)" % (e_min, e_max),
+              units=r"\rm{photons}\ \rm{cm}^{-3}\ \rm{s}^{-1}",
+              projected_units=r"\rm{photons}\ \rm{cm}^{-2}\ \rm{s}^{-1}")
+    return field_name

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r b90af0249db1f1fef85913ba2f58719ac8ff88f0 yt/data_objects/time_series.py
--- a/yt/data_objects/time_series.py
+++ b/yt/data_objects/time_series.py
@@ -258,9 +258,12 @@
         ...     SlicePlot(pf, "x", "Density").save()
 
         """
+        
         if isinstance(filenames, types.StringTypes):
             filenames = glob.glob(filenames)
             filenames.sort()
+        if len(filenames) == 0:
+            raise YTOutputNotIdentified(filenames, {})
         obj = cls(filenames[:], parallel = parallel, **kwargs)
         return obj
 

diff -r 18607c558f38ff5486530de13fe216c07426cc30 -r b90af0249db1f1fef85913ba2f58719ac8ff88f0 yt/frontends/flash/fields.py
--- a/yt/frontends/flash/fields.py
+++ b/yt/frontends/flash/fields.py
@@ -233,7 +233,7 @@
         mu = data.get_field_parameter("mu")
     else:
         mu = 0.6
-    return kboltz*data["Density"]*data["Temperature"]/(mu*mh) / (data.pf["Gamma"] - 1.0)
+    return kboltz*data["NumberDensity"]*data["Temperature"] / (data.pf["Gamma"] - 1.0)
     
 add_field("ThermalEnergy", function=_ThermalEnergy,
           units=r"\rm{ergs}/\rm{g}")
@@ -299,4 +299,34 @@
 add_field("DivB", function=_DivB, take_log=False,
           units=r"\rm{Gauss}\/\rm{cm}^{-1}")
 
+def _ConvertNumberDensity(data):
+    return 1.0/mh
 
+def _NumberDensity(field, data):
+    field_data = np.zeros(data["Density"].shape,
+                         dtype = data["Density"].dtype)
+    try:
+        mu = data.pf.parameters["eos_singleSpeciesA"]
+    except:
+        if data.has_field_parameter("mu"):
+            mu = data.get_field_parameter("mu")
+        else:
+            mu = 0.6
+        field_data += data["Density"] / mu
+    return field_data
+add_field("NumberDensity", units=r"\rm{cm}^{-3}",
+          function=_NumberDensity,
+          convert_function=_ConvertNumberDensity)
+
+def _H_NumberDensity(field, data):
+    field_data = np.zeros(data["Density"].shape,
+                          dtype=data["Density"].dtype)
+    if data.has_field_parameter("muh"):
+        muh = data.get_field_parameter("muh")
+    else:
+        muh = 0.75
+    field_data += data["Density"] / muh
+    return field_data
+add_field("H_NumberDensity", units=r"\rm{cm}^{-3}",
+          function=_H_NumberDensity,
+          convert_function=_ConvertNumberDensity)


https://bitbucket.org/yt_analysis/yt/commits/4190004c06a0/
Changeset:   4190004c06a0
Branch:      yt
User:        jzuhone
Date:        2013-01-12 16:31:39
Summary:     Merging
Affected #:  37 files
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/f3b4fcb6ba47/
Changeset:   f3b4fcb6ba47
Branch:      yt
User:        jzuhone
Date:        2013-01-22 02:59:54
Summary:     Merged yt_analysis/yt into yt
Affected #:  11 files
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/1ef8ad7f9081/
Changeset:   1ef8ad7f9081
Branch:      yt
User:        jzuhone
Date:        2013-02-10 07:02:47
Summary:     Merged yt_analysis/yt into yt
Affected #:  51 files
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/9ca5bb56ea08/
Changeset:   9ca5bb56ea08
Branch:      yt
User:        jzuhone
Date:        2013-02-12 18:00:29
Summary:     Simple FLASH answer tests. This is just to get the answer testing framework for FLASH data going, more will be added later.
Affected #:  1 file
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/813b806f980e/
Changeset:   813b806f980e
Branch:      yt
User:        jzuhone
Date:        2013-02-16 04:55:27
Summary:     Merged yt_analysis/yt into yt
Affected #:  62 files
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/700cd9eb832e/
Changeset:   700cd9eb832e
Branch:      yt
User:        jzuhone
Date:        2013-03-18 17:15:18
Summary:     Merged yt_analysis/yt into yt
Affected #:  78 files
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/ea7c50bf715d/
Changeset:   ea7c50bf715d
Branch:      yt
User:        jzuhone
Date:        2013-03-01 19:56:15
Summary:     Merging
Affected #:  108 files
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/9c0c43085bd9/
Changeset:   9c0c43085bd9
Branch:      yt
User:        jzuhone
Date:        2013-03-18 17:16:03
Summary:     Merging
Affected #:  78 files
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/513c90a4e35b/
Changeset:   513c90a4e35b
Branch:      yt
User:        jzuhone
Date:        2013-04-02 19:19:22
Summary:     Generalize to allow reading of grids on different levels.
Affected #:  1 file
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/3932d7a98908/
Changeset:   3932d7a98908
Branch:      yt
User:        jzuhone
Date:        2013-04-11 16:15:46
Summary:     More work on the Athena frontend.

1) Fully supporting static mesh refinement. Allowing the user to input conversion factors since Athena doesn't have any.
2) Attempting to cover all cases of derived fields, whether the dataset is in primitive or conservative form.
Affected #:  3 files
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/998650da73cd/
Changeset:   998650da73cd
Branch:      yt
User:        jzuhone
Date:        2013-04-11 16:17:43
Summary:     Merged yt_analysis/yt into yt
Affected #:  20 files
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/7eb7944931a2/
Changeset:   7eb7944931a2
Branch:      yt
User:        jzuhone
Date:        2013-05-07 18:41:34
Summary:     Merging
Affected #:  24 files
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/244feb766e2d/
Changeset:   244feb766e2d
Branch:      yt
User:        jzuhone
Date:        2013-05-07 18:43:02
Summary:     Fixing whitespace
Affected #:  1 file
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/d4a053ac5de6/
Changeset:   d4a053ac5de6
Branch:      yt
User:        jzuhone
Date:        2013-05-07 19:31:17
Summary:     Conversion factors for when units are not provided. Defined AthenaGrid's __repr__.
Affected #:  1 file
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/ba38721b1a0c/
Changeset:   ba38721b1a0c
Branch:      yt
User:        jzuhone
Date:        2013-05-07 20:30:57
Summary:     Reverting install script commit
Affected #:  2 files
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/5845923bd2ac/
Changeset:   5845923bd2ac
Branch:      yt
User:        jzuhone
Date:        2013-05-07 20:33:20
Summary:     Merged yt_analysis/yt into yt
Affected #:  1 file
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/10a41180c51d/
Changeset:   10a41180c51d
Branch:      yt
User:        jzuhone
Date:        2013-05-07 20:36:15
Summary:     Removing unnecessary print statements.
Affected #:  1 file
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/0d423cd34e75/
Changeset:   0d423cd34e75
Branch:      yt
User:        jzuhone
Date:        2013-05-07 20:36:31
Summary:     Merging
Affected #:  1 file
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/3653da492f99/
Changeset:   3653da492f99
Branch:      yt
User:        jzuhone
Date:        2013-05-07 20:37:51
Summary:     Changed copyright date.
Affected #:  1 file
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/d8d1d45dfde0/
Changeset:   d8d1d45dfde0
Branch:      yt
User:        jzuhone
Date:        2013-05-07 20:40:43
Summary:     Fixing affiliations
Affected #:  1 file
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/392feac977ce/
Changeset:   392feac977ce
Branch:      yt
User:        jzuhone
Date:        2013-05-07 21:58:21
Summary:     Forgot the magnetic field
Affected #:  1 file
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/b0d1232c9ead/
Changeset:   b0d1232c9ead
Branch:      yt
User:        jzuhone
Date:        2013-05-09 16:48:15
Summary:     Changing default scales of fields to linear. Replacing try...except with if...then.
Affected #:  1 file
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/823c608e0fd5/
Changeset:   823c608e0fd5
Branch:      yt
User:        jzuhone
Date:        2013-05-09 17:58:49
Summary:     Fixing typo
Affected #:  1 file
Diff not available.

https://bitbucket.org/yt_analysis/yt/commits/c3fb92bd4c79/
Changeset:   c3fb92bd4c79
Branch:      yt
User:        samskillman
Date:        2013-05-11 17:13:16
Summary:     Merged in jzuhone/yt (pull request #490)

Important Updates to the Athena Frontend
Affected #:  4 files
Diff not available.

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