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

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Mon Mar 24 12:11:12 PDT 2014


7 new commits in yt:

https://bitbucket.org/yt_analysis/yt/commits/6d9629a032ee/
Changeset:   6d9629a032ee
Branch:      yt-3.0
User:        galtay
Date:        2014-03-24 00:19:39
Summary:     Added read in of OWLS element mass fractions.
Affected #:  1 file

diff -r 4646247054fb995eb10d56ea41af868479098bdb -r 6d9629a032eed509bb6f1976cf956dfe34e757c6 yt/frontends/sph/io.py
--- a/yt/frontends/sph/io.py
+++ b/yt/frontends/sph/io.py
@@ -14,6 +14,13 @@
 # The full license is in the file COPYING.txt, distributed with this software.
 #-----------------------------------------------------------------------------
 
+
+
+    
+                                  
+
+
+
 import h5py
 import numpy as np
 from .definitions import gadget_ptypes, ghdf5_ptypes
@@ -52,6 +59,9 @@
     _vector_fields = ("Coordinates", "Velocity", "Velocities")
     _known_ptypes = ghdf5_ptypes
     _var_mass = None
+    _element_fields = ('Hydrogen', 'Helium', 'Carbon', 'Nitrogen', 'Oxygen', 
+                       'Neon', 'Magnesium', 'Silicon', 'Iron' )
+
 
     @property
     def var_mass(self):
@@ -99,13 +109,20 @@
                 del coords
                 if mask is None: continue
                 for field in field_list:
+                    
                     if field in ("Mass", "Masses") and \
                         ptype not in self.var_mass:
                         data = np.empty(mask.sum(), dtype="float64")
                         ind = self._known_ptypes.index(ptype) 
                         data[:] = self.pf["Massarr"][ind]
+
+                    elif field in self._element_fields:
+                        rfield = 'ElementAbundance/' + field
+                        data = g[rfield][:][mask,...]
+
                     else:
                         data = g[field][:][mask,...]
+
                     yield (ptype, field), data
             f.close()
 
@@ -143,24 +160,46 @@
         npart = dict(("PartType%s" % (i), v) for i, v in enumerate(pcount)) 
         return npart
 
+
     def _identify_fields(self, data_file):
         f = _get_h5_handle(data_file.filename)
         fields = []
-        cname = self.pf._particle_coordinates_name
-        mname = self.pf._particle_mass_name
-        for key in f.keys():
+        cname = self.pf._particle_coordinates_name  # Coordinates
+        mname = self.pf._particle_mass_name  # Mass
+
+        # loop over all keys in OWLS hdf5 file
+        #--------------------------------------------------
+        for key in f.keys():   
+
+            # only want particle data
+            #--------------------------------------
             if not key.startswith("PartType"): continue
+
+            # particle data group
+            #--------------------------------------
             g = f[key]
             if cname not in g: continue
+
+            # note str => not unicode!
+
             #ptype = int(key[8:])
             ptype = str(key)
+
+            # loop over all keys in PartTypeX group
+            #----------------------------------------
             for k in g.keys():
-                if not hasattr(g[k], "shape"): continue
-                # str => not unicode!
-                fields.append((ptype, str(k)))
-            if mname not in g.keys():
-                # We'll append it anyway.
-                fields.append((ptype, mname))
+
+                if k == 'ElementAbundance':
+                    gp = g[k]
+                    for j in gp.keys():
+                        kk = j
+                        fields.append((ptype, str(kk)))
+                else:
+                    kk = k
+                    if not hasattr(g[kk], "shape"): continue
+                    fields.append((ptype, str(kk)))
+
+
         f.close()
         return fields, {}
 


https://bitbucket.org/yt_analysis/yt/commits/27f3496a8f3f/
Changeset:   27f3496a8f3f
Branch:      yt-3.0
User:        galtay
Date:        2014-03-24 18:05:46
Summary:     aliases setup for species (metals) field such that they can be smoothed.
Affected #:  3 files

diff -r 6d9629a032eed509bb6f1976cf956dfe34e757c6 -r 27f3496a8f3f496bf735d1177645ae54c6158dac yt/fields/field_info_container.py
--- a/yt/fields/field_info_container.py
+++ b/yt/fields/field_info_container.py
@@ -109,7 +109,7 @@
         else:
             sml_name = None
         new_aliases = []
-        for _, alias_name in self.field_aliases:
+        for _, alias_name in self.field_aliases:            
             fn = add_volume_weighted_smoothed_field(ptype,
                 "particle_position", "particle_mass",
                 sml_name, "density", alias_name, self,

diff -r 6d9629a032eed509bb6f1976cf956dfe34e757c6 -r 27f3496a8f3f496bf735d1177645ae54c6158dac yt/frontends/sph/data_structures.py
--- a/yt/frontends/sph/data_structures.py
+++ b/yt/frontends/sph/data_structures.py
@@ -38,7 +38,7 @@
     mass_sun_cgs
 from yt.utilities.cosmology import Cosmology
 from .fields import \
-    SPHFieldInfo
+    SPHFieldInfo, OWLSFieldInfo
 from .definitions import \
     gadget_header_specs, \
     gadget_field_specs, \
@@ -284,6 +284,7 @@
 
 class OWLSDataset(GadgetHDF5Dataset):
     _particle_mass_name = "Mass"
+    _field_info_class = OWLSFieldInfo
 
     def _parse_parameter_file(self):
         handle = h5py.File(self.parameter_filename, mode="r")

diff -r 6d9629a032eed509bb6f1976cf956dfe34e757c6 -r 27f3496a8f3f496bf735d1177645ae54c6158dac yt/frontends/sph/fields.py
--- a/yt/frontends/sph/fields.py
+++ b/yt/frontends/sph/fields.py
@@ -50,3 +50,31 @@
         ("Phi", ("code_length", [], None)),
         ("FormationTime", ("code_time", ["creation_time"], None)),
     )
+
+
+
+
+class OWLSFieldInfo(SPHFieldInfo):
+
+    # override
+    #--------------------------------------------------------------
+    def __init__(self, *args, **kwargs):
+        
+        new_particle_fields = (
+            ('Hydrogen', ('', ['H_fraction'], None)),
+            ('Helium', ('', ['He_fraction'], None)),
+            ('Carbon', ('', ['C_fraction'], None)),
+            ('Nitrogen', ('', ['N_fraction'], None)),
+            ('Oxygen', ('', ['O_fraction'], None)),
+            ('Neon', ('', ['Ne_fraction'], None)),
+            ('Magnesium', ('', ['Mg_fraction'], None)),
+            ('Silicon', ('', ['Si_fraction'], None)),
+            ('Iron', ('', ['Fe_fraction'], None))
+            )
+
+        self.known_particle_fields += new_particle_fields
+        
+        super(OWLSFieldInfo,self).__init__( *args, **kwargs )
+
+
+                        


https://bitbucket.org/yt_analysis/yt/commits/e057f8209cd4/
Changeset:   e057f8209cd4
Branch:      yt-3.0
User:        MatthewTurk
Date:        2014-03-24 19:20:15
Summary:     Adding additional helpers for species fields.
Affected #:  1 file

