--- /dev/null
+package jalview.datamodel;\r
+\r
+import jalview.util.MapList;\r
+\r
+/**\r
+ * Stores mapping between the columns of a protein alignment and a DNA alignment\r
+ * and a list of individual codon to amino acid mappings between sequences.\r
+ */\r
+\r
+public class AlignedCodonFrame\r
+{\r
+ /**\r
+ * array of nucleotide positions for aligned codons at column of aligned proteins.\r
+ */\r
+ public int[][] codons = null;\r
+ /**\r
+ * width of protein sequence alignement\r
+ * implicit assertion that codons.length >= aaWidth\r
+ */\r
+ public int aaWidth=0;\r
+ /**\r
+ * initialise codon frame with a nominal alignment width\r
+ * @param aWidth\r
+ */\r
+ public AlignedCodonFrame(int aWidth)\r
+ {\r
+ codons = new int[aWidth][];\r
+ for (int res = 0; res < aWidth; res++)\r
+ codons[res] = null;\r
+ }\r
+\r
+ /**\r
+ * ensure that codons array is at least as wide as aslen residues\r
+ * @param aslen\r
+ * @return (possibly newly expanded) codon array\r
+ */\r
+ public int[][] checkCodonFrameWidth(int aslen)\r
+ {\r
+ if (codons.length <= aslen + 1)\r
+ {\r
+ // probably never have to do this ?\r
+ int[][] c = new int[codons.length + 10][];\r
+ for (int i = 0; i < codons.length; i++)\r
+ {\r
+ c[i] = codons[i];\r
+ codons[i] = null;\r
+ }\r
+ codons = c;\r
+ }\r
+ return codons;\r
+ }\r
+ /**\r
+ * @return width of aligned translated amino acid residues \r
+ */\r
+ public int getaaWidth()\r
+ {\r
+ return aaWidth;\r
+ }\r
+ /**\r
+ * increase aaWidth by one and insert a new aligned codon position space at aspos.\r
+ * @param aspos\r
+ */\r
+ public void insertAAGap(int aspos, char gapCharacter)\r
+ { \r
+ // this aa appears before the aligned codons at aspos - so shift them in each pair of mapped sequences\r
+ aaWidth++;\r
+ for (int sq=0;aaSeqs!=null && sq<aaSeqs.length; sq++) {\r
+ aaSeqs[sq].insertCharAt(aspos, gapCharacter);\r
+ }\r
+\r
+ checkCodonFrameWidth(aspos);\r
+ if (aspos<aaWidth)\r
+ {\r
+ aaWidth++;\r
+ System.arraycopy(codons, aspos, codons, aspos+1, aaWidth-aspos);\r
+ codons[aspos]=null; // clear so new codon position can be marked.\r
+ }\r
+ }\r
+\r
+ public void setAaWidth(int aapos)\r
+ {\r
+ aaWidth = aapos;\r
+ }\r
+ /**\r
+ * tied array of na Sequence objects.\r
+ */\r
+ SequenceI[] dnaSeqs=null;\r
+ /**\r
+ * tied array of protein sequence Objects\r
+ */\r
+ SequenceI[] aaSeqs=null;\r
+ /**\r
+ * tied array of MapLists where eac maps from the corresponding dnaSeqs element to corresponding aaSeqs element \r
+ */\r
+ MapList[] dnaToProt=null;\r
+ \r
+ public void addMap(SequenceI dnaseq, SequenceI aaseq, MapList map)\r
+ { \r
+ int nlen=1;\r
+ if (dnaSeqs!=null)\r
+ {\r
+ nlen = dnaSeqs.length+1;\r
+ }\r
+ SequenceI[] ndna = new SequenceI[nlen];\r
+ SequenceI[] naa = new SequenceI[nlen];\r
+ MapList[] ndtp = new MapList[nlen];\r
+ if (dnaSeqs!=null)\r
+ {\r
+ System.arraycopy(dnaSeqs,0,ndna, 0, dnaSeqs.length);\r
+ System.arraycopy(aaSeqs,0,naa, 0, dnaSeqs.length);\r
+ System.arraycopy(dnaToProt,0,ndtp, 0, dnaSeqs.length);\r
+ }\r
+ dnaSeqs = ndna;\r
+ aaSeqs = naa;\r
+ dnaToProt = ndtp;\r
+ nlen--;\r
+ dnaSeqs[nlen] = (dnaseq.getDatasetSequence()==null) ? dnaseq : dnaseq.getDatasetSequence();\r
+ aaSeqs[nlen] = (aaseq.getDatasetSequence()==null) ? aaseq : aaseq.getDatasetSequence();\r
+ dnaToProt[nlen] = map;\r
+ }\r
+\r
+\r
+ public SequenceI[] getdnaSeqs()\r
+ {\r
+ return dnaSeqs;\r
+ }\r
+ public SequenceI[] getAaSeqs()\r
+ {\r
+ return aaSeqs;\r
+ }\r
+ public MapList[] getdnaToProt()\r
+ {\r
+ return dnaToProt;\r
+ }\r
+ /**\r
+ * \r
+ * @param sequenceRef\r
+ * @return null or corresponding aaSeq entry for dnaSeq entry\r
+ */\r
+ public SequenceI getAaForDnaSeq(SequenceI dnaSeqRef)\r
+ {\r
+ if (dnaSeqs==null)\r
+ {\r
+ return null;\r
+ }\r
+ SequenceI dnads = dnaSeqRef.getDatasetSequence();\r
+ for (int ds=0;ds<dnaSeqs.length; ds++)\r
+ {\r
+ if (dnaSeqs[ds]==dnaSeqRef || dnaSeqs[ds]==dnads)\r
+ return aaSeqs[ds];\r
+ }\r
+ return null;\r
+ }\r
+ /**\r
+ * \r
+ * @param sequenceRef\r
+ * @return null or corresponding aaSeq entry for dnaSeq entry\r
+ */\r
+ public SequenceI getDnaForAaSeq(SequenceI aaSeqRef)\r
+ {\r
+ if (aaSeqs==null)\r
+ {\r
+ return null;\r
+ }\r
+ SequenceI aads = aaSeqRef.getDatasetSequence();\r
+ for (int as=0;as<aaSeqs.length; as++)\r
+ {\r
+ if (aaSeqs[as]==aaSeqRef || aaSeqs[as]==aads)\r
+ return dnaSeqs[as];\r
+ }\r
+ return null;\r
+ }\r
+ /**\r
+ * test to see if codon frame involves seq in any way\r
+ * @param seq a nucleotide or protein sequence\r
+ * @return true if a mapping exists to or from this sequence to any translated sequence\r
+ */\r
+ public boolean involvesSequence(SequenceI seq)\r
+ {\r
+ return getAaForDnaSeq(seq)!=null || getDnaForAaSeq(seq)!=null;\r
+ }\r
+ /**\r
+ * Add search results for regions in other sequences that translate or are translated from a particular position in seq \r
+ * @param seq\r
+ * @param index position in seq\r
+ * @param results where highlighted regions go\r
+ */\r
+ public void markMappedRegion(SequenceI seq, int index, SearchResults results)\r
+ {\r
+ int[] codon;\r
+ SequenceI ds = seq.getDatasetSequence();\r
+ for (int mi = 0; mi<aaSeqs.length; mi++)\r
+ {\r
+ if (dnaSeqs[mi]==seq || dnaSeqs[mi]==ds)\r
+ {\r
+ // DEBUG System.err.println("dna pos "+index);\r
+ codon = dnaToProt[mi].locateInTo(index,index);\r
+ if (codon!=null)\r
+ {\r
+ for (int i=0; i<codon.length; i+=2)\r
+ {\r
+ results.addResult(aaSeqs[mi], codon[i], codon[i+1]);\r
+ }\r
+ }\r
+ } else\r
+ if (aaSeqs[mi]==seq || aaSeqs[mi]==ds)\r
+ {\r
+ // DEBUG System.err.println("aa pos "+index);\r
+ {\r
+ codon = dnaToProt[mi].locateInFrom(index, index);\r
+ if (codon!=null)\r
+ {\r
+ for (int i=0; i<codon.length; i+=2)\r
+ {\r
+ results.addResult(dnaSeqs[mi], codon[i], codon[i+1]);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
{
return alignmentProperties;
}
+ AlignedCodonFrame[] codonFrameList=null;
+ /* (non-Javadoc)
+ * @see jalview.datamodel.AlignmentI#addCodonFrame(jalview.datamodel.AlignedCodonFrame)
+ */
+ public void addCodonFrame(AlignedCodonFrame codons)
+ {
+ if (codons==null)
+ return;
+ if (codonFrameList==null)
+ {
+ codonFrameList = new AlignedCodonFrame[] { codons };
+ return;
+ }
+ AlignedCodonFrame[] t = new AlignedCodonFrame[codonFrameList.length+1];
+ System.arraycopy(codonFrameList, 0, t, 0, codonFrameList.length);
+ t[codonFrameList.length+1] = codons;
+ codonFrameList = t;
+ }
+ /* (non-Javadoc)
+ * @see jalview.datamodel.AlignmentI#getCodonFrame(int)
+ */
+ public AlignedCodonFrame getCodonFrame(int index)
+ {
+ return codonFrameList[index];
+ }
+
+ /* (non-Javadoc)
+ * @see jalview.datamodel.AlignmentI#getCodonFrame(jalview.datamodel.SequenceI)
+ */
+ public AlignedCodonFrame[] getCodonFrame(SequenceI seq)
+ {
+ if (seq==null || codonFrameList==null)
+ return null;
+ Vector cframes=new Vector();
+ for (int f=0;f<codonFrameList.length; f++)
+ {
+ if (codonFrameList[f].involvesSequence(seq))
+ cframes.add(codonFrameList[f]);
+ }
+ if (cframes.size()==0)
+ return null;
+ AlignedCodonFrame[] cfr = new AlignedCodonFrame[cframes.size()];
+ cframes.copyInto(cfr);
+ return cfr;
+ }
+
+ /* (non-Javadoc)
+ * @see jalview.datamodel.AlignmentI#getCodonFrames()
+ */
+ public AlignedCodonFrame[] getCodonFrames()
+ {
+ return codonFrameList;
+ }
+
+ /* (non-Javadoc)
+ * @see jalview.datamodel.AlignmentI#removeCodonFrame(jalview.datamodel.AlignedCodonFrame)
+ */
+ public boolean removeCodonFrame(AlignedCodonFrame codons)
+ {
+ if (codons==null || codonFrameList==null)
+ return false;
+ boolean removed=false;
+ int i=0,iSize=codonFrameList.length;
+ while (i<iSize)
+ {
+ if (codonFrameList[i]==codons)
+ {
+ removed=true;
+ if (i+1<iSize)
+ {
+ System.arraycopy(codonFrameList,i+1,codonFrameList, i, iSize-i-1);
+ }
+ iSize--;
+ }
+ else
+ {
+ i++;
+ }
+ }
+ return removed;
+ }
}