1 # Copyright (C) 2008-2010 Massimo Sandal <devicerandom@gmail.com>
2 # W. Trevor King <wking@drexel.edu>
4 # This file is part of Hooke.
6 # Hooke is free software: you can redistribute it and/or
7 # modify it under the terms of the GNU Lesser General Public
8 # License as published by the Free Software Foundation, either
9 # version 3 of the License, or (at your option) any later version.
11 # Hooke is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU Lesser General Public License for more details.
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with Hooke. If not, see
18 # <http://www.gnu.org/licenses/>.
21 from .. import curve as lhc
23 class DataChunk(list):
24 #Dummy class to provide ext and ret methods to the data list.
28 return self[0:halflen]
34 class jpkDriver(lhc.Driver):
36 def __init__(self, filename):
37 self.filename=filename #self.filename can always be useful, and should be defined
38 self.filedata = open(filename,'r') #We open the file
39 self.filelines=self.filedata.readlines()
41 '''These are two strings that can be used by Hooke commands/plugins to understand what they are looking at. They have no other
42 meaning. They have to be somehow defined however - commands often look for those variables.
44 self.filetype should contain the name of the exact filetype defined by the driver (so that filetype-specific commands can know
45 if they're dealing with the correct filetype)
46 self.experiment should contain instead the type of data involved (for example, various drivers can be used for force-clamp experiments,
47 but hooke commands could like to know if we're looking at force clamp data, regardless of their origin, and not other
50 Of course, all other variables you like can be defined in the class.
53 self.experiment = 'smfs'
62 we define our magic heuristic for jpk files
64 myfile=file(self.filename)
65 headerlines=myfile.readlines()[0:3]
67 if headerlines[0][0:11]=='# xPosition' and headerlines[1][0:11]=='# yPosition':
75 def _read_data_segment(self):
76 #routine that actually reads the data
84 self.springconstant=0 #if we don't meet any spring constant, use deflection...
86 for line in self.filelines:
87 #we meet the segment defining the order of data columns
89 if line[0:9]=='# columns':
90 splitline=line.split()[2:]
91 height_ms_index=splitline.index('smoothedStrainGaugeHeight')
92 height_m_index=splitline.index('strainGaugeHeight')
93 height_index=splitline.index('height')
94 v_deflection_index=splitline.index('vDeflection')
95 #h_deflection=splitline.index('hDeflection')
97 if line[0:16]=='# springConstant':
98 self.springconstant=float(line.split()[2])
100 if line[0] != '#' and len(line.split())>1:
101 dataline=line.split()
102 height_ms.append(float(dataline[height_ms_index]))
103 height_m.append(float(dataline[height_m_index]))
104 height.append(float(dataline[height_index]))
105 v_deflection.append(float(dataline[v_deflection_index]))
106 #h_deflection.append(float(dataline[h_deflection_index]))
108 if self.springconstant != 0:
109 force=[item*self.springconstant for item in v_deflection]
110 else: #we have measured no spring constant :(
113 height_ms=DataChunk([item*-1 for item in height_ms])
114 height_m=DataChunk([item*-1 for item in height_m])
115 height=DataChunk([item*-1 for item in height])
116 deflection=DataChunk(v_deflection)
117 force=DataChunk(force)
119 return height_ms,height_m,height,deflection,force
121 def deflection(self):
122 height_ms,height_m,height,deflection,force=self._read_data_segment()
123 deflection_ext=deflection.ext()
124 deflection_ret=deflection.ret()
125 deflection_ret.reverse()
126 return deflection_ext,deflection_ret
128 def default_plots(self):
130 height_ms,height_m,height,deflection,force=self._read_data_segment()
132 height_ms_ext=height_ms.ext()
133 height_ms_ret=height_ms.ret()
134 force_ext=force.ext()
135 force_ret=force.ret()
136 #reverse the return data, to make it coherent with hooke standard
137 height_ms_ret.reverse()
140 main_plot=lhc.PlotObject()
141 main_plot.add_set(height_ms_ext,force_ext)
142 main_plot.add_set(height_ms_ret,force_ret)
146 if self.springconstant != 0:
147 main_plot.units=['meters','force']
149 main_plot.units=['meters','meters']
151 main_plot.normalize_vectors()
153 main_plot.destination=0
154 main_plot.title=self.filename