Clover icon

Coverage Report

  1. Project Clover database Wed Sep 18 2024 02:54:09 BST
  2. Package jalview.gui

File PymolViewer.java

 

Coverage histogram

../../img/srcFileCovDistChart0.png
59% of files have more coverage

Code metrics

38
132
17
1
426
318
39
0.3
7.76
17
2.29

Classes

Class Line # Actions
PymolViewer 48 132 39
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.gui;
22   
23    import java.awt.event.ActionEvent;
24    import java.awt.event.ActionListener;
25    import java.io.File;
26    import java.util.ArrayList;
27    import java.util.List;
28    import java.util.Map;
29   
30    import javax.swing.JInternalFrame;
31    import javax.swing.JMenuItem;
32    import javax.swing.event.InternalFrameAdapter;
33    import javax.swing.event.InternalFrameEvent;
34   
35    import jalview.api.AlignmentViewPanel;
36    import jalview.api.FeatureRenderer;
37    import jalview.bin.Console;
38    import jalview.datamodel.PDBEntry;
39    import jalview.datamodel.SequenceI;
40    import jalview.datamodel.StructureViewerModel;
41    import jalview.datamodel.StructureViewerModel.StructureData;
42    import jalview.gui.StructureViewer.ViewerType;
43    import jalview.io.DataSourceType;
44    import jalview.io.StructureFile;
45    import jalview.structures.models.AAStructureBindingModel;
46    import jalview.util.MessageManager;
47   
 
48    public class PymolViewer extends StructureViewerBase
49    {
50    private static final int myWidth = 500;
51   
52    private static final int myHeight = 150;
53   
54    private PymolBindingModel binding;
55   
56    private String pymolSessionFile;
57   
 
58  0 toggle public PymolViewer()
59    {
60  0 super();
61   
62    /*
63    * closeViewer will decide whether or not to close this frame
64    * depending on whether user chooses to Cancel or not
65    */
66  0 setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE);
67    }
68   
 
69  0 toggle public PymolViewer(PDBEntry pdb, SequenceI[] seqs, Object object,
70    AlignmentPanel ap)
71    {
72  0 this();
73  0 openNewPymol(ap, new PDBEntry[] { pdb }, new SequenceI[][] { seqs });
74    }
75   
 
76  0 toggle public PymolViewer(PDBEntry[] pe, boolean alignAdded, SequenceI[][] seqs,
77    AlignmentPanel ap)
78    {
79  0 this();
80  0 setAlignAddedStructures(alignAdded);
81  0 openNewPymol(ap, pe, seqs);
82    }
83   
84    /**
85    * Constructor given a session file to be restored
86    *
87    * @param sessionFile
88    * @param alignPanel
89    * @param pdbArray
90    * @param seqsArray
91    * @param colourByPymol
92    * @param colourBySequence
93    * @param newViewId
94    */
 
95  0 toggle public PymolViewer(StructureViewerModel viewerModel,
96    AlignmentPanel alignPanel, String sessionFile, String vid)
97    {
98    // TODO convert to base/factory class method
99  0 this();
100  0 setViewId(vid);
101  0 this.pymolSessionFile = sessionFile;
102  0 Map<File, StructureData> pdbData = viewerModel.getFileData();
103  0 PDBEntry[] pdbArray = new PDBEntry[pdbData.size()];
104  0 SequenceI[][] seqsArray = new SequenceI[pdbData.size()][];
105  0 int i = 0;
106  0 for (StructureData data : pdbData.values())
107    {
108  0 PDBEntry pdbentry = new PDBEntry(data.getPdbId(), null,
109    PDBEntry.Type.PDB, data.getFilePath());
110  0 pdbArray[i] = pdbentry;
111  0 List<SequenceI> sequencesForPdb = data.getSeqList();
112  0 seqsArray[i] = sequencesForPdb
113    .toArray(new SequenceI[sequencesForPdb.size()]);
114  0 i++;
115    }
116   
117  0 openNewPymol(alignPanel, pdbArray, seqsArray);
118  0 if (viewerModel.isColourByViewer())
119    {
120  0 binding.setColourBySequence(false);
121  0 seqColour.setSelected(false);
122  0 viewerColour.setSelected(true);
123    }
124  0 else if (viewerModel.isColourWithAlignPanel())
125    {
126  0 binding.setColourBySequence(true);
127  0 seqColour.setSelected(true);
128  0 viewerColour.setSelected(false);
129    }
130    }
131   
 
