3 import java.util.ArrayList;
4 import java.util.HashMap;
8 import jalview.api.AlignmentViewPanel;
9 import jalview.bin.Console;
10 import jalview.datamodel.PDBEntry;
11 import jalview.datamodel.SequenceI;
12 import jalview.ext.pymol.PymolCommands;
13 import jalview.ext.pymol.PymolManager;
14 import jalview.gui.StructureViewer.ViewerType;
15 import jalview.structure.AtomSpec;
16 import jalview.structure.AtomSpecModel;
17 import jalview.structure.StructureCommand;
18 import jalview.structure.StructureCommandI;
19 import jalview.structure.StructureSelectionManager;
20 import jalview.structures.models.AAStructureBindingModel;
22 public class PymolBindingModel extends AAStructureBindingModel
25 * format for labels shown on structures when mousing over sequence;
26 * see https://pymolwiki.org/index.php/Label#examples
27 * left not final so customisable e.g. with a Groovy script
29 private static String LABEL_FORMAT = "\"%s %s\" % (resn,resi)";
31 private PymolManager pymolManager;
34 * full paths to structure files opened in PyMOL
36 List<String> structureFiles = new ArrayList<>();
39 * lookup from file path to PyMOL object name
41 Map<String, String> pymolObjects = new HashMap<>();
43 private String lastLabelSpec;
53 public PymolBindingModel(StructureViewerBase viewer,
54 StructureSelectionManager ssm, PDBEntry[] pdbentry,
55 SequenceI[][] sequenceIs)
57 super(ssm, pdbentry, sequenceIs, null);
58 pymolManager = new PymolManager();
59 setStructureCommands(new PymolCommands());
64 public String[] getStructureFiles()
66 return structureFiles.toArray(new String[structureFiles.size()]);
70 public void highlightAtoms(List<AtomSpec> atoms)
73 * https://pymolwiki.org/index.php/indicate#examples
75 StringBuilder sb = new StringBuilder();
76 for (AtomSpec atom : atoms)
78 // todo promote to StructureCommandsI.showLabel()
79 String modelId = getModelIdForFile(atom.getPdbFile());
80 sb.append(String.format(" %s//%s/%d/*", modelId, atom.getChain(),
81 atom.getPdbResNum()));
83 String labelSpec = sb.toString();
84 if (labelSpec.equals(lastLabelSpec))
88 StructureCommandI command = new StructureCommand("indicate", labelSpec);
89 executeCommand(command, false);
91 lastLabelSpec = labelSpec;
95 public SequenceRenderer getSequenceRenderer(AlignmentViewPanel avp)
97 return new SequenceRenderer(avp.getAlignViewport());
101 protected List<String> executeCommand(StructureCommandI command,
104 // System.out.println(command.toString()); // debug
105 return pymolManager.sendCommand(command, getReply);
109 protected String getModelIdForFile(String file)
111 return pymolObjects.containsKey(file) ? pymolObjects.get(file) : "";
115 protected ViewerType getViewerType()
117 return ViewerType.PYMOL;
121 public boolean isViewerRunning()
123 return pymolManager != null && pymolManager.isPymolLaunched();
127 public void closeViewer(boolean closePymol)
129 super.closeViewer(closePymol);
133 public boolean launchPymol()
135 if (pymolManager.isPymolLaunched())
140 Process pymol = pymolManager.launchPymol();
143 // start listening for PyMOL selections - how??
144 startExternalViewerMonitor(pymol);
148 Console.error("Failed to launch PyMOL!");
150 return pymol != null;
153 public void openFile(PDBEntry pe)
155 // todo : check not already open, remap / rename, etc
156 String file = pe.getFile();
157 StructureCommandI cmd = getCommandGenerator().loadFile(file);
160 * a second parameter sets the pdbid as the loaded PyMOL object name
162 String pdbId = pe.getId();
165 String safePDBId = java.net.URLEncoder.encode(pdbId, "UTF-8");
166 pdbId = safePDBId.replace('%', '_');
167 pdbId = pdbId.replace("-", "__");
168 char fc = pdbId.charAt(0);
169 // put an 's' before any numerics
170 if (fc >= '0' && fc <= '9')
174 // pdbId.replace('-', 0)
175 } catch (Exception x)
177 Console.error("Unxpected encoding exception for '" + pdbId + "'", x);
179 cmd.addParameter(pdbId);
181 executeCommand(cmd, false);
183 pymolObjects.put(file, pdbId);
184 if (!structureFiles.contains(file))
186 structureFiles.add(file);
188 if (getSsm() != null)
190 getSsm().addStructureViewerListener(this);
196 protected String getModelId(int pdbfnum, String file)
202 * Returns the file extension to use for a saved viewer session file (.pse)
205 * @see https://pymolwiki.org/index.php/Save
208 public String getSessionFileExtension()
214 public String getHelpURL()
216 return "https://pymolwiki.org/";
220 * Constructs and sends commands to set atom properties for visible Jalview
221 * features on residues mapped to structure
226 public int sendFeaturesToViewer(AlignmentViewPanel avp)
228 // todo pull up this and JalviewChimeraBinding variant
229 Map<String, Map<Object, AtomSpecModel>> featureValues = buildFeaturesMap(
231 List<StructureCommandI> commands = getCommandGenerator()
232 .setAttributes(featureValues);
233 executeCommands(commands, false, null);
234 return commands.size();