'''
GENERALCLAMP.py
-(c) 2008 Marco Brucale, Massimo Sandal
-
Plugin regarding general force clamp measurements
'''
from libhooke import WX_GOOD, ClickedPoint
-import wxversion
+import wxversion\r
import libhookecurve as lhc
wxversion.select(WX_GOOD)
-from wx import PostEvent
-
-class generalclampCommands:
+from wx import PostEvent\r
+class generalclampCommands:\r
+\r
def plotmanip_clamp(self, plot, current, customvalue=False):
'''
- Handles some viewing options for the "force clamp" data format, depending on the state of these configuration variables:
- (1) If self.config['fc_showphase'] != 0, the 'phase' data column (i.e. the 2nd) is shown in the 0th graph (else it isn't)
- (2) If self.config['fc_showimposed'] != 0, the 'imposed deflection' data column (i.e. the 5th) is shown in the 1st graph (else it isn't)
+ Handles some viewing options for the "force clamp" data format, depending on the state of these configuration variables:\r
+ (1) If self.config['fc_showphase'] != 0, the 'phase' data column (i.e. the 2nd) is shown in the 0th graph (else it isn't)\r
+ (2) If self.config['fc_showimposed'] != 0, the 'imposed deflection' data column (i.e. the 5th) is shown in the 1st graph (else it isn't)\r
(3) If self.config['fc_interesting'] == 0, the entire curve is shown in the graphs; if it has a non-zero value N, only phase N is shown.
-
- NOTE - my implementation of point(3) feels quite awkward - someone smarter than me plz polish that!
-
+\r
+ NOTE - my implementation of point(3) feels quite awkward - someone smarter than me plz polish that!\r
+\r
'''
#not a fclamp curve...
if current.curve.experiment != 'clamp':
- return plot
-
- if self.config['fc_interesting'] != 0 and plot.destination==0:
- lower = int((self.config['fc_interesting'])-1)
- upper = int((self.config['fc_interesting'])+1)
- trim = current.curve.trimindexes()[lower:upper]
- newtime = []
- newzpiezo = []
- newphase = []
- for x in range(trim[0],trim[1]):
- newtime.append(self.plots[0].vectors[0][0][x])
- newzpiezo.append(self.plots[0].vectors[0][1][x])
- newphase.append(self.plots[0].vectors[1][1][x])
- self.plots[0].vectors[0][0] = newtime
- self.plots[0].vectors[0][1] = newzpiezo
- self.plots[0].vectors[1][0] = newtime
- self.plots[0].vectors[1][1] = newphase
-
- if self.config['fc_interesting'] != 0 and plot.destination==1:
- lower = int((self.config['fc_interesting'])-1)
- upper = int((self.config['fc_interesting'])+1)
- trim = current.curve.trimindexes()[lower:upper]
- newtime = []
- newdefl = []
- newimposed = []
- for x in range(trim[0],trim[1]):
- newtime.append(self.plots[1].vectors[0][0][x])
- newdefl.append(self.plots[1].vectors[0][1][x])
- newimposed.append(self.plots[1].vectors[1][1][x])
- self.plots[1].vectors[0][0] = newtime
- self.plots[1].vectors[0][1] = newdefl
- self.plots[1].vectors[1][0] = newtime
- self.plots[1].vectors[1][1] = newimposed
-
- if self.config['fc_showphase'] == 0 and plot.destination==0:
- self.plots[0].remove_set(1)
-
- if self.config['fc_showimposed'] == 0 and plot.destination==1:
- self.plots[1].remove_set(1)
-
+ return plot\r
+\r
+ if self.config['fc_interesting'] != 0 and plot.destination==0:\r
+ lower = int((self.config['fc_interesting'])-1)\r
+ upper = int((self.config['fc_interesting'])+1)\r
+ trim = current.curve.trimindexes()[lower:upper]\r
+ newtime = []\r
+ newzpiezo = []\r
+ newphase = []\r
+ for x in range(trim[0],trim[1]):\r
+ newtime.append(self.plots[0].vectors[0][0][x])\r
+ newzpiezo.append(self.plots[0].vectors[0][1][x])\r
+ newphase.append(self.plots[0].vectors[1][1][x])\r
+ self.plots[0].vectors[0][0] = newtime\r
+ self.plots[0].vectors[0][1] = newzpiezo\r
+ self.plots[0].vectors[1][0] = newtime\r
+ self.plots[0].vectors[1][1] = newphase\r
+\r
+ if self.config['fc_interesting'] != 0 and plot.destination==1:\r
+ lower = int((self.config['fc_interesting'])-1)\r
+ upper = int((self.config['fc_interesting'])+1)\r
+ trim = current.curve.trimindexes()[lower:upper]\r
+ newtime = []\r
+ newdefl = []\r
+ newimposed = []\r
+ for x in range(trim[0],trim[1]):\r
+ newtime.append(self.plots[1].vectors[0][0][x])\r
+ newdefl.append(self.plots[1].vectors[0][1][x])\r
+ newimposed.append(self.plots[1].vectors[1][1][x])\r
+ self.plots[1].vectors[0][0] = newtime\r
+ self.plots[1].vectors[0][1] = newdefl\r
+ self.plots[1].vectors[1][0] = newtime\r
+ self.plots[1].vectors[1][1] = newimposed \r
+ \r
+ if self.config['fc_showphase'] == 0 and plot.destination==0:\r
+ self.plots[0].remove_set(1)\r
+ \r
+ if self.config['fc_showimposed'] == 0 and plot.destination==1:\r
+ self.plots[1].remove_set(1)\r
+ \r
return plot
def do_time(self,args):
'''
- TIME
- Measure the time difference (in seconds) between two points
+ Measures the time difference (in seconds) between two points
Implemented only for force clamp
----
Syntax: time
'''
- if self.current.curve.experiment == 'clamp':
- print 'Click two points.'
- time=self._delta(set=0)[0]
+ if self.current.curve.experiment == 'clamp':\r
+ time=self._delta(set=0)[0]\r
print str(time*1000)+' ms'
else:
print 'This command makes no sense for a non-force clamp experiment.'
def do_zpiezo(self,args):
'''
- ZPIEZO
- Measure the zpiezo difference (in nm) between two points
+ Measures the zpiezo difference (in nm) between two points
Implemented only for force clamp
----
Syntax: zpiezo
'''
if self.current.curve.experiment == 'clamp':
- print 'Click two points.'
- points=self._measure_N_points(N=2)
- zpiezo=abs(points[0].graph_coords[1]-points[1].graph_coords[1])
+ zpiezo=self._delta(set=0)[2]\r
print str(zpiezo*(10**9))+' nm'
- to_dump='zpiezo '+self.current.path+' '+str(zpiezo*(10**9))+' nm'
- self.outlet.push(to_dump)
else:
print 'This command makes no sense for a non-force clamp experiment.'
def do_defl(self,args):
'''
- DEFL
- Measure the deflection difference (in nm) between two points
+ Measures the deflection difference (in nm) between two points
Implemented only for force clamp
NOTE: It makes sense only on the time VS defl plot; it is still not masked for the other plot...
-----
Syntax: defl
'''
if self.current.curve.experiment == 'clamp':
- print 'Click two points.'
- points=self._measure_N_points(N=2)
- defl=abs(points[0].graph_coords[1]-points[1].graph_coords[1])
+ print "Warning - don't use on the zpiezo plot!"
+ defl=self._delta(set=1)[2]
print str(defl*(10**12))+' pN'
- to_dump='deflection '+self.current.path+' '+str(defl*(10**12))+' pN'
- self.outlet.push(to_dump)
else:
print 'This command makes no sense for a non-force clamp experiment.'
def do_step(self,args):
'''
- STEP
-
Measures the length and time duration of a time-Z step
-----
Syntax: step
dt=abs(points[1].graph_coords[0]-points[0].graph_coords[0])
print 'dZ: ',dz,' nm'
print 'dT: ',dt,' s'
- to_dump='step '+self.current.path+' '+'dZ: '+str(dz)+' nm'+' dT: '+str(dt)+' s'
- self.outlet.push(to_dump)
else:
- print 'This command makes no sense for a non-force clamp experiment.'
\ No newline at end of file
+ print 'This command makes no sense for a non-force clamp experiment.'\r
+\r
+ def do_fcfilt(self,args):\r
+ '''\r
+ Filters out featureless force clamp curves of the current playlist.\r
+ It's very similar to 'flatfilt' for velocity clamp curves.\r
+ Creates a new playlist only containing non-empty curves.\r
+\r
+ WARNING - Only works if you set an appropriate fc_interesting config variable!\r
+ WARNING - arguments are NOT optional at the moment!\r
+\r
+ Syntax: fcfilt maxretraction(nm) mindeviation (pN)\r
+\r
+ Suggested values for an (i27)8 experiment with our setup are 200nm and 10-15 pN\r
+ '''\r
+\r
+ if self.config['fc_interesting'] == 0:\r
+ print 'You must specify the phase of interest (using set fc_interesing X) prior to running fcfilt!'\r
+ return\r
+ \r
+ maxretraction=0\r
+ threshold=0\r
+ args=args.split(' ')\r
+ if len(args)==2:\r
+ maxretraction=int(args[0])\r
+ threshold=int(args[1])\r
+ else:\r
+ print 'Arguments are not optional for fcfilt. You should pass two numbers:'\r
+ print '(1) the maximum plausible piezo retraction in NANOMETERS (e.g. the length of the protein)'\r
+ print "(2) the threshold, in PICONEWTONS. If signal deviates from imposed more than this, it's an event"\r
+ return\r
+ \r
+\r
+ print 'Processing playlist... go get yourself a cup of coffee.'\r
+ notflat_list=[]\r
+\r
+ c=0\r
+\r
+ for item in self.current_list:\r
+ c+=1\r
+ try:\r
+ notflat=self.has_stuff(item,maxretraction,threshold)\r
+ print 'Curve',item.path,'is',c,'of',len(self.current_list),'--->Has Stuff =',notflat\r
+ except:\r
+ notflat=False\r
+ print 'Curve',item.path,'is',c,'of',len(self.current_list),'--->could not be processed'\r
+ if notflat:\r
+ item.features=notflat\r
+ item.curve=None\r
+ notflat_list.append(item)\r
+\r
+ if len(notflat_list)==0:\r
+ print 'Nothing interesting here. Reconsider either your filtering criteria or your experimental data'\r
+ return\r
+ else:\r
+ print 'Found',len(notflat_list),'potentially interesting curves.'\r
+ print 'Regenerating Playlist...'\r
+ self.pointer=0\r
+ self.current_list=notflat_list\r
+ self.current=self.current_list[self.pointer]\r
+ self.do_plot(0)\r
+\r
+ def has_stuff(self,item,maxretraction,threshold):\r
+ '''\r
+ Decides whether a curve has some features in the interesting phase.\r
+ Algorithm:\r
+ - clip the interesting phase portion of the curve.\r
+ - discard the first 20 milliseconds (this is due to a quirk of our hardware).\r
+ - look at the zpiezo plot and note down when (if) retratcs more than [maxretraction] nm away from the first point.\r
+ - clip off any data after this point, with an excess of 100 points (again, an hardware quirk)\r
+ - if the remainder is less than 100 points, ditch the curve.\r
+ - now look at the deflection plot and check if there are points more than [threshold] pN over the 'flat zone'.\r
+ - if you find such points, bingo! \r
+ '''\r
+\r
+ item.identify(self.drivers)\r
+ \r
+ lower = int((self.config['fc_interesting'])-1)\r
+ upper = int((self.config['fc_interesting'])+1)\r
+ trim_idxs = item.curve.trimindexes()[lower:upper]\r
+ lo=trim_idxs[0]+20 #clipping the first 20 points off...\r
+ hi=trim_idxs[1]\r
+ trimmed_zpiezo=item.curve.default_plots()[0].vectors[0][1][lo:hi]\r
+ trimmed_defl=item.curve.default_plots()[1].vectors[0][1][lo:hi]\r
+ trimmed_imposed=item.curve.default_plots()[1].vectors[1][1][lo:hi]\r
+ imposed=trimmed_imposed[21] #just to match the 20-pts clipping...\r
+ \r
+ item.curve.close_all()\r
+ del item.curve\r
+ del item\r
+\r
+ starting_z=trimmed_zpiezo[0]\r
+ plausible=starting_z-(maxretraction*1e-9)\r
+ det_trim=0\r
+ while trimmed_zpiezo[det_trim]>plausible:\r
+ det_trim+=1\r
+ if det_trim >= len(trimmed_zpiezo): #breaking cycles makes me shiver...\r
+ det_trim=len(trimmed_zpiezo) #but I cannot think of anything better now.\r
+ break\r
+ further_trim=det_trim-100\r
+ if further_trim<100:\r
+ return False\r
+ trimmed_defl=trimmed_defl[:further_trim]\r
+\r
+ trimmed_defl.sort()\r
+ ninetypercent=int(0.9*len(trimmed_defl))\r
+ j=0\r
+ sum=0\r
+ for j in trimmed_defl[:ninetypercent]:\r
+ sum+=j\r
+ avg=float(sum/ninetypercent)\r
+ sweetspot=float(avg+(threshold*1e-12))\r
+ if trimmed_defl[-1]>sweetspot:\r
+ flag=True\r
+ else:\r
+ flag=False\r
+\r
+ return flag \r
+
\ No newline at end of file