[cig-commits] r4743 - in cs/pythia/trunk: . journal journal/colors journal/components journal/devices journal/diagnostics merlin/components mpi mpi/launchers mpi/scripts pyre pyre/applications pyre/components pyre/hooks pyre/idd pyre/inventory pyre/inventory/cfg pyre/inventory/odb pyre/ipa pyre/launchers pyre/odb/fs pyre/parsing/locators pyre/schedulers pyre/schedulers/scripts pyre/schedulers/scripts/lsf pyre/scripts pyre/templates pyre/util pyre/weaver pyre/weaver/mills pythia.egg-info

leif at geodynamics.org leif at geodynamics.org
Sun Oct 8 06:56:36 PDT 2006


Author: leif
Date: 2006-10-08 06:56:34 -0700 (Sun, 08 Oct 2006)
New Revision: 4743

Added:
   cs/pythia/trunk/journal/colors/
   cs/pythia/trunk/journal/colors/ColorANSI.py
   cs/pythia/trunk/journal/colors/ColorScheme.py
   cs/pythia/trunk/journal/colors/__init__.py
   cs/pythia/trunk/journal/colors/__vault__.odb
   cs/pythia/trunk/journal/colors/dark-bg.cfg
   cs/pythia/trunk/journal/colors/dark-bg.odb
   cs/pythia/trunk/journal/colors/light-bg.cfg
   cs/pythia/trunk/journal/colors/light-bg.odb
   cs/pythia/trunk/journal/components/ColorConsole.py
   cs/pythia/trunk/journal/components/ColorRenderer.py
   cs/pythia/trunk/journal/components/Stream.py
   cs/pythia/trunk/journal/devices/ANSIColorConsole.py
   cs/pythia/trunk/journal/devices/ColorRenderer.py
   cs/pythia/trunk/journal/devices/__vault__.odb
   cs/pythia/trunk/journal/devices/color-console.odb
   cs/pythia/trunk/journal/devices/console.odb
   cs/pythia/trunk/journal/devices/file.odb
   cs/pythia/trunk/journal/devices/remote.odb
   cs/pythia/trunk/journal/devices/xterm-color.odb
   cs/pythia/trunk/journal/devices/xterm.odb
   cs/pythia/trunk/mpi/__vault__.odb
   cs/pythia/trunk/mpi/_mpi.c
   cs/pythia/trunk/mpi/_mpi.pyx
   cs/pythia/trunk/mpi/cmpi.pxd
   cs/pythia/trunk/mpi/launchers/
   cs/pythia/trunk/mpi/launchers/__vault__.odb
   cs/pythia/trunk/mpi/launchers/mpich.odb
   cs/pythia/trunk/mpi/pympi.h
   cs/pythia/trunk/mpi/scripts/
   cs/pythia/trunk/mpi/scripts/__init__.py
   cs/pythia/trunk/mpi/scripts/mpistart.py
   cs/pythia/trunk/pyre/__vault__.odb
   cs/pythia/trunk/pyre/applications/AppRunner.py
   cs/pythia/trunk/pyre/applications/SuperCommandlineParser.py
   cs/pythia/trunk/pyre/applications/SuperScript.py
   cs/pythia/trunk/pyre/hooks/
   cs/pythia/trunk/pyre/hooks/ExceptHook.py
   cs/pythia/trunk/pyre/hooks/__init__.py
   cs/pythia/trunk/pyre/hooks/__vault__.odb
   cs/pythia/trunk/pyre/hooks/built-in.odb
   cs/pythia/trunk/pyre/hooks/current.odb
   cs/pythia/trunk/pyre/hooks/ultraTB.odb
   cs/pythia/trunk/pyre/idd/__vault__.odb
   cs/pythia/trunk/pyre/idd/idd-pickler.odb
   cs/pythia/trunk/pyre/inventory/ConfigContext.py
   cs/pythia/trunk/pyre/inventory/ConfigurableClass.py
   cs/pythia/trunk/pyre/inventory/cfg/
   cs/pythia/trunk/pyre/inventory/cfg/CodecConfig.py
   cs/pythia/trunk/pyre/inventory/cfg/Parser.py
   cs/pythia/trunk/pyre/inventory/cfg/__init__.py
   cs/pythia/trunk/pyre/ipa/__vault__.odb
   cs/pythia/trunk/pyre/ipa/ipa-pickler.odb
   cs/pythia/trunk/pyre/launchers/
   cs/pythia/trunk/pyre/launchers/Launcher.py
   cs/pythia/trunk/pyre/launchers/__init__.py
   cs/pythia/trunk/pyre/launchers/__vault__.odb
   cs/pythia/trunk/pyre/schedulers/
   cs/pythia/trunk/pyre/schedulers/BatchScheduler.py
   cs/pythia/trunk/pyre/schedulers/BatchScriptTemplate.py
   cs/pythia/trunk/pyre/schedulers/Job.py
   cs/pythia/trunk/pyre/schedulers/Scheduler.py
   cs/pythia/trunk/pyre/schedulers/SchedulerLSF.py
   cs/pythia/trunk/pyre/schedulers/SchedulerNone.py
   cs/pythia/trunk/pyre/schedulers/__init__.py
   cs/pythia/trunk/pyre/schedulers/__vault__.odb
   cs/pythia/trunk/pyre/schedulers/lsf.odb
   cs/pythia/trunk/pyre/schedulers/none.odb
   cs/pythia/trunk/pyre/schedulers/scripts/
   cs/pythia/trunk/pyre/schedulers/scripts/__vault__.odb
   cs/pythia/trunk/pyre/schedulers/scripts/lsf/
   cs/pythia/trunk/pyre/schedulers/scripts/lsf/__vault__.odb
   cs/pythia/trunk/pyre/schedulers/scripts/lsf/batch.sh.tmpl
   cs/pythia/trunk/pyre/scripts/
   cs/pythia/trunk/pyre/scripts/PyreScript.py
   cs/pythia/trunk/pyre/scripts/__init__.py
   cs/pythia/trunk/pyre/scripts/jobstart.py
   cs/pythia/trunk/pyre/templates/
   cs/pythia/trunk/pyre/templates/CodecTmpl.py
   cs/pythia/trunk/pyre/templates/__init__.py
   cs/pythia/trunk/pyre/weaver/__vault__.odb
   cs/pythia/trunk/pyre/weaver/mills/__vault__.odb
   cs/pythia/trunk/pyre/weaver/mills/c.odb
   cs/pythia/trunk/pyre/weaver/mills/csh.odb
   cs/pythia/trunk/pyre/weaver/mills/cxx.odb
   cs/pythia/trunk/pyre/weaver/mills/f77.odb
   cs/pythia/trunk/pyre/weaver/mills/f90.odb
   cs/pythia/trunk/pyre/weaver/mills/html.odb
   cs/pythia/trunk/pyre/weaver/mills/make.odb
   cs/pythia/trunk/pyre/weaver/mills/perl.odb
   cs/pythia/trunk/pyre/weaver/mills/python.odb
   cs/pythia/trunk/pyre/weaver/mills/sh.odb
   cs/pythia/trunk/pyre/weaver/mills/tex.odb
   cs/pythia/trunk/pyre/weaver/mills/xml.odb
Removed:
   cs/pythia/trunk/idd/
   cs/pythia/trunk/ipa/
   cs/pythia/trunk/journal/console.odb
   cs/pythia/trunk/journal/file.odb
   cs/pythia/trunk/journal/remote.odb
   cs/pythia/trunk/mpi/Communicator.h
   cs/pythia/trunk/mpi/DummyCommunicator.py
   cs/pythia/trunk/mpi/Group.h
   cs/pythia/trunk/mpi/LauncherPBS.py
   cs/pythia/trunk/mpi/_mpimodule.h
   cs/pythia/trunk/weaver/
Modified:
   cs/pythia/trunk/journal/components/DeviceFacility.py
   cs/pythia/trunk/journal/components/Renderer.py
   cs/pythia/trunk/journal/devices/Device.py
   cs/pythia/trunk/journal/devices/Renderer.py
   cs/pythia/trunk/journal/diagnostics/Diagnostic.py
   cs/pythia/trunk/merlin/components/Merlin.py
   cs/pythia/trunk/mpi/Application.py
   cs/pythia/trunk/mpi/Communicator.py
   cs/pythia/trunk/mpi/Launcher.py
   cs/pythia/trunk/mpi/LauncherMPICH.py
   cs/pythia/trunk/mpi/__init__.py
   cs/pythia/trunk/pyre/__init__.py
   cs/pythia/trunk/pyre/applications/Application.py
   cs/pythia/trunk/pyre/applications/CommandlineParser.py
   cs/pythia/trunk/pyre/applications/Executive.py
   cs/pythia/trunk/pyre/applications/Script.py
   cs/pythia/trunk/pyre/applications/__init__.py
   cs/pythia/trunk/pyre/components/Component.py
   cs/pythia/trunk/pyre/components/__init__.py
   cs/pythia/trunk/pyre/inventory/Configurable.py
   cs/pythia/trunk/pyre/inventory/Facility.py
   cs/pythia/trunk/pyre/inventory/Inventory.py
   cs/pythia/trunk/pyre/inventory/__init__.py
   cs/pythia/trunk/pyre/inventory/odb/Curator.py
   cs/pythia/trunk/pyre/inventory/odb/prefix.py
   cs/pythia/trunk/pyre/odb/fs/CodecODB.py
   cs/pythia/trunk/pyre/odb/fs/Curator.py
   cs/pythia/trunk/pyre/parsing/locators/__init__.py
   cs/pythia/trunk/pyre/util/__init__.py
   cs/pythia/trunk/pythia.egg-info/
   cs/pythia/trunk/setup.py
Log:
Moved launcher/scheduler functionality into Pyre, where it belongs. 
This version is based upon Addyndum's launcher/scheduler stuff
(developed for SPECFEM) -- rather than the old, original 'Lauchers.py'
stuff in CitcomS.  I stripped out the staging stuff, at least for now:
no one really uses it, and it was only implemented for LSF.  This
version contains some experimental techniques -- it doesn't quite work,
although it might if you set PYTHONPATH in .bashrc.  I will revert it to
proven Addyndum techniques shortly.

Moved .cfg file support into Pyre, where it belongs.

Nuked C++ _mpimodule, replacing it with _mpi.pyx/_mpi.c.  This requires
minor changes to extension modules.   Application Python code remains
unchanged.

Fixed an obscure bug:  "--facility=some.module.name" now works (before
only "--facility=module" worked).  One can now also write
"--facility=some.module.name:attr.attr".  Append a period to suppress
the addition of the facility (family) name: 
"--launcher=mystuff.pyreutil.mylauncherfactory.".

~~~ Merged-in some of my better ideas from Addyndum:

For users: when there are configuration errors, instead of crashing on
the first error and printing a Python traceback, Pyre apps now print a
list of error messages -- with filenames and line numbers -- and exit
gracefully with status 1.  When a facility cannot be bound to a
component, apps now exit with a configuration error (instead of merely
logging the error and running ahead anyway with a bad configuration).

For developers:  It is no longer necessary to specify the facility name
twice.  In a component class definition, the facility name is no longer
required; and the component name can optionally be a class attribute. 
And finally, the most radical idea:  optionally, properties and
facilities may be defined at the top level, instead of nested inside
"Inventory" (e.g., "self.xxx" instead of "self.inventory.xxx").  This
really cuts down on amount of text needed to define a component.  See
LauncherMPICH for an example.

~~~ Implemented some new ideas as they occurred to me:

Added SuperScript, which enables you to write Pyre apps that work like
cvs and svn:  "script [script-options] <subscript> [subscript-options]
[ARG...]".

Added the ability to configure the automatic ultraTB tracebacks using
Pyre ('mode', 'color-scheme', 'call-pdb', and whether you want ultraTB
at all) -- although it cannot be configured from the command line.  The
'excepthook' is now set before any Application initialization takes
place, so users should almost always get an ultraTB traceback (with
pretty colors) when an exception occurs... if IPython is installed, of
course.

Journal log messages -- including the new configuration error messages
-- are now optionally colorized on capable terminals.

Laid the foundation for bash completion scripts for Pyre apps.  See
issue5.

~~~ Misc.

Cleaned-up .odb/vault layout.  Nuked 'Make.mm' files.

~~~ Notes

Pythia now depends upon Cheetah, the Python template engine.

Once I got going, I just couldn't stop :-)



Property changes on: cs/pythia/trunk/journal/colors
___________________________________________________________________
Name: svn:ignore
   + *.pyc


Added: cs/pythia/trunk/journal/colors/ColorANSI.py
===================================================================
--- cs/pythia/trunk/journal/colors/ColorANSI.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/colors/ColorANSI.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,155 @@
+# -*- coding: utf-8 -*-
+"""Tools for coloring text in ANSI terminals.
+
+$Id: ColorANSI.py,v 1.10 2004/11/04 07:58:16 fperez Exp $"""
+
+#*****************************************************************************
+#       Copyright (C) 2002-2004 Fernando Perez. <fperez at colorado.edu>
+#
+#  Distributed under the terms of the BSD License.  The full license is in
+#  the file COPYING, distributed as part of this software.
+#*****************************************************************************
+
+from IPython import Release
+__author__  = '%s <%s>' % Release.authors['Fernando']
+__license__ = Release.license
+
+__all__ = ['TermColors','InputTermColors','ColorScheme','ColorSchemeTable']
+
+import os
+from UserDict import UserDict
+
+from IPython.Struct import Struct
+
+def make_color_table(in_class):
+    """Build a set of color attributes in a class.
+
+    Helper function for building the *TermColors classes."""
+    
+    color_templates = (
+        ("Black"       , "0;30"),
+        ("Red"         , "0;31"),
+        ("Green"       , "0;32"),
+        ("Brown"       , "0;33"),
+        ("Blue"        , "0;34"),
+        ("Purple"      , "0;35"),
+        ("Cyan"        , "0;36"),
+        ("LightGray"   , "0;37"),
+        ("DarkGray"    , "1;30"),
+        ("LightRed"    , "1;31"),
+        ("LightGreen"  , "1;32"),
+        ("Yellow"      , "1;33"),
+        ("LightBlue"   , "1;34"),
+        ("LightPurple" , "1;35"),
+        ("LightCyan"   , "1;36"),
+        ("White"       , "1;37"),  )
+
+    for name,value in color_templates:
+        setattr(in_class,name,in_class._base % value)
+
+class TermColors:
+    """Color escape sequences.
+
+    This class defines the escape sequences for all the standard (ANSI?) 
+    colors in terminals. Also defines a NoColor escape which is just the null
+    string, suitable for defining 'dummy' color schemes in terminals which get
+    confused by color escapes.
+
+    This class should be used as a mixin for building color schemes."""
+    
+    NoColor = ''  # for color schemes in color-less terminals.
+    Normal = '\033[0m'   # Reset normal coloring
+    _base  = '\033[%sm'  # Template for all other colors
+
+# Build the actual color table as a set of class attributes:
+make_color_table(TermColors)
+
+class InputTermColors:
+    """Color escape sequences for input prompts.
+
+    This class is similar to TermColors, but the escapes are wrapped in \001
+    and \002 so that readline can properly know the length of each line and
+    can wrap lines accordingly.  Use this class for any colored text which
+    needs to be used in input prompts, such as in calls to raw_input().
+
+    This class defines the escape sequences for all the standard (ANSI?) 
+    colors in terminals. Also defines a NoColor escape which is just the null
+    string, suitable for defining 'dummy' color schemes in terminals which get
+    confused by color escapes.
+
+    This class should be used as a mixin for building color schemes."""
+    
+    NoColor = ''  # for color schemes in color-less terminals.
+    Normal = '\001\033[0m\002'   # Reset normal coloring
+    _base  = '\001\033[%sm\002'  # Template for all other colors
+
+# Build the actual color table as a set of class attributes:
+make_color_table(InputTermColors)
+
+class ColorScheme:
+    """Generic color scheme class. Just a name and a Struct."""
+    def __init__(self,__scheme_name_,colordict=None,**colormap):
+        self.name = __scheme_name_
+        if colordict is None:
+            self.colors = Struct(**colormap)
+        else:
+            self.colors = Struct(colordict)
+        
+class ColorSchemeTable(UserDict):
+    """General class to handle tables of color schemes.
+
+    It's basically a dict of color schemes with a couple of shorthand
+    attributes and some convenient methods.
+    
+    active_scheme_name -> obvious
+    active_colors -> actual color table of the active scheme"""
+
+    def __init__(self,scheme_list=None,default_scheme=''):
+        """Create a table of color schemes.
+
+        The table can be created empty and manually filled or it can be
+        created with a list of valid color schemes AND the specification for
+        the default active scheme.
+        """
+        
+        UserDict.__init__(self)
+        if scheme_list is None:
+            self.active_scheme_name = ''
+            self.active_colors = None
+        else:
+            if default_scheme == '':
+                raise ValueError,'you must specify the default color scheme'
+            for scheme in scheme_list:
+                self.add_scheme(scheme)
+            self.set_active_scheme(default_scheme)
+
+    def add_scheme(self,new_scheme):
+        """Add a new color scheme to the table."""
+        if not isinstance(new_scheme,ColorScheme):
+            raise ValueError,'ColorSchemeTable only accepts ColorScheme instances'
+        self[new_scheme.name] = new_scheme
+        
+    def set_active_scheme(self,scheme,case_sensitive=0):
+        """Set the currently active scheme.
+
+        Names are by default compared in a case-insensitive way, but this can
+        be changed by setting the parameter case_sensitive to true."""
+
+        scheme_list = self.keys()
+        if case_sensitive:
+            valid_schemes = scheme_list
+            scheme_test = scheme
+        else:
+            valid_schemes = [s.lower() for s in scheme_list]
+            scheme_test = scheme.lower()
+        try:
+            scheme_idx = valid_schemes.index(scheme_test)
+        except ValueError:
+            raise ValueError,'Unrecognized color scheme: ' + scheme + \
+                  '\nValid schemes: '+str(scheme_list).replace("'', ",'')
+        else:
+            active = scheme_list[scheme_idx]
+            self.active_scheme_name = active
+            self.active_colors = self[active].colors
+            # Now allow using '' as an index for the current active scheme
+            self[''] = self[active]

Added: cs/pythia/trunk/journal/colors/ColorScheme.py
===================================================================
--- cs/pythia/trunk/journal/colors/ColorScheme.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/colors/ColorScheme.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from pyre.components import Component
+
+
+class ColorScheme(Component):
+
+
+    import pyre.inventory as pyre
+
+    filename         = pyre.str("filename",          default="NoColor")
+    line             = pyre.str("line",              default="NoColor")
+    function         = pyre.str("function",          default="NoColor")
+    stackTrace       = pyre.str("stack-trace",       default="NoColor")
+
+    src              = pyre.str("src",               default="NoColor")
+
+    facility         = pyre.str("facility",          default="NoColor")
+    severityDebug    = pyre.str("severity-debug",    default="NoColor")
+    severityInfo     = pyre.str("severity-info",     default="NoColor")
+    severityWarning  = pyre.str("severity-warning",  default="NoColor")
+    severityError    = pyre.str("severity-error",    default="NoColor")
+    
+    normal           = pyre.str("normal",            default="Normal")
+
+
+    def __getitem__(self, key):
+        return self.getTraitValue(key)
+
+    
+# end of file 

Added: cs/pythia/trunk/journal/colors/__init__.py
===================================================================
--- cs/pythia/trunk/journal/colors/__init__.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/colors/__init__.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from ColorScheme import ColorScheme
+
+
+# facilities and components
+
+def colorScheme(name, **kwds):
+    from pyre.inventory.Facility import Facility
+    kwds['factory'] = kwds.get('factory', ColorScheme)
+    kwds['vault'] = kwds.get('vault', ['colors'])
+    kwds['family'] = kwds.get('family', 'colorScheme')
+    return Facility(name, **kwds)
+
+
+# end of file 

Added: cs/pythia/trunk/journal/colors/__vault__.odb
===================================================================
--- cs/pythia/trunk/journal/colors/__vault__.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/colors/__vault__.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+# end of file

Added: cs/pythia/trunk/journal/colors/dark-bg.cfg
===================================================================
--- cs/pythia/trunk/journal/colors/dark-bg.cfg	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/colors/dark-bg.cfg	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,25 @@
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+[dark-bg]
+
+filename  = LightGreen
+line      = LightGreen
+function  = LightPurple
+src       = Yellow
+
+facility          = LightBlue
+severity-debug    = LightCyan
+severity-info     = LightGreen
+severity-error    = LightRed
+severity-warning  = Yellow
+
+
+# end of file

Added: cs/pythia/trunk/journal/colors/dark-bg.odb
===================================================================
--- cs/pythia/trunk/journal/colors/dark-bg.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/colors/dark-bg.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+def colorScheme():
+    from journal.colors import ColorScheme
+    return ColorScheme("dark-bg")
+
+
+# end of file

Added: cs/pythia/trunk/journal/colors/light-bg.cfg
===================================================================
--- cs/pythia/trunk/journal/colors/light-bg.cfg	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/colors/light-bg.cfg	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,25 @@
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+[light-bg]
+
+filename  = Green
+line      = Green
+function  = Purple
+src       = Red
+
+facility          = Blue
+severity-debug    = Cyan
+severity-info     = Green
+severity-error    = Red
+severity-warning  = Brown
+
+
+# end of file

