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.assertFalse;
25 import static org.testng.AssertJUnit.assertNotNull;
26 import static org.testng.AssertJUnit.assertSame;
27 import static org.testng.AssertJUnit.assertTrue;
28 import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
30 import jalview.api.FeatureColourI;
31 import jalview.api.FeatureRenderer;
32 import jalview.datamodel.Alignment;
33 import jalview.datamodel.AlignmentI;
34 import jalview.datamodel.SequenceDummy;
35 import jalview.datamodel.SequenceFeature;
36 import jalview.datamodel.SequenceI;
37 import jalview.datamodel.features.FeatureMatcherI;
38 import jalview.datamodel.features.FeatureMatcherSetI;
39 import jalview.datamodel.features.SequenceFeatures;
40 import jalview.gui.AlignFrame;
41 import jalview.gui.Desktop;
42 import jalview.gui.JvOptionPane;
43 import jalview.structure.StructureSelectionManager;
44 import jalview.util.matcher.Condition;
46 import java.awt.Color;
48 import java.io.IOException;
49 import java.util.ArrayList;
50 import java.util.Arrays;
51 import java.util.HashMap;
52 import java.util.Iterator;
53 import java.util.List;
56 import org.testng.annotations.AfterClass;
57 import org.testng.annotations.BeforeClass;
58 import org.testng.annotations.Test;
60 public class FeaturesFileTest
62 private static String simpleGffFile = "examples/testdata/simpleGff3.gff";
64 @AfterClass(alwaysRun = true)
65 public void tearDownAfterClass()
68 * remove any sequence mappings created so they don't pollute other tests
70 StructureSelectionManager ssm = StructureSelectionManager
71 .getStructureSelectionManager(Desktop.instance);
75 @BeforeClass(alwaysRun = true)
76 public void setUpJvOptionPane()
78 JvOptionPane.setInteractiveMode(false);
79 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
82 @Test(groups = { "Functional" })
83 public void testParse() throws Exception
85 File f = new File("examples/uniref50.fa");
86 AlignmentI al = readAlignmentFile(f);
87 AlignFrame af = new AlignFrame(al, 500, 500);
88 Map<String, FeatureColourI> colours = af.getFeatureRenderer()
90 FeaturesFile featuresFile = new FeaturesFile(
91 "examples/exampleFeatures.txt", DataSourceType.FILE);
92 assertTrue("Test " + "Features file test"
93 + "\nFailed to parse features file.",
94 featuresFile.parse(al.getDataset(), colours, true));
97 * Refetch the colour map from the FeatureRenderer (to confirm it has been
98 * updated - JAL-1904), and verify (some) feature group colours
100 colours = af.getFeatureRenderer().getFeatureColours();
101 assertEquals("27 feature group colours not found", 27, colours.size());
102 assertEquals(colours.get("Cath").getColour(), new Color(0x93b1d1));
103 assertEquals(colours.get("ASX-MOTIF").getColour(), new Color(0x6addbb));
104 FeatureColourI kdColour = colours.get("kdHydrophobicity");
105 assertTrue(kdColour.isGraduatedColour());
106 assertTrue(kdColour.isAboveThreshold());
107 assertEquals(-2f, kdColour.getThreshold());
110 * verify (some) features on sequences
112 List<SequenceFeature> sfs = al.getSequenceAt(0).getDatasetSequence()
113 .getSequenceFeatures(); // FER_CAPAA
114 SequenceFeatures.sortFeatures(sfs, true);
115 assertEquals(8, sfs.size());
118 * verify (in ascending start position order)
120 SequenceFeature sf = sfs.get(0);
121 assertEquals("Pfam family%LINK%", sf.description);
122 assertEquals(0, sf.begin);
123 assertEquals(0, sf.end);
124 assertEquals("uniprot", sf.featureGroup);
125 assertEquals("Pfam", sf.type);
126 assertEquals(1, sf.links.size());
127 assertEquals("Pfam family|http://pfam.xfam.org/family/PF00111",
131 assertEquals("Ferredoxin_fold Status: True Positive ", sf.description);
132 assertEquals(3, sf.begin);
133 assertEquals(93, sf.end);
134 assertEquals("uniprot", sf.featureGroup);
135 assertEquals("Cath", sf.type);
138 assertEquals("Fer2 Status: True Positive Pfam 8_8%LINK%",
140 assertEquals("Pfam 8_8|http://pfam.xfam.org/family/PF00111",
142 assertEquals(8, sf.begin);
143 assertEquals(83, sf.end);
144 assertEquals("uniprot", sf.featureGroup);
145 assertEquals("Pfam", sf.type);
148 assertEquals("Iron-sulfur (2Fe-2S)", sf.description);
149 assertEquals(39, sf.begin);
150 assertEquals(39, sf.end);
151 assertEquals("uniprot", sf.featureGroup);
152 assertEquals("METAL", sf.type);
155 assertEquals("Iron-sulfur (2Fe-2S)", sf.description);
156 assertEquals(44, sf.begin);
157 assertEquals(44, sf.end);
158 assertEquals("uniprot", sf.featureGroup);
159 assertEquals("METAL", sf.type);
162 assertEquals("Iron-sulfur (2Fe-2S)", sf.description);
163 assertEquals(47, sf.begin);
164 assertEquals(47, sf.end);
165 assertEquals("uniprot", sf.featureGroup);
166 assertEquals("METAL", sf.type);
169 assertEquals("Iron-sulfur (2Fe-2S)", sf.description);
170 assertEquals(77, sf.begin);
171 assertEquals(77, sf.end);
172 assertEquals("uniprot", sf.featureGroup);
173 assertEquals("METAL", sf.type);
177 "High confidence server. Only hits with scores over 0.8 are reported. PHOSPHORYLATION (T) 89_8%LINK%",
180 "PHOSPHORYLATION (T) 89_8|http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P83527&service=NetPhos-2.0",
182 assertEquals(89, sf.begin);
183 assertEquals(89, sf.end);
184 assertEquals("netphos", sf.featureGroup);
185 assertEquals("PHOSPHORYLATION (T)", sf.type);
189 * Test parsing a features file with a mix of Jalview and GFF formatted
194 @Test(groups = { "Functional" })
195 public void testParse_mixedJalviewGff() throws Exception
197 File f = new File("examples/uniref50.fa");
198 AlignmentI al = readAlignmentFile(f);
199 AlignFrame af = new AlignFrame(al, 500, 500);
200 Map<String, FeatureColourI> colours = af.getFeatureRenderer()
201 .getFeatureColours();
202 // GFF2 uses space as name/value separator in column 9
203 String gffData = "METAL\tcc9900\n"
205 + "FER_CAPAA\tuniprot\tMETAL\t44\t45\t4.0\t.\t.\tNote Iron-sulfur; Note 2Fe-2S\n"
206 + "FER1_SOLLC\tuniprot\tPfam\t55\t130\t2.0\t.\t.";
207 FeaturesFile featuresFile = new FeaturesFile(gffData,
208 DataSourceType.PASTE);
209 assertTrue("Failed to parse features file",
210 featuresFile.parse(al.getDataset(), colours, true));
212 // verify colours read or synthesized
213 colours = af.getFeatureRenderer().getFeatureColours();
214 assertEquals("1 feature group colours not found", 1, colours.size());
215 assertEquals(colours.get("METAL").getColour(), new Color(0xcc9900));
217 // verify feature on FER_CAPAA
218 List<SequenceFeature> sfs = al.getSequenceAt(0).getDatasetSequence()
219 .getSequenceFeatures();
220 assertEquals(1, sfs.size());
221 SequenceFeature sf = sfs.get(0);
222 assertEquals("Iron-sulfur,2Fe-2S", sf.description);
223 assertEquals(44, sf.begin);
224 assertEquals(45, sf.end);
225 assertEquals("uniprot", sf.featureGroup);
226 assertEquals("METAL", sf.type);
227 assertEquals(4f, sf.getScore(), 0.001f);
229 // verify feature on FER1_SOLLC
230 sfs = al.getSequenceAt(2).getDatasetSequence().getSequenceFeatures();
231 assertEquals(1, sfs.size());
233 assertEquals("uniprot", sf.description);
234 assertEquals(55, sf.begin);
235 assertEquals(130, sf.end);
236 assertEquals("uniprot", sf.featureGroup);
237 assertEquals("Pfam", sf.type);
238 assertEquals(2f, sf.getScore(), 0.001f);
241 public static AlignmentI readAlignmentFile(File f) throws IOException
243 System.out.println("Reading file: " + f);
244 String ff = f.getPath();
245 FormatAdapter rf = new FormatAdapter();
247 AlignmentI al = rf.readFile(ff, DataSourceType.FILE,
248 new IdentifyFile().identify(ff, DataSourceType.FILE));
250 al.setDataset(null); // creates dataset sequences
251 assertNotNull("Couldn't read supplied alignment data.", al);
256 * Test parsing a features file with GFF formatted content only
260 @Test(groups = { "Functional" })
261 public void testParse_pureGff3() throws Exception
263 File f = new File("examples/uniref50.fa");
264 AlignmentI al = readAlignmentFile(f);
265 AlignFrame af = new AlignFrame(al, 500, 500);
266 Map<String, FeatureColourI> colours = af.getFeatureRenderer()
267 .getFeatureColours();
268 // GFF3 uses '=' separator for name/value pairs in colum 9
269 String gffData = "##gff-version 3\n"
270 + "FER_CAPAA\tuniprot\tMETAL\t39\t39\t0.0\t.\t.\t"
271 + "Note=Iron-sulfur (2Fe-2S);Note=another note;evidence=ECO:0000255|PROSITE-ProRule:PRU00465\n"
272 + "FER1_SOLLC\tuniprot\tPfam\t55\t130\t3.0\t.\t.\tID=$23";
273 FeaturesFile featuresFile = new FeaturesFile(gffData,
274 DataSourceType.PASTE);
275 assertTrue("Failed to parse features file",
276 featuresFile.parse(al.getDataset(), colours, true));
278 // verify feature on FER_CAPAA
279 List<SequenceFeature> sfs = al.getSequenceAt(0).getDatasetSequence()
280 .getSequenceFeatures();
281 assertEquals(1, sfs.size());
282 SequenceFeature sf = sfs.get(0);
283 // description parsed from Note attribute
284 assertEquals("Iron-sulfur (2Fe-2S),another note", sf.description);
285 assertEquals(39, sf.begin);
286 assertEquals(39, sf.end);
287 assertEquals("uniprot", sf.featureGroup);
288 assertEquals("METAL", sf.type);
290 "Note=Iron-sulfur (2Fe-2S);Note=another note;evidence=ECO:0000255|PROSITE-ProRule:PRU00465",
291 sf.getValue("ATTRIBUTES"));
293 // verify feature on FER1_SOLLC1
294 sfs = al.getSequenceAt(2).getDatasetSequence().getSequenceFeatures();
295 assertEquals(1, sfs.size());
297 // ID used for description if available
298 assertEquals("$23", sf.description);
299 assertEquals(55, sf.begin);
300 assertEquals(130, sf.end);
301 assertEquals("uniprot", sf.featureGroup);
302 assertEquals("Pfam", sf.type);
303 assertEquals(3f, sf.getScore(), 0.001f);
307 * Test parsing a features file with Jalview format features (but no colour
308 * descriptors or startgroup to give the hint not to parse as GFF)
312 @Test(groups = { "Functional" })
313 public void testParse_jalviewFeaturesOnly() throws Exception
315 File f = new File("examples/uniref50.fa");
316 AlignmentI al = readAlignmentFile(f);
317 AlignFrame af = new AlignFrame(al, 500, 500);
318 Map<String, FeatureColourI> colours = af.getFeatureRenderer()
319 .getFeatureColours();
322 * one feature on FER_CAPAA and one on sequence 3 (index 2) FER1_SOLLC
324 String featureData = "Iron-sulfur (2Fe-2S)\tFER_CAPAA\t-1\t39\t39\tMETAL\n"
325 + "Iron-phosphorus (2Fe-P)\tID_NOT_SPECIFIED\t2\t86\t87\tMETALLIC\n";
326 FeaturesFile featuresFile = new FeaturesFile(featureData,
327 DataSourceType.PASTE);
328 assertTrue("Failed to parse features file",
329 featuresFile.parse(al.getDataset(), colours, true));
331 // verify FER_CAPAA feature
332 List<SequenceFeature> sfs = al.getSequenceAt(0).getDatasetSequence()
333 .getSequenceFeatures();
334 assertEquals(1, sfs.size());
335 SequenceFeature sf = sfs.get(0);
336 assertEquals("Iron-sulfur (2Fe-2S)", sf.description);
337 assertEquals(39, sf.begin);
338 assertEquals(39, sf.end);
339 assertEquals("METAL", sf.type);
341 // verify FER1_SOLLC feature
342 sfs = al.getSequenceAt(2).getDatasetSequence().getSequenceFeatures();
343 assertEquals(1, sfs.size());
345 assertEquals("Iron-phosphorus (2Fe-P)", sf.description);
346 assertEquals(86, sf.begin);
347 assertEquals(87, sf.end);
348 assertEquals("METALLIC", sf.type);
351 private void checkDatasetfromSimpleGff3(AlignmentI dataset)
353 assertEquals("no sequences extracted from GFF3 file", 2,
354 dataset.getHeight());
356 SequenceI seq1 = dataset.findName("seq1");
357 SequenceI seq2 = dataset.findName("seq2");
361 "Failed to replace dummy seq1 with real sequence",
362 seq1 instanceof SequenceDummy
363 && ((SequenceDummy) seq1).isDummy());
365 "Failed to replace dummy seq2 with real sequence",
366 seq2 instanceof SequenceDummy
367 && ((SequenceDummy) seq2).isDummy());
368 String placeholderseq = new SequenceDummy("foo").getSequenceAsString();
369 assertFalse("dummy replacement buggy for seq1",
370 placeholderseq.equals(seq1.getSequenceAsString()));
371 assertFalse("dummy replacement buggy for seq2",
372 placeholderseq.equals(seq2.getSequenceAsString()));
373 assertNotNull("No features added to seq1", seq1.getSequenceFeatures());
374 assertEquals("Wrong number of features", 3, seq1.getSequenceFeatures()
376 assertTrue(seq2.getSequenceFeatures().isEmpty());
378 "Wrong number of features",
380 seq2.getSequenceFeatures() == null ? 0 : seq2
381 .getSequenceFeatures().size());
383 "Expected at least one CDNA/Protein mapping for seq1",
384 dataset.getCodonFrame(seq1) != null
385 && dataset.getCodonFrame(seq1).size() > 0);
389 @Test(groups = { "Functional" })
390 public void readGff3File() throws IOException
392 FeaturesFile gffreader = new FeaturesFile(true, simpleGffFile,
393 DataSourceType.FILE);
394 Alignment dataset = new Alignment(gffreader.getSeqsAsArray());
395 gffreader.addProperties(dataset);
396 checkDatasetfromSimpleGff3(dataset);
399 @Test(groups = { "Functional" })
400 public void simpleGff3FileClass() throws IOException
402 AlignmentI dataset = new Alignment(new SequenceI[] {});
403 FeaturesFile ffile = new FeaturesFile(simpleGffFile,
404 DataSourceType.FILE);
406 boolean parseResult = ffile.parse(dataset, null, false, false);
407 assertTrue("return result should be true", parseResult);
408 checkDatasetfromSimpleGff3(dataset);
411 @Test(groups = { "Functional" })
412 public void simpleGff3FileLoader() throws IOException
414 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
415 simpleGffFile, DataSourceType.FILE);
417 "Didn't read the alignment into an alignframe from Gff3 File",
419 checkDatasetfromSimpleGff3(af.getViewport().getAlignment());
422 @Test(groups = { "Functional" })
423 public void simpleGff3RelaxedIdMatching() throws IOException
425 AlignmentI dataset = new Alignment(new SequenceI[] {});
426 FeaturesFile ffile = new FeaturesFile(simpleGffFile,
427 DataSourceType.FILE);
429 boolean parseResult = ffile.parse(dataset, null, false, true);
430 assertTrue("return result (relaxedID matching) should be true",
432 checkDatasetfromSimpleGff3(dataset);
435 @Test(groups = { "Functional" })
436 public void testPrintJalviewFormat() throws Exception
438 File f = new File("examples/uniref50.fa");
439 AlignmentI al = readAlignmentFile(f);
440 AlignFrame af = new AlignFrame(al, 500, 500);
441 Map<String, FeatureColourI> colours = af.getFeatureRenderer()
442 .getFeatureColours();
443 String features = "METAL\tcc9900\n"
444 + "GAMMA-TURN\tred|0,255,255|20.0|95.0|below|66.0\n"
446 + "STARTGROUP\tuniprot\n"
447 + "Cath\tFER_CAPAA\t-1\t0\t0\tDomain\n" // non-positional feature
448 + "Iron\tFER_CAPAA\t-1\t39\t39\tMETAL\n"
449 + "Turn\tFER_CAPAA\t-1\t36\t38\tGAMMA-TURN\n"
450 + "<html>Pfam domain<a href=\"http://pfam.xfam.org/family/PF00111\">Pfam_3_4</a></html>\tFER_CAPAA\t-1\t20\t20\tPfam\n"
451 + "ENDGROUP\tuniprot\n";
452 FeaturesFile featuresFile = new FeaturesFile(features,
453 DataSourceType.PASTE);
454 featuresFile.parse(al.getDataset(), colours, false);
457 * add positional and non-positional features with null and
458 * empty feature group to check handled correctly
460 SequenceI seq = al.getSequenceAt(1); // FER_CAPAN
461 seq.addSequenceFeature(new SequenceFeature("Pfam", "desc1", 0, 0, 1.3f,
463 seq.addSequenceFeature(new SequenceFeature("Pfam", "desc2", 4, 9,
465 seq = al.getSequenceAt(2); // FER1_SOLLC
466 seq.addSequenceFeature(new SequenceFeature("Pfam", "desc3", 0, 0,
468 seq.addSequenceFeature(new SequenceFeature("Pfam", "desc4", 5, 8,
472 * first with no features displayed, exclude non-positional features
474 FeatureRenderer fr = af.alignPanel.getFeatureRenderer();
475 Map<String, FeatureColourI> visible = fr.getDisplayedFeatureCols();
476 List<String> visibleGroups = new ArrayList<>(
477 Arrays.asList(new String[] {}));
478 String exported = featuresFile.printJalviewFormat(
479 al.getSequencesArray(), visible, null, visibleGroups, false);
480 String expected = "No Features Visible";
481 assertEquals(expected, exported);
484 * include non-positional features
486 visibleGroups.add("uniprot");
487 exported = featuresFile.printJalviewFormat(al.getSequencesArray(),
488 visible, null, visibleGroups, true);
489 expected = "Cath\tFER_CAPAA\t-1\t0\t0\tDomain\t0.0\n"
490 + "desc1\tFER_CAPAN\t-1\t0\t0\tPfam\t1.3\n"
491 + "desc3\tFER1_SOLLC\t-1\t0\t0\tPfam\n" // NaN is not output
492 + "\nSTARTGROUP\tuniprot\nENDGROUP\tuniprot\n";
493 assertEquals(expected, exported);
496 * set METAL (in uniprot group) and GAMMA-TURN visible, but not Pfam
498 fr.setVisible("METAL");
499 fr.setVisible("GAMMA-TURN");
500 visible = fr.getDisplayedFeatureCols();
501 exported = featuresFile.printJalviewFormat(al.getSequencesArray(),
502 visible, null, visibleGroups, false);
503 expected = "METAL\tcc9900\n"
504 + "GAMMA-TURN\tff0000|00ffff|20.0|95.0|below|66.0\n"
505 + "\nSTARTGROUP\tuniprot\n"
506 + "Turn\tFER_CAPAA\t-1\t36\t38\tGAMMA-TURN\t0.0\n"
507 + "Iron\tFER_CAPAA\t-1\t39\t39\tMETAL\t0.0\n"
508 + "ENDGROUP\tuniprot\n";
509 assertEquals(expected, exported);
512 * now set Pfam visible
514 fr.setVisible("Pfam");
515 visible = fr.getDisplayedFeatureCols();
516 exported = featuresFile.printJalviewFormat(al.getSequencesArray(),
517 visible, null, visibleGroups, false);
519 * features are output within group, ordered by sequence and by type
521 expected = "METAL\tcc9900\n"
523 + "GAMMA-TURN\tff0000|00ffff|20.0|95.0|below|66.0\n"
524 + "\nSTARTGROUP\tuniprot\n"
525 + "Turn\tFER_CAPAA\t-1\t36\t38\tGAMMA-TURN\t0.0\n"
526 + "Iron\tFER_CAPAA\t-1\t39\t39\tMETAL\t0.0\n"
527 + "<html>Pfam domain<a href=\"http://pfam.xfam.org/family/PF00111\">Pfam_3_4</a></html>\tFER_CAPAA\t-1\t20\t20\tPfam\t0.0\n"
528 + "ENDGROUP\tuniprot\n"
529 // null / empty group features output after features in named
531 + "desc2\tFER_CAPAN\t-1\t4\t9\tPfam\n"
532 + "desc4\tFER1_SOLLC\t-1\t5\t8\tPfam\t-2.6\n";
533 assertEquals(expected, exported);
536 @Test(groups = { "Functional" })
537 public void testPrintGffFormat() throws Exception
539 File f = new File("examples/uniref50.fa");
540 AlignmentI al = readAlignmentFile(f);
541 AlignFrame af = new AlignFrame(al, 500, 500);
546 FeaturesFile featuresFile = new FeaturesFile();
547 FeatureRenderer fr = af.alignPanel.getFeatureRenderer();
548 Map<String, FeatureColourI> visible = new HashMap<>();
549 List<String> visibleGroups = new ArrayList<>(
550 Arrays.asList(new String[] {}));
551 String exported = featuresFile.printGffFormat(al.getSequencesArray(),
552 visible, visibleGroups, false);
553 String gffHeader = "##gff-version 2\n";
554 assertEquals(gffHeader, exported);
555 exported = featuresFile.printGffFormat(al.getSequencesArray(), visible,
556 visibleGroups, true);
557 assertEquals(gffHeader, exported);
562 al.getSequenceAt(0).addSequenceFeature(
563 new SequenceFeature("Domain", "Cath", 0, 0, 0f, "Uniprot"));
564 al.getSequenceAt(0).addSequenceFeature(
565 new SequenceFeature("METAL", "Cath", 39, 39, 1.2f, null));
568 new SequenceFeature("GAMMA-TURN", "Turn", 36, 38, 2.1f,
570 SequenceFeature sf = new SequenceFeature("Pfam", "", 20, 20, 0f,
572 sf.setAttributes("x=y;black=white");
575 al.getSequenceAt(1).addSequenceFeature(sf);
578 * with no features displayed, exclude non-positional features
580 exported = featuresFile.printGffFormat(al.getSequencesArray(), visible,
581 visibleGroups, false);
582 assertEquals(gffHeader, exported);
585 * include non-positional features
587 visibleGroups.add("Uniprot");
588 exported = featuresFile.printGffFormat(al.getSequencesArray(), visible,
589 visibleGroups, true);
590 String expected = gffHeader
591 + "FER_CAPAA\tUniprot\tDomain\t0\t0\t0.0\t.\t.\n";
592 assertEquals(expected, exported);
595 * set METAL (in uniprot group) and GAMMA-TURN visible, but not Pfam
596 * only Uniprot group visible here...
598 fr.setVisible("METAL");
599 fr.setVisible("GAMMA-TURN");
600 visible = fr.getDisplayedFeatureCols();
601 exported = featuresFile.printGffFormat(al.getSequencesArray(), visible,
602 visibleGroups, false);
603 // METAL feature has null group: description used for column 2
604 expected = gffHeader + "FER_CAPAA\tCath\tMETAL\t39\t39\t1.2\t.\t.\n";
605 assertEquals(expected, exported);
608 * set s3dm group visible
610 visibleGroups.add("s3dm");
611 exported = featuresFile.printGffFormat(al.getSequencesArray(), visible,
612 visibleGroups, false);
613 // METAL feature has null group: description used for column 2
614 expected = gffHeader + "FER_CAPAA\tCath\tMETAL\t39\t39\t1.2\t.\t.\n"
615 + "FER_CAPAN\ts3dm\tGAMMA-TURN\t36\t38\t2.1\t.\t.\n";
616 assertEquals(expected, exported);
619 * now set Pfam visible
621 fr.setVisible("Pfam");
622 visible = fr.getDisplayedFeatureCols();
623 exported = featuresFile.printGffFormat(al.getSequencesArray(), visible,
624 visibleGroups, false);
625 // Pfam feature columns include strand(+), phase(2), attributes
627 + "FER_CAPAA\tCath\tMETAL\t39\t39\t1.2\t.\t.\n"
628 + "FER_CAPAN\ts3dm\tGAMMA-TURN\t36\t38\t2.1\t.\t.\n"
629 + "FER_CAPAN\tUniprot\tPfam\t20\t20\t0.0\t+\t2\tx=y;black=white\n";
630 assertEquals(expected, exported);
634 * Test for parsing of feature filters as represented in a Jalview features
639 @Test(groups = { "Functional" })
640 public void testParseFilters() throws Exception
642 Map<String, FeatureMatcherSetI> filters = new HashMap<>();
643 String text = "sequence_variant\tCSQ:PolyPhen NotContains 'damaging'\n"
644 + "missense_variant\t(label contains foobar) and (Score lt 1.3)";
645 FeaturesFile featuresFile = new FeaturesFile(text,
646 DataSourceType.PASTE);
647 featuresFile.parseFilters(filters);
648 assertEquals(filters.size(), 2);
650 FeatureMatcherSetI fm = filters.get("sequence_variant");
652 Iterator<FeatureMatcherI> matchers = fm.getMatchers().iterator();
653 FeatureMatcherI matcher = matchers.next();
654 assertFalse(matchers.hasNext());
655 String[] attributes = matcher.getAttribute();
656 assertArrayEquals(attributes, new String[] { "CSQ", "PolyPhen" });
657 assertSame(matcher.getMatcher().getCondition(), Condition.NotContains);
658 assertEquals(matcher.getMatcher().getPattern(), "damaging");
660 fm = filters.get("missense_variant");
662 matchers = fm.getMatchers().iterator();
663 matcher = matchers.next();
664 assertTrue(matcher.isByLabel());
665 assertSame(matcher.getMatcher().getCondition(), Condition.Contains);
666 assertEquals(matcher.getMatcher().getPattern(), "foobar");
667 matcher = matchers.next();
668 assertTrue(matcher.isByScore());
669 assertSame(matcher.getMatcher().getCondition(), Condition.LT);
670 assertEquals(matcher.getMatcher().getPattern(), "1.3");
671 assertEquals(matcher.getMatcher().getFloatValue(), 1.3f);
673 assertFalse(matchers.hasNext());