ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/osprai/osprai/trunk/io_module.py
Revision: 74
Committed: Mon Aug 20 23:13:37 2012 UTC (7 years, 2 months ago) by clausted
File size: 25027 byte(s)
Log Message:
Utilize Numpy genfromtxt() to simplify readcsv().  Might want to deprecate TsvTable.
Line File contents
1 """
2 io_module
3 ---------
4
5 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
13 Examples::
14
15 > import osprai_one as osp
16 > ba1 = osp.readsprit("spritdata.txt")
17 > ba1 = osp.readclamp("clampdata.txt")
18 > ba1 = osp.readicmtxt("icmdata.txt")
19 > ba1 = io.readbiosensor("biodata.txt")
20 > ba1 = osp.readcsv("rawdata.csv")
21 > ba2 = osp.applygal(ba1, "galfile.gal")
22 > ba2 = osp.applykey(ba1, "keyfile.tsv")
23 > ba3 = osp.applymethod(ba2, "icmmethod.xls")
24 > osp.writesprit(ba3, "newspritfile.txt")
25 > osp.writeclamp(ba3, "newclampfile.txt")
26 """
27 __version__ = "120820"
28
29 ## To do:
30 ## Use more Numpy functions to import data. It can handle strings.
31 ## See <http://docs.scipy.org/doc/numpy/reference/routines.array-creation.html>
32 ## Consider np.tostring, np.fromstring, np.load, np.save, np.loadtxt
33 ## Then I can get rid of TsvTable.
34
35
36 ## Import libraries.
37 from copy import deepcopy
38 from os import getcwd
39 from time import mktime
40 from string import replace
41 import re
42 import csv
43 import StringIO
44 import numpy as np ## Numpy array library.
45 import ba_class as ba ## Our Biosensor Array class.
46 reload(ba)
47
48
49 class TsvTable(object):
50 r"""
51 This class helps to convert between strings and lists.
52 This will help with CSV or TSV file import and export.
53 The string form has data in columns separated by a delimiter.
54 The list form is a list of lists of strings like data[column][row]
55 Best to convert numbers to strings before entering them in table.
56
57 Example:
58
59 >>> tsv = TsvTable(delimiter=',')
60 >>> tsv.read("1,2.2,3a \n 4,5.5,6b")
61 >>> print tsv.d
62 [['1', '4'], ['2.2', '5.5'], ['3a', '6b']]
63 >>> tsv.setcolumn(2, ['3.3', '6.6'])
64 >>> tsv.getcolumn(2)
65 ['3.3', '6.6']
66 >>> print tsv.columns, tsv.rows
67 3 2
68 >>> print tsv.write()
69 1,2.2,3.3
70 4,5.5,6.6
71 """
72
73 def __init__(self, columns=0, rows=0, delimiter='\t'):
74 ## Allocate a table d[columns][rows]
75 self.columns = columns
76 self.rows = rows
77 self.delimiter = delimiter
78 self.d = [['0']*rows for x in xrange(columns)]
79 return
80
81 def read(self, txt):
82 ## First get the dimensions: rows, columns.
83 self.columns, self.rows = 0, 0
84 reader = csv.reader(StringIO.StringIO(txt), delimiter=self.delimiter)
85 for row in reader:
86 self.columns = max(self.columns, len(row))
87 self.rows +=1
88 ## Initialize the table (2D array, a list of lists).
89 self.d = [['0']*self.rows for x in xrange(self.columns)]
90 ## Fill the table with 2D array of strings.
91 ## Size is i columns, j rows. No leading/trailing spaces.
92 reader = csv.reader(StringIO.StringIO(txt), delimiter=self.delimiter)
93 for i,row in enumerate(reader):
94 for j,data in enumerate(row):
95 self.d[j][i] = data.lstrip().rstrip()
96 #print self.d
97 return
98
99 def getcolumn(self, j):
100 ## ToDo: implement error checking.
101 return self.d[j]
102
103 def setcolumn(self, j, data):
104 ## ToDo: implement error checking.
105 self.d[j] = data
106 return
107
108 def write(self):
109 ## Convert table d to text string.
110 txt = ""
111 for i in xrange(self.rows):
112 if (i>0): txt += '\n'
113 ## Use generator and join method to create each line.
114 line = (str(self.d[j][i]) for j in xrange(self.columns))
115 line = self.delimiter.join(line)
116 ## Remove end spaces and concatenate.
117 line = line.lstrip().rstrip()
118 txt += line
119 return txt
120
121 """End of TsvTable() class."""
122
123
124 def readsprit(fname):
125 """
126 Read a SPRit text file into a ba class.
127 It has two tab-delimited columns and two header lines.
128 Here is a very simple example with 2 rois and 3 datapoints::
129
130 Elapsed Time (Seconds) Average Intensity (Pixel Intensity)
131 BEGIN
132 0.000000e+000 2.863145e+003
133 5.013000e+000 2.863367e+003
134 1.002500e+001 2.862950e+003
135 0.000000e+000 2.862875e+003
136 5.013000e+000 2.862510e+003
137
138 Example::
139
140 >>> import osprai_one as osp
141 >>> ba0 = osp.readsprit("./exampledata/example-sprit.txt")
142 Successfully loaded information for 2 ROIs.
143 """
144
145 ## Try to open file. Return tiny ba object if it fails.
146 ba0 = ba.BiosensorArray(1,1)
147 try:
148 fp = open(fname, "r")
149 except IOError:
150 print 'Error: Cannot open file %s for reading' % fname
151 return ba0
152
153 ## Check header lines for signature text.
154 txt = fp.readline() # 'Elapsed Time...'
155 txt = fp.readline() # 'BEGIN'
156 if ('BEGIN' not in txt):
157 print "Error: Second line is not BEGIN."
158 fp.close()
159 return ba0
160
161 ## Put data into one big text string and close.
162 txtfile = fp.readlines()
163 fp.close()
164
165 ## Change text into array
166 sprtable = np.zeros((len(txtfile),2), dtype=float) ## Redimension Nx2
167 for i in range(len(txtfile)):
168 txt = txtfile[i].split('\t')
169 sprtable[i,0] = float(txt[0]) ## Time column.
170 sprtable[i,1] = float(txt[1]) ## Signal column.
171
172 ## Find number of ROIs in file.
173 for i in range(1,len(sprtable)):
174 ## See when the time drops back to zero.
175 if (sprtable[i,0] < sprtable[i-1,0]): break
176 rows = i ## Datapoints or new array rows.
177 rois = int(len(sprtable) / rows)
178
179 ## Move data the old-fashioned iterative way.
180 ba0 = ba.BiosensorArray(rois,rows)
181 k = 0
182 for i in range(rois):
183 for j in range(rows):
184 ba0.roi[i].time[j] = sprtable[k,0]
185 ba0.roi[i].value[j] = sprtable[k,1]
186 k +=1
187
188 print "Successfully loaded information for %d ROIs." % rois
189 return ba0
190 """End of readsprit() function"""
191
192
193 def writesprit(ba0, fname):
194 """
195 Write a ba class to a SPRit text file.
196 """
197 fp=file(fname,'w')
198 fp.write("Elapsed Time (Seconds)\tAverage Intensity (Pixel Intensity)\r\n")
199 fp.write("BEGIN\r\n")
200 for roi in range(len(ba0.roi)): ## Could also use ba.rois.
201 for dpoint in range(len(ba0.roi[0].time)): ## Could also use ba.dpoints.
202 txt = "%f\t%f\r\n" % (ba0.roi[roi].time[dpoint], ba0.roi[roi].value[dpoint])
203 fp.write(txt)
204 fp.close
205 print "File %s saved in %s." % (fname, getcwd())
206 return
207 """End of writesprit() function"""
208
209
210 def readclamp(fname):
211 """
212 Read a Clamp text file into a ba class.
213 It has two tab-delimited columns per SPR flowcell/roi..
214 It has a varying number of header lines with injection information.
215 Here is a very simple example with 2 rois and 3 datapoints::
216
217 Vers 3.41 Data
218 Conc1 0 0 0 0
219 Start1 301.5 301.5 301.5 301.5
220 Stop1 949.8 949.8 949.8 949.8
221 RInd1 0 0 0 0
222 Conc2 0 0 0 0
223 Start2 986.4 0 0 0
224 Stop2 1626 0 0 0
225 RInd2 0 0 0 0
226 Flow 1 1 1 1
227 Time1 Data1 Time2 Data2
228 0.094 0.062 0.094 0.053
229 1.094 0.026 1.094 0.05
230 2.094 0.119 2.094 0.055
231
232 Example::
233
234 >>> import osprai_one as osp
235 >>> ba0 = osp.readclamp("./exampledata/example-clamp.txt")
236 This feature is under construction.
237 """
238
239 print "This feature is under construction."
240 return
241 """"End of readclamp() function"""
242
243
244 def writeclamp(ba0, fname):
245 """
246 Write a ba class to a Clamp text file.
247 """
248
249 fp=file(fname,'w')
250 ## First header line.
251 fp.write("Vers 3.41 Data\r\n")
252
253 ## Next write injection information.
254 for inj in range(len(ba0.roi[0].injconc)):
255 fp.write("Conc%i" % (inj+1))
256 for roi in ba0.roi: fp.write("\t%.3f" % roi.injconc[inj])
257 fp.write("\r\nStart%i" % (inj+1))
258 for roi in ba0.roi: fp.write("\t%.3f" % roi.injstart[inj])
259 fp.write("\r\nStop%i" % (inj+1))
260 for roi in ba0.roi: fp.write("\t%.3f" % roi.injstop[inj])
261 fp.write("\r\nRInd%i" % (inj+1))
262 for roi in ba0.roi: fp.write("\t%.3f" % roi.injrind[inj])
263 ## Next write flowrate line.
264 fp.write("\r\nFlow")
265 for roi in ba0.roi: fp.write("\t%.3f" % roi.flow)
266 fp.write("\r\n")
267
268 ## Write sensorgram data header line.
269 for i,roi in enumerate(ba0.roi):
270 if (i>0): fp.write("\t")
271 fp.write("Time%i" % (i+1))
272 fp.write("\t")
273 fp.write(roi.name)
274 fp.write("\r\n")
275 ## Write sensorgram data lines. Three decimal places.
276 for dpoint in range(len(ba0.roi[0].time)):
277 for i,roi in enumerate(ba0.roi):
278 if (i>0): fp.write("\t")
279 fp.write("%.3f\t%.3f" % (roi.time[dpoint], roi.value[dpoint]))
280 fp.write("\r\n")
281
282 ## Close file handle and print message.
283 fp.close
284 print "File %s saved in %s." % (fname, getcwd())
285 return
286 """End of writeclamp() function"""
287
288
289 def readicmtxt(fname):
290 """
291 Read a ICM text file into a ba class.
292 Here is a very simple example of the tab-delimited format::
293
294 03/05/2010 13:37:21.312 249.408 0.000 0.000
295 03/05/2010 13:37:22.312 249.306 0.000 0.000
296
297 Example::
298
299 >>> import osprai_one as osp
300 >>> ba0 = osp.readicmtxt("./exampledata/example-icm.txt")
301 This ICM file has 6034 datapoints for 25 ROIs.
302 """
303
304 ## Try to open file. Return tiny ba object if it fails.
305 ba0 = ba.BiosensorArray(1,1)
306 try:
307 fp = open(fname, "r")
308 except IOError:
309 print 'Error: Cannot open file %s for reading' % fname
310 return ba0
311
312 ## Put data into one big text string and close.
313 txtfile = fp.readlines()
314 fp.close()
315 dpoints = len(txtfile)
316 rois = txtfile[0].count("\t") ## Usually 25.
317
318 ## Create and size ba object.
319 print "This ICM file has %i datapoints for %i ROIs." % (dpoints, rois)
320 ba0 = ba.BiosensorArray(rois, dpoints)
321
322 ## Determine experiment start time so we can make other times relative.
323 x = txtfile[0].split("\t") ## E.g. "03/05/2010 13:37:20.218"
324 t0 = _icmtime2sec(x[0]) ## E.g. 1267825040.22
325
326 ## Move the data from txtfile to ba0.
327 for i, txtline in enumerate(txtfile):
328 x = txtline.split("\t")
329 tx = _icmtime2sec(x[0]) - t0
330 for j in range(0,rois):
331 ba0.roi[j].time[i] = tx
332 ba0.roi[j].value[i] = float(x[j+1])
333
334 return ba0
335 """End of readicmtxt"""
336
337
338 def _icmtime2sec(timetxt):
339 """
340 Take a time of the form "03/05/2010 15:19:27.312" and return seconds.
341 """
342 cal, clock = timetxt.split(" ")
343 mm, dd, yy = cal.split("/")
344 hh, min, ss = clock.split(":")
345 stime = (int(yy), int(mm), int(dd), int(hh), int(min), 0, 0, 0, 0)
346 return mktime(stime) + float(ss)
347 """End of __icmtime2sec"""
348
349
350 def readbiosensor(fname):
351 """
352 Read a Biacore-style text file into a ba class.
353 Here is a very simple example of the tab-delimited format::
354
355 Ab1 Fc=4- 1_X Ab1 Fc=4 -1_Y Ab2 Fc=4 -1_X Ab2 Fc=4 -1_Y
356 13.1 23.7644 93.1 0.713912
357 13.6 23.4265 93.6 0.0541172
358 14.1 23.1625 94.1 0.332768
359 14.6 23.5752 94.6 0.849459
360
361 Example::
362
363 >>> import osprai_one as osp
364 >>> ba0 = osp.readbiosensor("./exampledata/example-biosensor.txt")
365 This Biosensor file has 9 datapoints for 2 ROIs.
366 """
367
368 ## Try to open file. Return tiny ba object if it fails.
369 ba0 = ba.BiosensorArray(1,1)
370 try:
371 fp = open(fname, "r")
372 except IOError:
373 print 'Error: Cannot open file %s for reading' % fname
374 return ba0
375
376 ## Read header line. Check number of pairs of _X and _Y labels.
377 txthdr = fp.readline()
378 cols = txthdr.count("Fc=")
379 xys = txthdr.count("_X\t") + txthdr.count("_Y\t")+1
380 if ((cols != xys) or ((cols%2) != 0)):
381 print "Error: This is not a valid Biosensor file."
382 return ba0
383
384 ## Put data into one big text string and close.
385 txtfile = fp.readlines()
386 fp.close()
387 dpoints = len(txtfile)
388 rois = int(cols/2)
389
390 ## Create and size ba object.
391 print "This Biosensor file has %i datapoints for %i ROIs." % (dpoints, rois)
392 ba0 = ba.BiosensorArray(rois, dpoints)
393
394 ## Get names of ROIs from header like "Ab1 Fc=4 - 1_Y"
395 txthdr = txthdr.replace(" -","-").replace("- ","-") ## Remove unwanted spaces.
396 names = txthdr.split("\t") ## Use tab delimiter.
397 for j in range(rois):
398 name = names[j*2+1].replace("_Y","").strip(" -")
399 name = name.partition("Fc=") ## Now a 3-tuple.
400 ba0.roi[j].name = name[0] ## Text left of Fc.
401 ba0.roi[j].desc = ("Fc=" + name[2]) ## Text right of Fc.
402
403 ## Move the data from txtfile to ba0.
404 for i, txtline in enumerate(txtfile):
405 x = txtline.split("\t")
406 for j in range(rois):
407 ba0.roi[j].time[i] = float(x[j*2+0])
408 ba0.roi[j].value[i] = float(x[j*2+1])
409
410 return ba0
411 """End of readbiosensor()"""
412
413
414 def writebiosensor(ba0, fname):
415 """
416 Write a ba class to a Biosensor text file.
417 """
418
419 ## This is like a simplified Clamp file.
420 fp=file(fname,'w')
421 ## Write sensorgram data header line.
422 for i,roi in enumerate(ba0.roi):
423 if (i>0): fp.write("\t")
424 name = roi.name.strip()
425 name = re.sub(r'\W+', '', name) ## Remove nonprinting characters.
426 name = re.sub(r'_ ', '', name) ## Remove other unwanted stuff.
427 name = re.sub(r'Fc=[0-9]+', '', name)
428 name = re.sub(r'[0-9]+_[XY]', '', name)
429 txt = name + " Fc=" + str(i+1) + "-1_X\t"
430 txt = txt + name + " Fc=" + str(i+1) + "-1_Y"
431 fp.write(txt)
432 ## Write sensorgram data lines. Three decimal places.
433 for dpoint in range(len(ba0.roi[0].time)):
434 fp.write("\r\n")
435 for i,roi in enumerate(ba0.roi):
436 if (i>0): fp.write("\t")
437 fp.write("%.3f\t%.3f" % (roi.time[dpoint], roi.value[dpoint]))
438
439 ## Close file handle and print message.
440 fp.close
441 print "File %s saved in %s." % (fname, getcwd())
442 return
443 """End of writebiosensor()"""
444
445
446 def readcsv(fname):
447 """
448 Read a comma-separated value text file into a ba class.
449 The first column contains time data while the others contain response data.
450 Here is a very simple example of the format::
451
452 1.0001, 23.7644, 0.7139
453 2.0001, 23.4265, 0.0541
454 3.0001, 23.1625, 0.3327
455 4.0001, 23.5752, 0.8494
456
457 Example::
458
459 >>> import osprai_one as osp
460 >>> ba0 = osp.readcsv("./exampledata/example-csv.csv")
461 This file has 4 datapoints for 2 ROIs.
462 """
463
464 ## Open file using Numpy. Return tiny ba object if it fails.
465 ba0 = ba.BiosensorArray(1,1)
466 try:
467 d = np.genfromtxt(fname, delimiter=',', dtype=float)
468 except IOError:
469 print "Error: Cannot open file %s for reading" % fname
470 return ba0
471 ## Check the dimensions of the new Numpy 2D array.
472 (dpoints, rois) = d.shape
473 rois -= 1
474 if (rois<1) or (dpoints<2):
475 print "Error: not enough data in %s" % fname
476 return ba0
477
478 ## Redimension ba and copy the columns of data.
479 ba0 = ba.BiosensorArray(rois, dpoints)
480 for i in xrange(rois):
481 ba0.roi[i].time = d[:,0]
482 ba0.roi[i].value = d[:,(i+1)]
483 print "This file has %i datapoints for %i ROIs." % (dpoints, rois)
484 return ba0
485 """End of readcsv()"""
486
487
488 def applygal(ba0, fname):
489 """
490 Read a GAL file and apply its microarray information.
491 Return a new object containing the data of ba0 modified with the
492 data of the GAL file.
493
494 An example GAL file::
495
496 ATF 1
497 6 5
498 "Type=GenePix ArrayList V1.0"
499 "BlockCount=1"
500 "BlockType=0"
501 "Block1=10000, 38780, 150, 20, 200, 18, 200"
502 "SlideBarcode=abc0001"
503 "ScanResolution=10"
504 Block Column Row ID Name
505 1 1 1 aIgG Antibody01
506 1 1 2 aIgM Antibody02
507
508 A description of this GAL file::
509
510 ATF -> File conforms to Axon Text File
511 1 -> Version number of ATF
512 6 -> Header lines before the "Block, Column, Row, ..." line
513 5 -> Data columns (Block, Column, Row, Name, ID)
514 BlockCount=1 -> Number of blocks described in the file
515 BlockType=0 -> Type of block, 0 = rectangular
516 BlockX=xOrigin,yOrigin,diameter,xFeatures,yFeatures,xSpacing,ySpacing
517 SlideBarcode -> Barcode (optional)
518 ScanResolution -> Resolution in microns (optional)
519
520 The blocks are ordered from left to right and then top to bottom.
521 Fields must be separated by tabs.
522 Quotes are optional and might be used when fields contain spaces.
523 Each record (microarray feature) is applied to an ROI *in the order listed*
524 in the GAL file. The Block, Column, and Row number is not considered
525 when determined the corresponding ROI.
526
527 Example::
528
529 >>> import osprai_one as osp
530 >>> ba0 = osp.BiosensorArray(20,100)
531 >>> ba1 = osp.applygal(ba0, "./exampledata/example-20spot.gal")
532 Successfully loaded information for 20 ROIs.
533 """
534
535 ## Try to open file. Return unchanged ba object if it fails.
536 try:
537 fp = open(fname, 'r')
538 except IOError:
539 print "Cannot open file %s for reading" % fname
540 return ba0
541
542 ## Check first header line for signature text.
543 txt = fp.readline()
544 if ("ATF 1" not in txt):
545 print "Error: The first header line should contain 'ATF'."
546 fp.close()
547 return ba0
548
549 ## Check second header line for number of additional header lines.
550 ## Use any number of semicolons, commas, spaces, or tabs as delimiter.
551 pattern = re.compile(r'[;,\s\t]+')
552 txt = pattern.split(fp.readline())
553 hlines = int(txt[0])
554
555 ## Skip additional header lines.
556 ## ToDo: use the BlockX=... information.
557 for i in range(hlines):
558 txt = fp.readline()
559
560 ## Check for label (last) header line.
561 txt = fp.readline()
562 if ("Block" not in txt):
563 print "Error: The last header line should contain 'Block'."
564 fp.close()
565 return ba0
566
567 ## Read all text, convert to 2d list, then five lists (one for each column).
568 ## There's probably an easier way to do this. Maybe in CSV module.
569 txtfile = fp.readlines()
570 fp.close()
571 records = len(txtfile)
572 if (ba0.rois != records):
573 print "Error: We have %i ROIs but %i GAL file entries." % (ba0.rois, records)
574 return ba0
575 ## Change text into array
576 keytable = txtfile[:] ## Dimension rows in new 2d list.
577 for i in range(records):
578 txt = str(txtfile[i].strip())
579 keytable[i] = txt.split('\t')
580 ## Use list comprehensions to get one list for each column.
581 blk = [int(x[0]) for x in keytable] ## First column is integer.
582 col = [int(x[1]) for x in keytable] ## Second column is integer.
583 row = [int(x[2]) for x in keytable] ## Third column is integer.
584 desc1 = [x[3] for x in keytable] ## Fourth column is text.
585 desc2 = [x[4] for x in keytable] ## Fifth column is text.
586
587 ## Create new object and put data in it.
588 ba1 = deepcopy(ba0)
589 for i in range(records):
590 ba1.roi[i].name = desc1[i]
591 ba1.roi[i].desc = desc2[i]
592 ba1.roi[i].gridx = blk[i]
593 ba1.roi[i].gridy = 0 ## Need to calculate this using BlockX=...
594 ba1.roi[i].spotx = col[i]
595 ba1.roi[i].spoty = row[i]
596
597 print "Successfully loaded information for %i ROIs." % records
598 return ba1
599
600 """End of applygal()"""
601
602
603 def applykey(ba0, fname):
604 """
605 Read a Key file and apply its microarray information.
606 Multiple background ROIs are not yet supported.
607 Here is a very simple example::
608
609 No. Description1 Description2 Background ROI Col Row
610 1 Rat TNF Antibody01 2 1 1
611 2 ratIgG Antibody02 4 2 1
612 3 Hum TNF Antibody03 4 3 1
613 4 humIgG Antibody04 2 4 1
614
615 Example::
616
617 >>> import osprai_one as osp
618 >>> ba0 = osp.BiosensorArray(2,100)
619 >>> ba1 = osp.applykey(ba0, "./exampledata/example-key.tsv")
620 Successfully loaded information for 2 ROIs.
621 """
622
623 ## Try to open file. Return unchanged ba object if it fails.
624 try:
625 fp = open(fname, "r")
626 except IOError:
627 print 'Cannot open file %s for reading' % fname
628 return ba0
629 ## Check header lines for signature text.
630 txt = fp.readline()
631 if ("No." not in txt):
632 print "Error: The header line is unfamiliar."
633 fp.close()
634 return ba0
635
636 ## Read all text, convert to 2d list, then six lists (one for each column).
637 ## There's probably an easier way to do this. Maybe in CSV module.
638 txtfile = fp.readlines()
639 fp.close()
640 ## Change text into array
641 keytable = txtfile[:] ## Dimension rows in new 2d list.
642 for i in range(len(txtfile)):
643 txt = str(txtfile[i].strip())
644 keytable[i] = txt.split('\t')
645 ## Use list comprehensions to get one list for each column.
646 id = [int(x[0]) for x in keytable] ## First column is integer.
647 desc1 = [x[1] for x in keytable] ## Second column is text.
648 desc2 = [x[2] for x in keytable] ## Third column is text.
649 bg = [int(x[3]) for x in keytable] ## Fourth column is integer. Change base1 to base0?
650 col = [int(x[4]) for x in keytable] ## Fifth column is integer.
651 row = [int(x[5]) for x in keytable] ## Sixth column is integer.
652
653 ## Check if key file looks valid. These tests are not very thorough!
654 keys = 1 + max(id) - min(id)
655 if (ba0.rois != keys):
656 print "Error: We have %i ROIs but %i keyfile entries." % (ba0.rois, keys)
657 return ba0
658 if ((min(bg) < min(id)) or (max(bg) > max (id))):
659 print "Error: at least one specified background ROI does not exist"
660 print "Identifiers (id) range from %i to %i." % (min(id), max(id))
661 print "Background references range from %i to %i." % (min(bg), max(bg))
662 return ba0
663
664 ## Create new object and put data in it.
665 ba1 = deepcopy(ba0)
666 for i in range(len(id)):
667 ba1.roi[id[i]-1].name = desc1[i]
668 ba1.roi[id[i]-1].desc = desc2[i]
669 ba1.roi[id[i]-1].bgroi = [bg[i]] ## ToDo: Decide if bg will be id or index. Base1 now.
670 ba1.roi[id[i]-1].spotx = col[i]
671 ba1.roi[id[i]-1].spoty = row[i]
672
673 print "Successfully loaded information for %i ROIs." % keys
674 return ba1
675 """End of applykey()"""
676
677
678 def applymethod(ba0, fname):
679 """
680 Read a ICM Analyte/Method xls file and apply its information.
681
682 *(This feature is under construction.)*
683 """
684 print "This feature is under construction."
685 return
686 """End of applymethod()"""
687
688
689
690 def outputbindinglevels(ba0, fname, interval, *baselines):
691 """
692 Measure the binding level changes at multiple intervals along a sensorgram.
693 Write the data to a file. If interval is 500 and baselines are [100, 1100] then
694 binding levels are changes between 100-600s and between 1100-01600s.
695 Average 30s of data.
696 """
697 fp=file(fname,'w')
698
699 ## Measurements
700 for iroi in ba0.roi:
701 fp.write("%i\t%s" % (iroi.index, iroi.name))
702 for j in baselines:
703 t1 = j
704 t2 = j + interval
705 y1 = np.average(iroi.time2val(t1-15, t1+15))
706 y2 = np.average(iroi.time2val(t2-15, t2+15))
707 fp.write("\t%.3f" % (y2-y1))
708 fp.write("\n")
709 fp.close
710 print "File %s saved in %s." % (fname, getcwd())
711 return
712 """End of outputbindinglevels()"""
713
714
715 def _test():
716 """
717 Automatic Code testing with doctest.
718 Doctest runs the example code in the docstrings.
719 Enable use of ellipses as wildcard for returned text.
720 """
721 import doctest
722 doctest.testmod(optionflags=doctest.ELLIPSIS)
723 print "Automatic testing of io_module.py completed."
724 return
725
726
727 if __name__ == "__main__":
728 """Use 'python io_module.py' for code testing."""
729 _test()
730
731
732 ################################# End of module #################################