[yt-svn] commit/yt: 3 new changesets
commits-noreply at bitbucket.org
commits-noreply at bitbucket.org
Fri Mar 29 03:51:45 PDT 2013
3 new commits in yt:
https://bitbucket.org/yt_analysis/yt/commits/7e0900e6fa90/
Changeset: 7e0900e6fa90
Branch: stable
User: MatthewTurk
Date: 2013-03-29 11:50:51
Summary: Merging from yt into stable
Affected #: 31 files
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/analysis_modules/halo_finding/rockstar/rockstar.py
--- a/yt/analysis_modules/halo_finding/rockstar/rockstar.py
+++ b/yt/analysis_modules/halo_finding/rockstar/rockstar.py
@@ -238,6 +238,7 @@
tpf = ts[0]
def _particle_count(field, data):
+ if data.NumberOfParticles == 0: return 0
try:
data["particle_type"]
has_particle_type=True
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -36,6 +36,8 @@
import itertools
import shelve
import cStringIO
+import fileinput
+from re import finditer
from yt.funcs import *
from yt.config import ytcfg
@@ -4036,7 +4038,7 @@
sp1, ")"])
"""
_type_name = "boolean"
- _con_args = ("regions")
+ _con_args = ("regions",)
def __init__(self, regions, fields = None, pf = None, **kwargs):
# Center is meaningless, but we'll define it all the same.
AMR3DData.__init__(self, [0.5]*3, fields, pf, **kwargs)
@@ -4374,6 +4376,230 @@
vv[:,i,j] = self.vertices[j,i::3]
return vv
+ def export_obj(self, filename, transparency = 1.0, dist_fac = None,
+ color_field = None, emit_field = None, color_map = "algae",
+ color_log = True, emit_log = True, plot_index = None,
+ color_field_max = None, color_field_min = None,
+ emit_field_max = None, emit_field_min = None):
+ r"""This exports the surface to the OBJ format, suitable for visualization
+ in many different programs (e.g., Blender). NOTE: this exports an .obj file
+ and an .mtl file, both with the general 'filename' as a prefix.
+ The .obj file points to the .mtl file in its header, so if you move the 2
+ files, make sure you change the .obj header to account for this. ALSO NOTE:
+ the emit_field needs to be a combination of the other 2 fields used to
+ have the emissivity track with the color.
+
+ Parameters
+ ----------
+ filename : string
+ The file this will be exported to. This cannot be a file-like object.
+ Note - there are no file extentions included - both obj & mtl files
+ are created.
+ transparency : float
+ This gives the transparency of the output surface plot. Values
+ from 0.0 (invisible) to 1.0 (opaque).
+ dist_fac : float
+ Divide the axes distances by this amount.
+ color_field : string
+ Should a field be sample and colormapped?
+ emit_field : string
+ Should we track the emissivity of a field?
+ NOTE: this should be a combination of the other 2 fields being used.
+ color_map : string
+ Which color map should be applied?
+ color_log : bool
+ Should the color field be logged before being mapped?
+ emit_log : bool
+ Should the emitting field be logged before being mapped?
+ plot_index : integer
+ Index of plot for multiple plots. If none, then only 1 plot.
+ color_field_max : float
+ Maximum value of the color field across all surfaces.
+ color_field_min : float
+ Minimum value of the color field across all surfaces.
+ emit_field_max : float
+ Maximum value of the emitting field across all surfaces.
+ emit_field_min : float
+ Minimum value of the emitting field across all surfaces.
+
+ Examples
+ --------
+
+ >>> sp = pf.h.sphere("max", (10, "kpc"))
+ >>> trans = 1.0
+ >>> distf = 3.1e18*1e3 # distances into kpc
+ >>> surf = pf.h.surface(sp, "Density", 5e-27)
+ >>> surf.export_obj("my_galaxy", transparency=trans, dist_fac = distf)
+
+ >>> sp = pf.h.sphere("max", (10, "kpc"))
+ >>> mi, ma = sp.quantities['Extrema']('Temperature')[0]
+ >>> rhos = [1e-24, 1e-25]
+ >>> trans = [0.5, 1.0]
+ >>> distf = 3.1e18*1e3 # distances into kpc
+ >>> for i, r in enumerate(rhos):
+ ... surf = pf.h.surface(sp,'Density',r)
+ ... surf.export_obj("my_galaxy", transparency=trans[i],
+ ... color_field='Temperature', dist_fac = distf,
+ ... plot_index = i, color_field_max = ma,
+ ... color_field_min = mi)
+
+ >>> sp = pf.h.sphere("max", (10, "kpc"))
+ >>> rhos = [1e-24, 1e-25]
+ >>> trans = [0.5, 1.0]
+ >>> distf = 3.1e18*1e3 # distances into kpc
+ >>> def _Emissivity(field, data):
+ ... return (data['Density']*data['Density']*np.sqrt(data['Temperature']))
+ >>> add_field("Emissivity", function=_Emissivity, units=r"\rm{g K}/\rm{cm}^{6}")
+ >>> for i, r in enumerate(rhos):
+ ... surf = pf.h.surface(sp,'Density',r)
+ ... surf.export_obj("my_galaxy", transparency=trans[i],
+ ... color_field='Temperature', emit_field = 'Emissivity',
+ ... dist_fac = distf, plot_index = i)
+
+ """
+ if self.vertices is None:
+ self.get_data(color_field,"face")
+ elif color_field is not None:
+ if color_field not in self.field_data:
+ self[color_field]
+ if emit_field is not None:
+ if color_field not in self.field_data:
+ self[emit_field]
+ only_on_root(self._export_obj, filename, transparency, dist_fac, color_field, emit_field,
+ color_map, color_log, emit_log, plot_index, color_field_max,
+ color_field_min, emit_field_max, emit_field_min)
+
+ def _color_samples_obj(self, cs, em, color_log, emit_log, color_map, arr,
+ color_field_max, color_field_min,
+ emit_field_max, emit_field_min): # this now holds for obj files
+ if color_log: cs = np.log10(cs)
+ if emit_log: em = np.log10(em)
+ if color_field_min is None:
+ mi = cs.min()
+ else:
+ mi = color_field_min
+ if color_log: mi = np.log10(mi)
+ if color_field_max is None:
+ ma = cs.max()
+ else:
+ ma = color_field_max
+ if color_log: ma = np.log10(ma)
+ cs = (cs - mi) / (ma - mi)
+ # to get color indicies for OBJ formatting
+ from yt.visualization._colormap_data import color_map_luts
+ lut = color_map_luts[color_map]
+ x = np.mgrid[0.0:1.0:lut[0].shape[0]*1j]
+ arr["cind"][:] = (np.interp(cs,x,x)*(lut[0].shape[0]-1)).astype("uint8")
+ # now, get emission
+ if emit_field_min is None:
+ emi = em.min()
+ else:
+ emi = emit_field_min
+ if emit_log: emi = np.log10(emi)
+ if emit_field_max is None:
+ ema = em.max()
+ else:
+ ema = emit_field_max
+ if emit_log: ema = np.log10(ema)
+ em = (em - emi)/(ema - emi)
+ x = np.mgrid[0.0:255.0:2j] # assume 1 emissivity per color
+ arr["emit"][:] = (np.interp(em,x,x))*2.0 # for some reason, max emiss = 2
+
+ @parallel_root_only
+ def _export_obj(self, filename, transparency, dist_fac = None,
+ color_field = None, emit_field = None, color_map = "algae",
+ color_log = True, emit_log = True, plot_index = None,
+ color_field_max = None, color_field_min = None,
+ emit_field_max = None, emit_field_min = None):
+ if plot_index is None:
+ plot_index = 0
+ if isinstance(filename, file):
+ fobj = filename + '.obj'
+ fmtl = filename + '.mtl'
+ else:
+ if plot_index == 0:
+ fobj = open(filename + '.obj', "w")
+ fmtl = open(filename + '.mtl', 'w')
+ cc = 1
+ else:
+ # read in last vertex
+ linesave = ''
+ for line in fileinput.input(filename + '.obj'):
+ if line[0] == 'f':
+ linesave = line
+ p = [m.start() for m in finditer(' ', linesave)]
+ cc = int(linesave[p[len(p)-1]:])+1
+ fobj = open(filename + '.obj', "a")
+ fmtl = open(filename + '.mtl', 'a')
+ ftype = [("cind", "uint8"), ("emit", "float")]
+ vtype = [("x","float"),("y","float"), ("z","float")]
+ if plot_index == 0:
+ fobj.write("# yt OBJ file\n")
+ fobj.write("# www.yt-project.com\n")
+ fobj.write("mtllib " + filename + '.mtl\n\n') # use this material file for the faces
+ fmtl.write("# yt MLT file\n")
+ fmtl.write("# www.yt-project.com\n\n")
+ #(0) formulate vertices
+ nv = self.vertices.shape[1] # number of groups of vertices
+ f = np.empty(nv/self.vertices.shape[0], dtype=ftype) # store sets of face colors
+ v = np.empty(nv, dtype=vtype) # stores vertices
+ if color_field is not None:
+ cs = self[color_field]
+ else:
+ cs = np.empty(self.vertices.shape[1]/self.vertices.shape[0])
+ if emit_field is not None:
+ em = self[emit_field]
+ else:
+ em = np.empty(self.vertices.shape[1]/self.vertices.shape[0])
+ self._color_samples_obj(cs, em, color_log, emit_log, color_map, f,
+ color_field_max, color_field_min,
+ emit_field_max, emit_field_min) # map color values to color scheme
+ from yt.visualization._colormap_data import color_map_luts # import colors for mtl file
+ lut = color_map_luts[color_map] # enumerate colors
+ # interpolate emissivity to enumerated colors
+ emiss = np.interp(np.mgrid[0:lut[0].shape[0]],np.mgrid[0:len(cs)],f["emit"][:])
+ if dist_fac is None: # then normalize by bounds
+ DLE = self.pf.domain_left_edge
+ DRE = self.pf.domain_right_edge
+ bounds = [(DLE[i], DRE[i]) for i in range(3)]
+ for i, ax in enumerate("xyz"):
+ # Do the bounds first since we cast to f32
+ tmp = self.vertices[i,:]
+ np.subtract(tmp, bounds[i][0], tmp)
+ w = bounds[i][1] - bounds[i][0]
+ np.divide(tmp, w, tmp)
+ np.subtract(tmp, 0.5, tmp) # Center at origin.
+ v[ax][:] = tmp
+ else:
+ for i, ax in enumerate("xyz"):
+ tmp = self.vertices[i,:]
+ np.divide(tmp, dist_fac, tmp)
+ v[ax][:] = tmp
+ #(1) write all colors per surface to mtl file
+ for i in range(0,lut[0].shape[0]):
+ omname = "material_" + str(i) + '_' + str(plot_index) # name of the material
+ fmtl.write("newmtl " + omname +'\n') # the specific material (color) for this face
+ fmtl.write("Ka %.6f %.6f %.6f\n" %(0.0, 0.0, 0.0)) # ambient color, keep off
+ fmtl.write("Kd %.6f %.6f %.6f\n" %(lut[0][i], lut[1][i], lut[2][i])) # color of face
+ fmtl.write("Ks %.6f %.6f %.6f\n" %(0.0, 0.0, 0.0)) # specular color, keep off
+ fmtl.write("d %.6f\n" %(transparency)) # transparency
+ fmtl.write("em %.6f\n" %(emiss[i])) # emissivity per color
+ fmtl.write("illum 2\n") # not relevant, 2 means highlights on?
+ fmtl.write("Ns %.6f\n\n" %(0.0)) #keep off, some other specular thing
+ #(2) write vertices
+ for i in range(0,self.vertices.shape[1]):
+ fobj.write("v %.6f %.6f %.6f\n" %(v["x"][i], v["y"][i], v["z"][i]))
+ fobj.write("#done defining vertices\n\n")
+ #(3) define faces and materials for each face
+ for i in range(0,self.triangles.shape[0]):
+ omname = 'material_' + str(f["cind"][i]) + '_' + str(plot_index) # which color to use
+ fobj.write("usemtl " + omname + '\n') # which material to use for this face (color)
+ fobj.write("f " + str(cc) + ' ' + str(cc+1) + ' ' + str(cc+2) + '\n\n') # vertices to color
+ cc = cc+3
+ fmtl.close()
+ fobj.close()
+
+
def export_ply(self, filename, bounds = None, color_field = None,
color_map = "algae", color_log = True, sample_type = "face"):
r"""This exports the surface to the PLY format, suitable for visualization
@@ -4606,22 +4832,46 @@
mylog.error("Problem uploading.")
return upload_id
+# Many of these items are set up specifically to ensure that
+# we are not breaking old pickle files. This means we must only call the
+# _reconstruct_object and that we cannot mandate any additional arguments to
+# the reconstruction function.
+#
+# In the future, this would be better off being set up to more directly
+# reference objects or retain state, perhaps with a context manager.
+#
+# One final detail: time series or multiple parameter files in a single pickle
+# seems problematic.
+
+class ReconstructedObject(tuple):
+ pass
+
+def _check_nested_args(arg, ref_pf):
+ if not isinstance(arg, (tuple, list, ReconstructedObject)):
+ return arg
+ elif isinstance(arg, ReconstructedObject) and ref_pf == arg[0]:
+ return arg[1]
+ narg = [_check_nested_args(a, ref_pf) for a in arg]
+ return narg
+
+def _get_pf_by_hash(hash):
+ from yt.data_objects.static_output import _cached_pfs
+ for pf in _cached_pfs.values():
+ if pf._hash() == hash: return pf
+ return None
def _reconstruct_object(*args, **kwargs):
pfid = args[0]
dtype = args[1]
+ pf = _get_pf_by_hash(pfid)
+ if not pf:
+ pfs = ParameterFileStore()
+ pf = pfs.get_pf_hash(pfid)
field_parameters = args[-1]
# will be much nicer when we can do pfid, *a, fp = args
- args, new_args = args[2:-1], []
- for arg in args:
- if iterable(arg) and len(arg) == 2 \
- and not isinstance(arg, types.DictType) \
- and isinstance(arg[1], AMRData):
- new_args.append(arg[1])
- else: new_args.append(arg)
- pfs = ParameterFileStore()
- pf = pfs.get_pf_hash(pfid)
+ args = args[2:-1]
+ new_args = [_check_nested_args(a, pf) for a in args]
cls = getattr(pf.h, dtype)
obj = cls(*new_args)
obj.field_parameters.update(field_parameters)
- return pf, obj
+ return ReconstructedObject((pf, obj))
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/data_objects/field_info_container.py
--- a/yt/data_objects/field_info_container.py
+++ b/yt/data_objects/field_info_container.py
@@ -505,4 +505,3 @@
if isinstance(data, FieldDetector): return True
if getattr(data, "_type_name", None) == 'grid': return True
raise NeedsOriginalGrid()
-
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/data_objects/tests/test_pickle.py
--- /dev/null
+++ b/yt/data_objects/tests/test_pickle.py
@@ -0,0 +1,69 @@
+"""
+Testsuite for pickling yt objects.
+
+Author: Elizabeth Tasker <tasker at astro1.sci.hokudai.ac.jp>
+Affiliation: Hokkaido University
+Homepage: http://yt-project.org/
+License:
+ Copyright (C) 2013 Elizabeth Tasker. All Rights Reserved.
+
+ This file is part of yt.
+
+ yt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+import cPickle
+import os
+import tempfile
+from yt.testing \
+ import fake_random_pf, assert_equal
+
+
+def setup():
+ """Test specific setup."""
+ from yt.config import ytcfg
+ ytcfg["yt", "__withintesting"] = "True"
+
+
+def test_save_load_pickle():
+ """Main test for loading pickled objects"""
+ test_pf = fake_random_pf(64)
+
+ # create extracted region from boolean (fairly complex object)
+ center = (test_pf.domain_left_edge + test_pf.domain_right_edge) / 2
+ sp_outer = test_pf.h.sphere(center, test_pf.domain_width[0])
+ sp_inner = test_pf.h.sphere(center, test_pf.domain_width[0] / 10.0)
+ sp_boolean = test_pf.h.boolean([sp_outer, "NOT", sp_inner])
+
+ minv, maxv = sp_boolean.quantities["Extrema"]("Density")[0]
+ contour_threshold = min(minv * 10.0, 0.9 * maxv)
+
+ contours = sp_boolean.extract_connected_sets(
+ "Density", 1, contour_threshold, maxv + 1, log_space=True, cache=True)
+
+ # save object
+ cpklfile = tempfile.NamedTemporaryFile(delete=False)
+ cPickle.dump(contours[1][0], cpklfile)
+ cpklfile.close()
+
+ # load object
+ test_load = cPickle.load(open(cpklfile.name, "rb"))
+
+ assert_equal.description = \
+ "%s: File was pickle-loaded succesfully" % __name__
+ yield assert_equal, test_load is not None, True
+ assert_equal.description = \
+ "%s: Length of pickle-loaded connected set object" % __name__
+ yield assert_equal, len(contours[1][0]), len(test_load)
+
+ os.remove(cpklfile.name)
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/data_objects/universal_fields.py
--- a/yt/data_objects/universal_fields.py
+++ b/yt/data_objects/universal_fields.py
@@ -801,8 +801,9 @@
for i, ax in enumerate('xyz'):
np.subtract(data["%s%s" % (field_prefix, ax)], center[i], r)
if data.pf.periodicity[i] == True:
- np.subtract(DW[i], r, rdw)
np.abs(r, r)
+ np.subtract(r, DW[i], rdw)
+ np.abs(rdw, rdw)
np.minimum(r, rdw, r)
np.power(r, 2.0, r)
np.add(radius, r, radius)
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/frontends/chombo/data_structures.py
--- a/yt/frontends/chombo/data_structures.py
+++ b/yt/frontends/chombo/data_structures.py
@@ -39,8 +39,8 @@
ST_CTIME
from .definitions import \
- pluto2enzoDict, \
- yt2plutoFieldsDict, \
+ chombo2enzoDict, \
+ yt2chomboFieldsDict, \
parameterDict \
from yt.funcs import *
@@ -250,7 +250,7 @@
seconds = 1 #self["Time"]
for unit in sec_conversion.keys():
self.time_units[unit] = seconds / sec_conversion[unit]
- for key in yt2plutoFieldsDict:
+ for key in yt2chomboFieldsDict:
self.conversion_factors[key] = 1.0
def _setup_nounits_units(self):
@@ -270,29 +270,22 @@
def _parse_parameter_file(self):
"""
- Check to see whether a 'pluto.ini' or 'orion2.ini' file
+ Check to see whether an 'orion2.ini' file
exists in the plot file directory. If one does, attempt to parse it.
- Otherwise, assume the left edge starts at 0 and get the right edge
- from the hdf5 file.
+ Otherwise grab the dimensions from the hdf5 file.
"""
- if os.path.isfile('pluto.ini'):
- self._parse_pluto_file('pluto.ini')
- else:
- if os.path.isfile('orion2.ini'): self._parse_pluto_file('orion2.ini')
- self.unique_identifier = \
- int(os.stat(self.parameter_filename)[ST_CTIME])
- self.domain_left_edge = self.__calc_left_edge()
- self.domain_right_edge = self.__calc_right_edge()
- self.domain_dimensions = self.__calc_domain_dimensions()
- self.dimensionality = 3
- self.refine_by = self._handle['/level_0'].attrs['ref_ratio']
+
+ if os.path.isfile('orion2.ini'): self._parse_inputs_file('orion2.ini')
+ self.unique_identifier = \
+ int(os.stat(self.parameter_filename)[ST_CTIME])
+ self.domain_left_edge = self.__calc_left_edge()
+ self.domain_right_edge = self.__calc_right_edge()
+ self.domain_dimensions = self.__calc_domain_dimensions()
+ self.dimensionality = 3
+ self.refine_by = self._handle['/level_0'].attrs['ref_ratio']
self.periodicity = (True, True, True)
- def _parse_pluto_file(self, ini_filename):
- """
- Reads in an inputs file in the 'pluto.ini' format. Probably not
- especially robust at the moment.
- """
+ def _parse_inputs_file(self, ini_filename):
self.fullplotdir = os.path.abspath(self.parameter_filename)
self.ini_filename = self._localize( \
self.ini_filename, ini_filename)
@@ -305,8 +298,8 @@
param, sep, vals = map(rstrip,line.partition(' '))
except ValueError:
mylog.error("ValueError: '%s'", line)
- if pluto2enzoDict.has_key(param):
- paramName = pluto2enzoDict[param]
+ if chombo2enzoDict.has_key(param):
+ paramName = chombo2enzoDict[param]
t = map(parameterDict[paramName], vals.split())
if len(t) == 1:
self.parameters[paramName] = t[0]
@@ -336,13 +329,14 @@
@classmethod
def _is_valid(self, *args, **kwargs):
- try:
- fileh = h5py.File(args[0],'r')
- valid = "Chombo_global" in fileh["/"]
- fileh.close()
- return valid
- except:
- pass
+ if not os.path.isfile('pluto.ini'):
+ try:
+ fileh = h5py.File(args[0],'r')
+ valid = "Chombo_global" in fileh["/"]
+ fileh.close()
+ return valid
+ except:
+ pass
return False
@parallel_root_only
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/frontends/chombo/definitions.py
--- a/yt/frontends/chombo/definitions.py
+++ b/yt/frontends/chombo/definitions.py
@@ -56,10 +56,10 @@
"NumberOfParticleAttributes": int,
}
-pluto2enzoDict = {"GAMMA": "Gamma",
+chombo2enzoDict = {"GAMMA": "Gamma",
"Ref_ratio": "RefineBy"
}
-yt2plutoFieldsDict = {}
-pluto2ytFieldsDict = {}
+yt2chomboFieldsDict = {}
+chombo2ytFieldsDict = {}
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/frontends/enzo/fields.py
--- a/yt/frontends/enzo/fields.py
+++ b/yt/frontends/enzo/fields.py
@@ -130,14 +130,20 @@
def _ThermalEnergy(field, data):
if data.pf["HydroMethod"] == 2:
return data["TotalEnergy"]
- else:
- if data.pf["DualEnergyFormalism"]:
- return data["GasEnergy"]
- else:
- return data["TotalEnergy"] - 0.5*(
- data["x-velocity"]**2.0
- + data["y-velocity"]**2.0
- + data["z-velocity"]**2.0 )
+
+ if data.pf["DualEnergyFormalism"]:
+ return data["GasEnergy"]
+
+ if data.pf["HydroMethod"] in (4,6):
+ return data["TotalEnergy"] - 0.5*(
+ data["x-velocity"]**2.0
+ + data["y-velocity"]**2.0
+ + data["z-velocity"]**2.0 ) - data["MagneticEnergy"]
+
+ return data["TotalEnergy"] - 0.5*(
+ data["x-velocity"]**2.0
+ + data["y-velocity"]**2.0
+ + data["z-velocity"]**2.0 )
add_field("ThermalEnergy", function=_ThermalEnergy,
units=r"\rm{ergs}/\rm{g}")
@@ -171,22 +177,22 @@
# We set up fields for both TotalEnergy and Total_Energy in the known fields
# lists. Note that this does not mean these will be the used definitions.
add_enzo_field("TotalEnergy", function=NullFunc,
- display_name = "$\rm{Total}\/\rm{Energy}$",
+ display_name = r"\rm{Total}\/ \rm{Energy}",
units=r"\rm{ergs}/\rm{g}", convert_function=_convertEnergy)
add_enzo_field("Total_Energy", function=NullFunc,
- display_name = "$\rm{Total}\/\rm{Energy}$",
+ display_name = r"\rm{Total}\/ \rm{Energy}",
units=r"\rm{ergs}/\rm{g}", convert_function=_convertEnergy)
def _Total_Energy(field, data):
return data["TotalEnergy"] / _convertEnergy(data)
add_field("Total_Energy", function=_Total_Energy,
- display_name = "$\rm{Total}\/\rm{Energy}$",
+ display_name = r"\rm{Total}\/ \rm{Energy}",
units=r"\rm{ergs}/\rm{g}", convert_function=_convertEnergy)
def _TotalEnergy(field, data):
return data["Total_Energy"] / _convertEnergy(data)
add_field("TotalEnergy", function=_TotalEnergy,
- display_name = "$\rm{Total}\/\rm{Energy}$",
+ display_name = r"\rm{Total}\/ \rm{Energy}",
units=r"\rm{ergs}/\rm{g}", convert_function=_convertEnergy)
def _NumberDensity(field, data):
@@ -369,7 +375,7 @@
if not filter.any(): return blank
num = filter.sum()
else:
- filter = None
+ filter = Ellipsis
num = data["particle_position_x"].size
amr_utils.CICDeposit_3(data["particle_position_x"][filter].astype(np.float64),
data["particle_position_y"][filter].astype(np.float64),
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/frontends/pluto/api.py
--- /dev/null
+++ b/yt/frontends/pluto/api.py
@@ -0,0 +1,41 @@
+"""
+API for yt.frontends.pluto
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: UCSD
+Author: J.S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Homepage: http://yt.Chombotools.org/
+License:
+ Copyright (C) 2010-2011 Matthew Turk. All Rights Reserved.
+
+ This file is part of yt.
+
+ yt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""
+
+from .data_structures import \
+ PlutoGrid, \
+ PlutoHierarchy, \
+ PlutoStaticOutput
+
+from .fields import \
+ PlutoFieldInfo, \
+ add_pluto_field
+
+from .io import \
+ IOHandlerChomboHDF5
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/frontends/pluto/data_structures.py
--- /dev/null
+++ b/yt/frontends/pluto/data_structures.py
@@ -0,0 +1,307 @@
+"""
+Data structures for Pluto.
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Author: J. S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Homepage: http://yt-project.org/
+License:
+ Copyright (C) 2008-2011 Matthew Turk, J. S. Oishi. All Rights Reserved.
+
+ This file is part of yt.
+
+ yt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+
+import h5py
+import re
+import os
+import weakref
+import numpy as np
+
+from collections import \
+ defaultdict
+from string import \
+ strip, \
+ rstrip
+from stat import \
+ ST_CTIME
+
+from .definitions import \
+ pluto2enzoDict, \
+ yt2plutoFieldsDict, \
+ parameterDict \
+
+from yt.funcs import *
+from yt.data_objects.grid_patch import \
+ AMRGridPatch
+from yt.data_objects.hierarchy import \
+ AMRHierarchy
+from yt.data_objects.static_output import \
+ StaticOutput
+from yt.utilities.definitions import \
+ mpc_conversion, sec_conversion
+from yt.utilities.parallel_tools.parallel_analysis_interface import \
+ parallel_root_only
+from yt.utilities.io_handler import \
+ io_registry
+
+from yt.data_objects.field_info_container import \
+ FieldInfoContainer, NullFunc
+from .fields import PlutoFieldInfo, KnownPlutoFields
+
+class PlutoGrid(AMRGridPatch):
+ _id_offset = 0
+ __slots__ = ["_level_id", "stop_index"]
+ def __init__(self, id, hierarchy, level, start, stop):
+ AMRGridPatch.__init__(self, id, filename = hierarchy.hierarchy_filename,
+ hierarchy = hierarchy)
+ self.Parent = []
+ self.Children = []
+ self.Level = level
+ self.ActiveDimensions = stop - start + 1
+
+ def get_global_startindex(self):
+ """
+ Return the integer starting index for each dimension at the current
+ level.
+
+ """
+ if self.start_index != None:
+ return self.start_index
+ if self.Parent == []:
+ iLE = self.LeftEdge - self.pf.domain_left_edge
+ start_index = iLE / self.dds
+ return np.rint(start_index).astype('int64').ravel()
+ pdx = self.Parent[0].dds
+ start_index = (self.Parent[0].get_global_startindex()) + \
+ np.rint((self.LeftEdge - self.Parent[0].LeftEdge)/pdx)
+ self.start_index = (start_index*self.pf.refine_by).astype('int64').ravel()
+ return self.start_index
+
+ def _setup_dx(self):
+ # has already been read in and stored in hierarchy
+ self.dds = self.hierarchy.dds_list[self.Level]
+ self.field_data['dx'], self.field_data['dy'], self.field_data['dz'] = self.dds
+
+class PlutoHierarchy(AMRHierarchy):
+
+ grid = PlutoGrid
+
+ def __init__(self,pf,data_style='chombo_hdf5'):
+ self.domain_left_edge = pf.domain_left_edge
+ self.domain_right_edge = pf.domain_right_edge
+ self.data_style = data_style
+ self.field_indexes = {}
+ self.parameter_file = weakref.proxy(pf)
+ # for now, the hierarchy file is the parameter file!
+ self.hierarchy_filename = os.path.abspath(
+ self.parameter_file.parameter_filename)
+ self.directory = pf.fullpath
+ self._handle = pf._handle
+
+ self.float_type = self._handle['/level_0']['data:datatype=0'].dtype.name
+ self._levels = self._handle.keys()[2:]
+ AMRHierarchy.__init__(self,pf,data_style)
+
+ def _detect_fields(self):
+ ncomp = int(self._handle['/'].attrs['num_components'])
+ self.field_list = [c[1] for c in self._handle['/'].attrs.items()[-ncomp:]]
+
+ def _setup_classes(self):
+ dd = self._get_data_reader_dict()
+ AMRHierarchy._setup_classes(self, dd)
+ self.object_types.sort()
+
+ def _count_grids(self):
+ self.num_grids = 0
+ for lev in self._levels:
+ self.num_grids += self._handle[lev]['Processors'].len()
+
+ def _parse_hierarchy(self):
+ f = self._handle # shortcut
+
+ # this relies on the first Group in the H5 file being
+ # 'Chombo_global' and the second 'Expressions'
+ levels = f.keys()[2:]
+ grids = []
+ self.dds_list = []
+ i = 0
+ for lev in levels:
+ level_number = int(re.match('level_(\d+)',lev).groups()[0])
+ boxes = f[lev]['boxes'].value
+ dx = f[lev].attrs['dx']
+ self.dds_list.append(dx * np.ones(3))
+ for level_id, box in enumerate(boxes):
+ si = np.array([box['lo_%s' % ax] for ax in 'ijk'])
+ ei = np.array([box['hi_%s' % ax] for ax in 'ijk'])
+ pg = self.grid(len(grids),self,level=level_number,
+ start = si, stop = ei)
+ grids.append(pg)
+ grids[-1]._level_id = level_id
+ self.grid_left_edge[i] = dx*si.astype(self.float_type) + self.domain_left_edge
+ self.grid_right_edge[i] = dx*(ei.astype(self.float_type)+1) + self.domain_left_edge
+ 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
+# self.grids = np.array(self.grids, dtype='object')
+
+ def _populate_grid_objects(self):
+ 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 _setup_data_io(self):
+ self.io = io_registry[self.data_style](self.parameter_file)
+
+class PlutoStaticOutput(StaticOutput):
+ _hierarchy_class = PlutoHierarchy
+ _fieldinfo_fallback = PlutoFieldInfo
+ _fieldinfo_known = KnownPlutoFields
+
+ def __init__(self, filename, data_style='chombo_hdf5',
+ storage_filename = None, ini_filename = None):
+ self._handle = h5py.File(filename,'r')
+ self.current_time = self._handle.attrs['time']
+ self.ini_filename = ini_filename
+ self.fullplotdir = os.path.abspath(filename)
+ StaticOutput.__init__(self,filename,data_style)
+ self.storage_filename = storage_filename
+ self.cosmological_simulation = False
+
+ # These are parameters that I very much wish to get rid of.
+ self.parameters["HydroMethod"] = 'chombo' # always PPM DE
+ self.parameters["DualEnergyFormalism"] = 0
+ self.parameters["EOSType"] = -1 # default
+
+ 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 yt2plutoFieldsDict:
+ 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 _localize(self, f, default):
+ if f is None:
+ return os.path.join(self.directory, default)
+ return f
+
+ def _parse_parameter_file(self):
+ """
+ Reads in an inputs file in the 'pluto.ini' format. Probably not
+ especially robust at the moment.
+ """
+
+ ini_filename = 'pluto.ini'
+ self.fullplotdir = os.path.abspath(self.parameter_filename)
+ self.ini_filename = self._localize( \
+ self.ini_filename, ini_filename)
+ self.unique_identifier = \
+ int(os.stat(self.parameter_filename)[ST_CTIME])
+ lines = open(self.ini_filename).readlines()
+ # read the file line by line, storing important parameters
+ for lineI, line in enumerate(lines):
+ try:
+ param, sep, vals = map(rstrip,line.partition(' '))
+ except ValueError:
+ mylog.error("ValueError: '%s'", line)
+ if pluto2enzoDict.has_key(param):
+ paramName = pluto2enzoDict[param]
+ t = map(parameterDict[paramName], vals.split())
+ if len(t) == 1:
+ self.parameters[paramName] = t[0]
+ else:
+ if paramName == "RefineBy":
+ self.parameters[paramName] = t[0]
+ else:
+ self.parameters[paramName] = t
+
+ # assumes 3D for now
+ elif param.startswith("X1-grid"):
+ t = vals.split()
+ low1 = float(t[1])
+ high1 = float(t[4])
+ N1 = int(t[2])
+ elif param.startswith("X2-grid"):
+ t = vals.split()
+ low2 = float(t[1])
+ high2 = float(t[4])
+ N2 = int(t[2])
+ elif param.startswith("X3-grid"):
+ t = vals.split()
+ low3 = float(t[1])
+ high3 = float(t[4])
+ N3 = int(t[2])
+
+ self.dimensionality = 3
+ self.domain_left_edge = np.array([low1,low2,low3])
+ self.domain_right_edge = np.array([high1,high2,high3])
+ self.domain_dimensions = np.array([N1,N2,N3])
+ self.refine_by = self.parameters["RefineBy"]
+
+ @classmethod
+ def _is_valid(self, *args, **kwargs):
+ return os.path.isfile('pluto.ini')
+
+ @parallel_root_only
+ def print_key_parameters(self):
+ for a in ["current_time", "domain_dimensions", "domain_left_edge",
+ "domain_right_edge"]:
+ if not hasattr(self, a):
+ mylog.error("Missing %s in parameter file definition!", a)
+ continue
+ v = getattr(self, a)
+ mylog.info("Parameters: %-25s = %s", a, v)
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/frontends/pluto/definitions.py
--- /dev/null
+++ b/yt/frontends/pluto/definitions.py
@@ -0,0 +1,65 @@
+"""
+Various definitions for various other modules and routines
+
+Author: J. S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Homepage: http://yt-project.org/
+License:
+ Copyright (C) 2008-2011 J.S. Oishi. All Rights Reserved.
+
+ This file is part of yt.
+
+ yt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""
+
+parameterDict = {"CosmologyCurrentRedshift": float,
+ "CosmologyComovingBoxSize": float,
+ "CosmologyOmegaMatterNow": float,
+ "CosmologyOmegaLambdaNow": float,
+ "CosmologyHubbleConstantNow": float,
+ "CosmologyInitialRedshift": float,
+ "DualEnergyFormalismEta1": float,
+ "DualEnergyFormalismEta2": float,
+ "MetaDataString": str,
+ "HydroMethod": int,
+ "DualEnergyFormalism": int,
+ "InitialTime": float,
+ "ComovingCoordinates": int,
+ "DensityUnits": float,
+ "LengthUnits": float,
+ "LengthUnit": float,
+ "TemperatureUnits": float,
+ "TimeUnits": float,
+ "GravitationalConstant": float,
+ "Gamma": float,
+ "MultiSpecies": int,
+ "CompilerPrecision": str,
+ "CurrentTimeIdentifier": int,
+ "RefineBy": int,
+ "BoundaryConditionName": str,
+ "TopGridRank": int,
+ "TopGridDimensions": int,
+ "EOSSoundSpeed": float,
+ "EOSType": int,
+ "NumberOfParticleAttributes": int,
+ }
+
+pluto2enzoDict = {"GAMMA": "Gamma",
+ "Ref_ratio": "RefineBy"
+ }
+
+yt2plutoFieldsDict = {}
+pluto2ytFieldsDict = {}
+
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/frontends/pluto/fields.py
--- /dev/null
+++ b/yt/frontends/pluto/fields.py
@@ -0,0 +1,97 @@
+"""
+Pluto-specific fields
+
+Author: J. S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Homepage: http://yt-project.org/
+License:
+ Copyright (C) 2009-2011 J. S. Oishi, Matthew Turk. All Rights Reserved.
+
+ This file is part of yt.
+
+ yt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+
+from yt.data_objects.field_info_container import \
+ FieldInfoContainer, \
+ FieldInfo, \
+ NullFunc, \
+ ValidateParameter, \
+ ValidateDataField, \
+ ValidateProperty, \
+ ValidateSpatial, \
+ ValidateGridType
+import yt.data_objects.universal_fields
+import numpy as np
+
+KnownPlutoFields = FieldInfoContainer()
+add_pluto_field = KnownPlutoFields.add_field
+
+PlutoFieldInfo = FieldInfoContainer.create_with_fallback(FieldInfo)
+add_field = PlutoFieldInfo.add_field
+
+add_pluto_field("rho", function=NullFunc, take_log=True,
+ validators = [ValidateDataField("density")],
+ units=r"\rm{g}/\rm{cm}^3")
+
+KnownPlutoFields["rho"]._projected_units =r"\rm{g}/\rm{cm}^2"
+
+add_pluto_field("vx1", function=NullFunc, take_log=False,
+ validators = [ValidateDataField("X-Momentum")],
+ units=r"",display_name=r"M_x")
+KnownPlutoFields["vx1"]._projected_units=r""
+
+add_pluto_field("vx2", function=NullFunc, take_log=False,
+ validators = [ValidateDataField("Y-Momentum")],
+ units=r"",display_name=r"M_y")
+KnownPlutoFields["vx2"]._projected_units=r""
+
+add_pluto_field("vx3", function=NullFunc, take_log=False,
+ validators = [ValidateDataField("Z-Momentum")],
+ units=r"",display_name=r"M_z")
+KnownPlutoFields["vx3"]._projected_units=r""
+
+add_pluto_field("prs", function=NullFunc, take_log=True,
+ validators = [ValidateDataField("energy-density")],
+ units=r"\rm{erg}/\rm{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["rho"]
+add_field("Density",function=_Density, take_log=True,
+ units=r'\rm{g}/\rm{cm^3}')
+
+def _Xmomentum(field, data):
+ """ Generate x-momentum. """
+ return data["vx1"]*data["density"]
+add_field("X-momentum",function=_Xmomentum, take_log=False,
+ units=r'\rm{g}/\rm{cm^2 s}')
+
+def _Ymomentum(field, data):
+ """ Generate y-momentum """
+ return data["vx2"]*data["density"]
+add_field("Y-momentum",function=_Ymomentum, take_log=False,
+ units=r'\rm{g}/\rm{cm^2 s}')
+
+def _Zmomentum(field,data):
+ """ Generate z-momentum"""
+ return data["vx3"]*data["density"]
+add_field("Z-Momentum",function=_Zmomentum, take_log=False,
+ units=r'\rm{g}/\rm{cm^2 s}')
+
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/frontends/pluto/io.py
--- /dev/null
+++ b/yt/frontends/pluto/io.py
@@ -0,0 +1,73 @@
+"""
+The data-file handling functions
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Author: J. S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Homepage: http://yt-project.org/
+License:
+ Copyright (C) 2007-2011 Matthew Turk. All Rights Reserved.
+
+ This file is part of yt.
+
+ yt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+import h5py
+import os
+import re
+import numpy as np
+
+from yt.utilities.io_handler import \
+ BaseIOHandler
+
+class IOHandlerChomboHDF5(BaseIOHandler):
+ _data_style = "chombo_hdf5"
+ _offset_string = 'data:offsets=0'
+ _data_string = 'data:datatype=0'
+
+ def __init__(self, pf, *args, **kwargs):
+ BaseIOHandler.__init__(self, *args, **kwargs)
+ self.pf = pf
+ self._handle = pf._handle
+
+ _field_dict = None
+ @property
+ def field_dict(self):
+ if self._field_dict is not None:
+ return self._field_dict
+ ncomp = int(self._handle['/'].attrs['num_components'])
+ temp = self._handle['/'].attrs.items()[-ncomp:]
+ val, keys = zip(*temp)
+ val = [int(re.match('component_(\d+)',v).groups()[0]) for v in val]
+ self._field_dict = dict(zip(keys,val))
+ return self._field_dict
+
+ def _read_field_names(self,grid):
+ ncomp = int(self._handle['/'].attrs['num_components'])
+
+ 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()
+
+ 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')
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/frontends/pluto/setup.py
--- /dev/null
+++ b/yt/frontends/pluto/setup.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+import setuptools
+import os
+import sys
+import os.path
+
+
+def configuration(parent_package='', top_path=None):
+ from numpy.distutils.misc_util import Configuration
+ config = Configuration('pluto', parent_package, top_path)
+ config.make_config_py() # installs __config__.py
+ #config.make_svn_version_py()
+ return config
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/frontends/setup.py
--- a/yt/frontends/setup.py
+++ b/yt/frontends/setup.py
@@ -20,4 +20,5 @@
config.add_subpackage("maestro")
config.add_subpackage("castro")
config.add_subpackage("stream")
+ config.add_subpackage("pluto")
return config
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/frontends/stream/data_structures.py
--- a/yt/frontends/stream/data_structures.py
+++ b/yt/frontends/stream/data_structures.py
@@ -25,6 +25,7 @@
import weakref
import numpy as np
+import uuid
from yt.utilities.io_handler import io_registry
from yt.funcs import *
@@ -302,7 +303,10 @@
#self._conversion_override = conversion_override
self.stream_handler = stream_handler
- StaticOutput.__init__(self, "InMemoryParameterFile", self._data_style)
+ name = "InMemoryParameterFile_%s" % (uuid.uuid4().hex)
+ from yt.data_objects.static_output import _cached_pfs
+ _cached_pfs[name] = self
+ StaticOutput.__init__(self, name, self._data_style)
self.units = {}
self.time_units = {}
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/mods.py
--- a/yt/mods.py
+++ b/yt/mods.py
@@ -102,6 +102,9 @@
from yt.frontends.art.api import \
ARTStaticOutput, ARTFieldInfo, add_art_field
+from yt.frontends.pluto.api import \
+ PlutoStaticOutput, PlutoFieldInfo, add_pluto_field
+
#from yt.frontends.maestro.api import \
# MaestroStaticOutput, MaestroFieldInfo, add_maestro_field
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/utilities/decompose.py
--- a/yt/utilities/decompose.py
+++ b/yt/utilities/decompose.py
@@ -69,8 +69,8 @@
""" Evaluate longest to shortest edge ratio
BEWARE: lot's of magic here """
eff_dim = (n_d > 1).sum()
- ideal_bsize = eff_dim * (pieces * np.product(n_d) ** (eff_dim - 1)
- ) ** (1.0 / eff_dim)
+ exp = float(eff_dim - 1) / float(eff_dim)
+ ideal_bsize = eff_dim * pieces ** (1.0 / eff_dim) * np.product(n_d) ** exp
mask = np.where(n_d > 1)
nd_arr = np.array(n_d, dtype=np.float64)[mask]
bsize = int(np.sum(ldom[mask] / nd_arr * np.product(nd_arr)))
@@ -109,6 +109,10 @@
fac = factorize_number(pieces)
nfactors = len(fac[:, 2])
best = 0.0
+ p_size = np.ones(3, dtype=np.int)
+ if pieces == 1:
+ return p_size
+
while np.all(fac[:, 2] > 0):
ldom = np.ones(3, dtype=np.int)
for nfac in range(nfactors):
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/utilities/definitions.py
--- a/yt/utilities/definitions.py
+++ b/yt/utilities/definitions.py
@@ -48,7 +48,8 @@
y_names = ['z','z','y']
# How many of each thing are in an Mpc
-mpc_conversion = {'mpc' : mpc_per_mpc,
+mpc_conversion = {'Mpc' : mpc_per_mpc,
+ 'mpc' : mpc_per_mpc,
'kpc' : kpc_per_mpc,
'pc' : pc_per_mpc,
'au' : au_per_mpc,
@@ -56,7 +57,7 @@
'miles' : miles_per_mpc,
'cm' : cm_per_mpc}
-# How many seconds are in each thig
+# How many seconds are in each thing
sec_conversion = {'Gyr' : sec_per_Gyr,
'Myr' : sec_per_Myr,
'years' : sec_per_year,
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/utilities/grid_data_format/writer.py
--- a/yt/utilities/grid_data_format/writer.py
+++ b/yt/utilities/grid_data_format/writer.py
@@ -57,7 +57,7 @@
# don't forget to close the file.
f.close()
-def save_field(pf, field_name):
+def save_field(pf, field_name, field_parameters=None):
"""
Write a single field associated with the parameter file pf to the
backup file.
@@ -68,6 +68,8 @@
The yt parameter file that the field is associated with.
field_name : string
The name of the field to save.
+ field_parameters : dictionary
+ A dictionary of field parameters to set.
"""
field_obj = pf.field_info[field_name]
@@ -85,12 +87,12 @@
particle_type_name="dark_matter")
# now save the field
- _write_field_to_gdf(pf, f, field_name, particle_type_name="dark_matter")
+ _write_field_to_gdf(pf, f, field_name, particle_type_name="dark_matter", field_parameters=field_parameters)
# don't forget to close the file.
f.close()
-def _write_field_to_gdf(pf, fhandle, field_name, particle_type_name):
+def _write_field_to_gdf(pf, fhandle, field_name, particle_type_name, field_parameters=None):
# add field info to field_types group
g = fhandle["field_types"]
@@ -122,6 +124,12 @@
# now add actual data, grid by grid
g = fhandle["data"]
for grid in pf.h.grids:
+
+ # set field parameters, if specified
+ if field_parameters is not None:
+ for k,v in field_parameters.iteritems():
+ grid.set_field_parameter(k,v)
+
grid_group = g["grid_%010i" % (grid.id - grid._id_offset)]
particles_group = grid_group["particles"]
pt_group = particles_group[particle_type_name]
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/utilities/physical_constants.py
--- a/yt/utilities/physical_constants.py
+++ b/yt/utilities/physical_constants.py
@@ -63,6 +63,7 @@
# time
sec_per_Gyr = 31.5576e15
sec_per_Myr = 31.5576e12
+sec_per_kyr = 31.5576e9
sec_per_year = 31.5576e6 # "IAU Style Manual" by G.A. Wilkins, Comm. 5, in IAU Transactions XXB (1989)
sec_per_day = 86400.0
sec_per_hr = 3600.0
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/visualization/plot_modifications.py
--- a/yt/visualization/plot_modifications.py
+++ b/yt/visualization/plot_modifications.py
@@ -40,6 +40,11 @@
y_dict, y_names, \
axis_names, \
axis_labels
+from yt.utilities.physical_constants import \
+ sec_per_Gyr, sec_per_Myr, \
+ sec_per_kyr, sec_per_year, \
+ sec_per_day, sec_per_hr
+
import _MPL
callback_registry = {}
@@ -1204,15 +1209,18 @@
'min': 60.0,
'minute': 60.0,
'minutes': 60.0,
- 'h': 3600.0,
- 'hour': 3600.0,
- 'hours': 3600.0,
- 'd': 86400.0,
- 'day': 86400.0,
- 'days': 86400.0,
- 'y': 86400.0*365.25,
- 'year': 86400.0*365.25,
- 'years': 86400.0*365.25,
+ 'h': sec_per_hr,
+ 'hour': sec_per_hr,
+ 'hours': sec_per_hr,
+ 'd': sec_per_day,
+ 'day': sec_per_day,
+ 'days': sec_per_day,
+ 'y': sec_per_year,
+ 'year': sec_per_year,
+ 'years': sec_per_year,
+ 'kyr': sec_per_kyr,
+ 'myr': sec_per_Myr,
+ 'gyr': sec_per_Gyr,
'ev': 1e-9 * 7.6e-8 / 6.03,
'kev': 1e-12 * 7.6e-8 / 6.03,
'mev': 1e-15 * 7.6e-8 / 6.03,
@@ -1230,13 +1238,14 @@
self.bbox_dict = bbox_dict
else:
self.bbox_dict = self._bbox_dict
- self.kwargs = {'color': 'w'}
+ self.kwargs = {'color': 'k'}
self.kwargs.update(kwargs)
def __call__(self, plot):
if self.units is None:
t = plot.data.pf.current_time * plot.data.pf['Time']
- scale_keys = ['as', 'fs', 'ps', 'ns', 'us', 'ms', 's']
+ scale_keys = ['as', 'fs', 'ps', 'ns', 'us', 'ms', 's',
+ 'hour', 'day', 'year', 'kyr', 'myr', 'gyr']
self.units = 's'
for k in scale_keys:
if t < self._time_conv[k]:
diff -r 7e5edbc1482c0a52360fb28ecd360da0c11eb2a7 -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -65,6 +65,7 @@
ortho_find
from yt.utilities.parallel_tools.parallel_analysis_interface import \
GroupOwnership
+from yt.utilities.exceptions import YTUnitNotRecognized
from yt.data_objects.time_series import \
TimeSeriesData
@@ -726,6 +727,8 @@
"""
# blind except because it could be in conversion_factors or units
if unit_name is not None:
+ if isinstance(unit_name, str):
+ unit_name = (unit_name, unit_name)
for un in unit_name:
try:
self.pf[un]
https://bitbucket.org/yt_analysis/yt/commits/34a5e6774ceb/
Changeset: 34a5e6774ceb
Branch: stable
User: MatthewTurk
Date: 2013-03-29 11:51:18
Summary: Updating version string
Affected #: 1 file
diff -r 7e0900e6fa901b693adc93574f7b217ddf73ed36 -r 34a5e6774ceb26896c9d767563951d185a720774 setup.py
--- a/setup.py
+++ b/setup.py
@@ -155,7 +155,7 @@
import setuptools
-VERSION = "2.5"
+VERSION = "2.5.1"
if os.path.exists('MANIFEST'):
os.remove('MANIFEST')
https://bitbucket.org/yt_analysis/yt/commits/8dce70a9c689/
Changeset: 8dce70a9c689
Branch: stable
User: MatthewTurk
Date: 2013-03-29 11:51:24
Summary: Added tag yt-2.5.1 for changeset 34a5e6774ceb
Affected #: 1 file
diff -r 34a5e6774ceb26896c9d767563951d185a720774 -r 8dce70a9c68991ef8c16b1f45244393508c36b0f .hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -5163,3 +5163,4 @@
3836676ee6307f9caf5ccdb0f0dd373676a68535 yt-2.3
076cec2c57d2e4b508babbfd661f5daa1e34ec80 yt-2.4
bd285a9a8a643ebb7b47b543e9343da84cd294c5 yt-2.5
+34a5e6774ceb26896c9d767563951d185a720774 yt-2.5.1
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