~ubuntu-branches/ubuntu/natty/python-cogent/natty

« back to all changes in this revision

Viewing changes to doc/cookbook/analysis_of_sequence_composition.rst

  • Committer: Bazaar Package Importer
  • Author(s): Steffen Moeller
  • Date: 2010-12-04 22:30:35 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20101204223035-j11kinhcrrdgg2p2
Tags: 1.5-1
* Bumped standard to 3.9.1, no changes required.
* New upstream version.
  - major additions to Cookbook
  - added AlleleFreqs attribute to ensembl Variation objects.
  - added getGeneByStableId method to genome objects.
  - added Introns attribute to Transcript objects and an Intron class.
  - added Mann-Whitney test and a Monte-Carlo version
  - exploratory and confirmatory period estimation techniques (suitable for
    symbolic and continuous data)
  - Information theoretic measures (AIC and BIC) added
  - drawing of trees with collapsed nodes
  - progress display indicator support for terminal and GUI apps
  - added parser for illumina HiSeq2000 and GAiix sequence files as 
    cogent.parse.illumina_sequence.MinimalIlluminaSequenceParser.
  - added parser to FASTQ files, one of the output options for illumina's
    workflow, also added cookbook demo.
  - added functionality for parsing of SFF files without the Roche tools in
    cogent.parse.binary_sff
  - thousand fold performance improvement to nmds
  - >10-fold performance improvements to some Table operations

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
Analysis of sequence composition
3
3
********************************
4
4
 
 
5
.. sectionauthor:: Jesse Zaneveld
 
6
 
 
7
PyCogent provides several tools for analyzing the composition of DNA, RNA, or
 
8
protein sequences.
 
9
 
 
10
Loading your sequence
 
11
=====================
 
12
 
 
13
Let us say that we wish to study the sequence composition of the *Y. pseudotuberculosis* PB1 DNA Polymerase III beta subunit.
 
14
 
 
15
First we input the sequence as a string.
 
16
 
 
17
.. doctest::
 
18
 
 
19
    >>> y_pseudo_seq = \
 
20
    ...        """ atgaaatttatcattgaacgtgagcatctgctaaaaccactgcaacaggtcagtagcccg
 
21
    ...        ctgggtggacgccctacgttgcctattttgggtaacttgttgctgcaagtcacggaaggc
 
22
    ...        tctttgcggctgaccggtaccgacttggagatggagatggtggcttgtgttgccttgtct
 
23
    ...        cagtcccatgagccgggtgctaccacagtacccgcacggaagttttttgatatctggcgt
 
24
    ...        ggtttacccgaaggggcggaaattacggtagcgttggatggtgatcgcctgctagtgcgc
 
25
    ...        tctggtcgcagccgtttctcgctgtctaccttgcctgcgattgacttccctaatctggat
 
26
    ...        gactggcagagtgaggttgaattcactttaccgcaggctacgttaaagcgtctgattgag
 
27
    ...        tccactcagttttcgatggcccatcaggatgtccgttattatttgaacggcatgctgttt
 
28
    ...        gagaccgaaggcgaagagttacgtactgtggcgaccgatgggcatcgcttggctgtatgc
 
29
    ...        tcaatgcctattggccagacgttaccctcacattcggtgatcgtgccgcgtaaaggtgtg
 
30
    ...        atggagctggttcggttgctggatggtggtgatacccccttgcggctgcaaattggcagt
 
31
    ...        aataatattcgtgctcatgtgggcgattttattttcacatctaagctggttgatggccgt
 
32
    ...        ttcccggattatcgccgcgtattgccgaagaatcctgataaaatgctggaagccggttgc
 
33
    ...        gatttactgaaacaggcattttcgcgtgcggcaattctgtcaaatgagaagttccgtggt
 
34
    ...        gttcggctctatgtcagccacaatcaactcaaaatcactgctaataatcctgaacaggaa
 
35
    ...        gaagcagaagagatcctcgatgttagctacgaggggacagaaatggagatcggtttcaac
 
36
    ...        gtcagctatgtgcttgatgtgctaaatgcactgaagtgcgaagatgtgcgcctgttattg
 
37
    ...        actgactctgtatccagtgtgcagattgaagacagcgccagccaagctgcagcctatgtc
 
38
    ...        gtcatgccaatgcgtttgtag"""
 
39
 
 
40
To check that our results are reasonable, we can also load a small example string.
 
41
 
 
42
.. doctest::
 
43
 
 
44
    >>> example_seq = "GCGTTT"
 
45
 
 
46
In order to calculate compositional statistics, we need to import one of the ``Usage`` objects from ``cogent.core.usage``, create an object from our string, and normalize the counts contained in the string into frequencies. ``Usage`` objects include ``BaseUsage``, ``PositionalBaseUsage``, ``CodonUsage``, and ``AminoAcidUsage``.
 
