Clover icon

Coverage Report

  1. Project Clover database Thu Aug 13 2020 12:04:21 BST
  2. Package jalview.ext.pymol

File PymolCommands.java

 

Coverage histogram

../../../img/srcFileCovDistChart9.png
12% of files have more coverage

Code metrics

8
72
19
1
335
206
23
0.32
3.79
19
1.21

Classes

Class Line # Actions
PymolCommands 24 72 23
0.888888988.9%
 

Contributing tests

This file is covered by 17 tests. .

Source view

1    package jalview.ext.pymol;
2   
3    import java.awt.Color;
4    import java.util.ArrayList;
5    import java.util.Arrays;
6    import java.util.List;
7    import java.util.Map;
8   
9    import jalview.structure.AtomSpecModel;
10    import jalview.structure.StructureCommand;
11    import jalview.structure.StructureCommandI;
12    import jalview.structure.StructureCommandsBase;
13   
14    /**
15    * A class that generates commands to send to PyMol over its XML-RPC interface.
16    * <p>
17    * Note that because the xml-rpc interface can only accept one command at a
18    * time, we can't concatenate commands, and must instead form and send them
19    * individually.
20    *
21    * @see https://pymolwiki.org/index.php/Category:Commands
22    * @see https://pymolwiki.org/index.php/RPC
23    */
 
