[yt-svn] commit/yt: 11 new changesets

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Mon Dec 7 18:57:41 PST 2015


11 new commits in yt:

https://bitbucket.org/yt_analysis/yt/commits/370e4a426d8b/
Changeset:   370e4a426d8b
Branch:      yt
User:        MatthewTurk
Date:        2015-11-24 01:15:46+00:00
Summary:     Adding max/min location tests
Affected #:  1 file

diff -r 129722a2fc4cfca129377785af88e615c4aec7a1 -r 370e4a426d8b4207121925f24768f2c39d676749 yt/data_objects/tests/test_derived_quantities.py
--- a/yt/data_objects/tests/test_derived_quantities.py
+++ b/yt/data_objects/tests/test_derived_quantities.py
@@ -55,6 +55,36 @@
                         ad["cell_mass"].sum())
         yield assert_rel_equal, my_std, a_std, 12
 
+def test_max_location():
+    for nprocs in [1, 2, 4, 8]:
+        ds = fake_random_ds(16, nprocs = nprocs, fields = ("density", ))
+        ad = ds.all_data()
+
+        mv, ind, x, y, z = ad.quantities.max_location(("gas", "density"))
+
+        yield assert_equal, mv, ad["density"].max()
+
+        mi = np.argmax(ad["density"])
+
+        yield assert_equal, ad["x"][mi], x
+        yield assert_equal, ad["y"][mi], y
+        yield assert_equal, ad["z"][mi], z
+
+def test_min_location():
+    for nprocs in [1, 2, 4, 8]:
+        ds = fake_random_ds(16, nprocs = nprocs, fields = ("density", ))
+        ad = ds.all_data()
+
+        mv, ind, x, y, z = ad.quantities.min_location(("gas", "density"))
+
+        yield assert_equal, mv, ad["density"].min()
+
+        mi = np.argmin(ad["density"])
+
+        yield assert_equal, ad["x"][mi], x
+        yield assert_equal, ad["y"][mi], y
+        yield assert_equal, ad["z"][mi], z
+
 if __name__ == "__main__":
     for i in test_extrema():
         i[0](*i[1:])


https://bitbucket.org/yt_analysis/yt/commits/d81b240c1687/
Changeset:   d81b240c1687
Branch:      yt
User:        MatthewTurk
Date:        2015-11-24 01:36:43+00:00
Summary:     Refactor max location and add tests.
Affected #:  2 files

diff -r 370e4a426d8b4207121925f24768f2c39d676749 -r d81b240c1687e93f497778bf7783f08adb02f83c yt/data_objects/derived_quantities.py
--- a/yt/data_objects/derived_quantities.py
+++ b/yt/data_objects/derived_quantities.py
@@ -522,11 +522,63 @@
         return [self.data_source.ds.arr([mis.min(), mas.max()])
                 for mis, mas in zip(values[::2], values[1::2])]
 
-class MaxLocation(DerivedQuantity):
+class MaxLocationFieldValue(DerivedQuantity):
+    r"""
+    Calculates the maximum value plus the index and returns whichever fields
+    are asked to be sampled.
+
+    The index is not necessarily relevant, and should not be relied upon.
+
+    Parameters
+    ----------
+    field : field
+        The field over which the extrema are to be calculated.
+    sample_fields : list of fields
+        The fields to sample and return at the minimum value.
+
+    Examples
+    --------
+
+    >>> ds = load("IsolatedGalaxy/galaxy0030/galaxy0030")
+    >>> ad = ds.all_data()
+    >>> print ad.quantities.max_location_field_value(("gas", "density"),
+    ...         ["temperature", "velocity_magnitude"])
+
+    """
+    def count_values(self, field, sample_fields):
+        # field itself, then index, then the number of sample fields
+        self.num_vals = 2 + len(sample_fields)
+
+    def __call__(self, field, sample_fields):
+        rv = super(MaxLocationFieldValue, self).__call__(field, sample_fields)
+        if len(rv) == 1: rv = rv[0]
+        return rv
+
+    def process_chunk(self, data, field, sample_fields):
+        field = data._determine_fields(field)[0]
+        ma = array_like_field(data, -HUGE, field)
+        vals = [array_like_field(data, -1, sf) for sf in sample_fields]
+        maxi = -1
+        if data[field].size > 0:
+            maxi = self._func(data[field])
+            ma = data[field][maxi]
+            vals = [data[sf][maxi] for sf in sample_fields]
+        return (ma, maxi) + tuple(vals)
+
+    def reduce_intermediate(self, values):
+        i = self._func(values[0]) # ma is values[0]
+        return [val[i] for val in values]
+
+    def _func(self, arr):
+        return np.argmax(arr)
+
+class MaxLocation(MaxLocationFieldValue):
     r"""
     Calculates the maximum value plus the index, x, y, and z position
     of the maximum.
 
+    The index is not necessarily relevant, and should not be relied upon.
+
     Parameters
     ----------
     field : field
@@ -540,37 +592,45 @@
     >>> print ad.quantities.max_location(("gas", "density"))
 
     """
-    def count_values(self, *args, **kwargs):
-        self.num_vals = 5
-
     def __call__(self, field):
-        rv = super(MaxLocation, self).__call__(field)
+        sample_fields = get_position_fields(field, self.data_source)
+        rv = super(MaxLocation, self).__call__(field, sample_fields)
         if len(rv) == 1: rv = rv[0]
         return rv
 
-    def process_chunk(self, data, field):
-        field = data._determine_fields(field)[0]
-        ma = array_like_field(data, -HUGE, field)
-        position_fields = get_position_fields(field, data)
-        mx = array_like_field(data, -1, position_fields[0])
-        my = array_like_field(data, -1, position_fields[1])
-        mz = array_like_field(data, -1, position_fields[2])
-        maxi = -1
-        if data[field].size > 0:
-            maxi = np.argmax(data[field])
-            ma = data[field][maxi]
-            mx, my, mz = [data[ax][maxi] for ax in position_fields]
-        return (ma, maxi, mx, my, mz)
+class MinLocationFieldValue(MaxLocationFieldValue):
+    r"""
+    Calculates the minimum value plus the index and returns whichever fields
+    are asked to be sampled.
 
-    def reduce_intermediate(self, values):
-        i = np.argmax(values[0]) # ma is values[0]
-        return [val[i] for val in values]
+    The index is not necessarily relevant, and should not be relied upon.
 
-class MinLocation(DerivedQuantity):
+    Parameters
+    ----------
+    field : field
+        The field over which the extrema are to be calculated.
+    sample_fields : list of fields
+        The fields to sample and return at the minimum value.
+
+    Examples
+    --------
+
+    >>> ds = load("IsolatedGalaxy/galaxy0030/galaxy0030")
+    >>> ad = ds.all_data()
+    >>> print ad.quantities.min_location_field_value(("gas", "density"),
+    ...         ["temperature", "velocity_magnitude"])
+
+    """
+    def _func(self, arr):
+        return np.argmin(arr)
+
+class MinLocation(MinLocationFieldValue):
     r"""
     Calculates the minimum value plus the index, x, y, and z position
     of the minimum.
 
+    The index is not necessarily relevant, and should not be relied upon.
+
     Parameters
     ----------
     field : field
@@ -584,32 +644,12 @@
     >>> print ad.quantities.min_location(("gas", "density"))
 
     """
-    def count_values(self, *args, **kwargs):
-        self.num_vals = 5
-
     def __call__(self, field):
