[yt-svn] commit/yt: ngoldbaum: Merged in atmyers/yt (pull request #1186)

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Sat Sep 20 20:24:41 PDT 2014


1 new commit in yt:

https://bitbucket.org/yt_analysis/yt/commits/d596ad6eafb7/
Changeset:   d596ad6eafb7
Branch:      yt
User:        ngoldbaum
Date:        2014-09-21 03:24:32+00:00
Summary:     Merged in atmyers/yt (pull request #1186)

Chombo frontend improvements
Affected #:  15 files

diff -r dc60658345cd68e6e29218b52b0566053c62b144 -r d596ad6eafb7a3f32ed448f66aaa633aae216520 doc/source/reference/code_support.rst
--- a/doc/source/reference/code_support.rst
+++ b/doc/source/reference/code_support.rst
@@ -24,7 +24,7 @@
 +-----------------------+------------+-----------+------------+-------+----------+----------+------------+----------+ 
 | Castro                |     Y      |     Y     |   Partial  |   Y   |    Y     |    Y     |     N      |   Full   |
 +-----------------------+------------+-----------+------------+-------+----------+----------+------------+----------+ 
-| Chombo                |     Y      |     N     |      Y     |   Y   |    Y     |    Y     |     Y      | Partial  |
+| Chombo                |     Y      |     Y     |      Y     |   Y   |    Y     |    Y     |     Y      |   Full   |
 +-----------------------+------------+-----------+------------+-------+----------+----------+------------+----------+ 
 | Enzo                  |     Y      |     Y     |      Y     |   Y   |    Y     |    Y     |     Y      |   Full   |
 +-----------------------+------------+-----------+------------+-------+----------+----------+------------+----------+ 

diff -r dc60658345cd68e6e29218b52b0566053c62b144 -r d596ad6eafb7a3f32ed448f66aaa633aae216520 yt/data_objects/profiles.py
--- a/yt/data_objects/profiles.py
+++ b/yt/data_objects/profiles.py
@@ -955,7 +955,7 @@
     x_min : float
         The minimum value of the x profile field.
     x_max : float
-        The maximum value of hte x profile field.
+        The maximum value of the x profile field.
     x_log : boolean
         Controls whether or not the bins for the x field are evenly
         spaced in linear (False) or log (True) space.

diff -r dc60658345cd68e6e29218b52b0566053c62b144 -r d596ad6eafb7a3f32ed448f66aaa633aae216520 yt/fields/derived_field.py
--- a/yt/fields/derived_field.py
+++ b/yt/fields/derived_field.py
@@ -195,7 +195,7 @@
 
     def get_label(self, projected=False):
         """
-        Return a data label for the given field, inluding units.
+        Return a data label for the given field, including units.
         """
         name = self.name[1]
         if self.display_name is not None:

diff -r dc60658345cd68e6e29218b52b0566053c62b144 -r d596ad6eafb7a3f32ed448f66aaa633aae216520 yt/fields/vector_operations.py
--- a/yt/fields/vector_operations.py
+++ b/yt/fields/vector_operations.py
@@ -43,18 +43,14 @@
                            ftype = "gas", slice_info = None,
                            validators = None, particle_type=False):
 
-    xn, yn, zn = [(ftype, "%s_%s" % (basename, ax)) for ax in 'xyz']
-
-    # Is this safe?
-    if registry.ds.dimensionality < 3:
-        zn = ("index", "zeros")
-    if registry.ds.dimensionality < 2:
-        yn = ("index", "zeros")
+    field_components = [(ftype, "%s_%s" % (basename, ax)) for ax in 'xyz']
 
     def _magnitude(field, data):
-        mag  = data[xn] * data[xn]
-        mag += data[yn] * data[yn]
-        mag += data[zn] * data[zn]
+        fn = field_components[0]
+        mag = data[fn] * data[fn]
+        for idim in range(1, registry.ds.dimensionality):
+            fn = field_components[idim]
+            mag += data[fn] * data[fn]
         return np.sqrt(mag)
 
     registry.add_field((ftype, "%s_magnitude" % basename),
@@ -65,18 +61,14 @@
                          ftype = "gas", slice_info = None,
                          validators = None, particle_type=False):
 
-    xn, yn, zn = [(ftype, "%s_%s" % (basename, ax)) for ax in 'xyz']
-
-    # Is this safe?
-    if registry.ds.dimensionality < 3:
-        zn = ("index", "zeros")
-    if registry.ds.dimensionality < 2:
-        yn = ("index", "zeros")
+    field_components = [(ftype, "%s_%s" % (basename, ax)) for ax in 'xyz']
 
     def _squared(field, data):
-        squared  = data[xn] * data[xn]
-        squared += data[yn] * data[yn]
-        squared += data[zn] * data[zn]
+        fn = field_components[0]
+        squared  = data[fn] * data[fn]
+        for idim in range(1, registry.ds.dimensionality):
+            fn = field_components[idim]
+            squared += data[fn] * data[fn]
         return squared
 
     registry.add_field((ftype, "%s_squared" % basename),

diff -r dc60658345cd68e6e29218b52b0566053c62b144 -r d596ad6eafb7a3f32ed448f66aaa633aae216520 yt/frontends/chombo/api.py
--- a/yt/frontends/chombo/api.py
+++ b/yt/frontends/chombo/api.py
@@ -14,14 +14,24 @@
 #-----------------------------------------------------------------------------
 
 from .data_structures import \
-      ChomboGrid, \
-      ChomboHierarchy, \
-      ChomboDataset, \
-      Orion2Hierarchy, \
-      Orion2Dataset
+    ChomboGrid, \
+    ChomboHierarchy, \
+    ChomboDataset, \
+    Orion2Hierarchy, \
+    Orion2Dataset, \
+    ChomboPICHierarchy, \
+    ChomboPICDataset, \
+    PlutoHierarchy, \
+    PlutoDataset
 
 from .fields import \
-      ChomboFieldInfo
+    ChomboFieldInfo, \
+    Orion2FieldInfo, \
+    ChomboPICFieldInfo1D, \
+    ChomboPICFieldInfo2D, \
+    ChomboPICFieldInfo3D, \
+    PlutoFieldInfo
 
 from .io import \
-      IOHandlerChomboHDF5
+    IOHandlerChomboHDF5,\
+    IOHandlerPlutoHDF5

diff -r dc60658345cd68e6e29218b52b0566053c62b144 -r d596ad6eafb7a3f32ed448f66aaa633aae216520 yt/frontends/chombo/data_structures.py
--- a/yt/frontends/chombo/data_structures.py
+++ b/yt/frontends/chombo/data_structures.py
@@ -18,6 +18,7 @@
 import os
 import weakref
 import numpy as np
+import six
 
 from collections import \
      defaultdict
@@ -42,7 +43,10 @@
 from yt.utilities.io_handler import \
     io_registry
 
-from .fields import ChomboFieldInfo, Orion2FieldInfo
+from .fields import ChomboFieldInfo, Orion2FieldInfo, \
+    ChomboPICFieldInfo1D, ChomboPICFieldInfo2D, ChomboPICFieldInfo3D, \
+    PlutoFieldInfo
+
 
 class ChomboGrid(AMRGridPatch):
     _id_offset = 0
@@ -89,6 +93,7 @@
         return [self.index.grids[cid - self._id_offset]
                 for cid in self._children_ids]
 
+
 class ChomboHierarchy(GridIndex):
 
     grid = ChomboGrid
@@ -123,7 +128,7 @@
         # only do anything if the dataset contains particles
         if not any([f[1].startswith('particle_') for f in self.field_list]):
             return
-        
+
         self.num_particles = 0
         particles_per_grid = []
         for key, val in self._handle.items():
@@ -189,7 +194,7 @@
             for level_id, box in enumerate(boxes):
                 si = np.array([box['lo_%s' % ax] for ax in 'ijk'[:D]])
                 ei = np.array([box['hi_%s' % ax] for ax in 'ijk'[:D]])
-                
+
                 if D == 1:
                     si = np.concatenate((si, [0.0, 0.0]))
                     ei = np.concatenate((ei, [0.0, 0.0]))
@@ -236,6 +241,7 @@
             for child in grid.Children:
                 child._parent_id.append(i + grid._id_offset)
 
+
 class ChomboDataset(Dataset):
     _index_class = ChomboHierarchy
     _field_info_class = ChomboFieldInfo
@@ -254,12 +260,17 @@
         if D == 3:
             self.dataset_type = 'chombo_hdf5'
 
-        # some datasets will not be time-dependent, make
+        # some datasets will not be time-dependent, and to make
+        # matters worse, the simulation time is not always
+        # stored in the same place in the hdf file! Make
         # sure we handle that here.
         try:
             self.current_time = self._handle.attrs['time']
         except KeyError:
-            self.current_time = 0.0
+            try:
+                self.current_time = self._handle['/level_0'].attrs['time']
+            except KeyError:
+                self.current_time = 0.0
 
         self.geometry = "cartesian"
         self.ini_filename = ini_filename
@@ -274,10 +285,13 @@
         self.parameters["EOSType"] = -1 # default
 
     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")
+        mylog.warning("Setting code length to be 1.0 cm")
+        mylog.warning("Setting code mass to be 1.0 g")
+        mylog.warning("Setting code time to be 1.0 s")
+        self.length_unit = self.quan(1.0, "cm")
+        self.mass_unit = self.quan(1.0, "g")
+        self.time_unit = self.quan(1.0, "s")
+        self.velocity_unit = self.length_unit / self.time_unit
 
     def _localize(self, f, default):
         if f is None:
@@ -285,7 +299,7 @@
         return f
 
     def _parse_parameter_file(self):
-        
+
         self.unique_identifier = \
                                int(os.stat(self.parameter_filename)[ST_CTIME])
         self.dimensionality = self._handle['Chombo_global/'].attrs['SpaceDim']
@@ -303,9 +317,19 @@
             self.domain_left_edge = np.concatenate((self.domain_left_edge, [0.0]))
             self.domain_right_edge = np.concatenate((self.domain_right_edge, [1.0]))
             self.domain_dimensions = np.concatenate((self.domain_dimensions, [1]))
-        
+
         self.refine_by = self._handle['/level_0'].attrs['ref_ratio']
-        self.periodicity = (True, True, True)
+        self._determine_periodic()
+
+    def _determine_periodic(self):
+        # we default to true unless the HDF5 file says otherwise
+        is_periodic = np.array([True, True, True])
+        for dir in range(self.dimensionality):
+            try:
+                is_periodic[dir] = self._handle['/level_0'].attrs['is_periodic_%d' % dir]
+            except KeyError:
+                is_periodic[dir] = True
+        self.periodicity = tuple(is_periodic)
 
     def _calc_left_edge(self):
         fileh = self._handle
@@ -331,22 +355,23 @@
     @classmethod
     def _is_valid(self, *args, **kwargs):
 
-        pluto_ini_file_exists  = False
+        pluto_ini_file_exists = False
         orion2_ini_file_exists = False
 
-        if type(args[0]) == type(""):
+        if isinstance(args[0], six.string_types): 
             dir_name = os.path.dirname(os.path.abspath(args[0]))
             pluto_ini_filename = os.path.join(dir_name, "pluto.ini")
             orion2_ini_filename = os.path.join(dir_name, "orion2.ini")
             pluto_ini_file_exists = os.path.isfile(pluto_ini_filename)
             orion2_ini_file_exists = os.path.isfile(orion2_ini_filename)
 
-        if not (pluto_ini_file_exists and orion2_ini_file_exists):
+        if not (pluto_ini_file_exists or orion2_ini_file_exists):
             try:
                 fileh = h5py.File(args[0],'r')
                 valid = "Chombo_global" in fileh["/"]
                 # ORION2 simulations should always have this:
                 valid = valid and not ('CeilVA_mass' in fileh.attrs.keys())
+                valid = valid and not ('Charm_global' in fileh.keys())
                 fileh.close()
                 return valid
             except:
@@ -363,6 +388,138 @@
             v = getattr(self, a)
             mylog.info("Parameters: %-25s = %s", a, v)
 
+
+class PlutoHierarchy(ChomboHierarchy):
+
+    def __init__(self, ds, dataset_type="pluto_chombo_native"):
+        ChomboHierarchy.__init__(self, ds, dataset_type)
+
+    def _parse_index(self):
+        f = self._handle # shortcut
+        self.max_level = f.attrs['num_levels'] - 1
+
+        grids = []
+        self.dds_list = []
+        i = 0
+        D = self.dataset.dimensionality
+        for lev_index, lev in enumerate(self._levels):
+            level_number = int(re.match('level_(\d+)',lev).groups()[0])
+            try:
+                boxes = f[lev]['boxes'].value
+            except KeyError:
+                boxes = f[lev]['particles:boxes'].value
+            dx = f[lev].attrs['dx']
+            self.dds_list.append(dx * np.ones(3))
+
+            if D == 1:
+                self.dds_list[lev_index][1] = 1.0
+                self.dds_list[lev_index][2] = 1.0
+
+            if D == 2:
+                self.dds_list[lev_index][2] = 1.0
+
+            for level_id, box in enumerate(boxes):
+                si = np.array([box['lo_%s' % ax] for ax in 'ijk'[:D]])
+                ei = np.array([box['hi_%s' % ax] for ax in 'ijk'[:D]])
+
+                if D == 1:
+                    si = np.concatenate((si, [0.0, 0.0]))
+                    ei = np.concatenate((ei, [0.0, 0.0]))
+
+                if D == 2:
+                    si = np.concatenate((si, [0.0]))
+                    ei = np.concatenate((ei, [0.0]))
+
+                pg = self.grid(len(grids),self,level=level_number,
+                               start = si, stop = ei)
+                grids.append(pg)
+                grids[-1]._level_id = level_id
+                self.grid_levels[i] = level_number
+                self.grid_left_edge[i] = self.dds_list[lev_index]*si.astype(self.float_type)+self.domain_left_edge.value
+                self.grid_right_edge[i] = self.dds_list[lev_index]*(ei.astype(self.float_type)+1)+self.domain_left_edge.value
+                self.grid_particle_count[i] = 0
+                self.grid_dimensions[i] = ei - si + 1
+                i += 1
+        self.grids = np.empty(len(grids), dtype='object')
+        for gi, g in enumerate(grids): self.grids[gi] = g
+
+
+class PlutoDataset(ChomboDataset):
+
+    _index_class = PlutoHierarchy
+    _field_info_class = PlutoFieldInfo
+
+    def __init__(self, filename, dataset_type='pluto_chombo_native',
+                 storage_filename = None, ini_filename = None):
+
+        ChomboDataset.__init__(self, filename, dataset_type, 
+                    storage_filename, ini_filename)
+
+    def _parse_parameter_file(self):
+        """
+        Check to see whether a 'pluto.ini' file
+        exists in the plot file directory. If one does, attempt to parse it.
+        Otherwise grab the dimensions from the hdf5 file.
+        """
+
+        pluto_ini_file_exists = False
+        dir_name = os.path.dirname(os.path.abspath(self.fullplotdir))
+        pluto_ini_filename = os.path.join(dir_name, "pluto.ini")
+        pluto_ini_file_exists = os.path.isfile(pluto_ini_filename)
+
+        self.unique_identifier = \
+                               int(os.stat(self.parameter_filename)[ST_CTIME])
+        self.dimensionality = self._handle['Chombo_global/'].attrs['SpaceDim']
+        self.domain_dimensions = self._calc_domain_dimensions()
+        self.refine_by = self._handle['/level_0'].attrs['ref_ratio']
+
+        if pluto_ini_file_exists:
+            lines=[line.strip() for line in open(pluto_ini_filename)]
+            self.domain_left_edge = np.zeros(self.dimensionality)
+            self.domain_right_edge = np.zeros(self.dimensionality)
+            for il,ll in enumerate(lines[lines.index('[Grid]')+2:lines.index('[Grid]')+2+self.dimensionality]):
+                self.domain_left_edge[il] = float(ll.split()[2])
+                self.domain_right_edge[il] = float(ll.split()[-1])
+            self.periodicity = [0]*3
+            for il,ll in enumerate(lines[lines.index('[Boundary]')+2:lines.index('[Boundary]')+2+6:2]):
+                self.periodicity[il] = (ll.split()[1] == 'periodic')
+            self.periodicity=tuple(self.periodicity)
+            for il,ll in enumerate(lines[lines.index('[Parameters]')+2:]):
+                if (ll.split()[0] == 'GAMMA'):
+                    self.gamma = float(ll.split()[1])
+        else:
+            self.domain_left_edge = self._calc_left_edge()
+            self.domain_right_edge = self._calc_right_edge()
+            self.periodicity = (True, True, True)
+
+        # if a lower-dimensional dataset, set up pseudo-3D stuff here.
+        if self.dimensionality == 1:
+            self.domain_left_edge = np.concatenate((self.domain_left_edge, [0.0, 0.0]))
+            self.domain_right_edge = np.concatenate((self.domain_right_edge, [1.0, 1.0]))
+            self.domain_dimensions = np.concatenate((self.domain_dimensions, [1, 1]))
+
+        if self.dimensionality == 2:
+            self.domain_left_edge = np.concatenate((self.domain_left_edge, [0.0]))
+            self.domain_right_edge = np.concatenate((self.domain_right_edge, [1.0]))
+            self.domain_dimensions = np.concatenate((self.domain_dimensions, [1]))
+
+
+    @classmethod
+    def _is_valid(self, *args, **kwargs):
+
+        pluto_ini_file_exists = False
+
+        if isinstance(args[0], six.string_types):
+            dir_name = os.path.dirname(os.path.abspath(args[0]))
+            pluto_ini_filename = os.path.join(dir_name, "pluto.ini")
+            pluto_ini_file_exists = os.path.isfile(pluto_ini_filename)
+
+        if pluto_ini_file_exists:
+            return True
+
+        return False
+
+
 class Orion2Hierarchy(ChomboHierarchy):
 
     def __init__(self, ds, dataset_type="orion_chombo_native"):
@@ -396,6 +553,7 @@
                     self.grid_particle_count[ind] += 1
                     self.grids[ind].NumberOfParticles += 1
 
+
 class Orion2Dataset(ChomboDataset):
 
     _index_class = Orion2Hierarchy
@@ -427,7 +585,7 @@
         self.domain_right_edge = self._calc_right_edge()
         self.domain_dimensions = self._calc_domain_dimensions()
         self.refine_by = self._handle['/level_0'].attrs['ref_ratio']
-        self.periodicity = (True, True, True)
+        self._determine_periodic()
 
     def _parse_inputs_file(self, ini_filename):
         self.fullplotdir = os.path.abspath(self.parameter_filename)
@@ -449,7 +607,7 @@
     @classmethod
     def _is_valid(self, *args, **kwargs):
 
-        pluto_ini_file_exists  = False
+        pluto_ini_file_exists = False
         orion2_ini_file_exists = False
 
         if type(args[0]) == type(""):
@@ -458,18 +616,70 @@
             orion2_ini_filename = os.path.join(dir_name, "orion2.ini")
             pluto_ini_file_exists = os.path.isfile(pluto_ini_filename)
             orion2_ini_file_exists = os.path.isfile(orion2_ini_filename)
-        
+
         if orion2_ini_file_exists:
             return True
 
         if not pluto_ini_file_exists:
             try:
                 fileh = h5py.File(args[0],'r')
-                valid = "Chombo_global" in fileh["/"]
                 valid = 'CeilVA_mass' in fileh.attrs.keys()
+                valid = "Chombo_global" in fileh["/"] and "Charm_global" not in fileh["/"]
+                valid = valid and 'CeilVA_mass' in fileh.attrs.keys()
                 fileh.close()
                 return valid
             except:
                 pass
         return False
 
+
+class ChomboPICHierarchy(ChomboHierarchy):
+
+    def __init__(self, ds, dataset_type="chombo_hdf5"):
+        ChomboHierarchy.__init__(self, ds, dataset_type)
+
+
+class ChomboPICDataset(ChomboDataset):
+
+    _index_class = ChomboPICHierarchy
+    _field_info_class = ChomboPICFieldInfo3D
+
+    def __init__(self, filename, dataset_type='chombo_hdf5',
+                 storage_filename=None, ini_filename=None):
+
+        ChomboDataset.__init__(self, filename, dataset_type,
+                               storage_filename, ini_filename)
+
+        if self.dimensionality == 1:
+            self._field_info_class = ChomboPICFieldInfo1D
+
+        if self.dimensionality == 2:
+            self._field_info_class = ChomboPICFieldInfo2D
+
+    @classmethod
+    def _is_valid(self, *args, **kwargs):
+
+        pluto_ini_file_exists = False
+        orion2_ini_file_exists = False
+
+        if isinstance(args[0], six.string_types):
+            dir_name = os.path.dirname(os.path.abspath(args[0]))
+            pluto_ini_filename = os.path.join(dir_name, "pluto.ini")
+            orion2_ini_filename = os.path.join(dir_name, "orion2.ini")
+            pluto_ini_file_exists = os.path.isfile(pluto_ini_filename)
+            orion2_ini_file_exists = os.path.isfile(orion2_ini_filename)
+
+        if orion2_ini_file_exists:
+            return False
+
+        if pluto_ini_file_exists:
+            return False
+
+        try:
+            fileh = h5py.File(args[0],'r')
+            valid = "Charm_global" in fileh["/"]
+            fileh.close()
+            return valid
+        except:
+            pass
+        return False

diff -r dc60658345cd68e6e29218b52b0566053c62b144 -r d596ad6eafb7a3f32ed448f66aaa633aae216520 yt/frontends/chombo/fields.py
--- a/yt/frontends/chombo/fields.py
+++ b/yt/frontends/chombo/fields.py
@@ -14,8 +14,13 @@
 #-----------------------------------------------------------------------------
 
 import numpy as np
+from yt.units.unit_object import Unit
 from yt.fields.field_info_container import \
-    FieldInfoContainer
+    FieldInfoContainer, \
+    particle_deposition_functions, \
+    particle_vector_functions, \
+    standard_particle_fields
+
 from yt.frontends.boxlib.fields import \
     rho_units, \
     mom_units, \
@@ -27,6 +32,8 @@
 rho_units = "code_mass / code_length**3"
 mom_units = "code_mass / (code_time * code_length**2)"
 eden_units = "code_mass / (code_time**2 * code_length)" # erg / cm^3
+vel_units = "code_length / code_time"
+b_units = "code_magnetic"
 
 # Chombo does not have any known fields by itself.
 class ChomboFieldInfo(FieldInfoContainer):
@@ -88,3 +95,174 @@
                        units = "erg/cm**3")
         self.add_field("temperature", function=_temperature,
                        units="K")
+
+
+class ChomboPICFieldInfo3D(FieldInfoContainer):
+    known_other_fields = (
+        ("density", (rho_units, ["density", "Density"], None)),
+        ("potential", ("code_length**2 / code_time**2", ["potential", "Potential"], None)),
+        ("gravitational_field_x", ("code_length / code_time**2", [], None)),
+        ("gravitational_field_y", ("code_length / code_time**2", [], None)),
+        ("gravitational_field_z", ("code_length / code_time**2", [], None)),
+    )
+    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_velocity_x", ("code_length / code_time", [], None)),
+        ("particle_velocity_y", ("code_length / code_time", [], None)),
+        ("particle_velocity_z", ("code_length / code_time", [], None)),
+    )
+
+    # I am re-implementing this here to override a few default behaviors:
+    # I don't want to skip output units for code_length and I do want
+    # particle_fields to default to take_log = False.
+    def setup_particle_fields(self, ptype, ftype='gas', num_neighbors=64 ):
+        skip_output_units = ()
+        for f, (units, aliases, dn) in sorted(self.known_particle_fields):
+            units = self.ds.field_units.get((ptype, f), units)
+            if (f in aliases or ptype not in self.ds.particle_types_raw) and \
+                units not in skip_output_units:
+                u = Unit(units, registry = self.ds.unit_registry)
+                output_units = str(u.get_cgs_equivalent())
+            else:
+                output_units = units
+            if (ptype, f) not in self.field_list:
+                continue
+            self.add_output_field((ptype, f),
+                units = units, particle_type = True,
+                display_name = dn, output_units = output_units, take_log=False)
+            for alias in aliases:
+                self.alias((ptype, alias), (ptype, f), units = output_units)
+
+        # We'll either have particle_position or particle_position_[xyz]
+        if (ptype, "particle_position") in self.field_list or \
+           (ptype, "particle_position") in self.field_aliases:
+            particle_scalar_functions(ptype,
+                   "particle_position", "particle_velocity",
+                   self)
+        else:
+            # We need to check to make sure that there's a "known field" that
+            # overlaps with one of the vector fields.  For instance, if we are
+            # in the Stream frontend, and we have a set of scalar position
+            # fields, they will overlap with -- and be overridden by -- the
+            # "known" vector field that the frontend creates.  So the easiest
+            # thing to do is to simply remove the on-disk field (which doesn't
+            # exist) and replace it with a derived field.
+            if (ptype, "particle_position") in self and \
+                 self[ptype, "particle_position"]._function == NullFunc:
+                self.pop((ptype, "particle_position"))
+            particle_vector_functions(ptype,
+                    ["particle_position_%s" % ax for ax in 'xyz'],
+                    ["particle_velocity_%s" % ax for ax in 'xyz'],
+                    self)
+        particle_deposition_functions(ptype, "particle_position",
+            "particle_mass", self)
+        standard_particle_fields(self, ptype)
+        # Now we check for any leftover particle fields
+        for field in sorted(self.field_list):
+            if field in self: continue
+            if not isinstance(field, tuple):
+                raise RuntimeError
+            if field[0] not in self.ds.particle_types:
+                continue
+            self.add_output_field(field, 
+                                  units = self.ds.field_units.get(field, ""),
+                                  particle_type = True)
+        self.setup_smoothed_fields(ptype, 
+                                   num_neighbors=num_neighbors,
+                                   ftype=ftype)
+
+def _dummy_position(field, data):
+    return 0.5*np.ones_like(data['particle_position_x'])
+
+def _dummy_velocity(field, data):
+    return np.zeros_like(data['particle_velocity_x'])
+
+def _dummy_field(field, data):
+    return 0.0 * data['gravitational_field_x']
+
+fluid_field_types = ['chombo', 'gas']
+particle_field_types = ['io', 'all']
+
+class ChomboPICFieldInfo2D(ChomboPICFieldInfo3D):
+    known_other_fields = (
+        ("density", (rho_units, ["density", "Density"], None)),
+        ("potential", ("code_length**2 / code_time**2", ["potential", "Potential"], None)),
+        ("gravitational_field_x", ("code_length / code_time**2", [], None)),
+        ("gravitational_field_y", ("code_length / code_time**2", [], None)),
+    )
+    known_particle_fields = (
+        ("particle_mass", ("code_mass", [], None)),
+        ("particle_position_x", ("code_length", [], None)),
+        ("particle_position_y", ("code_length", [], None)),
+        ("particle_velocity_x", ("code_length / code_time", [], None)),
+        ("particle_velocity_y", ("code_length / code_time", [], None)),
+    )
+
+    def __init__(self, ds, field_list):
+        super(ChomboPICFieldInfo2D, self).__init__(ds, field_list)
+
+        for ftype in fluid_field_types:
+            self.add_field((ftype, 'gravitational_field_z'), function = _dummy_field, 
+                            units = "code_length / code_time**2")
+
+        for ptype in particle_field_types:                
+            self.add_field((ptype, "particle_position_z"), function = _dummy_position,
+                           particle_type = True,
+                           units = "code_length")
+
+            self.add_field((ptype, "particle_velocity_z"), function = _dummy_velocity,
+                           particle_type = True,
+                           units = "code_length / code_time")
+
+class ChomboPICFieldInfo1D(ChomboPICFieldInfo3D):
+    known_other_fields = (
+        ("density", (rho_units, ["density", "Density"], None)),
+        ("potential", ("code_length**2 / code_time**2", ["potential", "Potential"], None)),
+        ("gravitational_field_x", ("code_length / code_time**2", [], None)),
+    )
+    known_particle_fields = (
+        ("particle_mass", ("code_mass", [], None)),
+        ("particle_position_x", ("code_length", [], None)),
+        ("particle_velocity_x", ("code_length / code_time", [], None)),
+    )
+
+    def __init__(self, ds, field_list):
+        super(ChomboPICFieldInfo1D, self).__init__(ds, field_list)
+
+        for ftype in fluid_field_types:
+            self.add_field((ftype, 'gravitational_field_y'), function = _dummy_field, 
+                            units = "code_length / code_time**2")
+
+            self.add_field((ftype, 'gravitational_field_z'), function = _dummy_field, 
+                    units = "code_length / code_time**2")
+
+        for ptype in particle_field_types:
+            self.add_field((ptype, "particle_position_y"), function = _dummy_position,
+                           particle_type = True,
+                           units = "code_length")
+            self.add_field((ptype, "particle_position_z"), function = _dummy_position,
+                           particle_type = True,
+                           units = "code_length")
+            self.add_field((ptype, "particle_velocity_y"), function = _dummy_velocity,
+                           particle_type = True,
+                           units = "code_length / code_time")
+            self.add_field((ptype, "particle_velocity_z"), function = _dummy_velocity,
+                           particle_type = True,
+                           units = "code_length / code_time")
+
+class PlutoFieldInfo(ChomboFieldInfo):
+    known_other_fields = (
+        ("rho", (rho_units, ["density"], None)),
+        ("prs", ("code_mass / (code_length * code_time**2)", ["pressure"], None)),
+        ("vx1", (vel_units, ["velocity_x"], None)),
+        ("vx2", (vel_units, ["velocity_y"], None)),
+        ("vx3", (vel_units, ["velocity_z"], None)),
+        ("bx1", (b_units, ["magnetic_field_x"], None)),
+        ("bx2", (b_units, ["magnetic_field_y"], None)),
+        ("bx3", (b_units, ["magnetic_field_z"], None)),
+    )
+
+    known_particle_fields = ()