Added: cs/pythia/trunk/journal/colors/light-bg.odb
===================================================================
--- cs/pythia/trunk/journal/colors/light-bg.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/colors/light-bg.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+def colorScheme():
+    from journal.colors import ColorScheme
+    return ColorScheme("light-bg")
+
+
+# end of file

Added: cs/pythia/trunk/journal/components/ColorConsole.py
===================================================================
--- cs/pythia/trunk/journal/components/ColorConsole.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/components/ColorConsole.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from Console import Console
+
+
+class ColorConsole(Console):
+
+
+    class Inventory(Console.Inventory):
+
+        from RendererFacility import RendererFacility
+        from ColorRenderer import ColorRenderer
+
+        renderer = RendererFacility(factory=ColorRenderer)
+        renderer.meta['tip'] = 'the facility that controls how the messages are formatted'
+
+
+    def createDevice(self):
+        from journal.devices.ANSIColorConsole import ANSIColorConsole
+        return ANSIColorConsole()
+
+
+# end of file 

Added: cs/pythia/trunk/journal/components/ColorRenderer.py
===================================================================
--- cs/pythia/trunk/journal/components/ColorRenderer.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/components/ColorRenderer.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from Renderer import Renderer
+
+
+class ColorRenderer(Renderer):
+
+
+    class Inventory(Renderer.Inventory):
+
+        import journal.colors
+
+        colorScheme = journal.colors.colorScheme("color-scheme", default="dark-bg")
+
+
+    def _init(self):
+        renderer = Renderer._init(self)
+        renderer.colorScheme = self.inventory.colorScheme
+        return renderer
+
+
+    def createRenderer(self):
+        from journal.devices.ColorRenderer import ColorRenderer
+        return ColorRenderer()
+
+
+# end of file 

Modified: cs/pythia/trunk/journal/components/DeviceFacility.py
===================================================================
--- cs/pythia/trunk/journal/components/DeviceFacility.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/components/DeviceFacility.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -18,15 +18,37 @@
 
 
     def __init__(self, factory=None, args=[]):
-        if factory is None:
-            args = []
-            from Console import Console as factory
+        Facility.__init__(self, name="device", factory=factory, args=args,
+                          vault=['devices'])
 
-        Facility.__init__(self, name="device", factory=factory, args=args)
 
-        return
+    def _getDefaultValue(self, instance):
+        
+        if (self.default is None) and (self.factory is None):
+            
+            import pyre.parsing.locators
+            locator = pyre.parsing.locators.default()
+            
+            import sys
+            if hasattr(sys.stdout, 'isatty') and sys.stdout.isatty():
+                from os import environ
+                term = environ.get('TERM', 'console')
+                component = instance.retrieveComponent(term, factory=self.family, vault=self.vault)
+                if component is None:
+                    from Console import Console
+                    component = Console()
+                else:
+                    component.aliases.append(self.name)
+                    locator = pyre.parsing.locators.chain(component.getLocator(), locator)
+            else:
+                from Stream import Stream
+                component = Stream(sys.stdout, "stdout")
 
+            return component, locator
+        
+        return super(DeviceFacility, self)._getDefaultValue(instance)
 
+
 # version
 __id__ = "$Id: DeviceFacility.py,v 1.1.1.1 2005/03/08 16:13:53 aivazis Exp $"
 

Modified: cs/pythia/trunk/journal/components/Renderer.py
===================================================================
--- cs/pythia/trunk/journal/components/Renderer.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/components/Renderer.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -40,8 +40,7 @@
 
 
     def _init(self):
-        from journal.devices.Renderer import Renderer
-        renderer = Renderer()
+        renderer = self.createRenderer()
 
         renderer.header = self.inventory.header
         renderer.footer = self.inventory.footer
@@ -52,6 +51,11 @@
         return renderer
 
 
+    def createRenderer(self):
+        from journal.devices.Renderer import Renderer
+        return Renderer()
+
+
 # version
 __id__ = "$Id: Renderer.py,v 1.2 2005/03/10 06:16:37 aivazis Exp $"
 

Added: cs/pythia/trunk/journal/components/Stream.py
===================================================================
--- cs/pythia/trunk/journal/components/Stream.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/components/Stream.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from Device import Device
+
+
+class Stream(Device):
+
+
+    def createDevice(self):
+        from journal.devices.File import File
+        return File(self.stream)
+
+
+    def __init__(self, stream, name=None):
+        if name is None:
+            name = "stream"
+        Device.__init__(self, name)
+        self.stream = stream
+        return
+
+
+# end of file 

Deleted: cs/pythia/trunk/journal/console.odb
===================================================================
--- cs/pythia/trunk/journal/console.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/console.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -1,24 +0,0 @@
-#!/usr/bin/env python
-#
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-#
-#                             Michael A.G. Aivazis
-#                      California Institute of Technology
-#                      (C) 1998-2005  All Rights Reserved
-#
-# {LicenseText}
-#
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-#
-
-
-def device():
-
-    from journal.components.Console import Console
-    return Console()
-
-
-# version
-__id__ = "$Id: console.odb,v 1.1.1.1 2005/03/08 16:13:52 aivazis Exp $"
-
-# End of file 

Added: cs/pythia/trunk/journal/devices/ANSIColorConsole.py
===================================================================
--- cs/pythia/trunk/journal/devices/ANSIColorConsole.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/devices/ANSIColorConsole.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from Console import Console
+
+
+class ANSIColorConsole(Console):
+    from journal.colors.ColorANSI import TermColors
+
+
+# end of file 

Added: cs/pythia/trunk/journal/devices/ColorRenderer.py
===================================================================
--- cs/pythia/trunk/journal/devices/ColorRenderer.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/devices/ColorRenderer.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from Renderer import Renderer
+
+
+class ColorRenderer(Renderer):
+
+
+    def subst(self, dct, device):
+        
+        TermColors = device.TermColors
+        colorScheme = self.colorScheme
+        
+        colorized = {}
+        for k, v in dct.iteritems():
+            colorKey = k
+            if colorKey == 'severity':
+                colorKey = colorKey + '-' + v
+            colorized[k] = (
+                getattr(TermColors, colorScheme[colorKey]) +
+                str(v) +
+                getattr(TermColors, colorScheme['normal']))
+        
+        return colorized
+
+
+    def __init__(self, header=None, format=None, footer=None, colorScheme=None):
+        Renderer.__init__(self, header, format, footer)
+        self.colorScheme = colorScheme
+
+
+# end of file 

Modified: cs/pythia/trunk/journal/devices/Device.py
===================================================================
--- cs/pythia/trunk/journal/devices/Device.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/devices/Device.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -16,7 +16,7 @@
 
 
     def record(self, entry):
-        text = self.renderer.render(entry)
+        text = self.renderer.render(entry, self)
         self._write(text)
         return
 

Modified: cs/pythia/trunk/journal/devices/Renderer.py
===================================================================
--- cs/pythia/trunk/journal/devices/Renderer.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/devices/Renderer.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -15,7 +15,7 @@
 class Renderer(object):
 
 
-    def render(self, entry):
+    def render(self, entry, device):
 
         text = []
         meta = entry.meta
@@ -25,17 +25,21 @@
             if self.trimFilename and len(filename) > 53:
                 filename = filename[0:20] + "..." + filename[-30:]
                 meta["filename"] = filename
-            text.append(self.header % meta)
+            text.append(self.header % self.subst(meta, device))
 
         for line in entry.text:
             text.append(self.format % line)
 
         if self.footer:
-            text.append(self.footer % meta)
+            text.append(self.footer % self.subst(meta, device))
 
         return text
 
 
+    def subst(self, dct, device):
+        return dct
+
+
     def __init__(self, header=None, format=None, footer=None):
         if header is None:
             header = " >> %(filename)s:%(line)s:%(function)s\n >> %(facility)s(%(severity)s)"

Added: cs/pythia/trunk/journal/devices/__vault__.odb
===================================================================
--- cs/pythia/trunk/journal/devices/__vault__.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/devices/__vault__.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                             Michael A.G. Aivazis
+#                      California Institute of Technology
+#                      (C) 1998-2005  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+# version
+__id__ = "$Id: __vault__.odb,v 1.1.1.1 2005/03/08 16:13:52 aivazis Exp $"
+
+# End of file 

Added: cs/pythia/trunk/journal/devices/color-console.odb
===================================================================
--- cs/pythia/trunk/journal/devices/color-console.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/devices/color-console.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+def device():
+
+    from journal.components.ColorConsole import ColorConsole
+    return ColorConsole()
+
+
+# end of file

Copied: cs/pythia/trunk/journal/devices/console.odb (from rev 4634, cs/pythia/trunk/journal/console.odb)

Copied: cs/pythia/trunk/journal/devices/file.odb (from rev 4634, cs/pythia/trunk/journal/file.odb)

Copied: cs/pythia/trunk/journal/devices/remote.odb (from rev 4634, cs/pythia/trunk/journal/remote.odb)

Added: cs/pythia/trunk/journal/devices/xterm-color.odb
===================================================================
--- cs/pythia/trunk/journal/devices/xterm-color.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/devices/xterm-color.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+def device():
+
+    from journal.components.ColorConsole import ColorConsole
+    return ColorConsole()
+
+
+# end of file

Added: cs/pythia/trunk/journal/devices/xterm.odb
===================================================================
--- cs/pythia/trunk/journal/devices/xterm.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/devices/xterm.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+def device():
+
+    from journal.components.ColorConsole import ColorConsole
+    return ColorConsole()
+
+
+# end of file

Modified: cs/pythia/trunk/journal/diagnostics/Diagnostic.py
===================================================================
--- cs/pythia/trunk/journal/diagnostics/Diagnostic.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/diagnostics/Diagnostic.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -14,6 +14,7 @@
 
 import journal
 import traceback
+import linecache
 from Entry import Entry
 
 
@@ -28,25 +29,41 @@
         return self
 
 
-    def log(self, message=None):
+    def log(self, message=None, locator=None):
         if not self.state:
             return
 
         if message is not None:
             self._entry.line(message)
 
-        stackDepth = -2
-        stackTrace = traceback.extract_stack()
-        file, line, function, src = stackTrace[stackDepth]
+        meta = self._entry.meta
+        
+        if locator is None:
+            stackDepth = -2
+            stackTrace = traceback.extract_stack()
+            meta["stack-trace"] = stackTrace[:stackDepth+1]
+            file, line, function, src = stackTrace[stackDepth]
+        else:
+            try:
+                file = locator.source
+            except AttributeError:
+                file = ""
+            try:
+                line = locator.line
+            except AttributeError:
+                line = ""
+                src = ""
+            else:
+                src = linecache.getline(locator.source, locator.line)
+                src = src.rstrip()
+            function = ""
 
-        meta = self._entry.meta
         meta["facility"] = self.facility
         meta["severity"] = self.severity
         meta["filename"] = file
         meta["function"] = function
         meta["line"] = line
         meta["src"] = src
-        meta["stack-trace"] = stackTrace[:stackDepth+1]
 
         journal.journal().record(self._entry)
 

Deleted: cs/pythia/trunk/journal/file.odb
===================================================================
--- cs/pythia/trunk/journal/file.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/file.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -1,24 +0,0 @@
-#!/usr/bin/env python
-#
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-#
-#                             Michael A.G. Aivazis
-#                      California Institute of Technology
-#                      (C) 1998-2005  All Rights Reserved
-#
-# {LicenseText}
-#
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-#
-
-
-def device():
-
-    from journal.components.File import File
-    return File()
-
-
-# version
-__id__ = "$Id: file.odb,v 1.1.1.1 2005/03/08 16:13:52 aivazis Exp $"
-
-# End of file 

Deleted: cs/pythia/trunk/journal/remote.odb
===================================================================
--- cs/pythia/trunk/journal/remote.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/journal/remote.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -1,24 +0,0 @@
-#!/usr/bin/env python
-#
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-#
-#                             Michael A.G. Aivazis
-#                      California Institute of Technology
-#                      (C) 1998-2005  All Rights Reserved
-#
-# {LicenseText}
-#
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-#
-
-
-def device():
-
-    from journal.components.Remote import Remote
-    return Remote()
-
-
-# version
-__id__ = "$Id: remote.odb,v 1.1.1.1 2005/03/08 16:13:52 aivazis Exp $"
-
-# End of file 

Modified: cs/pythia/trunk/merlin/components/Merlin.py
===================================================================
--- cs/pythia/trunk/merlin/components/Merlin.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/merlin/components/Merlin.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -33,7 +33,7 @@
         print " ** NYI"
 
         spell = self.retrieveComponent(
-            name='', factory='project', args=[self], encoding='merlin')
+            name='', factory='project', args=[self], encodings=['merlin'])
 
         if spell:
             self._info.log("loaded project definition file from %s" % spell.getLocator())
@@ -118,7 +118,7 @@
 
         agents = filter(None, self.agents(project, actions))
         for agent in agents:
-            up, uc = self.configureComponent(agent)
+            self.configureComponent(agent)
             agent.init()
             agent.execute(self, project)
             agent.fini()

Modified: cs/pythia/trunk/mpi/Application.py
===================================================================
--- cs/pythia/trunk/mpi/Application.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/mpi/Application.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -2,11 +2,10 @@
 #
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 #
-#                             Michael A.G. Aivazis
 #                      California Institute of Technology
-#                      (C) 1998-2005  All Rights Reserved
+#                        (C) 2006  All Rights Reserved
 #
-# <LicenseText>
+# {LicenseText}
 #
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 #
@@ -18,57 +17,74 @@
 class Application(Script):
 
 
-    class Inventory(Script.Inventory):
+    import pyre.inventory
+    nodes = pyre.inventory.int("nodes", default=1)
 
-        import pyre.inventory
+    import pyre.schedulers
+    scheduler = pyre.schedulers.scheduler("scheduler", default="none")
+    job = pyre.schedulers.job("job")
+        
+    import pyre.launchers
+    launcher = pyre.launchers.facility("launcher", default="mpich")
 
-        from LauncherMPICH import LauncherMPICH
 
-        mode = pyre.inventory.str(
-            name="mode", default="server", validator=pyre.inventory.choice(["server", "worker"]))
-        launcher = pyre.inventory.facility("launcher", factory=LauncherMPICH)
+    nodes.meta['tip'] = """number of machine nodes"""
 
 
     def execute(self, *args, **kwds):
+        self.onLoginNode(*args, **kwds)
 
-        if self.inventory.mode == "worker":
-            self.onComputeNodes(*args, **kwds)
-            return
+
+    def onLoginNode(self, *args, **kwds):
+        import sys
+        from pkg_resources import resource_filename
         
-        self.onServer(*args, **kwds)
+        jobstart = resource_filename("pyre", "scripts/jobstart.py")
+        entry = self.entryName()
+        argv = self.getArgv(*args, **kwds)
+        
+        # initialize the job
+        job = self.job
+        job.nodes = self.nodes
+        job.executable = self.executable
+        job.arguments = [jobstart, entry] + argv
 
+        # schedule
+        self.scheduler.schedule(job)
+        
         return
 
 
-    def onComputeNodes(self, *args, **kwds):
-        self.main(*args, **kwds)
-        return
+    def onLauncherNode(self, *args, **kwds):
+        import sys
+        from pkg_resources import resource_filename
 
-
-    def onServer(self, *args, **kwds):
-        self._debug.log("%s: onServer" % self.name)
-
-        launcher = self.inventory.launcher
-        launched = launcher.launch()
-        if not launched:
-            self.onComputeNodes(*args, **kwds)
+        mpistart = resource_filename(__name__, "scripts/mpistart.py")
+        entry = self.entryName()
+        argv = self.getArgv(*args, **kwds)
         
+        # initialize the launcher
+        launcher = self.launcher
+        launcher.nodes = self.nodes
+        self.getNodes()
+        launcher.executable = self.executable
+        launcher.arguments = [mpistart, entry] + argv
+        
+        # launch
+        launcher.launch()
+        
         return
 
 
-    def __init__(self, name):
-        Script.__init__(self, name)
-        self.launcher = None
-        return
+    def onComputeNodes(self, *args, **kwds):
+        self.main(*args, **kwds)
 
 
-    def _configure(self):
-        Script._configure(self)
-        self.launcher = self.inventory.launcher
-        return
+    def __init__(self, name=None):
+        super(Application, self).__init__(name)
 
+        import sys
+        self.executable = sys.executable
 
-# version
-__id__ = "$Id: Application.py,v 1.1.1.1 2005/03/08 16:13:30 aivazis Exp $"
 
-# End of file 
+# end of file

Deleted: cs/pythia/trunk/mpi/Communicator.h
===================================================================
--- cs/pythia/trunk/mpi/Communicator.h	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/mpi/Communicator.h	2006-10-08 13:56:34 UTC (rev 4743)
@@ -1,105 +0,0 @@
-// -*- C++ -*-
-//
-//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-//                              Michael A.G. Aivazis
-//                        California Institute of Technology
-//                        (C) 1998-2005 All Rights Reserved
-//
-// <LicenseText>
-//
-//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-
-#if !defined(pympi_Communicator_h__)
-#define pympi_Communicator_h__
-
-#include <mpi.h>
-
-namespace mpi {
-
-    class Group;
-    class Communicator;
-}
-
-class mpi::Communicator {
-// interface
-public:
-    
-    int size() const {
-        int size;
-        return (MPI_Comm_size(_communicator, &size) == MPI_SUCCESS) ? size : -1;
-    }
-    
-    int rank() const {
-        int rank;
-        return (MPI_Comm_rank(_communicator, &rank) == MPI_SUCCESS) ? rank : -1;
-    }
-
-    void barrier() const { MPI_Barrier(_communicator); }
-    
-    void cartesianCoordinates(int rank, int dim, int * coordinates) const {
-        MPI_Cart_coords(_communicator, rank, dim, coordinates);
-    }
-
-    MPI_Comm handle() const { return _communicator; }
-
-    // factories
-    inline Communicator * communicator(const Group & group) const;
-    
-    Communicator * cartesian(int size, int * procs, int * periods, int reorder) const {
-        MPI_Comm cartesian;
-        int status = MPI_Cart_create(_communicator, size, procs, periods, reorder, &cartesian);
-        if (status != MPI_SUCCESS || cartesian == MPI_COMM_NULL) {
-            return 0;
-        }
-        return new Communicator(cartesian);
-    }
-
-
-// meta-methods
-public:
-    Communicator(MPI_Comm handle) :
-        _communicator(handle) {}
-    
-    ~Communicator() { MPI_Comm_free(&_communicator); }
-
-// hide these
-private:
-    Communicator(const Communicator &);
-    Communicator & operator=(const Communicator &);
-
-// instance atributes
-protected:
-
-    MPI_Comm _communicator;
-};
-
-
-#if !defined(pympi_Group_h__)
-#include "Group.h"
-#endif
-
-
-mpi::Communicator * mpi::Communicator::communicator(const Group & group) const {
-    MPI_Comm oldHandle = _communicator;
-    MPI_Group groupHandle = group.handle();
-    MPI_Comm comm;
-    int status = MPI_Comm_create(oldHandle, groupHandle, &comm);
-    if (status != MPI_SUCCESS || comm ==  MPI_COMM_NULL) {
-        return 0;
-    }
-    return new Communicator(comm);
-}
-
-
-#include "_mpimodule.h"
-
-
-#endif
-
-// version
-// $Id: Communicator.h,v 1.1.1.1 2005/03/08 16:13:30 aivazis Exp $
-
-//
-// End of file

Modified: cs/pythia/trunk/mpi/Communicator.py
===================================================================
--- cs/pythia/trunk/mpi/Communicator.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/mpi/Communicator.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -71,11 +71,13 @@
         return Port(self, peer, tag)
 
     def __init__(self, handle):
-        import _mpi
 
         self._handle = handle
-        self.rank = _mpi.communicatorRank(self._handle)
-        self.size = _mpi.communicatorSize(self._handle)
+        
+        from mpi import MPI_Comm_rank, MPI_Comm_size
+        self.rank = MPI_Comm_rank(self._handle)
+        self.size = MPI_Comm_size(self._handle)
+        
         return
 
 
@@ -86,14 +88,8 @@
 def world():
     global _mpi_world
     if not _mpi_world:
-
-        try:
-            import _mpi
-        except:
-            _mpi_world = None
-        else:
-            _mpi_world = Communicator(_mpi.world)
-
+        from mpi import MPI_COMM_WORLD
+        _mpi_world = Communicator(MPI_COMM_WORLD)
     return _mpi_world
 
 

Deleted: cs/pythia/trunk/mpi/DummyCommunicator.py
===================================================================
--- cs/pythia/trunk/mpi/DummyCommunicator.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/mpi/DummyCommunicator.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -1,31 +0,0 @@
-#!/usr/bin/env python
-#
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-#
-#                               Michael A.G. Aivazis
-#                        California Institute of Technology
-#                        (C) 1998-2005 All Rights Reserved
-#
-# <LicenseText>
-#
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-#
-
-
-class DummyCommunicator:
-
-
-    def handle(self):
-        return None
-
-
-    def __init__(self, *args):
-        self.rank = 0
-        self.size = 0
-        return
-
-
-# version
-__id__ = "$Id: DummyCommunicator.py,v 1.1.1.1 2005/03/08 16:13:30 aivazis Exp $"
-
-# End of file