-        rv = super(MinLocation, self).__call__(field)
+        sample_fields = get_position_fields(field, self.data_source)
+        rv = super(MinLocation, self).__call__(field, sample_fields)
         if len(rv) == 1: rv = rv[0]
         return rv
 
-    def process_chunk(self, data, field):
-        field = data._determine_fields(field)[0]
-        ma = array_like_field(data, HUGE, field)
-        position_fields = get_position_fields(field, data)
-        mx = array_like_field(data, -1, position_fields[0])
-        my = array_like_field(data, -1, position_fields[1])
-        mz = array_like_field(data, -1, position_fields[2])
-        mini = -1
-        if data[field].size > 0:
-            mini = np.argmin(data[field])
-            ma = data[field][mini]
-            mx, my, mz = [data[ax][mini] for ax in position_fields]
-        return (ma, mini, mx, my, mz)
-
-    def reduce_intermediate(self, values):
-        i = np.argmin(values[0]) # ma is values[0]
-        return [val[i] for val in values]
-
 class SpinParameter(DerivedQuantity):
     r"""
     Calculates the dimensionless spin parameter.

diff -r 370e4a426d8b4207121925f24768f2c39d676749 -r d81b240c1687e93f497778bf7783f08adb02f83c yt/data_objects/tests/test_derived_quantities.py
--- a/yt/data_objects/tests/test_derived_quantities.py
+++ b/yt/data_objects/tests/test_derived_quantities.py
@@ -85,6 +85,38 @@
         yield assert_equal, ad["y"][mi], y
         yield assert_equal, ad["z"][mi], z
 
+def test_min_location_field_value():
+    for nprocs in [1, 2, 4, 8]:
+        ds = fake_random_ds(16, nprocs = nprocs,
+            fields = ("density", "temperature", "velocity_x"))
+        ad = ds.all_data()
+
+        mv, ind, temp, vm = ad.quantities.min_location_field_value(
+            "density", ["temperature", "velocity_x"])
+
+        yield assert_equal, mv, ad["density"].min()
+
+        mi = np.argmin(ad["density"])
+
+        yield assert_equal, ad["temperature"][mi], temp
+        yield assert_equal, ad["velocity_x"][mi], vm
+
+def test_max_location_field_value():
+    for nprocs in [1, 2, 4, 8]:
+        ds = fake_random_ds(16, nprocs = nprocs,
+            fields = ("density", "temperature", "velocity_x"))
+        ad = ds.all_data()
+
+        mv, ind, temp, vm = ad.quantities.max_location_field_value(
+            "density", ["temperature", "velocity_x"])
+
+        yield assert_equal, mv, ad["density"].max()
+
+        mi = np.argmax(ad["density"])
+
+        yield assert_equal, ad["temperature"][mi], temp
+        yield assert_equal, ad["velocity_x"][mi], vm
+
 if __name__ == "__main__":
     for i in test_extrema():
         i[0](*i[1:])


https://bitbucket.org/yt_analysis/yt/commits/83ac79358d43/
Changeset:   83ac79358d43
Branch:      yt
User:        MatthewTurk
Date:        2015-11-24 01:42:24+00:00
Summary:     Adding argmin and argmax
Affected #:  1 file

diff -r d81b240c1687e93f497778bf7783f08adb02f83c -r 83ac79358d43566dc14b13f1ad1cb354e0ae83a2 yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -613,10 +613,78 @@
 
     # Numpy-like Operations
     def argmax(self, field, axis=None):
-        raise NotImplementedError
+        r"""Return the values at which the field is maximized.
+
+        This will, in a parallel-aware fashion, find the maximum value and then
+        return to you the values at that maximum location that are requested
+        for "axis".  By default it will return the spatial positions (in the
+        natural coordinate system), but it can be any field
+
+        Parameters
+        ----------
+        field : string or tuple of strings
+            The field to maximize.
+        axis : string, optional
+            If supplied, the fields to sample along; if not supplied, defaults
+            to the coordinate fields.
+
+        Returns
+        -------
+        A list of YTQuantities.
+
+        Examples
+        --------
+
+        >>> temp_at_max_rho = reg.argmax("density", axis="temperature")
+        >>> max_rho_xyz = reg.argmax("density")
+        >>> t_mrho, v_mrho = reg.argmax("density", axis=["temperature",
+        ...                 "velocity_magnitude"])
+
+        """
+        if axis is None:
+            mv, i, pos0, pos1, pos2 = self.quantities.max_location(field)
+            return pos0, pos1, pos2
+        rv = self.quantities.max_location_field_value(field, axis)
+        if len(rv) == 3:
+            return rv[2]
+        return rv[2:]
 
     def argmin(self, field, axis=None):
-        raise NotImplementedError
+        r"""Return the values at which the field is minimized.
+
+        This will, in a parallel-aware fashion, find the minimum value and then
+        return to you the values at that minimum location that are requested
+        for "axis".  By default it will return the spatial positions (in the
+        natural coordinate system), but it can be any field
+
+        Parameters
+        ----------
+        field : string or tuple of strings
+            The field to minimize.
+        axis : string, optional
+            If supplied, the fields to sample along; if not supplied, defaults
+            to the coordinate fields.
+
+        Returns
+        -------
+        A list of YTQuantities.
+
+        Examples
+        --------
+
+        >>> temp_at_min_rho = reg.argmin("density", axis="temperature")
+        >>> min_rho_xyz = reg.argmin("density")
+        >>> t_mrho, v_mrho = reg.argmin("density", axis=["temperature",
+        ...                 "velocity_magnitude"])
+
+        """
+        if axis is None:
+            mv, i, pos0, pos1, pos2 = self.quantities.min_location(field)
+            return pos0, pos1, pos2
+        rv = self.quantities.min_location_field_value(field, axis)
+        if len(rv) == 3:
+            return rv[2]
+        return rv[2:]
 
     def _compute_extrema(self, field):
         if self._extrema_cache is None:


https://bitbucket.org/yt_analysis/yt/commits/c967f91add55/
Changeset:   c967f91add55
Branch:      yt
User:        MatthewTurk
Date:        2015-11-24 03:16:50+00:00
Summary:     Adding tests for argmin and argmax.
Affected #:  1 file

diff -r 83ac79358d43566dc14b13f1ad1cb354e0ae83a2 -r c967f91add553a4d299d52e3323a646f71a3038f yt/data_objects/tests/test_numpy_ops.py
--- a/yt/data_objects/tests/test_numpy_ops.py
+++ b/yt/data_objects/tests/test_numpy_ops.py
@@ -1,4 +1,5 @@
 from yt.testing import fake_random_ds, fake_amr_ds, assert_equal
+import numpy as np
 
 
 def setup():
@@ -90,3 +91,51 @@
         qrho, qtemp = ad.min(["density", "temperature"])
         yield assert_equal, qrho, ad["density"].min()
         yield assert_equal, qtemp, ad["temperature"].min()
+
+def test_argmin():
+    for nprocs in [-1, 1, 2, 16]:
+        if nprocs == -1:
+            ds = fake_amr_ds(fields=("density","temperature"))
+        else:
+            ds = fake_random_ds(32, nprocs=nprocs,
+                fields=("density","temperature"))
+
+        ad = ds.all_data()
+
+        q = ad.argmin("density", axis=["density"])
+        yield assert_equal, q, ad["density"].min()
+
+        q1, q2 = ad.argmin("density", axis=["density", "temperature"])
+        mi = np.argmin(ad["density"])
+        yield assert_equal, q1, ad["density"].min()
+        yield assert_equal, q2, ad["temperature"][mi]
+
+        pos = ad.argmin("density")
+        mi = np.argmin(ad["density"])
+        yield assert_equal, pos[0], ad["x"][mi]
+        yield assert_equal, pos[1], ad["y"][mi]
+        yield assert_equal, pos[2], ad["z"][mi]
+
+def test_argmax():
+    for nprocs in [-1, 1, 2, 16]:
+        if nprocs == -1:
+            ds = fake_amr_ds(fields=("density","temperature"))
+        else:
+            ds = fake_random_ds(32, nprocs=nprocs,
+                fields=("density","temperature"))
+
+        ad = ds.all_data()
+
+        q = ad.argmax("density", axis=["density"])
+        yield assert_equal, q, ad["density"].max()
+
+        q1, q2 = ad.argmax("density", axis=["density", "temperature"])
+        mi = np.argmax(ad["density"])
+        yield assert_equal, q1, ad["density"].max()
+        yield assert_equal, q2, ad["temperature"][mi]
+
+        pos = ad.argmax("density")
+        mi = np.argmax(ad["density"])
+        yield assert_equal, pos[0], ad["x"][mi]
+        yield assert_equal, pos[1], ad["y"][mi]
+        yield assert_equal, pos[2], ad["z"][mi]


https://bitbucket.org/yt_analysis/yt/commits/9f99620e708a/
Changeset:   9f99620e708a
Branch:      yt
User:        MatthewTurk
Date:        2015-11-24 03:19:58+00:00
Summary:     Adding a few lines in the docs.
Affected #:  1 file

diff -r c967f91add553a4d299d52e3323a646f71a3038f -r 9f99620e708ab52e7fa675bc2228cbe14dc4d4a4 doc/source/analyzing/objects.rst
--- a/doc/source/analyzing/objects.rst
+++ b/doc/source/analyzing/objects.rst
@@ -468,6 +468,15 @@
 
 All of these projections supply the data object as their base input.
 
+Often, it can be useful to sample a field at the minimum and maximum of a
+different field.  You can use the ``argmax`` and ``argmin`` operations to do
+this.  If you don't specify an ``axis``, it will return the spatial position of
+the maximum value of the queried field.  Here is an example:::
+
+  reg.argmin("density", axis="temperature")
+
+This will return the temperature at the minimum density.
+
 Available Derived Quantities
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -494,11 +503,15 @@
     | Usage: ``extrema(fields, non_zero=False)``
     | The extrema of a field or list of fields.
 
-**Maximum Location**
-    | Class :class:`~yt.data_objects.derived_quantities.MaxLocation`
-    | Usage: ``max_location(fields)``
-    | The maximum of a field or list of fields as well
-      as the x,y,z location of that maximum.
+**Maximum Location Sampling**
+    | Class :class:`~yt.data_objects.derived_quantities.MaxLocationFieldValue`
+    | Usage: ``max_location_field_value(fields, sample_fields)``
+    | The value of sample_fields at the maximum value in fields.
+
+**Minimum Location Sampling**
+    | Class :class:`~yt.data_objects.derived_quantities.MinLocationFieldValue`
+    | Usage: ``min_location_field_value(fields, sample_fields)``
+    | The value of sample_fields at the minimum value in fields.
 
 **Minimum Location**
     | Class :class:`~yt.data_objects.derived_quantities.MinLocation`
@@ -506,6 +519,12 @@
     | The minimum of a field or list of fields as well
       as the x,y,z location of that minimum.
 
+**Maximum Location**
+    | Class :class:`~yt.data_objects.derived_quantities.MaxLocation`
+    | Usage: ``max_location(fields)``
+    | The maximum of a field or list of fields as well
+      as the x,y,z location of that maximum.
+
 **Spin Parameter**
     | Class :class:`~yt.data_objects.derived_quantities.SpinParameter`
     | Usage: ``spin_parameter(use_gas=True, use_particles=True)``


https://bitbucket.org/yt_analysis/yt/commits/a7969e4e99c4/
Changeset:   a7969e4e99c4
Branch:      yt
User:        MatthewTurk
Date:        2015-11-30 19:22:26+00:00
Summary:     Changing API to remove index for max/min location.
Affected #:  6 files

diff -r 9f99620e708ab52e7fa675bc2228cbe14dc4d4a4 -r a7969e4e99c4dd950ce3258297165ffc975cb2c4 yt/analysis_modules/halo_analysis/halo_callbacks.py
--- a/yt/analysis_modules/halo_analysis/halo_callbacks.py
+++ b/yt/analysis_modules/halo_analysis/halo_callbacks.py
@@ -123,7 +123,7 @@
     s_ds = halo.data_object.ds
     old_sphere = halo.data_object
     max_vals = old_sphere.quantities.max_location(field)
-    new_center = s_ds.arr(max_vals[2:])
+    new_center = s_ds.arr(max_vals[1:])
     new_sphere = s_ds.sphere(new_center.in_units("code_length"),
                                old_sphere.radius.in_units("code_length"))
     mylog.info("Moving sphere center from %s to %s." % (old_sphere.center,

diff -r 9f99620e708ab52e7fa675bc2228cbe14dc4d4a4 -r a7969e4e99c4dd950ce3258297165ffc975cb2c4 yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -642,12 +642,12 @@
 
         """
         if axis is None:
-            mv, i, pos0, pos1, pos2 = self.quantities.max_location(field)
+            mv, pos0, pos1, pos2 = self.quantities.max_location(field)
             return pos0, pos1, pos2
         rv = self.quantities.max_location_field_value(field, axis)
-        if len(rv) == 3:
-            return rv[2]
-        return rv[2:]
+        if len(rv) == 2:
+            return rv[1]
+        return rv[1:]
 
     def argmin(self, field, axis=None):
         r"""Return the values at which the field is minimized.
@@ -679,12 +679,12 @@
 
         """
         if axis is None:
-            mv, i, pos0, pos1, pos2 = self.quantities.min_location(field)
+            mv, pos0, pos1, pos2 = self.quantities.min_location(field)
             return pos0, pos1, pos2
         rv = self.quantities.min_location_field_value(field, axis)
-        if len(rv) == 3:
-            return rv[2]
-        return rv[2:]
+        if len(rv) == 2:
+            return rv[1]
+        return rv[1:]
 
     def _compute_extrema(self, field):
         if self._extrema_cache is None:

diff -r 9f99620e708ab52e7fa675bc2228cbe14dc4d4a4 -r a7969e4e99c4dd950ce3258297165ffc975cb2c4 yt/data_objects/derived_quantities.py
--- a/yt/data_objects/derived_quantities.py
+++ b/yt/data_objects/derived_quantities.py
@@ -524,10 +524,8 @@
 
 class MaxLocationFieldValue(DerivedQuantity):
     r"""
-    Calculates the maximum value plus the index and returns whichever fields
-    are asked to be sampled.
-
-    The index is not necessarily relevant, and should not be relied upon.
+    Calculates the maximum value and returns whichever fields are asked to be
+    sampled.
 
     Parameters
     ----------
@@ -547,7 +545,7 @@
     """
     def count_values(self, field, sample_fields):
         # field itself, then index, then the number of sample fields
-        self.num_vals = 2 + len(sample_fields)
+        self.num_vals = 1 + len(sample_fields)
 
     def __call__(self, field, sample_fields):
         rv = super(MaxLocationFieldValue, self).__call__(field, sample_fields)
@@ -563,7 +561,7 @@
             maxi = self._func(data[field])
             ma = data[field][maxi]
             vals = [data[sf][maxi] for sf in sample_fields]
