Clover icon

jalviewX

  1. Project Clover database Wed Oct 31 2018 15:13:58 GMT
  2. Package jalview.ext.rbvi.chimera

File JalviewChimeraView.java

 

Code metrics

16
159
8
1
486
307
20
0.13
19.88
8
2.5

Classes

Class Line # Actions
JalviewChimeraView 61 159 20 183
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

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.ext.rbvi.chimera;
22   
23    import static org.testng.Assert.assertEquals;
24    import static org.testng.Assert.assertFalse;
25    import static org.testng.Assert.assertNotNull;
26    import static org.testng.Assert.assertTrue;
27   
28    import jalview.api.FeatureRenderer;
29    import jalview.api.structures.JalviewStructureDisplayI;
30    import jalview.bin.Cache;
31    import jalview.bin.Jalview;
32    import jalview.datamodel.DBRefEntry;
33    import jalview.datamodel.PDBEntry;
34    import jalview.datamodel.SequenceFeature;
35    import jalview.datamodel.SequenceI;
36    import jalview.gui.AlignFrame;
37    import jalview.gui.Desktop;
38    import jalview.gui.JvOptionPane;
39    import jalview.gui.Preferences;
40    import jalview.gui.StructureViewer;
41    import jalview.gui.StructureViewer.ViewerType;
42    import jalview.io.DataSourceType;
43    import jalview.io.FileLoader;
44    import jalview.structure.StructureMapping;
45    import jalview.structure.StructureSelectionManager;
46    import jalview.ws.sifts.SiftsClient;
47    import jalview.ws.sifts.SiftsException;
48    import jalview.ws.sifts.SiftsSettings;
49   
50    import java.io.File;
51    import java.io.IOException;
52    import java.util.List;
53    import java.util.Vector;
54   
55    import org.testng.annotations.AfterClass;
56    import org.testng.annotations.AfterMethod;
57    import org.testng.annotations.BeforeClass;
58    import org.testng.annotations.Test;
59   
60    @Test(singleThreaded = true)
 