Deleted: cs/pythia/trunk/mpi/Group.h
===================================================================
--- cs/pythia/trunk/mpi/Group.h	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/mpi/Group.h	2006-10-08 13:56:34 UTC (rev 4743)
@@ -1,107 +0,0 @@
-// -*- C++ -*-
-//
-//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-//                              Michael A.G. Aivazis
-//                        California Institute of Technology
-//                        (C) 1998-2005 All Rights Reserved
-//
-// <LicenseText>
-//
-//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-
-#if !defined(pympi_Group_h__)
-#define pympi_Group_h__
-
-#include <mpi.h>
-
-namespace mpi {
-
-    class Group;
-    class Communicator;
-}
-
-
-class mpi::Group {
-
-// interface
-public:
-    
-    int size() const {
-        int size;
-        return (MPI_Group_size(_group, &size) == MPI_SUCCESS) ? size : -1;
-    }
-    
-    int rank() const {
-        int rank;
-        return (MPI_Group_rank(_group, &rank) == MPI_SUCCESS) ? rank : -1;
-    }
-    
-    MPI_Group handle() const { return _group; }
-
-    // factories
-    static inline Group * group(const Communicator & comm);
-
-    Group * include(int size, int ranks[]) const {
-        MPI_Group newGroup = MPI_GROUP_NULL;
-        int status = MPI_Group_incl(_group, size, ranks, &newGroup);
-        if (status != MPI_SUCCESS || newGroup == MPI_GROUP_NULL) {
-            return 0;
-        }
-        return new Group(newGroup);
-    }
-    
-    Group * exclude(int size, int ranks[]) const {
-        MPI_Group newGroup = MPI_GROUP_NULL;
-        int status = MPI_Group_excl(_group, size, ranks, &newGroup);
-        if (status != MPI_SUCCESS || newGroup == MPI_GROUP_NULL) {
-            return 0;
-        }
-        return new Group(newGroup);
-    }
-    
-// meta-methods
-public:
-    Group(MPI_Group handle) : _group(handle) {}
-    ~Group() { MPI_Group_free(&_group); }
-
-// hide these
-private:
-        
-    Group(const Group &);
-    Group & operator=(const Group &);
-
-// data
-protected:
-
-    MPI_Group _group;
-};
-
-
-#if !defined(pympi_Communicator_h__)
-#include "Communicator.h"
-#endif
-
-
-mpi::Group * mpi::Group::group(const mpi::Communicator & comm) {
-    MPI_Comm commHandle = comm.handle();
-    MPI_Group group;
-    int status = MPI_Comm_group(commHandle, &group);
-    if (status != MPI_SUCCESS || group == MPI_GROUP_NULL) {
-        return 0;
-    }
-    return new Group(group);
-}
-
-
-#include "_mpimodule.h"
-
-
-// version
-// $Id: Group.h,v 1.1.1.1 2005/03/08 16:13:30 aivazis Exp $
-
-#endif
-
-//
-// End of file

Modified: cs/pythia/trunk/mpi/Launcher.py
===================================================================
--- cs/pythia/trunk/mpi/Launcher.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/mpi/Launcher.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -2,48 +2,84 @@
 #
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 #
-#                             Michael A.G. Aivazis
 #                      California Institute of Technology
-#                      (C) 1998-2005  All Rights Reserved
+#                        (C) 2006  All Rights Reserved
 #
-# <LicenseText>
+# {LicenseText}
 #
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 #
 
 
-from pyre.components.Component import Component
+from pyre.launchers.Launcher import Launcher as Base
 
 
-class Launcher(Component):
+class Launcher(Base):
+    
+    
+    import pyre.inventory as pyre
 
+    dry = pyre.bool("dry", default=False)
+    dry.meta['tip'] = "prints the command line and exits"
+        
+    nodegen = pyre.str("nodegen")
+    nodegen.meta['tip'] = """a printf-style format string, used in conjunction with 'nodelist' to generate the list of machine names (e.g., "n%03d")"""
+        
+    extra = pyre.str("extra")
+    extra.meta['tip'] = "extra arguments to pass to mpirun"
+        
+    command = pyre.str("command", default="mpirun")
 
-    class Inventory(Component.Inventory):
 
-        import pyre.inventory
+    def launch(self):
+        import os
 
-        nodes = pyre.inventory.int("nodes", default=0)
-        nodelist = pyre.inventory.slice("nodelist")
+        self.executable = os.path.abspath(self.executable)
 
+        argv = self._buildArgumentList()
+        if not argv:
+            return self.dry
+        
+        command = ' '.join(argv)
+        
+        if self.dry:
+            print command
+            return True
+        
+        self._info.log("spawning: %s" % command)
+        status = os.spawnvp(os.P_WAIT, argv[0], argv)
+        statusMsg = "%s: %s: exit %d" % (sys.argv[0], argv[0], status)
+        if status != 0:
+            sys.exit(statusMsg)
+        self._info.log(statusMsg)
 
-    def launch(self):
-        raise NotImplementedError("class '%s' must override 'launch'" % self.__class__.__name__)
+        return True
 
 
-    def __init__(self, name):
-        Component.__init__(self, name, facility="launcher")
-        self.nodes = 0
-        self.nodelist = None
-        return
+    def _buildArgumentList(self):
+        if not self.nodes:
+            self.nodes = len(self.nodelist)
 
+        if self.nodes < 1:
+            self.nodes = 1
 
-    def _configure(self):
-        self.nodes = self.inventory.nodes
-        self.nodelist = self.inventory.nodelist
-        return
+        # build the command
+        args = self.command.split(' ')
+        self._appendMpiRunArgs(args)
 
+        args.append(self.executable)
+        args += self.arguments
 
-# version
-__id__ = "$Id: Launcher.py,v 1.1.1.1 2005/03/08 16:13:30 aivazis Exp $"
+        return args
 
-# End of file 
+
+    def _appendMpiRunArgs(self, args):
+        args.append(self.extra)
+        args.append("-np %d" % self.nodes)
+        
+        # use only the specific nodes specified explicitly
+        if self.nodelist:
+            self._appendNodeListArgs(args)
+
+
+# end of file 

Modified: cs/pythia/trunk/mpi/LauncherMPICH.py
===================================================================
--- cs/pythia/trunk/mpi/LauncherMPICH.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/mpi/LauncherMPICH.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -2,11 +2,10 @@
 #
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 #
-#                             Michael A.G. Aivazis
 #                      California Institute of Technology
-#                      (C) 1998-2005  All Rights Reserved
+#                        (C) 2006  All Rights Reserved
 #
-# <LicenseText>
+# {LicenseText}
 #
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 #
@@ -18,81 +17,23 @@
 class LauncherMPICH(Launcher):
 
 
-    class Inventory(Launcher.Inventory):
+    name = "mpich"
 
-        import pyre.inventory
 
-        dry = pyre.inventory.bool("dry", default=False)
-        debug = pyre.inventory.bool("debug", default=False)
-        nodegen = pyre.inventory.str("nodegen")
-        extra = pyre.inventory.str("extra")
-        command = pyre.inventory.str("command", default="mpirun")
-        python_mpi = pyre.inventory.str("python-mpi", default="`which mpipython.exe`")
-        machinefile = pyre.inventory.str("machinefile", default="mpirun.nodes")
+    import pyre.inventory as pyre
 
+    machinefile = pyre.str("machinefile", default="mpirun.nodes")
+    machinefile.meta['tip'] = """filename of machine file"""
 
-    def launch(self):
-        args = self._buildArgumentList()
-        if not args:
-            return False
-        
-        command = " ".join(args)
-        self._info.log("executing: {%s}" % command)
 
-        dry = self.inventory.dry
-        if not dry:
-            import os
-            os.system(command)
-            return True
+    def _appendNodeListArgs(self, args):
+        machinefile = self.machinefile
+        nodegen = self.nodegen
+        file = open(machinefile, "w")
+        for node in self.nodelist:
+            file.write((nodegen + '\n') % node)
+        file.close()
+        args.append("-machinefile %s" % machinefile)
 
-        return False
 
-            
-    def __init__(self):
-        Launcher.__init__(self, "mpirun")
-        return
-
-
-    def _buildArgumentList(self):
-        import sys
-
-        nodes = self.nodes
-        nodelist = self.nodelist
-        nodegen = self.inventory.nodegen
-        python_mpi = self.inventory.python_mpi
-        machinefile = self.inventory.machinefile
-
-        if not nodes:
-            nodes = len(nodelist)
-
-        if nodes < 2:
-            self.inventory.nodes = 1
-            return []
-        
-        # build the command
-        args = []
-        args.append(self.inventory.command)
-        args.append(self.inventory.extra)
-        args.append("-np %d" % nodes)
-
-        # use only the specific nodes specified explicitly
-        if nodelist:
-            file = open(machinefile, "w")
-            for node in nodelist:
-                file.write((nodegen + '\n') % node)
-            file.close()
-            args.append("-machinefile %s" % machinefile)
-
-        # add the parallel version of the interpreter on the command line
-        args.append(python_mpi)
-
-        args += sys.argv
-        args.append("--mode=worker")
-
-        return args
-
-
-# version
-__id__ = "$Id: LauncherMPICH.py,v 1.1.1.1 2005/03/08 16:13:30 aivazis Exp $"
-
-# End of file 
+# end of file 

Deleted: cs/pythia/trunk/mpi/LauncherPBS.py
===================================================================
--- cs/pythia/trunk/mpi/LauncherPBS.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/mpi/LauncherPBS.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -1,131 +0,0 @@
-#!/usr/bin/env python
-#
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-#
-#                             Michael A.G. Aivazis
-#                      California Institute of Technology
-#                      (C) 1998-2005  All Rights Reserved
-#
-# <LicenseText>
-#
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-#
-
-# NYI: this needs some serious attention
-
-from Launcher import Launcher
-
-
-class LauncherPBS(Launcher):
-
-
-    class Inventory(Launcher.Inventory):
-
-        import pyre.inventory
-
-        inventory = [
-            pyre.properties.bool("dry", False),
-            pyre.properties.bool("debug", False),
-            pyre.properties.str("extra"),
-
-            pyre.properties.str("command", "qsub"),
-            pyre.properties.str("task"),
-
-            pyre.properties.str("wallclock"),
-            pyre.properties.bool("mail", False),
-            pyre.properties.int("nodes", 1),
-            pyre.properties.str("queue", "standard"),
-
-            pyre.properties.timerep("script"),
-            pyre.properties.str("stdout"),
-            pyre.properties.str("stderr"),
-
-            pyre.properties.str("ext_script", ".pbs"),
-            pyre.properties.str("ext_stdout", ".stdout"),
-            pyre.properties.str("ext_stderr", ".stderr"),
-            ]
-
-
-    def launch(self):
-        import sys
-
-        dry = self.inventory.dry
-
-##FELDMANN
-        nodes = self.inventory.nodes
-        nodelist = self.inventory.nodelist
-        nodegen = self.inventory.nodegen
-        python_mpi = self.inventory.python_mpi
-        machinefile = self.inventory.machinefile
-
-        if not nodes:
-            nodes = len(nodelist)
-
-        if nodes < 2:
-            self.inventory.nodes = 1
-            return False
-##FELDMANN
-
-        
-        # build the command
-        args = []
-        args.append(self.inventory.command)
-        args.append(self.inventory.extra)
-
-        args.append(self.inventory.scriptName)
-        scriptFile = open(self.inventory.scriptName,"w")
-        scriptFile.writeline(build_script_string())
-        scriptFile.close()
-        
-        args += sys.argv
-
-        command = " ".join(args)
-        self._info.log("executing: {%s}" % command)
-
-        if not dry:
-            self._execStrategy(command)
-
-        return True
-
-            
-    def build_script_string(self):
-        script  = [
-           "", 
-           ]
-
-        queue = self.inventory.queue
-        if queue:
-            script.append("#PBS -q %s" % queue)
-
-        task = self.inventory.task
-        if task:
-            script.append("#PBS -N %s" % task)
-
-        nodes = self.inventory.nodes
-        if nodes:
-            script.append("#PBS -l nodes %s" % nodes)
-
-        clock = self.inventory.wallclock
-        if clock:
-            script.append("#PBS -l walltime %s" % clock)
-
-        script += [
-            "#PBS -o %s" % pyre.inventory.stdout,
-            "#PBS -e %s" % pyre.inventory.stderr,
-            ]
-
-        # add the mpirun command line
-        # script += "some command line to submit\n\n"
-
-        return script
-
-
-    def __init__(self):
-        Launcher.__init__(self, "mpirun")
-        return
-
-
-# version
-__id__ = "$Id: LauncherPBS.py,v 1.1.1.1 2005/03/08 16:13:29 aivazis Exp $"
-
-# End of file 

Modified: cs/pythia/trunk/mpi/__init__.py
===================================================================
--- cs/pythia/trunk/mpi/__init__.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/mpi/__init__.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -1,61 +1,49 @@
 #!/usr/bin/env python
 #
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 #
-#                               Michael A.G. Aivazis
-#                        California Institute of Technology
-#                        (C) 1998-2005 All Rights Reserved
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
 #
-# <LicenseText>
+# {LicenseText}
 #
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 #
 
-# timers
-def timingCenter():
-    from TimingCenter import timingCenter
-    return timingCenter()
 
+from _mpi import *
 
-def timer(name):
-    return timingCenter().timer(name)
 
-
 def world():
-    try:
-        import _mpi
-    except:
-        from DummyCommunicator import DummyCommunicator
-        return DummyCommunicator()
-    else:
-        import Communicator
-        return Communicator.world()
+    import Communicator
+    return Communicator.world()
 
 
-def inParallel():
-    try:
-        import _mpi
-    except:
-        return 0
-    else:
-        return 1
+def mpistart(argv=None, **kwds):
+    """entry point for MPI applications"""
 
+    import sys
+    from pyre.applications import start, AppRunner
 
-def processors():
+    if argv is None:
+        argv = sys.argv
+    argv = [sys.executable] + argv
+    
+    MPI_Init(argv)
+
+    argv = argv[1:]
+
     try:
-        import _mpi
+        start(argv,
+              applicationClass = AppRunner,
+              kwds = dict(message = 'onComputeNodes'))
     except:
-        return 1
-    else:
-        return world().size
+        #MPI_Abort(MPI_COMM_WORLD, 1)
+        raise
     
+    MPI_Finalize()
+    
+    return 0
 
-def copyright():
-    return "pythia.mpi: Copyright (c) 1998-2005 Michael A.G. Aivazis"
 
-
-# version
-__version__ = "0.8"
-__id__ = "$Id: __init__.py,v 1.1.1.1 2005/03/08 16:13:30 aivazis Exp $"
-
-# End of file
+# end of file

Added: cs/pythia/trunk/mpi/__vault__.odb
===================================================================
--- cs/pythia/trunk/mpi/__vault__.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/mpi/__vault__.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                             Michael A.G. Aivazis
+#                      California Institute of Technology
+#                      (C) 1998-2005  All Rights Reserved
+#
+# <LicenseText>
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+# version
+__id__ = "$Id: __vault__.odb,v 1.1.1.1 2005/03/08 16:13:58 aivazis Exp $"
+
+# End of file 

