Added illysam branch
[hooke.git] / drivers / hemingclamp.py
1 #!/usr/bin/env python
2
3 '''
4 hemingclamp.py
5
6 Library for interpreting Hemingway force spectroscopy files.
7
8 Copyright 2008 by Massimo Sandal, Marco Brucale (University of Bologna, Italy)
9 with modifications by Dr. Rolf Schmidt (Concordia University, Canada)
10
11 This program is released under the GNU General Public License version 2.
12 '''
13
14 __version__='2007_02_15_devel'
15
16 __changelog__='''
17 2010_01_22: initial release for Hooke GUI
18 2007_02_15: fixed time counter with my counter
19 2007_02_07: initial implementation
20 '''
21
22 import copy
23 import os.path
24 import string
25
26 import lib.curve
27 import lib.driver
28 import lib.plot
29
30 class DataChunk(list):
31     #TODO: something similar is also used in jpk.py
32     #potential for OOP/inheritance?
33     '''
34     Dummy class to provide ext and ret methods to the data list.
35     In this case ext and self can be equal.
36     '''
37
38     def ext(self):
39         return self
40
41     def ret(self):
42         return self
43
44 class hemingclampDriver(lib.driver.Driver):
45
46     def __init__(self, filename):
47
48         self.filedata = open(filename,'r')
49         self.data = self.filedata.readlines()[6:]
50         self.filedata.close()
51
52         self.filetype = 'hemingclamp'
53         self.experiment = 'clamp'
54
55         self.filename=filename
56
57     def __del__(self):
58         self.filedata.close()
59
60     def _getdata_all(self):
61         time = []
62         phase = []
63         zpiezo = []
64         defl = []
65         imposed = []
66         trim_indexes = []
67         trim_counter = 0.0
68
69         for i in self.data:
70             temp = string.split(i)
71             #time.append(float(temp[0])*(1.0e-3)) # This is managed differently now, since each data point = 1ms: see below
72             phase.append(float(temp[1])*(1.0e-7)) # The nonsensical (e-7) multiplier is just there to make phase data nicely plottable along other data
73             zpiezo.append(float(temp[2])*(1.0e-9))
74             defl.append(float(temp[3])*(1.0e-9))
75             imposed.append(float(temp[4])*(1.0e-9))
76
77         for x in range (0,len(phase)):
78             if phase[x] != trim_counter:
79                 trim_indexes.append(x)
80                 trim_counter = phase[x]
81
82         #we rebuild the time counter assuming 1 point = 1 millisecond
83         c=0.0
84         for z in zpiezo:
85             time.append(c)
86             c+=(1.0e-3)
87
88         return time,phase,zpiezo,defl,imposed,trim_indexes
89
90     def close_all(self):
91         '''
92         Explicitly closes all files
93         '''
94         self.filedata.close()
95
96     def default_plots(self):
97         time=self.time()
98         phase=self.phase()
99         zpiezo=self.zpiezo()
100         deflection=self.deflection()
101         imposed=self.imposed()
102
103         #return [main_plot, defl_plot]
104         main_extension = lib.curve.Curve()
105         main_retraction = lib.curve.Curve()
106
107         #TODO: check 'title' below
108         main_extension.color = 'red'
109         main_extension.label = 'extension'
110         main_extension.style = 'plot'
111         main_extension.title = 'Force curve'
112         main_extension.units.x = 's'
113         main_extension.units.y = 'm'
114         main_extension.x = time
115         main_extension.y = zpiezo
116         main_retraction.color = 'blue'
117         main_retraction.label = 'retraction'
118         main_retraction.style = 'plot'
119         main_retraction.title = 'Force curve'
120         main_retraction.units.x = 's'
121         #TODO: what is the real unit for y?
122         main_retraction.units.y = 'degree'
123         main_retraction.x = time
124         main_retraction.y = phase
125
126         deflection_extension = copy.deepcopy(main_extension)
127         deflection_retraction = copy.deepcopy(main_retraction)
128         #TODO: check 'title' below
129         deflection_extension.destination.row = 2
130         deflection_extension.units.y = 'N'
131         deflection_extension.y = deflection
132         #TODO: what is the real unit for y?
133         deflection_retraction.destination.row = 2
134         deflection_retraction.units.y = 'N'
135         deflection_retraction.y = imposed
136
137         plot = lib.plot.Plot()
138         plot.title = os.path.basename(self.filename)
139         plot.curves.append(main_extension)
140         plot.curves.append(main_retraction)
141         plot.curves.append(deflection_extension)
142         plot.curves.append(deflection_retraction)
143
144         plot.normalize()
145         return plot
146
147     def deflection(self):
148         return DataChunk(self._getdata_all()[3])
149
150     def imposed(self):
151         return DataChunk(self._getdata_all()[4])
152
153     def is_me(self):
154         '''
155         we define our magic heuristic for HemingClamp files
156         '''
157         myfile=file(self.filename)
158         headerlines=myfile.readlines()[0:3]
159         myfile.close()
160         if headerlines[0][0:10]=='#Hemingway' and headerlines[1][0:19]=='#Experiment: FClamp':
161             return True
162         else:
163             return False
164
165     def phase(self):
166         return DataChunk(self._getdata_all()[1])
167
168     def time(self):
169         return DataChunk(self._getdata_all()[0])
170
171     def trimindexes(self):
172         return DataChunk(self._getdata_all()[5])
173
174     def zpiezo(self):
175         return DataChunk(self._getdata_all()[2])