df12df640b6deb09423ef89d3ab514eb566f9265
[hooke.git] / drivers / mcs.py
1 #!/usr/bin/env python
2
3 '''
4 mcs.py
5
6 Driver for mcs fluorescence files.
7
8 Copyright 2009 by Massimo Sandal, Allen Chen
9 with modifications by Dr. Rolf Schmidt (Concordia University, Canada)
10
11 This program is released under the GNU General Public License version 2.
12 '''
13
14 import os.path
15
16 import lib.curve
17 import lib.driver
18 import lib.plot
19 import struct
20
21 class mcsDriver(lib.driver.Driver):
22
23     def __init__(self, filename):
24         '''
25         Open the RED (A) ones; the BLUE (D) mirror ones will be automatically opened
26         '''
27         #obtain name of blue files
28         othername=filename
29         if othername[-8]=='a': #fixme: how to make it general? (maybe should not be in driverspace but in environment...)
30             oth=list(othername)
31             oth[-8]='d'
32             othername=''.join(oth)
33         self.filename=filename
34         self.othername=othername
35
36         #print self.filename, self.othername
37
38         self.filedata=open(filename,'rb')
39         self.reddata=self.filedata.read()
40         self.filedata.close()
41
42         self.filebluedata=open(othername,'rb') #open also the blue ones
43         self.bluedata=self.filebluedata.read()
44         self.filebluedata.close()
45
46         self.filetype = 'mcs'
47         self.experiment = 'smfluo'
48
49     def close_all(self):
50         self.filedata.close()
51         self.filebluedata.close()
52
53     def default_plots(self):
54         #TODO: rename blue and red data to something more appropriate if possible
55         red_data=self.read_file(self.reddata)
56         blue_data=self.read_file(self.bluedata)
57         blue_data=[-1*float(item) for item in blue_data] #visualize blue as "mirror" of red
58
59         extension = lib.curve.Curve()
60         retraction = lib.curve.Curve()
61
62         extension.color = 'red'
63         extension.label = 'extension'
64         extension.style = 'plot'
65         extension.title = 'Force curve'
66         #FIXME: if there's an header saying something about the time count, should be used
67         #TODO: time is not really a unit
68         extension.units.x = 'time'
69         extension.units.y = 'count'
70         extension.x = range(len(red_data))
71         extension.y = red_data
72         retraction.color = 'blue'
73         retraction.label = 'retraction'
74         retraction.style = 'plot'
75         retraction.title = 'Force curve'
76         #FIXME: if there's an header saying something about the time count, should be used
77         #TODO: time is not really a unit
78         retraction.units.x = 'time'
79         retraction.units.y = 'count'
80         retraction.x = range(len(blue_data))
81         retraction.y = blue_data
82
83         plot = lib.plot.Plot()
84         plot.title = os.path.basename(self.filename)
85         plot.curves.append(extension)
86         plot.curves.append(retraction)
87
88         plot.normalize()
89         return plot
90
91     def is_me(self):
92         if self.filename[-3:].lower()=='mcs':
93             return True
94         else:
95             return False
96
97     def read_file(self, raw_data):
98         real_data=[]
99         intervalsperfile=struct.unpack('h', raw_data[10:12])[0] #read in number of intervals in this file
100                                                                 #this data is contained in bit offset 10-12 in mcs file
101         #see http://docs.python.org/library/struct.html#module-struct for additional explanation
102
103         numbytes=len(raw_data) #data is stored in 4-byte chunks, starting with pos 256
104         for j in range(0,intervalsperfile): #read in all intervals in file
105             temp=raw_data[256+j*4:256+j*4+4]    #data starts at byte offset 256
106             real_data.append(struct.unpack('i', temp)[0]) #[0] because it returns a 1-element tuple
107         return real_data