6 Export commands for Hooke.
8 Copyright 2010 by Dr. Rolf Schmidt (Concordia University, Canada)
10 This program is released under the GNU General Public License version 2.
13 import lib.libhooke as lh
15 wxversion.select(lh.WX_GOOD)
22 class exportCommands(object):
24 Export force curves, fits and results in different formats
30 def do_fits(self):#, ext='', folder='', prefix='', separator=''):
32 Exports all approach and retraction files in a playlist and
33 all fitting results (if available) in a columnar ASCII format.
34 Please make sure that the number of points in the fit is smaller
35 or equal to the number of points in the approach/retraction.
36 For the time being, exports only one set of results (e.g. WLC
40 ext = self.GetStringFromConfig('export', 'fits', 'ext')
41 folder = self.GetStringFromConfig('export', 'fits', 'folder')
42 prefix = self.GetStringFromConfig('export', 'fits', 'prefix')
43 separator = self.GetStringFromConfig('export', 'fits', 'separator')
44 #TODO: add list for Tab, Space, Comma, Other
47 active_file = self.GetActiveFile()
48 plot = self.GetDisplayedPlot()
50 #TODO: fix for multiple results
51 #add empty columns before adding new results if necessary
53 for results_str, results in plot.results.items():
54 for curve in results.results:
58 header_str += curve.label + '_x (' + curve.units.x + ')' + separator + curve.label + '_y (' + curve.units.y + ')'
59 output.append(header_str)
60 for index, row in enumerate(curve.x):
61 output.append(separator.join([str(curve.x[index]), str(curve.y[index])]))
63 #TODO: add option to replace or add the new file extension
64 #add option to rename file from default.000 to default_000
65 filename = os.path.basename(active_file.filename)
66 filename = ''.join([prefix, filename, '_', curve.label, '.', ext])
67 filename = os.path.join(folder, filename)
68 output_file = open(filename, 'w')
69 output_file.write('\n'.join(output))
72 def do_force_curve(self):
75 Saves the current curve as a text file
76 Columns are, in order:
77 X1 , Y1 , X2 , Y2 , X3 , Y3 ...
80 Syntax: txt [filename] {plot to export}
83 ext = self.GetStringFromConfig('export', 'force_curve', 'ext')
84 folder = self.GetStringFromConfig('export', 'force_curve', 'folder')
85 prefix = self.GetStringFromConfig('export', 'force_curve', 'prefix')
86 separator = self.GetStringFromConfig('export', 'force_curve', 'separator')
87 #TODO: add list for Tab, Space, Comma, Other
90 active_file = self.GetActiveFile()
91 plot = self.GetActivePlot()
92 extension = plot.curves[lh.EXTENSION]
93 retraction = plot.curves[lh.RETRACTION]
97 for index, curve in enumerate(plot.curves):
98 header_str += curve.label + '_x (' + curve.units.x + ')' + separator + curve.label + '_y (' + curve.units.y + ')'
99 if index < len(plot.curves) - 1:
100 header_str += separator
101 output.append(header_str)
103 for index, row in enumerate(extension.x):
104 output.append(separator.join([str(extension.x[index]), str(extension.y[index]), str(retraction.x[index]), str(retraction.y[index])]))
107 #TODO: add option to replace or add the new file extension
108 #add option to rename file from default.000 to default_000
109 filename = os.path.basename(active_file.filename)
110 filename = ''.join([prefix, filename, '.', ext])
111 filename = os.path.join(folder, filename)
112 output_file = open(filename, 'w')
113 output_file.write('\n'.join(output))
116 def do_overlay(self):
118 Exports all retraction files in a playlist with the same scale.
119 The files can then be overlaid in a graphing program to see which
120 ones have the same shape.
121 Use this export command only on filtered lists as it takes a long time
122 to complete even with a small number of curves.
124 playlist = self.GetActivePlaylist()
126 filename_prefix = self.GetStringFromConfig('export', 'overlay', 'prefix')
130 number_of_curves = playlist.count
131 message_str = ''.join([str(number_of_curves), ' files to load.\n\n'])
132 progress_dialog = wx.ProgressDialog('Loading', message_str, maximum=number_of_curves, parent=self, style=wx.PD_APP_MODAL|wx.PD_SMOOTH|wx.PD_AUTO_HIDE)
133 for index, current_file in enumerate(playlist.files):
134 current_file.identify(self.drivers)
135 plot = current_file.plot
137 plot.raw_curves = copy.deepcopy(plot.curves)
138 #apply all active plotmanipulators and add the 'manipulated' data
139 for plotmanipulator in self.plotmanipulators:
140 if self.GetBoolFromConfig('core', 'plotmanipulators', plotmanipulator.name):
141 plot = plotmanipulator.method(plot, current_file)
142 #add corrected curves to plot
143 plot.corrected_curves = copy.deepcopy(plot.curves)
145 curve = current_file.plot.corrected_curves[lh.RETRACTION]
146 differences_x.append(curve.x[0] - curve.x[-1])
147 differences_y.append(curve.x[0] - curve.y[-1])
148 progress_dialog.Update(index, ''.join([message_str, 'Loading ', str(index + 1), '/', str(number_of_curves)]))
149 progress_dialog.Destroy()
151 max_x = max(differences_x)
152 max_y = max(differences_y)
153 message_str = ''.join([str(number_of_curves), ' files to export.\n\n'])
154 for index, current_file in enumerate(playlist.files):
155 curve = current_file.plot.corrected_curves[lh.RETRACTION]
158 new_x = [x - first_x for x in curve.x]
159 new_y = [y - first_y for y in curve.y]
163 for row_index, row in enumerate(new_x):
164 output_str += ''.join([str(new_x[row_index]), ', ', str(new_y[row_index]), '\n'])
167 filename = ''.join([filename_prefix, current_file.name])
168 filename = current_file.filename.replace(current_file.name, filename)
169 output_file = open(filename, 'w')
170 output_file.write(output_str)
172 progress_dialog.Destroy()
174 def do_results(self, filename='', separator=''):
177 Exports all visible fit results in a playlist into a delimited text file
180 filename = self.GetStringFromConfig('export', 'results', 'filename')
182 separator = self.GetStringFromConfig('export', 'results', 'separator')
184 playlist = self.GetActivePlaylist()
187 for current_file in playlist.files:
188 if len(current_file.plot.results) > 0:
189 for key in current_file.plot.results.keys():
190 #if there are different types of fit results in the playlist, the header might have to change
191 #here, we generate a temporary header and compare it to the current header
192 #if they are different, the tempeorary header is used
193 #we get the header from the fit and add the 'filename' column
194 temporary_header_str = ''.join([current_file.plot.results[key].get_header_as_str(), separator, 'Filename'])
195 if temporary_header_str != header_str:
196 header_str = ''.join([current_file.plot.results[key].get_header_as_str(), separator, 'Filename'])
197 output_str = ''.join([output_str, header_str, '\n'])
198 for index, result in enumerate(current_file.plot.results[key].results):
200 #similar to above, we get the result from the fit and add the filename
201 line_str = current_file.plot.results[key].get_result_as_string(index)
202 line_str = ''.join([line_str, separator, current_file.filename])
203 output_str = ''.join([output_str, line_str, '\n'])
205 output_str = ''.join(['Analysis started ', time.asctime(), '\n', output_str])
206 output_file = open(filename, 'w')
207 output_file.write(output_str)
210 dialog = wx.MessageDialog(None, 'No results found, file not saved.', 'Info', wx.OK)