[Yt-dev] Fwd: [Yt-svn] yt-commit r1126 - trunk/yt/lagos

Britton Smith brittonsmith at gmail.com
Sat Jan 17 15:29:46 PST 2009


Hi everyone,

I made a sizable update to the Clump class, allowing far more flexibility in
the type of output you get from the clump finder.  In case anyone is
interested, here's the commit log.

Britton

Author: britton
Date: Sat Jan 17 12:43:53 2009
New Revision: 1126
URL: http://yt.spacepope.org/changeset/1126

Log:
Added clump_info attribute to Clump objects.  clump_info is an list of
dictionaries, each with two entries: "quantity" and "format".  The
quantity entry contains a string representing the function to be called to
get
some Clump quantity or quantities.  The format entry contains another string
that controls the format that the quantity is to be written out.  Both are
used with eval statemets by the new Clump info writing method, write_info.
 The
method, write_info, is called by the write_clumps and write_clump_hierarchy
routines.

This allows the user to add their own quantities to the list to be printed
out
by write_clumps and write_clump_hierarchy.  This is done by the Clump method
add_info_item, which takes arguments quantity and format to be added to the
clump_info list.  After adding the entry to the clump_info list, the method
is called for each of the clumps children in a recursive fashion so that all
children in the hierarchy have the same clump_info list.  The Clump __init__
function now also accepts the keyword, clump_info, so that clump_info traits
can be passed down at instantiation.  This means that add_info_item can be
called either before or after the clump finding is done.

If clump objects are instantiated with no entries in clump_info, the method,
set_default_clump_info is called to add the standard info items that were
printed out by the old writing functions.  This means that by running the
clump
finder the way it has always been run, you will get the same output as
before.
Check out this method for examples of proper calls to add_info_item.

The clump_info list can be cleared with the clear_clump_info method.

Clump objects now also contain a method called "pass_down", which allows the
user to pass down any sort of command that is to be executed by all clumps
in
the hierarchy.  The argument to pass_down is given as a string to be
executed with eval.  For example, this allows the user to define clump
characteristics for each clump that depend on external data not known before
clump finding.  One specific example would be a clump info item that is the
distance from the center of mass of the master clump.

Finally, for backwards compatibility, the original clump writing functions
have
been kept around as write_old_clumps and write_old_clump_hierarchy.


Modified:
  trunk/yt/lagos/Clump.py

