3 """Processed plots plugin for force curves.
6 from ..libhooke import WX_GOOD
8 wxversion.select(WX_GOOD)
16 from .. import curve as lhc
19 class procplotsCommands(object):
24 def do_derivplot(self,args):
28 Plots the derivate (actually, the discrete differentiation) of the current force curve
32 dplot=self.derivplot_curves()
33 plot_graph=self.list_of_events['plot_graph']
34 wx.PostEvent(self.frame,plot_graph(plots=[dplot]))
36 def derivplot_curves(self):
38 do_derivplot helper function
40 create derivate plot curves for force curves.
42 dplot=lhc.PlotObject()
45 for vector in self.plots[0].vectors:
46 dplot.vectors.append([])
47 dplot.vectors[-1].append(vector[0][:-1])
48 dplot.vectors[-1].append(np.diff(vector[1]))
51 dplot.units=self.plots[0].units
55 def do_subtplot(self, args):
59 Plots the difference between ret and ext current curve
63 #FIXME: sub_filter and sub_order must be args
65 if len(self.plots[0].vectors) != 2:
66 print 'This command only works on a curve with two different plots.'
69 outplot=self.subtract_curves(sub_order=1)
71 plot_graph=self.list_of_events['plot_graph']
72 wx.PostEvent(self.frame,plot_graph(plots=[outplot]))
74 def subtract_curves(self, sub_order):
76 subtracts the extension from the retraction
78 xext=self.plots[0].vectors[0][0]
79 yext=self.plots[0].vectors[0][1]
80 xret=self.plots[0].vectors[1][0]
81 yret=self.plots[0].vectors[1][1]
83 #we want the same number of points
84 maxpoints_tot=min(len(xext),len(xret))
85 xext=xext[0:maxpoints_tot]
86 yext=yext[0:maxpoints_tot]
87 xret=xret[0:maxpoints_tot]
88 yret=yret[0:maxpoints_tot]
91 ydiff=[yretval-yextval for yretval,yextval in zip(yret,yext)]
92 else: #reverse subtraction (not sure it's useful, but...)
93 ydiff=[yextval-yretval for yextval,yretval in zip(yext,yret)]
95 outplot=copy.deepcopy(self.plots[0])
96 outplot.vectors[0][0], outplot.vectors[1][0] = xext,xret #FIXME: if I use xret, it is not correct!
97 outplot.vectors[1][1]=ydiff
98 outplot.vectors[0][1]=[0 for item in outplot.vectors[1][0]]
103 #-----PLOT MANIPULATORS
104 def plotmanip_median(self, plot, current, customvalue=None):
106 does the median of the y values of a plot
109 median_filter=customvalue
111 median_filter=self.config['medfilt']
116 if float(median_filter)/2 == int(median_filter)/2:
119 nplots=len(plot.vectors)
122 plot.vectors[c][1]=scipy.signal.medfilt(plot.vectors[c][1],median_filter)
128 def plotmanip_correct(self, plot, current, customvalue=None):
130 does the correction for the deflection for a force spectroscopy curve.
132 - the current plot has a deflection() method that returns a vector of values
133 - the deflection() vector is as long as the X of extension + the X of retraction
134 - plot.vectors[0][0] is the X of extension curve
135 - plot.vectors[1][0] is the X of retraction curve
137 FIXME: both this method and the picoforce driver have to be updated, deflection() must return
138 a more senseful data structure!
140 #use only for force spectroscopy experiments!
141 if current.curve.experiment != 'smfs':
144 if customvalue != None:
145 execute_me=customvalue
147 execute_me=self.config['correct']
151 defl_ext,defl_ret=current.curve.deflection()
152 #halflen=len(deflall)/2
154 plot.vectors[0][0]=[(zpoint-deflpoint) for zpoint,deflpoint in zip(plot.vectors[0][0],defl_ext)]
155 plot.vectors[1][0]=[(zpoint-deflpoint) for zpoint,deflpoint in zip(plot.vectors[1][0],defl_ret)]
160 def plotmanip_centerzero(self, plot, current, customvalue=None):
162 Centers the force curve so the median (the free level) corresponds to 0 N
164 - plot.vectors[0][1] is the Y of extension curve
165 - plot.vectors[1][1] is the Y of retraction curve
169 #use only for force spectroscopy experiments!
170 if current.curve.experiment != 'smfs':
173 if customvalue != None:
174 execute_me=customvalue
176 execute_me=self.config['centerzero']
182 #levelapp=float(np.median(plot.vectors[0][1]))
183 levelret=float(np.median(plot.vectors[1][1][-300:-1]))
187 approach=[i-level for i in plot.vectors[0][1]]
188 retract=[i-level for i in plot.vectors[1][1]]
190 plot.vectors[0][1]=approach
191 plot.vectors[1][1]=retract
195 def plotmanip_detriggerize(self, plot, current, customvalue=None):
197 if self.config['detrigger']==0:
201 startvalue=plot.vectors[0][0][0]
203 for index in range(len(plot.vectors[0][0])-1,2,-2):
204 if plot.vectors[0][0][index]>startvalue:
209 plot.vectors[0][0]=plot.vectors[0][0][:cutindex]
210 plot.vectors[0][1]=plot.vectors[0][1][:cutindex]
217 #FFT---------------------------
218 def fft_plot(self, vector):
220 calculates the fast Fourier transform for the selected vector in the plot
222 fftplot=lhc.PlotObject()
225 fftlen=len(vector)/2 #need just 1/2 of length
226 fftplot.vectors[-1].append(np.arange(1,fftlen).tolist())
229 fftplot.vectors[-1].append(abs(np.fft(vector)[1:fftlen]).tolist())
230 except TypeError: #we take care of newer NumPy (1.0.x)
231 fftplot.vectors[-1].append(abs(np.fft.fft(vector)[1:fftlen]).tolist())
234 fftplot.destination=1
240 def do_fft(self,args):
243 (procplots.py plugin)
244 Plots the fast Fourier transform of the selected plot
246 Syntax: fft [top,bottom] [select] [0,1...]
248 By default, fft performs the Fourier transform on all the 0-th data set on the
251 [top,bottom]: which plot is the data set to fft (default: top)
252 [select]: you pick up two points on the plot and fft only the segment between
253 [0,1,...]: which data set on the selected plot you want to fft (default: 0)
257 #whatplot = plot to fft
258 #whatset = set to fft in the plot
259 select=('select' in args)
262 elif 'bottom' in args:
274 points=self._measure_N_points(N=2, whatset=whatset)
275 boundaries=[points[0].index, points[1].index]
277 y_to_fft=self.plots[whatplot].vectors[whatset][1][boundaries[0]:boundaries[1]] #y
279 y_to_fft=self.plots[whatplot].vectors[whatset][1] #y
281 fftplot=self.fft_plot(y_to_fft)
282 fftplot.units=['frequency', 'power']
283 plot_graph=self.list_of_events['plot_graph']
284 wx.PostEvent(self.frame,plot_graph(plots=[fftplot]))