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