-        return (ma, maxi) + tuple(vals)
+        return (ma,) + tuple(vals)
 
     def reduce_intermediate(self, values):
         i = self._func(values[0]) # ma is values[0]
@@ -574,10 +572,7 @@
 
 class MaxLocation(MaxLocationFieldValue):
     r"""
-    Calculates the maximum value plus the index, x, y, and z position
-    of the maximum.
-
-    The index is not necessarily relevant, and should not be relied upon.
+    Calculates the maximum value plus the x, y, and z position of the maximum.
 
     Parameters
     ----------
@@ -600,10 +595,8 @@
 
 class MinLocationFieldValue(MaxLocationFieldValue):
     r"""
-    Calculates the minimum value plus the index and returns whichever fields
-    are asked to be sampled.
-
-    The index is not necessarily relevant, and should not be relied upon.
+    Calculates the minimum value and returns whichever fields are asked to be
+    sampled.
 
     Parameters
     ----------
@@ -626,10 +619,7 @@
 
 class MinLocation(MinLocationFieldValue):
     r"""
-    Calculates the minimum value plus the index, x, y, and z position
-    of the minimum.
-
-    The index is not necessarily relevant, and should not be relied upon.
+    Calculates the minimum value plus the x, y, and z position of the minimum.
 
     Parameters
     ----------

diff -r 9f99620e708ab52e7fa675bc2228cbe14dc4d4a4 -r a7969e4e99c4dd950ce3258297165ffc975cb2c4 yt/data_objects/tests/test_derived_quantities.py
--- a/yt/data_objects/tests/test_derived_quantities.py
+++ b/yt/data_objects/tests/test_derived_quantities.py
@@ -60,7 +60,7 @@
         ds = fake_random_ds(16, nprocs = nprocs, fields = ("density", ))
         ad = ds.all_data()
 
-        mv, ind, x, y, z = ad.quantities.max_location(("gas", "density"))
+        mv, x, y, z = ad.quantities.max_location(("gas", "density"))
 
         yield assert_equal, mv, ad["density"].max()
 
@@ -75,7 +75,7 @@
         ds = fake_random_ds(16, nprocs = nprocs, fields = ("density", ))
         ad = ds.all_data()
 
-        mv, ind, x, y, z = ad.quantities.min_location(("gas", "density"))
+        mv, x, y, z = ad.quantities.min_location(("gas", "density"))
 
         yield assert_equal, mv, ad["density"].min()
 
@@ -91,7 +91,7 @@
             fields = ("density", "temperature", "velocity_x"))
         ad = ds.all_data()
 
-        mv, ind, temp, vm = ad.quantities.min_location_field_value(
+        mv, temp, vm = ad.quantities.min_location_field_value(
             "density", ["temperature", "velocity_x"])
 
         yield assert_equal, mv, ad["density"].min()
@@ -107,7 +107,7 @@
             fields = ("density", "temperature", "velocity_x"))
         ad = ds.all_data()
 
-        mv, ind, temp, vm = ad.quantities.max_location_field_value(
+        mv, temp, vm = ad.quantities.max_location_field_value(
             "density", ["temperature", "velocity_x"])
 
         yield assert_equal, mv, ad["density"].max()

diff -r 9f99620e708ab52e7fa675bc2228cbe14dc4d4a4 -r a7969e4e99c4dd950ce3258297165ffc975cb2c4 yt/frontends/artio/data_structures.py
--- a/yt/frontends/artio/data_structures.py
+++ b/yt/frontends/artio/data_structures.py
@@ -199,7 +199,7 @@
         if finest_levels is not False:
             source.min_level = self.max_level - finest_levels
         mylog.debug("Searching for maximum value of %s", field)
-        max_val, maxi, mx, my, mz = \
+        max_val, mx, my, mz = \
             source.quantities["MaxLocation"](field)
         mylog.info("Max Value is %0.5e at %0.16f %0.16f %0.16f",
                    max_val, mx, my, mz)

diff -r 9f99620e708ab52e7fa675bc2228cbe14dc4d4a4 -r a7969e4e99c4dd950ce3258297165ffc975cb2c4 yt/geometry/object_finding_mixin.py
--- a/yt/geometry/object_finding_mixin.py
+++ b/yt/geometry/object_finding_mixin.py
@@ -79,7 +79,7 @@
             source = self.all_data()
         mylog.debug("Searching %s grids for maximum value of %s",
                     len(source._grids), field)
-        max_val, maxi, mx, my, mz = \
+        max_val, mx, my, mz = \
             source.quantities["MaxLocation"]( field )
         mylog.info("Max Value is %0.5e at %0.16f %0.16f %0.16f", 
               max_val, mx, my, mz)


https://bitbucket.org/yt_analysis/yt/commits/911828fd526e/
Changeset:   911828fd526e
Branch:      yt
User:        MatthewTurk
Date:        2015-11-30 19:39:38+00:00
Summary:     Changing names of functions
Affected #:  4 files

diff -r a7969e4e99c4dd950ce3258297165ffc975cb2c4 -r 911828fd526e6a2f65a010f5da50b5af5de0e755 doc/source/analyzing/objects.rst
--- a/doc/source/analyzing/objects.rst
+++ b/doc/source/analyzing/objects.rst
@@ -504,13 +504,13 @@
     | The extrema of a field or list of fields.
 
 **Maximum Location Sampling**
-    | Class :class:`~yt.data_objects.derived_quantities.MaxLocationFieldValue`
-    | Usage: ``max_location_field_value(fields, sample_fields)``
+    | Class :class:`~yt.data_objects.derived_quantities.SampleAtMaxFieldValues`
+    | Usage: ``sample_at_max_field_values(fields, sample_fields)``
     | The value of sample_fields at the maximum value in fields.
 
 **Minimum Location Sampling**
-    | Class :class:`~yt.data_objects.derived_quantities.MinLocationFieldValue`
-    | Usage: ``min_location_field_value(fields, sample_fields)``
+    | Class :class:`~yt.data_objects.derived_quantities.SampleAtMinFieldValues`
+    | Usage: ``sample_at_min_field_values(fields, sample_fields)``
     | The value of sample_fields at the minimum value in fields.
 
 **Minimum Location**

diff -r a7969e4e99c4dd950ce3258297165ffc975cb2c4 -r 911828fd526e6a2f65a010f5da50b5af5de0e755 yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -644,7 +644,7 @@
         if axis is None:
             mv, pos0, pos1, pos2 = self.quantities.max_location(field)
             return pos0, pos1, pos2
-        rv = self.quantities.max_location_field_value(field, axis)
+        rv = self.quantities.sample_at_max_field_values(field, axis)
         if len(rv) == 2:
             return rv[1]
         return rv[1:]
@@ -681,7 +681,7 @@
         if axis is None:
             mv, pos0, pos1, pos2 = self.quantities.min_location(field)
             return pos0, pos1, pos2
-        rv = self.quantities.min_location_field_value(field, axis)
+        rv = self.quantities.sample_at_min_field_values(field, axis)
         if len(rv) == 2:
             return rv[1]
         return rv[1:]

diff -r a7969e4e99c4dd950ce3258297165ffc975cb2c4 -r 911828fd526e6a2f65a010f5da50b5af5de0e755 yt/data_objects/derived_quantities.py
--- a/yt/data_objects/derived_quantities.py
+++ b/yt/data_objects/derived_quantities.py
@@ -522,7 +522,7 @@
         return [self.data_source.ds.arr([mis.min(), mas.max()])
                 for mis, mas in zip(values[::2], values[1::2])]
 
-class MaxLocationFieldValue(DerivedQuantity):
+class SampleAtMaxFieldValues(DerivedQuantity):
     r"""
     Calculates the maximum value and returns whichever fields are asked to be
     sampled.
