[Yt-svn] yt-commit r474 - in trunk/yt: . raven reason
mturk at wrangler.dreamhost.com
mturk at wrangler.dreamhost.com
Thu May 15 16:14:06 PDT 2008
Author: mturk
Date: Thu May 15 16:14:03 2008
New Revision: 474
URL: http://yt.spacepope.org/changeset/474
Log:
Some major changes to reason, which are not yet finished, but at least ready to
function... I think.
* The shell has been detached from the main window, and moved into a menu
item.
* Logging now goes to the main window. (Repaint issues though.)
* PyCrust has been utilized to allow for editing and running scripts inline,
modifying and interacting with the local namespace.
Also added a parameter for 'sphere' in the new threephase.
Added:
trunk/yt/reason/LoggingSetup.py
Modified:
trunk/yt/logger.py
trunk/yt/raven/PlotCollection.py
trunk/yt/reason/App.py
trunk/yt/reason/Windows.py
trunk/yt/reason/__init__.py
Modified: trunk/yt/logger.py
==============================================================================
--- trunk/yt/logger.py (original)
+++ trunk/yt/logger.py Thu May 15 16:14:03 2008
@@ -95,7 +95,11 @@
reasonHandler.setFormatter(f)
reasonLogger.addHandler(reasonHandler)
-if ytcfg.getboolean("yt","suppressStreamLogging"):
+def disable_stream_logging():
# We just remove the root logger's handlers
for handler in rootLogger.handlers:
- handler.disabled = 1
+ if isinstance(handler, logging.StreamHandler):
+ rootLogger.removeHandler(handler)
+
+if ytcfg.getboolean("yt","suppressStreamLogging"):
+ disable_stream_logging()
Modified: trunk/yt/raven/PlotCollection.py
==============================================================================
--- trunk/yt/raven/PlotCollection.py (original)
+++ trunk/yt/raven/PlotCollection.py Thu May 15 16:14:03 2008
@@ -173,11 +173,12 @@
weight="CellMassMsun", accumulation=False,
x_bins=64, x_log=True, x_bounds=None,
y_bins=64, y_log=True, y_bounds=None,
- lazy_reader=False):
+ lazy_reader=False, sphere = None):
if center == None:
center = self.c
r = radius/self.pf[unit]
- sphere = self.pf.hierarchy.sphere(center, r, fields)
+ if sphere is None:
+ sphere = self.pf.hierarchy.sphere(center, r, fields)
if x_bounds is None:
x_min, x_max = sphere[fields[0]].min(), sphere[fields[0]].max()
else:
Modified: trunk/yt/reason/App.py
==============================================================================
--- trunk/yt/reason/App.py (original)
+++ trunk/yt/reason/App.py Thu May 15 16:14:03 2008
@@ -81,8 +81,11 @@
'windows':self.windows,
'mainwindow':self,
'data_objects':self.data_objects}
+ wx.py.buffer.Buffer.updateNamespace = \
+ get_new_updateNamespace(self.locals)
self.int_panel = wx.Panel(self.main_splitter, -1)
- self.interpreter = ReasonInterpreterPanel(self.int_panel, -1, self.locals)
+ #self.interpreter = ReasonInterpreterPanel(self.int_panel, -1, self.locals)
+ self.interpreter = LoggingWindowBox(self.int_panel, -1)
def __setup_menubar(self):
menu_bar = wx.MenuBar()
@@ -93,12 +96,16 @@
open_hierarchy = file_menu.Append(-1, "Open Hierarchy")
field_inspector = file_menu.Append(-1, "Inspect Fields")
+ open_shell = file_menu.Append(-1, "Open Shell")
+ open_editor = file_menu.Append(-1, "Open Editor")
save_image = file_menu.Append(-1, "Save Image")
file_menu.AppendSeparator()
exit = file_menu.Append(-1, "Exit")
self.Bind(wx.EVT_MENU, self.OnOpenHierarchy, open_hierarchy)
self.Bind(wx.EVT_MENU, self.OnInspectFields, field_inspector)
+ self.Bind(wx.EVT_MENU, self.OnOpenShell, open_shell)
+ self.Bind(wx.EVT_MENU, self.OnOpenEditor, open_editor)
self.Bind(wx.EVT_MENU, self.OnSaveImage, save_image)
self.Bind(wx.EVT_MENU, self.OnExit, exit)
@@ -258,7 +265,7 @@
def _add_phase(self, event=None):
MyID = wx.NewId()
- self.interpreter.shell.writeOut("\n")
+# self.interpreter.shell.writeOut("\n")
o = self.get_output()
t = "Phase Plot"
self.windows.append( \
@@ -267,21 +274,21 @@
dataObject = o,
CreationID = MyID,
mw = self))
- self.interpreter.shell.writeOut("Adding phase plot\n")
+# self.interpreter.shell.writeOut("Adding phase plot\n")
self.plot_panel.AddPlot(self.windows[-1], t, MyID)
mylog.debug("Adding with ID: %s", MyID)
- self.interpreter.shell.push("\n")
+# self.interpreter.shell.push("\n")
def _add_proj(self, event=None):
MyID = wx.NewId()
- self.interpreter.shell.writeOut("\n")
+# self.interpreter.shell.writeOut("\n")
o = self.get_output()
field = "Density"
width = 1.0
unit = "1"
for i, ax in zip(range(3), 'xyz'):
t = "%s - Projection - %s" % (o.basename, ax)
- self.interpreter.shell.writeOut("Adding %s projection of %s\n" % (ax, o))
+# self.interpreter.shell.writeOut("Adding %s projection of %s\n" % (ax, o))
self.windows.append( \
ProjPlotPage(parent=self.plot_panel.nb,
status_bar=self.status_bar,
@@ -295,18 +302,20 @@
_ProjObjectMenuItems)
print "Adding with ID:", MyID
for w in self.windows[-3:]: w.ChangeWidth(1,'1')
- self.interpreter.shell.push("\n")
+# self.interpreter.shell.push("\n")
def _add_slice(self, event=None):
+ wx.SafeYield()
MyID = wx.NewId()
- self.interpreter.shell.writeOut("\n")
+# self.interpreter.shell.writeOut("\n")
o = self.get_output()
field = "Density"
width = 1.0
unit = "1"
for i, ax in zip(range(3), 'xyz'):
+ wx.Yield()
t = "%s - Slice - %s" % (o.basename, ax)
- self.interpreter.shell.writeOut("Adding %s slice of %s\n" % (ax, o))
+# self.interpreter.shell.writeOut("Adding %s slice of %s\n" % (ax, o))
self.windows.append( \
SlicePlotPage(parent=self.plot_panel.nb,
status_bar=self.status_bar,
@@ -320,7 +329,7 @@
_SliceObjectMenuItems)
print "Adding with ID:", MyID
for w in self.windows[-3:]: w.ChangeWidth(1,'1')
- self.interpreter.shell.push("\n")
+# self.interpreter.shell.push("\n")
def get_output(self, event=None):
# Figure out which outputs are selected
@@ -367,6 +376,18 @@
#self.RefreshOutputs()
dialog.Destroy()
+ def OnOpenEditor(self, event):
+ frame = ReasonEditorNotebookFrame(parent=self,
+ title="Editor")
+ frame.SetStatusText("Reason Shell")
+ frame.Show()
+ self.ff = frame
+
+ def OnOpenShell(self, event):
+ frame = wx.py.shell.ShellFrame(parent=self, locals=self.locals)
+ frame.SetStatusText("Reason Shell")
+ frame.Show()
+
def OnSaveImage(self, event):
pgI = self.plot_panel.nb.Selection
pg = self.plot_panel.nb.GetPage(pgI)
Added: trunk/yt/reason/LoggingSetup.py
==============================================================================
--- (empty file)
+++ trunk/yt/reason/LoggingSetup.py Thu May 15 16:14:03 2008
@@ -0,0 +1,138 @@
+"""
+Logging facilities for Reason
+
+ at author: U{Matthew Turk<http://www.stanford.edu/~mturk/>}
+ at organization: U{KIPAC<http://www-group.slac.stanford.edu/KIPAC/>}
+ at contact: U{mturk at slac.stanford.edu<mailto:mturk at slac.stanford.edu>}
+ at license:
+ Copyright (C) 2008 Matthew Turk. All Rights Reserved.
+
+ This file is part of yt.
+
+ yt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+
+from yt.reason import *
+
+import logging, sys
+import wx.lib.mixins.listctrl as listmix
+
+class LoggingListBox(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin):
+ def __init__(self, parent, dataSource):
+ wx.ListCtrl.__init__(self, parent,
+ style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_VIRTUAL)
+ listmix.ListCtrlAutoWidthMixin.__init__(self)
+ columns = dataSource.GetColumnHeaders()
+ for col, text in enumerate(columns):
+ self.InsertColumn(col, text)
+ self.SetItemCount(dataSource.GetCount())
+ self.dataSource = dataSource
+
+ def UpdateCounts(self):
+ c = self.dataSource.GetCount()
+ self.SetItemCount(c)
+ self.EnsureVisible(c-1)
+ self.Refresh()
+
+ def OnGetItemText(self, item, col):
+ return self.dataSource.GetItem(item)[col]
+
+ def OnGetItemAttr(self, item): return None
+ def OnGetItemImage(self, item): return -1
+
+class LoggingWindowBox(wx.Panel):
+ def __init__(self, parent, id):
+ wx.Panel.__init__(self, parent, id)
+ self.__redirect_logging()
+ self.__setup_controls()
+ mylog.info("Welcome to Reason.")
+
+ def __setup_controls(self):
+ self.event_list = LoggingListBox(self, self.handler.output)
+ self.handler.setTextBox(self.event_list)
+ self.sizer = wx.BoxSizer(wx.VERTICAL)
+ self.sizer.Add(self.event_list, 1, wx.EXPAND)
+ self.SetSizer(self.sizer)
+ self.Fit()
+
+ def __redirect_logging(self):
+ yt.logger.disable_stream_logging()
+ self.handler = OutputWindowStream()
+ self.handler.setFormatter(logging.Formatter(yt.logger.fstring))
+ yt.logger.rootLogger.addHandler(self.handler)
+
+class OutputWindowStream(logging.Handler):
+ # Shamelessly borrowed from:
+ # http://lists.wxwidgets.org/pipermail/wxpython-users/2007-October/069288.html
+ def __init__(self):
+ logging.Handler.__init__(self)
+ self.output = LoggingDataSource()
+ self.buffer = []
+ self.events = []
+
+ def setTextBox(self, textbox):
+ """
+ textbox presents the instance of textctrl in the mainframe
+ Method is called after frame is up and running
+ """
+ self.textbox = textbox
+
+ def shouldFlush(self):
+ if self.textbox:
+ return True
+ else:
+ return False
+
+ def emit(self, record):
+ self.buffer.append(record)
+ if self.shouldFlush():
+ self.flush()
+
+ def flush(self):
+ """
+ Thread safe flush method which schedule the
+ textbox update after a wx main loop ends
+ """
+ for record in self.buffer:
+ self.format(record)
+ wx.CallAfter(self.output.AppendItem, record)
+ wx.CallAfter(self.textbox.UpdateCounts)
+ wx.CallAfter(wx.YieldIfNeeded)
+ self.buffer = []
+
+ def close(self):
+ self.flush()
+ self.textbox = None
+ logging.Handler.close(self)
+
+class LoggingDataSource(object):
+ cols = ("Component","Level","Time","Message")
+ attrs = ("name","levelname","asctime","message")
+ def __init__(self):
+ self.records = []
+
+ def GetColumnHeaders(self):
+ return self.cols
+
+ def GetCount(self):
+ return len(self.records)
+
+ def GetItem(self, index):
+ return [getattr(self.records[index],att) for att in self.attrs]
+
+ def UpdateCache(self, start, end):
+ pass
+
+ def AppendItem(self, rec):
+ self.records.append(rec)
\ No newline at end of file
Modified: trunk/yt/reason/Windows.py
==============================================================================
--- trunk/yt/reason/Windows.py (original)
+++ trunk/yt/reason/Windows.py Thu May 15 16:14:03 2008
@@ -37,6 +37,7 @@
self.SetSizer(self.sizer)
self.Fit()
+
def ChooseField(page):
allFields = page.QueryFields()
toChoose = nativeFields + [''] + derivedFields
@@ -184,3 +185,64 @@
self.SetSizer(self.MainSizer)
self.Layout()
+
+def get_new_updateNamespace(my_locals):
+ def updateNamespace(self):
+ """Update the namespace for autocompletion and calltips.
+
+ Return True if updated, False if there was an error."""
+ if not self.interp or not hasattr(self.editor, 'getText'):
+ return False
+ syspath = sys.path
+ sys.path = self.syspath
+ text = self.editor.getText()
+ text = text.replace('\r\n', '\n')
+ text = text.replace('\r', '\n')
+ name = self.modulename or self.name
+ try:
+ try:
+ code = compile(text, name, 'exec')
+ except:
+ raise
+ try:
+ exec code in my_locals
+ except:
+ raise
+ finally:
+ sys.path = syspath
+ for m in sys.modules.keys():
+ if m not in self.modules:
+ del sys.modules[m]
+ return updateNamespace
+
+
+class ReasonEditorNotebookFrame(wx.py.editor.EditorNotebookFrame):
+
+ def _setup(self):
+ """Setup prior to first buffer creation.
+ Called automatically by base class during init.
+
+ Mostly taken from the wx.py.editor source.
+ """
+ self.notebook = wx.py.editor.EditorNotebook(parent=self)
+ intro = 'Reason 0.3'
+ if hasattr(self.Parent, 'locals'):
+ namespace = self.Parent.locals
+ else:
+ import imp
+ module = imp.new_module('__main__')
+ import __builtin__
+ module.__dict__['__builtins__'] = __builtin__
+ namespace = module.__dict__.copy()
+ self.crust = wx.py.crust.Crust(parent=self.notebook, intro=intro, locals=namespace)
+ self.shell = self.crust.shell
+ # Override the filling so that status messages go to the status bar.
+ self.crust.filling.tree.setStatusText = self.SetStatusText
+ # Override the shell so that status messages go to the status bar.
+ self.shell.setStatusText = self.SetStatusText
+ # Fix a problem with the sash shrinking to nothing.
+ self.crust.filling.SetSashPosition(40)
+ self.notebook.AddPage(page=self.crust, text='*Shell*', select=True)
+ self.setEditor(self.crust.editor)
+ self.crust.editor.SetFocus()
+ self.MenuBar.GetMenu(0).GetMenuItems()[11].SetText("Run Script")
Modified: trunk/yt/reason/__init__.py
==============================================================================
--- trunk/yt/reason/__init__.py (original)
+++ trunk/yt/reason/__init__.py Thu May 15 16:14:03 2008
@@ -25,7 +25,8 @@
from yt.config import ytcfg
-from yt.logger import lagosLogger as mylog
+import yt.logger
+mylog = yt.logger.reasonLogger
import yt.lagos as lagos
import yt.raven as raven
@@ -43,10 +44,12 @@
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_agg import FigureCanvasAgg
import wx, wx.py, wx.aui
+import wx.lib.mixins.listctrl as listmix
from wx.lib.pubsub import Publisher
import matplotlib.backends.backend_wx as be_wx
import matplotlib.figure
+from LoggingSetup import *
from Windows import *
from Notebook import *
from App import *
More information about the yt-svn
mailing list