diff -r 929d2a2983cbc7e83a4fec194e19ffc86c6cc366 -r e057f8209cd4d76731e0b983efaf753f3390b3d5 yt/fields/species_fields.py
--- a/yt/fields/species_fields.py
+++ b/yt/fields/species_fields.py
@@ -53,6 +53,11 @@
              / amu_cgs
     return _number_density
 
+def _create_density_function(ftype, species):
+    def _density(field, data):
+        return data[ftype, "%s_fraction" % species]
+    return _density
+
 def add_species_field_by_density(registry, ftype, species):
     """
     This takes a field registry, a fluid type, and a species name and then
@@ -68,3 +73,19 @@
     registry.add_field((ftype, "%s_number_density" % species),
                         function = _create_number_density_func(ftype, species),
                         units = "cm**-3")
+
+def add_species_field_by_fraction(registry, ftype, species):
+    """
+    This takes a field registry, a fluid type, and a species name and then
+    adds the other fluids based on that.  This assumes that the field
+    "SPECIES_fraction" already exists and refers to mass fraction.
+    """
+    registry.add_field((ftype, "%s_density" % species), 
+                        function = _create_density_func(ftype, species),
+                        units = "g/cm**3")
+    registry.add_field((ftype, "%s_mass" % species),
+                        function = _create_mass_func(ftype, species),
+                        units = "g")
+    registry.add_field((ftype, "%s_number_density" % species),
+                        function = _create_number_density_func(ftype, species),
+                        units = "cm**-3")


https://bitbucket.org/yt_analysis/yt/commits/a151c11e5925/
Changeset:   a151c11e5925
Branch:      yt-3.0
User:        galtay
Date:        2014-03-24 19:27:45
Summary:     merging with matts
Affected #:  26 files

diff -r 27f3496a8f3f496bf735d1177645ae54c6158dac -r a151c11e592522ee0676476b380d0e94706b546f doc/source/analyzing/creating_derived_fields.rst
--- a/doc/source/analyzing/creating_derived_fields.rst
+++ b/doc/source/analyzing/creating_derived_fields.rst
@@ -295,8 +295,6 @@
      (*Advanced*) Should this field appear in the dropdown box in Reason?
    ``not_in_all``
      (*Advanced*) If this is *True*, the field may not be in all the grids.
-   ``projection_conversion``
-     (*Advanced*) Which unit should we multiply by in a projection?
 
 How Do Units Work?
 ------------------

diff -r 27f3496a8f3f496bf735d1177645ae54c6158dac -r a151c11e592522ee0676476b380d0e94706b546f doc/source/analyzing/objects.rst
--- a/doc/source/analyzing/objects.rst
+++ b/doc/source/analyzing/objects.rst
@@ -40,8 +40,7 @@
 
    add_enzo_field("Cooling_Time", units=r"\rm{s}",
                   function=NullFunc,
-                  validators=ValidateDataField("Cooling_Time"),
-                  projection_conversion="1")
+                  validators=ValidateDataField("Cooling_Time"))
 
 Note that we used the ``NullFunc`` function here.  To add a derived field,
 which is not expected to necessarily exist on disk, use the standard

diff -r 27f3496a8f3f496bf735d1177645ae54c6158dac -r a151c11e592522ee0676476b380d0e94706b546f yt/analysis_modules/sunyaev_zeldovich/projection.py
--- a/yt/analysis_modules/sunyaev_zeldovich/projection.py
+++ b/yt/analysis_modules/sunyaev_zeldovich/projection.py
@@ -39,26 +39,35 @@
     pass
 
 vlist = "xyz"
+def setup_sunyaev_zeldovich_fields(registry, ftype, sl_info):
+    def _t_squared(field, data):
+        return data["gas","density"]*data["gas","kT"]*data["gas","kT"]
+    registry.add_field(("gas", "t_squared"),
+                       function = _t_squared,
+                       units="g*keV**2/cm**3")
+    def _beta_perp_squared(field, data):
+        return data["gas","density"]*data["gas","velocity_magnitude"]**2/clight/clight - data["gas","beta_par_squared"]
+    registry.add_field(("gas","beta_perp_squared"), 
+                       function = _beta_perp_squared,
+                       units="g/cm**3")
 
- at derived_field(name=("gas","t_squared"), units="g*keV**2/cm**3")
-def _t_squared(field, data):
-    return data["gas","density"]*data["gas","kT"]*data["gas","kT"]
+    def _beta_par_squared(field, data):
+        return data["gas","beta_par"]**2/data["gas","density"]
+    registry.add_field("gas","beta_par_squared",
+                       function = _beta_par_squared,
+                       units="g/cm**3")
 
- at derived_field(name=("gas","beta_perp_squared"), units="g/cm**3")
-def _beta_perp_squared(field, data):
-    return data["gas","density"]*data["gas","velocity_magnitude"]**2/clight/clight - data["gas","beta_par_squared"]
+    def _t_beta_par(field, data):
+        return data["gas","kT"]*data["gas","beta_par"]
+    registry.add_field(("gas","t_beta_par"),
+                       function = _t_beta_par,
+                       units="keV*g/cm**3")
 
- at derived_field(name=("gas","beta_par_squared"), units="g/cm**3")
-def _beta_par_squared(field, data):
-    return data["gas","beta_par"]**2/data["gas","density"]
-
- at derived_field(name=("gas","t_beta_par"), units="keV*g/cm**3")
-def _t_beta_par(field, data):
-    return data["gas","kT"]*data["gas","beta_par"]
-
- at derived_field(name=("gas","t_sz"), units="keV*g/cm**3")
-def _t_sz(field, data):
-    return data["gas","density"]*data["gas","kT"]
+    def _t_sz(field, data):
+        return data["gas","density"]*data["gas","kT"]
+    registry.add_field(("gas","t_sz"),
+                       function = _t_sz,
+                       units="keV*g/cm**3")
 
 def generate_beta_par(L):
     def _beta_par(field, data):
@@ -90,6 +99,7 @@
     def __init__(self, pf, freqs, mue=1.143, high_order=False):
 
         self.pf = pf
+        pf.field_info.load_plugin(setup_sunyaev_zeldovich_fields)
         self.num_freqs = len(freqs)
         self.high_order = high_order
         self.freqs = pf.arr(freqs, "GHz")
@@ -139,7 +149,6 @@
 
         beta_par = generate_beta_par(L)
         self.pf.field_info.add_field(name=("gas","beta_par"), function=beta_par, units="g/cm**3")
-        proj = self.pf.proj("density", axis, center=ctr, data_source=source)
         frb = proj.to_frb(width, nx)
         dens = frb["density"]
         Te = frb["t_sz"]/dens

diff -r 27f3496a8f3f496bf735d1177645ae54c6158dac -r a151c11e592522ee0676476b380d0e94706b546f yt/data_objects/static_output.py
--- a/yt/data_objects/static_output.py
+++ b/yt/data_objects/static_output.py
@@ -517,7 +517,7 @@
 
     # Now all the object related stuff
     def all_data(self, find_max=False):
-        if find_max: c = self.find_max("Density")[1]
+        if find_max: c = self.find_max("density")[1]
         else: c = (self.domain_right_edge + self.domain_left_edge)/2.0
         return self.region(c,
             self.domain_left_edge, self.domain_right_edge)

diff -r 27f3496a8f3f496bf735d1177645ae54c6158dac -r a151c11e592522ee0676476b380d0e94706b546f yt/fields/derived_field.py
--- a/yt/fields/derived_field.py
+++ b/yt/fields/derived_field.py
@@ -78,14 +78,11 @@
        Used for baryon fields from the data that are not in all the grids
     display_name : str
        A name used in the plots
-    projection_conversion : unit
-       which unit should we multiply by in a projection?
     """
     def __init__(self, name, function, units=None,
                  take_log=True, validators=None,
                  particle_type=False, vector_field=False, display_field=True,
-                 not_in_all=False, display_name=None,
-                 projection_conversion="cm"):
+                 not_in_all=False, display_name=None):
         self.name = name
         self.take_log = take_log
         self.display_name = display_name