@@ -539,7 +539,7 @@
 
     >>> ds = load("IsolatedGalaxy/galaxy0030/galaxy0030")
     >>> ad = ds.all_data()
-    >>> print ad.quantities.max_location_field_value(("gas", "density"),
+    >>> print ad.quantities.sample_at_max_field_values(("gas", "density"),
     ...         ["temperature", "velocity_magnitude"])
 
     """
@@ -548,7 +548,7 @@
         self.num_vals = 1 + len(sample_fields)
 
     def __call__(self, field, sample_fields):
-        rv = super(MaxLocationFieldValue, self).__call__(field, sample_fields)
+        rv = super(SampleAtMaxFieldValues, self).__call__(field, sample_fields)
         if len(rv) == 1: rv = rv[0]
         return rv
 
@@ -570,7 +570,7 @@
     def _func(self, arr):
         return np.argmax(arr)
 
-class MaxLocation(MaxLocationFieldValue):
+class MaxLocation(SampleAtMaxFieldValues):
     r"""
     Calculates the maximum value plus the x, y, and z position of the maximum.
 
@@ -593,7 +593,7 @@
         if len(rv) == 1: rv = rv[0]
         return rv
 
-class MinLocationFieldValue(MaxLocationFieldValue):
+class SampleAtMinFieldValues(SampleAtMaxFieldValues):
     r"""
     Calculates the minimum value and returns whichever fields are asked to be
     sampled.
@@ -610,14 +610,14 @@
 
     >>> ds = load("IsolatedGalaxy/galaxy0030/galaxy0030")
     >>> ad = ds.all_data()
-    >>> print ad.quantities.min_location_field_value(("gas", "density"),
+    >>> print ad.quantities.sample_at_min_field_values(("gas", "density"),
     ...         ["temperature", "velocity_magnitude"])
 
     """
     def _func(self, arr):
         return np.argmin(arr)
 
-class MinLocation(MinLocationFieldValue):
+class MinLocation(SampleAtMinFieldValues):
     r"""
     Calculates the minimum value plus the x, y, and z position of the minimum.
 

diff -r a7969e4e99c4dd950ce3258297165ffc975cb2c4 -r 911828fd526e6a2f65a010f5da50b5af5de0e755 yt/data_objects/tests/test_derived_quantities.py
--- a/yt/data_objects/tests/test_derived_quantities.py
+++ b/yt/data_objects/tests/test_derived_quantities.py
@@ -85,13 +85,13 @@
         yield assert_equal, ad["y"][mi], y
         yield assert_equal, ad["z"][mi], z
 
-def test_min_location_field_value():
+def test_sample_at_min_field_values():
     for nprocs in [1, 2, 4, 8]:
         ds = fake_random_ds(16, nprocs = nprocs,
             fields = ("density", "temperature", "velocity_x"))
         ad = ds.all_data()
 
-        mv, temp, vm = ad.quantities.min_location_field_value(
+        mv, temp, vm = ad.quantities.sample_at_min_field_values(
             "density", ["temperature", "velocity_x"])
 
         yield assert_equal, mv, ad["density"].min()
@@ -101,13 +101,13 @@
         yield assert_equal, ad["temperature"][mi], temp
         yield assert_equal, ad["velocity_x"][mi], vm
 
-def test_max_location_field_value():
+def test_sample_at_max_field_values():
     for nprocs in [1, 2, 4, 8]:
         ds = fake_random_ds(16, nprocs = nprocs,
             fields = ("density", "temperature", "velocity_x"))
         ad = ds.all_data()
 
-        mv, temp, vm = ad.quantities.max_location_field_value(
+        mv, temp, vm = ad.quantities.sample_at_max_field_values(
             "density", ["temperature", "velocity_x"])
 
         yield assert_equal, mv, ad["density"].max()


https://bitbucket.org/yt_analysis/yt/commits/63c42f38054b/
Changeset:   63c42f38054b
Branch:      yt
User:        MatthewTurk
Date:        2015-11-30 19:41:15+00:00
Summary:     Missed one location for maxi/mini
Affected #:  1 file

diff -r 911828fd526e6a2f65a010f5da50b5af5de0e755 -r 63c42f38054b7a59e6f13a7be95a63b2c1435133 yt/data_objects/static_output.py
--- a/yt/data_objects/static_output.py
+++ b/yt/data_objects/static_output.py
@@ -625,7 +625,7 @@
         """
         mylog.debug("Searching for maximum value of %s", field)
         source = self.all_data()
-        max_val, maxi, mx, my, mz = \
+        max_val, mx, my, mz = \
             source.quantities.max_location(field)
         mylog.info("Max Value is %0.5e at %0.16f %0.16f %0.16f",
               max_val, mx, my, mz)
@@ -637,7 +637,7 @@
         """
         mylog.debug("Searching for minimum value of %s", field)
         source = self.all_data()
-        min_val, maxi, mx, my, mz = \
+        min_val, mx, my, mz = \
             source.quantities.min_location(field)
         mylog.info("Min Value is %0.5e at %0.16f %0.16f %0.16f",
               min_val, mx, my, mz)


https://bitbucket.org/yt_analysis/yt/commits/7b7ef534c1b2/
Changeset:   7b7ef534c1b2
Branch:      yt
User:        MatthewTurk
Date:        2015-11-30 19:42:06+00:00
Summary:     Adding doc note
Affected #:  1 file

diff -r 63c42f38054b7a59e6f13a7be95a63b2c1435133 -r 7b7ef534c1b2ccef939ea8798c9ac39545a0d9aa yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -630,7 +630,7 @@
 
         Returns
         -------
-        A list of YTQuantities.
+        A list of YTQuantities as specified by the axis argument.
 
         Examples
         --------
@@ -667,7 +667,7 @@
 
         Returns
         -------
-        A list of YTQuantities.
+        A list of YTQuantities as specified by the axis argument.
 
         Examples
         --------


https://bitbucket.org/yt_analysis/yt/commits/af8ef441266e/
Changeset:   af8ef441266e
Branch:      yt
User:        MatthewTurk
Date:        2015-11-30 19:49:40+00:00
Summary:     Adding more docs
Affected #:  2 files

diff -r 7b7ef534c1b2ccef939ea8798c9ac39545a0d9aa -r af8ef441266e5f74df76b21038f102b75514f63a doc/source/analyzing/objects.rst
--- a/doc/source/analyzing/objects.rst
+++ b/doc/source/analyzing/objects.rst
@@ -470,13 +470,17 @@
 
 Often, it can be useful to sample a field at the minimum and maximum of a
 different field.  You can use the ``argmax`` and ``argmin`` operations to do
-this.  If you don't specify an ``axis``, it will return the spatial position of
-the maximum value of the queried field.  Here is an example:::
+this.::
 
   reg.argmin("density", axis="temperature")
 
 This will return the temperature at the minimum density.
 
+If you don't specify an ``axis``, it will return the spatial position of
+the maximum value of the queried field.  Here is an example:::
+
+  x, y, z = reg.argmin("density")
+
 Available Derived Quantities
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 

diff -r 7b7ef534c1b2ccef939ea8798c9ac39545a0d9aa -r af8ef441266e5f74df76b21038f102b75514f63a yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -624,9 +624,11 @@
         ----------
         field : string or tuple of strings
             The field to maximize.
-        axis : string, optional
+        axis : string or list of strings, optional
             If supplied, the fields to sample along; if not supplied, defaults
-            to the coordinate fields.
+            to the coordinate fields.  This can be the name of the coordinate
+            fields (i.e., 'x', 'y', 'z') or a list of fields, but cannot be 0,
+            1, 2.
 
         Returns
         -------
@@ -639,6 +641,7 @@
         >>> max_rho_xyz = reg.argmax("density")
         >>> t_mrho, v_mrho = reg.argmax("density", axis=["temperature",
         ...                 "velocity_magnitude"])
+        >>> x, y, z = reg.argmax("density")
 
         """
         if axis is None:
@@ -661,9 +664,11 @@
         ----------
         field : string or tuple of strings
             The field to minimize.
-        axis : string, optional
+        axis : string or list of strings, optional
             If supplied, the fields to sample along; if not supplied, defaults
-            to the coordinate fields.
+            to the coordinate fields.  This can be the name of the coordinate
+            fields (i.e., 'x', 'y', 'z') or a list of fields, but cannot be 0,
+            1, 2.
 
         Returns
         -------
@@ -676,6 +681,7 @@
         >>> min_rho_xyz = reg.argmin("density")
         >>> t_mrho, v_mrho = reg.argmin("density", axis=["temperature",
         ...                 "velocity_magnitude"])
+        >>> x, y, z = reg.argmin("density")
 
         """
         if axis is None:


https://bitbucket.org/yt_analysis/yt/commits/753456ba481f/
Changeset:   753456ba481f
Branch:      yt
User:        ngoldbaum
Date:        2015-12-08 02:57:31+00:00
Summary:     Merged in MatthewTurk/yt (pull request #1885)

Implement argmin and argmax
Affected #:  9 files

diff -r 4a8fa18eaf118a4249c1e31c6b31c8ab6997d66b -r 753456ba481faf74ba9e4f7e6def423537be8b32 doc/source/analyzing/objects.rst
--- a/doc/source/analyzing/objects.rst
+++ b/doc/source/analyzing/objects.rst
@@ -468,6 +468,19 @@
 
 All of these projections supply the data object as their base input.
 
+Often, it can be useful to sample a field at the minimum and maximum of a
+different field.  You can use the ``argmax`` and ``argmin`` operations to do
+this.::
+
+  reg.argmin("density", axis="temperature")
+
+This will return the temperature at the minimum density.
+
+If you don't specify an ``axis``, it will return the spatial position of
+the maximum value of the queried field.  Here is an example:::
+
+  x, y, z = reg.argmin("density")
+
 Available Derived Quantities
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -494,11 +507,15 @@
     | Usage: ``extrema(fields, non_zero=False)``
     | The extrema of a field or list of fields.
 
-**Maximum Location**
-    | Class :class:`~yt.data_objects.derived_quantities.MaxLocation`
-    | Usage: ``max_location(fields)``
-    | The maximum of a field or list of fields as well
-      as the x,y,z location of that maximum.
+**Maximum Location Sampling**
+    | Class :class:`~yt.data_objects.derived_quantities.SampleAtMaxFieldValues`
+    | Usage: ``sample_at_max_field_values(fields, sample_fields)``
+    | The value of sample_fields at the maximum value in fields.
+
+**Minimum Location Sampling**
+    | Class :class:`~yt.data_objects.derived_quantities.SampleAtMinFieldValues`
+    | Usage: ``sample_at_min_field_values(fields, sample_fields)``
+    | The value of sample_fields at the minimum value in fields.
 
 **Minimum Location**
     | Class :class:`~yt.data_objects.derived_quantities.MinLocation`
@@ -506,6 +523,12 @@
     | The minimum of a field or list of fields as well
       as the x,y,z location of that minimum.
 
+**Maximum Location**
+    | Class :class:`~yt.data_objects.derived_quantities.MaxLocation`
+    | Usage: ``max_location(fields)``
+    | The maximum of a field or list of fields as well
+      as the x,y,z location of that maximum.
+
 **Spin Parameter**
     | Class :class:`~yt.data_objects.derived_quantities.SpinParameter`
     | Usage: ``spin_parameter(use_gas=True, use_particles=True)``

diff -r 4a8fa18eaf118a4249c1e31c6b31c8ab6997d66b -r 753456ba481faf74ba9e4f7e6def423537be8b32 yt/analysis_modules/halo_analysis/halo_callbacks.py
--- a/yt/analysis_modules/halo_analysis/halo_callbacks.py
+++ b/yt/analysis_modules/halo_analysis/halo_callbacks.py
@@ -123,7 +123,7 @@
     s_ds = halo.data_object.ds
     old_sphere = halo.data_object
     max_vals = old_sphere.quantities.max_location(field)
-    new_center = s_ds.arr(max_vals[2:])
+    new_center = s_ds.arr(max_vals[1:])
     new_sphere = s_ds.sphere(new_center.in_units("code_length"),
                                old_sphere.radius.in_units("code_length"))
     mylog.info("Moving sphere center from %s to %s." % (old_sphere.center,

diff -r 4a8fa18eaf118a4249c1e31c6b31c8ab6997d66b -r 753456ba481faf74ba9e4f7e6def423537be8b32 yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -613,10 +613,84 @@
 
     # Numpy-like Operations
     def argmax(self, field, axis=None):
-        raise NotImplementedError
+        r"""Return the values at which the field is maximized.
+
+        This will, in a parallel-aware fashion, find the maximum value and then
+        return to you the values at that maximum location that are requested
+        for "axis".  By default it will return the spatial positions (in the
+        natural coordinate system), but it can be any field
+
+        Parameters
+        ----------
+        field : string or tuple of strings
+            The field to maximize.
+        axis : string or list of strings, optional
+            If supplied, the fields to sample along; if not supplied, defaults
+            to the coordinate fields.  This can be the name of the coordinate
+            fields (i.e., 'x', 'y', 'z') or a list of fields, but cannot be 0,
+            1, 2.
+
+        Returns
+        -------
+        A list of YTQuantities as specified by the axis argument.
+
+        Examples
+        --------
+
+        >>> temp_at_max_rho = reg.argmax("density", axis="temperature")
+        >>> max_rho_xyz = reg.argmax("density")
+        >>> t_mrho, v_mrho = reg.argmax("density", axis=["temperature",
+        ...                 "velocity_magnitude"])
+        >>> x, y, z = reg.argmax("density")
+
+        """
+        if axis is None:
+            mv, pos0, pos1, pos2 = self.quantities.max_location(field)
+            return pos0, pos1, pos2
+        rv = self.quantities.sample_at_max_field_values(field, axis)
+        if len(rv) == 2:
+            return rv[1]
+        return rv[1:]
 
     def argmin(self, field, axis=None):
-        raise NotImplementedError
+        r"""Return the values at which the field is minimized.
+
+        This will, in a parallel-aware fashion, find the minimum value and then
+        return to you the values at that minimum location that are requested
+        for "axis".  By default it will return the spatial positions (in the
+        natural coordinate system), but it can be any field
+
+        Parameters
+        ----------
+        field : string or tuple of strings
+            The field to minimize.
+        axis : string or list of strings, optional
+            If supplied, the fields to sample along; if not supplied, defaults
+            to the coordinate fields.  This can be the name of the coordinate
+            fields (i.e., 'x', 'y', 'z') or a list of fields, but cannot be 0,
+            1, 2.
+
+        Returns
+        -------
+        A list of YTQuantities as specified by the axis argument.
+
+        Examples
+        --------
+
+        >>> temp_at_min_rho = reg.argmin("density", axis="temperature")
+        >>> min_rho_xyz = reg.argmin("density")
+        >>> t_mrho, v_mrho = reg.argmin("density", axis=["temperature",
+        ...                 "velocity_magnitude"])
+        >>> x, y, z = reg.argmin("density")
+
+        """
+        if axis is None:
+            mv, pos0, pos1, pos2 = self.quantities.min_location(field)
+            return pos0, pos1, pos2
+        rv = self.quantities.sample_at_min_field_values(field, axis)
+        if len(rv) == 2:
+            return rv[1]
+        return rv[1:]
 
     def _compute_extrema(self, field):
         if self._extrema_cache is None:

diff -r 4a8fa18eaf118a4249c1e31c6b31c8ab6997d66b -r 753456ba481faf74ba9e4f7e6def423537be8b32 yt/data_objects/derived_quantities.py
--- a/yt/data_objects/derived_quantities.py
+++ b/yt/data_objects/derived_quantities.py
@@ -522,10 +522,57 @@
         return [self.data_source.ds.arr([mis.min(), mas.max()])
                 for mis, mas in zip(values[::2], values[1::2])]
 
-class MaxLocation(DerivedQuantity):
+class SampleAtMaxFieldValues(DerivedQuantity):
     r"""
-    Calculates the maximum value plus the index, x, y, and z position
-    of the maximum.
+    Calculates the maximum value and returns whichever fields are asked to be
+    sampled.
+
+    Parameters
+    ----------
+    field : field
+        The field over which the extrema are to be calculated.
+    sample_fields : list of fields
+        The fields to sample and return at the minimum value.
+
+    Examples
+    --------
+
+    >>> ds = load("IsolatedGalaxy/galaxy0030/galaxy0030")
+    >>> ad = ds.all_data()
+    >>> print ad.quantities.sample_at_max_field_values(("gas", "density"),
+    ...         ["temperature", "velocity_magnitude"])
+
+    """
+    def count_values(self, field, sample_fields):
+        # field itself, then index, then the number of sample fields
+        self.num_vals = 1 + len(sample_fields)
+
+    def __call__(self, field, sample_fields):
+        rv = super(SampleAtMaxFieldValues, self).__call__(field, sample_fields)
+        if len(rv) == 1: rv = rv[0]
+        return rv
+
+    def process_chunk(self, data, field, sample_fields):
+        field = data._determine_fields(field)[0]
+        ma = array_like_field(data, -HUGE, field)
+        vals = [array_like_field(data, -1, sf) for sf in sample_fields]
+        maxi = -1
+        if data[field].size > 0:
+            maxi = self._func(data[field])
+            ma = data[field][maxi]
+            vals = [data[sf][maxi] for sf in sample_fields]
+        return (ma,) + tuple(vals)
+
+    def reduce_intermediate(self, values):
+        i = self._func(values[0]) # ma is values[0]
+        return [val[i] for val in values]
+
+    def _func(self, arr):
+        return np.argmax(arr)
+
+class MaxLocation(SampleAtMaxFieldValues):
+    r"""
+    Calculates the maximum value plus the x, y, and z position of the maximum.
 
     Parameters
     ----------
@@ -540,36 +587,39 @@
     >>> print ad.quantities.max_location(("gas", "density"))
 
     """
-    def count_values(self, *args, **kwargs):
-        self.num_vals = 5
-
     def __call__(self, field):
-        rv = super(MaxLocation, self).__call__(field)
+        sample_fields = get_position_fields(field, self.data_source)
+        rv = super(MaxLocation, self).__call__(field, sample_fields)
         if len(rv) == 1: rv = rv[0]
         return rv
 
-    def process_chunk(self, data, field):
-        field = data._determine_fields(field)[0]
-        ma = array_like_field(data, -HUGE, field)
-        position_fields = get_position_fields(field, data)
-        mx = array_like_field(data, -1, position_fields[0])
-        my = array_like_field(data, -1, position_fields[1])
-        mz = array_like_field(data, -1, position_fields[2])
-        maxi = -1
-        if data[field].size > 0:
-            maxi = np.argmax(data[field])
-            ma = data[field][maxi]
-            mx, my, mz = [data[ax][maxi] for ax in position_fields]
-        return (ma, maxi, mx, my, mz)
+class SampleAtMinFieldValues(SampleAtMaxFieldValues):
+    r"""
+    Calculates the minimum value and returns whichever fields are asked to be
+    sampled.
 
-    def reduce_intermediate(self, values):
-        i = np.argmax(values[0]) # ma is values[0]
-        return [val[i] for val in values]
+    Parameters
+    ----------
+    field : field
+        The field over which the extrema are to be calculated.
+    sample_fields : list of fields
+        The fields to sample and return at the minimum value.
 
-class MinLocation(DerivedQuantity):
+    Examples
+    --------
+
+    >>> ds = load("IsolatedGalaxy/galaxy0030/galaxy0030")
+    >>> ad = ds.all_data()
+    >>> print ad.quantities.sample_at_min_field_values(("gas", "density"),
+    ...         ["temperature", "velocity_magnitude"])
+
+    """
+    def _func(self, arr):
+        return np.argmin(arr)
+
+class MinLocation(SampleAtMinFieldValues):
     r"""
-    Calculates the minimum value plus the index, x, y, and z position
-    of the minimum.
+    Calculates the minimum value plus the x, y, and z position of the minimum.
 
     Parameters
     ----------
@@ -584,32 +634,12 @@
     >>> print ad.quantities.min_location(("gas", "density"))
 
     """
-    def count_values(self, *args, **kwargs):
-        self.num_vals = 5
-
     def __call__(self, field):
-        rv = super(MinLocation, self).__call__(field)
+        sample_fields = get_position_fields(field, self.data_source)
+        rv = super(MinLocation, self).__call__(field, sample_fields)
         if len(rv) == 1: rv = rv[0]
         return rv
 
-    def process_chunk(self, data, field):
-        field = data._determine_fields(field)[0]
-        ma = array_like_field(data, HUGE, field)
-        position_fields = get_position_fields(field, data)
-        mx = array_like_field(data, -1, position_fields[0])
-        my = array_like_field(data, -1, position_fields[1])
-        mz = array_like_field(data, -1, position_fields[2])
-        mini = -1
-        if data[field].size > 0:
-            mini = np.argmin(data[field])
-            ma = data[field][mini]
-            mx, my, mz = [data[ax][mini] for ax in position_fields]
-        return (ma, mini, mx, my, mz)
-
-    def reduce_intermediate(self, values):
-        i = np.argmin(values[0]) # ma is values[0]
-        return [val[i] for val in values]
-
 class SpinParameter(DerivedQuantity):
     r"""
     Calculates the dimensionless spin parameter.

diff -r 4a8fa18eaf118a4249c1e31c6b31c8ab6997d66b -r 753456ba481faf74ba9e4f7e6def423537be8b32 yt/data_objects/static_output.py
--- a/yt/data_objects/static_output.py
+++ b/yt/data_objects/static_output.py
@@ -625,7 +625,7 @@
         """
         mylog.debug("Searching for maximum value of %s", field)
         source = self.all_data()
-        max_val, maxi, mx, my, mz = \
+        max_val, mx, my, mz = \
             source.quantities.max_location(field)
         mylog.info("Max Value is %0.5e at %0.16f %0.16f %0.16f",
               max_val, mx, my, mz)
@@ -637,7 +637,7 @@
         """
         mylog.debug("Searching for minimum value of %s", field)
         source = self.all_data()
-        min_val, maxi, mx, my, mz = \
+        min_val, mx, my, mz = \
             source.quantities.min_location(field)
         mylog.info("Min Value is %0.5e at %0.16f %0.16f %0.16f",
               min_val, mx, my, mz)

diff -r 4a8fa18eaf118a4249c1e31c6b31c8ab6997d66b -r 753456ba481faf74ba9e4f7e6def423537be8b32 yt/data_objects/tests/test_derived_quantities.py
--- a/yt/data_objects/tests/test_derived_quantities.py
+++ b/yt/data_objects/tests/test_derived_quantities.py
@@ -55,6 +55,68 @@
                         ad["cell_mass"].sum())
         yield assert_rel_equal, my_std, a_std, 12
 
