[Yt-svn] yt: 2 new changesets

hg at spacepope.org hg at spacepope.org
Wed Mar 24 00:23:54 PDT 2010


hg Repository: yt
details:   yt/rev/f3711bc5f358
changeset: 1466:f3711bc5f358
user:      Matthew Turk <matthewturk at gmail.com>
date:
Wed Mar 24 00:22:51 2010 -0700
description:
Adding some objects that can utilize IPython for remote image windowing.
Future enhancements will include auto-generation of extents, but for now it
nicely distributes the pixelization process, if you ask it just right.

hg Repository: yt
details:   yt/rev/ec150b6d629b
changeset: 1467:ec150b6d629b
user:      Matthew Turk <matthewturk at gmail.com>
date:
Wed Mar 24 00:23:49 2010 -0700
description:
Merging image panning in

diffstat:

 yt/extensions/StarAnalysis.py                     |   15 ++-
 yt/extensions/image_panner/__init__.py            |    2 +-
 yt/extensions/image_panner/pan_and_scan_widget.py |    3 +
 yt/extensions/image_panner/vm_panner.py           |  120 +++++++++++++++++++++++-
 yt/lagos/HaloFinding.py                           |    4 +-
 yt/lagos/kd.py                                    |    2 +-
 yt/lagos/parallelHOP/parallelHOP.py               |    5 +-
 7 files changed, 139 insertions(+), 12 deletions(-)

diffs (275 lines):

diff -r 1aa6eb842a66 -r ec150b6d629b yt/extensions/StarAnalysis.py
--- a/yt/extensions/StarAnalysis.py	Sun Mar 21 14:58:21 2010 -0700
+++ b/yt/extensions/StarAnalysis.py	Wed Mar 24 00:23:49 2010 -0700
@@ -215,7 +215,7 @@
     
     def calculate_spectrum(self, data_source=None, star_mass=None,
             star_creation_time=None, star_metallicity_fraction=None,
-            star_metallicity_constant=None):
+            star_metallicity_constant=None, min_age=0.):
         """
         For the set of stars, calculate the collective spectrum.
         Attached to the output are several useful objects:
@@ -233,6 +233,8 @@
         metallicity fractions, in code units (which is not Z/Zsun).
         :param star_metallicity_constant (float): If desired, override the star
         metallicity fraction of all the stars to the given value.
+        :param min_age (float): Removes young stars below this number (in years
+        from the spectrum. Default: 0 (all stars).
         """
         # Initialize values
         self.final_spec = na.zeros(self.wavelength.size, dtype='float64')
@@ -240,6 +242,7 @@
         self.star_mass = star_mass
         self.star_creation_time = star_creation_time
         self.star_metal = star_metallicity_fraction
+        self.min_age = min_age
         
         # Check to make sure we have the right set of data.
         if data_source is None:
@@ -273,8 +276,13 @@
         self.star_metal /= Zsun
         # Age of star in years.
         dt = (self.time_now - self.star_creation_time * self._pf['Time']) / YEAR
+        # Remove young stars
+        sub = dt > self.min_age
+        self.star_metal = self.star_metal[sub]
+        dt = dt[sub]
+        self.star_creation_time = self.star_creation_time[sub]
         # Figure out which METALS bin the star goes into.
-        Mindex = na.digitize(dt, METALS)
+        Mindex = na.digitize(self.star_metal, METALS)
         # Replace the indices with strings.
         Mname = MtoD[Mindex]
         # Figure out which age bin this star goes into.
@@ -284,7 +292,8 @@
         ratio2 = (self.age[Aindex] - dt) / (self.age[Aindex] - self.age[Aindex-1])
         # Sort the stars by metallicity and then by age, which should reduce
         # memory access time by a little bit in the loop.
-        sort = na.lexsort((Aindex, Mname))
+        indexes = na.arange(self.star_metal.size)
+        sort = na.asarray([indexes[i] for i in na.lexsort([indexes, Aindex, Mname])])
         Mname = Mname[sort]
         Aindex = Aindex[sort]
         ratio1 = ratio1[sort]