@@ -124,7 +121,6 @@
         dd['display_field'] = True
         dd['not_in_all'] = self.not_in_all
         dd['display_name'] = self.display_name
-        dd['projection_conversion'] = self.projection_conversion
         return dd
 
     def get_units(self):

diff -r 27f3496a8f3f496bf735d1177645ae54c6158dac -r a151c11e592522ee0676476b380d0e94706b546f yt/fields/field_detector.py
--- a/yt/fields/field_detector.py
+++ b/yt/fields/field_detector.py
@@ -128,7 +128,9 @@
                 return self[item]
         elif finfo is not None and finfo.particle_type:
             if "particle_position" in (item, item[1]) or \
-               "particle_velocity" in (item, item[1]):
+               "particle_velocity" in (item, item[1]) or \
+               "Velocity" in (item, item[1]) or \
+               "Coordinates" in (item, item[1]):
                 # A vector
                 self[item] = \
                   YTArray(np.ones((self.NumberOfParticles, 3)),

diff -r 27f3496a8f3f496bf735d1177645ae54c6158dac -r a151c11e592522ee0676476b380d0e94706b546f yt/fields/field_info_container.py
--- a/yt/fields/field_info_container.py
+++ b/yt/fields/field_info_container.py
@@ -55,6 +55,7 @@
     known_particle_fields = ()
 
     def __init__(self, pf, field_list, slice_info = None):
+        self._show_field_errors = []
         self.pf = pf
         # Now we start setting things up.
         self.field_list = field_list
@@ -171,8 +172,11 @@
         self.find_dependencies(loaded)
 
     def load_plugin(self, plugin_name, ftype = "gas", skip_check = False):
+        if callable(plugin_name):
+            f = plugin_name
+        else:
+            f = field_plugins[plugin_name]
         orig = set(self.items())
-        f = field_plugins[plugin_name]
         f(self, ftype, slice_info = self.slice_info)
         loaded = [n for n, v in set(self.items()).difference(orig)]
         return loaded
@@ -309,6 +313,8 @@
             try:
                 fd = fi.get_dependencies(pf = self.pf)
             except Exception as e:
+                if field in self._show_field_errors:
+                    raise
                 if type(e) != YTFieldNotFound:
                     mylog.debug("Raises %s during field %s detection.",
                                 str(type(e)), field)

diff -r 27f3496a8f3f496bf735d1177645ae54c6158dac -r a151c11e592522ee0676476b380d0e94706b546f yt/fields/geometric_fields.py
--- a/yt/fields/geometric_fields.py
+++ b/yt/fields/geometric_fields.py
@@ -78,7 +78,6 @@
 
     registry.add_field(("index", "zeros"), function=_zeros,
               units = "",
-              projection_conversion="unitary",
               display_field=False)
 
     def _ones(field, data):
@@ -88,7 +87,6 @@
         return data.apply_units(arr, field.units)
 
     registry.add_field(("index", "ones"), function=_ones,
-              projection_conversion="unitary",
               units = "",
               display_field=False)
 

diff -r 27f3496a8f3f496bf735d1177645ae54c6158dac -r a151c11e592522ee0676476b380d0e94706b546f yt/fields/local_fields.py
--- a/yt/fields/local_fields.py
+++ b/yt/fields/local_fields.py
@@ -18,7 +18,8 @@
 from .field_plugin_registry import \
     register_field_plugin
 
-from .field_info_container import FieldInfoContainer
+from .field_info_container import \
+    FieldInfoContainer
 
 # Empty FieldInfoContainer
 local_fields = FieldInfoContainer(None, [], None)
@@ -31,4 +32,6 @@
     # info container, and since they are not mutable in any real way, we are
     # fine.
     # Note that we actually don't care about the ftype here.
+    for f in local_fields:
+        registry._show_field_errors.append(f)
     registry.update(local_fields)

diff -r 27f3496a8f3f496bf735d1177645ae54c6158dac -r a151c11e592522ee0676476b380d0e94706b546f yt/fields/particle_fields.py
--- a/yt/fields/particle_fields.py
+++ b/yt/fields/particle_fields.py
@@ -80,8 +80,7 @@
     registry.add_field(("deposit", "%s_count" % ptype),
              function = particle_count,
              validators = [ValidateSpatial()],
-             display_name = "\\mathrm{%s Count}" % ptype,
-             projection_conversion = '1')
+             display_name = "\\mathrm{%s Count}" % ptype)
 
     def particle_mass(field, data):
         pos = data[ptype, coord_name]

diff -r 27f3496a8f3f496bf735d1177645ae54c6158dac -r a151c11e592522ee0676476b380d0e94706b546f yt/fields/species_fields.py
--- a/yt/fields/species_fields.py
+++ b/yt/fields/species_fields.py
@@ -53,6 +53,11 @@
              / amu_cgs
     return _number_density
 
