(mfp_igor_scripts) Scripts committed
[hooke.git] / generalclamp.py
index 477454e0536e51b9d7b52623a6c0f1a01656b830..4ac30e71554dfa7449f8fabac78cd2832848caeb 100644 (file)
@@ -70,14 +70,12 @@ class generalclampCommands:
       
     def do_time(self,args):
         '''
-        TIME
-        Measure the time difference (in seconds) between two points
+        Measures the time difference (in seconds) between two points
         Implemented only for force clamp
         ----
         Syntax: time
         '''
         if self.current.curve.experiment == 'clamp':\r
-            print 'Click two points.'
             time=self._delta(set=0)[0]\r
             print str(time*1000)+' ms'
         else:
@@ -85,41 +83,34 @@ class generalclampCommands:
             
     def do_zpiezo(self,args):
         '''
-        ZPIEZO
-        Measure the zpiezo difference (in nm) between two points
+        Measures the zpiezo difference (in nm) between two points
         Implemented only for force clamp
         ----
         Syntax: zpiezo
         '''
         if self.current.curve.experiment == 'clamp':
-            print 'Click two points.'
-            points=self._measure_N_points(N=2)
-            zpiezo=abs(points[0].graph_coords[1]-points[1].graph_coords[1])
+            zpiezo=self._delta(set=0)[2]\r
             print str(zpiezo*(10**9))+' nm'
         else:
             print 'This command makes no sense for a non-force clamp experiment.'
             
     def do_defl(self,args):
         '''
-        DEFL
-        Measure the deflection difference (in nm) between two points
+        Measures the deflection difference (in nm) between two points
         Implemented only for force clamp
         NOTE: It makes sense only on the time VS defl plot; it is still not masked for the other plot...
         -----
         Syntax: defl
         '''
         if self.current.curve.experiment == 'clamp':
-            print 'Click two points.'
-            points=self._measure_N_points(N=2)
-            defl=abs(points[0].graph_coords[1]-points[1].graph_coords[1])
+            print "Warning - don't use on the zpiezo plot!"
+            defl=self._delta(set=1)[2]
             print str(defl*(10**12))+' pN'
         else:
             print 'This command makes no sense for a non-force clamp experiment.'
             
     def do_step(self,args):
         '''
-        STEP
-        
         Measures the length and time duration of a time-Z step
         -----
         Syntax: step
@@ -137,4 +128,124 @@ class generalclampCommands:
             print 'dT: ',dt,' s'
             
         else:
-            print 'This command makes no sense for a non-force clamp experiment.'
\ No newline at end of file
+            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