3 Processed plots plugin for force curves.
5 Licensed under the GNU GPL version 2
7 from libhooke import WX_GOOD
9 wxversion.select(WX_GOOD)
12 import libhookecurve as lhc
18 class procplotsCommands:
23 def do_derivplot(self,args):
27 Plots the derivate (actually, the discrete differentiation) of the current force curve
31 dplot=self.derivplot_curves()
32 plot_graph=self.list_of_events['plot_graph']
33 wx.PostEvent(self.frame,plot_graph(plots=[dplot]))
35 def derivplot_curves(self):
37 do_derivplot helper function
39 create derivate plot curves for force curves.
41 dplot=lhc.PlotObject()
44 for vector in self.plots[0].vectors:
45 dplot.vectors.append([])
46 dplot.vectors[-1].append(vector[0][:-1])
47 dplot.vectors[-1].append(np.diff(vector[1]))
50 dplot.units=self.plots[0].units
54 def do_subtplot(self,args):
58 Plots the difference between ret and ext current curve
62 #FIXME: sub_filter and sub_order must be args
64 if len(self.plots[0].vectors) != 2:
65 print 'This command only works on a curve with two different plots.'
68 outplot=self.subtract_curves(sub_order=1)
70 plot_graph=self.list_of_events['plot_graph']
71 wx.PostEvent(self.frame,plot_graph(plots=[outplot]))
73 def subtract_curves(self, sub_order):
75 subtracts the extension from the retraction
77 xext=self.plots[0].vectors[0][0]
78 yext=self.plots[0].vectors[0][1]
79 xret=self.plots[0].vectors[1][0]
80 yret=self.plots[0].vectors[1][1]
82 #we want the same number of points
83 maxpoints_tot=min(len(xext),len(xret))
84 xext=xext[0:maxpoints_tot]
85 yext=yext[0:maxpoints_tot]
86 xret=xret[0:maxpoints_tot]
87 yret=yret[0:maxpoints_tot]
90 ydiff=[yretval-yextval for yretval,yextval in zip(yret,yext)]
91 else: #reverse subtraction (not sure it's useful, but...)
92 ydiff=[yextval-yretval for yextval,yretval in zip(yext,yret)]
94 outplot=copy.deepcopy(self.plots[0])
95 outplot.vectors[0][0], outplot.vectors[1][0] = xext,xret #FIXME: if I use xret, it is not correct!
96 outplot.vectors[1][1]=ydiff
97 outplot.vectors[0][1]=[0 for item in outplot.vectors[1][0]]
102 #-----PLOT MANIPULATORS
103 def plotmanip_median(self, plot, current, customvalue=None):
105 does the median of the y values of a plot
108 median_filter=customvalue
110 median_filter=self.config['medfilt']
115 if float(median_filter)/2 == int(median_filter)/2:
118 nplots=len(plot.vectors)
121 plot.vectors[c][1]=scipy.signal.medfilt(plot.vectors[c][1],median_filter)
127 def plotmanip_correct(self, plot, current, customvalue=None):
129 does the correction for the deflection for a force spectroscopy curve.
131 - the current plot has a deflection() method that returns a vector of values
132 - the deflection() vector is as long as the X of extension + the X of retraction
133 - plot.vectors[0][0] is the X of extension curve
134 - plot.vectors[1][0] is the X of retraction curve
136 FIXME: both this method and the picoforce driver have to be updated, deflection() must return
137 a more senseful data structure!
139 #use only for force spectroscopy experiments!
140 if current.curve.experiment != 'smfs':
143 if customvalue != None:
144 execute_me=customvalue
146 execute_me=self.config['correct']
150 defl_ext,defl_ret=current.curve.deflection()
151 #halflen=len(deflall)/2
153 plot.vectors[0][0]=[(zpoint-deflpoint) for zpoint,deflpoint in zip(plot.vectors[0][0],defl_ext)]
154 plot.vectors[1][0]=[(zpoint-deflpoint) for zpoint,deflpoint in zip(plot.vectors[1][0],defl_ret)]
159 def plotmanip_detriggerize(self, plot, current, customvalue=None):
161 if self.config['detrigger']==0:
165 startvalue=plot.vectors[0][0][0]
167 for index in range(len(plot.vectors[0][0])-1,2,-2):
168 if plot.vectors[0][0][index]>startvalue:
173 plot.vectors[0][0]=plot.vectors[0][0][:cutindex]
174 plot.vectors[0][1]=plot.vectors[0][1][:cutindex]
181 #FFT---------------------------
182 def fft_plot(self, vector):
184 calculates the fast Fourier transform for the selected vector in the plot
186 fftplot=lhc.PlotObject()
189 fftlen=len(vector)/2 #need just 1/2 of length
190 fftplot.vectors[-1].append(np.arange(1,fftlen).tolist())
193 fftplot.vectors[-1].append(abs(np.fft(vector)[1:fftlen]).tolist())
194 except TypeError: #we take care of newer NumPy (1.0.x)
195 fftplot.vectors[-1].append(abs(np.fft.fft(vector)[1:fftlen]).tolist())
198 fftplot.destination=1
204 def do_fft(self,args):
207 (procplots.py plugin)
208 Plots the fast Fourier transform of the selected plot
210 Syntax: fft [top,bottom] [select] [0,1...]
212 By default, fft performs the Fourier transform on all the 0-th data set on the
215 [top,bottom]: which plot is the data set to fft (default: top)
216 [select]: you pick up two points on the plot and fft only the segment between
217 [0,1,...]: which data set on the selected plot you want to fft (default: 0)
221 #whatplot = plot to fft
222 #whatset = set to fft in the plot
223 select=('select' in args)
226 elif 'bottom' in args:
238 points=self._measure_N_points(N=2, whatset=whatset)
239 boundaries=[points[0].index, points[1].index]
241 y_to_fft=self.plots[whatplot].vectors[whatset][1][boundaries[0]:boundaries[1]] #y
243 y_to_fft=self.plots[whatplot].vectors[whatset][1] #y
245 fftplot=self.fft_plot(y_to_fft)
246 fftplot.units=['frequency', 'power']
247 plot_graph=self.list_of_events['plot_graph']
248 wx.PostEvent(self.frame,plot_graph(plots=[fftplot]))