[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