Ran update_copyright.py, updating all the copyright blurbs and adding AUTHORS.
[hooke.git] / hooke / plugin / generalclamp.py
index 4ac30e71554dfa7449f8fabac78cd2832848caeb..54aff5f123c391b113c4f49580f3e24ba703f914 100644 (file)
@@ -1,73 +1,93 @@
-#!/usr/bin/env python
+# Copyright (C) 2008-2010 Alberto Gomez-Casado
+#                         Marco Brucale
+#                         Massimo Sandal <devicerandom@gmail.com>
+#                         W. Trevor King <wking@drexel.edu>
+#
+# This file is part of Hooke.
+#
+# Hooke is free software: you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation, either
+# version 3 of the License, or (at your option) any later version.
+#
+# Hooke 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with Hooke.  If not, see
+# <http://www.gnu.org/licenses/>.
 
-'''
-GENERALCLAMP.py
+"""Plugin regarding general force clamp measurements
+"""
 
-Plugin regarding general force clamp measurements
-'''
-from libhooke import WX_GOOD, ClickedPoint
-import wxversion\r
-import libhookecurve as lhc
+from hooke.libhooke import WX_GOOD, ClickedPoint
+
+import wxversion
 wxversion.select(WX_GOOD)
-from wx import PostEvent\r
+from wx import PostEvent
+
+from .. import curve as lhc
+
+
+class generalclampCommands(object):
 
-class generalclampCommands:\r
-\r
     def plotmanip_clamp(self, plot, current, customvalue=False):
         '''
-        Handles some viewing options for the "force clamp" data format, depending on the state of these configuration variables:\r
-        (1) If self.config['fc_showphase'] != 0, the 'phase' data column (i.e. the 2nd) is shown in the 0th graph (else it isn't)\r
-        (2) If self.config['fc_showimposed'] != 0, the 'imposed deflection' data column (i.e. the 5th) is shown in the 1st graph (else it isn't)\r
+        Handles some viewing options for the "force clamp" data format, depending on the state of these configuration variables:
+        (1) If self.config['fc_showphase'] != 0, the 'phase' data column (i.e. the 2nd) is shown in the 0th graph (else it isn't)
+        (2) If self.config['fc_showimposed'] != 0, the 'imposed deflection' data column (i.e. the 5th) is shown in the 1st graph (else it isn't)
         (3) If self.config['fc_interesting'] == 0, the entire curve is shown in the graphs; if it has a non-zero value N, only phase N is shown.
-\r
-        NOTE - my implementation of point(3) feels quite awkward - someone smarter than me plz polish that!\r
-\r
+
+        NOTE - my implementation of point(3) feels quite awkward - someone smarter than me plz polish that!
+
         '''
-        
+
         #not a fclamp curve...
         if current.curve.experiment != 'clamp':
