added first (still to debug) version of pcluster
[hooke.git] / pcluster.py
1 #!/usr/bin/env python
2
3 from libhooke import WX_GOOD, ClickedPoint
4 import wxversion
5 wxversion.select(WX_GOOD)
6 from wx import PostEvent
7 import numpy as np
8 import scipy as sp
9 import copy
10 import os.path
11 import time
12
13 import warnings
14 warnings.simplefilter('ignore',np.RankWarning)
15
16
17 class pclusterCommands:
18
19                 def do_pcluster(self,args):
20                                 '''
21                                 pCLUSTER
22                                 (pcluster.py)
23                                 '''
24                                 
25                                 #configuration variables
26                                 min_npks = 5
27                                 min_deviation = 5
28                                 
29                                 # ------ FUNCTION ------
30                                 def fit_interval_nm(start_index,plot,nm,backwards):
31                                                 '''
32                                                 Calculates the number of points to fit, given a fit interval in nm
33                                                 start_index: index of point
34                                                 plot: plot to use
35                                                 backwards: if true, finds a point backwards.
36                                                 '''
37                                                 whatset=1 #FIXME: should be decidable
38                                                 x_vect=plot.vectors[1][0]
39                                                 
40                                                 c=0
41                                                 i=start_index
42                                                 start=x_vect[start_index]
43                                                 maxlen=len(x_vect)
44                                                 while abs(x_vect[i]-x_vect[start_index])*(10**9) < nm:
45                                                                 if i==0 or i==maxlen-1: #we reached boundaries of vector!
46                                                                                 return c
47                                                                 if backwards:
48                                                                                 i-=1
49                                                                 else:
50                                                                                 i+=1
51                                                                 c+=1
52                                                 return c
53                                 
54                                 def plot_informations(itplot):
55                                                 '''
56                                                 OUR VARIABLES
57                                                 contact_point.absolute_coords           (2.4584142802103689e-007, -6.9647135616234017e-009)
58                                                 peak_point.absolute_coords                      (3.6047748250571423e-008, -7.7142802788854212e-009)
59                                                 other_fit_point.absolute_coords (4.1666139243838867e-008, -7.3759393477579707e-009)
60                                                 peak_location                                                                           [510, 610, 703, 810, 915, 1103]
61                                                 peak_size                                                                                               [-1.2729111505202212e-009, -9.1632775347399312e-010, -8.1707438353929907e-010, -8.0335812578148904e-010, -8.7483955226387558e-010, -3.6269619757067322e-009]
62                                                 params                                                                                                  [2.2433999931959462e-007, 3.3230248825175678e-010]
63                                                 fit_errors                                                                                      [6.5817195369767644e-010, 2.4415923138871498e-011]
64                                                 '''
65                                                 fit_points=int(self.config['auto_fit_points']) # number of points to fit before the peak maximum <50>
66                                                 pl_value=None # persistent length <None>
67                                                 T=self.config['temperature'] #temperature of the system in kelvins. By default it is 293 K. <301.0>
68                                                 cindex=self.find_contact_point() #Automatically find contact point <158, libhooke.ClickedPoint>
69                                                 contact_point=self._clickize(itplot[0].vectors[1][0], itplot[0].vectors[1][1], cindex)
70                                                 self.basepoints=[]
71                                                 base_index_0=peak_location[-1]+fit_interval_nm(peak_location[-1], itplot[0], self.config['auto_right_baseline'],False)
72                                                 self.basepoints.append(self._clickize(itplot[0].vectors[1][0],itplot[0].vectors[1][1],base_index_0))
73                                                 base_index_1=self.basepoints[0].index+fit_interval_nm(self.basepoints[0].index, itplot[0], self.config['auto_left_baseline'],False)
74                                                 self.basepoints.append(self._clickize(itplot[0].vectors[1][0],itplot[0].vectors[1][1],base_index_1))
75                                                 self.basecurrent=self.current.path
76                                                 boundaries=[self.basepoints[0].index, self.basepoints[1].index]
77                                                 boundaries.sort()
78                                                 to_average=itplot[0].vectors[1][1][boundaries[0]:boundaries[1]] #y points to average
79                                                 avg=np.mean(to_average)
80                                                 return fit_points, contact_point, pl_value, T, cindex, avg
81                                                 
82                                 def features_peaks(itplot, peak, fit_points, contact_point, pl_value, T, cindex, avg):
83                                                 '''
84                                                 calculate informations for each peak and add they in 
85                                                 c_lengths, p_lengths, sigma_c_lengths, sigma_p_lengths, forces, slopes
86                                                 '''
87                                                 c_leng=None
88                                                 p_leng=None
89                                                 sigma_c_leng=None
90                                                 sigma_p_leng=None
91                                                 force=None
92                                                 slope=None
93                                                 
94                                                 delta_force=10
95                                                 slope_span=int(self.config['auto_slope_span'])
96                                                 
97                                                 peak_point=self._clickize(itplot[0].vectors[1][0],itplot[0].vectors[1][1],peak)
98                                                 other_fit_point=self._clickize(itplot[0].vectors[1][0],itplot[0].vectors[1][1],peak-fit_points)
99                                                 
100                                                 points=[contact_point, peak_point, other_fit_point]
101                                                 
102                                                 params, yfit, xfit, fit_errors = self.wlc_fit(points, itplot[0].vectors[1][0], itplot[0].vectors[1][1], pl_value, T, return_errors=True)
103                                                 
104                                                 #Measure forces
105                                                 delta_to_measure=itplot[0].vectors[1][1][peak-delta_force:peak+delta_force]
106                                                 y=min(delta_to_measure)
107                                                 #Measure slopes
108                                                 slope=self.linefit_between(peak-slope_span,peak)[0]
109                                                 #check fitted data and, if right, add peak to the measurement
110                                                 if len(params)==1: #if we did choose 1-value fit
111                                                                 p_leng=pl_value
112                                                                 c_leng=params[0]*(1.0e+9)
113                                                                 sigma_p_lengths=0
114                                                                 sigma_c_lengths=fit_errors[0]*(1.0e+9)
115                                                                 force = abs(y-avg)*(1.0e+12)
116                                                 else: #2-value fit
117                                                                 p_leng=params[1]*(1.0e+9)
118                                                                 #check if persistent length makes sense. otherwise, discard peak.
119                                                                 if p_leng>self.config['auto_min_p'] and p_leng<self.config['auto_max_p']:
120                                                                                 '''
121                                                                                 p_lengths.append(p_leng)       
122                                                                                 c_lengths.append(params[0]*(1.0e+9))
123                                                                                 sigma_c_lengths.append(fit_errors[0]*(1.0e+9))
124                                                                                 sigma_p_lengths.append(fit_errors[1]*(1.0e+9))
125                                                                                 forces.append(abs(y-avg)*(1.0e+12))
126                                                                                 slopes.append(slope)     
127                                                                                 '''
128                                                                                 c_leng=params[0]*(1.0e+9)
129                                                                                 sigma_c_leng=fit_errors[0]*(1.0e+9)
130                                                                                 sigma_p_leng=fit_errors[1]*(1.0e+9)
131                                                                                 force=abs(y-avg)*(1.0e+12)
132                                                                                 
133                                                                 else:
134                                                                                 p_leng=None
135                                                                                 slope=None
136                                                 #return c_lengths, p_lengths, sigma_c_lengths, sigma_p_lengths, forces, slopes
137                                                 return  c_leng, p_leng, sigma_c_leng, sigma_p_leng, force, slope
138
139                                 
140                                 # ------ PROGRAM -------
141                                 c=0
142                                 for item in self.current_list:
143                                                 c+=1
144                                                 item.identify(self.drivers)
145                                                 itplot=item.curve.default_plots()
146                                                 peak_location,peak_size=self.exec_has_peaks(item,min_deviation)
147                                                 fit_points, contact_point, pl_value, T, cindex, avg = plot_informations(itplot)
148                                                 print '\n\nCurve',item.path, 'is',c,'of',len(self.current_list),': found '+str(len(peak_location))+' peaks.'
149                                                 
150                                                 #initialize output data vectors
151                                                 c_lengths=[]
152                                                 p_lengths=[]
153                                                 sigma_c_lengths=[]
154                                                 sigma_p_lengths=[]
155                                                 forces=[]
156                                                 slopes=[]
157                                                 
158                                                 #loop each peak of my curve
159                                                 for peak in peak_location:
160                                                     c_leng, p_leng, sigma_c_leng, sigma_p_leng, force, slope = features_peaks(itplot, peak, fit_points, contact_point, pl_value, T, cindex, avg)
161                                                     for var, vector in zip([c_leng, p_leng, sigma_c_leng, sigma_p_leng, force, slope],[c_lengths, p_lengths, sigma_c_lengths, sigma_p_lengths, forces, slopes]):
162                                                         if var is not None:
163                                                             vector.append(var)
164                                                     
165                                                     '''
166                                                     c_lengths.append(c_leng)
167                                                     p_lengths.append(p_leng)
168                                                     sigma_c_lengths.append(sigma_c_leng)
169                                                     sigma_p_lengths.append(sigma_p_leng)
170                                                     forces.append(force)
171                                                     slopes.append(slope)
172                                                     '''
173                                                                                                 
174                                                 print 'Measurements for all peaks detected:'
175                                                 print 'contour (nm)', c_lengths
176                                                 print 'sigma contour (nm)',sigma_c_lengths
177                                                 print 'p (nm)',p_lengths
178                                                 print 'sigma p (nm)',sigma_p_lengths
179                                                 print 'forces (pN)',forces
180                                                 print 'slopes (N/m)',slopes
181                                                                                 
182                                 print ""
183