This might be more along the lines of what you need: ----- from StringIO import StringIO import sys import threading class Controller_buffer(StringIO): def __init__(self): StringIO.__init__(self) self.lock = threading.Lock() def readlines(self): self.lock.acquire() self.seek(0) lines = StringIO.readlines(self) self.truncate(0) self.lock.release() return lines def write(self, text): self.lock.acquire() StringIO.write(self, text) self.lock.release() output = Controller_buffer() sys.stdout = output print "1" print "2" print "3" sys.stdout.write("4\n5\n") print "6" print "7" print "8" sys.stdout = sys.__stdout__ print "1st read: " + `output.readlines()` output.seek(0) print "2nd read: " + `output.readlines()` output.write("9\n10\n") print "3rd read: " + `output.readlines()` output.seek(0) print "4th read: " + `output.readlines()` ----- This is functional. The only issue is that it might slow things down. Regards, Edward On 25 February 2010 00:56, Edward d'Auvergne <edward@xxxxxxxxxxxxx> wrote:
Hi, For this, you might need to create an object, similar to DummyFileObject or SplitIO in relax_io.py. You might be able to use the StringIO module for this - its trucate() method might be what is needed. The best might be to google search to find out how other people create a buffer that can be emptied. Actually, cStringIO (http://docs.python.org/library/stringio.html#module-cStringIO) might be better as it is faster (though it cannot be locked, see below)! This is about all you need, copy and paste the following into Python: ----- import cStringIO import sys output = cStringIO.StringIO() sys.stdout = output print "1" print "2" print "3" sys.stdout.write("4\n5\n") print "6" print "7" print "8" sys.stdout = sys.__stdout__ print "1st read: " + `output.readlines()` output.seek(0) print "2nd read: " + `output.readlines()` print "3rd read: " + `output.readlines()` output.reset() print "4th read: " + `output.readlines()` output.reset() print "5th read: " + `output.readline()` print "6th read: " + `output.readline()` print "7th read: " + `output.readline()` output.truncate() output.reset() print "8th read: " + `output.readlines()` output.truncate(0) output.reset() print "9th read: " + `output.readlines()` ----- This demonstrates all the concepts you need for the relax controller! seek(0) goes to the start of the buffer where you can get the lines. truncate() removes everything from the current spot. And truncate(0) removes the lot! The only problem is that as the calculation is running in a thread, you might have to play with locking (threading.Lock). I.e. you might need to make a class like: class Controller_buffer(StringIO.StringIO): __init__(self): self.lock = threading.Lock() readlines(self): self.lock.acquire() self.seek(0) lines = super(Controller_buffer).readlines() self.truncate(0) self.lock.release() return lines write(self, text): self.lock.acquire() super(Controller_buffer).write(text) self.lock.release() This is very minimalistic, but might be enough. Regards, Edward On 24 February 2010 21:40, Michael Bieri <michael.bieri@xxxxxx> wrote:Hi Unfortunately, it does not completely solve the problem.... But it is definitely the source of it. By disabling the redirect function, relaxGUI does not crash. Do you have an idea how to clear the ram? I was thinking of completly remove all entries of the log window after, let's say 10'000 lines, and start with a blank. This would slow down the calculation less, as the log window entries don't have to be updated (and manipulated) after each new entry. Cheers Edward d'Auvergne schrieb:Hi, Awesome, you have your commit access up and running! I'll go through each commit and check for issues line by line. I have a few below for this commit: On 24 February 2010 05:00, <michael.bieri@xxxxxx> wrote:Author: michaelbieri Date: Wed Feb 24 05:00:23 2010 New Revision: 10887 URL: http://svn.gna.org/viewcvs/relax?rev=10887&view=rev Log: The number of maximum lines in the relaxGUI log window is limited to 1000 lines. relaxGUI calculation crashed during local tm calculation due to too many lines in the relaxGUI log window. Therefore, the maximum amout of numbers is limited to 1000 as discussed with Edward d'Auvergne (https://gna.org/bugs/?15173). A new function to limit maximum lines in relaxGUI log windows was introduced into controller.py. Modified: branches/bieri_gui/gui_bieri/controller.py Modified: branches/bieri_gui/gui_bieri/controller.py URL: http://svn.gna.org/viewcvs/relax/branches/bieri_gui/gui_bieri/controller.py?rev=10887&r1=10886&r2=10887&view=diff ============================================================================== --- branches/bieri_gui/gui_bieri/controller.py (original) +++ branches/bieri_gui/gui_bieri/controller.py Wed Feb 24 05:00:23 2010 @@ -26,6 +26,7 @@ # Python module imports. from os import sep +from string import split, replace import sys import time import thread @@ -185,10 +186,37 @@ self.out=aWxTextCtrl + def limit_entries(self): + """ Function to overcome feedback problem of wx.CallAfter() command"""This is an incredibly important one. The reason is because of the automatic parsing of docstrings performed through out relax. This is used for building the API documentation (http://www.nmr-relax.com/api/1.3/), for the automatic building of the user function section of the relax manual, for the help() function provided on the prompt interface, etc. The problem is that automatic parsing will break here. The fix is simple, there should be no space between """ and the first word, and there should be a '.' character at the end of the sentence.+ + # Maximum allowed number of lines in log window. + max_entries = 1000 + new_entries = ''I would suggest 10,000 max_entries. In future versions, maybe the user could set this in the 'settings' menu?+ + # read number of lines in log window. + total_entries = self.out.log_panel.GetNumberOfLines() + + # Shift entries backwards if maximum of line exeeded. + if total_entries > max_entries: + # Convert entries to list + list_of_entries = split(self.out.log_panel.GetValue(), '\n') + + for i in range(1, max_entries + 1): + new_entries = new_entries + (list_of_entries[i]) + '\n' + + # Reset log window entries + #new_entries = str(list_of_entries)This last line looks like debugging code that can be eliminated. It could be confusing in the future when the reason for this commenting out is long forgotten.+ self.out.log_panel.SetValue(new_entries) + + def write(self,string): global progress - wx.CallAfter(self.out.log_panel.WriteText, string) + # Limit panle entries to max_entries Lines. + wx.CallAfter(self.limit_entries) + + # Add new output. + wx.CallAfter(self.out.log_panel.AppendText, string) time.sleep(0.001) # allow relaxGUI log panel to get refreshed # split print out into listThis all looks good! Does this solve the segfault problem you see? I can think of one other problem here. The text should be removed from the buffer as your are reading it into the log window. This will prevent the buffer from blowing up and taking up all of the RAM + swap space. Cheers, Edward _______________________________________________ relax (http://nmr-relax.com) This is the relax-devel mailing list relax-devel@xxxxxxx To unsubscribe from this list, get a password reminder, or change your subscription options, visit the list information page at https://mail.gna.org/listinfo/relax-devel_______________________________________________ relax (http://nmr-relax.com) This is the relax-devel mailing list relax-devel@xxxxxxx To unsubscribe from this list, get a password reminder, or change your subscription options, visit the list information page at https://mail.gna.org/listinfo/relax-devel