Added: cs/pythia/trunk/mpi/_mpi.c
===================================================================
--- cs/pythia/trunk/mpi/_mpi.c	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/mpi/_mpi.c	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,971 @@
+/* Generated by Pyrex 0.9.4.1 on Wed Oct  4 19:01:14 2006 */
+
+#include "Python.h"
+#include "structmember.h"
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#ifdef __cplusplus
+#define __PYX_EXTERN_C extern "C"
+#else
+#define __PYX_EXTERN_C extern
+#endif
+__PYX_EXTERN_C double pow(double, double);
+#include "stdlib.h"
+#include "mpi.h"
+
+
+typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/
+typedef struct {PyObject **p; char *s; long n;} __Pyx_StringTabEntry; /*proto*/
+static PyObject *__Pyx_UnpackItem(PyObject *, int); /*proto*/
+static int __Pyx_EndUnpack(PyObject *, int); /*proto*/
+static int __Pyx_PrintItem(PyObject *); /*proto*/
+static int __Pyx_PrintNewline(void); /*proto*/
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+static void __Pyx_ReRaise(void); /*proto*/
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
+static PyObject *__Pyx_GetExcValue(void); /*proto*/
+static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name); /*proto*/
+static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
+static int __Pyx_GetStarArgs(PyObject **args, PyObject **kwds, char *kwd_list[], int nargs, PyObject **args2, PyObject **kwds2); /*proto*/
+static void __Pyx_WriteUnraisable(char *name); /*proto*/
+static void __Pyx_AddTraceback(char *funcname); /*proto*/
+static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size);  /*proto*/
+static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
+static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
+static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, char *modname); /*proto*/
+static int __Pyx_InternStrings(__Pyx_InternTabEntry *t); /*proto*/
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static int __pyx_lineno;
+static char *__pyx_filename;
+static char **__pyx_f;
+
+/* Declarations from cmpi */
+
+
+/* Declarations from _mpi */
+
+
+struct __pyx_obj_4_mpi_MPI_Comm {
+  PyObject_HEAD
+  MPI_Comm comm;
+};
+
+static PyTypeObject *__pyx_ptype_4_mpi_MPI_Comm = 0;
+static char (__pyx_v_4_mpi_cstring[1024]);
+
+/* Implementation of _mpi */
+
+
+static PyObject *__pyx_n_cmpi;
+static PyObject *__pyx_n_MPI_COMM_WORLD;
+static PyObject *__pyx_n_MPI_Error;
+static PyObject *__pyx_n_MPI_Init;
+static PyObject *__pyx_n_MPI_Finalize;
+static PyObject *__pyx_n_MPI_Comm_rank;
+static PyObject *__pyx_n_MPI_Comm_size;
+static PyObject *__pyx_n_MPI_Error_string;
+static PyObject *__pyx_n_EnvironmentError;
+static PyObject *__pyx_n___str__;
+
+static int __pyx_f_4_mpi_8MPI_Comm___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_f_4_mpi_8MPI_Comm___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_r;
+  static char *__pyx_argnames[] = {0};
+  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "", __pyx_argnames)) return -1;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":17 */
+  ((struct __pyx_obj_4_mpi_MPI_Comm *)__pyx_v_self)->comm = MPI_COMM_WORLD;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1:;
+  __Pyx_AddTraceback("_mpi.MPI_Comm.__init__");
+  __pyx_r = -1;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_args;
+
+static PyObject *__pyx_f_4_mpi_9MPI_Error___str__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_4_mpi_9MPI_Error___str__ = {"__str__", (PyCFunction)__pyx_f_4_mpi_9MPI_Error___str__, METH_VARARGS|METH_KEYWORDS, 0};
+static PyObject *__pyx_f_4_mpi_9MPI_Error___str__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_self = 0;
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  static char *__pyx_argnames[] = {"self",0};
+  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O", __pyx_argnames, &__pyx_v_self)) return 0;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":25 */
+  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error_string); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; goto __pyx_L1;}
+  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_n_args); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; goto __pyx_L1;}
+  __pyx_3 = PyInt_FromLong(0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; goto __pyx_L1;}
+  __pyx_4 = PyObject_GetItem(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_4);
+  __pyx_4 = 0;
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_r = __pyx_3;
+  __pyx_3 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
+  __Pyx_AddTraceback("_mpi.MPI_Error.__str__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_len;
+static PyObject *__pyx_n_append;
+
+static PyObject *__pyx_f_4_mpi_MPI_Init(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_4_mpi_MPI_Init(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_argv = 0;
+  int __pyx_v_error;
+  int __pyx_v_cargc;
+  int __pyx_v_i;
+  char (*(*__pyx_v_cargv));
+  char (*(*__pyx_v_mycargv));
+  PyObject *__pyx_v_myargv;
+  PyObject *__pyx_v_arg;
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  int __pyx_4;
+  char (*__pyx_5);
+  static char *__pyx_argnames[] = {"argv",0};
+  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O", __pyx_argnames, &__pyx_v_argv)) return 0;
+  Py_INCREF(__pyx_v_argv);
+  __pyx_v_myargv = Py_None; Py_INCREF(Py_None);
+  __pyx_v_arg = Py_None; Py_INCREF(Py_None);
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":31 */
+  __pyx_1 = PyList_New(0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; goto __pyx_L1;}
+  Py_DECREF(__pyx_v_myargv);
+  __pyx_v_myargv = __pyx_1;
+  __pyx_1 = 0;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":34 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_len); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; goto __pyx_L1;}
+  Py_INCREF(__pyx_v_argv);
+  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_v_argv);
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  __pyx_4 = PyInt_AsLong(__pyx_3); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; goto __pyx_L1;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  __pyx_v_cargc = __pyx_4;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":35 */
+  __pyx_v_cargv = ((char (*(*)))malloc(((__pyx_v_cargc + 1) * (sizeof(char (*))))));
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":36 */
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_cargc; ++__pyx_v_i) {
+
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":37 */
+    __pyx_1 = PyInt_FromLong(__pyx_v_i); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; goto __pyx_L1;}
+    __pyx_2 = PyObject_GetItem(__pyx_v_argv, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; goto __pyx_L1;}
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    Py_DECREF(__pyx_v_arg);
+    __pyx_v_arg = __pyx_2;
+    __pyx_2 = 0;
+
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":38 */
+    __pyx_3 = PyObject_GetAttr(__pyx_v_myargv, __pyx_n_append); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; goto __pyx_L1;}
+    __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; goto __pyx_L1;}
+    Py_INCREF(__pyx_v_arg);
+    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_v_arg);
+    __pyx_2 = PyObject_CallObject(__pyx_3, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; goto __pyx_L1;}
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":39 */
+    __pyx_5 = PyString_AsString(__pyx_v_arg); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; goto __pyx_L1;}
+    (__pyx_v_cargv[__pyx_v_i]) = __pyx_5;
+    __pyx_L2:;
+  }
+  __pyx_L3:;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":40 */
+  (__pyx_v_cargv[__pyx_v_cargc]) = 0;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":43 */
+  __pyx_v_mycargv = __pyx_v_cargv;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":44 */
+  __pyx_v_error = MPI_Init((&__pyx_v_cargc),(&__pyx_v_cargv));
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":45 */
+  __pyx_4 = (__pyx_v_error != MPI_SUCCESS);
+  if (__pyx_4) {
+
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":46 */
+    free(__pyx_v_mycargv);
+
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":47 */
+    __pyx_3 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; goto __pyx_L1;}
+    __pyx_1 = PyInt_FromLong(__pyx_v_error); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; goto __pyx_L1;}
+    __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_2, 0, __pyx_1);
+    __pyx_1 = 0;
+    __pyx_1 = PyObject_CallObject(__pyx_3, __pyx_2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; goto __pyx_L1;}
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    __Pyx_Raise(__pyx_1, 0, 0);
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; goto __pyx_L1;}
+    goto __pyx_L4;
+  }
+  __pyx_L4:;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":50 */
+  if (PySequence_DelSlice(__pyx_v_argv, 0, 0x7fffffff) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; goto __pyx_L1;}
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":51 */
+  for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_cargc; ++__pyx_v_i) {
+
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":52 */
+    __pyx_3 = PyObject_GetAttr(__pyx_v_argv, __pyx_n_append); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; goto __pyx_L1;}
+    __pyx_2 = PyString_FromString((__pyx_v_cargv[__pyx_v_i])); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; goto __pyx_L1;}
+    __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_2);
+    __pyx_2 = 0;
+    __pyx_2 = PyObject_CallObject(__pyx_3, __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; goto __pyx_L1;}
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    __pyx_L5:;
+  }
+  __pyx_L6:;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":53 */
+  free(__pyx_v_mycargv);
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":55 */
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  __Pyx_AddTraceback("_mpi.MPI_Init");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_myargv);
+  Py_DECREF(__pyx_v_arg);
+  Py_DECREF(__pyx_v_argv);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_4_mpi_MPI_Finalize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_4_mpi_MPI_Finalize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_v_error;
+  PyObject *__pyx_r;
+  int __pyx_1;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  static char *__pyx_argnames[] = {0};
+  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "", __pyx_argnames)) return 0;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":60 */
+  __pyx_v_error = MPI_Finalize();
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":61 */
+  __pyx_1 = (__pyx_v_error != MPI_SUCCESS);
+  if (__pyx_1) {
+
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":62 */
+    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; goto __pyx_L1;}
+    __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
+    __pyx_3 = 0;
+    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    __Pyx_Raise(__pyx_3, 0, 0);
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":63 */
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
+  __Pyx_AddTraceback("_mpi.MPI_Finalize");
+  __pyx_r = 0;
+  __pyx_L0:;
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_4_mpi_MPI_Comm_rank(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_4_mpi_MPI_Comm_rank(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_comm = 0;
+  int __pyx_v_error;
+  int __pyx_v_rank;
+  struct __pyx_obj_4_mpi_MPI_Comm *__pyx_v_c_comm;
+  PyObject *__pyx_r;
+  int __pyx_1;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  static char *__pyx_argnames[] = {"comm",0};
+  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O", __pyx_argnames, &__pyx_v_comm)) return 0;
+  Py_INCREF(__pyx_v_comm);
+  __pyx_v_c_comm = ((struct __pyx_obj_4_mpi_MPI_Comm *)Py_None); Py_INCREF(Py_None);
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":70 */
+  if (!__Pyx_TypeTest(__pyx_v_comm, __pyx_ptype_4_mpi_MPI_Comm)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; goto __pyx_L1;}
+  Py_INCREF(__pyx_v_comm);
+  Py_DECREF(((PyObject *)__pyx_v_c_comm));
+  __pyx_v_c_comm = ((struct __pyx_obj_4_mpi_MPI_Comm *)__pyx_v_comm);
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":71 */
+  __pyx_v_error = MPI_Comm_rank(__pyx_v_c_comm->comm,(&__pyx_v_rank));
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":72 */
+  __pyx_1 = (__pyx_v_error != MPI_SUCCESS);
+  if (__pyx_1) {
+
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":73 */
+    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; goto __pyx_L1;}
+    __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
+    __pyx_3 = 0;
+    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    __Pyx_Raise(__pyx_3, 0, 0);
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":74 */
+  __pyx_2 = PyInt_FromLong(__pyx_v_rank); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; goto __pyx_L1;}
+  __pyx_r = __pyx_2;
+  __pyx_2 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
+  __Pyx_AddTraceback("_mpi.MPI_Comm_rank");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_c_comm);
+  Py_DECREF(__pyx_v_comm);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_4_mpi_MPI_Comm_size(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_4_mpi_MPI_Comm_size(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_comm = 0;
+  int __pyx_v_error;
+  int __pyx_v_size;
+  struct __pyx_obj_4_mpi_MPI_Comm *__pyx_v_c_comm;
+  PyObject *__pyx_r;
+  int __pyx_1;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  static char *__pyx_argnames[] = {"comm",0};
+  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O", __pyx_argnames, &__pyx_v_comm)) return 0;
+  Py_INCREF(__pyx_v_comm);
+  __pyx_v_c_comm = ((struct __pyx_obj_4_mpi_MPI_Comm *)Py_None); Py_INCREF(Py_None);
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":81 */
+  if (!__Pyx_TypeTest(__pyx_v_comm, __pyx_ptype_4_mpi_MPI_Comm)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; goto __pyx_L1;}
+  Py_INCREF(__pyx_v_comm);
+  Py_DECREF(((PyObject *)__pyx_v_c_comm));
+  __pyx_v_c_comm = ((struct __pyx_obj_4_mpi_MPI_Comm *)__pyx_v_comm);
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":82 */
+  __pyx_v_error = MPI_Comm_size(__pyx_v_c_comm->comm,(&__pyx_v_size));
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":83 */
+  __pyx_1 = (__pyx_v_error != MPI_SUCCESS);
+  if (__pyx_1) {
+
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":84 */
+    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; goto __pyx_L1;}
+    __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
+    __pyx_3 = 0;
+    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    __Pyx_Raise(__pyx_3, 0, 0);
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":85 */
+  __pyx_2 = PyInt_FromLong(__pyx_v_size); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; goto __pyx_L1;}
+  __pyx_r = __pyx_2;
+  __pyx_2 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
+  __Pyx_AddTraceback("_mpi.MPI_Comm_size");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_c_comm);
+  Py_DECREF(__pyx_v_comm);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_n_RuntimeError;
+
+static PyObject *__pyx_k2p;
+
+static char (__pyx_k2[]) = "buffer overflow";
+
+static PyObject *__pyx_f_4_mpi_MPI_Error_string(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_4_mpi_MPI_Error_string(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_v_errorcode;
+  int __pyx_v_error;
+  int __pyx_v_resultlen;
+  PyObject *__pyx_v_string;
+  PyObject *__pyx_r;
+  int __pyx_1;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  static char *__pyx_argnames[] = {"errorcode",0};
+  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "i", __pyx_argnames, &__pyx_v_errorcode)) return 0;
+  __pyx_v_string = Py_None; Py_INCREF(Py_None);
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":93 */
+  __pyx_v_error = MPI_Error_string(__pyx_v_errorcode,__pyx_v_4_mpi_cstring,(&__pyx_v_resultlen));
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":94 */
+  __pyx_1 = (__pyx_v_error != MPI_SUCCESS);
+  if (__pyx_1) {
+
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":95 */
+    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; goto __pyx_L1;}
+    __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
+    __pyx_3 = 0;
+    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    __Pyx_Raise(__pyx_3, 0, 0);
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":96 */
+  __pyx_1 = (__pyx_v_resultlen >= 1024);
+  if (__pyx_1) {
+
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":97 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_RuntimeError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; goto __pyx_L1;}
+    Py_INCREF(__pyx_k2p);
+    PyTuple_SET_ITEM(__pyx_4, 0, __pyx_k2p);
+    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    __Pyx_Raise(__pyx_3, 0, 0);
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; goto __pyx_L1;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":98 */
+  __pyx_2 = PyString_FromString(__pyx_v_4_mpi_cstring); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; goto __pyx_L1;}
+  Py_DECREF(__pyx_v_string);
+  __pyx_v_string = __pyx_2;
+  __pyx_2 = 0;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":99 */
+  Py_INCREF(__pyx_v_string);
+  __pyx_r = __pyx_v_string;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
+  __Pyx_AddTraceback("_mpi.MPI_Error_string");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_string);
+  return __pyx_r;
+}
+
+static __Pyx_InternTabEntry __pyx_intern_tab[] = {
+  {&__pyx_n_EnvironmentError, "EnvironmentError"},
+  {&__pyx_n_MPI_COMM_WORLD, "MPI_COMM_WORLD"},
+  {&__pyx_n_MPI_Comm_rank, "MPI_Comm_rank"},
+  {&__pyx_n_MPI_Comm_size, "MPI_Comm_size"},
+  {&__pyx_n_MPI_Error, "MPI_Error"},
+  {&__pyx_n_MPI_Error_string, "MPI_Error_string"},
+  {&__pyx_n_MPI_Finalize, "MPI_Finalize"},
+  {&__pyx_n_MPI_Init, "MPI_Init"},
+  {&__pyx_n_RuntimeError, "RuntimeError"},
+  {&__pyx_n___str__, "__str__"},
+  {&__pyx_n_append, "append"},
+  {&__pyx_n_args, "args"},
+  {&__pyx_n_cmpi, "cmpi"},
+  {&__pyx_n_len, "len"},
+  {0, 0}
+};
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_k2p, __pyx_k2, sizeof(__pyx_k2)},
+  {0, 0, 0}
+};
+
+static PyObject *__pyx_tp_new_4_mpi_MPI_Comm(PyTypeObject *t, PyObject *a, PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  struct __pyx_obj_4_mpi_MPI_Comm *p = (struct __pyx_obj_4_mpi_MPI_Comm *)o;
+  return o;
+}
+
+static void __pyx_tp_dealloc_4_mpi_MPI_Comm(PyObject *o) {
+  struct __pyx_obj_4_mpi_MPI_Comm *p = (struct __pyx_obj_4_mpi_MPI_Comm *)o;
+  (*o->ob_type->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_4_mpi_MPI_Comm(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_4_mpi_MPI_Comm *p = (struct __pyx_obj_4_mpi_MPI_Comm *)o;
+  return 0;
+}
+
+static int __pyx_tp_clear_4_mpi_MPI_Comm(PyObject *o) {
+  struct __pyx_obj_4_mpi_MPI_Comm *p = (struct __pyx_obj_4_mpi_MPI_Comm *)o;
+  return 0;
+}
+
+static struct PyMethodDef __pyx_methods_4_mpi_MPI_Comm[] = {
+  {0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_MPI_Comm = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  0, /*nb_divide*/
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  0, /*nb_coerce*/
+  0, /*nb_int*/
+  0, /*nb_long*/
+  0, /*nb_float*/
+  0, /*nb_oct*/
+  0, /*nb_hex*/
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  0, /*nb_inplace_divide*/
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_MPI_Comm = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_MPI_Comm = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_MPI_Comm = {
+  0, /*bf_getreadbuffer*/
+  0, /*bf_getwritebuffer*/
+  0, /*bf_getsegcount*/
+  0, /*bf_getcharbuffer*/
+};
+
+PyTypeObject __pyx_type_4_mpi_MPI_Comm = {
+  PyObject_HEAD_INIT(0)
+  0, /*ob_size*/
+  "_mpi.MPI_Comm", /*tp_name*/
+  sizeof(struct __pyx_obj_4_mpi_MPI_Comm), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_4_mpi_MPI_Comm, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  0, /*tp_compare*/
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_MPI_Comm, /*tp_as_number*/
+  &__pyx_tp_as_sequence_MPI_Comm, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_MPI_Comm, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_MPI_Comm, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  0, /*tp_doc*/
+  __pyx_tp_traverse_4_mpi_MPI_Comm, /*tp_traverse*/
+  __pyx_tp_clear_4_mpi_MPI_Comm, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_4_mpi_MPI_Comm, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_f_4_mpi_8MPI_Comm___init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_4_mpi_MPI_Comm, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+};
+
+static struct PyMethodDef __pyx_methods[] = {
+  {"MPI_Init", (PyCFunction)__pyx_f_4_mpi_MPI_Init, METH_VARARGS|METH_KEYWORDS, 0},
+  {"MPI_Finalize", (PyCFunction)__pyx_f_4_mpi_MPI_Finalize, METH_VARARGS|METH_KEYWORDS, 0},
+  {"MPI_Comm_rank", (PyCFunction)__pyx_f_4_mpi_MPI_Comm_rank, METH_VARARGS|METH_KEYWORDS, 0},
+  {"MPI_Comm_size", (PyCFunction)__pyx_f_4_mpi_MPI_Comm_size, METH_VARARGS|METH_KEYWORDS, 0},
+  {"MPI_Error_string", (PyCFunction)__pyx_f_4_mpi_MPI_Error_string, METH_VARARGS|METH_KEYWORDS, 0},
+  {0, 0, 0, 0}
+};
+
+static void __pyx_init_filenames(void); /*proto*/
+
+PyMODINIT_FUNC init_mpi(void); /*proto*/
+PyMODINIT_FUNC init_mpi(void) {
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  __pyx_init_filenames();
+  __pyx_m = Py_InitModule4("_mpi", __pyx_methods, 0, 0, PYTHON_API_VERSION);
+  if (!__pyx_m) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; goto __pyx_L1;};
+  __pyx_b = PyImport_AddModule("__builtin__");
+  if (!__pyx_b) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; goto __pyx_L1;};
+  if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; goto __pyx_L1;};
+  if (__Pyx_InternStrings(__pyx_intern_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; goto __pyx_L1;};
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; goto __pyx_L1;};
+  if (PyType_Ready(&__pyx_type_4_mpi_MPI_Comm) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "MPI_Comm", (PyObject *)&__pyx_type_4_mpi_MPI_Comm) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; goto __pyx_L1;}
+  __pyx_ptype_4_mpi_MPI_Comm = &__pyx_type_4_mpi_MPI_Comm;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":20 */
+  __pyx_1 = PyTuple_New(0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; goto __pyx_L1;}
+  __pyx_2 = PyObject_CallObject(((PyObject*)__pyx_ptype_4_mpi_MPI_Comm), __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_MPI_COMM_WORLD, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":23 */
+  __pyx_1 = PyDict_New(); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; goto __pyx_L1;}
+  __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_EnvironmentError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; goto __pyx_L1;}
+  PyTuple_SET_ITEM(__pyx_3, 0, __pyx_2);
+  __pyx_2 = 0;
+  __pyx_2 = __Pyx_CreateClass(__pyx_3, __pyx_1, __pyx_n_MPI_Error, "_mpi"); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; goto __pyx_L1;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":24 */
+  __pyx_3 = PyCFunction_New(&__pyx_mdef_4_mpi_9MPI_Error___str__, 0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; goto __pyx_L1;}
+  __pyx_4 = PyMethod_New(__pyx_3, 0, __pyx_2); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; goto __pyx_L1;}
+  Py_DECREF(__pyx_3); __pyx_3 = 0;
+  if (PyObject_SetAttr(__pyx_2, __pyx_n___str__, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; goto __pyx_L1;}
+  Py_DECREF(__pyx_4); __pyx_4 = 0;
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_MPI_Error, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; goto __pyx_L1;}
+  Py_DECREF(__pyx_2); __pyx_2 = 0;
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":90 */
+  return;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
+  __Pyx_AddTraceback("_mpi");
+}
+
+static char *__pyx_filenames[] = {
+  "_mpi.pyx",
+};
+
+/* Runtime support code */
+
+static void __pyx_init_filenames(void) {
+  __pyx_f = __pyx_filenames;
+}
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
+    PyObject *result;
+    result = PyObject_GetAttr(dict, name);
+    if (!result)
+        PyErr_SetObject(PyExc_NameError, name);
+    return result;
+}
+
+static PyObject *__Pyx_CreateClass(
+    PyObject *bases, PyObject *dict, PyObject *name, char *modname)
+{
+    PyObject *py_modname;
+    PyObject *result = 0;
+    
+    py_modname = PyString_FromString(modname);
+    if (!py_modname)
+        goto bad;
+    if (PyDict_SetItemString(dict, "__module__", py_modname) < 0)
+        goto bad;
+    result = PyClass_New(bases, dict, name);
+bad:
+    Py_XDECREF(py_modname);
+    return result;
+}
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
+    Py_XINCREF(type);
+    Py_XINCREF(value);
+    Py_XINCREF(tb);
+    /* First, check the traceback argument, replacing None with NULL. */
+    if (tb == Py_None) {
+        Py_DECREF(tb);
+        tb = 0;
+    }
+    else if (tb != NULL && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: arg 3 must be a traceback or None");
+        goto raise_error;
+    }
+    /* Next, replace a missing value with None */
+    if (value == NULL) {
+        value = Py_None;
+        Py_INCREF(value);
+    }
+    /* Next, repeatedly, replace a tuple exception with its first item */
+    while (PyTuple_Check(type) && PyTuple_Size(type) > 0) {
+        PyObject *tmp = type;
+        type = PyTuple_GET_ITEM(type, 0);
+        Py_INCREF(type);
+        Py_DECREF(tmp);
+    }
+    if (PyString_Check(type))
+        ;
+    else if (PyClass_Check(type))
+        ; /*PyErr_NormalizeException(&type, &value, &tb);*/
+    else if (PyInstance_Check(type)) {
+        /* Raising an instance.  The value should be a dummy. */
+        if (value != Py_None) {
+            PyErr_SetString(PyExc_TypeError,
+              "instance exception may not have a separate value");
+            goto raise_error;
+        }
+        else {
+            /* Normalize to raise <class>, <instance> */
+            Py_DECREF(value);
+            value = type;
+            type = (PyObject*) ((PyInstanceObject*)type)->in_class;
+            Py_INCREF(type);
+        }
+    }
+    else {
+        /* Not something you can raise.  You get an exception
+           anyway, just not what you specified :-) */
+        PyErr_Format(PyExc_TypeError,
+                 "exceptions must be strings, classes, or "
+                 "instances, not %s", type->ob_type->tp_name);
+        goto raise_error;
+    }
+    PyErr_Restore(type, value, tb);
+    return;
+raise_error:
+    Py_XDECREF(value);
+    Py_XDECREF(type);
+    Py_XDECREF(tb);
+    return;
+}
+
+static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+    if (!type) {
+        PyErr_Format(PyExc_SystemError, "Missing type object");
+        return 0;
+    }
+    if (obj == Py_None || PyObject_TypeCheck(obj, type))
+        return 1;
+    PyErr_Format(PyExc_TypeError, "Cannot convert %s to %s",
+        obj->ob_type->tp_name, type->tp_name);
+    return 0;
+}
+
+static int __Pyx_InternStrings(__Pyx_InternTabEntry *t) {
+    while (t->p) {
+        *t->p = PyString_InternFromString(t->s);
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+
+static void __Pyx_AddTraceback(char *funcname) {
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    PyObject *py_globals = 0;
+    PyObject *empty_tuple = 0;
+    PyObject *empty_string = 0;
+    PyCodeObject *py_code = 0;
+    PyFrameObject *py_frame = 0;
+    
+    py_srcfile = PyString_FromString(__pyx_filename);
+    if (!py_srcfile) goto bad;
+    py_funcname = PyString_FromString(funcname);
+    if (!py_funcname) goto bad;
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    empty_tuple = PyTuple_New(0);
+    if (!empty_tuple) goto bad;
+    empty_string = PyString_FromString("");
+    if (!empty_string) goto bad;
+    py_code = PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        empty_string, /*PyObject *code,*/
+        empty_tuple,  /*PyObject *consts,*/
+        empty_tuple,  /*PyObject *names,*/
+        empty_tuple,  /*PyObject *varnames,*/
+        empty_tuple,  /*PyObject *freevars,*/
+        empty_tuple,  /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        __pyx_lineno,   /*int firstlineno,*/
+        empty_string  /*PyObject *lnotab*/
+    );
+    if (!py_code) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_Get(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = __pyx_lineno;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    Py_XDECREF(empty_tuple);
+    Py_XDECREF(empty_string);
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}

Added: cs/pythia/trunk/mpi/_mpi.pyx
===================================================================
--- cs/pythia/trunk/mpi/_mpi.pyx	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/mpi/_mpi.pyx	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,102 @@
+# Process this file with Pyrex to produce mpi.c
+
+
+cimport cmpi
+
+
+cdef extern from "stdlib.h":
+    void *malloc(int)
+    void free(void *)
+
+
+cdef class MPI_Comm:
+
+    cdef cmpi.MPI_Comm comm
+
+    def __init__(MPI_Comm self):
+        self.comm = cmpi.MPI_COMM_WORLD
+
+
+MPI_COMM_WORLD = MPI_Comm()
+
+
+class MPI_Error(EnvironmentError):
+    def __str__(self):
+        return MPI_Error_string(self.args[0])
+
+
+def MPI_Init(argv):
+    cdef int error, cargc, i
+    cdef char **cargv, **mycargv
+    myargv = []
+
+    # Construct a C char** argument vector from 'argv'.
+    cargc = len(argv)
+    cargv = <char **>malloc((cargc + 1) * sizeof(char *))
+    for i from 0 <= i < cargc:
+        arg = argv[i]
+        myargv.append(arg) # add ref
+        cargv[i] = arg
+    cargv[cargc] = NULL
+
+    # Call MPI_Init().
+    mycargv = cargv; # MPI might allocate & return its own.
+    error = cmpi.MPI_Init(&cargc, &cargv)
+    if error != cmpi.MPI_SUCCESS:
+        free(mycargv)
+        raise MPI_Error(error)
+
+    # Reconstruct Python's 'argv' from the modified 'cargv'.
+    del argv[:]
+    for i from 0 <= i < cargc:
+        argv.append(cargv[i])
+    free(mycargv)
+    
+    return
+
+
+def MPI_Finalize():
+    cdef int error
+    error = cmpi.MPI_Finalize()
+    if error != cmpi.MPI_SUCCESS:
+        raise MPI_Error(error)
+    return
+
+
+def MPI_Comm_rank(comm):
+    cdef int error
+    cdef int rank
+    cdef MPI_Comm c_comm
+    c_comm = comm
+    error = cmpi.MPI_Comm_rank(c_comm.comm, &rank)
+    if error != cmpi.MPI_SUCCESS:
+        raise MPI_Error(error)
+    return rank
+
+
+def MPI_Comm_size(comm):
+    cdef int error
+    cdef int size
+    cdef MPI_Comm c_comm
+    c_comm = comm
+    error = cmpi.MPI_Comm_size(c_comm.comm, &size)
+    if error != cmpi.MPI_SUCCESS:
+        raise MPI_Error(error)
+    return size
+
+
+cdef char cstring[1024]
+
+def MPI_Error_string(int errorcode):
+    cdef int error
+    cdef int resultlen
+    error = cmpi.MPI_Error_string(errorcode, cstring, &resultlen)
+    if error != cmpi.MPI_SUCCESS:
+        raise MPI_Error(error)
+    if resultlen >= 1024:
+        raise RuntimeError("buffer overflow")
+    string = cstring
+    return string
+    
+
+# end of file

Deleted: cs/pythia/trunk/mpi/_mpimodule.h
===================================================================
--- cs/pythia/trunk/mpi/_mpimodule.h	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/mpi/_mpimodule.h	2006-10-08 13:56:34 UTC (rev 4743)
@@ -1,110 +0,0 @@
-// -*- C++ -*-
-// 
-//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// 
-//                               Michael A.G. Aivazis
-//                        California Institute of Technology
-//                        (C) 1998-2005 All Rights Reserved
-// 
-//  <LicenseText>
-// 
-//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// 
-
-#if !defined(pympi__mpimodule_h__)
-#define pympi__mpimodule_h__
-
-#include <mpi.h>
-#include <Python.h>
-
-#if !defined(pympi_Communicator_h__)
-#include "Communicator.h"
-#endif
-
-
-namespace mpi {
-    
-    class _mpimodule;
-    
-}
-
-
-class mpi::_mpimodule {
-
-// meta-methods
-public:
-    
-    _mpimodule() {
-        static bool once = true;
-        if (once) {
-            once = false;
-            PyImport_AppendInittab("_mpi", &init_mpi);
-        }
-    }
-    
-    ~_mpimodule() {}
-    
-private:
-    static inline void init_mpi();
-    
-    static PyObject * communicatorRank(PyObject *, PyObject * args) {
-        PyObject * py_comm;
-        if (!PyArg_ParseTuple(args, "O:communicatorRank", &py_comm)) return 0;
-        Communicator * comm = (Communicator *) PyCObject_AsVoidPtr(py_comm);
-        return PyInt_FromLong(comm->rank());
-    }
-    
-    static PyObject * communicatorSize(PyObject *, PyObject * args) {
-        PyObject * py_comm;
-        if (!PyArg_ParseTuple(args, "O:communicatorSize", &py_comm)) return 0;
-        Communicator * comm = (Communicator *) PyCObject_AsVoidPtr(py_comm);
-        return PyInt_FromLong(comm->size());
-    }
-    
-};
-
-
-inline void mpi::_mpimodule::init_mpi()
-{
-    static struct PyMethodDef _methods[] = {
-        {"communicatorRank", communicatorRank, METH_VARARGS, ""},
-        {"communicatorSize", communicatorSize, METH_VARARGS, ""},
-        {0, 0}
-    };
-
-    // create the module and add the functions
-    PyObject * m = Py_InitModule4(
-        "_mpi", _methods, "", 0, PYTHON_API_VERSION);
-
-    // get its dictionary
-    PyObject * d = PyModule_GetDict(m);
-
-    // check for errors
-    if (PyErr_Occurred()) {
-        Py_FatalError("can't initialize module _mpi");
-    }
-
-    // install the module exceptions
-    PyObject *pympi_runtimeError = PyErr_NewException("mpi.runtime", 0, 0);
-    PyDict_SetItemString(d, "RuntimeException", pympi_runtimeError);
-
-    // add some constants
-    PyDict_SetItemString(d, "initialized", PyLong_FromLong(1));
-    PyDict_SetItemString(
-        d, "world", PyCObject_FromVoidPtr(new mpi::Communicator(MPI_COMM_WORLD), 0));
-
-    return;
-}
-
-
-namespace mpi {
-    static _mpimodule _theModule;
-}
-
-
-// version
-// $Id: _mpimodule.cc,v 1.1.1.1 2005/03/08 16:13:30 aivazis Exp $
-
-#endif
-
-// End of file

Added: cs/pythia/trunk/mpi/cmpi.pxd
===================================================================
--- cs/pythia/trunk/mpi/cmpi.pxd	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/mpi/cmpi.pxd	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,19 @@
+# Pyrex module for MPI
+
+cdef extern from "mpi.h":
+
+    enum MPI_Error:
+        MPI_SUCCESS
+
+    ctypedef struct MPI_Comm_Imp:
+        pass
+    ctypedef MPI_Comm_Imp *MPI_Comm
+    MPI_Comm MPI_COMM_WORLD
+
+    int MPI_Init(int *, char ***)
+    int MPI_Finalize()
+    int MPI_Comm_rank(MPI_Comm, int *)
+    int MPI_Comm_size(MPI_Comm, int *)
+    int MPI_Error_string(int, char *, int *)
+
+# end of file

Added: cs/pythia/trunk/mpi/launchers/__vault__.odb
===================================================================
--- cs/pythia/trunk/mpi/launchers/__vault__.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/mpi/launchers/__vault__.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                             Michael A.G. Aivazis
+#                      California Institute of Technology
+#                      (C) 1998-2005  All Rights Reserved
+#
+# <LicenseText>
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+# version
+__id__ = "$Id: __vault__.odb,v 1.1.1.1 2005/03/08 16:13:58 aivazis Exp $"
+
+# End of file 

Added: cs/pythia/trunk/mpi/launchers/mpich.odb
===================================================================
--- cs/pythia/trunk/mpi/launchers/mpich.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/mpi/launchers/mpich.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+def launcher():
+    from mpi.LauncherMPICH import LauncherMPICH
+    return LauncherMPICH()
+
+
+# end of file

Added: cs/pythia/trunk/mpi/pympi.h
===================================================================
--- cs/pythia/trunk/mpi/pympi.h	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/mpi/pympi.h	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,36 @@
+// 
+//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// 
+//                        California Institute of Technology
+//                          (C) 2006  All Rights Reserved
+// 
+//  <LicenseText>
+// 
+//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// 
+
+#if !defined(mpi_pympi_h)
+#define mpi_pympi_h
+
+
+#include <mpi.h>
+#include <Python.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    struct PyMPICommObject {
+        PyObject_HEAD
+        MPI_Comm comm;
+    };
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* mpi_pympi_h */
+
+/* end of file */

Added: cs/pythia/trunk/mpi/scripts/__init__.py
===================================================================
--- cs/pythia/trunk/mpi/scripts/__init__.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/mpi/scripts/__init__.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+# end of file 

Added: cs/pythia/trunk/mpi/scripts/mpistart.py
===================================================================
--- cs/pythia/trunk/mpi/scripts/mpistart.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/mpi/scripts/mpistart.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from mpi import mpistart
+mpistart()
+
+
+# end of file

Modified: cs/pythia/trunk/pyre/__init__.py
===================================================================
--- cs/pythia/trunk/pyre/__init__.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/__init__.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -21,4 +21,46 @@
 __version__ = "0.8"
 __id__ = "$Id: __init__.py,v 1.1.1.1 2005/03/08 16:13:40 aivazis Exp $"
 
+
+
+# a component which allows the user to configure the Python system
+# itself using Pyre
+
+
+from pyre.components import Component
+
+
+class System(Component):
+
+
+    name = "sys"
+
+
+    import pyre.hooks
+    excepthook = pyre.hooks.facility("excepthook", family="excepthook", default="ultraTB")
+
+
+    def startup(self):
+        import pyre.inventory
+        registry = self.createRegistry()
+        self.registry = registry
+        curator = pyre.inventory.curator(self.name)
+        curator.config(registry)
+        self.setCurator(curator)
+        curator.depositories += self.inventory.getDepositories()
+        self.initializeConfiguration()
+        self.applyConfiguration()
+        self.init()
+
+        import sys
+        if self.excepthook:
+            sys.excepthook = self.excepthook.excepthook
+
+        return
+
+
+system = System()
+system.startup()
+
+
 # End of file 

Added: cs/pythia/trunk/pyre/__vault__.odb
===================================================================
--- cs/pythia/trunk/pyre/__vault__.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/__vault__.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                             Michael A.G. Aivazis
+#                      California Institute of Technology
+#                      (C) 1998-2005  All Rights Reserved
+#
+# <LicenseText>
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+# version
+__id__ = "$Id: __vault__.odb,v 1.1.1.1 2005/03/08 16:13:58 aivazis Exp $"
+
+# End of file 

Added: cs/pythia/trunk/pyre/applications/AppRunner.py
===================================================================
--- cs/pythia/trunk/pyre/applications/AppRunner.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/applications/AppRunner.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from SuperScript import SuperScript
+
+
+class AppRunner(SuperScript):
+
+
+    name = "AppRunner"
+
+
+    def createSubscript(self, name):
+        from pyre.util import loadObject
+        cls = loadObject(name)
+        return cls()
+
+
+
+# end of file

Modified: cs/pythia/trunk/pyre/applications/Application.py
===================================================================
--- cs/pythia/trunk/pyre/applications/Application.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/applications/Application.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -19,6 +19,9 @@
 class Application(Component, Executive):
 
 
+    name = "application"
+
+
     class Inventory(Component.Inventory):
 
         import pyre.inventory
@@ -44,7 +47,11 @@
         self.registry = registry
 
         # command line
-        help, self.argv = self.processCommandline(registry)
+        argv = self.getArgv(*args, **kwds)
+        commandLine = self.processCommandline(registry, argv)
+        action = commandLine.action
+        self.argv = commandLine.processed
+        self.unprocessedArguments = commandLine.unprocessed
 
         # curator
         curator = self.createCurator()
@@ -53,6 +60,9 @@
         # look for my settings
         self.initializeConfiguration()
 
+        # read parameter files given on the command line
+        self.readParameterFiles(registry)
+
         # give descendants an opportunity to collect input from other (unregistered) sources
         self.collectUserInput(registry)
 
@@ -60,8 +70,13 @@
         self.updateConfiguration(registry)
 
         # transfer user input to my inventory
-        unknownProperties, unknownComponents = self.applyConfiguration()
+        context = self.applyConfiguration()
 
+        # verify that the user input did not contain any typos
+        if not self.verifyConfiguration(context, self.inventory.typos):
+            import sys
+            sys.exit("%s: configuration error(s)" % self.name)
+
         # initialize the trait cascade
         self.init()
 
@@ -69,12 +84,15 @@
         self.generateBanner()
 
         # the main application behavior
-        if help:
-            self.help()
+        action = action and getattr(self, action)
+        if action:
+            action()
         elif self._showHelpOnly:
             pass
-        elif self.verifyConfiguration(unknownProperties, unknownComponents, self.inventory.typos):
-            self.execute(*args, **kwds)
+        else:
+            message = kwds.get('message', 'execute')
+            method = getattr(self, message)
+            method(*args, **kwds)
 
         # shutdown
         self.fini()
@@ -98,6 +116,31 @@
         return curator
 
 
+    def readParameterFiles(self, registry):
+        """read parameter files given on the command line"""
+        import journal
+        error = journal.error(self.name)
+        from os.path import isfile, splitext
+        argv = self.argv
+        self.argv = []
+        for arg in argv:
+            base, ext = splitext(arg)
+            encoding = ext[1:] # NYI: not quite
+            codec = self.getCurator().codecs.get(encoding)
+            if codec:
+                try:
+                    shelf = codec.open(base)
+                except Exception, e:
+                    error.log(str(e))
+                else:
+                    paramRegistry = shelf['inventory'].getFacility(self.name)
+                    if paramRegistry:
+                        self.updateConfiguration(paramRegistry)
+            else:
+                self.argv.append(arg)
+        return
+
+    
     def collectUserInput(self, registry):
         """collect user input from additional sources"""
         return
@@ -108,10 +151,11 @@
         return
 
 
-    def __init__(self, name, facility=None):
-        if facility is None:
-            facility = "application"
-            
+    def entryName(self):
+        return self.__class__.__module__ + ':' + self.__class__.__name__
+
+
+    def __init__(self, name=None, facility=None):
         Component.__init__(self, name, facility)
         Executive.__init__(self)
     
@@ -121,6 +165,7 @@
 
         # commandline arguments left over after parsing
         self.argv = []
+        self.unprocessedArguments = []
 
         # the user input
         self.registry = None

Modified: cs/pythia/trunk/pyre/applications/CommandlineParser.py
===================================================================
--- cs/pythia/trunk/pyre/applications/CommandlineParser.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/applications/CommandlineParser.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -20,15 +20,25 @@
             import sys
             argv = sys.argv[1:]
 
-        return self._parse(argv, root)
+        self._parse(argv, root)
 
+        return
 
+
     def __init__(self):
-        self.help = ['?', 'h']
+        self.actions = {
+            'help': ['?', 'h'],
+            'complete': ['c'],
+            }
         self.assignment = '='
         self.prefixes = ['--', '-']
         self.separator = '.'
 
+        self.action = None
+        self.argv = []
+        self.processed = []
+        self.unprocessed = []
+
         import pyre.parsing.locators
         self.locator = pyre.parsing.locators.simple('command line')
 
@@ -39,55 +49,81 @@
 
 
     def _parse(self, argv, root):
-        help = False
-        unprocessed = []
+        self.action = None
+        self.argv = argv
+        self.processed = []
+        self.unprocessed = []
 
-        for arg in argv:
+        while self.argv:
+            arg = self.argv.pop(0)
+            
             self._debug.line("processing '%s'" % arg)
 
             # is this an option
-            for prefix in self.prefixes:
-                if arg.startswith(prefix):
-                    self._debug.line("    prefix: '%s starts with '%s'" % (arg, prefix))
-                    candidate = arg[len(prefix):]
-                    break
-            else:
-                # prefix matching failed; leave this argument alone
-                self._debug.line("    prefix: '%s' is not an option" % arg)
-                unprocessed.append(arg)
+            candidate = self._filterNonOptionArgument(arg)
+            if candidate is None:
                 continue
-                
-            self._debug.line("    prefix: arg='%s' after prefix stripping" % candidate)
 
-            # check for assignment
-            tokens = candidate.split(self.assignment)
-            self._debug.line("    tokens: %s" % `candidate`)
-
-            # dangling =
-            if len(tokens) > 1 and not tokens[1]:
-                self._debug.log("tokens: bad expression: %s" % arg)
-                raise CommandlineParser.CommandlineException("bad expression: '%s': no rhs" % arg)
-
-            # lhs, rhs
-            lhs = tokens[0]
-            if len(tokens) > 1:
-                rhs = tokens[1]
-            else:
-                rhs = "true"
-            self._debug.line("    tokens: key={%s}, value={%s}" % (lhs,  rhs))
-
-            if lhs in self.help:
-                help = True
+            candidate = self._filterAction(candidate)
+            if candidate is None:
                 continue
 
+            lhs, rhs = self._parseArgument(candidate)
+            
             # store this option
             self._processArgument(lhs, rhs, root)
             
         self._debug.log()
 
-        return help, unprocessed
+        return
 
 
+    def _filterNonOptionArgument(self, arg):
+        for prefix in self.prefixes:
+            if arg.startswith(prefix):
+                self._debug.line("    prefix: '%s starts with '%s'" % (arg, prefix))
+                candidate = arg[len(prefix):]
+                return candidate
+        else:
+            # prefix matching failed; leave this argument alone
+            self._debug.line("    prefix: '%s' is not an option" % arg)
+        self.processed.append(arg)
+        return None
+
+
+    def _parseArgument(self, candidate):
+        self._debug.line("    prefix: arg='%s' after prefix stripping" % candidate)
+
+        # check for assignment
+        tokens = candidate.split(self.assignment)
+        self._debug.line("    tokens: %s" % `candidate`)
+
+        # dangling =
+        if len(tokens) > 1 and not tokens[1]:
+            self._debug.log("tokens: bad expression: %s" % arg)
+            raise CommandlineParser.CommandlineException("bad expression: '%s': no rhs" % arg)
+
+        # lhs, rhs
+        lhs = tokens[0]
+        if len(tokens) > 1:
+            rhs = tokens[1]
+        else:
+            rhs = "true"
+        self._debug.line("    tokens: key={%s}, value={%s}" % (lhs,  rhs))
+
+        return lhs, rhs
+
+
+    def _filterAction(self, candidate):
+        for action, args in self.actions.iteritems():
+            if candidate in args:
+                self.action = action
+                self.unprocessed.extend(self.argv)
+                self.argv = []
+                return None
+        return candidate
+
+
     def _processArgument(self, key, value, root):
         separator = self.separator
         fields = key.split(separator)

Modified: cs/pythia/trunk/pyre/applications/Executive.py
===================================================================
--- cs/pythia/trunk/pyre/applications/Executive.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/applications/Executive.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -46,39 +46,33 @@
 
 
     # configuration
-    def processCommandline(self, registry, parser=None):
+    def getArgv(self, *args, **kwds):
+        argv = kwds.get('argv')
+        if argv is None:
+            import sys
+            argv = sys.argv
+        self.arg0 = argv[0]
+        argv = argv[1:]
+        return argv
+
+
+    def processCommandline(self, registry, argv=None, parser=None):
         """convert the command line arguments to a trait registry"""
 
         if parser is None:
             parser = self.createCommandlineParser()
 
-        help, unprocessedArguments = parser.parse(registry)    
+        parser.parse(registry, argv)
 
-        return help, unprocessedArguments
+        return parser
 
 
-    def verifyConfiguration(self, unknownProperties, unknownComponents, mode='strict'):
+    def verifyConfiguration(self, context, mode='strict'):
         """verify that the user input did not contain any typos"""
 
-        if mode == 'relaxed':
-            return True
-        
-        if unknownProperties:
-            print " ## unrecognized properties:"
-            for key, value, locator in unknownProperties:
-                print "    %s <- '%s' from %s" % (key, value, locator)
+        return context.verifyConfiguration(mode)
 
-            self.usage()
-            return False
 
-        if mode == 'pedantic' and unknownComponents:
-            print ' ## unknown components: %s' % ", ".join(unknownComponents)
-            self.usage()
-            return False
-        
-        return True
-
-
     def pruneRegistry(self):
         registry = self.registry
         
@@ -104,11 +98,20 @@
         return
 
 
+    def complete(self):
+        # NYI: bash tab-completion
+        return
+
+
     def usage(self):
         print 'Please consider writing a usage screen for this application'
         return
 
 
+    def __init__(self):
+        self.arg0 = self.name
+
+
 # version
 __id__ = "$Id: Executive.py,v 1.1.1.1 2005/03/08 16:13:48 aivazis Exp $"
 

Modified: cs/pythia/trunk/pyre/applications/Script.py
===================================================================
--- cs/pythia/trunk/pyre/applications/Script.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/applications/Script.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -19,32 +19,12 @@
 class Script(Application, Stager):
 
 
-    def __init__(self, name):
+    def __init__(self, name=None):
         Application.__init__(self, name)
         Stager.__init__(self)
         return
 
 
-    def run(self, *args, **kwds):
-        
-        # Fire-up pdb and IPython when an exception occurs -- if IPython is available.
-        try:
-            import sys, IPython.ultraTB
-            if sys.stderr.isatty():
-                colorScheme = 'Linux'
-            else:
-                colorScheme = 'NoColor'
-            if sys.stdin.isatty() and sys.stdout.isatty() and sys.stderr.isatty():
-                callPdb = 1
-            else:
-                callPdb = 0
-            sys.excepthook = IPython.ultraTB.FormattedTB(mode='Verbose', color_scheme=colorScheme, call_pdb=callPdb)
-        except ImportError:
-            pass
-
-        return super(Script, self).run(*args, **kwds)
-
-
 # version
 __id__ = "$Id: Script.py,v 1.3 2005/03/10 06:06:37 aivazis Exp $"
 

Added: cs/pythia/trunk/pyre/applications/SuperCommandlineParser.py
===================================================================
--- cs/pythia/trunk/pyre/applications/SuperCommandlineParser.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/applications/SuperCommandlineParser.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from CommandlineParser import CommandlineParser
+
+
+class SuperCommandlineParser(CommandlineParser):
+
+
+    def _filterNonOptionArgument(self, arg):
+        candidate = super(SuperCommandlineParser, self)._filterNonOptionArgument(arg)
+        if candidate:
+            return candidate
+        # 'arg' is the first non-option argument -- we are done
+        self.unprocessed.extend(self.argv)
+        self.argv = []
+        return None
+
+
+# end of file

Added: cs/pythia/trunk/pyre/applications/SuperScript.py
===================================================================
--- cs/pythia/trunk/pyre/applications/SuperScript.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/applications/SuperScript.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from Script import Script
+
+
+class SuperScript(Script):
+
+
+    def createCommandlineParser(self):
+        import pyre.applications
+        return pyre.applications.superCommandlineParser()
+
+
+    def createSubscript(self, name):
+        try:
+            factory = self.subscripts[name]
+        except KeyError:
+            self._error.log("unknown command: %s" % name)
+            self.usage()
+            import sys
+            sys.exit(1)
+            
+        subscript = factory()
+        subscript.arg0 = name
+        return subscript
+
+
+    def execute(self, *args, **kwds):
+
+        if len(self.argv) < 1:
+            self.usage()
+            import sys
+            sys.exit(1)
+        
+        subscriptName = self.argv[-1]
+        self.subscript = self.createSubscript(subscriptName)
+        
+        self.main(*args, **kwds)
+        
+        return
+
+
+    def main(self, *args, **kwds):
+        self.runSubscript(*args, **kwds)
+
+
+    def runSubscript(self, *args, **kwds):
+        args = kwds.get('args', [])
+        kwds = kwds.get('kwds', dict())
+        kwds['argv'] = [self.argv[-1]] + self.unprocessedArguments
+        self.subscript.run(*args, **kwds)
+
+
+    def usage(self):
+        print 'usage: %s [options] <command> [COMMAND-ARG...]' % self.arg0
+        return
+
+
+# end of file

Modified: cs/pythia/trunk/pyre/applications/__init__.py
===================================================================
--- cs/pythia/trunk/pyre/applications/__init__.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/applications/__init__.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -11,11 +11,33 @@
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 #
 
+
+from Application import Application
+from AppRunner import AppRunner
+from Script import Script
+from SuperScript import SuperScript
+
+
 def commandlineParser():
     from CommandlineParser import CommandlineParser
     return CommandlineParser()
     
 
+def superCommandlineParser():
+    from SuperCommandlineParser import SuperCommandlineParser
+    return SuperCommandlineParser()
+    
+
+def start(argv=None, **kwds):
+    """general-purpose entry point for applications"""
+    cls = kwds.get('applicationClass')
+    app = cls()
+    kwds = dict(**kwds)
+    kwds['argv'] = argv
+    app.run(**kwds)
+    return 0
+
+
 # version
 __id__ = "$Id: __init__.py,v 1.1.1.1 2005/03/08 16:13:49 aivazis Exp $"
 

Modified: cs/pythia/trunk/pyre/components/Component.py
===================================================================
--- cs/pythia/trunk/pyre/components/Component.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/components/Component.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -47,9 +47,9 @@
         return Configurable.updateConfiguration(self, registry)
 
 
-    def __init__(self, name, facility):
+    def __init__(self, name=None, facility=None):
         Configurable.__init__(self, name)
-        self.facility = facility
+        #self.facility = facility # not used
 
         self._showHelpOnly = False
         

Modified: cs/pythia/trunk/pyre/components/__init__.py
===================================================================
--- cs/pythia/trunk/pyre/components/__init__.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/components/__init__.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -12,6 +12,9 @@
 #
 
 
+from Component import Component
+
+
 # version
 __id__ = "$Id: __init__.py,v 1.1.1.1 2005/03/08 16:13:44 aivazis Exp $"
 


Property changes on: cs/pythia/trunk/pyre/hooks
___________________________________________________________________
Name: svn:ignore
   + *.pyc


Added: cs/pythia/trunk/pyre/hooks/ExceptHook.py
===================================================================
--- cs/pythia/trunk/pyre/hooks/ExceptHook.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/hooks/ExceptHook.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from pyre.components import Component
+
+
+class ExceptHook(Component):
+
+
+    name = "excepthook"
+
+
+    def __init__(self, excepthook):
+        Component.__init__(self)
+        self.excepthook = excepthook
+
+
+# end of file 

Added: cs/pythia/trunk/pyre/hooks/__init__.py
===================================================================
--- cs/pythia/trunk/pyre/hooks/__init__.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/hooks/__init__.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from ExceptHook import ExceptHook
+
+
+# facilities and components
+
+def facility(name, **kwds):
+    from pyre.inventory.Facility import Facility
+    kwds['vault'] = kwds.get('vault', ['hooks'])
+    kwds['family'] = kwds.get('family', 'hook')
+    return Facility(name, **kwds)
+
+
+# end of file 

Added: cs/pythia/trunk/pyre/hooks/__vault__.odb
===================================================================
--- cs/pythia/trunk/pyre/hooks/__vault__.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/hooks/__vault__.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+# end of file

Added: cs/pythia/trunk/pyre/hooks/built-in.odb
===================================================================
--- cs/pythia/trunk/pyre/hooks/built-in.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/hooks/built-in.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+def excepthook():
+    from pyre.hooks import ExceptHook
+    import sys
+    
+    hook = ExceptHook(sys.__excepthook__)
+    
+    return hook
+
+
+# end of file

Added: cs/pythia/trunk/pyre/hooks/current.odb
===================================================================
--- cs/pythia/trunk/pyre/hooks/current.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/hooks/current.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+def excepthook():
+    from pyre.hooks import ExceptHook
+    import sys
+    
+    hook = ExceptHook(sys.excepthook)
+    
+    return hook
+
+
+# end of file

Added: cs/pythia/trunk/pyre/hooks/ultraTB.odb
===================================================================
--- cs/pythia/trunk/pyre/hooks/ultraTB.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/hooks/ultraTB.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+def excepthook():
+
+    try:
+        import IPython.ultraTB
+    except ImportError:
+        return None
+
+
+    from pyre.components import Component
+
+
+    class ultraTB(Component):
+
+
+        name = "ultraTB"
+
+
+        import pyre.inventory as pyre
+
+        mode         = pyre.str("mode", default="Verbose")
+        colorScheme  = pyre.str("color-scheme", default="Linux")
+        callPdb      = pyre.bool("call-pdb", default=True)
+
+        callPdb.meta['tip'] = 'call pdb when an exception occurs'
+
+
+        def __init__(self):
+            Component.__init__(self)
+            self.excepthook = None
+
+
+        def _init(self):
+            import sys
+
+            if sys.stderr.isatty():
+                colorScheme = self.colorScheme
+            else:
+                colorScheme = "NoColor"
+
+            if sys.stdin.isatty() and sys.stdout.isatty() and sys.stderr.isatty():
+                callPdb = self.callPdb
+            else:
+                callPdb = False
+
+            self.excepthook = IPython.ultraTB.FormattedTB(
+                mode          = self.mode,
+                color_scheme  = colorScheme,
+                call_pdb      = callPdb
+                )
+
+            return
+
+
+    hook = ultraTB()
+
+    return hook
+    
+
+
+# end of file

Copied: cs/pythia/trunk/pyre/idd/__vault__.odb (from rev 4634, cs/pythia/trunk/idd/__vault__.odb)

Copied: cs/pythia/trunk/pyre/idd/idd-pickler.odb (from rev 4634, cs/pythia/trunk/idd/idd-pickler.odb)

Added: cs/pythia/trunk/pyre/inventory/ConfigContext.py
===================================================================
--- cs/pythia/trunk/pyre/inventory/ConfigContext.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/inventory/ConfigContext.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,122 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+class ConfigContext(object):
+
+
+    def error(self, *args):
+        self.ue.append(args)
+
+
+    def unknownComponent(self, name):
+        self.uuc.append(name)
+
+
+    def unknownProperty(self, *args):
+        self.uup.append(args)
+
+
+    def claim(self, name):
+
+        if not (self.uup or self.uuc or self.ue):
+            return True
+        
+        self.up = [ (name + '.' + key, value, locator)
+                    for key, value, locator in self.uup ]
+        
+        self.uc = [ name + '.' + key
+                    for key in self.uuc]
+        
+        self.ue = [ (error, name + '.' + key, value, locator)
+                    for error, key, value, locator in self.ue ]
+        
+        self.unknownProperties += self.uup
+        self.unknownComponents += self.uuc
+        self.errors += self.ue
+        
+        self.uup = []
+        self.uuc = []
+        self.ue = []
+        
+        return False
+
+
+    def verifyConfiguration(self, modeName):
+        """verify that the user input did not contain any typos"""
+
+        class Channel(object):
+            def __init__(self, factory):
+                self.channel = factory("pyre.inventory")
+                self.tally = 0
+            def line(self, message):
+                self.channel.line(message)
+            def log(self, message=None, locator=None):
+                self.channel.log(message, locator)
+                self.tally += 1
+
+        import journal
+        info     = Channel(journal.info)
+        warning  = Channel(journal.warning)
+        error    = Channel(journal.error)
+
+        mode = dict(
+            relaxed   = dict(up=warning, uc=info,    e=warning),
+            strict    = dict(up=error,   uc=warning, e=error),
+            pedantic  = dict(up=error,   uc=error,   e=error),
+            )
+        
+        channel = mode[modeName]
+
+        if self.unknownProperties:
+            for key, value, locator in self.unknownProperties:
+                problem = ("unrecognized property '%s'" % key, key, value, locator)
+                self.log(channel['up'], problem)
+
+        if self.unknownComponents:
+            self.log(channel['uc'], ("unknown components: %s" % ", ".join(self.unknownComponents),
+                                     None, None, None))
+        
+        if self.errors:
+            for problem in self.errors:
+                self.log(channel['e'], problem)
+
+        return error.tally == 0
+
+
+    def log(self, channel, problem):
+        
+        error, key, value, locator = problem
+
+        if value:
+            channel.line("%s <- '%s'" % (key, value))
+        channel.log(error, locator)
+
+        channel.tally = channel.tally + 1
+        
+        return
+
+
+    def __init__(self):
+        self.unknownProperties = []
+        self.unknownComponents = []
+        self.errors = []
+
+        # unclaimed errors
+        self.uup = []
+        self.uuc = []
+        self.ue = []
+
+        return
+
+
+# end of file 

Modified: cs/pythia/trunk/pyre/inventory/Configurable.py
===================================================================
--- cs/pythia/trunk/pyre/inventory/Configurable.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/inventory/Configurable.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -65,50 +65,59 @@
         return self.inventory.updateConfiguration(registry)
 
 
-    def applyConfiguration(self):
+    def applyConfiguration(self, context=None):
         """transfer user settings to my inventory"""
 
+        if context is None:
+            context = self.newConfigContext()
+        
         # apply user settings to my properties
-        up, uc = self.configureProperties()
-        unknownProperties = up
-        unknownComponents = uc
+        self.configureProperties(context)
 
         # apply user settings to my components
-        up, uc = self.configureComponents()
-        unknownProperties += up
-        unknownComponents += uc
+        self.configureComponents(context)
 
         # give descendants a chance to adjust to configuration changes
         self._configure()
         
-        return (unknownProperties, unknownComponents)
+        return context
 
 
-    def configureProperties(self):
+    def newConfigContext(self):
+        from ConfigContext import ConfigContext
+        return ConfigContext()
+
+
+    def configureProperties(self, context):
         """set the values of all the properties and facilities in my inventory"""
-        up, uc = self.inventory.configureProperties()
-        return self._claim(up, uc)
+        self.inventory.configureProperties(context)
+        self._claim(context)
 
 
-    def configureComponents(self):
+    def configureComponents(self, context):
         """guide my subcomponents through the configuration process"""
-        up, uc = self.inventory.configureComponents()
-        return self._claim(up, uc)
+        self.inventory.configureComponents(context)
+        self._claim(context)
 
 
     def getDepositories(self):
         return self.inventory.getDepositories()
 
     # single component management
-    def retrieveComponent(self, name, factory, args=(), encoding='odb', vault=[], extras=[]):
+    def retrieveComponent(self, name, factory, args=(), encodings=['odb'], vault=[], extras=[]):
         """retrieve component <name> from the persistent store"""
-        return self.inventory.retrieveComponent(name, factory, args, encoding, vault, extras)
+        return self.inventory.retrieveComponent(name, factory, args, encodings, vault, extras)
 
 
-    def configureComponent(self, component, registry=None):
+    def configureComponent(self, component, context=None, registry=None):
         """guide <component> through the configuration process"""
-        up, uc = self.inventory.configureComponent(component, registry)
-        return up, uc
+        
+        if context is None:
+            context = self.newConfigContext()
+        
+        self.inventory.configureComponent(component, context, registry)
+        
+        return context
 
 
     def collectDefaults(self, registry=None):
@@ -118,6 +127,27 @@
         return self.inventory.collectDefaults(registry)
 
 
+    # resource management
+    def retrieveObject(self, name, symbol, encodings, vault=[], extras=[]):
+        """retrieve object <name> from the persistent store"""
+        return self.inventory.retrieveObject(name, symbol, encodings, vault, extras)
+
+
+    def retrieveTemplate(self, name, vault=[], extras=[]):
+        return self.retrieveObject(name, 'template', ['tmpl'], vault, extras)
+
+
+    # vault accessors
+    def getVault(self):
+        """return the address of my vault"""
+        return self.inventory.getVault()
+
+
+    def setVault(self, vault):
+        """set the address of my vault"""
+        return self.inventory.setVault(vault)
+
+
     # curator accessors
     def getCurator(self):
         """return my persistent store manager"""
@@ -278,18 +308,23 @@
         return self.Inventory(self.name)
 
 
-    def __init__(self, name):
+    def __init__(self, name=None):
         Traceable.__init__(self)
-        
-        self.name = name
+
+        if name is None:
+            name = self.name # class attribute
+        else:
+            self.name = name
         self.inventory = self.createInventory()
 
         # other names by which I am known for configuration purposes
         self.aliases = [ name ]
 
         import journal
+        self._debug = journal.debug(name)
         self._info = journal.info(name)
-        self._debug = journal.debug(name)
+        self._error = journal.error(name)
+        self._warning = journal.warning(name)
 
         # modify the inventory defaults that were hardwired at compile time
         # gives derived components an opportunity to modify their default behavior
@@ -321,17 +356,20 @@
 
 
     # misc
-    def _claim(self, up, uc):
+    def _claim(self, context):
         """decorate the missing traits with my name"""
-        rup = [ (self.name + '.' + key, value, locator) for key, value, locator in up ]
-        ruc = [ self.name + '.' + key for key in uc]
-        return rup, ruc
-        
+        return context.claim(self.name)
 
+
     # inventory
     from Inventory import Inventory
 
 
+    # metaclass
+    from ConfigurableClass import ConfigurableClass
+    __metaclass__ = ConfigurableClass
+
+
 # version
 __id__ = "$Id: Configurable.py,v 1.5 2005/03/27 01:22:41 aivazis Exp $"
 

Added: cs/pythia/trunk/pyre/inventory/ConfigurableClass.py
===================================================================
--- cs/pythia/trunk/pyre/inventory/ConfigurableClass.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/inventory/ConfigurableClass.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+class ConfigurableClass(type):
+
+    
+    class TraitForwarder(object):
+        def __init__(self, trait):
+            self.trait = trait
+        def __get__(self, instance, cls=None):
+            return self.trait.__get__(instance and instance.inventory or None,
+                                      cls and cls.Inventory or None)
+        def __set__(self, instance, value):
+            self.trait.__set__(instance.inventory, value)
+
+
+    def __init__(cls, name, bases, dct):
+        
+        type.__init__(cls, name, bases, dct)
+        
+        if dct.has_key('Inventory'):
+            # allow for traditional components
+            return
+        
+        from Notary import Notary
+        from Trait import Trait
+        
+        # derive the bases for the inventory class
+        inventoryBases = []
+        bases = list(bases)
+        for base in bases:
+            baseInventory = getattr(base, 'Inventory', None)
+            if baseInventory:
+                inventoryBases.append(baseInventory)
+        inventoryBases = tuple(inventoryBases)
+
+        # populate the inventory class dictionary
+        import pyre.inventory
+        inventoryDict = {}
+        for traitName, trait in [kv for kv in dct.iteritems() if isinstance(kv[1], Trait)]:
+            # move the trait to the inventory...
+            inventoryDict[traitName] = trait
+            # ...replacing it with a forwarder
+            setattr(cls, traitName, ConfigurableClass.TraitForwarder(trait))
+
+        # create the inventory class
+        cls.Inventory = Notary('%s.Inventory' % name,
+                               inventoryBases,
+                               inventoryDict)
+
+
+# end of file 

Modified: cs/pythia/trunk/pyre/inventory/Facility.py
===================================================================
--- cs/pythia/trunk/pyre/inventory/Facility.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/inventory/Facility.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -18,7 +18,8 @@
 class Facility(Trait):
 
 
-    def __init__(self, name, family=None, default=None, factory=None, args=(), meta=None):
+    def __init__(self, name, family=None, default=None, factory=None, args=(), meta=None,
+                 vault=None):
         Trait.__init__(self, name, 'facility', default, meta)
 
         self.args = args
@@ -28,23 +29,25 @@
             family = name
         self.family = family
 
+        if vault is not None:
+            self.vault = vault
+
         return
 
 
     def _getDefaultValue(self, instance):
         component = self.default
 
-        # build a default locator
         import pyre.parsing.locators
-        here = pyre.parsing.locators.simple('default')
+        locator = pyre.parsing.locators.default()
 
         if component is not None:
             # if we got a string, resolve
             if isinstance(component, basestring):
-                component, locator = self._retrieveComponent(instance, component)
-                here = pyre.parsing.locators.chain(locator, here)
+                component, loc = self._retrieveComponent(instance, component)
+                locator = pyre.parsing.locators.chain(loc, locator)
                 
-            return component, here
+            return component, locator
 
         if self.factory is not None:
             # instantiate the component
@@ -54,9 +57,6 @@
             if self.name not in aliases:
                 aliases.append(self.name)
             
-            # build a default locator
-            import pyre.parsing.locators
-            locator = pyre.parsing.locators.simple('default')
             # return
             return component, locator
 
@@ -94,13 +94,16 @@
 
 
     def _retrieveComponent(self, instance, componentName):
-        component = instance.retrieveComponent(name=componentName, factory=self.family)
+        component = instance.retrieveComponent(
+            name=componentName,
+            factory=self.family,
+            vault=self.vault)
 
         if component is not None:
             locator = component.getLocator()
         else:
             import pyre.parsing.locators
-            component = self._import(componentName)
+            component = self._import(instance, componentName)
 
             if component:
                 locator = pyre.parsing.locators.simple('imported')
@@ -118,35 +121,76 @@
         return instance.retrieveAllComponents(factory=self.family)
 
 
-    def _import(self, name):
-        try:
-            module = __import__(name, {}, {})
-        except ImportError:
-            import journal
-            journal.error("pyre.inventory").log(
-                "could not bind facility '%s': component '%s' not found" % (self.name, name)
-                )
-            return
+    class Error(Exception):
+        def __init__(self, **kwds):
+            self.__dict__.update(kwds)
 
-        try:
-            factory = module.__dict__[self.family]
-        except KeyError:
-            import journal
-            journal.error("pyre.inventory").log(
-                "no factory for facility '%s' in '%s'" % (self.name, module.__file__))
-            return
 
+    class ComponentNotFound(Error):
+        def __str__(self):
+            return "could not bind facility '%(facility)s': component '%(component)s' not found" % self.__dict__
+
+
+    class FactoryNotFound(Error):
+        def __str__(self):
+            return "could not bind facility '%(facility)s': no factory named '%(factory)s' in '%(module)s'" % self.__dict__
+
+
+    class FactoryNotCallable(Error):
+        def __str__(self):
+            return "could not bind facility '%(facility)s': factory '%(module)s:%(factory)s' is not callable" % self.__dict__
+
+
+    def _import(self, instance, name):
+
+        # Initialize my value (preventing further lookups), in case we
+        # don't make it out of here alive.
+        import pyre.parsing.locators
+        locator = pyre.parsing.locators.error()
+        instance._initializeTraitValue(self.name, None, locator)
+
+        factoryName = self.family
+        path = name.split(':')
+        c = len(path)
+        if c == 1:
+            factoryPath = [factoryName]
+        elif c == 2:
+            factoryPath = path[1].split('.')
+            if not factoryPath[-1]:
+                factoryPath.pop()
+                if not factoryPath:
+                    factoryPath.append(factoryName)
+            else:
+                factoryPath.append(factoryName)
+        else:
+            raise Facility.ComponentNotFound(
+                facility=self.name, component=name)
+        module = path[0]
+        factoryName = '.'.join(factoryPath)
+        objName = module + ':' + factoryName
+        
         try:
-            item = factory(*self.args)
-        except TypeError:
-            import journal
-            journal.error("pyre.inventory").log(
-                "no factory for facility '%s' in '%s'" % (self.name, module.__file__))
-            return
+            from pyre.util import loadObject
+            factory = loadObject(objName)
+        except (ImportError, ValueError):
+            raise Facility.ComponentNotFound(
+                facility=self.name, component=name)
+        except AttributeError:
+            raise Facility.FactoryNotFound(
+                facility=self.name, module=module, factory=factoryName)
 
+        if not callable(factory):
+            raise Facility.FactoryNotCallable(
+                facility=self.name, module=module, factory=factoryName)
+
+        item = factory(*self.args)
+
         return item
 
 
+    vault = []
+
+
     # interface registry
     _interfaceRegistry = {}
 

Modified: cs/pythia/trunk/pyre/inventory/Inventory.py
===================================================================
--- cs/pythia/trunk/pyre/inventory/Inventory.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/inventory/Inventory.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -21,7 +21,9 @@
         #      it might be useful when we auto-generate settings for an entire group of clients
         #      whose names may not be known when their configurations are built
         self._priv_registry = self._priv_curator.getTraits(
-            self._priv_name, self._priv_depositories)
+            self._priv_name,
+            vault=self._priv_vault,
+            extraDepositories=self._priv_depositories)
 
         return
 
