1 |
.. Osprai tutorial #1 |
2 |
Chris Lausted 110202 |
3 |
|
4 |
|
5 |
OSPRAI Tutorial 1 |
6 |
================= |
7 |
|
8 |
Viewing data from an SPR file |
9 |
----------------------------- |
10 |
|
11 |
Analysis begins with viewing data generated by a biosensor instrument such as a Biacore or Plexera. |
12 |
Launch a python interpreter such as the standard interpreter or IPython and navigate to the directory containing the OSPRAI code and example data files. |
13 |
Enter the following commands to load and view an example data file:: |
14 |
|
15 |
>>> from osprai_one import * |
16 |
>>> ba1 = readicmtxt("example-icm.txt") |
17 |
This ICM files has 6034 datapoints for 25 ROIs. |
18 |
>>> linegraph(ba1) |
19 |
|
20 |
.. image:: ./images/figure02.png |
21 |
|
22 |
The first line imports all of the functions and data classes needed by the user. |
23 |
Function ``readicmtxt()`` reads an SPR data file saved by the Plexera Instrument Control Software. |
24 |
Other data formats are supported and described later. |
25 |
A object of the class Biosensor_array (BA) is created named ``ba1`` containing the data. |
26 |
|
27 |
Function ``linegraph()`` plots the data as a sensorgram--the SPR signal versus time. |
28 |
This plot appears in a separate window. |
29 |
At the lower left corner of the window are buttons for zooming, copying, and saving (PNG format). |
30 |
These buttons will be familiar to matplotlib users. |
31 |
At the lower right corner are three buttons for changing which ROIs are displayed. |
32 |
While it is possible to display all ROIs in a BA object, a plot with 25 ROIs would be too cluttered. |
33 |
By default, only the first six ROIs in the BA are shown. |
34 |
Clicking the "Next6" button will change the plot to display ROIs 6-11 and a subsequent click on the "Prev6" button will display ROIs 0-5 again. |
35 |
An arbitrary list of ROIs can be specified by clicking the "Choose..." button. |
36 |
The window must be closed in order to continue the execution of Osparai commands |
37 |
|
38 |
|
39 |
Calibration and background subtraction |
40 |
-------------------------------------- |
41 |
|
42 |
Data produced by a biosensing instrument can be reported as angle shift, reflectance, wavelength shift, resonance units (RU), or other units. |
43 |
This data can come from a single surface or channel, in which case the bulk refractive index changes of the samples and washes can be seen, or it may be the difference between two surfaces or channels. |
44 |
The example file used here is uncalibrated and unreferenced. |
45 |
Enter the following commands for calibration and referencing:: |
46 |
|
47 |
>>> ba2 = calibrate(ba1, ba1, 2850, 3120, 1333000, 1334000) |
48 |
>>> linegraph(ba2, "Calibrated SPR Data") |
49 |
.. image:: ./images/figure03a.png" |
50 |
>>> bgset(ba2, 16) |
51 |
>>> ba3 = bgsubt(ba2) |
52 |
>>> dotgraph(ba3, "Referenced SPR Data") |
53 |
|
54 |
.. image:: ./images/figure03b.png |
55 |
|
56 |
:: |
57 |
|
58 |
>>> dualgraph(ba2, ba3, "Unreferenced and Referenced SPR Data") |
59 |
|
60 |
.. image:: ./images/figure03c.png |
61 |
|
62 |
Function ``calibrate()`` uses the data in ``ba1`` to calibrate the data in ``ba1`` and place it in a new object ``ba2``. |
63 |
The two-point calibration uses the time points (t1,t2) where the refractive indices (n1,n2) are known. |
64 |
In this case, we use t1=2850s with n1=1333000 |uRIU|, and t2=3120 with n2=1334000. |
65 |
Function ``bgset()`` is used to specify one ROI as the reference for all ROIs in the ba object. |
66 |
In this case, ROI number 16 is used. |
67 |
No data is affected by this step. |
68 |
To apply background subtraction, we call the ``bgsubt()`` function. |
69 |
This creates a new object ``ba3``. |
70 |
Function ``dotgraph()`` provides a slightly different display, with dotted data points instead of continuous lines. |
71 |
Function ``dualgraph()`` displays both dotted and continuous sensorgrams. |
72 |
This feature is useful for comparing two related Biosensor_array objects of the same size. |
73 |
|
74 |
|
75 |
Data simulation |
76 |
--------------- |
77 |
|
78 |
Now we will create some simulated sensorgrams using a simple 1:1 interaction model. |
79 |
*(the model is a reference to a function)* |
80 |
*(the parameters are provided as a list of lists)* |
81 |
:: |
82 |
|
83 |
>>> reset |
84 |
>>> from osprai_one import * |
85 |
>>> dpar = {} |
86 |
>>> dpar['t1'] = dict(value=30.0, min=30.0, max=30.0, fixed='fixed') |
87 |
>>> dpar['rmax'] = dict(value=100.0, min=1.0, max=1000.0, fixed='fixed') |
88 |
>>> dpar['conc'] = dict(value=1e-5, min=1e-12, max=1e1, fixed='fixed') |
89 |
>>> dpar['cofa'] = dict(value=1.0, min=1e-10, max=1e10, fixed='fixed') |
90 |
>>> dpar['kon'] = dict(value=2e4, min=1e1, max=1e10, fixed='fixed') |
91 |
>>> dpar['t2'] = dict(value=150.0, min=150.0, max=150.0, fixed='fixed') |
92 |
>>> dpar['koff'] = dict(value=1e-2, min=1e-5, max=1e-1, fixed='fixed') |
93 |
>>> dpar['t3'] = dict(value=270.0, min=270.0, max=270.0, fixed='fixed') |
94 |
>>> print dpar |
95 |
{'cofa': {'fixed': 'fixed', 'max': 10000000000.0, 'min': 1e-010, 'value |
96 |
'conc': {'fixed': 'fixed','max': 10.0,'min': 1.0e-012,'value': 1.0e-005}, |
97 |
'koff': {'fixed': 'fixed','max': 0.1,'min': 1.0e-005,'value': 0.01}, |
98 |
'kon': {'fixed': 'fixed','max': 10000000000.0,'min': 10.0,'value': 20000.0}, |
99 |
'rmax': {'fixed': 'fixed', 'max': 1000.0, 'min': 1.0, 'value': 100.0}, |
100 |
't1': {'fixed': 'fixed', 'max': 30.0, 'min': 30.0, 'value': 30.0}, |
101 |
't2': {'fixed': 'fixed', 'max': 150.0, 'min': 150.0, 'value': 150.0}, |
102 |
't3': {'fixed': 'fixed', 'max': 270.0, 'min': 270.0, 'value': 270.0}} |
103 |
>>> |
104 |
>>> ba1 = BiosensorArray(3,300) |
105 |
>>> for roi in ba1.roi: |
106 |
>>> roi.time = arange(300, dtype=float) ## Samples every 1 second. |
107 |
>>> roi.value = zeros(300, dtype=float) + 20 ## Baseline signal is 20 units. |
108 |
>>> roi.params = deepcopy(dpar) |
109 |
>>> roi.model = simple1to1 |
110 |
>>> ba1.roi[0].params['cofa']['value'] = 1.0 / 27 |
111 |
>>> ba1.roi[1].params['cofa']['value'] = 1.0 / 9 |
112 |
>>> ba1.roi[2].params['cofa']['value'] = 1.0 / 3 |
113 |
>>> for roi in ba1.roi: |
114 |
>>> roi.value = roi.model(roi.time, roi.value, roi.params) |
115 |
>>> dotgraph(ba1, "Simulation") |
116 |
|
117 |
.. image:: ./images/figure04.png |
118 |
|
119 |
|
120 |
Curve-fitting |
121 |
------------- |
122 |
|
123 |
Osprai uses a modified version of the Levenberg-Marquardt least-squares algorithm (LMA) for fitting parameters. |
124 |
The function ``mcmla()`` provides LMA fitting on multiple curves with constrained parameters. |
125 |
The use of constraints can improve speed and eliminate nonsense solutions such as negative values for binding kinetic rate parameters. |
126 |
In this example, we constrain the ``rmax`` parameter to deliberately produce incorrect ``kon`` and ``koff`` parameter results:: |
127 |
|
128 |
>>> ba2 = deepcopy(ba1) |
129 |
>>> ba2.roi[0].params['rmax'] = {'value':10.0, 'min':1.0, 'max':80.0, 'fixed':'float'} |
130 |
>>> ba2.roi[0].params['kon']['fixed'] = 'float' |
131 |
>>> ba2.roi[0].params['koff']['fixed'] = 'float' |
132 |
>>> ba2.roi[1].params['rmax']['fixed'] = 0 |
133 |
>>> ba2.roi[1].params['kon']['fixed'] = 0 |
134 |
>>> ba2.roi[1].params['koff']['fixed'] = 0 |
135 |
>>> ba2.roi[2].params['rmax']['fixed'] = 0 |
136 |
>>> ba2.roi[2].params['kon']['fixed'] = 0 |
137 |
>>> ba2.roi[2].params['koff']['fixed'] = 0 |
138 |
>>> mclma(ba2.roi) |
139 |
... 0 koff 0.0100 kon 20000.0000 rmax 10.0000 1 2 ssq 1477505.8 |
140 |
0 koff 0.0100 kon 20000.0000 rmax 10.0000 1 2 ssq 1477505.8 |
141 |
0 koff 0.0100 kon 20000.0000 rmax 10.0000 1 2 ssq 1477505.8 |
142 |
0 koff 0.0100 kon 20000.0000 rmax 10.0000 1 2 ssq 1477505.8 |
143 |
0 koff 0.0100 kon 20000.0039 rmax 10.0000 1 2 ssq 1477505.8 |
144 |
0 koff 0.0100 kon 20000.0000 rmax 10.0000 1 2 ssq 1477505.8 |
145 |
0 koff 0.0100 kon 19999.9870 rmax 79.9923 1 2 ssq 73019.8 |
146 |
0 koff 0.0100 kon 19999.9870 rmax 79.9923 1 2 ssq 73019.8 |
147 |
0 koff 0.0100 kon 19999.9909 rmax 79.9923 1 2 ssq 73019.8 |
148 |
0 koff 0.0100 kon 19999.9870 rmax 79.9923 1 2 ssq 73019.8 |
149 |
0 koff 0.0081 kon 29949.8389 rmax 80.0000 1 2 ssq 23159.0 |
150 |
0 koff 0.0081 kon 29949.8389 rmax 80.0000 1 2 ssq 23159.0 |
151 |
0 koff 0.0081 kon 29949.8446 rmax 80.0000 1 2 ssq 23159.0 |
152 |
0 koff 0.0081 kon 29949.8389 rmax 80.0000 1 2 ssq 23159.0 |
153 |
0 koff 0.0081 kon 28038.4215 rmax 80.0000 1 2 ssq 22549.1 |
154 |
0 koff 0.0081 kon 28038.4215 rmax 80.0000 1 2 ssq 22549.1 |
155 |
0 koff 0.0081 kon 28038.4268 rmax 80.0000 1 2 ssq 22549.1 |
156 |
0 koff 0.0081 kon 28038.4215 rmax 80.0000 1 2 ssq 22549.1 |
157 |
0 koff 0.0081 kon 28217.6911 rmax 80.0000 1 2 ssq 22541.4 |
158 |
0 koff 0.0081 kon 28217.6911 rmax 80.0000 1 2 ssq 22541.4 |
159 |
0 koff 0.0081 kon 28217.6965 rmax 80.0000 1 2 ssq 22541.4 |
160 |
0 koff 0.0081 kon 28217.6911 rmax 80.0000 1 2 ssq 22541.4 |
161 |
0 koff 0.0081 kon 28196.8328 rmax 80.0000 1 2 ssq 22541.3 |
162 |
0 koff 0.0081 kon 28196.8328 rmax 80.0000 1 2 ssq 22541.3 |
163 |
0 koff 0.0081 kon 28196.8382 rmax 80.0000 1 2 ssq 22541.3 |
164 |
0 koff 0.0081 kon 28196.8328 rmax 80.0000 1 2 ssq 22541.3 |
165 |
0 koff 0.0081 kon 28199.1282 rmax 80.0000 1 2 ssq 22541.3 |
166 |
0 koff 0.0081 kon 28199.1282 rmax 80.0000 1 2 ssq 22541.3 |
167 |
0 koff 0.0081 kon 28199.1335 rmax 80.0000 1 2 ssq 22541.3 |
168 |
0 koff 0.0081 kon 28199.1282 rmax 80.0000 1 2 ssq 22541.3 |
169 |
0 koff 0.0081 kon 28198.8747 rmax 80.0000 1 2 ssq 22541.3 |
170 |
|
171 |
>>> for roi in ba2.roi: |
172 |
>>> roi.value = roi.model(roi.time, roi.value, roi.params) |
173 |
>>> dualgraph(ba1, ba2, "Fitted Data with an incorrect rmax constraint") |
174 |
|
175 |
.. image:: ./images/figure05a.png |
176 |
|
177 |
First, we make a copy of ``ba1`` using the ``deepcopy()`` function. |
178 |
Next, we specify which parameters we wish to solve for by changing their 'fixed' key from 'fixed' to 'float'. |
179 |
All three ROIs in this BA have the same model and the same parameters, so we only set the parameters in one of the ROIs to 'float'. |
180 |
Here, we choose the the first ROI, ``roi[0]``, and change 'fixed' to 'float' for 'rmax', 'kon', and 'koff' parameters. |
181 |
In addition, we specify that 'rmax' will have a 'max' value of 80.0. |
182 |
Next, we specify that the 'rmax', 'kon', and 'koff' values for ``roi[1]`` and ``roi[2]`` are the same as for ``roi[0]``. |
183 |
We do this by setting their 'fixed' key to 0, a reference to ``roi[0]``. |
184 |
|
185 |
We call the curve-fitting function with ``mclma(ba2.roi)`` |
186 |
This function will print out the values of the floating parameters and the sum-squared error after each iteration. |
187 |
After 30 iterations, in this case, the algorithm converges upon a solution. |
188 |
Since 'rmax' was constrained to 80.0, with the real 'rmax' is 100.0, the resulting best-fit kon is found to be high (28000 vs. 20000). |
189 |
We then use a ``for`` loop to simulate the three sensorgrams in ``ba2`` using the fitted parameters. |
190 |
Last, we plot both the original sensorgrams of ``ba1`` and the fitted sensorgrams of ``ba2`` using the ``dualgraph()`` function. |
191 |
|
192 |
|
193 |
File format conversion |
194 |
---------------------- |
195 |
|
196 |
Functions are provided to read and write several Biacore and Plexera file formats. |
197 |
Optionally, microarray annotations can be added to the SPR data from GAL or Key files. |
198 |
These annotations are saved when data files are written, if the file format provides support. |
199 |
Examples are given below:: |
200 |
|
201 |
>>> ba = readbiosensor("example-biosensor.txt") |
202 |
This Biosensor file has 9 datapoints for 2 ROIs. |
203 |
>>> ba = readicmtxt("example-icm.txt") |
204 |
This ICM file has 6034 datapoints for 25 ROIs. |
205 |
>>> ba = readsprit("example-sprit.txt") |
206 |
This SPRit file has 9 datapoints for 2 ROIs. |
207 |
>>> ba = applykey(ba1, "example-key.tsv") |
208 |
>>> writesprit(ba,"testwritesprit.txt") |
209 |
>>> writeclamp(ba,"testwriteclamp.txt") |
210 |
>>> writebiosensor(ba, "testwritebiosensor.txt") |
211 |
|
212 |
|
213 |
Online help |
214 |
----------- |
215 |
The Python ``help()`` function can be used at any time to display the online documentation for all Osprai functions and classes. |
216 |
|
217 |
.. parsed-literal:: |
218 |
|
219 |
>>> import osprai_one |
220 |
>>> help(osprai_one) |
221 |
Help on module osprai_one: |
222 |
|
223 |
NAME |
224 |
osprai_one |
225 |
|
226 |
FILE |
227 |
( ...many pages of documentation follow... ) |
228 |
|
229 |
>>> help(linegraph) |
230 |
Help on function linegraph in module vu_module: |
231 |
|
232 |
linegraph(baLine, title='') |
233 |
Display signal vs time using continuous lines. |
234 |
|
235 |
:param baLine: Object containing the data. |
236 |
:type baLine: ba_class |
237 |
:param title: Title to place above the graph. |
238 |
:type title: str |
239 |
:returns: nothing |
240 |
|
241 |
|
242 |
.. End of tutorial. |
243 |
|
244 |
.. Define a Greek character code that will trim off a trailing space. |
245 |
.. |mu| unicode:: U+003BC .. GREEK SMALL LETTER MU :rtrim: |
246 |
.. Another useful definition. |
247 |
.. |uRIU| unicode:: U+003BC RIU .. Micro-refractive index units. |