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