/** * */ package jalview.gui; import java.util.BitSet; import java.util.Vector; import jalview.bin.Cache; import jalview.datamodel.PDBEntry; import jalview.datamodel.SequenceI; import org.jmol.popup.JmolPopup; class AppJmolBinding extends jalview.ext.jmol.JalviewJmolBinding { /** * */ private AppJmol appJmolWindow; public AppJmolBinding(AppJmol appJmol, PDBEntry[] pdbentry, SequenceI[][] sequenceIs, String[][] chains, String protocol) { super(pdbentry, sequenceIs, chains, protocol); appJmolWindow = appJmol; } FeatureRenderer fr = null; @Override public jalview.api.FeatureRenderer getFeatureRenderer() { if (appJmolWindow.ap.av.showSequenceFeatures) { if (fr == null) { fr = new FeatureRenderer(appJmolWindow.ap); } fr.transferSettings(appJmolWindow.ap.seqPanel.seqCanvas .getFeatureRenderer()); } return fr; } @Override public jalview.api.SequenceRenderer getSequenceRenderer() { return new SequenceRenderer(appJmolWindow.ap.av); } public void sendConsoleEcho(String strEcho) { if (appJmolWindow.scriptWindow != null) { appJmolWindow.scriptWindow.sendConsoleEcho(strEcho); } } public void sendConsoleMessage(String strStatus) { if (appJmolWindow.scriptWindow != null && strStatus != null) // && !strStatus.equals("Script completed")) // should we squash the script completed string ? { appJmolWindow.scriptWindow.sendConsoleMessage(strStatus); } } @Override public void showUrl(String url, String target) { try { jalview.util.BrowserLauncher.openURL(url); } catch (Exception e) { Cache.log.error("Failed to launch Jmol-associated url " + url, e); // TODO: 2.6 : warn user if browser was not configured. } } @Override public void refreshGUI() { // appJmolWindow.repaint(); appJmolWindow.updateTitleAndMenus(); } public void updateColours(Object source) { AlignmentPanel ap = (AlignmentPanel) source; if (appJmolWindow.ap.alignFrame.getCurrentView() != ap.av) return; colourBySequence(ap.av.getShowSequenceFeatures(), ap.av.alignment); } public void notifyScriptTermination(String strStatus, int msWalltime) { if (appJmolWindow.scriptWindow != null) appJmolWindow.scriptWindow.notifyScriptTermination(strStatus, msWalltime); } public void showUrl(String url) { showUrl(url, "jmol"); } public void newJmolPopup(boolean translateLocale, String menuName, boolean asPopup) { jmolpopup = JmolPopup.newJmolPopup(viewer, translateLocale, menuName, asPopup); } /** * add structures and any known sequence associations * * @returns the pdb entries added to the current set. */ private PDBEntry[] addSequenceAndChain(PDBEntry[] pdbe, SequenceI[][] seq, String[][] chns) { int pe = -1; Vector v = new Vector(); Vector rtn = new Vector(); for (int i = 0; i < pdbentry.length; i++) { v.addElement(pdbentry[i]); } for (int i = 0; i < pdbe.length; i++) { int r = v.indexOf(pdbe[i]); if (r == -1 || r >= pdbentry.length) { rtn.addElement(new int[] { v.size(), i }); v.addElement(pdbe[i]); } else { // just make sure the sequence/chain entries are all up to date addSequenceAndChain(r, seq[i], chns[i]); } } pdbe = new PDBEntry[v.size()]; v.copyInto(pdbe); pdbentry = pdbe; if (rtn.size() > 0) { // expand the tied seuqence[] and string[] arrays SequenceI[][] sqs = new SequenceI[pdbentry.length][]; String[][] sch = new String[pdbentry.length][]; System.arraycopy(sequence, 0, sqs, 0, sequence.length); System.arraycopy(chains, 0, sch, 0, this.chains.length); sequence = sqs; chains = sch; pdbe = new PDBEntry[rtn.size()]; for (int r = 0; r < pdbe.length; r++) { int[] stri = ((int[]) rtn.elementAt(r)); // record the pdb file as a new addition pdbe[r] = pdbentry[stri[0]]; // and add the new sequence/chain entries addSequenceAndChain(stri[0], seq[stri[1]], chns[stri[1]]); } } else { pdbe = null; } return pdbe; } void addSequence(int pe, SequenceI[] seq) { // add sequences to the pe'th pdbentry's seuqence set. addSequenceAndChain(pe, seq, null); } private void addSequenceAndChain(int pe, SequenceI[] seq, String[] tchain) { if (pe < 0 || pe >= pdbentry.length) { throw new Error( "Implementation error - no corresponding pdbentry (for index " + pe + ") to add sequences mappings to"); } final String nullChain = "TheNullChain"; Vector s = new Vector(); Vector c = new Vector(); if (chains == null) { chains = new String[pdbentry.length][]; } if (sequence[pe] != null) { for (int i = 0; i < sequence[pe].length; i++) { s.addElement(sequence[pe][i]); if (chains[pe] != null) { if (i < chains[pe].length) { c.addElement(chains[pe][i]); } else { c.addElement(nullChain); } } else { if (tchain != null && tchain.length > 0) { c.addElement(nullChain); } } } } for (int i = 0; i < seq.length; i++) { if (!s.contains(seq[i])) { s.addElement(seq[i]); if (tchain != null && i < tchain.length) { c.addElement(tchain[i] == null ? nullChain : tchain[i]); } } } SequenceI[] tmp = new SequenceI[s.size()]; s.copyInto(tmp); sequence[pe] = tmp; if (c.size() > 0) { String[] tch = new String[c.size()]; c.copyInto(tch); for (int i = 0; i < tch.length; i++) { if (tch[i] == nullChain) { tch[i] = null; } } chains[pe] = tch; } else { chains[pe] = null; } } public void selectionChanged(BitSet arg0) { // TODO Auto-generated method stub } public void refreshPdbEntries() { // TODO Auto-generated method stub } /** * add another pdb entry into the view, with associated sequences and chains * * @param pdbentry * @param seq * @param chains * @param align * if true, new structure(s) will be align using associated alignment */ public synchronized void addStructure(PDBEntry pdbentry, SequenceI[] seq, String[] chains, final boolean align) { PDBEntry[] pe = addSequenceAndChain(new PDBEntry[] { pdbentry }, new SequenceI[][] { seq }, new String[][] { chains }); if (pe != null) { StringBuffer cmd = new StringBuffer(); cmd.append("load APPEND"); for (int p = 0; p < pe.length; p++) { cmd.append(" \""); cmd.append(pe[p].getFile()); cmd.append("\""); } cmd.append("\n"); final String command = cmd.toString(); cmd = null; new Thread(new Runnable() { public void run() { evalStateCommand(command); if (align) { // may need to wait around until script has finished while (viewer.isScriptExecuting()) { try { Thread.sleep(20); } catch (Exception e) { } ; } superposeStructures(appJmolWindow.ap.av.getAlignment(), -1, null); } } }).start(); } } /** * add the given sequences to the mapping scope for the given pdb file handle * * @param pdbFile * - pdbFile identifier * @param seq * - set of sequences it can be mapped to */ public void addSequenceForStructFile(String pdbFile, SequenceI[] seq) { for (int pe = 0; pe < pdbentry.length; pe++) { if (pdbentry[pe].getFile().equals(pdbFile)) { addSequence(pe, seq); } } } }