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