Hi everyone,<br><br>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.<br><br>Britton<br>
<div class="gmail_quote"><br>Author: britton<br>
Date: Sat Jan 17 12:43:53 2009<br>
New Revision: 1126<br>
URL: <a href="http://yt.spacepope.org/changeset/1126" target="_blank">http://yt.spacepope.org/changeset/1126</a><br>
<br>
Log:<br>
Added clump_info attribute to Clump objects.  clump_info is an list of<br>
dictionaries, each with two entries: "quantity" and "format".  The<br>
quantity entry contains a string representing the function to be called to get<br>
some Clump quantity or quantities.  The format entry contains another string<br>
that controls the format that the quantity is to be written out.  Both are<br>
used with eval statemets by the new Clump info writing method, write_info.  The<br>
method, write_info, is called by the write_clumps and write_clump_hierarchy<br>
routines.<br>
<br>
This allows the user to add their own quantities to the list to be printed out<br>
by write_clumps and write_clump_hierarchy.  This is done by the Clump method<br>
add_info_item, which takes arguments quantity and format to be added to the<br>
clump_info list.  After adding the entry to the clump_info list, the method<br>
is called for each of the clumps children in a recursive fashion so that all<br>
children in the hierarchy have the same clump_info list.  The Clump __init__<br>
function now also accepts the keyword, clump_info, so that clump_info traits<br>
can be passed down at instantiation.  This means that add_info_item can be<br>
called either before or after the clump finding is done.<br>
<br>
If clump objects are instantiated with no entries in clump_info, the method,<br>
set_default_clump_info is called to add the standard info items that were<br>
printed out by the old writing functions.  This means that by running the clump<br>
finder the way it has always been run, you will get the same output as before.<br>
Check out this method for examples of proper calls to add_info_item.<br>
<br>
The clump_info list can be cleared with the clear_clump_info method.<br>
<br>
Clump objects now also contain a method called "pass_down", which allows the<br>
user to pass down any sort of command that is to be executed by all clumps in<br>
the hierarchy.  The argument to pass_down is given as a string to be<br>
executed with eval.  For example, this allows the user to define clump<br>
characteristics for each clump that depend on external data not known before<br>
clump finding.  One specific example would be a clump info item that is the<br>
distance from the center of mass of the master clump.<br>
<br>
Finally, for backwards compatibility, the original clump writing functions have<br>
been kept around as write_old_clumps and write_old_clump_hierarchy.<br>
<br>
<br>
Modified:<br>
   trunk/yt/lagos/Clump.py<br>
