ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/osprai/osprai/trunk/io_module.py
Revision: 7
Committed: Fri Apr 9 17:11:42 2010 UTC (9 years, 6 months ago) by clausted
File size: 10567 byte(s)
Log Message:
Initial addition of ba_class, an alternative to SPRdataclass.  This class, ba or Biosensor Array, has one internal structure rather than different internal structures depending on whether SPRit or Biacore or other data was imported.  This makes the code smaller and more readable.  It provides default values, usually 0 or null text, that make it easier to import and export different file formats.  We also add io_module to provide import and export features.  We also add test.py as a convenience for testing and demonstration.
Line File contents
1 """
2 io: Input/Output module for converting files to Biosensor Array class.
3 Christopher Lausted, Institute for Systems Biology
4 Last modified on 100408 (yymmdd)
5
6 Examples:
7 #import io_module as io
8 #ba1 = io.readsprit("spritdata.txt")
9 #ba1 = io.readclamp("spritdata.txt")
10 #ba2 = io.applygal(ba1, "galfile.gal")
11 #ba2 = io.applykey(ba1, "keyfile.tsv")
12 #ba3 = io.applymethod(ba2, "icmmethod.xls")
13 #io.writesprit(ba3, "newspritfile.txt")
14 #io.writeclamp(ba3, "newclampfile.txt")
15 """
16 __version__ = "100408"
17
18 ## Import libraries.
19 from copy import deepcopy
20 from os import getcwd
21 from time import mktime
22 import numpy as np ## Numpy array library.
23 import ba_class as ba ## Our Biosensor Array class.
24 reload(ba)
25
26 def readsprit(fname):
27 """
28 Read a SPRit text file into a ba class.
29 It has two tab-delimited columns and two header lines.
30 Here is a very simple example with 2 rois and 3 datapoints:
31
32 Elapsed Time (Seconds) Average Intensity (Pixel Intensity)
33 BEGIN
34 0.000000e+000 2.863145e+003
35 5.013000e+000 2.863367e+003
36 1.002500e+001 2.862950e+003
37 0.000000e+000 2.862875e+003
38 5.013000e+000 2.862510e+003
39 """
40
41 ## Try to open file. Return tiny ba object if it fails.
42 ba0 = ba.BiosensorArray(1,1)
43 try:
44 fp = open(fname, "r")
45 except IOError:
46 print 'Error: Cannot open file %s for reading' % fname
47 return ba0
48
49 ## Check header lines for signature text.
50 txt = fp.readline() # 'Elapsed Time...'
51 txt = fp.readline() # 'BEGIN'
52 if ('BEGIN' not in txt):
53 print "Error: Second line is not BEGIN."
54 fp.close()
55 return ba0
56
57 ## Put data into one big text string and close.
58 txtfile = fp.readlines()
59 fp.close()
60
61 ## Change text into array
62 sprtable = np.zeros((len(txtfile),2), dtype=float) ## Redimension Nx2
63 for i in range(len(txtfile)):
64 txt = txtfile[i].split('\t')
65 sprtable[i,0] = float(txt[0]) ## Time column.
66 sprtable[i,1] = float(txt[1]) ## Signal column.
67
68 ## Find number of ROIs in file.
69 for i in range(1,len(sprtable)):
70 ## See when the time drops back to zero.
71 if (sprtable[i,0] < sprtable[i-1,0]): break
72 rows = i ## Datapoints or new array rows.
73 rois = int(len(sprtable) / rows)
74
75 ## Move data the old-fashioned iterative way.
76 ba0 = ba.BiosensorArray(rois,rows)
77 k = 0
78 for i in range(rois):
79 for j in range(rows):
80 ba0.roi[i].time[j] = sprtable[k,0]
81 ba0.roi[i].value[j] = sprtable[k,1]
82 k +=1
83
84 return ba0
85 ## End of readsprit() function
86
87
88 def writesprit(ba0, fname):
89 """Write a ba class to a SPRit text file."""
90 fp=file(fname,'w')
91 fp.write("Elapsed Time (Seconds)\tAverage Intensity (Pixel Intensity)\r\n")
92 fp.write("BEGIN\r\n")
93 for roi in range(len(ba0.roi)): ## Could also use ba.rois.
94 for dpoint in range(len(ba0.roi[0].time)): ## Could also use ba.dpoints.
95 txt = "%f\t%f\r\n" % (ba0.roi[roi].time[dpoint], ba0.roi[roi].value[dpoint])
96 fp.write(txt)
97 fp.close
98 print "File %s saved in %s." % (fname, getcwd())
99 ## End of writesprit() function
100
101
102 def readclamp(fname):
103 """
104 Read a Clamp text file into a ba class.
105 It has two tab-delimited columns per SPR flowcell/roi..
106 It has a varying number of header lines with injection information.
107 Here is a very simple example with 2 rois and 3 datapoints:
108
109 Vers 3.41 Data
110 Conc1 0 0 0 0
111 Start1 301.5 301.5 301.5 301.5
112 Stop1 949.8 949.8 949.8 949.8
113 RInd1 0 0 0 0
114 Conc2 0 0 0 0
115 Start2 986.4 0 0 0
116 Stop2 1626 0 0 0
117 RInd2 0 0 0 0
118 Flow 1 1 1 1
119 Time1 Data1 Time2 Data2
120 0.094 0.062 0.094 0.053
121 1.094 0.026 1.094 0.05
122 2.094 0.119 2.094 0.055
123 """
124
125 print "This feature is under construction."
126 ## End of readclamp() function
127
128
129 def writeclamp(ba0, fname):
130 """Write a ba class to a Clamp text file."""
131
132 fp=file(fname,'w')
133 ## First header line.
134 fp.write("Vers 3.41 Data\r\n")
135
136 ## Next write injection information.
137 for inj in range(len(ba0.roi[0].injconc)):
138 fp.write("Conc%i" % (inj+1))
139 for roi in ba0.roi: fp.write("\t%.3f" % roi.injconc[inj])
140 fp.write("\r\nStart%i" % (inj+1))
141 for roi in ba0.roi: fp.write("\t%.3f" % roi.injstart[inj])
142 fp.write("\r\nStop%i" % (inj+1))
143 for roi in ba0.roi: fp.write("\t%.3f" % roi.injstop[inj])
144 fp.write("\r\nRInd%i" % (inj+1))
145 for roi in ba0.roi: fp.write("\t%.3f" % roi.injrind[inj])
146 ## Next write flowrate line.
147 fp.write("\r\nFlow")
148 for roi in ba0.roi: fp.write("\t%.3f" % roi.flow)
149 fp.write("\r\n")
150
151 ## Write sensorgram data header line.
152 for i,roi in enumerate(ba0.roi):
153 if (i>0): fp.write("\t")
154 fp.write("Time%i" % (i+1))
155 fp.write("\t")
156 fp.write(roi.name)
157 fp.write("\r\n")
158 ## Write sensorgram data lines. Three decimal places.
159 for dpoint in range(len(ba0.roi[0].time)):
160 for i,roi in enumerate(ba0.roi):
161 if (i>0): fp.write("\t")
162 fp.write("%.3f\t%.3f" % (roi.time[dpoint], roi.value[dpoint]))
163 fp.write("\r\n")
164
165 ## Close file handle and print message.
166 fp.close
167 print "File %s saved in %s." % (fname, getcwd())
168 ## End of writeclamp() function
169
170
171 def readicmtxt(fname):
172 """
173 Read a ICM text file into a ba class.
174 Here is a very simple example of the tab-delimited format:
175
176 03/05/2010 13:37:21.312 249.408 0.000 0.000
177 03/05/2010 13:37:22.312 249.306 0.000 0.000
178 """
179
180 ## Try to open file. Return tiny ba object if it fails.
181 ba0 = ba.BiosensorArray(1,1)
182 try:
183 fp = open(fname, "r")
184 except IOError:
185 print 'Error: Cannot open file %s for reading' % fname
186 return ba0
187
188 ## Put data into one big text string and close.
189 txtfile = fp.readlines()
190 fp.close()
191 dpoints = len(txtfile)
192 rois = txtfile[0].count("\t") ## Usually 25.
193
194 ## Create and size ba object.
195 print "This ICM file has %i datapoints for %i ROIs." % (dpoints, rois)
196 ba0 = ba.BiosensorArray(rois, dpoints)
197
198 ## Determine experiment start time so we can make other times relative.
199 x = txtfile[0].split("\t") ## E.g. "03/05/2010 13:37:20.218"
200 t0 = icmtime2sec(x[0]) ## E.g. 1267825040.22
201
202 ## Move the data from txtfile to ba0.
203 for i, txtline in enumerate(txtfile):
204 x = txtline.split("\t")
205 tx = icmtime2sec(x[0]) - t0
206 for j in range(1,rois):
207 ba0.roi[j].time[i] = tx
208 ba0.roi[j].value[i] = float(x[j])
209
210 return ba0
211 ## End of readicmtxt
212
213
214 def icmtime2sec(timetxt):
215 """
216 Take a time of the form "03/05/2010 15:19:27.312" and return seconds.
217 """
218 cal, clock = timetxt.split(" ")
219 mm, dd, yy = cal.split("/")
220 hh, min, ss = clock.split(":")
221 stime = (int(yy), int(mm), int(dd), int(hh), int(min), 0, 0, 0, 0)
222 return mktime(stime) + float(ss)
223
224
225 def applygal(ba0, fname):
226 """Read a Gal file and apply its microarray information."""
227 print "This feature is under construction."
228 ## End of applygal() function
229
230
231 def applykey(ba0, fname):
232 """
233 Read a Key file and apply its microarray information.
234 Multiple background ROIs are not yet supported.
235 Here is a very simple example :
236
237 No. Description1 Description2 Background ROI Col Row
238 1 Rat TNF Antibody01 2 1 1
239 2 ratIgG Antibody02 4 2 1
240 3 Hum TNF Antibody03 4 3 1
241 4 humIgG Antibody04 2 4 1
242 """
243
244 ## Try to open file. Return unchanged ba object if it fails.
245 try:
246 fp = open(fname, "r")
247 except IOError:
248 print 'Cannot open file %s for reading' % fname
249 return ba0
250 ## Check header lines for signature text.
251 txt = fp.readline()
252 if ("No." not in txt):
253 print "Error: The header line is unfamiliar."
254 fp.close()
255 return ba0
256
257 ## Read all text, convert to 2d list, then six lists (one for each column).
258 ## There's probably an easier way to do this. Maybe in CSV module.
259 txtfile = fp.readlines()
260 fp.close()
261 ## Change text into array
262 keytable = txtfile[:] ## Dimension rows in new 2d list.
263 for i in range(len(txtfile)):
264 txt = str(txtfile[i].strip())
265 keytable[i] = txt.split('\t')
266 ## Use list comprehensions to get one list for each column.
267 id = [int(x[0]) for x in keytable] ## First column is integer.
268 desc1 = [x[1] for x in keytable] ## Second column is text.
269 desc2 = [x[2] for x in keytable] ## Third column is text.
270 bg = [int(x[3]) for x in keytable] ## Fourth column is integer.
271 col = [int(x[4]) for x in keytable] ## Fifth column is integer.
272 row = [int(x[5]) for x in keytable] ## Sixth column is integer.
273
274 ## Check if key file looks valid. These tests are not very thorough!
275 keys = 1 + max(id) - min(id)
276 if (ba0.rois != keys):
277 print "Error: We have %i ROIs but %i keyfile entries." % (ba0.rois, keys)
278 return ba0
279 if ((min(bg) < min(id)) or (max(bg) > max (id))):
280 print "Error: a specified background ROI does not exist"
281 return ba0
282
283 ## Create new object and put data in it.
284 ba1 = deepcopy(ba0)
285 for i in range(len(id)):
286 ba1.roi[id[i]-1].name = desc1[i]
287 ba1.roi[id[i]-1].desc = desc2[i]
288 ba1.roi[id[i]-1].bgroi = [bg[i]]
289 ba1.roi[id[i]-1].spotx = col[i]
290 ba1.roi[id[i]-1].spoty = row[i]
291
292 print "Successfully loaded information for %i ROIs." % keys
293 return ba1
294 ## End of applykey() function
295
296
297 def applymethod(ba0, fname):
298 """Read a ICM Analyte/Method xls file and apply its information."""
299 print "This feature is under construction."
300 ## End of applymethod() function
301
302
303 ## Here are a few lines to test this module.
304 if __name__ == '__main__':
305 print "This module isn't a stand-alone app."
306
307 ################################# End of module #################################