Modified: trunk/yt/lagos/Clump.py
==============================================================================
--- trunk/yt/lagos/Clump.py     (original)
+++ trunk/yt/lagos/Clump.py     Sat Jan 17 12:43:53 2009
@@ -22,13 +22,13 @@
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """

-
 from yt.lagos import *
 import numpy as na
+import copy

 class Clump(object):
    children = None
-    def __init__(self, data, parent, field, cached_fields = None,
function=None):
+    def __init__(self, data, parent, field, cached_fields = None,
function=None, clump_info=None):
        self.parent = parent
        self.data = data
        self.field = field
@@ -36,6 +36,14 @@
        self.max = self.data[field].max()
        self.cached_fields = cached_fields

+        # List containing characteristics about clumps that are to be
written
+        # out by the write routines.
+        if clump_info is None:
+            self.set_default_clump_info()
+        else:
+            # Clump info will act the same if add_info_item is called
before or after clump finding.
+            self.clump_info = copy.deepcopy(clump_info)
+
        # Function determining whether a clump is valid and should be kept.
        self.default_function =
'self.data.quantities["IsBound"](truncate=True,include_thermal_energy=True)
> 1.0'
        if function is None:
@@ -46,14 +54,53 @@
        # Return value of validity function, saved so it does not have to be
calculated again.
        self.function_value = None

-    def _isValid(self):
-        "Perform user specified function to determine if child clumps
should be kept."
-
-        # Only call function is it has not been already.
-        if self.function_value is None:
-            self.function_value = eval(self.function)
+    def add_info_item(self,quantity,format):
+        "Adds an entry to clump_info list and tells children to do the
same."

-        return self.function_value
+        self.clump_info.append({'quantity':quantity, 'format':format})
+        if self.children is None: return
+        for child in self.children:
+            child.add_info_item(quantity,format)
+
+    def set_default_clump_info(self):
+        "Defines default entries in the clump_info array."
+
+        # add_info_item is recursive so this function does not need to be.
+        self.clump_info = []
+
+        # Number of cells.
+        self.add_info_item('self.data["CellMassMsun"].size','"Cells: %d" %
value')
+        # Gas mass in solar masses.
+        self.add_info_item('self.data["CellMassMsun"].sum()','"Mass: %e
Msolar" % value')
+        # Volume-weighted Jeans mass.
+
 self.add_info_item('self.data.quantities["WeightedAverageQuantity"]("JeansMassMsun","CellVolume")',
+                           '"Jeans Mass (vol-weighted): %.6e Msolar" %
value')
+        # Mass-weighted Jeans mass.
+
 self.add_info_item('self.data.quantities["WeightedAverageQuantity"]("JeansMassMsun","CellMassMsun")',
+                           '"Jeans Mass (mass-weighted): %.6e Msolar" %
value')
+        # Max level.
+        self.add_info_item('self.data["GridLevel"].max()','"Max grid level:
%d" % value')
+        # Minimum number density.
+        self.add_info_item('self.data["NumberDensity"].min()','"Min number
density: %.6e cm^-3" % value')
+        # Maximum number density.
+        self.add_info_item('self.data["NumberDensity"].max()','"Max number
density: %.6e cm^-3" % value')
+
+    def clear_clump_info(self):
+        "Clears the clump_info array and passes the instruction to its
children."
+
+        self.clump_info = []
+        if self.children is None: return
+        for child in self.children:
+            child.clear_clump_info()
+
+    def write_info(self,level,f_ptr):
+        "Writes information for clump using the list of items in
clump_info."
+
+        for item in self.clump_info:
+            value = eval(item['quantity'])
+            output = eval(item['format'])
+            f_ptr.write("%s%s" % ('\t'*level,output))
+            f_ptr.write("\n")

    def find_children(self, min, max = None):
        if self.children is not None:
@@ -65,22 +112,41 @@
        for cid in contour_info:
            new_clump = self.data.extract_region(contour_info[cid])
            self.children.append(Clump(new_clump, self, self.field,
-
 self.cached_fields,function=self.function))
+
self.cached_fields,function=self.function,
+                                       clump_info=self.clump_info))
+
+    def pass_down(self,operation):
+        "Performs an operation on a clump with an exec and passes the
instruction down to clump children."
+
+        exec(operation)
+
+        for child in self.children:
+            child.pass_down(operation)
+
+    def _isValid(self):
+        "Perform user specified function to determine if child clumps
should be kept."
+
+        # Only call function if it has not been already.
+        if self.function_value is None:
+            self.function_value = eval(self.function)
+
+        return self.function_value

    def __reduce__(self):
        return (_reconstruct_clump,
                (self.parent, self.field, self.min, self.max,
-                 self.function_value, self.children, self.data,
self.function))
+                 self.function_value, self.children, self.data,
self.clump_info, self.function))

    def __getitem__(self,request):
        return self.data[request]
-def _reconstruct_clump(parent, field, mi, ma, function_value, children,
data,
+
+def _reconstruct_clump(parent, field, mi, ma, function_value, children,
data, clump_info,
        function=None):
    obj = object.__new__(Clump)
    if iterable(parent): parent = parent[1]
    if children is None: children = []
-    obj.parent, obj.field, obj.min, obj.max, obj.function_value, \
-       obj.children, obj.function = parent, field, mi, ma, function_value,
children, function
+    obj.parent, obj.field, obj.min, obj.max, obj.function_value,
obj.children, obj.clump_info, obj.function = \
+        parent, field, mi, ma, function_value, children, clump_info,
function
    # Now we override, because the parent/child relationship seems a bit
    # unreliable in the unpickling
    for child in children: child.parent = obj
@@ -117,12 +183,11 @@
            print "%d of %d children survived, erasing children." %
(len(these_children),len(clump.children))
            clump.children = []

-
 def write_clump_hierarchy(clump,level,f_ptr):
    for q in range(level):
        f_ptr.write("\t")
    f_ptr.write("Clump at level %d:\n" % level)
-    write_clump_info(clump,level,f_ptr)
+    clump.write_info(level,f_ptr)
    f_ptr.write("\n")
    f_ptr.flush()
    if ((clump.children is not None) and (len(clump.children) > 0)):
@@ -132,7 +197,30 @@
 def write_clumps(clump,level,f_ptr):
    if ((clump.children is None) or (len(clump.children) == 0)):
        f_ptr.write("%sClump:\n" % ("\t"*level))
-        write_clump_info(clump,level,f_ptr)
+        clump.write_info(level,f_ptr)
+        f_ptr.write("\n")
+        f_ptr.flush()
+    if ((clump.children is not None) and (len(clump.children) > 0)):
+        for child in clump.children:
+            write_clumps(child,0,f_ptr)
+
+# Old clump info writing routines.
+def write_old_clump_hierarchy(clump,level,f_ptr):
+    for q in range(level):
+        f_ptr.write("\t")
+    f_ptr.write("Clump at level %d:\n" % level)
+    clump.write_info(level,f_ptr)
+    write_old_clump_info(clump,level,f_ptr)
+    f_ptr.write("\n")
+    f_ptr.flush()
+    if ((clump.children is not None) and (len(clump.children) > 0)):
+        for child in clump.children:
+            write_clump_hierarchy(child,(level+1),f_ptr)
+
+def write_old_clumps(clump,level,f_ptr):
+    if ((clump.children is None) or (len(clump.children) == 0)):
+        f_ptr.write("%sClump:\n" % ("\t"*level))
+        write_old_clump_info(clump,level,f_ptr)
        f_ptr.write("\n")
        f_ptr.flush()
    if ((clump.children is not None) and (len(clump.children) > 0)):
@@ -151,7 +239,7 @@

 """

-def write_clump_info(clump,level,f_ptr):
+def write_old_clump_info(clump,level,f_ptr):
    fmt_dict = {'tl':  "\t" * level}
    fmt_dict['num_cells'] = clump.data["CellMassMsun"].size,
    fmt_dict['total_mass'] = clump.data["CellMassMsun"].sum()
_______________________________________________
Yt-svn mailing list
Yt-svn at lists.spacepope.org
http://lists.spacepope.org/listinfo.cgi/yt-svn-spacepope.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.spacepope.org/pipermail/yt-dev-spacepope.org/attachments/20090117/0968879d/attachment.html>


More information about the yt-dev mailing list