diff -r dc60658345cd68e6e29218b52b0566053c62b144 -r d596ad6eafb7a3f32ed448f66aaa633aae216520 yt/frontends/chombo/io.py
--- a/yt/frontends/chombo/io.py
+++ b/yt/frontends/chombo/io.py
@@ -19,7 +19,7 @@
 from yt.utilities.logger import ytLogger as mylog
 
 from yt.utilities.io_handler import \
-           BaseIOHandler
+    BaseIOHandler
 
 class IOHandlerChomboHDF5(BaseIOHandler):
     _dataset_type = "chombo_hdf5"
@@ -30,6 +30,18 @@
         BaseIOHandler.__init__(self, ds, *args, **kwargs)
         self.ds = ds
         self._handle = ds._handle
+        self.dim = self._handle['Chombo_global/'].attrs['SpaceDim']
+        self._read_ghost_info()
+
+    def _read_ghost_info(self):
+        try:
+            self.ghost = tuple(self._handle['level_0/data_attributes'].attrs['outputGhost'])
+            # pad with zeros if the dataset is low-dimensional
+            self.ghost += (3 - self.dim)*(0,)
+            self.ghost = np.array(self.ghost)
+        except KeyError:
+            # assume zero ghosts if outputGhosts not present
+            self.ghost = np.zeros(self.dim)
 
     _field_dict = None
     @property
