(autopeak.py) Corrected a bug introduced in r208
[hooke.git] / generalvclamp.py
index e200a59910bcd3bb643667073931fbb6941cbb9d..1c71de0e03ab61074a9501cc31ce5f54e11fb301 100644 (file)
@@ -120,7 +120,33 @@ class generalvclampCommands:
         print str(forcebase*(10**12))+' pN'
         to_dump='forcebase '+self.current.path+' '+str(forcebase*(10**12))+' pN'
         self.outlet.push(to_dump)
+\r
+    def plotmanip_multiplier(self, plot, current):
+        '''
+        Multiplies all the Y values of an SMFS curve by a value stored in the 'force_multiplier'\r
+        configuration variable. Useful for calibrations and other stuff.
+        '''
+        
+        #not a smfs curve...
+        if current.curve.experiment != 'smfs':
+            return plot
+        
+        #only one set is present...
+        if len(self.plots[0].vectors) != 2:
+            return plot
         
+        #multiplier is 1...
+        if (self.config['force_multiplier']==1):
+            return plot\r
+\r
+        for i in range(len(plot.vectors[0][1])):
+            plot.vectors[0][1][i]=plot.vectors[0][1][i]*self.config['force_multiplier']        \r
+\r
+        for i in range(len(plot.vectors[1][1])):
+            plot.vectors[1][1][i]=plot.vectors[1][1][i]*self.config['force_multiplier']\r
+\r
+        return plot            \r
+   
     
     def plotmanip_flatten(self, plot, current, customvalue=False):
         '''
@@ -270,7 +296,7 @@ class generalvclampCommands:
         
         self._send_plot([lineplot])
 
-    def linefit_between(self,index1,index2):
+    def linefit_between(self,index1,index2,whatset=1):
         '''
         Creates two vectors (xtofit,ytofit) slicing out from the
         current return trace a portion delimited by the two indexes