@@ -40,33 +42,31 @@
         return self._priv_registry.update(registry)
 
 
-    def configureProperties(self):
+    def configureProperties(self, context):
         """configure my properties using user settings in my registry"""
         
-        unknownProperties = []
-
         # loop over the registry property entries and
         # attempt to set the value of the corresponding inventory item
         for name, descriptor in self._priv_registry.properties.iteritems():
             try:
                 prop = self._traitRegistry[name]
             except KeyError:
-                unknownProperties.append((name, descriptor.value, descriptor.locator))
+                context.unknownProperty(name, descriptor.value, descriptor.locator)
                 continue
             
-            prop._set(self, descriptor.value, descriptor.locator)
+            try:
+                prop._set(self, descriptor.value, descriptor.locator)
+            except Exception, error:
+                context.error(error, name, descriptor.value, descriptor.locator)
 
-        return unknownProperties, []
+        return
 
 
-    def configureComponents(self):
+    def configureComponents(self, context):
         """configure my components using options from my registry"""
 
-        unknownProperties = []
-        unknownComponents = []
+        myComponents = self.components(context)
 
-        myComponents = self.components()
-
         aliases = {}
         for component in myComponents:
             # associate a persistent store with every subcomponent
@@ -86,9 +86,7 @@
                 if registry:
                     component.updateConfiguration(registry)
 
