JAL-3551 working proof of concept of Jalview driving PyMOL
[jalview.git] / src / jalview / gui / PymolBindingModel.java
diff --git a/src/jalview/gui/PymolBindingModel.java b/src/jalview/gui/PymolBindingModel.java
new file mode 100644 (file)
index 0000000..af4afb0
--- /dev/null
@@ -0,0 +1,176 @@
+package jalview.gui;
+
+import jalview.api.AlignmentViewPanel;
+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.StructureCommandI;
+import jalview.structure.StructureSelectionManager;
+import jalview.structures.models.AAStructureBindingModel;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class PymolBindingModel extends AAStructureBindingModel
+{
+  private PymolManager pymolManager;
+
+  private Thread pymolMonitor;
+
+  /*
+   * full paths to structure files opened in PyMOL
+   */
+  List<String> structureFiles = new ArrayList<>();
+
+  /*
+   * lookup from file path to PyMOL object name
+   */
+  Map<String, String> pymolObjects = new HashMap<>();
+
+  /**
+   * Constructor
+   * 
+   * @param viewer
+   * @param ssm
+   * @param pdbentry
+   * @param sequenceIs
+   */
+  public PymolBindingModel(StructureViewerBase viewer,
+          StructureSelectionManager ssm, PDBEntry[] pdbentry,
+          SequenceI[][] sequenceIs)
+  {
+    super(ssm, pdbentry, sequenceIs, null);
+    pymolManager = new PymolManager();
+    setStructureCommands(new PymolCommands());
+    setViewer(viewer);
+  }
+
+  @Override
+  public String[] getStructureFiles()
+  {
+    return structureFiles.toArray(new String[structureFiles.size()]);
+  }
+
+  @Override
+  public void highlightAtoms(List<AtomSpec> atoms)
+  {
+  }
+
+  @Override
+  public SequenceRenderer getSequenceRenderer(AlignmentViewPanel alignment)
+  {
+    // pull up?
+    return new SequenceRenderer(alignment.getAlignViewport());
+  }
+
+  @Override
+  protected List<String> executeCommand(StructureCommandI command,
+          boolean getReply)
+  {
+    System.out.println(command.toString()); // debug
+    return pymolManager.sendCommand(command, getReply);
+  }
+
+  @Override
+  protected String getModelIdForFile(String file)
+  {
+    return pymolObjects.containsKey(file) ? pymolObjects.get(file) : "";
+  }
+
+  @Override
+  protected ViewerType getViewerType()
+  {
+    return ViewerType.PYMOL;
+  }
+
+  public boolean isPymolRunning()
+  {
+    return pymolManager.isPymolLaunched();
+  }
+
+  public void closeViewer(boolean closePymol)
+  {
+    getSsm().removeStructureViewerListener(this, this.getStructureFiles());
+    if (closePymol)
+    {
+      pymolManager.exitPymol();
+    }
+    // if (this.pymolListener != null)
+    // {
+    // pymolListener.shutdown();
+    // pymolListener = null;
+    // }
+    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()
+  {
+    if (pymolManager.isPymolLaunched())
+    {
+      return true;
+    }
+
+    boolean launched = pymolManager.launchPymol();
+    if (launched)
+    {
+      // start listening for PyMOL selections - how??
+    }
+    else
+    {
+      System.err.println("Failed to launch PyMOL!");
+    }
+    return launched;
+  }
+
+  public void openFile(PDBEntry pe)
+  {
+    // todo : check not already open, remap / rename, etc
+    String file = pe.getFile();
+    StructureCommandI cmd = getCommandGenerator().loadFile(file);
+
+    /*
+     * a second parameter sets the pdbid as the loaded PyMOL object name
+     */
+    String pdbId = pe.getId();
+    cmd.addParameter(pdbId);
+
+    executeCommand(cmd, false);
+
+    pymolObjects.put(file, pdbId);
+    if (!structureFiles.contains(file))
+    {
+      structureFiles.add(file);
+    }
+    if (getSsm() != null)
+    {
+      getSsm().addStructureViewerListener(this);
+    }
+
+  }
+
+  @Override
+  protected String getModelId(int pdbfnum, String file)
+  {
+    return file;
+  }
+
+}