AlignedCodonFrame holds mapping information between individual cDNA regions on dna...
[jalview.git] / src / jalview / datamodel / AlignedCodonFrame.java
1 package jalview.datamodel;\r
2 \r
3 import jalview.util.MapList;\r
4 \r
5 /**\r
6  * Stores mapping between the columns of a protein alignment and a DNA alignment\r
7  * and a list of individual codon to amino acid mappings between sequences.\r
8  */\r
9 \r
10 public class AlignedCodonFrame\r
11 {\r
12   /**\r
13    * array of nucleotide positions for aligned codons at column of aligned proteins.\r
14    */\r
15   public int[][] codons = null;\r
16   /**\r
17    * width of protein sequence alignement\r
18    * implicit assertion that codons.length >= aaWidth\r
19    */\r
20   public int aaWidth=0;\r
21   /**\r
22    * initialise codon frame with a nominal alignment width\r
23    * @param aWidth\r
24    */\r
25   public AlignedCodonFrame(int aWidth)\r
26   {\r
27     codons = new int[aWidth][];\r
28     for (int res = 0; res < aWidth; res++)\r
29       codons[res] = null;\r
30   }\r
31 \r
32   /**\r
33    * ensure that codons array is at least as wide as aslen residues\r
34    * @param aslen\r
35    * @return (possibly newly expanded) codon array\r
36    */\r
37   public int[][] checkCodonFrameWidth(int aslen)\r
38   {\r
39     if (codons.length <= aslen + 1)\r
40     {\r
41       // probably never have to do this ?\r
42       int[][] c = new int[codons.length + 10][];\r
43       for (int i = 0; i < codons.length; i++)\r
44       {\r
45         c[i] = codons[i];\r
46         codons[i] = null;\r
47       }\r
48       codons = c;\r
49     }\r
50     return codons;\r
51   }\r
52   /**\r
53    * @return width of aligned translated amino acid residues \r
54    */\r
55   public int getaaWidth()\r
56   {\r
57     return aaWidth;\r
58   }\r
59   /**\r
60    * increase aaWidth by one and insert a new aligned codon position space at aspos.\r
61    * @param aspos\r
62    */\r
63   public void insertAAGap(int aspos, char gapCharacter)\r
64   {            \r
65     // this aa appears before the aligned codons at aspos - so shift them in each pair of mapped sequences\r
66     aaWidth++;\r
67     for (int sq=0;aaSeqs!=null && sq<aaSeqs.length; sq++) {\r
68       aaSeqs[sq].insertCharAt(aspos, gapCharacter);\r
69     }\r
70 \r
71     checkCodonFrameWidth(aspos);\r
72     if (aspos<aaWidth)\r
73     {\r
74       aaWidth++;\r
75       System.arraycopy(codons, aspos, codons, aspos+1, aaWidth-aspos);\r
76       codons[aspos]=null; // clear so new codon position can be marked.\r
77     }\r
78   }\r
79 \r
80   public void setAaWidth(int aapos)\r
81   {\r
82     aaWidth = aapos;\r
83   }\r
84   /**\r
85    * tied array of na Sequence objects.\r
86    */\r
87   SequenceI[] dnaSeqs=null;\r
88   /**\r
89    * tied array of protein sequence Objects\r
90    */\r
91   SequenceI[] aaSeqs=null;\r
92   /**\r
93    * tied array of MapLists where eac maps from the corresponding dnaSeqs element to corresponding aaSeqs element  \r
94    */\r
95   MapList[] dnaToProt=null;\r
96   \r
97   public void addMap(SequenceI dnaseq, SequenceI aaseq, MapList map)\r
98   { \r
99     int nlen=1;\r
100     if (dnaSeqs!=null)\r
101     {\r
102       nlen = dnaSeqs.length+1;\r
103     }\r
104     SequenceI[] ndna = new SequenceI[nlen];\r
105     SequenceI[] naa = new SequenceI[nlen];\r
106     MapList[] ndtp = new MapList[nlen];\r
107     if (dnaSeqs!=null)\r
108     {\r
109       System.arraycopy(dnaSeqs,0,ndna, 0, dnaSeqs.length);\r
110       System.arraycopy(aaSeqs,0,naa, 0, dnaSeqs.length);\r
111       System.arraycopy(dnaToProt,0,ndtp, 0, dnaSeqs.length);\r
112     }\r
113     dnaSeqs = ndna;\r
114     aaSeqs = naa;\r
115     dnaToProt = ndtp;\r
116     nlen--;\r
117     dnaSeqs[nlen] = (dnaseq.getDatasetSequence()==null) ? dnaseq : dnaseq.getDatasetSequence();\r
118     aaSeqs[nlen] = (aaseq.getDatasetSequence()==null) ? aaseq : aaseq.getDatasetSequence();\r
119     dnaToProt[nlen] = map;\r
120   }\r
121 \r
122 \r
123   public SequenceI[] getdnaSeqs()\r
124   {\r
125     return dnaSeqs;\r
126   }\r
127   public SequenceI[] getAaSeqs()\r
128   {\r
129     return aaSeqs;\r
130   }\r
131   public MapList[] getdnaToProt()\r
132   {\r
133     return dnaToProt;\r
134   }\r
135   /**\r
136    * \r
137    * @param sequenceRef\r
138    * @return null or corresponding aaSeq entry for dnaSeq entry\r
139    */\r
140   public SequenceI getAaForDnaSeq(SequenceI dnaSeqRef)\r
141   {\r
142     if (dnaSeqs==null)\r
143     {\r
144       return null;\r
145     }\r
146     SequenceI dnads = dnaSeqRef.getDatasetSequence();\r
147     for (int ds=0;ds<dnaSeqs.length; ds++)\r
148     {\r
149       if (dnaSeqs[ds]==dnaSeqRef || dnaSeqs[ds]==dnads)\r
150         return aaSeqs[ds];\r
151     }\r
152     return null;\r
153   }\r
154   /**\r
155    * \r
156    * @param sequenceRef\r
157    * @return null or corresponding aaSeq entry for dnaSeq entry\r
158    */\r
159   public SequenceI getDnaForAaSeq(SequenceI aaSeqRef)\r
160   {\r
161     if (aaSeqs==null)\r
162     {\r
163       return null;\r
164     }\r
165     SequenceI aads = aaSeqRef.getDatasetSequence();\r
166     for (int as=0;as<aaSeqs.length; as++)\r
167     {\r
168       if (aaSeqs[as]==aaSeqRef || aaSeqs[as]==aads)\r
169         return dnaSeqs[as];\r
170     }\r
171     return null;\r
172   }\r
173   /**\r
174    * test to see if codon frame involves seq in any way\r
175    * @param seq a nucleotide or protein sequence\r
176    * @return true if a mapping exists to or from this sequence to any translated sequence\r
177    */\r
178   public boolean involvesSequence(SequenceI seq)\r
179   {\r
180     return getAaForDnaSeq(seq)!=null || getDnaForAaSeq(seq)!=null;\r
181   }\r
182   /**\r
183    * Add search results for regions in other sequences that translate or are translated from a particular position in seq \r
184    * @param seq\r
185    * @param index position in seq\r
186    * @param results where highlighted regions go\r
187    */\r
188   public void markMappedRegion(SequenceI seq, int index, SearchResults results)\r
189   {\r
190     int[] codon;\r
191     SequenceI ds = seq.getDatasetSequence();\r
192     for (int mi = 0; mi<aaSeqs.length; mi++)\r
193     {\r
194       if (dnaSeqs[mi]==seq || dnaSeqs[mi]==ds)\r
195       {\r
196         // DEBUG System.err.println("dna pos "+index);\r
197         codon = dnaToProt[mi].locateInTo(index,index);\r
198         if (codon!=null)\r
199         {\r
200           for (int i=0; i<codon.length; i+=2)\r
201             {\r
202               results.addResult(aaSeqs[mi], codon[i], codon[i+1]);\r
203             }\r
204         }\r
205       } else\r
206         if (aaSeqs[mi]==seq || aaSeqs[mi]==ds)\r
207         {\r
208           // DEBUG System.err.println("aa pos "+index);\r
209           {\r
210             codon = dnaToProt[mi].locateInFrom(index, index);\r
211             if (codon!=null)\r
212             {\r
213             for (int i=0; i<codon.length; i+=2)\r
214               {\r
215                 results.addResult(dnaSeqs[mi], codon[i], codon[i+1]);\r
216               }\r
217           }\r
218         }\r
219         }\r
220     }\r
221   }\r
222 }\r