-            up, uc = component.applyConfiguration()
-            unknownProperties += up
-            unknownComponents += uc
+            component.applyConfiguration(context)
 
         # loop over the registry facility entries and
         # update the configuration of all the named components/facilities
@@ -99,10 +97,10 @@
             try:
                 component = aliases[name]
             except KeyError:
-                unknownComponents.append(name)
+                context.unknownComponent(name)
                 continue
 
-        return (unknownProperties, unknownComponents)
+        return
 
 
     def retrieveConfiguration(self, registry):
@@ -155,7 +153,7 @@
         return registry
 
 
-    def configureComponent(self, component, registry=None):
+    def configureComponent(self, component, context, registry=None):
         """configure <component> using options from the given registry"""
 
         # if none were given, let the registry be our own
@@ -175,14 +173,13 @@
             component.updateConfiguration(traits)
 
         # apply the settings
-        unknownProperties, unknownComponents = component.applyConfiguration()
+        component.applyConfiguration(context)
 
-        # return the unrecognized traits
-        return (unknownProperties, unknownComponents)
+        return
 
 
     def retrieveComponent(
-        self, name, factory, args=(), encoding='odb', vault=[], extraDepositories=[]):
+        self, name, factory, args=(), encodings=['odb'], vault=[], extraDepositories=[]):
         """retrieve component <name> from the persistent store"""
 
         if extraDepositories:
