X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fanalysis%2FAlignmentUtils.java;h=1b8f84f6a849c878bfc0228d827ede402717740b;hb=3d0101179759ef157b088ea135423cd909512d9f;hp=ba3cd6008723ca88bffda1261706cfad4b4838f6;hpb=db93a1adcbe0a4eaaf06e0a70ade0d6c5c1961c3;p=jalview.git diff --git a/src/jalview/analysis/AlignmentUtils.java b/src/jalview/analysis/AlignmentUtils.java index ba3cd60..1b8f84f 100644 --- a/src/jalview/analysis/AlignmentUtils.java +++ b/src/jalview/analysis/AlignmentUtils.java @@ -1,6 +1,6 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9.0b2) - * Copyright (C) 2015 The Jalview Authors + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors * * This file is part of Jalview. * @@ -42,6 +42,7 @@ import jalview.util.Comparison; import jalview.util.DBRefUtils; import jalview.util.MapList; import jalview.util.MappingUtils; +import jalview.util.RangeComparator; import jalview.util.StringUtils; import java.io.UnsupportedEncodingException; @@ -60,6 +61,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.NoSuchElementException; import java.util.Set; +import java.util.SortedMap; import java.util.TreeMap; /** @@ -169,10 +171,12 @@ public class AlignmentUtils } } // TODO use Character.toLowerCase to avoid creating String objects? - char[] upstream = new String(ds.getSequence(s.getStart() - 1 - - ustream_ds, s.getStart() - 1)).toLowerCase().toCharArray(); - char[] downstream = new String(ds.getSequence(s_end - 1, s_end - + dstream_ds)).toLowerCase().toCharArray(); + char[] upstream = new String(ds + .getSequence(s.getStart() - 1 - ustream_ds, s.getStart() - 1)) + .toLowerCase().toCharArray(); + char[] downstream = new String( + ds.getSequence(s_end - 1, s_end + dstream_ds)).toLowerCase() + .toCharArray(); char[] coreseq = s.getSequence(); char[] nseq = new char[offset + upstream.length + downstream.length + coreseq.length]; @@ -187,8 +191,8 @@ public class AlignmentUtils System.arraycopy(upstream, 0, nseq, p, upstream.length); System.arraycopy(coreseq, 0, nseq, p + upstream.length, coreseq.length); - System.arraycopy(downstream, 0, nseq, p + coreseq.length - + upstream.length, downstream.length); + System.arraycopy(downstream, 0, nseq, + p + coreseq.length + upstream.length, downstream.length); s.setSequence(new String(nseq)); s.setStart(s.getStart() - ustream_ds); s.setEnd(s_end + downstream.length); @@ -315,9 +319,9 @@ public class AlignmentUtils * @return */ protected static boolean mapProteinToCdna( - final AlignmentI proteinAlignment, - final AlignmentI cdnaAlignment, Set mappedDna, - Set mappedProtein, boolean xrefsOnly) + final AlignmentI proteinAlignment, final AlignmentI cdnaAlignment, + Set mappedDna, Set mappedProtein, + boolean xrefsOnly) { boolean mappingExistsOrAdded = false; List thisSeqs = proteinAlignment.getSequences(); @@ -346,9 +350,8 @@ public class AlignmentUtils * Don't map non-xrefd sequences more than once each. This heuristic * allows us to pair up similar sequences in ordered alignments. */ - if (!xrefsOnly - && (mappedProtein.contains(aaSeq) || mappedDna - .contains(cdnaSeq))) + if (!xrefsOnly && (mappedProtein.contains(aaSeq) + || mappedDna.contains(cdnaSeq))) { continue; } @@ -401,7 +404,8 @@ public class AlignmentUtils /** * Builds a mapping (if possible) of a cDNA to a protein sequence. *
    - *
  • first checks if the cdna translates exactly to the protein sequence
  • + *
  • first checks if the cdna translates exactly to the protein + * sequence
  • *
  • else checks for translation after removing a STOP codon
  • *
  • else checks for translation after removing a START codon
  • *
  • if that fails, inspect CDS features on the cDNA sequence
  • @@ -423,8 +427,9 @@ public class AlignmentUtils * String objects. */ final SequenceI proteinDataset = proteinSeq.getDatasetSequence(); - char[] aaSeqChars = proteinDataset != null ? proteinDataset - .getSequence() : proteinSeq.getSequence(); + char[] aaSeqChars = proteinDataset != null + ? proteinDataset.getSequence() + : proteinSeq.getSequence(); final SequenceI cdnaDataset = cdnaSeq.getDatasetSequence(); char[] cdnaSeqChars = cdnaDataset != null ? cdnaDataset.getSequence() : cdnaSeq.getSequence(); @@ -465,8 +470,7 @@ public class AlignmentUtils * If lengths still don't match, try ignoring start codon. */ int startOffset = 0; - if (cdnaLength != mappedLength - && cdnaLength > 2 + if (cdnaLength != mappedLength && cdnaLength > 2 && String.valueOf(cdnaSeqChars, 0, CODON_LENGTH).toUpperCase() .equals(ResidueProperties.START)) { @@ -480,8 +484,9 @@ public class AlignmentUtils /* * protein is translation of dna (+/- start/stop codons) */ - MapList map = new MapList(new int[] { cdnaStart, cdnaEnd }, new int[] - { proteinStart, proteinEnd }, CODON_LENGTH, 1); + MapList map = new MapList(new int[] { cdnaStart, cdnaEnd }, + new int[] + { proteinStart, proteinEnd }, CODON_LENGTH, 1); return map; } @@ -511,7 +516,8 @@ public class AlignmentUtils int aaPos = 0; int dnaPos = cdnaStart; - for (; dnaPos < cdnaSeqChars.length - 2 && aaPos < aaSeqChars.length; dnaPos += CODON_LENGTH, aaPos++) + for (; dnaPos < cdnaSeqChars.length - 2 + && aaPos < aaSeqChars.length; dnaPos += CODON_LENGTH, aaPos++) { String codon = String.valueOf(cdnaSeqChars, dnaPos, CODON_LENGTH); final String translated = ResidueProperties.codonTranslate(codon); @@ -630,10 +636,9 @@ public class AlignmentUtils * @param preserveUnmappedGaps * @param preserveMappedGaps */ - public static void alignSequenceAs(SequenceI alignTo, - SequenceI alignFrom, AlignedCodonFrame mapping, String myGap, - char sourceGap, boolean preserveMappedGaps, - boolean preserveUnmappedGaps) + public static void alignSequenceAs(SequenceI alignTo, SequenceI alignFrom, + AlignedCodonFrame mapping, String myGap, char sourceGap, + boolean preserveMappedGaps, boolean preserveUnmappedGaps) { // TODO generalise to work for Protein-Protein, dna-dna, dna-protein @@ -828,8 +833,9 @@ public class AlignmentUtils } else { - gapsToAdd = Math.min(intronLength + trailingGapLength - - sourceGapMappedLength, trailingGapLength); + gapsToAdd = Math.min( + intronLength + trailingGapLength - sourceGapMappedLength, + trailingGapLength); } } } @@ -928,7 +934,8 @@ public class AlignmentUtils * @return */ static boolean alignCdsSequenceAsProtein(SequenceI cdsSeq, - AlignmentI protein, List mappings, char gapChar) + AlignmentI protein, List mappings, + char gapChar) { SequenceI cdsDss = cdsSeq.getDatasetSequence(); if (cdsDss == null) @@ -955,20 +962,19 @@ public class AlignmentUtils mapList = mapList.getInverse(); } int cdsLength = cdsDss.getLength(); - int mappedFromLength = MappingUtils.getLength(mapList - .getFromRanges()); + int mappedFromLength = MappingUtils + .getLength(mapList.getFromRanges()); int mappedToLength = MappingUtils .getLength(mapList.getToRanges()); boolean addStopCodon = (cdsLength == mappedFromLength * CODON_LENGTH + CODON_LENGTH) - || (peptide.getDatasetSequence().getLength() == mappedFromLength - 1); + || (peptide.getDatasetSequence() + .getLength() == mappedFromLength - 1); if (cdsLength != mappedToLength && !addStopCodon) { - System.err - .println(String - .format("Can't align cds as protein (length mismatch %d/%d): %s", - cdsLength, mappedToLength, - cdsSeq.getName())); + System.err.println(String.format( + "Can't align cds as protein (length mismatch %d/%d): %s", + cdsLength, mappedToLength, cdsSeq.getName())); } /* @@ -1029,7 +1035,8 @@ public class AlignmentUtils break; } } - for (int i = nucleotides.length - CODON_LENGTH; i < nucleotides.length; i++) + for (int i = nucleotides.length + - CODON_LENGTH; i < nucleotides.length; i++) { alignedCds[cdsCol++] = nucleotides[i]; } @@ -1085,8 +1092,8 @@ public class AlignmentUtils if (prot != null) { Mapping seqMap = mapping.getMappingForSequence(dnaSeq); - addCodonPositions(dnaSeq, prot, protein.getGapCharacter(), - seqMap, alignedCodons); + addCodonPositions(dnaSeq, prot, protein.getGapCharacter(), seqMap, + alignedCodons); unmappedProtein.remove(prot); } } @@ -1139,8 +1146,8 @@ public class AlignmentUtils AlignedCodon codon = sequenceCodon.getValue(); if (codon.peptideCol > 1) { - System.err - .println("Problem mapping protein with >1 unmapped start positions: " + System.err.println( + "Problem mapping protein with >1 unmapped start positions: " + seq.getName()); } else if (codon.peptideCol == 1) @@ -1151,8 +1158,8 @@ public class AlignmentUtils if (lastCodon != null) { AlignedCodon firstPeptide = new AlignedCodon(lastCodon.pos1, - lastCodon.pos2, lastCodon.pos3, String.valueOf(seq - .getCharAt(0)), 0); + lastCodon.pos2, lastCodon.pos3, + String.valueOf(seq.getCharAt(0)), 0); toAdd.put(seq, firstPeptide); } else @@ -1301,7 +1308,8 @@ public class AlignmentUtils *
      *
    • One alignment must be nucleotide, and the other protein
    • *
    • At least one pair of sequences must be already mapped, or mappable
    • - *
    • Mappable means the nucleotide translation matches the protein sequence
    • + *
    • Mappable means the nucleotide translation matches the protein + * sequence
    • *
    • The translation may ignore start and stop codons if present in the * nucleotide
    • *
    @@ -1357,9 +1365,10 @@ public class AlignmentUtils return false; } - SequenceI dnaDs = dnaSeq.getDatasetSequence() == null ? dnaSeq : dnaSeq - .getDatasetSequence(); - SequenceI proteinDs = proteinSeq.getDatasetSequence() == null ? proteinSeq + SequenceI dnaDs = dnaSeq.getDatasetSequence() == null ? dnaSeq + : dnaSeq.getDatasetSequence(); + SequenceI proteinDs = proteinSeq.getDatasetSequence() == null + ? proteinSeq : proteinSeq.getDatasetSequence(); for (AlignedCodonFrame mapping : mappings) @@ -1396,8 +1405,7 @@ public class AlignmentUtils * the alignment to check for presence of annotations */ public static void findAddableReferenceAnnotations( - List sequenceScope, - Map labelForCalcId, + List sequenceScope, Map labelForCalcId, final Map> candidates, AlignmentI al) { @@ -1501,8 +1509,8 @@ public class AlignmentUtils /** * Set visibility of alignment annotations of specified types (labels), for - * specified sequences. This supports controls like - * "Show all secondary structure", "Hide all Temp factor", etc. + * specified sequences. This supports controls like "Show all secondary + * structure", "Hide all Temp factor", etc. * * @al the alignment to scan for annotations * @param types @@ -1526,9 +1534,8 @@ public class AlignmentUtils { if (anyType || types.contains(aa.label)) { - if ((aa.sequenceRef != null) - && (forSequences == null || forSequences - .contains(aa.sequenceRef))) + if ((aa.sequenceRef != null) && (forSequences == null + || forSequences.contains(aa.sequenceRef))) { aa.visible = doShow; } @@ -1616,8 +1623,8 @@ public class AlignmentUtils productSeqs = new HashSet(); for (SequenceI seq : products) { - productSeqs.add(seq.getDatasetSequence() == null ? seq : seq - .getDatasetSequence()); + productSeqs.add(seq.getDatasetSequence() == null ? seq + : seq.getDatasetSequence()); } } @@ -1710,8 +1717,9 @@ public class AlignmentUtils /* * add a mapping from CDS to the (unchanged) mapped to range */ - List cdsRange = Collections.singletonList(new int[] { 1, - cdsSeq.getLength() }); + List cdsRange = Collections + .singletonList(new int[] + { 1, cdsSeq.getLength() }); MapList cdsToProteinMap = new MapList(cdsRange, mapList.getToRanges(), mapList.getFromRatio(), mapList.getToRatio()); @@ -1776,12 +1784,11 @@ public class AlignmentUtils // 'CDS|emblcdsacc' // assuming cds version same as dna ?!? - DBRefEntry proteinToCdsRef = new DBRefEntry( - primRef.getSource(), primRef.getVersion(), - cdsSeq.getName()); + DBRefEntry proteinToCdsRef = new DBRefEntry(primRef.getSource(), + primRef.getVersion(), cdsSeq.getName()); // - proteinToCdsRef.setMap(new Mapping(cdsSeqDss, cdsToProteinMap - .getInverse())); + proteinToCdsRef.setMap( + new Mapping(cdsSeqDss, cdsToProteinMap.getInverse())); proteinProduct.addDBRef(proteinToCdsRef); } @@ -1794,8 +1801,8 @@ public class AlignmentUtils } } - AlignmentI cds = new Alignment(cdsSeqs.toArray(new SequenceI[cdsSeqs - .size()])); + AlignmentI cds = new Alignment( + cdsSeqs.toArray(new SequenceI[cdsSeqs.size()])); cds.setDataset(dataset); return cds; @@ -1832,8 +1839,8 @@ public class AlignmentUtils * is this mapping from the whole dna sequence (i.e. CDS)? * allowing for possible stop codon on dna but not peptide */ - int mappedFromLength = MappingUtils.getLength(aMapping.getMap() - .getFromRanges()); + int mappedFromLength = MappingUtils + .getLength(aMapping.getMap().getFromRanges()); int dnaLength = seqDss.getLength(); if (mappedFromLength == dnaLength || mappedFromLength == dnaLength - CODON_LENGTH) @@ -1857,8 +1864,8 @@ public class AlignmentUtils && proteinProduct == mapping.getTo() && seqDss != map.getFromSeq()) { - mappedFromLength = MappingUtils.getLength(mapping.getMap() - .getFromRanges()); + mappedFromLength = MappingUtils + .getLength(mapping.getMap().getFromRanges()); if (mappedFromLength == map.getFromSeq().getLength()) { /* @@ -1956,8 +1963,8 @@ public class AlignmentUtils } else { - System.err - .println("JAL-2154 regression: warning - found (and ignnored a duplicate CDS sequence):" + System.err.println( + "JAL-2154 regression: warning - found (and ignnored a duplicate CDS sequence):" + mtch.toString()); } } @@ -2009,16 +2016,17 @@ public class AlignmentUtils for (DBRefEntry cdsref : direct) { // clone maplist and mapping - MapList cdsposmap = new MapList(Arrays.asList(new int[][] { new int[] - { cdsSeq.getStart(), cdsSeq.getEnd() } }), cdsref.getMap().getMap() - .getToRanges(), 3, 1); - Mapping cdsmap = new Mapping(cdsref.getMap().getTo(), cdsref.getMap() - .getMap()); + MapList cdsposmap = new MapList( + Arrays.asList(new int[][] + { new int[] { cdsSeq.getStart(), cdsSeq.getEnd() } }), + cdsref.getMap().getMap().getToRanges(), 3, 1); + Mapping cdsmap = new Mapping(cdsref.getMap().getTo(), + cdsref.getMap().getMap()); // create dbref DBRefEntry newref = new DBRefEntry(cdsref.getSource(), - cdsref.getVersion(), cdsref.getAccessionId(), new Mapping( - cdsmap.getTo(), cdsposmap)); + cdsref.getVersion(), cdsref.getAccessionId(), + new Mapping(cdsmap.getTo(), cdsposmap)); // and see if we can map to the protein product for this mapping. // onSource is the filtered set of accessions on protein that we are @@ -2238,8 +2246,8 @@ public class AlignmentUtils if (begin > end) { // shouldn't happen! - System.err - .println("Error: start phase extends beyond start CDS in " + System.err.println( + "Error: start phase extends beyond start CDS in " + dnaSeq.getName()); } } @@ -2264,14 +2272,7 @@ public class AlignmentUtils * ranges are assembled in order. Other cases should not use this method, * but instead construct an explicit mapping for CDS (e.g. EMBL parsing). */ - Collections.sort(result, new Comparator() - { - @Override - public int compare(int[] o1, int[] o2) - { - return Integer.compare(o1[0], o2[0]); - } - }); + Collections.sort(result, new RangeComparator(true)); return result; } @@ -2460,8 +2461,8 @@ public class AlignmentUtils * are currently ignored here */ String trans = codon.contains("-") ? "-" - : (codon.length() > CODON_LENGTH ? null : ResidueProperties - .codonTranslate(codon)); + : (codon.length() > CODON_LENGTH ? null + : ResidueProperties.codonTranslate(codon)); if (trans != null && !trans.equals(residue)) { String residue3Char = StringUtils @@ -2487,10 +2488,8 @@ public class AlignmentUtils StringBuilder link = new StringBuilder(32); try { - link.append(desc) - .append(" ") - .append(id) - .append("|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=") + link.append(desc).append(" ").append(id).append( + "|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=") .append(URLEncoder.encode(id, "UTF-8")); sf.addLink(link.toString()); } catch (UnsupportedEncodingException e) @@ -2593,8 +2592,8 @@ public class AlignmentUtils * get this peptide's codon positions e.g. [3, 4, 5] or [4, 7, 10] */ int[] codon = peptidePosition == lastPeptidePostion ? lastCodon - : MappingUtils.flattenRanges(dnaToProtein.locateInFrom( - peptidePosition, peptidePosition)); + : MappingUtils.flattenRanges(dnaToProtein + .locateInFrom(peptidePosition, peptidePosition)); lastPeptidePostion = peptidePosition; lastCodon = codon; @@ -2603,8 +2602,8 @@ public class AlignmentUtils */ for (int codonPos = 0; codonPos < CODON_LENGTH; codonPos++) { - String nucleotide = String.valueOf( - dnaSeq.getCharAt(codon[codonPos] - dnaStart)) + String nucleotide = String + .valueOf(dnaSeq.getCharAt(codon[codonPos] - dnaStart)) .toUpperCase(); List codonVariant = codonVariants[codonPos]; if (codon[codonPos] == dnaCol) @@ -2816,8 +2815,8 @@ public class AlignmentUtils */ for (SequenceI seq : unaligned.getSequences()) { - List alignedSequences = alignedDatasets.get(seq - .getDatasetSequence()); + List alignedSequences = alignedDatasets + .get(seq.getDatasetSequence()); // TODO: getSequenceAsString() will be deprecated in the future // TODO: need to leave to SequenceI implementor to update gaps seq.setSequence(alignedSequences.get(0).getSequenceAsString()); @@ -2840,15 +2839,16 @@ public class AlignmentUtils * @param unmapped * @return */ - static Map> buildMappedColumnsMap( - AlignmentI unaligned, AlignmentI aligned, List unmapped) + static SortedMap> buildMappedColumnsMap( + AlignmentI unaligned, AlignmentI aligned, + List unmapped) { /* * Map will hold, for each aligned column position, a map of * {unalignedSequence, characterPerSequence} at that position. * TreeMap keeps the entries in ascending column order. */ - Map> map = new TreeMap>(); + SortedMap> map = new TreeMap>(); /* * record any sequences that have no mapping so can't be realigned @@ -2876,7 +2876,8 @@ public class AlignmentUtils } /** - * Helper method that adds to a map the mapped column positions of a sequence.
    + * Helper method that adds to a map the mapped column positions of a sequence. + *
    * For example if aaTT-Tg-gAAA is mapped to TTTAAA then the map should record * that columns 3,4,6,10,11,12 map to characters T,T,T,A,A,A of the mapped to * sequence. @@ -2905,8 +2906,8 @@ public class AlignmentUtils */ if (seqMap.getTo() == fromSeq.getDatasetSequence()) { - seqMap = new Mapping(seq.getDatasetSequence(), seqMap.getMap() - .getInverse()); + seqMap = new Mapping(seq.getDatasetSequence(), + seqMap.getMap().getInverse()); } char[] fromChars = fromSeq.getSequence();