package jalview.io; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.Annotation; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; import java.io.File; import java.util.BitSet; import java.util.HashMap; import java.util.Map; import org.junit.Test; public class StockholmFileTest { static String PfamFile = "examples/PF00111_seed.stk", RfamFile = "examples/RF00031_folded.stk"; @Test public void pfamFileIO() throws Exception { testFileIOwithFormat(new File(PfamFile), "STH"); } @Test public void pfamFileDataExtraction() throws Exception { AppletFormatAdapter af = new AppletFormatAdapter(); AlignmentI al = af.readFile(PfamFile, af.FILE, new IdentifyFile().Identify(PfamFile, af.FILE)); int numpdb = 0; for (SequenceI sq : al.getSequences()) { if (sq.getPDBId() != null) { numpdb += sq.getPDBId().size(); } } assertTrue( "PF00111 seed alignment has at least 1 PDB file, but the reader found none.", numpdb > 0); } @Test public void rfamFileIO() throws Exception { testFileIOwithFormat(new File(RfamFile), "STH"); } /** * 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) * @param ioformat * - label for IO class used to write and read back in the data from * f */ public static void testFileIOwithFormat(File f, String ioformat) { System.out.println("Reading file: " + f); String ff = f.getPath(); try { AppletFormatAdapter rf = new AppletFormatAdapter(); Alignment al = rf.readFile(ff, AppletFormatAdapter.FILE, new IdentifyFile().Identify(ff, AppletFormatAdapter.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)); } String outputfile = rf.formatSequences(ioformat, al, true); System.out.println("Output file in '"+ioformat+"':\n"+outputfile+"\n< orig_groups=new HashMap(),new_groups=new HashMap(); if (aa_new != null && aa_original != null) { for (int i = 0; i < aa_original.length; i++) { if (aa_new.length>i) { assertTrue("Different alignment annotation at position "+i, equalss(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)); // 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); if (orig_g==null) { orig_groups.put(o_ggrp,orig_g= new BitSet()); } if (new_g==null) { new_groups.put(n_ggrp, new_g=new BitSet()); } assertTrue("Graph Group pattern differs at annotation "+i, orig_g.equals(new_g)); orig_g.set(i); new_g.set(i); } else { System.err.println("No matching annotation row for "+aa_original[i].toString()); } } } assertTrue( "Generated and imported alignment have different annotation sets (" + aa_new_size + " != " + aa_original_size + ")", aa_new_size == aa_original_size); // check sequences, annotation and features SequenceI[] seq_original = new SequenceI[al.getSequencesArray().length]; seq_original = al.getSequencesArray(); SequenceI[] seq_new = new SequenceI[al_input.getSequencesArray().length]; seq_new = al_input.getSequencesArray(); SequenceFeature[] sequenceFeatures_original, sequenceFeatures_new; AlignmentAnnotation annot_original, annot_new; // for (int i = 0; i < al.getSequencesArray().length; i++) { String name = seq_original[i].getName(); int start = seq_original[i].getStart(); int end = seq_original[i].getEnd(); System.out.println("Check sequence: " + name + "/" + start + "-" + end); // search equal sequence for (int in = 0; in < al_input.getSequencesArray().length; in++) { if (name.equals(seq_new[in].getName()) && start == seq_new[in].getStart() && end == seq_new[in].getEnd()) { 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)); assertTrue( "Sequence Features were not equivalent", (seq_original[i].getSequenceFeatures() == null && seq_new[in] .getSequenceFeatures() == null) || (seq_original[i].getSequenceFeatures() != null && seq_new[in] .getSequenceFeatures() != null)); // compare sequence features if (seq_original[i].getSequenceFeatures() != null && seq_new[in].getSequenceFeatures() != null) { System.out.println("There are feature!!!"); sequenceFeatures_original = new SequenceFeature[seq_original[i] .getSequenceFeatures().length]; sequenceFeatures_original = seq_original[i] .getSequenceFeatures(); sequenceFeatures_new = new SequenceFeature[seq_new[in] .getSequenceFeatures().length]; sequenceFeatures_new = seq_new[in].getSequenceFeatures(); assertTrue("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])); } } // compare alignment annotation if (al.getSequenceAt(i).getAnnotation() != null && al_input.getSequenceAt(in).getAnnotation() != null) { for (int j = 0; j < al.getSequenceAt(i).getAnnotation().length; j++) { if (al.getSequenceAt(i).getAnnotation()[j] != null && al_input.getSequenceAt(in).getAnnotation()[j] != null) { annot_original = al.getSequenceAt(i).getAnnotation()[j]; annot_new = al_input.getSequenceAt(in).getAnnotation()[j]; assertTrue("Different annotation elements", equalss(annot_original, annot_new)); } } } else if (al.getSequenceAt(i).getAnnotation() == null && al_input.getSequenceAt(in).getAnnotation() == null) { System.out.println("No annotations"); } else if (al.getSequenceAt(i).getAnnotation() != null && al_input.getSequenceAt(in).getAnnotation() == null) { assertTrue("Annotations differed between sequences (" + al.getSequenceAt(i).getName() + ") and (" + al_input.getSequenceAt(i).getName() + ")", false); } break; } } } } /* * compare annotations */ private static boolean equalss(AlignmentAnnotation annot_or, AlignmentAnnotation annot_new) { if (annot_or.annotations.length != annot_new.annotations.length) { System.err.println("Different lengths for annotation row elements: "+annot_or.annotations.length +"!="+ annot_new.annotations.length); return false; } 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 == null || !an_or.description .equals(an_new.description)))) { 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; } } else if (annot_or.annotations[i] == null && annot_new.annotations[i] == null) { continue; } else { System.err.println("Annotation Element Mismatch\nElement "+i+" in original: "+(annot_or.annotations[i]==null ? "is null" : annot_or.annotations[i].toString())+"\nElement "+i+" in new: "+(annot_new.annotations[i] == null ? "is null" : annot_new.annotations[i].toString())); return false; } } return true; } }