+def test_max_location():
+    for nprocs in [1, 2, 4, 8]:
+        ds = fake_random_ds(16, nprocs = nprocs, fields = ("density", ))
+        ad = ds.all_data()
+
+        mv, x, y, z = ad.quantities.max_location(("gas", "density"))
+
+        yield assert_equal, mv, ad["density"].max()
+
+        mi = np.argmax(ad["density"])
+
+        yield assert_equal, ad["x"][mi], x
+        yield assert_equal, ad["y"][mi], y
+        yield assert_equal, ad["z"][mi], z
+
+def test_min_location():
+    for nprocs in [1, 2, 4, 8]:
+        ds = fake_random_ds(16, nprocs = nprocs, fields = ("density", ))
+        ad = ds.all_data()
+
+        mv, x, y, z = ad.quantities.min_location(("gas", "density"))
+
+        yield assert_equal, mv, ad["density"].min()
+
+        mi = np.argmin(ad["density"])
+
+        yield assert_equal, ad["x"][mi], x
+        yield assert_equal, ad["y"][mi], y
+        yield assert_equal, ad["z"][mi], z
+
+def test_sample_at_min_field_values():
+    for nprocs in [1, 2, 4, 8]:
+        ds = fake_random_ds(16, nprocs = nprocs,
+            fields = ("density", "temperature", "velocity_x"))
+        ad = ds.all_data()
+
+        mv, temp, vm = ad.quantities.sample_at_min_field_values(
+            "density", ["temperature", "velocity_x"])
+
+        yield assert_equal, mv, ad["density"].min()
+
+        mi = np.argmin(ad["density"])
+
+        yield assert_equal, ad["temperature"][mi], temp
+        yield assert_equal, ad["velocity_x"][mi], vm
+
+def test_sample_at_max_field_values():
+    for nprocs in [1, 2, 4, 8]:
+        ds = fake_random_ds(16, nprocs = nprocs,
+            fields = ("density", "temperature", "velocity_x"))
+        ad = ds.all_data()
+
+        mv, temp, vm = ad.quantities.sample_at_max_field_values(
+            "density", ["temperature", "velocity_x"])
+
+        yield assert_equal, mv, ad["density"].max()
+
+        mi = np.argmax(ad["density"])
+
+        yield assert_equal, ad["temperature"][mi], temp
+        yield assert_equal, ad["velocity_x"][mi], vm
+
 if __name__ == "__main__":
     for i in test_extrema():
         i[0](*i[1:])

