Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
StockholmFileTest | 53 | 253 | 93 |
1 | /* | |
2 | * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) | |
3 | * Copyright (C) $$Year-Rel$$ The Jalview Authors | |
4 | * | |
5 | * This file is part of Jalview. | |
6 | * | |
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. | |
11 | * | |
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. | |
16 | * | |
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. | |
20 | */ | |
21 | package jalview.io; | |
22 | ||
23 | import static org.testng.Assert.assertTrue; | |
24 | import static org.testng.AssertJUnit.assertEquals; | |
25 | import static org.testng.AssertJUnit.assertNotNull; | |
26 | import static org.testng.AssertJUnit.assertTrue; | |
27 | import static org.testng.AssertJUnit.fail; | |
28 | ||
29 | import java.io.File; | |
30 | import java.util.Arrays; | |
31 | import java.util.BitSet; | |
32 | import java.util.HashMap; | |
33 | import java.util.List; | |
34 | import java.util.Map; | |
35 | import java.util.regex.Matcher; | |
36 | import java.util.regex.Pattern; | |
37 | ||
38 | import org.testng.Assert; | |
39 | import org.testng.annotations.BeforeClass; | |
40 | import org.testng.annotations.Test; | |
41 | ||
42 | import jalview.datamodel.Alignment; | |
43 | import jalview.datamodel.AlignmentAnnotation; | |
44 | import jalview.datamodel.AlignmentI; | |
45 | import jalview.datamodel.Annotation; | |
46 | import jalview.datamodel.DBRefEntry; | |
47 | import jalview.datamodel.Sequence; | |
48 | import jalview.datamodel.SequenceFeature; | |
49 | import jalview.datamodel.SequenceI; | |
50 | import jalview.gui.JvOptionPane; | |
51 | import jalview.util.DBRefUtils; | |
52 | ||
53 | public class StockholmFileTest | |
54 | { | |
55 | ||
56 | 1 | @BeforeClass(alwaysRun = true) |
57 | public void setUpJvOptionPane() | |
58 | { | |
59 | 1 | JvOptionPane.setInteractiveMode(false); |
60 | 1 | JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION); |
61 | } | |
62 | ||
63 | static String PfamFile = "examples/PF00111_seed.stk", | |
64 | RfamFile = "examples/RF00031_folded.stk", | |
65 | RnaSSTestFile = "examples/rna_ss_test.stk"; | |
66 | ||
67 | 1 | @Test(groups = { "Functional" }) |
68 | public void pfamFileIO() throws Exception | |
69 | { | |
70 | 1 | testFileIOwithFormat(new File(PfamFile), FileFormat.Stockholm, -1, 0, |
71 | false, false, false); | |
72 | } | |
73 | ||
74 | 1 | @Test(groups = { "Functional" }) |
75 | public void pfamFileDataExtraction() throws Exception | |
76 | { | |
77 | 1 | AppletFormatAdapter af = new AppletFormatAdapter(); |
78 | 1 | AlignmentI al = af.readFile(PfamFile, DataSourceType.FILE, |
79 | new IdentifyFile().identify(PfamFile, DataSourceType.FILE)); | |
80 | 1 | int numpdb = 0; |
81 | 1 | for (SequenceI sq : al.getSequences()) |
82 | { | |
83 | 206 | if (sq.getAllPDBEntries() != null) |
84 | { | |
85 | 206 | numpdb += sq.getAllPDBEntries().size(); |
86 | } | |
87 | } | |
88 | 1 | assertTrue( |
89 | "PF00111 seed alignment has at least 1 PDB file, but the reader found none.", | |
90 | numpdb > 0); | |
91 | } | |
92 | ||
93 | 1 | @Test(groups = { "Functional" }) |
94 | public void rfamFileIO() throws Exception | |
95 | { | |
96 | 1 | testFileIOwithFormat(new File(RfamFile), FileFormat.Stockholm, 2, 1, |
97 | false, false, false); | |
98 | } | |
99 | ||
100 | /** | |
101 | * JAL-3529 - verify uniprot refs for sequences are output for sequences | |
102 | * retrieved via Pfam | |
103 | */ | |
104 | 1 | @Test(groups = { "Functional" }) |
105 | public void dbrefOutput() throws Exception | |
106 | { | |
107 | // sequences retrieved in a Pfam domain alignment also have a PFAM database | |
108 | // reference | |
109 | 1 | SequenceI sq = new Sequence("FER2_SPIOL", "AASSDDDFFF"); |
110 | 1 | sq.addDBRef(new DBRefEntry("UNIPROT", "1", "P00224")); |
111 | 1 | sq.addDBRef(new DBRefEntry("PFAM", "1", "P00224.1")); |
112 | 1 | sq.addDBRef(new DBRefEntry("PFAM", "1", "PF00111")); |
113 | 1 | AppletFormatAdapter af = new AppletFormatAdapter(); |
114 | 1 | String toStockholm = af.formatSequences(FileFormat.Stockholm, |
115 | new Alignment(new SequenceI[] | |
116 | { sq }), false); | |
117 | 1 | System.out.println(toStockholm); |
118 | // bleh - java.util.Regex sucks | |
119 | 1 | assertTrue( |
120 | Pattern.compile( | |
121 | "^#=GS\\s+FER2_SPIOL(/\\d+-\\d+)?\\s+AC\\s+P00224$", | |
122 | Pattern.MULTILINE).matcher(toStockholm).find(), | |
123 | "Couldn't locate UNIPROT Accession in generated Stockholm file."); | |
124 | 1 | AlignmentI fromStockholm = af.readFile(toStockholm, |
125 | DataSourceType.PASTE, FileFormat.Stockholm); | |
126 | 1 | SequenceI importedSeq = fromStockholm.getSequenceAt(0); |
127 | 1 | assertTrue(importedSeq.getDBRefs().size() == 1, |
128 | "Expected just one database reference to be added to sequence."); | |
129 | 1 | assertTrue( |
130 | importedSeq.getDBRefs().get(0).getAccessionId() | |
131 | .indexOf(" ") == -1, | |
132 | "Spaces were found in accession ID."); | |
133 | 1 | List<DBRefEntry> dbrefs = DBRefUtils.searchRefs(importedSeq.getDBRefs(), |
134 | "P00224"); | |
135 | 1 | assertTrue(dbrefs.size() == 1, |
136 | "Couldn't find Uniprot DBRef on re-imported sequence."); | |
137 | ||
138 | } | |
139 | ||
140 | 1 | @Test(groups = { "Functional" }) |
141 | public void descriptionLineOutput() throws Exception | |
142 | { | |
143 | // quick test that sequence description is exported & reimported | |
144 | ||
145 | 1 | SequenceI sq = new Sequence("FER2_SPIOL", "AASSDDDFFF"); |
146 | 1 | String expected_descr = "This is a description !@&^%@£@"; |
147 | 1 | sq.setDescription(expected_descr); |
148 | 1 | AppletFormatAdapter af = new AppletFormatAdapter(); |
149 | 1 | String toStockholm = af.formatSequences(FileFormat.Stockholm, |
150 | new Alignment(new SequenceI[] | |
151 | { sq }), false); | |
152 | 1 | System.out.println(toStockholm); |
153 | ||
154 | // bleh - java.util.Regex sucks | |
155 | 1 | assertTrue(toStockholm.contains(expected_descr), |
156 | "Couldn't locate expected description srting in generated Stockholm file."); | |
157 | ||
158 | 1 | AlignmentI fromStockholm = af.readFile(toStockholm, |
159 | DataSourceType.PASTE, FileFormat.Stockholm); | |
160 | 1 | SequenceI importedSeq = fromStockholm.getSequenceAt(0); |
161 | 1 | assertEquals("Description did not get reimported.", expected_descr, |
162 | importedSeq.getDescription()); | |
163 | } | |
164 | ||
165 | /** | |
166 | * test alignment data in given file can be imported, exported and reimported | |
167 | * with no dataloss | |
168 | * | |
169 | * @param f | |
170 | * - source datafile (IdentifyFile.identify() should work with it) | |
171 | * @param ioformat | |
172 | * - label for IO class used to write and read back in the data from | |
173 | * f | |
174 | * @param ignoreFeatures | |
175 | * @param ignoreRowVisibility | |
176 | * @param allowNullAnnotations | |
177 | */ | |
178 | ||
179 | 3 | public static void testFileIOwithFormat(File f, FileFormatI ioformat, |
180 | int naliannot, int nminseqann, boolean ignoreFeatures, | |
181 | boolean ignoreRowVisibility, boolean allowNullAnnotations) | |
182 | { | |
183 | 3 | System.out.println("Reading file: " + f); |
184 | 3 | String ff = f.getPath(); |
185 | 3 | try |
186 | { | |
187 | 3 | AppletFormatAdapter rf = new AppletFormatAdapter(); |
188 | ||
189 | 3 | AlignmentI al = rf.readFile(ff, DataSourceType.FILE, |
190 | new IdentifyFile().identify(ff, DataSourceType.FILE)); | |
191 | ||
192 | 3 | assertNotNull("Couldn't read supplied alignment data.", al); |
193 | ||
194 | // make sure dataset is initialised ? not sure about this | |
195 | 272 | for (int i = 0; i < al.getSequencesArray().length; ++i) |
196 | { | |
197 | 269 | al.getSequenceAt(i).createDatasetSequence(); |
198 | } | |
199 | 3 | String outputfile = rf.formatSequences(ioformat, al, true); |
200 | 3 | System.out.println("Output file in '" + ioformat + "':\n" + outputfile |
201 | + "\n<<EOF\n"); | |
202 | // test for consistency in io | |
203 | 3 | AlignmentI al_input = new AppletFormatAdapter().readFile(outputfile, |
204 | DataSourceType.PASTE, ioformat); | |
205 | 3 | assertNotNull("Couldn't parse reimported alignment data.", al_input); |
206 | ||
207 | 3 | FileFormatI identifyoutput = new IdentifyFile().identify(outputfile, |
208 | DataSourceType.PASTE); | |
209 | 3 | assertNotNull("Identify routine failed for outputformat " + ioformat, |
210 | identifyoutput); | |
211 | 3 | assertTrue( |
212 | "Identify routine could not recognise output generated by '" | |
213 | + ioformat + "' writer", | |
214 | ioformat.equals(identifyoutput)); | |
215 | 3 | testAlignmentEquivalence(al, al_input, ignoreFeatures, |
216 | ignoreRowVisibility, allowNullAnnotations); | |
217 | 3 | int numaliannot = 0, numsqswithali = 0; |
218 | 3 | for (AlignmentAnnotation ala : al_input.getAlignmentAnnotation()) |
219 | { | |
220 | 80 | if (ala.sequenceRef == null) |
221 | { | |
222 | 4 | numaliannot++; |
223 | } | |
224 | else | |
225 | { | |
226 | 76 | numsqswithali++; |
227 | } | |
228 | } | |
229 | 3 | if (naliannot > -1) |
230 | { | |
231 | 1 | assertEquals("Number of alignment annotations", naliannot, |
232 | numaliannot); | |
233 | } | |
234 | ||
235 | 3 | assertTrue( |
236 | "Number of sequence associated annotations wasn't at least " | |
237 | + nminseqann, | |
238 | numsqswithali >= nminseqann); | |
239 | ||
240 | } catch (Exception e) | |
241 | { | |
242 | 0 | e.printStackTrace(); |
243 | 0 | assertTrue("Couln't format the alignment for output file.", false); |
244 | } | |
245 | } | |
246 | ||
247 | /** | |
248 | * assert alignment equivalence | |
249 | * | |
250 | * @param al | |
251 | * 'original' | |
252 | * @param al_input | |
253 | * 'secondary' or generated alignment from some datapreserving | |
254 | * transformation | |
255 | * @param ignoreFeatures | |
256 | * when true, differences in sequence feature annotation are ignored | |
257 | */ | |
258 | 0 | public static void testAlignmentEquivalence(AlignmentI al, |
259 | AlignmentI al_input, boolean ignoreFeatures) | |
260 | { | |
261 | 0 | testAlignmentEquivalence(al, al_input, ignoreFeatures, false, false); |
262 | } | |
263 | ||
264 | /** | |
265 | * assert alignment equivalence - uses special comparators for RNA structure | |
266 | * annotation rows. | |
267 | * | |
268 | * @param al | |
269 | * 'original' | |
270 | * @param al_input | |
271 | * 'secondary' or generated alignment from some datapreserving | |
272 | * transformation | |
273 | * @param ignoreFeatures | |
274 | * when true, differences in sequence feature annotation are ignored | |
275 | * | |
276 | * @param ignoreRowVisibility | |
277 | * when true, do not fail if there are differences in the visibility | |
278 | * of annotation rows | |
279 | * @param allowNullAnnotation | |
280 | * when true, positions in alignment annotation that are null will be | |
281 | * considered equal to positions containing annotation where | |
282 | * Annotation.isWhitespace() returns true. | |
283 | * | |
284 | */ | |
285 | 13 | public static void testAlignmentEquivalence(AlignmentI al, |
286 | AlignmentI al_input, boolean ignoreFeatures, | |
287 | boolean ignoreRowVisibility, boolean allowNullAnnotation) | |
288 | { | |
289 | 13 | assertNotNull("Original alignment was null", al); |
290 | 13 | assertNotNull("Generated alignment was null", al_input); |
291 | ||
292 | 13 | assertTrue( |
293 | "Alignment dimension mismatch: original: " + al.getHeight() | |
294 | + "x" + al.getWidth() + ", generated: " | |
295 | + al_input.getHeight() + "x" + al_input.getWidth(), | |
296 | al.getHeight() == al_input.getHeight() | |
297 | && al.getWidth() == al_input.getWidth()); | |
298 | ||
299 | // check Alignment annotation | |
300 | 13 | AlignmentAnnotation[] aa_new = al_input.getAlignmentAnnotation(); |
301 | 13 | AlignmentAnnotation[] aa_original = al.getAlignmentAnnotation(); |
302 | 13 | boolean expectProteinSS = !al.isNucleotide(); |
303 | 13 | assertTrue( |
304 | "Alignments not both " | |
305 | 13 | + (al.isNucleotide() ? "nucleotide" : "protein"), |
306 | al_input.isNucleotide() == al.isNucleotide()); | |
307 | ||
308 | // note - at moment we do not distinguish between alignment without any | |
309 | // annotation rows and alignment with no annotation row vector | |
310 | // we might want to revise this in future | |
311 | 13 | int aa_new_size = (aa_new == null ? 0 : aa_new.length); |
312 | 13 | int aa_original_size = (aa_original == null ? 0 : aa_original.length); |
313 | 13 | Map<Integer, BitSet> orig_groups = new HashMap<>(); |
314 | 13 | Map<Integer, BitSet> new_groups = new HashMap<>(); |
315 | ||
316 | 13 | if (aa_new != null && aa_original != null) |
317 | { | |
318 | 173 | for (int i = 0; i < aa_original.length; i++) |
319 | { | |
320 | 163 | if (aa_new.length > i) |
321 | { | |
322 | 163 | assertEqualSecondaryStructure( |
323 | "Different alignment annotation at position " + i, | |
324 | aa_original[i], aa_new[i], allowNullAnnotation); | |
325 | 163 | if (aa_original[i].hasIcons) |
326 | { | |
327 | 83 | assertTrue( |
328 | "Secondary structure expected to be " | |
329 | 83 | + (expectProteinSS ? "protein" : "nucleotide"), |
330 | expectProteinSS == !aa_original[i].isRNA()); | |
331 | } | |
332 | // compare graphGroup or graph properties - needed to verify JAL-1299 | |
333 | 163 | assertEquals("Graph type not identical.", aa_original[i].graph, |
334 | aa_new[i].graph); | |
335 | 163 | if (!ignoreRowVisibility) |
336 | { | |
337 | 158 | assertEquals("Visibility not identical.", |
338 | aa_original[i].visible, aa_new[i].visible); | |
339 | } | |
340 | 163 | assertEquals("Threshold line not identical.", |
341 | aa_original[i].threshold, aa_new[i].threshold); | |
342 | // graphGroup may differ, but pattern should be the same | |
343 | 163 | Integer o_ggrp = Integer.valueOf(aa_original[i].graphGroup + 2); |
344 | 163 | Integer n_ggrp = Integer.valueOf(aa_new[i].graphGroup + 2); |
345 | 163 | BitSet orig_g = orig_groups.get(o_ggrp); |
346 | 163 | BitSet new_g = new_groups.get(n_ggrp); |
347 | 163 | if (orig_g == null) |
348 | { | |
349 | 43 | orig_groups.put(o_ggrp, orig_g = new BitSet()); |
350 | } | |
351 | 163 | if (new_g == null) |
352 | { | |
353 | 43 | new_groups.put(n_ggrp, new_g = new BitSet()); |
354 | } | |
355 | 163 | assertEquals("Graph Group pattern differs at annotation " + i, |
356 | orig_g, new_g); | |
357 | 163 | orig_g.set(i); |
358 | 163 | new_g.set(i); |
359 | } | |
360 | else | |
361 | { | |
362 | 0 | System.err.println("No matching annotation row for " |
363 | + aa_original[i].toString()); | |
364 | } | |
365 | } | |
366 | } | |
367 | 13 | assertEquals( |
368 | "Generated and imported alignment have different annotation sets", | |
369 | aa_original_size, aa_new_size); | |
370 | ||
371 | // check sequences, annotation and features | |
372 | 13 | SequenceI[] seq_original = new SequenceI[al.getSequencesArray().length]; |
373 | 13 | seq_original = al.getSequencesArray(); |
374 | 13 | SequenceI[] seq_new = new SequenceI[al_input |
375 | .getSequencesArray().length]; | |
376 | 13 | seq_new = al_input.getSequencesArray(); |
377 | 13 | List<SequenceFeature> sequenceFeatures_original; |
378 | 13 | List<SequenceFeature> sequenceFeatures_new; |
379 | 13 | AlignmentAnnotation annot_original, annot_new; |
380 | // | |
381 | 380 | for (int i = 0; i < al.getSequencesArray().length; i++) |
382 | { | |
383 | 367 | String name = seq_original[i].getName(); |
384 | 367 | int start = seq_original[i].getStart(); |
385 | 367 | int end = seq_original[i].getEnd(); |
386 | 367 | System.out |
387 | .println("Check sequence: " + name + "/" + start + "-" + end); | |
388 | ||
389 | // search equal sequence | |
390 | 23928 | for (int in = 0; in < al_input.getSequencesArray().length; in++) |
391 | { | |
392 | 23928 | if (name.equals(seq_new[in].getName()) |
393 | && start == seq_new[in].getStart() | |
394 | && end == seq_new[in].getEnd()) | |
395 | { | |
396 | 367 | String ss_original = seq_original[i].getSequenceAsString(); |
397 | 367 | String ss_new = seq_new[in].getSequenceAsString(); |
398 | 367 | assertEquals("The sequences " + name + "/" + start + "-" + end |
399 | + " are not equal", ss_original, ss_new); | |
400 | ||
401 | 367 | assertTrue( |
402 | "Sequence Features were not equivalent" | |
403 | 367 | + (ignoreFeatures ? " ignoring." : ""), |
404 | ignoreFeatures | |
405 | || (seq_original[i].getSequenceFeatures() == null | |
406 | && seq_new[in] | |
407 | .getSequenceFeatures() == null) | |
408 | || (seq_original[i].getSequenceFeatures() != null | |
409 | && seq_new[in] | |
410 | .getSequenceFeatures() != null)); | |
411 | // compare sequence features | |
412 | 367 | if (seq_original[i].getSequenceFeatures() != null |
413 | && seq_new[in].getSequenceFeatures() != null) | |
414 | { | |
415 | 367 | System.out.println("There are feature!!!"); |
416 | 367 | sequenceFeatures_original = seq_original[i] |
417 | .getSequenceFeatures(); | |
418 | 367 | sequenceFeatures_new = seq_new[in].getSequenceFeatures(); |
419 | ||
420 | 367 | assertEquals("different number of features", |
421 | seq_original[i].getSequenceFeatures().size(), | |
422 | seq_new[in].getSequenceFeatures().size()); | |
423 | ||
424 | 367 | for (int feat = 0; feat < seq_original[i].getSequenceFeatures() |
425 | .size(); feat++) | |
426 | { | |
427 | 0 | assertEquals("Different features", |
428 | sequenceFeatures_original.get(feat), | |
429 | sequenceFeatures_new.get(feat)); | |
430 | } | |
431 | } | |
432 | // compare alignment annotation | |
433 | 367 | if (al.getSequenceAt(i).getAnnotation() != null |
434 | && al_input.getSequenceAt(in).getAnnotation() != null) | |
435 | { | |
436 | 264 | for (int j = 0; j < al.getSequenceAt(i) |
437 | .getAnnotation().length; j++) | |
438 | { | |
439 | 153 | if (al.getSequenceAt(i).getAnnotation()[j] != null && al_input |
440 | .getSequenceAt(in).getAnnotation()[j] != null) | |
441 | { | |
442 | 153 | annot_original = al.getSequenceAt(i).getAnnotation()[j]; |
443 | 153 | annot_new = al_input.getSequenceAt(in).getAnnotation()[j]; |
444 | 153 | assertEqualSecondaryStructure( |
445 | "Different annotation elements", annot_original, | |
446 | annot_new, allowNullAnnotation); | |
447 | } | |
448 | } | |
449 | } | |
450 | 256 | else if (al.getSequenceAt(i).getAnnotation() == null |
451 | && al_input.getSequenceAt(in).getAnnotation() == null) | |
452 | { | |
453 | 256 | System.out.println("No annotations"); |
454 | } | |
455 | 0 | else if (al.getSequenceAt(i).getAnnotation() != null |
456 | && al_input.getSequenceAt(in).getAnnotation() == null) | |
457 | { | |
458 | 0 | fail("Annotations differed between sequences (" |
459 | + al.getSequenceAt(i).getName() + ") and (" | |
460 | + al_input.getSequenceAt(i).getName() + ")"); | |
461 | } | |
462 | 367 | break; |
463 | } | |
464 | } | |
465 | } | |
466 | } | |
467 | ||
468 | /** | |
469 | * compare two annotation rows, with special support for secondary structure | |
470 | * comparison. With RNA, only the value and the secondaryStructure symbols are | |
471 | * compared, displayCharacter and description are ignored. Annotations where | |
472 | * Annotation.isWhitespace() is true are always considered equal. | |
473 | * | |
474 | * @param message | |
475 | * - not actually used yet.. | |
476 | * @param annot_or | |
477 | * - the original annotation | |
478 | * @param annot_new | |
479 | * - the one compared to the original annotation | |
480 | * @param allowNullEquivalence | |
481 | * when true, positions in alignment annotation that are null will be | |
482 | * considered equal to non-null positions for which | |
483 | * Annotation.isWhitespace() is true. | |
484 | */ | |
485 | 366 | private static void assertEqualSecondaryStructure(String message, |
486 | AlignmentAnnotation annot_or, AlignmentAnnotation annot_new, | |
487 | boolean allowNullEqivalence) | |
488 | { | |
489 | // TODO: test to cover this assert behaves correctly for all allowed | |
490 | // variations of secondary structure annotation row equivalence | |
491 | 366 | if (annot_or.annotations.length != annot_new.annotations.length) |
492 | { | |
493 | 0 | fail("Different lengths for annotation row elements: " |
494 | + annot_or.annotations.length + "!=" | |
495 | + annot_new.annotations.length); | |
496 | } | |
497 | 366 | boolean isRna = annot_or.isRNA(); |
498 | 366 | assertTrue( |
499 | 366 | "Expected " + (isRna ? " valid RNA " : " no RNA ") |
500 | + " secondary structure in the row.", | |
501 | isRna == annot_new.isRNA()); | |
502 | 40796 | for (int i = 0; i < annot_or.annotations.length; i++) |
503 | { | |
504 | 40458 | Annotation an_or = annot_or.annotations[i], |
505 | an_new = annot_new.annotations[i]; | |
506 | 40458 | if (an_or != null && an_new != null) |
507 | { | |
508 | ||
509 | 28788 | if (isRna) |
510 | { | |
511 | 9141 | if (an_or.secondaryStructure != an_new.secondaryStructure |
512 | || ((Float.isNaN(an_or.value) != Float | |
513 | .isNaN(an_new.value)) | |
514 | || an_or.value != an_new.value)) | |
515 | { | |
516 | 0 | fail("Different RNA secondary structure at column " + i |
517 | + " expected: [" + annot_or.annotations[i].toString() | |
518 | + "] but got: [" + annot_new.annotations[i].toString() | |
519 | + "]"); | |
520 | } | |
521 | } | |
522 | else | |
523 | { | |
524 | // not RNA secondary structure, so expect all elements to match... | |
525 | 19647 | if ((an_or.isWhitespace() != an_new.isWhitespace()) |
526 | || !an_or.displayCharacter.trim() | |
527 | .equals(an_new.displayCharacter.trim()) | |
528 | || !("" + an_or.secondaryStructure).trim() | |
529 | .equals(("" + an_new.secondaryStructure).trim()) | |
530 | || (an_or.description != an_new.description | |
531 | && !((an_or.description == null | |
532 | && an_new.description.trim() | |
533 | .length() == 0) | |
534 | || (an_new.description == null | |
535 | && an_or.description.trim() | |
536 | .length() == 0) | |
537 | || an_or.description.trim().equals( | |
538 | an_new.description.trim()))) | |
539 | || !((Float.isNaN(an_or.value) | |
540 | && Float.isNaN(an_new.value)) | |
541 | || an_or.value == an_new.value)) | |
542 | { | |
543 | 12 | fail("Annotation Element Mismatch\nElement " + i |
544 | + " in original: " + annot_or.annotations[i].toString() | |
545 | + "\nElement " + i + " in new: " | |
546 | + annot_new.annotations[i].toString()); | |
547 | } | |
548 | } | |
549 | } | |
550 | 11670 | else if (annot_or.annotations[i] == null |
551 | && annot_new.annotations[i] == null) | |
552 | { | |
553 | 11602 | continue; |
554 | } | |
555 | else | |
556 | { | |
557 | 68 | if (allowNullEqivalence) |
558 | { | |
559 | 65 | if (an_or != null && an_or.isWhitespace()) |
560 | ||
561 | { | |
562 | 0 | continue; |
563 | } | |
564 | 65 | if (an_new != null && an_new.isWhitespace()) |
565 | { | |
566 | 62 | continue; |
567 | } | |
568 | } | |
569 | // need also to test for null in one, non-SS annotation in other... | |
570 | 6 | fail("Annotation Element Mismatch\nElement " + i + " in original: " |
571 | 6 | + (an_or == null ? "is null" : an_or.toString()) |
572 | + "\nElement " + i + " in new: " | |
573 | 6 | + (an_new == null ? "is null" : an_new.toString())); |
574 | } | |
575 | } | |
576 | } | |
577 | ||
578 | /** | |
579 | * @see assertEqualSecondaryStructure - test if two secondary structure | |
580 | * annotations are not equal | |
581 | * @param message | |
582 | * @param an_orig | |
583 | * @param an_new | |
584 | * @param allowNullEquivalence | |
585 | */ | |
586 | 28 | public static void assertNotEqualSecondaryStructure(String message, |
587 | AlignmentAnnotation an_orig, AlignmentAnnotation an_new, | |
588 | boolean allowNullEquivalence) | |
589 | { | |
590 | 28 | boolean thrown = false; |
591 | 28 | try |
592 | { | |
593 | 28 | assertEqualSecondaryStructure("", an_orig, an_new, |
594 | allowNullEquivalence); | |
595 | } catch (AssertionError af) | |
596 | { | |
597 | 28 | thrown = true; |
598 | } | |
599 | 28 | if (!thrown) |
600 | { | |
601 | 0 | fail("Expected difference for [" + an_orig + "] and [" + an_new |
602 | + "]"); | |
603 | } | |
604 | } | |
605 | ||
606 | 26 | private AlignmentAnnotation makeAnnot(Annotation ae) |
607 | { | |
608 | 26 | return new AlignmentAnnotation("label", "description", |
609 | new Annotation[] | |
610 | { ae }); | |
611 | } | |
612 | ||
613 | 1 | @Test(groups = { "Functional" }) |
614 | public void testAnnotationEquivalence() | |
615 | { | |
616 | 1 | AlignmentAnnotation one = makeAnnot(new Annotation("", "", ' ', 1)); |
617 | 1 | AlignmentAnnotation anotherOne = makeAnnot( |
618 | new Annotation("", "", ' ', 1)); | |
619 | 1 | AlignmentAnnotation sheet = makeAnnot(new Annotation("", "", 'E', 0f)); |
620 | 1 | AlignmentAnnotation anotherSheet = makeAnnot( |
621 | new Annotation("", "", 'E', 0f)); | |
622 | 1 | AlignmentAnnotation sheetWithLabel = makeAnnot( |
623 | new Annotation("1", "", 'E', 0f)); | |
624 | 1 | AlignmentAnnotation anotherSheetWithLabel = makeAnnot( |
625 | new Annotation("1", "", 'E', 0f)); | |
626 | 1 | AlignmentAnnotation rnaNoDC = makeAnnot( |
627 | new Annotation("", "", '<', 0f)); | |
628 | 1 | AlignmentAnnotation anotherRnaNoDC = makeAnnot( |
629 | new Annotation("", "", '<', 0f)); | |
630 | 1 | AlignmentAnnotation rnaWithDC = makeAnnot( |
631 | new Annotation("B", "", '<', 0f)); | |
632 | 1 | AlignmentAnnotation anotherRnaWithDC = makeAnnot( |
633 | new Annotation("B", "", '<', 0f)); | |
634 | ||
635 | // check self equivalence | |
636 | 1 | for (boolean allowNull : new boolean[] { true, false }) |
637 | { | |
638 | 2 | assertEqualSecondaryStructure("Should be equal", one, anotherOne, |
639 | allowNull); | |
640 | 2 | assertEqualSecondaryStructure("Should be equal", sheet, anotherSheet, |
641 | allowNull); | |
642 | 2 | assertEqualSecondaryStructure("Should be equal", sheetWithLabel, |
643 | anotherSheetWithLabel, allowNull); | |
644 | 2 | assertEqualSecondaryStructure("Should be equal", rnaNoDC, |
645 | anotherRnaNoDC, allowNull); | |
646 | 2 | assertEqualSecondaryStructure("Should be equal", rnaWithDC, |
647 | anotherRnaWithDC, allowNull); | |
648 | // display character doesn't matter for RNA structure (for 2.10.2) | |
649 | 2 | assertEqualSecondaryStructure("Should be equal", rnaWithDC, rnaNoDC, |
650 | allowNull); | |
651 | 2 | assertEqualSecondaryStructure("Should be equal", rnaNoDC, rnaWithDC, |
652 | allowNull); | |
653 | } | |
654 | ||
655 | // verify others are different | |
656 | 1 | List<AlignmentAnnotation> aaSet = Arrays.asList(one, sheet, |
657 | sheetWithLabel, rnaWithDC); | |
658 | 5 | for (int p = 0; p < aaSet.size(); p++) |
659 | { | |
660 | 20 | for (int q = 0; q < aaSet.size(); q++) |
661 | { | |
662 | 16 | if (p != q) |
663 | { | |
664 | 12 | assertNotEqualSecondaryStructure("Should be different", |
665 | aaSet.get(p), aaSet.get(q), false); | |
666 | } | |
667 | else | |
668 | { | |
669 | 4 | assertEqualSecondaryStructure("Should be same", aaSet.get(p), |
670 | aaSet.get(q), false); | |
671 | 4 | assertEqualSecondaryStructure("Should be same", aaSet.get(p), |
672 | aaSet.get(q), true); | |
673 | 4 | assertNotEqualSecondaryStructure( |
674 | "Should be different to empty anot", aaSet.get(p), | |
675 | makeAnnot(Annotation.EMPTY_ANNOTATION), false); | |
676 | 4 | assertNotEqualSecondaryStructure( |
677 | "Should be different to empty annot", | |
678 | makeAnnot(Annotation.EMPTY_ANNOTATION), aaSet.get(q), | |
679 | true); | |
680 | 4 | assertNotEqualSecondaryStructure("Should be different to null", |
681 | aaSet.get(p), makeAnnot(null), false); | |
682 | 4 | assertNotEqualSecondaryStructure("Should be different to null", |
683 | makeAnnot(null), aaSet.get(q), true); | |
684 | } | |
685 | } | |
686 | } | |
687 | ||
688 | // test null | |
689 | ||
690 | } | |
691 | ||
692 | String aliFile = ">Dm\nAAACCCUUUUACACACGGGAAAGGG"; | |
693 | ||
694 | String annFile = "JALVIEW_ANNOTATION\n# Created: Thu May 04 11:16:52 BST 2017\n\n" | |
695 | + "SEQUENCE_REF\tDm\nNO_GRAPH\tsecondary structure\tsecondary structure\t" | |
696 | + "(|(|(|(|, .|, .|, .|, .|)|)|)|)|\t0.0\nROWPROPERTIES\t" | |
697 | + "secondary structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false"; | |
698 | ||
699 | String annFileCurlyWuss = "JALVIEW_ANNOTATION\n# Created: Thu May 04 11:16:52 BST 2017\n\n" | |
700 | + "SEQUENCE_REF\tDm\nNO_GRAPH\tsecondary structure\tsecondary structure\t" | |
701 | + "(|(|(|(||{|{||{|{||)|)|)|)||}|}|}|}|\t0.0\nROWPROPERTIES\t" | |
702 | + "secondary structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false"; | |
703 | ||
704 | String annFileFullWuss = "JALVIEW_ANNOTATION\n# Created: Thu May 04 11:16:52 BST 2017\n\n" | |
705 | + "SEQUENCE_REF\tDm\nNO_GRAPH\tsecondary structure\tsecondary structure\t" | |
706 | + "(|(|(|(||{|{||[|[||)|)|)|)||}|}|]|]|\t0.0\nROWPROPERTIES\t" | |
707 | + "secondary structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false"; | |
708 | ||
709 | 1 | @Test(groups = { "Functional" }) |
710 | public void secondaryStructureForRNASequence() throws Exception | |
711 | { | |
712 | 1 | roundTripSSForRNA(aliFile, annFile); |
713 | } | |
714 | ||
715 | 1 | @Test(groups = { "Functional" }) |
716 | public void curlyWUSSsecondaryStructureForRNASequence() throws Exception | |
717 | { | |
718 | 1 | roundTripSSForRNA(aliFile, annFileCurlyWuss); |
719 | } | |
720 | ||
721 | 1 | @Test(groups = { "Functional" }) |
722 | public void fullWUSSsecondaryStructureForRNASequence() throws Exception | |
723 | { | |
724 | 1 | roundTripSSForRNA(aliFile, annFileFullWuss); |
725 | } | |
726 | ||
727 | 1 | @Test(groups = { "Functional" }) |
728 | public void detectWussBrackets() | |
729 | { | |
730 | 1 | for (char ch : new char[] { '{', '}', '[', ']', '(', ')', '<', '>' }) |
731 | { | |
732 | 8 | Assert.assertTrue(StockholmFile.RNASS_BRACKETS.indexOf(ch) >= 0, |
733 | "Didn't recognise '" + ch + "' as a WUSS bracket"); | |
734 | } | |
735 | 1 | for (char ch : new char[] { '@', '!', '*', ' ', '-', '.' }) |
736 | { | |
737 | 6 | Assert.assertFalse(StockholmFile.RNASS_BRACKETS.indexOf(ch) >= 0, |
738 | "Shouldn't recognise '" + ch + "' as a WUSS bracket"); | |
739 | } | |
740 | } | |
741 | ||
742 | 3 | private static void roundTripSSForRNA(String aliFile, String annFile) |
743 | throws Exception | |
744 | { | |
745 | 3 | AlignmentI al = new AppletFormatAdapter().readFile(aliFile, |
746 | DataSourceType.PASTE, jalview.io.FileFormat.Fasta); | |
747 | 3 | AnnotationFile aaf = new AnnotationFile(); |
748 | 3 | aaf.readAnnotationFile(al, annFile, DataSourceType.PASTE); |
749 | 3 | al.getAlignmentAnnotation()[0].visible = true; |
750 | ||
751 | // TODO: create a better 'save as <format>' pattern | |
752 | 3 | StockholmFile sf = new StockholmFile(al); |
753 | ||
754 | 3 | String stockholmFile = sf.print(al.getSequencesArray(), true); |
755 | ||
756 | 3 | AlignmentI newAl = new AppletFormatAdapter().readFile(stockholmFile, |
757 | DataSourceType.PASTE, jalview.io.FileFormat.Stockholm); | |
758 | // AlignmentUtils.showOrHideSequenceAnnotations(newAl.getViewport() | |
759 | // .getAlignment(), Arrays.asList("Secondary Structure"), newAl | |
760 | // .getViewport().getAlignment().getSequences(), true, true); | |
761 | 3 | testAlignmentEquivalence(al, newAl, true, true, true); |
762 | ||
763 | } | |
764 | ||
765 | // this is the single sequence alignment and the SS annotations equivalent to | |
766 | // the ones in file RnaSSTestFile | |
767 | String aliFileRnaSS = ">Test.sequence/1-14\n" + "GUACAAAAAAAAAA"; | |
768 | ||
769 | String annFileRnaSSAlphaChars = "JALVIEW_ANNOTATION\n" | |
770 | + "# Created: Thu Aug 02 14:54:57 BST 2018\n" + "\n" | |
771 | + "NO_GRAPH\tSecondary Structure\tSecondary Structure\t<,<|(,(|E,E|H,H|B,B|h,h|e,e|b,b|(,(|E,E|),)|e,e|),)|>,>|\t2.0\n" | |
772 | + "\n" | |
773 | + "ROWPROPERTIES\tSecondary Structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false\n" | |
774 | + "\n" + "\n" + "ALIGNMENT\tID=RNA.SS.TEST\tTP=RNA;"; | |
775 | ||
776 | String wrongAnnFileRnaSSAlphaChars = "JALVIEW_ANNOTATION\n" | |
777 | + "# Created: Thu Aug 02 14:54:57 BST 2018\n" + "\n" | |
778 | + "NO_GRAPH\tSecondary Structure\tSecondary Structure\t<,<|(,(|H,H|E,E|B,B|h,h|e,e|b,b|(,(|E,E|),)|e,e|),)|>,>|\t2.0\n" | |
779 | + "\n" | |
780 | + "ROWPROPERTIES\tSecondary Structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false\n" | |
781 | + "\n" + "\n" + "ALIGNMENT\tID=RNA.SS.TEST\tTP=RNA;"; | |
782 | ||
783 | 1 | @Test(groups = { "Functional" }) |
784 | public void stockholmFileRnaSSAlphaChars() throws Exception | |
785 | { | |
786 | 1 | AppletFormatAdapter af = new AppletFormatAdapter(); |
787 | 1 | AlignmentI al = af.readFile(RnaSSTestFile, DataSourceType.FILE, |
788 | jalview.io.FileFormat.Stockholm); | |
789 | 1 | Iterable<AlignmentAnnotation> aai = al.findAnnotations(null, null, |
790 | "Secondary Structure"); | |
791 | 1 | AlignmentAnnotation aa = aai.iterator().next(); |
792 | 1 | Assert.assertTrue(aa.isRNA(), |
793 | "'" + RnaSSTestFile + "' not recognised as RNA SS"); | |
794 | 1 | Assert.assertTrue(aa.isValidStruc(), |
795 | "'" + RnaSSTestFile + "' not recognised as valid structure"); | |
796 | 1 | Annotation[] as = aa.annotations; |
797 | 1 | char[] As = new char[as.length]; |
798 | 15 | for (int i = 0; i < as.length; i++) |
799 | { | |
800 | 14 | As[i] = as[i].secondaryStructure; |
801 | } | |
802 | 1 | char[] shouldBe = { '<', '(', 'E', 'H', 'B', 'h', 'e', 'b', '(', 'E', |
803 | ')', 'e', ')', '>' }; | |
804 | 1 | Assert.assertTrue(Arrays.equals(As, shouldBe), "Annotation is " |
805 | + new String(As) + " but should be " + new String(shouldBe)); | |
806 | ||
807 | // this should result in the same RNA SS Annotations | |
808 | 1 | AlignmentI newAl = new AppletFormatAdapter().readFile(aliFileRnaSS, |
809 | DataSourceType.PASTE, jalview.io.FileFormat.Fasta); | |
810 | 1 | AnnotationFile aaf = new AnnotationFile(); |
811 | 1 | aaf.readAnnotationFile(newAl, annFileRnaSSAlphaChars, |
812 | DataSourceType.PASTE); | |
813 | ||
814 | 1 | Assert.assertTrue( |
815 | testRnaSSAnnotationsEquivalent(al.getAlignmentAnnotation()[0], | |
816 | newAl.getAlignmentAnnotation()[0]), | |
817 | "RNA SS Annotations SHOULD be pair-wise equivalent (but apparently aren't): \n" | |
818 | + "RNA SS A 1:" + al.getAlignmentAnnotation()[0] + "\n" | |
819 | + "RNA SS A 2:" + newAl.getAlignmentAnnotation()[0]); | |
820 | ||
821 | // this should NOT result in the same RNA SS Annotations | |
822 | 1 | newAl = new AppletFormatAdapter().readFile(aliFileRnaSS, |
823 | DataSourceType.PASTE, jalview.io.FileFormat.Fasta); | |
824 | 1 | aaf = new AnnotationFile(); |
825 | 1 | aaf.readAnnotationFile(newAl, wrongAnnFileRnaSSAlphaChars, |
826 | DataSourceType.PASTE); | |
827 | ||
828 | 1 | boolean mismatch = testRnaSSAnnotationsEquivalent( |
829 | al.getAlignmentAnnotation()[0], | |
830 | newAl.getAlignmentAnnotation()[0]); | |
831 | 1 | Assert.assertFalse(mismatch, |
832 | "RNA SS Annotations SHOULD NOT be pair-wise equivalent (but apparently are): \n" | |
833 | + "RNA SS A 1:" + al.getAlignmentAnnotation()[0] + "\n" | |
834 | + "RNA SS A 2:" + newAl.getAlignmentAnnotation()[0]); | |
835 | } | |
836 | ||
837 | 4 | private static boolean testRnaSSAnnotationsEquivalent( |
838 | AlignmentAnnotation a1, AlignmentAnnotation a2) | |
839 | { | |
840 | 4 | return a1.rnaSecondaryStructureEquivalent(a2); |
841 | } | |
842 | ||
843 | String annFileRnaSSWithSpaceChars = "JALVIEW_ANNOTATION\n" | |
844 | + "# Created: Thu Aug 02 14:54:57 BST 2018\n" + "\n" | |
845 | + "NO_GRAPH\tSecondary Structure\tSecondary Structure\t<,<|.,.|H,H| , |B,B|h,h| , |b,b|(,(|E,E|.,.|e,e|),)|>,>|\t2.0\n" | |
846 | + "\n" | |
847 | + "ROWPROPERTIES\tSecondary Structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false\n" | |
848 | + "\n" + "\n" + "ALIGNMENT\tID=RNA.SS.TEST\tTP=RNA;"; | |
849 | ||
850 | String annFileRnaSSWithoutSpaceChars = "JALVIEW_ANNOTATION\n" | |
851 | + "# Created: Thu Aug 02 14:54:57 BST 2018\n" + "\n" | |
852 | + "NO_GRAPH\tSecondary Structure\tSecondary Structure\t<,<|.,.|H,H|.,.|B,B|h,h|.,.|b,b|(,(|E,E|.,.|e,e|),)|>,>|\t2.0\n" | |
853 | + "\n" | |
854 | + "ROWPROPERTIES\tSecondary Structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false\n" | |
855 | + "\n" + "\n" + "ALIGNMENT\tID=RNA.SS.TEST\tTP=RNA;"; | |
856 | ||
857 | String wrongAnnFileRnaSSWithoutSpaceChars = "JALVIEW_ANNOTATION\n" | |
858 | + "# Created: Thu Aug 02 14:54:57 BST 2018\n" + "\n" | |
859 | + "NO_GRAPH\tSecondary Structure\tSecondary Structure\t<,<|.,.|H,H|Z,Z|B,B|h,h|z,z|b,b|(,(|E,E|.,.|e,e|),)|>,>|\t2.0\n" | |
860 | + "\n" | |
861 | + "ROWPROPERTIES\tSecondary Structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false\n" | |
862 | + "\n" + "\n" + "ALIGNMENT\tID=RNA.SS.TEST\tTP=RNA;"; | |
863 | ||
864 | 1 | @Test(groups = { "Functional" }) |
865 | public void stockholmFileRnaSSSpaceChars() throws Exception | |
866 | { | |
867 | 1 | AlignmentI alWithSpaces = new AppletFormatAdapter().readFile( |
868 | aliFileRnaSS, DataSourceType.PASTE, | |
869 | jalview.io.FileFormat.Fasta); | |
870 | 1 | AnnotationFile afWithSpaces = new AnnotationFile(); |
871 | 1 | afWithSpaces.readAnnotationFile(alWithSpaces, |
872 | annFileRnaSSWithSpaceChars, DataSourceType.PASTE); | |
873 | ||
874 | 1 | Iterable<AlignmentAnnotation> aaiWithSpaces = alWithSpaces |
875 | .findAnnotations(null, null, "Secondary Structure"); | |
876 | 1 | AlignmentAnnotation aaWithSpaces = aaiWithSpaces.iterator().next(); |
877 | 1 | Assert.assertTrue(aaWithSpaces.isRNA(), |
878 | "'" + aaWithSpaces + "' not recognised as RNA SS"); | |
879 | 1 | Assert.assertTrue(aaWithSpaces.isValidStruc(), |
880 | "'" + aaWithSpaces + "' not recognised as valid structure"); | |
881 | 1 | Annotation[] annWithSpaces = aaWithSpaces.annotations; |
882 | 1 | char[] As = new char[annWithSpaces.length]; |
883 | 15 | for (int i = 0; i < annWithSpaces.length; i++) |
884 | { | |
885 | 14 | As[i] = annWithSpaces[i].secondaryStructure; |
886 | } | |
887 | // check all spaces and dots are spaces in the internal representation | |
888 | 1 | char[] shouldBe = { '<', ' ', 'H', ' ', 'B', 'h', ' ', 'b', '(', 'E', |
889 | ' ', 'e', ')', '>' }; | |
890 | 1 | Assert.assertTrue(Arrays.equals(As, shouldBe), "Annotation is " |
891 | + new String(As) + " but should be " + new String(shouldBe)); | |
892 | ||
893 | // this should result in the same RNA SS Annotations | |
894 | 1 | AlignmentI alWithoutSpaces = new AppletFormatAdapter().readFile( |
895 | aliFileRnaSS, DataSourceType.PASTE, | |
896 | jalview.io.FileFormat.Fasta); | |
897 | 1 | AnnotationFile afWithoutSpaces = new AnnotationFile(); |
898 | 1 | afWithoutSpaces.readAnnotationFile(alWithoutSpaces, |
899 | annFileRnaSSWithoutSpaceChars, DataSourceType.PASTE); | |
900 | ||
901 | 1 | Assert.assertTrue( |
902 | testRnaSSAnnotationsEquivalent( | |
903 | alWithSpaces.getAlignmentAnnotation()[0], | |
904 | alWithoutSpaces.getAlignmentAnnotation()[0]), | |
905 | "RNA SS Annotations SHOULD be pair-wise equivalent (but apparently aren't): \n" | |
906 | + "RNA SS A 1:" | |
907 | + alWithSpaces.getAlignmentAnnotation()[0] | |
908 | .getRnaSecondaryStructure() | |
909 | + "\n" + "RNA SS A 2:" | |
910 | + alWithoutSpaces.getAlignmentAnnotation()[0] | |
911 | .getRnaSecondaryStructure()); | |
912 | ||
913 | // this should NOT result in the same RNA SS Annotations | |
914 | 1 | AlignmentI wrongAlWithoutSpaces = new AppletFormatAdapter().readFile( |
915 | aliFileRnaSS, DataSourceType.PASTE, | |
916 | jalview.io.FileFormat.Fasta); | |
917 | 1 | AnnotationFile wrongAfWithoutSpaces = new AnnotationFile(); |
918 | 1 | wrongAfWithoutSpaces.readAnnotationFile(wrongAlWithoutSpaces, |
919 | wrongAnnFileRnaSSWithoutSpaceChars, DataSourceType.PASTE); | |
920 | ||
921 | 1 | Assert.assertFalse( |
922 | testRnaSSAnnotationsEquivalent( | |
923 | alWithSpaces.getAlignmentAnnotation()[0], | |
924 | wrongAlWithoutSpaces.getAlignmentAnnotation()[0]), | |
925 | "RNA SS Annotations SHOULD NOT be pair-wise equivalent (but apparently are): \n" | |
926 | + "RNA SS A 1:" | |
927 | + alWithSpaces.getAlignmentAnnotation()[0] | |
928 | .getRnaSecondaryStructure() | |
929 | + "\n" + "RNA SS A 2:" | |
930 | + wrongAlWithoutSpaces.getAlignmentAnnotation()[0] | |
931 | .getRnaSecondaryStructure()); | |
932 | ||
933 | // check no spaces in the output | |
934 | // TODO: create a better 'save as <format>' pattern | |
935 | 1 | alWithSpaces.getAlignmentAnnotation()[0].visible = true; |
936 | 1 | StockholmFile sf = new StockholmFile(alWithSpaces); |
937 | ||
938 | 1 | String stockholmFile = sf.print(alWithSpaces.getSequencesArray(), true); |
939 | 1 | Pattern noSpacesInRnaSSAnnotation = Pattern |
940 | .compile("\\n#=GC SS_cons\\s+\\S{14}\\n"); | |
941 | 1 | Matcher m = noSpacesInRnaSSAnnotation.matcher(stockholmFile); |
942 | 1 | boolean matches = m.find(); |
943 | 1 | Assert.assertTrue(matches, |
944 | "StockholmFile output does not contain expected output (may contain spaces):\n" | |
945 | + stockholmFile); | |
946 | ||
947 | } | |
948 | } |