[Yt-svn] yt-commit r1126 - trunk/yt/lagos

britton at wrangler.dreamhost.com britton at wrangler.dreamhost.com
Sat Jan 17 12:43:53 PST 2009


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()



More information about the yt-svn mailing list