@@ -62,18 +74,20 @@
         fns = [c[1] for c in f.attrs.items()[-ncomp-1:-1]]
     
     def _read_data(self,grid,field):
-
         lstring = 'level_%i' % grid.Level
         lev = self._handle[lstring]
         dims = grid.ActiveDimensions
-        boxsize = dims.prod()
+        shape = grid.ActiveDimensions + 2*self.ghost
+        boxsize = shape.prod()
         
         grid_offset = lev[self._offset_string][grid._level_id]
         start = grid_offset+self.field_dict[field]*boxsize
         stop = start + boxsize
         data = lev[self._data_string][start:stop]
-        
-        return data.reshape(dims, order='F')
+        data_no_ghost = data.reshape(shape, order='F')
+        ghost_slice = [slice(g, d-g, None) for g, d in zip(self.ghost, grid.ActiveDimensions)]
+        ghost_slice = ghost_slice[0:self.dim]
+        return data_no_ghost[ghost_slice]
 
     def _read_fluid_selection(self, chunks, selector, fields, size):
         rv = {}
@@ -168,6 +182,8 @@
         BaseIOHandler.__init__(self, ds, *args, **kwargs)
         self.ds = ds
         self._handle = ds._handle
+        self.dim = 2
+        self._read_ghost_info()
 
 class IOHandlerChombo1DHDF5(IOHandlerChomboHDF5):
     _dataset_type = "chombo1d_hdf5"