@@ -190,7 +187,7 @@
             journal.firewall("inventory").log("non-null extraDepositories")
 
         return self._priv_curator.retrieveComponent(
-            name=name, facility=factory, args=args, encoding=encoding,
+            name=name, facility=factory, args=args, encodings=encodings,
             vault=vault, extraDepositories=self._priv_depositories)
         
 
@@ -207,6 +204,19 @@
             vault=vault, extraDepositories=self._priv_depositories)
         
 
+    def retrieveObject(
+        self, name, symbol, encodings, vault=[], extraDepositories=[]):
+        """retrieve object <name> from the persistent store"""
+
+        if extraDepositories:
+            import journal
+            journal.firewall("inventory").log("non-null extraDepositories")
+
+        return self._priv_curator.retrieveObject(
+            name=name, symbol=symbol, encodings=encodings,
+            vault=vault, extraDepositories=self._priv_depositories)
+        
+
     def init(self):
         """initialize subcomponents"""
 
@@ -226,6 +236,18 @@
 
 
     # lower level interface
+    def getVault(self):
+        """return the address of my vault"""
+        return self._priv_vault
+
+
+    def setVault(self, vault):
+        """set the address of my vault"""
+        assert self._priv_depositories is None # must be called before setCurator()
+        self._priv_vault = vault
+        return
+
+
     def getCurator(self):
         """return the curator that resolves my trait requests"""
         return self._priv_curator
@@ -304,20 +326,40 @@
         return self._facilityRegistry.keys()
 
 
-    def components(self):
+    def components(self, context=None):
         """return a list of my components"""
-        candidates = [
-            facility.__get__(self) for facility in self._facilityRegistry.itervalues() ]
+
+        candidates = []
+
+        import pyre.parsing.locators
+        locator = pyre.parsing.locators.default()
+
+        for name, facility in self._facilityRegistry.iteritems():
+            try:
+                component = facility.__get__(self)
+                candidates.append(component)
+            except Exception, error:
+                if context:
+                    context.error(error, name, None, locator)
+                else:
+                    raise
+        
         return filter(None, candidates)
 
 
     def __init__(self, name):
         # the name of the configurable that manages me
         self._priv_name = name
+
+        # the name of my vault
+        self._priv_vault = []
         
         # the manager of my persistent trait store
         self._priv_curator = None
 
+        # the private depositories
+        self._priv_depositories = None
+
         # the accumulator of user supplied state
         self._priv_registry = None
 

Modified: cs/pythia/trunk/pyre/inventory/__init__.py
===================================================================
--- cs/pythia/trunk/pyre/inventory/__init__.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/inventory/__init__.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -35,6 +35,11 @@
     return CodecPML()
 
 
+def codecConfig():
+    from cfg.CodecConfig import CodecConfig
+    return CodecConfig()
+
+
 def renderer(mode="pml"):
     if mode == "pml":
         from pml.Renderer import Renderer


Property changes on: cs/pythia/trunk/pyre/inventory/cfg
___________________________________________________________________
Name: svn:ignore
   + *.pyc


Copied: cs/pythia/trunk/pyre/inventory/cfg/CodecConfig.py (from rev 4638, mc/3D/CitcomS/trunk/CitcomS/Components/CodecConfig.py)
===================================================================
--- mc/3D/CitcomS/trunk/CitcomS/Components/CodecConfig.py	2006-09-27 21:11:50 UTC (rev 4638)
+++ cs/pythia/trunk/pyre/inventory/cfg/CodecConfig.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from pyre.inventory.odb.Registry import Registry
+from pyre.odb.fs.CodecODB import CodecODB
+from Parser import Parser
+
+
+class CodecConfig(CodecODB):
+
+    def __init__(self):
+        CodecODB.__init__(self, encoding='cfg')
+        return
+
+    def _decode(self, shelf):
+        root = Registry("root")
+        parser = Parser(root)
+        parser.read(shelf.name)
+        shelf['inventory'] = root
+        shelf._frozen = True
+        return
+
+
+# end of file

Copied: cs/pythia/trunk/pyre/inventory/cfg/Parser.py (from rev 4638, mc/3D/CitcomS/trunk/CitcomS/Components/HackedConfigParser.py)
===================================================================
--- mc/3D/CitcomS/trunk/CitcomS/Components/HackedConfigParser.py	2006-09-27 21:11:50 UTC (rev 4638)
+++ cs/pythia/trunk/pyre/inventory/cfg/Parser.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from ConfigParser import SafeConfigParser
+import pyre.parsing.locators as locators
+
+
+class Parser(SafeConfigParser):
+
+    """Python's SafeConfigParser, hacked to provide file & line info,
+    and extended to populate a Pyre Registry."""
+
+    # This class goes to extreme lengths to extract file and line info
+    # from Python's ConfigParser module.  It injects proxy 'file' and
+    # 'dict' objects into ConfigParser's code.  As the file is parsed,
+    # the proxy objects gain control, spying upon the parsing process.
+    
+    # We should probably write our own parser... *sigh*
+
+    class FileProxy(object):
+
+        def __init__(self):
+            self.fp = None
+            self.name = "unknown"
+            self.lineno = 0
+
+        def readline(self, size=-1):
+            line = self.fp.readline()
+            if line:
+                self.lineno = self.lineno + 1
+            return line
+
+        def __getattr__(self, name):
+            return getattr(self.fp, name)
+
+    class Section(dict):
+
+        def __init__(self, sectname, node, fp):
+            dict.__init__(self)
+            self.node = node
+            self.fp = fp
+        
+        def __setitem__(self, key, value):
+            locator = locators.file(self.fp.name, self.fp.lineno)
+            self.node.setProperty(key, value, locator)
+            dict.__setitem__(self, key, value)
+
+    class SectionDict(dict):
+
+        def __init__(self, root):
+            dict.__init__(self)
+            self.root = root
+            self.fp = Parser.FileProxy()
+        
+        def __contains__(self, sectname):
+            # Prevent 'ConfigParser' from creating section
+            # dictionaries; instead, create our own.
+            if not dict.__contains__(self, sectname):
+                node = self._getNode(self.root, sectname.split('.'))
+                cursect = Parser.Section(sectname, node, self.fp)
+                self[sectname] = cursect
+            return True
+        
+        def __setitem__(self, key, value):
+            dict.__setitem__(self, key, value)
+
+        def _getNode(self, node, path):
+            if len(path) == 0:
+                return node
+            key = path[0].strip()
+            return self._getNode(node.getNode(key), path[1:])
+    
+    def __init__(self, root, defaults=None):
+        SafeConfigParser.__init__(self, defaults)
+        self._sections = Parser.SectionDict(root)
+
+    def _read(self, fp, fpname):
+        self._sections.fp.fp = fp
+        self._sections.fp.name = fpname
+        self._sections.fp.lineno = 0
+        SafeConfigParser._read(self, self._sections.fp, fpname)
+        self._sections.fp.__init__()
+
+    def optionxform(self, optionstr):
+        # Don't lower() option names.
+        return optionstr
+
+
+# end of file

Added: cs/pythia/trunk/pyre/inventory/cfg/__init__.py
===================================================================
--- cs/pythia/trunk/pyre/inventory/cfg/__init__.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/inventory/cfg/__init__.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                             Michael A.G. Aivazis
+#                      California Institute of Technology
+#                      (C) 1998-2005  All Rights Reserved
+#
+# <LicenseText>
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+# version
+__id__ = "$Id: __init__.py,v 1.1.1.1 2005/03/08 16:13:43 aivazis Exp $"
+
+# End of file 

Modified: cs/pythia/trunk/pyre/inventory/odb/Curator.py
===================================================================
--- cs/pythia/trunk/pyre/inventory/odb/Curator.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/inventory/odb/Curator.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -18,19 +18,22 @@
 class Curator(Base):
 
 
-    def getTraits(self, name, extraDepositories=[], encoding='pml'):
+    def getTraits(self, name, encodings=['pml','cfg'], vault=[], extraDepositories=[]):
         """load cascade of inventory values for component <name>"""
 
         # initialize the registry object
         registry = self._registryFactory(name)
 
-        # get the relevant codec
-        codec = self.codecs[encoding]
+        # get the relevant codecs
+        codecs = [self.codecs[encoding] for encoding in encodings]
         
+        # create the depository address
+        location = vault + [name]
+
         # loop over depositories loading relevant traits
         for traits, locator in self.loadSymbol(
             tag=name,
-            codec=codec, address=[name], symbol='inventory', extras=extraDepositories,
+            codecs=codecs, address=location, symbol='inventory', extras=extraDepositories,
             errorHandler=self._recordTraitLookup):
 
             # update the registry
@@ -48,22 +51,19 @@
 
 
     def retrieveComponent(
-        self, name, facility, args=(), encoding='odb', vault=[], extraDepositories=[]):
+        self, name, facility, args=(), encodings=['odb'], vault=[], extraDepositories=[]):
         """construct a component by locating and invoking a component factory"""
 
-        # get the requested codec
-        codec = self.codecs[encoding]
+        # get the requested codecs
+        codecs = [self.codecs[encoding] for encoding in encodings]
 
         # create the depository address
-        if vault:
-            location = vault + [name]
-        else:
-            location = [name]
+        location = vault + [name]
 
         # loop over my depositories looking for apprpriate factories
         for factory, locator in self.loadSymbol(
             tag=name,
-            codec=codec, address=location, symbol=facility, extras=extraDepositories,
+            codecs=codecs, address=location, symbol=facility, extras=extraDepositories,
             errorHandler=self._recordComponentLookup):
 
             if not callable(factory):
@@ -71,26 +71,21 @@
                     name, locator, "factory '%s' found but not callable" % facility)
                 continue
 
-            try:
-                component = factory(*args)
-            except TypeError, message:
-                self._recordComponentLookup(
-                    name, locator, "error invoking '%s': %s" % (facility, message))
-                continue
+            component = factory(*args)
 
-            # set the locator
             if component:
+                # set the locator
                 component.setLocator(locator)
 
+                # set the vault
+                component.setVault(vault)
+
             # record this request
             self._recordComponentLookup(name, locator, "success")
 
             return component
                 
         # return failure
-        import pyre.parsing.locators
-        locator = pyre.parsing.locators.simple('not found')
-        
         return None
 
 
@@ -120,10 +115,13 @@
                     facility, locator, "error invoking '%s': %s" % (facility, message))
                 continue
 
-            # set the locator
             if component:
+                # set the locator
                 component.setLocator(locator)
 
+                # set the vault
+                component.setVault(vault)
+
             # record this request
             self._recordComponentLookup(facility, locator, "success")
 
@@ -132,6 +130,31 @@
         return components
 
 
+    def retrieveObject(
+        self, name, symbol, encodings, vault=[], extraDepositories=[]):
+        """construct an object from the persistent store"""
+
+        # get the requested codecs
+        codecs = [self.codecs[encoding] for encoding in encodings]
+
+        # create the depository address
+        location = vault + [name]
+
+        # loop over my depositories looking for apprpriate factories
+        for obj, locator in self.loadSymbol(
+            tag=name,
+            codecs=codecs, address=location, symbol=symbol, extras=extraDepositories,
+            errorHandler=self._recordObjectLookup):
+
+            # record this request
+            self._recordObjectLookup(name, locator, "success")
+
+            return obj
+
+        # return failure
+        return None
+
+
     def config(self, registry):
         # gain access to the installation defaults
         import prefix
@@ -167,11 +190,22 @@
         userDepository = self.setUserDepository(user)
         systemDepository = self.setSystemDepository(system)
 
+        # create the built-in depositories
+        from pkg_resources import resource_listdir, resource_isdir, resource_exists, resource_filename, Requirement
+        pythia = Requirement.parse("pythia")
+        entries = resource_listdir(pythia, "")
+        for entry in entries:
+            if resource_isdir(pythia, entry):
+                vault = entry + '/__vault__.odb'
+                if resource_exists(pythia, vault):
+                    builtin = self.createDepository(resource_filename(pythia, entry))
+                    self.builtinDepositories.append(builtin)
+
         return
 
 
     def createPrivateDepositories(self, name):
-        """ create private system and user depositories from <name>"""
+        """create private system and user depositories from <name>"""
 
         # initialize the depository list
         depositories = []
@@ -225,9 +259,20 @@
                 for entry in record:
                     print "            %s: %s" % entry
             
+        if self._objectRequests:
+            print "    object requests:"
+            for symbol, record in self._objectRequests.iteritems():
+                print "        object='%s'" % symbol
+                for entry in record:
+                    print "            %s: %s" % entry
+            
         return
 
 
+    def searchOrder(self, extraDepositories=[]):
+        return Base.searchOrder(self, extraDepositories) + self.builtinDepositories
+
+
     def __init__(self, name):
         Base.__init__(self, name)
 
@@ -235,12 +280,16 @@
         self.userDepository = None
         self.systemDepository = None
 
+        # the built-in depositories
+        self.builtinDepositories = []
+
         # install the peristent store recognizers
         self._registerCodecs()
 
         # keep a record of requests
         self._traitRequests = {}
         self._componentRequests = {}
+        self._objectRequests = {}
         
         # constants
         # the curator commandline argument name
@@ -250,15 +299,19 @@
 
 
     def _registerCodecs(self):
-        # codec for properties
+        # codecs for properties
         import pyre.inventory
         pml = pyre.inventory.codecPML()
+        cfg = pyre.inventory.codecConfig()
 
         import pyre.odb
         odb = pyre.odb.odb()
 
-        self.registerCodecs(pml, odb)
+        import pyre.templates
+        tmpl = pyre.templates.codecTmpl()
 
+        self.registerCodecs(pml, cfg, odb, tmpl)
+
         return
 
 
@@ -279,6 +332,12 @@
         return
 
 
+    def _recordObjectLookup(self, symbol, filename, message):
+        requests = self._objectRequests.setdefault(symbol, [])
+        requests.append((filename, message))
+        return
+
+
 # version
 __id__ = "$Id: Curator.py,v 1.2 2005/03/10 06:06:37 aivazis Exp $"
 

Modified: cs/pythia/trunk/pyre/inventory/odb/prefix.py
===================================================================
--- cs/pythia/trunk/pyre/inventory/odb/prefix.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/inventory/odb/prefix.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -13,8 +13,9 @@
 
 import os
 from os.path import dirname
+from pyre import __version__
 
-_SYSTEM_ROOT = dirname(dirname(dirname(dirname(__file__))))
+_SYSTEM_ROOT = '/etc/pythia-' + __version__ # PORTABILITY: unix only
 _USER_ROOT = os.path.join(os.path.expanduser('~'), '.pyre')
 _LOCAL_ROOT = [ '.' ]
 

Copied: cs/pythia/trunk/pyre/ipa/__vault__.odb (from rev 4634, cs/pythia/trunk/ipa/__vault__.odb)

Copied: cs/pythia/trunk/pyre/ipa/ipa-pickler.odb (from rev 4634, cs/pythia/trunk/ipa/ipa-pickler.odb)


Property changes on: cs/pythia/trunk/pyre/launchers
___________________________________________________________________
Name: svn:ignore
   + *.pyc


Added: cs/pythia/trunk/pyre/launchers/Launcher.py
===================================================================
--- cs/pythia/trunk/pyre/launchers/Launcher.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/launchers/Launcher.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from pyre.components import Component
+
+
+class Launcher(Component):
+    
+    
+    import pyre.inventory as pyre
+    
+    dry         = pyre.bool("dry")
+    nodes       = pyre.int("nodes", default=1); nodes.meta['tip'] = """number of machine nodes"""
+    nodelist    = pyre.slice("nodelist");
+    executable  = pyre.str("executable")
+    arguments   = pyre.list("arguments")
+
+
+    nodelist.meta['tip'] = """a comma-separated list of machine names in square brackets (e.g., [101-103,105,107])"""
+
+    
+    def launch(self):
+        raise NotImplementedError("class '%s' must override 'launch'" % self.__class__.__name__)
+
+
+# end of file 

Added: cs/pythia/trunk/pyre/launchers/__init__.py
===================================================================
--- cs/pythia/trunk/pyre/launchers/__init__.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/launchers/__init__.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from Launcher import Launcher
+
+
+# facilities and components
+
+def facility(name, **kwds):
+    from pyre.inventory.Facility import Facility
+    kwds['factory'] = kwds.get('factory', Launcher)
+    kwds['vault'] = kwds.get('vault', ['launchers'])
+    kwds['family'] = kwds.get('family', 'launcher')
+    return Facility(name, **kwds)
+
+
+# end of file 

Added: cs/pythia/trunk/pyre/launchers/__vault__.odb
===================================================================
--- cs/pythia/trunk/pyre/launchers/__vault__.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/launchers/__vault__.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+# end of file