diff -r 4a8fa18eaf118a4249c1e31c6b31c8ab6997d66b -r 753456ba481faf74ba9e4f7e6def423537be8b32 yt/data_objects/tests/test_numpy_ops.py
--- a/yt/data_objects/tests/test_numpy_ops.py
+++ b/yt/data_objects/tests/test_numpy_ops.py
@@ -1,4 +1,5 @@
 from yt.testing import fake_random_ds, fake_amr_ds, assert_equal
+import numpy as np
 
 
 def setup():
@@ -93,3 +94,51 @@
         qrho, qtemp = ad.min(["density", "temperature"])
         yield assert_equal, qrho, ad["density"].min()
         yield assert_equal, qtemp, ad["temperature"].min()
+
+def test_argmin():
+    for nprocs in [-1, 1, 2, 16]:
+        if nprocs == -1:
+            ds = fake_amr_ds(fields=("density","temperature"))
+        else:
+            ds = fake_random_ds(32, nprocs=nprocs,
+                fields=("density","temperature"))
+
+        ad = ds.all_data()
+
+        q = ad.argmin("density", axis=["density"])
+        yield assert_equal, q, ad["density"].min()
+
+        q1, q2 = ad.argmin("density", axis=["density", "temperature"])
+        mi = np.argmin(ad["density"])
+        yield assert_equal, q1, ad["density"].min()
+        yield assert_equal, q2, ad["temperature"][mi]
+
+        pos = ad.argmin("density")
+        mi = np.argmin(ad["density"])
+        yield assert_equal, pos[0], ad["x"][mi]
+        yield assert_equal, pos[1], ad["y"][mi]
+        yield assert_equal, pos[2], ad["z"][mi]
+
+def test_argmax():
+    for nprocs in [-1, 1, 2, 16]:
+        if nprocs == -1:
+            ds = fake_amr_ds(fields=("density","temperature"))
+        else:
+            ds = fake_random_ds(32, nprocs=nprocs,
+                fields=("density","temperature"))
+
+        ad = ds.all_data()
+
+        q = ad.argmax("density", axis=["density"])
+        yield assert_equal, q, ad["density"].max()
+
+        q1, q2 = ad.argmax("density", axis=["density", "temperature"])
+        mi = np.argmax(ad["density"])
+        yield assert_equal, q1, ad["density"].max()
+        yield assert_equal, q2, ad["temperature"][mi]
+
+        pos = ad.argmax("density")
+        mi = np.argmax(ad["density"])
+        yield assert_equal, pos[0], ad["x"][mi]
+        yield assert_equal, pos[1], ad["y"][mi]
+        yield assert_equal, pos[2], ad["z"][mi]