@@ -177,7 +193,19 @@
     def __init__(self, ds, *args, **kwargs):
         BaseIOHandler.__init__(self, ds, *args, **kwargs)
         self.ds = ds
-        self._handle = ds._handle   
+        self.dim = 1
+        self._handle = ds._handle
+        self._read_ghost_info()
+
+class IOHandlerPlutoHDF5(IOHandlerChomboHDF5):
+    _dataset_type = "pluto_chombo_native"
+    _offset_string = 'data:offsets=0'
+    _data_string = 'data:datatype=0'
+
+    def __init__(self, ds, *args, **kwargs):
+        BaseIOHandler.__init__(self, ds, *args, **kwargs)
+        self.ds = ds
+        self._handle = ds._handle
 
 class IOHandlerOrion2HDF5(IOHandlerChomboHDF5):
     _dataset_type = "orion_chombo_native"
@@ -185,7 +213,7 @@
     def _read_particles(self, grid, field):
         """
         parses the Orion Star Particle text files
-             
+
         """
 
         fn = grid.ds.fullplotdir[:-4] + "sink"

diff -r dc60658345cd68e6e29218b52b0566053c62b144 -r d596ad6eafb7a3f32ed448f66aaa633aae216520 yt/frontends/chombo/tests/test_outputs.py
--- a/yt/frontends/chombo/tests/test_outputs.py
+++ b/yt/frontends/chombo/tests/test_outputs.py
@@ -22,7 +22,8 @@
     data_dir_load
 from yt.frontends.chombo.api import \
     ChomboDataset, \