132  0 toggle private void openNewPymol(AlignmentPanel ap, PDBEntry[] pe,
133    SequenceI[][] seqs)
134    {
135  0 createProgressBar();
136  0 binding = new PymolBindingModel(this, ap.getStructureSelectionManager(),
137    pe, seqs);
138  0 addAlignmentPanel(ap);
139  0 useAlignmentPanelForColourbyseq(ap);
140   
141  0 if (pe.length > 1)
142    {
143  0 useAlignmentPanelForSuperposition(ap);
144    }
145  0 binding.setColourBySequence(true);
146  0 setSize(myWidth, myHeight);
147  0 initMenus();
148  0 viewerActionMenu.setText("PyMOL");
149  0 updateTitleAndMenus();
150   
151  0 addingStructures = false;
152  0 worker = new Thread(this);
153  0 worker.start();
154   
155  0 this.addInternalFrameListener(new InternalFrameAdapter()
156    {
 
157  0 toggle @Override
158    public void internalFrameClosing(
159    InternalFrameEvent internalFrameEvent)
160    {
161  0 closeViewer(false);
162    }
163    });
164   
165    }
166   
167    /**
168    * Create a helper to manage progress bar display
169    */
 
170  0 toggle protected void createProgressBar()
171    {
172  0 if (getProgressIndicator() == null)
173    {
174  0 setProgressIndicator(new ProgressBar(statusPanel, statusBar));
175    }
176    }
177   
 
178  0 toggle @Override
179    public void run()
180    {
181    // todo pull up much of this
182   
183  0 StringBuilder errormsgs = new StringBuilder(128);
184  0 List<PDBEntry> filePDB = new ArrayList<>();
185  0 List<Integer> filePDBpos = new ArrayList<>();
186  0 String[] curfiles = binding.getStructureFiles(); // files currently in
187    // viewer
188  0 for (int pi = 0; pi < binding.getPdbCount(); pi++)
189    {
190  0 String file = null;
191  0 PDBEntry thePdbEntry = binding.getPdbEntry(pi);
192  0 if (thePdbEntry.getFile() == null)
193    {
194    /*
195    * Retrieve PDB data, save to file, attach to PDBEntry
196    */
197  0 file = fetchPdbFile(thePdbEntry);
198  0 if (file == null)
199    {
200  0 errormsgs.append("'" + thePdbEntry.getId() + "' ");
201    }
202    }
203    else
204    {
205    /*
206    * got file already
207    */
208  0 file = new File(thePdbEntry.getFile()).getAbsoluteFile().getPath();
209    // todo - skip if already loaded in PyMOL
210    }
211  0 if (file != null)
212    {
213  0 filePDB.add(thePdbEntry);
214  0 filePDBpos.add(Integer.valueOf(pi));
215    }
216    }
217   
218  0 if (!filePDB.isEmpty())
219    {
220    /*
221    * at least one structure to add to viewer
222    */
223  0 binding.setFinishedInit(false);
224  0 if (!addingStructures)
225    {
226  0 try
227    {
228  0 initPymol();
229    } catch (Exception ex)
230    {
231  0 Console.error("Couldn't open PyMOL viewer!", ex);
232    // if we couldn't open Pymol, no point continuing
233  0 return;
234    }
235    }
236  0 if (!binding.isViewerRunning())
237    {
238    // nothing to do
239    // TODO: ensure we tidy up JAL-3619
240   
241  0 return;
242    }
243   
244  0 int num = -1;
245  0 for (PDBEntry pe : filePDB)
246    {
247  0 num++;
248  0 if (pe.getFile() != null)
249    {
250  0 try
251    {
252  0 int pos = filePDBpos.get(num).intValue();
253  0 long startTime = startProgressBar(getViewerName() + " "
254    + MessageManager.getString("status.opening_file_for")
255    + " " + pe.getId());
256  0 binding.openFile(pe);
257  0 binding.addSequence(pos, binding.getSequence()[pos]);
258  0 File fl = new File(pe.getFile());
259  0 DataSourceType protocol = DataSourceType.URL;
260  0 try
261    {
262  0 if (fl.exists())
263    {
264  0 protocol = DataSourceType.FILE;
265    }
266    } catch (Throwable e)
267    {
268    } finally
269    {
270  0 stopProgressBar("", startTime);
271    }
272   
273  0 StructureFile pdb = null;
274  0 if (pe.hasStructureFile())
275    {
276  0 pdb = pe.getStructureFile();
277  0 Console.debug("(Re)Using StructureFile " + pdb.getId());
278    }
279    else
280    {
281  0 pdb = binding.getSsm().setMapping(binding.getSequence()[pos],
282    binding.getChains()[pos], pe.getFile(), protocol,
283    getProgressIndicator());
284    }
285  0 binding.stashFoundChains(pdb, pe.getFile());
286    } catch (Exception ex)
287    {
288  0 Console.error("Couldn't open " + pe.getFile() + " in "
289    + getViewerName() + "!", ex);
290    } finally
291    {
292    // Cache.debug("File locations are " + files);
293    }
294    }
295    }
296   
297  0 binding.refreshGUI();
298  0 binding.setFinishedInit(true);
299  0 binding.setLoadingFromArchive(false);
300   
301    /*
302    * ensure that any newly discovered features (e.g. RESNUM)
303    * are added to any open feature settings dialog
304    */
305  0 FeatureRenderer fr = getBinding().getFeatureRenderer(null);
306  0 if (fr != null)
307    {
308  0 fr.featuresAdded();
309    }
310   
311    // refresh the sequence colours for the new structure(s)
312  0 for (AlignmentViewPanel ap : _colourwith)
313    {
314  0 binding.updateColours(ap);
315    }
316    // do superposition if asked to
317  0 if (alignAddedStructures)
318    {
319  0 new Thread(new Runnable()
320    {
 
321  0 toggle @Override
322    public void run()
323    {
324  0 alignStructsWithAllAlignPanels();
325    }
326    }).start();
327    }
328  0 addingStructures = false;
329    }
330  0 _started = false;
331  0 worker = null;
332   
333    }
334   
335    /**
336    * Launch PyMOL. If we have a session file name, send PyMOL the command to
337    * open its saved session file.
338    */
 
