[yt-svn] commit/yt: jzuhone: Merged in ngoldbaum/yt (pull request #2172)
commits-noreply at bitbucket.org
commits-noreply at bitbucket.org
Thu May 26 09:19:21 PDT 2016
1 new commit in yt:
https://bitbucket.org/yt_analysis/yt/commits/f609b1cbd8dd/
Changeset: f609b1cbd8dd
Branch: yt
User: jzuhone
Date: 2016-05-26 16:19:07+00:00
Summary: Merged in ngoldbaum/yt (pull request #2172)
[New Feature] Make it possible to use DerivedField instances to access data
Affected #: 5 files
diff -r 19d0848c5d8f453d3b5e9c0996d43f805517be9f -r f609b1cbd8dd18374c28cbd7511641b64438cd94 doc/source/analyzing/fields.rst
--- a/doc/source/analyzing/fields.rst
+++ b/doc/source/analyzing/fields.rst
@@ -14,14 +14,117 @@
out of favor, as these discrete fields can be any type of sparsely populated
data.
+What are fields?
+----------------
+
+Fields in yt are denoted by a two-element tuple, of the form ``(field_type,
+field_name)``. The first element, the "field type" is a category for a
+field. Possible field types used in yt include *gas* (for fluid mesh fields
+defined on a mesh) or *io* (for fields defined at particle locations). Field
+types can also correspond to distinct particle of fluid types in a single
+simulation. For example, a plasma physics simulation using the Particle in Cell
+method might have particle types corresponding to *electrons* and *ions*. See
+:ref:`known-field-types` below for more info about field types in yt.
+
+The second element of field tuples, the "field name", denotes the specific field
+to select, given the field type. Possible field names include *density*,
+*velocity_x* or *pressure* --- these three fields are examples of field names
+that might be used for a fluid defined on a mesh. Examples of particle fields
+include *particle_mass*, *particle_position*, or *particle_velocity_x*. In
+general, particle field names are prefixed by "particle\_", which makes it easy
+to distinguish between a particle field or a mesh field when no field type is
+provided.
+
+What fields are available?
+--------------------------
+
+We provide a full list of fields that yt recognizes by default at
+:ref:`field-list`. If you want to create additional custom derived fields,
+see :ref:`creating-derived-fields`.
+
+Every dataset has an attribute, ``ds.fields``. This attribute possesses
+attributes itself, each of which is a "field type," and each field type has as
+its attributes the fields themselves. When one of these is printed, it returns
+information about the field and things like units and so on. You can use this
+for tab-completing as well as easier access to information.
+
+As an example, you might browse the available fields like so:
+
+.. code-block:: python
+
+ print(dir(ds.fields))
+ print(dir(ds.fields.gas))
+ print(ds.fields.gas.density)
+
+On an Enzo dataset, the result from the final command would look something like
+this:::
+
+ Alias Field for "('enzo', 'Density')" (gas, density): (units: g/cm**3)
+
+You can use this to easily explore available fields, particularly through
+tab-completion in Jupyter/IPython.
+
+For a more programmatic method of accessing fields, you can utilize the
+``ds.field_list``, ``ds.derived_field_list`` and some accessor methods to gain
+information about fields. The full list of fields available for a dataset can
+be found as the attribute ``field_list`` for native, on-disk fields and
+``derived_field_list`` for derived fields (``derived_field_list`` is a superset
+of ``field_list``). You can view these lists by examining a dataset like this:
+
+.. code-block:: python
+
+ ds = yt.load("my_data")
+ print(ds.field_list)
+ print(ds.derived_field_list)
+
+By using the ``field_info()`` class, one can access information about a given
+field, like its default units or the source code for it.
+
+.. code-block:: python
+
+ ds = yt.load("my_data")
+ ds.index
+ print(ds.field_info["gas", "pressure"].get_units())
+ print(ds.field_info["gas", "pressure"].get_source())
+
+Using fields to access data
+---------------------------
+
+The primary *use* of fields in yt is to access data from a dataset. For example,
+if I want to use a data object (see :ref:`Data-objects` for more detail about
+data objects) to access the ``('gas', 'density')`` field, one can do any of the
+following:
+
+.. code-block:: python
+
+ ad = ds.all_data()
+ density = ad['density']
+ density = ad['gas', 'density']
+ density = ad[('gas', 'density')]
+ dnesity = ad[ds.fields.gas.density]
+
+The first data access example is the simplest. In that example, the field type
+is inferred from the name of the field. The next two examples use the field type
+explicitly, this might be necessary if there is more than one field type with a
+"density" field defined in the same simulation. The third example is a slightly
+more verbose and is syntactically identical to the second example due to the way
+indexing functions in Python. The final example uses the ``ds.fields` object
+described above. This way of accessing fields lends itself to interactive use,
+especially if you make heavy use of IPython's tab completion features. Any of
+these ways of denoting the ``('gas', 'density')`` field can be used when
+supplying a field name to a yt data object, analysis routines, or plotting and
+visualization function.
+
+Accessing Fields without a Field Type
+-------------------------------------
+
In previous versions of yt, there was a single mechanism of accessing fields on
-a data container -- by their name, which was mandated to be a single string,
-and which often varied between different code frontends. yt 3.0 allows
-for datasets containing multiple different types of fluid fields, mesh fields,
-particles (with overlapping or disjoint lists of fields). To enable accessing
-these fields in a meaningful, simple way, the mechanism for accessing them has
-changed to take an optional *field type* in addition to the *field name* of
-the form ('*field type*', '*field name*').
+a data container -- by their name, which was mandated to be a single string, and
+which often varied between different code frontends. yt 3.0 allows for datasets
+containing multiple different types of fluid fields, mesh fields, particles
+(with overlapping or disjoint lists of fields). However, to preserve backward
+compatibility and make interactive use simpler, yt will still accept field names
+given as a string and will try to infer the field type given a field name.
As an example, we may be in a situation where have multiple types of particles
which possess the ``particle_position`` field. In the case where a data
@@ -30,9 +133,9 @@
.. code-block:: python
- print(ad["humans", "particle_position"])
- print(ad["dogs", "particle_position"])
- print(ad["dinosaurs", "particle_position"])
+ print(ad["dark_matter", "particle_position"])
+ print(ad["stars", "particle_position"])
+ print(ad["black_holes", "particle_position"])
Each of these three fields may have different sizes. In order to enable
falling back on asking only for a field by the name, yt will use the most
@@ -45,7 +148,8 @@
print(ad["particle_velocity"])
-it would select ``dinosaurs`` as the field type.
+it would select ``black_holes`` as the field type, since the last field accessed
+used that field type.
The same operations work for fluid and mesh fields. As an example, in some
cosmology simulations, we may want to examine the mass of particles in a region
@@ -189,58 +293,6 @@
* Species fields, such as for chemistry species (yt can recognize the entire
periodic table in field names and construct ionization fields as need be)
-What fields are available?
---------------------------
-
-We provide a full list of fields that yt recognizes by default at
-:ref:`field-list`. If you want to create additional custom derived fields,
-see :ref:`creating-derived-fields`.
-
-Every dataset has an attribute, ``ds.fields``. This attribute possesses
-attributes itself, each of which is a "field type," and each field type has as
-its attributes the fields themselves. When one of these is printed, it returns
-information about the field and things like units and so on. You can use this
-for tab-completing as well as easier access to information.
-
-As an example, you might browse the available fields like so:
-
-.. code-block:: python
-
- print(dir(ds.fields))
- print(dir(ds.fields.gas))
- print(ds.fields.gas.density)
-
-On an Enzo dataset, the result from the final command would look something like
-this:::
-
- Alias Field for "('enzo', 'Density')" (gas, density): (units: g/cm**3)
-
-You can use this to easily explore available fields, particularly through
-tab-completion in Jupyter/IPython.
-
-For a more programmatic method of accessing fields, you can utilize the
-``ds.field_list``, ``ds.derived_field_list`` and some accessor methods to gain
-information about fields. The full list of fields available for a dataset can
-be found as the attribute ``field_list`` for native, on-disk fields and
-``derived_field_list`` for derived fields (``derived_field_list`` is a superset
-of ``field_list``). You can view these lists by examining a dataset like this:
-
-.. code-block:: python
-
- ds = yt.load("my_data")
- print(ds.field_list)
- print(ds.derived_field_list)
-
-By using the ``field_info()`` class, one can access information about a given
-field, like its default units or the source code for it.
-
-.. code-block:: python
-
- ds = yt.load("my_data")
- ds.index
- print(ds.field_info["gas", "pressure"].get_units())
- print(ds.field_info["gas", "pressure"].get_source())
-
.. _bfields:
Magnetic Fields
diff -r 19d0848c5d8f453d3b5e9c0996d43f805517be9f -r f609b1cbd8dd18374c28cbd7511641b64438cd94 yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -24,6 +24,8 @@
from contextlib import contextmanager
from yt.data_objects.particle_io import particle_handler_registry
+from yt.fields.derived_field import \
+ DerivedField
from yt.frontends.ytdata.utilities import \
save_as_dataset
from yt.funcs import \
@@ -983,6 +985,9 @@
raise YTFieldNotParseable(field)
ftype, fname = field
finfo = self.ds._get_field_info(ftype, fname)
+ elif isinstance(field, DerivedField):
+ ftype, fname = field.name
+ finfo = field
else:
fname = field
finfo = self.ds._get_field_info("unknown", fname)
diff -r 19d0848c5d8f453d3b5e9c0996d43f805517be9f -r f609b1cbd8dd18374c28cbd7511641b64438cd94 yt/data_objects/profiles.py
--- a/yt/data_objects/profiles.py
+++ b/yt/data_objects/profiles.py
@@ -15,6 +15,7 @@
import numpy as np
+from yt.fields.derived_field import DerivedField
from yt.frontends.ytdata.utilities import \
save_as_dataset
from yt.funcs import \
@@ -249,8 +250,11 @@
def __getitem__(self, field):
fname = self.field_map.get(field, None)
- if fname is None and isinstance(field, tuple):
- fname = self.field_map.get(field[1], None)
+ if fname is None:
+ if isinstance(field, tuple):
+ fname = self.field_map.get(field[1], None)
+ elif isinstance(field, DerivedField):
+ fname = self.field_map.get(field.name[1], None)
if fname is None:
raise KeyError(field)
else:
diff -r 19d0848c5d8f453d3b5e9c0996d43f805517be9f -r f609b1cbd8dd18374c28cbd7511641b64438cd94 yt/data_objects/static_output.py
--- a/yt/data_objects/static_output.py
+++ b/yt/data_objects/static_output.py
@@ -24,6 +24,8 @@
from yt.extern.six import add_metaclass, string_types
from yt.config import ytcfg
+from yt.fields.derived_field import \
+ DerivedField
from yt.funcs import \
mylog, \
set_intersection, \
@@ -590,7 +592,10 @@
def _get_field_info(self, ftype, fname = None):
self.index
if fname is None:
- ftype, fname = "unknown", ftype
+ if isinstance(ftype, DerivedField):
+ ftype, fname = ftype.name
+ else:
+ ftype, fname = "unknown", ftype
guessing_type = False
if ftype == "unknown":
guessing_type = True
diff -r 19d0848c5d8f453d3b5e9c0996d43f805517be9f -r f609b1cbd8dd18374c28cbd7511641b64438cd94 yt/fields/tests/test_field_access.py
--- /dev/null
+++ b/yt/fields/tests/test_field_access.py
@@ -0,0 +1,40 @@
+from yt.testing import fake_random_ds, assert_equal
+from yt.data_objects.profiles import create_profile
+from yt.visualization.plot_window import \
+ SlicePlot, \
+ ProjectionPlot, \
+ OffAxisProjectionPlot
+from yt.visualization.profile_plotter import \
+ ProfilePlot, \
+ PhasePlot
+
+def test_field_access():
+ ds = fake_random_ds(16)
+
+ ad = ds.all_data()
+ sp = ds.sphere(ds.domain_center, 0.25)
+ cg = ds.covering_grid(0, ds.domain_left_edge, ds.domain_dimensions)
+ scg = ds.smoothed_covering_grid(0, ds.domain_left_edge, ds.domain_dimensions)
+ sl = ds.slice(0, ds.domain_center[0])
+ proj = ds.proj('density', 0)
+ prof = create_profile(ad, 'radius', 'density')
+
+ for data_object in [ad, sp, cg, scg, sl, proj, prof]:
+ assert_equal(
+ data_object['gas', 'density'],
+ data_object[ds.fields.gas.density]
+ )
+
+ for field in [('gas', 'density'), ds.fields.gas.density]:
+ ad = ds.all_data()
+ prof = ProfilePlot(ad, 'radius', field)
+ phase = PhasePlot(ad, 'radius', field, 'cell_mass')
+ s = SlicePlot(ds, 2, field)
+ oas = SlicePlot(ds, [1, 1, 1], field)
+ p = ProjectionPlot(ds, 2, field)
+ oap = OffAxisProjectionPlot(ds, [1, 1, 1], field)
+
+ for plot_object in [s, oas, p, oap, prof, phase]:
+ plot_object._setup_plots()
+ if hasattr(plot_object, '_frb'):
+ plot_object._frb[field]
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