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