Merge branch 'alpha/JAL-3362_Jalview_212_alpha' into alpha/merge_212_JalviewJS_2112
[jalview.git] / test / jalview / datamodel / AlignmentTest.java
index 74ac146..a3f9096 100644 (file)
@@ -34,6 +34,7 @@ import jalview.io.DataSourceType;
 import jalview.io.FileFormat;
 import jalview.io.FileFormatI;
 import jalview.io.FormatAdapter;
+import jalview.util.Comparison;
 import jalview.util.MapList;
 
 import java.io.IOException;
@@ -247,7 +248,9 @@ public class AlignmentTest
                   if (raiseAssert)
                   {
                     Assert.fail(message
-                            + " DBRefEntry for sequence in alignment had map to sequence not in dataset");
+                            + " DBRefEntry " + dbr + " for sequence "
+                            + seqds
+                            + " in alignment has map to sequence not in dataset");
                   }
                   return false;
                 }
@@ -1170,14 +1173,14 @@ public class AlignmentTest
     /*
      * verify peptide.cdsdbref.peptidedbref is now mapped to peptide dataset
      */
-    DBRefEntry[] dbRefs = pep.getDBRefs();
-    assertEquals(2, dbRefs.length);
-    assertSame(dna, dbRefs[0].map.to);
-    assertSame(cds, dbRefs[1].map.to);
-    assertEquals(1, dna.getDBRefs().length);
-    assertSame(pep.getDatasetSequence(), dna.getDBRefs()[0].map.to);
-    assertEquals(1, cds.getDBRefs().length);
-    assertSame(pep.getDatasetSequence(), cds.getDBRefs()[0].map.to);
+    List<DBRefEntry> dbRefs = pep.getDBRefs();
+    assertEquals(2, dbRefs.size());
+    assertSame(dna, dbRefs.get(0).map.to);
+    assertSame(cds, dbRefs.get(1).map.to);
+    assertEquals(1, dna.getDBRefs().size());
+    assertSame(pep.getDatasetSequence(), dna.getDBRefs().get(0).map.to);
+    assertEquals(1, cds.getDBRefs().size());
+    assertSame(pep.getDatasetSequence(), cds.getDBRefs().get(0).map.to);
   }
 
   @Test(groups = { "Functional" })
@@ -1348,6 +1351,243 @@ public class AlignmentTest
             "Temperature Factor", null, false, seq, null);
     assertNotNull(ala);
     assertEquals(seq, ala.sequenceRef);
-    assertEquals("", ala.calcId);
+    assertEquals("", ala.getCalcId());
+  }
+
+  @Test(groups = {"Functional"})
+  public void testUpdateFromOrAddAnnotation()
+  {
+    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.getCalcId());
+
+    // Assuming findOrCreateForNullCalcId passed then this should work
+
+    assertTrue(ala == alignment.updateFromOrCopyAnnotation(ala));
+    AlignmentAnnotation updatedAla = new AlignmentAnnotation(ala);
+    updatedAla.description = "updated Description";
+    Assert.assertTrue(
+            ala == alignment.updateFromOrCopyAnnotation(updatedAla));
+    Assert.assertEquals(ala.toString(), updatedAla.toString());
+    updatedAla.calcId = "newCalcId";
+    AlignmentAnnotation newUpdatedAla = alignment
+            .updateFromOrCopyAnnotation(updatedAla);
+    Assert.assertTrue(updatedAla != newUpdatedAla);
+    Assert.assertEquals(updatedAla.toString(), newUpdatedAla.toString());
+  }
+
+  @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());
+  }
+
+  /**
+   * Test for setHiddenColumns, to check it returns true if the hidden columns
+   * have changed, else false
+   */
+  @Test(groups = { "Functional" })
+  public void testSetHiddenColumns()
+  {
+    AlignmentI al = new Alignment(new SequenceI[] {});
+    assertFalse(al.getHiddenColumns().hasHiddenColumns());
+
+    HiddenColumns hc = new HiddenColumns();
+    assertFalse(al.setHiddenColumns(hc)); // no change
+    assertSame(hc, al.getHiddenColumns());
+
+    hc.hideColumns(2, 4);
+    assertTrue(al.getHiddenColumns().hasHiddenColumns());
+
+    /*
+     * set a different object but with the same columns hidden
+     */
+    HiddenColumns hc2 = new HiddenColumns();
+    hc2.hideColumns(2, 4);
+    assertFalse(al.setHiddenColumns(hc2)); // no change
+    assertSame(hc2, al.getHiddenColumns());
+
+    assertTrue(al.setHiddenColumns(null));
+    assertNull(al.getHiddenColumns());
+    assertTrue(al.setHiddenColumns(hc));
+    assertSame(hc, al.getHiddenColumns());
+
+    al.getHiddenColumns().hideColumns(10, 12);
+    hc2.hideColumns(10, 12);
+    assertFalse(al.setHiddenColumns(hc2)); // no change
+
+    /*
+     * hide columns 15-16 then 17-18 in hc
+     * hide columns 15-18 in hc2
+     * these are not now 'equal' objects even though they
+     * represent the same set of columns
+     */
+    assertSame(hc2, al.getHiddenColumns());
+    hc.hideColumns(15, 16);
+    hc.hideColumns(17, 18);
+    hc2.hideColumns(15, 18);
+    assertFalse(hc.equals(hc2));
+    assertTrue(al.setHiddenColumns(hc)); // 'changed'
+  }
+
+  @Test(groups = { "Functional" })
+  public void testGetWidth()
+  {
+    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 });
+
+    assertEquals(9, a.getWidth());
+
+    // width includes hidden columns
+    a.getHiddenColumns().hideColumns(2, 5);
+    assertEquals(9, a.getWidth());
+  }
+
+  @Test(groups = { "Functional" })
+  public void testGetVisibleWidth()
+  {
+    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 });
+
+    assertEquals(9, a.getVisibleWidth());
+
+    // width excludes hidden columns
+    a.getHiddenColumns().hideColumns(2, 5);
+    assertEquals(5, a.getVisibleWidth());
   }
 }