+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.gui;
import java.util.ArrayList;
import java.util.Map;
import jalview.api.AlignmentViewPanel;
+import jalview.bin.Console;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
import jalview.ext.pymol.PymolCommands;
import jalview.ext.pymol.PymolManager;
import jalview.gui.StructureViewer.ViewerType;
import jalview.structure.AtomSpec;
+import jalview.structure.AtomSpecModel;
+import jalview.structure.StructureCommand;
import jalview.structure.StructureCommandI;
import jalview.structure.StructureSelectionManager;
import jalview.structures.models.AAStructureBindingModel;
public class PymolBindingModel extends AAStructureBindingModel
{
- private PymolManager pymolManager;
+ /*
+ * format for labels shown on structures when mousing over sequence;
+ * see https://pymolwiki.org/index.php/Label#examples
+ * left not final so customisable e.g. with a Groovy script
+ */
+ private static String LABEL_FORMAT = "\"%s %s\" % (resn,resi)";
- private Thread pymolMonitor;
+ private PymolManager pymolManager;
/*
* full paths to structure files opened in PyMOL
*/
Map<String, String> pymolObjects = new HashMap<>();
+ private String lastLabelSpec;
+
/**
* Constructor
*
@Override
public void highlightAtoms(List<AtomSpec> atoms)
{
+ /*
+ * https://pymolwiki.org/index.php/indicate#examples
+ */
+ StringBuilder sb = new StringBuilder();
+ for (AtomSpec atom : atoms)
+ {
+ // todo promote to StructureCommandsI.showLabel()
+ String modelId = getModelIdForFile(atom.getPdbFile());
+ sb.append(String.format(" %s//%s/%d/*", modelId, atom.getChain(),
+ atom.getPdbResNum()));
+ }
+ String labelSpec = sb.toString();
+ if (labelSpec.equals(lastLabelSpec))
+ {
+ return;
+ }
+ StructureCommandI command = new StructureCommand("indicate", labelSpec);
+ executeCommand(command, false);
+
+ lastLabelSpec = labelSpec;
}
@Override
- public SequenceRenderer getSequenceRenderer(AlignmentViewPanel alignment)
+ public SequenceRenderer getSequenceRenderer(AlignmentViewPanel avp)
{
- // pull up?
- return new SequenceRenderer(alignment.getAlignViewport());
+ return new SequenceRenderer(avp.getAlignViewport());
}
@Override
return ViewerType.PYMOL;
}
- public boolean isPymolRunning()
+ @Override
+ public boolean isViewerRunning()
{
- return pymolManager.isPymolLaunched();
+ return pymolManager != null && pymolManager.isPymolLaunched();
}
+ @Override
public void closeViewer(boolean closePymol)
{
- getSsm().removeStructureViewerListener(this, this.getStructureFiles());
- if (closePymol)
- {
- pymolManager.exitPymol();
- }
+ super.closeViewer(closePymol);
pymolManager = null;
-
- if (pymolMonitor != null)
- {
- pymolMonitor.interrupt();
- }
- releaseUIResources();
- }
-
- public boolean openSession(String pymolSessionFile)
- {
- StructureCommandI cmd = getCommandGenerator()
- .loadFile(pymolSessionFile);
- executeCommand(cmd, false);
- return true;
}
public boolean launchPymol()
return true;
}
- boolean launched = pymolManager.launchPymol();
- if (launched)
+ Process pymol = pymolManager.launchPymol();
+ if (pymol != null)
{
// start listening for PyMOL selections - how??
+ startExternalViewerMonitor(pymol);
}
else
{
- System.err.println("Failed to launch PyMOL!");
+ Console.error("Failed to launch PyMOL!");
}
- return launched;
+ return pymol != null;
}
public void openFile(PDBEntry pe)
* a second parameter sets the pdbid as the loaded PyMOL object name
*/
String pdbId = pe.getId();
+ try
+ {
+ String safePDBId = java.net.URLEncoder.encode(pdbId, "UTF-8");
+ pdbId = safePDBId.replace('%', '_');
+ pdbId = pdbId.replace("-", "__");
+ char fc = pdbId.charAt(0);
+ // put an 's' before any numerics
+ if (fc >= '0' && fc <= '9')
+ {
+ pdbId = 's' + pdbId;
+ }
+ // pdbId.replace('-', 0)
+ } catch (Exception x)
+ {
+ Console.error("Unxpected encoding exception for '" + pdbId + "'", x);
+ }
cmd.addParameter(pdbId);
executeCommand(cmd, false);
return ".pse";
}
+ @Override
+ public String getHelpURL()
+ {
+ return "https://pymolwiki.org/";
+ }
+
+ /**
+ * Constructs and sends commands to set atom properties for visible Jalview
+ * features on residues mapped to structure
+ *
+ * @param avp
+ * @return
+ */
+ public int sendFeaturesToViewer(AlignmentViewPanel avp)
+ {
+ // todo pull up this and JalviewChimeraBinding variant
+ Map<String, Map<Object, AtomSpecModel>> featureValues = buildFeaturesMap(
+ avp);
+ List<StructureCommandI> commands = getCommandGenerator()
+ .setAttributes(featureValues);
+ executeCommands(commands, false, null);
+ return commands.size();
+ }
+
}