X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fanalysis%2FDna.java;h=9611a4cf99beaf07463b674fbd7f15e6efd3b8a6;hb=4f9cb2ca5ee0d5556c44b223b0cc87334c7df74a;hp=2106dc2136f060e704afa778a535f48f333ef014;hpb=df2bf54c7050c42db156e96e73bbabce63e718d7;p=jalview.git diff --git a/src/jalview/analysis/Dna.java b/src/jalview/analysis/Dna.java index 2106dc2..9611a4c 100644 --- a/src/jalview/analysis/Dna.java +++ b/src/jalview/analysis/Dna.java @@ -44,6 +44,7 @@ import jalview.util.ShiftList; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; +import java.util.Iterator; import java.util.List; public class Dna @@ -56,19 +57,23 @@ public class Dna * 'final' variables describe the inputs to the translation, which should not * be modified. */ - final private List selection; + private final List selection; - final private String[] seqstring; + private final String[] seqstring; - final private int[] contigs; + private final Iterator contigs; - final private char gapChar; + private final char gapChar; - final private AlignmentAnnotation[] annotations; + private final AlignmentAnnotation[] annotations; - final private int dnaWidth; + private final int dnaWidth; - final private AlignmentI dataset; + private final AlignmentI dataset; + + private ShiftList vismapping; + + private int[] startcontigs; /* * Working variables for the translation. @@ -91,7 +96,7 @@ public class Dna * @param viewport * @param visibleContigs */ - public Dna(AlignViewportI viewport, int[] visibleContigs) + public Dna(AlignViewportI viewport, Iterator visibleContigs) { this.selection = Arrays.asList(viewport.getSequenceSelection()); this.seqstring = viewport.getViewAsString(true); @@ -100,6 +105,45 @@ public class Dna this.annotations = viewport.getAlignment().getAlignmentAnnotation(); this.dnaWidth = viewport.getAlignment().getWidth(); this.dataset = viewport.getAlignment().getDataset(); + initContigs(); + } + + /** + * Initialise contigs used as starting point for translateCodingRegion + */ + private void initContigs() + { + vismapping = new ShiftList(); // map from viscontigs to seqstring + // intervals + + int npos = 0; + int[] lastregion = null; + ArrayList tempcontigs = new ArrayList<>(); + while (contigs.hasNext()) + { + int[] region = contigs.next(); + if (lastregion == null) + { + vismapping.addShift(npos, region[0]); + } + else + { + // hidden region + vismapping.addShift(npos, region[0] - lastregion[1] + 1); + } + lastregion = region; + tempcontigs.add(region[0]); + tempcontigs.add(region[1]); + } + + startcontigs = new int[tempcontigs.size()]; + int i = 0; + for (Integer val : tempcontigs) + { + startcontigs[i] = val; + i++; + } + tempcontigs = null; } /** @@ -133,7 +177,8 @@ public class Dna * @param ac2 * @return */ - private static int jalview_2_8_2compare(AlignedCodon ac1, AlignedCodon ac2) + private static int jalview_2_8_2compare(AlignedCodon ac1, + AlignedCodon ac2) { if (ac1 == null || ac2 == null || (ac1.equals(ac2))) { @@ -149,10 +194,11 @@ public class Dna } /** + * Translates cDNA using the specified code table * * @return */ - public AlignmentI translateCdna() + public AlignmentI translateCdna(GeneticCodeI codeTable) { AlignedCodonFrame acf = new AlignedCodonFrame(); @@ -160,11 +206,11 @@ public class Dna int s; int sSize = selection.size(); - List pepseqs = new ArrayList(); + List pepseqs = new ArrayList<>(); for (s = 0; s < sSize; s++) { SequenceI newseq = translateCodingRegion(selection.get(s), - seqstring[s], acf, pepseqs); + seqstring[s], acf, pepseqs, codeTable); if (newseq != null) { @@ -212,7 +258,7 @@ public class Dna if (dnarefs != null) { // intersect with pep - List mappedrefs = new ArrayList(); + List mappedrefs = new ArrayList<>(); DBRefEntry[] refs = dna.getDBRefs(); for (int d = 0; d < refs.length; d++) { @@ -384,33 +430,21 @@ public class Dna * @param acf * Definition of global ORF alignment reference frame * @param proteinSeqs + * @param codeTable * @return sequence ready to be added to alignment. */ protected SequenceI translateCodingRegion(SequenceI selection, String seqstring, AlignedCodonFrame acf, - List proteinSeqs) + List proteinSeqs, GeneticCodeI codeTable) { - List skip = new ArrayList(); - int skipint[] = null; - ShiftList vismapping = new ShiftList(); // map from viscontigs to seqstring - // intervals - int vc; - int[] scontigs = new int[contigs.length]; + List skip = new ArrayList<>(); + int[] skipint = null; + int npos = 0; - for (vc = 0; vc < contigs.length; vc += 2) - { - if (vc == 0) - { - vismapping.addShift(npos, contigs[vc]); - } - else - { - // hidden region - vismapping.addShift(npos, contigs[vc] - contigs[vc - 1] + 1); - } - scontigs[vc] = contigs[vc]; - scontigs[vc + 1] = contigs[vc + 1]; - } + int vc = 0; + + int[] scontigs = new int[startcontigs.length]; + System.arraycopy(startcontigs, 0, scontigs, 0, startcontigs.length); // allocate a roughly sized buffer for the protein sequence StringBuilder protein = new StringBuilder(seqstring.length() / 2); @@ -435,7 +469,7 @@ public class Dna * Filled up a reading frame... */ AlignedCodon alignedCodon = new AlignedCodon(cdp[0], cdp[1], cdp[2]); - String aa = ResidueProperties.codonTranslate(new String(codon)); + String aa = codeTable.translate(new String(codon)); rf = 0; final String gapString = String.valueOf(gapChar); if (aa == null) @@ -443,10 +477,11 @@ public class Dna aa = gapString; if (skipint == null) { - skipint = new int[] { alignedCodon.pos1, alignedCodon.pos3 /* - * cdp[0], - * cdp[2] - */}; + skipint = new int[] { alignedCodon.pos1, + alignedCodon.pos3 /* + * cdp[0], + * cdp[2] + */ }; } skipint[1] = alignedCodon.pos3; // cdp[2]; } @@ -501,8 +536,8 @@ public class Dna } if (vc + 2 < t.length) { - System.arraycopy(scontigs, vc + 2, t, vc, t.length - - vc + 2); + System.arraycopy(scontigs, vc + 2, t, vc, + t.length - vc + 2); } scontigs = t; } @@ -541,7 +576,7 @@ public class Dna skip.add(skipint); skipint = null; } - if (aa.equals("STOP")) + if (aa.equals(ResidueProperties.STOP)) { aa = STOP_ASTERIX; } @@ -595,9 +630,9 @@ public class Dna } else if (!alignedCodons[aspos].equals(alignedCodon)) { - throw new IllegalStateException("Tried to coalign " - + alignedCodons[aspos].toString() + " with " - + alignedCodon.toString()); + throw new IllegalStateException( + "Tried to coalign " + alignedCodons[aspos].toString() + + " with " + alignedCodon.toString()); } if (aspos >= aaWidth) { @@ -797,7 +832,7 @@ public class Dna public AlignmentI reverseCdna(boolean complement) { int sSize = selection.size(); - List reversed = new ArrayList(); + List reversed = new ArrayList<>(); for (int s = 0; s < sSize; s++) { SequenceI newseq = reverseSequence(selection.get(s).getName(), @@ -848,6 +883,23 @@ public class Dna } /** + * Answers the reverse complement of the input string + * + * @see #getComplement(char) + * @param s + * @return + */ + public static String reverseComplement(String s) + { + StringBuilder sb = new StringBuilder(s.length()); + for (int i = s.length() - 1; i >= 0; i--) + { + sb.append(Dna.getComplement(s.charAt(i))); + } + return sb.toString(); + } + + /** * Returns dna complement (preserving case) for aAcCgGtTuU. Ambiguity codes * are treated as on http://reverse-complement.com/. Anything else is left * unchanged.