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>