2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertNotNull;
25 import static org.testng.AssertJUnit.assertNull;
26 import static org.testng.AssertJUnit.assertTrue;
27 import static org.testng.AssertJUnit.fail;
29 import jalview.datamodel.Alignment;
30 import jalview.datamodel.AlignmentAnnotation;
31 import jalview.datamodel.AlignmentI;
32 import jalview.datamodel.Annotation;
33 import jalview.datamodel.DBRefEntry;
34 import jalview.datamodel.Sequence;
35 import jalview.datamodel.SequenceFeature;
36 import jalview.datamodel.SequenceI;
37 import jalview.gui.JvOptionPane;
40 import java.util.Arrays;
41 import java.util.BitSet;
42 import java.util.HashMap;
43 import java.util.List;
46 import org.testng.Assert;
47 import org.testng.annotations.BeforeClass;
48 import org.testng.annotations.Test;
50 public class StockholmFileTest
53 @BeforeClass(alwaysRun = true)
54 public void setUpJvOptionPane()
56 JvOptionPane.setInteractiveMode(false);
57 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
60 static String PfamFile = "examples/PF00111_seed.stk",
61 RfamFile = "examples/RF00031_folded.stk";
63 @Test(groups = { "Functional" })
64 public void pfamFileIO() throws Exception
66 testFileIOwithFormat(new File(PfamFile), FileFormat.Stockholm, -1, 0,
70 @Test(groups = { "Functional" })
71 public void pfamFileDataExtraction() throws Exception
73 AppletFormatAdapter af = new AppletFormatAdapter();
74 AlignmentI al = af.readFile(PfamFile, DataSourceType.FILE,
75 new IdentifyFile().identify(PfamFile, DataSourceType.FILE));
77 for (SequenceI sq : al.getSequences())
79 if (sq.getAllPDBEntries() != null)
81 numpdb += sq.getAllPDBEntries().size();
85 "PF00111 seed alignment has at least 1 PDB file, but the reader found none.",
89 @Test(groups = { "Functional" })
90 public void rfamFileIO() throws Exception
92 testFileIOwithFormat(new File(RfamFile), FileFormat.Stockholm, 2, 1,
97 * test alignment data in given file can be imported, exported and reimported
101 * - source datafile (IdentifyFile.identify() should work with it)
103 * - label for IO class used to write and read back in the data from
105 * @param ignoreFeatures
106 * @param ignoreRowVisibility
107 * @param allowNullAnnotations
110 public static void testFileIOwithFormat(File f, FileFormatI ioformat,
111 int naliannot, int nminseqann, boolean ignoreFeatures,
112 boolean ignoreRowVisibility, boolean allowNullAnnotations)
114 System.out.println("Reading file: " + f);
115 String ff = f.getPath();
118 AppletFormatAdapter rf = new AppletFormatAdapter();
120 AlignmentI al = rf.readFile(ff, DataSourceType.FILE,
121 new IdentifyFile().identify(ff, DataSourceType.FILE));
123 assertNotNull("Couldn't read supplied alignment data.", al);
125 // make sure dataset is initialised ? not sure about this
126 for (int i = 0; i < al.getSequencesArray().length; ++i)
128 al.getSequenceAt(i).createDatasetSequence();
130 String outputfile = rf.formatSequences(ioformat, al, true);
131 System.out.println("Output file in '" + ioformat + "':\n"
132 + outputfile + "\n<<EOF\n");
133 // test for consistency in io
134 AlignmentI al_input = new AppletFormatAdapter().readFile(outputfile,
135 DataSourceType.PASTE, ioformat);
136 assertNotNull("Couldn't parse reimported alignment data.", al_input);
138 FileFormatI identifyoutput = new IdentifyFile().identify(outputfile,
139 DataSourceType.PASTE);
140 assertNotNull("Identify routine failed for outputformat " + ioformat,
143 "Identify routine could not recognise output generated by '"
144 + ioformat + "' writer",
145 ioformat.equals(identifyoutput));
146 testAlignmentEquivalence(al, al_input, ignoreFeatures,
147 ignoreRowVisibility, allowNullAnnotations);
148 int numaliannot = 0, numsqswithali = 0;
149 for (AlignmentAnnotation ala : al_input.getAlignmentAnnotation())
151 if (ala.sequenceRef == null)
162 assertEquals("Number of alignment annotations", naliannot,
167 "Number of sequence associated annotations wasn't at least "
168 + nminseqann, numsqswithali >= nminseqann);
170 } catch (Exception e)
173 assertTrue("Couln't format the alignment for output file.", false);
178 * assert alignment equivalence
183 * 'secondary' or generated alignment from some datapreserving
185 * @param ignoreFeatures
186 * when true, differences in sequence feature annotation are ignored
188 public static void testAlignmentEquivalence(AlignmentI al,
189 AlignmentI al_input, boolean ignoreFeatures)
191 testAlignmentEquivalence(al, al_input, ignoreFeatures, false, false);
195 * assert alignment equivalence - uses special comparators for RNA structure
201 * 'secondary' or generated alignment from some datapreserving
203 * @param ignoreFeatures
204 * when true, differences in sequence feature annotation are ignored
206 * @param ignoreRowVisibility
207 * when true, do not fail if there are differences in the visibility
209 * @param allowNullAnnotation
210 * when true, positions in alignment annotation that are null will be
211 * considered equal to positions containing annotation where
212 * Annotation.isWhitespace() returns true.
215 public static void testAlignmentEquivalence(AlignmentI al,
216 AlignmentI al_input, boolean ignoreFeatures,
217 boolean ignoreRowVisibility, boolean allowNullAnnotation)
219 assertNotNull("Original alignment was null", al);
220 assertNotNull("Generated alignment was null", al_input);
222 assertTrue("Alignment dimension mismatch: original: " + al.getHeight()
223 + "x" + al.getWidth() + ", generated: " + al_input.getHeight()
224 + "x" + al_input.getWidth(),
225 al.getHeight() == al_input.getHeight()
226 && al.getWidth() == al_input.getWidth());
228 // check Alignment annotation
229 AlignmentAnnotation[] aa_new = al_input.getAlignmentAnnotation();
230 AlignmentAnnotation[] aa_original = al.getAlignmentAnnotation();
232 // note - at moment we do not distinguish between alignment without any
233 // annotation rows and alignment with no annotation row vector
234 // we might want to revise this in future
235 int aa_new_size = (aa_new == null ? 0 : aa_new.length);
236 int aa_original_size = (aa_original == null ? 0 : aa_original.length);
237 Map<Integer, BitSet> orig_groups = new HashMap<>();
238 Map<Integer, BitSet> new_groups = new HashMap<>();
240 if (aa_new != null && aa_original != null)
242 for (int i = 0; i < aa_original.length; i++)
244 if (aa_new.length > i)
246 assertEqualSecondaryStructure(
247 "Different alignment annotation at position " + i,
248 aa_original[i], aa_new[i], allowNullAnnotation);
249 // compare graphGroup or graph properties - needed to verify JAL-1299
250 assertEquals("Graph type not identical.", aa_original[i].graph,
252 if (!ignoreRowVisibility)
254 assertEquals("Visibility not identical.",
255 aa_original[i].visible,
258 assertEquals("Threshold line not identical.",
259 aa_original[i].threshold, aa_new[i].threshold);
260 // graphGroup may differ, but pattern should be the same
261 Integer o_ggrp = new Integer(aa_original[i].graphGroup + 2);
262 Integer n_ggrp = new Integer(aa_new[i].graphGroup + 2);
263 BitSet orig_g = orig_groups.get(o_ggrp);
264 BitSet new_g = new_groups.get(n_ggrp);
267 orig_groups.put(o_ggrp, orig_g = new BitSet());
271 new_groups.put(n_ggrp, new_g = new BitSet());
273 assertEquals("Graph Group pattern differs at annotation " + i,
280 System.err.println("No matching annotation row for "
281 + aa_original[i].toString());
286 "Generated and imported alignment have different annotation sets",
287 aa_original_size, aa_new_size);
289 // check sequences, annotation and features
290 SequenceI[] seq_original = new SequenceI[al.getSequencesArray().length];
291 seq_original = al.getSequencesArray();
292 SequenceI[] seq_new = new SequenceI[al_input.getSequencesArray().length];
293 seq_new = al_input.getSequencesArray();
294 List<SequenceFeature> sequenceFeatures_original;
295 List<SequenceFeature> sequenceFeatures_new;
296 AlignmentAnnotation annot_original, annot_new;
298 for (int i = 0; i < al.getSequencesArray().length; i++)
300 String name = seq_original[i].getName();
301 int start = seq_original[i].getStart();
302 int end = seq_original[i].getEnd();
303 System.out.println("Check sequence: " + name + "/" + start + "-"
306 // search equal sequence
307 for (int in = 0; in < al_input.getSequencesArray().length; in++)
309 if (name.equals(seq_new[in].getName())
310 && start == seq_new[in].getStart()
311 && end == seq_new[in].getEnd())
313 String ss_original = seq_original[i].getSequenceAsString();
314 String ss_new = seq_new[in].getSequenceAsString();
315 assertEquals("The sequences " + name + "/" + start + "-" + end
316 + " are not equal", ss_original, ss_new);
319 "Sequence Features were not equivalent"
320 + (ignoreFeatures ? " ignoring." : ""),
322 || (seq_original[i].getSequenceFeatures() == null && seq_new[in]
323 .getSequenceFeatures() == null)
324 || (seq_original[i].getSequenceFeatures() != null && seq_new[in]
325 .getSequenceFeatures() != null));
326 // compare sequence features
327 if (seq_original[i].getSequenceFeatures() != null
328 && seq_new[in].getSequenceFeatures() != null)
330 System.out.println("There are feature!!!");
331 sequenceFeatures_original = seq_original[i]
332 .getSequenceFeatures();
333 sequenceFeatures_new = seq_new[in].getSequenceFeatures();
335 assertEquals("different number of features", seq_original[i]
336 .getSequenceFeatures().size(), seq_new[in]
337 .getSequenceFeatures().size());
339 for (int feat = 0; feat < seq_original[i].getSequenceFeatures()
342 assertEquals("Different features",
343 sequenceFeatures_original.get(feat),
344 sequenceFeatures_new.get(feat));
347 // compare alignment annotation
348 if (al.getSequenceAt(i).getAnnotation() != null
349 && al_input.getSequenceAt(in).getAnnotation() != null)
351 for (int j = 0; j < al.getSequenceAt(i).getAnnotation().length; j++)
353 if (al.getSequenceAt(i).getAnnotation()[j] != null
354 && al_input.getSequenceAt(in).getAnnotation()[j] != null)
356 annot_original = al.getSequenceAt(i).getAnnotation()[j];
357 annot_new = al_input.getSequenceAt(in).getAnnotation()[j];
358 assertEqualSecondaryStructure(
359 "Different annotation elements", annot_original,
360 annot_new, allowNullAnnotation);
364 else if (al.getSequenceAt(i).getAnnotation() == null
365 && al_input.getSequenceAt(in).getAnnotation() == null)
367 System.out.println("No annotations");
369 else if (al.getSequenceAt(i).getAnnotation() != null
370 && al_input.getSequenceAt(in).getAnnotation() == null)
372 fail("Annotations differed between sequences ("
373 + al.getSequenceAt(i).getName() + ") and ("
374 + al_input.getSequenceAt(i).getName() + ")");
383 * compare two annotation rows, with special support for secondary structure
384 * comparison. With RNA, only the value and the secondaryStructure symbols are
385 * compared, displayCharacter and description are ignored. Annotations where
386 * Annotation.isWhitespace() is true are always considered equal.
389 * - not actually used yet..
391 * - the original annotation
393 * - the one compared to the original annotation
394 * @param allowNullEquivalence
395 * when true, positions in alignment annotation that are null will be
396 * considered equal to non-null positions for which
397 * Annotation.isWhitespace() is true.
399 private static void assertEqualSecondaryStructure(String message,
400 AlignmentAnnotation annot_or, AlignmentAnnotation annot_new,
401 boolean allowNullEqivalence)
403 // TODO: test to cover this assert behaves correctly for all allowed
404 // variations of secondary structure annotation row equivalence
405 if (annot_or.annotations.length != annot_new.annotations.length)
407 fail("Different lengths for annotation row elements: "
408 + annot_or.annotations.length + "!="
409 + annot_new.annotations.length);
411 boolean isRna = annot_or.isRNA();
412 assertTrue("Expected " + (isRna ? " valid RNA " : " no RNA ")
413 + " secondary structure in the row.",
414 isRna == annot_new.isRNA());
415 for (int i = 0; i < annot_or.annotations.length; i++)
417 Annotation an_or = annot_or.annotations[i], an_new = annot_new.annotations[i];
418 if (an_or != null && an_new != null)
423 if (an_or.secondaryStructure != an_new.secondaryStructure
424 || ((Float.isNaN(an_or.value) != Float
425 .isNaN(an_new.value)) || an_or.value != an_new.value))
427 fail("Different RNA secondary structure at column " + i
428 + " expected: [" + annot_or.annotations[i].toString()
429 + "] but got: [" + annot_new.annotations[i].toString()
435 // not RNA secondary structure, so expect all elements to match...
436 if ((an_or.isWhitespace() != an_new.isWhitespace())
437 || !an_or.displayCharacter.trim().equals(
438 an_new.displayCharacter.trim())
439 || !("" + an_or.secondaryStructure).trim().equals(
440 ("" + an_new.secondaryStructure).trim())
441 || (an_or.description != an_new.description && !((an_or.description == null && an_new.description
442 .trim().length() == 0)
443 || (an_new.description == null && an_or.description
444 .trim().length() == 0) || an_or.description
445 .trim().equals(an_new.description.trim())))
446 || !((Float.isNaN(an_or.value) && Float
447 .isNaN(an_new.value)) || an_or.value == an_new.value))
449 fail("Annotation Element Mismatch\nElement " + i
450 + " in original: " + annot_or.annotations[i].toString()
451 + "\nElement " + i + " in new: "
452 + annot_new.annotations[i].toString());
456 else if (annot_or.annotations[i] == null
457 && annot_new.annotations[i] == null)
463 if (allowNullEqivalence)
465 if (an_or != null && an_or.isWhitespace())
470 if (an_new != null && an_new.isWhitespace())
475 // need also to test for null in one, non-SS annotation in other...
476 fail("Annotation Element Mismatch\nElement " + i + " in original: "
477 + (an_or == null ? "is null" : an_or.toString())
478 + "\nElement " + i + " in new: "
479 + (an_new == null ? "is null" : an_new.toString()));
485 * @see assertEqualSecondaryStructure - test if two secondary structure
486 * annotations are not equal
490 * @param allowNullEquivalence
492 public static void assertNotEqualSecondaryStructure(String message,
493 AlignmentAnnotation an_orig, AlignmentAnnotation an_new,
494 boolean allowNullEquivalence)
496 boolean thrown = false;
499 assertEqualSecondaryStructure("", an_orig, an_new,
500 allowNullEquivalence);
501 } catch (AssertionError af)
507 fail("Expected difference for [" + an_orig + "] and [" + an_new + "]");
510 private AlignmentAnnotation makeAnnot(Annotation ae)
512 return new AlignmentAnnotation("label", "description", new Annotation[]
516 @Test(groups={"Functional"})
517 public void testAnnotationEquivalence()
519 AlignmentAnnotation one = makeAnnot(new Annotation("", "", ' ', 1));
520 AlignmentAnnotation anotherOne = makeAnnot(new Annotation("", "", ' ',
522 AlignmentAnnotation sheet = makeAnnot(new Annotation("","",'E',0f));
523 AlignmentAnnotation anotherSheet = makeAnnot(new Annotation("","",'E',0f));
524 AlignmentAnnotation sheetWithLabel = makeAnnot(new Annotation("1", "",
526 AlignmentAnnotation anotherSheetWithLabel = makeAnnot(new Annotation(
528 AlignmentAnnotation rnaNoDC = makeAnnot(new Annotation("","",'<',0f));
529 AlignmentAnnotation anotherRnaNoDC = makeAnnot(new Annotation("","",'<',0f));
530 AlignmentAnnotation rnaWithDC = makeAnnot(new Annotation("B", "", '<',
532 AlignmentAnnotation anotherRnaWithDC = makeAnnot(new Annotation("B",
535 // check self equivalence
536 for (boolean allowNull : new boolean[] { true, false })
538 assertEqualSecondaryStructure("Should be equal", one, anotherOne,
540 assertEqualSecondaryStructure("Should be equal", sheet, anotherSheet,
542 assertEqualSecondaryStructure("Should be equal", sheetWithLabel,
543 anotherSheetWithLabel, allowNull);
544 assertEqualSecondaryStructure("Should be equal", rnaNoDC,
545 anotherRnaNoDC, allowNull);
546 assertEqualSecondaryStructure("Should be equal", rnaWithDC,
547 anotherRnaWithDC, allowNull);
548 // display character doesn't matter for RNA structure (for 2.10.2)
549 assertEqualSecondaryStructure("Should be equal", rnaWithDC, rnaNoDC,
551 assertEqualSecondaryStructure("Should be equal", rnaNoDC, rnaWithDC,
555 // verify others are different
556 List<AlignmentAnnotation> aaSet = Arrays.asList(one, sheet,
557 sheetWithLabel, rnaWithDC);
558 for (int p = 0; p < aaSet.size(); p++)
560 for (int q = 0; q < aaSet.size(); q++)
564 assertNotEqualSecondaryStructure("Should be different",
565 aaSet.get(p), aaSet.get(q), false);
569 assertEqualSecondaryStructure("Should be same", aaSet.get(p),
570 aaSet.get(q), false);
571 assertEqualSecondaryStructure("Should be same", aaSet.get(p),
573 assertNotEqualSecondaryStructure(
574 "Should be different to empty anot", aaSet.get(p),
575 makeAnnot(Annotation.EMPTY_ANNOTATION), false);
576 assertNotEqualSecondaryStructure(
577 "Should be different to empty annot",
578 makeAnnot(Annotation.EMPTY_ANNOTATION), aaSet.get(q),
580 assertNotEqualSecondaryStructure("Should be different to null",
581 aaSet.get(p), makeAnnot(null), false);
582 assertNotEqualSecondaryStructure("Should be different to null",
583 makeAnnot(null), aaSet.get(q), true);
592 String aliFile = ">Dm\nAAACCCUUUUACACACGGGAAAGGG";
593 String annFile = "JALVIEW_ANNOTATION\n# Created: Thu May 04 11:16:52 BST 2017\n\n"
594 + "SEQUENCE_REF\tDm\nNO_GRAPH\tsecondary structure\tsecondary structure\t"
595 + "(|(|(|(|, .|, .|, .|, .|)|)|)|)|\t0.0\nROWPROPERTIES\t"
596 + "secondary structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false";
598 String annFileCurlyWuss = "JALVIEW_ANNOTATION\n# Created: Thu May 04 11:16:52 BST 2017\n\n"
599 + "SEQUENCE_REF\tDm\nNO_GRAPH\tsecondary structure\tsecondary structure\t"
600 + "(|(|(|(||{|{||{|{||)|)|)|)||}|}|}|}|\t0.0\nROWPROPERTIES\t"
601 + "secondary structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false";
602 String annFileFullWuss = "JALVIEW_ANNOTATION\n# Created: Thu May 04 11:16:52 BST 2017\n\n"
603 + "SEQUENCE_REF\tDm\nNO_GRAPH\tsecondary structure\tsecondary structure\t"
604 + "(|(|(|(||{|{||[|[||)|)|)|)||}|}|]|]|\t0.0\nROWPROPERTIES\t"
605 + "secondary structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false";
607 @Test(groups = { "Functional" })
608 public void secondaryStructureForRNASequence() throws Exception
610 roundTripSSForRNA(aliFile, annFile);
613 @Test(groups = { "Functional" })
614 public void curlyWUSSsecondaryStructureForRNASequence() throws Exception
616 roundTripSSForRNA(aliFile, annFileCurlyWuss);
619 @Test(groups = { "Functional" })
620 public void fullWUSSsecondaryStructureForRNASequence() throws Exception
622 roundTripSSForRNA(aliFile, annFileFullWuss);
625 @Test(groups = { "Functional" })
626 public void detectWussBrackets()
628 for (char ch : new char[] { '{', '}', '[', ']', '(', ')', '<', '>' })
630 Assert.assertTrue(StockholmFile.DETECT_BRACKETS.matchAt("" + ch, 0),
631 "Didn't recognise " + ch + " as a WUSS bracket");
633 for (char ch : new char[] { '@', '!', 'V', 'Q', '*', ' ', '-', '.' })
635 Assert.assertFalse(StockholmFile.DETECT_BRACKETS.matchAt("" + ch, 0),
636 "Shouldn't recognise " + ch + " as a WUSS bracket");
639 private static void roundTripSSForRNA(String aliFile, String annFile)
642 AlignmentI al = new AppletFormatAdapter().readFile(aliFile,
643 DataSourceType.PASTE, jalview.io.FileFormat.Fasta);
644 AnnotationFile aaf = new AnnotationFile();
645 aaf.readAnnotationFile(al, annFile, DataSourceType.PASTE);
646 al.getAlignmentAnnotation()[0].visible = true;
648 // TODO: create a better 'save as <format>' pattern
649 StockholmFile sf = new StockholmFile(al);
651 String stockholmFile = sf.print(al.getSequencesArray(), true);
653 AlignmentI newAl = new AppletFormatAdapter().readFile(stockholmFile,
654 DataSourceType.PASTE, jalview.io.FileFormat.Stockholm);
655 // AlignmentUtils.showOrHideSequenceAnnotations(newAl.getViewport()
656 // .getAlignment(), Arrays.asList("Secondary Structure"), newAl
657 // .getViewport().getAlignment().getSequences(), true, true);
658 testAlignmentEquivalence(al, newAl, true, true, true);
662 @Test(groups = { "Functional" })
663 public void testTypeToDescription()
665 assertEquals("Secondary Structure",
666 StockholmFile.typeToDescription("SS"));
667 assertEquals("Surface Accessibility",
668 StockholmFile.typeToDescription("SA"));
669 assertEquals("transmembrane", StockholmFile.typeToDescription("TM"));
670 assertEquals("Posterior Probability",
671 StockholmFile.typeToDescription("PP"));
672 assertEquals("ligand binding", StockholmFile.typeToDescription("LI"));
673 assertEquals("active site", StockholmFile.typeToDescription("AS"));
674 assertEquals("intron", StockholmFile.typeToDescription("IN"));
675 assertEquals("interacting residue",
676 StockholmFile.typeToDescription("IR"));
677 assertEquals("accession", StockholmFile.typeToDescription("AC"));
678 assertEquals("organism", StockholmFile.typeToDescription("OS"));
679 assertEquals("class", StockholmFile.typeToDescription("CL"));
680 assertEquals("description", StockholmFile.typeToDescription("DE"));
681 assertEquals("reference", StockholmFile.typeToDescription("DR"));
682 assertEquals("look", StockholmFile.typeToDescription("LO"));
683 assertEquals("Reference Positions",
684 StockholmFile.typeToDescription("RF"));
687 assertEquals("Rf", StockholmFile.typeToDescription("Rf"));
688 assertEquals("junk", StockholmFile.typeToDescription("junk"));
689 assertEquals("", StockholmFile.typeToDescription(""));
690 assertNull(StockholmFile.typeToDescription(null));
693 @Test(groups = { "Functional" })
694 public void testDescriptionToType()
697 StockholmFile.descriptionToType("Secondary Structure"));
699 StockholmFile.descriptionToType("Surface Accessibility"));
700 assertEquals("TM", StockholmFile.descriptionToType("transmembrane"));
702 // test is not case-sensitive:
704 StockholmFile.descriptionToType("secondary structure"));
706 // test is white-space sensitive:
707 assertNull(StockholmFile.descriptionToType("secondary structure "));
709 assertNull(StockholmFile.descriptionToType("any old junk"));
710 assertNull(StockholmFile.descriptionToType(""));
711 assertNull(StockholmFile.descriptionToType(null));
714 @Test(groups = { "Functional" })
715 public void testPrint()
717 SequenceI seq1 = new Sequence("seq1", "LKMF-RS-Q");
718 SequenceI seq2 = new Sequence("seq2/10-15", "RRS-LIP-");
719 SequenceI[] seqs = new SequenceI[] { seq1, seq2 };
720 AlignmentI al = new Alignment(seqs);
722 StockholmFile testee = new StockholmFile(al);
725 * basic output (sequences only):
726 * sequence ids are padded with 9 spaces more than the widest id
728 String output = testee.print(seqs, true);
729 String expected = "# STOCKHOLM 1.0\n" + "seq1/1-7 LKMF-RS-Q\n"
730 + "seq2/10-15 RRS-LIP-\n//\n";
731 assertEquals(expected, output);
736 seq1.addDBRef(new DBRefEntry("PFAM", "1", "PF00111"));
737 seq1.addDBRef(new DBRefEntry("UNIPROT", "1", "P83527"));
738 seq2.addDBRef(new DBRefEntry("RFAM", "1", "AY119185.1"));
739 seq2.addDBRef(new DBRefEntry("EMBL", "1", "AF125575"));
740 output = testee.print(seqs, true);
741 // PFAM and RFAM dbrefs should be output as AC, others as DR
742 expected = "# STOCKHOLM 1.0\n" + "#=GS seq1/1-7 AC PF00111\n"
743 + "#=GS seq1/1-7 DR UNIPROT ; P83527\n"
744 + "#=GS seq2/10-15 AC AY119185.1\n"
745 + "#=GS seq2/10-15 DR EMBL ; AF125575\n"
746 + "seq1/1-7 LKMF-RS-Q\n"
747 + "seq2/10-15 RRS-LIP-\n//\n";
748 assertEquals(expected, output);
751 * add some sequence and alignment annotation
753 Annotation[] anns = new Annotation[5];
754 for (int i = 0; i < anns.length; i++)
756 anns[i] = new Annotation(String.valueOf((char) ('B' + i)),
758 (char) ('C' + i), i + 3);
761 // expect "secondary structure" to be output as #=GR seqid SS
762 // using the secondary structure character (CDEFG) not display char (BCDEF)
763 AlignmentAnnotation aa1 = new AlignmentAnnotation("secondary structure",
765 aa1.sequenceRef = seq1;
766 seq1.addAlignmentAnnotation(aa1);
767 al.addAnnotation(aa1);
769 // "sec structure" should not be output as no corresponding feature id
770 AlignmentAnnotation aa2 = new AlignmentAnnotation("sec structure",
772 aa2.sequenceRef = seq2;
773 seq2.addAlignmentAnnotation(aa2);
774 al.addAnnotation(aa2);
776 // alignment annotation for Reference Positions: output as #=GC RF
777 AlignmentAnnotation aa3 = new AlignmentAnnotation("reference positions",
779 al.addAnnotation(aa3);
781 // 'seq' annotation: output as seq_cons
782 AlignmentAnnotation aa4 = new AlignmentAnnotation("seq", "seqdesc",
784 al.addAnnotation(aa4);
786 // 'intron' annotation: output as IN_cons
787 AlignmentAnnotation aa5 = new AlignmentAnnotation("intron",
789 al.addAnnotation(aa5);
791 // 'binding site' annotation: output as binding_site
792 AlignmentAnnotation aa6 = new AlignmentAnnotation("binding site",
793 "bindingdesc", anns);
794 al.addAnnotation(aa6);
796 // 'autocalc' annotation should not be output
797 AlignmentAnnotation aa7 = new AlignmentAnnotation("Consensus",
798 "consensusdesc", anns);
799 aa7.autoCalculated = true;
800 al.addAnnotation(aa7);
802 // hidden annotation should not be output
803 AlignmentAnnotation aa8 = new AlignmentAnnotation("domains",
806 al.addAnnotation(aa8);
808 output = testee.print(seqs, true);
812 + "#=GS seq1/1-7 AC PF00111\n"
813 + "#=GS seq1/1-7 DR UNIPROT ; P83527\n"
814 + "#=GS seq2/10-15 AC AY119185.1\n"
815 + "#=GS seq2/10-15 DR EMBL ; AF125575\n"
816 + "#=GR seq1/1-7 SS CDEFG\n"
817 + "seq1/1-7 LKMF-RS-Q\n"
818 + "seq2/10-15 RRS-LIP-\n"
819 + "#=GC RF BCDEF\n" + "#=GC seq_cons BCDEF\n"
820 + "#=GC IN_cons BCDEF\n" + "#=GC binding_site BCDEF\n"
823 assertEquals(expected, output);