47
 
 
48
Let us start with the ``BaseUsage`` object. The first few steps will be the same for the other Usage objects, however (as we will see below).
 
49
 
 
50
GC content
 
51
==========
 
52
 
 
53
Total GC  content
 
54
-----------------
 
55
 
 
56
GC content is one commonly used compositional statistic. To calculate the total GC content of our gene, we will need to initiate and normalize a ``BaseUsage`` object.
 
57
 
 
58
.. doctest::
 
59
    
 
60
    >>> from cogent.core.usage import BaseUsage
 
61
    >>> example_bu = BaseUsage(example_seq)
 
62
    >>> # Print raw counts
 
63
    >>> print example_bu.content("GC")
 
64
    3.0
 
65
    >>> example_bu.normalize()
 
66
    >>> print example_bu.content("GC")
 
67
    0.5
 
68
 
 
69
We can now visually verify that the reported GC contents are correct, and use the same technique on our full sequence.
 
70
 
 
71
.. doctest::
 
72
 
 
73
    >>> y_pseudo_bu = BaseUsage(y_pseudo_seq)
 
74
    >>> # Print raw counts
 
75
    >>> y_pseudo_bu.content("GC")
 
76
    555.0
 
77
    >>> y_pseudo_bu.normalize()
 
78
    >>> print y_pseudo_bu.content("GC")
 
79
    0.50408719346
 
80
 
 
81
Positional GC content of Codons
 
82
-------------------------------
 
83
 
 
84
When analyzing protein coding genes, it is often useful to subdivide the GC content by codon position. In particular, the 3rd codon position ``CodonUsage`` objects allow us to calculate the GC content at each codon position.
 
85
 
 
86
First, let us calculate the GC content for the codons in the example sequence as follows.
 
87
 
 
88
.. doctest::
 
89
 
 
90
    >>> # Import CodonUsage object
 
91
    >>> from cogent.core.usage import CodonUsage
 
92
    >>> # Initiate & normalize CodonUsage object
 
93
    >>> example_seq_cu = CodonUsage(example_seq)
 
94
    >>> example_seq_cu.normalize() 
 
95
    >>> GC,P1,P2,P3 = example_seq_cu.positionalGC()
 
96
 
 
97
Here, GC is the overall GC content for the sequence, while P1, P2, and P3 are the GC content at the first, second, and third codon positions, respectively.
 
98
 
 
99
Printing the results for the example gives the following results.
 
100
 
 
101
.. doctest::
 
102
    
 
103
    >>> print "GC:", GC
 
104
    GC: 0.5
 
105
    >>> print "P1:", P1
 
106
    P1: 0.5
 
107
    >>> print "P2:", P2
 
108
    P2: 0.5
 
109
    >>> print "P3:", P3
 
110
    P3: 0.5
 
111
 
 
112
We can then do the same for our biological sequence.
 
113
    
 
114
.. doctest::
 
115
 
 
116
    >>> y_pseudo_cu = CodonUsage(y_pseudo_seq)
 
117
    >>> y_pseudo_cu.normalize()
 
118
    >>> y_pseudo_GC = y_pseudo_cu.positionalGC()
 
119
    >>> print y_pseudo_GC
 
120
    [0.51874999999999993, 0.58437499999999987, 0.47500000000000009, 0.49687499999999996]
 
121
 
 
122
These results could then be fed into downstream analyses.
 
123
 
 
124
One important note is that ``CodonUsage`` objects calculate the GC content of codons within nucleotide sequences, rather than the full GC content.  Therefore, ``BaseUsage`` rather than ``CodonUsage`` objects should be used for calculating the GC content of non-coding sequences.
 
125
 
 
126
Total Base Usage
 
127
================
 
128
 
 
129
A more detailed view of composition incorporates the relative counts or frequencies of all bases. We can calculate total base usage as follows.
 
130
 
 
131
.. doctest::
 
132
    
 
133
    >>> from cogent.core.usage import BaseUsage
 
134
    >>> example_bu = BaseUsage(example_seq)
 
135
    >>> # Print raw counts
 
136
    >>> for k in example_bu.RequiredKeys:
 
137
    ...    print k, example_bu[k]
 
138
    A 0.0
 
139
    C 1.0
 
140
    U 3.0
 
141
    G 2.0
 
142
    >>> example_bu.normalize()
 
143
    >>> for k in example_bu.RequiredKeys:
 
144
    ...    print k, example_bu[k]
 
145
    A 0.0
 
146
    C 0.166666666667
 
147
    U 0.5
 
148
    G 0.333333333333
 
149
 
 
150
Dinucleotide Content
 
151
====================
 
152
 
 
153
The ``DinucUsage`` object allows us to calculate Dinucleotide usage for our sequence.
 
154
 
 
155
Dinucleotide usage can be calculated using overlapping, non-overlapping, or '3-1' dinucleotides.
 