-            return plot\r
-\r
-        if self.config['fc_interesting'] != 0 and plot.destination==0:\r
-            lower = int((self.config['fc_interesting'])-1)\r
-            upper = int((self.config['fc_interesting'])+1)\r
-            trim = current.curve.trimindexes()[lower:upper]\r
-            newtime = []\r
-            newzpiezo = []\r
-            newphase = []\r
-            for x in range(trim[0],trim[1]):\r
-                newtime.append(self.plots[0].vectors[0][0][x])\r
-                newzpiezo.append(self.plots[0].vectors[0][1][x])\r
-                newphase.append(self.plots[0].vectors[1][1][x])\r
-            self.plots[0].vectors[0][0] = newtime\r
-            self.plots[0].vectors[0][1] = newzpiezo\r
-            self.plots[0].vectors[1][0] = newtime\r
-            self.plots[0].vectors[1][1] = newphase\r
-\r
-        if self.config['fc_interesting'] != 0 and plot.destination==1:\r
-            lower = int((self.config['fc_interesting'])-1)\r
-            upper = int((self.config['fc_interesting'])+1)\r
-            trim = current.curve.trimindexes()[lower:upper]\r
-            newtime = []\r
-            newdefl = []\r
-            newimposed = []\r
-            for x in range(trim[0],trim[1]):\r
-                newtime.append(self.plots[1].vectors[0][0][x])\r
-                newdefl.append(self.plots[1].vectors[0][1][x])\r
-                newimposed.append(self.plots[1].vectors[1][1][x])\r
-            self.plots[1].vectors[0][0] = newtime\r
-            self.plots[1].vectors[0][1] = newdefl\r
-            self.plots[1].vectors[1][0] = newtime\r
-            self.plots[1].vectors[1][1] = newimposed            \r
-                        \r
-        if self.config['fc_showphase'] == 0 and plot.destination==0:\r
-            self.plots[0].remove_set(1)\r
-            \r
-        if self.config['fc_showimposed'] == 0 and plot.destination==1:\r
-            self.plots[1].remove_set(1)\r
-                         \r
+            return plot
+
+        if self.config['fc_interesting'] != 0 and plot.destination==0:
+            lower = int((self.config['fc_interesting'])-1)
+            upper = int((self.config['fc_interesting'])+1)
+            trim = current.curve.trimindexes()[lower:upper]
+            newtime = []
+            newzpiezo = []
+            newphase = []
+            for x in range(trim[0],trim[1]):
+                newtime.append(self.plots[0].vectors[0][0][x])
+                newzpiezo.append(self.plots[0].vectors[0][1][x])
+                newphase.append(self.plots[0].vectors[1][1][x])
+            self.plots[0].vectors[0][0] = newtime
+            self.plots[0].vectors[0][1] = newzpiezo
+            self.plots[0].vectors[1][0] = newtime
+            self.plots[0].vectors[1][1] = newphase
+
+        if self.config['fc_interesting'] != 0 and plot.destination==1:
+            lower = int((self.config['fc_interesting'])-1)
+            upper = int((self.config['fc_interesting'])+1)
+            trim = current.curve.trimindexes()[lower:upper]
+            newtime = []
+            newdefl = []
+            newimposed = []
+            for x in range(trim[0],trim[1]):
+                newtime.append(self.plots[1].vectors[0][0][x])
+                newdefl.append(self.plots[1].vectors[0][1][x])
+                newimposed.append(self.plots[1].vectors[1][1][x])
+            self.plots[1].vectors[0][0] = newtime
+            self.plots[1].vectors[0][1] = newdefl
+            self.plots[1].vectors[1][0] = newtime
+            self.plots[1].vectors[1][1] = newimposed
+
+        if self.config['fc_showphase'] == 0 and plot.destination==0:
+            self.plots[0].remove_set(1)
+
+        if self.config['fc_showimposed'] == 0 and plot.destination==1:
+            self.plots[1].remove_set(1)
+
         return plot
-      
+
     def do_time(self,args):
         '''
         Measures the time difference (in seconds) between two points
@@ -75,12 +95,12 @@ class generalclampCommands:
         ----
         Syntax: time
         '''
-        if self.current.curve.experiment == 'clamp':\r
-            time=self._delta(set=0)[0]\r
+        if self.current.curve.experiment == 'clamp':
+            time=self._delta(set=0)[0]
             print str(time*1000)+' ms'
         else:
             print 'This command makes no sense for a non-force clamp experiment.'
-            
+
     def do_zpiezo(self,args):
         '''
         Measures the zpiezo difference (in nm) between two points
@@ -89,11 +109,11 @@ class generalclampCommands:
         Syntax: zpiezo
         '''
         if self.current.curve.experiment == 'clamp':
-            zpiezo=self._delta(set=0)[2]\r
+            zpiezo=self._delta(set=0)[2]
             print str(zpiezo*(10**9))+' nm'
         else:
             print 'This command makes no sense for a non-force clamp experiment.'
-            
+
     def do_defl(self,args):
         '''
         Measures the deflection difference (in nm) between two points
@@ -108,7 +128,7 @@ class generalclampCommands:
             print str(defl*(10**12))+' pN'
         else:
             print 'This command makes no sense for a non-force clamp experiment.'
-            
+
     def do_step(self,args):
         '''
         Measures the length and time duration of a time-Z step
@@ -126,126 +146,126 @@ class generalclampCommands:
             dt=abs(points[1].graph_coords[0]-points[0].graph_coords[0])
             print 'dZ: ',dz,' nm'
             print 'dT: ',dt,' s'