61    public class JalviewChimeraView
62    {
63   
 
64  0 toggle @BeforeClass(alwaysRun = true)
65    public void setUpJvOptionPane()
66    {
67  0 JvOptionPane.setInteractiveMode(false);
68  0 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
69    }
70   
71    private JalviewStructureDisplayI chimeraViewer;
72   
73    /**
74    * @throws java.lang.Exception
75    */
 
76  0 toggle @BeforeClass(alwaysRun = true)
77    public static void setUpBeforeClass() throws Exception
78    {
79  0 Jalview.main(new String[] { "-noquestionnaire", "-nonews", "-props",
80    "test/jalview/ext/rbvi/chimera/testProps.jvprops" });
81  0 Cache.setProperty(Preferences.STRUCTURE_DISPLAY,
82    ViewerType.CHIMERA.name());
83  0 Cache.setProperty("SHOW_ANNOTATIONS", "false");
84  0 Cache.setProperty(Preferences.STRUCT_FROM_PDB, "false");
85  0 Cache.setProperty(Preferences.STRUCTURE_DISPLAY,
86    ViewerType.CHIMERA.name());
87  0 Cache.setProperty("MAP_WITH_SIFTS", "true");
88    // TODO this should not be necessary!
89  0 SiftsSettings.setMapWithSifts(true);
90    }
91   
92    /**
93    * @throws java.lang.Exception
94    */
 
95  0 toggle @AfterClass(alwaysRun = true)
96    public static void tearDownAfterClass() throws Exception
97    {
98  0 Desktop.instance.closeAll_actionPerformed(null);
99    }
100   
 
101  0 toggle @AfterMethod(alwaysRun = true)
102    public void tearDownAfterTest() throws Exception
103    {
104  0 SiftsClient.setMockSiftsFile(null);
105  0 if (chimeraViewer != null)
106    {
107  0 chimeraViewer.closeViewer(true);
108    }
109    }
110   
111    /**
112    * Load 1GAQ and view the first structure for which a PDB id is found. Note no
113    * network connection is needed - PDB file is read locally, SIFTS fetch fails
114    * so mapping falls back to Needleman-Wunsch - ok for this test.
115    */
116    // External as local install of Chimera required
 
117  0 toggle @Test(groups = { "External" })
118    public void testSingleSeqViewChimera()
119    {
120  0 String inFile = "examples/1gaq.txt";
121  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
122    DataSourceType.FILE);
123  0 assertNotNull(af, "Failed to create AlignFrame");
124  0 SequenceI sq = af.getViewport().getAlignment().getSequenceAt(0);
125  0 assertEquals(sq.getName(), "1GAQ|A");
126  0 SequenceI dsq = sq.getDatasetSequence();
127  0 Vector<PDBEntry> pdbIds = dsq.getAllPDBEntries();
128  0 assertEquals(pdbIds.size(), 1);
129  0 PDBEntry pdbEntry = pdbIds.get(0);
130  0 assertEquals(pdbEntry.getId(), "1GAQ");
131  0 StructureViewer structureViewer = new StructureViewer(af.getViewport()
132    .getStructureSelectionManager());
133  0 chimeraViewer = structureViewer.viewStructures(pdbEntry,
134    new SequenceI[] { sq }, af.getCurrentView().getAlignPanel());
135  0 JalviewChimeraBinding binding = (JalviewChimeraBinding) chimeraViewer
136    .getBinding();
137   
138    /*
139    * Wait for viewer load thread to complete
140    */
141  0 while (!binding.isFinishedInit())
142    {
143  0 try
144    {
145  0 Thread.sleep(500);
146    } catch (InterruptedException e)
147    {
148    }
149    }
150   
151  0 assertTrue(binding.isChimeraRunning(), "Failed to start Chimera");
152   
153  0 assertEquals(chimeraViewer.getBinding().getPdbCount(), 1);
154  0 chimeraViewer.closeViewer(true);
155  0 chimeraViewer = null;
156  0 return;
157    }
158   
159    /**
160    * Test for writing Jalview features as attributes on mapped residues in
161    * Chimera. Note this uses local copies of PDB and SIFTS file, no network
162    * connection required.
163    *
164    * @throws IOException
165    * @throws SiftsException
166    */
167    // External as this requires a local install of Chimera
 
