Merge branch 'feature/JAL-2759' into merge/JAL-2759_2104
authorJim Procter <jprocter@issues.jalview.org>
Tue, 27 Feb 2018 11:16:41 +0000 (11:16 +0000)
committerJim Procter <jprocter@issues.jalview.org>
Tue, 27 Feb 2018 11:16:41 +0000 (11:16 +0000)
13 files changed:
1  2 
src/jalview/appletgui/AnnotationLabels.java
src/jalview/datamodel/Alignment.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/AlignmentPanel.java
src/jalview/gui/AnnotationLabels.java
src/jalview/gui/AnnotationPanel.java
src/jalview/gui/IdCanvas.java
src/jalview/gui/ScalePanel.java
src/jalview/gui/SeqCanvas.java
src/jalview/viewmodel/AlignmentViewport.java
src/jalview/viewmodel/OverviewDimensionsHideHidden.java
src/jalview/viewmodel/OverviewDimensionsShowHidden.java
test/jalview/datamodel/AlignmentTest.java

Simple merge
Simple merge
Simple merge
@@@ -50,9 -49,10 +51,11 @@@ import java.awt.event.MouseEvent
  import java.awt.event.MouseListener;
  import java.awt.event.MouseMotionListener;
  import java.awt.geom.AffineTransform;
+ import java.awt.image.BufferedImage;
 +import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.Collections;
+ import java.util.Iterator;
  import java.util.regex.Pattern;
  
  import javax.swing.JCheckBoxMenuItem;
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -101,10 -97,10 +101,10 @@@ public class OverviewDimensionsShowHidd
      // get mouse location in viewport coords, add translation in viewport
      // coords,
      // convert back to pixel coords
-     int vpx = Math.round(mousex * widthRatio);
-     int visXAsRes = hiddenCols.findColumnPosition(vpx) + xdiff;
+     int vpx = Math.round((float) mousex * alwidth / width);
+     int visXAsRes = hiddenCols.absoluteToVisibleColumn(vpx) + xdiff;
  
 -    int vpy = Math.round((float) mousey * alheight / sequencesHeight);
 +    int vpy = Math.round(mousey * heightRatio);
      int visYAsRes = hiddenSeqs.findIndexWithoutHiddenSeqs(vpy) + ydiff;
  
      // update viewport accordingly
    public void setDragPoint(int x, int y, HiddenSequences hiddenSeqs,
            HiddenColumns hiddenCols)
    {
 +    resetAlignmentDims();
 +
      // get alignment position of x and box (can get directly from vpranges) and
      // calculate difference between the positions
 -    int vpx = Math.round((float) x * alwidth / width);
 -    int vpy = Math.round((float) y * alheight / sequencesHeight);
 +    int vpx = Math.round(x * widthRatio);
 +    int vpy = Math.round(y * heightRatio);
  
-     xdiff = ranges.getStartRes() - hiddenCols.findColumnPosition(vpx);
+     xdiff = ranges.getStartRes() - hiddenCols.absoluteToVisibleColumn(vpx);
      ydiff = ranges.getStartSeq()
              - hiddenSeqs.findIndexWithoutHiddenSeqs(vpy);
    }
@@@ -1333,21 -1323,134 +1334,152 @@@ public class AlignmentTes
      // hidden sequences, properties
    }
  
 +  /**
 +   * test that calcId == null on findOrCreate doesn't raise an NPE, and yields
 +   * an annotation with a null calcId
 +   * 
 +   */
 +  @Test(groups = "Functional")
 +  public void testFindOrCreateForNullCalcId()
 +  {
 +    SequenceI seq = new Sequence("seq1", "FRMLPSRT-A--L-");
 +    AlignmentI alignment = new Alignment(new SequenceI[] { seq });
 +
 +    AlignmentAnnotation ala = alignment.findOrCreateAnnotation(
 +            "Temperature Factor", null, false, seq, null);
 +    assertNotNull(ala);
 +    assertEquals(seq, ala.sequenceRef);
 +    assertEquals("", ala.calcId);
 +  }