+def _create_density_function(ftype, species):
+    def _density(field, data):
+        return data[ftype, "%s_fraction" % species]
+    return _density
+
 def add_species_field_by_density(registry, ftype, species):
     """
     This takes a field registry, a fluid type, and a species name and then
@@ -68,3 +73,19 @@
     registry.add_field((ftype, "%s_number_density" % species),
                         function = _create_number_density_func(ftype, species),
                         units = "cm**-3")
+
+def add_species_field_by_fraction(registry, ftype, species):
+    """
+    This takes a field registry, a fluid type, and a species name and then
+    adds the other fluids based on that.  This assumes that the field
+    "SPECIES_fraction" already exists and refers to mass fraction.
+    """
+    registry.add_field((ftype, "%s_density" % species), 
+                        function = _create_density_func(ftype, species),
+                        units = "g/cm**3")
+    registry.add_field((ftype, "%s_mass" % species),
+                        function = _create_mass_func(ftype, species),
+                        units = "g")
+    registry.add_field((ftype, "%s_number_density" % species),
+                        function = _create_number_density_func(ftype, species),
+                        units = "cm**-3")

diff -r 27f3496a8f3f496bf735d1177645ae54c6158dac -r a151c11e592522ee0676476b380d0e94706b546f yt/frontends/boxlib/fields.py
--- a/yt/frontends/boxlib/fields.py
+++ b/yt/frontends/boxlib/fields.py
@@ -24,8 +24,6 @@
 mom_units = "code_mass * code_length / code_time"
 eden_units = "code_mass / (code_time**2 * code_length)" # erg / cm^3
 
-
-
 def _thermal_energy_density(field, data):
     ke = 0.5 * ( data["momentum_x"]**2
                + data["momentum_y"]**2

diff -r 27f3496a8f3f496bf735d1177645ae54c6158dac -r a151c11e592522ee0676476b380d0e94706b546f yt/frontends/chombo/api.py
--- a/yt/frontends/chombo/api.py
+++ b/yt/frontends/chombo/api.py
@@ -19,8 +19,8 @@
       ChomboDataset
 
 from .fields import \
-      ChomboFieldInfo, \
-      add_chombo_field
+      ChomboFieldInfo
+add_chombo_field = ChomboFieldInfo.add_field
 
 from .io import \
       IOHandlerChomboHDF5

diff -r 27f3496a8f3f496bf735d1177645ae54c6158dac -r a151c11e592522ee0676476b380d0e94706b546f yt/frontends/chombo/data_structures.py
--- a/yt/frontends/chombo/data_structures.py
+++ b/yt/frontends/chombo/data_structures.py
@@ -43,12 +43,15 @@
      mpc_conversion, sec_conversion
 from yt.utilities.parallel_tools.parallel_analysis_interface import \
      parallel_root_only
+from yt.units.yt_array import \
+    YTArray, \
+    YTQuantity
+from yt.utilities.lib.misc_utilities import \
+    get_box_grids_level
 from yt.utilities.io_handler import \
     io_registry
 
-from yt.fields.field_info_container import \
-    FieldInfoContainer, NullFunc
-from .fields import ChomboFieldInfo, KnownChomboFields
+from .fields import ChomboFieldInfo
 
 class ChomboGrid(AMRGridPatch):
     _id_offset = 0
@@ -104,7 +107,6 @@
         self._levels = self._handle.keys()[1:]
         GridIndex.__init__(self,pf,dataset_type)
         self._read_particles()
-        self._fhandle.close()
 
     def _read_particles(self):
         self.particle_filename = self.index_filename[:-4] + 'sink'
@@ -136,7 +138,7 @@
 
     def _detect_output_fields(self):
         ncomp = int(self._handle['/'].attrs['num_components'])
-        self.field_list = [c[1] for c in self._handle['/'].attrs.items()[-ncomp:]]
+        self.field_list = [("chombo", c[1]) for c in self._handle['/'].attrs.items()[-ncomp:]]
           
     def _count_grids(self):
         self.num_grids = 0
@@ -174,32 +176,38 @@
 #        self.grids = np.array(self.grids, dtype='object')
 
     def _populate_grid_objects(self):
+        self._reconstruct_parent_child()
         for g in self.grids:
             g._prepare_grid()
             g._setup_dx()
-
-        for g in self.grids:
-            g.Children = self._get_grid_children(g)
-            for g1 in g.Children:
-                g1.Parent.append(g)
         self.max_level = self.grid_levels.max()
 
     def _setup_derived_fields(self):
         self.derived_field_list = []
 
-    def _get_grid_children(self, grid):
-        mask = np.zeros(self.num_grids, dtype='bool')
-        grids, grid_ind = self.get_box_grids(grid.LeftEdge, grid.RightEdge)
-        mask[grid_ind] = True
-        return [g for g in self.grids[mask] if g.Level == grid.Level + 1]
+    def _reconstruct_parent_child(self):
+        mask = np.empty(len(self.grids), dtype='int32')
+        mylog.debug("First pass; identifying child grids")
+        for i, grid in enumerate(self.grids):
+            get_box_grids_level(self.grid_left_edge[i,:],
+                                self.grid_right_edge[i,:],
+                                self.grid_levels[i] + 1,
+                                self.grid_left_edge, self.grid_right_edge,
+                                self.grid_levels, mask)
+            ids = np.where(mask.astype("bool")) # where is a tuple
+            grid._children_ids = ids[0] + grid._id_offset 
+        mylog.debug("Second pass; identifying parents")
+        for i, grid in enumerate(self.grids): # Second pass
+            for child in grid.Children:
+                child._parent_id.append(i + grid._id_offset)
 
 class ChomboDataset(Dataset):
     _index_class = ChomboHierarchy
-    _fieldinfo_fallback = ChomboFieldInfo
-    _fieldinfo_known = KnownChomboFields
+    _field_info_class = ChomboFieldInfo
 
     def __init__(self, filename, dataset_type='chombo_hdf5',
                  storage_filename = None, ini_filename = None):
+        self.fluid_types += ("chombo",)
         self._handle = h5py.File(filename,'r')
         self.current_time = self._handle.attrs['time']
         self.ini_filename = ini_filename
@@ -216,34 +224,11 @@
     def __del__(self):
         self._handle.close()
 
-    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:
-            self._parse_parameter_file()
-        self._setup_nounits_units()
-        self.conversion_factors = defaultdict(lambda: 1.0)
-        self.time_units['1'] = 1
-        self.units['1'] = 1.0
-        self.units['unitary'] = 1.0 / (self.domain_right_edge - self.domain_left_edge).max()
-        seconds = 1 #self["Time"]
-        for unit in sec_conversion.keys():
-            self.time_units[unit] = seconds / sec_conversion[unit]
-        for key in yt2chomboFieldsDict:
-            self.conversion_factors[key] = 1.0
-
-    def _setup_nounits_units(self):
-        z = 0
-        mylog.warning("Setting 1.0 in code units to be 1.0 cm")
-        if not self.has_key("TimeUnits"):
-            mylog.warning("No time units.  Setting 1.0 = 1 second.")
-            self.conversion_factors["Time"] = 1.0
-        for unit in mpc_conversion.keys():
-            self.units[unit] = mpc_conversion[unit] / mpc_conversion["cm"]
-
+    def _set_code_unit_attributes(self):
+        self.length_unit = YTQuantity(1.0, "cm")
+        self.mass_unit = YTQuantity(1.0, "g")
+        self.time_unit = YTQuantity(1.0, "s")
+        self.velocity_unit = YTQuantity(1.0, "cm/s")
 
     def _localize(self, f, default):
         if f is None:

diff -r 27f3496a8f3f496bf735d1177645ae54c6158dac -r a151c11e592522ee0676476b380d0e94706b546f yt/frontends/chombo/fields.py
--- a/yt/frontends/chombo/fields.py
+++ b/yt/frontends/chombo/fields.py
@@ -13,159 +13,71 @@
 # The full license is in the file COPYING.txt, distributed with this software.
 #-----------------------------------------------------------------------------
 
+import numpy as np
 from yt.fields.field_info_container import \
-    FieldInfoContainer, \
-    FieldInfo, \
-    NullFunc, \
-    ValidateParameter, \
-    ValidateDataField, \
-    ValidateProperty, \
-    ValidateSpatial, \
-    ValidateGridType
-import numpy as np
+    FieldInfoContainer
+from yt.frontends.boxlib.fields import \
+    rho_units, \
+    mom_units, \
+    eden_units, \
+    _thermal_energy_density, \
+    _thermal_energy, \
+    _temperature
 
-KnownChomboFields = FieldInfoContainer()
-add_chombo_field = KnownChomboFields.add_field
+rho_units = "code_mass / code_length**3"
+mom_units = "code_mass * code_length / code_time"
+eden_units = "code_mass / (code_time**2 * code_length)" # erg / cm^3
 
-ChomboFieldInfo = FieldInfoContainer.create_with_fallback(FieldInfo)
-add_field = ChomboFieldInfo.add_field
+# We duplicate everything here from Boxlib, because we want to be able to
+# subclass it and that can be somewhat tricky.
+class ChomboFieldInfo(FieldInfoContainer):
+    known_other_fields = (
+        ("density", (rho_units, ["density"], None)),
+        ("energy-density", (eden_units, ["energy_density"], None)),
+        ("radiation-energy-density", (eden_units, ["radiation_energy_density"], None)),
+        ("X-momentum", (mom_units, ["momentum_x"], None)),
+        ("Y-momentum", (mom_units, ["momentum_y"], None)),
+        ("Z-momentum", (mom_units, ["momentum_z"], None)),
+        ("temperature", ("K", ["temperature"], None)),
+        ("X-magnfield", ("gauss", ["magnetic_field_x"], None)),
+        ("Y-magnfield", ("gauss", ["magnetic_field_y"], None)),
+        ("Z-magnfield", ("gauss", ["magnetic_field_z"], None)),
+    )
 
-add_chombo_field("density", function=NullFunc, take_log=True,
-                 validators = [ValidateDataField("density")],
-                 units="g/cm**3")
+    known_particle_fields = (
+        ("particle_mass", ("code_mass", [], None)),
+        ("particle_position_x", ("code_length", [], None)),
+        ("particle_position_y", ("code_length", [], None)),
+        ("particle_position_z", ("code_length", [], None)),
+        ("particle_momentum_x", (mom_units, [], None)),
+        ("particle_momentum_y", (mom_units, [], None)),
+        ("particle_momentum_z", (mom_units, [], None)),
+        # Note that these are *internal* agmomen
+        ("particle_angmomen_x", ("code_length**2/code_time", [], None)),
+        ("particle_angmomen_y", ("code_length**2/code_time", [], None)),
+        ("particle_angmomen_z", ("code_length**2/code_time", [], None)),
+        ("particle_mlast", ("code_mass", [], None)),
+        ("particle_r", ("code_length", [], None)),
+        ("particle_mdeut", ("code_mass", [], None)),
+        ("particle_n", ("", [], None)),
+        ("particle_mdot", ("code_mass/code_time", [], None)),
+        ("particle_burnstate", ("", [], None)),
+        ("particle_luminosity", ("", [], None)),
+        ("particle_id", ("", ["particle_index"], None)),
+    )
 
-add_chombo_field("X-momentum", function=NullFunc, take_log=False,
-                 validators = [ValidateDataField("X-Momentum")],
-                 units="g/cm**2/s",display_name=r"M_x")
-
-add_chombo_field("Y-momentum", function=NullFunc, take_log=False,
-                 validators = [ValidateDataField("Y-Momentum")],
-                 units="g/cm**2/s",display_name=r"M_y")
-
-add_chombo_field("Z-momentum", function=NullFunc, take_log=False,
-                 validators = [ValidateDataField("Z-Momentum")],
-                 units="g/cm**2/s",display_name=r"M_z")
-
-add_chombo_field("X-magnfield", function=NullFunc, take_log=False,
-                 validators = [ValidateDataField("X-Magnfield")],
-                 units="gauss",display_name=r"B_x")
-
-add_chombo_field("Y-magnfield", function=NullFunc, take_log=False,
-                 validators = [ValidateDataField("Y-Magnfield")],
-                 units="gauss",display_name=r"B_y")
-
-add_chombo_field("Z-magnfield", function=NullFunc, take_log=False,
-                  validators = [ValidateDataField("Z-Magnfield")],
-                  units="gauss",display_name=r"B_z")
-
-add_chombo_field("energy-density", function=NullFunc, take_log=True,
-                 validators = [ValidateDataField("energy-density")],
-                 units="erg/cm**3")
-
-add_chombo_field("radiation-energy-density", function=NullFunc, take_log=True,
-                 validators = [ValidateDataField("radiation-energy-density")],
-                 units="erg/cm**3")
-
-def _Density(field,data):
-    """A duplicate of the density field. This is needed because when you try 
-    to instantiate a PlotCollection without passing in a center, the code
-    will try to generate one for you using the "Density" field, which gives an error 
-    if it isn't defined.
-
-    """
-    return data["density"]
-add_field("Density",function=_Density, take_log=True,
-          units='g/cm**3')
-
-def _Bx(field,data):
-    return data["X-magnfield"]
-add_field("Bx", function=_Bx, take_log=False,
-          units="gauss", display_name=r"B_x")
-
-def _By(field,data):
-    return data["Y-magnfield"]
-add_field("By", function=_By, take_log=False,
-          units="gauss", display_name=r"B_y")
-
-def _Bz(field,data):
-    return data["Z-magnfield"]
-add_field("Bz", function=_Bz, take_log=False,
-          units="gauss", display_name=r"B_z")
-
-def _MagneticEnergy(field,data):
-    return (data["X-magnfield"]**2 +
-            data["Y-magnfield"]**2 +
-            data["Z-magnfield"]**2)/2.
-add_field("MagneticEnergy", function=_MagneticEnergy, take_log=True,
-          units=r"erg/cm**3", display_name=r"B^2 / 8 \pi")
-
-def _xVelocity(field, data):
-    """ Generate x-velocity from x-momentum and density. """
-    return data["X-momentum"]/data["density"]
-add_field("x-velocity",function=_xVelocity, take_log=False,
-          units='cm/s')
-
-def _yVelocity(field,data):
-    """ Generate y-velocity from y-momentum and density. """
-    #try:
-    #    return data["xvel"]
-    #except KeyError:
-    return data["Y-momentum"]/data["density"]
-add_field("y-velocity",function=_yVelocity, take_log=False,
-          units='cm/s')
-
-def _zVelocity(field,data):
-    """ Generate z-velocity from z-momentum and density. """
-    return data["Z-momentum"]/data["density"]
-add_field("z-velocity",function=_zVelocity, take_log=False,
-          units='cm/s')
-
-def particle_func(p_field, dtype='float64'):
-    def _Particles(field, data):
-        io = data.index.io
-        if not data.NumberOfParticles > 0:
-            return np.array([], dtype=dtype)
-        else:
-            return io._read_particles(data, p_field).astype(dtype)
-        
-    return _Particles
-
-_particle_field_list = ["mass",
-                        "position_x",
-                        "position_y",
-                        "position_z",
-                        "momentum_x",
-                        "momentum_y",
-                        "momentum_z",
-                        "angmomen_x",
-                        "angmomen_y",
-                        "angmomen_z",
-                        "mlast",
-                        "r",
-                        "mdeut",
-                        "n",
-                        "mdot",
-                        "burnstate",
-                        "luminosity",
-                        "id"]
-
-for pf in _particle_field_list:
-    pfunc = particle_func("particle_%s" % (pf))
-    add_field("particle_%s" % pf, function=pfunc,
-              validators = [ValidateSpatial(0)],
-              particle_type=True)
-
-def _ParticleMass(field, data):
-    particles = data["particle_mass"].astype('float64')
-    return particles
-
-def _ParticleMassMsun(field, data):
-    particles = data["particle_mass"].astype('float64')
-    return particles/1.989e33
-
-add_field("ParticleMass",
-          function=_ParticleMass, validators=[ValidateSpatial(0)],
-          particle_type=True)
-add_field("ParticleMassMsun",
-          function=_ParticleMassMsun, validators=[ValidateSpatial(0)],
-          particle_type=True)
+    def setup_fluid_fields(self):
+        def _get_vel(axis):
+            def velocity(field, data):
+                return data["%smom" % ax]/data["density"]
+        for ax in 'xyz':
+            self.add_field("velocity_%s" % ax, function = _get_vel(ax),
+                           units = "cm/s")
+        self.add_field("thermal_energy",
+                       function = _thermal_energy,
+                       units = "erg/g")
+        self.add_field("thermal_energy_density",
+                       function = _thermal_energy_density,
+                       units = "erg/cm**3")
+        self.add_field("temperature", function=_temperature,
+                       units="K")

diff -r 27f3496a8f3f496bf735d1177645ae54c6158dac -r a151c11e592522ee0676476b380d0e94706b546f yt/frontends/chombo/io.py
--- a/yt/frontends/chombo/io.py
+++ b/yt/frontends/chombo/io.py
@@ -16,6 +16,7 @@
 import os
 import re
 import numpy as np
+from yt.utilities.logger import ytLogger as mylog
 
 from yt.utilities.io_handler import \
            BaseIOHandler
@@ -26,8 +27,7 @@
     _data_string = 'data:datatype=0'
 
     def __init__(self, pf, *args, **kwargs):
-        BaseIOHandler.__init__(self, *args, **kwargs)
-        self.pf = pf
+        BaseIOHandler.__init__(self, pf)
         self._handle = pf._handle
 
     _field_dict = None
@@ -61,6 +61,52 @@
         
         return data.reshape(dims, order='F')
 
+    def _read_fluid_selection(self, chunks, selector, fields, size):
+        rv = {}
+        chunks = list(chunks)
+        fields.sort(key=lambda a: self.field_dict[a[1]])
+        if selector.__class__.__name__ == "GridSelector":
+            if not (len(chunks) == len(chunks[0].objs) == 1):
+                raise RuntimeError
+            grid = chunks[0].objs[0]
+            lstring = 'level_%i' % grid.Level
+            lev = self._handle[lstring]
+            grid_offset = lev[self._offset_string][grid._level_id]
+            boxsize = grid.ActiveDimensions.prod()
+            for ftype, fname in fields:
+                start = grid_offset+self.field_dict[fname]*boxsize
+                stop = start + boxsize
+                data = lev[self._data_string][start:stop]
+                rv[ftype, fname] = data.reshape(grid.ActiveDimensions,
+                                        order='F')
+            return rv
+        if size is None:
+            size = sum((g.count(selector) for chunk in chunks
+                        for g in chunk.objs))
+        for field in fields:
+            ftype, fname = field
+            fsize = size
+            rv[field] = np.empty(fsize, dtype="float64")
+        ng = sum(len(c.objs) for c in chunks)
+        mylog.debug("Reading %s cells of %s fields in %s grids",
+                   size, [f2 for f1, f2 in fields], ng)
+        ind = 0
+        for chunk in chunks:
+            for g in chunk.objs:
+                lstring = 'level_%i' % g.Level
+                lev = self._handle[lstring]
+                grid_offset = lev[self._offset_string][g._level_id]
+                boxsize = g.ActiveDimensions.prod()
+                nd = 0
+                for field in fields:
+                    start = grid_offset+self.field_dict[fname]*boxsize
+                    stop = start + boxsize
+                    data = lev[self._data_string][start:stop]
+                    data = data.reshape(g.ActiveDimensions, order='F')
+                    nd = g.select(selector, data, rv[field], ind) # caches
+                ind += nd
+        return rv
+
     def _read_particles(self, grid, field):
         """
         parses the Orion Star Particle text files

