X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=test%2Fjalview%2Fio%2FStockholmFileTest.java;h=bd1400b5eba09f412f17dd415d3810bf79a56ec1;hb=5b3d1cf1e78adbeeedf14eec91b6a0be75ca21e4;hp=45de531bcae5503c9d1638948fe9bf68762dd28e;hpb=44e5428356c618d139354d02bbfc2f9008ae50b6;p=jalview.git diff --git a/test/jalview/io/StockholmFileTest.java b/test/jalview/io/StockholmFileTest.java index 45de531..bd1400b 100644 --- a/test/jalview/io/StockholmFileTest.java +++ b/test/jalview/io/StockholmFileTest.java @@ -23,44 +23,56 @@ package jalview.io; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertTrue; +import static org.testng.AssertJUnit.fail; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.Annotation; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; +import jalview.gui.JvOptionPane; import java.io.File; import java.util.BitSet; import java.util.HashMap; import java.util.Map; +import org.testng.Assert; +import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; public class StockholmFileTest { + @BeforeClass(alwaysRun = true) + public void setUpJvOptionPane() + { + JvOptionPane.setInteractiveMode(false); + JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION); + } + static String PfamFile = "examples/PF00111_seed.stk", RfamFile = "examples/RF00031_folded.stk"; - @Test + @Test(groups = { "Functional" }) public void pfamFileIO() throws Exception { - testFileIOwithFormat(new File(PfamFile), "STH", -1, 0); + testFileIOwithFormat(new File(PfamFile), FileFormat.Stockholm, -1, 0, + false); } - @Test + @Test(groups = { "Functional" }) public void pfamFileDataExtraction() throws Exception { AppletFormatAdapter af = new AppletFormatAdapter(); - AlignmentI al = af.readFile(PfamFile, af.FILE, - new IdentifyFile().Identify(PfamFile, af.FILE)); + AlignmentI al = af.readFile(PfamFile, DataSourceType.FILE, + new IdentifyFile().identify(PfamFile, DataSourceType.FILE)); int numpdb = 0; for (SequenceI sq : al.getSequences()) { - if (sq.getPDBId() != null) + if (sq.getAllPDBEntries() != null) { - numpdb += sq.getPDBId().size(); + numpdb += sq.getAllPDBEntries().size(); } } assertTrue( @@ -68,10 +80,11 @@ public class StockholmFileTest numpdb > 0); } - @Test + @Test(groups = { "Functional" }) public void rfamFileIO() throws Exception { - testFileIOwithFormat(new File(RfamFile), "STH", 2, 1); + testFileIOwithFormat(new File(RfamFile), FileFormat.Stockholm, 2, 1, + false); } /** @@ -83,10 +96,11 @@ public class StockholmFileTest * @param ioformat * - label for IO class used to write and read back in the data from * f + * @param ignoreRowVisibility */ - public static void testFileIOwithFormat(File f, String ioformat, - int naliannot, int nminseqann) + public static void testFileIOwithFormat(File f, FileFormatI ioformat, + int naliannot, int nminseqann, boolean ignoreRowVisibility) { System.out.println("Reading file: " + f); String ff = f.getPath(); @@ -94,26 +108,26 @@ public class StockholmFileTest { AppletFormatAdapter rf = new AppletFormatAdapter(); - AlignmentI al = rf.readFile(ff, AppletFormatAdapter.FILE, - new IdentifyFile().Identify(ff, AppletFormatAdapter.FILE)); + AlignmentI al = rf.readFile(ff, DataSourceType.FILE, + new IdentifyFile().identify(ff, DataSourceType.FILE)); assertNotNull("Couldn't read supplied alignment data.", al); // make sure dataset is initialised ? not sure about this for (int i = 0; i < al.getSequencesArray().length; ++i) { - al.getSequenceAt(i).setDatasetSequence(al.getSequenceAt(i)); + al.getSequenceAt(i).createDatasetSequence(); } String outputfile = rf.formatSequences(ioformat, al, true); System.out.println("Output file in '" + ioformat + "':\n" + outputfile + "\n< -1) { assertEquals("Number of alignment annotations", naliannot, - numaliannot); + numaliannot); } assertTrue( @@ -159,20 +173,38 @@ public class StockholmFileTest * 'secondary' or generated alignment from some datapreserving * transformation * @param ignoreFeatures - * when true, differences in seuqence feature annotation are ignored. + * when true, differences in sequence feature annotation are ignored */ public static void testAlignmentEquivalence(AlignmentI al, AlignmentI al_input, boolean ignoreFeatures) { + } + + /** + * assert alignment equivalence + * + * @param al + * 'original' + * @param al_input + * 'secondary' or generated alignment from some datapreserving + * transformation + * @param ignoreFeatures + * when true, differences in sequence feature annotation are ignored + * + * @param ignoreRowVisibility + * when true, do not fail if there are differences in the visibility + * of annotation rows + */ + public static void testAlignmentEquivalence(AlignmentI al, + AlignmentI al_input, boolean ignoreFeatures, + boolean ignoreRowVisibility) + { assertNotNull("Original alignment was null", al); assertNotNull("Generated alignment was null", al_input); - assertTrue( - "Alignment dimension mismatch: originl contains " - + al.getHeight() + " and generated has " - + al_input.getHeight() + " sequences; original has " - + al.getWidth() + " and generated has " - + al_input.getWidth() + " columns.", + assertTrue("Alignment dimension mismatch: original: " + al.getHeight() + + "x" + al.getWidth() + ", generated: " + al_input.getHeight() + + "x" + al_input.getWidth(), al.getHeight() == al_input.getHeight() && al.getWidth() == al_input.getWidth()); @@ -183,9 +215,10 @@ public class StockholmFileTest // note - at moment we do not distinguish between alignment without any // annotation rows and alignment with no annotation row vector // we might want to revise this in future - int aa_new_size = (aa_new == null ? 0 : aa_new.length), aa_original_size = (aa_original == null ? 0 - : aa_original.length); - Map orig_groups = new HashMap(), new_groups = new HashMap(); + int aa_new_size = (aa_new == null ? 0 : aa_new.length); + int aa_original_size = (aa_original == null ? 0 : aa_original.length); + Map orig_groups = new HashMap(); + Map new_groups = new HashMap(); if (aa_new != null && aa_original != null) { @@ -193,23 +226,25 @@ public class StockholmFileTest { if (aa_new.length > i) { - assertTrue("Different alignment annotation at position " + i, - equalss(aa_original[i], aa_new[i])); + assertEqualSecondaryStructure( + "Different alignment annotation at position " + i, + aa_original[i], aa_new[i]); // compare graphGroup or graph properties - needed to verify JAL-1299 - assertTrue("Graph type not identical.", - aa_original[i].graph == aa_new[i].graph); - assertTrue("Visibility not identical.", - aa_original[i].visible == aa_new[i].visible); - assertTrue( - "Threshold line not identical.", - aa_original[i].threshold == null ? aa_new[i].threshold == null - : aa_original[i].threshold - .equals(aa_new[i].threshold)); + assertEquals("Graph type not identical.", aa_original[i].graph, + aa_new[i].graph); + if (!ignoreRowVisibility) + { + assertEquals("Visibility not identical.", + aa_original[i].visible, + aa_new[i].visible); + } + 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), n_ggrp = new Integer( - aa_new[i].graphGroup + 2); - BitSet orig_g = orig_groups.get(o_ggrp), new_g = new_groups - .get(n_ggrp); + Integer o_ggrp = new Integer(aa_original[i].graphGroup + 2); + Integer n_ggrp = new Integer(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) { orig_groups.put(o_ggrp, orig_g = new BitSet()); @@ -218,8 +253,8 @@ public class StockholmFileTest { new_groups.put(n_ggrp, new_g = new BitSet()); } - assertTrue("Graph Group pattern differs at annotation " + i, - orig_g.equals(new_g)); + assertEquals("Graph Group pattern differs at annotation " + i, + orig_g, new_g); orig_g.set(i); new_g.set(i); } @@ -230,10 +265,9 @@ public class StockholmFileTest } } } - assertTrue( - "Generated and imported alignment have different annotation sets (" - + aa_new_size + " != " + aa_original_size + ")", - aa_new_size == aa_original_size); + assertEquals( + "Generated and imported alignment have different annotation sets", + aa_original_size, aa_new_size); // check sequences, annotation and features SequenceI[] seq_original = new SequenceI[al.getSequencesArray().length]; @@ -260,15 +294,15 @@ public class StockholmFileTest { String ss_original = seq_original[i].getSequenceAsString(); String ss_new = seq_new[in].getSequenceAsString(); - assertTrue("The sequences " + name + "/" + start + "-" + end - + " are not equal", ss_original.equals(ss_new)); + assertEquals("The sequences " + name + "/" + start + "-" + end + + " are not equal", ss_original, ss_new); assertTrue( "Sequence Features were not equivalent" + (ignoreFeatures ? " ignoring." : ""), ignoreFeatures || (seq_original[i].getSequenceFeatures() == null && seq_new[in] - .getSequenceFeatures() == null) + .getSequenceFeatures() == null) || (seq_original[i].getSequenceFeatures() != null && seq_new[in] .getSequenceFeatures() != null)); // compare sequence features @@ -284,15 +318,15 @@ public class StockholmFileTest .getSequenceFeatures().length]; sequenceFeatures_new = seq_new[in].getSequenceFeatures(); - assertTrue("different number of features", seq_original[i] - .getSequenceFeatures().length == seq_new[in] - .getSequenceFeatures().length); + assertEquals("different number of features", + seq_original[i].getSequenceFeatures().length, + seq_new[in].getSequenceFeatures().length); for (int feat = 0; feat < seq_original[i].getSequenceFeatures().length; feat++) { - assertTrue("Different features", - sequenceFeatures_original[feat] - .equals(sequenceFeatures_new[feat])); + assertEquals("Different features", + sequenceFeatures_original[feat], + sequenceFeatures_new[feat]); } } // compare alignment annotation @@ -306,8 +340,9 @@ public class StockholmFileTest { annot_original = al.getSequenceAt(i).getAnnotation()[j]; annot_new = al_input.getSequenceAt(in).getAnnotation()[j]; - assertTrue("Different annotation elements", - equalss(annot_original, annot_new)); + assertEqualSecondaryStructure( + "Different annotation elements", annot_original, + annot_new); } } } @@ -319,9 +354,9 @@ public class StockholmFileTest else if (al.getSequenceAt(i).getAnnotation() != null && al_input.getSequenceAt(in).getAnnotation() == null) { - assertTrue("Annotations differed between sequences (" + fail("Annotations differed between sequences (" + al.getSequenceAt(i).getName() + ") and (" - + al_input.getSequenceAt(i).getName() + ")", false); + + al_input.getSequenceAt(i).getName() + ")"); } break; } @@ -329,39 +364,57 @@ public class StockholmFileTest } } - /* - * compare annotations - */ - private static boolean equalss(AlignmentAnnotation annot_or, + private static void assertEqualSecondaryStructure(String message, + AlignmentAnnotation annot_or, AlignmentAnnotation annot_new) { + // TODO: test to cover this assert behaves correctly for all allowed + // variations of secondary structure annotation row equivalence if (annot_or.annotations.length != annot_new.annotations.length) { - System.err.println("Different lengths for annotation row elements: " + fail("Different lengths for annotation row elements: " + annot_or.annotations.length + "!=" + annot_new.annotations.length); - return false; } + boolean isRna = annot_or.isRNA(); + assertTrue("Expected " + (isRna ? " valid RNA " : " no RNA ") + + " secondary structure in the row.", + isRna == annot_new.isRNA()); for (int i = 0; i < annot_or.annotations.length; i++) { Annotation an_or = annot_or.annotations[i], an_new = annot_new.annotations[i]; if (an_or != null && an_new != null) { - if (!an_or.displayCharacter.trim().equals( - an_new.displayCharacter.trim()) - || !("" + an_or.secondaryStructure).trim().equals( - ("" + an_new.secondaryStructure).trim()) - || (an_or.description != an_new.description && !((an_or.description == null && an_new.description - .trim().length() == 0) - || (an_new.description == null && an_or.description - .trim().length() == 0) || an_or.description - .trim().equals(an_new.description.trim())))) + + if (isRna) + { + if (an_or.secondaryStructure != an_new.secondaryStructure + || an_or.value != an_new.value) + { + fail("Different RNA secondary structure at column " + i + + " expected: [" + annot_or.annotations[i].toString() + + "] but got: [" + annot_new.annotations[i].toString() + + "]"); + } + } + else { - System.err.println("Annotation Element Mismatch\nElement " + i - + " in original: " + annot_or.annotations[i].toString() - + "\nElement " + i + " in new: " - + annot_new.annotations[i].toString()); - return false; + // not RNA secondary structure, so expect all elements to match... + if (!an_or.displayCharacter.trim().equals( + an_new.displayCharacter.trim()) + || !("" + an_or.secondaryStructure).trim().equals( + ("" + an_new.secondaryStructure).trim()) + || (an_or.description != an_new.description && !((an_or.description == null && an_new.description + .trim().length() == 0) + || (an_new.description == null && an_or.description + .trim().length() == 0) || an_or.description + .trim().equals(an_new.description.trim())))) + { + fail("Annotation Element Mismatch\nElement " + i + + " in original: " + annot_or.annotations[i].toString() + + "\nElement " + i + " in new: " + + annot_new.annotations[i].toString()); + } } } else if (annot_or.annotations[i] == null @@ -371,7 +424,7 @@ public class StockholmFileTest } else { - System.err.println("Annotation Element Mismatch\nElement " + fail("Annotation Element Mismatch\nElement " + i + " in original: " + (annot_or.annotations[i] == null ? "is null" @@ -381,9 +434,53 @@ public class StockholmFileTest + " in new: " + (annot_new.annotations[i] == null ? "is null" : annot_new.annotations[i].toString())); - return false; } } - return true; + } + + String aliFile = ">Dm\nAAACCCUUUUACACACGGGAAAGGG"; + String annFile = "JALVIEW_ANNOTATION\n# Created: Thu May 04 11:16:52 BST 2017\n\n" + + "SEQUENCE_REF\tDm\nNO_GRAPH\tsecondary structure\tsecondary structure\t" + + "(|(|(|(|, .|, .|, .|, .|)|)|)|)|\t0.0\nROWPROPERTIES\t" + + "secondary structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false"; + + String annFileFullWuss = "JALVIEW_ANNOTATION\n# Created: Thu May 04 11:16:52 BST 2017\n\n" + + "SEQUENCE_REF\tDm\nNO_GRAPH\tsecondary structure\tsecondary structure\t" + + "(|(|(|(||{|{||[|[||)|)|)|)||}|}|]|]\t0.0\nROWPROPERTIES\t" + + "secondary structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false"; + + @Test(groups = { "Functional" }) + public void secondaryStructureForRNASequence() throws Exception + { + roundTripSSForRNA(aliFile, annFile); + } + + @Test(groups = { "Functional" }) + public void fullWUSSsecondaryStructureForRNASequence() throws Exception + { + roundTripSSForRNA(aliFile, annFileFullWuss); + } + + private static void roundTripSSForRNA(String aliFile, String annFile) + throws Exception + { + AlignmentI al = new AppletFormatAdapter().readFile(aliFile, + DataSourceType.PASTE, jalview.io.FileFormat.Fasta); + AnnotationFile aaf = new AnnotationFile(); + aaf.readAnnotationFile(al, annFile, DataSourceType.PASTE); + al.getAlignmentAnnotation()[0].visible = true; + + // TODO: create a better 'save as ' pattern + StockholmFile sf = new StockholmFile(al); + + String stockholmFile = sf.print(al.getSequencesArray(), true); + + AlignmentI newAl = new AppletFormatAdapter().readFile(stockholmFile, + DataSourceType.PASTE, jalview.io.FileFormat.Stockholm); + // AlignmentUtils.showOrHideSequenceAnnotations(newAl.getViewport() + // .getAlignment(), Arrays.asList("Secondary Structure"), newAl + // .getViewport().getAlignment().getSequences(), true, true); + testAlignmentEquivalence(al, newAl, true, true); + } }