-    Orion2Dataset
+    Orion2Dataset, \
+    PlutoDataset
 
 _fields = ("density", "velocity_magnitude",  # "velocity_divergence",
            "magnetic_field_x")
@@ -57,6 +58,14 @@
         test_tb.__name__ = test.description
         yield test
 
+kho = "KelvinHelmholtz/data.0004.hdf5"
+ at requires_ds(kho)
+def test_kho():
+    ds = data_dir_load(kho)
+    yield assert_equal, str(ds), "data.0004.hdf5"
+    for test in small_patch_amr(kho, _fields):
+        test_gc.__name__ = test.description
+        yield test
 
 @requires_file(zp)
 def test_ChomboDataset():
@@ -68,6 +77,6 @@
     assert isinstance(data_dir_load(gc), Orion2Dataset)
 
 
-#@requires_file(kho)
-#def test_PlutoDataset():
-#    assert isinstance(data_dir_load(kho), PlutoDataset)
+ at requires_file(kho)
+def test_PlutoDataset():
+    assert isinstance(data_dir_load(kho), PlutoDataset)

diff -r dc60658345cd68e6e29218b52b0566053c62b144 -r d596ad6eafb7a3f32ed448f66aaa633aae216520 yt/visualization/api.py
--- a/yt/visualization/api.py
+++ b/yt/visualization/api.py
@@ -49,9 +49,9 @@
     OffAxisProjectionPlot
 
 from .profile_plotter import \