diff -r 27f3496a8f3f496bf735d1177645ae54c6158dac -r a151c11e592522ee0676476b380d0e94706b546f yt/frontends/sph/io.py
--- a/yt/frontends/sph/io.py
+++ b/yt/frontends/sph/io.py
@@ -14,13 +14,7 @@
 # The full license is in the file COPYING.txt, distributed with this software.
 #-----------------------------------------------------------------------------
 
-
-
-    
-                                  
-
-
-
+import glob
 import h5py
 import numpy as np
 from .definitions import gadget_ptypes, ghdf5_ptypes
@@ -396,6 +390,7 @@
                 "DarkMatter",
                 "Stars" )
 
+    _aux_fields = []
     _fields = ( ("Gas", "Mass"),
                 ("Gas", "Coordinates"),
                 ("Gas", "Velocities"),
@@ -421,7 +416,50 @@
     def _read_fluid_selection(self, chunks, selector, fields, size):
         raise NotImplementedError
 
-    def _fill_fields(self, fields, vals, mask):
+    def _read_aux_fields(self, field, mask, data_file):
+        """
+        Read in auxiliary files from gasoline/pkdgrav 
+        """
+        filename = data_file.filename+'.'+field
+        dtype = None
+        # We need to do some fairly ugly detection to see what format the auxiliary
+        # files are in.  They can be either ascii or binary, and the binary files can be
+        # either floats, ints, or doubles.  We're going to use a try-catch cascade to 
+        # determine the format.
+        try:#ASCII
+            auxdata = np.genfromtxt(filename, skip_header=1)
+            if auxdata.size != np.sum(data_file.total_particles.values()):
+                print "Error reading auxiliary tipsy file"
+                raise RuntimeError 
+        except ValueError:#binary/xdr
+            f = open(filename, 'rb')
+            l = struct.unpack(data_file.pf.endian+"i", f.read(4))[0]
+            if l != np.sum(data_file.total_particles.values()):
+                print "Error reading auxiliary tipsy file"
+                raise RuntimeError
+            dtype = 'd'
+            if field in ('iord', 'igasorder', 'grp'):#These fields are integers
+                dtype = 'i'
+            try:# If we try loading doubles by default, we can catch an exception and try floats next
+                auxdata = np.array(struct.unpack(data_file.pf.endian+(l*dtype), f.read()))
+            except struct.error:
+                f.seek(4)
+                dtype = 'f'
+                try:
+                    auxdata = np.array(struct.unpack(data_file.pf.endian+(l*dtype), f.read()))
+                except struct.error: # None of the binary attempts to read succeeded
+                    print "Error reading auxiliary tipsy file"
+                    raise RuntimeError
+            
+        # Use the mask to slice out the appropriate particle type data
+        if mask.size == data_file.total_particles['DarkMatter']:
+            return auxdata[:data_file.total_particles['DarkMatter']]
+        elif mask.size == data_file.total_particles['Gas']:
+            return auxdata[data_file.total_particles['DarkMatter']:data_file.total_particles['Stars']]
+        else:
+            return auxdata[data_file.total_particles['Stars']:]
+
+    def _fill_fields(self, fields, vals, mask, data_file):
         if mask is None:
             size = 0
         else:
@@ -429,7 +467,9 @@
         rv = {}
         for field in fields:
             mylog.debug("Allocating %s values for %s", size, field)
-            if field in self._vector_fields:
+            if field in self._aux_fields: #Read each of the auxiliary fields
+                rv[field] = self._read_aux_fields(field, mask, data_file)
+            elif field in self._vector_fields:
                 rv[field] = np.empty((size, 3), dtype="float64")
                 if size == 0: continue
                 rv[field][:,0] = vals[field]['x'][mask]
@@ -447,6 +487,7 @@
                       self.domain_right_edge[i] - eps)
         return rv
 
