[Yt-svn] commit/yt: 2 new changesets

Bitbucket commits-noreply at bitbucket.org
Fri Jul 29 12:52:53 PDT 2011


2 new changesets in yt:

http://bitbucket.org/yt_analysis/yt/changeset/91b117ca654b/
changeset:   91b117ca654b
branch:      yt
user:        brittonsmith
date:        2011-07-29 21:52:35
summary:     Removed derived dust temperature field.
affected #:  1 file (404 bytes)

--- a/yt/frontends/enzo/fields.py	Mon Jul 25 09:53:27 2011 -0400
+++ b/yt/frontends/enzo/fields.py	Fri Jul 29 15:52:35 2011 -0400
@@ -213,7 +213,7 @@
 _default_fields = ["Density","Temperature",
                    "x-velocity","y-velocity","z-velocity",
                    "x-momentum","y-momentum","z-momentum",
-                   "Bx", "By", "Bz", "Dust_Temperature_Density"]
+                   "Bx", "By", "Bz", "Dust_Temperature"]
 # else:
 #     _default_fields = ["Density","Temperature","Gas_Energy","Total_Energy",
 #                        "x-velocity","y-velocity","z-velocity"]
@@ -246,6 +246,8 @@
 
 EnzoFieldInfo["Temperature"]._units = r"\rm{K}"
 EnzoFieldInfo["Temperature"].units = r"K"
+EnzoFieldInfo["Dust_Temperature"]._units = r"\rm{K}"
+EnzoFieldInfo["Dust_Temperature"].units = r"K"
 
 def _convertVelocity(data):
     return data.convert("x-velocity")
@@ -255,17 +257,6 @@
     f._convert_function = _convertVelocity
     f.take_log = False
 
-# Dust temperature - raw field is T_dust * Density
-def _dust_temperature(field, data):
-    return data['Dust_Temperature_Density'] / data['Density']
-def _convert_dust_temperature(data):
-    ef = (1.0 + data.pf.current_redshift)**3.0
-    return data.convert("Density") / ef
-add_field("Dust_Temperature", function=_dust_temperature, 
-          convert_function=_convert_dust_temperature, take_log=True,
-          validators=[ValidateDataField('Dust_Temperature_Density')],
-          units = r"K")
-
 def _spdensity(field, data):
     blank = na.zeros(data.ActiveDimensions, dtype='float32')
     if data.NumberOfParticles == 0: return blank


http://bitbucket.org/yt_analysis/yt/changeset/26614b0e924b/
changeset:   26614b0e924b
branch:      yt
user:        brittonsmith
date:        2011-07-29 21:52:48
summary:     Merged.
affected #:  22 files (49.0 KB)

--- a/yt/analysis_modules/halo_finding/halo_objects.py	Fri Jul 29 15:52:35 2011 -0400
+++ b/yt/analysis_modules/halo_finding/halo_objects.py	Fri Jul 29 15:52:48 2011 -0400
@@ -228,7 +228,8 @@
         r"""Returns a sphere source.
 
         This will generate a new, empty sphere source centered on this halo,
-        with the maximum radius of the halo.
+        with the maximum radius of the halo. This can be used like any other
+        data container in yt.
         
         Parameters
         ----------
@@ -974,6 +975,34 @@
         """
         return self.max_radius
 
+    def get_sphere(self):
+        r"""Returns a sphere source.
+
+        This will generate a new, empty sphere source centered on this halo,
+        with the maximum radius of the halo. This can be used like any other
+        data container in yt.
+        
+        Parameters
+        ----------
+        center_of_mass : bool, optional
+            True chooses the center of mass when calculating the maximum radius.
+            False chooses from the maximum density location for HOP halos
+            (it has no effect for FOF halos).
+            Default = True.
+        
+        Returns
+        -------
+        sphere : `yt.data_objects.api.AMRSphereBase`
+            The empty data source.
+
+        Examples
+        --------
+        >>> sp = halos[0].get_sphere()
+        """
+        cen = self.center_of_mass()
+        r = self.maximum_radius()
+        return self.pf.h.sphere(cen, r)
+
 class HaloList(object):
 
     _fields = ["particle_position_%s" % ax for ax in 'xyz']
@@ -1337,7 +1366,11 @@
         locations = []
         for line in lines:
             line = line.split()
-            locations.append(line[1:])
+            # Prepend the hdf5 file names with the full path.
+            temp = []
+            for item in line[1:]:
+                temp.append(self.pf.fullpath + '/' + item)
+            locations.append(temp)
         lines.close()
         return locations
 
@@ -2216,4 +2249,4 @@
         LoadedHaloList.__init__(self, pf, self.basename)
 
 
-        
\ No newline at end of file
+        


--- a/yt/data_objects/grid_patch.py	Fri Jul 29 15:52:35 2011 -0400
+++ b/yt/data_objects/grid_patch.py	Fri Jul 29 15:52:48 2011 -0400
@@ -54,12 +54,13 @@
                  'start_index', 'filename', '__weakref__', 'dds',
                  '_child_mask', '_child_indices', '_child_index_mask',
                  '_parent_id', '_children_ids']
-    def __init__(self, id, filename = None, hierarchy = None):
+
+    def __init__(self, id, filename=None, hierarchy=None):
         self.data = {}
         self.field_parameters = {}
         self.id = id
         if hierarchy: self.hierarchy = weakref.proxy(hierarchy)
-        self.pf = self.hierarchy.parameter_file # weakref already
+        self.pf = self.hierarchy.parameter_file  # weakref already
         self._child_mask = self._child_indices = self._child_index_mask = None
         self.start_index = None
 
@@ -67,6 +68,7 @@
         """
         Return the integer starting index for each dimension at the current
         level.
+
         """
         if self.start_index != None:
             return self.start_index
@@ -161,7 +163,7 @@
 
     def keys(self):
         return self.data.keys()