168  0 toggle @Test(groups = { "External" })
169    public void testTransferFeatures() throws IOException, SiftsException
170    {
171  0 String inFile = "examples/uniref50.fa";
172  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
173    DataSourceType.FILE);
174  0 assertNotNull(af, "Failed to create AlignFrame");
175  0 SequenceI sq = af.getViewport().getAlignment().findName("FER2_ARATH");
176  0 assertNotNull(sq, "Didn't find FER2_ARATH");
177   
178    /*
179    * need a Uniprot dbref for SIFTS mapping to work!!
180    */
181  0 sq.addDBRef(new DBRefEntry("UNIPROT", "0", "P16972", null));
182   
183    /*
184    * use local test PDB and SIFTS files
185    */
186  0 String pdbFilePath = new File(
187    "test/jalview/ext/rbvi/chimera/4zho.pdb").getPath();
188  0 PDBEntry pdbEntry = new PDBEntry("4ZHO", null, null, pdbFilePath);
189  0 String siftsFilePath = new File(
190    "test/jalview/ext/rbvi/chimera/4zho.xml.gz")
191    .getPath();
192  0 SiftsClient.setMockSiftsFile(new File(siftsFilePath));
193   
194  0 StructureViewer structureViewer = new StructureViewer(af.getViewport()
195    .getStructureSelectionManager());
196  0 chimeraViewer = structureViewer.viewStructures(pdbEntry,
197    new SequenceI[] { sq }, af.getCurrentView().getAlignPanel());
198   
199  0 JalviewChimeraBinding binding = (JalviewChimeraBinding) chimeraViewer
200    .getBinding();
201  0 do
202    {
203  0 try
204    {
205  0 Thread.sleep(500);
206    } catch (InterruptedException e)
207    {
208    }
209  0 } while (!binding.isFinishedInit());
210   
211  0 assertTrue(binding.isChimeraRunning(), "Failed to launch Chimera");
212   
213  0 assertEquals(binding.getPdbCount(), 1);
214   
215    /*
216    * check mapping is (sequence) 53-145 to (structure) 2-94 A/B
217    * (or possibly 52-145 to 1-94 - see JAL-2319)
218    */
219  0 StructureSelectionManager ssm = binding.getSsm();
220  0 String pdbFile = binding.getStructureFiles()[0];
221  0 StructureMapping[] mappings = ssm.getMapping(pdbFile);
222  0 assertTrue(mappings[0].getMappingDetailsOutput().contains("SIFTS"),
223    "Failed to perform SIFTS mapping");
224  0 assertEquals(mappings.length, 2);
225  0 assertEquals(mappings[0].getChain(), "A");
226  0 assertEquals(mappings[0].getPDBResNum(53), 2);
227  0 assertEquals(mappings[0].getPDBResNum(145), 94);
228  0 assertEquals(mappings[1].getChain(), "B");
229  0 assertEquals(mappings[1].getPDBResNum(53), 2);
230  0 assertEquals(mappings[1].getPDBResNum(145), 94);
231   
232    /*
233    * now add some features to FER2_ARATH
234    */
235    // feature on a sequence region not mapped to structure:
236  0 sq.addSequenceFeature(new SequenceFeature("transit peptide",
237    "chloroplast", 1, 51, Float.NaN, null));
238    // feature on a region mapped to structure:
239  0 sq.addSequenceFeature(new SequenceFeature("domain",
240    "2Fe-2S ferredoxin-type", 55, 145, Float.NaN, null));
241    // on sparse positions of the sequence
242  0 sq.addSequenceFeature(new SequenceFeature("metal ion-binding site",
243    "Iron-Sulfur (2Fe-2S)", 91, 91, Float.NaN, null));
244  0 sq.addSequenceFeature(new SequenceFeature("metal ion-binding site",
245    "Iron-Sulfur (2Fe-2S)", 96, 96, Float.NaN, null));
246    // on a sequence region that is partially mapped to structure:
247  0 sq.addSequenceFeature(new SequenceFeature("helix", null, 50, 60,
248    Float.NaN, null));
249    // and again:
250  0 sq.addSequenceFeature(new SequenceFeature("chain", null, 50, 70,
251    Float.NaN, null));
252    // add numeric valued features - score is set as attribute value
253  0 sq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 62,
254    62, -2.1f, null));
255  0 sq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 65,
256    65, 3.6f, null));
257  0 sq.addSequenceFeature(new SequenceFeature("RESNUM", "ALA: 2 4zhoA",
258    53, 53, Float.NaN, null));
259   
260    /*
261    * set all features visible except for chain
262    */
263  0 af.setShowSeqFeatures(true);
264  0 FeatureRenderer fr = af.getFeatureRenderer();
265  0 fr.setVisible("transit peptide");
266  0 fr.setVisible("domain");
267  0 fr.setVisible("metal ion-binding site");
268  0 fr.setVisible("helix");
269  0 fr.setVisible("kd");
270  0 fr.setVisible("RESNUM");
271   
272    /*
273    * 'perform' menu action to copy visible features to
274    * attributes in Chimera
275    */
276    // TODO rename and pull up method to binding interface
277    // once functionality is added for Jmol as well
278  0 binding.sendFeaturesToViewer(af.getViewport().getAlignPanel());
279   
280    /*
281    * give Chimera time to open the commands file and execute it
282    */
283  0 try
284    {
285  0 Thread.sleep(1000);
286    } catch (InterruptedException e)
287    {
288    }
289   
290    /*
291    * ask Chimera for its residue attribute names
292    */
293  0 List<String> reply = binding.sendChimeraCommand("list resattr", true);
294    // prefixed and sanitised attribute names for Jalview features:
295  0 assertTrue(reply.contains("resattr jv_domain"));
296  0 assertTrue(reply.contains("resattr jv_metal_ion_binding_site"));
297  0 assertTrue(reply.contains("resattr jv_helix"));
298  0 assertTrue(reply.contains("resattr jv_kd"));
299  0 assertTrue(reply.contains("resattr jv_RESNUM"));
300    // feature is not on a mapped region - no attribute created
301  0 assertFalse(reply.contains("resattr jv_transit_peptide"));
302    // feature is not visible - no attribute created
303  0 assertFalse(reply.contains("resattr jv_chain"));
304   
305    /*
306    * ask Chimera for residues with an attribute
307    * 91 and 96 on sequence --> residues 40 and 45 on chains A and B
308    */
309  0 reply = binding.sendChimeraCommand(
310    "list resi att jv_metal_ion_binding_site", true);
311  0 assertEquals(reply.size(), 4);
312  0 assertTrue(reply
313    .contains("residue id #0:40.A jv_metal_ion_binding_site \"Iron-Sulfur (2Fe-2S)\" index 40"));
314  0 assertTrue(reply
315    .contains("residue id #0:45.A jv_metal_ion_binding_site \"Iron-Sulfur (2Fe-2S)\" index 45"));
316  0 assertTrue(reply
317    .contains("residue id #0:40.B jv_metal_ion_binding_site \"Iron-Sulfur (2Fe-2S)\" index 40"));
318  0 assertTrue(reply
319    .contains("residue id #0:45.B jv_metal_ion_binding_site \"Iron-Sulfur (2Fe-2S)\" index 45"));
320   
321    /*
322    * check attributes with score values
323    * sequence positions 62 and 65 --> residues 11 and 14 on chains A and B
324    */
325  0 reply = binding.sendChimeraCommand("list resi att jv_kd", true);
326  0 assertEquals(reply.size(), 4);
327  0 assertTrue(reply.contains("residue id #0:11.A jv_kd -2.1 index 11"));
328  0 assertTrue(reply.contains("residue id #0:14.A jv_kd 3.6 index 14"));
329  0 assertTrue(reply.contains("residue id #0:11.B jv_kd -2.1 index 11"));
330  0 assertTrue(reply.contains("residue id #0:14.B jv_kd 3.6 index 14"));
331   
332    /*
333    * list residues with positive kd score
334    */
335  0 reply = binding.sendChimeraCommand(
336    "list resi spec :*/jv_kd>0 attr jv_kd", true);
337  0 assertEquals(reply.size(), 2);
338  0 assertTrue(reply.contains("residue id #0:14.A jv_kd 3.6 index 14"));
339  0 assertTrue(reply.contains("residue id #0:14.B jv_kd 3.6 index 14"));
340   
341  0 SiftsClient.setMockSiftsFile(null);
342  0 chimeraViewer.closeViewer(true);
343  0 chimeraViewer = null;
344    }
345   
346    /**
347    * Test for creating Jalview features from attributes on mapped residues in
348    * Chimera. Note this uses local copies of PDB and SIFTS file, no network
349    * connection required.
350    *
351    * @throws IOException
352    * @throws SiftsException
353    */
354    // External as this requires a local install of Chimera
 
