X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=test%2Fjalview%2Fio%2FStockholmFileTest.java;h=bb822a06cabf7b70ab54d9d7540e4281d35e2dcf;hb=c794c5033adeee182b03a5ea92c0a7495a29661f;hp=1c9c79db3dc8ed12d79df62a91feaacde7c098b8;hpb=98f314390c233ae362d53cbd2ef62fedfc3d816d;p=jalview.git diff --git a/test/jalview/io/StockholmFileTest.java b/test/jalview/io/StockholmFileTest.java index 1c9c79d..bb822a0 100644 --- a/test/jalview/io/StockholmFileTest.java +++ b/test/jalview/io/StockholmFileTest.java @@ -20,34 +20,36 @@ */ package jalview.io; +import static org.testng.Assert.assertTrue; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotNull; -import static org.testng.AssertJUnit.assertNull; import static org.testng.AssertJUnit.assertTrue; import static org.testng.AssertJUnit.fail; -import jalview.datamodel.Alignment; -import jalview.datamodel.AlignmentAnnotation; -import jalview.datamodel.AlignmentI; -import jalview.datamodel.Annotation; -import jalview.datamodel.DBRefEntry; -import jalview.datamodel.Sequence; -import jalview.datamodel.SequenceFeature; -import jalview.datamodel.SequenceI; -import jalview.gui.JvOptionPane; - import java.io.File; -import java.io.IOException; import java.util.Arrays; import java.util.BitSet; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.testng.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; +import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.Annotation; +import jalview.datamodel.DBRefEntry; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceFeature; +import jalview.datamodel.SequenceI; +import jalview.gui.JvOptionPane; +import jalview.util.DBRefUtils; + public class StockholmFileTest { @@ -59,7 +61,8 @@ public class StockholmFileTest } static String PfamFile = "examples/PF00111_seed.stk", - RfamFile = "examples/RF00031_folded.stk"; + RfamFile = "examples/RF00031_folded.stk", + RnaSSTestFile = "examples/rna_ss_test.stk"; @Test(groups = { "Functional" }) public void pfamFileIO() throws Exception @@ -95,14 +98,57 @@ public class StockholmFileTest } /** + * JAL-3529 - verify uniprot refs for sequences are output for sequences + * retrieved via Pfam + */ + @Test(groups = { "Functional" }) + public void dbrefOutput() throws Exception + { + // sequences retrieved in a Pfam domain alignment also have a PFAM database + // reference + SequenceI sq = new Sequence("FER2_SPIOL", "AASSDDDFFF"); + sq.addDBRef(new DBRefEntry("UNIPROT", "1", "P00224")); + sq.addDBRef(new DBRefEntry("PFAM", "1", "P00224.1")); + sq.addDBRef(new DBRefEntry("PFAM", "1", "PF00111")); + AppletFormatAdapter af = new AppletFormatAdapter(); + String toStockholm = af.formatSequences(FileFormat.Stockholm, + new Alignment(new SequenceI[] + { sq }), false); + System.out.println(toStockholm); + // bleh - java.util.Regex sucks + assertTrue( + Pattern.compile( + "^#=GS\\s+FER2_SPIOL(/\\d+-\\d+)?\\s+AC\\s+P00224$", + Pattern.MULTILINE).matcher(toStockholm) + .find(), + "Couldn't locate UNIPROT Accession in generated Stockholm file."); + AlignmentI fromStockholm = af.readFile(toStockholm, + DataSourceType.PASTE, FileFormat.Stockholm); + SequenceI importedSeq = fromStockholm.getSequenceAt(0); + assertTrue(importedSeq.getDBRefs() + .size() == 1, + "Expected just one database reference to be added to sequence."); + assertTrue( + importedSeq.getDBRefs().get(0).getAccessionId().indexOf( + " ") == -1, + "Spaces were found in accession ID."); + List dbrefs = DBRefUtils.searchRefs(importedSeq.getDBRefs(), + "P00224"); + assertTrue(dbrefs.size() == 1, + "Couldn't find Uniprot DBRef on re-imported sequence."); + + } + + /** * test alignment data in given file can be imported, exported and reimported * with no dataloss * * @param f - * - source datafile (IdentifyFile.identify() should work with it) + * - source datafile (IdentifyFile.identify() + * should work with it) * @param ioformat - * - label for IO class used to write and read back in the data from - * f + * - label for IO class used to write and read + * back in the data from f * @param ignoreFeatures * @param ignoreRowVisibility * @param allowNullAnnotations @@ -259,8 +305,8 @@ public class StockholmFileTest assertEquals("Threshold line not identical.", aa_original[i].threshold, aa_new[i].threshold); // graphGroup may differ, but pattern should be the same - Integer o_ggrp = new Integer(aa_original[i].graphGroup + 2); - Integer n_ggrp = new Integer(aa_new[i].graphGroup + 2); + Integer o_ggrp = Integer.valueOf(aa_original[i].graphGroup + 2); + Integer n_ggrp = Integer.valueOf(aa_new[i].graphGroup + 2); BitSet orig_g = orig_groups.get(o_ggrp); BitSet new_g = new_groups.get(n_ggrp); if (orig_g == null) @@ -325,10 +371,11 @@ public class StockholmFileTest || (seq_original[i].getSequenceFeatures() != null && seq_new[in] .getSequenceFeatures() != null)); // compare sequence features - if (seq_original[i].getSequenceFeatures() != null + if (!ignoreFeatures + && seq_original[i].getSequenceFeatures() != null && seq_new[in].getSequenceFeatures() != null) { - System.out.println("There are feature!!!"); + System.out.println("Checking feature equivalence."); sequenceFeatures_original = seq_original[i] .getSequenceFeatures(); sequenceFeatures_new = seq_new[in].getSequenceFeatures(); @@ -628,13 +675,13 @@ public class StockholmFileTest { for (char ch : new char[] { '{', '}', '[', ']', '(', ')', '<', '>' }) { - Assert.assertTrue(StockholmFile.DETECT_BRACKETS.matchAt("" + ch, 0), - "Didn't recognise " + ch + " as a WUSS bracket"); + Assert.assertTrue(StockholmFile.RNASS_BRACKETS.indexOf(ch) >= 0, + "Didn't recognise '" + ch + "' as a WUSS bracket"); } - for (char ch : new char[] { '@', '!', 'V', 'Q', '*', ' ', '-', '.' }) + for (char ch : new char[] { '@', '!', '*', ' ', '-', '.' }) { - Assert.assertFalse(StockholmFile.DETECT_BRACKETS.matchAt("" + ch, 0), - "Shouldn't recognise " + ch + " as a WUSS bracket"); + Assert.assertFalse(StockholmFile.RNASS_BRACKETS.indexOf(ch) >= 0, + "Shouldn't recognise '" + ch + "' as a WUSS bracket"); } } private static void roundTripSSForRNA(String aliFile, String annFile) @@ -660,272 +707,190 @@ public class StockholmFileTest } + // this is the single sequence alignment and the SS annotations equivalent to + // the ones in file RnaSSTestFile + String aliFileRnaSS = ">Test.sequence/1-14\n" + + "GUACAAAAAAAAAA"; + String annFileRnaSSAlphaChars = "JALVIEW_ANNOTATION\n" + + "# Created: Thu Aug 02 14:54:57 BST 2018\n" + "\n" + + "NO_GRAPH\tSecondary Structure\tSecondary Structure\t<,<|(,(|E,E|H,H|B,B|h,h|e,e|b,b|(,(|E,E|),)|e,e|),)|>,>|\t2.0\n" + + "\n" + + "ROWPROPERTIES\tSecondary Structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false\n" + + "\n" + "\n" + "ALIGNMENT\tID=RNA.SS.TEST\tTP=RNA;"; + String wrongAnnFileRnaSSAlphaChars = "JALVIEW_ANNOTATION\n" + + "# Created: Thu Aug 02 14:54:57 BST 2018\n" + "\n" + + "NO_GRAPH\tSecondary Structure\tSecondary Structure\t<,<|(,(|H,H|E,E|B,B|h,h|e,e|b,b|(,(|E,E|),)|e,e|),)|>,>|\t2.0\n" + + "\n" + + "ROWPROPERTIES\tSecondary Structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false\n" + + "\n" + "\n" + "ALIGNMENT\tID=RNA.SS.TEST\tTP=RNA;"; @Test(groups = { "Functional" }) - public void testTypeToDescription() + public void stockholmFileRnaSSAlphaChars() throws Exception { - assertEquals("Secondary Structure", - StockholmFile.typeToDescription("SS")); - assertEquals("Surface Accessibility", - StockholmFile.typeToDescription("SA")); - assertEquals("transmembrane", StockholmFile.typeToDescription("TM")); - assertEquals("Posterior Probability", - StockholmFile.typeToDescription("PP")); - assertEquals("ligand binding", StockholmFile.typeToDescription("LI")); - assertEquals("active site", StockholmFile.typeToDescription("AS")); - assertEquals("intron", StockholmFile.typeToDescription("IN")); - assertEquals("interacting residue", - StockholmFile.typeToDescription("IR")); - assertEquals("accession", StockholmFile.typeToDescription("AC")); - assertEquals("organism", StockholmFile.typeToDescription("OS")); - assertEquals("class", StockholmFile.typeToDescription("CL")); - assertEquals("description", StockholmFile.typeToDescription("DE")); - assertEquals("reference", StockholmFile.typeToDescription("DR")); - assertEquals("look", StockholmFile.typeToDescription("LO")); - assertEquals("Reference Positions", - StockholmFile.typeToDescription("RF")); - - // case-sensitive: - assertEquals("Rf", StockholmFile.typeToDescription("Rf")); - assertEquals("junk", StockholmFile.typeToDescription("junk")); - assertEquals("", StockholmFile.typeToDescription("")); - assertNull(StockholmFile.typeToDescription(null)); + AppletFormatAdapter af = new AppletFormatAdapter(); + AlignmentI al = af.readFile(RnaSSTestFile, DataSourceType.FILE, + jalview.io.FileFormat.Stockholm); + Iterable aai = al.findAnnotations(null, null, + "Secondary Structure"); + AlignmentAnnotation aa = aai.iterator().next(); + Assert.assertTrue(aa.isRNA(), + "'" + RnaSSTestFile + "' not recognised as RNA SS"); + Assert.assertTrue(aa.isValidStruc(), + "'" + RnaSSTestFile + "' not recognised as valid structure"); + Annotation[] as = aa.annotations; + char[] As = new char[as.length]; + for (int i = 0; i < as.length; i++) + { + As[i] = as[i].secondaryStructure; + } + char[] shouldBe = { '<', '(', 'E', 'H', 'B', 'h', 'e', 'b', '(', 'E', + ')', 'e', ')', '>' }; + Assert.assertTrue( + Arrays.equals(As, shouldBe), + "Annotation is " + new String(As) + " but should be " + + new String(shouldBe)); + + // this should result in the same RNA SS Annotations + AlignmentI newAl = new AppletFormatAdapter().readFile( + aliFileRnaSS, + DataSourceType.PASTE, jalview.io.FileFormat.Fasta); + AnnotationFile aaf = new AnnotationFile(); + aaf.readAnnotationFile(newAl, annFileRnaSSAlphaChars, + DataSourceType.PASTE); + + Assert.assertTrue( + testRnaSSAnnotationsEquivalent(al.getAlignmentAnnotation()[0], + newAl.getAlignmentAnnotation()[0]), + "RNA SS Annotations SHOULD be pair-wise equivalent (but apparently aren't): \n" + + "RNA SS A 1:" + al.getAlignmentAnnotation()[0] + "\n" + + "RNA SS A 2:" + newAl.getAlignmentAnnotation()[0]); + + // this should NOT result in the same RNA SS Annotations + newAl = new AppletFormatAdapter().readFile( + aliFileRnaSS, DataSourceType.PASTE, + jalview.io.FileFormat.Fasta); + aaf = new AnnotationFile(); + aaf.readAnnotationFile(newAl, wrongAnnFileRnaSSAlphaChars, + DataSourceType.PASTE); + + boolean mismatch = testRnaSSAnnotationsEquivalent(al.getAlignmentAnnotation()[0], + newAl.getAlignmentAnnotation()[0]); + Assert.assertFalse(mismatch, + "RNA SS Annotations SHOULD NOT be pair-wise equivalent (but apparently are): \n" + + "RNA SS A 1:" + al.getAlignmentAnnotation()[0] + "\n" + + "RNA SS A 2:" + newAl.getAlignmentAnnotation()[0]); } - @Test(groups = { "Functional" }) - public void testDescriptionToType() + private static boolean testRnaSSAnnotationsEquivalent( + AlignmentAnnotation a1, + AlignmentAnnotation a2) { - assertEquals("SS", - StockholmFile.descriptionToType("Secondary Structure")); - assertEquals("SA", - StockholmFile.descriptionToType("Surface Accessibility")); - assertEquals("TM", StockholmFile.descriptionToType("transmembrane")); - - // test is not case-sensitive: - assertEquals("SS", - StockholmFile.descriptionToType("secondary structure")); - - // test is white-space sensitive: - assertNull(StockholmFile.descriptionToType("secondary structure ")); - - assertNull(StockholmFile.descriptionToType("any old junk")); - assertNull(StockholmFile.descriptionToType("")); - assertNull(StockholmFile.descriptionToType(null)); + return a1.rnaSecondaryStructureEquivalent(a2); } + String annFileRnaSSWithSpaceChars = "JALVIEW_ANNOTATION\n" + + "# Created: Thu Aug 02 14:54:57 BST 2018\n" + "\n" + + "NO_GRAPH\tSecondary Structure\tSecondary Structure\t<,<|.,.|H,H| , |B,B|h,h| , |b,b|(,(|E,E|.,.|e,e|),)|>,>|\t2.0\n" + + "\n" + + "ROWPROPERTIES\tSecondary Structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false\n" + + "\n" + "\n" + "ALIGNMENT\tID=RNA.SS.TEST\tTP=RNA;"; + String annFileRnaSSWithoutSpaceChars = "JALVIEW_ANNOTATION\n" + + "# Created: Thu Aug 02 14:54:57 BST 2018\n" + "\n" + + "NO_GRAPH\tSecondary Structure\tSecondary Structure\t<,<|.,.|H,H|.,.|B,B|h,h|.,.|b,b|(,(|E,E|.,.|e,e|),)|>,>|\t2.0\n" + + "\n" + + "ROWPROPERTIES\tSecondary Structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false\n" + + "\n" + "\n" + "ALIGNMENT\tID=RNA.SS.TEST\tTP=RNA;"; + + String wrongAnnFileRnaSSWithoutSpaceChars = "JALVIEW_ANNOTATION\n" + + "# Created: Thu Aug 02 14:54:57 BST 2018\n" + "\n" + + "NO_GRAPH\tSecondary Structure\tSecondary Structure\t<,<|.,.|H,H|Z,Z|B,B|h,h|z,z|b,b|(,(|E,E|.,.|e,e|),)|>,>|\t2.0\n" + + "\n" + + "ROWPROPERTIES\tSecondary Structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false\n" + + "\n" + "\n" + "ALIGNMENT\tID=RNA.SS.TEST\tTP=RNA;"; + @Test(groups = { "Functional" }) - public void testPrint() + public void stockholmFileRnaSSSpaceChars() throws Exception { - SequenceI seq1 = new Sequence("seq1", "LKMF-RS-Q"); - SequenceI seq2 = new Sequence("seq2/10-15", "RRS-LIP-"); - SequenceI[] seqs = new SequenceI[] { seq1, seq2 }; - AlignmentI al = new Alignment(seqs); - - StockholmFile testee = new StockholmFile(al); - - /* - * basic output (sequences only): - * sequence ids are padded with 9 spaces more than the widest id - */ - String output = testee.print(seqs, true); - String expected = "# STOCKHOLM 1.0\n" + "seq1/1-7 LKMF-RS-Q\n" - + "seq2/10-15 RRS-LIP-\n//\n"; - assertEquals(expected, output); - - /* - * add some dbrefs - */ - seq1.addDBRef(new DBRefEntry("PFAM", "1", "PF00111")); - seq1.addDBRef(new DBRefEntry("UNIPROT", "1", "P83527")); - seq2.addDBRef(new DBRefEntry("RFAM", "1", "AY119185.1")); - seq2.addDBRef(new DBRefEntry("EMBL", "1", "AF125575")); - output = testee.print(seqs, true); - // PFAM and RFAM dbrefs should be output as AC, others as DR - expected = "# STOCKHOLM 1.0\n" + "#=GS seq1/1-7 AC PF00111\n" - + "#=GS seq1/1-7 DR UNIPROT ; P83527\n" - + "#=GS seq2/10-15 AC AY119185.1\n" - + "#=GS seq2/10-15 DR EMBL ; AF125575\n" - + "seq1/1-7 LKMF-RS-Q\n" - + "seq2/10-15 RRS-LIP-\n//\n"; - assertEquals(expected, output); - - /* - * add some sequence and alignment annotation - */ - Annotation[] anns = new Annotation[5]; - for (int i = 0; i < anns.length; i++) + AlignmentI alWithSpaces = new AppletFormatAdapter().readFile( + aliFileRnaSS, DataSourceType.PASTE, + jalview.io.FileFormat.Fasta); + AnnotationFile afWithSpaces = new AnnotationFile(); + afWithSpaces.readAnnotationFile(alWithSpaces, + annFileRnaSSWithSpaceChars, DataSourceType.PASTE); + + Iterable aaiWithSpaces = alWithSpaces + .findAnnotations(null, null, "Secondary Structure"); + AlignmentAnnotation aaWithSpaces = aaiWithSpaces.iterator().next(); + Assert.assertTrue(aaWithSpaces.isRNA(), + "'" + aaWithSpaces + "' not recognised as RNA SS"); + Assert.assertTrue(aaWithSpaces.isValidStruc(), + "'" + aaWithSpaces + "' not recognised as valid structure"); + Annotation[] annWithSpaces = aaWithSpaces.annotations; + char[] As = new char[annWithSpaces.length]; + for (int i = 0; i < annWithSpaces.length; i++) { - anns[i] = new Annotation(String.valueOf((char) ('B' + i)), - "Desc " + i, - (char) ('C' + i), i + 3); + As[i] = annWithSpaces[i].secondaryStructure; } + // check all spaces and dots are spaces in the internal representation + char[] shouldBe = { '<', ' ', 'H', ' ', 'B', 'h', ' ', 'b', '(', 'E', + ' ', 'e', ')', '>' }; + Assert.assertTrue(Arrays.equals(As, shouldBe), "Annotation is " + + new String(As) + " but should be " + new String(shouldBe)); + + // this should result in the same RNA SS Annotations + AlignmentI alWithoutSpaces = new AppletFormatAdapter().readFile( + aliFileRnaSS, DataSourceType.PASTE, + jalview.io.FileFormat.Fasta); + AnnotationFile afWithoutSpaces = new AnnotationFile(); + afWithoutSpaces.readAnnotationFile(alWithoutSpaces, + annFileRnaSSWithoutSpaceChars, + DataSourceType.PASTE); + + Assert.assertTrue( + testRnaSSAnnotationsEquivalent( + alWithSpaces.getAlignmentAnnotation()[0], + alWithoutSpaces.getAlignmentAnnotation()[0]), + "RNA SS Annotations SHOULD be pair-wise equivalent (but apparently aren't): \n" + + "RNA SS A 1:" + + alWithSpaces.getAlignmentAnnotation()[0] + .getRnaSecondaryStructure() + + "\n" + "RNA SS A 2:" + + alWithoutSpaces.getAlignmentAnnotation()[0] + .getRnaSecondaryStructure()); + + // this should NOT result in the same RNA SS Annotations + AlignmentI wrongAlWithoutSpaces = new AppletFormatAdapter().readFile( + aliFileRnaSS, DataSourceType.PASTE, + jalview.io.FileFormat.Fasta); + AnnotationFile wrongAfWithoutSpaces = new AnnotationFile(); + wrongAfWithoutSpaces.readAnnotationFile(wrongAlWithoutSpaces, + wrongAnnFileRnaSSWithoutSpaceChars, + DataSourceType.PASTE); + + Assert.assertFalse( + testRnaSSAnnotationsEquivalent( + alWithSpaces.getAlignmentAnnotation()[0], + wrongAlWithoutSpaces.getAlignmentAnnotation()[0]), + "RNA SS Annotations SHOULD NOT be pair-wise equivalent (but apparently are): \n" + + "RNA SS A 1:" + + alWithSpaces.getAlignmentAnnotation()[0] + .getRnaSecondaryStructure() + + "\n" + "RNA SS A 2:" + + wrongAlWithoutSpaces.getAlignmentAnnotation()[0] + .getRnaSecondaryStructure()); + + // check no spaces in the output + // TODO: create a better 'save as ' pattern + alWithSpaces.getAlignmentAnnotation()[0].visible = true; + StockholmFile sf = new StockholmFile(alWithSpaces); + + String stockholmFile = sf.print(alWithSpaces.getSequencesArray(), true); + Pattern noSpacesInRnaSSAnnotation = Pattern + .compile("\\n#=GC SS_cons\\s+\\S{14}\\n"); + Matcher m = noSpacesInRnaSSAnnotation.matcher(stockholmFile); + boolean matches = m.find(); + Assert.assertTrue(matches, + "StockholmFile output does not contain expected output (may contain spaces):\n" + + stockholmFile); - // expect "secondary structure" to be output as #=GR seqid SS - // using the secondary structure character (CDEFG) not display char (BCDEF) - AlignmentAnnotation aa1 = new AlignmentAnnotation("secondary structure", - "ssdesc", anns); - aa1.sequenceRef = seq1; - seq1.addAlignmentAnnotation(aa1); - al.addAnnotation(aa1); - - // "sec structure" should not be output as no corresponding feature id - AlignmentAnnotation aa2 = new AlignmentAnnotation("sec structure", - "ssdesc", anns); - aa2.sequenceRef = seq2; - seq2.addAlignmentAnnotation(aa2); - al.addAnnotation(aa2); - - // alignment annotation for Reference Positions: output as #=GC RF - AlignmentAnnotation aa3 = new AlignmentAnnotation("reference positions", - "refpos", anns); - al.addAnnotation(aa3); - - // 'seq' annotation: output as seq_cons - AlignmentAnnotation aa4 = new AlignmentAnnotation("seq", "seqdesc", - anns); - al.addAnnotation(aa4); - - // 'intron' annotation: output as IN_cons - AlignmentAnnotation aa5 = new AlignmentAnnotation("intron", - "introndesc", anns); - al.addAnnotation(aa5); - - // 'binding site' annotation: output as binding_site - AlignmentAnnotation aa6 = new AlignmentAnnotation("binding site", - "bindingdesc", anns); - al.addAnnotation(aa6); - - // 'autocalc' annotation should not be output - AlignmentAnnotation aa7 = new AlignmentAnnotation("Consensus", - "consensusdesc", anns); - aa7.autoCalculated = true; - al.addAnnotation(aa7); - - // hidden annotation should not be output - AlignmentAnnotation aa8 = new AlignmentAnnotation("domains", - "domaindesc", anns); - aa8.visible = false; - al.addAnnotation(aa8); - - output = testee.print(seqs, true); - //@formatter:off - expected = - "# STOCKHOLM 1.0\n" - + "#=GS seq1/1-7 AC PF00111\n" - + "#=GS seq1/1-7 DR UNIPROT ; P83527\n" - + "#=GS seq2/10-15 AC AY119185.1\n" - + "#=GS seq2/10-15 DR EMBL ; AF125575\n" - + "#=GR seq1/1-7 SS CDEFG\n" - + "seq1/1-7 LKMF-RS-Q\n" - + "seq2/10-15 RRS-LIP-\n" - + "#=GC RF BCDEF\n" + "#=GC seq_cons BCDEF\n" - + "#=GC IN_cons BCDEF\n" + "#=GC binding_site BCDEF\n" - + "//\n"; - //@formatter:on - assertEquals(expected, output); - } - - @Test(groups = "Functional") - public void testGetAnnotationCharacter() - { - SequenceI seq = new Sequence("seq", "abc--def-"); - - Annotation[] ann = new Annotation[8]; - ann[1] = new Annotation("Z", "desc", 'E', 1f); - ann[2] = new Annotation("Q", "desc", ' ', 1f); - ann[4] = new Annotation("", "desc", 'E', 1f); - ann[6] = new Annotation("ZH", "desc", 'E', 1f); - - /* - * null annotation in column (not Secondary Structure annotation) - * should answer sequence character, or '-' if null sequence - */ - assertEquals('-', - StockholmFile.getAnnotationCharacter("RF", 0, ann[0], null)); - assertEquals('d', - StockholmFile.getAnnotationCharacter("RF", 5, ann[5], seq)); - assertEquals('-', - StockholmFile.getAnnotationCharacter("RF", 8, null, seq)); - - /* - * null annotation in column (SS annotation) should answer underscore - */ - assertEquals('_', - StockholmFile.getAnnotationCharacter("SS", 0, ann[0], seq)); - - /* - * SS secondary structure symbol - */ - assertEquals('E', - StockholmFile.getAnnotationCharacter("SS", 1, ann[1], seq)); - - /* - * no SS symbol, use label instead - */ - assertEquals('Q', - StockholmFile.getAnnotationCharacter("SS", 2, ann[2], seq)); - - /* - * SS with 2 character label - second character overrides SS symbol - */ - assertEquals('H', - StockholmFile.getAnnotationCharacter("SS", 6, ann[6], seq)); - - /* - * empty display character, not SS - answers '.' - */ - assertEquals('.', - StockholmFile.getAnnotationCharacter("RF", 4, ann[4], seq)); - } - - /** - * Test to verify that gaps are input/output as underscore in STO annotation - * - * @throws IOException - */ - @Test(groups = "Functional") - public void testRoundtripWithGaps() throws IOException - { - /* - * small extract from RF00031_folded.stk - */ - // @formatter:off - String stoData = - "# STOCKHOLM 1.0\n" + - "#=GR B.taurus.4 SS .._((.))_\n" + - "B.taurus.4 AC.UGCGU.\n" + - "#=GR B.taurus.5 SS ..((_._))\n" + - "B.taurus.5 ACUU.G.CG\n" + - "//\n"; - // @formatter:on - StockholmFile parser = new StockholmFile(stoData, DataSourceType.PASTE); - SequenceI[] seqs = parser.getSeqsAsArray(); - assertEquals(2, seqs.length); - - /* - * B.taurus.4 has a trailing gap - * rendered as underscore in Stockholm annotation - */ - assertEquals("AC.UGCGU.", seqs[0].getSequenceAsString()); - AlignmentAnnotation[] anns = seqs[0].getAnnotation(); - assertEquals(1, anns.length); - AlignmentAnnotation taurus4SS = anns[0]; - assertEquals(9, taurus4SS.annotations.length); - assertEquals(" .", taurus4SS.annotations[0].displayCharacter); - assertNull(taurus4SS.annotations[2]); // gapped position - assertNull(taurus4SS.annotations[8]); // gapped position - assertEquals('(', taurus4SS.annotations[3].secondaryStructure); - assertEquals("(", taurus4SS.annotations[3].displayCharacter); - assertEquals(')', taurus4SS.annotations[7].secondaryStructure); - - /* - * output as Stockholm and verify it matches the original input - * (gaps output as underscore in annotation lines) - * note: roundtrip test works with the input lines ordered as above; - * can also parse in other orders, but then input doesn't match output - */ - AlignmentFileWriterI afile = FileFormat.Stockholm - .getWriter(new Alignment(seqs)); - String output = afile.print(seqs, false); - assertEquals(stoData, output); } }