@@ -282,8 +308,8 @@ class generalvclampCommands:
         (c) Marco Brucale, Massimo Sandal 2008
         '''
         # Translates the indexes into two vectors containing the x,y data to fit
-        xtofit=self.plots[0].vectors[1][0][index1:index2]
-        ytofit=self.plots[0].vectors[1][1][index1:index2]
+        xtofit=self.plots[0].vectors[whatset][0][index1:index2]
+        ytofit=self.plots[0].vectors[whatset][1][index1:index2]
         
         # Does the actual linear fitting (simple least squares with numpy.polyfit)
         linefit=[]
@@ -293,262 +319,3 @@ class generalvclampCommands:
     
     
     
-#====================
-#AUTOMATIC ANALYSES
-#====================
-    '''
-    def do_autopeak(self,args):
-        #FIXME: this function is too long. split it and make it rational.
-        #FIXME: also, *generalize fits* to allow FJC and any other model in the future!
-        
-        def fit_interval_nm(start_index,plot,nm,backwards):
-    '''
-            
-    '''
-            Calculates the number of points to fit, given a fit interval in nm
-            start_index: index of point
-            plot: plot to use
-            backwards: if true, finds a point backwards.
-    '''
-            
-    '''
-            x_vect=plot.vectors[1][0]
-            
-            c=0
-            i=start_index
-            start=x_vect[start_index]
-            maxlen=len(x_vect)
-            while abs(x_vect[i]-x_vect[start_index])*(10**9) < nm:
-                if i==0 or i==maxlen-1: #we reached boundaries of vector!
-                    return c
-                
-                if backwards:
-                    i-=1
-                else:
-                    i+=1
-                c+=1
-            return c
-            
-        
-        pl_value=None
-        T=self.config['temperature']
-        
-        if 'usepoints' in args.split():
-            fit_points=int(self.config['auto_fit_points'])
-            usepoints=True
-        else:
-            fit_points=None
-            usepoints=False
-            
-        slope_span=int(self.config['auto_slope_span'])
-        delta_force=10
-        rebase=False #if true=we select rebase
-        
-        #Pick up plot
-        displayed_plot=self._get_displayed_plot(0)
-        
-        if self.current.curve.experiment != 'smfs' or len(displayed_plot.vectors) < 2:
-            print 'Cannot work on this curve.'
-            return
-        
-        #Look for custom persistent length / custom temperature
-        for arg in args.split():
-            #look for a persistent length argument.
-            if 'pl=' in arg:
-                pl_expression=arg.split('=')
-                pl_value=float(pl_expression[1]) #actual value
-            #look for a T argument. FIXME: spaces are not allowed between 'pl' and value
-            if ('t=' in arg[0:2]) or ('T=' in arg[0:2]):
-                t_expression=arg.split('=')
-                T=float(t_expression[1])
-                              
-        #Handle contact point arguments
-        def pickup_contact_point():
-            #macro to pick up the contact point by clicking
-            contact_point=self._measure_N_points(N=1, whatset=1)[0]
-            contact_point_index=contact_point.index
-            self.wlccontact_point=contact_point
-            self.wlccontact_index=contact_point.index
-            self.wlccurrent=self.current.path
-            return contact_point, contact_point_index
-                
-        if 'reclick' in args.split():
-            print 'Click contact point'
-            contact_point, contact_point_index = pickup_contact_point()
-        elif 'noauto' in args.split():
-            if self.wlccontact_index==None or self.wlccurrent != self.current.path:
-                print 'Click contact point'
-                contact_point , contact_point_index = pickup_contact_point()
-            else:
-                contact_point=self.wlccontact_point
-                contact_point_index=self.wlccontact_index
-        else:
-            #Automatically find contact point
-            cindex=self.find_contact_point()
-            contact_point=ClickedPoint()
-            contact_point.absolute_coords=displayed_plot.vectors[1][0][cindex], displayed_plot.vectors[1][1][cindex]
-            contact_point.find_graph_coords(displayed_plot.vectors[1][0], displayed_plot.vectors[1][1])
-            contact_point.is_marker=True
-        
-        
-        #Find peaks.
-        defplot=self.current.curve.default_plots()[0]
-        flatten=self._find_plotmanip('flatten') #Extract flatten plotmanip
-        defplot=flatten(defplot, self.current, customvalue=1) #Flatten curve before feeding it to has_peaks
-        peak_location,peak_size=self.has_peaks(defplot, self.convfilt_config['mindeviation'])
-        
-        #Create a new plot to send
-        fitplot=copy.deepcopy(displayed_plot)
-        
-        #Pick up force baseline
-        whatset=1 #fixme: for all sets
-        if 'rebase' in args or (self.basecurrent != self.current.path):
-            rebase=True               
-        if rebase:
-            clicks=self.config['baseline_clicks']
-            if clicks==0:
-                self.basepoints=[]
-                self.basepoints.append(ClickedPoint())
-                self.basepoints.append(ClickedPoint())
-                self.basepoints[0].index=peak_location[-1]+fit_interval_nm(peak_location[-1], displayed_plot, self.config['auto_right_baseline'],False)
-                self.basepoints[1].index=self.basepoints[0].index+fit_interval_nm(self.basepoints[0].index, displayed_plot, self.config['auto_left_baseline'],False)
-                for point in self.basepoints:
-                    #for graphing etc. purposes, fill-in with coordinates
-                    point.absolute_coords=displayed_plot.vectors[1][0][point.index], displayed_plot.vectors[1][1][point.index]
-                    point.find_graph_coords(displayed_plot.vectors[1][0], displayed_plot.vectors[1][1])
-            elif clicks>0:
-                print 'Select baseline'
-                if clicks==1:
-                    self.basepoints=self._measure_N_points(N=1, whatset=whatset)
-                    self.basepoints.append(ClickedPoint())
-                    self.basepoints[1].index=self.basepoints[0].index+fit_interval_nm(self.basepoints[0].index, displayed_plot, self.config['auto_left_baseline'], False)
-                    #for graphing etc. purposes, fill-in with coordinates
-                    self.basepoints[1].absolute_coords=displayed_plot.vectors[1][0][self.basepoints[1].index], displayed_plot.vectors[1][1][self.basepoints[1].index]
-                    self.basepoints[1].find_graph_coords(displayed_plot.vectors[1][0], displayed_plot.vectors[1][1])
-                else:
-                    self.basepoints=self._measure_N_points(N=2, whatset=whatset)
-            
-            self.basecurrent=self.current.path
-        
-        boundaries=[self.basepoints[0].index, self.basepoints[1].index]
-        boundaries.sort()
-        to_average=displayed_plot.vectors[1][1][boundaries[0]:boundaries[1]] #y points to average
-        avg=np.mean(to_average)
-        
-        
-        #Initialize data vectors
-        c_lengths=[]
-        p_lengths=[]
-        forces=[]
-        slopes=[]
-        
-        
-        
-        #Cycle between peaks and do analysis.
-        for peak in peak_location:
-            #Do WLC fits.
-            #FIXME: clean wlc fitting, to avoid this clickedpoint hell
-            #-create a clicked point for the peak point
-            peak_point=ClickedPoint()
-            peak_point.absolute_coords=displayed_plot.vectors[1][0][peak], displayed_plot.vectors[1][1][peak]
-            peak_point.find_graph_coords(displayed_plot.vectors[1][0], displayed_plot.vectors[1][1])    
-            
-            if not usepoints:
-                fit_points=fit_interval_nm(peak, displayed_plot, self.config['auto_fit_nm'], True)
-            
-            #-create a clicked point for the other fit point
-            other_fit_point=ClickedPoint()
-            other_fit_point.absolute_coords=displayed_plot.vectors[1][0][peak-fit_points], displayed_plot.vectors[1][1][peak-fit_points]
-            other_fit_point.find_graph_coords(displayed_plot.vectors[1][0], displayed_plot.vectors[1][1])    
-            #do the fit
-            points=[contact_point, peak_point, other_fit_point]
-            
-            #Check if we have enough points for a fit. If not, wlc_fit could crash
-            if abs(peak_point.index-other_fit_point.index) < 2:
-                continue
-            
-            params, yfit, xfit = self.wlc_fit(points, displayed_plot.vectors[1][0], displayed_plot.vectors[1][1],pl_value,T)
-            #save wlc values (nm)
-            c_lengths.append(params[0]*(1.0e+9))
-            if len(params)==2: #if we did choose 2-value fit
-                p_lengths.append(params[1]*(1.0e+9))
-            else:
-                p_lengths.append(pl_value)
-            #Add WLC fit lines to plot
-            fitplot.add_set(xfit,yfit)
-            
-            if len(fitplot.styles)==0:
-                fitplot.styles=[]
-            else:
-                fitplot.styles.append(None)
-            #Measure forces
-            delta_to_measure=displayed_plot.vectors[1][1][peak-delta_force:peak+delta_force]
-            y=min(delta_to_measure)
-            #save force values (pN)
-            forces.append(abs(y-avg)*(1.0e+12))
-                
-            #Measure slopes
-            slope=self.linefit_between(peak-slope_span,peak)[0]
-            slopes.append(slope)
-        
-        #--DEBUG STUFF--
-        fitplot.add_set([self.basepoints[0].graph_coords[0],self.basepoints[1].graph_coords[0]],[self.basepoints[0].graph_coords[1],self.basepoints[1].graph_coords[1]]) 
-        fitplot.styles.append('scatter')
-        
-        #Show wlc fits and peak locations
-        self._send_plot([fitplot])
-        self.do_peaks('')
-        
-        #Ask the user what peaks to ignore from analysis.
-        print 'Peaks to ignore (0,1...n from contact point,return to take all)'
-        print 'N to discard measurement'
-        exclude_raw=raw_input('Input:')
-        if exclude_raw=='N':
-            print 'Discarded.'
-            return
-        if not exclude_raw=='':
-            exclude=exclude_raw.split(',')
-            try:
-                exclude=[int(item) for item in exclude]
-                for i in exclude:
-                    c_lengths[i]=None
-                    p_lengths[i]=None
-                    forces[i]=None
-                    slopes[i]=None
-            except:
-                 print 'Bad input, taking all...'
-        #Clean data vectors from ignored peaks        
-        c_lengths=[item for item in c_lengths if item != None]
-        p_lengths=[item for item in p_lengths if item != None]
-        forces=[item for item in forces if item != None]
-        slopes=[item for item in slopes if item != None]    
-        print 'contour (nm)',c_lengths
-        print 'p (nm)',p_lengths
-        print 'forces (pN)',forces
-        print 'slopes (N/m)',slopes
-        
-        #Save file info
-        if self.autofile=='':
-            self.autofile=raw_input('Autopeak filename? (return to ignore) ')
-            if self.autofile=='':
-                print 'Not saved.'
-                return
-        
-        if not os.path.exists(self.autofile):
-            f=open(self.autofile,'w+')
-            f.write('Analysis started '+time.asctime()+'\n')
-            f.write('----------------------------------------\n')
-            f.write('; Contour length (nm)  ;  Persistence length (nm) ;  Max.Force (pN)  ;  Slope (N/m) \n')
-            f.close()
-            
-        print 'Saving...'
-        f=open(self.autofile,'a+')
-        
-        f.write(self.current.path+'\n')
-        for i in range(len(c_lengths)):
-            f.write(' ; '+str(c_lengths[i])+' ; '+str(p_lengths[i])+' ; '+str(forces[i])+' ; '+str(slopes[i])+'\n')
-            
-        f.close()
-        self.do_note('autopeak')
-        '''
\ No newline at end of file