-    
+
     def get_data(self, field):
         """
         Returns a field or set of fields for a key or set of keys
@@ -230,7 +232,7 @@
         cond = na.logical_and(cond, self.RightEdge[y] >= LE[:,y])
         cond = na.logical_and(cond, self.LeftEdge[y] <= RE[:,y])
         return cond
-   
+
     def __repr__(self):
         return "AMRGridPatch_%04i" % (self.id)
 
@@ -373,7 +375,7 @@
         mask[startIndex[0]:endIndex[0],
              startIndex[1]:endIndex[1],
              startIndex[2]:endIndex[2]] = tofill
-        
+
     def __generate_child_mask(self):
         """
         Generates self.child_mask, which is zero where child grids exist (and
@@ -475,7 +477,7 @@
             na.multiply(new_field, 0.125, new_field)
             if self.pf.field_info[field].take_log:
                 new_field = na.log10(new_field)
-            
+
             new_field[:,:, -1] = 2.0*new_field[:,:,-2] - new_field[:,:,-3]
             new_field[:,:, 0]  = 2.0*new_field[:,:,1] - new_field[:,:,2]
 


--- a/yt/data_objects/static_output.py	Fri Jul 29 15:52:35 2011 -0400
+++ b/yt/data_objects/static_output.py	Fri Jul 29 15:52:48 2011 -0400
@@ -47,11 +47,11 @@
     class __metaclass__(type):
         def __init__(cls, name, b, d):
             type.__init__(cls, name, b, d)
-            output_type_registry[name]=cls
+            output_type_registry[name] = cls
             mylog.debug("Registering: %s as %s", name, cls)
 
     def __new__(cls, filename=None, *args, **kwargs):
-        if not isinstance(filename, types.StringTypes): 
+        if not isinstance(filename, types.StringTypes):
             obj = object.__new__(cls)
             obj.__init__(filename, *args, **kwargs)
             return obj
@@ -69,21 +69,27 @@
         """
         self.data_style = data_style
         self.file_style = file_style
+        self.conversion_factors = {}
+        self.parameters = {}
+
+        # path stuff
         self.parameter_filename = str(filename)
         self.basename = os.path.basename(filename)
         self.directory = os.path.expanduser(os.path.dirname(filename))
         self.fullpath = os.path.abspath(self.directory)
-        self._instantiated = time.time()
         if len(self.directory) == 0:
             self.directory = "."
-        self.conversion_factors = {}
-        self.parameters = {}
+
+        # to get the timing right, do this before the heavy lifting
+        self._instantiated = time.time()
+
         self._parse_parameter_file()
         self._set_units()
+
         # Because we need an instantiated class to check the pf's existence in
         # the cache, we move that check to here from __new__.  This avoids
         # double-instantiation.
-        if ytcfg.getboolean('yt','serialize'):
+        if ytcfg.getboolean('yt', 'serialize'):
             try:
                 _pf_store.check_pf(self)
             except NoParameterShelf:
@@ -111,9 +117,7 @@
         return False
 
     def __getitem__(self, key):
-        """
-        Returns _units, parameters, or _conversion_factors in that order
-        """
+        """ Returns units, parameters, or conversion_factors in that order. """
         for d in [self.units, self.time_units, self.parameters, \
                   self.conversion_factors]:
             if key in d: return d[key]
@@ -121,8 +125,9 @@
 
     def keys(self):
         """
-        Returns a list of possible keys, from _units, parameters and
-        _conversion_factors
+        Returns a list of possible keys, from units, parameters and
+        conversion_factors.
+
         """
         return self.units.keys() \
              + self.time_units.keys() \
@@ -137,7 +142,7 @@
     def get_smallest_appropriate_unit(self, v):
         max_nu = 1e30
         good_u = None
-        for unit in ['mpc','kpc','pc','au','rsun','cm']:
+        for unit in ['mpc', 'kpc', 'pc', 'au', 'rsun', 'cm']:
             vv = v*self[unit]
             if vv < max_nu and vv > 1.0:
                 good_u = unit
@@ -146,7 +151,8 @@
 
     def has_key(self, key):
         """
-        Returns true or false
+        Checks units, parameters, and conversion factors. Returns a boolean.
+
         """
         return key in self.units or \
                key in self.time_units or \
@@ -162,19 +168,19 @@
             self._instantiated_hierarchy = self._hierarchy_class(
                 self, data_style=self.data_style)
         return self._instantiated_hierarchy
-    h = hierarchy
+    h = hierarchy  # alias
 
     @parallel_root_only
     def print_key_parameters(self):
         for a in ["current_time", "domain_dimensions", "domain_left_edge",
-                 "domain_right_edge", "cosmological_simulation"]:
+                  "domain_right_edge", "cosmological_simulation"]:
             if not hasattr(self, a):
                 mylog.error("Missing %s in parameter file definition!", a)
                 continue
             v = getattr(self, a)
             mylog.info("Parameters: %-25s = %s", a, v)
         if hasattr(self, "cosmological_simulation") and \
-            getattr(self, "cosmological_simulation"):
+           getattr(self, "cosmological_simulation"):
             for a in ["current_redshift", "omega_lambda", "omega_matter",
                       "hubble_constant"]:
                 if not hasattr(self, a):


--- a/yt/frontends/castro/data_structures.py	Fri Jul 29 15:52:35 2011 -0400
+++ b/yt/frontends/castro/data_structures.py	Fri Jul 29 15:52:48 2011 -0400
@@ -1,5 +1,5 @@
 """
-Data structures for Castro. 
+Data structures for Castro.
 
 Author: J. S. Oishi <jsoishi at gmail.com>
 Affiliation: KIPAC/SLAC/Stanford
@@ -69,7 +69,7 @@
         self.filename = filename
         self._offset = offset
         self._paranoid = paranoia
-        
+
         # should error check this
         self.ActiveDimensions = (dimensions.copy()).astype('int32')#.transpose()
         self.start_index = start.copy()#.transpose()
@@ -134,14 +134,14 @@
         #self._setup_classes()
 
         # This also sets up the grid objects
-        self.read_global_header(header_filename, self.parameter_file.paranoid_read) 
+        self.read_global_header(header_filename, self.parameter_file.paranoid_read)
         self.read_particle_header()
         self.__cache_endianness(self.levels[-1].grids[-1])
         AMRHierarchy.__init__(self, pf, self.data_style)
         self._setup_data_io()
         self._setup_field_list()
         self._populate_hierarchy()
-        
+
     def read_global_header(self, filename, paranoid_read):
         """
         read the global header file for an Castro plotfile output.
@@ -280,7 +280,7 @@
             self.num_grids = grid_counter
             self.float_type = 'float64'
 
-        self.maxLevel = self.n_levels - 1 
+        self.maxLevel = self.n_levels - 1
         self.max_level = self.n_levels - 1
         header_file.close()
 
@@ -320,7 +320,7 @@
         header = inFile.readline()
         inFile.close()
         header.strip()
-        
+
         # parse it. the patter is in CastroDefs.py
         headerRe = re.compile(castro_FAB_header_pattern)
         bytesPerReal, endian, start, stop, centerType, nComponents = headerRe.search(header).groups()
@@ -340,7 +340,7 @@
         stop = na.array(map(int, start_stop[1].split(',')))
         dimension = stop - start + 1
         return dimension, start, stop
-        
+
     def _populate_grid_objects(self):
         mylog.debug("Creating grid objects")
         self.grids = na.concatenate([level.grids for level in self.levels])
@@ -437,7 +437,7 @@
                         particle_type=True)
 
     def _count_grids(self):
-        """this is already provided in 
+        """this is already provided in
 
         """
         pass
@@ -452,7 +452,7 @@
 
     def _parse_hierarchy(self):
         pass
-    
+
     def _detect_fields(self):
         pass
 
@@ -482,13 +482,13 @@
         self._data_file = None
         self._data_mode = None
         self._max_locations = {}
-    
+
 class CastroLevel:
     def __init__(self, level, ngrids):
         self.level = level
         self.ngrids = ngrids
         self.grids = []
-    
+
 
 class CastroStaticOutput(StaticOutput):
     """
@@ -551,10 +551,12 @@
         pfn = os.path.join(pfname)
         if not os.path.exists(pfn): return False
         castro = any(("castro." in line for line in open(pfn)))
+        nyx = any(("nyx." in line for line in open(pfn)))
+        castro = castro and (not nyx) # it's only castro if it's not nyx
         maestro = os.path.exists(os.path.join(pname, "job_info"))
         orion = (not castro) and (not maestro)
         return castro
-        
+
     def _parse_parameter_file(self):
         """
         Parses the parameter file and establishes the various
@@ -596,7 +598,7 @@
                         self.parameters[paramName] = t[0]
                     else:
                         self.parameters[paramName] = t
-                
+
             elif param.startswith("geometry.prob_hi"):
                 self.domain_right_edge = \
                     na.array([float(i) for i in vals.split()])
@@ -649,7 +651,7 @@
         """
         Parses the BoxLib header file to get any parameters stored
         there. Hierarchy information is read out of this file in
-        CastroHierarchy. 
+        CastroHierarchy.
 
         Currently, only Time is read here.
         """
@@ -660,7 +662,7 @@
         self.current_time = float(lines[3+n_fields])
 
 
-                
+
     def _set_units(self):
         """
         Generates the conversion to various physical _units based on the parameter file
@@ -680,7 +682,7 @@
             self.conversion_factors["Time"] = 1.0
         for unit in mpc_conversion.keys():
             self.units[unit] = mpc_conversion[unit] / mpc_conversion["cm"]
-        
+
         self.conversion_factors = defaultdict(lambda: 1.0)
         self.time_units['1'] = 1
         self.units['1'] = 1.0


--- a/yt/frontends/castro/definitions.py	Fri Jul 29 15:52:35 2011 -0400
+++ b/yt/frontends/castro/definitions.py	Fri Jul 29 15:52:48 2011 -0400
@@ -5,7 +5,7 @@
 Affiliation: KIPAC/SLAC/Stanford
 Homepage: http://yt.enzotools.org/
 License:
-  Copyright (C) 2008-20010 J.S. Oishi.  All Rights Reserved.
+  Copyright (C) 2008-2010 J.S. Oishi.  All Rights Reserved.
 
   This file is part of yt.
 
@@ -89,4 +89,4 @@
 castro_particle_field_names = \
     ['particle_position_%s' % ax for ax in 'xyz'] + \
     ['particle_mass'] +  \
-    ['particle_velocity_%s' % ax for ax in 'xyz'] 
+    ['particle_velocity_%s' % ax for ax in 'xyz']


--- a/yt/frontends/chombo/fields.py	Fri Jul 29 15:52:35 2011 -0400
+++ b/yt/frontends/chombo/fields.py	Fri Jul 29 15:52:48 2011 -0400
@@ -41,39 +41,38 @@
 add_field = add_chombo_field
 
 add_field("density", function=lambda a,b: None, take_log=True,
-          validators = [ValidateDataField("density")],
-          units=r"\rm{g}/\rm{cm}^3")
-
+          validators=[ValidateDataField("density")],
+          units=r"\rm{g} / \rm{cm}^3")
 ChomboFieldInfo["density"]._projected_units =r"\rm{g}/\rm{cm}^2"
 
 add_field("X-momentum", function=lambda a,b: None, take_log=False,
-          validators = [ValidateDataField("X-Momentum")],
-          units=r"",display_name=r"B_x")
+          validators=[ValidateDataField("X-Momentum")],
+          units=r"", display_name=r"x momentum")
 ChomboFieldInfo["X-momentum"]._projected_units=r""
 
 add_field("Y-momentum", function=lambda a,b: None, take_log=False,
-          validators = [ValidateDataField("Y-Momentum")],
-          units=r"",display_name=r"B_y")
+          validators=[ValidateDataField("Y-Momentum")],
+          units=r"", display_name=r"y momentum")
 ChomboFieldInfo["Y-momentum"]._projected_units=r""
 
 add_field("Z-momentum", function=lambda a,b: None, take_log=False,
-          validators = [ValidateDataField("Z-Momentum")],
-          units=r"",display_name=r"B_z")
+          validators=[ValidateDataField("Z-Momentum")],
+          units=r"", display_name=r"z momentum")
 ChomboFieldInfo["Z-momentum"]._projected_units=r""
 
 add_field("X-magnfield", function=lambda a,b: None, take_log=False,
-          validators = [ValidateDataField("X-Magnfield")],
-          units=r"",display_name=r"B_x")
+          validators=[ValidateDataField("X-Magnfield")],
+          units=r"", display_name=r"B_x")
 ChomboFieldInfo["X-magnfield"]._projected_units=r""
 
 add_field("Y-magnfield", function=lambda a,b: None, take_log=False,
-          validators = [ValidateDataField("Y-Magnfield")],
-          units=r"",display_name=r"B_y")
+          validators=[ValidateDataField("Y-Magnfield")],
+          units=r"", display_name=r"B_y")
 ChomboFieldInfo["Y-magnfield"]._projected_units=r""
 
 add_field("Z-magnfield", function=lambda a,b: None, take_log=False,
-          validators = [ValidateDataField("Z-Magnfield")],
-          units=r"",display_name=r"B_z")
+          validators=[ValidateDataField("Z-Magnfield")],
+          units=r"", display_name=r"B_z")
 ChomboFieldInfo["Z-magnfield"]._projected_units=r""
 
 def _MagneticEnergy(field,data):
@@ -81,21 +80,17 @@
             data["Y-magnfield"]**2 +
             data["Z-magnfield"]**2)/2.
 add_field("MagneticEnergy", function=_MagneticEnergy, take_log=True,
-          units=r"",display_name=r"B^2/8\pi")
+          units=r"", display_name=r"B^2 / 8 \pi")
 ChomboFieldInfo["MagneticEnergy"]._projected_units=r""
 
 def _xVelocity(field, data):
-    """generate x-velocity from x-momentum and density
-
-    """
+    """ Generate x-velocity from x-momentum and density. """
     return data["X-momentum"]/data["density"]
 add_field("x-velocity",function=_xVelocity, take_log=False,
           units=r'\rm{cm}/\rm{s}')
 
 def _yVelocity(field,data):
-    """generate y-velocity from y-momentum and density
-
-    """
+    """ Generate y-velocity from y-momentum and density. """
     #try:
     #    return data["xvel"]
     #except KeyError:
@@ -104,10 +99,7 @@
           units=r'\rm{cm}/\rm{s}')
 
 def _zVelocity(field,data):
-    """generate z-velocity from z-momentum and density
-
-    """
+    """ Generate z-velocity from z-momentum and density. """
     return data["Z-momentum"]/data["density"]
 add_field("z-velocity",function=_zVelocity, take_log=False,
           units=r'\rm{cm}/\rm{s}')
-    


--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/yt/frontends/nyx/api.py	Fri Jul 29 15:52:48 2011 -0400
@@ -0,0 +1,29 @@
+"""
+API for yt.frontends.nyx
+
+Author: Casey W. Stark <caseywstark at gmail.com>
+Affiliation: UC Berkeley
+Homepage: http://yt.enzotools.org/
+License:
+  Copyright (C) 2011 Casey W. Stark, Matthew Turk.  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/>.
+
+"""
+
+from .data_structures import NyxGrid, NyxHierarchy, NyxStaticOutput
+from .fields import NyxFieldContainer, nyx_fields, add_nyx_field
+from .io import IOHandlerNative


--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/yt/frontends/nyx/data_structures.py	Fri Jul 29 15:52:48 2011 -0400
@@ -0,0 +1,759 @@
+"""
+Data structures for Nyx.
+
+Author: Casey W. Stark <caseywstark at gmail.com>
+Affiliation: UC Berkeley
+Author: J. S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Homepage: http://yt.enzotools.org/
+License:
+  Copyright (C) 2011 Casey W. Stark, J. S. Oishi, Matthew Turk.  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/>.
+
+"""
+
+from collections import defaultdict
+import itertools
+import os
+import re
+from stat import ST_CTIME
+from string import strip, rstrip
+import weakref
+
+import numpy as na
+
+from yt.funcs import *
+from yt.data_objects.grid_patch import AMRGridPatch
+from yt.data_objects.hierarchy import AMRHierarchy
+from yt.data_objects.static_output import StaticOutput
+from yt.utilities.amr_utils import get_box_grids_level
+from yt.utilities.definitions import mpc_conversion
+
+from .definitions import parameter_type_dict, nyx_to_enzo_dict, \
+                         fab_header_pattern, nyx_particle_field_names
+from .utils import boxlib_bool_to_int
+from .fields import NyxFieldContainer, add_field
+
+
+class NyxGrid(AMRGridPatch):
+    _id_offset = 0
+
+    def __init__(self, left_edge, right_edge, index, level, filename, offset,
+                 dimensions, start, stop, **kwargs):
+        """ Build a grid that understands Nyx's boxlib format. """
+        # passes index as the patch ``id``
+        AMRGridPatch.__init__(self, index, **kwargs)
+        self.filename = filename
+        self._offset = offset
+
+        # @todo: enzo-isms.
+        # Must copy to avoid refs, in case the user alters the args later.
+        self.ActiveDimensions = (dimensions.copy()).astype('int32')
+        self.start_index = start.copy()
+        self.stop_index = stop.copy()
+        self.LeftEdge  = left_edge.copy()
+        self.RightEdge = right_edge.copy()
+        self.index = index
+        self.Level = level
+
+    def get_global_startindex(self):
+        return self.start_index
+
+    def _prepare_grid(self):
+        """ Copies all the appropriate attributes from the hierarchy. """
+        # This is definitely the slowest part of generating the hierarchy
+        h = self.hierarchy  # alias
+        h.grid_levels[self.id, 0] = self.Level
+        h.grid_left_edge[self.id,:] = self.LeftEdge[:]
+        h.grid_right_edge[self.id,:] = self.RightEdge[:]
+
+        # Might still work
+        #self.Time = h.gridTimes[self.id,0]
+        #self.NumberOfParticles = h.gridNumberOfParticles[self.id,0]
+
+        # @todo: enzo-isms
+        self.field_indexes = h.field_indexes
+        self.Children = h.gridTree[self.id]
+        pIDs = h.gridReverseTree[self.id]
+
+        if len(pIDs) > 0:
+            self.Parent = [weakref.proxy(h.grids[pID]) for pID in pIDs]
+        else:
+            self.Parent = None
+
+    def _setup_dx(self):
+        # So first we figure out what the index is. We don't assume that
+        # dx=dy=dz, at least here. We probably do elsewhere.
+        id = self.id - self._id_offset
+        if self.Parent is not None:
+            self.dds = self.Parent[0].dds / self.pf.refine_by
+        else:
+            LE, RE = self.hierarchy.grid_left_edge[id,:], \
+                     self.hierarchy.grid_right_edge[id,:]
+            self.dds = na.array((RE - LE) / self.ActiveDimensions)
+
+        if self.pf.dimensionality < 2: self.dds[1] = 1.0
+        if self.pf.dimensionality < 3: self.dds[2] = 1.0
+        self.data['dx'], self.data['dy'], self.data['dz'] = self.dds
+
+    def __repr__(self):
+        return "NyxGrid_%04i" % (self.id)
+
+class NyxHierarchy(AMRHierarchy):
+    grid = NyxGrid
+
+    def __init__(self, pf, data_style="nyx_native"):
+        self.field_info = NyxFieldContainer()
+        self.field_indexes = {}
+        self.parameter_file = weakref.proxy(pf)
+        self.directory = pf.path
+        header_path = os.path.join(self.directory, "Header")  # make a kwarg?
+
+        self.data_style = data_style
+        #self._setup_classes()
+
+        # This also sets up the grid objects
+        self.read_global_header(header_path)
+        self.read_particle_header()
+        self.__cache_endianness(self.levels[-1].grids[-1])
+
+        # @todo: should be first line
+        AMRHierarchy.__init__(self, pf, self.data_style)
+        self._setup_data_io()
+        self._setup_field_list()
+        self._populate_hierarchy()
+
+    def read_global_header(self, header_path):
+        """ Read the global header file for an Nyx plotfile output. """
+        counter = 0
+        header_file = open(header_path, 'r')
+        self.__global_header_lines = header_file.readlines()
+
+        # parse the file
+        self.nyx_version = self.__global_header_lines[0].rstrip()
+        self.n_fields = int(self.__global_header_lines[1])
+
+        # why the 2?
+        counter = self.n_fields + 2
+        self.field_list = []
+        for i, line in enumerate(self.__global_header_lines[2:counter]):
+            self.field_list.append(line.rstrip())
+
+        # figure out dimensions and make sure it's 3D
+        self.dimension = int(self.__global_header_lines[counter])
+        if self.dimension != 3:
+            raise RunTimeError("Current data is %iD. yt only supports Nyx data in 3D" % self.dimension)
+
+        counter += 1
+        self.Time = float(self.__global_header_lines[counter])
+        counter += 1
+        self.finest_grid_level = int(self.__global_header_lines[counter])
+        self.n_levels = self.finest_grid_level + 1
+        counter += 1
+
+        # quantities with _unnecessary are also stored in the inputs
+        # file and are not needed.  they are read in and stored in
+        # case in the future we want to enable a "backwards" way of
+        # taking the data out of the Header file and using it to fill
+        # in in the case of a missing inputs file
+        self.domainLeftEdge_unnecessary = na.array(map(float, self.__global_header_lines[counter].split()))
+        counter += 1
+        self.domainRightEdge_unnecessary = na.array(map(float, self.__global_header_lines[counter].split()))
+        counter += 1
+        self.refinementFactor_unnecessary = self.__global_header_lines[counter].split() #na.array(map(int, self.__global_header_lines[counter].split()))
+        counter += 1
+        self.globalIndexSpace_unnecessary = self.__global_header_lines[counter]
+        counter += 1
+        self.timestepsPerLevel_unnecessary = self.__global_header_lines[counter]
+        counter += 1
+
+        self.dx = na.zeros((self.n_levels, 3))
+        for i, line in enumerate(self.__global_header_lines[counter:counter + self.n_levels]):
+            self.dx[i] = na.array(map(float, line.split()))
+        counter += self.n_levels
+        self.geometry = int(self.__global_header_lines[counter])
+        if self.geometry != 0:
+            raise RunTimeError("yt only supports cartesian coordinates.")
+        counter += 1
+
+        # @todo: this is just to debug. eventually it should go away.
+        linebreak = int(self.__global_header_lines[counter])
+        if linebreak != 0:
+            raise RunTimeError("INTERNAL ERROR! This should be a zero.")
+        counter += 1
+
+        # each level is one group with ngrids on it. each grid has 3 lines of 2
+        # reals
+        self.levels = []
+        grid_counter = 0
+        file_finder_pattern = r"FabOnDisk: (\w+_D_[0-9]{4}) (\d+)\n"
+        re_file_finder = re.compile(file_finder_pattern)
+        dim_finder_pattern = r"\(\((\d+,\d+,\d+)\) \((\d+,\d+,\d+)\) \(\d+,\d+,\d+\)\)\n"
+        re_dim_finder = re.compile(dim_finder_pattern)
+        data_files_pattern = r"Level_[\d]/"
+        data_files_finder = re.compile(data_files_pattern)
+
+        for level in range(0, self.n_levels):
+            tmp = self.__global_header_lines[counter].split()
+            # should this be grid_time or level_time??
+            lev, ngrids, grid_time = int(tmp[0]), int(tmp[1]), float(tmp[2])
+            counter += 1
+            nsteps = int(self.__global_header_lines[counter])
+            counter += 1
+            self.levels.append(NyxLevel(lev, ngrids))
+
+            # Open level header, extract file names and offsets for each grid
+            # read slightly out of order here: at the end of the lo, hi pairs
+            # for x, y, z is a *list* of files types in the Level directory.
+            # Each type has Header and a number of data files (one per
+            # processor)
+            tmp_offset = counter + 3 * ngrids
+            nfiles = 0
+            key_off = 0
+            files = {}
+            offsets = {}
+            while nfiles + tmp_offset < len(self.__global_header_lines) \
+                  and data_files_finder.match(self.__global_header_lines[nfiles + tmp_offset]):
+                filen = os.path.join(self.parameter_file.path, \
+                                     self.__global_header_lines[nfiles + tmp_offset].strip())
+                # open each "_H" header file, and get the number of
+                # components within it
+                level_header_file = open(filen + '_H', 'r').read()
+                start_stop_index = re_dim_finder.findall(level_header_file) # just take the last one
+                grid_file_offset = re_file_finder.findall(level_header_file)
+                ncomp_this_file = int(level_header_file.split('\n')[2])
+
+                for i in range(ncomp_this_file):
+                    key = self.field_list[i + key_off]
+                    f, o = zip(*grid_file_offset)
+                    files[key] = f
+                    offsets[key] = o
+                    self.field_indexes[key] = i
+
+                key_off += ncomp_this_file
+                nfiles += 1
+
+            # convert dict of lists to list of dicts
+            fn = []
+            off = []
+            lead_path = os.path.join(self.parameter_file.path,
+                                     'Level_%i' % level)
+            for i in range(ngrids):
+                fi = [os.path.join(lead_path, files[key][i]) for key in self.field_list]
+                of = [int(offsets[key][i]) for key in self.field_list]
+                fn.append(dict(zip(self.field_list, fi)))
+                off.append(dict(zip(self.field_list, of)))
+
+            for grid in range(0, ngrids):
+                gfn = fn[grid]  # filename of file containing this grid
+                gfo = off[grid] # offset within that file
+                xlo, xhi = map(float, self.__global_header_lines[counter].split())
+                counter += 1
+                ylo, yhi = map(float, self.__global_header_lines[counter].split())
+                counter += 1
+                zlo, zhi = map(float, self.__global_header_lines[counter].split())
+                counter += 1
+                lo = na.array([xlo, ylo, zlo])
+                hi = na.array([xhi, yhi, zhi])
+                dims, start, stop = self.__calculate_grid_dimensions(start_stop_index[grid])
+                self.levels[-1].grids.append(self.grid(lo, hi, grid_counter,
+                                             level, gfn, gfo, dims, start, stop,
+                                             hierarchy=self))
+                grid_counter += 1 # this is global, and shouldn't be reset
+                                  # for each level
+
+            # already read the filenames above...
+            counter += nfiles
+            self.num_grids = grid_counter
+            self.float_type = 'float64'
+
+        self.maxLevel = self.n_levels - 1
+        self.max_level = self.n_levels - 1
+        header_file.close()
+
+    def read_particle_header(self):
+        # We need to get particle offsets and particle counts
+        if not self.parameter_file.use_particles:
+            self.pgrid_info = na.zeros((self.num_grids, 3), dtype='int64')
+            return
+        self.field_list += nyx_particle_field_names[:]
+        header = open(os.path.join(self.parameter_file.path, "DM", "Header"))
+        version = header.readline()
+        ndim = header.readline()
+        nfields = header.readline()
+        ntotalpart = int(header.readline())
+        dummy = header.readline() # nextid
+        maxlevel = int(header.readline()) # max level
+
+        # Skip over how many grids on each level; this is degenerate
+        for i in range(maxlevel + 1):dummy = header.readline()
+
+        grid_info = na.fromiter((int(i) for line in header.readlines()
+                                 for i in line.split()),
+                                dtype='int64',
+                                count=3*self.num_grids).reshape((self.num_grids, 3))
+        self.pgrid_info = grid_info
+
+    def __cache_endianness(self, test_grid):
+        """
+        Cache the endianness and bytes per real of the grids by using a test
+        grid and assuming that all grids have the same endianness. This is a
+        pretty safe assumption since Nyx uses one file per processor (@todo:
+        make sure this is still true, I don't think so). If you are running on a
+        cluster with different endian processors, then you are disappoint.
+
+        """
+        # open the test file & grab the header
+        inFile = open(os.path.expanduser(test_grid.filename[self.field_list[0]]), 'rb')
+        header = inFile.readline()
+        inFile.close()
+        header.strip()
+
+        headerRe = re.compile(fab_header_pattern)
+        bytesPerReal, endian, start, stop, centerType, nComponents = \
+            headerRe.search(header).groups()
+        self._bytesPerReal = int(bytesPerReal)
+        if self._bytesPerReal == int(endian[0]):
+            dtype = '<'
+        elif self._bytesPerReal == int(endian[-1]):
+            dtype = '>'
+        else:
+            raise ValueError("FAB header is neither big nor little endian. Perhaps the file is corrupt?")
+
+        dtype += ('f%i' % self._bytesPerReal) # always a floating point
+        self._dtype = dtype
+
+    def __calculate_grid_dimensions(self, start_stop):
+        start = na.array(map(int, start_stop[0].split(',')))
+        stop = na.array(map(int, start_stop[1].split(',')))
+        dimension = stop - start + 1
+        return dimension, start, stop
+
+    def _populate_grid_objects(self):
+        mylog.debug("Creating grid objects")
+
+        self.grids = na.concatenate([level.grids for level in self.levels])
+        basedir = self.parameter_file.path
+        for g, pg in itertools.izip(self.grids, self.pgrid_info):
+            g.particle_filename = os.path.join(basedir, "DM",
+                                               "Level_%s" % (g.Level),
+                                               "DATA_%04i" % pg[0])
+            g.NumberOfParticles = pg[1]
+            g._particle_offset = pg[2]
+
+        self.grid_particle_count[:,0] = self.pgrid_info[:,1]
+        del self.pgrid_info  # if this is all pgrid_info is used for...
+
+        gls = na.concatenate([level.ngrids * [level.level] for level in self.levels])
+        self.grid_levels[:] = gls.reshape((self.num_grids, 1))
+        grid_dcs = na.concatenate([level.ngrids*[self.dx[level.level]]
+                                   for level in self.levels], axis=0)
+
+        self.grid_dxs = grid_dcs[:,0].reshape((self.num_grids, 1))
+        self.grid_dys = grid_dcs[:,1].reshape((self.num_grids, 1))
+        self.grid_dzs = grid_dcs[:,2].reshape((self.num_grids, 1))
+
+        left_edges = []
+        right_edges = []
+        dims = []
+        for level in self.levels:
+            left_edges += [g.LeftEdge for g in level.grids]
+            right_edges += [g.RightEdge for g in level.grids]
+            dims += [g.ActiveDimensions for g in level.grids]
+
+        self.grid_left_edge = na.array(left_edges)
+        self.grid_right_edge = na.array(right_edges)
+        self.grid_dimensions = na.array(dims)
+        self.gridReverseTree = [] * self.num_grids
+        self.gridReverseTree = [ [] for i in range(self.num_grids)]  # why the same thing twice?
+        self.gridTree = [ [] for i in range(self.num_grids)]  # meh
+
+        mylog.debug("Done creating grid objects")
+
+    def _populate_hierarchy(self):
+        self.__setup_grid_tree()
+
+        for i, grid in enumerate(self.grids):
+            if (i%1e4) == 0:
+                mylog.debug("Prepared % 7i / % 7i grids", i, self.num_grids)
+
+            grid._prepare_grid()
+            grid._setup_dx()
+
+    def __setup_grid_tree(self):
+        mask = na.empty(self.grids.size, dtype='int32')
+        for i, grid in enumerate(self.grids):
+            get_box_grids_level(grid.LeftEdge, grid.RightEdge, grid.Level + 1,
+                                self.grid_left_edge, self.grid_right_edge,
+                                self.grid_levels, mask)
+            children = self.grids[mask.astype("bool")]
+            for child in children:
+                self.gridReverseTree[child.id].append(i)
+                self.gridTree[i].append(weakref.proxy(child))
+
+    def _setup_classes(self):
+        dd = self._get_data_reader_dict()
+        dd["field_indexes"] = self.field_indexes
+        AMRHierarchy._setup_classes(self, dd)
+        self.object_types.sort()
+
+    def _get_grid_children(self, grid):
+        mask = na.zeros(self.num_grids, dtype='bool')
+        grids, grid_ind = self.get_box_grids(grid.LeftEdge, grid.RightEdge)
+        mask[grid_ind] = True
+        mask = na.logical_and(mask, (self.grid_levels == (grid.Level + 1)).flat)
+        return self.grids[mask]
+
+    def _setup_field_list(self):
+        self.derived_field_list = []
+
+        for field in self.field_info:
+            try:
+                fd = self.field_info[field].get_dependencies(pf=self.parameter_file)
+            except:
+                continue
+            available = na.all([f in self.field_list for f in fd.requested])
+            if available: self.derived_field_list.append(field)
+
+        for field in self.field_list:
+            if field not in self.derived_field_list:
+                self.derived_field_list.append(field)
+
+        if self.parameter_file.use_particles:
+            # We know which particle fields will exist -- pending further
+            # changes in the future.
+            for field in nyx_particle_field_names:
+                def external_wrapper(f):
+                    def _convert_function(data):
+                        return data.convert(f)
+                    return _convert_function
+                cf = external_wrapper(field)
+                # Note that we call add_field on the field_info directly.  This
+                # will allow the same field detection mechanism to work for 1D,
+                # 2D and 3D fields.
+                self.pf.field_info.add_field(field, lambda a, b: None,
+                                             convert_function=cf,
+                                             take_log=False, particle_type=True)
+
+    def _count_grids(self):
+        """ this is already provided in ??? """
+        pass
+
+    def _initialize_grid_arrays(self):
+        mylog.debug("Allocating arrays for %s grids", self.num_grids)
+        self.grid_dimensions = na.ones((self.num_grids, 3), 'int32')
+        self.grid_left_edge = na.zeros((self.num_grids, 3), self.float_type)
+        self.grid_right_edge = na.ones((self.num_grids, 3), self.float_type)
+        self.grid_levels = na.zeros((self.num_grids, 1), 'int32')
+        self.grid_particle_count = na.zeros((self.num_grids, 1), 'int32')
+
+    def _parse_hierarchy(self):
+        pass
+
+    def _detect_fields(self):
+        pass
+
+    def _setup_unknown_fields(self):
+        # Doesn't seem useful
+        for field in self.field_list:
+            if field in self.parameter_file.field_info: continue
+            mylog.info("Adding %s to list of fields", field)
+            cf = None
+            if self.parameter_file.has_key(field):
+                def external_wrapper(f):
+                    def _convert_function(data):
+                        return data.convert(f)
+                    return _convert_function
+                cf = external_wrapper(field)
+            add_field(field, lambda a, b: None, convert_function=cf,
+                      take_log=False)
+
+    def _setup_derived_fields(self):
+        pass
+
+    def _initialize_state_variables(self):
+        """
+        Override not to re-initialize num_grids in AMRHierarchy.__init__
+
+        """
+        self._parallel_locking = False
+        self._data_file = None
+        self._data_mode = None
+        self._max_locations = {}
+
+class NyxLevel:
+    def __init__(self, level, ngrids):
+        self.level = level
+        self.ngrids = ngrids
+        self.grids = []
+
+class NyxStaticOutput(StaticOutput):
+    """
+    This class is a stripped down class that simply reads and parses *filename*,
+    without looking at the Nyx hierarchy.
+
+    """
+    _hierarchy_class = NyxHierarchy
+    _fieldinfo_class = NyxFieldContainer
+
+    @classmethod
+    def _is_valid(cls, *args, **kwargs):
+        # fill our args
+        pname = args[0].rstrip("/")
+        dn = os.path.dirname(pname)
+        if len(args) > 1:
+            kwargs['paramFilename'] = args[1]
+
+        pfname = kwargs.get("paramFilename", os.path.join(dn, "inputs"))
+
+        # @todo: new Nyx output.
+        # We check for the job_info file's existence because this is currently
+        # what distinguishes Nyx data from MAESTRO data.
+        pfn = os.path.join(pfname)
+        if not os.path.exists(pfn): return False
+        nyx = any(("nyx." in line for line in open(pfn)))
+        maestro = os.path.exists(os.path.join(pname, "job_info"))
+        orion = (not nyx) and (not maestro)
+        return nyx
+
+    def __init__(self, plotname, param_filename="inputs",
+                 fparam_filename="probin", data_style="nyx_native",
+                 storage_filename=None):
+        """
+        Need to override for Nyx file structure, for now.
+
+        The paramfile is usually called "inputs" and there may be a fortran
+        inputs file usually called "probin". `plotname` here will be a directory
+        name as per BoxLib, data_style will be one of
+
+         * Native
+         * IEEE (not implemented in yt)
+         * ASCII (not implemented in yt)
+
+        """
+        self.storage_filename = storage_filename
+        self.parameter_filename = param_filename
+        self.parameter_file_path = os.path.abspath(self.parameter_filename)
+        self.fparameter_filename = fparam_filename
+        self.fparameter_file_path = os.path.abspath(self.fparameter_filename)
+        self.path = os.path.abspath(plotname)  # data folder
+
+        self.fparameters = {}
+
+        # @todo: quick fix...
+        self.use_particles = False
+
+        # @todo: first line
+        # runs ``self._parse_parameter_file()``, ``self._set_units()``, and
+        # ``self.print_key_parameters()``
+        StaticOutput.__init__(self, plotname.rstrip("/"), data_style=data_style)
+
+        # @todo: field pruning should happen here
+        self.field_info = self._fieldinfo_class()
+
+        # @todo: check all of these and hopefully factor out of the constructor.
+        # These should maybe not be hardcoded?
+        self.parameters["HydroMethod"] = "nyx"  # always PPM DE
+        self.parameters["Time"] = 1.  # default unit is 1...
+        self.parameters["DualEnergyFormalism"] = 0  # always off.
+        self.parameters["EOSType"] = -1  # default
+
+        # @todo: hopefully delete this after implementing new Nyx output
+        if self.fparameters.has_key("mu"):
+            self.parameters["mu"] = self.fparameters["mu"]
+
+    def _parse_parameter_file(self):
+        """
+        Parses the parameter file and establishes the various dictionaries.
+
+        """
+        # More boxlib madness...
+        self._parse_header_file()
+
+        if os.path.isfile(self.fparameter_file_path):
+            self._parse_fparameter_file()
+
+        # Let's read the file
+        self.unique_identifier = int(os.stat(self.parameter_filename)[ST_CTIME])
+        lines = open(self.parameter_file_path).readlines()
+
+        for line in lines:
+            if line.find("#") >= 1:  # Keep the commented lines...
+                line = line[:line.find("#")]
+            line = line.strip()
+            if len(line) < 2 or line.find("#") == 0: # ...but skip comments
+                continue
+
+            try:
+                param, val_string = map(strip, line.split("="))
+            except ValueError:
+                mylog.error("ValueError: '%s'", line)
+
+            vals = val_string.split()
+
+            # @todo: don't do this here...
+            if nyx_to_enzo_dict.has_key(param):
+                param_name = nyx_to_enzo_dict[param]
+                vals = map(parameter_type_dict[param_name], vals)
+                if len(vals) == 1:
+                    self.parameters[param_name] = vals[0]
+                else:
+                    # don't know why this is special
+                    if param_name == "RefineBy":
+                        self.parameters[param_name] = vals[0]
+                    else:
+                        self.parameters[param_name] = vals
+
+            elif param.startswith("geometry.prob_hi"):
+                self.domain_right_edge = na.array([float(i) for i in vals])
+            elif param.startswith("geometry.prob_lo"):
+                self.domain_left_edge = na.array([float(i) for i in vals])
+            elif param.startswith("particles.write_in_plotfile"):
+                self.use_particles = boxlib_bool_to_int(vals[0])
+
+        # aliases we need
+        self.parameters["TopGridRank"] = len(self.parameters["TopGridDimensions"])
+        self.dimensionality = self.parameters["TopGridRank"]
+        self.domain_dimensions = self.parameters["TopGridDimensions"]
+        self.refine_by = self.parameters.get("RefineBy", 2)  # 2 is silent default? Makes sense I suppose.
+
+        if self.parameters.has_key("ComovingCoordinates") \
+           and self.parameters["ComovingCoordinates"]:
+            self.cosmological_simulation = 1
+            self.omega_lambda = self.parameters["CosmologyOmegaLambdaNow"]
+            self.omega_matter = self.parameters["CosmologyOmegaMatterNow"]
+            self.hubble_constant = self.parameters["CosmologyHubbleConstantNow"]
+
+            # So broken. We will fix this in the new Nyx output format
+            a_file = open(os.path.join(self.path, "comoving_a"))
+            line = a_file.readline().strip()
+            a_file.close()
+            self.parameters["CosmologyCurrentRedshift"] = 1 / float(line) - 1
+            self.cosmological_scale_factor = float(line)
+
+            # alias
+            self.current_redshift = self.parameters["CosmologyCurrentRedshift"]
+
+        else:
+            # @todo: automatic defaults
+            self.current_redshift = self.omega_lambda = self.omega_matter = \
+                self.hubble_constant = self.cosmological_simulation = 0.0
+
+    def _parse_header_file(self):
+        """
+        Parses the BoxLib header file to get any parameters stored there.
+        Hierarchy information is read out of this file in NyxHierarchy.
+
+        Currently, only Time is read here.
+
+        """
+        # @todo: header filename option? probably not.
+        header_file = open(os.path.join(self.path, "Header"))
+        lines = header_file.readlines()  # hopefully this is small
+        header_file.close()
+
+        n_fields = int(lines[1])  # this could change
+        self.current_time = float(lines[3 + n_fields])  # very fragile
+
+    def _parse_fparameter_file(self):
+        """
+        Parses the fortran parameter file for Nyx. Most of this will be useless,
+        but this is where it keeps mu = mass per particle/m_hydrogen. Also it
+        contains the cosmological variables.
+
+        """
+        # @todo: delete after new Nyx output
+        lines = open(self.fparameter_file_path).readlines()
+        for line in lines:
+            if line.count("=") == 1:
+                nyx_param, val_string = map(strip, line.split("="))
+
+                # Check if we care about this param. If so, translate it.
+                if nyx_to_enzo_dict.has_key(nyx_param):
+                    param = nyx_to_enzo_dict[nyx_param]
+                else:
+                    continue
+
+                # parse vals string and correct for fortran double syntax
+                vals = val_string.split()
+                if val_string.count("'") == 0:  # must be floats
+                    vals = map(float, [val.replace('D', 'e').replace('d', 'e')
+                                       for val in vals])
+
+                # single element or array?
+                if len(vals) == 1:
+                    self.parameters[param] = vals[0]
+                else:
+                    self.parameters[param] = vals
+
+    def _set_units(self):
+        """
+        Generates the conversion to various physical _units based on the
+        parameter file.
+
+        """
+        self.units = {}
+        self.time_units = {}
+
+        if len(self.parameters) == 0:  # don't think this is possible, but safe
+            self._parse_parameter_file()
+
+        # Masses are always in $ M_{\odot} $
+        self.units["particle_mass"] = 1.989e33
+
+        mylog.warning("Length units: setting 1.0 = 1.0 Mpc.")
+        self.units.update(mpc_conversion)
+        self.units["density"] = self.units["particle_mass"]/(self.units["cm"])**3
+        self.units["particle_mass_density"] = self.units["density"]
+        self.units["Density"] = 1
+
+        # @todo: enzo-isms
+        mylog.warning("Time units: setting 1.0 = Mpc/km s ~ 10^12 yr .")
+        self.time_units["s"] = 1.0 / 3.08568025e19
+        self.conversion_factors["Time"] = 1.0 / 3.08568025e19
+
+        # velocities are not comoving!
+        # Nyx is in km/s so we need to convert to cm/s, hence 1e5
+        cf = 1e5 * (self.cosmological_scale_factor)
+        for ax in "xyz":
+            self.units["particle_velocity_%s" % ax] = cf
+
+        # misc
+        self.conversion_factors = defaultdict(lambda: 1.0)  # what is this for? - Steffen: this is to get 1.0 for values not in the dict
+        self.time_units["1"] = 1
+        self.units["1"] = 1.0
+        self.units["unitary"] = 1.0 / (self.domain_right_edge -
+                                       self.domain_left_edge).max()
+
+        # time
+        seconds = self.time_units["s"]
+        self.time_units["days"] = seconds / (3600 * 24.0)
+        self.time_units["years"] = seconds / (3600 * 24.0 * 365)
+
+
+        # not the most useful right now, but someday
+        for key in nyx_particle_field_names:
+            self.conversion_factors[key] = 1.0
+
+    def _setup_nounits_units(self):
+        z = 0
+
+    def _localize(self, f, default):
+        if f is None:
+            return os.path.join(self.directory, default)
+        return f


--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/yt/frontends/nyx/definitions.py	Fri Jul 29 15:52:48 2011 -0400
@@ -0,0 +1,91 @@
+"""
+Definitions specific to Nyx
+
+Author: Casey W. Stark <caseywstark at gmail.com>
+Affiliation: UC Berkeley
+Author: J. S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Homepage: http://yt.enzotools.org/
+License:
+  Copyright (C) 2011 Casey W. Stark, J. S. Oishi, Matthew Turk.  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/>.
+
+"""
+
+from utils import boxlib_bool_to_int
+
+# This gives the type of each parameter we want, used to cast with a ``map()``
+# @todo: get rid of enzo parameters we do not need
+parameter_type_dict = {
+    "CosmologyCurrentRedshift": float,
+    "CosmologyComovingBoxSize": float,
+    "CosmologyOmegaMatterNow": float,
+    "CosmologyOmegaLambdaNow": float,
+    "CosmologyHubbleConstantNow": float,
+    "CosmologyInitialRedshift": float,
+    "DualEnergyFormalismEta1": float,
+    "DualEnergyFormalismEta2": float,
+    "MetaDataString": str,
+    "HydroMethod": int,
+    "DualEnergyFormalism": int,
+    "InitialTime": float,
+    "ComovingCoordinates": boxlib_bool_to_int,
+    "DensityUnits": float,
+    "LengthUnits": float,
+    "LengthUnit": float,
+    "TemperatureUnits": float,
+    "TimeUnits": float,
+    "GravitationalConstant": float,
+    "Gamma": float,
+    "MultiSpecies": int,
+    "CompilerPrecision": str,
+    "CurrentTimeIdentifier": int,
+    "RefineBy": int,
+    "BoundaryConditionName": str,
+    "TopGridRank": int,
+    "TopGridDimensions": int,
+    "EOSSoundSpeed": float,
+    "EOSType": int,
+    "NumberOfParticleAttributes": int,
+}
+
+# Provides translation between parameters in the nyx `inputs` file names to the
+# enzo/yt name expected throughout the code. The key is nyx name, value is
+# enzo/yt equivalent.
+nyx_to_enzo_dict = {
+    "amr.n_cell": "TopGridDimensions",
+    "amr.ref_ratio": "RefineBy",
+    "materials.gamma": "Gamma",
+    "castro.use_comoving": "ComovingCoordinates",
+    "castro.redshift_in": "CosmologyInitialRedshift",
+    "comoving_OmL": "CosmologyOmegaLambdaNow",
+    "comoving_OmM": "CosmologyOmegaMatterNow",
+    "comoving_h": "CosmologyHubbleConstantNow"
+}
+
+# is this the same as nyx_to_enzo.
+yt_to_nyx_fields_dict = {}
+nyx_to_yt_fields_dict = {}
+
+fab_header_pattern = r"^FAB \(\((\d+), \([0-9 ]+\)\),\(\d+, \(([0-9 ]+)\)\)\)\(\((\d+,\d+,\d+)\) \((\d+,\d+,\d+)\) \((\d+,\d+,\d+)\)\) (\d+)\n"
+
+# need to specify units eventually
+nyx_particle_field_names = ['particle_position_%s' % ax for ax in 'xyz'] + \
+                           ['particle_mass'] +  \
+                           ['particle_velocity_%s' % ax for ax in 'xyz']
+


--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/yt/frontends/nyx/fields.py	Fri Jul 29 15:52:48 2011 -0400
@@ -0,0 +1,153 @@
+"""
+Field specifications for Nyx
+
+Author: Casey W. Stark <caseywstark at gmail.com>
+Affiliation: UC Berkeley
+Author: J. S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Homepage: http://yt.enzotools.org/
+License:
+  Copyright (C) 2011 Casey W. Stark, J. S. Oishi, Matthew Turk.  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 yt.data_objects.universal_fields
+
+from yt.data_objects.field_info_container import CodeFieldInfoContainer, \
+    ValidateParameter, ValidateDataField, ValidateProperty, ValidateSpatial, \
+    ValidateGridType
+from yt.utilities.physical_constants import mh, kboltz
+
+class NyxFieldContainer(CodeFieldInfoContainer):
+    """ All nyx-specific fields are stored in here. """
+    _shared_state = {}
+    _field_list = {}
+
+nyx_fields = NyxFieldContainer()
+add_field = nyx_fields.add_field
+add_nyx_field = add_field  # alias for API
+
+# Density
+add_field("density", function=lambda a, b: None, take_log=True,
+          validators=[ValidateDataField("density")],
+          units=r"\rm{g}} / \rm{cm}^3",
+          projected_units =r"\rm{g}} / \rm{cm}^2")
+nyx_fields["density"]._projected_units =r"\rm{g}} / \rm{cm}^2"
+
+add_field("Density", function=lambda a, b: b["density"], take_log=True,
+          units=r"\rm{g}} / \rm{cm}^3",
+          projected_units =r"\rm{g}} / \rm{cm}^2")
+
+# Particle mass in units of $ M_{\odot}
+def _convertParticleMassMsun(data):
+    return (1/1.989e33)
+def _particle_mass_m_sun(field, data):
+    return data["particle_mass"]
+add_field("ParticleMassMsun", function=_particle_mass_m_sun,
+          validators=[ValidateSpatial(0), ValidateDataField("particle_mass")],
+          particle_type=True, convert_function=_convertParticleMassMsun, take_log=True, units=r"\rm{M_{\odot}}")
+          
+add_field("Dark_Matter_Density", function=lambda a, b: b["particle_mass_density"], take_log=True,
+          units=r"\rm{g}} / \rm{cm}^3",particle_type=True,
+          projected_units =r"\rm{g}} / \rm{cm}^2")
+
+
+# Energy Density
+# @todo: ``energy_density``
+add_field("total_energy", function=lambda a, b: None, take_log=True,
+          validators=[ValidateDataField("total_energy")],
+          units=r"\rm{M_{\odot}} (\rm{km} / \rm{s})^2")
+
+# Momentum in each dimension.
+# @todo: ``momentum_x``
+add_field("x-momentum", function=lambda a, b: None, take_log=False,
+          validators=[ValidateDataField("x-momentum")],
+          units=r"\rm{M_{\odot}} \rm{km} / \rm{s}")
+add_field("y-momentum", function=lambda a, b: None, take_log=False,
+          validators=[ValidateDataField("y-momentum")],
+          units=r"\rm{M_{\odot}} \rm{km} / \rm{s}")
+add_field("z-momentum", function=lambda a, b: None, take_log=False,
+          validators=[ValidateDataField("z-momentum")],
+          units=r"\rm{M_{\odot}} \rm{km} / \rm{s}")
+
+### Now derived fields
+
+# Velocity fields in each dimension
+# @todo: ``velocity_x``
+def _x_velocity(field, data):
+    """ Generate x-velocity from x-momentum and density. """
+    return data["x-momentum"] / data["density"]
+add_field("x-velocity", function=_x_velocity, take_log=False,
+          units=r"\rm{km} / \rm{s}")
+
+def _y_velocity(field, data):
+    """ Generate y-velocity from y-momentum and density. """
+    return data["y-momentum"] / data["density"]
+add_field("y-velocity", function=_y_velocity, take_log=False,
+          units=r"\rm{km} / \rm{s}")
+
+def _z_velocity(field, data):
+    """ Generate z-velocity from z-momentum and density. """
+    return data["z-momentum"] / data["density"]
+add_field("z-velocity", function=_z_velocity, take_log=False,
+          units=r"\rm{km} / \rm{s}")
+
+# The gas **thermal** energy.
+# @todo: should be called ``gas_energy`` whether it is data or derived
+def _thermal_energy(field, data):
+    """
+    Generate thermal (gas energy). Dual Energy Formalism was implemented by
+    Stella, but this isn't how it's called, so I'll leave that commented out for
+    now.
+
+    """
+    #if data.pf["DualEnergyFormalism"]:
+    #    return data["Gas_Energy"]
+    #else:
+    return data["Total_Energy"] - 0.5 * data["density"] * (
+                                          data["x-velocity"]**2.0
+                                        + data["y-velocity"]**2.0
+                                        + data["z-velocity"]**2.0 )
+add_field("ThermalEnergy", function=_thermal_energy,
+          units=r"\rm{M_{\odot}} (\rm{km} / \rm{s})^2")
+
+# Gas pressure
+# @todo: eventually figure out a way to detect when using radiation and change
+#        this.
+def _pressure(field, data):
+    """
+    Computed using
+
+    $$ pressure = (\gamma - 1.0) * e$$
+
+    where e is thermal energy density. Note that this will need to be modified
+    when radiation is accounted for.
+
+    """
+    return (data.pf["Gamma"] - 1.0) * data["ThermalEnergy"]
+add_field("Pressure", function=_pressure,
+          units=r"\rm{M_{\odot}} (\rm{km} / \rm{s})^2 / \rm{Mpc}^3")
+
+# Gas temperature
+def _temperature(field, data):
+    return ((data.pf["Gamma"] - 1.0) * data.pf["mu"] * mh *
+            data["ThermalEnergy"] / (kboltz * data["Density"]))
+add_field("Temperature", function=_temperature, take_log=False,
+          units=r"\rm{Kelvin}")
+


--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/yt/frontends/nyx/io.py	Fri Jul 29 15:52:48 2011 -0400
@@ -0,0 +1,141 @@
+"""
+Nyx data-file handling functions (basically a boxlib reader)
+
+Author: Casey W. Stark <caseywstark at gmail.com>
+Affiliation: UC Berkeley
+Author: Matthew Turk <matthewturk at gmail.com>
+Author: J. S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Homepage: http://yt.enzotools.org/
+License:
+  Copyright (C) 2011 Casey W. Stark, Matthew Turk.  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 numpy as na
+from yt.utilities.amr_utils import read_castro_particles
+from yt.utilities.io_handler import BaseIOHandler
+
+from definitions import fab_header_pattern, nyx_particle_field_names, \
+                        yt_to_nyx_fields_dict
+
+class IOHandlerNative(BaseIOHandler):
+    """ File handler that can somehow read the native boxlib format. """
+
+    _data_style = "nyx_native"
+
+    def modify(self, field):
+        return field.swapaxes(0, 2)
+
+    def _read_particle_field(self, grid, field):
+        offset = grid._particle_offset
+        filen = os.path.expanduser(grid.particle_filename)
+        off = grid._particle_offset
+        tr = na.zeros(grid.NumberOfParticles, dtype='float64')
+        read_castro_particles(filen, off,
+                              nyx_particle_field_names.index(field),
+                              len(nyx_particle_field_names), tr)
+        return tr
+
+    def _read_data_set(self, grid, field):
+        """ reads packed multiFABs output by BoxLib in "NATIVE" format. """
+        if field in nyx_particle_field_names:
+            return self._read_particle_field(grid, field)
+        filen = os.path.expanduser(grid.filename[field])
+        off = grid._offset[field]
+        inFile = open(filen, 'rb')
+        inFile.seek(off)
+        header = inFile.readline()
+        header.strip()
+
+        """
+        if grid._paranoid:
+            mylog.warn("Castro Native reader: Paranoid read mode.")
+            header_re = re.compile(fab_header_pattern)
+            bytesPerReal, endian, start, stop, centerType, nComponents = \
+                headerRe.search(header).groups()
+
+            # we will build up a dtype string, starting with endian.
+            # @todo: this code is ugly.
+            bytesPerReal = int(bytesPerReal)
+            if bytesPerReal == int(endian[0]):
+                dtype = '<'
+            elif bytesPerReal == int(endian[-1]):
+                dtype = '>'
+            else:
+                raise ValueError("FAB header is neither big nor little endian. Perhaps the file is corrupt?")
+
+            dtype += ('f%i' % bytesPerReal)  # always a floating point
+
+            # determine size of FAB
+            start = na.array(map(int, start.split(',')))
+            stop = na.array(map(int, stop.split(',')))
+
+            gridSize = stop - start + 1
+
+            error_count = 0
+            if (start != grid.start).any():
+                print "Paranoia Error: Cell_H and %s do not agree on grid start." % grid.filename
+                error_count += 1
+            if (stop != grid.stop).any():
+                print "Paranoia Error: Cell_H and %s do not agree on grid stop." % grid.filename
+                error_count += 1
+            if (gridSize != grid.ActiveDimensions).any():
+                print "Paranoia Error: Cell_H and %s do not agree on grid dimensions." % grid.filename
+                error_count += 1
+            if bytesPerReal != grid.hierarchy._bytesPerReal:
+                print "Paranoia Error: Cell_H and %s do not agree on bytes per real number." % grid.filename
+                error_count += 1
+            if (bytesPerReal == grid.hierarchy._bytesPerReal and dtype != grid.hierarchy._dtype):
+                print "Paranoia Error: Cell_H and %s do not agree on endianness." % grid.filename
+                error_count += 1
+
+            if error_count > 0:
+                raise RunTimeError("Paranoia unveiled %i differences between Cell_H and %s." % (error_count, grid.filename))
+        else:
+        """
+        start = grid.start_index
+        stop = grid.stop_index
+        dtype = grid.hierarchy._dtype
+        bytesPerReal = grid.hierarchy._bytesPerReal
+
+        nElements = grid.ActiveDimensions.prod()
+
+        # one field has nElements * bytesPerReal bytes and is located
+        # nElements * bytesPerReal * field_index from the offset location
+        if yt_to_nyx_fields_dict.has_key(field):
+            fieldname = yt_to_nyx_fields_dict[field]
+        else:
+            fieldname = field
+        field_index = grid.field_indexes[fieldname]
+        inFile.seek(int(nElements*bytesPerReal*field_index),1)
+        field = na.fromfile(inFile, count=nElements, dtype=dtype)
+        field = field.reshape(grid.ActiveDimensions[::-1]).swapaxes(0,2)
+
+        # @todo: we can/should also check against the max and min in the header
+        # file
+
+        inFile.close()
+        return field
+
+    def _read_data_slice(self, grid, field, axis, coord):
+        # wishful thinking?
+        sl = [slice(None), slice(None), slice(None)]
+        sl[axis] = slice(coord, coord + 1)
+        #sl = tuple(reversed(sl))
+        return self._read_data_set(grid, field)[sl]


--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/yt/frontends/nyx/setup.py	Fri Jul 29 15:52:48 2011 -0400
@@ -0,0 +1,12 @@
+#!/usr/bin/env python
+import setuptools
+import os, sys, os.path
+
+import os.path
+
+def configuration(parent_package='', top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('nyx', parent_package, top_path)
+    config.make_config_py()  # installs __config__.py
+    config.make_svn_version_py()
+    return config


--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/yt/frontends/nyx/utils.py	Fri Jul 29 15:52:48 2011 -0400
@@ -0,0 +1,36 @@
+"""
+Utilities for dealing with Nyx data
+
+Author: Casey W. Stark <caseywstark at gmail.com>
+Affiliation: UC Berkeley
+Homepage: http://yt.enzotools.org/
+License:
+  Copyright (C) 2011 Casey W. Stark, Matthew Turk.  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/>.
+
+"""
+
+def boxlib_bool_to_int(v):
+    try:
+        return int(v)
+    except ValueError:
+        pass
+    v = v.upper().strip()
+    if v[0] == 'T':
+        return 1
+    elif v[0] == 'F':
+        return 0
\ No newline at end of file


--- a/yt/frontends/orion/data_structures.py	Fri Jul 29 15:52:35 2011 -0400
+++ b/yt/frontends/orion/data_structures.py	Fri Jul 29 15:52:48 2011 -0400
@@ -494,8 +494,9 @@
         pfn = os.path.join(pfname)
         if not os.path.exists(pfn): return False
         castro = any(("castro." in line for line in open(pfn)))
+        nyx = any(("nyx." in line for line in open(pfn)))
         maestro = os.path.exists(os.path.join(pname, "job_info"))
-        orion = (not castro) and (not maestro)
+        orion = (not castro) and (not maestro) and (not nyx)
         return orion
         
     def _parse_parameter_file(self):


--- a/yt/frontends/setup.py	Fri Jul 29 15:52:35 2011 -0400
+++ b/yt/frontends/setup.py	Fri Jul 29 15:52:48 2011 -0400
@@ -9,6 +9,7 @@
     config.add_subpackage("chombo")
     config.add_subpackage("enzo")
     config.add_subpackage("flash")
+    config.add_subpackage("nyx")
     config.add_subpackage("orion")
     config.add_subpackage("ramses")
     config.add_subpackage("tiger")


--- a/yt/gui/reason/html/js/reason.js	Fri Jul 29 15:52:35 2011 -0400
+++ b/yt/gui/reason/html/js/reason.js	Fri Jul 29 15:52:48 2011 -0400
@@ -55,7 +55,9 @@
 }
 
 var repl_input = new Ext.FormPanel({
+    title: 'YT Input',
     url: 'push',
+    flex: 0.2,
     layout: 'fit',
     padding: 5,
     height: '100%',
@@ -133,7 +135,7 @@
     title: 'YT Output',
     id: 'output_container',
     autoScroll: true,
-    flex: 0.7,
+    flex: 0.8,
     items: []
 });
 


--- a/yt/mods.py	Fri Jul 29 15:52:35 2011 -0400
+++ b/yt/mods.py	Fri Jul 29 15:52:48 2011 -0400
@@ -14,12 +14,12 @@
   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/>.
 """
@@ -60,6 +60,9 @@
 from yt.frontends.castro.api import \
     CastroStaticOutput, CastroFieldInfo, add_castro_field
 
+from yt.frontends.nyx.api import \
+    NyxStaticOutput, nyx_fields, add_nyx_field
+
 from yt.frontends.orion.api import \
     OrionStaticOutput, OrionFieldInfo, add_orion_field
 


--- a/yt/utilities/parameter_file_storage.py	Fri Jul 29 15:52:35 2011 -0400
+++ b/yt/utilities/parameter_file_storage.py	Fri Jul 29 15:52:48 2011 -0400
@@ -33,7 +33,7 @@
     parallel_simple_proxy
 
 output_type_registry = {}
-_field_names = ('hash','bn','fp','tt','ctid','class_name','last_seen')
+_field_names = ('hash', 'bn', 'fp', 'tt', 'ctid', 'class_name', 'last_seen')
 
 class NoParameterShelf(Exception):
     pass
@@ -49,6 +49,14 @@
         return "%s" % self.name
 
 class ParameterFileStore(object):
+    """
+    This class is designed to be a semi-persistent storage for parameter
+    files.  By identifying each parameter file with a unique hash, objects
+    can be stored independently of parameter files -- when an object is
+    loaded, the parameter file is as well, based on the hash.  For
+    storage concerns, only a few hundred will be retained in cache.
+
+    """
 
     _shared_state = {}
     _distributed = True
@@ -60,13 +68,11 @@
         self.__dict__ = cls._shared_state
         return self
 
-    def __init__(self, in_memory = False):
+    def __init__(self, in_memory=False):
         """
-        This class is designed to be a semi-persistent storage for parameter
-        files.  By identifying each parameter file with a unique hash, objects
-        can be stored independently of parameter files -- when an object is
-        loaded, the parameter file is as well, based on the hash.  For
-        storage concerns, only a few hundred will be retained in cache.
+        Create the parameter file database if yt is configured to store them.
+        Otherwise, use read-only settings.
+
         """
         if ytcfg.getboolean("yt", "StoreParameterFiles"):
             self._read_only = False
@@ -92,29 +98,23 @@
         # these will be broadcast
 
     def _get_db_name(self):
-        base_file_name = ytcfg.get("yt","ParameterFileStore")
+        base_file_name = ytcfg.get("yt", "ParameterFileStore")
         if not os.access(os.path.expanduser("~/"), os.W_OK):
             return os.path.abspath(base_file_name)
         return os.path.expanduser("~/.yt/%s" % base_file_name)
 
     def get_pf_hash(self, hash):
-        """
-        This returns a parameter file based on a hash.
-        """
+        """ This returns a parameter file based on a hash. """
         return self._convert_pf(self._records[hash])
 
     def get_pf_ctid(self, ctid):
-        """
-        This returns a parameter file based on a CurrentTimeIdentifier.
-        """
+        """ This returns a parameter file based on a CurrentTimeIdentifier. """
         for h in self._records:
             if self._records[h]['ctid'] == ctid:
                 return self._convert_pf(self._records[h])
 
     def _adapt_pf(self, pf):
-        """
-        This turns a parameter file into a CSV entry
-        """
+        """ This turns a parameter file into a CSV entry. """
         return dict(bn=pf.basename,
                     fp=pf.fullpath,
                     tt=pf.current_time,
@@ -123,9 +123,7 @@
                     last_seen=pf._instantiated)
 
     def _convert_pf(self, pf_dict):
-        """
-        This turns a CSV entry into a parameter file 
-        """
+        """ This turns a CSV entry into a parameter file. """
         bn = pf_dict['bn']
         fp = pf_dict['fp']
         fn = os.path.join(fp, bn)
@@ -145,7 +143,7 @@
     def check_pf(self, pf):
         """
         This will ensure that the parameter file (*pf*) handed to it is
-        recorded in the storage unit.  In doing so, it will update path 
+        recorded in the storage unit.  In doing so, it will update path
         and "last_seen" information.
         """
         hash = pf._hash()
@@ -160,9 +158,7 @@
             self.insert_pf(pf)
 
     def insert_pf(self, pf):
-        """
-        This will insert a new *pf* and flush the database to disk.
-        """
+        """ This will insert a new *pf* and flush the database to disk. """
         self._records[pf._hash()] = self._adapt_pf(pf)
         self.flush_db()
 
@@ -176,16 +172,13 @@
         self.flush_db()
 
     def flush_db(self):
-        """
-        This flushes the storage to disk.
-        """
+        """ This flushes the storage to disk. """
         if self._read_only: return
         self._write_out()
         self.read_db()
 
     def get_recent(self, n=10):
-        recs = sorted(self._records.values(),
-                      key = lambda a: -a['last_seen'])[:n]
+        recs = sorted(self._records.values(), key=lambda a: -a['last_seen'])[:n]
         return recs
 
     @parallel_simple_proxy
@@ -204,10 +197,8 @@
 
     @parallel_simple_proxy
     def read_db(self):
-        """
-        This will read the storage device from disk.
-        """
-        f=open(self._get_db_name(), 'rb')
+        """ This will read the storage device from disk. """
+        f = open(self._get_db_name(), 'rb')
         vals = csv.DictReader(f, _field_names)
         db = {}
         for v in vals:


--- a/yt/visualization/plot_modifications.py	Fri Jul 29 15:52:35 2011 -0400
+++ b/yt/visualization/plot_modifications.py	Fri Jul 29 15:52:48 2011 -0400
@@ -60,13 +60,17 @@
 
 class VelocityCallback(PlotCallback):
     _type_name = "velocity"
-    def __init__(self, factor=16):
+    def __init__(self, factor=16, scale=None, scale_units=None):
         """
         Adds a 'quiver' plot of velocity to the plot, skipping all but
         every *factor* datapoint
+        *scale* is the data units per arrow length unit using *scale_units* 
+        (see matplotlib.axes.Axes.quiver for more info)
         """
         PlotCallback.__init__(self)
         self.factor = factor
+        self.scale  = scale
+        self.scale_units = scale_units
 
     def __call__(self, plot):
         # Instantiation of these is cheap
@@ -77,7 +81,7 @@
         else:
             xv = "%s-velocity" % (x_names[plot.data.axis])
             yv = "%s-velocity" % (y_names[plot.data.axis])
-            qcb = QuiverCallback(xv, yv, self.factor)
+            qcb = QuiverCallback(xv, yv, self.factor, self.scale, self.scale_units)
         return qcb(plot)
 
 class MagFieldCallback(PlotCallback):
@@ -102,16 +106,20 @@
 
 class QuiverCallback(PlotCallback):
     _type_name = "quiver"
-    def __init__(self, field_x, field_y, factor):
+    def __init__(self, field_x, field_y, factor, scale, scale_units):
         """
         Adds a 'quiver' plot to any plot, using the *field_x* and *field_y*
-        from the associated data, skipping every *factor* datapoints.
+        from the associated data, skipping every *factor* datapoints
+        *scale* is the data units per arrow length unit using *scale_units* 
+        (see matplotlib.axes.Axes.quiver for more info)
         """
         PlotCallback.__init__(self)
         self.field_x = field_x
         self.field_y = field_y
         self.bv_x = self.bv_y = 0
         self.factor = factor
+        self.scale = scale
+        self.scale_units = scale_units
 
     def __call__(self, plot):
         x0, x1 = plot.xlim
@@ -137,7 +145,7 @@
                            (x0, x1, y0, y1),).transpose()
         X = na.mgrid[0:plot.image._A.shape[0]-1:nx*1j]# + 0.5*factor
         Y = na.mgrid[0:plot.image._A.shape[1]-1:ny*1j]# + 0.5*factor
-        plot._axes.quiver(X,Y, pixX, pixY)
+        plot._axes.quiver(X,Y, pixX, pixY, scale=self.scale, scale_units=self.scale_units)
         plot._axes.set_xlim(xx0,xx1)
         plot._axes.set_ylim(yy0,yy1)
         plot._axes.hold(False)

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