<html><body>
<p>1 new commit in yt:</p>
<p><a href="http://link.bitbucket.org/wf/click?upn=8USRlNyft-2BCzk2l4Ywl6gDx2lD2xxoS9E7MwXb2SMR-2BXcTD42YocdnOFkyGBVHOUtmqRdJv6-2BukVVr5hGmJmaVzeiOznziiy5NMixq1phf4-3D_ll4ctv0L-2ByeRZFC1LslHcg6aJmnQ70VruLbmeLQr27ASmtSKNGFKr1dQ2QCSDW0xsQXA1fneCMfdlKyrTwzMrGkfvNisaE5843fEJEtsgO0dcP1SsiZdoZwebq4vxSuT214WqknaOAiEzqQ-2By-2FDfky-2BoliJzy3ZjnzVrqYu7KmXkEjO-2BJfcMBHWtObYvymsL5biULyGbRwo2UC2qEuJb06SQTnRVSicpX9tZfxhPqeQ-3D">https://bitbucket.org/yt_analysis/yt/commits/7d98d561e68c/</a> Changeset:   7d98d561e68c Branch:      yt User:        ngoldbaum Date:        2016-03-23 20:55:41+00:00 Summary:     Merged in brittonsmith/yt (pull request #2061)</p>
<p>Adding halo analysis recipes Affected #:  7 files</p>
<p>diff -r ee78f27e30fbc234af0d10107fc4022f5d42d1d9 -r 7d98d561e68cde5957a324cf1c6d6e3d92b43674 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 @@ -65,12 +65,13 @@</p>
<pre>Analysis is done by adding actions to the
:class:`~yt.analysis_modules.halo_analysis.halo_catalog.HaloCatalog`.</pre>
<p>-Each action is represented by a callback function that will be run on each halo. -There are three types of actions: +Each action is represented by a callback function that will be run on +each halo.  There are four types of actions:</p>
<pre>* Filters
* Quantities
* Callbacks</pre>
<p>+* Recipes</p>
<pre>A list of all available filters, quantities, and callbacks can be found in
:ref:`halo_analysis_ref`.</pre>
<p>@@ -213,6 +214,50 @@</p>
<pre>   # ...  Later on in your script
   hc.add_callback("my_callback")
</pre>
<p>+Recipes +^^^^^^^ + +Recipes allow you to create analysis tasks that consist of a series of +callbacks, quantities, and filters that are run in succession.  An example +of this is +:func:`~yt.analysis_modules.halo_analysis.halo_recipes.calculate_virial_quantities`, +which calculates virial quantities by first creating a sphere container, +performing 1D radial profiles, and then interpolating to get values at a +specified threshold overdensity.  All of these operations are separate +callbacks, but the recipes allow you to add them to your analysis pipeline +with one call.  For example, + +.. code-block:: python + +   hc.add_recipe("calculate_virial_quantities", ["radius", “matter_mass"]) + +The available recipes are located in +``yt/analysis_modules/halo_analysis/halo_recipes.py``.  New recipes can be +created in the following manner: + +.. code-block:: python + +   def my_recipe(halo_catalog, fields, weight_field=None): +       # create a sphere +       halo_catalog.add_callback("sphere”) +       # make profiles +       halo_catalog.add_callback("profile", ["radius"], fields, +                                 weight_field=weight_field) +       # save the profile data +       halo_catalog.add_callback("save_profiles", output_dir="profiles") + +   # add recipe to the registry of recipes +   add_recipe("profile_and_save", my_recipe) + + +   # …  Later on in your script +   hc.add_recipe("profile_and_save", ["density", “temperature"], +                 weight_field="cell_mass”) + +Note, that unlike callback, filter, and quantity functions that take a ``Halo`` +object as the first argument, recipe functions should take a ``HaloCatalog`` +object as the first argument. +</p>
<pre>Running Analysis
----------------
</pre>
<p>diff -r ee78f27e30fbc234af0d10107fc4022f5d42d1d9 -r 7d98d561e68cde5957a324cf1c6d6e3d92b43674 doc/source/cookbook/halo_profiler.py --- a/doc/source/cookbook/halo_profiler.py +++ b/doc/source/cookbook/halo_profiler.py @@ -12,26 +12,16 @@</p>
<pre># Filter out less massive halos
hc.add_filter("quantity_value", "particle_mass", ">", 1e14, "Msun")
</pre>
<p>-# attach a sphere object to each halo whose radius extends -#   to twice the radius of the halo -hc.add_callback("sphere", factor=2.0) +# This recipe creates a spherical data container, computes +# radial profiles, and calculates r_200 and M_200. +hc.add_recipe("calculate_virial_quantities", ["radius", "matter_mass"])</p>
<p>-# use the sphere to calculate radial profiles of gas density -# weighted by cell volume in terms of the virial radius -hc.add_callback("profile", ["radius"],</p>
<ul><li><p>[("gas", "overdensity")],</p></li>
<li><p>weight_field="cell_volume",</p></li>
<li><p>accumulation=True,</p></li>
<li><p>storage="virial_quantities_profiles")</p></li></ul>
<p>– – -hc.add_callback("virial_quantities", ["radius"],</p>
<ul><li><p>profile_storage="virial_quantities_profiles")</p></li></ul>
<p>-hc.add_callback('delete_attribute', ‘virial_quantities_profiles’) – +# Create a sphere container with radius 5x r_200.</p>
<pre>field_params = dict(virial_radius=('quantity', 'radius_200'))
hc.add_callback('sphere', radius_field='radius_200', factor=5,
                field_parameters=field_params)</pre>