156
 
 
157
Given the sequence "AATTAAGCC", each method will count dinucleotide usage differently. Overlapping dinucleotide usage will count "AA", "AT", "TT", "TA", "AA", "AG", "GC", "CC". Non-overlapping dinucleotide usage will count "AA", "TT", "AA", "GC" 3-1 dinucleotide usage will count "TT", "AC".
 
158
 
 
159
Calculating the GC content at the third and first codon positions ("3-1" usage) is useful for some applications, such as gene transfer detection, because changes at these positions tend to produce the most conservative amino acid substitutions, and thus are thought to better reflect mutational (rather than selective) pressure.
 
160
 
 
161
Overlapping dinucleotide content
 
162
--------------------------------
 
163
 
 
164
To calculate overlapping dinucleotide usage for our *Y. pseudotuberculosis* PB1 sequence.
 
165
 
 
166
.. doctest::
 
167
 
 
168
    >>> from cogent.core.usage import DinucUsage
 
169
    >>> du  = DinucUsage(y_pseudo_seq, Overlapping=True)
 
170
    >>> du.normalize()
 
171
 
 
172
We can inspect individual dinucleotide usages and confirm that the results add to 100% as follows
 
173
 
 
174
.. doctest::
 
175
    
 
176
    >>> total = 0.0
 
177
    >>> for k in du.RequiredKeys:
 
178
    ...    print k, du[k]
 
179
    ...    total += du[k]
 
180
    UU 0.0757855822551
 
181
    UC 0.0517560073937
 
182
    UA 0.043438077634
 
183
    UG 0.103512014787
 
184
    CU 0.0619223659889
 
185
    CC 0.0517560073937
 
186
    CA 0.0517560073937
 
187
    CG 0.0573012939002
 
188
    AU 0.0674676524954
 
189
    AC 0.043438077634
 
190
    AA 0.0573012939002
 
191
    AG 0.054528650647
 
192
    GU 0.0711645101664
 
193
    GC 0.0794824399261
 
194
    GA 0.0674676524954
 
195
    GG 0.0619223659889
 
196
    >>> print "Total:",total
 
197
    Total: 1.0
 
198
 
 
199
Non-overlapping Dinucleotide Content
 
200
------------------------------------
 
201
 
 
202
To calculate non-overlapping dinucleotide usage we simply change the ``Overlapping`` parameter to ``False`` when initiating the ``DinucUsage`` object.
 
203
 
 
204
.. doctest::
 
205
 
 
206
    >>> from cogent.core.usage import DinucUsage
 
207
    >>> du_no  = DinucUsage(y_pseudo_seq, Overlapping=False)
 
208
    >>> du_no.normalize()
 
209
    >>> total = 0
 
210
    >>> for k in du_no.RequiredKeys:
 
211
    ...    print k, du_no[k]
 
212
    ...    total += du_no[k]
 
213
    UU 0.0733082706767
 
214
    UC 0.0507518796992
 
215
    UA 0.0375939849624
 
216
    UG 0.105263157895
 
217
    CU 0.0733082706767
 
218
    CC 0.046992481203
 
219
    CA 0.0394736842105
 
220
    CG 0.0601503759398
 
221
    AU 0.0751879699248
 
222
    AC 0.046992481203
 
223
    AA 0.062030075188
 
224
    AG 0.0545112781955
 
225
    GU 0.0601503759398
 
226
    GC 0.0845864661654
 
227
    GA 0.0676691729323
 
228
    GG 0.062030075188
 
229
    >>> print "Total:",total
 
230
    Total: 1.0
 
231
 
 
232
'3-1' Dinucleotide Content
 
233
--------------------------
 
234
 
 
235
To calculate dinucleotide usage considering only adjacent first and third codon positions, we set the Overlapping parameter to '3-1' when constructing our ``DinucUsage`` object
 
236
 
 
237
.. doctest::
 
238
    
 
239
    >>> from cogent.core.usage import DinucUsage
 
240
    >>> du_3_1  = DinucUsage(y_pseudo_seq, Overlapping='3-1')
 
241
    >>> du_3_1.normalize()
 
242
    >>> total = 0
 
243
    >>> for k in du_3_1.RequiredKeys:
 
244
    ...    print k, du_3_1[k]
 
245
    ...    total += du_3_1[k]
 
246
    UU 0.0720221606648
 
247
    UC 0.0664819944598
 
248
    UA 0.0360110803324
 
249
    UG 0.0914127423823
 
250
    CU 0.0387811634349
 
251
    CC 0.0415512465374
 
252
    CA 0.0554016620499
 
253
    CG 0.0554016620499
 
254
    AU 0.0498614958449
 
255
    AC 0.0470914127424
 
256
    AA 0.0664819944598
 
257
    AG 0.0747922437673
 