+
     def _read_particle_coords(self, chunks, ptf):
         data_files = set([])
         for chunk in chunks:
@@ -482,7 +523,7 @@
                     p["Coordinates"]['y'].astype("float64"),
                     p["Coordinates"]['z'].astype("float64"))
                 if mask is None: continue
-                tf = self._fill_fields(field_list, p, mask)
+                tf = self._fill_fields(field_list, p, mask, data_file)
                 for field in field_list:
                     yield (ptype, field), tf.pop(field)
             f.close()
@@ -549,6 +590,8 @@
         pds = {}
         field_list = []
         tp = data_file.total_particles
+        aux_filenames = glob.glob(data_file.filename+'.*') # Find out which auxiliaries we have
+        self._aux_fields = [f[1+len(data_file.filename):] for f in aux_filenames]
         for ptype, field in self._fields:
             pfields = []
             if tp[ptype] == 0: continue
@@ -562,6 +605,12 @@
             field_list.append((ptype, field))
         for ptype in pds:
             self._pdtypes[ptype] = np.dtype(pds[ptype])
+        if any(["Gas"==f[0] for f in field_list]): #Add the auxiliary fields to each ptype we have
+            field_list += [("Gas",a) for a in self._aux_fields] 
+        if any(["DarkMatter"==f[0] for f in field_list]):
+            field_list += [("DarkMatter",a) for a in self._aux_fields] 
+        if any(["Stars"==f[0] for f in field_list]):
+            field_list += [("Stars",a) for a in self._aux_fields] 
         self._field_list = field_list
         return self._field_list
 