<br>
Modified: trunk/yt/lagos/Clump.py<br>
==============================================================================<br>
--- trunk/yt/lagos/Clump.py     (original)<br>
+++ trunk/yt/lagos/Clump.py     Sat Jan 17 12:43:53 2009<br>
@@ -22,13 +22,13 @@<br>
   along with this program.  If not, see <<a href="http://www.gnu.org/licenses/" target="_blank">http://www.gnu.org/licenses/</a>>.<br>
 """<br>
<br>
-<br>
 from yt.lagos import *<br>
 import numpy as na<br>
+import copy<br>
<br>
 class Clump(object):<br>
     children = None<br>
-    def __init__(self, data, parent, field, cached_fields = None, function=None):<br>
+    def __init__(self, data, parent, field, cached_fields = None, function=None, clump_info=None):<br>
         self.parent = parent<br>
         self.data = data<br>
         self.field = field<br>
@@ -36,6 +36,14 @@<br>
         self.max = self.data[field].max()<br>
         self.cached_fields = cached_fields<br>
<br>
+        # List containing characteristics about clumps that are to be written<br>
+        # out by the write routines.<br>
+        if clump_info is None:<br>
+            self.set_default_clump_info()<br>
+        else:<br>
+            # Clump info will act the same if add_info_item is called before or after clump finding.<br>
+            self.clump_info = copy.deepcopy(clump_info)<br>
+<br>
         # Function determining whether a clump is valid and should be kept.<br>
         self.default_function = 'self.data.quantities["IsBound"](truncate=True,include_thermal_energy=True) > 1.0'<br>
         if function is None:<br>
@@ -46,14 +54,53 @@<br>
         # Return value of validity function, saved so it does not have to be calculated again.<br>
         self.function_value = None<br>
<br>
-    def _isValid(self):<br>
-        "Perform user specified function to determine if child clumps should be kept."<br>
-<br>
-        # Only call function is it has not been already.<br>
-        if self.function_value is None:<br>
-            self.function_value = eval(self.function)<br>
+    def add_info_item(self,quantity,format):<br>
+        "Adds an entry to clump_info list and tells children to do the same."<br>
<br>
-        return self.function_value<br>
+        self.clump_info.append({'quantity':quantity, 'format':format})<br>
+        if self.children is None: return<br>
+        for child in self.children:<br>
+            child.add_info_item(quantity,format)<br>
+<br>
+    def set_default_clump_info(self):<br>
+        "Defines default entries in the clump_info array."<br>
+<br>
+        # add_info_item is recursive so this function does not need to be.<br>
+        self.clump_info = []<br>
+<br>
+        # Number of cells.<br>
+        self.add_info_item('self.data["CellMassMsun"].size','"Cells: %d" % value')<br>
+        # Gas mass in solar masses.<br>
+        self.add_info_item('self.data["CellMassMsun"].sum()','"Mass: %e Msolar" % value')<br>
+        # Volume-weighted Jeans mass.<br>
+        self.add_info_item('self.data.quantities["WeightedAverageQuantity"]("JeansMassMsun","CellVolume")',<br>
+                           '"Jeans Mass (vol-weighted): %.6e Msolar" % value')<br>
+        # Mass-weighted Jeans mass.<br>
+        self.add_info_item('self.data.quantities["WeightedAverageQuantity"]("JeansMassMsun","CellMassMsun")',<br>
+                           '"Jeans Mass (mass-weighted): %.6e Msolar" % value')<br>
+        # Max level.<br>
+        self.add_info_item('self.data["GridLevel"].max()','"Max grid level: %d" % value')<br>
+        # Minimum number density.<br>
+        self.add_info_item('self.data["NumberDensity"].min()','"Min number density: %.6e cm^-3" % value')<br>
+        # Maximum number density.<br>
+        self.add_info_item('self.data["NumberDensity"].max()','"Max number density: %.6e cm^-3" % value')<br>
+<br>
+    def clear_clump_info(self):<br>
+        "Clears the clump_info array and passes the instruction to its children."<br>
+<br>
+        self.clump_info = []<br>
+        if self.children is None: return<br>
+        for child in self.children:<br>
+            child.clear_clump_info()<br>
+<br>
+    def write_info(self,level,f_ptr):<br>
+        "Writes information for clump using the list of items in clump_info."<br>
+<br>
+        for item in self.clump_info:<br>
+            value = eval(item['quantity'])<br>
+            output = eval(item['format'])<br>
+            f_ptr.write("%s%s" % ('\t'*level,output))<br>
+            f_ptr.write("\n")<br>
<br>
     def find_children(self, min, max = None):<br>
         if self.children is not None:<br>
@@ -65,22 +112,41 @@<br>
         for cid in contour_info:<br>
             new_clump = self.data.extract_region(contour_info[cid])<br>
             self.children.append(Clump(new_clump, self, self.field,<br>
-                                    self.cached_fields,function=self.function))<br>
+                                       self.cached_fields,function=self.function,<br>
+                                       clump_info=self.clump_info))<br>
+<br>
+    def pass_down(self,operation):<br>
+        "Performs an operation on a clump with an exec and passes the instruction down to clump children."<br>
+<br>
+        exec(operation)<br>
+<br>
+        for child in self.children:<br>
+            child.pass_down(operation)<br>
+<br>
+    def _isValid(self):<br>
+        "Perform user specified function to determine if child clumps should be kept."<br>
+<br>
+        # Only call function if it has not been already.<br>
+        if self.function_value is None:<br>
+            self.function_value = eval(self.function)<br>
+<br>
+        return self.function_value<br>
<br>
     def __reduce__(self):<br>
         return (_reconstruct_clump,<br>
                 (self.parent, self.field, self.min, self.max,<br>
-                 self.function_value, self.children, self.data, self.function))<br>
+                 self.function_value, self.children, self.data, self.clump_info, self.function))<br>
<br>
     def __getitem__(self,request):<br>
         return self.data[request]<br>
-def _reconstruct_clump(parent, field, mi, ma, function_value, children, data,<br>
+<br>
+def _reconstruct_clump(parent, field, mi, ma, function_value, children, data, clump_info,<br>
         function=None):<br>
     obj = object.__new__(Clump)<br>
     if iterable(parent): parent = parent[1]<br>
     if children is None: children = []<br>
-    obj.parent, obj.field, obj.min, obj.max, obj.function_value, \<br>
-       obj.children, obj.function = parent, field, mi, ma, function_value, children, function<br>
+    obj.parent, obj.field, obj.min, obj.max, obj.function_value, obj.children, obj.clump_info, obj.function = \<br>
+        parent, field, mi, ma, function_value, children, clump_info, function<br>
     # Now we override, because the parent/child relationship seems a bit<br>
     # unreliable in the unpickling<br>
     for child in children: child.parent = obj<br>
@@ -117,12 +183,11 @@<br>
             print "%d of %d children survived, erasing children." % (len(these_children),len(clump.children))<br>
             clump.children = []<br>
<br>
-<br>
 def write_clump_hierarchy(clump,level,f_ptr):<br>
     for q in range(level):<br>
         f_ptr.write("\t")<br>
     f_ptr.write("Clump at level %d:\n" % level)<br>
-    write_clump_info(clump,level,f_ptr)<br>
+    clump.write_info(level,f_ptr)<br>
     f_ptr.write("\n")<br>
     f_ptr.flush()<br>
     if ((clump.children is not None) and (len(clump.children) > 0)):<br>
@@ -132,7 +197,30 @@<br>
 def write_clumps(clump,level,f_ptr):<br>
     if ((clump.children is None) or (len(clump.children) == 0)):<br>
         f_ptr.write("%sClump:\n" % ("\t"*level))<br>
-        write_clump_info(clump,level,f_ptr)<br>
+        clump.write_info(level,f_ptr)<br>
+        f_ptr.write("\n")<br>
+        f_ptr.flush()<br>
+    if ((clump.children is not None) and (len(clump.children) > 0)):<br>
+        for child in clump.children:<br>
+            write_clumps(child,0,f_ptr)<br>
+<br>
+# Old clump info writing routines.<br>
+def write_old_clump_hierarchy(clump,level,f_ptr):<br>
+    for q in range(level):<br>
+        f_ptr.write("\t")<br>
+    f_ptr.write("Clump at level %d:\n" % level)<br>
+    clump.write_info(level,f_ptr)<br>
+    write_old_clump_info(clump,level,f_ptr)<br>
+    f_ptr.write("\n")<br>
+    f_ptr.flush()<br>
+    if ((clump.children is not None) and (len(clump.children) > 0)):<br>
+        for child in clump.children:<br>
+            write_clump_hierarchy(child,(level+1),f_ptr)<br>
+<br>
+def write_old_clumps(clump,level,f_ptr):<br>
+    if ((clump.children is None) or (len(clump.children) == 0)):<br>
+        f_ptr.write("%sClump:\n" % ("\t"*level))<br>
+        write_old_clump_info(clump,level,f_ptr)<br>
         f_ptr.write("\n")<br>
         f_ptr.flush()<br>
     if ((clump.children is not None) and (len(clump.children) > 0)):<br>
@@ -151,7 +239,7 @@<br>
<br>
 """<br>
<br>
-def write_clump_info(clump,level,f_ptr):<br>
+def write_old_clump_info(clump,level,f_ptr):<br>
     fmt_dict = {'tl':  "\t" * level}<br>
     fmt_dict['num_cells'] = clump.data["CellMassMsun"].size,<br>
     fmt_dict['total_mass'] = clump.data["CellMassMsun"].sum()<br>
_______________________________________________<br>
Yt-svn mailing list<br>
<a href="mailto:Yt-svn@lists.spacepope.org">Yt-svn@lists.spacepope.org</a><br>
<a href="http://lists.spacepope.org/listinfo.cgi/yt-svn-spacepope.org" target="_blank">http://lists.spacepope.org/listinfo.cgi/yt-svn-spacepope.org</a><br>
</div><br>