++
+   @Test(groups = "Functional")
+   public void testPropagateInsertions()
+   {
+     // create an alignment with no gaps - this will be the profile seq and other
+     // JPRED seqs
+     AlignmentGenerator gen = new AlignmentGenerator(false);
+     AlignmentI al = gen.generate(25, 10, 1234, 0, 0);
+     // get the profileseq
+     SequenceI profileseq = al.getSequenceAt(0);
+     SequenceI gappedseq = new Sequence(profileseq);
+     gappedseq.insertCharAt(5, al.getGapCharacter());
+     gappedseq.insertCharAt(6, al.getGapCharacter());
+     gappedseq.insertCharAt(7, al.getGapCharacter());
+     gappedseq.insertCharAt(8, al.getGapCharacter());
+     // force different kinds of padding
+     al.getSequenceAt(3).deleteChars(2, 23);
+     al.getSequenceAt(4).deleteChars(2, 27);
+     al.getSequenceAt(5).deleteChars(10, 27);
+     // create an alignment view with the gapped sequence
+     SequenceI[] seqs = new SequenceI[1];
+     seqs[0] = gappedseq;
+     AlignmentI newal = new Alignment(seqs);
+     HiddenColumns hidden = new HiddenColumns();
+     hidden.hideColumns(15, 17);
+     AlignmentView view = new AlignmentView(newal, hidden, null, true, false,
+             false);
+     // confirm that original contigs are as expected
+     Iterator<int[]> visible = hidden.getVisContigsIterator(0, 25, false);
+     int[] region = visible.next();
+     assertEquals("[0, 14]", Arrays.toString(region));
+     region = visible.next();
+     assertEquals("[18, 24]", Arrays.toString(region));
+     // propagate insertions
+     HiddenColumns result = al.propagateInsertions(profileseq, view);
+     // confirm that the contigs have changed to account for the gaps
+     visible = result.getVisContigsIterator(0, 25, false);
+     region = visible.next();
+     assertEquals("[0, 10]", Arrays.toString(region));
+     region = visible.next();
+     assertEquals("[14, 24]", Arrays.toString(region));
+     // confirm the alignment has been changed so that the other sequences have
+     // gaps inserted where the columns are hidden
+     assertFalse(Comparison.isGap(al.getSequenceAt(1).getSequence()[10]));
+     assertTrue(Comparison.isGap(al.getSequenceAt(1).getSequence()[11]));
+     assertTrue(Comparison.isGap(al.getSequenceAt(1).getSequence()[12]));
+     assertTrue(Comparison.isGap(al.getSequenceAt(1).getSequence()[13]));
+     assertFalse(Comparison.isGap(al.getSequenceAt(1).getSequence()[14]));
+   }
+   @Test(groups = "Functional")
+   public void testPropagateInsertionsOverlap()
+   {
+     // test propagateInsertions where gaps and hiddenColumns overlap
+     // create an alignment with no gaps - this will be the profile seq and other
+     // JPRED seqs
+     AlignmentGenerator gen = new AlignmentGenerator(false);
+     AlignmentI al = gen.generate(20, 10, 1234, 0, 0);
+     // get the profileseq
+     SequenceI profileseq = al.getSequenceAt(0);
+     SequenceI gappedseq = new Sequence(profileseq);
+     gappedseq.insertCharAt(5, al.getGapCharacter());
+     gappedseq.insertCharAt(6, al.getGapCharacter());
+     gappedseq.insertCharAt(7, al.getGapCharacter());
+     gappedseq.insertCharAt(8, al.getGapCharacter());
+     // create an alignment view with the gapped sequence
+     SequenceI[] seqs = new SequenceI[1];
+     seqs[0] = gappedseq;
+     AlignmentI newal = new Alignment(seqs);
+     // hide columns so that some overlap with the gaps
+     HiddenColumns hidden = new HiddenColumns();
+     hidden.hideColumns(7, 10);
+     AlignmentView view = new AlignmentView(newal, hidden, null, true, false,
+             false);
+     // confirm that original contigs are as expected
+     Iterator<int[]> visible = hidden.getVisContigsIterator(0, 20, false);
+     int[] region = visible.next();
+     assertEquals("[0, 6]", Arrays.toString(region));
+     region = visible.next();
+     assertEquals("[11, 19]", Arrays.toString(region));
+     assertFalse(visible.hasNext());
+     // propagate insertions
+     HiddenColumns result = al.propagateInsertions(profileseq, view);
+     // confirm that the contigs have changed to account for the gaps
+     visible = result.getVisContigsIterator(0, 20, false);
+     region = visible.next();
+     assertEquals("[0, 4]", Arrays.toString(region));
+     region = visible.next();
+     assertEquals("[7, 19]", Arrays.toString(region));
+     assertFalse(visible.hasNext());
+     // confirm the alignment has been changed so that the other sequences have
+     // gaps inserted where the columns are hidden
+     assertFalse(Comparison.isGap(al.getSequenceAt(1).getSequence()[4]));
+     assertTrue(Comparison.isGap(al.getSequenceAt(1).getSequence()[5]));
+     assertTrue(Comparison.isGap(al.getSequenceAt(1).getSequence()[6]));
+     assertFalse(Comparison.isGap(al.getSequenceAt(1).getSequence()[7]));
+   }
+   @Test(groups = { "Functional" })
+   public void testPadGaps()
+   {
+     SequenceI seq1 = new Sequence("seq1", "ABCDEF--");
+     SequenceI seq2 = new Sequence("seq2", "-JKLMNO--");
+     SequenceI seq3 = new Sequence("seq2", "-PQR");
+     AlignmentI a = new Alignment(new SequenceI[] { seq1, seq2, seq3 });
+     a.setGapCharacter('.'); // this replaces existing gaps
+     assertEquals("ABCDEF..", seq1.getSequenceAsString());
+     a.padGaps();
+     // trailing gaps are pruned, short sequences padded with gap character
+     assertEquals("ABCDEF.", seq1.getSequenceAsString());
+     assertEquals(".JKLMNO", seq2.getSequenceAsString());
+     assertEquals(".PQR...", seq3.getSequenceAsString());
+   }
  }