diff -r 27f3496a8f3f496bf735d1177645ae54c6158dac -r a151c11e592522ee0676476b380d0e94706b546f yt/mods.py
--- a/yt/mods.py
+++ b/yt/mods.py
@@ -102,8 +102,8 @@
     HaloCatalogDataset, HaloCatalogFieldInfo, \
     RockstarDataset, RockstarFieldInfo
 
-#from yt.frontends.chombo.api import \
-#    ChomboDataset, ChomboFieldInfo, add_chombo_field
+from yt.frontends.chombo.api import \
+    ChomboDataset, ChomboFieldInfo, add_chombo_field
 
 from yt.frontends.gdf.api import \
     GDFDataset, GDFFieldInfo, add_gdf_field
@@ -161,7 +161,7 @@
 
 from yt.visualization.volume_rendering.api import \
     ColorTransferFunction, PlanckTransferFunction, ProjectionTransferFunction, \
-    HomogenizedVolume, Camera, off_axis_projection, MosaicFisheyeCamera
+    Camera, off_axis_projection, MosaicFisheyeCamera
 
 from yt.utilities.parallel_tools.parallel_analysis_interface import \
     parallel_objects

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

https://bitbucket.org/yt_analysis/yt/commits/39c441c0c163/
Changeset:   39c441c0c163
Branch:      yt-3.0
User:        galtay
Date:        2014-03-24 19:51:13
Summary:     OWLS metal fields read and all aliases (_fraction, _mass, _density) are
available for SlicePlot and so on.
Affected #:  2 files

diff -r a151c11e592522ee0676476b380d0e94706b546f -r 39c441c0c1631e17df621e6b833b2284814bf77d yt/fields/species_fields.py
--- a/yt/fields/species_fields.py
+++ b/yt/fields/species_fields.py
@@ -53,9 +53,10 @@
              / amu_cgs
     return _number_density
 
-def _create_density_function(ftype, species):
+def _create_density_func(ftype, species):
     def _density(field, data):
-        return data[ftype, "%s_fraction" % species]
+        return data[ftype, "%s_fraction" % species] \
+            * data[ftype,'density']
     return _density
 
 def add_species_field_by_density(registry, ftype, species):

diff -r a151c11e592522ee0676476b380d0e94706b546f -r 39c441c0c1631e17df621e6b833b2284814bf77d yt/frontends/sph/fields.py
--- a/yt/frontends/sph/fields.py
+++ b/yt/frontends/sph/fields.py
@@ -23,6 +23,10 @@
     gadget_ptypes, \
     ghdf5_ptypes
 
+from yt.fields.species_fields import add_species_field_by_fraction
+
+
+
 # Here are helper functions for things like vector fields and so on.
 
 def _get_conv(cf):
@@ -56,6 +60,10 @@
 
 class OWLSFieldInfo(SPHFieldInfo):
 
+    _species_fractions = ['H_fraction', 'He_fraction', 'C_fraction',
+                          'N_fraction', 'O_fraction', 'Ne_fraction',
+                          'Mg_fraction', 'Si_fraction', 'Fe_fraction']
+
     # override
     #--------------------------------------------------------------
     def __init__(self, *args, **kwargs):
@@ -77,4 +85,9 @@
         super(OWLSFieldInfo,self).__init__( *args, **kwargs )
 
 
-                        
+        
+    def setup_fluid_fields(self):
+        # here species_name is "H", "He", etc
+        for s in self._species_fractions:
+            species_name = s.split('_')[0]
+            add_species_field_by_fraction(self, "gas", species_name)


https://bitbucket.org/yt_analysis/yt/commits/0536fb651691/
Changeset:   0536fb651691
Branch:      yt-3.0
User:        galtay
Date:        2014-03-24 20:06:43
Summary:     removed white space
Affected #:  1 file

diff -r 39c441c0c1631e17df621e6b833b2284814bf77d -r 0536fb6516915620927dcffb4281021a46b73214 yt/fields/field_info_container.py
--- a/yt/fields/field_info_container.py
+++ b/yt/fields/field_info_container.py
@@ -110,7 +110,7 @@
         else:
             sml_name = None
         new_aliases = []