diff -r 4a8fa18eaf118a4249c1e31c6b31c8ab6997d66b -r 753456ba481faf74ba9e4f7e6def423537be8b32 yt/frontends/artio/data_structures.py
--- a/yt/frontends/artio/data_structures.py
+++ b/yt/frontends/artio/data_structures.py
@@ -199,7 +199,7 @@
         if finest_levels is not False:
             source.min_level = self.max_level - finest_levels
         mylog.debug("Searching for maximum value of %s", field)
-        max_val, maxi, mx, my, mz = \
+        max_val, mx, my, mz = \
             source.quantities["MaxLocation"](field)
         mylog.info("Max Value is %0.5e at %0.16f %0.16f %0.16f",
                    max_val, mx, my, mz)

diff -r 4a8fa18eaf118a4249c1e31c6b31c8ab6997d66b -r 753456ba481faf74ba9e4f7e6def423537be8b32 yt/geometry/object_finding_mixin.py
--- a/yt/geometry/object_finding_mixin.py
+++ b/yt/geometry/object_finding_mixin.py
@@ -79,7 +79,7 @@
             source = self.all_data()
         mylog.debug("Searching %s grids for maximum value of %s",
                     len(source._grids), field)
-        max_val, maxi, mx, my, mz = \
+        max_val, mx, my, mz = \
             source.quantities["MaxLocation"]( field )
         mylog.info("Max Value is %0.5e at %0.16f %0.16f %0.16f", 
               max_val, mx, my, mz)

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