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, 6 months ago) by clausted
File size: 13605 byte(s)
Log Message:
Add readbiosensor() and writebiosensor() capabilities to io_module.  
Line User Rev File contents
1 clausted 7 """
2     io: Input/Output module for converting files to Biosensor Array class.
3 clausted 9 Christopher Lausted, Institute for Systems Biology, OSPRAI developers
4     Last modified on 100409 (yymmdd)
5 clausted 7
6     Examples:
7     #import io_module as io
8     #ba1 = io.readsprit("spritdata.txt")
9     #ba1 = io.readclamp("spritdata.txt")
10 clausted 9 #ba1 = io.readicmtxt("icmdata.txt")
11     #ba1 = io.readbiosensor("icmdata.txt")
12 clausted 7 #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 clausted 9 __version__ = "100409"
19 clausted 7
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 clausted 9 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 clausted 7 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 #################################