[yt-svn] commit/yt: 51 new changesets
commits-noreply at bitbucket.org
commits-noreply at bitbucket.org
Wed Jul 12 10:59:11 PDT 2017
51 new commits in yt:
https://bitbucket.org/yt_analysis/yt/commits/eb8a68473134/
Changeset: eb8a68473134
Branch: yt
User: al007
Date: 2017-02-17 00:40:45+00:00
Summary: Get started on line plot.
Affected #: 2 files
diff -r 662fdbe5331ad344f09868c8115f697e5a3bae62 -r eb8a6847313443e439e5981daa86c129d1cfc2a9 yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -65,6 +65,7 @@
def pixelize(self, dimension, data_source, field, bounds, size,
antialias = True, periodic = True):
+ import pdb; pdb.set_trace()
index = data_source.ds.index
if (hasattr(index, 'meshes') and
not isinstance(index.meshes[0], SemiStructuredMesh)):
diff -r 662fdbe5331ad344f09868c8115f697e5a3bae62 -r eb8a6847313443e439e5981daa86c129d1cfc2a9 yt/utilities/lib/pixelization_routines.pyx
--- a/yt/utilities/lib/pixelization_routines.pyx
+++ b/yt/utilities/lib/pixelization_routines.pyx
@@ -862,3 +862,73 @@
free(vertices)
free(field_vals)
return img
+
+def element_mesh_line_plot(np.ndarray[np.float64_t, ndim=2] coords,
+ np.ndarray[np.int64_t, ndim=2] conn,
+ np.ndarray[np.float64_t, ndim=1] start_point,
+ np.ndarray[np.float64_t, ndim=1] end_point,
+ resolution
+ np.ndarray[np.float64_t, ndim=2] field,
+ int index_offset = 0):
+
+ cdef np.float64_t *vertices
+ cdef np.float64_t *field_vals
+ cdef int nvertices = conn.shape[1]
+ cdef int ndim = coords.shape[1]
+ cdef int num_field_vals = field.shape[1]
+ cdef double[4] mapped_coord
+ cdef ElementSampler sampler
+ cdef np.float64_t lin_vec[3]
+ cdef np.float64_t lin_inc[3]
+ cdef np.ndarray[np.float64_t, ndim=2] lin_sample_points
+ lin_sample_points = np.zeros((resolution + 1, 3), dtype="float64")
+ cdef np.int64_t i, n
+ cdef np.float64_t arc_length[resolution + 1]
+ cdef np.float64_t lin_length
+
+ # Pick the right sampler and allocate storage for the mapped coordinate
+ if ndim == 3 and nvertices == 4:
+ sampler = P1Sampler3D()
+ elif ndim == 3 and nvertices == 6:
+ sampler = W1Sampler3D()
+ elif ndim == 3 and nvertices == 8:
+ sampler = Q1Sampler3D()
+ elif ndim == 3 and nvertices == 20:
+ sampler = S2Sampler3D()
+ elif ndim == 2 and nvertices == 3:
+ sampler = P1Sampler2D()
+ elif ndim == 1 and nvertices == 2:
+ sampler = P1Sampler1D()
+ elif ndim == 2 and nvertices == 4:
+ sampler = Q1Sampler2D()
+ elif ndim == 2 and nvertices == 6:
+ sampler = T2Sampler2D()
+ elif ndim == 3 and nvertices == 10:
+ sampler = Tet2Sampler3D()
+ else:
+ raise YTElementTypeNotRecognized(ndim, nvertices)
+
+ # allocate temporary storage
+ vertices = <np.float64_t *> malloc(ndim * sizeof(np.float64_t) * nvertices)
+ field_vals = <np.float64_t *> malloc(sizeof(np.float64_t) * num_field_vals)
+
+ for ci in range(conn.shape[0]):
+
+ for n in range(num_field_vals):
+ field_vals[n] = field[ci, n]
+
+ # Fill the vertices
+ for n in range(nvertices):
+ cj = conn[ci, n] - index_offset
+ for i in range(ndim):
+ vertices[ndim*n + i] = coords[cj, i]
+
+ lin_vec = end_point - start_point
+ lin_length = np.linalg.norm(lin_vec)
+ lin_inc = lin_vec / resolution
+ inc_length = np.linalg.norm(lin_inc)
+ lin_sample_points[0] = start_point
+ arc_length[0] = 0
+ for i in range(1, resolution + 1):
+ lin_sample_points[i] = lin_sample_points[i-1] + lin_inc
+ arc_length[i] = arc_length[i-1] + inc_length
https://bitbucket.org/yt_analysis/yt/commits/f061532a8b56/
Changeset: f061532a8b56
Branch: yt
User: al007
Date: 2017-02-17 19:25:02+00:00
Summary: Ready to try compiling.
Affected #: 2 files
diff -r eb8a6847313443e439e5981daa86c129d1cfc2a9 -r f061532a8b566df8e2a4c8660debdcc30d15afa1 yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -120,6 +120,39 @@
return self._oblique_pixelize(data_source, field, bounds, size,
antialias)
+ def line_plot(self, data_source, field, start_point, end_point, resolution):
+ import pdb; pdb.set_trace()
+ index = data_source.ds.index
+ if (hasattr(index, 'meshes') and
+ not isinstance(index.meshes[0], SemiStructuredMesh)):
+ ftype, fname = field
+ if ftype == "all":
+ mesh_id = 0
+ indices = np.concatenate([mesh.connectivity_indices for mesh in index.mesh_union])
+ else:
+ mesh_id = int(ftype[-1]) - 1
+ indices = index.meshes[mesh_id].connectivity_indices
+
+ coords = index.meshes[mesh_id].connectivity_coords
+ offset = index.meshes[mesh_id]._index_offset
+ ad = data_source.ds.all_data()
+ field_data = ad[field]
+ if field_data.shape[1] == 27:
+ # hexahedral
+ mylog.warning("High order elements not yet supported, " +
+ "dropping to 1st order.")
+ field_data = field_data[:, 0:8]
+ indices = indices[:, 0:8]
+
+ arc_length, plot_values = element_mesh_line_plot(coords, indices,
+ start_point,
+ end_point,
+ resolution, field,
+ index_offset=offset)
+
+ return arc_length, plot_values
+
+
def _ortho_pixelize(self, data_source, field, bounds, size, antialias,
dim, periodic):
# We should be using fcoords
diff -r eb8a6847313443e439e5981daa86c129d1cfc2a9 -r f061532a8b566df8e2a4c8660debdcc30d15afa1 yt/utilities/lib/pixelization_routines.pyx
--- a/yt/utilities/lib/pixelization_routines.pyx
+++ b/yt/utilities/lib/pixelization_routines.pyx
@@ -119,7 +119,7 @@
# (lr) and then iterate up to "right column" (rc) and "uppeR row" (rr),
# depositing into them the data value. Overlap computes the relative
# overlap of a data value with a pixel.
- #
+ #
# NOTE ON ROWS AND COLUMNS:
#
# The way that images are plotting in matplotlib is somewhat different
@@ -497,7 +497,7 @@
cdef np.float64_t r_i, theta_i, dr_i, dtheta_i, dthetamin
cdef np.float64_t costheta, sintheta
cdef int i, pi, pj
-
+
cdef int imax = np.asarray(radius).argmax()
rmax = radius[imax] + dradius[imax]
@@ -867,7 +867,7 @@
np.ndarray[np.int64_t, ndim=2] conn,
np.ndarray[np.float64_t, ndim=1] start_point,
np.ndarray[np.float64_t, ndim=1] end_point,
- resolution
+ resolution,
np.ndarray[np.float64_t, ndim=2] field,
int index_offset = 0):
@@ -876,15 +876,20 @@
cdef int nvertices = conn.shape[1]
cdef int ndim = coords.shape[1]
cdef int num_field_vals = field.shape[1]
+ cdef int num_plot_nodes = resolution + 1
cdef double[4] mapped_coord
cdef ElementSampler sampler
cdef np.float64_t lin_vec[3]
cdef np.float64_t lin_inc[3]
cdef np.ndarray[np.float64_t, ndim=2] lin_sample_points
- lin_sample_points = np.zeros((resolution + 1, 3), dtype="float64")
+ lin_sample_points = np.zeros((num_plot_nodes, 3), dtype="float64")
cdef np.int64_t i, n
- cdef np.float64_t arc_length[resolution + 1]
+ cdef np.ndarray[np.float64_t, ndim=1] arc_length
+ arc_length = np.zeros(num_plot_nodes, dtype="float64")
cdef np.float64_t lin_length
+ cdef np.ndarray[np.float64_t, ndim=1] plot_values
+ plot_values = np.zeros(num_plot_nodes, dtype="foat64")
+ cdef np.float64_t sample_point[3]
# Pick the right sampler and allocate storage for the mapped coordinate
if ndim == 3 and nvertices == 4:
@@ -912,8 +917,17 @@
vertices = <np.float64_t *> malloc(ndim * sizeof(np.float64_t) * nvertices)
field_vals = <np.float64_t *> malloc(sizeof(np.float64_t) * num_field_vals)
+ lin_vec = end_point - start_point
+ lin_length = np.linalg.norm(lin_vec)
+ lin_inc = lin_vec / resolution
+ inc_length = np.linalg.norm(lin_inc)
+ lin_sample_points[0] = start_point
+ arc_length[0] = 0
+ for i in range(1, resolution + 1):
+ lin_sample_points[i] = lin_sample_points[i-1] + lin_inc
+ arc_length[i] = arc_length[i-1] + inc_length
+
for ci in range(conn.shape[0]):
-
for n in range(num_field_vals):
field_vals[n] = field[ci, n]
@@ -923,12 +937,13 @@
for i in range(ndim):
vertices[ndim*n + i] = coords[cj, i]
- lin_vec = end_point - start_point
- lin_length = np.linalg.norm(lin_vec)
- lin_inc = lin_vec / resolution
- inc_length = np.linalg.norm(lin_inc)
- lin_sample_points[0] = start_point
- arc_length[0] = 0
- for i in range(1, resolution + 1):
- lin_sample_points[i] = lin_sample_points[i-1] + lin_inc
- arc_length[i] = arc_length[i-1] + inc_length
+ for i in range(resolution + 1):
+ sample_point = lin_sample_points[i]
+ sampler.map_real_to_unit(mapped_coord, vertices, sample_point)
+ if not sampler.check_inside(mapped_coord):
+ continue
+ plot_values = sampler.sample_at_unit_point(mapped_coord, field_vals)
+
+ free(vertices)
+ free(field_vals)
+ return arc_length, plot_values
https://bitbucket.org/yt_analysis/yt/commits/59e73dee28b5/
Changeset: 59e73dee28b5
Branch: yt
User: al007
Date: 2017-02-17 22:19:57+00:00
Summary: Bad ordering of for loops in pixelization_routines
Affected #: 2 files
diff -r f061532a8b566df8e2a4c8660debdcc30d15afa1 -r 59e73dee28b5eec194176aae9e3ae1094c828447 yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -24,7 +24,8 @@
from yt.funcs import mylog
from yt.utilities.lib.pixelization_routines import \
pixelize_element_mesh, pixelize_off_axis_cartesian, \
- pixelize_cartesian, pixelize_cartesian_nodal
+ pixelize_cartesian, pixelize_cartesian_nodal,
+ element_mesh_line_plot
from yt.data_objects.unstructured_mesh import SemiStructuredMesh
from yt.utilities.nodal_data_utils import get_nodal_data
@@ -120,12 +121,11 @@
return self._oblique_pixelize(data_source, field, bounds, size,
antialias)
- def line_plot(self, data_source, field, start_point, end_point, resolution):
- import pdb; pdb.set_trace()
- index = data_source.ds.index
+ def line_plot(self, field, start_point, end_point, resolution):
+ index = self.ds.index
if (hasattr(index, 'meshes') and
not isinstance(index.meshes[0], SemiStructuredMesh)):
- ftype, fname = field
+ ftype, fname = field[0]
if ftype == "all":
mesh_id = 0
indices = np.concatenate([mesh.connectivity_indices for mesh in index.mesh_union])
@@ -134,9 +134,14 @@
indices = index.meshes[mesh_id].connectivity_indices
coords = index.meshes[mesh_id].connectivity_coords
+ if coords.shape[1] != end_point.size != start_point.size:
+ raise ValueError("The coordinate dimension doesn't match the "
+ "start and end point dimensions.")
+
+
offset = index.meshes[mesh_id]._index_offset
- ad = data_source.ds.all_data()
- field_data = ad[field]
+ ad = self.ds.all_data()
+ field_data = ad[field[0]]
if field_data.shape[1] == 27:
# hexahedral
mylog.warning("High order elements not yet supported, " +
@@ -147,7 +152,7 @@
arc_length, plot_values = element_mesh_line_plot(coords, indices,
start_point,
end_point,
- resolution, field,
+ resolution, field_data,
index_offset=offset)
return arc_length, plot_values
diff -r f061532a8b566df8e2a4c8660debdcc30d15afa1 -r 59e73dee28b5eec194176aae9e3ae1094c828447 yt/utilities/lib/pixelization_routines.pyx
--- a/yt/utilities/lib/pixelization_routines.pyx
+++ b/yt/utilities/lib/pixelization_routines.pyx
@@ -879,18 +879,22 @@
cdef int num_plot_nodes = resolution + 1
cdef double[4] mapped_coord
cdef ElementSampler sampler
- cdef np.float64_t lin_vec[3]
- cdef np.float64_t lin_inc[3]
+ cdef np.ndarray[np.float64_t, ndim=1] lin_vec
+ cdef np.ndarray[np.float64_t, ndim=1] lin_inc
cdef np.ndarray[np.float64_t, ndim=2] lin_sample_points
- lin_sample_points = np.zeros((num_plot_nodes, 3), dtype="float64")
- cdef np.int64_t i, n
+ cdef np.int64_t i, n, j
cdef np.ndarray[np.float64_t, ndim=1] arc_length
- arc_length = np.zeros(num_plot_nodes, dtype="float64")
- cdef np.float64_t lin_length
+ cdef np.float64_t lin_length, inc_length
cdef np.ndarray[np.float64_t, ndim=1] plot_values
- plot_values = np.zeros(num_plot_nodes, dtype="foat64")
cdef np.float64_t sample_point[3]
+ lin_vec = np.zeros(ndim, dtype="float64")
+ lin_inc = np.zeros(ndim, dtype="float64")
+
+ lin_sample_points = np.zeros((num_plot_nodes, ndim), dtype="float64")
+ arc_length = np.zeros(num_plot_nodes, dtype="float64")
+ plot_values = np.zeros(num_plot_nodes, dtype="float64")
+
# Pick the right sampler and allocate storage for the mapped coordinate
if ndim == 3 and nvertices == 4:
sampler = P1Sampler3D()
@@ -920,29 +924,39 @@
lin_vec = end_point - start_point
lin_length = np.linalg.norm(lin_vec)
lin_inc = lin_vec / resolution
- inc_length = np.linalg.norm(lin_inc)
- lin_sample_points[0] = start_point
+ inc_length = lin_length / resolution
+ for j in range(ndim):
+ lin_sample_points[0, j] = start_point[j]
arc_length[0] = 0
for i in range(1, resolution + 1):
- lin_sample_points[i] = lin_sample_points[i-1] + lin_inc
- arc_length[i] = arc_length[i-1] + inc_length
+ for j in range(ndim):
+ lin_sample_points[i, j] = lin_sample_points[i-1, j] + lin_inc[j]
+ arc_length[i] = arc_length[i-1] + inc_length
- for ci in range(conn.shape[0]):
- for n in range(num_field_vals):
- field_vals[n] = field[ci, n]
+ for i in range(resolution + 1):
+ for j in range(3):
+ if j < ndim:
+ sample_point[j] = lin_sample_points[i][j]
+ else:
+ sample_point[j] = 0
+ for ci in range(conn.shape[0]):
+ for n in range(num_field_vals):
+ field_vals[n] = field[ci, n]
- # Fill the vertices
- for n in range(nvertices):
- cj = conn[ci, n] - index_offset
- for i in range(ndim):
- vertices[ndim*n + i] = coords[cj, i]
+ # Fill the vertices
+ for n in range(nvertices):
+ cj = conn[ci, n] - index_offset
+ for i in range(ndim):
+ vertices[ndim*n + i] = coords[cj, i]
- for i in range(resolution + 1):
- sample_point = lin_sample_points[i]
sampler.map_real_to_unit(mapped_coord, vertices, sample_point)
- if not sampler.check_inside(mapped_coord):
+ if not sampler.check_inside(mapped_coord) and ci != conn.shape[0] - 1:
continue
- plot_values = sampler.sample_at_unit_point(mapped_coord, field_vals)
+ elif not sampler.check_inside(mapped_coord):
+ raise RuntimeError("It's impossible that the line point doesn't "
+ "fall within any of the elements.")
+ plot_values[i] = sampler.sample_at_unit_point(mapped_coord, field_vals)
+ break
free(vertices)
free(field_vals)
https://bitbucket.org/yt_analysis/yt/commits/ce965bc94703/
Changeset: ce965bc94703
Branch: yt
User: al007
Date: 2017-02-18 00:18:18+00:00
Summary: New code doesn't show any spikes. Nice!
Affected #: 1 file
diff -r 59e73dee28b5eec194176aae9e3ae1094c828447 -r ce965bc94703ab0bbc2fa1d4fd2fd402c6db3238 yt/utilities/lib/pixelization_routines.pyx
--- a/yt/utilities/lib/pixelization_routines.pyx
+++ b/yt/utilities/lib/pixelization_routines.pyx
@@ -882,7 +882,7 @@
cdef np.ndarray[np.float64_t, ndim=1] lin_vec
cdef np.ndarray[np.float64_t, ndim=1] lin_inc
cdef np.ndarray[np.float64_t, ndim=2] lin_sample_points
- cdef np.int64_t i, n, j
+ cdef np.int64_t i, n, j, k
cdef np.ndarray[np.float64_t, ndim=1] arc_length
cdef np.float64_t lin_length, inc_length
cdef np.ndarray[np.float64_t, ndim=1] plot_values
@@ -946,8 +946,8 @@
# Fill the vertices
for n in range(nvertices):
cj = conn[ci, n] - index_offset
- for i in range(ndim):
- vertices[ndim*n + i] = coords[cj, i]
+ for k in range(ndim):
+ vertices[ndim*n + k] = coords[cj, k]
sampler.map_real_to_unit(mapped_coord, vertices, sample_point)
if not sampler.check_inside(mapped_coord) and ci != conn.shape[0] - 1:
https://bitbucket.org/yt_analysis/yt/commits/48059f104435/
Changeset: 48059f104435
Branch: yt
User: al007
Date: 2017-02-20 14:56:10+00:00
Summary: Remove pdb set trace
Affected #: 1 file
diff -r ce965bc94703ab0bbc2fa1d4fd2fd402c6db3238 -r 48059f1044355dee30eddb937ae3fb4cbd783041 yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -66,7 +66,6 @@
def pixelize(self, dimension, data_source, field, bounds, size,
antialias = True, periodic = True):
- import pdb; pdb.set_trace()
index = data_source.ds.index
if (hasattr(index, 'meshes') and
not isinstance(index.meshes[0], SemiStructuredMesh)):
@@ -125,7 +124,7 @@
index = self.ds.index
if (hasattr(index, 'meshes') and
not isinstance(index.meshes[0], SemiStructuredMesh)):
- ftype, fname = field[0]
+ ftype, fname = field
if ftype == "all":
mesh_id = 0
indices = np.concatenate([mesh.connectivity_indices for mesh in index.mesh_union])
@@ -141,7 +140,7 @@
offset = index.meshes[mesh_id]._index_offset
ad = self.ds.all_data()
- field_data = ad[field[0]]
+ field_data = ad[field]
if field_data.shape[1] == 27:
# hexahedral
mylog.warning("High order elements not yet supported, " +
https://bitbucket.org/yt_analysis/yt/commits/8595f7887f5f/
Changeset: 8595f7887f5f
Branch: yt
User: al007
Date: 2017-03-17 23:17:43+00:00
Summary: Demonstrate quad9 support with line plot.
Affected #: 1 file
diff -r 48059f1044355dee30eddb937ae3fb4cbd783041 -r 8595f7887f5fb5064ce41c571734621b7473ff0d yt/utilities/lib/pixelization_routines.pyx
--- a/yt/utilities/lib/pixelization_routines.pyx
+++ b/yt/utilities/lib/pixelization_routines.pyx
@@ -910,6 +910,8 @@
sampler = P1Sampler1D()
elif ndim == 2 and nvertices == 4:
sampler = Q1Sampler2D()
+ elif ndim == 2 and nvertices == 9:
+ sampler = Q2Sampler2D()
elif ndim == 2 and nvertices == 6:
sampler = T2Sampler2D()
elif ndim == 3 and nvertices == 10:
https://bitbucket.org/yt_analysis/yt/commits/d4b51a2d6fcc/
Changeset: d4b51a2d6fcc
Branch: yt
User: al007
Date: 2017-02-17 00:40:45+00:00
Summary: Get started on line plot.
Affected #: 2 files
diff -r fb62830c163dff615a41314214a81e4e784155b1 -r d4b51a2d6fcc6de3e4ee7872b850b59a353e3172 yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -64,6 +64,7 @@
def pixelize(self, dimension, data_source, field, bounds, size,
antialias = True, periodic = True):
+ import pdb; pdb.set_trace()
index = data_source.ds.index
if (hasattr(index, 'meshes') and
not isinstance(index.meshes[0], SemiStructuredMesh)):
diff -r fb62830c163dff615a41314214a81e4e784155b1 -r d4b51a2d6fcc6de3e4ee7872b850b59a353e3172 yt/utilities/lib/pixelization_routines.pyx
--- a/yt/utilities/lib/pixelization_routines.pyx
+++ b/yt/utilities/lib/pixelization_routines.pyx
@@ -694,3 +694,73 @@
free(vertices)
free(field_vals)
return img
+
+def element_mesh_line_plot(np.ndarray[np.float64_t, ndim=2] coords,
+ np.ndarray[np.int64_t, ndim=2] conn,
+ np.ndarray[np.float64_t, ndim=1] start_point,
+ np.ndarray[np.float64_t, ndim=1] end_point,
+ resolution
+ np.ndarray[np.float64_t, ndim=2] field,
+ int index_offset = 0):
+
+ cdef np.float64_t *vertices
+ cdef np.float64_t *field_vals
+ cdef int nvertices = conn.shape[1]
+ cdef int ndim = coords.shape[1]
+ cdef int num_field_vals = field.shape[1]
+ cdef double[4] mapped_coord
+ cdef ElementSampler sampler
+ cdef np.float64_t lin_vec[3]
+ cdef np.float64_t lin_inc[3]
+ cdef np.ndarray[np.float64_t, ndim=2] lin_sample_points
+ lin_sample_points = np.zeros((resolution + 1, 3), dtype="float64")
+ cdef np.int64_t i, n
+ cdef np.float64_t arc_length[resolution + 1]
+ cdef np.float64_t lin_length
+
+ # Pick the right sampler and allocate storage for the mapped coordinate
+ if ndim == 3 and nvertices == 4:
+ sampler = P1Sampler3D()
+ elif ndim == 3 and nvertices == 6:
+ sampler = W1Sampler3D()
+ elif ndim == 3 and nvertices == 8:
+ sampler = Q1Sampler3D()
+ elif ndim == 3 and nvertices == 20:
+ sampler = S2Sampler3D()
+ elif ndim == 2 and nvertices == 3:
+ sampler = P1Sampler2D()
+ elif ndim == 1 and nvertices == 2:
+ sampler = P1Sampler1D()
+ elif ndim == 2 and nvertices == 4:
+ sampler = Q1Sampler2D()
+ elif ndim == 2 and nvertices == 6:
+ sampler = T2Sampler2D()
+ elif ndim == 3 and nvertices == 10:
+ sampler = Tet2Sampler3D()
+ else:
+ raise YTElementTypeNotRecognized(ndim, nvertices)
+
+ # allocate temporary storage
+ vertices = <np.float64_t *> malloc(ndim * sizeof(np.float64_t) * nvertices)
+ field_vals = <np.float64_t *> malloc(sizeof(np.float64_t) * num_field_vals)
+
+ for ci in range(conn.shape[0]):
+
+ for n in range(num_field_vals):
+ field_vals[n] = field[ci, n]
+
+ # Fill the vertices
+ for n in range(nvertices):
+ cj = conn[ci, n] - index_offset
+ for i in range(ndim):
+ vertices[ndim*n + i] = coords[cj, i]
+
+ lin_vec = end_point - start_point
+ lin_length = np.linalg.norm(lin_vec)
+ lin_inc = lin_vec / resolution
+ inc_length = np.linalg.norm(lin_inc)
+ lin_sample_points[0] = start_point
+ arc_length[0] = 0
+ for i in range(1, resolution + 1):
+ lin_sample_points[i] = lin_sample_points[i-1] + lin_inc
+ arc_length[i] = arc_length[i-1] + inc_length
https://bitbucket.org/yt_analysis/yt/commits/95d92056c4fd/
Changeset: 95d92056c4fd
Branch: yt
User: al007
Date: 2017-02-17 19:25:02+00:00
Summary: Ready to try compiling.
Affected #: 2 files
diff -r d4b51a2d6fcc6de3e4ee7872b850b59a353e3172 -r 95d92056c4fd0e9bf638a7e411a308ed2feda04d yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -125,6 +125,39 @@
return self._oblique_pixelize(data_source, field, bounds, size,
antialias)
+ def line_plot(self, data_source, field, start_point, end_point, resolution):
+ import pdb; pdb.set_trace()
+ index = data_source.ds.index
+ if (hasattr(index, 'meshes') and
+ not isinstance(index.meshes[0], SemiStructuredMesh)):
+ ftype, fname = field
+ if ftype == "all":
+ mesh_id = 0
+ indices = np.concatenate([mesh.connectivity_indices for mesh in index.mesh_union])
+ else:
+ mesh_id = int(ftype[-1]) - 1
+ indices = index.meshes[mesh_id].connectivity_indices
+
+ coords = index.meshes[mesh_id].connectivity_coords
+ offset = index.meshes[mesh_id]._index_offset
+ ad = data_source.ds.all_data()
+ field_data = ad[field]
+ if field_data.shape[1] == 27:
+ # hexahedral
+ mylog.warning("High order elements not yet supported, " +
+ "dropping to 1st order.")
+ field_data = field_data[:, 0:8]
+ indices = indices[:, 0:8]
+
+ arc_length, plot_values = element_mesh_line_plot(coords, indices,
+ start_point,
+ end_point,
+ resolution, field,
+ index_offset=offset)
+
+ return arc_length, plot_values
+
+
def _ortho_pixelize(self, data_source, field, bounds, size, antialias,
dim, periodic):
# We should be using fcoords
diff -r d4b51a2d6fcc6de3e4ee7872b850b59a353e3172 -r 95d92056c4fd0e9bf638a7e411a308ed2feda04d yt/utilities/lib/pixelization_routines.pyx
--- a/yt/utilities/lib/pixelization_routines.pyx
+++ b/yt/utilities/lib/pixelization_routines.pyx
@@ -118,7 +118,7 @@
# (lr) and then iterate up to "right column" (rc) and "uppeR row" (rr),
# depositing into them the data value. Overlap computes the relative
# overlap of a data value with a pixel.
- #
+ #
# NOTE ON ROWS AND COLUMNS:
#
# The way that images are plotting in matplotlib is somewhat different
@@ -331,7 +331,7 @@
cdef np.float64_t r_i, theta_i, dr_i, dtheta_i, dthetamin
cdef np.float64_t costheta, sintheta
cdef int i, pi, pj
-
+
cdef int imax = np.asarray(radius).argmax()
rmax = radius[imax] + dradius[imax]
@@ -699,7 +699,7 @@
np.ndarray[np.int64_t, ndim=2] conn,
np.ndarray[np.float64_t, ndim=1] start_point,
np.ndarray[np.float64_t, ndim=1] end_point,
- resolution
+ resolution,
np.ndarray[np.float64_t, ndim=2] field,
int index_offset = 0):
@@ -708,15 +708,20 @@
cdef int nvertices = conn.shape[1]
cdef int ndim = coords.shape[1]
cdef int num_field_vals = field.shape[1]
+ cdef int num_plot_nodes = resolution + 1
cdef double[4] mapped_coord
cdef ElementSampler sampler
cdef np.float64_t lin_vec[3]
cdef np.float64_t lin_inc[3]
cdef np.ndarray[np.float64_t, ndim=2] lin_sample_points
- lin_sample_points = np.zeros((resolution + 1, 3), dtype="float64")
+ lin_sample_points = np.zeros((num_plot_nodes, 3), dtype="float64")
cdef np.int64_t i, n
- cdef np.float64_t arc_length[resolution + 1]
+ cdef np.ndarray[np.float64_t, ndim=1] arc_length
+ arc_length = np.zeros(num_plot_nodes, dtype="float64")
cdef np.float64_t lin_length
+ cdef np.ndarray[np.float64_t, ndim=1] plot_values
+ plot_values = np.zeros(num_plot_nodes, dtype="foat64")
+ cdef np.float64_t sample_point[3]
# Pick the right sampler and allocate storage for the mapped coordinate
if ndim == 3 and nvertices == 4:
@@ -744,8 +749,17 @@
vertices = <np.float64_t *> malloc(ndim * sizeof(np.float64_t) * nvertices)
field_vals = <np.float64_t *> malloc(sizeof(np.float64_t) * num_field_vals)
+ lin_vec = end_point - start_point
+ lin_length = np.linalg.norm(lin_vec)
+ lin_inc = lin_vec / resolution
+ inc_length = np.linalg.norm(lin_inc)
+ lin_sample_points[0] = start_point
+ arc_length[0] = 0
+ for i in range(1, resolution + 1):
+ lin_sample_points[i] = lin_sample_points[i-1] + lin_inc
+ arc_length[i] = arc_length[i-1] + inc_length
+
for ci in range(conn.shape[0]):
-
for n in range(num_field_vals):
field_vals[n] = field[ci, n]
@@ -755,12 +769,13 @@
for i in range(ndim):
vertices[ndim*n + i] = coords[cj, i]
- lin_vec = end_point - start_point
- lin_length = np.linalg.norm(lin_vec)
- lin_inc = lin_vec / resolution
- inc_length = np.linalg.norm(lin_inc)
- lin_sample_points[0] = start_point
- arc_length[0] = 0
- for i in range(1, resolution + 1):
- lin_sample_points[i] = lin_sample_points[i-1] + lin_inc
- arc_length[i] = arc_length[i-1] + inc_length
+ for i in range(resolution + 1):
+ sample_point = lin_sample_points[i]
+ sampler.map_real_to_unit(mapped_coord, vertices, sample_point)
+ if not sampler.check_inside(mapped_coord):
+ continue
+ plot_values = sampler.sample_at_unit_point(mapped_coord, field_vals)
+
+ free(vertices)
+ free(field_vals)
+ return arc_length, plot_values
https://bitbucket.org/yt_analysis/yt/commits/6415ed2c5dbb/
Changeset: 6415ed2c5dbb
Branch: yt
User: al007
Date: 2017-02-17 22:19:57+00:00
Summary: Bad ordering of for loops in pixelization_routines
Affected #: 2 files
diff -r 95d92056c4fd0e9bf638a7e411a308ed2feda04d -r 6415ed2c5dbb93ff0f09860b2e4a7f0cb6fb5698 yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -24,7 +24,7 @@
from yt.funcs import mylog
from yt.utilities.lib.pixelization_routines import \
pixelize_element_mesh, pixelize_off_axis_cartesian, \
- pixelize_cartesian
+ pixelize_cartesian, element_mesh_line_plot
from yt.data_objects.unstructured_mesh import SemiStructuredMesh
@@ -125,12 +125,11 @@
return self._oblique_pixelize(data_source, field, bounds, size,
antialias)
- def line_plot(self, data_source, field, start_point, end_point, resolution):
- import pdb; pdb.set_trace()
- index = data_source.ds.index
+ def line_plot(self, field, start_point, end_point, resolution):
+ index = self.ds.index
if (hasattr(index, 'meshes') and
not isinstance(index.meshes[0], SemiStructuredMesh)):
- ftype, fname = field
+ ftype, fname = field[0]
if ftype == "all":
mesh_id = 0
indices = np.concatenate([mesh.connectivity_indices for mesh in index.mesh_union])
@@ -139,9 +138,14 @@
indices = index.meshes[mesh_id].connectivity_indices
coords = index.meshes[mesh_id].connectivity_coords
+ if coords.shape[1] != end_point.size != start_point.size:
+ raise ValueError("The coordinate dimension doesn't match the "
+ "start and end point dimensions.")
+
+
offset = index.meshes[mesh_id]._index_offset
- ad = data_source.ds.all_data()
- field_data = ad[field]
+ ad = self.ds.all_data()
+ field_data = ad[field[0]]
if field_data.shape[1] == 27:
# hexahedral
mylog.warning("High order elements not yet supported, " +
@@ -152,7 +156,7 @@
arc_length, plot_values = element_mesh_line_plot(coords, indices,
start_point,
end_point,
- resolution, field,
+ resolution, field_data,
index_offset=offset)
return arc_length, plot_values
diff -r 95d92056c4fd0e9bf638a7e411a308ed2feda04d -r 6415ed2c5dbb93ff0f09860b2e4a7f0cb6fb5698 yt/utilities/lib/pixelization_routines.pyx
--- a/yt/utilities/lib/pixelization_routines.pyx
+++ b/yt/utilities/lib/pixelization_routines.pyx
@@ -711,18 +711,22 @@
cdef int num_plot_nodes = resolution + 1
cdef double[4] mapped_coord
cdef ElementSampler sampler
- cdef np.float64_t lin_vec[3]
- cdef np.float64_t lin_inc[3]
+ cdef np.ndarray[np.float64_t, ndim=1] lin_vec
+ cdef np.ndarray[np.float64_t, ndim=1] lin_inc
cdef np.ndarray[np.float64_t, ndim=2] lin_sample_points
- lin_sample_points = np.zeros((num_plot_nodes, 3), dtype="float64")
- cdef np.int64_t i, n
+ cdef np.int64_t i, n, j
cdef np.ndarray[np.float64_t, ndim=1] arc_length
- arc_length = np.zeros(num_plot_nodes, dtype="float64")
- cdef np.float64_t lin_length
+ cdef np.float64_t lin_length, inc_length
cdef np.ndarray[np.float64_t, ndim=1] plot_values
- plot_values = np.zeros(num_plot_nodes, dtype="foat64")
cdef np.float64_t sample_point[3]
+ lin_vec = np.zeros(ndim, dtype="float64")
+ lin_inc = np.zeros(ndim, dtype="float64")
+
+ lin_sample_points = np.zeros((num_plot_nodes, ndim), dtype="float64")
+ arc_length = np.zeros(num_plot_nodes, dtype="float64")
+ plot_values = np.zeros(num_plot_nodes, dtype="float64")
+
# Pick the right sampler and allocate storage for the mapped coordinate
if ndim == 3 and nvertices == 4:
sampler = P1Sampler3D()
@@ -752,29 +756,39 @@
lin_vec = end_point - start_point
lin_length = np.linalg.norm(lin_vec)
lin_inc = lin_vec / resolution
- inc_length = np.linalg.norm(lin_inc)
- lin_sample_points[0] = start_point
+ inc_length = lin_length / resolution
+ for j in range(ndim):
+ lin_sample_points[0, j] = start_point[j]
arc_length[0] = 0
for i in range(1, resolution + 1):
- lin_sample_points[i] = lin_sample_points[i-1] + lin_inc
- arc_length[i] = arc_length[i-1] + inc_length
+ for j in range(ndim):
+ lin_sample_points[i, j] = lin_sample_points[i-1, j] + lin_inc[j]
+ arc_length[i] = arc_length[i-1] + inc_length
- for ci in range(conn.shape[0]):
- for n in range(num_field_vals):
- field_vals[n] = field[ci, n]
+ for i in range(resolution + 1):
+ for j in range(3):
+ if j < ndim:
+ sample_point[j] = lin_sample_points[i][j]
+ else:
+ sample_point[j] = 0
+ for ci in range(conn.shape[0]):
+ for n in range(num_field_vals):
+ field_vals[n] = field[ci, n]
- # Fill the vertices
- for n in range(nvertices):
- cj = conn[ci, n] - index_offset
- for i in range(ndim):
- vertices[ndim*n + i] = coords[cj, i]
+ # Fill the vertices
+ for n in range(nvertices):
+ cj = conn[ci, n] - index_offset
+ for i in range(ndim):
+ vertices[ndim*n + i] = coords[cj, i]
- for i in range(resolution + 1):
- sample_point = lin_sample_points[i]
sampler.map_real_to_unit(mapped_coord, vertices, sample_point)
- if not sampler.check_inside(mapped_coord):
+ if not sampler.check_inside(mapped_coord) and ci != conn.shape[0] - 1:
continue
- plot_values = sampler.sample_at_unit_point(mapped_coord, field_vals)
+ elif not sampler.check_inside(mapped_coord):
+ raise RuntimeError("It's impossible that the line point doesn't "
+ "fall within any of the elements.")
+ plot_values[i] = sampler.sample_at_unit_point(mapped_coord, field_vals)
+ break
free(vertices)
free(field_vals)
https://bitbucket.org/yt_analysis/yt/commits/72b76ebf266e/
Changeset: 72b76ebf266e
Branch: yt
User: al007
Date: 2017-02-18 00:18:18+00:00
Summary: New code doesn't show any spikes. Nice!
Affected #: 1 file
diff -r 6415ed2c5dbb93ff0f09860b2e4a7f0cb6fb5698 -r 72b76ebf266e65869b4531cc7af248e48745463f yt/utilities/lib/pixelization_routines.pyx
--- a/yt/utilities/lib/pixelization_routines.pyx
+++ b/yt/utilities/lib/pixelization_routines.pyx
@@ -714,7 +714,7 @@
cdef np.ndarray[np.float64_t, ndim=1] lin_vec
cdef np.ndarray[np.float64_t, ndim=1] lin_inc
cdef np.ndarray[np.float64_t, ndim=2] lin_sample_points
- cdef np.int64_t i, n, j
+ cdef np.int64_t i, n, j, k
cdef np.ndarray[np.float64_t, ndim=1] arc_length
cdef np.float64_t lin_length, inc_length
cdef np.ndarray[np.float64_t, ndim=1] plot_values
@@ -778,8 +778,8 @@
# Fill the vertices
for n in range(nvertices):
cj = conn[ci, n] - index_offset
- for i in range(ndim):
- vertices[ndim*n + i] = coords[cj, i]
+ for k in range(ndim):
+ vertices[ndim*n + k] = coords[cj, k]
sampler.map_real_to_unit(mapped_coord, vertices, sample_point)
if not sampler.check_inside(mapped_coord) and ci != conn.shape[0] - 1:
https://bitbucket.org/yt_analysis/yt/commits/153dfc60f6e2/
Changeset: 153dfc60f6e2
Branch: yt
User: al007
Date: 2017-02-20 14:56:10+00:00
Summary: Remove pdb set trace
Affected #: 1 file
diff -r 72b76ebf266e65869b4531cc7af248e48745463f -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -64,7 +64,6 @@
def pixelize(self, dimension, data_source, field, bounds, size,
antialias = True, periodic = True):
- import pdb; pdb.set_trace()
index = data_source.ds.index
if (hasattr(index, 'meshes') and
not isinstance(index.meshes[0], SemiStructuredMesh)):
@@ -129,7 +128,7 @@
index = self.ds.index
if (hasattr(index, 'meshes') and
not isinstance(index.meshes[0], SemiStructuredMesh)):
- ftype, fname = field[0]
+ ftype, fname = field
if ftype == "all":
mesh_id = 0
indices = np.concatenate([mesh.connectivity_indices for mesh in index.mesh_union])
@@ -145,7 +144,7 @@
offset = index.meshes[mesh_id]._index_offset
ad = self.ds.all_data()
- field_data = ad[field[0]]
+ field_data = ad[field]
if field_data.shape[1] == 27:
# hexahedral
mylog.warning("High order elements not yet supported, " +
https://bitbucket.org/yt_analysis/yt/commits/83eae35d29c6/
Changeset: 83eae35d29c6
Branch: yt
User: al007
Date: 2017-03-17 21:04:42+00:00
Summary: Merge quad9 bookmark into line_plotting bookmark.
Affected #: 72 files
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 doc/Makefile
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -47,6 +47,9 @@
-rm -rf _temp/*.done source/cookbook/_static/*
html:
+ sphinx-apidoc -o source/reference/api/ -e ../yt ../yt/extern/* \
+ $(shell find ../yt -name "*tests*" -type d) ../yt/utilities/voropp*
+ sed -e '/show-inheritance/ a\ \ \ \ :inherited-members:' -i source/reference/api/yt*.rst
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 doc/extensions/pythonscript_sphinxext.py
--- a/doc/extensions/pythonscript_sphinxext.py
+++ b/doc/extensions/pythonscript_sphinxext.py
@@ -1,4 +1,5 @@
import tempfile
+import time
import os
import glob
import shutil
@@ -37,12 +38,16 @@
f.write(content)
# Use sphinx logger?
+ uid = uuid.uuid4().hex[:8]
print("")
+ print(">> Contents of the script: %s" % uid)
print(content)
print("")
+ start = time.time()
subprocess.call(['python', 'temp.py'])
-
+ print(">> The execution of the script %s took %f s" %
+ (uid, time.time() - start))
text = ''
for im in sorted(glob.glob("*.png")):
text += get_image_tag(im, image_dir, image_rel_dir)
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 doc/source/analyzing/Particle_Trajectories.ipynb
--- a/doc/source/analyzing/Particle_Trajectories.ipynb
+++ b/doc/source/analyzing/Particle_Trajectories.ipynb
@@ -279,9 +279,9 @@
"source": [
"fig = plt.figure(figsize=(8.0, 8.0))\n",
"ax = fig.add_subplot(111, projection='3d')\n",
- "ax.plot(trajs[\"particle_position_x\"][100], trajs[\"particle_position_z\"][100], trajs[\"particle_position_z\"][100])\n",
- "ax.plot(trajs[\"particle_position_x\"][8], trajs[\"particle_position_z\"][8], trajs[\"particle_position_z\"][8])\n",
- "ax.plot(trajs[\"particle_position_x\"][25], trajs[\"particle_position_z\"][25], trajs[\"particle_position_z\"][25])"
+ "ax.plot(trajs[\"particle_position_x\"][100], trajs[\"particle_position_y\"][100], trajs[\"particle_position_z\"][100])\n",
+ "ax.plot(trajs[\"particle_position_x\"][8], trajs[\"particle_position_y\"][8], trajs[\"particle_position_z\"][8])\n",
+ "ax.plot(trajs[\"particle_position_x\"][25], trajs[\"particle_position_y\"][25], trajs[\"particle_position_z\"][25])"
]
},
{
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 doc/source/analyzing/analysis_modules/halo_catalogs.rst
--- a/doc/source/analyzing/analysis_modules/halo_catalogs.rst
+++ b/doc/source/analyzing/analysis_modules/halo_catalogs.rst
@@ -481,7 +481,9 @@
A :class:`~yt.analysis_modules.halo_analysis.halo_catalog.HaloCatalog`
saved to disk can be reloaded as a yt dataset with the
-standard call to ``yt.load``. Any side data, such as profiles, can be reloaded
+standard call to ``yt.load``. See :ref:`halocatalog` for a demonstration
+of loading and working only with the catalog.
+Any side data, such as profiles, can be reloaded
with a ``load_profiles`` callback and a call to
:func:`~yt.analysis_modules.halo_analysis.halo_catalog.HaloCatalog.load`.
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 doc/source/analyzing/analysis_modules/xray_emission_fields.rst
--- a/doc/source/analyzing/analysis_modules/xray_emission_fields.rst
+++ b/doc/source/analyzing/analysis_modules/xray_emission_fields.rst
@@ -1,3 +1,6 @@
.. _xray_emission_fields:
+X-ray Emission Fields
+=====================
+
.. notebook:: XrayEmissionFields.ipynb
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 doc/source/examining/loading_data.rst
--- a/doc/source/examining/loading_data.rst
+++ b/doc/source/examining/loading_data.rst
@@ -151,9 +151,9 @@
import yt
- units_override = {"length_unit":(1.0,"Mpc"),
- "time_unit"(1.0,"Myr"),
- "mass_unit":(1.0e14,"Msun")}
+ units_override = {"length_unit": (1.0, "Mpc"),
+ "time_unit": (1.0, "Myr"),
+ "mass_unit": (1.0e14, "Msun")}
ds = yt.load("id0/cluster_merger.0250.vtk", units_override=units_override)
@@ -1458,7 +1458,8 @@
If you have access to both the halo catalog and the simulation snapshot from
the same redshift, additional analysis can be performed for each halo using
-:ref:`halo_catalog`.
+:ref:`halo_catalog`. The resulting product can be reloaded in a similar manner
+to the other halo catalogs shown here.
.. _rockstar:
@@ -1600,6 +1601,39 @@
# The halo mass
print(ad["FOF", "particle_mass"])
+.. _halocatalog:
+
+HaloCatalog
+^^^^^^^^^^^
+
+These are catalogs produced by the analysis discussed in :ref:`halo_catalog`.
+In the case where multiple files were produced, one need only provide the path
+to a single one of them. The field type for all fields is "halos". The fields
+available here are similar to other catalogs. Any addition
+:ref:`halo_catalog_quantities` will also be accessible as fields.
+
++-------------------+---------------------------+
+| HaloCatalog field | yt field name |
++===================+===========================+
+| halo id | particle_identifier |
++-------------------+---------------------------+
+| virial mass | particle_mass |
++-------------------+---------------------------+
+| virial radius | virial_radius |
++-------------------+---------------------------+
+| halo position | particle_position_(x,y,z) |
++-------------------+---------------------------+
+| halo velocity | particle_velocity_(x,y,z) |
++-------------------+---------------------------+
+
+.. code-block:: python
+
+ import yt
+ ds = yt.load("catalogs/catalog.0.h5")
+ ad = ds.all_data()
+ # The halo mass
+ print(ad["halos", "particle_mass"])
+
.. _loading-openpmd-data:
openPMD Data
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 doc/source/reference/api/api.rst
--- a/doc/source/reference/api/api.rst
+++ b/doc/source/reference/api/api.rst
@@ -10,7 +10,6 @@
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autosummary::
- :toctree: generated/
~yt.visualization.plot_window.SlicePlot
~yt.visualization.plot_window.AxisAlignedSlicePlot
@@ -24,7 +23,6 @@
^^^^^^^^^^^^^^^^^^^^^^^^^
.. autosummary::
- :toctree: generated/
~yt.visualization.profile_plotter.ProfilePlot
~yt.visualization.profile_plotter.PhasePlot
@@ -34,7 +32,6 @@
^^^^^^^^^^^^^^
.. autosummary::
- :toctree: generated/
~yt.visualization.particle_plots.ParticleProjectionPlot
~yt.visualization.particle_plots.ParticlePhasePlot
@@ -44,7 +41,6 @@
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autosummary::
- :toctree: generated/
~yt.visualization.fixed_resolution.FixedResolutionBuffer
~yt.visualization.fixed_resolution.ParticleImageBuffer
@@ -69,7 +65,6 @@
These will almost never need to be instantiated on their own.
.. autosummary::
- :toctree: generated/
~yt.data_objects.data_containers.YTDataContainer
~yt.data_objects.data_containers.YTSelectionContainer
@@ -85,7 +80,6 @@
geometric.
.. autosummary::
- :toctree: generated/
~yt.data_objects.selection_data_containers.YTPoint
~yt.data_objects.selection_data_containers.YTOrthoRay
@@ -108,7 +102,6 @@
expensive set of intermediate data.
.. autosummary::
- :toctree: generated/
~yt.data_objects.construction_data_containers.YTStreamline
~yt.data_objects.construction_data_containers.YTQuadTreeProj
@@ -124,7 +117,6 @@
datasets.
.. autosummary::
- :toctree: generated/
~yt.data_objects.time_series.DatasetSeries
~yt.data_objects.time_series.DatasetSeriesObject
@@ -138,7 +130,6 @@
These objects generate an "index" into multiresolution data.
.. autosummary::
- :toctree: generated/
~yt.geometry.geometry_handler.Index
~yt.geometry.grid_geometry_handler.GridIndex
@@ -152,7 +143,6 @@
These classes and functions enable yt's symbolic unit handling system.
.. autosummary::
- :toctree: generated/
yt.data_objects.static_output.Dataset.arr
yt.data_objects.static_output.Dataset.quan
@@ -173,13 +163,11 @@
---------
.. autosummary::
- :toctree: generated/
ARTIO
^^^^^
.. autosummary::
- :toctree: generated/
~yt.frontends.artio.data_structures.ARTIOIndex
~yt.frontends.artio.data_structures.ARTIOOctreeSubset
@@ -194,7 +182,6 @@
^^^^^^
.. autosummary::
- :toctree: generated/
~yt.frontends.athena.data_structures.AthenaGrid
~yt.frontends.athena.data_structures.AthenaHierarchy
@@ -206,7 +193,6 @@
^^^^^^
.. autosummary::
- :toctree: generated/
~yt.frontends.boxlib.data_structures.BoxlibGrid
~yt.frontends.boxlib.data_structures.BoxlibHierarchy
@@ -225,7 +211,6 @@
^^^^^^
.. autosummary::
- :toctree: generated/
~yt.frontends.chombo.data_structures.ChomboGrid
~yt.frontends.chombo.data_structures.ChomboHierarchy
@@ -239,7 +224,6 @@
^^^^
.. autosummary::
- :toctree: generated/
~yt.frontends.enzo.answer_testing_support.ShockTubeTest
~yt.frontends.enzo.data_structures.EnzoGrid
@@ -264,7 +248,6 @@
^^^^
.. autosummary::
- :toctree: generated/
~yt.frontends.fits.data_structures.FITSGrid
~yt.frontends.fits.data_structures.FITSHierarchy
@@ -276,7 +259,6 @@
^^^^^
.. autosummary::
- :toctree: generated/
~yt.frontends.flash.data_structures.FLASHGrid
~yt.frontends.flash.data_structures.FLASHHierarchy
@@ -288,7 +270,6 @@
^^^
.. autosummary::
- :toctree: generated/
~yt.frontends.gdf.data_structures.GDFGrid
~yt.frontends.gdf.data_structures.GDFHierarchy
@@ -299,7 +280,6 @@
^^^^^^^^^^^^^
.. autosummary::
- :toctree: generated/
~yt.frontends.halo_catalog.data_structures.HaloCatalogHDF5File
~yt.frontends.halo_catalog.data_structures.HaloCatalogDataset
@@ -319,7 +299,6 @@
^^^^
.. autosummary::
- :toctree: generated/
~yt.frontends.moab.data_structures.MoabHex8Hierarchy
~yt.frontends.moab.data_structures.MoabHex8Mesh
@@ -334,7 +313,6 @@
^^^^^^^
.. autosummary::
- :toctree: generated/
~yt.frontends.open_pmd.data_structures.OpenPMDGrid
~yt.frontends.open_pmd.data_structures.OpenPMDHierarchy
@@ -349,7 +327,6 @@
^^^^^^
.. autosummary::
- :toctree: generated/
~yt.frontends.ramses.data_structures.RAMSESDomainFile
~yt.frontends.ramses.data_structures.RAMSESDomainSubset
@@ -362,7 +339,6 @@
^^^^^^^^^^^^^^^^^^^^^^
.. autosummary::
- :toctree: generated/
~yt.frontends.gadget.data_structures.GadgetBinaryFile
~yt.frontends.gadget.data_structures.GadgetHDF5Dataset
@@ -384,7 +360,6 @@
^^^^^^
.. autosummary::
- :toctree: generated/
~yt.frontends.stream.data_structures.StreamDictFieldHandler
~yt.frontends.stream.data_structures.StreamGrid
@@ -410,7 +385,6 @@
^^^^^^
.. autosummary::
- :toctree: generated/
~yt.frontends.ytdata.data_structures.YTDataContainerDataset
~yt.frontends.ytdata.data_structures.YTSpatialPlotDataset
@@ -434,7 +408,6 @@
------------
.. autosummary::
- :toctree: generated/
~yt.convenience.load
~yt.convenience.simulation
@@ -457,7 +430,6 @@
.. autosummary::
- :toctree: generated/
~yt.data_objects.profiles.ProfileND
~yt.data_objects.profiles.Profile1D
@@ -475,7 +447,6 @@
of topologically disconnected structures, i.e., clump finding.
.. autosummary::
- :toctree: generated/
~yt.analysis_modules.level_sets.clump_handling.Clump
~yt.analysis_modules.level_sets.clump_handling.Clump.add_info_item
@@ -495,7 +466,6 @@
on cosmological halos. It is also the primary interface for halo finding.
.. autosummary::
- :toctree: generated/
~yt.analysis_modules.halo_analysis.halo_catalog.HaloCatalog
~yt.analysis_modules.halo_analysis.halo_finding_methods.HaloFindingMethod
@@ -526,7 +496,6 @@
to use the ``HaloCatalog``.
.. autosummary::
- :toctree: generated/
~yt.analysis_modules.halo_finding.halo_objects.FOFHaloFinder
~yt.analysis_modules.halo_finding.halo_objects.HOPHaloFinder
@@ -541,7 +510,6 @@
.. autosummary::
- :toctree: generated/
~yt.analysis_modules.two_point_functions.two_point_functions.TwoPointFunctions
~yt.analysis_modules.two_point_functions.two_point_functions.FcnSet
@@ -550,7 +518,6 @@
-----------
.. autosummary::
- :toctree: generated/
~yt.fields.field_info_container.FieldInfoContainer
~yt.fields.derived_field.DerivedField
@@ -564,7 +531,6 @@
---------------
.. autosummary::
- :toctree: generated/
~yt.fields.field_info_container.FieldInfoContainer.add_field
~yt.data_objects.static_output.Dataset.add_field
@@ -574,7 +540,6 @@
----------------
.. autosummary::
- :toctree: generated/
~yt.data_objects.particle_filters.add_particle_filter
~yt.data_objects.particle_filters.particle_filter
@@ -587,7 +552,6 @@
writing to bitmaps.
.. autosummary::
- :toctree: generated/
~yt.data_objects.image_array.ImageArray
@@ -601,7 +565,6 @@
.. autosummary::
- :toctree: generated/
~yt.analysis_modules.star_analysis.sfr_spectrum.StarFormationRate
~yt.analysis_modules.star_analysis.sfr_spectrum.SpectrumBuilder
@@ -611,7 +574,6 @@
.. autosummary::
- :toctree: generated/
~yt.analysis_modules.cosmological_observation.light_cone.light_cone.LightCone
~yt.analysis_modules.cosmological_observation.light_ray.light_ray.LightRay
@@ -619,7 +581,6 @@
Absorption and X-ray spectra and spectral lines:
.. autosummary::
- :toctree: generated/
~yt.analysis_modules.absorption_spectrum.absorption_spectrum.AbsorptionSpectrum
~yt.fields.xray_emission_fields.XrayEmissivityIntegrator
@@ -628,14 +589,12 @@
Absorption spectra fitting:
.. autosummary::
- :toctree: generated/
~yt.analysis_modules.absorption_spectrum.absorption_spectrum_fit.generate_total_fit
Sunrise exporting:
.. autosummary::
- :toctree: generated/
~yt.analysis_modules.sunrise_export.sunrise_exporter.export_to_sunrise
~yt.analysis_modules.sunrise_export.sunrise_exporter.export_to_sunrise_from_halolist
@@ -643,7 +602,6 @@
RADMC-3D exporting:
.. autosummary::
- :toctree: generated/
~yt.analysis_modules.radmc3d_export.RadMC3DInterface.RadMC3DLayer
~yt.analysis_modules.radmc3d_export.RadMC3DInterface.RadMC3DWriter
@@ -657,7 +615,6 @@
Scene infrastructure:
.. autosummary::
- :toctree: generated/
~yt.visualization.volume_rendering.volume_rendering.volume_render
~yt.visualization.volume_rendering.volume_rendering.create_scene
@@ -669,7 +626,6 @@
The different kinds of sources:
.. autosummary::
- :toctree: generated/
~yt.visualization.volume_rendering.render_source.RenderSource
~yt.visualization.volume_rendering.render_source.VolumeSource
@@ -683,7 +639,6 @@
The different kinds of transfer functions:
.. autosummary::
- :toctree: generated/
~yt.visualization.volume_rendering.transfer_functions.TransferFunction
~yt.visualization.volume_rendering.transfer_functions.ColorTransferFunction
@@ -695,7 +650,6 @@
The different kinds of lenses:
.. autosummary::
- :toctree: generated/
~yt.visualization.volume_rendering.lens.Lens
~yt.visualization.volume_rendering.lens.PlaneParallelLens
@@ -712,7 +666,6 @@
.. autosummary::
- :toctree: generated/
~yt.visualization.streamlines.Streamlines
@@ -725,7 +678,6 @@
.. autosummary::
- :toctree: generated/
~yt.visualization.image_writer.multi_image_composite
~yt.visualization.image_writer.write_bitmap
@@ -740,7 +692,6 @@
particularly with complicated layouts.
.. autosummary::
- :toctree: generated/
~yt.visualization.eps_writer.DualEPS
~yt.visualization.eps_writer.single_plot
@@ -757,7 +708,6 @@
.. autosummary::
- :toctree: generated/
~yt.data_objects.derived_quantities.DerivedQuantity
~yt.data_objects.derived_quantities.DerivedQuantityCollection
@@ -783,7 +733,6 @@
See also :ref:`callbacks`.
.. autosummary::
- :toctree: generated/
~yt.visualization.plot_window.PWViewerMPL.annotate_clear
~yt.visualization.plot_modifications.ArrowCallback
@@ -817,7 +766,6 @@
See also :ref:`colormaps`.
.. autosummary::
- :toctree: generated/
~yt.visualization.color_maps.add_cmap
~yt.visualization.color_maps.make_colormap
@@ -828,7 +776,6 @@
.. autosummary::
- :toctree: generated/
~yt.convenience.load
~yt.frontends.ytdata.utilities.save_as_dataset
@@ -864,7 +811,6 @@
.. autosummary::
- :toctree: generated/
~yt.utilities.math_utils.periodic_position
~yt.utilities.math_utils.periodic_dist
@@ -899,7 +845,6 @@
.. autosummary::
- :toctree: generated/
~yt.config.YTConfigParser
~yt.utilities.parameter_file_storage.ParameterFileStore
@@ -913,7 +858,6 @@
--------------------
.. autosummary::
- :toctree: generated/
~yt.utilities.cosmology.Cosmology
~yt.utilities.cosmology.Cosmology.hubble_distance
@@ -937,7 +881,6 @@
The first set of functions are all provided by NumPy.
.. autosummary::
- :toctree: generated/
~yt.testing.assert_array_equal
~yt.testing.assert_almost_equal
@@ -953,7 +896,6 @@
These are yt-provided functions:
.. autosummary::
- :toctree: generated/
~yt.testing.assert_rel_equal
~yt.testing.amrspace
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 doc/source/visualizing/callbacks.rst
--- a/doc/source/visualizing/callbacks.rst
+++ b/doc/source/visualizing/callbacks.rst
@@ -433,7 +433,7 @@
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. function:: annotate_particles(self, width, p_size=1.0, col='k', marker='o',\
- stride=1.0, ptype=None, minimum_mass=None, \
+ stride=1, ptype='all', minimum_mass=None, \
alpha=1.0)
(This is a proxy for
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 scripts/pr_backport.py
--- a/scripts/pr_backport.py
+++ b/scripts/pr_backport.py
@@ -40,19 +40,19 @@
"""
with hglib.open(repo_path) as client:
tags = client.log("reverse(tag())")
- tags = sorted([LooseVersion(t[2]) for t in tags])
+ tags = [t[2].decode('utf8') for t in tags]
+ tags = sorted([t for t in tags if t[:2] == 'yt'])
for t in tags[::-1]:
- if t.version[0:2] != ['yt', '-']:
- continue
- if len(t.version) == 4 or t.version[4] == 0:
+ ver = LooseVersion(t)
+ if len(ver.version) == 4 or ver.version[4] == 0:
last_major_tag = t
break
last_before_release = client.log(
"last(ancestors(%s) and branch(yt))" % str(last_major_tag))
+ rev = last_before_release[0][1].decode()
first_after_release = client.log(
- "first(descendants(%s) and branch(yt) and not %s)"
- % (last_before_release[0][1], last_before_release[0][1]))
- return str(first_after_release[0][1][:12])
+ "first(descendants(%s) and branch(yt) and not %s)" % (rev, rev))
+ return first_after_release[0][1][:12].decode('utf8')
def get_branch_tip(repo_path, branch, exclude=None):
@@ -65,7 +65,7 @@
revset += "and not %s" % exclude
except hglib.error.CommandError:
pass
- change = client.log(revset)[0][1][:12]
+ change = client.log(revset)[0][1][:12].decode('utf8')
return change
@@ -153,7 +153,7 @@
"""
for pr in prs[::-1]:
if pr['merge_commit'] is not None:
- if pr['merge_commit']['hash'] == needle[1][:12]:
+ if pr['merge_commit']['hash'] == needle[1][:12].decode('utf8'):
return pr
return None
@@ -167,8 +167,8 @@
my_prs = list(prs)
commit_data = cache_commit_data(my_prs)
for commit in lineage:
- cset_hash = commit[1]
- message = commit[5]
+ cset_hash = commit[1].decode('utf8')
+ message = commit[5].decode('utf8')
if message.startswith('Merged in') and '(pull request #' in message:
pr = find_merge_commit_in_prs(commit, my_prs)
if pr is None:
@@ -186,7 +186,7 @@
def invert_commits_to_prs_mapping(commits_to_prs):
"""invert the mapping from individual commits to pull requests"""
inv_map = {}
- for k, v in commits_to_prs.iteritems():
+ for k, v in commits_to_prs.items():
# can't save v itself in inv_map since it's an unhashable dictionary
if v is not None:
created_date = v['created_on'].split('.')[0]
@@ -210,14 +210,18 @@
def screen_already_backported(repo_path, inv_map):
with hglib.open(repo_path) as client:
tags = client.log("reverse(tag())")
- major_tags = [t for t in tags if t[2].endswith('.0')]
- most_recent_major_tag_name = major_tags[0][2]
+ tags = [t[2].decode('utf8') for t in tags]
+ tags = [LooseVersion(t) for t in tags if t.startswith('yt')]
+ major_tags = [
+ t for t in tags if len(t.version) == 4 or t.version[-1] == 0]
+ most_recent_major_tag_name = major_tags[0].vstring
lineage = client.log(
"descendants(%s) and branch(stable)" % most_recent_major_tag_name)
prs_to_screen = []
for pr in inv_map:
for commit in lineage:
- if commit[5].startswith('Backporting PR #%s' % pr[0]):
+ desc = commit[5].decode('utf8')
+ if desc.startswith('Backporting PR #%s' % pr[0]):
prs_to_screen.append(pr)
for pr in prs_to_screen:
del inv_map[pr]
@@ -227,6 +231,7 @@
with hglib.open(repo_path) as client:
commit_info = client.log(commit)[0]
most_recent_tag_name = client.log("reverse(tag())")[0][2]
+ most_recent_tag_name = most_recent_tag_name.decode('utf8')
lineage = client.log(
"descendants(%s) and branch(stable)" % most_recent_tag_name)
# if there is a stable commit with the same commit message,
@@ -263,7 +268,7 @@
revset = '"%s"' % revset
message = "Backporting PR #%s %s" % \
(pr['id'], pr['links']['html']['href'])
- dest = get_last_descendant(repo_path, last_stable)
+ dest = get_last_descendant(repo_path, last_stable).decode('utf8')
message = \
"hg rebase -r %s --keep --collapse -m \"%s\" -d %s\n" % \
(revset, message, dest)
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/analysis_modules/halo_analysis/halo_catalog.py
--- a/yt/analysis_modules/halo_analysis/halo_catalog.py
+++ b/yt/analysis_modules/halo_analysis/halo_catalog.py
@@ -72,11 +72,11 @@
--------
>>> # create profiles or overdensity vs. radius for each halo and save to disk
- >>> from yt.mods import *
+ >>> import yt
>>> from yt.analysis_modules.halo_analysis.api import *
- >>> data_ds = load("DD0064/DD0064")
- >>> halos_ds = load("rockstar_halos/halos_64.0.bin",
- ... output_dir="halo_catalogs/catalog_0064")
+ >>> data_ds = yt.load("DD0064/DD0064")
+ >>> halos_ds = yt.load("rockstar_halos/halos_64.0.bin",
+ ... output_dir="halo_catalogs/catalog_0064")
>>> hc = HaloCatalog(data_ds=data_ds, halos_ds=halos_ds)
>>> # filter out halos with mass < 1e13 Msun
>>> hc.add_filter("quantity_value", "particle_mass", ">", 1e13, "Msun")
@@ -91,7 +91,7 @@
>>> hc.create()
>>> # load in the saved halo catalog and all the profile data
- >>> halos_ds = load("halo_catalogs/catalog_0064/catalog_0064.0.h5")
+ >>> halos_ds = yt.load("halo_catalogs/catalog_0064/catalog_0064.0.h5")
>>> hc = HaloCatalog(halos_ds=halos_ds,
output_dir="halo_catalogs/catalog_0064")
>>> hc.add_callback("load_profiles", output_dir="profiles")
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/analysis_modules/halo_finding/halo_objects.py
--- a/yt/analysis_modules/halo_finding/halo_objects.py
+++ b/yt/analysis_modules/halo_finding/halo_objects.py
@@ -708,12 +708,12 @@
-------
tuple : (cm, mag_A, mag_B, mag_C, e0_vector, tilt)
The 6-tuple has in order:
- #. The center of mass as an array.
- #. mag_A as a float.
- #. mag_B as a float.
- #. mag_C as a float.
- #. e0_vector as an array.
- #. tilt as a float.
+ #. The center of mass as an array.
+ #. mag_A as a float.
+ #. mag_B as a float.
+ #. mag_C as a float.
+ #. e0_vector as an array.
+ #. tilt as a float.
Examples
--------
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/analysis_modules/halo_finding/hop/EnzoHop.c
--- a/yt/analysis_modules/halo_finding/hop/EnzoHop.c
+++ b/yt/analysis_modules/halo_finding/hop/EnzoHop.c
@@ -27,6 +27,9 @@
#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
#endif
+void PrepareKD(KD kd);
+int kdMedianJst(KD kd, int d, int l, int u);
+void kdUpPass(KD kd, int iCell);
void initgrouplist(Grouplist *g);
void hop_main(KD kd, HC *my_comm, float densthres);
void regroup_main(float dens_outer, HC *my_comm);
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/analysis_modules/halo_finding/rockstar/rockstar_groupies.pyx
--- a/yt/analysis_modules/halo_finding/rockstar/rockstar_groupies.pyx
+++ b/yt/analysis_modules/halo_finding/rockstar/rockstar_groupies.pyx
@@ -2,14 +2,11 @@
import os, sys
cimport numpy as np
cimport cython
+from cython cimport floating
#from cpython.mem cimport PyMem_Malloc
from libc.stdlib cimport malloc, free
import sys
-ctypedef fused anyfloat:
- np.float32_t
- np.float64_t
-
# Importing relevant rockstar data types particle, fof halo, halo
cdef import from "particle.h":
@@ -366,8 +363,8 @@
@cython.wraparound(False)
def make_rockstar_fof(self, np.ndarray[np.int64_t, ndim=1] pind,
np.ndarray[np.int64_t, ndim=1] fof_tags,
- np.ndarray[anyfloat, ndim=2] pos,
- np.ndarray[anyfloat, ndim=2] vel):
+ np.ndarray[floating, ndim=2] pos,
+ np.ndarray[floating, ndim=2] vel):
verbose = False
# Define fof object
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/analysis_modules/halo_mass_function/halo_mass_function.py
--- a/yt/analysis_modules/halo_mass_function/halo_mass_function.py
+++ b/yt/analysis_modules/halo_mass_function/halo_mass_function.py
@@ -327,22 +327,22 @@
def sigmaM(self):
"""
- Written by BWO, 2006 (updated 25 January 2007).
- Converted to Python by Stephen Skory December 2009.
+ Written by BWO, 2006 (updated 25 January 2007).
+ Converted to Python by Stephen Skory December 2009.
- This routine takes in cosmological parameters and creates a file (array) with
- sigma(M) in it, which is necessary for various press-schechter type
- stuff. In principle one can calculate it ahead of time, but it's far,
- far faster in the long run to calculate your sigma(M) ahead of time.
+ This routine takes in cosmological parameters and creates a file (array) with
+ sigma(M) in it, which is necessary for various press-schechter type
+ stuff. In principle one can calculate it ahead of time, but it's far,
+ far faster in the long run to calculate your sigma(M) ahead of time.
- Inputs: cosmology, user must set parameters
+ Inputs: cosmology, user must set parameters
- Outputs: four columns of data containing the following information:
+ Outputs: four columns of data containing the following information:
- 1) mass (Msolar/h)
- 2) sigma (normalized) using Msun/h as the input
-
- The arrays output are used later.
+ 1) mass (Msolar/h)
+ 2) sigma (normalized) using Msun/h as the input
+
+ The arrays output are used later.
"""
# Set up the transfer function object.
@@ -446,13 +446,12 @@
def sigma_squared_of_R(self, R):
"""
- /* calculates sigma^2(R). This is the routine where the magic happens (or
- whatever it is that we do here). Integrates the sigma_squared_integrand
- parameter from R to infinity. Calls GSL (gnu scientific library) to do
- the actual integration.
+ calculates sigma^2(R). This is the routine where the magic happens (or
+ whatever it is that we do here). Integrates the sigma_squared_integrand
+ parameter from R to infinity. Calls GSL (gnu scientific library) to do
+ the actual integration.
- Note that R is in h^-1 Mpc (comoving)
- */
+ Note that R is in h^-1 Mpc (comoving)
"""
self.R = R
result = integrate_inf(self.sigma_squared_integrand)
@@ -463,7 +462,7 @@
def sigma_squared_integrand(self, k):
"""
- /* integrand for integral to get sigma^2(R). */
+ integrand for integral to get sigma^2(R).
"""
Rcom = self.R; # this is R in comoving Mpc/h
@@ -474,7 +473,7 @@
def PofK(self, k):
"""
- /* returns power spectrum as a function of wavenumber k */
+ returns power spectrum as a function of wavenumber k
"""
thisPofK = np.power(k, self.primordial_index) * np.power( self.TofK(k), 2.0);
@@ -483,7 +482,7 @@
def TofK(self, k):
"""
- /* returns transfer function as a function of wavenumber k. */
+ returns transfer function as a function of wavenumber k.
"""
thisTofK = self.TF.TFmdm_onek_hmpc(k);
@@ -503,9 +502,9 @@
def multiplicityfunction(self, sigma):
"""
- /* Multiplicity function - this is where the various fitting functions/analytic
+ Multiplicity function - this is where the various fitting functions/analytic
theories are different. The various places where I found these fitting functions
- are listed below. */
+ are listed below.
"""
nu = self.delta_c0 / sigma;
@@ -552,7 +551,7 @@
def sigmaof_M_z(self, sigmabin, redshift):
"""
- /* sigma(M, z) */
+ sigma(M, z)
"""
thissigma = self.Dofz(redshift) * self.sigmaarray[sigmabin];
@@ -561,7 +560,7 @@
def Dofz(self, redshift):
"""
- /* Growth function */
+ Growth function
"""
thisDofz = self.gofz(redshift) / self.gofz(0.0) / (1.0+redshift);
@@ -571,7 +570,7 @@
def gofz(self, redshift):
"""
- /* g(z) - I don't think this has any other name*/
+ g(z) - I don't think this has any other name
"""
thisgofz = 2.5 * self.omega_matter_of_z(redshift) / \
@@ -585,7 +584,7 @@
def omega_matter_of_z(self,redshift):
"""
- /* Omega matter as a function of redshift */
+ Omega matter as a function of redshift
"""
thisomofz = self.omega_matter0 * math.pow( 1.0+redshift, 3.0) / \
@@ -595,7 +594,7 @@
def omega_lambda_of_z(self,redshift):
"""
- /* Omega lambda as a function of redshift */
+ Omega lambda as a function of redshift
"""
thisolofz = self.omega_lambda0 / math.pow( self.Eofz(redshift), 2.0 )
@@ -604,7 +603,7 @@
def Eofz(self, redshift):
"""
- /* E(z) - I don't think this has any other name */
+ E(z) - I don't think this has any other name
"""
thiseofz = math.sqrt( self.omega_lambda0 \
+ (1.0 - self.omega_lambda0 - self.omega_matter0)*math.pow( 1.0+redshift, 2.0) \
@@ -614,15 +613,15 @@
"""
-/* Fitting Formulae for CDM + Baryon + Massive Neutrino (MDM) cosmologies. */
-/* Daniel J. Eisenstein & Wayne Hu, Institute for Advanced Study */
+Fitting Formulae for CDM + Baryon + Massive Neutrino (MDM) cosmologies.
+Daniel J. Eisenstein & Wayne Hu, Institute for Advanced Study
-/* There are two primary routines here, one to set the cosmology, the
+There are two primary routines here, one to set the cosmology, the
other to construct the transfer function for a single wavenumber k.
You should call the former once (per cosmology) and the latter as
-many times as you want. */
+many times as you want.
-/* TFmdm_set_cosm() -- User passes all the cosmological parameters as
+ TFmdm_set_cosm() -- User passes all the cosmological parameters as
arguments; the routine sets up all of the scalar quantites needed
computation of the fitting formula. The input parameters are:
1) omega_matter -- Density of CDM, baryons, and massive neutrinos,
@@ -634,7 +633,7 @@
6) hubble -- Hubble constant, in units of 100 km/s/Mpc
7) redshift -- The redshift at which to evaluate */
-/* TFmdm_onek_mpc() -- User passes a single wavenumber, in units of Mpc^-1.
+ TFmdm_onek_mpc() -- User passes a single wavenumber, in units of Mpc^-1.
Routine returns the transfer function from the Eisenstein & Hu
fitting formula, based on the cosmology currently held in the
internal variables. The routine returns T_cb (the CDM+Baryon
@@ -642,29 +641,40 @@
Baryon+Neutrino density-weighted transfer function) is stored
in the global variable tf_cbnu. */
-/* We also supply TFmdm_onek_hmpc(), which is identical to the previous
- routine, but takes the wavenumber in units of h Mpc^-1. */
+We also supply TFmdm_onek_hmpc(), which is identical to the previous
+routine, but takes the wavenumber in units of h Mpc^-1.
-/* We hold the internal scalar quantities in global variables, so that
-the user may access them in an external program, via "extern" declarations. */
+We hold the internal scalar quantities in global variables, so that
+the user may access them in an external program, via "extern" declarations.
-/* Please note that all internal length scales are in Mpc, not h^-1 Mpc! */
+Please note that all internal length scales are in Mpc, not h^-1 Mpc!
"""
class TransferFunction(object):
"""
- /* This routine takes cosmological parameters and a redshift and sets up
- all the internal scalar quantities needed to compute the transfer function. */
- /* INPUT: omega_matter -- Density of CDM, baryons, and massive neutrinos,
- in units of the critical density. */
- /* omega_baryon -- Density of baryons, in units of critical. */
- /* omega_hdm -- Density of massive neutrinos, in units of critical */
- /* degen_hdm -- (Int) Number of degenerate massive neutrino species */
- /* omega_lambda -- Cosmological constant */
- /* hubble -- Hubble constant, in units of 100 km/s/Mpc */
- /* redshift -- The redshift at which to evaluate */
- /* OUTPUT: Returns 0 if all is well, 1 if a warning was issued. Otherwise,
- sets many global variables for use in TFmdm_onek_mpc() */
+ This routine takes cosmological parameters and a redshift and sets up
+ all the internal scalar quantities needed to compute the transfer function.
+
+ Parameters
+ ----------
+ omega_matter : float
+ Density of CDM, baryons, and massive neutrinos, in units
+ of the critical density.
+ omega_baryon : float
+ Density of baryons, in units of critical.
+ omega_hdm : float
+ Density of massive neutrinos, in units of critical
+ degen_hdm : integer
+ Number of degenerate massive neutrino species
+ omega_lambda : float
+ Cosmological constant
+ hubble : float
+ Hubble constant, in units of 100 km/s/Mpc
+ redshift : float
+ The redshift at which to evaluate
+
+ Returns 0 if all is well, 1 if a warning was issued. Otherwise,
+ sets many global variables for use in TFmdm_onek_mpc()
"""
def __init__(self, omega_matter, omega_baryon, omega_hdm,
degen_hdm, omega_lambda, hubble, redshift):
@@ -751,15 +761,23 @@
def TFmdm_onek_mpc(self, kk):
"""
- /* Given a wavenumber in Mpc^-1, return the transfer function for the
- cosmology held in the global variables. */
- /* Input: kk -- Wavenumber in Mpc^-1 */
- /* Output: The following are set as global variables:
- growth_cb -- the transfer function for density-weighted
- CDM + Baryon perturbations.
- growth_cbnu -- the transfer function for density-weighted
- CDM + Baryon + Massive Neutrino perturbations. */
- /* The function returns growth_cb */
+ Given a wavenumber in Mpc^-1, return the transfer function for the
+ cosmology held in the global variables.
+
+ Parameters
+ ----------
+ kk : float
+ Wavenumber in Mpc^-1
+
+ Returns
+ -------
+ growth_cb : float
+ the transfer function for density-weighted
+ CDM + Baryon perturbations. (returned and set as a global var)
+ growth_cbnu : float
+ the transfer function for density-weighted
+ CDM + Baryon + Massive Neutrino perturbations.
+ (set as a global var)
"""
self.qq = kk/self.omhh*SQR(self.theta_cmb);
@@ -794,15 +812,22 @@
def TFmdm_onek_hmpc(self, kk):
"""
- /* Given a wavenumber in h Mpc^-1, return the transfer function for the
- cosmology held in the global variables. */
- /* Input: kk -- Wavenumber in h Mpc^-1 */
- /* Output: The following are set as global variables:
- growth_cb -- the transfer function for density-weighted
- CDM + Baryon perturbations.
- growth_cbnu -- the transfer function for density-weighted
- CDM + Baryon + Massive Neutrino perturbations. */
- /* The function returns growth_cb */
+ Given a wavenumber in h Mpc^-1, return the transfer function for the
+ cosmology held in the global variables.
+
+ Parameters
+ ----------
+ kk : float
+ Wavenumber in h Mpc^-1
+
+ Returns
+ -------
+ growth_cb : float
+ the transfer function for density-weighted
+ CDM + Baryon perturbations. (return and set as a global var)
+ growth_cbnu : float
+ the transfer function for density-weighted
+ CDM + Baryon + Massive Neutrino perturbations.
"""
return self.TFmdm_onek_mpc(kk*self.hhubble);
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/analysis_modules/sunyaev_zeldovich/projection.py
--- a/yt/analysis_modules/sunyaev_zeldovich/projection.py
+++ b/yt/analysis_modules/sunyaev_zeldovich/projection.py
@@ -78,7 +78,7 @@
Parameters
----------
- ds : Dataset
+ ds : ~yt.data_objects.static_output.Dataset
The dataset
freqs : array_like
The frequencies (in GHz) at which to compute the SZ spectral distortion.
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -1957,7 +1957,7 @@
multiple data objects.
This object is not designed to be created directly; it is designed to be
- created implicitly by using one of the bitwise operations (&, |, ^, ~) on
+ created implicitly by using one of the bitwise operations (&, \|, ^, \~) on
one or two other data objects. These correspond to the appropriate boolean
operations, and the resultant object can be nested.
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/data_objects/static_output.py
--- a/yt/data_objects/static_output.py
+++ b/yt/data_objects/static_output.py
@@ -194,6 +194,8 @@
self.data = weakref.WeakKeyDictionary()
def __get__(self, instance, owner):
+ if not instance:
+ return None
ret = self.data.get(instance, None)
try:
ret = ret.copy()
@@ -1056,7 +1058,7 @@
Parameters
----------
- input_array : iterable
+ input_array : Iterable
A tuple, list, or array to attach units to
input_units : String unit specification, unit symbol or astropy object
The units of the array. Powers must be specified using python syntax
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/fields/species_fields.py
--- a/yt/fields/species_fields.py
+++ b/yt/fields/species_fields.py
@@ -126,8 +126,8 @@
"""
This takes a field registry, a fluid type, and two species names.
The first species name is one you wish to alias to an existing species
- name. For instance you might alias all "H_p0" fields to "H_" fields
- to indicate that "H_" fields are really just neutral hydrogen fields.
+ name. For instance you might alias all "H_p0" fields to "H\_" fields
+ to indicate that "H\_" fields are really just neutral hydrogen fields.
This function registers field aliases for the density, number_density,
mass, and fraction fields between the two species given in the arguments.
"""
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/fields/xray_emission_fields.py
--- a/yt/fields/xray_emission_fields.py
+++ b/yt/fields/xray_emission_fields.py
@@ -72,7 +72,7 @@
Parameters
----------
- table_type: string
+ table_type : string
The type of data to use when computing the emissivity values. If "cloudy",
a file called "cloudy_emissivity.h5" is used, for photoionized
plasmas. If, "apec", a file called "apec_emissivity.h5" is used for
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/frontends/boxlib/data_structures.py
--- a/yt/frontends/boxlib/data_structures.py
+++ b/yt/frontends/boxlib/data_structures.py
@@ -405,8 +405,8 @@
periodicity = (True, True, True)
def __init__(self, output_dir,
- cparam_filename="inputs",
- fparam_filename="probin",
+ cparam_filename=None,
+ fparam_filename=None,
dataset_type='boxlib_native',
storage_filename=None,
units_override=None,
@@ -459,6 +459,8 @@
return False
args = inspect.getcallargs(cls.__init__, args, kwargs)
# This might need to be localized somehow
+ if args['cparam_filename'] is None:
+ return True # Treat as generic boxlib data
inputs_filename = os.path.join(
os.path.dirname(os.path.abspath(output_dir)),
args['cparam_filename'])
@@ -820,7 +822,7 @@
if any(("castro." in line for line in lines)): return False
if any(("nyx." in line for line in lines)): return False
if any(("maestro" in line.lower() for line in lines)): return False
- if any(("geometry.prob_lo" in line for line in lines)): return True
+ if any(("hyp." in line for line in lines)): return True
return False
@@ -848,6 +850,22 @@
_index_class = CastroHierarchy
_field_info_class = CastroFieldInfo
+ def __init__(self, output_dir,
+ cparam_filename='inputs',
+ fparam_filename='probin',
+ dataset_type='boxlib_native',
+ storage_filename=None,
+ units_override=None,
+ unit_system="cgs"):
+
+ super(CastroDataset, self).__init__(output_dir,
+ cparam_filename,
+ fparam_filename,
+ dataset_type,
+ storage_filename,
+ units_override,
+ unit_system)
+
@classmethod
def _is_valid(cls, *args, **kwargs):
# fill our args
@@ -916,6 +934,22 @@
_field_info_class = MaestroFieldInfo
+ def __init__(self, output_dir,
+ cparam_filename='inputs',
+ fparam_filename='probin',
+ dataset_type='boxlib_native',
+ storage_filename=None,
+ units_override=None,
+ unit_system="cgs"):
+
+ super(MaestroDataset, self).__init__(output_dir,
+ cparam_filename,
+ fparam_filename,
+ dataset_type,
+ storage_filename,
+ units_override,
+ unit_system)
+
@classmethod
def _is_valid(cls, *args, **kwargs):
# fill our args
@@ -993,6 +1027,22 @@
_index_class = NyxHierarchy
_field_info_class = NyxFieldInfo
+ def __init__(self, output_dir,
+ cparam_filename='inputs',
+ fparam_filename='probin',
+ dataset_type='boxlib_native',
+ storage_filename=None,
+ units_override=None,
+ unit_system="cgs"):
+
+ super(NyxDataset, self).__init__(output_dir,
+ cparam_filename,
+ fparam_filename,
+ dataset_type,
+ storage_filename,
+ units_override,
+ unit_system)
+
@classmethod
def _is_valid(cls, *args, **kwargs):
# fill our args
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/frontends/boxlib/io.py
--- a/yt/frontends/boxlib/io.py
+++ b/yt/frontends/boxlib/io.py
@@ -126,7 +126,11 @@
rdata = np.fromfile(f, pheader.real_type, pheader.num_real * npart)
x = np.asarray(rdata[0::pheader.num_real], dtype=np.float64)
y = np.asarray(rdata[1::pheader.num_real], dtype=np.float64)
- z = np.asarray(rdata[2::pheader.num_real], dtype=np.float64)
+ if (grid.ds.dimensionality == 2):
+ z = np.ones_like(y)
+ z *= 0.5*(grid.LeftEdge[2] + grid.RightEdge[2])
+ else:
+ z = np.asarray(rdata[2::pheader.num_real], dtype=np.float64)
mask = selector.select_points(x, y, z, 0.0)
if mask is None:
@@ -150,7 +154,11 @@
rdata = np.fromfile(f, pheader.real_type, pheader.num_real * npart)
x = np.asarray(rdata[0::pheader.num_real], dtype=np.float64)
y = np.asarray(rdata[1::pheader.num_real], dtype=np.float64)
- z = np.asarray(rdata[2::pheader.num_real], dtype=np.float64)
+ if (grid.ds.dimensionality == 2):
+ z = np.ones_like(y)
+ z *= 0.5*(grid.LeftEdge[2] + grid.RightEdge[2])
+ else:
+ z = np.asarray(rdata[2::pheader.num_real], dtype=np.float64)
mask = selector.select_points(x, y, z, 0.0)
if mask is None:
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/frontends/chombo/io.py
--- a/yt/frontends/chombo/io.py
+++ b/yt/frontends/chombo/io.py
@@ -199,11 +199,9 @@
def parse_orion_sinks(fn):
'''
-
Orion sink particles are stored in text files. This function
is for figuring what particle fields are present based on the
- number of entries per line in the *.sink file.
-
+ number of entries per line in the \*.sink file.
'''
# Figure out the format of the particle file
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/frontends/exodus_ii/data_structures.py
--- a/yt/frontends/exodus_ii/data_structures.py
+++ b/yt/frontends/exodus_ii/data_structures.py
@@ -180,18 +180,18 @@
def _parse_parameter_file(self):
self._handle = NetCDF4FileHandler(self.parameter_filename)
- self._vars = self._handle.dataset.variables
- self._read_glo_var()
- self.dimensionality = self._vars['coor_names'].shape[0]
- self.parameters['info_records'] = self._load_info_records()
- self.unique_identifier = self._get_unique_identifier()
- self.num_steps = len(self._vars['time_whole'])
- self.current_time = self._get_current_time()
- self.parameters['num_meshes'] = self._vars['eb_status'].shape[0]
- self.parameters['elem_names'] = self._get_elem_names()
- self.parameters['nod_names'] = self._get_nod_names()
- self.domain_left_edge, self.domain_right_edge = self._load_domain_edge()
- self.periodicity = (False, False, False)
+ with self._handle.open_ds() as ds:
+ self._read_glo_var()
+ self.dimensionality = ds.variables['coor_names'].shape[0]
+ self.parameters['info_records'] = self._load_info_records()
+ self.unique_identifier = self._get_unique_identifier()
+ self.num_steps = len(ds.variables['time_whole'])
+ self.current_time = self._get_current_time()
+ self.parameters['num_meshes'] = ds.variables['eb_status'].shape[0]
+ self.parameters['elem_names'] = self._get_elem_names()
+ self.parameters['nod_names'] = self._get_nod_names()
+ self.domain_left_edge, self.domain_right_edge = self._load_domain_edge()
+ self.periodicity = (False, False, False)
# These attributes don't really make sense for unstructured
# mesh data, but yt warns if they are not present, so we set
@@ -205,18 +205,18 @@
self.refine_by = 0
def _get_fluid_types(self):
- handle = NetCDF4FileHandler(self.parameter_filename).dataset
- fluid_types = ()
- i = 1
- while True:
- ftype = 'connect%d' % i
- if ftype in handle.variables:
- fluid_types += (ftype,)
- i += 1
- else:
- break
- fluid_types += ('all',)
- return fluid_types
+ with NetCDF4FileHandler(self.parameter_filename).open_ds() as ds:
+ fluid_types = ()
+ i = 1
+ while True:
+ ftype = 'connect%d' % i
+ if ftype in ds.variables:
+ fluid_types += (ftype,)
+ i += 1
+ else:
+ break
+ fluid_types += ('all',)
+ return fluid_types
def _read_glo_var(self):
"""
@@ -226,31 +226,34 @@
names = self._get_glo_names()
if not names:
return
- values = self._vars['vals_glo_var'][:].transpose()
- for name, value in zip(names, values):
- self.parameters[name] = value
+ with self._handle.open_ds() as ds:
+ values = ds.variables['vals_glo_var'][:].transpose()
+ for name, value in zip(names, values):
+ self.parameters[name] = value
def _load_info_records(self):
"""
Returns parsed version of the info_records.
"""
- try:
- return load_info_records(self._vars['info_records'])
- except (KeyError, TypeError):
- mylog.warning("No info_records found")
- return []
+ with self._handle.open_ds() as ds:
+ try:
+ return load_info_records(ds.variables['info_records'])
+ except (KeyError, TypeError):
+ mylog.warning("No info_records found")
+ return []
def _get_unique_identifier(self):
return self.parameter_filename
def _get_current_time(self):
- try:
- return self._vars['time_whole'][self.step]
- except IndexError:
- raise RuntimeError("Invalid step number, max is %d" \
- % (self.num_steps - 1))
- except (KeyError, TypeError):
- return 0.0
+ with self._handle.open_ds() as ds:
+ try:
+ return ds.variables['time_whole'][self.step]
+ except IndexError:
+ raise RuntimeError("Invalid step number, max is %d" \
+ % (self.num_steps - 1))
+ except (KeyError, TypeError):
+ return 0.0
def _get_glo_names(self):
"""
@@ -259,12 +262,13 @@
"""
- if "name_glo_var" not in self._vars:
- mylog.warning("name_glo_var not found")
- return []
- else:
- return [sanitize_string(v.tostring()) for v in
- self._vars["name_glo_var"]]
+ with self._handle.open_ds() as ds:
+ if "name_glo_var" not in ds.variables:
+ mylog.warning("name_glo_var not found")
+ return []
+ else:
+ return [sanitize_string(v.tostring()) for v in
+ ds.variables["name_glo_var"]]
def _get_elem_names(self):
"""
@@ -273,12 +277,13 @@
"""
- if "name_elem_var" not in self._vars:
- mylog.warning("name_elem_var not found")
- return []
- else:
- return [sanitize_string(v.tostring()) for v in
- self._vars["name_elem_var"]]
+ with self._handle.open_ds() as ds:
+ if "name_elem_var" not in ds.variables:
+ mylog.warning("name_elem_var not found")
+ return []
+ else:
+ return [sanitize_string(v.tostring()) for v in
+ ds.variables["name_elem_var"]]
def _get_nod_names(self):
"""
@@ -287,12 +292,13 @@
"""
- if "name_nod_var" not in self._vars:
- mylog.warning("name_nod_var not found")
- return []
- else:
- return [sanitize_string(v.tostring()) for v in
- self._vars["name_nod_var"]]
+ with self._handle.open_ds() as ds:
+ if "name_nod_var" not in ds.variables:
+ mylog.warning("name_nod_var not found")
+ return []
+ else:
+ return [sanitize_string(v.tostring()) for v in
+ ds.variables["name_nod_var"]]
def _read_coordinates(self):
"""
@@ -304,13 +310,14 @@
coord_axes = 'xyz'[:self.dimensionality]
mylog.info("Loading coordinates")
- if "coord" not in self._vars:
- coords = np.array([self._vars["coord%s" % ax][:]
- for ax in coord_axes]).transpose().copy()
- else:
- coords = np.array([coord for coord in
- self._vars["coord"][:]]).transpose().copy()
- return coords
+ with self._handle.open_ds() as ds:
+ if "coord" not in ds.variables:
+ coords = np.array([ds.variables["coord%s" % ax][:]
+ for ax in coord_axes]).transpose().copy()
+ else:
+ coords = np.array([coord for coord in
+ ds.variables["coord"][:]]).transpose().copy()
+ return coords
def _apply_displacement(self, coords, mesh_id):
@@ -324,13 +331,14 @@
offset = self.displacements[mesh_name][1]
coord_axes = 'xyz'[:self.dimensionality]
- for i, ax in enumerate(coord_axes):
- if "disp_%s" % ax in self.parameters['nod_names']:
- ind = self.parameters['nod_names'].index("disp_%s" % ax)
- disp = self._vars['vals_nod_var%d' % (ind + 1)][self.step]
- new_coords[:, i] = coords[:, i] + fac*disp + offset[i]
+ with self._handle.open_ds() as ds:
+ for i, ax in enumerate(coord_axes):
+ if "disp_%s" % ax in self.parameters['nod_names']:
+ ind = self.parameters['nod_names'].index("disp_%s" % ax)
+ disp = ds.variables['vals_nod_var%d' % (ind + 1)][self.step]
+ new_coords[:, i] = coords[:, i] + fac*disp + offset[i]
- return new_coords
+ return new_coords
def _read_connectivity(self):
"""
@@ -338,9 +346,10 @@
"""
mylog.info("Loading connectivity")
connectivity = []
- for i in range(self.parameters['num_meshes']):
- connectivity.append(self._vars["connect%d" % (i+1)][:].astype("i8"))
- return connectivity
+ with self._handle.open_ds() as ds:
+ for i in range(self.parameters['num_meshes']):
+ connectivity.append(ds.variables["connect%d" % (i+1)][:].astype("i8"))
+ return connectivity
def _load_domain_edge(self):
"""
@@ -373,7 +382,7 @@
for i in range(self.dimensionality, 3):
mi[i] = 0.0
ma[i] = 1.0
-
+
return mi, ma
@classmethod
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/frontends/exodus_ii/io.py
--- a/yt/frontends/exodus_ii/io.py
+++ b/yt/frontends/exodus_ii/io.py
@@ -28,7 +28,7 @@
def __init__(self, ds):
self.filename = ds.index_filename
exodus_ii_handler = NetCDF4FileHandler(self.filename)
- self.handler = exodus_ii_handler.dataset
+ self.handler = exodus_ii_handler
super(IOHandlerExodusII, self).__init__(ds)
self.node_fields = ds._get_nod_names()
self.elem_fields = ds._get_elem_names()
@@ -46,46 +46,47 @@
# dict gets returned at the end and it should be flat, with selected
# data. Note that if you're reading grid data, you might need to
# special-case a grid selector object.
- chunks = list(chunks)
- rv = {}
- for field in fields:
- ftype, fname = field
- if ftype == "all":
- ci = np.concatenate([mesh.connectivity_indices - self._INDEX_OFFSET \
- for mesh in self.ds.index.mesh_union])
- else:
- ci = self.handler.variables[ftype][:] - self._INDEX_OFFSET
- num_elem = ci.shape[0]
- if fname in self.node_fields:
- nodes_per_element = ci.shape[1]
- rv[field] = np.zeros((num_elem, nodes_per_element), dtype="float64")
- elif fname in self.elem_fields:
- rv[field] = np.zeros(num_elem, dtype="float64")
- for field in fields:
- ind = 0
- ftype, fname = field
- if ftype == "all":
- mesh_ids = [mesh.mesh_id + 1 for mesh in self.ds.index.mesh_union]
- objs = [mesh for mesh in self.ds.index.mesh_union]
- else:
- mesh_ids = [int(ftype[-1])]
- chunk = chunks[mesh_ids[0] - 1]
- objs = chunk.objs
- if fname in self.node_fields:
- field_ind = self.node_fields.index(fname)
- fdata = self.handler.variables['vals_nod_var%d' % (field_ind + 1)]
- for g in objs:
- ci = g.connectivity_indices - self._INDEX_OFFSET
- data = fdata[self.ds.step][ci]
- ind += g.select(selector, data, rv[field], ind) # caches
- if fname in self.elem_fields:
- field_ind = self.elem_fields.index(fname)
- for g, mesh_id in zip(objs, mesh_ids):
- fdata = self.handler.variables['vals_elem_var%deb%s' %
- (field_ind + 1, mesh_id)][:]
- data = fdata[self.ds.step, :]
- ind += g.select(selector, data, rv[field], ind) # caches
- return rv
+ with self.handler.open_ds() as ds:
+ chunks = list(chunks)
+ rv = {}
+ for field in fields:
+ ftype, fname = field
+ if ftype == "all":
+ ci = np.concatenate([mesh.connectivity_indices - self._INDEX_OFFSET \
+ for mesh in self.ds.index.mesh_union])
+ else:
+ ci = ds.variables[ftype][:] - self._INDEX_OFFSET
+ num_elem = ci.shape[0]
+ if fname in self.node_fields:
+ nodes_per_element = ci.shape[1]
+ rv[field] = np.zeros((num_elem, nodes_per_element), dtype="float64")
+ elif fname in self.elem_fields:
+ rv[field] = np.zeros(num_elem, dtype="float64")
+ for field in fields:
+ ind = 0
+ ftype, fname = field
+ if ftype == "all":
+ mesh_ids = [mesh.mesh_id + 1 for mesh in self.ds.index.mesh_union]
+ objs = [mesh for mesh in self.ds.index.mesh_union]
+ else:
+ mesh_ids = [int(ftype[-1])]
+ chunk = chunks[mesh_ids[0] - 1]
+ objs = chunk.objs
+ if fname in self.node_fields:
+ field_ind = self.node_fields.index(fname)
+ fdata = ds.variables['vals_nod_var%d' % (field_ind + 1)]
+ for g in objs:
+ ci = g.connectivity_indices - self._INDEX_OFFSET
+ data = fdata[self.ds.step][ci]
+ ind += g.select(selector, data, rv[field], ind) # caches
+ if fname in self.elem_fields:
+ field_ind = self.elem_fields.index(fname)
+ for g, mesh_id in zip(objs, mesh_ids):
+ fdata = ds.variables['vals_elem_var%deb%s' %
+ (field_ind + 1, mesh_id)][:]
+ data = fdata[self.ds.step, :]
+ ind += g.select(selector, data, rv[field], ind) # caches
+ return rv
def _read_chunk_data(self, chunk, fields):
# This reads the data from a single chunk, and is only used for
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/frontends/exodus_ii/simulation_handling.py
--- a/yt/frontends/exodus_ii/simulation_handling.py
+++ b/yt/frontends/exodus_ii/simulation_handling.py
@@ -14,7 +14,6 @@
from yt.data_objects.time_series import \
DatasetSeries, \
RegisteredSimulationTimeSeries
-from yt.frontends.exodus_ii.api import ExodusIIDataset
@add_metaclass(RegisteredSimulationTimeSeries)
@@ -45,6 +44,25 @@
self.all_outputs = self._check_for_outputs(potential_outputs)
self.all_outputs.sort(key=lambda obj: obj["filename"])
+ def __iter__(self):
+ for o in self._pre_outputs:
+ fn, step = o
+ ds = load(fn, step=step)
+ self._setup_function(ds)
+ yield ds
+
+ def __getitem__(self, key):
+ if isinstance(key, slice):
+ if isinstance(key.start, float):
+ return self.get_range(key.start, key.stop)
+ # This will return a sliced up object!
+ return DatasetSeries(self._pre_outputs[key], self.parallel)
+ o = self._pre_outputs[key]
+ fn, step = o
+ o = load(fn, step=step)
+ self._setup_function(o)
+ return o
+
def get_time_series(self, parallel=False, setup_function=None):
r"""
Instantiate a DatasetSeries object for a set of outputs.
@@ -55,15 +73,14 @@
Fine-level filtering is currently not implemented.
"""
-
+
all_outputs = self.all_outputs
ds_list = []
for output in all_outputs:
num_steps = output['num_steps']
fn = output['filename']
for step in range(num_steps):
- ds = ExodusIIDataset(fn, step=step)
- ds_list.append(ds)
+ ds_list.append((fn, step))
super(ExodusIISimulation, self).__init__(ds_list,
parallel=parallel,
setup_function=setup_function)
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/frontends/fits/misc.py
--- a/yt/frontends/fits/misc.py
+++ b/yt/frontends/fits/misc.py
@@ -49,7 +49,7 @@
Parameters
----------
- ds : Dataset
+ ds : `~yt.data_objects.static_output.Dataset`
The FITS events file dataset to add the counts fields to.
ebounds : list of tuples
A list of tuples, one for each field, with (emin, emax) as the
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/frontends/gadget/fields.py
--- a/yt/frontends/gadget/fields.py
+++ b/yt/frontends/gadget/fields.py
@@ -83,8 +83,11 @@
# Assume cosmic abundances
x_H = 0.76
gamma = 5.0/3.0
- # Assume zero ionization
- mu = 4.0 / (3.0 * x_H + 1.0)
+ if data.has_field_parameter("mean_molecular_weight"):
+ mu = data.get_field_parameter("mean_molecular_weight")
+ else:
+ # Assume zero ionization
+ mu = 4.0 / (3.0 * x_H + 1.0)
ret = data[ptype, "InternalEnergy"]*(gamma-1)*mu*mp/kb
return ret.in_units(self.ds.unit_system["temperature"])
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/frontends/gamer/data_structures.py
--- a/yt/frontends/gamer/data_structures.py
+++ b/yt/frontends/gamer/data_structures.py
@@ -126,12 +126,12 @@
son_list = self._handle["Tree/Son"].value
for gid in range(self.num_grids):
- grid = self.grids.flat[gid]
+ grid = self.grids[gid]
son_gid0 = son_list[gid]
# set up the parent-children relationship
if son_gid0 >= 0:
- grid.Children = [ self.grids.flat[son_gid0+s] for s in range(8) ]
+ grid.Children = [ self.grids[son_gid0+s] for s in range(8) ]
for son_grid in grid.Children: son_grid.Parent = grid
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/frontends/sdf/data_structures.py
--- a/yt/frontends/sdf/data_structures.py
+++ b/yt/frontends/sdf/data_structures.py
@@ -78,7 +78,7 @@
unit_system="cgs"):
if bounding_box is not None:
self._subspace = True
- bbox = np.array(bounding_box, dtype="float32")
+ bbox = np.array(bounding_box, dtype="float64")
if bbox.shape == (2, 3):
bbox = bbox.transpose()
self.domain_left_edge = bbox[:,0]
@@ -121,8 +121,7 @@
except:
self.unique_identifier = time.time()
-
- if None in (self.domain_left_edge, self.domain_right_edge):
+ if self.domain_left_edge is None or self.domain_right_edge is None:
R0 = self.parameters['R0']
if 'offset_center' in self.parameters and self.parameters['offset_center']:
self.domain_left_edge = np.array([0, 0, 0], dtype=np.float64)
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/frontends/stream/data_structures.py
--- a/yt/frontends/stream/data_structures.py
+++ b/yt/frontends/stream/data_structures.py
@@ -903,7 +903,7 @@
Parameters
----------
- base_ds : Dataset
+ base_ds : `~yt.data_objects.static_output.Dataset`
This is any static output. It can also be a stream static output, for
instance as returned by load_uniform_data.
refinement_critera : list of :class:`~yt.utilities.flagging_methods.FlaggingMethod`
@@ -1167,7 +1167,7 @@
r"""Define the cell coordinates and cell neighbors of a hexahedral mesh
for a semistructured grid. Used to specify the connectivity and
coordinates parameters used in
- :function:`~yt.frontends.stream.data_structures.load_hexahedral_mesh`.
+ :func:`~yt.frontends.stream.data_structures.load_hexahedral_mesh`.
Parameters
----------
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/frontends/ytdata/data_structures.py
--- a/yt/frontends/ytdata/data_structures.py
+++ b/yt/frontends/ytdata/data_structures.py
@@ -275,7 +275,7 @@
# since this is now particle-like data.
data_type = self.parameters.get("data_type")
container_type = self.parameters.get("container_type")
- ex_container_type = ["cutting", "proj", "ray", "slice"]
+ ex_container_type = ["cutting", "proj", "ray", "slice", "cut_region"]
if data_type == "yt_light_ray" or container_type in ex_container_type:
mylog.info("Returning an all_data data container.")
return self.all_data()
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/frontends/ytdata/tests/test_outputs.py
--- a/yt/frontends/ytdata/tests/test_outputs.py
+++ b/yt/frontends/ytdata/tests/test_outputs.py
@@ -100,6 +100,12 @@
assert isinstance(sphere_ds, YTDataContainerDataset)
yield YTDataFieldTest(full_fn, ("grid", "density"))
yield YTDataFieldTest(full_fn, ("all", "particle_mass"))
+ cr = ds.cut_region(sphere, ['obj["temperature"] > 1e4'])
+ fn = cr.save_as_dataset(fields=["temperature"])
+ full_fn = os.path.join(tmpdir, fn)
+ cr_ds = load(full_fn)
+ assert isinstance(cr_ds, YTDataContainerDataset)
+ assert (cr["temperature"] == cr_ds.data["temperature"]).all()
os.chdir(curdir)
shutil.rmtree(tmpdir)
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/frontends/ytdata/utilities.py
--- a/yt/frontends/ytdata/utilities.py
+++ b/yt/frontends/ytdata/utilities.py
@@ -239,4 +239,9 @@
val = np.array(val)
if val.dtype.kind == 'U':
val = val.astype('|S')
- fh.attrs[str(attr)] = val
+ try:
+ fh.attrs[str(attr)] = val
+ # This is raised if no HDF5 equivalent exists.
+ # In that case, save its string representation.
+ except TypeError:
+ fh.attrs[str(attr)] = str(val)
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/funcs.py
--- a/yt/funcs.py
+++ b/yt/funcs.py
@@ -400,7 +400,8 @@
maxval = max(maxval, 1)
from yt.config import ytcfg
if ytcfg.getboolean("yt", "suppressStreamLogging") or \
- ytcfg.getboolean("yt", "__withintesting"):
+ ytcfg.getboolean("yt", "__withintesting") or \
+ maxval == 1: \
return DummyProgressBar()
elif ytcfg.getboolean("yt", "__parallel"):
# If parallel is True, update progress on root only.
@@ -746,6 +747,7 @@
With a name provided by the user, this will decide how to
appropriately name the output file by the following rules:
+
1. if name is None, the filename will be the keyword plus
the suffix.
2. if name ends with "/", assume name is a directory and
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/geometry/oct_container.pyx
--- a/yt/geometry/oct_container.pyx
+++ b/yt/geometry/oct_container.pyx
@@ -744,7 +744,7 @@
self.visit_all_octs(selector, visitor)
assert ((visitor.global_index+1)*visitor.nz == visitor.index)
-cdef int root_node_compare(void *a, void *b) nogil:
+cdef int root_node_compare(const void *a, const void *b) nogil:
cdef OctKey *ao
cdef OctKey *bo
ao = <OctKey *>a
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/geometry/particle_oct_container.pyx
--- a/yt/geometry/particle_oct_container.pyx
+++ b/yt/geometry/particle_oct_container.pyx
@@ -23,6 +23,7 @@
import numpy as np
from selection_routines cimport SelectorObject
cimport cython
+from cython cimport floating
cdef class ParticleOctreeContainer(OctreeContainer):
cdef Oct** oct_list
@@ -261,10 +262,6 @@
self.visit(o.children[cind(i,j,k)], counts, level + 1)
return
-ctypedef fused anyfloat:
- np.float32_t
- np.float64_t
-
cdef np.uint64_t ONEBIT=1
cdef class ParticleRegions:
@@ -299,7 +296,7 @@
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
- cdef void _mask_positions(self, np.ndarray[anyfloat, ndim=2] pos,
+ cdef void _mask_positions(self, np.ndarray[floating, ndim=2] pos,
np.uint64_t file_id, int filter):
# TODO: Replace with the bitarray
cdef np.int64_t no = pos.shape[0]
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/geometry/selection_routines.pxd
--- a/yt/geometry/selection_routines.pxd
+++ b/yt/geometry/selection_routines.pxd
@@ -19,10 +19,6 @@
from grid_visitors cimport GridTreeNode, GridVisitorData, \
grid_visitor_function, check_child_masked
-ctypedef fused anyfloat:
- np.float32_t
- np.float64_t
-
cdef inline _ensure_code(arr):
if hasattr(arr, "units"):
if "code_length" == str(arr.units):
diff -r 153dfc60f6e2dbd910865b3d5034df037fd8da65 -r 83eae35d29c676e9380ccf1429a2c85542333387 yt/geometry/selection_routines.pyx
--- a/yt/geometry/selection_routines.pyx
+++ b/yt/geometry/selection_routines.pyx
@@ -17,6 +17,7 @@
import numpy as np
cimport numpy as np
cimport cython
+from cython cimport floating
from libc.stdlib cimport malloc, free
from yt.utilities.lib.fp_utils cimport fclip, iclip, fmax, fmin, imin, imax
from .oct_container cimport OctreeContainer, Oct
@@ -96,7 +97,7 @@
cdef _mask_fill(np.ndarray[np.float64_t, ndim=1] out,
np.int64_t offset,
np.ndarray[np.uint8_t, ndim=3, cast=True] mask,
- np.ndarray[anyfloat, ndim=3] vals):
+ np.ndarray[floating, ndim=3] vals):
cdef np.int64_t count = 0
cdef int i, j, k
for i in range(mask.shape[0]):
@@ -550,9 +551,9 @@
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
- def count_points(self, np.ndarray[anyfloat, ndim=1] x,
- np.ndarray[anyfloat, ndim=1] y,
- np.ndarray[anyfloat, ndim=1] z,
+ def count_points(self, np.ndarray[floating, ndim=1] x,
+ np.ndarray[floating, ndim=1] y,
+ np.ndarray[floating, ndim=1] z,
np.float64_t radius):
cdef int count = 0
cdef int i
@@ -578,9 +579,9 @@
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
- def select_points(self, np.ndarray[anyfloat, ndim=1] x,
- np.ndarray[anyfloat, ndim=1] y,
- np.ndarray[anyfloat, ndim=1] z,
+ def select_points(self, np.ndarray[floating, ndim=1] x,
+ np.ndarray[floating, ndim=1] y,
+ np.ndarray[floating, ndim=1] z,
np.float64_t radius):
cdef int count = 0
cdef int i
This diff is so big that we needed to truncate the remainder.
https://bitbucket.org/yt_analysis/yt/commits/add68b583bb1/
Changeset: add68b583bb1
Branch: yt
User: al007
Date: 2017-03-17 23:17:43+00:00
Summary: Demonstrate quad9 support with line plot.
Affected #: 1 file
diff -r 83eae35d29c676e9380ccf1429a2c85542333387 -r add68b583bb1f40f49f724237fe658ee0769a978 yt/utilities/lib/pixelization_routines.pyx
--- a/yt/utilities/lib/pixelization_routines.pyx
+++ b/yt/utilities/lib/pixelization_routines.pyx
@@ -745,6 +745,8 @@
sampler = P1Sampler1D()
elif ndim == 2 and nvertices == 4:
sampler = Q1Sampler2D()
+ elif ndim == 2 and nvertices == 9:
+ sampler = Q2Sampler2D()
elif ndim == 2 and nvertices == 6:
sampler = T2Sampler2D()
elif ndim == 3 and nvertices == 10:
https://bitbucket.org/yt_analysis/yt/commits/8ee92ca7654f/
Changeset: 8ee92ca7654f
Branch: yt
User: al007
Date: 2017-04-04 16:59:15+00:00
Summary: Merge in yt-tip.
Affected #: 38 files
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a doc/Makefile
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -33,23 +33,24 @@
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " clean to remove the build directory"
- @echo " fullclean to remove the build directory and autogenerated api docs"
@echo " recipeclean to remove files produced by running the cookbook scripts"
clean:
-rm -rf $(BUILDDIR)/*
+ -rm -rf source/reference/api/yt.*
+ -rm -rf source/reference/api/modules.rst
-fullclean:
- -rm -rf $(BUILDDIR)/*
- -rm -rf source/reference/api/generated
+fullclean: clean
recipeclean:
-rm -rf _temp/*.done source/cookbook/_static/*
html:
- sphinx-apidoc -o source/reference/api/ -e ../yt ../yt/extern/* \
- $(shell find ../yt -name "*tests*" -type d) ../yt/utilities/voropp*
- sed -e '/show-inheritance/ a\ \ \ \ :inherited-members:' -i source/reference/api/yt*.rst
+ifneq ($(READTHEDOCS),True)
+ SPHINX_APIDOC_OPTIONS=members,undoc-members,inherited-members,show-inheritance sphinx-apidoc \
+ -o source/reference/api/ \
+ -e ../yt ../yt/extern/* $(shell find ../yt -name "*tests*" -type d) ../yt/utilities/voropp*
+endif
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a doc/source/analyzing/analysis_modules/star_analysis.rst
--- a/doc/source/analyzing/analysis_modules/star_analysis.rst
+++ b/doc/source/analyzing/analysis_modules/star_analysis.rst
@@ -209,8 +209,8 @@
There are two ways to write out the data once the spectrum has been calculated.
The command ``write_out`` outputs two columns of data:
- 1. Wavelength :math:`(\text{\AA})`
- 2. Flux (Luminosity per unit wavelength :math:`(\mathrm{\rm{L}_\odot} / \text{\AA})` , where
+ 1. Wavelength (:math:`\text{Angstroms}`)
+ 2. Flux (Luminosity per unit wavelength :math:`(\mathrm{\rm{L}_\odot} / \text{Angstrom})` , where
:math:`\mathrm{\rm{L}_\odot} = 3.826 \cdot 10^{33}\, \mathrm{ergs / s}` ).
and can be called simply, specifying the output file:
@@ -225,7 +225,7 @@
distribution to. The default is 5200 Angstroms. This command outputs the data
in two columns:
- 1. Wavelength :math:`(\text{\AA})`
+ 1. Wavelength :math:`(\text{Angstroms})`
2. Relative flux normalized to the flux at *flux_norm*.
.. code-block:: python
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a doc/source/conf.py
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -11,9 +11,9 @@
# All configuration values have a default; values that are commented out
# serve to show the default.
-import sys, os, glob, re
-from sphinx.search import WordCollector
-from docutils.nodes import comment, title, Text, SkipNode
+import sys
+import os
+import glob
on_rtd = os.environ.get("READTHEDOCS", None) == "True"
@@ -30,7 +30,7 @@
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx',
- 'sphinx.ext.pngmath', 'sphinx.ext.viewcode',
+ 'sphinx.ext.mathjax', 'sphinx.ext.viewcode',
'sphinx.ext.napoleon', 'yt_cookbook', 'yt_colormaps',
'config_help']
@@ -228,13 +228,6 @@
# If true, show URL addresses after external links.
#latex_show_urls = False
-# Additional stuff for the LaTeX preamble.
-latex_preamble = r"""
-\renewcommand{\AA}{\text{\r{A}}} % Allow \AA in math mode
-\usepackage[utf8]{inputenc} % Allow unicode symbols in text
-\DeclareUnicodeCharacter {212B} {\AA} % Angstrom
-"""
-
# Documents to append as an appendix to all manuals.
#latex_appendices = []
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a doc/source/help/index.rst
--- a/doc/source/help/index.rst
+++ b/doc/source/help/index.rst
@@ -72,8 +72,8 @@
$ yt --help
-If you continue to see errors, you should try contacting us via IRC or email
-but you may have to reinstall yt (see :ref:`getting-and-installing-yt`).
+If you continue to see errors, you should try contacting us via Slack, IRC or
+email but you may have to reinstall yt (see :ref:`getting-and-installing-yt`).
.. _search-the-documentation:
@@ -170,17 +170,24 @@
.. _irc:
-Go on IRC to ask a question
----------------------------
+Go on Slack or IRC to ask a question
+------------------------------------
+
+If you want a fast, interactive experience, you could try jumping into our Slack
+or IRC channels to get your questions answered in a chatroom style environment.
-If you want a fast, interactive experience, you could try jumping into our IRC
-channel to get your questions answered in a chatroom style environment. You
-don't even need to have any special IRC client in order to join. We are the
-#yt channel on irc.freenode.net, but you can also connect using your web
-browser by going to http://yt-project.org/irc.html . There are usually 2-8
-members of the user base and development team online, so you'll probably get
-your answers quickly. Remember to bring the information from the
-:ref:`last step <isolate_and_document>`.
+To join our slack channel you will need to request an invite by going to
+http://yt-project.org/development.html, click the "Join as @ Slack!" button, and
+fill out the form. You will get an invite as soon as an administrator approves
+your request.
+
+Alternatively you can go to our IRC channel, which does not require an
+invite. You don't even need to have any special IRC client in order to join the
+IRC channel. We are the #yt channel on irc.freenode.net, but you can also
+connect using your web browser by going to http://yt-project.org/irc.html .
+There are usually 2-8 members of the user base and development team online, so
+you'll probably get your answers quickly. Remember to bring the information
+from the :ref:`last step <isolate_and_document>`.
.. _mailing-list:
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a doc/source/installing.rst
--- a/doc/source/installing.rst
+++ b/doc/source/installing.rst
@@ -270,7 +270,7 @@
.. code-block:: bash
- $ conda install yt
+ $ conda install -c conda-forge yt
which will install stable branch of yt along with all of its dependencies.
@@ -284,7 +284,7 @@
.. code-block:: bash
- $ conda install -c http://use.yt/with_conda/ yt
+ $ conda install -c http://use.yt/with_conda/ -c conda-forge yt
New packages for development branch are built after every pull request is
merged. In order to make sure you are running latest version, it's recommended
@@ -292,7 +292,12 @@
.. code-block:: bash
- $ conda update -c http://use.yt/with_conda/ yt
+ $ conda update -c http://use.yt/with_conda/ -c conda-forge yt
+
+We recommend trying to install dependencies from conda-forge as indicated above
+since focused individual communities stand a better chance of successfully
+maintaining build recipes. However, if you wish to use the default anaconda
+packages, simply remove ``-c conda-forge`` during conda installation.
Location of our channel can be added to ``.condarc`` to avoid retyping it during
each *conda* invocation. Please refer to `Conda Manual
@@ -309,7 +314,7 @@
.. code-block:: bash
- $ conda install cython mercurial sympy ipython matplotlib
+ $ conda install -c conda-forge cython mercurial sympy ipython matplotlib netCDF4
In addition, you will need a C compiler installed.
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a setup.cfg
--- a/setup.cfg
+++ b/setup.cfg
@@ -15,4 +15,4 @@
# vendored libraries
exclude = doc,benchmarks,*/api.py,*/__init__.py,*/__config__.py,yt/visualization/_mpl_imports.py,yt/utilities/lodgeit.py,yt/utilities/lru_cache.py,yt/utilities/poster/*,yt/extern/*,yt/mods.py,yt/utilities/fits_image.py
max-line-length=999
-ignore = E111,E121,E122,E123,E124,E125,E126,E127,E128,E129,E131,E201,E202,E211,E221,E222,E227,E228,E241,E301,E203,E225,E226,E231,E251,E261,E262,E265,E266,E302,E303,E402,E502,E701,E703,E731,W291,W292,W293,W391,W503
\ No newline at end of file
+ignore = E111,E121,E122,E123,E124,E125,E126,E127,E128,E129,E131,E201,E202,E211,E221,E222,E227,E228,E241,E301,E203,E225,E226,E231,E251,E261,E262,E265,E266,E302,E303,E305,E306,E402,E502,E701,E703,E731,W291,W292,W293,W391,W503
\ No newline at end of file
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a tests/nose_runner.py
--- a/tests/nose_runner.py
+++ b/tests/nose_runner.py
@@ -28,12 +28,17 @@
result = next_task()
self.task_queue.task_done()
self.result_queue.put(result)
+ if next_task.exclusive:
+ print("%s: Exiting (exclusive)" % proc_name)
+ break
return
class NoseTask(object):
- def __init__(self, argv):
+ def __init__(self, job):
+ argv, exclusive = job
self.argv = argv
self.name = argv[0]
+ self.exclusive = exclusive
def __call__(self):
old_stderr = sys.stderr
@@ -69,12 +74,12 @@
if DROP_TAG not in line])
tests = yaml.load(data)
- base_argv = ['--local-dir=%s' % answers_dir,
+ base_argv = ['--local-dir=%s' % answers_dir, '-s', '--nologcapture',
'--with-answer-testing', '--answer-big-data', '--local']
args = []
for test in list(tests["other_tests"].keys()):
- args.append([test] + tests["other_tests"][test])
+ args.append(([test] + tests["other_tests"][test], True))
for answer in list(tests["answer_tests"].keys()):
if tests["answer_tests"][answer] is None:
continue
@@ -82,10 +87,10 @@
argv += base_argv
argv.append('--answer-name=%s' % argv[0])
argv += tests["answer_tests"][answer]
- args.append(argv)
+ args.append((argv, False))
- args = [item + ['-s', '--nologcapture', '--xunit-file=%s.xml' % item[0]]
- for item in args]
+ args = [(item + ['--xunit-file=%s.xml' % item[0]], exclusive)
+ for item, exclusive in args]
return args
if __name__ == "__main__":
@@ -93,13 +98,15 @@
tasks = multiprocessing.JoinableQueue()
results = multiprocessing.Queue()
- num_consumers = 6 # TODO
+ num_consumers = int(os.environ.get('NUM_WORKERS', 6))
consumers = [NoseWorker(tasks, results) for i in range(num_consumers)]
for w in consumers:
w.start()
num_jobs = 0
for job in generate_tasks_input():
+ if job[1]:
+ num_consumers -= 1 # take into account exclusive jobs
tasks.put(NoseTask(job))
num_jobs += 1
@@ -110,5 +117,4 @@
while num_jobs:
result = results.get()
- print(result)
num_jobs -= 1
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a tests/tests.yaml
--- a/tests/tests.yaml
+++ b/tests/tests.yaml
@@ -42,7 +42,7 @@
local_owls_001:
- yt/frontends/owls/tests/test_outputs.py
- local_pw_012:
+ local_pw_013:
- yt/visualization/tests/test_plotwindow.py:test_attributes
- yt/visualization/tests/test_plotwindow.py:test_attributes_wt
- yt/visualization/tests/test_profile_plots.py:test_phase_plot_attributes
@@ -63,9 +63,10 @@
- yt/analysis_modules/photon_simulator/tests/test_spectra.py
- yt/analysis_modules/photon_simulator/tests/test_sloshing.py
- local_unstructured_002:
+ local_unstructured_005:
- yt/visualization/volume_rendering/tests/test_mesh_render.py
- yt/visualization/tests/test_mesh_slices.py:test_tri2
+ - yt/visualization/tests/test_mesh_slices.py:test_quad2
- yt/visualization/tests/test_mesh_slices.py:test_multi_region
local_boxlib_003:
@@ -77,7 +78,7 @@
- yt/frontends/boxlib/tests/test_outputs.py:test_RT_particles
- yt/frontends/boxlib/tests/test_outputs.py:test_units_override
- local_boxlib_particles_002:
+ local_boxlib_particles_003:
- yt/frontends/boxlib/tests/test_outputs.py:test_LyA
- yt/frontends/boxlib/tests/test_outputs.py:test_nyx_particle_io
- yt/frontends/boxlib/tests/test_outputs.py:test_castro_particle_io
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/data_objects/profiles.py
--- a/yt/data_objects/profiles.py
+++ b/yt/data_objects/profiles.py
@@ -708,7 +708,7 @@
self.GridDimensions,
cell_size)
- locs = storage.values[:, :, fi] > 0.0
+ locs = storage.values[:, :, fi] != 0.0
storage.used[locs] = True
if self.weight_field is not None:
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/data_objects/static_output.py
--- a/yt/data_objects/static_output.py
+++ b/yt/data_objects/static_output.py
@@ -567,6 +567,7 @@
self.field_dependencies.update(deps)
self.fields = FieldTypeContainer(self)
self.index.field_list = sorted(self.field_list)
+ self._last_freq = (None, None)
def setup_deprecated_fields(self):
from yt.fields.field_aliases import _field_name_aliases
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/data_objects/tests/test_covering_grid.py
--- a/yt/data_objects/tests/test_covering_grid.py
+++ b/yt/data_objects/tests/test_covering_grid.py
@@ -111,7 +111,18 @@
obj = ds.arbitrary_grid(LE, RE, dims)
deposited_mass = obj["deposit", "all_density"].sum() * volume
- yield assert_equal, deposited_mass, ds.quan(1.0, 'g')
+ assert_equal(deposited_mass, ds.quan(1.0, 'g'))
+
+ LE = np.array([0.00, 0.00, 0.00])
+ RE = np.array([0.05, 0.05, 0.05])
+ dims = np.array([ncells, ncells, ncells])
+
+ obj = ds.arbitrary_grid(LE, RE, dims)
+
+ deposited_mass = obj["deposit", "all_density"].sum()
+
+ assert_equal(deposited_mass, 0)
+
# Test that we get identical results to the covering grid for unigrid data.
# Testing AMR data is much harder.
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/data_objects/tests/test_profiles.py
--- a/yt/data_objects/tests/test_profiles.py
+++ b/yt/data_objects/tests/test_profiles.py
@@ -1,3 +1,4 @@
+import yt
import numpy as np
from yt.data_objects.profiles import \
@@ -195,3 +196,28 @@
assert_raises(
YTIllDefinedProfile, PhasePlot, ad, 'particle_radius', 'particle_mass',
'particle_ones')
+
+def test_particle_profile_negative_field():
+ # see Issue #1340
+ n_particles = int(1e4)
+
+ ppx, ppy, ppz = np.random.normal(size=[3, n_particles])
+ pvx, pvy, pvz = - np.ones((3, n_particles))
+
+ data = {'particle_position_x': ppx,
+ 'particle_position_y': ppy,
+ 'particle_position_z': ppz,
+ 'particle_velocity_x': pvx,
+ 'particle_velocity_y': pvy,
+ 'particle_velocity_z': pvz}
+
+ bbox = 1.1*np.array([[min(ppx), max(ppx)], [min(ppy), max(ppy)], [min(ppz), max(ppz)]])
+ ds = yt.load_particles(data, bbox=bbox)
+ ad = ds.all_data()
+
+ profile = yt.create_profile(
+ ad,
+ ["particle_position_x", "particle_position_y"],
+ "particle_velocity_x",
+ weight_field=None)
+ assert profile['particle_velocity_x'].min() < 0
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/fields/tests/test_fields.py
--- a/yt/fields/tests/test_fields.py
+++ b/yt/fields/tests/test_fields.py
@@ -317,3 +317,11 @@
a1 = np.argsort(mi)
a2 = np.argsort(mi2)
assert_array_equal(a1, a2)
+
+
+def test_field_inference():
+ ds = fake_random_ds(16)
+ ds.index
+ # If this is not true this means the result of field inference depends
+ # on the order we did field detection, which is random in Python3
+ assert_equal(ds._last_freq, (None, None))
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/frontends/boxlib/data_structures.py
--- a/yt/frontends/boxlib/data_structures.py
+++ b/yt/frontends/boxlib/data_structures.py
@@ -139,7 +139,193 @@
startIndex[2]:endIndex[2]] = tofill
+class BoxLibParticleHeader(object):
+
+ def __init__(self, ds, directory_name, is_checkpoint,
+ extra_field_names=None):
+
+ self.particle_type = directory_name
+ header_filename = ds.output_dir + "/" + directory_name + "/Header"
+ with open(header_filename, "r") as f:
+ self.version_string = f.readline().strip()
+
+ particle_real_type = self.version_string.split('_')[-1]
+ particle_real_type = self.version_string.split('_')[-1]
+ if particle_real_type == 'double':
+ self.real_type = np.float64
+ elif particle_real_type == 'single':
+ self.real_type = np.float32
+ else:
+ raise RuntimeError("yt did not recognize particle real type.")
+ self.int_type = np.int32
+
+ self.dim = int(f.readline().strip())
+ self.num_int_base = 2 + self.dim
+ self.num_real_base = self.dim
+ self.num_int_extra = 0 # this should be written by Boxlib, but isn't
+ self.num_real_extra = int(f.readline().strip())
+ self.num_int = self.num_int_base + self.num_int_extra
+ self.num_real = self.num_real_base + self.num_real_extra
+ self.num_particles = int(f.readline().strip())
+ self.max_next_id = int(f.readline().strip())
+ self.finest_level = int(f.readline().strip())
+ self.num_levels = self.finest_level + 1
+
+ # Boxlib particles can be written in checkpoint or plotfile mode
+ # The base integer fields are only there for checkpoints, but some
+ # codes use the checkpoint format for plotting
+ if not is_checkpoint:
+ self.num_int_base = 0
+ self.num_int_extra = 0
+ self.num_int = 0
+
+ self.grids_per_level = np.zeros(self.num_levels, dtype='int64')
+ self.data_map = {}
+ for level_num in range(self.num_levels):
+ self.grids_per_level[level_num] = int(f.readline().strip())
+ self.data_map[level_num] = {}
+
+ pfd = namedtuple("ParticleFileDescriptor",
+ ["file_number", "num_particles", "offset"])
+
+ for level_num in range(self.num_levels):
+ for grid_num in range(self.grids_per_level[level_num]):
+ entry = [int(val) for val in f.readline().strip().split()]
+ self.data_map[level_num][grid_num] = pfd(*entry)
+
+ self._generate_particle_fields(extra_field_names)
+
+ def _generate_particle_fields(self, extra_field_names):
+
+ # these are the 'base' integer fields
+ self.known_int_fields = [(self.particle_type, "particle_id"),
+ (self.particle_type, "particle_cpu"),
+ (self.particle_type, "particle_cell_x"),
+ (self.particle_type, "particle_cell_y"),
+ (self.particle_type, "particle_cell_z")]
+ self.known_int_fields = self.known_int_fields[0:self.num_int_base]
+
+ # these are extra integer fields
+ extra_int_fields = ["particle_int_comp%d" % i
+ for i in range(self.num_int_extra)]
+ self.known_int_fields.extend([(self.particle_type, field)
+ for field in extra_int_fields])
+
+ # these are the base real fields
+ self.known_real_fields = [(self.particle_type, "particle_position_x"),
+ (self.particle_type, "particle_position_y"),
+ (self.particle_type, "particle_position_z")]
+ self.known_real_fields = self.known_real_fields[0:self.num_real_base]
+
+ # these are the extras
+ if extra_field_names is not None:
+ assert(len(extra_field_names) == self.num_real_extra)
+ else:
+ extra_field_names = ["particle_real_comp%d" % i
+ for i in range(self.num_real_extra)]
+
+ self.known_real_fields.extend([(self.particle_type, field)
+ for field in extra_field_names])
+
+ self.known_fields = self.known_int_fields + self.known_real_fields
+
+ self.particle_int_dtype = np.dtype([(t[1], self.int_type)
+ for t in self.known_int_fields])
+
+ self.particle_real_dtype = np.dtype([(t[1], self.real_type)
+ for t in self.known_real_fields])
+
+
+class AMReXParticleHeader(object):
+
+ def __init__(self, ds, directory_name, is_checkpoint,
+ extra_field_names=None):
+
+ self.particle_type = directory_name
+ header_filename = ds.output_dir + "/" + directory_name + "/Header"
+ self.real_component_names = []
+ self.int_component_names = []
+ with open(header_filename, "r") as f:
+ self.version_string = f.readline().strip()
+
+ particle_real_type = self.version_string.split('_')[-1]
+ particle_real_type = self.version_string.split('_')[-1]
+ if particle_real_type == 'double':
+ self.real_type = np.float64
+ elif particle_real_type == 'single':
+ self.real_type = np.float32
+ else:
+ raise RuntimeError("yt did not recognize particle real type.")
+ self.int_type = np.int32
+
+ self.dim = int(f.readline().strip())
+ self.num_int_base = 2
+ self.num_real_base = self.dim
+ self.num_real_extra = int(f.readline().strip())
+ for i in range(self.num_real_extra):
+ self.real_component_names.append(f.readline().strip())
+ self.num_int_extra = int(f.readline().strip())
+ for i in range(self.num_int_extra):
+ self.int_component_names.append(f.readline().strip())
+ self.num_int = self.num_int_base + self.num_int_extra
+ self.num_real = self.num_real_base + self.num_real_extra
+ self.is_checkpoint = bool(int(f.readline().strip()))
+ self.num_particles = int(f.readline().strip())
+ self.max_next_id = int(f.readline().strip())
+ self.finest_level = int(f.readline().strip())
+ self.num_levels = self.finest_level + 1
+
+ if not self.is_checkpoint:
+ self.num_int_base = 0
+ self.num_int_extra = 0
+ self.num_int = 0
+
+ self.grids_per_level = np.zeros(self.num_levels, dtype='int64')
+ self.data_map = {}
+ for level_num in range(self.num_levels):
+ self.grids_per_level[level_num] = int(f.readline().strip())
+ self.data_map[level_num] = {}
+
+ pfd = namedtuple("ParticleFileDescriptor",
+ ["file_number", "num_particles", "offset"])
+
+ for level_num in range(self.num_levels):
+ for grid_num in range(self.grids_per_level[level_num]):
+ entry = [int(val) for val in f.readline().strip().split()]
+ self.data_map[level_num][grid_num] = pfd(*entry)
+
+ self._generate_particle_fields()
+
+ def _generate_particle_fields(self):
+
+ # these are the 'base' integer fields
+ self.known_int_fields = [(self.particle_type, "particle_id"),
+ (self.particle_type, "particle_cpu")]
+ self.known_int_fields = self.known_int_fields[0:self.num_int_base]
+
+ self.known_int_fields.extend([(self.particle_type, "particle_" + field)
+ for field in self.int_component_names])
+
+ # these are the base real fields
+ self.known_real_fields = [(self.particle_type, "particle_position_x"),
+ (self.particle_type, "particle_position_y"),
+ (self.particle_type, "particle_position_z")]
+ self.known_real_fields = self.known_real_fields[0:self.num_real_base]
+
+ self.known_real_fields.extend([(self.particle_type, "particle_" + field)
+ for field in self.real_component_names])
+
+ self.known_fields = self.known_int_fields + self.known_real_fields
+
+ self.particle_int_dtype = np.dtype([(t[1], self.int_type)
+ for t in self.known_int_fields])
+
+ self.particle_real_dtype = np.dtype([(t[1], self.real_type)
+ for t in self.known_real_fields])
+
+
class BoxlibHierarchy(GridIndex):
+
grid = BoxlibGrid
def __init__(self, ds, dataset_type='boxlib_native'):
@@ -365,12 +551,21 @@
def _setup_data_io(self):
self.io = io_registry[self.dataset_type](self.dataset)
- def _read_particles(self, directory_name, is_checkpoint, extra_field_names=None):
+ def _determine_particle_output_type(self, directory_name):
+ header_filename = self.ds.output_dir + "/" + directory_name + "/Header"
+ with open(header_filename, "r") as f:
+ version_string = f.readline().strip()
+ if version_string.startswith("Version_Two"):
+ return AMReXParticleHeader
+ else:
+ return BoxLibParticleHeader
- self.particle_headers[directory_name] = BoxLibParticleHeader(self.ds,
- directory_name,
- is_checkpoint,
- extra_field_names)
+ def _read_particles(self, directory_name, is_checkpoint, extra_field_names=None):
+ pheader = self._determine_particle_output_type(directory_name)
+ self.particle_headers[directory_name] = pheader(self.ds,
+ directory_name,
+ is_checkpoint,
+ extra_field_names)
base_particle_fn = self.ds.output_dir + '/' + directory_name + "/Level_%d/DATA_%.4d"
@@ -1137,118 +1332,14 @@
return vals
-class BoxLibParticleHeader(object):
-
- def __init__(self, ds, directory_name, is_checkpoint, extra_field_names=None):
-
- self.species_name = directory_name
- header_filename = ds.output_dir + "/" + directory_name + "/Header"
- with open(header_filename, "r") as f:
- self.version_string = f.readline().strip()
-
- particle_real_type = self.version_string.split('_')[-1]
- particle_real_type = self.version_string.split('_')[-1]
- if particle_real_type == 'double':
- self.real_type = np.float64
- elif particle_real_type == 'single':
- self.real_type = np.float32
- else:
- raise RuntimeError("yt did not recognize particle real type.")
- self.int_type = np.int32
-
- self.dim = int(f.readline().strip())
- self.num_int_base = 2 + self.dim
- self.num_real_base = self.dim
- self.num_int_extra = 0 # this should be written by Boxlib, but isn't
- self.num_real_extra = int(f.readline().strip())
- self.num_int = self.num_int_base + self.num_int_extra
- self.num_real = self.num_real_base + self.num_real_extra
- self.num_particles = int(f.readline().strip())
- self.max_next_id = int(f.readline().strip())
- self.finest_level = int(f.readline().strip())
- self.num_levels = self.finest_level + 1
-
- # Boxlib particles can be written in checkpoint or plotfile mode
- # The base integer fields are only there for checkpoints, but some
- # codes use the checkpoint format for plotting
- if not is_checkpoint:
- self.num_int_base = 0
- self.num_int_extra = 0
- self.num_int = 0
-
- self.grids_per_level = np.zeros(self.num_levels, dtype='int64')
- self.data_map = {}
- for level_num in range(self.num_levels):
- self.grids_per_level[level_num] = int(f.readline().strip())
- self.data_map[level_num] = {}
-
- pfd = namedtuple("ParticleFileDescriptor",
- ["file_number", "num_particles", "offset"])
-
- for level_num in range(self.num_levels):
- for grid_num in range(self.grids_per_level[level_num]):
- entry = [int(val) for val in f.readline().strip().split()]
- self.data_map[level_num][grid_num] = pfd(*entry)
-
- self._generate_particle_fields(extra_field_names)
-
- def _generate_particle_fields(self, extra_field_names):
-
- # these are the 'base' integer fields
- self.known_int_fields = [(self.species_name, "particle_id"),
- (self.species_name, "particle_cpu"),
- (self.species_name, "particle_cell_x"),
- (self.species_name, "particle_cell_y"),
- (self.species_name, "particle_cell_z")]
- self.known_int_fields = self.known_int_fields[0:self.num_int_base]
-
- # these are extra integer fields
- extra_int_fields = ["particle_int_comp%d" % i
- for i in range(self.num_int_extra)]
- self.known_int_fields.extend([(self.species_name, field)
- for field in extra_int_fields])
-
- # these are the base real fields
- self.known_real_fields = [(self.species_name, "particle_position_x"),
- (self.species_name, "particle_position_y"),
- (self.species_name, "particle_position_z")]
- self.known_real_fields = self.known_real_fields[0:self.num_real_base]
-
- # these are the extras
- if extra_field_names is not None:
- assert(len(extra_field_names) == self.num_real_extra)
- else:
- extra_field_names = ["particle_real_comp%d" % i
- for i in range(self.num_real_extra)]
-
- self.known_real_fields.extend([(self.species_name, field)
- for field in extra_field_names])
-
- self.known_fields = self.known_int_fields + self.known_real_fields
-
- self.particle_int_dtype = np.dtype([(t[1], self.int_type)
- for t in self.known_int_fields])
-
- self.particle_real_dtype = np.dtype([(t[1], self.real_type)
- for t in self.known_real_fields])
-
-
class WarpXHierarchy(BoxlibHierarchy):
def __init__(self, ds, dataset_type="boxlib_native"):
super(WarpXHierarchy, self).__init__(ds, dataset_type)
- # extra beyond the base real fields that all Boxlib
- # particles have, i.e. the xyz positions
- warpx_extra_real_fields = ['particle_weight',
- 'particle_velocity_x',
- 'particle_velocity_y',
- 'particle_velocity_z']
-
- is_checkpoint = False
-
+ is_checkpoint = True
for ptype in self.ds.particle_types:
- self._read_particles(ptype, is_checkpoint, warpx_extra_real_fields)
+ self._read_particles(ptype, is_checkpoint)
# Additional WarpX particle information (used to set up species)
with open(self.ds.output_dir + "/WarpXHeader", 'r') as f:
@@ -1351,3 +1442,48 @@
setdefaultattr(self, 'mass_unit', self.quan(1.0, "kg"))
setdefaultattr(self, 'time_unit', self.quan(1.0, "s"))
setdefaultattr(self, 'velocity_unit', self.quan(1.0, "m/s"))
+
+
+class AMReXHierarchy(BoxlibHierarchy):
+
+ def __init__(self, ds, dataset_type="boxlib_native"):
+ super(AMReXHierarchy, self).__init__(ds, dataset_type)
+
+ if ("particles" in self.ds.parameters):
+ is_checkpoint = True
+ for ptype in self.ds.particle_types:
+ self._read_particles(ptype, is_checkpoint)
+
+
+class AMReXDataset(BoxlibDataset):
+
+ _index_class = AMReXHierarchy
+
+ def __init__(self, output_dir,
+ cparam_filename=None,
+ fparam_filename=None,
+ dataset_type='boxlib_native',
+ storage_filename=None,
+ units_override=None,
+ unit_system="cgs"):
+
+ super(AMReXDataset, self).__init__(output_dir,
+ cparam_filename,
+ fparam_filename,
+ dataset_type,
+ storage_filename,
+ units_override,
+ unit_system)
+
+ def _parse_parameter_file(self):
+ super(AMReXDataset, self)._parse_parameter_file()
+ particle_types = glob.glob(self.output_dir + "/*/Header")
+ particle_types = [cpt.split("/")[-2] for cpt in particle_types]
+ if len(particle_types) > 0:
+ self.parameters["particles"] = 1
+ self.particle_types = tuple(particle_types)
+ self.particle_types_raw = self.particle_types
+
+ @classmethod
+ def _is_valid(cls, *args, **kwargs):
+ return False
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/frontends/boxlib/tests/test_outputs.py
--- a/yt/frontends/boxlib/tests/test_outputs.py
+++ b/yt/frontends/boxlib/tests/test_outputs.py
@@ -144,22 +144,22 @@
assert(np.all(np.logical_and(reg['particle_position_y'] <= right_edge[1],
reg['particle_position_y'] >= left_edge[1])))
-langmuir = "LangmuirWave/plt00020"
+langmuir = "LangmuirWave/plt00020_v2"
@requires_ds(langmuir)
def test_langmuir():
ds = data_dir_load(langmuir)
- yield assert_equal, str(ds), "plt00020"
+ yield assert_equal, str(ds), "plt00020_v2"
for test in small_patch_amr(ds, _warpx_fields,
input_center="c",
input_weight="Ex"):
test_langmuir.__name__ = test.description
yield test
-plasma = "PlasmaAcceleration/plt00030"
+plasma = "PlasmaAcceleration/plt00030_v2"
@requires_ds(plasma)
def test_plasma():
ds = data_dir_load(plasma)
- yield assert_equal, str(ds), "plt00030"
+ yield assert_equal, str(ds), "plt00030_v2"
for test in small_patch_amr(ds, _warpx_fields,
input_center="c",
input_weight="Ex"):
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/frontends/chombo/data_structures.py
--- a/yt/frontends/chombo/data_structures.py
+++ b/yt/frontends/chombo/data_structures.py
@@ -34,7 +34,8 @@
from yt.data_objects.static_output import \
Dataset
from yt.utilities.file_handler import \
- HDF5FileHandler
+ HDF5FileHandler, \
+ warn_h5py
from yt.utilities.parallel_tools.parallel_analysis_interface import \
parallel_root_only
from yt.utilities.lib.misc_utilities import \
@@ -730,6 +731,8 @@
@classmethod
def _is_valid(self, *args, **kwargs):
+ warn_h5py(args[0])
+
if not is_chombo_hdf5(args[0]):
return False
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/frontends/exodus_ii/data_structures.py
--- a/yt/frontends/exodus_ii/data_structures.py
+++ b/yt/frontends/exodus_ii/data_structures.py
@@ -23,8 +23,9 @@
from yt.data_objects.static_output import \
Dataset
from yt.data_objects.unions import MeshUnion
-from .io import \
- NetCDF4FileHandler
+from yt.utilities.file_handler import \
+ NetCDF4FileHandler, \
+ warn_netcdf
from yt.utilities.logger import ytLogger as mylog
from .fields import \
ExodusIIFieldInfo
@@ -387,6 +388,7 @@
@classmethod
def _is_valid(self, *args, **kwargs):
+ warn_netcdf(args[0])
try:
from netCDF4 import Dataset
filename = args[0]
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/frontends/flash/data_structures.py
--- a/yt/frontends/flash/data_structures.py
+++ b/yt/frontends/flash/data_structures.py
@@ -30,7 +30,8 @@
from yt.geometry.particle_geometry_handler import \
ParticleIndex
from yt.utilities.file_handler import \
- HDF5FileHandler
+ HDF5FileHandler, \
+ warn_h5py
from yt.utilities.physical_ratios import cm_per_mpc
from .fields import FLASHFieldInfo
@@ -439,7 +440,7 @@
fileh = HDF5FileHandler(args[0])
if "bounding box" in fileh["/"].keys():
return True
- except:
+ except (IOError, OSError, ImportError):
pass
return False
@@ -489,12 +490,13 @@
@classmethod
def _is_valid(self, *args, **kwargs):
+ warn_h5py(args[0])
try:
fileh = HDF5FileHandler(args[0])
if "bounding box" not in fileh["/"].keys() \
and "localnp" in fileh["/"].keys():
return True
- except IOError:
+ except (IOError, OSError, ImportError):
pass
return False
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/frontends/open_pmd/data_structures.py
--- a/yt/frontends/open_pmd/data_structures.py
+++ b/yt/frontends/open_pmd/data_structures.py
@@ -31,7 +31,8 @@
get_component
from yt.funcs import setdefaultattr
from yt.geometry.grid_geometry_handler import GridIndex
-from yt.utilities.file_handler import HDF5FileHandler
+from yt.utilities.file_handler import HDF5FileHandler, \
+ warn_h5py
from yt.utilities.logger import ytLogger as mylog
from yt.utilities.on_demand_imports import _h5py as h5
@@ -495,9 +496,10 @@
def _is_valid(self, *args, **kwargs):
"""Checks whether the supplied file can be read by this frontend.
"""
+ warn_h5py(args[0])
try:
f = h5.File(args[0], "r")
- except (IOError, OSError):
+ except (IOError, OSError, ImportError):
return False
requirements = ["openPMD", "basePath", "meshesPath", "particlesPath"]
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -102,12 +102,6 @@
"dropping to 1st order.")
field_data = field_data[:, 0:8]
indices = indices[:, 0:8]
- elif field_data.shape[1] == 10:
- # tetrahedral
- mylog.warning("High order elements not yet supported, " +
- "dropping to 1st order.")
- field_data = field_data[:,0:4]
- indices = indices[:, 0:4]
img = pixelize_element_mesh(coords,
indices,
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/geometry/grid_container.pyx
--- a/yt/geometry/grid_container.pyx
+++ b/yt/geometry/grid_container.pyx
@@ -63,9 +63,9 @@
np.ndarray[np.int64_t, ndim=1] num_children):
cdef int i, j, k
- cdef np.ndarray[np.int64_t, ndim=1] child_ptr
+ cdef np.ndarray[np.int_t, ndim=1] child_ptr
- child_ptr = np.zeros(num_grids, dtype='int64')
+ child_ptr = np.zeros(num_grids, dtype='int')
self.num_grids = num_grids
self.num_root_grids = 0
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/geometry/grid_visitors.pxd
--- a/yt/geometry/grid_visitors.pxd
+++ b/yt/geometry/grid_visitors.pxd
@@ -37,7 +37,7 @@
np.float64_t right_edge_x
np.float64_t right_edge_y
np.float64_t right_edge_z
- np.int64_t children_pointers
+ np.int_t children_pointers
np.int64_t start_index_x
np.int64_t start_index_y
np.int64_t start_index_z
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/geometry/particle_deposit.pxd
--- a/yt/geometry/particle_deposit.pxd
+++ b/yt/geometry/particle_deposit.pxd
@@ -136,7 +136,7 @@
cdef kernel_func sph_kernel
cdef public object nvals
cdef public int update_values
- cdef void process(self, int dim[3], np.float64_t left_edge[3],
- np.float64_t dds[3], np.int64_t offset,
- np.float64_t ppos[3], np.float64_t[:] fields,
- np.int64_t domain_ind)
+ cdef int process(self, int dim[3], np.float64_t left_edge[3],
+ np.float64_t dds[3], np.int64_t offset,
+ np.float64_t ppos[3], np.float64_t[:] fields,
+ np.int64_t domain_ind) except -1
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/geometry/particle_deposit.pyx
--- a/yt/geometry/particle_deposit.pyx
+++ b/yt/geometry/particle_deposit.pyx
@@ -122,10 +122,12 @@
cdef np.int64_t gid = getattr(gobj, "id", -1)
cdef np.float64_t dds[3]
cdef np.float64_t left_edge[3]
+ cdef np.float64_t right_edge[3]
cdef int dims[3]
for i in range(3):
dds[i] = gobj.dds[i]
left_edge[i] = gobj.LeftEdge[i]
+ right_edge[i] = gobj.RightEdge[i]
dims[i] = gobj.ActiveDimensions[i]
for i in range(positions.shape[0]):
# Now we process
@@ -133,15 +135,21 @@
field_vals[j] = field_pointers[j,i]
for j in range(3):
pos[j] = positions[i, j]
+ continue_loop = False
+ for j in range(3):
+ if pos[j] < left_edge[j] or pos[j] > right_edge[j]:
+ continue_loop = True
+ if continue_loop:
+ continue
self.process(dims, left_edge, dds, 0, pos, field_vals, gid)
if self.update_values == 1:
for j in range(nf):
field_pointers[j][i] = field_vals[j]
- cdef void process(self, int dim[3], np.float64_t left_edge[3],
- np.float64_t dds[3], np.int64_t offset,
- np.float64_t ppos[3], np.float64_t[:] fields,
- np.int64_t domain_ind):
+ cdef int process(self, int dim[3], np.float64_t left_edge[3],
+ np.float64_t dds[3], np.int64_t offset,
+ np.float64_t ppos[3], np.float64_t[:] fields,
+ np.int64_t domain_ind) except -1:
raise NotImplementedError
cdef class CountParticles(ParticleDepositOperation):
@@ -152,20 +160,21 @@
np.zeros(self.nvals, dtype="int64", order='F'), 4)
@cython.cdivision(True)
- cdef void process(self, int dim[3],
- np.float64_t left_edge[3],
- np.float64_t dds[3],
- np.int64_t offset, # offset into IO field
- np.float64_t ppos[3], # this particle's position
- np.float64_t[:] fields,
- np.int64_t domain_ind
- ):
+ cdef int process(self, int dim[3],
+ np.float64_t left_edge[3],
+ np.float64_t dds[3],
+ np.int64_t offset, # offset into IO field
+ np.float64_t ppos[3], # this particle's position
+ np.float64_t[:] fields,
+ np.int64_t domain_ind
+ ) except -1:
# here we do our thing; this is the kernel
cdef int ii[3]
cdef int i
for i in range(3):
ii[i] = <int>((ppos[i] - left_edge[i])/dds[i])
self.count[ii[2], ii[1], ii[0], offset] += 1
+ return 0
def finalize(self):
arr = np.asarray(self.count)
@@ -188,14 +197,14 @@
np.zeros(self.nvals, dtype="float64", order='F'), 4)
@cython.cdivision(True)
- cdef void process(self, int dim[3],
- np.float64_t left_edge[3],
- np.float64_t dds[3],
- np.int64_t offset,
- np.float64_t ppos[3],
- np.float64_t[:] fields,
- np.int64_t domain_ind
- ):
+ cdef int process(self, int dim[3],
+ np.float64_t left_edge[3],
+ np.float64_t dds[3],
+ np.int64_t offset,
+ np.float64_t ppos[3],
+ np.float64_t[:] fields,
+ np.int64_t domain_ind
+ ) except -1:
cdef int ii[3]
cdef int ib0[3]
cdef int ib1[3]
@@ -210,7 +219,7 @@
ib0[i] = ii[i] - half_len
ib1[i] = ii[i] + half_len
if ib0[i] >= dim[i] or ib1[i] <0:
- return
+ return 0
ib0[i] = iclip(ib0[i], 0, dim[i] - 1)
ib1[i] = iclip(ib1[i], 0, dim[i] - 1)
for i from ib0[0] <= i <= ib1[0]:
@@ -233,6 +242,7 @@
for k from ib0[2] <= k <= ib1[2]:
dist = self.temp[k,j,i,offset] / kernel_sum
self.data[k,j,i,offset] += fields[1] * dist
+ return 0
def finalize(self):
return self.odata
@@ -246,20 +256,20 @@
np.zeros(self.nvals, dtype="float64", order='F'), 4)
@cython.cdivision(True)
- cdef void process(self, int dim[3],
- np.float64_t left_edge[3],
- np.float64_t dds[3],
- np.int64_t offset,
- np.float64_t ppos[3],
- np.float64_t[:] fields,
- np.int64_t domain_ind
- ):
+ cdef int process(self, int dim[3],
+ np.float64_t left_edge[3],
+ np.float64_t dds[3],
+ np.int64_t offset,
+ np.float64_t ppos[3],
+ np.float64_t[:] fields,
+ np.int64_t domain_ind
+ ) except -1:
cdef int ii[3]
cdef int i
for i in range(3):
ii[i] = <int>((ppos[i] - left_edge[i]) / dds[i])
self.sum[ii[2], ii[1], ii[0], offset] += fields[0]
- return
+ return 0
def finalize(self):
sum = np.asarray(self.sum)
@@ -288,14 +298,14 @@
np.zeros(self.nvals, dtype="float64", order='F'), 4)
@cython.cdivision(True)
- cdef void process(self, int dim[3],
- np.float64_t left_edge[3],
- np.float64_t dds[3],
- np.int64_t offset,
- np.float64_t ppos[3],
- np.float64_t[:] fields,
- np.int64_t domain_ind
- ):
+ cdef int process(self, int dim[3],
+ np.float64_t left_edge[3],
+ np.float64_t dds[3],
+ np.int64_t offset,
+ np.float64_t ppos[3],
+ np.float64_t[:] fields,
+ np.int64_t domain_ind
+ ) except -1:
cdef int ii[3]
cdef int i, cell_index
cdef float k, mk, qk
@@ -313,6 +323,7 @@
self.qk[ii[2], ii[1], ii[0], offset] = \
qk + (k - 1.0) * (fields[0] - mk) * (fields[0] - mk) / k
self.i[ii[2], ii[1], ii[0], offset] += 1
+ return 0
def finalize(self):
# This is the standard variance
@@ -338,14 +349,14 @@
np.zeros(self.nvals, dtype="float64", order='F'), 4)
@cython.cdivision(True)
- cdef void process(self, int dim[3],
- np.float64_t left_edge[3],
- np.float64_t dds[3],
- np.int64_t offset, # offset into IO field
- np.float64_t ppos[3], # this particle's position
- np.float64_t[:] fields,
- np.int64_t domain_ind
- ):
+ cdef int process(self, int dim[3],
+ np.float64_t left_edge[3],
+ np.float64_t dds[3],
+ np.int64_t offset, # offset into IO field
+ np.float64_t ppos[3], # this particle's position
+ np.float64_t[:] fields,
+ np.int64_t domain_ind
+ ) except -1:
cdef int i, j, k
cdef np.uint64_t ii
@@ -371,6 +382,8 @@
self.field[ind[2] - k, ind[1] - j, ind[0] - i, offset] += \
fields[0]*rdds[0][i]*rdds[1][j]*rdds[2][k]
+ return 0
+
def finalize(self):
rv = np.asarray(self.field)
rv.shape = self.nvals
@@ -390,20 +403,21 @@
np.zeros(self.nvals, dtype='float64', order='F'), 4)
@cython.cdivision(True)
- cdef void process(self, int dim[3],
- np.float64_t left_edge[3],
- np.float64_t dds[3],
- np.int64_t offset,
- np.float64_t ppos[3],
- np.float64_t[:] fields,
- np.int64_t domain_ind
- ):
+ cdef int process(self, int dim[3],
+ np.float64_t left_edge[3],
+ np.float64_t dds[3],
+ np.int64_t offset,
+ np.float64_t ppos[3],
+ np.float64_t[:] fields,
+ np.int64_t domain_ind
+ ) except -1:
cdef int ii[3]
cdef int i
for i in range(3):
ii[i] = <int>((ppos[i] - left_edge[i]) / dds[i])
self.w[ii[2], ii[1], ii[0], offset] += fields[1]
self.wf[ii[2], ii[1], ii[0], offset] += fields[0] * fields[1]
+ return 0
def finalize(self):
wf = np.asarray(self.wf)
@@ -422,15 +436,16 @@
self.update_values = 1
@cython.cdivision(True)
- cdef void process(self, int dim[3],
+ cdef int process(self, int dim[3],
np.float64_t left_edge[3],
np.float64_t dds[3],
np.int64_t offset,
np.float64_t ppos[3],
np.float64_t[:] fields,
np.int64_t domain_ind
- ):
+ ) except -1:
fields[0] = domain_ind
+ return 0
def finalize(self):
return
@@ -448,14 +463,14 @@
self.distfield[:] = np.inf
@cython.cdivision(True)
- cdef void process(self, int dim[3],
- np.float64_t left_edge[3],
- np.float64_t dds[3],
- np.int64_t offset,
- np.float64_t ppos[3],
- np.float64_t[:] fields,
- np.int64_t domain_ind
- ):
+ cdef int process(self, int dim[3],
+ np.float64_t left_edge[3],
+ np.float64_t dds[3],
+ np.int64_t offset,
+ np.float64_t ppos[3],
+ np.float64_t[:] fields,
+ np.int64_t domain_ind
+ ) except -1:
# This one is a bit slow. Every grid cell is going to be iterated
# over, and we're going to deposit particles in it.
cdef int i, j, k
@@ -477,7 +492,7 @@
gpos[2] += dds[2]
gpos[1] += dds[1]
gpos[0] += dds[0]
- return
+ return 0
def finalize(self):
nn = np.asarray(self.nnfield)
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/geometry/particle_smooth.pyx
--- a/yt/geometry/particle_smooth.pyx
+++ b/yt/geometry/particle_smooth.pyx
@@ -314,8 +314,7 @@
# Note that what we will be providing to our processing functions will
# actually be indirectly-sorted fields. This preserves memory at the
# expense of additional pointer lookups.
- pind = np.argsort(pdoms)
- pind = np.asarray(pind, dtype='int64', order='C')
+ pind = np.asarray(np.argsort(pdoms), dtype='int64', order='C')
# So what this means is that we now have all the oct-0 particle indices
# in order, then the oct-1, etc etc.
# This now gives us the indices to the particles for each domain.
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/utilities/exodusII_reader.py
--- a/yt/utilities/exodusII_reader.py
+++ /dev/null
@@ -1,51 +0,0 @@
-import string
-from itertools import takewhile
-from netCDF4 import Dataset
-import numpy as np
-from yt.config import ytcfg
-import os
-import warnings
-
-
-def sanitize_string(s):
- s = "".join(_ for _ in takewhile(lambda a: a in string.printable, s))
- return s
-
-
-def get_data(fn):
- warnings.warn("The yt.utilities.exodusII_reader module is deprecated "
- "and will be removed in a future release. "
- "Please use the normal yt.load() command to access "
- "your data instead.")
- try:
- f = Dataset(fn)
- except RuntimeError:
- f = Dataset(os.path.join(ytcfg.get("yt", "test_data_dir"), fn))
- fvars = f.variables
- # Is this correct?
- etypes = fvars["eb_status"][:]
- nelem = etypes.shape[0]
- varnames = [sanitize_string(v.tostring()) for v in
- fvars["name_elem_var"][:]]
- nodnames = [sanitize_string(v.tostring()) for v in
- fvars["name_nod_var"][:]]
- coord = np.array([fvars["coord%s" % ax][:]
- for ax in 'xyz']).transpose().copy()
- coords = []
- connects = []
- data = []
- for i in range(nelem):
- connects.append(fvars["connect%s" % (i+1)][:].astype("i8"))
- ci = connects[-1]
- coords.append(coord) # Same for all
- vals = {}
- for j, v in enumerate(varnames):
- values = fvars["vals_elem_var%seb%s" % (j+1, i+1)][:]
- vals['gas', v] = values.astype("f8")[-1, :]
- for j, v in enumerate(nodnames):
- # We want just for this set of nodes all the node variables
- # Use (ci - 1) to get these values
- values = fvars["vals_nod_var%s" % (j+1)][:]
- vals['gas', v] = values.astype("f8")[-1, ci - 1, ...]
- data.append(vals)
- return coords, connects, data
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/utilities/file_handler.py
--- a/yt/utilities/file_handler.py
+++ b/yt/utilities/file_handler.py
@@ -14,8 +14,26 @@
#-----------------------------------------------------------------------------
from yt.utilities.on_demand_imports import _h5py as h5py
+from yt.utilities.on_demand_imports import NotAModule
from contextlib import contextmanager
+def valid_hdf5_signature(fn):
+ signature = b'\x89HDF\r\n\x1a\n'
+ try:
+ with open(fn, 'rb') as f:
+ header = f.read(8)
+ return header == signature
+ except:
+ return False
+
+
+def warn_h5py(fn):
+ needs_h5py = valid_hdf5_signature(fn)
+ if needs_h5py and isinstance(h5py.File, NotAModule):
+ raise RuntimeError("This appears to be an HDF5 file, "
+ "but h5py is not installed.")
+
+
class HDF5FileHandler(object):
handle = None
@@ -68,13 +86,33 @@
def close(self):
self.handle.close()
-class NetCDF4FileHandler():
+
+def valid_netcdf_classic_signature(filename):
+ signature_v1 = b'CDF\x01'
+ signature_v2 = b'CDF\x02'
+ try:
+ with open(filename, 'rb') as f:
+ header = f.read(4)
+ return (header == signature_v1 or header == signature_v2)
+ except:
+ return False
+
+
+def warn_netcdf(fn):
+ needs_netcdf = valid_netcdf_classic_signature(fn)
+ from yt.utilities.on_demand_imports import _netCDF4 as netCDF4
+ if needs_netcdf and isinstance(netCDF4.Dataset, NotAModule):
+ raise RuntimeError("This appears to be a netCDF file, but the "
+ "python bindings for netCDF4 are not installed.")
+
+
+class NetCDF4FileHandler(object):
def __init__(self, filename):
self.filename = filename
@contextmanager
def open_ds(self):
- from netCDF4 import Dataset
- ds = Dataset(self.filename)
+ from yt.utilities.on_demand_imports import _netCDF4 as netCDF4
+ ds = netCDF4.Dataset(self.filename)
yield ds
ds.close()
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/utilities/lib/alt_ray_tracers.pyx
--- a/yt/utilities/lib/alt_ray_tracers.pyx
+++ b/yt/utilities/lib/alt_ray_tracers.pyx
@@ -101,7 +101,7 @@
rleft, rright, zleft, zright, \
cleft, cright, thetaleft, thetaright, \
tmleft, tpleft, tmright, tpright, tsect
- cdef np.ndarray[np.int64_t, ndim=1, cast=True] inds, tinds, sinds
+ cdef np.ndarray[np.int_t, ndim=1, cast=True] inds, tinds, sinds
cdef np.ndarray[np.float64_t, ndim=2] xyz, rztheta, ptemp, b1, b2, dsect
# set up points
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/utilities/lib/element_mappings.pyx
--- a/yt/utilities/lib/element_mappings.pyx
+++ b/yt/utilities/lib/element_mappings.pyx
@@ -344,6 +344,10 @@
double* physical_x) nogil:
'''
+ A thorough description of Newton's method and modifications for global
+ convergence can be found in Dennis's text "Numerical Methods for
+ Unconstrained Optimization and Nonlinear Equations."
+
x: solution vector; holds unit/mapped coordinates
xk: temporary vector for holding solution of current iteration
f: residual vector
@@ -352,11 +356,16 @@
d: Jacobian determinant
s_n: Newton step vector
lam: fraction of Newton step by which to change x
- alpha: constant proportional to how much residual required to decrease
+ alpha: constant proportional to how much residual required to decrease.
+ 1e-4 is value of alpha recommended by Dennis
err_c: Error of current iteration
err_plus: Error of next iteration
+ min_lam: minimum fraction of Newton step that the line search is allowed
+ to take. General experience suggests that lambda values smaller
+ than 1e-3 will not significantly reduce the residual, but we
+ set to 1e-6 just to be safe
+ '''
- '''
cdef int i
cdef double d, lam
cdef double[3] f
@@ -367,6 +376,7 @@
cdef int iterations = 0
cdef double err_c, err_plus
cdef double alpha = 1e-4
+ cdef double min_lam = 1e-6
# initial guess
for i in range(3):
@@ -391,7 +401,7 @@
err_plus = maxnorm(f, 3)
lam = 1
- while err_plus > err_c * (1. - alpha * lam) and lam > 1e-6:
+ while err_plus > err_c * (1. - alpha * lam) and lam > min_lam:
lam = lam / 2
xk[0] = x[0] + lam * s_n[0]
xk[1] = x[1] + lam * s_n[1]
@@ -791,6 +801,10 @@
double* physical_x) nogil:
'''
+ A thorough description of Newton's method and modifications for global
+ convergence can be found in Dennis's text "Numerical Methods for
+ Unconstrained Optimization and Nonlinear Equations."
+
x: solution vector; holds unit/mapped coordinates
xk: temporary vector for holding solution of current iteration
f: residual vector
@@ -798,11 +812,16 @@
d: Jacobian determinant
s_n: Newton step vector
lam: fraction of Newton step by which to change x
- alpha: constant proportional to how much residual required to decrease
+ alpha: constant proportional to how much residual required to decrease.
+ 1e-4 is value of alpha recommended by Dennis
err_c: Error of current iteration
err_plus: Error of next iteration
+ min_lam: minimum fraction of Newton step that the line search is allowed
+ to take. General experience suggests that lambda values smaller
+ than 1e-3 will not significantly reduce the residual, but we
+ set to 1e-6 just to be safe
+ '''
- '''
cdef int i
cdef double d, lam
cdef double[2] f
@@ -811,6 +830,7 @@
cdef int iterations = 0
cdef double err_c, err_plus
cdef double alpha = 1e-4
+ cdef double min_lam = 1e-6
# initial guess
for i in range(2):
@@ -833,7 +853,7 @@
err_plus = maxnorm(f, 2)
lam = 1
- while err_plus > err_c * (1. - alpha * lam) and lam > 1e-6:
+ while err_plus > err_c * (1. - alpha * lam) and lam > min_lam:
lam = lam / 2
xk[0] = x[0] + lam * s_n[0]
xk[1] = x[1] + lam * s_n[1]
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/utilities/lib/image_utilities.pyx
--- a/yt/utilities/lib/image_utilities.pyx
+++ b/yt/utilities/lib/image_utilities.pyx
@@ -17,6 +17,7 @@
def add_points_to_greyscale_image(
np.ndarray[np.float64_t, ndim=2] buffer,
+ np.ndarray[np.int_t, ndim=2] buffer_mask,
np.ndarray[np.float64_t, ndim=1] px,
np.ndarray[np.float64_t, ndim=1] py,
np.ndarray[np.float64_t, ndim=1] pv):
@@ -28,6 +29,7 @@
j = <int> (xs * px[pi])
i = <int> (ys * py[pi])
buffer[i, j] += pv[pi]
+ buffer_mask[i, j] = 1
return
def add_points_to_image(
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/utilities/lib/pixelization_routines.pyx
--- a/yt/utilities/lib/pixelization_routines.pyx
+++ b/yt/utilities/lib/pixelization_routines.pyx
@@ -245,7 +245,7 @@
np.float64_t[:] pdz,
np.float64_t[:] center,
np.float64_t[:,:] inv_mat,
- np.int64_t[:] indices,
+ np.int_t[:] indices,
np.float64_t[:] data,
bounds):
cdef np.float64_t x_min, x_max, y_min, y_max
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/utilities/on_demand_imports.py
--- a/yt/utilities/on_demand_imports.py
+++ b/yt/utilities/on_demand_imports.py
@@ -30,6 +30,23 @@
def __call__(self, *args, **kwargs):
raise self.error
+class netCDF4_imports(object):
+ _name = "netCDF4"
+ _Dataset = None
+ @property
+ def Dataset(self):
+ if self._Dataset is None:
+ try:
+ from netCDF4 import Dataset
+ except ImportError:
+ Dataset = NotAModule(self._name)
+ self._Dataset = Dataset
+ return self._Dataset
+
+
+_netCDF4 = netCDF4_imports()
+
+
class astropy_imports(object):
_name = "astropy"
_pyfits = None
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/visualization/fixed_resolution.py
--- a/yt/visualization/fixed_resolution.py
+++ b/yt/visualization/fixed_resolution.py
@@ -648,24 +648,31 @@
# splat particles
buff = np.zeros(self.buff_size)
+ buff_mask = np.zeros(self.buff_size).astype('int')
add_points_to_greyscale_image(buff,
+ buff_mask,
px[mask],
py[mask],
splat_vals)
+ # remove values in no-particle region
+ buff[buff_mask==0] = np.nan
ia = ImageArray(buff, input_units=data.units,
info=self._get_info(item))
# divide by the weight_field, if needed
if weight_field is not None:
weight_buff = np.zeros(self.buff_size)
+ weight_buff_mask = np.zeros(self.buff_size).astype('int')
add_points_to_greyscale_image(weight_buff,
+ weight_buff_mask,
px[mask],
py[mask],
weight_data[mask])
weight_array = ImageArray(weight_buff,
input_units=weight_data.units,
info=self._get_info(item))
-
+ # remove values in no-particle region
+ weight_buff[weight_buff_mask==0] = np.nan
locs = np.where(weight_array > 0)
ia[locs] /= weight_array[locs]
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/visualization/plot_modifications.py
--- a/yt/visualization/plot_modifications.py
+++ b/yt/visualization/plot_modifications.py
@@ -2033,10 +2033,6 @@
# Callback only works for plots with axis ratios of 1
xsize = plot.xlim[1] - plot.xlim[0]
- if plot.aspect != 1.0:
- raise NotImplementedError(
- "Scale callback has only been implemented for plots with no "
- "aspect ratio scaling. (aspect = {%s})".format(plot._aspect))
# Setting pos overrides corner argument
if self.pos is None:
@@ -2076,8 +2072,8 @@
text = "{scale} {units}".format(scale=int(self.coeff), units=self.unit)
image_scale = (plot.frb.convert_distance_x(self.scale) /
plot.frb.convert_distance_x(xsize)).v
-
- size_vertical = self.size_bar_args.pop('size_vertical', .005)
+ size_vertical = self.size_bar_args.pop(
+ 'size_vertical', .005 * plot.aspect)
fontproperties = self.size_bar_args.pop(
'fontproperties', plot.font_properties.copy())
frameon = self.size_bar_args.pop('frameon', self.draw_inset_box)
@@ -2336,12 +2332,12 @@
plot.data,
self.field_x,
bounds,
- (nx,ny))
+ (ny,nx))
pixY = plot.data.ds.coordinates.pixelize(plot.data.axis,
plot.data,
self.field_y,
bounds,
- (nx,ny))
+ (ny,nx))
vectors = np.concatenate((pixX[...,np.newaxis],
pixY[...,np.newaxis]),axis=2)
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/visualization/profile_plotter.py
--- a/yt/visualization/profile_plotter.py
+++ b/yt/visualization/profile_plotter.py
@@ -84,6 +84,7 @@
def __init__(self, plots):
self.plots = plots
self.ylim = {}
+ self.xlim = (None, None)
super(AxesContainer, self).__init__()
def __missing__(self, key):
@@ -357,6 +358,7 @@
axes.set_xlabel(xtitle)
axes.set_ylabel(ytitle)
axes.set_ylim(*self.axes.ylim[fname])
+ axes.set_xlim(*self.axes.xlim)
if any(self.label):
axes.legend(loc="best")
self._set_font_properties()
@@ -539,6 +541,7 @@
>>> pp.save()
"""
+ self.axes.xlim = (xmin, xmax)
for i, p in enumerate(self.profiles):
if xmin is None:
xmi = p.x_bins.min()
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/visualization/tests/test_callbacks.py
--- a/yt/visualization/tests/test_callbacks.py
+++ b/yt/visualization/tests/test_callbacks.py
@@ -107,32 +107,38 @@
ds = fake_amr_ds(fields = ("density",))
p = ProjectionPlot(ds, ax, "density")
p.annotate_scale()
- yield assert_fname, p.save(prefix)[0]
+ assert_fname(p.save(prefix)[0])
+ p = ProjectionPlot(ds, ax, "density", width=(0.5, 1.0))
+ p.annotate_scale()
+ assert_fname(p.save(prefix)[0])
+ p = ProjectionPlot(ds, ax, "density", width=(1.0, 1.5))
+ p.annotate_scale()
+ assert_fname(p.save(prefix)[0])
p = SlicePlot(ds, ax, "density")
p.annotate_scale()
- yield assert_fname, p.save(prefix)[0]
+ assert_fname(p.save(prefix)[0])
p = OffAxisSlicePlot(ds, vector, "density")
p.annotate_scale()
- yield assert_fname, p.save(prefix)[0]
+ assert_fname(p.save(prefix)[0])
# Now we'll check a few additional minor things
p = SlicePlot(ds, "x", "density")
p.annotate_scale(corner='upper_right', coeff=10., unit='kpc')
- yield assert_fname, p.save(prefix)[0]
+ assert_fname(p.save(prefix)[0])
p = SlicePlot(ds, "x", "density")
p.annotate_scale(text_args={"size": 24})
- yield assert_fname, p.save(prefix)[0]
+ assert_fname(p.save(prefix)[0])
p = SlicePlot(ds, "x", "density")
p.annotate_scale(text_args={"font": 24})
- yield assert_raises, YTPlotCallbackError
+ assert_raises(YTPlotCallbackError)
with _cleanup_fname() as prefix:
ds = fake_amr_ds(fields = ("density",), geometry="spherical")
p = ProjectionPlot(ds, "r", "density")
p.annotate_scale()
- yield assert_raises, YTDataTypeUnsupported, p.save, prefix
+ assert_raises(YTDataTypeUnsupported, p.save, prefix)
p = ProjectionPlot(ds, "r", "density")
p.annotate_scale(coord_system="axis")
- yield assert_raises, YTDataTypeUnsupported, p.save, prefix
+ assert_raises(YTDataTypeUnsupported, p.save, prefix)
def test_line_callback():
with _cleanup_fname() as prefix:
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/visualization/tests/test_mesh_slices.py
--- a/yt/visualization/tests/test_mesh_slices.py
+++ b/yt/visualization/tests/test_mesh_slices.py
@@ -49,6 +49,15 @@
for field in ds.field_list:
yield compare(ds, field, "answers_tri2_%s_%s" % (field[0], field[1]))
+quad2 = "SecondOrderQuads/lid_driven_out.e"
+
+ at requires_ds(quad2)
+def test_quad2():
+ ds = data_dir_load(quad2, kwargs={'step':-1})
+ field_list = [('all', 'T'), ('all', 'vel_x'), ('all', 'vel_y')]
+ for field in field_list:
+ yield compare(ds, field, "answers_quad2_%s_%s" % (field[0], field[1]))
+
multi_region = "MultiRegion/two_region_example_out.e"
@requires_ds(multi_region)
diff -r add68b583bb1f40f49f724237fe658ee0769a978 -r 8ee92ca7654fcd5c12a0c703aa9d48c89fa7435a yt/visualization/volume_rendering/scene.py
--- a/yt/visualization/volume_rendering/scene.py
+++ b/yt/visualization/volume_rendering/scene.py
@@ -393,8 +393,6 @@
rs = rensources[0]
tf = rs.transfer_function
label = rs.data_source.ds._get_field_info(rs.field).get_label()
- if rs.log_field:
- label = r'$\rm{log}\ $' + label
ax = self._show_mpl(self._last_render.swapaxes(0, 1),
sigma_clip=sigma_clip, dpi=dpi)
https://bitbucket.org/yt_analysis/yt/commits/8873fcbb5c4c/
Changeset: 8873fcbb5c4c
User: Alex Lindsay
Date: 2017-06-03 19:59:50+00:00
Summary: Merge branch 'line_plot_plus_quad9' of ssh://github.com/lindsayad/yt into line_plot_plus_quad9
Affected #: 2 files
https://bitbucket.org/yt_analysis/yt/commits/f2b2d87a28ed/
Changeset: f2b2d87a28ed
User: Alex Lindsay
Date: 2017-06-03 22:06:40+00:00
Summary: First interesting error
Affected #: 4 files
diff -r 8873fcbb5c4c2514043a0b11243a83a59023fd69 -r f2b2d87a28ed6d646a65f44d8fa23d1ce4cfe078 yt/__init__.py
--- a/yt/__init__.py
+++ b/yt/__init__.py
@@ -103,7 +103,7 @@
FixedResolutionBuffer, ObliqueFixedResolutionBuffer, \
write_bitmap, write_image, \
apply_colormap, scale_image, write_projection, \
- SlicePlot, AxisAlignedSlicePlot, OffAxisSlicePlot, \
+ SlicePlot, AxisAlignedSlicePlot, OffAxisSlicePlot, LinePlot, \
ProjectionPlot, OffAxisProjectionPlot, \
show_colormaps, add_cmap, make_colormap, \
ProfilePlot, PhasePlot, ParticlePhasePlot, \
diff -r 8873fcbb5c4c2514043a0b11243a83a59023fd69 -r f2b2d87a28ed6d646a65f44d8fa23d1ce4cfe078 yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -24,7 +24,7 @@
from yt.funcs import mylog
from yt.utilities.lib.pixelization_routines import \
pixelize_element_mesh, pixelize_off_axis_cartesian, \
- pixelize_cartesian, pixelize_cartesian_nodal,
+ pixelize_cartesian, pixelize_cartesian_nodal, \
element_mesh_line_plot
from yt.data_objects.unstructured_mesh import SemiStructuredMesh
from yt.utilities.nodal_data_utils import get_nodal_data
@@ -66,6 +66,7 @@
def pixelize(self, dimension, data_source, field, bounds, size,
antialias = True, periodic = True):
+ import pdb; pdb.set_trace()
index = data_source.ds.index
if (hasattr(index, 'meshes') and
not isinstance(index.meshes[0], SemiStructuredMesh)):
diff -r 8873fcbb5c4c2514043a0b11243a83a59023fd69 -r f2b2d87a28ed6d646a65f44d8fa23d1ce4cfe078 yt/visualization/api.py
--- a/yt/visualization/api.py
+++ b/yt/visualization/api.py
@@ -51,7 +51,8 @@
AxisAlignedSlicePlot, \
OffAxisSlicePlot, \
ProjectionPlot, \
- OffAxisProjectionPlot
+ OffAxisProjectionPlot, \
+ LinePlot
from .profile_plotter import \
ProfilePlot, \
diff -r 8873fcbb5c4c2514043a0b11243a83a59023fd69 -r f2b2d87a28ed6d646a65f44d8fa23d1ce4cfe078 yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -24,7 +24,7 @@
from numbers import Number
from .base_plot_types import \
- ImagePlotMPL
+ ImagePlotMPL, PlotMPL
from .fixed_resolution import \
FixedResolutionBuffer, \
OffAxisProjectionFixedResolutionBuffer
@@ -67,6 +67,7 @@
YTPlotCallbackError, \
YTDataTypeUnsupported, \
YTInvalidFieldType
+from yt.geometry.coordinates.cartesian_coordinates import CartesianCoordinateHandler
MPL_VERSION = LooseVersion(matplotlib.__version__)
@@ -1118,7 +1119,8 @@
----------
field : string, field tuple, or list of strings or field tuples (optional)
- The name of the field(s) that we want to show the colorbar.
+ The name of the field(s) that we want to show
+ the colorbar.
"""
if field is None:
field = self.fields
@@ -2014,3 +2016,44 @@
del kwargs['north_vector']
return AxisAlignedSlicePlot(ds, normal, fields, *args, **kwargs)
+
+class LinePlot(PlotMPL):
+ r"""
+ A factory function for
+ :class:`yt.visualization.plot_window.AxisAlignedSlicePlot`
+ and :class:`yt.visualization.plot_window.OffAxisSlicePlot` objects. This
+ essentially allows for a single entry point to both types of slice plots,
+ the distinction being determined by the specified normal vector to the
+ slice.
+
+ The returned plot object can be updated using one of the many helper
+ functions defined in PlotWindow.
+
+ Parameters
+ ----------
+
+ ds : :class:`yt.data_objects.static_output.Dataset`
+ This is the dataset object corresponding to the
+ simulation output to be plotted.
+ fields : string
+ The name of the field(s) to be plotted.
+ point1: tuple
+ Contains the coordinates of the first point for constructing the line
+ point2: tuple
+ Contains the coordinates of the second point for constructing the line
+ resolution: int
+ How many points to sample between point1 and point2 for constructing
+ the line plot
+ """
+
+ def __init__(self, ds, fields, point1, point2, resolution):
+ self.ds = ds
+ self.handler = CartesianCoordinateHandler(self.ds)
+ # super(LinePlot, self).__init__(fsize, axrect, None, None)
+ super(LinePlot, self).__init__(None, None, None, None)
+ for field in fields:
+ x, y = self.handler.line_plot(field, np.asarray(point1, dtype='float64'),
+ np.asarray(point2, dtype='float64'), resolution)
+ self.ax.plot(x, y)
+
+
https://bitbucket.org/yt_analysis/yt/commits/8aa3a4319b7c/
Changeset: 8aa3a4319b7c
User: Alex Lindsay
Date: 2017-06-05 18:52:24+00:00
Summary: First test working
Affected #: 3 files
diff -r f2b2d87a28ed6d646a65f44d8fa23d1ce4cfe078 -r 8aa3a4319b7c047a70f1eb0bc8d80fd645df0b14 yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -66,7 +66,7 @@
def pixelize(self, dimension, data_source, field, bounds, size,
antialias = True, periodic = True):
- import pdb; pdb.set_trace()
+ # import pdb; pdb.set_trace()
index = data_source.ds.index
if (hasattr(index, 'meshes') and
not isinstance(index.meshes[0], SemiStructuredMesh)):
@@ -122,6 +122,7 @@
antialias)
def line_plot(self, field, start_point, end_point, resolution):
+ import pdb; pdb.set_trace()
index = self.ds.index
if (hasattr(index, 'meshes') and
not isinstance(index.meshes[0], SemiStructuredMesh)):
@@ -168,13 +169,13 @@
period = period.in_units("code_length").d
buff = np.zeros((size[1], size[0]), dtype="f8")
-
+
finfo = self.ds._get_field_info(field)
nodal_flag = finfo.nodal_flag
if np.any(nodal_flag):
nodal_data = get_nodal_data(data_source, field)
coord = data_source.coord.d
- pixelize_cartesian_nodal(buff,
+ pixelize_cartesian_nodal(buff,
data_source['px'], data_source['py'], data_source['pz'],
data_source['pdx'], data_source['pdy'], data_source['pdz'],
nodal_data, coord, bounds, int(antialias),
@@ -186,7 +187,7 @@
bounds, int(antialias),
period, int(periodic))
return buff
-
+
def _oblique_pixelize(self, data_source, field, bounds, size, antialias):
indices = np.argsort(data_source['pdx'])[::-1].astype(np.int_)
buff = np.zeros((size[1], size[0]), dtype="f8")
diff -r f2b2d87a28ed6d646a65f44d8fa23d1ce4cfe078 -r 8aa3a4319b7c047a70f1eb0bc8d80fd645df0b14 yt/visualization/base_plot_types.py
--- a/yt/visualization/base_plot_types.py
+++ b/yt/visualization/base_plot_types.py
@@ -50,7 +50,7 @@
class CallbackWrapper(object):
- def __init__(self, viewer, window_plot, frb, field, font_properties,
+ def __init__(self, viewer, window_plot, frb, field, font_properties,
font_color):
self.frb = frb
self.data = frb.data_source
@@ -83,6 +83,7 @@
def __init__(self, fsize, axrect, figure, axes):
"""Initialize PlotMPL class"""
+ import pdb; pdb.set_trace()
import matplotlib.figure
self._plot_valid = True
if figure is None:
@@ -279,10 +280,10 @@
x_frac_widths = xbins/size[0]
y_frac_widths = ybins/size[1]
- # axrect is the rectangle defining the area of the
- # axis object of the plot. Its range goes from 0 to 1 in
- # x and y directions. The first two values are the x,y
- # start values of the axis object (lower left corner), and the
+ # axrect is the rectangle defining the area of the
+ # axis object of the plot. Its range goes from 0 to 1 in
+ # x and y directions. The first two values are the x,y
+ # start values of the axis object (lower left corner), and the
# second two values are the size of the axis object. To get
# the upper right corner, add the first x,y to the second x,y.
axrect = (
@@ -452,5 +453,3 @@
ax.clear()
cbars.append(ax)
return fig, tr, cbars
-
-
diff -r f2b2d87a28ed6d646a65f44d8fa23d1ce4cfe078 -r 8aa3a4319b7c047a70f1eb0bc8d80fd645df0b14 yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -661,6 +661,7 @@
_data_valid = False
def __init__(self, *args, **kwargs):
+ import pdb; pdb.set_trace()
if self._frb_generator is None:
self._frb_generator = kwargs.pop("frb_generator")
if self._plot_type is None:
@@ -1037,7 +1038,7 @@
@invalidate_plot
def annotate_clear(self, index=None):
"""
- Clear callbacks from the plot. If index is not set, clear all
+ Clear callbacks from the plot. If index is not set, clear all
callbacks. If index is set, clear that index (ie 0 is the first one
created, 1 is the 2nd one created, -1 is the last one created, etc.)
"""
@@ -1052,7 +1053,7 @@
for f in self.fields:
keys = self.frb.keys()
for name, (args, kwargs) in self._callbacks:
- cbw = CallbackWrapper(self, self.plots[f], self.frb, f,
+ cbw = CallbackWrapper(self, self.plots[f], self.frb, f,
self._font_properties, self._font_color)
CallbackMaker = callback_registry[name]
callback = CallbackMaker(*args[1:], **kwargs)
@@ -1070,8 +1071,8 @@
def hide_colorbar(self, field=None):
"""
- Hides the colorbar for a plot and updates the size of the
- plot accordingly. Defaults to operating on all fields for a
+ Hides the colorbar for a plot and updates the size of the
+ plot accordingly. Defaults to operating on all fields for a
PlotWindow object.
Parameters
@@ -1111,8 +1112,8 @@
def show_colorbar(self, field=None):
"""
- Shows the colorbar for a plot and updates the size of the
- plot accordingly. Defaults to operating on all fields for a
+ Shows the colorbar for a plot and updates the size of the
+ plot accordingly. Defaults to operating on all fields for a
PlotWindow object. See hide_colorbar().
Parameters
@@ -1131,8 +1132,8 @@
def hide_axes(self, field=None):
"""
- Hides the axes for a plot and updates the size of the
- plot accordingly. Defaults to operating on all fields for a
+ Hides the axes for a plot and updates the size of the
+ plot accordingly. Defaults to operating on all fields for a
PlotWindow object.
Parameters
@@ -1170,8 +1171,8 @@
def show_axes(self, field=None):
"""
- Shows the axes for a plot and updates the size of the
- plot accordingly. Defaults to operating on all fields for a
+ Shows the axes for a plot and updates the size of the
+ plot accordingly. Defaults to operating on all fields for a
PlotWindow object. See hide_axes().
Parameters
@@ -1285,7 +1286,7 @@
A dictionary of field parameters than can be accessed by derived
fields.
data_source: YTSelectionContainer object
- Object to be used for data selection. Defaults to ds.all_data(), a
+ Object to be used for data selection. Defaults to ds.all_data(), a
region covering the full domain
Examples
@@ -1440,7 +1441,7 @@
fontsize : integer
The size of the fonts for the axis, colorbar, and tick labels.
method : string
- The method of projection. Valid methods are:
+ The method of projection. Valid methods are:
"integrate" with no weight_field specified : integrate the requested
field along the line of sight.
@@ -1466,7 +1467,7 @@
A dictionary of field parameters than can be accessed by derived
fields.
data_source: YTSelectionContainer object
- Object to be used for data selection. Defaults to ds.all_data(), a
+ Object to be used for data selection. Defaults to ds.all_data(), a
region covering the full domain
Examples
@@ -1492,7 +1493,7 @@
self.ts = ts
ds = self.ds = ts[0]
axis = fix_axis(axis, ds)
- # proj_style is deprecated, but if someone specifies then it trumps
+ # proj_style is deprecated, but if someone specifies then it trumps
# method.
if proj_style is not None:
method = proj_style
@@ -1521,7 +1522,7 @@
field_parameters=field_parameters, method=method,
max_level=max_level)
PWViewerMPL.__init__(self, proj, bounds, fields=fields, origin=origin,
- right_handed=right_handed, fontsize=fontsize, window_size=window_size,
+ right_handed=right_handed, fontsize=fontsize, window_size=window_size,
aspect=aspect)
if axes_unit is None:
axes_unit = get_axes_unit(width, ds)
@@ -1595,7 +1596,7 @@
A dictionary of field parameters than can be accessed by derived
fields.
data_source : YTSelectionContainer Object
- Object to be used for data selection. Defaults ds.all_data(), a
+ Object to be used for data selection. Defaults ds.all_data(), a
region covering the full domain.
"""
@@ -1750,7 +1751,7 @@
This should only be used for uniform resolution grid datasets, as other
datasets may result in unphysical images.
data_source: YTSelectionContainer object
- Object to be used for data selection. Defaults to ds.all_data(), a
+ Object to be used for data selection. Defaults to ds.all_data(), a
region covering the full domain
"""
_plot_type = 'OffAxisProjection'
@@ -2042,18 +2043,57 @@
point2: tuple
Contains the coordinates of the second point for constructing the line
resolution: int
- How many points to sample between point1 and point2 for constructing
+ How many points to sample between point1 and point2 for constructing
the line plot
"""
- def __init__(self, ds, fields, point1, point2, resolution):
- self.ds = ds
- self.handler = CartesianCoordinateHandler(self.ds)
+ def __init__(self, ds, fields, point1, point2, resolution,
+ figure_size=5., aspect=None, fontsize=18.):
+ handler = CartesianCoordinateHandler(ds)
+ if not isinstance(fields, list):
+ fields = [fields]
+ if aspect is None:
+ aspect = 1.
+ fontscale = fontsize / 18.
+ ax_text_size = [1.2*fontscale, 0.9*fontscale]
+ top_buff_size = 0.3*fontscale
+
+ if iterable(figure_size):
+ x_fig_size = figure_size[0]
+ y_fig_size = figure_size[1]
+ else:
+ x_fig_size = figure_size
+ y_fig_size = figure_size/aspect
+
+ x_axis_size = ax_text_size[0]
+ y_axis_size = ax_text_size[1]
+
+ top_buff_size = top_buff_size
+
+ xbins = np.array([x_axis_size, x_fig_size, x_axis_size])
+ ybins = np.array([y_axis_size, y_fig_size, top_buff_size])
+
+ size = [xbins.sum(), ybins.sum()]
+
+ x_frac_widths = xbins/size[0]
+ y_frac_widths = ybins/size[1]
+
+ # axrect is the rectangle defining the area of the
+ # axis object of the plot. Its range goes from 0 to 1 in
+ # x and y directions. The first two values are the x,y
+ # start values of the axis object (lower left corner), and the
+ # second two values are the size of the axis object. To get
+ # the upper right corner, add the first x,y to the second x,y.
+ axrect = (
+ x_frac_widths[0],
+ y_frac_widths[0],
+ x_frac_widths[1],
+ y_frac_widths[1],
+ )
+
# super(LinePlot, self).__init__(fsize, axrect, None, None)
- super(LinePlot, self).__init__(None, None, None, None)
+ super(LinePlot, self).__init__(size, axrect, None, None)
for field in fields:
- x, y = self.handler.line_plot(field, np.asarray(point1, dtype='float64'),
+ x, y = handler.line_plot(field, np.asarray(point1, dtype='float64'),
np.asarray(point2, dtype='float64'), resolution)
- self.ax.plot(x, y)
-
-
+ self.axes.plot(x, y)
https://bitbucket.org/yt_analysis/yt/commits/4ca701abb425/
Changeset: 4ca701abb425
User: Alex Lindsay
Date: 2017-06-05 19:22:53+00:00
Summary: Add some documentation
Affected #: 4 files
diff -r 8aa3a4319b7c047a70f1eb0bc8d80fd645df0b14 -r 4ca701abb425577ab00ecd0e899d3a63e4c7418b yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -66,7 +66,11 @@
def pixelize(self, dimension, data_source, field, bounds, size,
antialias = True, periodic = True):
- # import pdb; pdb.set_trace()
+ """
+ Method for pixelizing grid data sets in preparation for
+ two-dimensional image plots. Relies on several sampling
+ routines written in cython
+ """
index = data_source.ds.index
if (hasattr(index, 'meshes') and
not isinstance(index.meshes[0], SemiStructuredMesh)):
@@ -121,8 +125,14 @@
return self._oblique_pixelize(data_source, field, bounds, size,
antialias)
+
def line_plot(self, field, start_point, end_point, resolution):
- import pdb; pdb.set_trace()
+ """
+ Method for sampling grid data sets along a line in preparation for
+ one-dimensional line plots. For UnstructuredMesh, relies on a
+ sampling routine written in cython
+ """
+
index = self.ds.index
if (hasattr(index, 'meshes') and
not isinstance(index.meshes[0], SemiStructuredMesh)):
@@ -158,6 +168,10 @@
return arc_length, plot_values
+ else:
+ raise NotImplementedError("Currently line plotting routines have only "
+ "been implemented for unstructured meshes.")
+
def _ortho_pixelize(self, data_source, field, bounds, size, antialias,
dim, periodic):
diff -r 8aa3a4319b7c047a70f1eb0bc8d80fd645df0b14 -r 4ca701abb425577ab00ecd0e899d3a63e4c7418b yt/utilities/lib/pixelization_routines.pyx
--- a/yt/utilities/lib/pixelization_routines.pyx
+++ b/yt/utilities/lib/pixelization_routines.pyx
@@ -254,7 +254,7 @@
cdef int lc, lr, rc, rr
cdef np.float64_t lypx, rypx, lxpx, rxpx, overlap1, overlap2
# These are the temp vars we get from the arrays
- cdef np.float64_t oxsp, oysp, ozsp
+ cdef np.float64_t oxsp, oysp, ozsp
cdef np.float64_t xsp, ysp, zsp
cdef np.float64_t dxsp, dysp, dzsp
# Some periodicity helpers
@@ -303,7 +303,7 @@
# (lr) and then iterate up to "right column" (rc) and "uppeR row" (rr),
# depositing into them the data value. Overlap computes the relative
# overlap of a data value with a pixel.
- #
+ #
# NOTE ON ROWS AND COLUMNS:
#
# The way that images are plotting in matplotlib is somewhat different
@@ -871,6 +871,8 @@
np.ndarray[np.float64_t, ndim=2] field,
int index_offset = 0):
+ # This routine chooses the correct element sampler to interpolate field
+ # values at evenly spaced points along a sampling line
cdef np.float64_t *vertices
cdef np.float64_t *field_vals
cdef int nvertices = conn.shape[1]
@@ -955,8 +957,8 @@
if not sampler.check_inside(mapped_coord) and ci != conn.shape[0] - 1:
continue
elif not sampler.check_inside(mapped_coord):
- raise RuntimeError("It's impossible that the line point doesn't "
- "fall within any of the elements.")
+ raise ValueError("Check to see that both starting and ending line points "
+ "are within the domain of the mesh.")
plot_values[i] = sampler.sample_at_unit_point(mapped_coord, field_vals)
break
diff -r 8aa3a4319b7c047a70f1eb0bc8d80fd645df0b14 -r 4ca701abb425577ab00ecd0e899d3a63e4c7418b yt/visualization/base_plot_types.py
--- a/yt/visualization/base_plot_types.py
+++ b/yt/visualization/base_plot_types.py
@@ -83,7 +83,6 @@
def __init__(self, fsize, axrect, figure, axes):
"""Initialize PlotMPL class"""
- import pdb; pdb.set_trace()
import matplotlib.figure
self._plot_valid = True
if figure is None:
diff -r 8aa3a4319b7c047a70f1eb0bc8d80fd645df0b14 -r 4ca701abb425577ab00ecd0e899d3a63e4c7418b yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -661,7 +661,6 @@
_data_valid = False
def __init__(self, *args, **kwargs):
- import pdb; pdb.set_trace()
if self._frb_generator is None:
self._frb_generator = kwargs.pop("frb_generator")
if self._plot_type is None:
@@ -2020,15 +2019,7 @@
class LinePlot(PlotMPL):
r"""
- A factory function for
- :class:`yt.visualization.plot_window.AxisAlignedSlicePlot`
- and :class:`yt.visualization.plot_window.OffAxisSlicePlot` objects. This
- essentially allows for a single entry point to both types of slice plots,
- the distinction being determined by the specified normal vector to the
- slice.
-
- The returned plot object can be updated using one of the many helper
- functions defined in PlotWindow.
+ A class for constructing line plots
Parameters
----------
@@ -2037,7 +2028,7 @@
This is the dataset object corresponding to the
simulation output to be plotted.
fields : string
- The name of the field(s) to be plotted.
+ The name(s) of the field(s) to be plotted.
point1: tuple
Contains the coordinates of the first point for constructing the line
point2: tuple
https://bitbucket.org/yt_analysis/yt/commits/41338deb4c96/
Changeset: 41338deb4c96
User: Alex Lindsay
Date: 2017-06-05 23:20:39+00:00
Summary: Add show method, documentation, and answer test.
Affected #: 5 files
diff -r 4ca701abb425577ab00ecd0e899d3a63e4c7418b -r 41338deb4c9629c22d03b4f4fe6d6196617c09ff doc/source/cookbook/simple_plots.rst
--- a/doc/source/cookbook/simple_plots.rst
+++ b/doc/source/cookbook/simple_plots.rst
@@ -237,3 +237,11 @@
When creating movies of multiple outputs from the same simulation (see :ref:`time-series-analysis`), it can be helpful to include a timestamp and the physical scale of each individual output. This is simply achieved using the :ref:`annotate_timestamp() <annotate-timestamp>` and :ref:`annotate_scale() <annotate-scale>` callbacks on your plots. For more information about similar plot modifications using other callbacks, see the section on :ref:`Plot Modifications <callbacks>`.
.. yt_cookbook:: annotate_timestamp_and_scale.py
+
+Simple 1D Unstructured Mesh Line Plotting
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This script shows how to make a `LinePlot` through an `UnstructuredMesh`
+data-set. See :ref:`how-to-1d-unstructured-mesh` for more information.
+
+.. yt_cookbook:: simple_unstructured_1d.py
diff -r 4ca701abb425577ab00ecd0e899d3a63e4c7418b -r 41338deb4c9629c22d03b4f4fe6d6196617c09ff doc/source/visualizing/plots.rst
--- a/doc/source/visualizing/plots.rst
+++ b/doc/source/visualizing/plots.rst
@@ -30,7 +30,7 @@
in other environments as well:
.. code-block:: python
-
+
%matplotlib notebook
import yt
yt.toggle_interactivity()
@@ -943,6 +943,7 @@
# Save the image.
plot.save()
+
Customizing axis limits
~~~~~~~~~~~~~~~~~~~~~~~
@@ -1054,6 +1055,45 @@
# change only the first line
plot.set_line_property("linestyle", "--", 0)
+.. _how-to-1d-unstructured-mesh:
+
+1D Sampling on Unstructured Meshes
+----------------------------------
+
+YT has the ability to sample unstructured mesh data-sets along arbitrary lines
+and plot the result. You must supply five arguments to the `LinePlot`
+class. They are enumerated below:
+
+1. Data-set
+2. A list of fields or a single field you wish to plot
+3. The starting point of the sampling line. This should be a tuple of three
+ floats corresponding to the coordinates of the starting point
+4. The ending point of the sampling line. This should also be a tuple of three
+ floats
+5. The resolution of the sampling line. This is the number of sampling points
+ along the line, e.g. if 1000 is specified, then data will be sampled at
+ 1000 points evenly spaced between the starting and ending points.
+
+The below code snippet illustrates how this is done:
+
+.. python-script::
+
+ ds = yt.load(home + "/yt_data/SecondOrderTris/RZ_p_no_parts_do_nothing_bcs_cone_out.e", step=-1)
+ ln = yt.LinePlot(ds, [('all', 'v'), ('all', 'u')], (0, 0, 0), (0, 1, 0), 1000)
+ ln.save("first_test.png")
+
+You can also add plots to existing `LinePlot` instances with `add_plot` as shown
+below:
+
+.. python-script::
+
+ ln.add_plot(('all', 'p'), (0, 0, 0), (1, 1, 0), 1000)
+ ln.save("added_plot.png")
+
+Note that the beginning and end-points of multiple plots can be different. If
+working in an IPython Notebook, `LinePlot` also has the `show()` method.
+
+
.. _how-to-make-2d-profiles:
2D Phase Plots
diff -r 4ca701abb425577ab00ecd0e899d3a63e4c7418b -r 41338deb4c9629c22d03b4f4fe6d6196617c09ff tests/tests.yaml
--- a/tests/tests.yaml
+++ b/tests/tests.yaml
@@ -69,6 +69,7 @@
- yt/visualization/tests/test_mesh_slices.py:test_tri2
- yt/visualization/tests/test_mesh_slices.py:test_quad2
- yt/visualization/tests/test_mesh_slices.py:test_multi_region
+ - yt/visualization/tests/test_line_plots.py:test_line_plot
local_boxlib_004:
- yt/frontends/boxlib/tests/test_outputs.py:test_radadvect
diff -r 4ca701abb425577ab00ecd0e899d3a63e4c7418b -r 41338deb4c9629c22d03b4f4fe6d6196617c09ff yt/visualization/plot_container.py
--- a/yt/visualization/plot_container.py
+++ b/yt/visualization/plot_container.py
@@ -230,10 +230,10 @@
for field in self.data_source._determine_fields(fields):
if log:
if linthresh is not None:
- if not linthresh > 0.:
+ if not linthresh > 0.:
raise ValueError('\"linthresh\" must be positive')
self._field_transform[field] = symlog_transform
- self._field_transform[field].func = linthresh
+ self._field_transform[field].func = linthresh
else:
self._field_transform[field] = log_transform
else:
@@ -306,7 +306,7 @@
if field == 'all', applies to all plots.
color : string or RGBA tuple (optional)
if set, set the background color to this color
- if unset, background color is set to the bottom value of
+ if unset, background color is set to the bottom value of
the color map
"""
@@ -402,7 +402,7 @@
def set_cbar_minorticks(self, field, state):
"""turn colorbar minor ticks on or off in the current plot
- Displaying minor ticks reduces performance; turn them off
+ Displaying minor ticks reduces performance; turn them off
using set_cbar_minorticks('all', 'off') if drawing speed is a problem.
Parameters
@@ -471,7 +471,7 @@
----------
font_dict : dict
- A dict of keyword parameters to be passed to
+ A dict of keyword parameters to be passed to
:class:`matplotlib.font_manager.FontProperties`.
Possible keys include:
diff -r 4ca701abb425577ab00ecd0e899d3a63e4c7418b -r 41338deb4c9629c22d03b4f4fe6d6196617c09ff yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -67,7 +67,7 @@
YTPlotCallbackError, \
YTDataTypeUnsupported, \
YTInvalidFieldType
-from yt.geometry.coordinates.cartesian_coordinates import CartesianCoordinateHandler
+from yt.extern.six.moves import builtins
MPL_VERSION = LooseVersion(matplotlib.__version__)
@@ -1119,8 +1119,7 @@
----------
field : string, field tuple, or list of strings or field tuples (optional)
- The name of the field(s) that we want to show
- the colorbar.
+ The name of the field(s) that we want to show the colorbar.
"""
if field is None:
field = self.fields
@@ -2040,9 +2039,10 @@
def __init__(self, ds, fields, point1, point2, resolution,
figure_size=5., aspect=None, fontsize=18.):
- handler = CartesianCoordinateHandler(ds)
- if not isinstance(fields, list):
- fields = [fields]
+ """
+ Sets up figure and axes
+ """
+ self.handler = ds.coordinates
if aspect is None:
aspect = 1.
fontscale = fontsize / 18.
@@ -2082,9 +2082,30 @@
y_frac_widths[1],
)
- # super(LinePlot, self).__init__(fsize, axrect, None, None)
super(LinePlot, self).__init__(size, axrect, None, None)
+ self.add_plot(fields, point1, point2, resolution)
+
+ def add_plot(self, fields, point1, point2, resolution):
+ r"""
+ Used to add plots to the figure
+ """
+ if not isinstance(fields, list):
+ fields = [fields]
for field in fields:
- x, y = handler.line_plot(field, np.asarray(point1, dtype='float64'),
+ x, y = self.handler.line_plot(field, np.asarray(point1, dtype='float64'),
np.asarray(point2, dtype='float64'), resolution)
self.axes.plot(x, y)
+
+ def show(self):
+ r"""This will send any existing plots to the IPython notebook.
+
+ 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
+ notebook for display.
+
+ If yt can't determine if it's inside an IPython session, it will raise
+ YTNotInsideNotebook.
+ """
+ if "__IPYTHON__" in dir(builtins):
+ from IPython.display import display
+ display(self)
https://bitbucket.org/yt_analysis/yt/commits/1138d932bf4b/
Changeset: 1138d932bf4b
User: Alex Lindsay
Date: 2017-06-06 13:54:35+00:00
Summary: Add YTNotInsideNotebook exceptions
Affected #: 2 files
diff -r 41338deb4c9629c22d03b4f4fe6d6196617c09ff -r 1138d932bf4b92e02475b76b9eaa3249b0a3bd65 yt/visualization/plot_container.py
--- a/yt/visualization/plot_container.py
+++ b/yt/visualization/plot_container.py
@@ -657,6 +657,8 @@
if "__IPYTHON__" in dir(builtins):
from IPython.display import display
display(self)
+ else:
+ raise YTNotInsideNotebook
@validate_plot
def display(self, name=None, mpl_kwargs=None):
diff -r 41338deb4c9629c22d03b4f4fe6d6196617c09ff -r 1138d932bf4b92e02475b76b9eaa3249b0a3bd65 yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -66,7 +66,8 @@
YTUnitConversionError, \
YTPlotCallbackError, \
YTDataTypeUnsupported, \
- YTInvalidFieldType
+ YTInvalidFieldType, \
+ YTNotInsideNotebook
from yt.extern.six.moves import builtins
MPL_VERSION = LooseVersion(matplotlib.__version__)
@@ -2109,3 +2110,5 @@
if "__IPYTHON__" in dir(builtins):
from IPython.display import display
display(self)
+ else:
+ raise YTNotInsideNotebook
https://bitbucket.org/yt_analysis/yt/commits/07ed5d34c300/
Changeset: 07ed5d34c300
User: Alex Lindsay
Date: 2017-06-06 15:02:46+00:00
Summary: Add legend and label methods
Affected #: 3 files
diff -r 1138d932bf4b92e02475b76b9eaa3249b0a3bd65 -r 07ed5d34c30032208c27d129cce8ff1d61f8da8c doc/source/cookbook/simple_plots.rst
--- a/doc/source/cookbook/simple_plots.rst
+++ b/doc/source/cookbook/simple_plots.rst
@@ -241,7 +241,7 @@
Simple 1D Unstructured Mesh Line Plotting
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-This script shows how to make a `LinePlot` through an `UnstructuredMesh`
+This script shows how to make a ``LinePlot`` through an ``UnstructuredMesh``
data-set. See :ref:`how-to-1d-unstructured-mesh` for more information.
.. yt_cookbook:: simple_unstructured_1d.py
diff -r 1138d932bf4b92e02475b76b9eaa3249b0a3bd65 -r 07ed5d34c30032208c27d129cce8ff1d61f8da8c doc/source/visualizing/plots.rst
--- a/doc/source/visualizing/plots.rst
+++ b/doc/source/visualizing/plots.rst
@@ -1061,7 +1061,7 @@
----------------------------------
YT has the ability to sample unstructured mesh data-sets along arbitrary lines
-and plot the result. You must supply five arguments to the `LinePlot`
+and plot the result. You must supply five arguments to the ``LinePlot``
class. They are enumerated below:
1. Data-set
@@ -1082,7 +1082,7 @@
ln = yt.LinePlot(ds, [('all', 'v'), ('all', 'u')], (0, 0, 0), (0, 1, 0), 1000)
ln.save("first_test.png")
-You can also add plots to existing `LinePlot` instances with `add_plot` as shown
+You can also add plots to existing ``LinePlot`` instances with ``add_plot`` as shown
below:
.. python-script::
@@ -1091,7 +1091,30 @@
ln.save("added_plot.png")
Note that the beginning and end-points of multiple plots can be different. If
-working in an IPython Notebook, `LinePlot` also has the `show()` method.
+working in an IPython Notebook, ``LinePlot`` also has the ``show()`` method.
+
+You can also create legends and add x and y axes labels to these 1D sampling
+plots. The legend process takes two steps:
+
+1. When instantiating the ``LinePlot`` or invoking ``add_plot`` pass a dictionary of
+ labels with keys corresponding to the field names
+2. Call the ``LinePlot`` ``add_legend`` method
+
+X- and Y- axis labels are set simply with ``set_xlabel`` and ``set_ylabel``
+methods. The below code snippet combines all the features we've discussed:
+
+.. python-script::
+
+ import yt
+ ds = yt.load("SecondOrderTris/RZ_p_no_parts_do_nothing_bcs_cone_out.e", step=-1)
+ ln = yt.LinePlot(ds, [('all', 'v'), ('all', 'u')], (0, 0, 0), (0, 1, 0), 1000,
+ labels={('all', 'u') : r"u$_s$", ('all', 'v') : r"v$_s$"})
+ ln.add_plot([('all', 'v'), ('all', 'u')], (0, 0, 0), (1, 1, 0), 1000,
+ labels={('all', 'u') : r"u$_l$", ('all', 'v') : r"v$_l$"})
+ ln.add_legend()
+ ln.set_xlabel("Arc Length (cm)")
+ ln.set_ylabel(r"Velocity (m s$^{-1}$)")
+ ln.save("line_plot.eps")
.. _how-to-make-2d-profiles:
diff -r 1138d932bf4b92e02475b76b9eaa3249b0a3bd65 -r 07ed5d34c30032208c27d129cce8ff1d61f8da8c yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -2039,7 +2039,7 @@
"""
def __init__(self, ds, fields, point1, point2, resolution,
- figure_size=5., aspect=None, fontsize=18.):
+ figure_size=5., aspect=None, fontsize=18., labels={}):
"""
Sets up figure and axes
"""
@@ -2084,18 +2084,35 @@
)
super(LinePlot, self).__init__(size, axrect, None, None)
- self.add_plot(fields, point1, point2, resolution)
+ self.add_plot(fields, point1, point2, resolution, labels=labels)
+ self._xlabel = ("Arc Length [Arb. Units]", 14.)
+ self._ylabel = ("Field Value [Arb. Units]", 14.)
- def add_plot(self, fields, point1, point2, resolution):
+ def add_plot(self, fields, point1, point2, resolution, labels={}):
r"""
Used to add plots to the figure
"""
if not isinstance(fields, list):
fields = [fields]
for field in fields:
+ if field not in labels:
+ labels[field] = field[1]
x, y = self.handler.line_plot(field, np.asarray(point1, dtype='float64'),
np.asarray(point2, dtype='float64'), resolution)
- self.axes.plot(x, y)
+ self.axes.plot(x, y, label=labels[field])
+
+ def add_legend(self):
+ self.axes.legend()
+
+ def set_xlabel(self, label, fontsize=14):
+ self._xlabel = (label, fontsize)
+
+ def set_ylabel(self, label, fontsize=14):
+ self._ylabel = (label, fontsize)
+
+ def _setup_plot(self):
+ self.axes.set_xlabel(self._xlabel[0], fontsize=self._xlabel[1])
+ self.axes.set_ylabel(self._ylabel[0], fontsize=self._ylabel[1])
def show(self):
r"""This will send any existing plots to the IPython notebook.
@@ -2107,8 +2124,13 @@
If yt can't determine if it's inside an IPython session, it will raise
YTNotInsideNotebook.
"""
+ self._setup_plot()
if "__IPYTHON__" in dir(builtins):
from IPython.display import display
display(self)
else:
raise YTNotInsideNotebook
+
+ def save(self, name):
+ self._setup_plot()
+ super(LinePlot, self).save(name)
https://bitbucket.org/yt_analysis/yt/commits/cdc638ea224d/
Changeset: cdc638ea224d
User: Alex Lindsay
Date: 2017-06-06 15:06:36+00:00
Summary: Add new files
Affected #: 2 files
diff -r 07ed5d34c30032208c27d129cce8ff1d61f8da8c -r cdc638ea224dbb4b404a358c83d10a151f6a7954 doc/source/cookbook/simple_unstructured_1d.py
--- /dev/null
+++ b/doc/source/cookbook/simple_unstructured_1d.py
@@ -0,0 +1,24 @@
+import yt
+
+# Load the dataset
+ds = yt.load("SecondOrderTris/RZ_p_no_parts_do_nothing_bcs_cone_out.e", step=-1)
+
+# Create a line plot of the variables 'u' and 'v' with 1000 sampling points evenly spaced
+# between the coordinates (0, 0, 0) and (0, 1, 0)
+ln = yt.LinePlot(ds, [('all', 'v'), ('all', 'u')], (0, 0, 0), (0, 1, 0), 1000)
+
+# Add a plot to the LinePlot instance of the variable 'p' with 100 sampling points evenly
+# spaced between (0.5, 0, 0) and (1, 1, 0). Also create a label for p
+ln.add_plot(('all', 'p'), (0.5, 0, 0), (1, 1, 0), 100, labels={('all', 'p') : 'p'})
+
+# Add a legend
+ln.add_legend()
+
+# Set xlabel
+ln.set_xlabel("Arc Length (cm)")
+
+# Set ylabel
+ln.set_ylabel("Field Values [Arb. Units]")
+
+# Save the line plot. Note that the save string is a required argument
+ln.save("line_plot.png")
diff -r 07ed5d34c30032208c27d129cce8ff1d61f8da8c -r cdc638ea224dbb4b404a358c83d10a151f6a7954 yt/visualization/tests/test_line_plots.py
--- /dev/null
+++ b/yt/visualization/tests/test_line_plots.py
@@ -0,0 +1,41 @@
+"""
+Tests for making line plots
+
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (c) 2017, yt Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+import yt
+from yt.utilities.answer_testing.framework import \
+ requires_ds, \
+ data_dir_load, \
+ GenericImageTest
+
+def setup():
+ """Test specific setup."""
+ from yt.config import ytcfg
+ ytcfg["yt", "__withintesting"] = "True"
+
+def compare(ds, fields, point1, point2, resolution, test_prefix, decimals=12):
+ def line_plot(filename_prefix):
+ ln = yt.LinePlot(ds, fields, point1, point2, resolution)
+ image_file = ln.save(filename_prefix)
+ return image_file
+
+ line_plot.__name__ = "line_{}".format(test_prefix)
+ test = GenericImageTest(ds, line_plot, decimals)
+ test.prefix = test_prefix
+ return test
+
+tri2 = "SecondOrderTris/RZ_p_no_parts_do_nothing_bcs_cone_out.e"
+
+ at requires_ds(tri2)
+def test_line_plot():
+ ds = data_dir_load(tri2, kwargs={'step':-1})
+ fields = [field for field in ds.field_list if field[0] == 'all']
+ yield compare(ds, fields, (0, 0, 0), (1, 1, 0), 1000, "answers_line_plot")
https://bitbucket.org/yt_analysis/yt/commits/583f58085559/
Changeset: 583f58085559
User: Alex Lindsay
Date: 2017-06-08 20:17:00+00:00
Summary: No other failures. Increment unstructured counter.
Affected #: 1 file
diff -r cdc638ea224dbb4b404a358c83d10a151f6a7954 -r 583f5808555944565a6de1ad073ac5141cc98ef2 tests/tests.yaml
--- a/tests/tests.yaml
+++ b/tests/tests.yaml
@@ -64,7 +64,7 @@
- yt/analysis_modules/photon_simulator/tests/test_spectra.py
- yt/analysis_modules/photon_simulator/tests/test_sloshing.py
- local_unstructured_005:
+ local_unstructured_006:
- yt/visualization/volume_rendering/tests/test_mesh_render.py
- yt/visualization/tests/test_mesh_slices.py:test_tri2
- yt/visualization/tests/test_mesh_slices.py:test_quad2
https://bitbucket.org/yt_analysis/yt/commits/07c8c38b97de/
Changeset: 07c8c38b97de
User: ngoldbaum
Date: 2017-06-26 17:18:42+00:00
Summary: make LinePlot work with cartesian AMR data as well
Affected #: 3 files
diff -r 583f5808555944565a6de1ad073ac5141cc98ef2 -r 07c8c38b97deee212c083c3e96cd18fd15be2d0a yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -22,6 +22,7 @@
cartesian_to_cylindrical, \
cylindrical_to_cartesian
from yt.funcs import mylog
+from yt.units.yt_array import uvstack
from yt.utilities.lib.pixelization_routines import \
pixelize_element_mesh, pixelize_off_axis_cartesian, \
pixelize_cartesian, pixelize_cartesian_nodal, \
@@ -29,6 +30,26 @@
from yt.data_objects.unstructured_mesh import SemiStructuredMesh
from yt.utilities.nodal_data_utils import get_nodal_data
+def _sample_ray(ray, resolution, field):
+ start_point = ray.start_point
+ end_point = ray.end_point
+ sample_dr = (end_point - start_point)/(resolution-1)
+ sample_points = [np.arange(resolution)*sample_dr[i] for i in
+ range(ray.ds.dimensionality)]
+ sample_points = uvstack(sample_points).T
+ ray_coordinates = uvstack([ray[d] for d in 'xyz']).T
+ ray_dds = uvstack([ray['d'+d] for d in 'xyz']).T
+ field_values = np.zeros(resolution)
+ ray_field = ray[field]
+ for i, sample_point in enumerate(sample_points):
+ ray_contains = ((sample_point >= (ray_coordinates - ray_dds/2)) &
+ (sample_point <= (ray_coordinates + ray_dds/2)))
+ ray_contains = ray_contains.all(axis=-1)
+ wh = np.where(ray_contains)[0]
+ if wh.shape != (1,):
+ raise RuntimeError
+ field_values[i] = ray_field[wh]
+ return sample_points, field_values
class CartesianCoordinateHandler(CoordinateHandler):
name = "cartesian"
@@ -165,12 +186,11 @@
end_point,
resolution, field_data,
index_offset=offset)
-
- return arc_length, plot_values
+ else:
+ ray = self.ds.ray(start_point, end_point)
+ arc_length, plot_values = _sample_ray(ray, resolution, field)
+ return arc_length, plot_values
- else:
- raise NotImplementedError("Currently line plotting routines have only "
- "been implemented for unstructured meshes.")
def _ortho_pixelize(self, data_source, field, bounds, size, antialias,
diff -r 583f5808555944565a6de1ad073ac5141cc98ef2 -r 07c8c38b97deee212c083c3e96cd18fd15be2d0a yt/utilities/lib/fixed_interpolator.pxd
--- a/yt/utilities/lib/fixed_interpolator.pxd
+++ b/yt/utilities/lib/fixed_interpolator.pxd
@@ -30,4 +30,3 @@
np.float64_t vl[3], np.float64_t dds[3],
np.float64_t x, np.float64_t y, np.float64_t z,
int vind1, int vind2) nogil
-
diff -r 583f5808555944565a6de1ad073ac5141cc98ef2 -r 07c8c38b97deee212c083c3e96cd18fd15be2d0a yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -14,6 +14,7 @@
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------
import numpy as np
+import os
import matplotlib
import types
import six
@@ -45,7 +46,8 @@
YTSpatialPlotDataset
from yt.funcs import \
mylog, iterable, ensure_list, \
- fix_axis, fix_unitary
+ fix_axis, fix_unitary, ensure_dir, \
+ get_image_suffix
from yt.units.unit_object import \
Unit
from yt.units.unit_registry import \
@@ -2017,6 +2019,13 @@
return AxisAlignedSlicePlot(ds, normal, fields, *args, **kwargs)
+def _validate_point(point, ds):
+ if not iterable(point):
+ raise RuntimeError
+ if not isinstance(point, YTArray):
+ point = ds.arr(point, 'code_length')
+ return point
+
class LinePlot(PlotMPL):
r"""
A class for constructing line plots
@@ -2029,21 +2038,24 @@
simulation output to be plotted.
fields : string
The name(s) of the field(s) to be plotted.
- point1: tuple
- Contains the coordinates of the first point for constructing the line
- point2: tuple
- Contains the coordinates of the second point for constructing the line
+ start_point: n-element list, tuple, ndarray, or YTArray
+ Contains the coordinates of the first point for constructing the line.
+ Must contain n elements where n is the dimensionality of the dataset.
+ end_point: n-element list, tuple, ndarray, or YTArray
+ Contains the coordinates of the first point for constructing the line.
+ Must contain n elements where n is the dimensionality of the dataset.
resolution: int
- How many points to sample between point1 and point2 for constructing
+ How many points to sample between start_point and end_point for constructing
the line plot
"""
- def __init__(self, ds, fields, point1, point2, resolution,
+ def __init__(self, ds, fields, start_point, end_point, resolution,
figure_size=5., aspect=None, fontsize=18., labels={}):
"""
Sets up figure and axes
"""
self.handler = ds.coordinates
+ self.ds = ds
if aspect is None:
aspect = 1.
fontscale = fontsize / 18.
@@ -2083,12 +2095,16 @@
y_frac_widths[1],
)
+ start_point = _validate_point(start_point, ds)
+ end_point = _validate_point(end_point, ds)
+
super(LinePlot, self).__init__(size, axrect, None, None)
- self.add_plot(fields, point1, point2, resolution, labels=labels)
+
+ self.add_plot(fields, start_point, end_point, resolution, labels=labels)
self._xlabel = ("Arc Length [Arb. Units]", 14.)
self._ylabel = ("Field Value [Arb. Units]", 14.)
- def add_plot(self, fields, point1, point2, resolution, labels={}):
+ def add_plot(self, fields, start_point, end_point, resolution, labels={}):
r"""
Used to add plots to the figure
"""
@@ -2097,8 +2113,8 @@
for field in fields:
if field not in labels:
labels[field] = field[1]
- x, y = self.handler.line_plot(field, np.asarray(point1, dtype='float64'),
- np.asarray(point2, dtype='float64'), resolution)
+ x, y = self.handler.line_plot(
+ field, start_point, end_point, resolution)
self.axes.plot(x, y, label=labels[field])
def add_legend(self):
@@ -2131,6 +2147,16 @@
else:
raise YTNotInsideNotebook
- def save(self, name):
+ def save(self, name=None, mpl_kwargs=None):
self._setup_plot()
+ if name is None:
+ name = str(self.ds)
+ name = os.path.expanduser(name)
+ if name[-1] == os.sep and not os.path.isdir(name):
+ ensure_dir(name)
+ if os.path.isdir(name) and name != str(self.ds):
+ name = name + (os.sep if name[-1] != os.sep else '') + str(self.ds)
+ suffix = get_image_suffix(name)
+ if suffix == '':
+ name = name + '_LinePlot.png'
super(LinePlot, self).save(name)
https://bitbucket.org/yt_analysis/yt/commits/db0f96ce2051/
Changeset: db0f96ce2051
User: Alex Lindsay
Date: 2017-06-26 17:31:14+00:00
Summary: Address components of Nathan review.
- Add additional documentation
- Change python-script to code-block python
- Remove empty dictionary as default argument
- Add test for class methods
Affected #: 4 files
diff -r 583f5808555944565a6de1ad073ac5141cc98ef2 -r db0f96ce205128988d5c67e860a4c88ff96de237 doc/source/visualizing/plots.rst
--- a/doc/source/visualizing/plots.rst
+++ b/doc/source/visualizing/plots.rst
@@ -14,8 +14,8 @@
The :class:`~yt.visualization.plot_window.PlotWindow` interface is useful for
taking a quick look at simulation outputs. Simple mechanisms exist for making
-plots of slices, projections, 1D profiles, and 2D profiles (phase plots), all of
-which are described below.
+plots of slices, projections, 1D spatial line plots, 1D profiles, and 2D
+profiles (phase plots), all of which are described below.
.. _viewing-plots:
@@ -1064,34 +1064,36 @@
and plot the result. You must supply five arguments to the ``LinePlot``
class. They are enumerated below:
-1. Data-set
+1. Dataset
2. A list of fields or a single field you wish to plot
-3. The starting point of the sampling line. This should be a tuple of three
- floats corresponding to the coordinates of the starting point
-4. The ending point of the sampling line. This should also be a tuple of three
- floats
+3. The starting point of the sampling line. This should be an n-element list, tuple,
+ ndarray, or YTArray with the elements corresponding to the coordinates of the
+ starting point. (n should equal the dimension of the dataset)
+4. The ending point of the sampling line. This should also be an n-element list, tuple,
+ ndarray, or YTArray with the elements corresponding to the coordinates of the
+ ending point.
5. The resolution of the sampling line. This is the number of sampling points
along the line, e.g. if 1000 is specified, then data will be sampled at
1000 points evenly spaced between the starting and ending points.
The below code snippet illustrates how this is done:
-.. python-script::
+.. code-block:: python
- ds = yt.load(home + "/yt_data/SecondOrderTris/RZ_p_no_parts_do_nothing_bcs_cone_out.e", step=-1)
+ ds = yt.load("SecondOrderTris/RZ_p_no_parts_do_nothing_bcs_cone_out.e", step=-1)
ln = yt.LinePlot(ds, [('all', 'v'), ('all', 'u')], (0, 0, 0), (0, 1, 0), 1000)
ln.save("first_test.png")
You can also add plots to existing ``LinePlot`` instances with ``add_plot`` as shown
below:
-.. python-script::
+.. code-block:: python
ln.add_plot(('all', 'p'), (0, 0, 0), (1, 1, 0), 1000)
ln.save("added_plot.png")
Note that the beginning and end-points of multiple plots can be different. If
-working in an IPython Notebook, ``LinePlot`` also has the ``show()`` method.
+working in an Jupyter Notebook, ``LinePlot`` also has the ``show()`` method.
You can also create legends and add x and y axes labels to these 1D sampling
plots. The legend process takes two steps:
@@ -1114,7 +1116,7 @@
ln.add_legend()
ln.set_xlabel("Arc Length (cm)")
ln.set_ylabel(r"Velocity (m s$^{-1}$)")
- ln.save("line_plot.eps")
+ ln.save("line_plot.png")
.. _how-to-make-2d-profiles:
diff -r 583f5808555944565a6de1ad073ac5141cc98ef2 -r db0f96ce205128988d5c67e860a4c88ff96de237 yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -67,7 +67,7 @@
def pixelize(self, dimension, data_source, field, bounds, size,
antialias = True, periodic = True):
"""
- Method for pixelizing grid data sets in preparation for
+ Method for pixelizing datasets in preparation for
two-dimensional image plots. Relies on several sampling
routines written in cython
"""
@@ -128,7 +128,7 @@
def line_plot(self, field, start_point, end_point, resolution):
"""
- Method for sampling grid data sets along a line in preparation for
+ Method for sampling datasets along a line in preparation for
one-dimensional line plots. For UnstructuredMesh, relies on a
sampling routine written in cython
"""
diff -r 583f5808555944565a6de1ad073ac5141cc98ef2 -r db0f96ce205128988d5c67e860a4c88ff96de237 yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -2039,7 +2039,7 @@
"""
def __init__(self, ds, fields, point1, point2, resolution,
- figure_size=5., aspect=None, fontsize=18., labels={}):
+ figure_size=5., aspect=None, fontsize=18., labels=None):
"""
Sets up figure and axes
"""
@@ -2088,10 +2088,29 @@
self._xlabel = ("Arc Length [Arb. Units]", 14.)
self._ylabel = ("Field Value [Arb. Units]", 14.)
- def add_plot(self, fields, point1, point2, resolution, labels={}):
+ def add_plot(self, fields, point1, point2, resolution, labels=None):
r"""
Used to add plots to the figure
+
+ parameters
+ ----------
+
+ fields : A single field tuple or a list of field tuples
+ The fields to plot
+ start_point : list, tuple, ndarray, or YTArray
+ The coordinates of the start point of the line plot. Length of
+ iterable should be equal to the number of dimensions of the
+ dataset
+ end_point : list, tuple, ndarray, or YTArray
+ The coordinates of the end point of the line plot. Length of
+ iterable should be equal to the number of dimensions of the
+ dataset
+ resolution : integer
+ How many points to sample between start_point and end_point for
+ constructing the line plot
"""
+ if labels is None:
+ labels = {}
if not isinstance(fields, list):
fields = [fields]
for field in fields:
@@ -2102,15 +2121,38 @@
self.axes.plot(x, y, label=labels[field])
def add_legend(self):
+ r"""
+ Adds a legend to the `LinePlot` instance
+ """
self.axes.legend()
def set_xlabel(self, label, fontsize=14):
+ r"""
+ Method for setting the x-label
+
+ parameters
+ ----------
+ label : string
+ The label for the x-axis
+ """
self._xlabel = (label, fontsize)
def set_ylabel(self, label, fontsize=14):
+ r"""
+ Method for setting the y-label
+
+ parameters
+ ----------
+ label : string
+ The label for the y-axis
+ """
self._ylabel = (label, fontsize)
def _setup_plot(self):
+ r"""
+ Private method called from either `show` or `save`. Sets x and
+ y labels
+ """
self.axes.set_xlabel(self._xlabel[0], fontsize=self._xlabel[1])
self.axes.set_ylabel(self._ylabel[0], fontsize=self._ylabel[1])
@@ -2132,5 +2174,14 @@
raise YTNotInsideNotebook
def save(self, name):
+ r"""
+ Method for saving line plots. No default so user should specify
+ extension
+
+ parameters
+ ----------
+ name : string
+ Name to save file to
+ """
self._setup_plot()
super(LinePlot, self).save(name)
diff -r 583f5808555944565a6de1ad073ac5141cc98ef2 -r db0f96ce205128988d5c67e860a4c88ff96de237 yt/visualization/tests/test_line_plots.py
--- a/yt/visualization/tests/test_line_plots.py
+++ b/yt/visualization/tests/test_line_plots.py
@@ -39,3 +39,23 @@
ds = data_dir_load(tri2, kwargs={'step':-1})
fields = [field for field in ds.field_list if field[0] == 'all']
yield compare(ds, fields, (0, 0, 0), (1, 1, 0), 1000, "answers_line_plot")
+
+def test_line_plot_methods():
+ # Perform I/O in safe place instead of yt main dir
+ tmpdir = tempfile.mkdtemp()
+ curdir = os.getcwd()
+ os.chdir(tmpdir)
+
+ # hexahedral ds
+ ds = fake_hexahedral_ds()
+
+ ln = yt.LinePlot(ds, ds.field_list, (0, 0, -.25), (0, 0, .25), 100)
+ ln.add_plot(ds.field_list, (0, 0, -.25), (0, 0, .25), 100)
+ ln.add_legend()
+ ln.set_xlabel("Test x label")
+ ln.set_ylabel("Test y label")
+ ln.save()
+
+ os.chdir(curdir)
+ # clean up
+ shutil.rmtree(tmpdir)
https://bitbucket.org/yt_analysis/yt/commits/71a0b2eea9a2/
Changeset: 71a0b2eea9a2
User: ngoldbaum
Date: 2017-06-26 19:10:52+00:00
Summary: Merge commit 'refs/pull/1440/head' of https://github.com/yt-project/yt into line_plot_plus_quad9
Affected #: 4 files
diff -r 07c8c38b97deee212c083c3e96cd18fd15be2d0a -r 71a0b2eea9a242e99ea74b55fc2d8badd254c720 doc/source/visualizing/plots.rst
--- a/doc/source/visualizing/plots.rst
+++ b/doc/source/visualizing/plots.rst
@@ -14,8 +14,8 @@
The :class:`~yt.visualization.plot_window.PlotWindow` interface is useful for
taking a quick look at simulation outputs. Simple mechanisms exist for making
-plots of slices, projections, 1D profiles, and 2D profiles (phase plots), all of
-which are described below.
+plots of slices, projections, 1D spatial line plots, 1D profiles, and 2D
+profiles (phase plots), all of which are described below.
.. _viewing-plots:
@@ -1064,34 +1064,36 @@
and plot the result. You must supply five arguments to the ``LinePlot``
class. They are enumerated below:
-1. Data-set
+1. Dataset
2. A list of fields or a single field you wish to plot
-3. The starting point of the sampling line. This should be a tuple of three
- floats corresponding to the coordinates of the starting point
-4. The ending point of the sampling line. This should also be a tuple of three
- floats
+3. The starting point of the sampling line. This should be an n-element list, tuple,
+ ndarray, or YTArray with the elements corresponding to the coordinates of the
+ starting point. (n should equal the dimension of the dataset)
+4. The ending point of the sampling line. This should also be an n-element list, tuple,
+ ndarray, or YTArray with the elements corresponding to the coordinates of the
+ ending point.
5. The resolution of the sampling line. This is the number of sampling points
along the line, e.g. if 1000 is specified, then data will be sampled at
1000 points evenly spaced between the starting and ending points.
The below code snippet illustrates how this is done:
-.. python-script::
+.. code-block:: python
- ds = yt.load(home + "/yt_data/SecondOrderTris/RZ_p_no_parts_do_nothing_bcs_cone_out.e", step=-1)
+ ds = yt.load("SecondOrderTris/RZ_p_no_parts_do_nothing_bcs_cone_out.e", step=-1)
ln = yt.LinePlot(ds, [('all', 'v'), ('all', 'u')], (0, 0, 0), (0, 1, 0), 1000)
ln.save("first_test.png")
You can also add plots to existing ``LinePlot`` instances with ``add_plot`` as shown
below:
-.. python-script::
+.. code-block:: python
ln.add_plot(('all', 'p'), (0, 0, 0), (1, 1, 0), 1000)
ln.save("added_plot.png")
Note that the beginning and end-points of multiple plots can be different. If
-working in an IPython Notebook, ``LinePlot`` also has the ``show()`` method.
+working in an Jupyter Notebook, ``LinePlot`` also has the ``show()`` method.
You can also create legends and add x and y axes labels to these 1D sampling
plots. The legend process takes two steps:
@@ -1114,7 +1116,7 @@
ln.add_legend()
ln.set_xlabel("Arc Length (cm)")
ln.set_ylabel(r"Velocity (m s$^{-1}$)")
- ln.save("line_plot.eps")
+ ln.save("line_plot.png")
.. _how-to-make-2d-profiles:
diff -r 07c8c38b97deee212c083c3e96cd18fd15be2d0a -r 71a0b2eea9a242e99ea74b55fc2d8badd254c720 yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -88,7 +88,7 @@
def pixelize(self, dimension, data_source, field, bounds, size,
antialias = True, periodic = True):
"""
- Method for pixelizing grid data sets in preparation for
+ Method for pixelizing datasets in preparation for
two-dimensional image plots. Relies on several sampling
routines written in cython
"""
@@ -149,7 +149,7 @@
def line_plot(self, field, start_point, end_point, resolution):
"""
- Method for sampling grid data sets along a line in preparation for
+ Method for sampling datasets along a line in preparation for
one-dimensional line plots. For UnstructuredMesh, relies on a
sampling routine written in cython
"""
diff -r 07c8c38b97deee212c083c3e96cd18fd15be2d0a -r 71a0b2eea9a242e99ea74b55fc2d8badd254c720 yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -2050,7 +2050,7 @@
"""
def __init__(self, ds, fields, start_point, end_point, resolution,
- figure_size=5., aspect=None, fontsize=18., labels={}):
+ figure_size=5., aspect=None, fontsize=18., labels=None):
"""
Sets up figure and axes
"""
@@ -2104,10 +2104,29 @@
self._xlabel = ("Arc Length [Arb. Units]", 14.)
self._ylabel = ("Field Value [Arb. Units]", 14.)
- def add_plot(self, fields, start_point, end_point, resolution, labels={}):
+ def add_plot(self, fields, start_point, end_point, resolution, labels=None):
r"""
Used to add plots to the figure
+
+ parameters
+ ----------
+
+ fields : A single field tuple or a list of field tuples
+ The fields to plot
+ start_point : list, tuple, ndarray, or YTArray
+ The coordinates of the start point of the line plot. Length of
+ iterable should be equal to the number of dimensions of the
+ dataset
+ end_point : list, tuple, ndarray, or YTArray
+ The coordinates of the end point of the line plot. Length of
+ iterable should be equal to the number of dimensions of the
+ dataset
+ resolution : integer
+ How many points to sample between start_point and end_point for
+ constructing the line plot
"""
+ if labels is None:
+ labels = {}
if not isinstance(fields, list):
fields = [fields]
for field in fields:
@@ -2118,15 +2137,38 @@
self.axes.plot(x, y, label=labels[field])
def add_legend(self):
+ r"""
+ Adds a legend to the `LinePlot` instance
+ """
self.axes.legend()
def set_xlabel(self, label, fontsize=14):
+ r"""
+ Method for setting the x-label
+
+ parameters
+ ----------
+ label : string
+ The label for the x-axis
+ """
self._xlabel = (label, fontsize)
def set_ylabel(self, label, fontsize=14):
+ r"""
+ Method for setting the y-label
+
+ parameters
+ ----------
+ label : string
+ The label for the y-axis
+ """
self._ylabel = (label, fontsize)
def _setup_plot(self):
+ r"""
+ Private method called from either `show` or `save`. Sets x and
+ y labels
+ """
self.axes.set_xlabel(self._xlabel[0], fontsize=self._xlabel[1])
self.axes.set_ylabel(self._ylabel[0], fontsize=self._ylabel[1])
@@ -2148,6 +2190,17 @@
raise YTNotInsideNotebook
def save(self, name=None, mpl_kwargs=None):
+ r"""
+ Method for saving line plots. No default so user should specify
+ extension
+
+ parameters
+ ----------
+ name : string
+ Name to save file to
+ mpl_kwargs: dict
+ A dictionary of keywoard arguments to pass to matplotlib
+ """
self._setup_plot()
if name is None:
name = str(self.ds)
diff -r 07c8c38b97deee212c083c3e96cd18fd15be2d0a -r 71a0b2eea9a242e99ea74b55fc2d8badd254c720 yt/visualization/tests/test_line_plots.py
--- a/yt/visualization/tests/test_line_plots.py
+++ b/yt/visualization/tests/test_line_plots.py
@@ -39,3 +39,23 @@
ds = data_dir_load(tri2, kwargs={'step':-1})
fields = [field for field in ds.field_list if field[0] == 'all']
yield compare(ds, fields, (0, 0, 0), (1, 1, 0), 1000, "answers_line_plot")
+
+def test_line_plot_methods():
+ # Perform I/O in safe place instead of yt main dir
+ tmpdir = tempfile.mkdtemp()
+ curdir = os.getcwd()
+ os.chdir(tmpdir)
+
+ # hexahedral ds
+ ds = fake_hexahedral_ds()
+
+ ln = yt.LinePlot(ds, ds.field_list, (0, 0, -.25), (0, 0, .25), 100)
+ ln.add_plot(ds.field_list, (0, 0, -.25), (0, 0, .25), 100)
+ ln.add_legend()
+ ln.set_xlabel("Test x label")
+ ln.set_ylabel("Test y label")
+ ln.save()
+
+ os.chdir(curdir)
+ # clean up
+ shutil.rmtree(tmpdir)
https://bitbucket.org/yt_analysis/yt/commits/b5e69528f853/
Changeset: b5e69528f853
User: ngoldbaum
Date: 2017-06-26 22:26:06+00:00
Summary: Add a get_latex_display_name function to DerivedField for generating nice labels for fields
Affected #: 2 files
diff -r 71a0b2eea9a242e99ea74b55fc2d8badd254c720 -r b5e69528f85359e97533fc4b51bf5f7cd6c381ce yt/fields/derived_field.py
--- a/yt/fields/derived_field.py
+++ b/yt/fields/derived_field.py
@@ -13,6 +13,7 @@
import contextlib
import inspect
+import re
import warnings
from yt.extern.six import string_types, PY2
@@ -292,6 +293,51 @@
s += ")"
return s
+ def _is_ion(self):
+ p = re.compile("_p[0-9]+_")
+ result = False
+ if p.search(self.name[1]) is not None:
+ result = True
+ return result
+
+ def _ion_to_label(self):
+ pnum2rom = {
+ "0":"I", "1":"II", "2":"III", "3":"IV", "4":"V",
+ "5":"VI", "6":"VII", "7":"VIII", "8":"IX", "9":"X",
+ "10":"XI", "11":"XII", "12":"XIII", "13":"XIV", "14":"XV",
+ "15":"XVI", "16":"XVII", "17":"XVIII", "18":"XIX", "19":"XX"}
+
+ p = re.compile("_p[0-9]+_")
+ m = p.search(self.name[1])
+ if m is not None:
+ pstr = m.string[m.start()+1:m.end()-1]
+ segments = self.name[1].split("_")
+ for i,s in enumerate(segments):
+ segments[i] = s.capitalize()
+ if s == pstr:
+ ipstr = i
+ element = segments[ipstr-1]
+ roman = pnum2rom[pstr[1:]]
+ label = element + '\ ' + roman + '\ ' + \
+ '\ '.join(segments[ipstr+1:])
+ else:
+ label = self.name[1]
+ return label
+
+ def get_latex_display_name(self):
+ label = self.display_name
+ if label is None:
+ if self._is_ion():
+ fname = self._ion_to_label()
+ label = r'$\rm{'+fname.replace('_','\ ')+r'}$'
+ else:
+ label = r'$\rm{'+self.name[1].replace('_','\ ').title()+r'}$'
+ elif label.find('$') == -1:
+ label = label.replace(' ','\ ')
+ label = r'$\rm{'+label+r'}$'
+ return label
+
+
class FieldValidator(object):
pass
@@ -361,6 +407,7 @@
FieldValidator.__init__(self)
self.ghost_zones = ghost_zones
self.fields = fields
+
def __call__(self, data):
# When we say spatial information, we really mean
# that it has a three-dimensional data structure
diff -r 71a0b2eea9a242e99ea74b55fc2d8badd254c720 -r b5e69528f85359e97533fc4b51bf5f7cd6c381ce yt/visualization/fixed_resolution.py
--- a/yt/visualization/fixed_resolution.py
+++ b/yt/visualization/fixed_resolution.py
@@ -30,7 +30,6 @@
import numpy as np
import weakref
-import re
import types
class FixedResolutionBuffer(object):
@@ -155,38 +154,6 @@
if f not in exclude and f[0] not in self.data_source.ds.particle_types:
self[f]
- def _is_ion( self, fname ):
- p = re.compile("_p[0-9]+_")
- result = False
- if p.search( fname ) is not None:
- result = True
- return result
-
- def _ion_to_label( self, fname ):
- pnum2rom = {
- "0":"I", "1":"II", "2":"III", "3":"IV", "4":"V",
- "5":"VI", "6":"VII", "7":"VIII", "8":"IX", "9":"X",
- "10":"XI", "11":"XII", "12":"XIII", "13":"XIV", "14":"XV",
- "15":"XVI", "16":"XVII", "17":"XVIII", "18":"XIX", "19":"XX"}
-
- p = re.compile("_p[0-9]+_")
- m = p.search( fname )
- if m is not None:
- pstr = m.string[m.start()+1:m.end()-1]
- segments = fname.split("_")
- for i,s in enumerate(segments):
- segments[i] = s.capitalize()
- if s == pstr:
- ipstr = i
- element = segments[ipstr-1]
- roman = pnum2rom[pstr[1:]]
- label = element + '\ ' + roman + '\ ' + \
- '\ '.join(segments[ipstr+1:])
- else:
- label = fname
- return label
-
-
def _get_info(self, item):
info = {}
ftype, fname = field = self.data_source._determine_fields(item)[0]
@@ -210,18 +177,7 @@
except AttributeError:
pass
- info['label'] = finfo.display_name
- if info['label'] is None:
- if self._is_ion( fname ):
- fname = self._ion_to_label( fname )
- info['label'] = r'$\rm{'+fname+r'}$'
- info['label'] = r'$\rm{'+fname.replace('_','\ ')+r'}$'
- else:
- info['label'] = r'$\rm{'+fname+r'}$'
- info['label'] = r'$\rm{'+fname.replace('_','\ ').title()+r'}$'
- elif info['label'].find('$') == -1:
- info['label'] = info['label'].replace(' ','\ ')
- info['label'] = r'$\rm{'+info['label']+r'}$'
+ info['label'] = finfo.get_latex_display_name()
return info
https://bitbucket.org/yt_analysis/yt/commits/457f673b7c51/
Changeset: 457f673b7c51
User: ngoldbaum
Date: 2017-06-26 22:26:49+00:00
Summary: Refactor to make LinePlot a sublcass of PlotContainer
Affected #: 6 files
diff -r b5e69528f85359e97533fc4b51bf5f7cd6c381ce -r 457f673b7c51106719338ec6914a026685e1fac1 yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -39,8 +39,8 @@
sample_points = uvstack(sample_points).T
ray_coordinates = uvstack([ray[d] for d in 'xyz']).T
ray_dds = uvstack([ray['d'+d] for d in 'xyz']).T
- field_values = np.zeros(resolution)
ray_field = ray[field]
+ field_values = ray.ds.arr(np.zeros(resolution), ray_field.units)
for i, sample_point in enumerate(sample_points):
ray_contains = ((sample_point >= (ray_coordinates - ray_dds/2)) &
(sample_point <= (ray_coordinates + ray_dds/2)))
diff -r b5e69528f85359e97533fc4b51bf5f7cd6c381ce -r 457f673b7c51106719338ec6914a026685e1fac1 yt/visualization/api.py
--- a/yt/visualization/api.py
+++ b/yt/visualization/api.py
@@ -51,7 +51,9 @@
AxisAlignedSlicePlot, \
OffAxisSlicePlot, \
ProjectionPlot, \
- OffAxisProjectionPlot, \
+ OffAxisProjectionPlot
+
+from .line_plot import \
LinePlot
from .profile_plotter import \
diff -r b5e69528f85359e97533fc4b51bf5f7cd6c381ce -r 457f673b7c51106719338ec6914a026685e1fac1 yt/visualization/line_plot.py
--- /dev/null
+++ b/yt/visualization/line_plot.py
@@ -0,0 +1,245 @@
+"""
+A mechanism for plotting field values along a line through a dataset
+
+
+
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (c) 2013, yt Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+
+import numpy as np
+
+from yt.funcs import \
+ iterable
+from yt.units.unit_object import \
+ Unit
+from yt.units.yt_array import \
+ YTArray
+from yt.visualization.base_plot_types import \
+ PlotMPL
+from yt.visualization.plot_container import \
+ PlotContainer, \
+ PlotDictionary, \
+ log_transform, \
+ linear_transform, \
+ invalidate_plot
+
+class LinePlotDictionary(PlotDictionary):
+ def __init__(self, data_source):
+ super(LinePlotDictionary, self).__init__(data_source)
+ self.known_dimensions = {}
+
+ def _sanitize_dimensions(self, item):
+ field = self.data_source._determine_fields(item)[0]
+ finfo = self.data_source.ds.field_info[field]
+ dimensions = Unit(
+ finfo.units, registry=self.data_source.ds.unit_registry).dimensions
+ if dimensions not in self.known_dimensions:
+ self.known_dimensions[dimensions] = item
+ ret_item = item
+ else:
+ ret_item = self.known_dimensions[dimensions]
+ return ret_item
+
+ def __getitem__(self, item):
+ ret_item = self._sanitize_dimensions(item)
+ return super(LinePlotDictionary, self).__getitem__(ret_item)
+
+ def __setitem__(self, item, value):
+ ret_item = self._sanitize_dimensions(item)
+ super(LinePlotDictionary, self).__setitem__(ret_item, value)
+
+ def __contains__(self, item):
+ ret_item = self._sanitize_dimensions(item)
+ return super(LinePlotDictionary, self).__contains__(ret_item)
+
+class LinePlot(PlotContainer):
+ r"""
+ A class for constructing line plots
+
+ Parameters
+ ----------
+
+ ds: :class:`yt.data_objects.static_output.Dataset`
+ This is the dataset object corresponding to the
+ simulation output to be plotted.
+ fields: string
+ The name(s) of the field(s) to be plotted.
+ start_point: n-element list, tuple, ndarray, or YTArray
+ Contains the coordinates of the first point for constructing the line.
+ Must contain n elements where n is the dimensionality of the dataset.
+ end_point: n-element list, tuple, ndarray, or YTArray
+ Contains the coordinates of the first point for constructing the line.
+ Must contain n elements where n is the dimensionality of the dataset.
+ figure_size: integer or two-element
+ resolution: int
+ How many points to sample between start_point and end_point for
+ constructing the line plot
+ """
+ _plot_type = 'line_plot'
+
+ def __init__(self, ds, fields, start_point, end_point, resolution,
+ figure_size=5., fontsize=14., labels=None):
+ """
+ Sets up figure and axes
+ """
+ self.start_point = _validate_point(start_point, ds)
+ self.end_point = _validate_point(end_point, ds)
+ self.resolution = resolution
+ self._x_unit = None
+ self._y_units = {}
+ self._titles = {}
+
+ data_source = ds.all_data()
+
+ self.fields = data_source._determine_fields(fields)
+ self.plots = LinePlotDictionary(data_source)
+ if labels is None:
+ self.labels = {}
+
+ super(LinePlot, self).__init__(data_source, figure_size, fontsize)
+
+ for f in self.fields:
+ if f not in self.labels:
+ self.labels[f] = f[1]
+ finfo = self.data_source.ds._get_field_info(*f)
+ if finfo.take_log:
+ self._field_transform[f] = log_transform
+ else:
+ self._field_transform[f] = linear_transform
+
+ self._setup_plots()
+
+ def add_legend(self):
+ """Adds a legend to the `LinePlot` instance"""
+ self.axes.legend()
+
+ def _setup_plots(self):
+ if self._plot_valid is True:
+ return
+ for field in self.fields:
+ fontscale = self._font_properties._size / 14.
+ top_buff_size = 0.3*fontscale
+
+ x_axis_size = 1.2*fontscale
+ y_axis_size = 0.9*fontscale
+ right_buff_size = 0.2*fontscale
+
+ xbins = np.array([x_axis_size, self.figure_size[0],
+ right_buff_size])
+ ybins = np.array([y_axis_size, self.figure_size[1], top_buff_size])
+
+ size = [xbins.sum(), ybins.sum()]
+
+ x_frac_widths = xbins/size[0]
+ y_frac_widths = ybins/size[1]
+
+ axrect = (
+ x_frac_widths[0],
+ y_frac_widths[0],
+ x_frac_widths[1],
+ y_frac_widths[1],
+ )
+
+ try:
+ plot_used = True
+ plot = self.plots[field]
+ except KeyError:
+ plot_used = False
+ plot = PlotMPL(self.figure_size, axrect, None, None)
+ self.plots[field] = plot
+
+ plot._set_font_properties(self._font_properties, None)
+
+ x, y = self.ds.coordinates.line_plot(
+ field, self.start_point, self.end_point, self.resolution)
+
+ if self._x_unit is None:
+ unit_x = x.units
+ else:
+ unit_x = self._x_unit
+
+ if field in self._y_units:
+ unit_y = self._y_units[field]
+ else:
+ unit_y = y.units
+
+ x = x.to(unit_x)
+ y = y.to(unit_y)
+
+ plot.axes.plot(x, y, label=self.labels[field])
+
+ if self._field_transform[field] != linear_transform:
+ if (y < 0).any():
+ plot.axes.set_yscale('symlog')
+ else:
+ plot.axes.set_yscale('log')
+
+ axes_unit_labels = self._get_axes_unit_labels(unit_x, unit_y)
+
+ finfo = self.ds.field_info[field]
+
+ x_label = r'$\rm{Path\ Length' + axes_unit_labels[0]+'}$'
+ if plot_used:
+ y_label = (r'$\rm{Multiple\ Fields}$' + r'$\rm{' +
+ axes_unit_labels[1]+'}$')
+ else:
+ y_label = (finfo.get_latex_display_name() + r'$\rm{' +
+ axes_unit_labels[1]+'}$')
+
+ plot.axes.set_xlabel(x_label)
+ plot.axes.set_ylabel(y_label)
+
+ if field in self._titles:
+ plot.axes.set_title(self._titles[field])
+
+ @invalidate_plot
+ def set_x_unit(self, unit_name):
+ """Set the unit to use along the x-axis
+
+ Parameters
+ ----------
+ unit_name: str
+ The name of the unit to use for the x-axis unit
+ """
+ self._x_unit = unit_name
+
+ @invalidate_plot
+ def set_unit(self, field, unit_name):
+ """Set the unit used to plot the field
+
+ Parameters
+ ----------
+ field: str or field tuple
+ The name of the field to set the units for
+ unit_name: str
+ The name of the unit to use for this field
+ """
+ self._y_units[self.data_source._determine_fields(field)[0]] = unit_name
+
+ @invalidate_plot
+ def annotate_title(self, field, title):
+ """Set the unit used to plot the field
+
+ Parameters
+ ----------
+ field: str or field tuple
+ The name of the field to set the units for
+ title: str
+ The title to use for the plot
+ """
+ self._titles[self.data_source._determine_fields(field)[0]] = title
+
+def _validate_point(point, ds):
+ if not iterable(point):
+ raise RuntimeError
+ if not isinstance(point, YTArray):
+ point = ds.arr(point, 'code_length')
+ return point
+
diff -r b5e69528f85359e97533fc4b51bf5f7cd6c381ce -r 457f673b7c51106719338ec6914a026685e1fac1 yt/visualization/plot_container.py
--- a/yt/visualization/plot_container.py
+++ b/yt/visualization/plot_container.py
@@ -30,11 +30,19 @@
from yt.config import \
ytcfg
+from yt.data_objects.time_series import \
+ DatasetSeries
from yt.funcs import \
get_image_suffix, \
iterable, \
ensure_dir, \
ensure_list
+from yt.units.unit_lookup_table import \
+ prefixable_units, latex_prefixes
+from yt.units.unit_object import \
+ Unit
+from yt.utilities.definitions import \
+ formatted_length_unit_names
from yt.utilities.exceptions import \
YTNotInsideNotebook
from yt.visualization.color_maps import \
@@ -178,36 +186,27 @@
self.data_source = data_source
return defaultdict.__init__(self, default_factory)
-class ImagePlotContainer(object):
- """A container for plots with colorbars.
-
- """
+class PlotContainer(object):
+ """A container for generic plots"""
_plot_type = None
_plot_valid = False
- _colorbar_valid = False
def __init__(self, data_source, figure_size, fontsize):
from matplotlib.font_manager import FontProperties
-
self.data_source = data_source
+ self.ds = data_source.ds
+ self.ts = self._initialize_dataset(self.ds)
if iterable(figure_size):
self.figure_size = float(figure_size[0]), float(figure_size[1])
else:
- self.figure_size = float(figure_size)
- self.plots = PlotDictionary(data_source)
- self._callbacks = []
- self._field_transform = {}
- self._colormaps = defaultdict(
- lambda: ytcfg.get("yt", "default_colormap"))
+ self.figure_size = float(figure_size), float(figure_size)
font_path = matplotlib.get_data_path() + '/fonts/ttf/STIXGeneral.ttf'
self._font_properties = FontProperties(size=fontsize, fname=font_path)
self._font_color = None
self._xlabel = None
self._ylabel = None
self._minorticks = {}
- self._cbar_minorticks = {}
- self._colorbar_label = PlotDictionary(
- self.data_source, lambda: None)
+ self._field_transform = {}
@invalidate_plot
def set_log(self, field, log, linthresh=None):
@@ -270,109 +269,6 @@
return self
@invalidate_plot
- def set_cmap(self, field, cmap):
- """set the colormap for one of the fields
-
- Parameters
- ----------
- field : string
- the field to set the colormap
- if field == 'all', applies to all plots.
- cmap : string or tuple
- If a string, will be interpreted as name of the colormap.
- If a tuple, it is assumed to be of the form (name, type, number)
- to be used for palettable functionality. (name, type, number, bool)
- can be used to specify if a reverse colormap is to be used.
-
- """
-
- if field == 'all':
- fields = list(self.plots.keys())
- else:
- fields = [field]
- for field in self.data_source._determine_fields(fields):
- self._colorbar_valid = False
- self._colormaps[field] = cmap
- return self
-
- @invalidate_plot
- def set_background_color(self, field, color=None):
- """set the background color to match provided color
-
- Parameters
- ----------
- field : string
- the field to set the colormap
- if field == 'all', applies to all plots.
- color : string or RGBA tuple (optional)
- if set, set the background color to this color
- if unset, background color is set to the bottom value of
- the color map
-
- """
- actual_field = self.data_source._determine_fields(field)[0]
- if color is None:
- cmap = self._colormaps[actual_field]
- if isinstance(cmap, string_types):
- try:
- cmap = yt_colormaps[cmap]
- except KeyError:
- cmap = getattr(matplotlib.cm, cmap)
- color = cmap(0)
- if LooseVersion(matplotlib.__version__) < LooseVersion("2.0.0"):
- self.plots[actual_field].axes.set_axis_bgcolor(color)
- else:
- self.plots[actual_field].axes.set_facecolor(color)
- return self
-
- @invalidate_plot
- def set_zlim(self, field, zmin, zmax, dynamic_range=None):
- """set the scale of the colormap
-
- Parameters
- ----------
- field : string
- the field to set a colormap scale
- if field == 'all', applies to all plots.
- zmin : float
- the new minimum of the colormap scale. If 'min', will
- set to the minimum value in the current view.
- zmax : float
- the new maximum of the colormap scale. If 'max', will
- set to the maximum value in the current view.
-
- Other Parameters
- ----------------
- dynamic_range : float (default: None)
- The dynamic range of the image.
- If zmin == None, will set zmin = zmax / dynamic_range
- If zmax == None, will set zmax = zmin * dynamic_range
- When dynamic_range is specified, defaults to setting
- zmin = zmax / dynamic_range.
-
- """
- if field is 'all':
- fields = list(self.plots.keys())
- else:
- fields = ensure_list(field)
- for field in self.data_source._determine_fields(fields):
- myzmin = zmin
- myzmax = zmax
- if zmin == 'min':
- myzmin = self.plots[field].image._A.min()
- if zmax == 'max':
- myzmax = self.plots[field].image._A.max()
- if dynamic_range is not None:
- if zmax is None:
- myzmax = myzmin * dynamic_range
- else:
- myzmin = myzmax / dynamic_range
-
- self.plots[field].zmin = myzmin
- self.plots[field].zmax = myzmax
- return self
-
- @invalidate_plot
def set_minorticks(self, field, state):
"""turn minor ticks on or off in the current plot
@@ -398,36 +294,16 @@
self._minorticks[field] = False
return self
- @invalidate_plot
- def set_cbar_minorticks(self, field, state):
- """turn colorbar minor ticks on or off in the current plot
-
- Displaying minor ticks reduces performance; turn them off
- using set_cbar_minorticks('all', 'off') if drawing speed is a problem.
-
- Parameters
- ----------
- field : string
- the field to remove colorbar minorticks
- state : string
- the state indicating 'on' or 'off'
-
- """
- if field == 'all':
- fields = list(self.plots.keys())
- else:
- fields = [field]
- for field in self.data_source._determine_fields(fields):
- if state == 'on':
- self._cbar_minorticks[field] = True
- else:
- self._cbar_minorticks[field] = False
- return self
-
def _setup_plots(self):
# Left blank to be overriden in subclasses
pass
+ def _initialize_dataset(self, ts):
+ if not isinstance(ts, DatasetSeries):
+ if not iterable(ts): ts = [ts]
+ ts = DatasetSeries(ts)
+ return ts
+
def _switch_ds(self, new_ds, data_source=None):
old_object = self.data_source
name = old_object._type_name
@@ -585,8 +461,11 @@
for k, v in iteritems(self.plots):
names.append(v.save(name, mpl_kwargs))
return names
- axis = self.ds.coordinates.axis_name.get(
- self.data_source.axis, '')
+ if hasattr(self.data_source, 'axis'):
+ axis = self.ds.coordinates.axis_name.get(
+ self.data_source.axis, '')
+ else:
+ axis = None
weight = None
type = self._plot_type
if type in ['Projection', 'OffAxisProjection']:
@@ -616,21 +495,6 @@
return self
@validate_plot
- def _send_zmq(self):
- from ._mpl_imports import FigureCanvasAgg
- try:
- # pre-IPython v1.0
- from IPython.zmq.pylab.backend_inline import send_figure as display
- except ImportError:
- # IPython v1.0+
- from IPython.core.display import display
- for k, v in sorted(iteritems(self.plots)):
- # Due to a quirk in the matplotlib API, we need to create
- # a dummy canvas variable here that is never used.
- canvas = FigureCanvasAgg(v.figure) # NOQA
- display(v.figure)
-
- @validate_plot
def show(self):
r"""This will send any existing plots to the IPython notebook.
@@ -715,6 +579,211 @@
self._ylabel = label
return self
+ def _get_axes_unit_labels(self, unit_x, unit_y):
+ axes_unit_labels = ['', '']
+ comoving = False
+ hinv = False
+ for i, un in enumerate((unit_x, unit_y)):
+ unn = None
+ if hasattr(self.data_source, 'axis'):
+ if hasattr(self.ds.coordinates, "image_units"):
+ # This *forces* an override
+ unn = self.ds.coordinates.image_units[
+ self.data_source.axis][i]
+ elif hasattr(self.ds.coordinates, "default_unit_label"):
+ axax = getattr(self.ds.coordinates,
+ "%s_axis" % ("xy"[i]))[self.data_source.axis]
+ unn = self.ds.coordinates.default_unit_label.get(
+ axax, None)
+ if unn is not None:
+ axes_unit_labels[i] = r'\ \ \left('+unn+r'\right)'
+ continue
+ # Use sympy to factor h out of the unit. In this context 'un'
+ # is a string, so we call the Unit constructor.
+ expr = Unit(un, registry=self.ds.unit_registry).expr
+ h_expr = Unit('h', registry=self.ds.unit_registry).expr
+ # See http://docs.sympy.org/latest/modules/core.html#sympy.core.expr.Expr
+ h_power = expr.as_coeff_exponent(h_expr)[1]
+ # un is now the original unit, but with h factored out.
+ un = str(expr*h_expr**(-1*h_power))
+ un_unit = Unit(un, registry=self.ds.unit_registry)
+ cm = Unit('cm').expr
+ if str(un).endswith('cm') and cm not in un_unit.expr.atoms():
+ comoving = True
+ un = un[:-2]
+ # no length units besides code_length end in h so this is safe
+ if h_power == -1:
+ hinv = True
+ elif h_power != 0:
+ # It doesn't make sense to scale a position by anything
+ # other than h**-1
+ raise RuntimeError
+ if un not in ['1', 'u', 'unitary']:
+ if un in formatted_length_unit_names:
+ un = formatted_length_unit_names[un]
+ else:
+ un = Unit(un, registry=self.ds.unit_registry)
+ un = un.latex_representation()
+ if hinv:
+ un = un + '\,h^{-1}'
+ if comoving:
+ un = un + '\,(1+z)^{-1}'
+ pp = un[0]
+ if pp in latex_prefixes:
+ symbol_wo_prefix = un[1:]
+ if symbol_wo_prefix in prefixable_units:
+ un = un.replace(
+ pp, "{"+latex_prefixes[pp]+"}", 1)
+ axes_unit_labels[i] = '\ \ ('+un+')'
+ return axes_unit_labels
+
+
+class ImagePlotContainer(PlotContainer):
+ """A container for plots with colorbars.
+
+ """
+ _colorbar_valid = False
+
+ def __init__(self, data_source, figure_size, fontsize):
+ super(ImagePlotContainer, self).__init__(
+ data_source, figure_size, fontsize)
+ self.plots = PlotDictionary(data_source)
+ self._callbacks = []
+ self._colormaps = defaultdict(
+ lambda: ytcfg.get("yt", "default_colormap"))
+ self._cbar_minorticks = {}
+ self._colorbar_label = PlotDictionary(
+ self.data_source, lambda: None)
+
+ @invalidate_plot
+ def set_cmap(self, field, cmap):
+ """set the colormap for one of the fields
+
+ Parameters
+ ----------
+ field : string
+ the field to set the colormap
+ if field == 'all', applies to all plots.
+ cmap : string or tuple
+ If a string, will be interpreted as name of the colormap.
+ If a tuple, it is assumed to be of the form (name, type, number)
+ to be used for palettable functionality. (name, type, number, bool)
+ can be used to specify if a reverse colormap is to be used.
+
+ """
+
+ if field == 'all':
+ fields = list(self.plots.keys())
+ else:
+ fields = [field]
+ for field in self.data_source._determine_fields(fields):
+ self._colorbar_valid = False
+ self._colormaps[field] = cmap
+ return self
+
+ @invalidate_plot
+ def set_background_color(self, field, color=None):
+ """set the background color to match provided color
+
+ Parameters
+ ----------
+ field : string
+ the field to set the colormap
+ if field == 'all', applies to all plots.
+ color : string or RGBA tuple (optional)
+ if set, set the background color to this color
+ if unset, background color is set to the bottom value of
+ the color map
+
+ """
+ actual_field = self.data_source._determine_fields(field)[0]
+ if color is None:
+ cmap = self._colormaps[actual_field]
+ if isinstance(cmap, string_types):
+ try:
+ cmap = yt_colormaps[cmap]
+ except KeyError:
+ cmap = getattr(matplotlib.cm, cmap)
+ color = cmap(0)
+ if LooseVersion(matplotlib.__version__) < LooseVersion("2.0.0"):
+ self.plots[actual_field].axes.set_axis_bgcolor(color)
+ else:
+ self.plots[actual_field].axes.set_facecolor(color)
+ return self
+
+ @invalidate_plot
+ def set_zlim(self, field, zmin, zmax, dynamic_range=None):
+ """set the scale of the colormap
+
+ Parameters
+ ----------
+ field : string
+ the field to set a colormap scale
+ if field == 'all', applies to all plots.
+ zmin : float
+ the new minimum of the colormap scale. If 'min', will
+ set to the minimum value in the current view.
+ zmax : float
+ the new maximum of the colormap scale. If 'max', will
+ set to the maximum value in the current view.
+
+ Other Parameters
+ ----------------
+ dynamic_range : float (default: None)
+ The dynamic range of the image.
+ If zmin == None, will set zmin = zmax / dynamic_range
+ If zmax == None, will set zmax = zmin * dynamic_range
+ When dynamic_range is specified, defaults to setting
+ zmin = zmax / dynamic_range.
+
+ """
+ if field is 'all':
+ fields = list(self.plots.keys())
+ else:
+ fields = ensure_list(field)
+ for field in self.data_source._determine_fields(fields):
+ myzmin = zmin
+ myzmax = zmax
+ if zmin == 'min':
+ myzmin = self.plots[field].image._A.min()
+ if zmax == 'max':
+ myzmax = self.plots[field].image._A.max()
+ if dynamic_range is not None:
+ if zmax is None:
+ myzmax = myzmin * dynamic_range
+ else:
+ myzmin = myzmax / dynamic_range
+
+ self.plots[field].zmin = myzmin
+ self.plots[field].zmax = myzmax
+ return self
+
+ @invalidate_plot
+ def set_cbar_minorticks(self, field, state):
+ """turn colorbar minor ticks on or off in the current plot
+
+ Displaying minor ticks reduces performance; turn them off
+ using set_cbar_minorticks('all', 'off') if drawing speed is a problem.
+
+ Parameters
+ ----------
+ field : string
+ the field to remove colorbar minorticks
+ state : string
+ the state indicating 'on' or 'off'
+
+ """
+ if field == 'all':
+ fields = list(self.plots.keys())
+ else:
+ fields = [field]
+ for field in self.data_source._determine_fields(fields):
+ if state == 'on':
+ self._cbar_minorticks[field] = True
+ else:
+ self._cbar_minorticks[field] = False
+ return self
+
@invalidate_plot
def set_colorbar_label(self, field, label):
r"""
diff -r b5e69528f85359e97533fc4b51bf5f7cd6c381ce -r 457f673b7c51106719338ec6914a026685e1fac1 yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -14,7 +14,6 @@
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------
import numpy as np
-import os
import matplotlib
import types
import six
@@ -25,7 +24,7 @@
from numbers import Number
from .base_plot_types import \
- ImagePlotMPL, PlotMPL
+ ImagePlotMPL
from .fixed_resolution import \
FixedResolutionBuffer, \
OffAxisProjectionFixedResolutionBuffer
@@ -37,8 +36,6 @@
invalidate_data, invalidate_plot, apply_callback
from .base_plot_types import CallbackWrapper
-from yt.data_objects.time_series import \
- DatasetSeries
from yt.data_objects.image_array import \
ImageArray
from yt.extern.six import string_types
@@ -46,31 +43,24 @@
YTSpatialPlotDataset
from yt.funcs import \
mylog, iterable, ensure_list, \
- fix_axis, fix_unitary, ensure_dir, \
- get_image_suffix
+ fix_axis, fix_unitary
from yt.units.unit_object import \
Unit
from yt.units.unit_registry import \
UnitParseError
-from yt.units.unit_lookup_table import \
- prefixable_units, latex_prefixes
from yt.units.yt_array import \
YTArray, YTQuantity
-from yt.utilities.definitions import \
- formatted_length_unit_names
from yt.utilities.math_utils import \
ortho_find
from yt.utilities.orientation import \
Orientation
from yt.utilities.exceptions import \
- YTUnitNotRecognized, \
YTCannotParseUnitDisplayName, \
- YTUnitConversionError, \
YTPlotCallbackError, \
YTDataTypeUnsupported, \
YTInvalidFieldType, \
- YTNotInsideNotebook
-from yt.extern.six.moves import builtins
+ YTUnitNotRecognized, \
+ YTUnitConversionError
MPL_VERSION = LooseVersion(matplotlib.__version__)
@@ -183,11 +173,6 @@
periodic=True, origin='center-window', oblique=False, right_handed=True,
window_size=8.0, fields=None, fontsize=18, aspect=None,
setup=False):
- if not hasattr(self, "ds"):
- self.ds = data_source.ds
- ts = self._initialize_dataset(self.ds)
- self.ts = ts
- self._axes_unit_names = None
self.center = None
self._periodic = periodic
self.oblique = oblique
@@ -195,6 +180,7 @@
self._equivalencies = defaultdict(lambda: (None, {}))
self.buff_size = buff_size
self.antialias = antialias
+ self._axes_unit_names = None
self.aspect = aspect
skip = list(FixedResolutionBuffer._exclude_fields) + data_source._key_fields
@@ -224,12 +210,6 @@
self.setup_callbacks()
self._setup_plots()
- def _initialize_dataset(self, ts):
- if not isinstance(ts, DatasetSeries):
- if not iterable(ts): ts = [ts]
- ts = DatasetSeries(ts)
- return ts
-
def __iter__(self):
for ds in self.ts:
mylog.warning("Switching to %s", ds)
@@ -860,59 +840,7 @@
ax = self.plots[f].axes
ax.invert_xaxis()
- axes_unit_labels = ['', '']
- comoving = False
- hinv = False
- for i, un in enumerate((unit_x, unit_y)):
- unn = None
- if hasattr(self.ds.coordinates, "image_units"):
- # This *forces* an override
- unn = self.ds.coordinates.image_units[axis_index][i]
- elif hasattr(self.ds.coordinates, "default_unit_label"):
- axax = getattr(self.ds.coordinates,
- "%s_axis" % ("xy"[i]))[axis_index]
- unn = self.ds.coordinates.default_unit_label.get(axax,
- None)
- if unn is not None:
- axes_unit_labels[i] = r'\ \ \left('+unn+r'\right)'
- continue
- # Use sympy to factor h out of the unit. In this context 'un'
- # is a string, so we call the Unit constructor.
- expr = Unit(un, registry=self.ds.unit_registry).expr
- h_expr = Unit('h', registry=self.ds.unit_registry).expr
- # See http://docs.sympy.org/latest/modules/core.html#sympy.core.expr.Expr
- h_power = expr.as_coeff_exponent(h_expr)[1]
- # un is now the original unit, but with h factored out.
- un = str(expr*h_expr**(-1*h_power))
- un_unit = Unit(un, registry=self.ds.unit_registry)
- cm = Unit('cm').expr
- if str(un).endswith('cm') and cm not in un_unit.expr.atoms():
- comoving = True
- un = un[:-2]
- # no length units besides code_length end in h so this is safe
- if h_power == -1:
- hinv = True
- elif h_power != 0:
- # It doesn't make sense to scale a position by anything
- # other than h**-1
- raise RuntimeError
- if un not in ['1', 'u', 'unitary']:
- if un in formatted_length_unit_names:
- un = formatted_length_unit_names[un]
- else:
- un = Unit(un, registry=self.ds.unit_registry)
- un = un.latex_representation()
- if hinv:
- un = un + '\,h^{-1}'
- if comoving:
- un = un + '\,(1+z)^{-1}'
- pp = un[0]
- if pp in latex_prefixes:
- symbol_wo_prefix = un[1:]
- if symbol_wo_prefix in prefixable_units:
- un = un.replace(
- pp, "{"+latex_prefixes[pp]+"}", 1)
- axes_unit_labels[i] = '\ \ ('+un+')'
+ axes_unit_labels = self._get_axes_unit_labels(unit_x, unit_y)
if self.oblique:
labels = [r'$\rm{Image\ x'+axes_unit_labels[0]+'}$',
@@ -1308,9 +1236,6 @@
origin='center-window', right_handed=True, fontsize=18, field_parameters=None,
window_size=8.0, aspect=None, data_source=None):
# this will handle time series data and controllers
- ts = self._initialize_dataset(ds)
- self.ts = ts
- ds = self.ds = ts[0]
axis = fix_axis(axis, ds)
(bounds, center, display_center) = \
get_window_parameters(axis, center, width, ds)
@@ -1490,9 +1415,6 @@
right_handed=True, fontsize=18, field_parameters=None, data_source=None,
method = "integrate", proj_style = None, window_size=8.0,
aspect=None):
- ts = self._initialize_dataset(ds)
- self.ts = ts
- ds = self.ds = ts[0]
axis = fix_axis(axis, ds)
# proj_style is deprecated, but if someone specifies then it trumps
# method.
@@ -2018,198 +1940,3 @@
del kwargs['north_vector']
return AxisAlignedSlicePlot(ds, normal, fields, *args, **kwargs)
-
-def _validate_point(point, ds):
- if not iterable(point):
- raise RuntimeError
- if not isinstance(point, YTArray):
- point = ds.arr(point, 'code_length')
- return point
-
-class LinePlot(PlotMPL):
- r"""
- A class for constructing line plots
-
- Parameters
- ----------
-
- ds : :class:`yt.data_objects.static_output.Dataset`
- This is the dataset object corresponding to the
- simulation output to be plotted.
- fields : string
- The name(s) of the field(s) to be plotted.
- start_point: n-element list, tuple, ndarray, or YTArray
- Contains the coordinates of the first point for constructing the line.
- Must contain n elements where n is the dimensionality of the dataset.
- end_point: n-element list, tuple, ndarray, or YTArray
- Contains the coordinates of the first point for constructing the line.
- Must contain n elements where n is the dimensionality of the dataset.
- resolution: int
- How many points to sample between start_point and end_point for constructing
- the line plot
- """
-
- def __init__(self, ds, fields, start_point, end_point, resolution,
- figure_size=5., aspect=None, fontsize=18., labels=None):
- """
- Sets up figure and axes
- """
- self.handler = ds.coordinates
- self.ds = ds
- if aspect is None:
- aspect = 1.
- fontscale = fontsize / 18.
- ax_text_size = [1.2*fontscale, 0.9*fontscale]
- top_buff_size = 0.3*fontscale
-
- if iterable(figure_size):
- x_fig_size = figure_size[0]
- y_fig_size = figure_size[1]
- else:
- x_fig_size = figure_size
- y_fig_size = figure_size/aspect
-
- x_axis_size = ax_text_size[0]
- y_axis_size = ax_text_size[1]
-
- top_buff_size = top_buff_size
-
- xbins = np.array([x_axis_size, x_fig_size, x_axis_size])
- ybins = np.array([y_axis_size, y_fig_size, top_buff_size])
-
- size = [xbins.sum(), ybins.sum()]
-
- x_frac_widths = xbins/size[0]
- y_frac_widths = ybins/size[1]
-
- # axrect is the rectangle defining the area of the
- # axis object of the plot. Its range goes from 0 to 1 in
- # x and y directions. The first two values are the x,y
- # start values of the axis object (lower left corner), and the
- # second two values are the size of the axis object. To get
- # the upper right corner, add the first x,y to the second x,y.
- axrect = (
- x_frac_widths[0],
- y_frac_widths[0],
- x_frac_widths[1],
- y_frac_widths[1],
- )
-
- start_point = _validate_point(start_point, ds)
- end_point = _validate_point(end_point, ds)
-
- super(LinePlot, self).__init__(size, axrect, None, None)
-
- self.add_plot(fields, start_point, end_point, resolution, labels=labels)
- self._xlabel = ("Arc Length [Arb. Units]", 14.)
- self._ylabel = ("Field Value [Arb. Units]", 14.)
-
- def add_plot(self, fields, start_point, end_point, resolution, labels=None):
- r"""
- Used to add plots to the figure
-
- parameters
- ----------
-
- fields : A single field tuple or a list of field tuples
- The fields to plot
- start_point : list, tuple, ndarray, or YTArray
- The coordinates of the start point of the line plot. Length of
- iterable should be equal to the number of dimensions of the
- dataset
- end_point : list, tuple, ndarray, or YTArray
- The coordinates of the end point of the line plot. Length of
- iterable should be equal to the number of dimensions of the
- dataset
- resolution : integer
- How many points to sample between start_point and end_point for
- constructing the line plot
- """
- if labels is None:
- labels = {}
- if not isinstance(fields, list):
- fields = [fields]
- for field in fields:
- if field not in labels:
- labels[field] = field[1]
- x, y = self.handler.line_plot(
- field, start_point, end_point, resolution)
- self.axes.plot(x, y, label=labels[field])
-
- def add_legend(self):
- r"""
- Adds a legend to the `LinePlot` instance
- """
- self.axes.legend()
-
- def set_xlabel(self, label, fontsize=14):
- r"""
- Method for setting the x-label
-
- parameters
- ----------
- label : string
- The label for the x-axis
- """
- self._xlabel = (label, fontsize)
-
- def set_ylabel(self, label, fontsize=14):
- r"""
- Method for setting the y-label
-
- parameters
- ----------
- label : string
- The label for the y-axis
- """
- self._ylabel = (label, fontsize)
-
- def _setup_plot(self):
- r"""
- Private method called from either `show` or `save`. Sets x and
- y labels
- """
- self.axes.set_xlabel(self._xlabel[0], fontsize=self._xlabel[1])
- self.axes.set_ylabel(self._ylabel[0], fontsize=self._ylabel[1])
-
- def show(self):
- r"""This will send any existing plots to the IPython notebook.
-
- 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
- notebook for display.
-
- If yt can't determine if it's inside an IPython session, it will raise
- YTNotInsideNotebook.
- """
- self._setup_plot()
- if "__IPYTHON__" in dir(builtins):
- from IPython.display import display
- display(self)
- else:
- raise YTNotInsideNotebook
-
- def save(self, name=None, mpl_kwargs=None):
- r"""
- Method for saving line plots. No default so user should specify
- extension
-
- parameters
- ----------
- name : string
- Name to save file to
- mpl_kwargs: dict
- A dictionary of keywoard arguments to pass to matplotlib
- """
- self._setup_plot()
- if name is None:
- name = str(self.ds)
- name = os.path.expanduser(name)
- if name[-1] == os.sep and not os.path.isdir(name):
- ensure_dir(name)
- if os.path.isdir(name) and name != str(self.ds):
- name = name + (os.sep if name[-1] != os.sep else '') + str(self.ds)
- suffix = get_image_suffix(name)
- if suffix == '':
- name = name + '_LinePlot.png'
- super(LinePlot, self).save(name)
diff -r b5e69528f85359e97533fc4b51bf5f7cd6c381ce -r 457f673b7c51106719338ec6914a026685e1fac1 yt/visualization/profile_plotter.py
--- a/yt/visualization/profile_plotter.py
+++ b/yt/visualization/profile_plotter.py
@@ -60,7 +60,7 @@
canvas_cls = mpl.FigureCanvasAgg
return canvas_cls
-class PlotContainer(OrderedDict):
+class PlotContainerDict(OrderedDict):
def __missing__(self, key):
plot = PlotMPL((10, 8), [0.1, 0.1, 0.8, 0.8], None, None)
self[key] = plot
@@ -378,7 +378,7 @@
if plot_specs is None:
plot_specs = [dict() for p in obj.profiles]
obj.plot_spec = plot_specs
- obj.plots = PlotContainer()
+ obj.plots = PlotContainerDict()
obj.figures = FigureContainer(obj.plots)
obj.axes = AxesContainer(obj.plots)
obj._setup_plots()
@@ -1370,7 +1370,7 @@
if fontscale < 1.0:
fontscale = np.sqrt(fontscale)
- self._cb_size = 0.0375*figure_size
+ self._cb_size = 0.0375*figure_size[0]
self._ax_text_size = [1.1*fontscale, 0.9*fontscale]
self._top_buff_size = 0.30*fontscale
self._aspect = 1.0
https://bitbucket.org/yt_analysis/yt/commits/12295ae6bc0a/
Changeset: 12295ae6bc0a
User: ngoldbaum
Date: 2017-06-26 22:31:19+00:00
Summary: add NotImplementedError for LinePlot on non-cartesian data
Affected #: 1 file
diff -r 457f673b7c51106719338ec6914a026685e1fac1 -r 12295ae6bc0a6e2cbb63c3de3d691725f0f11ea5 yt/geometry/coordinates/coordinate_handler.py
--- a/yt/geometry/coordinates/coordinate_handler.py
+++ b/yt/geometry/coordinates/coordinate_handler.py
@@ -86,6 +86,9 @@
# pixelizer
raise NotImplementedError
+ def line_plot(self, field, start_point, end_point, resolution):
+ raise NotImplementedError
+
def distance(self, start, end):
p1 = self.convert_to_cartesian(start)
p2 = self.convert_to_cartesian(end)
https://bitbucket.org/yt_analysis/yt/commits/68faebd9e02c/
Changeset: 68faebd9e02c
User: Alex Lindsay
Date: 2017-06-27 20:46:35+00:00
Summary: Make y_label work for single fields. Make add_legend work. Account for lack of Exodus units in handler.
Affected #: 3 files
diff -r 12295ae6bc0a6e2cbb63c3de3d691725f0f11ea5 -r 68faebd9e02c58205342c0bfddba542020743195 yt/frontends/exodus_ii/fields.py
--- a/yt/frontends/exodus_ii/fields.py
+++ b/yt/frontends/exodus_ii/fields.py
@@ -33,6 +33,8 @@
def __init__(self, ds, field_list):
super(ExodusIIFieldInfo, self).__init__(ds, field_list)
+ for name in self:
+ self[name].take_log = False
# If you want, you can check self.field_list
def setup_fluid_fields(self):
diff -r 12295ae6bc0a6e2cbb63c3de3d691725f0f11ea5 -r 68faebd9e02c58205342c0bfddba542020743195 yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -21,6 +21,7 @@
_get_vert_fields, \
cartesian_to_cylindrical, \
cylindrical_to_cartesian
+from yt import YTArray
from yt.funcs import mylog
from yt.units.yt_array import uvstack
from yt.utilities.lib.pixelization_routines import \
@@ -186,6 +187,8 @@
end_point,
resolution, field_data,
index_offset=offset)
+ arc_length = YTArray(arc_length, start_point.units)
+ plot_values = YTArray(plot_values, field_data.units)
else:
ray = self.ds.ray(start_point, end_point)
arc_length, plot_values = _sample_ray(ray, resolution, field)
diff -r 12295ae6bc0a6e2cbb63c3de3d691725f0f11ea5 -r 68faebd9e02c58205342c0bfddba542020743195 yt/visualization/line_plot.py
--- a/yt/visualization/line_plot.py
+++ b/yt/visualization/line_plot.py
@@ -15,6 +15,7 @@
import numpy as np
+from collections import defaultdict
from yt.funcs import \
iterable
from yt.units.unit_object import \
@@ -34,7 +35,7 @@
def __init__(self, data_source):
super(LinePlotDictionary, self).__init__(data_source)
self.known_dimensions = {}
-
+
def _sanitize_dimensions(self, item):
field = self.data_source._determine_fields(item)[0]
finfo = self.data_source.ds.field_info[field]
@@ -46,7 +47,7 @@
else:
ret_item = self.known_dimensions[dimensions]
return ret_item
-
+
def __getitem__(self, item):
ret_item = self._sanitize_dimensions(item)
return super(LinePlotDictionary, self).__getitem__(ret_item)
@@ -77,9 +78,9 @@
end_point: n-element list, tuple, ndarray, or YTArray
Contains the coordinates of the first point for constructing the line.
Must contain n elements where n is the dimensionality of the dataset.
- figure_size: integer or two-element
+ figure_size: integer or two-element
resolution: int
- How many points to sample between start_point and end_point for
+ How many points to sample between start_point and end_point for
constructing the line plot
"""
_plot_type = 'line_plot'
@@ -102,7 +103,9 @@
self.plots = LinePlotDictionary(data_source)
if labels is None:
self.labels = {}
-
+ else:
+ self.labels = labels
+
super(LinePlot, self).__init__(data_source, figure_size, fontsize)
for f in self.fields:
@@ -115,14 +118,16 @@
self._field_transform[f] = linear_transform
self._setup_plots()
-
- def add_legend(self):
+
+ def add_legend(self, field):
"""Adds a legend to the `LinePlot` instance"""
- self.axes.legend()
+ plot = self.plots[field]
+ plot.axes.legend()
def _setup_plots(self):
if self._plot_valid is True:
return
+ dimensions_counter = defaultdict(int)
for field in self.fields:
fontscale = self._font_properties._size / 14.
top_buff_size = 0.3*fontscale
@@ -148,18 +153,16 @@
)
try:
- plot_used = True
plot = self.plots[field]
except KeyError:
- plot_used = False
plot = PlotMPL(self.figure_size, axrect, None, None)
self.plots[field] = plot
-
+
plot._set_font_properties(self._font_properties, None)
x, y = self.ds.coordinates.line_plot(
field, self.start_point, self.end_point, self.resolution)
-
+
if self._x_unit is None:
unit_x = x.units
else:
@@ -174,7 +177,7 @@
y = y.to(unit_y)
plot.axes.plot(x, y, label=self.labels[field])
-
+
if self._field_transform[field] != linear_transform:
if (y < 0).any():
plot.axes.set_yscale('symlog')
@@ -184,9 +187,13 @@
axes_unit_labels = self._get_axes_unit_labels(unit_x, unit_y)
finfo = self.ds.field_info[field]
-
+
x_label = r'$\rm{Path\ Length' + axes_unit_labels[0]+'}$'
- if plot_used:
+
+ finfo = self.ds.field_info[field]
+ dimensions = Unit(finfo.units, registry=self.ds.unit_registry).dimensions
+ dimensions_counter[dimensions] += 1
+ if dimensions_counter[dimensions] > 1:
y_label = (r'$\rm{Multiple\ Fields}$' + r'$\rm{' +
axes_unit_labels[1]+'}$')
else:
@@ -242,4 +249,3 @@
if not isinstance(point, YTArray):
point = ds.arr(point, 'code_length')
return point
-
https://bitbucket.org/yt_analysis/yt/commits/aa76b5ff39cc/
Changeset: aa76b5ff39cc
User: Alex Lindsay
Date: 2017-06-27 22:02:42+00:00
Summary: Prevent redrawing of same plot
Affected #: 1 file
diff -r 68faebd9e02c58205342c0bfddba542020743195 -r aa76b5ff39ccf28f52648f8542a9982577613c8e yt/visualization/line_plot.py
--- a/yt/visualization/line_plot.py
+++ b/yt/visualization/line_plot.py
@@ -101,6 +101,7 @@
self.fields = data_source._determine_fields(fields)
self.plots = LinePlotDictionary(data_source)
+ self.include_legend = defaultdict(bool)
if labels is None:
self.labels = {}
else:
@@ -119,14 +120,16 @@
self._setup_plots()
+ @invalidate_plot
def add_legend(self, field):
"""Adds a legend to the `LinePlot` instance"""
- plot = self.plots[field]
- plot.axes.legend()
+ self.include_legend[field] = True
def _setup_plots(self):
if self._plot_valid is True:
return
+ for plot in self.plots.values():
+ plot.axes.cla()
dimensions_counter = defaultdict(int)
for field in self.fields:
fontscale = self._font_properties._size / 14.
@@ -206,6 +209,9 @@
if field in self._titles:
plot.axes.set_title(self._titles[field])
+ if self.include_legend[field]:
+ plot.axes.legend()
+
@invalidate_plot
def set_x_unit(self, unit_name):
"""Set the unit to use along the x-axis
https://bitbucket.org/yt_analysis/yt/commits/2735e293c2b3/
Changeset: 2735e293c2b3
User: Alex Lindsay
Date: 2017-06-27 22:31:28+00:00
Summary: Update rst documentation
Affected #: 4 files
diff -r aa76b5ff39ccf28f52648f8542a9982577613c8e -r 2735e293c2b3dba69336d04ba9b8858532b9e7cf doc/source/cookbook/simple_1d_line_plot.py
--- /dev/null
+++ b/doc/source/cookbook/simple_1d_line_plot.py
@@ -0,0 +1,14 @@
+import yt
+
+# Load the dataset
+ds = yt.load("SecondOrderTris/RZ_p_no_parts_do_nothing_bcs_cone_out.e", step=-1)
+
+# Create a line plot of the variables 'u' and 'v' with 1000 sampling points evenly spaced
+# between the coordinates (0, 0, 0) and (0, 1, 0)
+ln = yt.LinePlot(ds, [('all', 'v'), ('all', 'u')], (0, 0, 0), (0, 1, 0), 1000)
+
+# Add a legend
+ln.add_legend()
+
+# Save the line plot
+ln.save()
diff -r aa76b5ff39ccf28f52648f8542a9982577613c8e -r 2735e293c2b3dba69336d04ba9b8858532b9e7cf doc/source/cookbook/simple_plots.rst
--- a/doc/source/cookbook/simple_plots.rst
+++ b/doc/source/cookbook/simple_plots.rst
@@ -43,6 +43,14 @@
.. yt_cookbook:: simple_phase.py
+Simple 1D Line Plotting
+~~~~~~~~~~~~~~~~~~~~~~~
+
+This script shows how to make a ``LinePlot`` through a dataset.
+See :ref:`how-to-1d-line-plot` for more information.
+
+.. yt_cookbook:: simple_1d_line_plot.py
+
Simple Probability Distribution Functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -237,11 +245,3 @@
When creating movies of multiple outputs from the same simulation (see :ref:`time-series-analysis`), it can be helpful to include a timestamp and the physical scale of each individual output. This is simply achieved using the :ref:`annotate_timestamp() <annotate-timestamp>` and :ref:`annotate_scale() <annotate-scale>` callbacks on your plots. For more information about similar plot modifications using other callbacks, see the section on :ref:`Plot Modifications <callbacks>`.
.. yt_cookbook:: annotate_timestamp_and_scale.py
-
-Simple 1D Unstructured Mesh Line Plotting
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This script shows how to make a ``LinePlot`` through an ``UnstructuredMesh``
-data-set. See :ref:`how-to-1d-unstructured-mesh` for more information.
-
-.. yt_cookbook:: simple_unstructured_1d.py
diff -r aa76b5ff39ccf28f52648f8542a9982577613c8e -r 2735e293c2b3dba69336d04ba9b8858532b9e7cf doc/source/cookbook/simple_unstructured_1d.py
--- a/doc/source/cookbook/simple_unstructured_1d.py
+++ /dev/null
@@ -1,24 +0,0 @@
-import yt
-
-# Load the dataset
-ds = yt.load("SecondOrderTris/RZ_p_no_parts_do_nothing_bcs_cone_out.e", step=-1)
-
-# Create a line plot of the variables 'u' and 'v' with 1000 sampling points evenly spaced
-# between the coordinates (0, 0, 0) and (0, 1, 0)
-ln = yt.LinePlot(ds, [('all', 'v'), ('all', 'u')], (0, 0, 0), (0, 1, 0), 1000)
-
-# Add a plot to the LinePlot instance of the variable 'p' with 100 sampling points evenly
-# spaced between (0.5, 0, 0) and (1, 1, 0). Also create a label for p
-ln.add_plot(('all', 'p'), (0.5, 0, 0), (1, 1, 0), 100, labels={('all', 'p') : 'p'})
-
-# Add a legend
-ln.add_legend()
-
-# Set xlabel
-ln.set_xlabel("Arc Length (cm)")
-
-# Set ylabel
-ln.set_ylabel("Field Values [Arb. Units]")
-
-# Save the line plot. Note that the save string is a required argument
-ln.save("line_plot.png")
diff -r aa76b5ff39ccf28f52648f8542a9982577613c8e -r 2735e293c2b3dba69336d04ba9b8858532b9e7cf doc/source/visualizing/plots.rst
--- a/doc/source/visualizing/plots.rst
+++ b/doc/source/visualizing/plots.rst
@@ -1057,10 +1057,10 @@
.. _how-to-1d-unstructured-mesh:
-1D Sampling on Unstructured Meshes
-----------------------------------
+1D Line Sampling
+----------------
-YT has the ability to sample unstructured mesh data-sets along arbitrary lines
+YT has the ability to sample datasets along arbitrary lines
and plot the result. You must supply five arguments to the ``LinePlot``
class. They are enumerated below:
@@ -1082,41 +1082,30 @@
ds = yt.load("SecondOrderTris/RZ_p_no_parts_do_nothing_bcs_cone_out.e", step=-1)
ln = yt.LinePlot(ds, [('all', 'v'), ('all', 'u')], (0, 0, 0), (0, 1, 0), 1000)
- ln.save("first_test.png")
+ ln.save()
-You can also add plots to existing ``LinePlot`` instances with ``add_plot`` as shown
-below:
-
-.. code-block:: python
+If working in a Jupyter Notebook, ``LinePlot`` also has the ``show()`` method.
- ln.add_plot(('all', 'p'), (0, 0, 0), (1, 1, 0), 1000)
- ln.save("added_plot.png")
+You can can add a legend to a 1D sampling plot. The legend process takes two steps:
-Note that the beginning and end-points of multiple plots can be different. If
-working in an Jupyter Notebook, ``LinePlot`` also has the ``show()`` method.
-
-You can also create legends and add x and y axes labels to these 1D sampling
-plots. The legend process takes two steps:
-
-1. When instantiating the ``LinePlot`` or invoking ``add_plot`` pass a dictionary of
+1. When instantiating the ``LinePlot``, pass a dictionary of
labels with keys corresponding to the field names
2. Call the ``LinePlot`` ``add_legend`` method
-X- and Y- axis labels are set simply with ``set_xlabel`` and ``set_ylabel``
-methods. The below code snippet combines all the features we've discussed:
+X- and Y- axis units can be set with ``set_x_unit`` and ``set_unit`` methods
+respectively. The below code snippet combines all the features we've discussed:
.. python-script::
import yt
- ds = yt.load("SecondOrderTris/RZ_p_no_parts_do_nothing_bcs_cone_out.e", step=-1)
- ln = yt.LinePlot(ds, [('all', 'v'), ('all', 'u')], (0, 0, 0), (0, 1, 0), 1000,
- labels={('all', 'u') : r"u$_s$", ('all', 'v') : r"v$_s$"})
- ln.add_plot([('all', 'v'), ('all', 'u')], (0, 0, 0), (1, 1, 0), 1000,
- labels={('all', 'u') : r"u$_l$", ('all', 'v') : r"v$_l$"})
- ln.add_legend()
- ln.set_xlabel("Arc Length (cm)")
- ln.set_ylabel(r"Velocity (m s$^{-1}$)")
- ln.save("line_plot.png")
+
+ ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030')
+
+ plot = yt.LinePlot(ds, 'density', [0, 0, 0], [1, 1, 1], 512)
+ plot.add_legend('density')
+ plot.set_x_unit('cm')
+ plot.set_unit('density', 'kg/cm**3')
+ plot.save()
.. _how-to-make-2d-profiles:
https://bitbucket.org/yt_analysis/yt/commits/1387c8c5c429/
Changeset: 1387c8c5c429
User: Alex Lindsay
Date: 2017-06-27 22:46:53+00:00
Summary: Update tests
Affected #: 2 files
diff -r 2735e293c2b3dba69336d04ba9b8858532b9e7cf -r 1387c8c5c429eabbbc320d0ca4d70bf51dfd88f6 doc/source/visualizing/plots.rst
--- a/doc/source/visualizing/plots.rst
+++ b/doc/source/visualizing/plots.rst
@@ -1107,6 +1107,15 @@
plot.set_unit('density', 'kg/cm**3')
plot.save()
+If a list of fields is passed to ``LinePlot``, yt will create a number of
+individual figures equal to the number of different dimensional
+quantities. E.g. if ``LinePlot`` receives two fields with units of "length/time"
+and a field with units of "temperature", two different figures will be created,
+one with plots of the "length/time" fields and another with the plot of the
+"temperature" field. It is only necessary to call ``add_legend``
+for one field of a multi-field plot to produce a legend containing all the
+labels passed in the initial construction of the ``LinePlot`` instance.
+
.. _how-to-make-2d-profiles:
diff -r 2735e293c2b3dba69336d04ba9b8858532b9e7cf -r 1387c8c5c429eabbbc320d0ca4d70bf51dfd88f6 yt/visualization/tests/test_line_plots.py
--- a/yt/visualization/tests/test_line_plots.py
+++ b/yt/visualization/tests/test_line_plots.py
@@ -33,6 +33,7 @@
return test
tri2 = "SecondOrderTris/RZ_p_no_parts_do_nothing_bcs_cone_out.e"
+iso_galaxy = "IsolatedGalaxy/galaxy0030/galaxy0030"
@requires_ds(tri2)
def test_line_plot():
@@ -40,21 +41,20 @@
fields = [field for field in ds.field_list if field[0] == 'all']
yield compare(ds, fields, (0, 0, 0), (1, 1, 0), 1000, "answers_line_plot")
+ at requires_ds(iso_galaxy)
def test_line_plot_methods():
# Perform I/O in safe place instead of yt main dir
tmpdir = tempfile.mkdtemp()
curdir = os.getcwd()
os.chdir(tmpdir)
- # hexahedral ds
- ds = fake_hexahedral_ds()
+ ds = data_dir_load(iso_galaxy)
- ln = yt.LinePlot(ds, ds.field_list, (0, 0, -.25), (0, 0, .25), 100)
- ln.add_plot(ds.field_list, (0, 0, -.25), (0, 0, .25), 100)
- ln.add_legend()
- ln.set_xlabel("Test x label")
- ln.set_ylabel("Test y label")
- ln.save()
+ plot = yt.LinePlot(ds, 'density', [0, 0, 0], [1, 1, 1], 512)
+ plot.add_legend('density')
+ plot.set_x_unit('cm')
+ plot.set_unit('density', 'kg/cm**3')
+ plot.save()
os.chdir(curdir)
# clean up
https://bitbucket.org/yt_analysis/yt/commits/3249ecb9ce42/
Changeset: 3249ecb9ce42
User: Alex Lindsay
Date: 2017-06-28 13:53:39+00:00
Summary: Address some failed tests and change ln to plot.
Affected #: 4 files
diff -r 1387c8c5c429eabbbc320d0ca4d70bf51dfd88f6 -r 3249ecb9ce42777551963f05fd3d4ed9207ffb76 doc/source/cookbook/simple_1d_line_plot.py
--- a/doc/source/cookbook/simple_1d_line_plot.py
+++ b/doc/source/cookbook/simple_1d_line_plot.py
@@ -5,10 +5,10 @@
# Create a line plot of the variables 'u' and 'v' with 1000 sampling points evenly spaced
# between the coordinates (0, 0, 0) and (0, 1, 0)
-ln = yt.LinePlot(ds, [('all', 'v'), ('all', 'u')], (0, 0, 0), (0, 1, 0), 1000)
+plot = yt.LinePlot(ds, [('all', 'v'), ('all', 'u')], (0, 0, 0), (0, 1, 0), 1000)
# Add a legend
-ln.add_legend()
+plot.add_legend(('all', 'v'))
# Save the line plot
-ln.save()
+plot.save()
diff -r 1387c8c5c429eabbbc320d0ca4d70bf51dfd88f6 -r 3249ecb9ce42777551963f05fd3d4ed9207ffb76 doc/source/visualizing/plots.rst
--- a/doc/source/visualizing/plots.rst
+++ b/doc/source/visualizing/plots.rst
@@ -1081,8 +1081,8 @@
.. code-block:: python
ds = yt.load("SecondOrderTris/RZ_p_no_parts_do_nothing_bcs_cone_out.e", step=-1)
- ln = yt.LinePlot(ds, [('all', 'v'), ('all', 'u')], (0, 0, 0), (0, 1, 0), 1000)
- ln.save()
+ plot = yt.LinePlot(ds, [('all', 'v'), ('all', 'u')], (0, 0, 0), (0, 1, 0), 1000)
+ plot.save()
If working in a Jupyter Notebook, ``LinePlot`` also has the ``show()`` method.
diff -r 1387c8c5c429eabbbc320d0ca4d70bf51dfd88f6 -r 3249ecb9ce42777551963f05fd3d4ed9207ffb76 tests/tests.yaml
--- a/tests/tests.yaml
+++ b/tests/tests.yaml
@@ -64,7 +64,7 @@
- yt/analysis_modules/photon_simulator/tests/test_spectra.py
- yt/analysis_modules/photon_simulator/tests/test_sloshing.py
- local_unstructured_006:
+ local_unstructured_007:
- yt/visualization/volume_rendering/tests/test_mesh_render.py
- yt/visualization/tests/test_mesh_slices.py:test_tri2
- yt/visualization/tests/test_mesh_slices.py:test_quad2
diff -r 1387c8c5c429eabbbc320d0ca4d70bf51dfd88f6 -r 3249ecb9ce42777551963f05fd3d4ed9207ffb76 yt/visualization/tests/test_line_plots.py
--- a/yt/visualization/tests/test_line_plots.py
+++ b/yt/visualization/tests/test_line_plots.py
@@ -15,6 +15,9 @@
requires_ds, \
data_dir_load, \
GenericImageTest
+import os
+import tempfile
+import shutil
def setup():
"""Test specific setup."""
https://bitbucket.org/yt_analysis/yt/commits/31f1a4ccea04/
Changeset: 31f1a4ccea04
User: Alex Lindsay
Date: 2017-06-28 14:11:33+00:00
Summary: Merge branch 'master' into line_plot_plus_quad9
Affected #: 70 files
diff -r 3249ecb9ce42777551963f05fd3d4ed9207ffb76 -r 31f1a4ccea0427e60c645abd49a11345168de4fe appveyor.yml
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -8,6 +8,7 @@
matrix:
- PYTHON_VERSION: "3.6"
+ - PYTHON_VERSION: "2.7"
platform:
-x64
@@ -27,7 +28,7 @@
- "python --version"
# Install specified version of numpy and dependencies
- - "conda install -q --yes -c conda-forge numpy scipy nose setuptools ipython Cython sympy fastcache h5py matplotlib flake8 "
+ - "conda install -q --yes -c conda-forge numpy scipy nose setuptools ipython Cython sympy fastcache h5py matplotlib flake8 mock"
- "pip install -e ."
# Not a .NET project
diff -r 3249ecb9ce42777551963f05fd3d4ed9207ffb76 -r 31f1a4ccea0427e60c645abd49a11345168de4fe doc/install_script.sh
--- a/doc/install_script.sh
+++ b/doc/install_script.sh
@@ -13,62 +13,23 @@
# If you do not have a working compiler environment, use the following
# configuration:
-INST_CONDA=1 # Should yt's dependencies be installed using miniconda?
INST_YT_SOURCE=0 # Should yt itself be installed from source?
-# If you want to install yt's dependencies using conda but want to build yt
-# itself from source, use the following configuration:
-
-# INST_CONDA=1
-# INST_YT_SOURCE=1
-
-# If you would like to build yt and all dependencies from source, then
-# use the following configuration by uncommenting the lines below.
-# NOTE: Building yt's dependencies from source will cause the install script
-# to require substantially more time to finish.
-
-# INST_CONDA=0
-# INST_YT_SOURCE=1
-
-BRANCH="master" # This is the branch we will install from for source installs
-
# What follows are some other options that you may or may not need to change.
-# Here's where you put the HDF5 path if you like; otherwise it'll download it
-# and install it on its own
-#HDF5_DIR=
-
-# If you've got yt some other place, set this to point to it. The script will
-# already check the current directory and the one above it in the tree.
+# If you've got a clone of the yt repository some other place, set this to
+# point to it. The script will already check the current directory and the one
+# above it in the tree.
YT_DIR=""
# These options can be set to customize the installation.
-INST_PY3=1 # Install Python 3 instead of Python 2. If this is turned
- # on, all Python packages (including yt) will be installed
- # in Python 3.
-INST_GIT=1 # Install git or not? If git is not already installed, yt
- # cannot be installed from source. Ignored if INST_CONDA=0
-INST_HG=0 # Install Mercurial or not? Ignored if INST_CONDA=0.
-INST_EMBREE=0 # Install dependencies needed for Embree-accelerated
- # ray tracing
-
-# These options control whether low-level system libraries are installed
-# they are necessary for building yt's dependencies from source and are
-# ignored when INST_CONDA=1
-
-INST_ZLIB=1 # On some systems (Kraken) matplotlib has issues with
- # the system zlib, which is compiled statically.
- # If need be, you can turn this off.
-INST_BZLIB=1 # On some systems, libbzip2 is missing. This can
- # lead to broken mercurial installations.
-INST_PNG=1 # Install a local libpng? Same things apply as with zlib.
-INST_FTYPE=1 # Install FreeType2 locally?
-INST_SQLITE3=1 # Install a local version of SQLite3?
-INST_0MQ=1 # Install 0mq (for IPython) and affiliated bindings?
-
-# These variables control whether optional dependencies are installed
-
+INST_PY3=1 # Install Python 3 instead of Python 2. If this is turned on,
+ # all Python packages (including yt) will be installed
+ # in Python 3.
+INST_GIT=1 # Install git or not? If git is not already installed, yt
+ # cannot be installed from source.
+INST_EMBREE=0 # Install dependencies needed for Embree-accelerated ray tracing
INST_PYX=0 # Install PyX? Sometimes PyX can be problematic without a
# working TeX installation.
INST_ROCKSTAR=0 # Install the Rockstar halo finder?
@@ -77,83 +38,47 @@
INST_ASTROPY=0 # Install astropy?
INST_NOSE=1 # Install nose?
INST_NETCDF4=1 # Install netcdf4 and its python bindings?
-
-# These options allow you to customize the builds of yt dependencies.
-# They are only used if INST_CONDA=0.
-
-# If you need to pass anything to the matplotlib build, do so here.
-MPL_SUPP_LDFLAGS=""
-MPL_SUPP_CFLAGS=""
-MPL_SUPP_CXXFLAGS=""
+INST_HG=0 # Install Mercurial or not?
-# If you need to supply arguments to the NumPy or SciPy build, supply them here
-# This one turns on gfortran manually:
-#NUMPY_ARGS="--fcompiler=gnu95"
-# If you absolutely can't get the fortran to work, try this:
-#NUMPY_ARGS="--fcompiler=fake"
+# This is the branch we will install from for INST_YT_SOURCE=1
+BRANCH="master"
-# If you want to spawn multiple Make jobs, here's the place to set the
-# arguments. For instance, "-j4"
-MAKE_PROCS=""
-
-# These variables control which miniconda version and yt recipe are used
-# when INST_CONDA=1.
+# These variables control which miniconda version is used
MINICONDA_URLBASE="http://repo.continuum.io/miniconda"
MINICONDA_VERSION="latest"
-if [ ${REINST_YT} ] && [ ${REINST_YT} -eq 1 ] && [ -n ${YT_DEST} ]
+if [ ! -z "${CONDA_DEFAULT_ENV}" ]
then
- DEST_DIR=${YT_DEST}
- INST_CONDA=0
+ echo "Aborting the yt installation because you appear to already"
+ echo "have a conda environment activated. Either deactivate it with:"
+ echo
+ echo " $ source deactivate"
+ echo
+ echo "or install yt into your current environment with:"
+ echo
+ echo " $ conda install -c conda-forge yt"
+ echo
+ exit 1
fi
-
-if [ $INST_CONDA -ne 0 ]
+DEST_SUFFIX="yt-conda"
+if [ -n "${PYTHONPATH}" ]
then
- if [ ! -z "${CONDA_DEFAULT_ENV}" ]
- then
- echo "Aborting the yt installation because you appear to already"
- echo "have a conda environment activated. Either deactivate it with:"
- echo
- echo " $ source deactivate"
- echo
- echo "or install yt into your current environment with:"
- echo
- echo " $ conda install -c conda-forge yt"
- echo
- exit 1
- fi
- DEST_SUFFIX="yt-conda"
- if [ -n "${PYTHONPATH}" ]
- then
- echo "WARNING WARNING WARNING WARNING WARNING WARNING WARNING"
- echo "*******************************************************"
- echo
- echo "The PYTHONPATH environment variable is set to:"
- echo
- echo " $PYTHONPATH"
- echo
- echo "If dependencies of yt (numpy, scipy, matplotlib) are installed"
- echo "to this path, this may cause issues. Exit the install script"
- echo "with Ctrl-C and unset PYTHONPATH if you are unsure."
- echo "Hit enter to continue."
- echo
- echo "WARNING WARNING WARNING WARNING WARNING WARNING WARNING"
- echo "*******************************************************"
- read -p "[hit enter]"
- fi
-else
- if [ $INST_YT_SOURCE -eq 0 ]
- then
- echo "yt must be compiled from source if INST_CONDA is set to 0"
- echo "Please set INST_YT_SOURCE to 1 and re-run."
- exit 1
- fi
- if [ $INST_GIT -eq 1 ]
- then
- INST_GIT=0
- fi
- DEST_SUFFIX="yt-`uname -m`"
+ echo "WARNING WARNING WARNING WARNING WARNING WARNING WARNING"
+ echo "*******************************************************"
+ echo
+ echo "The PYTHONPATH environment variable is set to:"
+ echo
+ echo " $PYTHONPATH"
+ echo
+ echo "If dependencies of yt (numpy, scipy, matplotlib) are installed"
+ echo "to this path, this may cause issues. Exit the install script"
+ echo "with Ctrl-C and unset PYTHONPATH if you are unsure."
+ echo "Hit enter to continue."
+ echo
+ echo "WARNING WARNING WARNING WARNING WARNING WARNING WARNING"
+ echo "*******************************************************"
+ read -p "[hit enter]"
fi
if [ -z "${DEST_DIR}" ]
@@ -204,31 +129,18 @@
function write_config
{
CONFIG_FILE=${DEST_DIR}/.yt_config
-
- echo INST_GIT=${INST_GIT} > ${CONFIG_FILE}
- echo INST_ZLIB=${INST_ZLIB} >> ${CONFIG_FILE}
- echo INST_BZLIB=${INST_BZLIB} >> ${CONFIG_FILE}
- echo INST_PNG=${INST_PNG} >> ${CONFIG_FILE}
- echo INST_FTYPE=${INST_FTYPE} >> ${CONFIG_FILE}
- echo INST_SQLITE3=${INST_SQLITE3} >> ${CONFIG_FILE}
+ echo INST_YT_SOURCE=${INST_YT_SOURCE} > ${CONFIG_FILE}
+ echo INST_GIT=${INST_GIT} >> ${CONFIG_FILE}
echo INST_PYX=${INST_PYX} >> ${CONFIG_FILE}
- echo INST_0MQ=${INST_0MQ} >> ${CONFIG_FILE}
echo INST_PY3=${INST_PY3} >> ${CONFIG_FILE}
echo INST_ROCKSTAR=${INST_ROCKSTAR} >> ${CONFIG_FILE}
echo INST_SCIPY=${INST_SCIPY} >> ${CONFIG_FILE}
+ echo INST_EMBREE=${INST_EMBREE} >> ${CONFIG_FILE}
+ echo INST_H5PY=${INST_H5PY} >> ${CONFIG_FILE}
+ echo INST_ASTROPY=${INST_ASTROPY} >> ${CONFIG_FILE}
+ echo INST_NOSE=${INST_NOSE} >> ${CONFIG_FILE}
+
echo YT_DIR=${YT_DIR} >> ${CONFIG_FILE}
- echo MPL_SUPP_LDFLAGS=${MPL_SUPP_LDFLAGS} >> ${CONFIG_FILE}
- echo MPL_SUPP_CFLAGS=${MPL_SUPP_CFLAGS} >> ${CONFIG_FILE}
- echo MPL_SUPP_CXXFLAGS=${MPL_SUPP_CXXFLAGS} >> ${CONFIG_FILE}
- echo MAKE_PROCS=${MAKE_PROCS} >> ${CONFIG_FILE}
- if [ ${HDF5_DIR} ]
- then
- echo ${HDF5_DIR} >> ${CONFIG_FILE}
- fi
- if [ ${NUMPY_ARGS} ]
- then
- echo ${NUMPY_ARGS} >> ${CONFIG_FILE}
- fi
}
function get_willwont
@@ -246,147 +158,22 @@
MYHOST=`hostname -s` # just give the short one, not FQDN
MYHOSTLONG=`hostname` # FQDN, for Ranger
MYOS=`uname -s` # A guess at the OS
- if [ "${MYHOST##kraken}" != "${MYHOST}" ]
- then
- echo "Looks like you're on Kraken."
- echo
- echo " ******************************************"
- echo " * It may be better to use the yt module! *"
- echo " * *"
- echo " * $ module load yt *"
- echo " * *"
- echo " ******************************************"
- echo
- echo "IF YOU CHOOSE TO PROCEED:"
- echo "YOU MUST BE IN THE GNU PROGRAMMING ENVIRONMENT"
- echo " $ module swap PrgEnv-pgi PrgEnv-gnu"
- echo
- return
- fi
- if [ "${MYHOST##nautilus}" != "${MYHOST}" ]
- then
- echo "Looks like you're on Nautilus."
- echo
- echo " ******************************************"
- echo " * It may be better to use the yt module! *"
- echo " * *"
- echo " * $ module load yt *"
- echo " * *"
- echo " ******************************************"
- echo
- echo "NOTE: YOU MUST BE IN THE GNU PROGRAMMING ENVIRONMENT"
- echo " $ module swap PE-intel PE-gnu"
- echo
- echo "Additionally, note that by default, yt will OVERWRITE"
- echo "any existing installations from Kraken! You might want"
- echo "to adjust the variable DEST_SUFFIX in the install script."
- echo
- return
- fi
- if [ "${MYHOST##verne}" != "${MYHOST}" ]
- then
- echo "Looks like you're on Verne."
- echo
- echo "NOTE: YOU MUST BE IN THE GNU PROGRAMMING ENVIRONMENT"
- echo "This command will take care of that for you:"
- echo
- echo " $ module swap PE-pgi PE-gnu"
- echo
- fi
- if [ "${MYHOST##steele}" != "${MYHOST}" ]
- then
- echo "Looks like you're on Steele."
- echo
- echo "NOTE: YOU MUST BE IN THE GNU PROGRAMMING ENVIRONMENT"
- echo "These commands should take care of that for you:"
- echo
- echo " $ module purge"
- echo " $ module load gcc"
- echo
- fi
- if [ "${MYHOST##midway}" != "${MYHOST}" ]
- then
- echo "Looks like you're on Midway."
- echo
- echo " ******************************************"
- echo " * It may be better to use the yt module! *"
- echo " * *"
- echo " * $ module load yt *"
- echo " * *"
- echo " ******************************************"
- echo
- return
- fi
if [ "${MYOS##Darwin}" != "${MYOS}" ]
then
- echo "Looks like you're running on Mac OSX."
+ echo "Looks like you're running on MacOS."
echo
echo "NOTE: you must have the Xcode command line tools installed."
echo
- echo "The instructions for obtaining these tools varies according"
- echo "to your exact OS version. On older versions of OS X, you"
- echo "must register for an account on the apple developer tools"
- echo "website: https://developer.apple.com/downloads to obtain the"
- echo "download link."
- echo
- echo "We have gathered some additional instructions for each"
- echo "version of OS X below. If you have trouble installing yt"
- echo "after following these instructions, don't hesitate to contact"
- echo "the yt user's e-mail list."
- echo
- echo "You can see which version of OSX you are running by clicking"
- echo "'About This Mac' in the apple menu on the left hand side of"
- echo "menu bar. We're assuming that you've installed all operating"
- echo "system updates; if you have an older version, we suggest"
- echo "running software update and installing all available updates."
- echo
- echo "OS X 10.5.8: search for and download Xcode 3.1.4 from the"
- echo "Apple developer tools website."
- echo
- echo "OS X 10.6.8: search for and download Xcode 3.2 from the Apple"
- echo "developer tools website. You can either download the"
- echo "Xcode 3.2.2 Developer Tools package (744 MB) and then use"
- echo "Software Update to update to XCode 3.2.6 or"
- echo "alternatively, you can download the Xcode 3.2.6/iOS SDK"
- echo "bundle (4.1 GB)."
- echo
- echo "OS X 10.7.5: download Xcode 4.2 from the mac app store"
- echo "(search for Xcode)."
- echo "Alternatively, download the Xcode command line tools from"
- echo "the Apple developer tools website."
- echo
- echo "OS X 10.8.4, 10.9, 10.10, and 10.11:"
- echo "download the appropriate version of Xcode from the"
- echo "mac app store (search for Xcode)."
+ echo "Download the appropriate version of Xcode from the"
+ echo "Mac App Store (search for Xcode)."
echo
echo "Additionally, you will have to manually install the Xcode"
echo "command line tools."
echo
- echo "For OS X 10.8, see:"
- echo "http://stackoverflow.com/questions/9353444"
- echo
- echo "For OS X 10.9 and newer the command line tools can be installed"
+ echo "For MacOS 10.10 and newer the command line tools can be installed"
echo "with the following command:"
echo " xcode-select --install"
echo
- if [ $INST_CONDA -eq 0 ]
- then
- echo "For OS X 10.11, you will additionally need to install the"
- echo "OpenSSL library using a package manager like homebrew or"
- echo "macports."
- echo
- echo "If your install fails with a message like"
- echo " ImportError: cannot import HTTPSHandler"
- echo "then you do not have the OpenSSL headers available in a"
- echo "location visible to your C compiler. Consider setting"
- echo "INST_CONDA=1 instead, as conda's python bundles OpenSSL."
- fi
- OSX_VERSION=`sw_vers -productVersion`
- if [ "${OSX_VERSION##10.8}" != "${OSX_VERSION}" ]
- then
- MPL_SUPP_CFLAGS="${MPL_SUPP_CFLAGS} -mmacosx-version-min=10.7"
- MPL_SUPP_CXXFLAGS="${MPL_SUPP_CXXFLAGS} -mmacosx-version-min=10.7"
- fi
fi
if [ -f /etc/redhat-release ]
then
@@ -462,31 +249,6 @@
echo " to avoid conflicts with other command-line programs "
echo " (like eog and evince, for example)."
fi
- if [ $INST_SCIPY -eq 1 ]
- then
- echo
- echo "Looks like you've requested that the install script build SciPy."
- echo
- echo "If the SciPy build fails, please uncomment one of the the lines"
- echo "at the top of the install script that sets NUMPY_ARGS, delete"
- echo "any broken installation tree, and re-run the install script"
- echo "verbatim."
- echo
- echo "If that doesn't work, don't hesitate to ask for help on the yt"
- echo "user's mailing list."
- echo
- fi
- if [ ! -z "${CFLAGS}" ]
- then
- echo "******************************************"
- echo "******************************************"
- echo "** **"
- echo "** Your CFLAGS is not empty. **"
- echo "** This can break h5py compilation. **"
- echo "** **"
- echo "******************************************"
- echo "******************************************"
- fi
}
function log_cmd
@@ -506,11 +268,6 @@
echo "Please set INST_YT_SOURCE to 1 and re-run the install script."
exit 1
fi
- if [ $INST_CONDA -eq 0 ]
- then
- echo "Embree support has not yet been implemented for INST_CONDA=0."
- exit 1
- fi
if [ `uname` = "Darwin" ]
then
EMBREE="embree-2.8.0.x86_64.macosx"
@@ -538,17 +295,6 @@
fi
fi
-if [ $INST_NETCDF4 -ne 0 ]
-then
- if [ $INST_CONDA -eq 0 ]
- then
- echo "This script can only install netcdf4 through conda."
- echo "Please set INST_CONDA to 1 to install netcdf4"
- echo "Setting INST_NETCDF4=0"
- INST_NETCDF4=0
- fi
-fi
-
echo
echo
echo "========================================================================"
@@ -562,10 +308,6 @@
echo "the script if you aren't such a fan."
echo
-printf "%-18s = %s so I " "INST_CONDA" "${INST_CONDA}"
-get_willwont ${INST_CONDA}
-echo "be installing a conda-based python environment"
-
printf "%-18s = %s so I " "INST_YT_SOURCE" "${INST_YT_SOURCE}"
get_willwont ${INST_YT_SOURCE}
echo "be compiling yt from source"
@@ -582,29 +324,6 @@
get_willwont ${INST_EMBREE}
echo "be installing Embree"
-if [ $INST_CONDA -eq 0 ]
-then
- printf "%-18s = %s so I " "INST_ZLIB" "${INST_ZLIB}"
- get_willwont ${INST_ZLIB}
- echo "be installing zlib"
-
- printf "%-18s = %s so I " "INST_BZLIB" "${INST_BZLIB}"
- get_willwont ${INST_BZLIB}
- echo "be installing bzlib"
-
- printf "%-18s = %s so I " "INST_PNG" "${INST_PNG}"
- get_willwont ${INST_PNG}
- echo "be installing libpng"
-
- printf "%-18s = %s so I " "INST_FTYPE" "${INST_FTYPE}"
- get_willwont ${INST_FTYPE}
- echo "be installing freetype2"
-
- printf "%-18s = %s so I " "INST_SQLITE3" "${INST_SQLITE3}"
- get_willwont ${INST_SQLITE3}
- echo "be installing SQLite3"
-fi
-
printf "%-18s = %s so I " "INST_PYX" "${INST_PYX}"
get_willwont ${INST_PYX}
echo "be installing PyX"
@@ -627,16 +346,6 @@
echo
-if [ $INST_CONDA -eq 0 ]
-then
- if [ -z "$HDF5_DIR" ]
- then
- echo "HDF5_DIR is not set, so I will be installing HDF5"
- else
- echo "HDF5_DIR=${HDF5_DIR} , so I will not be installing HDF5"
- fi
-fi
-
echo
echo "Installation will be to"
echo " ${DEST_DIR}"
@@ -654,21 +363,13 @@
host_specific
fi
-if [ $INST_CONDA -eq 0 ]
-then
- if [ ${USED_CONFIG} ]
- then
- echo "Settings were loaded from ${CONFIG_FILE}."
- echo "Remove this file if you wish to return to the default settings."
- echo
- fi
-fi
-echo "========================================================================"
echo
+
if [[ $1 != "--yes" ]]
then
read -p "[hit enter] "
fi
+
echo
echo "Awesome! Here we go."
echo
@@ -694,49 +395,6 @@
PYTHON_EXEC='python2.7'
fi
-function do_setup_py
-{
- [ -e $1/done ] && return
- LIB=$1
- shift
- if [ -z "$@" ]
- then
- echo "Installing $LIB"
- else
- echo "Installing $LIB (arguments: '$@')"
- fi
- [ ! -e $LIB/extracted ] && tar xfz $LIB.tar.gz
- touch $LIB/extracted
- BUILD_ARGS=""
- PYEXE=${PYTHON_EXEC}
- case $LIB in
- *h5py*)
- pushd $LIB &> /dev/null
- ( ${DEST_DIR}/bin/${PYTHON_EXEC} setup.py configure --hdf5=${HDF5_DIR} 2>&1 ) 1>> ${LOG_FILE} || do_exit
- popd &> /dev/null
- ;;
- *numpy*)
- if [ -e ${DEST_DIR}/lib/${PYTHON_EXEC}/site-packages/numpy/__init__.py ]
- then
- VER=$(${DEST_DIR}/bin/${PYTHON_EXEC} -c 'from distutils.version import StrictVersion as SV; \
- import numpy; print SV(numpy.__version__) < SV("1.8.0")')
- if [ $VER == "True" ]
- then
- echo "Removing previous NumPy instance (see issue #889)"
- rm -rf ${DEST_DIR}/lib/${PYTHON_EXEC}/site-packages/{numpy*,*.pth}
- fi
- fi
- ;;
- *)
- ;;
- esac
- cd $LIB
- ( ${DEST_DIR}/bin/${PYEXE} setup.py build ${BUILD_ARGS} $* 2>&1 ) 1>> ${LOG_FILE} || do_exit
- ( ${DEST_DIR}/bin/${PYEXE} setup.py install 2>&1 ) 1>> ${LOG_FILE} || do_exit
- touch done
- cd ..
-}
-
if type -P curl &>/dev/null
then
echo "Using curl"
@@ -746,40 +404,6 @@
export GETFILE="wget -nv"
fi
-if type -P sha512sum &> /dev/null
-then
- echo "Using sha512sum"
- export SHASUM="sha512sum"
-elif type -P shasum &> /dev/null
-then
- echo "Using shasum -a 512"
- export SHASUM="shasum -a 512"
-else
- echo
- echo "I am unable to locate any shasum-like utility."
- echo "ALL FILE INTEGRITY IS NOT VERIFIABLE."
- echo "THIS IS PROBABLY A BIG DEAL."
- echo
- echo "(I'll hang out for a minute for you to consider this.)"
- sleep 60
-fi
-
-function get_ytproject
-{
- [ -e $1 ] && return
- echo "Downloading $1 from yt-project.org"
- ${GETFILE} "http://yt-project.org/dependencies/$1" || do_exit
- ( ${SHASUM} -c $1.sha512 2>&1 ) 1>> ${LOG_FILE} || do_exit
-}
-
-function get_ytdata
-{
- echo "Downloading $1 from yt-project.org"
- [ -e $1 ] && return
- ${GETFILE} "http://yt-project.org/data/$1" || do_exit
- ( ${SHASUM} -c $1.sha512 2>&1 ) 1>> ${LOG_FILE} || do_exit
-}
-
function test_install
{
echo "Testing that yt can be imported"
@@ -788,298 +412,206 @@
ORIG_PWD=`pwd`
-if [ -z "${DEST_DIR}" ]
+MYARCH=`uname -m`
+MYOS=`uname -s`
+
+if [ $MYOS = "Darwin" ]
+then
+ MINICONDA_OS="MacOSX"
+ MINICONDA_ARCH="x86_64"
+elif [ $MYOS = "Linux" ]
then
- echo "Edit this script, set the DEST_DIR parameter and re-run."
+ MINICONDA_OS="Linux"
+ if [ $MYARCH = "i386" ]
+ then
+ MINICONDA_ARCH="x86"
+ elif [ $MYARCH = "i686" ]
+ then
+ MINICONDA_ARCH="x86"
+ elif [ $MYARCH = "x86_64" ]
+ then
+ MINICONDA_ARCH="x86_64"
+ else
+ echo "Not sure which architecture you are running."
+ echo "Going with x86_64 architecture."
+ MINICONDA_OS="Linux-x86_64"
+ fi
+else
+ echo "The yt install script is not supported on the ${MYOS}"
+ echo "operating system."
exit 1
fi
-# Set paths to what they should be when yt is activated.
-if [ $INST_CONDA -eq 0 ]
+if [ $INST_PY3 -eq 1 ]
then
- export PATH=${DEST_DIR}/bin:$PATH
- export LD_LIBRARY_PATH=${DEST_DIR}/lib:$LD_LIBRARY_PATH
- export PYTHONPATH=${DEST_DIR}/lib/${PYTHON_EXEC}/site-packages
+ PY_VERSION='3'
+else
+ PY_VERSION='2'
+fi
+
+MINICONDA_PKG="Miniconda${PY_VERSION}-${MINICONDA_VERSION}-${MINICONDA_OS}-${MINICONDA_ARCH}.sh"
- # Write config settings to file.
- CONFIG_FILE=${DEST_DIR}/.yt_config
- mkdir -p ${DEST_DIR}
- if [ -z ${REINST_YT} ] || [ ${REINST_YT} -neq 1 ]
- then
- write_config
- elif [ ${REINST_YT} ] && [ ${REINST_YT} -eq 1 ] && [ -f ${CONFIG_FILE} ]
- then
- USED_CONFIG=1
- source ${CONFIG_FILE}
- fi
-
- # Get supplemental data.
+echo
+echo "Downloading ${MINICONDA_URLBASE}/${MINICONDA_PKG}"
+echo
- mkdir -p ${DEST_DIR}/data
- cd ${DEST_DIR}/data
- echo 'de6d8c6ea849f0206d219303329a0276b3cce7c051eec34377d42aacbe0a4f47ac5145eb08966a338ecddd2b83c8f787ca9956508ad5c39ee2088ad875166410 cloudy_emissivity.h5' > cloudy_emissivity.h5.sha512
- [ ! -e cloudy_emissivity.h5 ] && get_ytdata cloudy_emissivity.h5
- echo '0f714ae2eace0141b1381abf1160dc8f8a521335e886f99919caf3beb31df1fe271d67c7b2a804b1467949eb16b0ef87a3d53abad0e8160fccac1e90d8d9e85f apec_emissivity.h5' > apec_emissivity.h5.sha512
- [ ! -e apec_emissivity.h5 ] && get_ytdata apec_emissivity.h5
-
- mkdir -p ${DEST_DIR}/src
- cd ${DEST_DIR}/src
+if [ -f ${MINICONDA_PKG} ]
+then
+ rm $MINICONDA_PKG
+fi
- PYTHON2='Python-2.7.11'
- PYTHON3='Python-3.5.1'
- CYTHON='Cython-0.23.5'
- if [ $INST_PY3 -eq 0 ]
- then
- PYX='PyX-0.12.1'
- else
- PYX='PyX-0.14.1'
- fi
- BZLIB='bzip2-1.0.6'
- FREETYPE_VER='freetype-2.4.12'
- H5PY='h5py-2.5.0'
- HDF5='hdf5-1.8.14'
- LAPACK='lapack-3.4.2'
- PNG='libpng-1.6.3'
- MATPLOTLIB='matplotlib-1.5.1'
- NOSE='nose-1.3.7'
- NUMPY='numpy-1.11.0'
- GITPYTHON='GitPython-2.1.3'
- ROCKSTAR='rockstar-0.99.6'
- SCIPY='scipy-0.17.0'
- SQLITE='sqlite-autoconf-3071700'
- SYMPY='sympy-1.0'
- ZLIB='zlib-1.2.8'
- SETUPTOOLS='setuptools-20.6.7'
- ASTROPY='astropy-1.1.2'
-
- # Now we dump all our SHA512 files out.
- echo '9052d74bbd0c93757fd916939cc3c39eb1aba6c9692b48887ae577256bec64b39b1fd25b6c751e6c8fe723de4c0ddf9a1a207de39f75b0839500dfcdde69f925 Cython-0.23.5.tar.gz' > Cython-0.23.5.tar.gz.sha512
- if [ $INST_PY3 -eq 0 ]
- then
- echo '4941f5aa21aff3743546495fb073c10d2657ff42b2aff401903498638093d0e31e344cce778980f28a7170c6d29eab72ac074277b9d4088376e8692dc71e55c1 PyX-0.12.1.tar.gz' > PyX-0.12.1.tar.gz.sha512
- else
- echo '16265bbdcaf28ce194189a2987b32952f296c850b829454bcccce0abd23838bfca0276c3e9c8e96b8cbfaf1473bf14669f9b7f2032ee039b61ae59ea3aa45a20 PyX-0.14.1.tar.gz' > PyX-0.14.1.tar.gz.sha512
- fi
- echo 'f21df53da87e9e3c14599a34388976e7dd09b951dff3c4b978fe224beeff07e749c0059ffd94f68ca9b75ecaef142b285d579b8dfaad4eab85aca33957114937 Python-2.7.11.tgz' > Python-2.7.11.tgz.sha512
- echo '73f1477f3d3f5bd978c4ea1d1b679467b45e9fd2f443287b88c5c107a9ced580c56e0e8f33acea84e06b11a252e2a4e733120b721a9b6e1bb3d34493a3353bfb Python-3.5.1.tgz' > Python-3.5.1.tgz.sha512
- echo 'b83c4a1415a3eb8c016507705d0d2f22971e4da937bb97953eec08f8f856933d8fa76ce8c536122235b19e7879b16add2e20fd2fee3e488f9b2b4bf1b9f4dbdb astropy-1.1.2.tar.gz' > astropy-1.1.2.tar.gz.sha512
- echo '276bd9c061ec9a27d478b33078a86f93164ee2da72210e12e2c9da71dcffeb64767e4460b93f257302b09328eda8655e93c4b9ae85e74472869afbeae35ca71e blas.tar.gz' > blas.tar.gz.sha512
- echo '00ace5438cfa0c577e5f578d8a808613187eff5217c35164ffe044fbafdfec9e98f4192c02a7d67e01e5a5ccced630583ad1003c37697219b0f147343a3fdd12 bzip2-1.0.6.tar.gz' > bzip2-1.0.6.tar.gz.sha512
- echo '609a68a3675087e0cc95268574f31e104549daa48efe15a25a33b8e269a93b4bd160f4c3e8178dca9c950ef5ca514b039d6fd1b45db6af57f25342464d0429ce freetype-2.4.12.tar.gz' > freetype-2.4.12.tar.gz.sha512
- echo '4a83f9ae1855a7fad90133b327d426201c8ccfd2e7fbe9f39b2d61a2eee2f3ebe2ea02cf80f3d4e1ad659f8e790c173df8cc99b87d0b7ce63d34aa88cfdc7939 h5py-2.5.0.tar.gz' > h5py-2.5.0.tar.gz.sha512
- echo '4073fba510ccadaba41db0939f909613c9cb52ba8fb6c1062fc9118edc601394c75e102310be1af4077d07c9b327e6bbb1a6359939a7268dc140382d0c1e0199 hdf5-1.8.14.tar.gz' > hdf5-1.8.14.tar.gz.sha512
- echo '8770214491e31f0a7a3efaade90eee7b0eb20a8a6ab635c5f854d78263f59a1849133c14ef5123d01023f0110cbb9fc6f818da053c01277914ae81473430a952 lapack-3.4.2.tar.gz' > lapack-3.4.2.tar.gz.sha512
- echo '887582e5a22e4cde338aa8fec7a89f6dd31f2f02b8842735f00f970f64582333fa03401cea6d01704083403c7e8b7ebc26655468ce930165673b33efa4bcd586 libpng-1.6.3.tar.gz' > libpng-1.6.3.tar.gz.sha512
- echo 'a0e78b5027a3a49cf8e77dc0d26f5f380dcd80f7b309b6121199acd5e1d94f48482864a9eee3bd397f7ac6f07fe1d3c21bf517217df3c72e8e3d105b7c2ae58e matplotlib-1.5.1.tar.gz' > matplotlib-1.5.1.tar.gz.sha512
- echo 'e65c914f621f8da06b9ab11a0ff2763d6e29b82ce2aaed56da0e3773dc899d9deb1f20015789d44c65a5dad7214520f5b659b3f8d7695fb207ad3f78e5cf1b62 nose-1.3.7.tar.gz' > nose-1.3.7.tar.gz.sha512
- echo '92c1889397ad013e25da3a0657fc01e787d528fc19c29cc2acd286c3f07d41b984252583457b1b9259fc303afbe9694565cdcf5752eb4ecb950cc7a99ec1ad8b numpy-1.11.0.tar.gz' > numpy-1.11.0.tar.gz.sha512
- echo '918ff1765a85a818619165c2bcbb0d417f35c979c2f42f1bb7e41636696c0cb4d6837725f3655fbdfebea966476d1255ee18adabe9ed5536455b63336a1f399d GitPython-2.1.3.tar.gz' > GitPython-2.1.3.tar.gz.sha512
- echo 'de6409d75a3ff3cf1e5391d3b09126f0bc7e1a40a15f9bee244195638fe2f8481fca032896d8534623e6122ff59aaf669664e27ff89cf1b094a5ce7312f220b7 scipy-0.17.0.tar.gz' > scipy-0.17.0.tar.gz.sha512
- echo '96f3e51b46741450bc6b63779c10ebb4a7066860fe544385d64d1eda52592e376a589ef282ace2e1df73df61c10eab1a0d793abbdaf770e60289494d4bf3bcb4 sqlite-autoconf-3071700.tar.gz' > sqlite-autoconf-3071700.tar.gz.sha512
- echo '977db6e9bc6a5918cceb255981a57e85e7060c0922aefd2968b004d25d704e25a5cb5bbe09eb387e8695581e23e2825d9c40310068fe25ece7e9c23037a21f39 sympy-1.0.tar.gz' > sympy-1.0.tar.gz.sha512
- echo 'ece209d4c7ec0cb58ede791444dc754e0d10811cbbdebe3df61c0fd9f9f9867c1c3ccd5f1827f847c005e24eef34fb5bf87b5d3f894d75da04f1797538290e4a zlib-1.2.8.tar.gz' > zlib-1.2.8.tar.gz.sha512
- echo '91a212b5007f9fdfacb4341e06dc0355c5c29897eb8ea407dd4864091f845ba1417bb0d33b5ed6897869d0233e2d0ec6548898d3dbe9eda23f751829bd51a104 setuptools-20.6.7.tar.gz' > setuptools-20.6.7.tar.gz.sha512
- # Individual processes
- [ -z "$HDF5_DIR" ] && get_ytproject $HDF5.tar.gz
- [ $INST_ZLIB -eq 1 ] && get_ytproject $ZLIB.tar.gz
- [ $INST_BZLIB -eq 1 ] && get_ytproject $BZLIB.tar.gz
- [ $INST_PNG -eq 1 ] && get_ytproject $PNG.tar.gz
- [ $INST_FTYPE -eq 1 ] && get_ytproject $FREETYPE_VER.tar.gz
- [ $INST_SQLITE3 -eq 1 ] && get_ytproject $SQLITE.tar.gz
- [ $INST_PYX -eq 1 ] && get_ytproject $PYX.tar.gz
- [ $INST_SCIPY -eq 1 ] && get_ytproject $SCIPY.tar.gz
- [ $INST_SCIPY -eq 1 ] && get_ytproject blas.tar.gz
- [ $INST_SCIPY -eq 1 ] && get_ytproject $LAPACK.tar.gz
- if [ $INST_PY3 -eq 1 ]
- then
- get_ytproject $PYTHON3.tgz
- else
- get_ytproject $PYTHON2.tgz
- fi
- [ $INST_H5PY -eq 1 ] && get_ytproject $H5PY.tar.gz
- [ $INST_NOSE -eq 1 ] && get_ytproject $NOSE.tar.gz
- [ $INST_ASTROPY -eq 1 ] && get_ytproject $ASTROPY.tar.gz
- get_ytproject $NUMPY.tar.gz
- get_ytproject $MATPLOTLIB.tar.gz
- get_ytproject $CYTHON.tar.gz
- get_ytproject $GITPYTHON.tar.gz
- get_ytproject $SYMPY.tar.gz
- get_ytproject $SETUPTOOLS.tar.gz
+echo "Installing the Miniconda python environment."
+
+if [ -e ${DEST_DIR} ]
+then
+ rm -rf $DEST_DIR/*
+else
+ mkdir $DEST_DIR
+fi
- if [ $INST_BZLIB -eq 1 ]
- then
- if [ ! -e $BZLIB/done ]
- then
- [ ! -e $BZLIB ] && tar xfz $BZLIB.tar.gz
- echo "Installing BZLIB"
- cd $BZLIB
- if [ `uname` = "Darwin" ]
- then
- if [ -z "${CC}" ]
- then
- sed -i.bak 's/soname/install_name/' Makefile-libbz2_so
- else
- sed -i.bak -e 's/soname/install_name/' -e "s|CC=gcc|CC=${CC}|" Makefile-libbz2_so
- fi
- fi
- ( make install CFLAGS=-fPIC LDFLAGS=-fPIC PREFIX=${DEST_DIR} 2>&1 ) 1>> ${LOG_FILE} || do_exit
- ( make -f Makefile-libbz2_so CFLAGS=-fPIC LDFLAGS=-fPIC PREFIX=${DEST_DIR} 2>&1 ) 1>> ${LOG_FILE} || do_exit
- ( cp -v libbz2.so.1.0.6 ${DEST_DIR}/lib 2>&1 ) 1>> ${LOG_FILE} || do_exit
- touch done
- cd ..
- fi
- BZLIB_DIR=${DEST_DIR}
- export LDFLAGS="${LDFLAGS} -L${BZLIB_DIR}/lib/ -L${BZLIB_DIR}/lib64/"
- LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${BZLIB_DIR}/lib/"
- fi
+log_cmd ${GETFILE} ${MINICONDA_URLBASE}/${MINICONDA_PKG} || do_exit
+
+log_cmd bash ./${MINICONDA_PKG} -b -p $DEST_DIR -f
+
+# Need to set PATH so we use miniconda's python environment
+export PATH=${DEST_DIR}/bin:$PATH
+
+echo "Installing the necessary packages for yt."
+echo "This may take a while, but don't worry. yt loves you."
- if [ $INST_ZLIB -eq 1 ]
- then
- if [ ! -e $ZLIB/done ]
- then
- [ ! -e $ZLIB ] && tar xfz $ZLIB.tar.gz
- echo "Installing ZLIB"
- cd $ZLIB
- ( ./configure --shared --prefix=${DEST_DIR}/ 2>&1 ) 1>> ${LOG_FILE} || do_exit
- ( make install 2>&1 ) 1>> ${LOG_FILE} || do_exit
- ( make clean 2>&1 ) 1>> ${LOG_FILE} || do_exit
- touch done
- cd ..
- fi
- ZLIB_DIR=${DEST_DIR}
- export LDFLAGS="${LDFLAGS} -L${ZLIB_DIR}/lib/ -L${ZLIB_DIR}/lib64/"
- LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${ZLIB_DIR}/lib/"
- fi
-
- if [ $INST_PNG -eq 1 ]
- then
- if [ ! -e $PNG/done ]
- then
- [ ! -e $PNG ] && tar xfz $PNG.tar.gz
- echo "Installing PNG"
- cd $PNG
- ( ./configure CPPFLAGS=-I${DEST_DIR}/include CFLAGS=-I${DEST_DIR}/include --prefix=${DEST_DIR}/ 2>&1 ) 1>> ${LOG_FILE} || do_exit
- ( make install 2>&1 ) 1>> ${LOG_FILE} || do_exit
- ( make clean 2>&1) 1>> ${LOG_FILE} || do_exit
- touch done
- cd ..
- fi
- PNG_DIR=${DEST_DIR}
- export LDFLAGS="${LDFLAGS} -L${PNG_DIR}/lib/ -L${PNG_DIR}/lib64/"
- LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${PNG_DIR}/lib/"
- fi
-
- if [ $INST_FTYPE -eq 1 ]
- then
- if [ ! -e $FREETYPE_VER/done ]
- then
- [ ! -e $FREETYPE_VER ] && tar xfz $FREETYPE_VER.tar.gz
- echo "Installing FreeType2"
- cd $FREETYPE_VER
- ( ./configure CFLAGS=-I${DEST_DIR}/include --prefix=${DEST_DIR}/ 2>&1 ) 1>> ${LOG_FILE} || do_exit
- ( make 2>&1 ) 1>> ${LOG_FILE} || do_exit
- ( make install 2>&1 ) 1>> ${LOG_FILE} || do_exit
- ( make clean 2>&1) 1>> ${LOG_FILE} || do_exit
- touch done
- cd ..
- fi
- FTYPE_DIR=${DEST_DIR}
- export LDFLAGS="${LDFLAGS} -L${FTYPE_DIR}/lib/ -L${FTYPE_DIR}/lib64/"
- LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${FTYPE_DIR}/lib/"
- fi
+declare -a YT_DEPS
+YT_DEPS+=('python')
+YT_DEPS+=('setuptools')
+YT_DEPS+=('numpy')
+YT_DEPS+=('jupyter')
+YT_DEPS+=('ipython')
+YT_DEPS+=('sphinx')
+if [ ${INST_GIT} -eq 1 ]
+then
+ YT_DEPS+=('git')
+ YT_DEPS+=('gitpython')
+fi
+if [ $INST_H5PY -ne 0 ]
+then
+ YT_DEPS+=('h5py')
+fi
+YT_DEPS+=('matplotlib')
+YT_DEPS+=('cython')
+if [ $INST_NOSE -ne 0 ]
+then
+ YT_DEPS+=('nose')
+fi
+if [ $INST_SCIPY -ne 0 ]
+then
+ YT_DEPS+=('scipy')
+fi
+if [ $INST_ASTROPY -ne 0 ]
+then
+ YT_DEPS+=('astropy')
+fi
+YT_DEPS+=('conda-build')
+if [ $INST_PY3 -eq 0 ] && [ $INST_HG -eq 1 ]
+then
+ YT_DEPS+=('mercurial')
+fi
+YT_DEPS+=('sympy')
- if [ -z "$HDF5_DIR" ]
- then
- if [ ! -e $HDF5/done ]
- then
- [ ! -e $HDF5 ] && tar xfz $HDF5.tar.gz
- echo "Installing HDF5"
- cd $HDF5
- ( ./configure --prefix=${DEST_DIR}/ --enable-shared 2>&1 ) 1>> ${LOG_FILE} || do_exit
- ( make ${MAKE_PROCS} install 2>&1 ) 1>> ${LOG_FILE} || do_exit
- ( make clean 2>&1) 1>> ${LOG_FILE} || do_exit
- touch done
- cd ..
- fi
- export HDF5_DIR=${DEST_DIR}
- else
- export HDF5_DIR=${HDF5_DIR}
- fi
- export HDF5_API=16
-
- if [ $INST_SQLITE3 -eq 1 ]
- then
- if [ ! -e $SQLITE/done ]
- then
- [ ! -e $SQLITE ] && tar xfz $SQLITE.tar.gz
- echo "Installing SQLite3"
- cd $SQLITE
- ( ./configure --prefix=${DEST_DIR}/ 2>&1 ) 1>> ${LOG_FILE} || do_exit
- ( make ${MAKE_PROCS} install 2>&1 ) 1>> ${LOG_FILE} || do_exit
- ( make clean 2>&1) 1>> ${LOG_FILE} || do_exit
- touch done
- cd ..
- fi
- fi
+if [ $INST_NETCDF4 -eq 1 ]
+then
+ YT_DEPS+=('netcdf4')
+fi
- if [ $INST_PY3 -eq 1 ]
- then
- if [ ! -e $PYTHON3/done ]
- then
- echo "Installing Python 3"
- [ ! -e $PYTHON3 ] && tar xfz $PYTHON3.tgz
- cd $PYTHON3
- ( ./configure --prefix=${DEST_DIR}/ ${PYCONF_ARGS} 2>&1 ) 1>> ${LOG_FILE} || do_exit
-
- ( make ${MAKE_PROCS} 2>&1 ) 1>> ${LOG_FILE} || do_exit
- ( make install 2>&1 ) 1>> ${LOG_FILE} || do_exit
- ( ln -sf ${DEST_DIR}/bin/python3.5 ${DEST_DIR}/bin/pyyt 2>&1 ) 1>> ${LOG_FILE}
- ( ln -sf ${DEST_DIR}/bin/python3.5 ${DEST_DIR}/bin/python 2>&1 ) 1>> ${LOG_FILE}
- ( ln -sf ${DEST_DIR}/bin/python3-config ${DEST_DIR}/bin/python-config 2>&1 ) 1>> ${LOG_FILE}
- ( make clean 2>&1) 1>> ${LOG_FILE} || do_exit
- touch done
- cd ..
- fi
- else
- if [ ! -e $PYTHON2/done ]
- then
- echo "Installing Python 2. This may take a while, but don't worry. yt loves you."
- [ ! -e $PYTHON2 ] && tar xfz $PYTHON2.tgz
- cd $PYTHON2
- ( ./configure --prefix=${DEST_DIR}/ ${PYCONF_ARGS} 2>&1 ) 1>> ${LOG_FILE} || do_exit
- ( make ${MAKE_PROCS} 2>&1 ) 1>> ${LOG_FILE} || do_exit
- ( make install 2>&1 ) 1>> ${LOG_FILE} || do_exit
- ( ln -sf ${DEST_DIR}/bin/python2.7 ${DEST_DIR}/bin/pyyt 2>&1 ) 1>> ${LOG_FILE}
- ( make clean 2>&1) 1>> ${LOG_FILE} || do_exit
- touch done
- cd ..
- fi
- fi
+log_cmd ${DEST_DIR}/bin/conda update --yes conda
- ( ${DEST_DIR}/bin/python -c "import _ssl" 2>&1 ) 1>> ${LOG_FILE}
- RESULT=$?
- if [ $RESULT -ne 0 ]
- then
- echo "Unable to import the python SSL bindings."
- echo "This means that OpenSSL is not installed or your system's OpenSSL"
- echo "installation is out of date."
- echo "Please install OpenSSL or set INST_CONDA=1"
- do_exit
- fi
-
- export PYTHONPATH=${DEST_DIR}/lib/${PYTHON_EXEC}/site-packages/
-
- # Install setuptools
- do_setup_py $SETUPTOOLS
-
+if [ $INST_GIT -eq 1 ]
+then
+ GIT_EXE=${DEST_DIR}/bin/git
+else
if type -P git &>/dev/null
then
GIT_EXE="git"
else
- echo "Cannot find git. Please install git."
- do_exit
+ if [ $INST_YT_SOURCE -eq 1 ]
+ then
+ echo "Cannot find git. Please install git or set INST_GIT=1."
+ do_exit
+ fi
+ fi
+fi
+
+log_cmd echo "DEPENDENCIES" ${YT_DEPS[@]}
+for YT_DEP in "${YT_DEPS[@]}"; do
+ echo "Installing $YT_DEP"
+ log_cmd ${DEST_DIR}/bin/conda install -c conda-forge --yes ${YT_DEP}
+done
+
+if [ $INST_PY3 -eq 1 ] && [ $INST_HG -eq 1 ]
+then
+ echo "Installing mercurial"
+ log_cmd ${DEST_DIR}/bin/conda create -y -n py27 python=2.7 mercurial
+ log_cmd ln -s ${DEST_DIR}/envs/py27/bin/hg ${DEST_DIR}/bin
+fi
+
+if [ $INST_YT_SOURCE -eq 1 ]
+then
+ log_cmd ${GIT_EXE} clone https://github.com/yt-project/yt_conda ${DEST_DIR}/src/yt_conda
+fi
+
+if [ $INST_EMBREE -eq 1 ]
+then
+ echo "Installing Embree"
+ if [ ! -d ${DEST_DIR}/src ]
+ then
+ mkdir ${DEST_DIR}/src
fi
+ cd ${DEST_DIR}/src
+ ( ${GETFILE} "$EMBREE_URL" 2>&1 ) 1>> ${LOG_FILE} || do_exit
+ log_cmd tar xfz ${EMBREE}.tar.gz
+ log_cmd mv ${DEST_DIR}/src/${EMBREE}/include/embree2 ${DEST_DIR}/include
+ log_cmd mv ${DEST_DIR}/src/${EMBREE}/lib/lib*.* ${DEST_DIR}/lib
+ if [ `uname` = "Darwin" ]
+ then
+ ln -s ${DEST_DIR}/lib/libembree.2.dylib ${DEST_DIR}/lib/libembree.dylib
+ install_name_tool -id ${DEST_DIR}/lib/libembree.2.dylib ${DEST_DIR}/lib/libembree.2.dylib
+ else
+ ln -s ${DEST_DIR}/lib/libembree.so.2 ${DEST_DIR}/lib/libembree.so
+ fi
+
+ echo "Installing pyembree from source"
+ ( ${GETFILE} "$PYEMBREE_URL" 2>&1 ) 1>> ${LOG_FILE} || do_exit
+ log_cmd unzip ${DEST_DIR}/src/master.zip
+ pushd ${DEST_DIR}/src/pyembree-master &> /dev/null
+ log_cmd ${DEST_DIR}/bin/${PYTHON_EXEC} setup.py install build_ext -I${DEST_DIR}/include -L${DEST_DIR}/lib
+ popd &> /dev/null
+fi
+if [ $INST_ROCKSTAR -eq 1 ]
+then
+ echo "Building Rockstar"
+ ( ${GIT_EXE} clone https://github.com/yt-project/rockstar ${DEST_DIR}/src/rockstar/ 2>&1 ) 1>> ${LOG_FILE}
+ ROCKSTAR_PACKAGE=$(${DEST_DIR}/bin/conda build ${DEST_DIR}/src/yt_conda/rockstar --output)
+ log_cmd ${DEST_DIR}/bin/conda build ${DEST_DIR}/src/yt_conda/rockstar
+ log_cmd ${DEST_DIR}/bin/conda install $ROCKSTAR_PACKAGE
+ ROCKSTAR_DIR=${DEST_DIR}/src/rockstar
+fi
+
+# conda doesn't package pyx, so we install manually with pip
+if [ $INST_PYX -eq 1 ]
+then
+ if [ $INST_PY3 -eq 1 ]
+ then
+ log_cmd ${DEST_DIR}/bin/pip install pyx
+ else
+ log_cmd ${DEST_DIR}/bin/pip install pyx==0.12.1
+ fi
+fi
+
+if [ $INST_YT_SOURCE -eq 0 ]
+then
+ echo "Installing yt"
+ log_cmd ${DEST_DIR}/bin/conda install -c conda-forge --yes yt
+else
+ echo "Building yt from source"
if [ -z "$YT_DIR" ]
then
if [ -e $ORIG_PWD/yt/mods.py ]
@@ -1088,512 +620,86 @@
elif [ -e $ORIG_PWD/../yt/mods.py ]
then
YT_DIR=$(dirname $ORIG_PWD)
- elif [ ! -e yt-git ]
- then
- echo "Cloning yt"
- YT_DIR="$PWD/yt-git/"
- ( ${GIT_EXE} clone https://github.com/yt-project/yt/ ${YT_DIR} 2>&1 ) 1>> ${LOG_FILE}
- elif [ -e yt-git ]
- then
- YT_DIR="$PWD/yt-git/"
+ else
+ YT_DIR="${DEST_DIR}/src/yt-git"
+ log_cmd ${GIT_EXE} clone https://github.com/yt-project/yt ${YT_DIR}
+ log_cmd ${GIT_EXE} -C ${YT_DIR} checkout ${BRANCH}
fi
echo Setting YT_DIR=${YT_DIR}
- fi
-
- # This fixes problems with gfortran linking.
- unset LDFLAGS
-
- echo "Installing pip"
- ( ${GETFILE} https://bootstrap.pypa.io/get-pip.py 2>&1 ) 1>> ${LOG_FILE} || do_exit
- ( ${DEST_DIR}/bin/${PYTHON_EXEC} get-pip.py 2>&1 ) 1>> ${LOG_FILE} || do_exit
-
- if [ $INST_SCIPY -eq 0 ]
- then
- do_setup_py $NUMPY ${NUMPY_ARGS}
else
- if [ ! -e $SCIPY/done ]
- then
- if [ ! -e BLAS/done ]
- then
- tar xfz blas.tar.gz
- echo "Building BLAS"
- cd BLAS
- gfortran -O2 -fPIC -fno-second-underscore -c *.f
- ( ar r libfblas.a *.o 2>&1 ) 1>> ${LOG_FILE}
- ( ranlib libfblas.a 2>&1 ) 1>> ${LOG_FILE}
- rm -rf *.o
- touch done
- cd ..
- fi
- if [ ! -e $LAPACK/done ]
- then
- tar xfz $LAPACK.tar.gz
- echo "Building LAPACK"
- cd $LAPACK/
- cp INSTALL/make.inc.gfortran make.inc
- ( make lapacklib OPTS="-fPIC -O2" NOOPT="-fPIC -O0" CFLAGS=-fPIC LDFLAGS=-fPIC 2>&1 ) 1>> ${LOG_FILE} || do_exit
- touch done
- cd ..
- fi
- fi
- export BLAS=$PWD/BLAS/libfblas.a
- export LAPACK=$PWD/$LAPACK/liblapack.a
- do_setup_py $NUMPY ${NUMPY_ARGS}
- do_setup_py $SCIPY ${NUMPY_ARGS}
- fi
-
- if [ -n "${MPL_SUPP_LDFLAGS}" ]
- then
- OLD_LDFLAGS=${LDFLAGS}
- export LDFLAGS="${MPL_SUPP_LDFLAGS}"
- echo "Setting LDFLAGS ${LDFLAGS}"
- fi
- if [ -n "${MPL_SUPP_CXXFLAGS}" ]
- then
- OLD_CXXFLAGS=${CXXFLAGS}
- export CXXFLAGS="${MPL_SUPP_CXXFLAGS}"
- echo "Setting CXXFLAGS ${CXXFLAGS}"
- fi
- if [ -n "${MPL_SUPP_CFLAGS}" ]
- then
- OLD_CFLAGS=${CFLAGS}
- export CFLAGS="${MPL_SUPP_CFLAGS}"
- echo "Setting CFLAGS ${CFLAGS}"
- fi
- # Now we set up the basedir for matplotlib:
- mkdir -p ${DEST_DIR}/src/$MATPLOTLIB
- echo "[directories]" >> ${DEST_DIR}/src/$MATPLOTLIB/setup.cfg
- echo "basedirlist = ${DEST_DIR}" >> ${DEST_DIR}/src/$MATPLOTLIB/setup.cfg
- if [ `uname` = "Darwin" ]
- then
- echo "[gui_support]" >> ${DEST_DIR}/src/$MATPLOTLIB/setup.cfg
- echo "macosx = False" >> ${DEST_DIR}/src/$MATPLOTLIB/setup.cfg
- fi
-
- _user_DISPLAY=$DISPLAY
- unset DISPLAY # see (yt-user link missing: "Installation failure" 01/29/15)
- do_setup_py $MATPLOTLIB
- export DISPLAY=${_user_DISPLAY}
- if [ -n "${OLD_LDFLAGS}" ]
- then
- export LDFLAG=${OLD_LDFLAGS}
- fi
- [ -n "${OLD_LDFLAGS}" ] && export LDFLAGS=${OLD_LDFLAGS}
- [ -n "${OLD_CXXFLAGS}" ] && export CXXFLAGS=${OLD_CXXFLAGS}
- [ -n "${OLD_CFLAGS}" ] && export CFLAGS=${OLD_CFLAGS}
-
- echo "Installing Jupyter"
- ( ${DEST_DIR}/bin/pip install "jupyter<2.0.0" 2>&1 ) 1>> ${LOG_FILE}
-
- do_setup_py $CYTHON
- if [ $INST_H5PY -eq 1 ]
- then
- do_setup_py $H5PY
- fi
- if [ $INST_NOSE -eq 1 ]
- then
- do_setup_py $NOSE
- fi
- if [ $INST_ASTROPY -eq 1 ]
- then
- do_setup_py $ASTROPY
- fi
- do_setup_py $GITPYTHON
- do_setup_py $SYMPY
- [ $INST_PYX -eq 1 ] && do_setup_py $PYX
-
- ( ${DEST_DIR}/bin/pip install jinja2 2>&1 ) 1>> ${LOG_FILE}
-
- # Now we build Rockstar and set its environment variable.
- if [ $INST_ROCKSTAR -eq 1 ]
- then
- if [ ! -e rockstar/done ]
- then
- echo "Building Rockstar"
- if [ ! -e rockstar ]
- then
- ( ${GIT_EXE} clone https://github.com/yt-project/rockstar 2>&1 ) 1>> ${LOG_FILE}
- fi
- cd rockstar
- ( make lib 2>&1 ) 1>> ${LOG_FILE} || do_exit
- cp librockstar.so ${DEST_DIR}/lib
- ROCKSTAR_DIR=${DEST_DIR}/src/rockstar
- echo $ROCKSTAR_DIR > ${YT_DIR}/rockstar.cfg
- touch done
- cd ..
- fi
- fi
-
- MY_PWD=`pwd`
- cd $YT_DIR
- ( ${GIT_EXE} pull 2>1 && ${GIT_EXE} checkout ${BRANCH} 2>&1 ) 1>> ${LOG_FILE}
-
- echo "Installing yt"
- [ $INST_PNG -eq 1 ] && echo $PNG_DIR > png.cfg
- ( export PATH=$DEST_DIR/bin:$PATH ; ${DEST_DIR}/bin/${PYTHON_EXEC} setup.py develop 2>&1 ) 1>> ${LOG_FILE} || do_exit
- touch done
- cd $MY_PWD
-
- if !( ( ${DEST_DIR}/bin/${PYTHON_EXEC} -c "import readline" 2>&1 )>> ${LOG_FILE}) || \
- [[ "${MYOS##Darwin}" != "${MYOS}" && $INST_PY3 -eq 1 ]]
- then
- if !( ( ${DEST_DIR}/bin/${PYTHON_EXEC} -c "import gnureadline" 2>&1 )>> ${LOG_FILE})
+ if [ ! -e $YT_DIR/.git ]
then
- echo "Installing pure-python readline"
- ( ${DEST_DIR}/bin/pip install gnureadline 2>&1 ) 1>> ${LOG_FILE}
- fi
- fi
-
- if [ -e $HOME/.matplotlib/fontList.cache ] && \
- ( grep -q python2.6 $HOME/.matplotlib/fontList.cache )
- then
- echo "WARNING WARNING WARNING WARNING WARNING WARNING WARNING"
- echo "*******************************************************"
- echo
- echo " You likely need to remove your old fontList.cache!"
- echo " You can do this with this command:"
- echo ""
- echo " rm $HOME/.matplotlib/fontList.cache"
- echo
- echo "*******************************************************"
- fi
-
- # Add the environment scripts
- ( cp ${YT_DIR}/doc/activate ${DEST_DIR}/bin/activate 2>&1 ) 1>> ${LOG_FILE}
- sed -i.bak -e "s,__YT_DIR__,${DEST_DIR}," ${DEST_DIR}/bin/activate
- ( cp ${YT_DIR}/doc/activate.csh ${DEST_DIR}/bin/activate.csh 2>&1 ) 1>> ${LOG_FILE}
- sed -i.bak -e "s,__YT_DIR__,${DEST_DIR}," ${DEST_DIR}/bin/activate.csh
-
- test_install
-
- function print_afterword
- {
- echo
- echo
- echo "========================================================================"
- echo
- echo "yt is now installed in $DEST_DIR ."
- echo
- echo "To run from this new installation, use the activate script for this "
- echo "environment."
- echo
- echo " $ source $DEST_DIR/bin/activate"
- echo
- echo "This modifies the environment variables YT_DEST, PATH, PYTHONPATH, and"
- echo "LD_LIBRARY_PATH to match your new yt install. If you use csh, just"
- echo "append .csh to the above."
- echo
- echo "To get started with yt, check out the orientation:"
- echo
- echo " http://yt-project.org/doc/quickstart/"
- echo
- echo "The source for yt is located at:"
- echo " $YT_DIR"
- echo
- echo "For support, see the website and join the mailing list:"
- echo
- echo " http://yt-project.org/"
- echo " http://yt-project.org/data/ (Sample data)"
- echo " http://yt-project.org/doc/ (Docs)"
- echo
- echo " http://lists.spacepope.org/listinfo.cgi/yt-users-spacepope.org"
- echo
- echo "========================================================================"
- echo
- echo "Oh, look at me, still talking when there's science to do!"
- echo "Good luck, and email the user list if you run into any problems."
- }
-
- print_afterword
- print_afterword >> ${LOG_FILE}
-
- echo "yt dependencies were last updated on" > ${DEST_DIR}/.yt_update
- date >> ${DEST_DIR}/.yt_update
-else # INST_CONDA -eq 1
- MYARCH=`uname -m` # A guess at the OS
- MYOS=`uname -s`
-
- if [ $MYOS = "Darwin" ]
- then
- MINICONDA_OS="MacOSX"
- MINICONDA_ARCH="x86_64"
- elif [ $MYOS = "Linux" ]
- then
- MINICONDA_OS="Linux"
- if [ $MYARCH = "i386" ]
- then
- MINICONDA_ARCH="x86"
- elif [ $MYARCH = "i686" ]
- then
- MINICONDA_ARCH="x86"
- elif [ $MYARCH = "x86_64" ]
- then
- MINICONDA_ARCH="x86_64"
- else
- echo "Not sure which architecture you are running."
- echo "Going with x86_64 architecture."
- MINICONDA_OS="Linux-x86_64"
- fi
- else
- echo "The yt install script is not supported on the ${MYOS}"
- echo "operating system."
- exit 1
- fi
-
- if [ $INST_PY3 -eq 1 ]
- then
- PY_VERSION='3'
- else
- PY_VERSION='2'
- fi
-
- MINICONDA_PKG="Miniconda${PY_VERSION}-${MINICONDA_VERSION}-${MINICONDA_OS}-${MINICONDA_ARCH}.sh"
-
- echo
- echo "Downloading ${MINICONDA_URLBASE}/${MINICONDA_PKG}"
- echo
-
- if [ -f ${MINICONDA_PKG} ]
- then
- rm $MINICONDA_PKG
- fi
-
- echo "Installing the Miniconda python environment."
-
- if [ -e ${DEST_DIR} ]
- then
- rm -rf $DEST_DIR/*
- else
- mkdir $DEST_DIR
- fi
-
- log_cmd ${GETFILE} ${MINICONDA_URLBASE}/${MINICONDA_PKG} || do_exit
-
- log_cmd bash ./${MINICONDA_PKG} -b -p $DEST_DIR -f
-
- # Need to set PATH so we use miniconda's python environment
- export PATH=${DEST_DIR}/bin:$PATH
-
- echo "Installing the necessary packages for yt."
- echo "This may take a while, but don't worry. yt loves you."
-
- declare -a YT_DEPS
- YT_DEPS+=('python')
- YT_DEPS+=('setuptools')
- YT_DEPS+=('numpy')
- YT_DEPS+=('jupyter')
- YT_DEPS+=('ipython')
- YT_DEPS+=('sphinx')
- if [ ${INST_GIT} -eq 1 ]
- then
- YT_DEPS+=('git')
- YT_DEPS+=('gitpython')
- fi
- if [ $INST_H5PY -ne 0 ]
- then
- YT_DEPS+=('h5py')
- fi
- YT_DEPS+=('matplotlib')
- YT_DEPS+=('cython')
- if [ $INST_NOSE -ne 0 ]
- then
- YT_DEPS+=('nose')
- fi
- if [ $INST_SCIPY -ne 0 ]
- then
- YT_DEPS+=('scipy')
- fi
- if [ $INST_ASTROPY -ne 0 ]
- then
- YT_DEPS+=('astropy')
- fi
- YT_DEPS+=('conda-build')
- if [ $INST_PY3 -eq 0 ] && [ $INST_HG -eq 1 ]
- then
- YT_DEPS+=('mercurial')
- fi
- YT_DEPS+=('sympy')
-
- if [ $INST_NETCDF4 -eq 1 ]
- then
- YT_DEPS+=('netcdf4')
- fi
-
- log_cmd ${DEST_DIR}/bin/conda update --yes conda
-
- if [ $INST_GIT -eq 1 ]
- then
- GIT_EXE=${DEST_DIR}/bin/git
- else
- if type -P git &>/dev/null
- then
- GIT_EXE="git"
- else
- echo "Cannot find git. Please install git or set INST_GIT=1."
+ echo "$YT_DIR is not a clone of the yt git repository, exiting"
do_exit
fi
fi
-
- log_cmd echo "DEPENDENCIES" ${YT_DEPS[@]}
- for YT_DEP in "${YT_DEPS[@]}"; do
- echo "Installing $YT_DEP"
- log_cmd ${DEST_DIR}/bin/conda install -c conda-forge --yes ${YT_DEP}
- done
-
- if [ $INST_PY3 -eq 1 ] && [ $INST_HG -eq 1 ]
- then
- echo "Installing mercurial"
- log_cmd ${DEST_DIR}/bin/conda create -y -n py27 python=2.7 mercurial
- log_cmd ln -s ${DEST_DIR}/envs/py27/bin/hg ${DEST_DIR}/bin
- fi
-
- log_cmd ${GIT_EXE} clone https://github.com/yt-project/yt_conda ${DEST_DIR}/src/yt_conda
-
if [ $INST_EMBREE -eq 1 ]
then
-
- echo "Installing Embree"
- if [ ! -d ${DEST_DIR}/src ]
- then
- mkdir ${DEST_DIR}/src
- fi
- cd ${DEST_DIR}/src
- ( ${GETFILE} "$EMBREE_URL" 2>&1 ) 1>> ${LOG_FILE} || do_exit
- log_cmd tar xfz ${EMBREE}.tar.gz
- log_cmd mv ${DEST_DIR}/src/${EMBREE}/include/embree2 ${DEST_DIR}/include
- log_cmd mv ${DEST_DIR}/src/${EMBREE}/lib/lib*.* ${DEST_DIR}/lib
- if [ `uname` = "Darwin" ]
- then
- ln -s ${DEST_DIR}/lib/libembree.2.dylib ${DEST_DIR}/lib/libembree.dylib
- install_name_tool -id ${DEST_DIR}/lib/libembree.2.dylib ${DEST_DIR}/lib/libembree.2.dylib
- else
- ln -s ${DEST_DIR}/lib/libembree.so.2 ${DEST_DIR}/lib/libembree.so
- fi
-
- echo "Installing pyembree from source"
- ( ${GETFILE} "$PYEMBREE_URL" 2>&1 ) 1>> ${LOG_FILE} || do_exit
- log_cmd unzip ${DEST_DIR}/src/master.zip
- pushd ${DEST_DIR}/src/pyembree-master &> /dev/null
- log_cmd ${DEST_DIR}/bin/${PYTHON_EXEC} setup.py install build_ext -I${DEST_DIR}/include -L${DEST_DIR}/lib
- popd &> /dev/null
+ echo $DEST_DIR > ${YT_DIR}/embree.cfg
fi
-
if [ $INST_ROCKSTAR -eq 1 ]
then
- echo "Building Rockstar"
- ( ${GIT_EXE} clone https://github.com/yt-project/rockstar ${DEST_DIR}/src/rockstar/ 2>&1 ) 1>> ${LOG_FILE}
- ROCKSTAR_PACKAGE=$(${DEST_DIR}/bin/conda build ${DEST_DIR}/src/yt_conda/rockstar --output)
- log_cmd ${DEST_DIR}/bin/conda build ${DEST_DIR}/src/yt_conda/rockstar
- log_cmd ${DEST_DIR}/bin/conda install $ROCKSTAR_PACKAGE
- ROCKSTAR_DIR=${DEST_DIR}/src/rockstar
- fi
-
- # conda doesn't package pyx, so we install manually with pip
- if [ $INST_PYX -eq 1 ]
- then
- if [ $INST_PY3 -eq 1 ]
- then
- log_cmd ${DEST_DIR}/bin/pip install pyx
- else
- log_cmd ${DEST_DIR}/bin/pip install pyx==0.12.1
- fi
- fi
-
- if [ $INST_YT_SOURCE -eq 0 ]
- then
- echo "Installing yt"
- log_cmd ${DEST_DIR}/bin/conda install -c conda-forge --yes yt
- else
- echo "Building yt from source"
- if [ -z "$YT_DIR" ]
- then
- if [ -e $ORIG_PWD/yt/mods.py ]
- then
- YT_DIR="$ORIG_PWD"
- elif [ -e $ORIG_PWD/../yt/mods.py ]
- then
- YT_DIR=$(dirname $ORIG_PWD)
- else
- YT_DIR="${DEST_DIR}/src/yt-git"
- log_cmd ${GIT_EXE} clone https://github.com/yt-project/yt ${YT_DIR}
- log_cmd ${GIT_EXE} -C ${YT_DIR} checkout ${BRANCH}
- fi
- echo Setting YT_DIR=${YT_DIR}
- else
- if [ ! -e $YT_DIR/.git ]
- then
- echo "$YT_DIR is not a clone of the yt git repository, exiting"
- do_exit
- fi
- fi
- if [ $INST_EMBREE -eq 1 ]
- then
- echo $DEST_DIR > ${YT_DIR}/embree.cfg
- fi
- if [ $INST_ROCKSTAR -eq 1 ]
- then
- echo $ROCKSTAR_DIR > ${YT_DIR}/rockstar.cfg
- ROCKSTAR_LIBRARY_PATH=${DEST_DIR}/lib
- fi
- pushd ${YT_DIR} &> /dev/null
- ( LIBRARY_PATH=$ROCKSTAR_LIBRARY_PATH ${DEST_DIR}/bin/${PYTHON_EXEC} setup.py develop 2>&1) 1>> ${LOG_FILE} || do_exit
- popd &> /dev/null
+ echo $ROCKSTAR_DIR > ${YT_DIR}/rockstar.cfg
+ ROCKSTAR_LIBRARY_PATH=${DEST_DIR}/lib
fi
+ pushd ${YT_DIR} &> /dev/null
+ ( LIBRARY_PATH=$ROCKSTAR_LIBRARY_PATH ${DEST_DIR}/bin/${PYTHON_EXEC} setup.py develop 2>&1) 1>> ${LOG_FILE} || do_exit
+ popd &> /dev/null
+fi
- test_install
+test_install
- echo
- echo
- echo "========================================================================"
- echo
- echo "yt and the Conda system are now installed in $DEST_DIR"
- echo
- echo "To get started with yt, check out the orientation:"
- echo
- echo " http://yt-project.org/doc/orientation/"
- echo
- echo "For support, see the website and join the mailing list:"
- echo
- echo " http://yt-project.org/"
- echo " http://yt-project.org/data/ (Sample data)"
- echo " http://yt-project.org/doc/ (Docs)"
- echo
- echo " http://lists.spacepope.org/listinfo.cgi/yt-users-spacepope.org"
- echo
- echo "You must now prepend the following folder to your PATH environment variable:"
- echo
- echo " $DEST_DIR/bin"
- echo
- echo "On Bash-style shells you can copy/paste the following command to "
- echo "temporarily activate the yt installation:"
+echo
+echo
+echo "========================================================================"
+echo
+echo "yt and the Conda system are now installed in $DEST_DIR"
+echo
+echo "To get started with yt, check out the orientation:"
+echo
+echo " http://yt-project.org/doc/orientation/"
+echo
+echo "For support, see the website and join the mailing list:"
+echo
+echo " http://yt-project.org/"
+echo " http://yt-project.org/data/ (Sample data)"
+echo " http://yt-project.org/doc/ (Docs)"
+echo
+echo " http://lists.spacepope.org/listinfo.cgi/yt-users-spacepope.org"
+echo
+echo "You must now prepend the following folder to your PATH environment variable:"
+echo
+echo " $DEST_DIR/bin"
+echo
+echo "On Bash-style shells you can copy/paste the following command to "
+echo "temporarily activate the yt installation:"
+echo
+echo " export PATH=$DEST_DIR/bin:\$PATH"
+echo
+echo "and on csh-style shells:"
+echo
+echo " setenv PATH $DEST_DIR/bin:\$PATH"
+echo
+echo "You can also update the init file appropriate for your shell"
+echo "(e.g. .bashrc, .bash_profile, .cshrc, or .zshrc) to include"
+echo "the same command."
+echo
+if [ $INST_ROCKSTAR -eq 1 ]
+then
+ if [ $MYOS = "Darwin" ]
+ then
+ LD_NAME="DYLD_LIBRARY_PATH"
+ else
+ LD_NAME="LD_LIBRARY_PATH"
+ fi
echo
- echo " export PATH=$DEST_DIR/bin:\$PATH"
- echo
- echo "and on csh-style shells:"
+ echo "For rockstar to work, you must also set $LD_NAME:"
echo
- echo " setenv PATH $DEST_DIR/bin:\$PATH"
- echo
- echo "You can also update the init file appropriate for your shell"
- echo "(e.g. .bashrc, .bash_profile, .cshrc, or .zshrc) to include"
- echo "the same command."
+ echo " export $LD_NAME=$DEST_DIR/lib:\$$LD_NAME"
echo
- if [ $INST_ROCKSTAR -eq 1 ]
- then
- if [ $MYOS = "Darwin" ]
- then
- LD_NAME="DYLD_LIBRARY_PATH"
- else
- LD_NAME="LD_LIBRARY_PATH"
- fi
- echo
- echo "For rockstar to work, you must also set $LD_NAME:"
- echo
- echo " export $LD_NAME=$DEST_DIR/lib:\$$LD_NAME"
- echo
- echo "or whichever invocation is appropriate for your shell."
- fi
- echo "========================================================================"
- echo
- echo "Oh, look at me, still talking when there's science to do!"
- echo "Good luck, and email the mailing list if you run into any problems."
+ echo "or whichever invocation is appropriate for your shell."
fi
+echo "========================================================================"
+echo
+echo "Oh, look at me, still talking when there's science to do!"
+echo "Good luck, and email the mailing list if you run into any problems."
diff -r 3249ecb9ce42777551963f05fd3d4ed9207ffb76 -r 31f1a4ccea0427e60c645abd49a11345168de4fe doc/source/analyzing/objects.rst
--- a/doc/source/analyzing/objects.rst
+++ b/doc/source/analyzing/objects.rst
@@ -197,7 +197,6 @@
(900.1, 'm')]
sl.plot()
-.. _available-objects:
Making Image Buffers
^^^^^^^^^^^^^^^^^^^^
@@ -214,6 +213,41 @@
This `frb` object then can be queried like a normal fixed resolution buffer,
and it will return arrays of shape (1024, 1024).
+Making Rays
+^^^^^^^^^^^
+
+The slicing syntax can also be used select 1D rays of points, whether along
+an axis or off-axis. To create a ray along an axis:::
+
+ ortho_ray = ds.r[(500.0, "kpc"), (200, "kpc"):(300.0, "kpc"), (-2.0, "Mpc")]
+
+To create a ray off-axis, use a single slice between the start and end points
+of the ray:::
+
+ start = [0.1, 0.2, 0.3] # interpreted in code_length
+ end = [0.4, 0.5, 0.6] # interpreted in code_length
+ ray = ds.r[start:end]
+
+As for the other slicing options, combinations of unitful quantities with even
+different units can be used. Here's a somewhat convoluted (yet working) example:::
+
+ start = ((500.0, "kpc"), (0.2, "Mpc"), (100.0, "kpc"))
+ end = ((1.0, "Mpc"), (300.0, "kpc"), (0.0, "kpc"))
+ ray = ds.r[start:end]
+
+Selecting Points
+^^^^^^^^^^^^^^^^
+
+Finally, you can quickly select a single point within the domain by providing
+a single coordinate for every axis:::
+
+ pt = ds.r[(10.0, 'km'), (200, 'm'), (1.0,'km')]
+
+Querying this object for fields will give you the value of the field at that
+point.
+
+.. _available-objects:
+
Available Objects
-----------------
diff -r 3249ecb9ce42777551963f05fd3d4ed9207ffb76 -r 31f1a4ccea0427e60c645abd49a11345168de4fe doc/source/examining/loading_data.rst
--- a/doc/source/examining/loading_data.rst
+++ b/doc/source/examining/loading_data.rst
@@ -482,6 +482,36 @@
fields. Projections, volume rendering, and many of the analysis modules will not
work.
+.. _loading-enzop-data:
+
+Enzo-P Data
+-----------
+
+Enzo-P outputs have three types of files.
+
+.. code-block:: none
+
+ hello-0200/
+ hello-0200/hello-0200.block_list
+ hello-0200/hello-0200.file_list
+ hello-0200/hello-0200.hello-c0020-p0000.h5
+
+To load Enzo-P data into yt, provide the block list file:
+
+.. code-block:: python
+
+ import yt
+ ds = yt.load("hello-0200/hello-0200.block_list")
+
+Mesh fields are fully supported for 1, 2, and 3D datasets.
+
+.. rubric:: Caveats
+
+ * The Enzo-P output format is still evolving somewhat as the code is being
+ actively developed. This frontend will be updated as development continues.
+ * Units are currently assumed to be in CGS.
+ * Particles are not yet supported.
+
.. _loading-exodusii-data:
Exodus II Data
diff -r 3249ecb9ce42777551963f05fd3d4ed9207ffb76 -r 31f1a4ccea0427e60c645abd49a11345168de4fe doc/source/faq/index.rst
--- a/doc/source/faq/index.rst
+++ b/doc/source/faq/index.rst
@@ -28,25 +28,16 @@
$ yt version
yt module located at:
- /Users/username/src/yt-x86_64/src/yt-hg
- The supplemental repositories are located at:
- /Users/username/src/yt-x86_64/src/yt-supplemental
+ /Users/username/src/yt-conda/src/yt-git
- The current version and changeset for the code is:
+ The current version of yt is:
---
- Version = 2.7-dev
- Changeset = 6bffc737a67a
+ Version = 3.4-dev
+ Changeset = 94033fca00e5
---
This installation CAN be automatically updated.
- yt dependencies were last updated on
- Wed Dec 4 15:47:40 MST 2013
-
- To update all dependencies, run "yt update --all".
-
-If the changeset is displayed followed by a "+", it means you have made
-modifications to the code since the last changeset.
For more information on this topic, see :ref:`updating-yt`.
diff -r 3249ecb9ce42777551963f05fd3d4ed9207ffb76 -r 31f1a4ccea0427e60c645abd49a11345168de4fe doc/source/help/index.rst
--- a/doc/source/help/index.rst
+++ b/doc/source/help/index.rst
@@ -36,19 +36,24 @@
Sometimes the pace of development is pretty fast on yt, particularly in the
development branch, so a fix to your problem may have already been developed
by the time you encounter it. Many users' problems can simply be corrected
-by updating to the latest version of the code and/or its dependencies. You
-can update yt's source by running:
+by updating to the latest version of the code and/or its dependencies. If you
+have installed the latest stable release of yt then you should update yt using
+the package manager appropriate for your python installation. For example, with
+``pip``::
+
+ $ pip install -U yt
+
+Or with conda::
+
+ $ conda update yt
+
+If you installed yt from a checkout of the git repository, you can update to
+the latest development version by issuing the following command:
.. code-block:: bash
$ yt update
-or you could update yt's source as well as any software dependencies by running:
-
-.. code-block:: bash
-
- $ yt update --all
-
.. _update-errors:
Update errors
This diff is so big that we needed to truncate the remainder.
https://bitbucket.org/yt_analysis/yt/commits/7f62ed5535f1/
Changeset: 7f62ed5535f1
User: ngoldbaum
Date: 2017-06-28 20:05:38+00:00
Summary: Fix incorrect x values for AMR data
Affected #: 1 file
diff -r 31f1a4ccea0427e60c645abd49a11345168de4fe -r 7f62ed5535f16f2007b844ba32687026cdfd81eb yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -50,7 +50,9 @@
if wh.shape != (1,):
raise RuntimeError
field_values[i] = ray_field[wh]
- return sample_points, field_values
+ dr = np.sqrt((sample_dr**2).sum())
+ x = np.arange(resolution)/(resolution-1)*(dr*resolution)
+ return x, field_values
class CartesianCoordinateHandler(CoordinateHandler):
name = "cartesian"
https://bitbucket.org/yt_analysis/yt/commits/a64a7e297534/
Changeset: a64a7e297534
User: ngoldbaum
Date: 2017-06-28 20:06:27+00:00
Summary: Ensure LinePlot works for reduced dimensionality data
Affected #: 2 files
diff -r 7f62ed5535f16f2007b844ba32687026cdfd81eb -r a64a7e2975347eeac175f59db769c7e68ad33c1a yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -35,8 +35,7 @@
start_point = ray.start_point
end_point = ray.end_point
sample_dr = (end_point - start_point)/(resolution-1)
- sample_points = [np.arange(resolution)*sample_dr[i] for i in
- range(ray.ds.dimensionality)]
+ sample_points = [np.arange(resolution)*sample_dr[i] for i in range(3)]
sample_points = uvstack(sample_points).T
ray_coordinates = uvstack([ray[d] for d in 'xyz']).T
ray_dds = uvstack([ray['d'+d] for d in 'xyz']).T
diff -r 7f62ed5535f16f2007b844ba32687026cdfd81eb -r a64a7e2975347eeac175f59db769c7e68ad33c1a yt/visualization/line_plot.py
--- a/yt/visualization/line_plot.py
+++ b/yt/visualization/line_plot.py
@@ -90,7 +90,7 @@
"""
Sets up figure and axes
"""
- self.start_point = _validate_point(start_point, ds)
+ self.start_point = _validate_point(start_point, ds, start=True)
self.end_point = _validate_point(end_point, ds)
self.resolution = resolution
self._x_unit = None
@@ -249,9 +249,26 @@
"""
self._titles[self.data_source._determine_fields(field)[0]] = title
-def _validate_point(point, ds):
+def _validate_point(point, ds, start=False):
if not iterable(point):
- raise RuntimeError
+ raise RuntimeError(
+ "Input point must be array-like"
+ )
if not isinstance(point, YTArray):
point = ds.arr(point, 'code_length')
+ if len(point.shape) != 1:
+ raise RuntimeError(
+ "Input point must be a 1D array"
+ )
+ if point.shape[0] < ds.dimensionality:
+ raise RuntimeError(
+ "Input point must have an element for each dimension"
+ )
+ # need to pad to 3D elements to avoid issues later
+ if point.shape[0] < 3:
+ if start:
+ val = 0
+ else:
+ val = 1
+ point = np.append(point.d, [val]*(3-ds.dimensionality))*point.uq
return point
https://bitbucket.org/yt_analysis/yt/commits/ea2c00f016aa/
Changeset: ea2c00f016aa
User: ngoldbaum
Date: 2017-06-28 20:07:12+00:00
Summary: Fix issue with missized figures
Affected #: 3 files
diff -r a64a7e2975347eeac175f59db769c7e68ad33c1a -r ea2c00f016aa2bc9b9a0d1d18226110900b4d70d yt/visualization/base_plot_types.py
--- a/yt/visualization/base_plot_types.py
+++ b/yt/visualization/base_plot_types.py
@@ -86,6 +86,8 @@
import matplotlib.figure
self._plot_valid = True
if figure is None:
+ if not iterable(fsize):
+ fsize = (fsize, fsize)
self.figure = matplotlib.figure.Figure(figsize=fsize, frameon=True)
else:
figure.set_size_inches(fsize)
diff -r a64a7e2975347eeac175f59db769c7e68ad33c1a -r ea2c00f016aa2bc9b9a0d1d18226110900b4d70d yt/visualization/line_plot.py
--- a/yt/visualization/line_plot.py
+++ b/yt/visualization/line_plot.py
@@ -139,9 +139,14 @@
y_axis_size = 0.9*fontscale
right_buff_size = 0.2*fontscale
- xbins = np.array([x_axis_size, self.figure_size[0],
+ if iterable(self.figure_size):
+ figure_size = self.figure_size
+ else:
+ figure_size = (self.figure_size, self.figure_size)
+
+ xbins = np.array([x_axis_size, figure_size[0],
right_buff_size])
- ybins = np.array([y_axis_size, self.figure_size[1], top_buff_size])
+ ybins = np.array([y_axis_size, figure_size[1], top_buff_size])
size = [xbins.sum(), ybins.sum()]
diff -r a64a7e2975347eeac175f59db769c7e68ad33c1a -r ea2c00f016aa2bc9b9a0d1d18226110900b4d70d yt/visualization/plot_container.py
--- a/yt/visualization/plot_container.py
+++ b/yt/visualization/plot_container.py
@@ -199,7 +199,7 @@
if iterable(figure_size):
self.figure_size = float(figure_size[0]), float(figure_size[1])
else:
- self.figure_size = float(figure_size), float(figure_size)
+ self.figure_size = float(figure_size)
font_path = matplotlib.get_data_path() + '/fonts/ttf/STIXGeneral.ttf'
self._font_properties = FontProperties(size=fontsize, fname=font_path)
self._font_color = None
https://bitbucket.org/yt_analysis/yt/commits/d48318cf04da/
Changeset: d48318cf04da
User: ngoldbaum
Date: 2017-06-28 20:07:33+00:00
Summary: Fix issue with invalid weakrefs
Affected #: 1 file
diff -r ea2c00f016aa2bc9b9a0d1d18226110900b4d70d -r d48318cf04dadff8e61b4ea52d0f8bfd7d837940 yt/visualization/plot_container.py
--- a/yt/visualization/plot_container.py
+++ b/yt/visualization/plot_container.py
@@ -325,6 +325,8 @@
lim = getattr(self, lim_name)
lim = tuple(new_ds.quan(l.value, str(l.units)) for l in lim)
setattr(self, lim_name, lim)
+ self.plots.data_source = new_object
+ self._colorbar_label.data_source = new_object
self._setup_plots()
@validate_plot
https://bitbucket.org/yt_analysis/yt/commits/03c82180a7d1/
Changeset: 03c82180a7d1
User: ngoldbaum
Date: 2017-06-28 20:07:50+00:00
Summary: Fix issue with incorrect fonts on minor tick labels
Affected #: 1 file
diff -r d48318cf04dadff8e61b4ea52d0f8bfd7d837940 -r 03c82180a7d183039d969f66b3fc8b5ac6e0af50 yt/visualization/base_plot_types.py
--- a/yt/visualization/base_plot_types.py
+++ b/yt/visualization/base_plot_types.py
@@ -166,6 +166,8 @@
def _get_labels(self):
ax = self.axes
labels = ax.xaxis.get_ticklabels() + ax.yaxis.get_ticklabels()
+ labels += ax.xaxis.get_minorticklabels()
+ labels += ax.yaxis.get_minorticklabels()
labels += [ax.title, ax.xaxis.label, ax.yaxis.label,
ax.xaxis.get_offset_text(), ax.yaxis.get_offset_text()]
return labels
https://bitbucket.org/yt_analysis/yt/commits/a65f1cca6a12/
Changeset: a65f1cca6a12
User: ngoldbaum
Date: 2017-06-28 20:08:33+00:00
Summary: Tweak figure positioning
Affected #: 1 file
diff -r 03c82180a7d183039d969f66b3fc8b5ac6e0af50 -r a65f1cca6a12d659cdacd618c558b27a821e7064 yt/visualization/line_plot.py
--- a/yt/visualization/line_plot.py
+++ b/yt/visualization/line_plot.py
@@ -133,10 +133,10 @@
dimensions_counter = defaultdict(int)
for field in self.fields:
fontscale = self._font_properties._size / 14.
- top_buff_size = 0.3*fontscale
+ top_buff_size = 0.35*fontscale
- x_axis_size = 1.2*fontscale
- y_axis_size = 0.9*fontscale
+ x_axis_size = 1.35*fontscale
+ y_axis_size = 0.7*fontscale
right_buff_size = 0.2*fontscale
if iterable(self.figure_size):
@@ -166,8 +166,6 @@
plot = PlotMPL(self.figure_size, axrect, None, None)
self.plots[field] = plot
- plot._set_font_properties(self._font_properties, None)
-
x, y = self.ds.coordinates.line_plot(
field, self.start_point, self.end_point, self.resolution)
@@ -192,6 +190,8 @@
else:
plot.axes.set_yscale('log')
+ plot._set_font_properties(self._font_properties, None)
+
axes_unit_labels = self._get_axes_unit_labels(unit_x, unit_y)
finfo = self.ds.field_info[field]
@@ -199,7 +199,8 @@
x_label = r'$\rm{Path\ Length' + axes_unit_labels[0]+'}$'
finfo = self.ds.field_info[field]
- dimensions = Unit(finfo.units, registry=self.ds.unit_registry).dimensions
+ dimensions = Unit(finfo.units,
+ registry=self.ds.unit_registry).dimensions
dimensions_counter[dimensions] += 1
if dimensions_counter[dimensions] > 1:
y_label = (r'$\rm{Multiple\ Fields}$' + r'$\rm{' +
https://bitbucket.org/yt_analysis/yt/commits/9b435dde7125/
Changeset: 9b435dde7125
User: ngoldbaum
Date: 2017-06-28 21:33:03+00:00
Summary: fix issues with saving PhasePlots
Affected #: 1 file
diff -r a65f1cca6a12d659cdacd618c558b27a821e7064 -r 9b435dde7125ec7f66e8a1fbb132400018dec39c yt/visualization/profile_plotter.py
--- a/yt/visualization/profile_plotter.py
+++ b/yt/visualization/profile_plotter.py
@@ -41,7 +41,8 @@
from yt.funcs import \
ensure_list, \
get_image_suffix, \
- matplotlib_style_context
+ matplotlib_style_context, \
+ iterable
def get_canvas(name):
from . import _mpl_imports as mpl
@@ -1370,7 +1371,10 @@
if fontscale < 1.0:
fontscale = np.sqrt(fontscale)
- self._cb_size = 0.0375*figure_size[0]
+ if iterable(figure_size):
+ self._cb_size = 0.0375*figure_size[0]
+ else:
+ self._cb_size = 0.0375*figure_size
self._ax_text_size = [1.1*fontscale, 0.9*fontscale]
self._top_buff_size = 0.30*fontscale
self._aspect = 1.0
https://bitbucket.org/yt_analysis/yt/commits/407271c1ee64/
Changeset: 407271c1ee64
User: ngoldbaum
Date: 2017-06-29 16:20:53+00:00
Summary: Use a fake in-memory dataset for the line_plot tests
Affected #: 1 file
diff -r 9b435dde7125ec7f66e8a1fbb132400018dec39c -r 407271c1ee64e310a8ef6f82338a1d60dacdb50f yt/visualization/tests/test_line_plots.py
--- a/yt/visualization/tests/test_line_plots.py
+++ b/yt/visualization/tests/test_line_plots.py
@@ -15,6 +15,7 @@
requires_ds, \
data_dir_load, \
GenericImageTest
+from yt.testing import fake_random_ds
import os
import tempfile
import shutil
@@ -36,7 +37,6 @@
return test
tri2 = "SecondOrderTris/RZ_p_no_parts_do_nothing_bcs_cone_out.e"
-iso_galaxy = "IsolatedGalaxy/galaxy0030/galaxy0030"
@requires_ds(tri2)
def test_line_plot():
@@ -44,14 +44,13 @@
fields = [field for field in ds.field_list if field[0] == 'all']
yield compare(ds, fields, (0, 0, 0), (1, 1, 0), 1000, "answers_line_plot")
- at requires_ds(iso_galaxy)
def test_line_plot_methods():
# Perform I/O in safe place instead of yt main dir
tmpdir = tempfile.mkdtemp()
curdir = os.getcwd()
os.chdir(tmpdir)
- ds = data_dir_load(iso_galaxy)
+ ds = fake_random_ds(32)
plot = yt.LinePlot(ds, 'density', [0, 0, 0], [1, 1, 1], 512)
plot.add_legend('density')
https://bitbucket.org/yt_analysis/yt/commits/9a5120b67fbb/
Changeset: 9a5120b67fbb
User: Alex Lindsay
Date: 2017-07-05 21:15:42+00:00
Summary: Address Britton Smith review.
Affected #: 4 files
diff -r 407271c1ee64e310a8ef6f82338a1d60dacdb50f -r 9a5120b67fbbe8408a3c77745c9083dff72a5f2b doc/source/visualizing/plots.rst
--- a/doc/source/visualizing/plots.rst
+++ b/doc/source/visualizing/plots.rst
@@ -1072,9 +1072,9 @@
4. The ending point of the sampling line. This should also be an n-element list, tuple,
ndarray, or YTArray with the elements corresponding to the coordinates of the
ending point.
-5. The resolution of the sampling line. This is the number of sampling points
- along the line, e.g. if 1000 is specified, then data will be sampled at
- 1000 points evenly spaced between the starting and ending points.
+5. The number of sampling points along the line, e.g. if 1000 is specified, then
+ data will be sampled at 1000 points evenly spaced between the starting and
+ ending points.
The below code snippet illustrates how this is done:
@@ -1114,7 +1114,17 @@
one with plots of the "length/time" fields and another with the plot of the
"temperature" field. It is only necessary to call ``add_legend``
for one field of a multi-field plot to produce a legend containing all the
-labels passed in the initial construction of the ``LinePlot`` instance.
+labels passed in the initial construction of the ``LinePlot`` instance. Example:
+
+.. python-script::
+
+ import yt
+
+ ds = yt.load("SecondOrderTris/RZ_p_no_parts_do_nothing_bcs_cone_out.e", step=-1)
+ plot = yt.LinePlot(ds, [('all', 'v'), ('all', 'u')], [0, 0, 0], [0, 1, 0],
+ 100, labels={('all', 'u') : r"v$_x$", ('all', 'v') : r"v$_y$"})
+ plot.add_legend(('all', 'u'))
+ plot.save()
.. _how-to-make-2d-profiles:
diff -r 407271c1ee64e310a8ef6f82338a1d60dacdb50f -r 9a5120b67fbbe8408a3c77745c9083dff72a5f2b yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -21,9 +21,8 @@
_get_vert_fields, \
cartesian_to_cylindrical, \
cylindrical_to_cartesian
-from yt import YTArray
from yt.funcs import mylog
-from yt.units.yt_array import uvstack
+from yt.units.yt_array import uvstack, YTArray
from yt.utilities.lib.pixelization_routines import \
pixelize_element_mesh, pixelize_off_axis_cartesian, \
pixelize_cartesian, pixelize_cartesian_nodal, \
@@ -31,16 +30,29 @@
from yt.data_objects.unstructured_mesh import SemiStructuredMesh
from yt.utilities.nodal_data_utils import get_nodal_data
-def _sample_ray(ray, resolution, field):
+def _sample_ray(ray, npoints, field):
+ """
+ Private function that uses a ray object for calculating the field values
+ that will be the y-axis values in a LinePlot object.
+
+ Parameters
+ ----------
+ ray : YTOrthoRay, YTRay, or LightRay
+ Ray object from which to sample field values
+ npoints : int
+ The number of points to sample
+ field : str or field tuple
+ The name of the field to sample
+ """
start_point = ray.start_point
end_point = ray.end_point
- sample_dr = (end_point - start_point)/(resolution-1)
- sample_points = [np.arange(resolution)*sample_dr[i] for i in range(3)]
+ sample_dr = (end_point - start_point)/(npoints-1)
+ sample_points = [np.arange(npoints)*sample_dr[i] for i in range(3)]
sample_points = uvstack(sample_points).T
ray_coordinates = uvstack([ray[d] for d in 'xyz']).T
ray_dds = uvstack([ray['d'+d] for d in 'xyz']).T
ray_field = ray[field]
- field_values = ray.ds.arr(np.zeros(resolution), ray_field.units)
+ field_values = ray.ds.arr(np.zeros(npoints), ray_field.units)
for i, sample_point in enumerate(sample_points):
ray_contains = ((sample_point >= (ray_coordinates - ray_dds/2)) &
(sample_point <= (ray_coordinates + ray_dds/2)))
@@ -50,7 +62,7 @@
raise RuntimeError
field_values[i] = ray_field[wh]
dr = np.sqrt((sample_dr**2).sum())
- x = np.arange(resolution)/(resolution-1)*(dr*resolution)
+ x = np.arange(npoints)/(npoints-1)*(dr*npoints)
return x, field_values
class CartesianCoordinateHandler(CoordinateHandler):
@@ -149,13 +161,15 @@
antialias)
- def line_plot(self, field, start_point, end_point, resolution):
+ def line_plot(self, field, start_point, end_point, npoints):
"""
Method for sampling datasets along a line in preparation for
one-dimensional line plots. For UnstructuredMesh, relies on a
sampling routine written in cython
"""
-
+ if npoints < 2:
+ raise ValueError("Must have at least two sample points in order "
+ "to draw a line plot.")
index = self.ds.index
if (hasattr(index, 'meshes') and
not isinstance(index.meshes[0], SemiStructuredMesh)):
@@ -186,13 +200,13 @@
arc_length, plot_values = element_mesh_line_plot(coords, indices,
start_point,
end_point,
- resolution, field_data,
+ npoints, field_data,
index_offset=offset)
arc_length = YTArray(arc_length, start_point.units)
plot_values = YTArray(plot_values, field_data.units)
else:
ray = self.ds.ray(start_point, end_point)
- arc_length, plot_values = _sample_ray(ray, resolution, field)
+ arc_length, plot_values = _sample_ray(ray, npoints, field)
return arc_length, plot_values
diff -r 407271c1ee64e310a8ef6f82338a1d60dacdb50f -r 9a5120b67fbbe8408a3c77745c9083dff72a5f2b yt/utilities/lib/pixelization_routines.pyx
--- a/yt/utilities/lib/pixelization_routines.pyx
+++ b/yt/utilities/lib/pixelization_routines.pyx
@@ -867,7 +867,7 @@
np.ndarray[np.int64_t, ndim=2] conn,
np.ndarray[np.float64_t, ndim=1] start_point,
np.ndarray[np.float64_t, ndim=1] end_point,
- resolution,
+ npoints,
np.ndarray[np.float64_t, ndim=2] field,
int index_offset = 0):
@@ -878,7 +878,8 @@
cdef int nvertices = conn.shape[1]
cdef int ndim = coords.shape[1]
cdef int num_field_vals = field.shape[1]
- cdef int num_plot_nodes = resolution + 1
+ cdef int num_plot_nodes = npoints
+ cdef int num_intervals = npoints - 1
cdef double[4] mapped_coord
cdef ElementSampler sampler
cdef np.ndarray[np.float64_t, ndim=1] lin_vec
@@ -927,17 +928,17 @@
lin_vec = end_point - start_point
lin_length = np.linalg.norm(lin_vec)
- lin_inc = lin_vec / resolution
- inc_length = lin_length / resolution
+ lin_inc = lin_vec / num_intervals
+ inc_length = lin_length / num_intervals
for j in range(ndim):
lin_sample_points[0, j] = start_point[j]
arc_length[0] = 0
- for i in range(1, resolution + 1):
+ for i in range(1, num_intervals + 1):
for j in range(ndim):
lin_sample_points[i, j] = lin_sample_points[i-1, j] + lin_inc[j]
arc_length[i] = arc_length[i-1] + inc_length
- for i in range(resolution + 1):
+ for i in range(num_intervals + 1):
for j in range(3):
if j < ndim:
sample_point[j] = lin_sample_points[i][j]
diff -r 407271c1ee64e310a8ef6f82338a1d60dacdb50f -r 9a5120b67fbbe8408a3c77745c9083dff72a5f2b yt/visualization/line_plot.py
--- a/yt/visualization/line_plot.py
+++ b/yt/visualization/line_plot.py
@@ -6,7 +6,7 @@
"""
#-----------------------------------------------------------------------------
-# Copyright (c) 2013, yt Development Team.
+# Copyright (c) 2017, yt Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
@@ -79,20 +79,34 @@
Contains the coordinates of the first point for constructing the line.
Must contain n elements where n is the dimensionality of the dataset.
figure_size: integer or two-element
- resolution: int
+ npoints: int
How many points to sample between start_point and end_point for
constructing the line plot
+
+ Example
+ -------
+
+ >>> import yt
+ >>>
+ >>> ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030')
+ >>>
+ >>> plot = yt.LinePlot(ds, 'density', [0, 0, 0], [1, 1, 1], 512)
+ >>> plot.add_legend('density')
+ >>> plot.set_x_unit('cm')
+ >>> plot.set_unit('density', 'kg/cm**3')
+ >>> plot.save()
+
"""
_plot_type = 'line_plot'
- def __init__(self, ds, fields, start_point, end_point, resolution,
+ def __init__(self, ds, fields, start_point, end_point, npoints,
figure_size=5., fontsize=14., labels=None):
"""
Sets up figure and axes
"""
self.start_point = _validate_point(start_point, ds, start=True)
self.end_point = _validate_point(end_point, ds)
- self.resolution = resolution
+ self.npoints = npoints
self._x_unit = None
self._y_units = {}
self._titles = {}
@@ -143,7 +157,7 @@
figure_size = self.figure_size
else:
figure_size = (self.figure_size, self.figure_size)
-
+
xbins = np.array([x_axis_size, figure_size[0],
right_buff_size])
ybins = np.array([y_axis_size, figure_size[1], top_buff_size])
@@ -167,7 +181,7 @@
self.plots[field] = plot
x, y = self.ds.coordinates.line_plot(
- field, self.start_point, self.end_point, self.resolution)
+ field, self.start_point, self.end_point, self.npoints)
if self._x_unit is None:
unit_x = x.units
https://bitbucket.org/yt_analysis/yt/commits/281cf5be7c9f/
Changeset: 281cf5be7c9f
User: Alex Lindsay
Date: 2017-07-06 01:57:15+00:00
Summary: Address remaining Britton review.
Affected #: 2 files
diff -r 9a5120b67fbbe8408a3c77745c9083dff72a5f2b -r 281cf5be7c9f796e4d60914cd972d0361481c0f7 doc/source/visualizing/plots.rst
--- a/doc/source/visualizing/plots.rst
+++ b/doc/source/visualizing/plots.rst
@@ -1126,6 +1126,15 @@
plot.add_legend(('all', 'u'))
plot.save()
+``LinePlot`` is a bit different from yt ray objects which are data
+containers. ``LinePlot`` is a plotting class that may use yt ray objects to
+supply field plotting information. However, perhaps the most important
+difference to highlight between rays and ``LinePlot`` is that rays return data
+elements that intersect with the ray and make no guarantee about the spacing
+between data elements. ``LinePlot`` sampling points are guaranteed to be evenly
+spaced. In the case of cell data where multiple points fall within the same
+cell, the ``LinePlot`` object will show the same field value for each sampling
+point that falls within the same cell.
.. _how-to-make-2d-profiles:
diff -r 9a5120b67fbbe8408a3c77745c9083dff72a5f2b -r 281cf5be7c9f796e4d60914cd972d0361481c0f7 yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -57,10 +57,7 @@
ray_contains = ((sample_point >= (ray_coordinates - ray_dds/2)) &
(sample_point <= (ray_coordinates + ray_dds/2)))
ray_contains = ray_contains.all(axis=-1)
- wh = np.where(ray_contains)[0]
- if wh.shape != (1,):
- raise RuntimeError
- field_values[i] = ray_field[wh]
+ field_values[i] = ray_field[ray_contains]
dr = np.sqrt((sample_dr**2).sum())
x = np.arange(npoints)/(npoints-1)*(dr*npoints)
return x, field_values
https://bitbucket.org/yt_analysis/yt/commits/df0dfe8d1cd3/
Changeset: df0dfe8d1cd3
User: Alex Lindsay
Date: 2017-07-06 14:52:13+00:00
Summary: Increment answer test counter since argument changed to n_nodes from n_elements for unstructured mesh plotting.
Affected #: 1 file
diff -r 281cf5be7c9f796e4d60914cd972d0361481c0f7 -r df0dfe8d1cd3f94a21a5fdc0c38fe6840d5933f2 tests/tests.yaml
--- a/tests/tests.yaml
+++ b/tests/tests.yaml
@@ -67,7 +67,7 @@
- yt/analysis_modules/photon_simulator/tests/test_spectra.py
- yt/analysis_modules/photon_simulator/tests/test_sloshing.py
- local_unstructured_007:
+ local_unstructured_008:
- yt/visualization/volume_rendering/tests/test_mesh_render.py
- yt/visualization/tests/test_mesh_slices.py:test_tri2
- yt/visualization/tests/test_mesh_slices.py:test_quad2
https://bitbucket.org/yt_analysis/yt/commits/7ebf1dd9b9a8/
Changeset: 7ebf1dd9b9a8
User: Alex Lindsay
Date: 2017-07-06 18:47:07+00:00
Summary: Finish line plot docstring
Affected #: 1 file
diff -r df0dfe8d1cd3f94a21a5fdc0c38fe6840d5933f2 -r 7ebf1dd9b9a8e74fae7866f907391d066705e7aa yt/visualization/line_plot.py
--- a/yt/visualization/line_plot.py
+++ b/yt/visualization/line_plot.py
@@ -67,21 +67,31 @@
Parameters
----------
- ds: :class:`yt.data_objects.static_output.Dataset`
+ ds : :class:`yt.data_objects.static_output.Dataset`
This is the dataset object corresponding to the
simulation output to be plotted.
- fields: string
+ fields : string / tuple, or list of strings / tuples
The name(s) of the field(s) to be plotted.
- start_point: n-element list, tuple, ndarray, or YTArray
+ start_point : n-element list, tuple, ndarray, or YTArray
+ Contains the coordinates of the first point for constructing the line.
+ Must contain n elements where n is the dimensionality of the dataset.
+ end_point : n-element list, tuple, ndarray, or YTArray
Contains the coordinates of the first point for constructing the line.
Must contain n elements where n is the dimensionality of the dataset.
- end_point: n-element list, tuple, ndarray, or YTArray
- Contains the coordinates of the first point for constructing the line.
- Must contain n elements where n is the dimensionality of the dataset.
- figure_size: integer or two-element
- npoints: int
+ npoints : int
How many points to sample between start_point and end_point for
constructing the line plot
+ figure_size : int or two-element iterable of ints
+ Size in inches of the image.
+ Default: 5 (5x5)
+ fontsize : int
+ Font size for all text in the plot.
+ Default: 14
+ labels : dictionary
+ Keys should be the field names. Values should be latex-formattable
+ strings used in the LinePlot legend
+ Default: None
+
Example
-------
https://bitbucket.org/yt_analysis/yt/commits/8ff2f719cd9d/
Changeset: 8ff2f719cd9d
User: Alex Lindsay
Date: 2017-07-06 19:05:45+00:00
Summary: Rename line plotting utilities to 'pixelize_'
Affected #: 4 files
diff -r 7ebf1dd9b9a8e74fae7866f907391d066705e7aa -r 8ff2f719cd9d489941dc3eae3bba7408f813efef yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -26,7 +26,7 @@
from yt.utilities.lib.pixelization_routines import \
pixelize_element_mesh, pixelize_off_axis_cartesian, \
pixelize_cartesian, pixelize_cartesian_nodal, \
- element_mesh_line_plot
+ pixelize_element_mesh_line
from yt.data_objects.unstructured_mesh import SemiStructuredMesh
from yt.utilities.nodal_data_utils import get_nodal_data
@@ -158,7 +158,7 @@
antialias)
- def line_plot(self, field, start_point, end_point, npoints):
+ def pixelize_line(self, field, start_point, end_point, npoints):
"""
Method for sampling datasets along a line in preparation for
one-dimensional line plots. For UnstructuredMesh, relies on a
@@ -194,11 +194,11 @@
field_data = field_data[:, 0:8]
indices = indices[:, 0:8]
- arc_length, plot_values = element_mesh_line_plot(coords, indices,
- start_point,
- end_point,
- npoints, field_data,
- index_offset=offset)
+ arc_length, plot_values = pixelize_element_mesh_line(coords, indices,
+ start_point,
+ end_point,
+ npoints, field_data,
+ index_offset=offset)
arc_length = YTArray(arc_length, start_point.units)
plot_values = YTArray(plot_values, field_data.units)
else:
diff -r 7ebf1dd9b9a8e74fae7866f907391d066705e7aa -r 8ff2f719cd9d489941dc3eae3bba7408f813efef yt/geometry/coordinates/coordinate_handler.py
--- a/yt/geometry/coordinates/coordinate_handler.py
+++ b/yt/geometry/coordinates/coordinate_handler.py
@@ -72,7 +72,7 @@
class CoordinateHandler(object):
name = None
-
+
def __init__(self, ds, ordering):
self.ds = weakref.proxy(ds)
self.axis_order = ordering
@@ -86,7 +86,7 @@
# pixelizer
raise NotImplementedError
- def line_plot(self, field, start_point, end_point, resolution):
+ def pixelize_line(self, field, start_point, end_point, npoints):
raise NotImplementedError
def distance(self, start, end):
@@ -268,4 +268,3 @@
c2[...,1] = np.sin(coord[...,0]) * coord[...,1] + center[1]
c2[...,2] = coord[...,2]
return c2
-
diff -r 7ebf1dd9b9a8e74fae7866f907391d066705e7aa -r 8ff2f719cd9d489941dc3eae3bba7408f813efef yt/utilities/lib/pixelization_routines.pyx
--- a/yt/utilities/lib/pixelization_routines.pyx
+++ b/yt/utilities/lib/pixelization_routines.pyx
@@ -863,13 +863,13 @@
free(field_vals)
return img
-def element_mesh_line_plot(np.ndarray[np.float64_t, ndim=2] coords,
- np.ndarray[np.int64_t, ndim=2] conn,
- np.ndarray[np.float64_t, ndim=1] start_point,
- np.ndarray[np.float64_t, ndim=1] end_point,
- npoints,
- np.ndarray[np.float64_t, ndim=2] field,
- int index_offset = 0):
+def pixelize_element_mesh_line(np.ndarray[np.float64_t, ndim=2] coords,
+ np.ndarray[np.int64_t, ndim=2] conn,
+ np.ndarray[np.float64_t, ndim=1] start_point,
+ np.ndarray[np.float64_t, ndim=1] end_point,
+ npoints,
+ np.ndarray[np.float64_t, ndim=2] field,
+ int index_offset = 0):
# This routine chooses the correct element sampler to interpolate field
# values at evenly spaced points along a sampling line
diff -r 7ebf1dd9b9a8e74fae7866f907391d066705e7aa -r 8ff2f719cd9d489941dc3eae3bba7408f813efef yt/visualization/line_plot.py
--- a/yt/visualization/line_plot.py
+++ b/yt/visualization/line_plot.py
@@ -190,7 +190,7 @@
plot = PlotMPL(self.figure_size, axrect, None, None)
self.plots[field] = plot
- x, y = self.ds.coordinates.line_plot(
+ x, y = self.ds.coordinates.pixelize_line(
field, self.start_point, self.end_point, self.npoints)
if self._x_unit is None:
https://bitbucket.org/yt_analysis/yt/commits/d326aefaa00a/
Changeset: d326aefaa00a
User: ngoldbaum
Date: 2017-07-06 19:28:49+00:00
Summary: Use argmax to disambiguate when we select multiple cells for a sampling point.
Affected #: 1 file
diff -r 8ff2f719cd9d489941dc3eae3bba7408f813efef -r d326aefaa00a8e9c1f4fb466fd496b685612740e yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -57,7 +57,10 @@
ray_contains = ((sample_point >= (ray_coordinates - ray_dds/2)) &
(sample_point <= (ray_coordinates + ray_dds/2)))
ray_contains = ray_contains.all(axis=-1)
- field_values[i] = ray_field[ray_contains]
+ # use argmax to find the first nonzero index, sometimes there
+ # are two indices if the sampling point happens to fall exactly at
+ # a cell boundary
+ field_values[i] = ray_field[np.argmax(ray_contains)]
dr = np.sqrt((sample_dr**2).sum())
x = np.arange(npoints)/(npoints-1)*(dr*npoints)
return x, field_values
https://bitbucket.org/yt_analysis/yt/commits/eef1091aa468/
Changeset: eef1091aa468
User: ngoldbaum
Date: 2017-07-06 21:29:54+00:00
Summary: fix issue with incorrect start_point for ray sampling
Affected #: 1 file
diff -r d326aefaa00a8e9c1f4fb466fd496b685612740e -r eef1091aa46826d2c7c55a49938da4302ee1180a yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -48,7 +48,7 @@
end_point = ray.end_point
sample_dr = (end_point - start_point)/(npoints-1)
sample_points = [np.arange(npoints)*sample_dr[i] for i in range(3)]
- sample_points = uvstack(sample_points).T
+ sample_points = uvstack(sample_points).T + start_point
ray_coordinates = uvstack([ray[d] for d in 'xyz']).T
ray_dds = uvstack([ray['d'+d] for d in 'xyz']).T
ray_field = ray[field]
https://bitbucket.org/yt_analysis/yt/commits/41f22e5d10cb/
Changeset: 41f22e5d10cb
User: jzuhone
Date: 2017-07-12 17:58:37+00:00
Summary: Merge pull request #1440 from lindsayad/line_plot_plus_quad9
Initial line plotting
Affected #: 19 files
diff -r d7bc05ca16057f120acd5d043f90b6a8a32a2de5 -r 41f22e5d10cbe6cd5a029b315a774d78513e43b1 doc/source/cookbook/simple_1d_line_plot.py
--- /dev/null
+++ b/doc/source/cookbook/simple_1d_line_plot.py
@@ -0,0 +1,14 @@
+import yt
+
+# Load the dataset
+ds = yt.load("SecondOrderTris/RZ_p_no_parts_do_nothing_bcs_cone_out.e", step=-1)
+
+# Create a line plot of the variables 'u' and 'v' with 1000 sampling points evenly spaced
+# between the coordinates (0, 0, 0) and (0, 1, 0)
+plot = yt.LinePlot(ds, [('all', 'v'), ('all', 'u')], (0, 0, 0), (0, 1, 0), 1000)
+
+# Add a legend
+plot.add_legend(('all', 'v'))
+
+# Save the line plot
+plot.save()
diff -r d7bc05ca16057f120acd5d043f90b6a8a32a2de5 -r 41f22e5d10cbe6cd5a029b315a774d78513e43b1 doc/source/cookbook/simple_plots.rst
--- a/doc/source/cookbook/simple_plots.rst
+++ b/doc/source/cookbook/simple_plots.rst
@@ -43,6 +43,14 @@
.. yt_cookbook:: simple_phase.py
+Simple 1D Line Plotting
+~~~~~~~~~~~~~~~~~~~~~~~
+
+This script shows how to make a ``LinePlot`` through a dataset.
+See :ref:`how-to-1d-line-plot` for more information.
+
+.. yt_cookbook:: simple_1d_line_plot.py
+
Simple Probability Distribution Functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff -r d7bc05ca16057f120acd5d043f90b6a8a32a2de5 -r 41f22e5d10cbe6cd5a029b315a774d78513e43b1 doc/source/visualizing/plots.rst
--- a/doc/source/visualizing/plots.rst
+++ b/doc/source/visualizing/plots.rst
@@ -14,8 +14,8 @@
The :class:`~yt.visualization.plot_window.PlotWindow` interface is useful for
taking a quick look at simulation outputs. Simple mechanisms exist for making
-plots of slices, projections, 1D profiles, and 2D profiles (phase plots), all of
-which are described below.
+plots of slices, projections, 1D spatial line plots, 1D profiles, and 2D
+profiles (phase plots), all of which are described below.
.. _viewing-plots:
@@ -30,7 +30,7 @@
in other environments as well:
.. code-block:: python
-
+
%matplotlib notebook
import yt
yt.toggle_interactivity()
@@ -943,6 +943,7 @@
# Save the image.
plot.save()
+
Customizing axis limits
~~~~~~~~~~~~~~~~~~~~~~~
@@ -1054,6 +1055,87 @@
# change only the first line
plot.set_line_property("linestyle", "--", 0)
+.. _how-to-1d-unstructured-mesh:
+
+1D Line Sampling
+----------------
+
+YT has the ability to sample datasets along arbitrary lines
+and plot the result. You must supply five arguments to the ``LinePlot``
+class. They are enumerated below:
+
+1. Dataset
+2. A list of fields or a single field you wish to plot
+3. The starting point of the sampling line. This should be an n-element list, tuple,
+ ndarray, or YTArray with the elements corresponding to the coordinates of the
+ starting point. (n should equal the dimension of the dataset)
+4. The ending point of the sampling line. This should also be an n-element list, tuple,
+ ndarray, or YTArray with the elements corresponding to the coordinates of the
+ ending point.
+5. The number of sampling points along the line, e.g. if 1000 is specified, then
+ data will be sampled at 1000 points evenly spaced between the starting and
+ ending points.
+
+The below code snippet illustrates how this is done:
+
+.. code-block:: python
+
+ ds = yt.load("SecondOrderTris/RZ_p_no_parts_do_nothing_bcs_cone_out.e", step=-1)
+ plot = yt.LinePlot(ds, [('all', 'v'), ('all', 'u')], (0, 0, 0), (0, 1, 0), 1000)
+ plot.save()
+
+If working in a Jupyter Notebook, ``LinePlot`` also has the ``show()`` method.
+
+You can can add a legend to a 1D sampling plot. The legend process takes two steps:
+
+1. When instantiating the ``LinePlot``, pass a dictionary of
+ labels with keys corresponding to the field names
+2. Call the ``LinePlot`` ``add_legend`` method
+
+X- and Y- axis units can be set with ``set_x_unit`` and ``set_unit`` methods
+respectively. The below code snippet combines all the features we've discussed:
+
+.. python-script::
+
+ import yt
+
+ ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030')
+
+ plot = yt.LinePlot(ds, 'density', [0, 0, 0], [1, 1, 1], 512)
+ plot.add_legend('density')
+ plot.set_x_unit('cm')
+ plot.set_unit('density', 'kg/cm**3')
+ plot.save()
+
+If a list of fields is passed to ``LinePlot``, yt will create a number of
+individual figures equal to the number of different dimensional
+quantities. E.g. if ``LinePlot`` receives two fields with units of "length/time"
+and a field with units of "temperature", two different figures will be created,
+one with plots of the "length/time" fields and another with the plot of the
+"temperature" field. It is only necessary to call ``add_legend``
+for one field of a multi-field plot to produce a legend containing all the
+labels passed in the initial construction of the ``LinePlot`` instance. Example:
+
+.. python-script::
+
+ import yt
+
+ ds = yt.load("SecondOrderTris/RZ_p_no_parts_do_nothing_bcs_cone_out.e", step=-1)
+ plot = yt.LinePlot(ds, [('all', 'v'), ('all', 'u')], [0, 0, 0], [0, 1, 0],
+ 100, labels={('all', 'u') : r"v$_x$", ('all', 'v') : r"v$_y$"})
+ plot.add_legend(('all', 'u'))
+ plot.save()
+
+``LinePlot`` is a bit different from yt ray objects which are data
+containers. ``LinePlot`` is a plotting class that may use yt ray objects to
+supply field plotting information. However, perhaps the most important
+difference to highlight between rays and ``LinePlot`` is that rays return data
+elements that intersect with the ray and make no guarantee about the spacing
+between data elements. ``LinePlot`` sampling points are guaranteed to be evenly
+spaced. In the case of cell data where multiple points fall within the same
+cell, the ``LinePlot`` object will show the same field value for each sampling
+point that falls within the same cell.
+
.. _how-to-make-2d-profiles:
2D Phase Plots
diff -r d7bc05ca16057f120acd5d043f90b6a8a32a2de5 -r 41f22e5d10cbe6cd5a029b315a774d78513e43b1 tests/tests.yaml
--- a/tests/tests.yaml
+++ b/tests/tests.yaml
@@ -67,11 +67,12 @@
- yt/analysis_modules/photon_simulator/tests/test_spectra.py
- yt/analysis_modules/photon_simulator/tests/test_sloshing.py
- local_unstructured_006:
+ local_unstructured_008:
- yt/visualization/volume_rendering/tests/test_mesh_render.py
- yt/visualization/tests/test_mesh_slices.py:test_tri2
- yt/visualization/tests/test_mesh_slices.py:test_quad2
- yt/visualization/tests/test_mesh_slices.py:test_multi_region
+ - yt/visualization/tests/test_line_plots.py:test_line_plot
local_boxlib_004:
- yt/frontends/boxlib/tests/test_outputs.py:test_radadvect
diff -r d7bc05ca16057f120acd5d043f90b6a8a32a2de5 -r 41f22e5d10cbe6cd5a029b315a774d78513e43b1 yt/__init__.py
--- a/yt/__init__.py
+++ b/yt/__init__.py
@@ -103,7 +103,7 @@
FixedResolutionBuffer, ObliqueFixedResolutionBuffer, \
write_bitmap, write_image, \
apply_colormap, scale_image, write_projection, \
- SlicePlot, AxisAlignedSlicePlot, OffAxisSlicePlot, \
+ SlicePlot, AxisAlignedSlicePlot, OffAxisSlicePlot, LinePlot, \
ProjectionPlot, OffAxisProjectionPlot, \
show_colormaps, add_cmap, make_colormap, \
ProfilePlot, PhasePlot, ParticlePhasePlot, \
diff -r d7bc05ca16057f120acd5d043f90b6a8a32a2de5 -r 41f22e5d10cbe6cd5a029b315a774d78513e43b1 yt/fields/derived_field.py
--- a/yt/fields/derived_field.py
+++ b/yt/fields/derived_field.py
@@ -13,6 +13,7 @@
import contextlib
import inspect
+import re
import warnings
from yt.extern.six import string_types, PY2
@@ -292,6 +293,51 @@
s += ")"
return s
+ def _is_ion(self):
+ p = re.compile("_p[0-9]+_")
+ result = False
+ if p.search(self.name[1]) is not None:
+ result = True
+ return result
+
+ def _ion_to_label(self):
+ pnum2rom = {
+ "0":"I", "1":"II", "2":"III", "3":"IV", "4":"V",
+ "5":"VI", "6":"VII", "7":"VIII", "8":"IX", "9":"X",
+ "10":"XI", "11":"XII", "12":"XIII", "13":"XIV", "14":"XV",
+ "15":"XVI", "16":"XVII", "17":"XVIII", "18":"XIX", "19":"XX"}
+
+ p = re.compile("_p[0-9]+_")
+ m = p.search(self.name[1])
+ if m is not None:
+ pstr = m.string[m.start()+1:m.end()-1]
+ segments = self.name[1].split("_")
+ for i,s in enumerate(segments):
+ segments[i] = s.capitalize()
+ if s == pstr:
+ ipstr = i
+ element = segments[ipstr-1]
+ roman = pnum2rom[pstr[1:]]
+ label = element + '\ ' + roman + '\ ' + \
+ '\ '.join(segments[ipstr+1:])
+ else:
+ label = self.name[1]
+ return label
+
+ def get_latex_display_name(self):
+ label = self.display_name
+ if label is None:
+ if self._is_ion():
+ fname = self._ion_to_label()
+ label = r'$\rm{'+fname.replace('_','\ ')+r'}$'
+ else:
+ label = r'$\rm{'+self.name[1].replace('_','\ ').title()+r'}$'
+ elif label.find('$') == -1:
+ label = label.replace(' ','\ ')
+ label = r'$\rm{'+label+r'}$'
+ return label
+
+
class FieldValidator(object):
pass
@@ -361,6 +407,7 @@
FieldValidator.__init__(self)
self.ghost_zones = ghost_zones
self.fields = fields
+
def __call__(self, data):
# When we say spatial information, we really mean
# that it has a three-dimensional data structure
diff -r d7bc05ca16057f120acd5d043f90b6a8a32a2de5 -r 41f22e5d10cbe6cd5a029b315a774d78513e43b1 yt/frontends/exodus_ii/fields.py
--- a/yt/frontends/exodus_ii/fields.py
+++ b/yt/frontends/exodus_ii/fields.py
@@ -33,6 +33,8 @@
def __init__(self, ds, field_list):
super(ExodusIIFieldInfo, self).__init__(ds, field_list)
+ for name in self:
+ self[name].take_log = False
# If you want, you can check self.field_list
def setup_fluid_fields(self):
diff -r d7bc05ca16057f120acd5d043f90b6a8a32a2de5 -r 41f22e5d10cbe6cd5a029b315a774d78513e43b1 yt/geometry/coordinates/cartesian_coordinates.py
--- a/yt/geometry/coordinates/cartesian_coordinates.py
+++ b/yt/geometry/coordinates/cartesian_coordinates.py
@@ -22,12 +22,48 @@
cartesian_to_cylindrical, \
cylindrical_to_cartesian
from yt.funcs import mylog
+from yt.units.yt_array import uvstack, YTArray
from yt.utilities.lib.pixelization_routines import \
pixelize_element_mesh, pixelize_off_axis_cartesian, \
- pixelize_cartesian, pixelize_cartesian_nodal
+ pixelize_cartesian, pixelize_cartesian_nodal, \
+ pixelize_element_mesh_line
from yt.data_objects.unstructured_mesh import SemiStructuredMesh
from yt.utilities.nodal_data_utils import get_nodal_data
+def _sample_ray(ray, npoints, field):
+ """
+ Private function that uses a ray object for calculating the field values
+ that will be the y-axis values in a LinePlot object.
+
+ Parameters
+ ----------
+ ray : YTOrthoRay, YTRay, or LightRay
+ Ray object from which to sample field values
+ npoints : int
+ The number of points to sample
+ field : str or field tuple
+ The name of the field to sample
+ """
+ start_point = ray.start_point
+ end_point = ray.end_point
+ sample_dr = (end_point - start_point)/(npoints-1)
+ sample_points = [np.arange(npoints)*sample_dr[i] for i in range(3)]
+ sample_points = uvstack(sample_points).T + start_point
+ ray_coordinates = uvstack([ray[d] for d in 'xyz']).T
+ ray_dds = uvstack([ray['d'+d] for d in 'xyz']).T
+ ray_field = ray[field]
+ field_values = ray.ds.arr(np.zeros(npoints), ray_field.units)
+ for i, sample_point in enumerate(sample_points):
+ ray_contains = ((sample_point >= (ray_coordinates - ray_dds/2)) &
+ (sample_point <= (ray_coordinates + ray_dds/2)))
+ ray_contains = ray_contains.all(axis=-1)
+ # use argmax to find the first nonzero index, sometimes there
+ # are two indices if the sampling point happens to fall exactly at
+ # a cell boundary
+ field_values[i] = ray_field[np.argmax(ray_contains)]
+ dr = np.sqrt((sample_dr**2).sum())
+ x = np.arange(npoints)/(npoints-1)*(dr*npoints)
+ return x, field_values
class CartesianCoordinateHandler(CoordinateHandler):
name = "cartesian"
@@ -65,6 +101,11 @@
def pixelize(self, dimension, data_source, field, bounds, size,
antialias = True, periodic = True):
+ """
+ Method for pixelizing datasets in preparation for
+ two-dimensional image plots. Relies on several sampling
+ routines written in cython
+ """
index = data_source.ds.index
if (hasattr(index, 'meshes') and
not isinstance(index.meshes[0], SemiStructuredMesh)):
@@ -119,6 +160,57 @@
return self._oblique_pixelize(data_source, field, bounds, size,
antialias)
+
+ def pixelize_line(self, field, start_point, end_point, npoints):
+ """
+ Method for sampling datasets along a line in preparation for
+ one-dimensional line plots. For UnstructuredMesh, relies on a
+ sampling routine written in cython
+ """
+ if npoints < 2:
+ raise ValueError("Must have at least two sample points in order "
+ "to draw a line plot.")
+ index = self.ds.index
+ if (hasattr(index, 'meshes') and
+ not isinstance(index.meshes[0], SemiStructuredMesh)):
+ ftype, fname = field
+ if ftype == "all":
+ mesh_id = 0
+ indices = np.concatenate([mesh.connectivity_indices for mesh in index.mesh_union])
+ else:
+ mesh_id = int(ftype[-1]) - 1
+ indices = index.meshes[mesh_id].connectivity_indices
+
+ coords = index.meshes[mesh_id].connectivity_coords
+ if coords.shape[1] != end_point.size != start_point.size:
+ raise ValueError("The coordinate dimension doesn't match the "
+ "start and end point dimensions.")
+
+
+ offset = index.meshes[mesh_id]._index_offset
+ ad = self.ds.all_data()
+ field_data = ad[field]
+ if field_data.shape[1] == 27:
+ # hexahedral
+ mylog.warning("High order elements not yet supported, " +
+ "dropping to 1st order.")
+ field_data = field_data[:, 0:8]
+ indices = indices[:, 0:8]
+
+ arc_length, plot_values = pixelize_element_mesh_line(coords, indices,
+ start_point,
+ end_point,
+ npoints, field_data,
+ index_offset=offset)
+ arc_length = YTArray(arc_length, start_point.units)
+ plot_values = YTArray(plot_values, field_data.units)
+ else:
+ ray = self.ds.ray(start_point, end_point)
+ arc_length, plot_values = _sample_ray(ray, npoints, field)
+ return arc_length, plot_values
+
+
+
def _ortho_pixelize(self, data_source, field, bounds, size, antialias,
dim, periodic):
# We should be using fcoords
@@ -129,13 +221,13 @@
period = period.in_units("code_length").d
buff = np.zeros((size[1], size[0]), dtype="f8")
-
+
finfo = self.ds._get_field_info(field)
nodal_flag = finfo.nodal_flag
if np.any(nodal_flag):
nodal_data = get_nodal_data(data_source, field)
coord = data_source.coord.d
- pixelize_cartesian_nodal(buff,
+ pixelize_cartesian_nodal(buff,
data_source['px'], data_source['py'], data_source['pz'],
data_source['pdx'], data_source['pdy'], data_source['pdz'],
nodal_data, coord, bounds, int(antialias),
@@ -147,7 +239,7 @@
bounds, int(antialias),
period, int(periodic))
return buff
-
+
def _oblique_pixelize(self, data_source, field, bounds, size, antialias):
indices = np.argsort(data_source['pdx'])[::-1].astype(np.int_)
buff = np.zeros((size[1], size[0]), dtype="f8")
diff -r d7bc05ca16057f120acd5d043f90b6a8a32a2de5 -r 41f22e5d10cbe6cd5a029b315a774d78513e43b1 yt/geometry/coordinates/coordinate_handler.py
--- a/yt/geometry/coordinates/coordinate_handler.py
+++ b/yt/geometry/coordinates/coordinate_handler.py
@@ -72,7 +72,7 @@
class CoordinateHandler(object):
name = None
-
+
def __init__(self, ds, ordering):
self.ds = weakref.proxy(ds)
self.axis_order = ordering
@@ -86,6 +86,9 @@
# pixelizer
raise NotImplementedError
+ def pixelize_line(self, field, start_point, end_point, npoints):
+ raise NotImplementedError
+
def distance(self, start, end):
p1 = self.convert_to_cartesian(start)
p2 = self.convert_to_cartesian(end)
@@ -265,4 +268,3 @@
c2[...,1] = np.sin(coord[...,0]) * coord[...,1] + center[1]
c2[...,2] = coord[...,2]
return c2
-
diff -r d7bc05ca16057f120acd5d043f90b6a8a32a2de5 -r 41f22e5d10cbe6cd5a029b315a774d78513e43b1 yt/utilities/lib/fixed_interpolator.pxd
--- a/yt/utilities/lib/fixed_interpolator.pxd
+++ b/yt/utilities/lib/fixed_interpolator.pxd
@@ -30,4 +30,3 @@
np.float64_t vl[3], np.float64_t dds[3],
np.float64_t x, np.float64_t y, np.float64_t z,
int vind1, int vind2) nogil
-
diff -r d7bc05ca16057f120acd5d043f90b6a8a32a2de5 -r 41f22e5d10cbe6cd5a029b315a774d78513e43b1 yt/utilities/lib/pixelization_routines.pyx
--- a/yt/utilities/lib/pixelization_routines.pyx
+++ b/yt/utilities/lib/pixelization_routines.pyx
@@ -119,7 +119,7 @@
# (lr) and then iterate up to "right column" (rc) and "uppeR row" (rr),
# depositing into them the data value. Overlap computes the relative
# overlap of a data value with a pixel.
- #
+ #
# NOTE ON ROWS AND COLUMNS:
#
# The way that images are plotting in matplotlib is somewhat different
@@ -254,7 +254,7 @@
cdef int lc, lr, rc, rr
cdef np.float64_t lypx, rypx, lxpx, rxpx, overlap1, overlap2
# These are the temp vars we get from the arrays
- cdef np.float64_t oxsp, oysp, ozsp
+ cdef np.float64_t oxsp, oysp, ozsp
cdef np.float64_t xsp, ysp, zsp
cdef np.float64_t dxsp, dysp, dzsp
# Some periodicity helpers
@@ -303,7 +303,7 @@
# (lr) and then iterate up to "right column" (rc) and "uppeR row" (rr),
# depositing into them the data value. Overlap computes the relative
# overlap of a data value with a pixel.
- #
+ #
# NOTE ON ROWS AND COLUMNS:
#
# The way that images are plotting in matplotlib is somewhat different
@@ -497,7 +497,7 @@
cdef np.float64_t r_i, theta_i, dr_i, dtheta_i, dthetamin
cdef np.float64_t costheta, sintheta
cdef int i, pi, pj
-
+
cdef int imax = np.asarray(radius).argmax()
rmax = radius[imax] + dradius[imax]
@@ -862,3 +862,107 @@
free(vertices)
free(field_vals)
return img
+
+def pixelize_element_mesh_line(np.ndarray[np.float64_t, ndim=2] coords,
+ np.ndarray[np.int64_t, ndim=2] conn,
+ np.ndarray[np.float64_t, ndim=1] start_point,
+ np.ndarray[np.float64_t, ndim=1] end_point,
+ npoints,
+ np.ndarray[np.float64_t, ndim=2] field,
+ int index_offset = 0):
+
+ # This routine chooses the correct element sampler to interpolate field
+ # values at evenly spaced points along a sampling line
+ cdef np.float64_t *vertices
+ cdef np.float64_t *field_vals
+ cdef int nvertices = conn.shape[1]
+ cdef int ndim = coords.shape[1]
+ cdef int num_field_vals = field.shape[1]
+ cdef int num_plot_nodes = npoints
+ cdef int num_intervals = npoints - 1
+ cdef double[4] mapped_coord
+ cdef ElementSampler sampler
+ cdef np.ndarray[np.float64_t, ndim=1] lin_vec
+ cdef np.ndarray[np.float64_t, ndim=1] lin_inc
+ cdef np.ndarray[np.float64_t, ndim=2] lin_sample_points
+ cdef np.int64_t i, n, j, k
+ cdef np.ndarray[np.float64_t, ndim=1] arc_length
+ cdef np.float64_t lin_length, inc_length
+ cdef np.ndarray[np.float64_t, ndim=1] plot_values
+ cdef np.float64_t sample_point[3]
+
+ lin_vec = np.zeros(ndim, dtype="float64")
+ lin_inc = np.zeros(ndim, dtype="float64")
+
+ lin_sample_points = np.zeros((num_plot_nodes, ndim), dtype="float64")
+ arc_length = np.zeros(num_plot_nodes, dtype="float64")
+ plot_values = np.zeros(num_plot_nodes, dtype="float64")
+
+ # Pick the right sampler and allocate storage for the mapped coordinate
+ if ndim == 3 and nvertices == 4:
+ sampler = P1Sampler3D()
+ elif ndim == 3 and nvertices == 6:
+ sampler = W1Sampler3D()
+ elif ndim == 3 and nvertices == 8:
+ sampler = Q1Sampler3D()
+ elif ndim == 3 and nvertices == 20:
+ sampler = S2Sampler3D()
+ elif ndim == 2 and nvertices == 3:
+ sampler = P1Sampler2D()
+ elif ndim == 1 and nvertices == 2:
+ sampler = P1Sampler1D()
+ elif ndim == 2 and nvertices == 4:
+ sampler = Q1Sampler2D()
+ elif ndim == 2 and nvertices == 9:
+ sampler = Q2Sampler2D()
+ elif ndim == 2 and nvertices == 6:
+ sampler = T2Sampler2D()
+ elif ndim == 3 and nvertices == 10:
+ sampler = Tet2Sampler3D()
+ else:
+ raise YTElementTypeNotRecognized(ndim, nvertices)
+
+ # allocate temporary storage
+ vertices = <np.float64_t *> malloc(ndim * sizeof(np.float64_t) * nvertices)
+ field_vals = <np.float64_t *> malloc(sizeof(np.float64_t) * num_field_vals)
+
+ lin_vec = end_point - start_point
+ lin_length = np.linalg.norm(lin_vec)
+ lin_inc = lin_vec / num_intervals
+ inc_length = lin_length / num_intervals
+ for j in range(ndim):
+ lin_sample_points[0, j] = start_point[j]
+ arc_length[0] = 0
+ for i in range(1, num_intervals + 1):
+ for j in range(ndim):
+ lin_sample_points[i, j] = lin_sample_points[i-1, j] + lin_inc[j]
+ arc_length[i] = arc_length[i-1] + inc_length
+
+ for i in range(num_intervals + 1):
+ for j in range(3):
+ if j < ndim:
+ sample_point[j] = lin_sample_points[i][j]
+ else:
+ sample_point[j] = 0
+ for ci in range(conn.shape[0]):
+ for n in range(num_field_vals):
+ field_vals[n] = field[ci, n]
+
+ # Fill the vertices
+ for n in range(nvertices):
+ cj = conn[ci, n] - index_offset
+ for k in range(ndim):
+ vertices[ndim*n + k] = coords[cj, k]
+
+ sampler.map_real_to_unit(mapped_coord, vertices, sample_point)
+ if not sampler.check_inside(mapped_coord) and ci != conn.shape[0] - 1:
+ continue
+ elif not sampler.check_inside(mapped_coord):
+ raise ValueError("Check to see that both starting and ending line points "
+ "are within the domain of the mesh.")
+ plot_values[i] = sampler.sample_at_unit_point(mapped_coord, field_vals)
+ break
+
+ free(vertices)
+ free(field_vals)
+ return arc_length, plot_values
diff -r d7bc05ca16057f120acd5d043f90b6a8a32a2de5 -r 41f22e5d10cbe6cd5a029b315a774d78513e43b1 yt/visualization/api.py
--- a/yt/visualization/api.py
+++ b/yt/visualization/api.py
@@ -53,6 +53,9 @@
ProjectionPlot, \
OffAxisProjectionPlot
+from .line_plot import \
+ LinePlot
+
from .profile_plotter import \
ProfilePlot, \
PhasePlot
diff -r d7bc05ca16057f120acd5d043f90b6a8a32a2de5 -r 41f22e5d10cbe6cd5a029b315a774d78513e43b1 yt/visualization/base_plot_types.py
--- a/yt/visualization/base_plot_types.py
+++ b/yt/visualization/base_plot_types.py
@@ -50,7 +50,7 @@
class CallbackWrapper(object):
- def __init__(self, viewer, window_plot, frb, field, font_properties,
+ def __init__(self, viewer, window_plot, frb, field, font_properties,
font_color):
self.frb = frb
self.data = frb.data_source
@@ -86,6 +86,8 @@
import matplotlib.figure
self._plot_valid = True
if figure is None:
+ if not iterable(fsize):
+ fsize = (fsize, fsize)
self.figure = matplotlib.figure.Figure(figsize=fsize, frameon=True)
else:
figure.set_size_inches(fsize)
@@ -164,6 +166,8 @@
def _get_labels(self):
ax = self.axes
labels = ax.xaxis.get_ticklabels() + ax.yaxis.get_ticklabels()
+ labels += ax.xaxis.get_minorticklabels()
+ labels += ax.yaxis.get_minorticklabels()
labels += [ax.title, ax.xaxis.label, ax.yaxis.label,
ax.xaxis.get_offset_text(), ax.yaxis.get_offset_text()]
return labels
@@ -279,10 +283,10 @@
x_frac_widths = xbins/size[0]
y_frac_widths = ybins/size[1]
- # axrect is the rectangle defining the area of the
- # axis object of the plot. Its range goes from 0 to 1 in
- # x and y directions. The first two values are the x,y
- # start values of the axis object (lower left corner), and the
+ # axrect is the rectangle defining the area of the
+ # axis object of the plot. Its range goes from 0 to 1 in
+ # x and y directions. The first two values are the x,y
+ # start values of the axis object (lower left corner), and the
# second two values are the size of the axis object. To get
# the upper right corner, add the first x,y to the second x,y.
axrect = (
@@ -452,5 +456,3 @@
ax.clear()
cbars.append(ax)
return fig, tr, cbars
-
-
diff -r d7bc05ca16057f120acd5d043f90b6a8a32a2de5 -r 41f22e5d10cbe6cd5a029b315a774d78513e43b1 yt/visualization/fixed_resolution.py
--- a/yt/visualization/fixed_resolution.py
+++ b/yt/visualization/fixed_resolution.py
@@ -30,7 +30,6 @@
import numpy as np
import weakref
-import re
import types
class FixedResolutionBuffer(object):
@@ -155,38 +154,6 @@
if f not in exclude and f[0] not in self.data_source.ds.particle_types:
self[f]
- def _is_ion( self, fname ):
- p = re.compile("_p[0-9]+_")
- result = False
- if p.search( fname ) is not None:
- result = True
- return result
-
- def _ion_to_label( self, fname ):
- pnum2rom = {
- "0":"I", "1":"II", "2":"III", "3":"IV", "4":"V",
- "5":"VI", "6":"VII", "7":"VIII", "8":"IX", "9":"X",
- "10":"XI", "11":"XII", "12":"XIII", "13":"XIV", "14":"XV",
- "15":"XVI", "16":"XVII", "17":"XVIII", "18":"XIX", "19":"XX"}
-
- p = re.compile("_p[0-9]+_")
- m = p.search( fname )
- if m is not None:
- pstr = m.string[m.start()+1:m.end()-1]
- segments = fname.split("_")
- for i,s in enumerate(segments):
- segments[i] = s.capitalize()
- if s == pstr:
- ipstr = i
- element = segments[ipstr-1]
- roman = pnum2rom[pstr[1:]]
- label = element + '\ ' + roman + '\ ' + \
- '\ '.join(segments[ipstr+1:])
- else:
- label = fname
- return label
-
-
def _get_info(self, item):
info = {}
ftype, fname = field = self.data_source._determine_fields(item)[0]
@@ -210,18 +177,7 @@
except AttributeError:
pass
- info['label'] = finfo.display_name
- if info['label'] is None:
- if self._is_ion( fname ):
- fname = self._ion_to_label( fname )
- info['label'] = r'$\rm{'+fname+r'}$'
- info['label'] = r'$\rm{'+fname.replace('_','\ ')+r'}$'
- else:
- info['label'] = r'$\rm{'+fname+r'}$'
- info['label'] = r'$\rm{'+fname.replace('_','\ ').title()+r'}$'
- elif info['label'].find('$') == -1:
- info['label'] = info['label'].replace(' ','\ ')
- info['label'] = r'$\rm{'+info['label']+r'}$'
+ info['label'] = finfo.get_latex_display_name()
return info
diff -r d7bc05ca16057f120acd5d043f90b6a8a32a2de5 -r 41f22e5d10cbe6cd5a029b315a774d78513e43b1 yt/visualization/line_plot.py
--- /dev/null
+++ b/yt/visualization/line_plot.py
@@ -0,0 +1,304 @@
+"""
+A mechanism for plotting field values along a line through a dataset
+
+
+
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (c) 2017, yt Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+
+import numpy as np
+
+from collections import defaultdict
+from yt.funcs import \
+ iterable
+from yt.units.unit_object import \
+ Unit
+from yt.units.yt_array import \
+ YTArray
+from yt.visualization.base_plot_types import \
+ PlotMPL
+from yt.visualization.plot_container import \
+ PlotContainer, \
+ PlotDictionary, \
+ log_transform, \
+ linear_transform, \
+ invalidate_plot
+
+class LinePlotDictionary(PlotDictionary):
+ def __init__(self, data_source):
+ super(LinePlotDictionary, self).__init__(data_source)
+ self.known_dimensions = {}
+
+ def _sanitize_dimensions(self, item):
+ field = self.data_source._determine_fields(item)[0]
+ finfo = self.data_source.ds.field_info[field]
+ dimensions = Unit(
+ finfo.units, registry=self.data_source.ds.unit_registry).dimensions
+ if dimensions not in self.known_dimensions:
+ self.known_dimensions[dimensions] = item
+ ret_item = item
+ else:
+ ret_item = self.known_dimensions[dimensions]
+ return ret_item
+
+ def __getitem__(self, item):
+ ret_item = self._sanitize_dimensions(item)
+ return super(LinePlotDictionary, self).__getitem__(ret_item)
+
+ def __setitem__(self, item, value):
+ ret_item = self._sanitize_dimensions(item)
+ super(LinePlotDictionary, self).__setitem__(ret_item, value)
+
+ def __contains__(self, item):
+ ret_item = self._sanitize_dimensions(item)
+ return super(LinePlotDictionary, self).__contains__(ret_item)
+
+class LinePlot(PlotContainer):
+ r"""
+ A class for constructing line plots
+
+ Parameters
+ ----------
+
+ ds : :class:`yt.data_objects.static_output.Dataset`
+ This is the dataset object corresponding to the
+ simulation output to be plotted.
+ fields : string / tuple, or list of strings / tuples
+ The name(s) of the field(s) to be plotted.
+ start_point : n-element list, tuple, ndarray, or YTArray
+ Contains the coordinates of the first point for constructing the line.
+ Must contain n elements where n is the dimensionality of the dataset.
+ end_point : n-element list, tuple, ndarray, or YTArray
+ Contains the coordinates of the first point for constructing the line.
+ Must contain n elements where n is the dimensionality of the dataset.
+ npoints : int
+ How many points to sample between start_point and end_point for
+ constructing the line plot
+ figure_size : int or two-element iterable of ints
+ Size in inches of the image.
+ Default: 5 (5x5)
+ fontsize : int
+ Font size for all text in the plot.
+ Default: 14
+ labels : dictionary
+ Keys should be the field names. Values should be latex-formattable
+ strings used in the LinePlot legend
+ Default: None
+
+
+ Example
+ -------
+
+ >>> import yt
+ >>>
+ >>> ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030')
+ >>>
+ >>> plot = yt.LinePlot(ds, 'density', [0, 0, 0], [1, 1, 1], 512)
+ >>> plot.add_legend('density')
+ >>> plot.set_x_unit('cm')
+ >>> plot.set_unit('density', 'kg/cm**3')
+ >>> plot.save()
+
+ """
+ _plot_type = 'line_plot'
+
+ def __init__(self, ds, fields, start_point, end_point, npoints,
+ figure_size=5., fontsize=14., labels=None):
+ """
+ Sets up figure and axes
+ """
+ self.start_point = _validate_point(start_point, ds, start=True)
+ self.end_point = _validate_point(end_point, ds)
+ self.npoints = npoints
+ self._x_unit = None
+ self._y_units = {}
+ self._titles = {}
+
+ data_source = ds.all_data()
+
+ self.fields = data_source._determine_fields(fields)
+ self.plots = LinePlotDictionary(data_source)
+ self.include_legend = defaultdict(bool)
+ if labels is None:
+ self.labels = {}
+ else:
+ self.labels = labels
+
+ super(LinePlot, self).__init__(data_source, figure_size, fontsize)
+
+ for f in self.fields:
+ if f not in self.labels:
+ self.labels[f] = f[1]
+ finfo = self.data_source.ds._get_field_info(*f)
+ if finfo.take_log:
+ self._field_transform[f] = log_transform
+ else:
+ self._field_transform[f] = linear_transform
+
+ self._setup_plots()
+
+ @invalidate_plot
+ def add_legend(self, field):
+ """Adds a legend to the `LinePlot` instance"""
+ self.include_legend[field] = True
+
+ def _setup_plots(self):
+ if self._plot_valid is True:
+ return
+ for plot in self.plots.values():
+ plot.axes.cla()
+ dimensions_counter = defaultdict(int)
+ for field in self.fields:
+ fontscale = self._font_properties._size / 14.
+ top_buff_size = 0.35*fontscale
+
+ x_axis_size = 1.35*fontscale
+ y_axis_size = 0.7*fontscale
+ right_buff_size = 0.2*fontscale
+
+ if iterable(self.figure_size):
+ figure_size = self.figure_size
+ else:
+ figure_size = (self.figure_size, self.figure_size)
+
+ xbins = np.array([x_axis_size, figure_size[0],
+ right_buff_size])
+ ybins = np.array([y_axis_size, figure_size[1], top_buff_size])
+
+ size = [xbins.sum(), ybins.sum()]
+
+ x_frac_widths = xbins/size[0]
+ y_frac_widths = ybins/size[1]
+
+ axrect = (
+ x_frac_widths[0],
+ y_frac_widths[0],
+ x_frac_widths[1],
+ y_frac_widths[1],
+ )
+
+ try:
+ plot = self.plots[field]
+ except KeyError:
+ plot = PlotMPL(self.figure_size, axrect, None, None)
+ self.plots[field] = plot
+
+ x, y = self.ds.coordinates.pixelize_line(
+ field, self.start_point, self.end_point, self.npoints)
+
+ if self._x_unit is None:
+ unit_x = x.units
+ else:
+ unit_x = self._x_unit
+
+ if field in self._y_units:
+ unit_y = self._y_units[field]
+ else:
+ unit_y = y.units
+
+ x = x.to(unit_x)
+ y = y.to(unit_y)
+
+ plot.axes.plot(x, y, label=self.labels[field])
+
+ if self._field_transform[field] != linear_transform:
+ if (y < 0).any():
+ plot.axes.set_yscale('symlog')
+ else:
+ plot.axes.set_yscale('log')
+
+ plot._set_font_properties(self._font_properties, None)
+
+ axes_unit_labels = self._get_axes_unit_labels(unit_x, unit_y)
+
+ finfo = self.ds.field_info[field]
+
+ x_label = r'$\rm{Path\ Length' + axes_unit_labels[0]+'}$'
+
+ finfo = self.ds.field_info[field]
+ dimensions = Unit(finfo.units,
+ registry=self.ds.unit_registry).dimensions
+ dimensions_counter[dimensions] += 1
+ if dimensions_counter[dimensions] > 1:
+ y_label = (r'$\rm{Multiple\ Fields}$' + r'$\rm{' +
+ axes_unit_labels[1]+'}$')
+ else:
+ y_label = (finfo.get_latex_display_name() + r'$\rm{' +
+ axes_unit_labels[1]+'}$')
+
+ plot.axes.set_xlabel(x_label)
+ plot.axes.set_ylabel(y_label)
+
+ if field in self._titles:
+ plot.axes.set_title(self._titles[field])
+
+ if self.include_legend[field]:
+ plot.axes.legend()
+
+ @invalidate_plot
+ def set_x_unit(self, unit_name):
+ """Set the unit to use along the x-axis
+
+ Parameters
+ ----------
+ unit_name: str
+ The name of the unit to use for the x-axis unit
+ """
+ self._x_unit = unit_name
+
+ @invalidate_plot
+ def set_unit(self, field, unit_name):
+ """Set the unit used to plot the field
+
+ Parameters
+ ----------
+ field: str or field tuple
+ The name of the field to set the units for
+ unit_name: str
+ The name of the unit to use for this field
+ """
+ self._y_units[self.data_source._determine_fields(field)[0]] = unit_name
+
+ @invalidate_plot
+ def annotate_title(self, field, title):
+ """Set the unit used to plot the field
+
+ Parameters
+ ----------
+ field: str or field tuple
+ The name of the field to set the units for
+ title: str
+ The title to use for the plot
+ """
+ self._titles[self.data_source._determine_fields(field)[0]] = title
+
+def _validate_point(point, ds, start=False):
+ if not iterable(point):
+ raise RuntimeError(
+ "Input point must be array-like"
+ )
+ if not isinstance(point, YTArray):
+ point = ds.arr(point, 'code_length')
+ if len(point.shape) != 1:
+ raise RuntimeError(
+ "Input point must be a 1D array"
+ )
+ if point.shape[0] < ds.dimensionality:
+ raise RuntimeError(
+ "Input point must have an element for each dimension"
+ )
+ # need to pad to 3D elements to avoid issues later
+ if point.shape[0] < 3:
+ if start:
+ val = 0
+ else:
+ val = 1
+ point = np.append(point.d, [val]*(3-ds.dimensionality))*point.uq
+ return point
diff -r d7bc05ca16057f120acd5d043f90b6a8a32a2de5 -r 41f22e5d10cbe6cd5a029b315a774d78513e43b1 yt/visualization/plot_container.py
--- a/yt/visualization/plot_container.py
+++ b/yt/visualization/plot_container.py
@@ -30,11 +30,19 @@
from yt.config import \
ytcfg
+from yt.data_objects.time_series import \
+ DatasetSeries
from yt.funcs import \
get_image_suffix, \
iterable, \
ensure_dir, \
ensure_list
+from yt.units.unit_lookup_table import \
+ prefixable_units, latex_prefixes
+from yt.units.unit_object import \
+ Unit
+from yt.utilities.definitions import \
+ formatted_length_unit_names
from yt.utilities.exceptions import \
YTNotInsideNotebook
from yt.visualization.color_maps import \
@@ -178,36 +186,27 @@
self.data_source = data_source
return defaultdict.__init__(self, default_factory)
-class ImagePlotContainer(object):
- """A container for plots with colorbars.
-
- """
+class PlotContainer(object):
+ """A container for generic plots"""
_plot_type = None
_plot_valid = False
- _colorbar_valid = False
def __init__(self, data_source, figure_size, fontsize):
from matplotlib.font_manager import FontProperties
-
self.data_source = data_source
+ self.ds = data_source.ds
+ self.ts = self._initialize_dataset(self.ds)
if iterable(figure_size):
self.figure_size = float(figure_size[0]), float(figure_size[1])
else:
self.figure_size = float(figure_size)
- self.plots = PlotDictionary(data_source)
- self._callbacks = []
- self._field_transform = {}
- self._colormaps = defaultdict(
- lambda: ytcfg.get("yt", "default_colormap"))
font_path = matplotlib.get_data_path() + '/fonts/ttf/STIXGeneral.ttf'
self._font_properties = FontProperties(size=fontsize, fname=font_path)
self._font_color = None
self._xlabel = None
self._ylabel = None
self._minorticks = {}
- self._cbar_minorticks = {}
- self._colorbar_label = PlotDictionary(
- self.data_source, lambda: None)
+ self._field_transform = {}
@invalidate_plot
def set_log(self, field, log, linthresh=None):
@@ -230,10 +229,10 @@
for field in self.data_source._determine_fields(fields):
if log:
if linthresh is not None:
- if not linthresh > 0.:
+ if not linthresh > 0.:
raise ValueError('\"linthresh\" must be positive')
self._field_transform[field] = symlog_transform
- self._field_transform[field].func = linthresh
+ self._field_transform[field].func = linthresh
else:
self._field_transform[field] = log_transform
else:
@@ -270,109 +269,6 @@
return self
@invalidate_plot
- def set_cmap(self, field, cmap):
- """set the colormap for one of the fields
-
- Parameters
- ----------
- field : string
- the field to set the colormap
- if field == 'all', applies to all plots.
- cmap : string or tuple
- If a string, will be interpreted as name of the colormap.
- If a tuple, it is assumed to be of the form (name, type, number)
- to be used for palettable functionality. (name, type, number, bool)
- can be used to specify if a reverse colormap is to be used.
-
- """
-
- if field == 'all':
- fields = list(self.plots.keys())
- else:
- fields = [field]
- for field in self.data_source._determine_fields(fields):
- self._colorbar_valid = False
- self._colormaps[field] = cmap
- return self
-
- @invalidate_plot
- def set_background_color(self, field, color=None):
- """set the background color to match provided color
-
- Parameters
- ----------
- field : string
- the field to set the colormap
- if field == 'all', applies to all plots.
- color : string or RGBA tuple (optional)
- if set, set the background color to this color
- if unset, background color is set to the bottom value of
- the color map
-
- """
- actual_field = self.data_source._determine_fields(field)[0]
- if color is None:
- cmap = self._colormaps[actual_field]
- if isinstance(cmap, string_types):
- try:
- cmap = yt_colormaps[cmap]
- except KeyError:
- cmap = getattr(matplotlib.cm, cmap)
- color = cmap(0)
- if LooseVersion(matplotlib.__version__) < LooseVersion("2.0.0"):
- self.plots[actual_field].axes.set_axis_bgcolor(color)
- else:
- self.plots[actual_field].axes.set_facecolor(color)
- return self
-
- @invalidate_plot
- def set_zlim(self, field, zmin, zmax, dynamic_range=None):
- """set the scale of the colormap
-
- Parameters
- ----------
- field : string
- the field to set a colormap scale
- if field == 'all', applies to all plots.
- zmin : float
- the new minimum of the colormap scale. If 'min', will
- set to the minimum value in the current view.
- zmax : float
- the new maximum of the colormap scale. If 'max', will
- set to the maximum value in the current view.
-
- Other Parameters
- ----------------
- dynamic_range : float (default: None)
- The dynamic range of the image.
- If zmin == None, will set zmin = zmax / dynamic_range
- If zmax == None, will set zmax = zmin * dynamic_range
- When dynamic_range is specified, defaults to setting
- zmin = zmax / dynamic_range.
-
- """
- if field is 'all':
- fields = list(self.plots.keys())
- else:
- fields = ensure_list(field)
- for field in self.data_source._determine_fields(fields):
- myzmin = zmin
- myzmax = zmax
- if zmin == 'min':
- myzmin = self.plots[field].image._A.min()
- if zmax == 'max':
- myzmax = self.plots[field].image._A.max()
- if dynamic_range is not None:
- if zmax is None:
- myzmax = myzmin * dynamic_range
- else:
- myzmin = myzmax / dynamic_range
-
- self.plots[field].zmin = myzmin
- self.plots[field].zmax = myzmax
- return self
-
- @invalidate_plot
def set_minorticks(self, field, state):
"""turn minor ticks on or off in the current plot
@@ -398,36 +294,16 @@
self._minorticks[field] = False
return self
- @invalidate_plot
- def set_cbar_minorticks(self, field, state):
- """turn colorbar minor ticks on or off in the current plot
-
- Displaying minor ticks reduces performance; turn them off
- using set_cbar_minorticks('all', 'off') if drawing speed is a problem.
-
- Parameters
- ----------
- field : string
- the field to remove colorbar minorticks
- state : string
- the state indicating 'on' or 'off'
-
- """
- if field == 'all':
- fields = list(self.plots.keys())
- else:
- fields = [field]
- for field in self.data_source._determine_fields(fields):
- if state == 'on':
- self._cbar_minorticks[field] = True
- else:
- self._cbar_minorticks[field] = False
- return self
-
def _setup_plots(self):
# Left blank to be overriden in subclasses
pass
+ def _initialize_dataset(self, ts):
+ if not isinstance(ts, DatasetSeries):
+ if not iterable(ts): ts = [ts]
+ ts = DatasetSeries(ts)
+ return ts
+
def _switch_ds(self, new_ds, data_source=None):
old_object = self.data_source
name = old_object._type_name
@@ -449,6 +325,8 @@
lim = getattr(self, lim_name)
lim = tuple(new_ds.quan(l.value, str(l.units)) for l in lim)
setattr(self, lim_name, lim)
+ self.plots.data_source = new_object
+ self._colorbar_label.data_source = new_object
self._setup_plots()
@validate_plot
@@ -471,7 +349,7 @@
----------
font_dict : dict
- A dict of keyword parameters to be passed to
+ A dict of keyword parameters to be passed to
:class:`matplotlib.font_manager.FontProperties`.
Possible keys include:
@@ -585,8 +463,11 @@
for k, v in iteritems(self.plots):
names.append(v.save(name, mpl_kwargs))
return names
- axis = self.ds.coordinates.axis_name.get(
- self.data_source.axis, '')
+ if hasattr(self.data_source, 'axis'):
+ axis = self.ds.coordinates.axis_name.get(
+ self.data_source.axis, '')
+ else:
+ axis = None
weight = None
type = self._plot_type
if type in ['Projection', 'OffAxisProjection']:
@@ -616,21 +497,6 @@
return self
@validate_plot
- def _send_zmq(self):
- from ._mpl_imports import FigureCanvasAgg
- try:
- # pre-IPython v1.0
- from IPython.zmq.pylab.backend_inline import send_figure as display
- except ImportError:
- # IPython v1.0+
- from IPython.core.display import display
- for k, v in sorted(iteritems(self.plots)):
- # Due to a quirk in the matplotlib API, we need to create
- # a dummy canvas variable here that is never used.
- canvas = FigureCanvasAgg(v.figure) # NOQA
- display(v.figure)
-
- @validate_plot
def show(self):
r"""This will send any existing plots to the IPython notebook.
@@ -657,6 +523,8 @@
if "__IPYTHON__" in dir(builtins):
from IPython.display import display
display(self)
+ else:
+ raise YTNotInsideNotebook
@validate_plot
def display(self, name=None, mpl_kwargs=None):
@@ -713,6 +581,211 @@
self._ylabel = label
return self
+ def _get_axes_unit_labels(self, unit_x, unit_y):
+ axes_unit_labels = ['', '']
+ comoving = False
+ hinv = False
+ for i, un in enumerate((unit_x, unit_y)):
+ unn = None
+ if hasattr(self.data_source, 'axis'):
+ if hasattr(self.ds.coordinates, "image_units"):
+ # This *forces* an override
+ unn = self.ds.coordinates.image_units[
+ self.data_source.axis][i]
+ elif hasattr(self.ds.coordinates, "default_unit_label"):
+ axax = getattr(self.ds.coordinates,
+ "%s_axis" % ("xy"[i]))[self.data_source.axis]
+ unn = self.ds.coordinates.default_unit_label.get(
+ axax, None)
+ if unn is not None:
+ axes_unit_labels[i] = r'\ \ \left('+unn+r'\right)'
+ continue
+ # Use sympy to factor h out of the unit. In this context 'un'
+ # is a string, so we call the Unit constructor.
+ expr = Unit(un, registry=self.ds.unit_registry).expr
+ h_expr = Unit('h', registry=self.ds.unit_registry).expr
+ # See http://docs.sympy.org/latest/modules/core.html#sympy.core.expr.Expr
+ h_power = expr.as_coeff_exponent(h_expr)[1]
+ # un is now the original unit, but with h factored out.
+ un = str(expr*h_expr**(-1*h_power))
+ un_unit = Unit(un, registry=self.ds.unit_registry)
+ cm = Unit('cm').expr
+ if str(un).endswith('cm') and cm not in un_unit.expr.atoms():
+ comoving = True
+ un = un[:-2]
+ # no length units besides code_length end in h so this is safe
+ if h_power == -1:
+ hinv = True
+ elif h_power != 0:
+ # It doesn't make sense to scale a position by anything
+ # other than h**-1
+ raise RuntimeError
+ if un not in ['1', 'u', 'unitary']:
+ if un in formatted_length_unit_names:
+ un = formatted_length_unit_names[un]
+ else:
+ un = Unit(un, registry=self.ds.unit_registry)
+ un = un.latex_representation()
+ if hinv:
+ un = un + '\,h^{-1}'
+ if comoving:
+ un = un + '\,(1+z)^{-1}'
+ pp = un[0]
+ if pp in latex_prefixes:
+ symbol_wo_prefix = un[1:]
+ if symbol_wo_prefix in prefixable_units:
+ un = un.replace(
+ pp, "{"+latex_prefixes[pp]+"}", 1)
+ axes_unit_labels[i] = '\ \ ('+un+')'
+ return axes_unit_labels
+
+
+class ImagePlotContainer(PlotContainer):
+ """A container for plots with colorbars.
+
+ """
+ _colorbar_valid = False
+
+ def __init__(self, data_source, figure_size, fontsize):
+ super(ImagePlotContainer, self).__init__(
+ data_source, figure_size, fontsize)
+ self.plots = PlotDictionary(data_source)
+ self._callbacks = []
+ self._colormaps = defaultdict(
+ lambda: ytcfg.get("yt", "default_colormap"))
+ self._cbar_minorticks = {}
+ self._colorbar_label = PlotDictionary(
+ self.data_source, lambda: None)
+
+ @invalidate_plot
+ def set_cmap(self, field, cmap):
+ """set the colormap for one of the fields
+
+ Parameters
+ ----------
+ field : string
+ the field to set the colormap
+ if field == 'all', applies to all plots.
+ cmap : string or tuple
+ If a string, will be interpreted as name of the colormap.
+ If a tuple, it is assumed to be of the form (name, type, number)
+ to be used for palettable functionality. (name, type, number, bool)
+ can be used to specify if a reverse colormap is to be used.
+
+ """
+
+ if field == 'all':
+ fields = list(self.plots.keys())
+ else:
+ fields = [field]
+ for field in self.data_source._determine_fields(fields):
+ self._colorbar_valid = False
+ self._colormaps[field] = cmap
+ return self
+
+ @invalidate_plot
+ def set_background_color(self, field, color=None):
+ """set the background color to match provided color
+
+ Parameters
+ ----------
+ field : string
+ the field to set the colormap
+ if field == 'all', applies to all plots.
+ color : string or RGBA tuple (optional)
+ if set, set the background color to this color
+ if unset, background color is set to the bottom value of
+ the color map
+
+ """
+ actual_field = self.data_source._determine_fields(field)[0]
+ if color is None:
+ cmap = self._colormaps[actual_field]
+ if isinstance(cmap, string_types):
+ try:
+ cmap = yt_colormaps[cmap]
+ except KeyError:
+ cmap = getattr(matplotlib.cm, cmap)
+ color = cmap(0)
+ if LooseVersion(matplotlib.__version__) < LooseVersion("2.0.0"):
+ self.plots[actual_field].axes.set_axis_bgcolor(color)
+ else:
+ self.plots[actual_field].axes.set_facecolor(color)
+ return self
+
+ @invalidate_plot
+ def set_zlim(self, field, zmin, zmax, dynamic_range=None):
+ """set the scale of the colormap
+
+ Parameters
+ ----------
+ field : string
+ the field to set a colormap scale
+ if field == 'all', applies to all plots.
+ zmin : float
+ the new minimum of the colormap scale. If 'min', will
+ set to the minimum value in the current view.
+ zmax : float
+ the new maximum of the colormap scale. If 'max', will
+ set to the maximum value in the current view.
+
+ Other Parameters
+ ----------------
+ dynamic_range : float (default: None)
+ The dynamic range of the image.
+ If zmin == None, will set zmin = zmax / dynamic_range
+ If zmax == None, will set zmax = zmin * dynamic_range
+ When dynamic_range is specified, defaults to setting
+ zmin = zmax / dynamic_range.
+
+ """
+ if field is 'all':
+ fields = list(self.plots.keys())
+ else:
+ fields = ensure_list(field)
+ for field in self.data_source._determine_fields(fields):
+ myzmin = zmin
+ myzmax = zmax
+ if zmin == 'min':
+ myzmin = self.plots[field].image._A.min()
+ if zmax == 'max':
+ myzmax = self.plots[field].image._A.max()
+ if dynamic_range is not None:
+ if zmax is None:
+ myzmax = myzmin * dynamic_range
+ else:
+ myzmin = myzmax / dynamic_range
+
+ self.plots[field].zmin = myzmin
+ self.plots[field].zmax = myzmax
+ return self
+
+ @invalidate_plot
+ def set_cbar_minorticks(self, field, state):
+ """turn colorbar minor ticks on or off in the current plot
+
+ Displaying minor ticks reduces performance; turn them off
+ using set_cbar_minorticks('all', 'off') if drawing speed is a problem.
+
+ Parameters
+ ----------
+ field : string
+ the field to remove colorbar minorticks
+ state : string
+ the state indicating 'on' or 'off'
+
+ """
+ if field == 'all':
+ fields = list(self.plots.keys())
+ else:
+ fields = [field]
+ for field in self.data_source._determine_fields(fields):
+ if state == 'on':
+ self._cbar_minorticks[field] = True
+ else:
+ self._cbar_minorticks[field] = False
+ return self
+
@invalidate_plot
def set_colorbar_label(self, field, label):
r"""
diff -r d7bc05ca16057f120acd5d043f90b6a8a32a2de5 -r 41f22e5d10cbe6cd5a029b315a774d78513e43b1 yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -36,8 +36,6 @@
invalidate_data, invalidate_plot, apply_callback
from .base_plot_types import CallbackWrapper
-from yt.data_objects.time_series import \
- DatasetSeries
from yt.data_objects.image_array import \
ImageArray
from yt.extern.six import string_types
@@ -50,23 +48,19 @@
Unit
from yt.units.unit_registry import \
UnitParseError
-from yt.units.unit_lookup_table import \
- prefixable_units, latex_prefixes
from yt.units.yt_array import \
YTArray, YTQuantity
-from yt.utilities.definitions import \
- formatted_length_unit_names
from yt.utilities.math_utils import \
ortho_find
from yt.utilities.orientation import \
Orientation
from yt.utilities.exceptions import \
- YTUnitNotRecognized, \
YTCannotParseUnitDisplayName, \
- YTUnitConversionError, \
YTPlotCallbackError, \
YTDataTypeUnsupported, \
- YTInvalidFieldType
+ YTInvalidFieldType, \
+ YTUnitNotRecognized, \
+ YTUnitConversionError
MPL_VERSION = LooseVersion(matplotlib.__version__)
@@ -179,11 +173,6 @@
periodic=True, origin='center-window', oblique=False, right_handed=True,
window_size=8.0, fields=None, fontsize=18, aspect=None,
setup=False):
- if not hasattr(self, "ds"):
- self.ds = data_source.ds
- ts = self._initialize_dataset(self.ds)
- self.ts = ts
- self._axes_unit_names = None
self.center = None
self._periodic = periodic
self.oblique = oblique
@@ -191,6 +180,7 @@
self._equivalencies = defaultdict(lambda: (None, {}))
self.buff_size = buff_size
self.antialias = antialias
+ self._axes_unit_names = None
self.aspect = aspect
skip = list(FixedResolutionBuffer._exclude_fields) + data_source._key_fields
@@ -220,12 +210,6 @@
self.setup_callbacks()
self._setup_plots()
- def _initialize_dataset(self, ts):
- if not isinstance(ts, DatasetSeries):
- if not iterable(ts): ts = [ts]
- ts = DatasetSeries(ts)
- return ts
-
def __iter__(self):
for ds in self.ts:
mylog.warning("Switching to %s", ds)
@@ -856,59 +840,7 @@
ax = self.plots[f].axes
ax.invert_xaxis()
- axes_unit_labels = ['', '']
- comoving = False
- hinv = False
- for i, un in enumerate((unit_x, unit_y)):
- unn = None
- if hasattr(self.ds.coordinates, "image_units"):
- # This *forces* an override
- unn = self.ds.coordinates.image_units[axis_index][i]
- elif hasattr(self.ds.coordinates, "default_unit_label"):
- axax = getattr(self.ds.coordinates,
- "%s_axis" % ("xy"[i]))[axis_index]
- unn = self.ds.coordinates.default_unit_label.get(axax,
- None)
- if unn is not None:
- axes_unit_labels[i] = r'\ \ \left('+unn+r'\right)'
- continue
- # Use sympy to factor h out of the unit. In this context 'un'
- # is a string, so we call the Unit constructor.
- expr = Unit(un, registry=self.ds.unit_registry).expr
- h_expr = Unit('h', registry=self.ds.unit_registry).expr
- # See http://docs.sympy.org/latest/modules/core.html#sympy.core.expr.Expr
- h_power = expr.as_coeff_exponent(h_expr)[1]
- # un is now the original unit, but with h factored out.
- un = str(expr*h_expr**(-1*h_power))
- un_unit = Unit(un, registry=self.ds.unit_registry)
- cm = Unit('cm').expr
- if str(un).endswith('cm') and cm not in un_unit.expr.atoms():
- comoving = True
- un = un[:-2]
- # no length units besides code_length end in h so this is safe
- if h_power == -1:
- hinv = True
- elif h_power != 0:
- # It doesn't make sense to scale a position by anything
- # other than h**-1
- raise RuntimeError
- if un not in ['1', 'u', 'unitary']:
- if un in formatted_length_unit_names:
- un = formatted_length_unit_names[un]
- else:
- un = Unit(un, registry=self.ds.unit_registry)
- un = un.latex_representation()
- if hinv:
- un = un + '\,h^{-1}'
- if comoving:
- un = un + '\,(1+z)^{-1}'
- pp = un[0]
- if pp in latex_prefixes:
- symbol_wo_prefix = un[1:]
- if symbol_wo_prefix in prefixable_units:
- un = un.replace(
- pp, "{"+latex_prefixes[pp]+"}", 1)
- axes_unit_labels[i] = '\ \ ('+un+')'
+ axes_unit_labels = self._get_axes_unit_labels(unit_x, unit_y)
if self.oblique:
labels = [r'$\rm{Image\ x'+axes_unit_labels[0]+'}$',
@@ -1036,7 +968,7 @@
@invalidate_plot
def annotate_clear(self, index=None):
"""
- Clear callbacks from the plot. If index is not set, clear all
+ Clear callbacks from the plot. If index is not set, clear all
callbacks. If index is set, clear that index (ie 0 is the first one
created, 1 is the 2nd one created, -1 is the last one created, etc.)
"""
@@ -1051,7 +983,7 @@
for f in self.fields:
keys = self.frb.keys()
for name, (args, kwargs) in self._callbacks:
- cbw = CallbackWrapper(self, self.plots[f], self.frb, f,
+ cbw = CallbackWrapper(self, self.plots[f], self.frb, f,
self._font_properties, self._font_color)
CallbackMaker = callback_registry[name]
callback = CallbackMaker(*args[1:], **kwargs)
@@ -1069,8 +1001,8 @@
def hide_colorbar(self, field=None):
"""
- Hides the colorbar for a plot and updates the size of the
- plot accordingly. Defaults to operating on all fields for a
+ Hides the colorbar for a plot and updates the size of the
+ plot accordingly. Defaults to operating on all fields for a
PlotWindow object.
Parameters
@@ -1110,8 +1042,8 @@
def show_colorbar(self, field=None):
"""
- Shows the colorbar for a plot and updates the size of the
- plot accordingly. Defaults to operating on all fields for a
+ Shows the colorbar for a plot and updates the size of the
+ plot accordingly. Defaults to operating on all fields for a
PlotWindow object. See hide_colorbar().
Parameters
@@ -1129,8 +1061,8 @@
def hide_axes(self, field=None):
"""
- Hides the axes for a plot and updates the size of the
- plot accordingly. Defaults to operating on all fields for a
+ Hides the axes for a plot and updates the size of the
+ plot accordingly. Defaults to operating on all fields for a
PlotWindow object.
Parameters
@@ -1168,8 +1100,8 @@
def show_axes(self, field=None):
"""
- Shows the axes for a plot and updates the size of the
- plot accordingly. Defaults to operating on all fields for a
+ Shows the axes for a plot and updates the size of the
+ plot accordingly. Defaults to operating on all fields for a
PlotWindow object. See hide_axes().
Parameters
@@ -1283,7 +1215,7 @@
A dictionary of field parameters than can be accessed by derived
fields.
data_source: YTSelectionContainer object
- Object to be used for data selection. Defaults to ds.all_data(), a
+ Object to be used for data selection. Defaults to ds.all_data(), a
region covering the full domain
Examples
@@ -1304,9 +1236,6 @@
origin='center-window', right_handed=True, fontsize=18, field_parameters=None,
window_size=8.0, aspect=None, data_source=None):
# this will handle time series data and controllers
- ts = self._initialize_dataset(ds)
- self.ts = ts
- ds = self.ds = ts[0]
axis = fix_axis(axis, ds)
(bounds, center, display_center) = \
get_window_parameters(axis, center, width, ds)
@@ -1438,7 +1367,7 @@
fontsize : integer
The size of the fonts for the axis, colorbar, and tick labels.
method : string
- The method of projection. Valid methods are:
+ The method of projection. Valid methods are:
"integrate" with no weight_field specified : integrate the requested
field along the line of sight.
@@ -1464,7 +1393,7 @@
A dictionary of field parameters than can be accessed by derived
fields.
data_source: YTSelectionContainer object
- Object to be used for data selection. Defaults to ds.all_data(), a
+ Object to be used for data selection. Defaults to ds.all_data(), a
region covering the full domain
Examples
@@ -1486,11 +1415,8 @@
right_handed=True, fontsize=18, field_parameters=None, data_source=None,
method = "integrate", proj_style = None, window_size=8.0,
aspect=None):
- ts = self._initialize_dataset(ds)
- self.ts = ts
- ds = self.ds = ts[0]
axis = fix_axis(axis, ds)
- # proj_style is deprecated, but if someone specifies then it trumps
+ # proj_style is deprecated, but if someone specifies then it trumps
# method.
if proj_style is not None:
method = proj_style
@@ -1519,7 +1445,7 @@
field_parameters=field_parameters, method=method,
max_level=max_level)
PWViewerMPL.__init__(self, proj, bounds, fields=fields, origin=origin,
- right_handed=right_handed, fontsize=fontsize, window_size=window_size,
+ right_handed=right_handed, fontsize=fontsize, window_size=window_size,
aspect=aspect)
if axes_unit is None:
axes_unit = get_axes_unit(width, ds)
@@ -1593,7 +1519,7 @@
A dictionary of field parameters than can be accessed by derived
fields.
data_source : YTSelectionContainer Object
- Object to be used for data selection. Defaults ds.all_data(), a
+ Object to be used for data selection. Defaults ds.all_data(), a
region covering the full domain.
"""
@@ -1748,7 +1674,7 @@
This should only be used for uniform resolution grid datasets, as other
datasets may result in unphysical images.
data_source: YTSelectionContainer object
- Object to be used for data selection. Defaults to ds.all_data(), a
+ Object to be used for data selection. Defaults to ds.all_data(), a
region covering the full domain
"""
_plot_type = 'OffAxisProjection'
diff -r d7bc05ca16057f120acd5d043f90b6a8a32a2de5 -r 41f22e5d10cbe6cd5a029b315a774d78513e43b1 yt/visualization/profile_plotter.py
--- a/yt/visualization/profile_plotter.py
+++ b/yt/visualization/profile_plotter.py
@@ -41,7 +41,8 @@
from yt.funcs import \
ensure_list, \
get_image_suffix, \
- matplotlib_style_context
+ matplotlib_style_context, \
+ iterable
def get_canvas(name):
from . import _mpl_imports as mpl
@@ -60,7 +61,7 @@
canvas_cls = mpl.FigureCanvasAgg
return canvas_cls
-class PlotContainer(OrderedDict):
+class PlotContainerDict(OrderedDict):
def __missing__(self, key):
plot = PlotMPL((10, 8), [0.1, 0.1, 0.8, 0.8], None, None)
self[key] = plot
@@ -378,7 +379,7 @@
if plot_specs is None:
plot_specs = [dict() for p in obj.profiles]
obj.plot_spec = plot_specs
- obj.plots = PlotContainer()
+ obj.plots = PlotContainerDict()
obj.figures = FigureContainer(obj.plots)
obj.axes = AxesContainer(obj.plots)
obj._setup_plots()
@@ -1370,7 +1371,10 @@
if fontscale < 1.0:
fontscale = np.sqrt(fontscale)
- self._cb_size = 0.0375*figure_size
+ if iterable(figure_size):
+ self._cb_size = 0.0375*figure_size[0]
+ else:
+ self._cb_size = 0.0375*figure_size
self._ax_text_size = [1.1*fontscale, 0.9*fontscale]
self._top_buff_size = 0.30*fontscale
self._aspect = 1.0
diff -r d7bc05ca16057f120acd5d043f90b6a8a32a2de5 -r 41f22e5d10cbe6cd5a029b315a774d78513e43b1 yt/visualization/tests/test_line_plots.py
--- /dev/null
+++ b/yt/visualization/tests/test_line_plots.py
@@ -0,0 +1,63 @@
+"""
+Tests for making line plots
+
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (c) 2017, yt Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+import yt
+from yt.utilities.answer_testing.framework import \
+ requires_ds, \
+ data_dir_load, \
+ GenericImageTest
+from yt.testing import fake_random_ds
+import os
+import tempfile
+import shutil
+
+def setup():
+ """Test specific setup."""
+ from yt.config import ytcfg
+ ytcfg["yt", "__withintesting"] = "True"
+
+def compare(ds, fields, point1, point2, resolution, test_prefix, decimals=12):
+ def line_plot(filename_prefix):
+ ln = yt.LinePlot(ds, fields, point1, point2, resolution)
+ image_file = ln.save(filename_prefix)
+ return image_file
+
+ line_plot.__name__ = "line_{}".format(test_prefix)
+ test = GenericImageTest(ds, line_plot, decimals)
+ test.prefix = test_prefix
+ return test
+
+tri2 = "SecondOrderTris/RZ_p_no_parts_do_nothing_bcs_cone_out.e"
+
+ at requires_ds(tri2)
+def test_line_plot():
+ ds = data_dir_load(tri2, kwargs={'step':-1})
+ fields = [field for field in ds.field_list if field[0] == 'all']
+ yield compare(ds, fields, (0, 0, 0), (1, 1, 0), 1000, "answers_line_plot")
+
+def test_line_plot_methods():
+ # Perform I/O in safe place instead of yt main dir
+ tmpdir = tempfile.mkdtemp()
+ curdir = os.getcwd()
+ os.chdir(tmpdir)
+
+ ds = fake_random_ds(32)
+
+ plot = yt.LinePlot(ds, 'density', [0, 0, 0], [1, 1, 1], 512)
+ plot.add_legend('density')
+ plot.set_x_unit('cm')
+ plot.set_unit('density', 'kg/cm**3')
+ plot.save()
+
+ os.chdir(curdir)
+ # clean up
+ shutil.rmtree(tmpdir)
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