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, 2 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 User Rev File contents
1 clausted 7 """
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 #################################