355  0 toggle @Test(groups = { "External" })
356    public void testGetAttributes() throws IOException, SiftsException
357    {
358  0 String inFile = "examples/uniref50.fa";
359  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
360    DataSourceType.FILE);
361  0 assertNotNull(af, "Failed to create AlignFrame");
362  0 SequenceI fer2Arath = af.getViewport().getAlignment()
363    .findName("FER2_ARATH");
364  0 assertNotNull(fer2Arath, "Didn't find FER2_ARATH");
365   
366    /*
367    * need a Uniprot dbref for SIFTS mapping to work!!
368    */
369  0 fer2Arath.addDBRef(new DBRefEntry("UNIPROT", "0", "P16972", null));
370   
371    /*
372    * use local test PDB and SIFTS files
373    */
374  0 String pdbFilePath = new File(
375    "test/jalview/ext/rbvi/chimera/4zho.pdb").getPath();
376  0 PDBEntry pdbEntry = new PDBEntry("4ZHO", null, null, pdbFilePath);
377  0 String siftsFilePath = new File(
378    "test/jalview/ext/rbvi/chimera/4zho.xml.gz")
379    .getPath();
380  0 SiftsClient.setMockSiftsFile(new File(siftsFilePath));
381   
382  0 StructureViewer structureViewer = new StructureViewer(af.getViewport()
383    .getStructureSelectionManager());
384  0 chimeraViewer = structureViewer.viewStructures(pdbEntry,
385    new SequenceI[] { fer2Arath }, af.getCurrentView()
386    .getAlignPanel());
387   
388  0 JalviewChimeraBinding binding = (JalviewChimeraBinding) chimeraViewer
389    .getBinding();
390  0 do
391    {
392  0 try
393    {
394  0 Thread.sleep(500);
395    } catch (InterruptedException e)
396    {
397    }
398  0 } while (!binding.isFinishedInit());
399   
400  0 assertTrue(binding.isChimeraRunning(), "Failed to launch Chimera");
401   
402  0 assertEquals(binding.getPdbCount(), 1);
403   
404    /*
405    * 'perform' menu action to copy visible features to
406    * attributes in Chimera
407    */
408    // TODO rename and pull up method to binding interface
409    // once functionality is added for Jmol as well
410  0 binding.copyStructureAttributesToFeatures("isHelix", af.getViewport()
411    .getAlignPanel());
412   
413    /*
414    * verify 22 residues have isHelix feature
415    * (may merge into ranges in future)
416    */
417  0 af.setShowSeqFeatures(true);
418  0 FeatureRenderer fr = af.getFeatureRenderer();
419  0 fr.setVisible("isHelix");
420  0 for (int res = 75; res <= 83; res++)
421    {
422  0 checkFeaturesAtRes(fer2Arath, fr, res, "isHelix");
423    }
424  0 for (int res = 117; res <= 123; res++)
425    {
426  0 checkFeaturesAtRes(fer2Arath, fr, res, "isHelix");
427    }
428  0 for (int res = 129; res <= 131; res++)
429    {
430  0 checkFeaturesAtRes(fer2Arath, fr, res, "isHelix");
431    }
432  0 for (int res = 143; res <= 145; res++)
433    {
434  0 checkFeaturesAtRes(fer2Arath, fr, res, "isHelix");
435    }
436   
437    /*
438    * fetch a numeric valued attribute
439    */
440  0 binding.copyStructureAttributesToFeatures("phi", af.getViewport()
441    .getAlignPanel());
442  0 fr.setVisible("phi");
443  0 List<SequenceFeature> fs = fer2Arath.getFeatures().findFeatures(54, 54);
444  0 assertEquals(fs.size(), 3);
445    /*
446    * order of returned features is not guaranteed
447    */
448  0 assertTrue("RESNUM".equals(fs.get(0).getType())
449    || "RESNUM".equals(fs.get(1).getType())
450    || "RESNUM".equals(fs.get(2).getType()));
451  0 assertTrue(fs.contains(new SequenceFeature("phi", "A", 54, 54,
452    -131.0713f, "Chimera")));
453  0 assertTrue(fs.contains(new SequenceFeature("phi", "B", 54, 54,
454    -127.39512f, "Chimera")));
455   
456    /*
457    * tear down - also in AfterMethod
458    */
459  0 SiftsClient.setMockSiftsFile(null);
460  0 chimeraViewer.closeViewer(true);
461  0 chimeraViewer = null;
462    }
463   
464    /**
465    * Helper method to verify new feature at a sequence position
466    *
467    * @param seq
468    * @param fr
469    * @param res
470    * @param featureType
471    */
 
472  0 toggle protected void checkFeaturesAtRes(SequenceI seq, FeatureRenderer fr,
473    int res, String featureType)
474    {
475  0 String where = "at position " + res;
476  0 List<SequenceFeature> fs = seq.getFeatures().findFeatures(res, res);
477   
478  0 assertEquals(fs.size(), 2, where);
479  0 assertEquals(fs.get(0).getType(), "RESNUM", where);
480  0 SequenceFeature sf = fs.get(1);
481  0 assertEquals(sf.getType(), featureType, where);
482  0 assertEquals(sf.getFeatureGroup(), "Chimera", where);
483  0 assertEquals(sf.getDescription(), "True", where);
484  0 assertEquals(sf.getScore(), Float.NaN, where);
485    }
486    }