Merged with trunk
[hooke.git] / hooke / driver / jpk.py
1 import string
2 from .. import libhookecurve as lhc
3
4 class DataChunk(list):
5     #Dummy class to provide ext and ret methods to the data list.
6
7     def ext(self):
8         halflen=(len(self)/2)
9         return self[0:halflen]
10
11     def ret(self):
12         halflen=(len(self)/2)
13         return self[halflen:]
14
15 class jpkDriver(lhc.Driver):
16
17     def __init__(self, filename):
18         self.filename=filename #self.filename can always be useful, and should be defined
19         self.filedata = open(filename,'r') #We open the file
20         self.filelines=self.filedata.readlines()
21         self.filedata.close()
22         '''These are two strings that can be used by Hooke commands/plugins to understand what they are looking at. They have no other
23         meaning. They have to be somehow defined however - commands often look for those variables.
24
25         self.filetype should contain the name of the exact filetype defined by the driver (so that filetype-specific commands can know
26                       if they're dealing with the correct filetype)
27         self.experiment should contain instead the type of data involved (for example, various drivers can be used for force-clamp experiments,
28                       but hooke commands could like to know if we're looking at force clamp data, regardless of their origin, and not other
29                       kinds of data)
30
31         Of course, all other variables you like can be defined in the class.
32         '''
33         self.filetype = 'jpk'
34         self.experiment = 'smfs'
35
36
37
38     def __del__(self):
39         self.filedata.close()
40
41     def is_me(self):
42         '''
43         we define our magic heuristic for jpk files
44         '''
45         myfile=file(self.filename)
46         headerlines=myfile.readlines()[0:3]
47         myfile.close()
48         if headerlines[0][0:11]=='# xPosition' and headerlines[1][0:11]=='# yPosition':
49             return True
50         else:
51             return False
52
53     def close_all(self):
54         self.filedata.close()
55
56     def _read_data_segment(self):
57         #routine that actually reads the data
58
59         height_ms=[]
60         height_m=[]
61         height=[]
62         v_deflection=[]
63         h_deflection=[]
64
65         self.springconstant=0 #if we don't meet any spring constant, use deflection...
66
67         for line in self.filelines:
68             #we meet the segment defining the order of data columns
69
70             if line[0:9]=='# columns':
71                 splitline=line.split()[2:]
72                 height_ms_index=splitline.index('smoothedStrainGaugeHeight')
73                 height_m_index=splitline.index('strainGaugeHeight')
74                 height_index=splitline.index('height')
75                 v_deflection_index=splitline.index('vDeflection')
76                 #h_deflection=splitline.index('hDeflection')
77
78             if line[0:16]=='# springConstant':
79                 self.springconstant=float(line.split()[2])
80
81             if line[0] != '#' and len(line.split())>1:
82                 dataline=line.split()
83                 height_ms.append(float(dataline[height_ms_index]))
84                 height_m.append(float(dataline[height_m_index]))
85                 height.append(float(dataline[height_index]))
86                 v_deflection.append(float(dataline[v_deflection_index]))
87                 #h_deflection.append(float(dataline[h_deflection_index]))
88
89         if self.springconstant != 0:
90             force=[item*self.springconstant for item in v_deflection]
91         else: #we have measured no spring constant :(
92             force=v_deflection
93
94         height_ms=DataChunk([item*-1 for item in height_ms])
95         height_m=DataChunk([item*-1 for item in height_m])
96         height=DataChunk([item*-1 for item in height])
97         deflection=DataChunk(v_deflection)
98         force=DataChunk(force)
99
100         return height_ms,height_m,height,deflection,force
101
102     def deflection(self):
103         height_ms,height_m,height,deflection,force=self._read_data_segment()
104         deflection_ext=deflection.ext()
105         deflection_ret=deflection.ret()
106         deflection_ret.reverse()
107         return deflection_ext,deflection_ret
108
109     def default_plots(self):
110
111         height_ms,height_m,height,deflection,force=self._read_data_segment()
112
113         height_ms_ext=height_ms.ext()
114         height_ms_ret=height_ms.ret()
115         force_ext=force.ext()
116         force_ret=force.ret()
117         #reverse the return data, to make it coherent with hooke standard
118         height_ms_ret.reverse()
119         force_ret.reverse()
120
121         main_plot=lhc.PlotObject()
122         main_plot.add_set(height_ms_ext,force_ext)
123         main_plot.add_set(height_ms_ret,force_ret)
124
125
126
127         if self.springconstant != 0:
128             main_plot.units=['meters','force']
129         else:
130             main_plot.units=['meters','meters']
131
132         main_plot.normalize_vectors()
133
134         main_plot.destination=0
135         main_plot.title=self.filename
136
137         return [main_plot]