JAL-1199 JAL-1272 remove main() method from test class
[jalview.git] / test / jalview / io / StockholmFileTest.java
1 package jalview.io;
2
3 import static org.junit.Assert.*;
4 import jalview.datamodel.Alignment;
5 import jalview.datamodel.AlignmentAnnotation;
6 import jalview.datamodel.AlignmentI;
7 import jalview.datamodel.SequenceFeature;
8 import jalview.datamodel.SequenceI;
9
10 import java.io.File;
11 import java.io.IOException;
12 import java.io.InputStream;
13
14 import org.junit.Test;
15
16 public class StockholmFileTest
17 {
18
19   static String PfamFile = "examples/PF00111_seed.stk",
20           RfamFile = "examples/RF00031_folded.stk";
21
22   @Test
23   public void pfamFileIO() throws Exception
24   {
25       test(new File(PfamFile));
26       AppletFormatAdapter af = new AppletFormatAdapter();
27       AlignmentI al = af.readFile(PfamFile, af.FILE, new IdentifyFile().Identify(PfamFile, af.FILE));
28       int numpdb=0;
29       for (SequenceI sq:al.getSequences())
30       {
31         if (sq.getPDBId()!=null)
32         {
33           numpdb+=sq.getPDBId().size();
34         }
35       }
36       assertTrue("PF00111 seed alignment has at least 1 PDB file, but the reader found none.",numpdb>0);
37   }
38   @Test
39   public void rfamFileIO() throws Exception
40   {
41     testFileIOwithFormat(new File(RfamFile), "STH");
42   }
43
44   /**
45    * test alignment data in given file can be imported, exported and reimported
46    * with no dataloss
47    * 
48    * @param f
49    *          - source datafile (IdentifyFile.identify() should work with it)
50    * @param ioformat
51    *          - label for IO class used to write and read back in the data from
52    *          f
53    */
54   public static void testFileIOwithFormat(File f, String ioformat)
55   {
56     System.out.println("Reading file: " + f);
57     String ff = f.getPath();
58     try
59     {
60       AppletFormatAdapter rf = new AppletFormatAdapter();
61
62       Alignment al = rf.readFile(ff, AppletFormatAdapter.FILE,
63               new IdentifyFile().Identify(ff, AppletFormatAdapter.FILE));
64
65       assertNotNull("Couldn't read supplied alignment data.", al);
66
67       // make sure dataset is initialised ? not sure about this
68       for (int i = 0; i < al.getSequencesArray().length; ++i)
69       {
70         al.getSequenceAt(i).setDatasetSequence(al.getSequenceAt(i));
71       }
72       String outputfile = rf.formatSequences(ioformat, al, true);
73       System.out.println("Output file in '"+ioformat+"':\n"+outputfile+"\n<<EOF\n");
74       // test for consistency in io
75       Alignment al_input = new AppletFormatAdapter().readFile(outputfile,
76               AppletFormatAdapter.PASTE, ioformat);
77       assertNotNull("Couldn't parse reimported alignment data.", al_input);
78
79       String identifyoutput = new IdentifyFile().Identify(outputfile,
80               AppletFormatAdapter.PASTE);
81       assertNotNull("Identify routine failed for outputformat " + ioformat,
82               identifyoutput);
83       assertTrue(
84               "Identify routine could not recognise output generated by '"
85                       + ioformat + "' writer",
86               ioformat.equals(identifyoutput));
87       testAlignmentEquivalence(al, al_input);
88     } catch (Exception e)
89     {
90       e.printStackTrace();
91       assertTrue("Couln't format the alignment for output file.", false);
92     }
93   }
94
95   /**
96    * assert alignment equivalence
97    * 
98    * @param al
99    *          'original'
100    * @param al_input
101    *          'secondary' or generated alignment from some datapreserving
102    *          transformation
103    */
104   private static void testAlignmentEquivalence(AlignmentI al,
105           AlignmentI al_input)
106   {
107     assertNotNull("Original alignment was null", al);
108     assertNotNull("Generated alignment was null", al_input);
109
110     assertTrue(
111             "Alignment dimension mismatch: originl contains "
112                     + al.getHeight() + " and generated has "
113                     + al_input.getHeight() + " sequences; original has "
114                     + al.getWidth() + " and generated has "
115                     + al_input.getWidth() + " columns.",
116             al.getHeight() == al_input.getHeight()
117                     && al.getWidth() == al_input.getWidth());
118
119     // check Alignment annotation
120     AlignmentAnnotation[] aa_new = al_input.getAlignmentAnnotation();
121     AlignmentAnnotation[] aa_original = al.getAlignmentAnnotation();
122
123     // note - at moment we do not distinguish between alignment without any
124     // annotation rows and alignment with no annotation row vector
125     // we might want to revise this in future
126     int aa_new_size = (aa_new == null ? 0 : aa_new.length), aa_original_size = (aa_original == null ? 0
127             : aa_original.length);
128
129     if (aa_new != null && aa_original != null)
130     {
131       for (int i = 0; i < aa_original.length; i++)
132       {
133         if (aa_new.length>i) {
134           assertTrue("Different alignment annotation ordering",
135                 equalss(aa_original[i], aa_new[i]));
136         } else {
137           System.err.println("No matching annotation row for "+aa_original[i].toString());
138         }
139       }
140     }
141     assertTrue(
142             "Generated and imported alignment have different annotation sets ("
143                     + aa_new_size + " != " + aa_original_size + ")",
144             aa_new_size == aa_original_size);
145
146     // check sequences, annotation and features
147     SequenceI[] seq_original = new SequenceI[al.getSequencesArray().length];
148     seq_original = al.getSequencesArray();
149     SequenceI[] seq_new = new SequenceI[al_input.getSequencesArray().length];
150     seq_new = al_input.getSequencesArray();
151     SequenceFeature[] sequenceFeatures_original, sequenceFeatures_new;
152     AlignmentAnnotation annot_original, annot_new;
153     //
154     for (int i = 0; i < al.getSequencesArray().length; i++)
155     {
156       String name = seq_original[i].getName();
157       int start = seq_original[i].getStart();
158       int end = seq_original[i].getEnd();
159       System.out.println("Check sequence: " + name + "/" + start + "-"
160               + end);
161
162       // search equal sequence
163       for (int in = 0; in < al_input.getSequencesArray().length; in++)
164       {
165         if (name.equals(seq_new[in].getName())
166                 && start == seq_new[in].getStart()
167                 && end == seq_new[in].getEnd())
168         {
169           String ss_original = seq_original[i].getSequenceAsString();
170           String ss_new = seq_new[in].getSequenceAsString();
171           assertTrue("The sequences " + name + "/" + start + "-" + end
172                   + " are not equal", ss_original.equals(ss_new));
173
174           assertTrue(
175                   "Sequence Features were not equivalent",
176                   (seq_original[i].getSequenceFeatures() == null && seq_new[in]
177                           .getSequenceFeatures() == null)
178                           || (seq_original[i].getSequenceFeatures() != null && seq_new[in]
179                                   .getSequenceFeatures() != null));
180           // compare sequence features
181           if (seq_original[i].getSequenceFeatures() != null
182                   && seq_new[in].getSequenceFeatures() != null)
183           {
184             System.out.println("There are feature!!!");
185             sequenceFeatures_original = new SequenceFeature[seq_original[i]
186                     .getSequenceFeatures().length];
187             sequenceFeatures_original = seq_original[i]
188                     .getSequenceFeatures();
189             sequenceFeatures_new = new SequenceFeature[seq_new[in]
190                     .getSequenceFeatures().length];
191             sequenceFeatures_new = seq_new[in].getSequenceFeatures();
192
193             assertTrue("different number of features", seq_original[i]
194                     .getSequenceFeatures().length == seq_new[in]
195                     .getSequenceFeatures().length);
196
197             for (int feat = 0; feat < seq_original[i].getSequenceFeatures().length; feat++)
198             {
199               assertTrue("Different features",
200                       sequenceFeatures_original[feat]
201                               .equals(sequenceFeatures_new[feat]));
202             }
203           }
204
205           // compare alignment annotation
206           if (al.getSequenceAt(i).getAnnotation() != null
207                   && al_input.getSequenceAt(in).getAnnotation() != null)
208           {
209             for (int j = 0; j < al.getSequenceAt(i).getAnnotation().length; j++)
210             {
211               if (al.getSequenceAt(i).getAnnotation()[j] != null
212                       && al_input.getSequenceAt(in).getAnnotation()[j] != null)
213               {
214                 annot_original = al.getSequenceAt(i).getAnnotation()[j];
215                 annot_new = al_input.getSequenceAt(in).getAnnotation()[j];
216                 assertTrue("Different annotation",
217                         equalss(annot_original, annot_new));
218               }
219             }
220           }
221           else if (al.getSequenceAt(i).getAnnotation() == null
222                   && al_input.getSequenceAt(in).getAnnotation() == null)
223           {
224             System.out.println("No annotations");
225           }
226           else if (al.getSequenceAt(i).getAnnotation() != null
227                   && al_input.getSequenceAt(in).getAnnotation() == null)
228           {
229             assertTrue("Annotations differed between sequences ("
230                     + al.getSequenceAt(i).getName() + ") and ("
231                     + al_input.getSequenceAt(i).getName() + ")", false);
232           }
233           break;
234         }
235       }
236     }
237   }
238
239   /*
240    * compare annotations
241    */
242   private static boolean equalss(AlignmentAnnotation annot_or,
243           AlignmentAnnotation annot_new)
244   {
245     if (annot_or.annotations.length != annot_new.annotations.length)
246     {
247       System.err.println("Different lengths for annotation row elements: "+annot_or.annotations.length +"!="+ annot_new.annotations.length);
248       return false;
249     }
250     for (int i = 0; i < annot_or.annotations.length; i++)
251     {
252       if (annot_or.annotations[i] != null
253               && annot_new.annotations[i] != null)
254       {
255         // Jim's comment - shouldn't the conditional here be using || not && for
256         // all these clauses ?
257         if (!annot_or.annotations[i].displayCharacter
258                 .equals(annot_new.annotations[i].displayCharacter)
259                 && annot_or.annotations[i].secondaryStructure != annot_new.annotations[i].secondaryStructure
260                 && !annot_or.annotations[i].description
261                         .equals(annot_new.annotations[i].description))
262         {
263           System.err.println("Annotation Element Mismatch\nElement "+i+" in original: "+annot_or.annotations[i].toString()+"\nElement "+i+" in new: "+annot_new.annotations[i].toString());
264           return false;
265         }
266       }
267       else if (annot_or.annotations[i] == null
268               && annot_new.annotations[i] == null)
269       {
270         continue;
271       }
272       else
273       {
274         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()));
275         return false;
276       }
277     }
278     return true;
279   }
280 }