[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