diff -r 1aa6eb842a66 -r ec150b6d629b yt/extensions/image_panner/__init__.py
--- a/yt/extensions/image_panner/__init__.py	Sun Mar 21 14:58:21 2010 -0700
+++ b/yt/extensions/image_panner/__init__.py	Wed Mar 24 00:23:49 2010 -0700
@@ -22,4 +22,4 @@
 """
 
 from vm_panner import VariableMeshPanner, WindowedVariableMeshPanner, \
-                MultipleWindowVariableMeshPanner
+                MultipleWindowVariableMeshPanner, ImageSaver
diff -r 1aa6eb842a66 -r ec150b6d629b yt/extensions/image_panner/pan_and_scan_widget.py
--- a/yt/extensions/image_panner/pan_and_scan_widget.py	Sun Mar 21 14:58:21 2010 -0700
+++ b/yt/extensions/image_panner/pan_and_scan_widget.py	Wed Mar 24 00:23:49 2010 -0700
@@ -41,6 +41,7 @@
 class VariableMeshPannerView(HasTraits):
 
     plot = Instance(Plot)
+    pd = Instance(ArrayPlotData)
     panner = Instance(VariableMeshPanner)
     fid = Instance(FunctionImageData)
     limits = Button
@@ -59,6 +60,7 @@
         super(VariableMeshPannerView, self).__init__(**kwargs)
         # Create the plot
         pd = ArrayPlotData()
+        self.pd = pd
         fid = FunctionImageData(func = self.panner.set_low_high)
         self.fid = fid
         bounds = self.panner.bounds
@@ -84,4 +86,5 @@
         self.plot = plot
 
     def _limits_fired(self):
+        print self.pd["imagedata"].min(), self.pd["imagedata"].max(),
         print self.fid.data.min(), self.fid.data.max()
diff -r 1aa6eb842a66 -r ec150b6d629b yt/extensions/image_panner/vm_panner.py
--- a/yt/extensions/image_panner/vm_panner.py	Sun Mar 21 14:58:21 2010 -0700
+++ b/yt/extensions/image_panner/vm_panner.py	Wed Mar 24 00:23:49 2010 -0700
@@ -26,12 +26,19 @@
 from yt.lagos import data_object_registry, AMRProjBase, AMRSliceBase, \
                      x_dict, y_dict
 
+class SourceTypeException(Exception):
+    def __init__(self, source):
+        self.source = source
+
+    def __repr__(self):
+        return "Wrong type: %s, %s" % (self.source, type(self.source))
+
 class VariableMeshPanner(object):
     _buffer = None
 
     def __init__(self, source, size, field, callback = None):
         if not isinstance(source, (AMRProjBase, AMRSliceBase)):
-            raise RuntimeError
+            print "PROBLEM WITH SOURCE", source, type(source)
         if callback is None:
             callback = lambda a: None
         self.callback = callback
@@ -160,3 +167,114 @@
 
     def pan_rel_y(self, delta):
         for w in self.windows: w.pan_rel_y(delta)
+
+class RemoteWindowedVariableMeshController(MultipleWindowVariableMeshPanner):
+    def __init__(self, source, mec = None):
+        if mec is None:
+            from IPython.kernel.client import get_multiengine_client
+            mec = get_multiengine_client()
+        self.mec = mec
+        self.mec.execute("import yt.extensions.image_panner")
+        self._var_name = "_image_panner_%s" % (id(self))
+        self._pf_name = "_pf_%s" % (id(self))
+        self._source_name = "_source_%s" % (id(self))
+        self.source = source
+        self.mec.execute("from yt.mods import *")
+        self.mec.execute("from yt.funcs import iterable")
+        self.mec.push({self._pf_name: self.pf})
+        self.mec.execute("%s.h" % self._pf_name)
+        self.mec.push({self._source_name: self.source})
+        # Now, because the double pickling tosses a PF hash reference inside
+        # the unpickled object, we work around it a little
+        self.mec.execute("while iterable(%s): %s = %s[1]" % (
+            self._source_name, self._source_name, self._source_name))
+        self.windows = []
+
+    def add_window(self, *args, **kwargs):
+        engine_id = len(self.windows)
+        an = "_args_%s" % id(self)
+        kn = "_kwargs_%s" % id(self)
+        kwargs['callback'] = ImageSaver(engine_id)
+        self.mec.push({an: args, kn: kwargs}, engine_id)
+        exec_string = "%s = %s.h.windowed_image_panner(%s, *%s, **%s)" % (
+            self._var_name, self._pf_name, self._source_name, an, kn)
+        self.mec.execute(exec_string, engine_id)
+        self.windows.append(WindowedVariableMeshPannerProxy(
+            self.mec, engine_id, self._var_name, id(self)))
+
+data_object_registry["remote_image_panner"] = RemoteWindowedVariableMeshController
+
+_wrapped_methods = ["zoom", "pan", "pan_x", "pan_y", "pan_rel",
+                     "pan_rel_x", "pan_rel_y", "set_low_high"]
+
+class WindowedVariableMeshPannerProxy(object):
+    class __metaclass__(type):
+        def __new__(cls, name, b, d):
+            # We add on a bunch of proxy functions
+            def return_proxy(fname):
+                def func(self, *args, **kwargs):
+                    vn = "_ret_%s" % self._cid
+                    an = "_args_%s" % self._cid
+                    kn = "_kwargs_%s" % self._cid
+                    self.mec.push({an: args, kn: kwargs}, self.engine_id)
+                    self.mec.execute("%s = %s.%s(*%s, **%s)" % (
+                        vn, self._var_name, fname, an, kn), self.engine_id)
+                    return self.mec.pull(vn, self.engine_id)
+                return func
+            new_dict = {}
+            new_dict.update(d)
+            for f in _wrapped_methods:
+                print "Constructing proxy for", f
+                new_dict[f] = return_proxy(f)
+            return type.__new__(cls, name, b, new_dict)
+
+    def __init__(self, mec, engine_id, var_name, cid):
+        # mec here is, optionally, an instance of MultiEngineClient
+        self._var_name = var_name
+        self._cid = cid
+        self.engine_id = engine_id
+        self.mec = mec
+
+    @property
+    def bounds(self):
+        vn = "_ret_%s" % self._cid
+        self.mec.execute("%s = %s.bounds" % (vn, self._var_name),
+                         self.engine_id)
+        return self.mec.pull(vn, self.engine_id)
+
+    @property
+    def width(self):
+        vn = "_ret_%s" % self._cid
+        self.mec.execute("%s = %s.width" % (vn, self._var_name),
+                         self.engine_id)
+        return self.mec.pull(vn, self.engine_id)
+
+    @property
+    def buffer(self):
+        vn = "_ret_%s" % self._cid
+        self.mec.execute("%s = %s.buffer" % (vn, self._var_name),
+                         self.engine_id)
+        return self.mec.pull(vn, self.engine_id)
+
+    def _regenerate_buffer(self):
+        return
+
+class ImageSaver(object):
+    def __init__(self, tile_id):
+        self.tile_id = tile_id
+
+        import matplotlib;matplotlib.use("Agg");import pylab
+        self.pylab = pylab
+        self.pylab.clf()
+        fig = pylab.gcf()
+        fig.subplots_adjust(left=0.0, bottom=0.0,
+                            right=1.0, top=1.0,
+                            wspace=0.0, hspace=0.0)
+        fig.set_dpi(100.0)
+        fig.set_size_inches((5.12, 5.12))
+
+    def __call__(self, val):
+        self.pylab.clf()
+        self.pylab.imshow(na.log10(val), interpolation='nearest')
+        self.pylab.savefig("wimage_%03i.png" % self.tile_id)
+
diff -r 1aa6eb842a66 -r ec150b6d629b yt/lagos/HaloFinding.py
--- a/yt/lagos/HaloFinding.py	Sun Mar 21 14:58:21 2010 -0700
+++ b/yt/lagos/HaloFinding.py	Wed Mar 24 00:23:49 2010 -0700
@@ -1144,7 +1144,7 @@
         # Adaptive subregions by bisection.
         ds_names = ["particle_position_x","particle_position_y","particle_position_z"]
         if ytcfg.getboolean("yt","inline") == False and \
-           resize and self._mpi_get_size() is not None:
+           resize and self._mpi_get_size() != 1:
             cut_list = self._partition_hierarchy_3d_bisection_list()
             for i,cut in enumerate(cut_list):
                 dim = cut[0]
@@ -1180,7 +1180,7 @@
             del bins, counts
         # If this isn't parallel, define the region as an AMRRegionStrict so
         # particle IO works.
-        if self._mpi_get_size() == None or self._mpi_get_size() == 1:
+        if self._mpi_get_size() == 1:
             self._data_source = self.hierarchy.periodic_region_strict([0.5]*3, LE, RE)
         # get the average spacing between particles for this region
         # The except is for the serial case, where the full box is what we want.
diff -r 1aa6eb842a66 -r ec150b6d629b yt/lagos/kd.py
--- a/yt/lagos/kd.py	Sun Mar 21 14:58:21 2010 -0700
+++ b/yt/lagos/kd.py	Wed Mar 24 00:23:49 2010 -0700
@@ -223,7 +223,7 @@
     
     # if this node is close enough (the distances are calculated in the previous
     # iteration), or if the query point is inside the node, continue on
-    if (neighbors.minDistanceSquared > distanceSquared) or inside:
+    if True or inside:
         # leafs don't have children, so this tests to see if this node
         # is a leaf, and if it is a leaf, calculate distances to the query point
         if (node.leftChild is None):
diff -r 1aa6eb842a66 -r ec150b6d629b yt/lagos/parallelHOP/parallelHOP.py
--- a/yt/lagos/parallelHOP/parallelHOP.py	Sun Mar 21 14:58:21 2010 -0700
+++ b/yt/lagos/parallelHOP/parallelHOP.py	Wed Mar 24 00:23:49 2010 -0700
@@ -1131,10 +1131,7 @@
         Set_list = []
         # We only want the holes that are modulo mine.
         keys = na.arange(groupID, dtype='int64')
-        if self._mpi_get_size() == None:
-            size = 1
-        else:
-            size = self._mpi_get_size()
+        size = self._mpi_get_size()
         select = (keys % size == self.mine)
         groupIDs = keys[select]
         mine_groupIDs = set([]) # Records only ones modulo mine.



More information about the yt-svn mailing list