-            
+
+        else:
+            print 'This command makes no sense for a non-force clamp experiment.'
+
+    def do_fcfilt(self,args):
+        '''
+        Filters out featureless force clamp curves of the current playlist.
+        It's very similar to 'flatfilt' for velocity clamp curves.
+        Creates a new playlist only containing non-empty curves.
+
+        WARNING - Only works if you set an appropriate fc_interesting config variable!
+        WARNING - arguments are NOT optional at the moment!
+
+        Syntax: fcfilt maxretraction(nm) mindeviation (pN)
+
+        Suggested values for an (i27)8 experiment with our setup are 200nm and 10-15 pN
+        '''
+
+        if self.config['fc_interesting'] == 0:
+            print 'You must specify the phase of interest (using set fc_interesing X) prior to running fcfilt!'
+            return
+
+        maxretraction=0
+        threshold=0
+        args=args.split(' ')
+        if len(args)==2:
+            maxretraction=int(args[0])
+            threshold=int(args[1])
+        else:
+            print 'Arguments are not optional for fcfilt. You should pass two numbers:'
+            print '(1) the maximum plausible piezo retraction in NANOMETERS (e.g. the length of the protein)'
+            print "(2) the threshold, in PICONEWTONS. If signal deviates from imposed more than this, it's an event"
+            return
+
+
+        print 'Processing playlist... go get yourself a cup of coffee.'
+        notflat_list=[]
+
+        c=0
+
+        for item in self.current_list:
+            c+=1
+            try:
+                notflat=self.has_stuff(item,maxretraction,threshold)
+                print 'Curve',item.path,'is',c,'of',len(self.current_list),'--->Has Stuff =',notflat
+            except:
+                notflat=False
+                print 'Curve',item.path,'is',c,'of',len(self.current_list),'--->could not be processed'
+            if notflat:
+                item.features=notflat
+                item.curve=None
+                notflat_list.append(item)
+
+        if len(notflat_list)==0:
+            print 'Nothing interesting here. Reconsider either your filtering criteria or your experimental data'
+            return
         else:
-            print 'This command makes no sense for a non-force clamp experiment.'\r
-\r
-    def do_fcfilt(self,args):\r
-        '''\r
-        Filters out featureless force clamp curves of the current playlist.\r
-        It's very similar to 'flatfilt' for velocity clamp curves.\r
-        Creates a new playlist only containing non-empty curves.\r
-\r
-        WARNING - Only works if you set an appropriate fc_interesting config variable!\r
-        WARNING - arguments are NOT optional at the moment!\r
-\r
-        Syntax: fcfilt maxretraction(nm) mindeviation (pN)\r
-\r
-        Suggested values for an (i27)8 experiment with our setup are 200nm and 10-15 pN\r
-        '''\r
-\r
-        if self.config['fc_interesting'] == 0:\r
-            print 'You must specify the phase of interest (using set fc_interesing X) prior to running fcfilt!'\r
-            return\r
-        \r
-        maxretraction=0\r
-        threshold=0\r
-        args=args.split(' ')\r
-        if len(args)==2:\r
-            maxretraction=int(args[0])\r
-            threshold=int(args[1])\r
-        else:\r
-            print 'Arguments are not optional for fcfilt. You should pass two numbers:'\r
-            print '(1) the maximum plausible piezo retraction in NANOMETERS (e.g. the length of the protein)'\r
-            print "(2) the threshold, in PICONEWTONS. If signal deviates from imposed more than this, it's an event"\r
-            return\r
-        \r
-\r
-        print 'Processing playlist... go get yourself a cup of coffee.'\r
-        notflat_list=[]\r
-\r
-        c=0\r
-\r
-        for item in self.current_list:\r
-            c+=1\r
-            try:\r
-                notflat=self.has_stuff(item,maxretraction,threshold)\r
-                print 'Curve',item.path,'is',c,'of',len(self.current_list),'--->Has Stuff =',notflat\r
-            except:\r
-                notflat=False\r
-                print 'Curve',item.path,'is',c,'of',len(self.current_list),'--->could not be processed'\r
-            if notflat:\r
-                item.features=notflat\r
-                item.curve=None\r
-                notflat_list.append(item)\r
-\r
-        if len(notflat_list)==0:\r
-            print 'Nothing interesting here. Reconsider either your filtering criteria or your experimental data'\r
-            return\r
-        else:\r
-            print 'Found',len(notflat_list),'potentially interesting curves.'\r
-            print 'Regenerating Playlist...'\r
-            self.pointer=0\r
-            self.current_list=notflat_list\r
-            self.current=self.current_list[self.pointer]\r
-            self.do_plot(0)\r
-\r
-    def has_stuff(self,item,maxretraction,threshold):\r
-        '''\r
-        Decides whether a curve has some features in the interesting phase.\r
-        Algorithm:\r
-            - clip the interesting phase portion of the curve.\r
-            - discard the first 20 milliseconds (this is due to a quirk of our hardware).\r
-            - look at the zpiezo plot and note down when (if) retratcs more than [maxretraction] nm away from the first point.\r
-            - clip off any data after this point, with an excess of 100 points (again, an hardware quirk)\r
-            - if the remainder is less than 100 points, ditch the curve.\r
-            - now look at the deflection plot and check if there are points more than [threshold] pN over the 'flat zone'.\r
-            - if you find such points, bingo!            \r
-        '''\r
-\r
-        item.identify(self.drivers)\r
-   \r
-        lower = int((self.config['fc_interesting'])-1)\r
-        upper = int((self.config['fc_interesting'])+1)\r
-        trim_idxs = item.curve.trimindexes()[lower:upper]\r
-        lo=trim_idxs[0]+20                                                  #clipping the first 20 points off...\r
-        hi=trim_idxs[1]\r
-        trimmed_zpiezo=item.curve.default_plots()[0].vectors[0][1][lo:hi]\r
-        trimmed_defl=item.curve.default_plots()[1].vectors[0][1][lo:hi]\r
-        trimmed_imposed=item.curve.default_plots()[1].vectors[1][1][lo:hi]\r
-        imposed=trimmed_imposed[21]                                         #just to match the 20-pts clipping...\r
-        \r
-        item.curve.close_all()\r
-        del item.curve\r
-        del item\r
-\r
-        starting_z=trimmed_zpiezo[0]\r
-        plausible=starting_z-(maxretraction*1e-9)\r
-        det_trim=0\r
-        while trimmed_zpiezo[det_trim]>plausible:\r
-            det_trim+=1\r
-            if det_trim >= len(trimmed_zpiezo):                              #breaking cycles makes me shiver...\r
-                det_trim=len(trimmed_zpiezo)                                 #but I cannot think of anything better now.\r
-                break\r
-        further_trim=det_trim-100\r
-        if further_trim<100:\r
-            return False\r
-        trimmed_defl=trimmed_defl[:further_trim]\r
-\r
-        trimmed_defl.sort()\r
-        ninetypercent=int(0.9*len(trimmed_defl))\r
-        j=0\r
-        sum=0\r
-        for j in trimmed_defl[:ninetypercent]:\r
-            sum+=j\r
-        avg=float(sum/ninetypercent)\r
-        sweetspot=float(avg+(threshold*1e-12))\r
-        if trimmed_defl[-1]>sweetspot:\r
-            flag=True\r
-        else:\r
-            flag=False\r
-\r
-        del trimmed_defl,trimmed_zpiezo,trimmed_imposed            \r
-\r
-        return flag            \r
-        
\ No newline at end of file
+            print 'Found',len(notflat_list),'potentially interesting curves.'
+            print 'Regenerating playlist...'
+            self.pointer=0
+            self.current_list=notflat_list
+            self.current=self.current_list[self.pointer]
+            self.do_plot(0)
+
+    def has_stuff(self,item,maxretraction,threshold):
+        '''
+        Decides whether a curve has some features in the interesting phase.
+        Algorithm:
+            - clip the interesting phase portion of the curve.
+            - discard the first 20 milliseconds (this is due to a quirk of our hardware).
+            - look at the zpiezo plot and note down when (if) retratcs more than [maxretraction] nm away from the first point.
+            - clip off any data after this point, with an excess of 100 points (again, an hardware quirk)
+            - if the remainder is less than 100 points, ditch the curve.
+            - now look at the deflection plot and check if there are points more than [threshold] pN over the 'flat zone'.
+            - if you find such points, bingo!
+        '''
+
+        item.identify(self.drivers)
+
+        lower = int((self.config['fc_interesting'])-1)
+        upper = int((self.config['fc_interesting'])+1)
+        trim_idxs = item.curve.trimindexes()[lower:upper]
+        lo=trim_idxs[0]+20                                                  #clipping the first 20 points off...
+        hi=trim_idxs[1]
+        trimmed_zpiezo=item.curve.default_plots()[0].vectors[0][1][lo:hi]
+        trimmed_defl=item.curve.default_plots()[1].vectors[0][1][lo:hi]
+        trimmed_imposed=item.curve.default_plots()[1].vectors[1][1][lo:hi]
+        imposed=trimmed_imposed[21]                                         #just to match the 20-pts clipping...
+
+        item.curve.close_all()
+        del item.curve
+        del item
+
+        starting_z=trimmed_zpiezo[0]
+        plausible=starting_z-(maxretraction*1e-9)
+        det_trim=0
+        while trimmed_zpiezo[det_trim]>plausible:
+            det_trim+=1
+            if det_trim >= len(trimmed_zpiezo):                              #breaking cycles makes me shiver...
+                det_trim=len(trimmed_zpiezo)                                 #but I cannot think of anything better now.
+                break
+        further_trim=det_trim-100
+        if further_trim<100:
+            return False
+        trimmed_defl=trimmed_defl[:further_trim]
+
+        trimmed_defl.sort()
+        ninetypercent=int(0.9*len(trimmed_defl))
+        j=0
+        sum=0
+        for j in trimmed_defl[:ninetypercent]:
+            sum+=j
+        avg=float(sum/ninetypercent)
+        sweetspot=float(avg+(threshold*1e-12))
+        if trimmed_defl[-1]>sweetspot:
+            flag=True
+        else:
+            flag=False
+
+        del trimmed_defl,trimmed_zpiezo,trimmed_imposed
+
+        return flag
+