*/
package jalview.analysis;
+import static org.testng.Assert.assertNotEquals;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertSame;
import static org.testng.AssertJUnit.assertTrue;
-import jalview.analysis.AlignmentUtils.DnaVariant;
+import java.awt.Color;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.Annotation;
+import jalview.datamodel.ContactListI;
+import jalview.datamodel.ContactMatrixI;
import jalview.datamodel.DBRefEntry;
import jalview.datamodel.GeneLociI;
import jalview.datamodel.Mapping;
import jalview.datamodel.SearchResultMatchI;
import jalview.datamodel.SearchResultsI;
+import jalview.datamodel.SeqDistanceContactMatrix;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
-import jalview.datamodel.features.SequenceFeatures;
import jalview.gui.JvOptionPane;
import jalview.io.AppletFormatAdapter;
import jalview.io.DataSourceType;
import jalview.io.FileFormatI;
import jalview.io.FormatAdapter;
import jalview.io.gff.SequenceOntologyI;
+import jalview.util.Comparison;
import jalview.util.MapList;
import jalview.util.MappingUtils;
-import jalview.ws.params.InvalidArgumentException;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
public class AlignmentUtilsTests
{
{
JvOptionPane.setInteractiveMode(false);
JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+
+ AlignmentAnnotation ann1 = new AlignmentAnnotation("Secondary Structure", "Secondary Structure",
+ new Annotation[] {});
+ AlignmentAnnotation ann2 = new AlignmentAnnotation("jnetpred", "jnetpred",
+ new Annotation[] {});
+ AlignmentAnnotation ann3 = new AlignmentAnnotation("Temp", "Temp",
+ new Annotation[] {});
+ AlignmentAnnotation ann4 = new AlignmentAnnotation("Temp", "Temp",
+ new Annotation[] {});
+
+ AlignmentAnnotation[] anns1 = new AlignmentAnnotation[] {ann1, ann3, ann4};
+
+ AlignmentAnnotation[] anns2 = new AlignmentAnnotation[] {ann2, ann3, ann4};
+
+ AlignmentAnnotation[] anns3 = new AlignmentAnnotation[] {ann3, ann4};
+
+ AlignmentAnnotation[] anns4 = new AlignmentAnnotation[0];
+
+ AlignmentAnnotation[] anns5 = new AlignmentAnnotation[] {ann1, ann2, ann3, ann4};
}
@Test(groups = { "Functional" })
* the given protein. That is, given a transcript-to-peptide mapping, find the
* cds-to-peptide mapping that relates to both, and return the CDS sequence.
*/
- @Test
+ @Test(groups = "Functional")
public void testFindCdsForProtein()
{
List<AlignedCodonFrame> mappings = new ArrayList<>();
* cds-to-peptide mapping that relates to both, and return the CDS sequence.
* This test is for the case where transcript and CDS are the same length.
*/
- @Test
+ @Test(groups = "Functional")
public void testFindCdsForProtein_noUTR()
{
List<AlignedCodonFrame> mappings = new ArrayList<>();
}
@Test(groups = "Functional")
+ public void testAddReferenceAnnotations()
+ {
+ SequenceI longseq = new Sequence("longA", "ASDASDASDASDAASDASDASDASDA");
+ Annotation[] aa = new Annotation[longseq.getLength()];
+
+ for (int p = 0; p < aa.length; p++)
+ {
+ aa[p] = new Annotation("P", "pos " + (p + 1), (char) 0,
+ (float) p + 1);
+ }
+ AlignmentAnnotation refAnnot = new AlignmentAnnotation("LongSeqAnnot",
+ "Annotations", aa);
+ refAnnot.setCalcId("Test");
+ longseq.addAlignmentAnnotation(refAnnot);
+ verifyExpectedSequenceAnnotation(refAnnot);
+
+ Alignment ourAl = new Alignment(
+ new SequenceI[]
+ { longseq.getSubSequence(5, 10),
+ longseq.getSubSequence(7, 12) });
+ ourAl.createDatasetAlignment();
+
+ // transfer annotation
+ SortedMap<String, String> tipEntries = new TreeMap<>();
+ Map<SequenceI, List<AlignmentAnnotation>> candidates = new LinkedHashMap<>();
+
+ AlignmentUtils.findAddableReferenceAnnotations(ourAl.getSequences(),
+ tipEntries, candidates, ourAl);
+ AlignmentUtils.addReferenceAnnotations(candidates, ourAl, null);
+
+ assertNotNull(ourAl.getAlignmentAnnotation());
+ assertEquals(ourAl.getAlignmentAnnotation().length, 2);
+
+ for (AlignmentAnnotation alan : ourAl.getAlignmentAnnotation())
+ {
+ verifyExpectedSequenceAnnotation(alan);
+ }
+ // Everything above works for 2.11.3 and 2.11.2.x.
+ // now simulate copy/paste to new alignment
+ SequenceI[] newSeqAl = new SequenceI[2];
+ // copy sequences but no annotation
+ newSeqAl[0] = new Sequence(ourAl.getSequenceAt(0),
+ ourAl.getSequenceAt(0).getAnnotation());
+ newSeqAl[1] = new Sequence(ourAl.getSequenceAt(1),
+ ourAl.getSequenceAt(1).getAnnotation());
+
+ Alignment newAl = new Alignment(newSeqAl);
+ // delete annotation
+ for (SequenceI sq : newAl.getSequences())
+ {
+ sq.setAlignmentAnnotation(new AlignmentAnnotation[0]);
+ }
+ // JAL-4182 scenario test
+ SequenceGroup sg = new SequenceGroup(Arrays.asList(newSeqAl));
+ sg.setStartRes(0);
+ sg.setEndRes(newAl.getWidth());
+ AlignmentUtils.addReferenceAnnotationTo(newAl, newSeqAl[0],
+ newSeqAl[0].getDatasetSequence().getAnnotation()[0], sg);
+ AlignmentUtils.addReferenceAnnotationTo(newAl, newSeqAl[1],
+ newSeqAl[1].getDatasetSequence().getAnnotation()[0], sg);
+ for (AlignmentAnnotation alan : newAl.getAlignmentAnnotation())
+ {
+ verifyExpectedSequenceAnnotation(alan);
+ }
+ }
+
+ /**
+ * helper - tests annotation is mapped to position it was originally created
+ * for
+ *
+ * @param alan
+ */
+ private void verifyExpectedSequenceAnnotation(AlignmentAnnotation alan)
+ {
+ for (int c = 0; c < alan.annotations.length; c++)
+ {
+ Annotation a = alan.annotations[c];
+ if (a != null)
+ {
+ assertEquals("Misaligned annotation at " + c,
+ (float) alan.sequenceRef.findPosition(c), a.value);
+ }
+ else
+ {
+ assertTrue("Unexpected Null at position " + c,
+ c >= alan.sequenceRef.getLength()
+ || Comparison.isGap(alan.sequenceRef.getCharAt(c)));
+ }
+ }
+ }
+
+ @Test(groups = "Functional")
public void testAddReferenceContactMap()
{
SequenceI sq = new Sequence("a", "SSSQ");
ContactMatrixI cm = new SeqDistanceContactMatrix(4);
AlignmentAnnotation cm_aan = sq.addContactList(cm);
+ cm_aan.description = cm_aan.description + " cm1";
SequenceI dssq = sq.createDatasetSequence();
- Alignment ds = new Alignment(new SequenceI[] { dssq });
// remove annotation on our non-dataset sequence
sq.removeAlignmentAnnotation(sq.getAnnotation()[0]);
// test transfer
Alignment al = new Alignment(new SequenceI[] { sq });
SortedMap<String, String> tipEntries = new TreeMap<>();
- final Map<SequenceI, List<AlignmentAnnotation>> candidates = new LinkedHashMap<>();
+ Map<SequenceI, List<AlignmentAnnotation>> candidates = new LinkedHashMap<>();
AlignmentUtils.findAddableReferenceAnnotations(al.getSequences(),
tipEntries, candidates, al);
&& al.getAlignmentAnnotation().length == 1);
AlignmentAnnotation alan = al.findAnnotations(sq, null, cm_aan.label)
.iterator().next();
+ ContactMatrixI t_cm = al.getContactMatrixFor(alan);
+ assertNotNull("No contact map for the transferred annotation row.",
+ t_cm);
+ assertTrue(t_cm instanceof SeqDistanceContactMatrix);
+ assertTrue(((SeqDistanceContactMatrix) t_cm).hasReferenceSeq());
+
ContactListI cl = al.getContactListFor(alan, 1);
assertNotNull(
"No contact matrix recovered after reference annotation transfer",
cl);
+ // semantics of sequence associated contact list is slightly tricky - column
+ // 3 in alignment should have data
+ cl = al.getContactListFor(alan, 3);
+ assertNotNull(
+ "Contact matrix should have data for last position in sequence",
+ cl);
+
+ ContactMatrixI cm2 = new SeqDistanceContactMatrix(4);
+ dssq.addContactList(cm2);
+ tipEntries = new TreeMap<>();
+ candidates = new LinkedHashMap<>();
+
+ AlignmentUtils.findAddableReferenceAnnotations(al.getSequences(),
+ tipEntries, candidates, al);
+ AlignmentUtils.addReferenceAnnotations(candidates, al, null);
+ assertTrue("Expected two contact map annotation transferred",
+ al.getAlignmentAnnotation() != null
+ && al.getAlignmentAnnotation().length == 2);
}
+
+ @Test(groups = "Functional", dataProvider = "SecondaryStructureAnnotations")
+ public void testSecondaryStructurePresentAndSources(AlignmentAnnotation[] annotations, boolean expectedSSPresent, ArrayList<String> expectedSSSources) {
+ Assert.assertEquals(expectedSSPresent, AlignmentUtils.isSecondaryStructurePresent(annotations));
+ Assert.assertEquals(expectedSSSources, AlignmentUtils.getSecondaryStructureSources(annotations));
+ }
+
+ @DataProvider(name = "SecondaryStructureAnnotations")
+ public static Object[][] provideSecondaryStructureAnnotations() {
+ AlignmentAnnotation ann1 = new AlignmentAnnotation("Secondary Structure", "Secondary Structure", new Annotation[]{});
+ AlignmentAnnotation ann2 = new AlignmentAnnotation("jnetpred", "jnetpred", new Annotation[]{});
+ AlignmentAnnotation ann3 = new AlignmentAnnotation("Temp", "Temp", new Annotation[]{});
+ AlignmentAnnotation ann4 = new AlignmentAnnotation("Temp", "Temp", new Annotation[]{});
+
+ List<String> ssSources1 = new ArrayList<>(Arrays.asList("3D Structures"));
+ List<String> ssSources2 = new ArrayList<>(Arrays.asList("JPred"));
+ List<String> ssSources3 = new ArrayList<>(Arrays.asList("3D Structures", "JPred"));
+ List<String> ssSources4 = new ArrayList<>();
+
+ return new Object[][]{
+ {new AlignmentAnnotation[]{ann1, ann3, ann4}, true, ssSources1},
+ {new AlignmentAnnotation[]{ann2, ann3, ann4}, true, ssSources2},
+ {new AlignmentAnnotation[]{ann3, ann4}, false, ssSources4},
+ {new AlignmentAnnotation[]{}, false, ssSources4},
+ {new AlignmentAnnotation[]{ann1, ann2, ann3, ann4}, true, ssSources3}
+ };
+ }
+
+ @Test(dataProvider = "SecondaryStructureAnnotationColours")
+ public void testSecondaryStructureAnnotationColour(char symbol, Color expectedColor) {
+ Color actualColor = AlignmentUtils.getSecondaryStructureAnnotationColour(symbol);
+ Assert.assertEquals(actualColor, expectedColor);
+ }
+
+ @DataProvider(name = "SecondaryStructureAnnotationColours")
+ public static Object[][] provideSecondaryStructureAnnotationColours() {
+ return new Object[][]{
+ {'C', Color.gray},
+ {'E', Color.green},
+ {'H', Color.red},
+ {'-', Color.gray}
+ };
+ }
+
+ @Test(dataProvider = "SSAnnotationPresence")
+ public void testIsSSAnnotationPresent(Map<SequenceI, List<AlignmentAnnotation>> annotations, boolean expectedPresence) {
+ boolean actualPresence = AlignmentUtils.isSSAnnotationPresent(annotations);
+ Assert.assertEquals(actualPresence, expectedPresence);
+ }
+
+ @DataProvider(name = "SSAnnotationPresence")
+ public static Object[][] provideSSAnnotationPresence() {
+ Map<SequenceI, List<AlignmentAnnotation>> annotations1 = new HashMap<>();
+ SequenceI seq1 = new Sequence("Seq1", "ASD---ASD---ASD", 37, 45);
+ List<AlignmentAnnotation> annotationsList1 = new ArrayList<>();
+ annotationsList1.add(new AlignmentAnnotation("Secondary Structure", "Secondary Structure", new Annotation[]{}));
+ annotations1.put(seq1, annotationsList1); // Annotation present secondary structure for seq1
+
+ Map<SequenceI, List<AlignmentAnnotation>> annotations2 = new HashMap<>();
+ SequenceI seq2 = new Sequence("Seq2", "ASD---ASD------", 37, 42);
+ List<AlignmentAnnotation> annotationsList2 = new ArrayList<>();
+ annotationsList2.add(new AlignmentAnnotation("Other Annotation", "Other Annotation", new Annotation[]{}));
+ annotations2.put(seq2, annotationsList2); // Annotation not related to any of secondary structure for seq2
+
+ Map<SequenceI, List<AlignmentAnnotation>> annotations3 = new HashMap<>();
+ // Empty annotation map
+
+ Map<SequenceI, List<AlignmentAnnotation>> annotations4 = new HashMap<>();
+ SequenceI seq4 = new Sequence("Seq4", "ASD---ASD---AS-", 37, 44);
+ List<AlignmentAnnotation> annotationsList4 = new ArrayList<>();
+ annotationsList4.add(new AlignmentAnnotation("jnetpred", "jnetpred", new Annotation[]{}));
+ annotations4.put(seq4, annotationsList4); // Annotation present from JPred for seq4
+
+
+ return new Object[][]{
+ {annotations1, true}, // Annotations present secondary structure present
+ {annotations2, false}, // No annotations related to any of the secondary structure present
+ {annotations3, false}, // Empty annotation map
+ {annotations4, true}, // Annotations present from JPred secondary structure present
+ };
+ }
+//
+// @Test(dataProvider = "SSSourceFromAnnotationDescription")
+// public void testGetSSSourceFromAnnotationDescription(Map<SequenceI, List<AlignmentAnnotation>> annotations, String expectedSSSource) {
+// String actualSSSource = AlignmentUtils.getSSSourceFromAnnotationDescription(annotations);
+// Assert.assertEquals(actualSSSource, expectedSSSource);
+// }
+
+ @DataProvider(name = "SSSourceFromAnnotationDescription")
+ public static Object[][] provideSSSourceFromAnnotationDescription() {
+ Map<SequenceI, List<AlignmentAnnotation>> annotations1 = new HashMap<>();
+ SequenceI seq1 = new Sequence("Seq1", "ASD---ASD---ASD", 37, 45);
+ List<AlignmentAnnotation> annotationsList1 = new ArrayList<>();
+ annotationsList1.add(new AlignmentAnnotation("jnetpred", "JPred Output", new Annotation[]{}));
+ annotations1.put(seq1, annotationsList1); // Annotation present from JPred for seq1
+
+ Map<SequenceI, List<AlignmentAnnotation>> annotations2 = new HashMap<>();
+ SequenceI seq2 = new Sequence("Seq2", "ASD---ASD------", 37, 42);
+ List<AlignmentAnnotation> annotationsList2 = new ArrayList<>();
+ annotationsList2.add(new AlignmentAnnotation("Secondary Structure",
+ "Secondary Structure for af-q43517-f1A", new Annotation[]{}));
+ annotations2.put(seq2, annotationsList2); // Annotation present secondary structure from Alphafold for seq2
+
+ Map<SequenceI, List<AlignmentAnnotation>> annotations3 = new HashMap<>();
+ // Empty annotation map
+
+ Map<SequenceI, List<AlignmentAnnotation>> annotations4 = new HashMap<>();
+ SequenceI seq4 = new Sequence("Seq4", "ASD---ASD---AS-", 37, 44);
+ List<AlignmentAnnotation> annotationsList4 = new ArrayList<>();
+ annotationsList4.add(new AlignmentAnnotation("Secondary Structure",
+ "Secondary Structure for 4zhpA", new Annotation[]{}));
+ annotations4.put(seq4, annotationsList4); // Annotation present secondary structure from pdb for seq4
+
+ Map<SequenceI, List<AlignmentAnnotation>> annotations5 = new HashMap<>();
+ SequenceI seq5 = new Sequence("Seq5", "ASD---ASD---AS-", 37, 44);
+ List<AlignmentAnnotation> annotationsList5 = new ArrayList<>();
+ annotationsList5.add(new AlignmentAnnotation("Secondary Structure",
+ "Secondary Structure for p09911_54-147__3a7wzn.1.p3502557454997462030P",
+ new Annotation[]{}));
+ annotations5.put(seq5, annotationsList5); // Annotation present secondary structure from Swiss model for seq5
+
+
+ //JPred Output - JPred
+ //Secondary Structure for af-q43517-f1A - Alphafold
+ //Secondary Structure for 4zhpA - Experimental
+ //Secondary Structure for p09911_54-147__3a7wzn.1.p3502557454997462030P - Swiss Model
+
+ return new Object[][]{
+ {annotations1, "JPred"},
+ {annotations2, "Alphafold"},
+ {annotations3, null},
+ {annotations4, "PDB"},
+ {annotations5, "Swiss Model"}
+ };
+ }
+
}