-        for _, alias_name in self.field_aliases:            
+        for _, alias_name in self.field_aliases:
             fn = add_volume_weighted_smoothed_field(ptype,
                 "particle_position", "particle_mass",
                 sml_name, "density", alias_name, self,


https://bitbucket.org/yt_analysis/yt/commits/5540ec009f97/
Changeset:   5540ec009f97
Branch:      yt-3.0
User:        MatthewTurk
Date:        2014-03-24 20:11:05
Summary:     Merged in galtay/yt/yt-3.0 (pull request #753)

IO for OWLS Element Fields
Affected #:  5 files

diff -r 21a57d1a44d2494dfe972e90280f5074e9f3da39 -r 5540ec009f9767fb11b35ec8aebf4d39f8709a85 yt/fields/species_fields.py
--- a/yt/fields/species_fields.py
+++ b/yt/fields/species_fields.py
@@ -53,6 +53,12 @@
              / amu_cgs
     return _number_density
 
+def _create_density_func(ftype, species):
+    def _density(field, data):
+        return data[ftype, "%s_fraction" % species] \
+            * data[ftype,'density']
+    return _density
+
 def add_species_field_by_density(registry, ftype, species):
     """
     This takes a field registry, a fluid type, and a species name and then
@@ -68,3 +74,19 @@
     registry.add_field((ftype, "%s_number_density" % species),
                         function = _create_number_density_func(ftype, species),
                         units = "cm**-3")
+
+def add_species_field_by_fraction(registry, ftype, species):
+    """
+    This takes a field registry, a fluid type, and a species name and then
+    adds the other fluids based on that.  This assumes that the field
+    "SPECIES_fraction" already exists and refers to mass fraction.
+    """
+    registry.add_field((ftype, "%s_density" % species), 
+                        function = _create_density_func(ftype, species),
+                        units = "g/cm**3")
+    registry.add_field((ftype, "%s_mass" % species),
+                        function = _create_mass_func(ftype, species),
+                        units = "g")
+    registry.add_field((ftype, "%s_number_density" % species),
+                        function = _create_number_density_func(ftype, species),
+                        units = "cm**-3")

diff -r 21a57d1a44d2494dfe972e90280f5074e9f3da39 -r 5540ec009f9767fb11b35ec8aebf4d39f8709a85 yt/frontends/sph/data_structures.py
--- a/yt/frontends/sph/data_structures.py
+++ b/yt/frontends/sph/data_structures.py
@@ -38,7 +38,7 @@
     mass_sun_cgs
 from yt.utilities.cosmology import Cosmology
 from .fields import \
-    SPHFieldInfo
+    SPHFieldInfo, OWLSFieldInfo
 from .definitions import \
     gadget_header_specs, \
     gadget_field_specs, \
@@ -284,6 +284,7 @@
 
 class OWLSDataset(GadgetHDF5Dataset):
     _particle_mass_name = "Mass"
+    _field_info_class = OWLSFieldInfo
 
     def _parse_parameter_file(self):
         handle = h5py.File(self.parameter_filename, mode="r")

diff -r 21a57d1a44d2494dfe972e90280f5074e9f3da39 -r 5540ec009f9767fb11b35ec8aebf4d39f8709a85 yt/frontends/sph/fields.py
--- a/yt/frontends/sph/fields.py
+++ b/yt/frontends/sph/fields.py
@@ -23,6 +23,10 @@
     gadget_ptypes, \
     ghdf5_ptypes
 
+from yt.fields.species_fields import add_species_field_by_fraction
+
+
+
 # Here are helper functions for things like vector fields and so on.
 
 def _get_conv(cf):
@@ -50,3 +54,40 @@
         ("Phi", ("code_length", [], None)),
         ("FormationTime", ("code_time", ["creation_time"], None)),
     )
+
+
+
+
+class OWLSFieldInfo(SPHFieldInfo):
+
+    _species_fractions = ['H_fraction', 'He_fraction', 'C_fraction',
+                          'N_fraction', 'O_fraction', 'Ne_fraction',
+                          'Mg_fraction', 'Si_fraction', 'Fe_fraction']
+
+    # override
+    #--------------------------------------------------------------
+    def __init__(self, *args, **kwargs):
+        
+        new_particle_fields = (
+            ('Hydrogen', ('', ['H_fraction'], None)),
+            ('Helium', ('', ['He_fraction'], None)),
+            ('Carbon', ('', ['C_fraction'], None)),
+            ('Nitrogen', ('', ['N_fraction'], None)),
+            ('Oxygen', ('', ['O_fraction'], None)),
+            ('Neon', ('', ['Ne_fraction'], None)),
+            ('Magnesium', ('', ['Mg_fraction'], None)),
+            ('Silicon', ('', ['Si_fraction'], None)),
+            ('Iron', ('', ['Fe_fraction'], None))
+            )
+
+        self.known_particle_fields += new_particle_fields
+        
+        super(OWLSFieldInfo,self).__init__( *args, **kwargs )
+
+
+        
+    def setup_fluid_fields(self):
+        # here species_name is "H", "He", etc
+        for s in self._species_fractions:
+            species_name = s.split('_')[0]
+            add_species_field_by_fraction(self, "gas", species_name)

diff -r 21a57d1a44d2494dfe972e90280f5074e9f3da39 -r 5540ec009f9767fb11b35ec8aebf4d39f8709a85 yt/frontends/sph/io.py
--- a/yt/frontends/sph/io.py
+++ b/yt/frontends/sph/io.py
@@ -53,6 +53,9 @@
     _vector_fields = ("Coordinates", "Velocity", "Velocities")
     _known_ptypes = ghdf5_ptypes
     _var_mass = None
+    _element_fields = ('Hydrogen', 'Helium', 'Carbon', 'Nitrogen', 'Oxygen', 
+                       'Neon', 'Magnesium', 'Silicon', 'Iron' )
+
 
     @property
     def var_mass(self):
@@ -100,13 +103,20 @@
                 del coords
                 if mask is None: continue
                 for field in field_list:
+                    
                     if field in ("Mass", "Masses") and \
                         ptype not in self.var_mass:
                         data = np.empty(mask.sum(), dtype="float64")
                         ind = self._known_ptypes.index(ptype) 
                         data[:] = self.pf["Massarr"][ind]
+
+                    elif field in self._element_fields:
+                        rfield = 'ElementAbundance/' + field
+                        data = g[rfield][:][mask,...]
+
                     else:
                         data = g[field][:][mask,...]
+
                     yield (ptype, field), data
             f.close()
 
@@ -144,24 +154,46 @@
         npart = dict(("PartType%s" % (i), v) for i, v in enumerate(pcount)) 
         return npart
 
+
     def _identify_fields(self, data_file):
         f = _get_h5_handle(data_file.filename)
         fields = []
-        cname = self.pf._particle_coordinates_name
-        mname = self.pf._particle_mass_name
-        for key in f.keys():
+        cname = self.pf._particle_coordinates_name  # Coordinates
+        mname = self.pf._particle_mass_name  # Mass
+
+        # loop over all keys in OWLS hdf5 file
+        #--------------------------------------------------
+        for key in f.keys():   
+
+            # only want particle data
+            #--------------------------------------
             if not key.startswith("PartType"): continue
+
+            # particle data group
+            #--------------------------------------
             g = f[key]
             if cname not in g: continue
+
+            # note str => not unicode!
+
             #ptype = int(key[8:])
             ptype = str(key)
+
+            # loop over all keys in PartTypeX group
+            #----------------------------------------
             for k in g.keys():
-                if not hasattr(g[k], "shape"): continue
-                # str => not unicode!
-                fields.append((ptype, str(k)))
-            if mname not in g.keys():
-                # We'll append it anyway.
-                fields.append((ptype, mname))
+
+                if k == 'ElementAbundance':
+                    gp = g[k]
+                    for j in gp.keys():
+                        kk = j
+                        fields.append((ptype, str(kk)))
+                else:
+                    kk = k
+                    if not hasattr(g[kk], "shape"): continue
+                    fields.append((ptype, str(kk)))
+
+
         f.close()
         return fields, {}

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