Modified: cs/pythia/trunk/pyre/odb/fs/CodecODB.py
===================================================================
--- cs/pythia/trunk/pyre/odb/fs/CodecODB.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/odb/fs/CodecODB.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -26,7 +26,7 @@
         import os
         exists = os.path.isfile(filename)
         
-        if mode in ['w'] and not exists:
+        if mode in ['r'] and not exists:
             raise IOError("file not found: '%s'" % filename)
 
         shelf = self._shelf(filename, False)

Modified: cs/pythia/trunk/pyre/odb/fs/Curator.py
===================================================================
--- cs/pythia/trunk/pyre/odb/fs/Curator.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/odb/fs/Curator.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -49,7 +49,7 @@
         return names
 
 
-    def loadSymbol(self, tag, codec, address, symbol, extras=[], errorHandler=None):
+    def loadSymbol(self, tag, codecs, address, symbol, extras=[], errorHandler=None):
         """extract <symbol> from a shelf pointed to by <address>"""
 
         import pyre.parsing.locators
@@ -58,31 +58,33 @@
 
         # loop over the depositories
         for depository in self.searchOrder(extraDepositories=extras):
-            spec = depository.resolve(address)
-            filename = codec.resolve(spec)
+            # loop over the codecs
+            for codec in codecs:
+                spec = depository.resolve(address)
+                filename = codec.resolve(spec)
 
-            locator = pyre.parsing.locators.file(filename)
+                locator = pyre.parsing.locators.file(filename)
 
-            # open the shelf
-            try:
-                shelf = codec.open(spec, 'r')
-            except IOError, error:
-                # the codec failed to open the spec
-                if callable(errorHandler):
-                    errorHandler(tag, locator, error)
-                continue
+                # open the shelf
+                try:
+                    shelf = codec.open(spec, 'r')
+                except IOError, error:
+                    # the codec failed to open the spec
+                    if callable(errorHandler):
+                        errorHandler(tag, locator, error)
+                    continue
 
-            # retrieve the factory method
-            try:
-                item = shelf[symbol]
-            except KeyError:
-                # no factory by that name exists
-                if callable(errorHandler):
-                    errorHandler(tag, locator, "'%s' not found" % symbol)
-                continue
+                # retrieve the factory method
+                try:
+                    item = shelf[symbol]
+                except KeyError:
+                    # no factory by that name exists
+                    if callable(errorHandler):
+                        errorHandler(tag, locator, "'%s' not found" % symbol)
+                    continue
 
-            # success
-            yield item, locator
+                # success
+                yield item, locator
             
         return
 

Modified: cs/pythia/trunk/pyre/parsing/locators/__init__.py
===================================================================
--- cs/pythia/trunk/pyre/parsing/locators/__init__.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/parsing/locators/__init__.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -17,6 +17,14 @@
     return SimpleLocator(tag)
 
 
+def default():
+    return simple('default')
+
+
+def error():
+    return simple('error')
+
+
 def script(source, line, function):
     from ScriptLocator import ScriptLocator
     return ScriptLocator(source, line, function)


Property changes on: cs/pythia/trunk/pyre/schedulers
___________________________________________________________________
Name: svn:ignore
   + *.pyc


Added: cs/pythia/trunk/pyre/schedulers/BatchScheduler.py
===================================================================
--- cs/pythia/trunk/pyre/schedulers/BatchScheduler.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/schedulers/BatchScheduler.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from Scheduler import Scheduler
+
+
+class BatchScheduler(Scheduler):
+    pass
+
+
+# end of file 

Added: cs/pythia/trunk/pyre/schedulers/BatchScriptTemplate.py
===================================================================
--- cs/pythia/trunk/pyre/schedulers/BatchScriptTemplate.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/schedulers/BatchScriptTemplate.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from Cheetah.Template import Template
+
+
+class BatchScriptTemplate(Template):
+
+
+    """base class for Cheetah batch script templates"""
+
+    
+    def getStdin(self):        return self.getRemoteFilename('stdin')
+    def getStdout(self):       return self.getRemoteFilename('stdout')
+    def getStderr(self):       return self.getRemoteFilename('stderr')
+
+
+    def getRemoteFilename(self, name):
+        # stub
+        stream = self.job.getTraitValue(name)
+        return stream.name
+
+
+    def getStagedFiles(self):
+        # stub
+        return []
+
+    
+    stdin        = property(getStdin)
+    stdout       = property(getStdout)
+    stderr       = property(getStderr)
+
+    stagedFiles  = property(getStagedFiles)
+
+
+# end of file 

Added: cs/pythia/trunk/pyre/schedulers/Job.py
===================================================================
--- cs/pythia/trunk/pyre/schedulers/Job.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/schedulers/Job.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from pyre.components import Component
+
+
+class Job(Component):
+    
+    
+    name = "job"
+    
+    
+    import pyre.inventory as pyre
+    import pyre.util as util
+    from pyre.units.time import minute
+
+    task              = pyre.str("name") # 'task' internally, to avoid name conflict
+    
+    queue             = pyre.str("queue")
+    mail              = pyre.bool("mail", default=False)
+    dwalltime         = pyre.dimensional("walltime", default=0*minute)
+    
+    stdin             = pyre.inputFile("stdin", default=util.devnull())
+    stdout            = pyre.outputFile("stdout", default="stdout.txt")
+    stderr            = pyre.outputFile("stderr", default="stderr.txt")
+
+    environment       = pyre.list("environment")
+
+    executable        = pyre.str("executable")
+    arguments         = pyre.list("arguments")
+
+    
+    def __init__(self):
+        super(Job, self).__init__()
+        self.nodes = 1
+
+
+# end of file

Added: cs/pythia/trunk/pyre/schedulers/Scheduler.py
===================================================================
--- cs/pythia/trunk/pyre/schedulers/Scheduler.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/schedulers/Scheduler.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from pyre.components import Component
+
+
+class Scheduler(Component):
+
+    
+    import pyre.inventory as pyre
+    
+    dry = pyre.bool("dry", default=False)
+    dry.meta['tip'] = """don't actually run the job; just print the batch script"""
+
+    wait = pyre.bool("wait", default=True)
+    wait.meta['tip'] = """wait for the job to finish"""
+
+    shell = pyre.str("shell", default="/bin/sh")
+    shell.meta['tip'] = """shell for #! line of batch scripts"""
+    
+    
+    def schedule(self, job):
+        raise NotImplementedError("class '%s' must override 'schedule'" % self.__class__.__name__)
+
+
+# end of file 

Added: cs/pythia/trunk/pyre/schedulers/SchedulerLSF.py
===================================================================
--- cs/pythia/trunk/pyre/schedulers/SchedulerLSF.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/schedulers/SchedulerLSF.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from BatchScheduler import BatchScheduler
+
+
+class SchedulerLSF(BatchScheduler):
+    
+    
+    name = "lsf"
+    
+
+    import pyre.inventory as pyre
+    
+    command         = pyre.str("command", default="mpijob mpirun")
+    batchCommand    = pyre.str("batch-command", default="bsub")
+    bsubOptions     = pyre.list("bsub-options")
+    
+    
+    def schedule(self, job):
+        import os, sys
+        import pyre.util as util
+
+        # Fix-up the job.
+        if not job.task:
+            # LSF scripts must have a job name; otherwise strange
+            # "/bin/sh: Event not found" errors occur (tested on
+            # TACC's Lonestar system).
+            job.task = "jobname"
+        job.walltime = util.hms(job.dwalltime.value)
+        job.arguments = ' '.join(job.arguments)
+        
+        # Generate the main LSF batch script.
+        script = self.retrieveTemplate('batch.sh', ['schedulers', 'scripts', 'lsf'])
+        script.scheduler = self
+        script.job = job
+        
+        if self.dry:
+            print script
+            return
+
+        try:
+            exitStatus = self.bsub(script)
+        except IOError, e:
+            self._error.log("%s: %s" % (self.batchCommand, e))
+            return
+        
+        # "[When given the -K option], bsub will exit with the same
+        # exit code as the job so that job scripts can take
+        # appropriate actions based on the exit codes. bsub exits with
+        # value 126 if the job was terminated while pending."
+        if exitStatus == 126:
+            pass
+        elif self.wait:
+            sys.exit(exitStatus)
+        
+        if exitStatus == 0:
+            pass
+        else:
+            sys.exit("%s: %s: %s" % (sys.argv[0], cmd[0], statusStr))
+        
+        return
+
+
+    def bsub(self, script):
+        import os
+        from popen2 import Popen4
+        
+        cmd = [self.batchCommand]
+        if self.wait:
+            cmd.append("-K")
+        self._info.log("spawning: %s" % ' '.join(cmd))
+        child = Popen4(cmd)
+        self._info.log("spawned process %d" % child.pid)
+        
+        print >> child.tochild, script
+        child.tochild.close()
+
+        if self.wait:
+            self._info.log("Waiting for dispatch...")
+        
+        for line in child.fromchild:
+            self._info.line("    " + line.rstrip())
+        status = child.wait()
+
+        exitStatus = None
+        if (os.WIFSIGNALED(status)):
+            statusStr = "signal %d" % os.WTERMSIG(status)
+        elif (os.WIFEXITED(status)):
+            exitStatus = os.WEXITSTATUS(status)
+            statusStr = "exit %d" % exitStatus
+        else:
+            statusStr = "status %d" % status
+        self._info.log("%s: %s" % (cmd[0], statusStr))
+
+        return exitStatus
+
+
+# end of file 

Added: cs/pythia/trunk/pyre/schedulers/SchedulerNone.py
===================================================================
--- cs/pythia/trunk/pyre/schedulers/SchedulerNone.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/schedulers/SchedulerNone.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from Scheduler import Scheduler
+
+
+class SchedulerNone(Scheduler):
+
+    
+    name = "scheduler-none"
+
+    
+    def schedule(self, job):
+        import os, sys
+
+        job.executable = os.path.abspath(job.executable)
+        
+        argv = [job.executable] + job.arguments
+        
+        if self.dry:
+            print ' '.join(argv)
+            return
+
+        mode = 0
+        if self.wait:
+            mode |= os.P_WAIT
+        else:
+            mode |= os.P_NOWAIT
+        ret = os.spawnvp(mode, argv[0], argv)
+        if self.wait:
+            if ret != 0:
+                sys.exit("%s: %s: exit %d" % (sys.argv[0], argv[0], ret))
+        else:
+            self._info.log("%s: spawned process %d: %r" % (sys.argv[0], ret, argv))
+        
+        return
+
+
+# end of file 

Added: cs/pythia/trunk/pyre/schedulers/__init__.py
===================================================================
--- cs/pythia/trunk/pyre/schedulers/__init__.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/schedulers/__init__.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from BatchScriptTemplate import BatchScriptTemplate
+from Scheduler import Scheduler
+from Job import Job
+
+
+# facilities and components
+
+def scheduler(name, **kwds):
+    from pyre.inventory.Facility import Facility
+    kwds['vault'] = kwds.get('vault', ['schedulers'])
+    kwds['family'] = kwds.get('family', 'scheduler')
+    return Facility(name, **kwds)
+
+
+def job(name, **kwds):
+    from pyre.inventory.Facility import Facility
+    kwds['factory'] = kwds.get('factory', Job)
+    kwds['vault'] = kwds.get('vault', ['schedulers'])
+    kwds['family'] = kwds.get('family', 'job')
+    return Facility(name, **kwds)
+
+
+# entry points
+
+def jobstart(argv=None, **kwds):
+    """entry point for batch jobs"""
+
+    import sys
+    from pyre.applications import start, AppRunner
+
+    return start(argv,
+                 applicationClass = AppRunner,
+                 kwds = dict(message='onLauncherNode'))
+
+
+# end of file 

Added: cs/pythia/trunk/pyre/schedulers/__vault__.odb
===================================================================
--- cs/pythia/trunk/pyre/schedulers/__vault__.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/schedulers/__vault__.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+# end of file

Added: cs/pythia/trunk/pyre/schedulers/lsf.odb
===================================================================
--- cs/pythia/trunk/pyre/schedulers/lsf.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/schedulers/lsf.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+def scheduler():
+    from pyre.schedulers.SchedulerLSF import SchedulerLSF
+    return SchedulerLSF()
+
+
+# end of file

Added: cs/pythia/trunk/pyre/schedulers/none.odb
===================================================================
--- cs/pythia/trunk/pyre/schedulers/none.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/schedulers/none.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+def scheduler():
+    from pyre.schedulers.SchedulerNone import SchedulerNone
+    return SchedulerNone()
+
+
+# end of file

Added: cs/pythia/trunk/pyre/schedulers/scripts/__vault__.odb
===================================================================
--- cs/pythia/trunk/pyre/schedulers/scripts/__vault__.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/schedulers/scripts/__vault__.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+# end of file

Added: cs/pythia/trunk/pyre/schedulers/scripts/lsf/__vault__.odb
===================================================================
--- cs/pythia/trunk/pyre/schedulers/scripts/lsf/__vault__.odb	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/schedulers/scripts/lsf/__vault__.odb	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+# end of file

Added: cs/pythia/trunk/pyre/schedulers/scripts/lsf/batch.sh.tmpl
===================================================================
--- cs/pythia/trunk/pyre/schedulers/scripts/lsf/batch.sh.tmpl	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/schedulers/scripts/lsf/batch.sh.tmpl	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,45 @@
+## -*- sh -*-
+#compiler-settings
+directiveStartToken = @
+#end compiler-settings
+ at from pyre.schedulers import BatchScriptTemplate
+ at extends BatchScriptTemplate
+ at implements respond
+ at set $self.substitutions = {'job.id': "%J"}
+#!${scheduler.shell}
+#BSUB -J ${job.task}
+ at if $job.queue
+#BSUB -q ${job.queue}
+ at end if
+ at if max($job.walltime)
+#BSUB -W @echo ("%d:%02d" % $job.walltime[0:2])
+ at end if
+#BSUB -n ${job.nodes}
+ at if $self.stdin
+#BSUB -i ${self.stdin}
+ at end if
+ at if $self.stdout
+#BSUB -o ${self.stdout}
+ at end if
+ at if $self.stderr
+#BSUB -e ${self.stderr}
+ at end if
+ at for direction, localPathname, remoteFilename in $self.stagedFiles
+ at if $direction == "in"
+#BSUB -f "${localPathname} > ${remoteFilename}"
+ at else if $direction == "out"
+#BSUB -f "${localPathname} < ${remoteFilename}"
+ at else
+ at raise RuntimeError("LSF doesn't understand the stage direction '%s'" % $direction)
+ at end if
+ at end for
+ at for option in $scheduler.bsubOptions
+#BSUB ${option}
+ at end for
+
+ at set $self.substitutions = {'job.id': "${LSB_JOBID}"}
+
+${job.executable} @echo ' '.join($job.arguments)
+
+# submit with:
+# ${scheduler.batchCommand} < [script]

Added: cs/pythia/trunk/pyre/scripts/PyreScript.py
===================================================================
--- cs/pythia/trunk/pyre/scripts/PyreScript.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/scripts/PyreScript.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from pyre.applications import SuperScript
+
+
+def mpirun():
+    # only import this as needed
+    from mpi.scripts import mpirun
+    return mpirun()
+
+
+class PyreScript(SuperScript):
+
+
+    name = "pyre"
+
+
+    subscripts = {
+        "mpirun": mpirun,
+        }
+
+
+if __name__ == '__main__':
+    from pyre.scripts import pyre
+    pyre()
+
+
+# end of file

Added: cs/pythia/trunk/pyre/scripts/__init__.py
===================================================================
--- cs/pythia/trunk/pyre/scripts/__init__.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/scripts/__init__.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+# end of file 

Added: cs/pythia/trunk/pyre/scripts/jobstart.py
===================================================================
--- cs/pythia/trunk/pyre/scripts/jobstart.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/scripts/jobstart.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from pyre.schedulers import jobstart
+jobstart()
+
+
+# end of file


Property changes on: cs/pythia/trunk/pyre/templates
___________________________________________________________________
Name: svn:ignore
   + *.pyc


Added: cs/pythia/trunk/pyre/templates/CodecTmpl.py
===================================================================
--- cs/pythia/trunk/pyre/templates/CodecTmpl.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/templates/CodecTmpl.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from pyre.odb.fs.CodecODB import CodecODB
+
+
+class CodecTmpl(CodecODB):
+
+    def __init__(self):
+        CodecODB.__init__(self, encoding='tmpl')
+        return
+
+    def _decode(self, shelf):
+        from Cheetah.Template import Template
+        template = Template(file=shelf.name)
+        shelf['template'] = template
+        shelf._frozen = True
+        return
+
+
+# end of file

Added: cs/pythia/trunk/pyre/templates/__init__.py
===================================================================
--- cs/pythia/trunk/pyre/templates/__init__.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/templates/__init__.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2006  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+def codecTmpl():
+    from CodecTmpl import CodecTmpl
+    return CodecTmpl()
+
+
+# end of file 

Modified: cs/pythia/trunk/pyre/util/__init__.py
===================================================================
--- cs/pythia/trunk/pyre/util/__init__.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/pyre/util/__init__.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -17,6 +17,18 @@
     return tmp()
 
 
+def devnull():
+    import os.path
+    try:
+        return os.path.devnull
+    except AttributeError:
+        return "/dev/null"
+
+
+def hms(t):
+    return (int(t / 3600), int((t % 3600) / 60), int(t % 60))
+
+
 def spawn(onParent, onChild):
     from subprocesses import spawn
     return spawn(onParent, onChild)
@@ -32,6 +44,22 @@
     return expandMacros(raw, substitutions)
 
 
+def loadObject(name):
+    """Load and return the object referenced by <name> ==
+    some.module[:some.attr].
+
+    Derived from pkg_resources:EntryPoint.
+
+    """
+
+    module, attrs = name.split(':')
+    attrs = attrs.split('.')
+    obj = __import__(module, globals(), globals(), ['__name__'])
+    for attr in attrs:
+        obj = getattr(obj, attr)
+    return obj
+
+
 # version
 __id__ = "$Id: __init__.py,v 1.1.1.1 2005/03/08 16:13:41 aivazis Exp $"
 

Copied: cs/pythia/trunk/pyre/weaver/__vault__.odb (from rev 4634, cs/pythia/trunk/weaver/__vault__.odb)

Copied: cs/pythia/trunk/pyre/weaver/mills/__vault__.odb (from rev 4634, cs/pythia/trunk/weaver/mills/__vault__.odb)

Copied: cs/pythia/trunk/pyre/weaver/mills/c.odb (from rev 4634, cs/pythia/trunk/weaver/mills/c.odb)

Copied: cs/pythia/trunk/pyre/weaver/mills/csh.odb (from rev 4634, cs/pythia/trunk/weaver/mills/csh.odb)

Copied: cs/pythia/trunk/pyre/weaver/mills/cxx.odb (from rev 4634, cs/pythia/trunk/weaver/mills/cxx.odb)

Copied: cs/pythia/trunk/pyre/weaver/mills/f77.odb (from rev 4634, cs/pythia/trunk/weaver/mills/f77.odb)

Copied: cs/pythia/trunk/pyre/weaver/mills/f90.odb (from rev 4634, cs/pythia/trunk/weaver/mills/f90.odb)

Copied: cs/pythia/trunk/pyre/weaver/mills/html.odb (from rev 4634, cs/pythia/trunk/weaver/mills/html.odb)

Copied: cs/pythia/trunk/pyre/weaver/mills/make.odb (from rev 4634, cs/pythia/trunk/weaver/mills/make.odb)

Copied: cs/pythia/trunk/pyre/weaver/mills/perl.odb (from rev 4634, cs/pythia/trunk/weaver/mills/perl.odb)

Copied: cs/pythia/trunk/pyre/weaver/mills/python.odb (from rev 4634, cs/pythia/trunk/weaver/mills/python.odb)

Copied: cs/pythia/trunk/pyre/weaver/mills/sh.odb (from rev 4634, cs/pythia/trunk/weaver/mills/sh.odb)

Copied: cs/pythia/trunk/pyre/weaver/mills/tex.odb (from rev 4634, cs/pythia/trunk/weaver/mills/tex.odb)

Copied: cs/pythia/trunk/pyre/weaver/mills/xml.odb (from rev 4634, cs/pythia/trunk/weaver/mills/xml.odb)


Property changes on: cs/pythia/trunk/pythia.egg-info
___________________________________________________________________
Name: svn:ignore
   + SOURCES.txt
top_level.txt
PKG-INFO
not-zip-safe
dependency_links.txt


Modified: cs/pythia/trunk/setup.py
===================================================================
--- cs/pythia/trunk/setup.py	2006-10-08 12:04:43 UTC (rev 4742)
+++ cs/pythia/trunk/setup.py	2006-10-08 13:56:34 UTC (rev 4743)
@@ -18,10 +18,15 @@
     zip_safe = False,
     packages = find_packages(),
     package_data = {
+    'mpi': ['_mpi.c', '_mpi.pyx', 'cmpi.pxd'],
     # If any package contains *.pml, *.odb, or *.h files, include them:
     '': ['*.pml', '*.odb', '*.h'],
     },
     
+    install_requires = [
+    'Cheetah',
+    ],
+    
     author = 'Michael A.G. Aivazis',
     author_email = 'aivazis at caltech.edu',
     description = 'An extensible, object-oriented framework for specifying and staging complex, multi-physics simulations.',



More information about the cig-commits mailing list