(liboutlet.py) collector of command line output
authoralbertogomcas <devnull@localhost>
Wed, 18 Jun 2008 12:36:17 +0000 (12:36 +0000)
committeralbertogomcas <devnull@localhost>
Wed, 18 Jun 2008 12:36:17 +0000 (12:36 +0000)
(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

CHANGELOG
fit.py
flatfilts.py
generalclamp.py
generalvclamp.py
hooke.conf
hooke_cli.py
libinput.py [new file with mode: 0644]
liboutlet.py [new file with mode: 0644]
libviewer.py [new file with mode: 0644]
viewer.py [new file with mode: 0644]

index c46b6eeccc74bf4283db2852e1916c5a3b4e5289..318ab348d939a015fc745bafde9cdc07f2661ef5 100755 (executable)
--- 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 f70636f06786a0eff4e760769c4e53ad986f13d8..886442323bee0b8258a2f837ddf7640b37eedc5f 100755 (executable)
--- 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=[], []
index 27e526f61427d8b45bc7280b09a7a5ee828ab237..25503f872d3660495b45380fd11b735e8883798d 100755 (executable)
@@ -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.
index 508d9a3d38ea2070bd78e1a802ecc8f5b8c9eaea..14974dc7225380678f8064fdaf390e2cd8e50012 100644 (file)
@@ -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
index d3adefd9bd2d9211b70f62a0913360d178415f48..482446540f3d889d9d6e493ea5eab49143a314b8 100644 (file)
@@ -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]
index b590ac9563eef91367267f9f4c9b5cf947a08838..8b39b46a5aec8901c866cadd45b34c66c17fa553 100755 (executable)
@@ -2,13 +2,13 @@
 <!-- To comment something, put dashes and ! like here -->
 <config>
 <!-- Internal variabls. -->
-    <display ext="1" colour_ext="None" ret="1" colour_ret="None" correct="1" colour_correct="None" contact_point="0" medfilt="0" xaxes="0" yaxes="0" flatten="1" temperature="293" auto_fit_points="50" auto_slope_span="20" auto_delta_force="10" fc_showphase="0" fc_showimposed="0" fc_interesting="0"/>
+    <display ext="1" colour_ext="None" ret="1" colour_ret="None" correct="1" colour_correct="None" contact_point="0" medfilt="0" xaxes="0" yaxes="0" flatten="1" temperature="293" auto_fit_points="10" auto_slope_span="10" auto_delta_force="10" fc_showphase="0" fc_showimposed="0" fc_interesting="0"/>
 
 <!-- 
 The following section defines your own work directory. Substitute your work directory.
      -->
 <workdir>
-    insert directory
+    /home/glacierre/hooke/
 </workdir>
 
 <!--
@@ -23,6 +23,7 @@ This section defines which plugins have to be loaded by Hooke.
     <!--superimpose/ -->
     <generalvclamp/>
     <massanalysis/>
+    <viewer/>
     <!-- tutorial/ -->
     <macro/>
 </plugins>
@@ -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.
     -->
 <drivers>
-    <picoforce/>
+    <picoforcealt/>
     <!-- hemingclamp/ -->
     <csvdriver/>
     <!-- tutorialdriver/ -->
index 8ed2ca0de612eb3c84870f1a9298d6a71ecc329e..da1379e4b06a1cec8c2291340f80276eae20dff7 100755 (executable)
@@ -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 (file)
index 0000000..af82cb8
--- /dev/null
@@ -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 reply<low or reply>high :
+                                       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 (file)
index 0000000..2aed871
--- /dev/null
@@ -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 (file)
index 0000000..37fe2eb
--- /dev/null
@@ -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 (file)
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()