1. Project Clover database Fri Dec 6 2024 13:47:14 GMT
  2. Package jalview.gui

File PymolBindingModel.java

 

Coverage histogram

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

Code metrics

14
54
15
1
257
163
24
0.44
3.6
15
1.6

Classes

Class
Line #
Actions
PymolBindingModel 42 54 24
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.util.ArrayList;
24    import java.util.HashMap;
25    import java.util.List;
26    import java.util.Map;
27   
28    import jalview.api.AlignmentViewPanel;
29    import jalview.bin.Console;
30    import jalview.datamodel.PDBEntry;
31    import jalview.datamodel.SequenceI;
32    import jalview.ext.pymol.PymolCommands;
33    import jalview.ext.pymol.PymolManager;
34    import jalview.gui.StructureViewer.ViewerType;
35    import jalview.structure.AtomSpec;
36    import jalview.structure.AtomSpecModel;
37    import jalview.structure.StructureCommand;
38    import jalview.structure.StructureCommandI;
39    import jalview.structure.StructureSelectionManager;
40    import jalview.structures.models.AAStructureBindingModel;
41   
 
42    public class PymolBindingModel extends AAStructureBindingModel
43    {
44    /*
45    * format for labels shown on structures when mousing over sequence;
46    * see https://pymolwiki.org/index.php/Label#examples
47    * left not final so customisable e.g. with a Groovy script
48    */
49    private static String LABEL_FORMAT = "\"%s %s\" % (resn,resi)";
50   
51    private PymolManager pymolManager;
52   
53    /*
54    * full paths to structure files opened in PyMOL
55    */
56    List<String> structureFiles = new ArrayList<>();
57   
58    /*
59    * lookup from file path to PyMOL object name
60    */
61    Map<String, String> pymolObjects = new HashMap<>();
62   
63    private String lastLabelSpec;
64   
65    /**
66    * Constructor
67    *
68    * @param viewer
69    * @param ssm
70    * @param pdbentry
71    * @param sequenceIs
72    */
 
73  0 toggle public PymolBindingModel(StructureViewerBase viewer,
74    StructureSelectionManager ssm, PDBEntry[] pdbentry,
75    SequenceI[][] sequenceIs)
76    {
77  0 super(ssm, pdbentry, sequenceIs, null);
78  0 pymolManager = new PymolManager();
79  0 setStructureCommands(new PymolCommands());
80  0 setViewer(viewer);
81    }
82   
 
83  0 toggle @Override
84    public String[] getStructureFiles()
85    {
86  0 return structureFiles.toArray(new String[structureFiles.size()]);
87    }
88   
 
89  0 toggle @Override
90    public void highlightAtoms(List<AtomSpec> atoms)
91    {
92    /*
93    * https://pymolwiki.org/index.php/indicate#examples
94    */
95  0 StringBuilder sb = new StringBuilder();
96  0 for (AtomSpec atom : atoms)
97    {
98    // todo promote to StructureCommandsI.showLabel()
99  0 String modelId = getModelIdForFile(atom.getPdbFile());
100  0 sb.append(String.format(" %s//%s/%d/*", modelId, atom.getChain(),
101    atom.getPdbResNum()));
102    }
103  0 String labelSpec = sb.toString();
104  0 if (labelSpec.equals(lastLabelSpec))
105    {
106  0 return;
107    }
108  0 StructureCommandI command = new StructureCommand("indicate", labelSpec);
109  0 executeCommand(command, false);
110   
111  0 lastLabelSpec = labelSpec;
112    }
113   
 
114  0 toggle @Override
115    public SequenceRenderer getSequenceRenderer(AlignmentViewPanel avp)
116    {
117  0 return new SequenceRenderer(avp.getAlignViewport());
118    }
119   
 
120  0 toggle @Override
121    protected List<String> executeCommand(StructureCommandI command,
122    boolean getReply)
123    {
124    // jalview.bin.Console.outPrintln(command.toString()); // debug
125  0 return pymolManager.sendCommand(command, getReply);
126    }
127   
 
128  0 toggle @Override
129    protected String getModelIdForFile(String file)
130    {
131  0 return pymolObjects.containsKey(file) ? pymolObjects.get(file) : "";
132    }
133   
 
134  0 toggle @Override
135    protected ViewerType getViewerType()
136    {
137  0 return ViewerType.PYMOL;
138    }
139   
 
140  0 toggle @Override
141    public boolean isViewerRunning()
142    {
143  0 return pymolManager != null && pymolManager.isPymolLaunched();
144    }
145   
 
146  0 toggle @Override
147    public void closeViewer(boolean closePymol)
148    {
149  0 super.closeViewer(closePymol);
150  0 pymolManager = null;
151    }
152   
 
153  0 toggle public boolean launchPymol()
154    {
155  0 if (pymolManager.isPymolLaunched())
156    {
157  0 return true;
158    }
159   
160  0 Process pymol = pymolManager.launchPymol();
161  0 if (pymol != null)
162    {
163    // start listening for PyMOL selections - how??
164  0 startExternalViewerMonitor(pymol);
165    }
166    else
167    {
168  0 Console.error("Failed to launch PyMOL!");
169    }
170  0 return pymol != null;
171    }
172   
 
173  0 toggle public void openFile(PDBEntry pe)
174    {
175    // todo : check not already open, remap / rename, etc
176  0 String file = pe.getFile();
177  0 StructureCommandI cmd = getCommandGenerator().loadFile(file);
178   
179    /*
180    * a second parameter sets the pdbid as the loaded PyMOL object name
181    */
182  0 String pdbId = pe.getId();
183  0 try
184    {
185  0 String safePDBId = java.net.URLEncoder.encode(pdbId, "UTF-8");
186  0 pdbId = safePDBId.replace('%', '_');
187  0 pdbId = pdbId.replace("-", "__");
188  0 char fc = pdbId.charAt(0);
189    // put an 's' before any numerics
190  0 if (fc >= '0' && fc <= '9')
191    {
192  0 pdbId = 's' + pdbId;
193    }
194    // pdbId.replace('-', 0)
195    } catch (Exception x)
196    {
197  0 Console.error("Unxpected encoding exception for '" + pdbId + "'", x);
198    }
199  0 cmd.addParameter(pdbId);
200   
201  0 executeCommand(cmd, false);
202   
203  0 pymolObjects.put(file, pdbId);
204  0 if (!structureFiles.contains(file))
205    {
206  0 structureFiles.add(file);
207    }
208  0 if (getSsm() != null)
209    {
210  0 getSsm().addStructureViewerListener(this);
211    }
212   
213    }
214   
 
215  0 toggle @Override
216    protected String getModelId(int pdbfnum, String file)
217    {
218  0 return file;
219    }
220   
221    /**
222    * Returns the file extension to use for a saved viewer session file (.pse)
223    *
224    * @return
225    * @see https://pymolwiki.org/index.php/Save
226    */
 
227  0 toggle @Override
228    public String getSessionFileExtension()
229    {
230  0 return ".pse";
231    }
232   
 
233  0 toggle @Override
234    public String getHelpURL()
235    {
236  0 return "https://pymolwiki.org/";
237    }
238   
239    /**
240    * Constructs and sends commands to set atom properties for visible Jalview
241    * features on residues mapped to structure
242    *
243    * @param avp
244    * @return
245    */
 
246  0 toggle public int sendFeaturesToViewer(AlignmentViewPanel avp)
247    {
248    // todo pull up this and JalviewChimeraBinding variant
249  0 Map<String, Map<Object, AtomSpecModel>> featureValues = buildFeaturesMap(
250    avp);
251  0 List<StructureCommandI> commands = getCommandGenerator()
252    .setAttributes(featureValues);
253  0 executeCommands(commands, false, null);
254  0 return commands.size();
255    }
256   
257    }