339  0 toggle void initPymol()
340    {
341  0 Desktop.addInternalFrame(this,
342    binding.getViewerTitle(getViewerName(), true),
343    getBounds().width, getBounds().height);
344   
345  0 if (!binding.launchPymol())
346    {
347  0 JvOptionPane.showMessageDialog(Desktop.desktop,
348    MessageManager.formatMessage("label.open_viewer_failed",
349    getViewerName()),
350    MessageManager.getString("label.error_loading_file"),
351    JvOptionPane.ERROR_MESSAGE);
352  0 binding.closeViewer(true);
353  0 this.dispose();
354  0 return;
355    }
356   
357  0 if (this.pymolSessionFile != null)
358    {
359  0 boolean opened = binding.openSession(pymolSessionFile);
360  0 if (!opened)
361    {
362  0 Console.error("An error occurred opening PyMOL session file "
363    + pymolSessionFile);
364    }
365    }
366    // binding.startPymolListener();
367    }
368   
 
369  0 toggle @Override
370    public AAStructureBindingModel getBinding()
371    {
372  0 return binding;
373    }
374   
 
375  0 toggle @Override
376    public ViewerType getViewerType()
377    {
378  0 return ViewerType.PYMOL;
379    }
380   
 
381  0 toggle @Override
382    protected String getViewerName()
383    {
384  0 return "PyMOL";
385    }
386   
387    JMenuItem writeFeatures = null;
388   
 
389  0 toggle @Override
390    protected void initMenus()
391    {
392  0 super.initMenus();
393   
394  0 savemenu.setVisible(false); // not yet implemented
395  0 viewMenu.add(fitToWindow);
396   
397  0 writeFeatures = new JMenuItem(
398    MessageManager.getString("label.create_viewer_attributes"));
399  0 writeFeatures.setToolTipText(
400    MessageManager.getString("label.create_viewer_attributes_tip"));
401  0 writeFeatures.addActionListener(new ActionListener()
402    {
 
403  0 toggle @Override
404    public void actionPerformed(ActionEvent e)
405    {
406  0 sendFeaturesToPymol();
407    }
408    });
409  0 viewerActionMenu.add(writeFeatures);
410    }
411   
 
412  0 toggle @Override
413    protected void buildActionMenu()
414    {
415  0 super.buildActionMenu();
416  0 viewerActionMenu.add(writeFeatures);
417    }
418   
 
419  0 toggle protected void sendFeaturesToPymol()
420    {
421  0 int count = binding.sendFeaturesToViewer(getAlignmentPanel());
422  0 statusBar.setText(MessageManager.formatMessage("label.attributes_set",
423    count, getViewerName()));
424    }
425   
426    }