<p>+ +# Compute profiles of T vs. r/r_200</p>
<pre>hc.add_callback('profile', ['virial_radius_fraction'],
                [('gas', 'temperature')],
                storage='virial_profiles',</pre>
<p>diff -r ee78f27e30fbc234af0d10107fc4022f5d42d1d9 -r 7d98d561e68cde5957a324cf1c6d6e3d92b43674 doc/source/reference/api/api.rst --- a/doc/source/reference/api/api.rst +++ b/doc/source/reference/api/api.rst @@ -472,6 +472,8 @@</p>
<pre>~yt.analysis_modules.halo_analysis.halo_quantities.HaloQuantity
~yt.analysis_modules.halo_analysis.halo_quantities.bulk_velocity
~yt.analysis_modules.halo_analysis.halo_quantities.center_of_mass</pre>
<p>+   ~yt.analysis_modules.halo_analysis.halo_recipes.HaloRecipe +   ~yt.analysis_modules.halo_analysis.halo_recipes.calculate_virial_quantities</p>
<pre>Halo Finding
^^^^^^^^^^^^</pre>
<p>diff -r ee78f27e30fbc234af0d10107fc4022f5d42d1d9 -r 7d98d561e68cde5957a324cf1c6d6e3d92b43674 yt/analysis_modules/halo_analysis/api.py --- a/yt/analysis_modules/halo_analysis/api.py +++ b/yt/analysis_modules/halo_analysis/api.py @@ -15,16 +15,19 @@</p>
<pre>from .halo_catalog import \</pre>
<ul><li><p>HaloCatalog</p></li></ul>
<p>+    HaloCatalog</p>
<pre>from .halo_callbacks import \</pre>
<ul><li><p>add_callback</p></li></ul>
<p>+    add_callback</p>
<pre>from .halo_finding_methods import \</pre>
<ul><li><p>add_finding_method</p></li></ul>
<p>+    add_finding_method</p>
<pre>from .halo_filters import \</pre>
<ul><li><p>add_filter</p></li></ul>
<p>+    add_filter</p>
<pre>from .halo_quantities import \</pre>
<ul><li><p>add_quantity</p></li></ul>
<p>+    add_quantity + +from .halo_recipes import \ +    add_recipe</p>
<p>diff -r ee78f27e30fbc234af0d10107fc4022f5d42d1d9 -r 7d98d561e68cde5957a324cf1c6d6e3d92b43674 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 @@ -76,7 +76,7 @@</p>
<pre>factor : float
    Factor to be multiplied by the base radius for defining
    the radius of the sphere.</pre>
<ul><li><p>Defautl: 1.0.</p></li></ul>
<p>+        Default: 1.0.</p>
<pre>field_parameters : dict
    Dictionary of field parameters to be set with the sphere
    created.</pre>
<p>@@ -166,8 +166,7 @@</p>
<pre>bin_fields : list of strings
    The binning fields for the profile.
profile_fields : string or list of strings</pre>
<ul><li><p>The fields to be propython</p></li>
<li><p>filed.</p></li></ul>
<p>+        The fields to be profiled.</p>
<pre>n_bins : int or list of ints
    The number of bins in each dimension.  If None, 32 bins for
    each bin are used for each bin field.</pre>
<p>diff -r ee78f27e30fbc234af0d10107fc4022f5d42d1d9 -r 7d98d561e68cde5957a324cf1c6d6e3d92b43674 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 @@ -35,6 +35,8 @@</p>
<pre>    finding_method_registry
from .halo_quantities import \
    quantity_registry</pre>
<p>+from .halo_recipes import \ +    recipe_registry</p>
<pre>class HaloCatalog(ParallelAnalysisInterface):
    r"""Create a HaloCatalog: an object that allows for the creation and association</pre>
<p>@@ -257,6 +259,46 @@</p>
<pre>        halo_filter = filter_registry.find(halo_filter, *args, **kwargs)
        self.actions.append(("filter", halo_filter))
</pre>
<p>+    def add_recipe(self, recipe, *args, **kwargs): +        r""" +        Add a recipe to the halo catalog action list. + +        A recipe is an operation consisting of a series of callbacks, quantities, +        and/or filters called in succession.  Recipes can be used to store a more +        complex series of analysis tasks as a single entity. + +        Parameters +        ---------- +        halo_recipe : string +            The name of the recipe. + +        Examples +        -------- + +        >>> import yt +        >>> from yt.analysis_modules.halo_analysis.api import HaloCatalog +        >>> +        >>> data_ds = yt.load('Enzo_64/RD0006/RedshiftOutput0006') +        >>> halos_ds = yt.load('rockstar_halos/halos_0.0.bin') +        >>> hc = HaloCatalog(data_ds=data_ds, halos_ds=halos_ds) +        >>> +        >>> # Filter out less massive halos +        >>> hc.add_filter("quantity_value", “particle_mass”, “>”, 1e14, “Msun”) +        >>> +        >>> # Calculate virial radii +        >>> hc.add_recipe("calculate_virial_quantities", ["radius", "matter_mass"]) +        >>> +        >>> hc.create() + +        Available Recipes +        ----------------- +        calculate_virial_quantities + +        """ + +        halo_recipe = recipe_registry.find(recipe, *args, **kwargs) +        halo_recipe(self) +</p>
<pre>def create(self, save_halos=False, save_catalog=True, njobs=-1, dynamic=False):
    r"""
    Create the halo catalog given the callbacks, quantities, and filters that</pre>
<p>diff -r ee78f27e30fbc234af0d10107fc4022f5d42d1d9 -r 7d98d561e68cde5957a324cf1c6d6e3d92b43674 yt/analysis_modules/halo_analysis/halo_recipes.py --- /dev/null +++ b/yt/analysis_modules/halo_analysis/halo_recipes.py @@ -0,0 +1,107 @@ +""" +Halo recipe object + + + +""" + +#----------------------------------------------------------------------------- +# Copyright © 2016, 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. +#----------------------------------------------------------------------------- + +from yt.utilities.operator_registry import \ +    OperatorRegistry + +recipe_registry = OperatorRegistry() + +def add_recipe(name, function): +    recipe_registry[name] =  HaloRecipe(function) + +class HaloRecipe(object): +    r""" +    A HaloRecipe is a function that minimally takes in a Halo object +    and performs some analysis on it.  This function may attach attributes +    to the Halo object, write out data, etc, but does not return anything. +    """ +    def __init__(self, function, args=None, kwargs=None): +        self.function = function +        self.args = args +        if self.args is None: self.args = [] +        self.kwargs = kwargs +        if self.kwargs is None: self.kwargs = {} + +    def __call__(self, halo_catalog): +        return self.function(halo_catalog, *self.args, **self.kwargs) + +def calculate_virial_quantities(hc, fields, +                                weight_field=None, accumulation=True, +                                radius_field="virial_radius", factor=2.0, +                                overdensity_field=("gas", “overdensity"), +                                critical_overdensity=200): +    r""" +    Calculate virial quantities with the following procedure: +    1. Create a sphere data container. +    2. Create 1D radial profiles of overdensity and any requested fields. +    3. Call virial_quantities callback to interpolate profiles for +       value of critical overdensity. +    4. Delete profile and sphere objects from halo. + +    Parameters +    ---------- +    halo : Halo object +        The Halo object to be provided by the HaloCatalog. +    fields: string or list of strings +        The fields for which virial values are to be calculated. +    weight_field : string +        Weight field for profiling. +        Default : “cell_mass” +    accumulation : bool or list of bools +        If True, the profile values for a bin n are the cumulative sum of +        all the values from bin 0 to n.  If -True, the sum is reversed so +        that the value for bin n is the cumulative sum from bin N (total bins) +        to n.  If the profile is 2D or 3D, a list of values can be given to +        control the summation in each dimension independently. +        Default: False. +    radius_field : string +        Field to be retrieved from the quantities dictionary as +        the basis of the halo radius. +        Default: “virial_radius”. +    factor : float +        Factor to be multiplied by the base radius for defining +        the radius of the sphere. +        Default: 2.0. +    overdensity_field : string or tuple of strings +        The field used as the overdensity from which interpolation is done to +        calculate virial quantities. +        Default: ("gas”, “overdensity”) +    critical_overdensity : float +        The value of the overdensity at which to evaulate the virial quantities. +        Overdensity is with respect to the critical density. +        Default: 200 + +    """ + +    storage = “virial_quantities_profiles” +    pfields = [field for field in fields if field != “radius”] + +    hc.add_callback("sphere", factor=factor) +    if pfields: +        hc.add_callback("profile", ["radius"], pfields, +                        weight_field=weight_field, +                        accumulation=accumulation, +                        storage=storage) +    hc.add_callback("profile", ["radius"], [overdensity_field], +                    weight_field="cell_volume", accumulation=True, +                    storage=storage) +    hc.add_callback("virial_quantities", fields, +                    overdensity_field=overdensity_field, +                    critical_overdensity=critical_overdensity, +                    profile_storage=storage) +    hc.add_callback("delete_attribute", storage) +    hc.add_callback("delete_attribute", “data_object”) + +add_recipe("calculate_virial_quantities", calculate_virial_quantities)</p>
<p>Repository URL: <a href="http://link.bitbucket.org/wf/click?upn=8USRlNyft-2BCzk2l4Ywl6gDx2lD2xxoS9E7MwXb2SMR-2BI0v8SbQq-2B8-2FZaaHaJT85r_ll4ctv0L-2ByeRZFC1LslHcg6aJmnQ70VruLbmeLQr27ASmtSKNGFKr1dQ2QCSDW0xsQXA1fneCMfdlKyrTwzMrACfLwhZTweYXkWtQG8ZiP-2BTEPnzR-2FRKaSu3rmtvW96KM0JcsjYKO5cCBX2P0xuHlh9yYQsNdeRTlCSxd77X-2Bn49FXs9GkUuTb9bdu-2Fs8mpmFdV40DF7PcOElzzyvV4mLFPBJSa6FR-2Fy-2Fn7hM5NDuCw-3D">https://bitbucket.org/yt_analysis/yt/</a></p>
<p>—</p>
<p>This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.</p>

<img src="http://link.bitbucket.org/wf/open?upn=ll4ctv0L-2ByeRZFC1LslHcg6aJmnQ70VruLbmeLQr27ASmtSKNGFKr1dQ2QCSDW0xsQXA1fneCMfdlKyrTwzMrKlDsS1XbVc18q6SfpTuUJc8gRwgwUlheJhLdOIEOrA8DX7xi8CI3eb7u2JUSGsqSKsNYgvjwf3QOGcHMH-2BRFfQln3GmvvuNIJQN7xY3ETVqTf2tQ8kRQ3tHi6AsRI27Va4sYPy-2FitdMbvhIWEunkdg-3D" alt="" width="1" height="1" border="0" style="height:1px !important;width:1px !important;border-width:0 !important;margin-top:0 !important;margin-bottom:0 !important;margin-right:0 !important;margin-left:0 !important;padding-top:0 !important;padding-bottom:0 !important;padding-right:0 !important;padding-left:0 !important;"/>
</body></html>