[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