-     ProfilePlot, \
-     PhasePlot
-    
+    ProfilePlot, \
+    PhasePlot
+
 from .base_plot_types import \
     get_multi_plot
 

diff -r dc60658345cd68e6e29218b52b0566053c62b144 -r d596ad6eafb7a3f32ed448f66aaa633aae216520 yt/visualization/plot_container.py
--- a/yt/visualization/plot_container.py
+++ b/yt/visualization/plot_container.py
@@ -121,7 +121,7 @@
         return defaultdict.__init__(self, default_factory)
 
 class ImagePlotContainer(object):
-    """A countainer for plots with colorbars.
+    """A container for plots with colorbars.
 
     """
     _plot_type = None
@@ -472,7 +472,6 @@
 
     def show(self):
         r"""This will send any existing plots to the IPython notebook.
-        function name.
 
         If yt is being run from within an IPython session, and it is able to
         determine this, this function will send any existing plots to the

diff -r dc60658345cd68e6e29218b52b0566053c62b144 -r d596ad6eafb7a3f32ed448f66aaa633aae216520 yt/visualization/profile_plotter.py
--- a/yt/visualization/profile_plotter.py
+++ b/yt/visualization/profile_plotter.py
@@ -184,7 +184,7 @@
     ...                                  plot_specs=plot_specs)
     >>> plot.save()
 
-    Use plot_line_property to change line properties of one or all profiles.
+    Use set_line_property to change line properties of one or all profiles.
     
     """
     x_log = None
@@ -256,7 +256,6 @@
 
     def show(self):
         r"""This will send any existing plots to the IPython notebook.
-        function name.
 
         If yt is being run from within an IPython session, and it is able to
         determine this, this function will send any existing plots to the

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