From: albertogomcas Date: Wed, 18 Jun 2008 12:36:17 +0000 (+0000) Subject: (liboutlet.py) collector of command line output X-Git-Tag: 0.9.0~95 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=911ce9d0dda6a23e000aa1f26a6e9c73f334c7f8;p=hooke.git (liboutlet.py) collector of command line output (libviewer.py, viewer.py) outlet output handling and sample code (libinput.py) safer than raw_input functions (flatfitls.py, generalclamp.py,hooke_cli.py, generalvclamp.py, fit.py) commands here now also send input to outlet (hooke_cli.py) inputs now use libinput calls --- diff --git a/CHANGELOG b/CHANGELOG index c46b6ee..318ab34 100755 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,6 +11,10 @@ FROM 0.8.4 ONWARD, DETAILED CHANGELOGS ARE AVAILABLE ON THE HOOKE SUBVERSION REP cleaned debug output in execmacro DRIVERS: alternative version of picoforce driver + INPUT + merged (partially) libinput (so far in hooke_cli) + OUTLET + merged liboutlet 0.8.3 diff --git a/fit.py b/fit.py index f70636f..8864423 100755 --- a/fit.py +++ b/fit.py @@ -240,8 +240,12 @@ class fitCommands: return print 'Contour length: ',params[0]*(1.0e+9),' nm' + to_dump='contour '+self.current.path+' '+str(params[0]*(1.0e+9))+' nm' + self.outlet.push(to_dump) if len(params)==2: #if we did choose 2-value fit print 'Persistent length: ',params[1]*(1.0e+9),' nm' + to_dump='persistent '+self.current.path+' '+str(params[1]*(1.0e+9))+' nm' + self.outlet.push(to_dump) #add the clicked points in the final PlotObject clickvector_x, clickvector_y=[], [] diff --git a/flatfilts.py b/flatfilts.py index 27e526f..25503f8 100755 --- a/flatfilts.py +++ b/flatfilts.py @@ -239,6 +239,8 @@ class flatfiltsCommands: peak_location,peak_size=self.has_peaks(defplots,abs_devs) print 'Found '+str(len(peak_location))+' peaks.' + to_dump='peaks '+self.current.path+' '+str(len(peak_location)) + self.outlet.push(to_dump) #print peak_location #if no peaks, we have nothing to plot. exit. diff --git a/generalclamp.py b/generalclamp.py index 508d9a3..14974dc 100644 --- a/generalclamp.py +++ b/generalclamp.py @@ -98,6 +98,8 @@ class generalclampCommands: points=self._measure_N_points(N=2) zpiezo=abs(points[0].graph_coords[1]-points[1].graph_coords[1]) print str(zpiezo*(10**9))+' nm' + to_dump='zpiezo '+self.current.path+' '+str(zpiezo*(10**9))+' nm' + self.outlet.push(to_dump) else: print 'This command makes no sense for a non-force clamp experiment.' @@ -115,6 +117,8 @@ class generalclampCommands: points=self._measure_N_points(N=2) defl=abs(points[0].graph_coords[1]-points[1].graph_coords[1]) print str(defl*(10**12))+' pN' + to_dump='deflection '+self.current.path+' '+str(defl*(10**12))+' pN' + self.outlet.push(to_dump) else: print 'This command makes no sense for a non-force clamp experiment.' @@ -137,6 +141,8 @@ class generalclampCommands: dt=abs(points[1].graph_coords[0]-points[0].graph_coords[0]) print 'dZ: ',dz,' nm' print 'dT: ',dt,' s' + to_dump='step '+self.current.path+' '+'dZ: '+str(dz)+' nm'+' dT: '+str(dt)+' s' + self.outlet.push(to_dump) else: print 'This command makes no sense for a non-force clamp experiment.' \ No newline at end of file diff --git a/generalvclamp.py b/generalvclamp.py index d3adefd..4824465 100644 --- a/generalvclamp.py +++ b/generalvclamp.py @@ -44,6 +44,8 @@ class generalvclampCommands: else: dx,unitx,dy,unity=self._delta(set=1) print str(dx*(10**9))+' nm' + to_dump='distance '+self.current.path+' '+str(dx*(10**9))+' nm' + self.outlet.push(to_dump) def do_force(self,args): @@ -59,6 +61,8 @@ class generalvclampCommands: return dx,unitx,dy,unity=self._delta(set=1) print str(dy*(10**12))+' pN' + to_dump='force '+self.current.path+' '+str(dy*(10**12))+' pN' + self.outlet.push(to_dump) def do_forcebase(self,args): @@ -114,6 +118,8 @@ class generalvclampCommands: avg=np.mean(to_average) forcebase=abs(y-avg) print str(forcebase*(10**12))+' pN' + to_dump='forcebase '+self.current.path+' '+str(forcebase*(10**12))+' pN' + self.outlet.push(to_dump) def plotmanip_flatten(self, plot, current, customvalue=False): @@ -226,6 +232,8 @@ class generalvclampCommands: # Outputs the relevant slope parameter print 'Slope:' print str(parameters[0]) + to_dump='slope '+self.current.path+' '+str(parameters[0]) + self.outlet.push(to_dump) # Makes a vector with the fitted parameters and sends it to the GUI xtoplot=parameters[2] diff --git a/hooke.conf b/hooke.conf index b590ac9..8b39b46 100755 --- a/hooke.conf +++ b/hooke.conf @@ -2,13 +2,13 @@ - + - insert directory + /home/glacierre/hooke/ + @@ -31,7 +32,7 @@ This section defines which plugins have to be loaded by Hooke. This section defines which drivers have to be loaded by Hooke. --> - + diff --git a/hooke_cli.py b/hooke_cli.py index 8ed2ca0..da1379e 100755 --- a/hooke_cli.py +++ b/hooke_cli.py @@ -14,6 +14,9 @@ This program is released under the GNU General Public License version 2. from libhooke import * #FIXME import libhookecurve as lhc +import libinput as linp +import liboutlet as lout + from libhooke import WX_GOOD from libhooke import HOOKE_VERSION @@ -99,6 +102,9 @@ class HookeCli(cmd.Cmd): self.playlist_saved=0 self.playlist_name='' self.notes_saved=1 + + #create outlet + self.outlet=lout.Outlet() #Data that must be saved in the playlist, related to the whole playlist (not individual curves) self.playlist_generics={} @@ -207,7 +213,7 @@ Syntax: loadlist [playlist file] def do_loadlist(self, args): #checking for args: if nothing is given as input, we warn and exit. while len(args)==0: - args=raw_input('File to load?') + args=linp.alphainput('File to load?','',0,[]) arglist=args.split() play_to_load=arglist[0] @@ -263,7 +269,7 @@ Syntax: genlist [input files] def do_genlist(self,args): #args list is: input path, output name if len(args)==0: - args=raw_input('Input files?') + args=linp.alphainput('Input files?','',1,[]) arglist=args.split() list_path=arglist[0] @@ -314,7 +320,7 @@ Syntax: genlist [input files] Syntax: savelist [filename] ''' while len(args)==0: - args=raw_input('Input files?') + args=linp.alphainput('Output files?','',1,[]) output_filename=args @@ -380,7 +386,7 @@ If the curve is not in the current playlist, it politely asks if we want to add ''' if filename=='': - filename=raw_input('Jump to?') + filename=linp.alphainput('Jump to?','',0,[]) filepath=os.path.abspath(filename) print filepath @@ -399,7 +405,7 @@ If the curve is not in the current playlist, it politely asks if we want to add c+=1 except IndexError: #We've found the end of the list. - answer=raw_input('Curve not found in playlist. Add it to list?') + answer=linp.alphainput('Curve not found in playlist. Add it to list?','y',0,[]) if answer.lower()[0]=='y': try: self.do_addtolist(filepath) @@ -555,7 +561,8 @@ Syntax: plot x,unitx,y,unity=self._point() print str(x)+' '+unitx print str(y)+' '+unity - + to_dump='point '+self.current.path+' '+str(x)+' '+unitx+', '+str(y)+' '+unity + self.outlet.push(to_dump) def do_close(self,args=None): @@ -603,7 +610,7 @@ If you have a multiple plot, the optional plot to export argument tells Hooke wh dest=0 if args=='': - name=raw_input('Filename?') + name=linp.alphainput('Filename?',self.current.path+'.png',0,[]) else: args=args.split() name=args[0] @@ -638,9 +645,9 @@ Syntax: txt [filename] {plot to export} whichplot=0 args=args.split() if len(args)==0: - filename=raw_input('Filename?') + filename=linp.alphainput('Filename?',self.current.path+'.txt',0,[]) else: - filename=args[0] + filename=linp.checkalphainput(args[0],self.current.path+'.txt',[]) try: whichplot=int(args[1]) except: @@ -698,7 +705,7 @@ Syntax notelog [filename] def do_notelog(self,args): if len(args)==0: - args=raw_input('Notelog filename?') + args=linp.alphainput('Notelog filename?','notelog.txt',0,[]) note_lines='Notes taken at '+time.asctime()+'\n' for item in self.current_list: @@ -728,7 +735,7 @@ Syntax copylog [directory] def do_copylog(self,args): if len(args)==0: - args=raw_input('Destination directory?') + args=linp.alphainput('Destination directory?','',0,[]) #TODO default mydir=os.path.abspath(args) if not os.path.isdir(mydir): @@ -742,6 +749,25 @@ Syntax copylog [directory] except OSError: print 'OSError. Cannot copy file. Perhaps you gave me a wrong directory?' +#OUTLET management + + + def do_outlet_show(self,args): + self.outlet.printbuf() + + def do_outlet_undo(self, args): + print 'Erasing last entry' + self.outlet.pop() + + def do_outlet_delete(self, args): + if len(args)==0: + print 'Index needed!, use outlet_show to know it' + else: + self.outlet.delete(args) + + + + #OS INTERACTION COMMANDS #----------------- @@ -849,9 +875,9 @@ Syntax: quit we_exit='N' if (not self.playlist_saved) or (not self.notes_saved): - we_exit=raw_input('You did not save your playlist and/or notes. Exit?') + we_exit=linp.alphainput('You did not save your playlist and/or notes. Exit?','n',0,[]) else: - we_exit=raw_input('Exit?') + we_exit=linp.alphainput('Exit?','y',0,[]) if we_exit[0].upper()=='Y': wx.CallAfter(self.frame.Close) @@ -866,6 +892,8 @@ Syntax: quit + + if __name__ == '__main__': mycli=HookeCli(0) - mycli.cmdloop() \ No newline at end of file + mycli.cmdloop() diff --git a/libinput.py b/libinput.py new file mode 100644 index 0000000..af82cb8 --- /dev/null +++ b/libinput.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python + +''' +Input check routines. + +Copyright (C) 2008 Alberto Gomez-Casado (University of Twente). + +This program is released under the GNU General Public License version 2. +''' + +def alphainput (message, default, repeat, valid): + if default and not repeat: + print 'Enter for default: '+str(default) + reply=raw_input(message) + if len(valid)>0: + if reply in valid: + return reply + else: + if repeat==1: + while reply not in valid: + reply=raw_input('You should enter any of these: '+ str(valid) +'\n'+ message) + return reply + else: + return default + else: + if len(reply)>0: + return reply + else: + if not repeat: + return default + else: + while len(reply)==0: + print 'Try again' + reply=raw_input(message) + return reply + + + +def checkalphainput (test, default, valid): +#useful when input was taken form command args + if len(valid)>0: + if test in valid: + return test + else: + return default + else: + #TODO: raise exception? + if len(test)>0: + return test + else: + return default + + +def numinput(message, default, repeat, limits): + if default and not repeat: + print 'Enter for default: '+str(default) + reply=raw_input(message) + if reply: + reply=int(reply) + if len(limits)==2: + high=int(limits.pop()) + low=int(limits.pop()) + if reply>=low and reply <= high: + return reply + else: + if repeat==1: + while replyhigh : + reply=raw_input('You should enter values between: '+ str(low)+' and '+str(high) +'\n'+ message) + if reply: + reply=int(reply) + return reply + else: + return default + else: + if len(reply)>0: + return int(reply) + else: + if not repeat: + return default + else: + while len(reply)==0: + print 'Try again' + reply=raw_input(message) + return reply + +def checknuminput(test,default,limits): + if len(limits)==2: + high=int(limits.pop()) + low=int(limits.pop()) + if test>=low and test <= high: + return int(test) + else: + return default + else: + if len(test)>0: + return int(test) + else: + return default + diff --git a/liboutlet.py b/liboutlet.py new file mode 100644 index 0000000..2aed871 --- /dev/null +++ b/liboutlet.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python + +''' +Basic outlet object + +Copyright (C) 2008 Alberto Gomez-Casado (University of Twente). + +This program is released under the GNU General Public License version 2. +''' + + +import re + + +class Outlet(object): + + def __init__(self): + self.buffer=[] + self.relations=[] + + def push(self, args): + self.buffer.append(args) + + def pop(self, args): + return self.buffer.pop(); + + def printbuf(self): + j=1; + for i in self.buffer: + print j, i + j=j+1 + + def delete(self, number): + if len(self.buffer)>int(number)-1 and int(number)>0: + self.buffer.pop(int(number)-1) + + def empty(self): + self.buffer=[] + + def read_last(self): + return self.buffer[len(self.buffer)-1] + + def read_first(self): + return self.buffer[0] + + def read_type(self,dtype): + aux=[] + index=0 + if dtype=='all': + return self.buffer + for i in self.buffer: + if re.match(dtype+'*',i): + aux.append(i) + return aux + + diff --git a/libviewer.py b/libviewer.py new file mode 100644 index 0000000..37fe2eb --- /dev/null +++ b/libviewer.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python + +''' +Basic Viewer and ascii saver examples + +Copyright (C) 2008 Alberto Gomez-Casado (University of Twente). + +This program is released under the GNU General Public License version 2. +''' + + +import liboutlet as lout + +class Viewer(object): + source=[] + data=[] + dtype='all' + action=[] + + + def setdtype(self, dt): + self.dtype=dt + + def show(self): + self.source.printbuf() + + def getdata(self): + self.data=self.source.read_type(self.dtype) + + + +class Ascii(Viewer): + + def __init__(self,outref): + self.source=outref + self.action=self.dump + + def dump(self): + self.getdata() + destination=raw_input('Enter filename:') + destfile=open(destination,'w+') + destfile.write('\n'.join(self.data)) + destfile.close() + diff --git a/viewer.py b/viewer.py new file mode 100644 index 0000000..bae4355 --- /dev/null +++ b/viewer.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python + +''' +Viewer test case + +Copyright (C) 2008 Alberto Gomez-Casado (University of Twente). + +This program is released under the GNU General Public License version 2. +''' + + +import libviewer as lview + +class viewerCommands: + + def _plug_init(self): + self.viewerlist=[] + + + def do_vwnew(self,args): + self.viewerlist.append(lview.Ascii(self.outlet)) + dt=raw_input('What type of data will this viewer handle? (force/distance/all)') + print dt + self.viewerlist[-1].setdtype(dt) + + + def do_vwaction(self,args): + ''' + triggers default action of viewer number n (default 0) + ''' + + if len(args)==0: + args=0 + self.viewerlist[int(args)].action()