258
    GU 0.0886426592798
 
259
    GC 0.0886426592798
 
260
    GA 0.0609418282548
 
261
    GG 0.0664819944598
 
262
    >>> print "Total:",total
 
263
    Total: 1.0
 
264
 
 
265
Comparing dinucleotide usages
 
266
-----------------------------
 
267
 
 
268
Above, we noted that there are several ways to calculate dinucleotide usages on a single sequence, and that the choice of methods changes the reported frequencies somewhat. How could we quantify the effect this choice make on the result?
 
269
 
 
270
One way to test this is to calculate the Euclidean distance between the resulting frequencies. We can do this using the dinucleotide usage's
 
271
 
 
272
.. doctest::
 
273
    
 
274
    >>> du_vs_du_3_1_dist = du.distance(du_3_1)
 
275
 
 
276
As required of a true distance, the results are independent of the direction of the calculation.
 
277
 
 
278
.. doctest::
 
279
    
 
280
    >>> du_3_1_vs_du_dist = du_3_1.distance(du)
 
281
    >>> print du_3_1_vs_du_dist == du_vs_du_3_1_dist
 
282
    True
 
283
 
 
284
Caution regarding unnormalized distances  
 
285
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
286
 
 
287
Note that in this case we have already called ``du.normalize()`` on each ``DinucUsage`` object. You MUST call ``du.normalize()`` before calculating distances. Otherwise the distance calculated will be for the dinucleotide counts, rather than frequencies. Distances of counts can be non-zero even for sequences with identical dinucleotide usage, if those sequences are of different lengths.
 
288
 
 
289
k-words
 
290
-------
 
291
 
 
292
*To be written.*
 
293
 
5
294
Codon usage analyses
6
295
====================
7
296
 
8
 
*To be written.*
9
 
 
10
 
k-words
11
 
=======
 
297
In addition to allowing a more detailed examination of GC content in coding sequences, ``CodonUsage`` objects (as the name implies) let us examine the codon usage of our sequence.
 
298
 
 
299
.. doctest::
 
300
   
 
301
    >>> from cogent.core.usage import CodonUsage
 
302
    >>> y_pseudo_cu  = CodonUsage(y_pseudo_seq)
 
303
    >>> # Print raw counts
 
304
    >>> for k in y_pseudo_cu.RequiredKeys:
 
305
    ...    print k, y_pseudo_cu[k]
 
306
    UUU 8.0
 
307
    UUC 4.0
 
308
    UUA 5.0
 
309
    UUG 14.0
 
310
    UCU 4.0
 
311
    UCC 3.0
 
312
    UCA 5.0
 
313
    UCG 3.0
 
314
    UAU 8.0...
 
315
 
 
316
Note that before normalization the ``CodonUsage`` object holds raw counts of results. However, for most purposes, we will want frequencies, so we normalize the counts.
 
317
 
 
318
.. doctest::
 
319
    
 
320
    >>> y_pseudo_cu.normalize()
 
321
    >>> # Print normalized frequencies 
 
322
    >>> for k in y_pseudo_cu.RequiredKeys:
 
323
    ...    print k, y_pseudo_cu[k]
 
324
    UUU 0.0225988700565
 
325
    UUC 0.0112994350282
 
326
    UUA 0.0141242937853
 
327
    UUG 0.0395480225989
 
328
    UCU 0.0112994350282
 
329
    UCC 0.00847457627119
 
330
    UCA 0.0141242937853
 
331
    UCG 0.00847457627119
 
332
    UAU 0.0225988700565...
 
333
 
 
334
Relative Synonymous Codon Usage
 
335
-------------------------------
 
336
 
 
337
The RSCU or relative synonymous codon usage metric divides the frequency of each codon by the total frequency of all codons encoding the same amino acid.
 
338
 
 
339
.. doctest::
 
340
    
 
341
    >>> y_pseudo_cu.normalize()
 
342
    >>> y_pseudo_rscu = y_pseudo_cu.rscu()
 
343
    >>> # Print rscu frequencies 
 
344
    >>> for k in y_pseudo_rscu.keys():
 
345
    ...    print k, y_pseudo_rscu[k]
 
346
    ACC 0.263157894737
 
347
    GUC 0.238095238095
 
348
    ACA 0.210526315789
 
349
    ACG 0.263157894737
 
350
    AAC 0.4
 
351
    CCU 0.315789473684
 
352
    UGG 1.0
 
353
    AUC 0.266666666667
 
354
    GUA 0.190476190476...
 
355
 
 
356
PR2 bias
 
357
--------
 
358
 
 
359
*To be written*
 
360
 
 
361
Fingerprint analysis
 
362
--------------------
 
363
 
 
364
*To be written*
 
365
 
 
366
Amino Acid Usage
 
367
================
12
368
 
13
369
*To be written.*
14
370