24    public class PymolCommands extends StructureCommandsBase
25    {
26    // https://pymol.org/dokuwiki/doku.php?id=command:zoom
27    // not currently documented on
28    // https://pymolwiki.org/index.php/Category:Commands
29    private static final StructureCommand FOCUS_VIEW = new StructureCommand(
30    "zoom");
31   
32    // https://pymolwiki.org/index.php/Quit
33    private static final StructureCommand CLOSE_PYMOL = new StructureCommand(
34    "quit");
35   
36    // not currently documented on
37    // https://pymolwiki.org/index.php/Category:Commands
38    private static final StructureCommand COLOUR_BY_CHAIN = new StructureCommand(
39    "spectrum", "chain");
40   
41    private static final List<StructureCommandI> COLOR_BY_CHARGE = Arrays
42    .asList(new StructureCommand("color", "white", "*"),
43    new StructureCommand("color", "red", "resn ASP resn GLU"),
44    new StructureCommand("color", "blue",
45    "resn LYS resn ARG"),
46    new StructureCommand("color", "yellow", "resn CYS"));
47   
48    private static final List<StructureCommandI> SHOW_BACKBONE = Arrays
49    .asList(new StructureCommand("hide", "everything"),
50    new StructureCommand("show", "ribbon"));
51   
 
52  1 toggle @Override
53    public StructureCommandI colourByChain()
54    {
55  1 return COLOUR_BY_CHAIN;
56    }
57   
 
58  1 toggle @Override
59    public List<StructureCommandI> colourByCharge()
60    {
61  1 return COLOR_BY_CHARGE;
62    }
63   
 
64  1 toggle @Override
65    public StructureCommandI setBackgroundColour(Color col)
66    {
67    // https://pymolwiki.org/index.php/Bg_Color
68  1 return new StructureCommand("bg_color", getColourString(col));
69    }
70   
71    /**
72    * Returns a colour formatted suitable for use in viewer command syntax. For
73    * example, red is {@code "0xff0000"}.
74    *
75    * @param c
76    * @return
77    */
 
78  5 toggle protected String getColourString(Color c)
79    {
80  5 return String.format("0x%02x%02x%02x", c.getRed(), c.getGreen(),
81    c.getBlue());
82    }
83   
 
84  0 toggle @Override
85    public StructureCommandI focusView()
86    {
87  0 return FOCUS_VIEW;
88    }
89   
 
90  0 toggle @Override
91    public List<StructureCommandI> showChains(List<String> toShow)
92    {
93    // https://pymolwiki.org/index.php/Show
94  0 List<StructureCommandI> commands = new ArrayList<>();
95  0 commands.add(new StructureCommand("hide", "everything"));
96  0 commands.add(new StructureCommand("show", "lines"));
97  0 StringBuilder chains = new StringBuilder();
98  0 for (String chain : toShow)
99    {
100  0 chains.append(" chain ").append(chain);
101    }
102  0 commands.add(
103    new StructureCommand("show", "cartoon", chains.toString()));
104  0 return commands;
105    }
106   
 
107  1 toggle @Override
108    public List<StructureCommandI> superposeStructures(AtomSpecModel refAtoms,
109    AtomSpecModel atomSpec)
110    {
111    // https://pymolwiki.org/index.php/Super
112  1 List<StructureCommandI> commands = new ArrayList<>();
113  1 String refAtomsAlphaOnly = getAtomSpec(refAtoms, true);
114  1 String atomSpec2AlphaOnly = getAtomSpec(atomSpec, true);
115  1 commands.add(new StructureCommand("super", refAtomsAlphaOnly,
116    atomSpec2AlphaOnly));
117   
118    /*
119    * and show superposed residues as cartoon
120    */
121  1 String refAtomsAll = getAtomSpec(refAtoms, false);
122  1 String atomSpec2All = getAtomSpec(atomSpec, false);
123  1 commands.add(new StructureCommand("show", "cartoon",
124    refAtomsAll + " " + atomSpec2All));
125   
126  1 return commands;
127    }
128   
 
129  1 toggle @Override
130    public StructureCommandI openCommandFile(String path)
131    {
132    // https://pymolwiki.org/index.php/Run
133  1 return new StructureCommand("run", path); // should be .pml
134    }
135   
 
136  1 toggle @Override
137    public StructureCommandI saveSession(String filepath)
138    {
139    // https://pymolwiki.org/index.php/Save#EXAMPLES
140  1 return new StructureCommand("save", filepath); // should be .pse
141    }
142   
143    /**
144    * Returns a selection string in PyMOL 'selection macro' format:
145    *
146    * <pre>
147    * modelId// chain/residues/
148    * </pre>
149    *
150    * If more than one chain, makes a selection expression for each, and they are
151    * separated by spaces.
152    *
153    * @see https://pymolwiki.org/index.php/Selection_Macros
154    */
 
155  36 toggle @Override
156    public String getAtomSpec(AtomSpecModel model, boolean alphaOnly)
157    {
158  36 StringBuilder sb = new StringBuilder(64);
159  36 boolean first = true;
160  36 for (String modelId : model.getModels())
161    {
162  52 for (String chain : model.getChains(modelId))
163    {
164  86 if (!first)
165    {
166  52 sb.append(" ");
167    }
168  86 first = false;
169  86 List<int[]> rangeList = model.getRanges(modelId, chain);
170  86 chain = chain.trim();
171  86 sb.append(modelId).append("//").append(chain).append("/");
172  86 boolean firstRange = true;
173  86 for (int[] range : rangeList)
174    {
175  111 if (!firstRange)
176    {
177  25 sb.append("+");
178    }
179  111 firstRange = false;
180  111 sb.append(String.valueOf(range[0]));
181  111 if (range[0] != range[1])
182    {
183  86 sb.append("-").append(String.valueOf(range[1]));
184    }
185    }
186  86 sb.append("/");
187  86 if (alphaOnly)
188    {
189  34 sb.append("CA");
190    }
191    }
192    }
193  36 return sb.toString();
194    }
195   
 
196  1 toggle @Override
197    public List<StructureCommandI> showBackbone()
198    {
199  1 return SHOW_BACKBONE;
200    }
201   
 
202  4 toggle @Override
203    protected StructureCommandI colourResidues(String atomSpec, Color colour)
204    {
205    // https://pymolwiki.org/index.php/Color
206  4 return new StructureCommand("color", getColourString(colour), atomSpec);
207    }
208   
 
209  1 toggle @Override
210    protected String getResidueSpec(String residue)
211    {
212    // https://pymolwiki.org/index.php/Selection_Algebra
213  1 return "resn " + residue;
214    }
215   
 
216  1 toggle @Override
217    public StructureCommandI loadFile(String file)
218    {
219  1 return new StructureCommand("load", file);
220    }
221   
222    /**
223    * Overrides the default implementation (which generates concatenated
224    * commands) to generate one per colour (because the XML-RPC interface to
225    * PyMOL only accepts one command at a time)
226    *
227    * @param colourMap
228    * @return
229    */
 
230  1 toggle @Override
231    public List<StructureCommandI> colourBySequence(
232    Map<Object, AtomSpecModel> colourMap)
233    {
234  1 List<StructureCommandI> commands = new ArrayList<>();
235  1 for (Object key : colourMap.keySet())
236    {
237  3 Color colour = (Color) key;
238  3 final AtomSpecModel colourData = colourMap.get(colour);
239  3 commands.add(getColourCommand(colourData, colour));
240    }
241   
242  1 return commands;
243    }
244   
245    /**
246    * Returns a viewer command to set the given atom property value on atoms
247    * specified by the AtomSpecModel, for example
248    *
249    * <pre>
250    * iterate 4zho//B/12-34,48-55/CA,jv_chain='primary'
251    * </pre>
252    *
253    * @param attributeName
254    * @param attributeValue
255    * @param atomSpecModel
256    * @return
257    */
 
258  7 toggle protected StructureCommandI setAttribute(String attributeName,
259    String attributeValue, AtomSpecModel atomSpecModel)
260    {
261  7 StringBuilder sb = new StringBuilder(128);
262  7 sb.append("p.").append(attributeName).append("='")
263    .append(attributeValue).append("'");
264  7 String atomSpec = getAtomSpec(atomSpecModel, false);
265  7 return new StructureCommand("iterate", atomSpec, sb.toString());
266    }
267   
268    /**
269    * Traverse the map of features/values/models/chains/positions to construct a
270    * list of 'set property' commands (one per distinct feature type and value).
271    * The values are stored in the 'p' dictionary of user-defined properties of
272    * each atom.
273    * <p>
274    * The format of each command is
275    *
276    * <pre>
277    * <blockquote> iterate atomspec, p.featureName='value'
278    * e.g. iterate 4zho//A/23,28-29/CA, p.jv_Metal='Fe'
279    * </blockquote>
280    * </pre>
281    *
282    * @param featureMap
283    * @return
284    */
 
285  5 toggle @Override
286    public List<StructureCommandI> setAttributes(
287    Map<String, Map<Object, AtomSpecModel>> featureMap)
288    {
289  5 List<StructureCommandI> commands = new ArrayList<>();
290  5 for (String featureType : featureMap.keySet())
291    {
292  5 String attributeName = makeAttributeName(featureType);
293   
294    /*
295    * todo: clear down existing attributes for this feature?
296    */
297    // commands.add(new StructureCommand("iterate", "all",
298    // "p."+attributeName+"='None'"); //?
299   
300  5 Map<Object, AtomSpecModel> values = featureMap.get(featureType);
301  5 for (Object value : values.keySet())
302    {
303    /*
304    * for each distinct value recorded for this feature type,
305    * add a command to set the attribute on the mapped residues
306    * Put values in single quotes, encoding any embedded single quotes
307    */
308  6 AtomSpecModel atomSpecModel = values.get(value);
309  6 String featureValue = value.toString();
310  6 featureValue = featureValue.replaceAll("\\'", "&#39;");
311  6 StructureCommandI cmd = setAttribute(attributeName, featureValue,
312    atomSpecModel);
313  6 commands.add(cmd);
314    }
315    }
316   
317  5 return commands;
318    }
319   
 
320  1 toggle @Override
321    public StructureCommandI openSession(String filepath)
322    {
323    // https://pymolwiki.org/index.php/Load
324    // this version of the command has no dependency on file extension
325  1 return new StructureCommand("load", filepath, "", "0", "pse");
326    }
327   
 
328  1 toggle @Override
329    public StructureCommandI closeViewer()
330    {
331    // https://pymolwiki.org/index.php/Quit
332  1 return CLOSE_PYMOL;
333    }
334   
335    }