5 Processed plots plugin for force curves.
7 Licensed under the GNU GPL version 2
9 from libhooke import WX_GOOD
11 wxversion.select(WX_GOOD)
14 import libhookecurve as lhc
20 class procplotsCommands:
25 def do_derivplot(self,args):
29 Plots the derivate (actually, the discrete differentiation) of the current force curve
33 dplot=self.derivplot_curves()
34 plot_graph=self.list_of_events['plot_graph']
35 wx.PostEvent(self.frame,plot_graph(plots=[dplot]))
37 def derivplot_curves(self):
39 do_derivplot helper function
41 create derivate plot curves for force curves.
43 dplot=lhc.PlotObject()
46 for vector in self.plots[0].vectors:
47 dplot.vectors.append([])
48 dplot.vectors[-1].append(vector[0][:-1])
49 dplot.vectors[-1].append(np.diff(vector[1]))
52 dplot.units=self.plots[0].units
56 def do_subtplot(self,args):
60 Plots the difference between ret and ext current curve
64 #FIXME: sub_filter and sub_order must be args
66 if len(self.plots[0].vectors) != 2:
67 print 'This command only works on a curve with two different plots.'
70 outplot=self.subtract_curves(sub_order=1)
72 plot_graph=self.list_of_events['plot_graph']
73 wx.PostEvent(self.frame,plot_graph(plots=[outplot]))
75 def subtract_curves(self, sub_order):
77 subtracts the extension from the retraction
79 xext=self.plots[0].vectors[0][0]
80 yext=self.plots[0].vectors[0][1]
81 xret=self.plots[0].vectors[1][0]
82 yret=self.plots[0].vectors[1][1]
84 #we want the same number of points
85 maxpoints_tot=min(len(xext),len(xret))
86 xext=xext[0:maxpoints_tot]
87 yext=yext[0:maxpoints_tot]
88 xret=xret[0:maxpoints_tot]
89 yret=yret[0:maxpoints_tot]
92 ydiff=[yretval-yextval for yretval,yextval in zip(yret,yext)]
93 else: #reverse subtraction (not sure it's useful, but...)
94 ydiff=[yextval-yretval for yextval,yretval in zip(yext,yret)]
96 outplot=copy.deepcopy(self.plots[0])
97 outplot.vectors[0][0], outplot.vectors[1][0] = xext,xret #FIXME: if I use xret, it is not correct!
98 outplot.vectors[1][1]=ydiff
99 outplot.vectors[0][1]=[0 for item in outplot.vectors[1][0]]
104 #-----PLOT MANIPULATORS
105 def plotmanip_median(self, plot, current, customvalue=None):
107 does the median of the y values of a plot
110 median_filter=customvalue
112 median_filter=self.config['medfilt']
117 if float(median_filter)/2 == int(median_filter)/2:
120 nplots=len(plot.vectors)
123 plot.vectors[c][1]=scipy.signal.medfilt(plot.vectors[c][1],median_filter)
129 def plotmanip_correct(self, plot, current, customvalue=None):
131 does the correction for the deflection for a force spectroscopy curve.
133 - the current plot has a deflection() method that returns a vector of values
134 - the deflection() vector is as long as the X of extension + the X of retraction
135 - plot.vectors[0][0] is the X of extension curve
136 - plot.vectors[1][0] is the X of retraction curve
138 FIXME: both this method and the picoforce driver have to be updated, deflection() must return
139 a more senseful data structure!
141 #use only for force spectroscopy experiments!
142 if current.curve.experiment != 'smfs':
145 if customvalue != None:
146 execute_me=customvalue
148 execute_me=self.config['correct']
152 defl_ext,defl_ret=current.curve.deflection()
153 #halflen=len(deflall)/2
155 plot.vectors[0][0]=[(zpoint-deflpoint) for zpoint,deflpoint in zip(plot.vectors[0][0],defl_ext)]
156 plot.vectors[1][0]=[(zpoint-deflpoint) for zpoint,deflpoint in zip(plot.vectors[1][0],defl_ret)]
161 def plotmanip_detriggerize(self, plot, current, customvalue=None):
163 if self.config['detrigger']==0:
167 startvalue=plot.vectors[0][0][0]
169 for index in range(len(plot.vectors[0][0])-1,2,-2):
170 if plot.vectors[0][0][index]>startvalue:
175 plot.vectors[0][0]=plot.vectors[0][0][:cutindex]
176 plot.vectors[0][1]=plot.vectors[0][1][:cutindex]
183 #FFT---------------------------
184 def fft_plot(self, vector):
186 calculates the fast Fourier transform for the selected vector in the plot
188 fftplot=lhc.PlotObject()
191 fftlen=len(vector)/2 #need just 1/2 of length
192 fftplot.vectors[-1].append(np.arange(1,fftlen).tolist())
195 fftplot.vectors[-1].append(abs(np.fft(vector)[1:fftlen]).tolist())
196 except TypeError: #we take care of newer NumPy (1.0.x)
197 fftplot.vectors[-1].append(abs(np.fft.fft(vector)[1:fftlen]).tolist())
200 fftplot.destination=1
206 def do_fft(self,args):
209 (procplots.py plugin)
210 Plots the fast Fourier transform of the selected plot
212 Syntax: fft [top,bottom] [select] [0,1...]
214 By default, fft performs the Fourier transform on all the 0-th data set on the
217 [top,bottom]: which plot is the data set to fft (default: top)
218 [select]: you pick up two points on the plot and fft only the segment between
219 [0,1,...]: which data set on the selected plot you want to fft (default: 0)
223 #whatplot = plot to fft
224 #whatset = set to fft in the plot
225 select=('select' in args)
228 elif 'bottom' in args:
240 points=self._measure_N_points(N=2, whatset=whatset)
241 boundaries=[points[0].index, points[1].index]
243 y_to_fft=self.plots[whatplot].vectors[whatset][1][boundaries[0]:boundaries[1]] #y
245 y_to_fft=self.plots[whatplot].vectors[whatset][1] #y
247 fftplot=self.fft_plot(y_to_fft)
248 fftplot.units=['frequency', 'power']
249 plot_graph=self.list_of_events['plot_graph']
250 wx.PostEvent(self.frame,plot_graph(plots=[fftplot]))