2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
21 package jalview.ext.jmol;
23 import jalview.api.AlignmentViewPanel;
24 import jalview.api.FeatureRenderer;
25 import jalview.api.SequenceRenderer;
26 import jalview.datamodel.AlignmentI;
27 import jalview.datamodel.HiddenColumns;
28 import jalview.datamodel.PDBEntry;
29 import jalview.datamodel.SequenceI;
30 import jalview.gui.IProgressIndicator;
31 import jalview.io.DataSourceType;
32 import jalview.io.StructureFile;
33 import jalview.schemes.ColourSchemeI;
34 import jalview.schemes.ResidueProperties;
35 import jalview.structure.AtomSpec;
36 import jalview.structure.StructureMappingcommandSet;
37 import jalview.structure.StructureSelectionManager;
38 import jalview.structures.models.AAStructureBindingModel;
39 import jalview.util.MessageManager;
41 import java.awt.Color;
42 import java.awt.Container;
43 import java.awt.event.ComponentEvent;
44 import java.awt.event.ComponentListener;
47 import java.util.ArrayList;
48 import java.util.BitSet;
49 import java.util.Hashtable;
50 import java.util.List;
52 import java.util.Vector;
54 import org.jmol.adapter.smarter.SmarterJmolAdapter;
55 import org.jmol.api.JmolAppConsoleInterface;
56 import org.jmol.api.JmolSelectionListener;
57 import org.jmol.api.JmolStatusListener;
58 import org.jmol.api.JmolViewer;
59 import org.jmol.c.CBK;
60 import org.jmol.script.T;
61 import org.jmol.viewer.Viewer;
63 public abstract class JalviewJmolBinding extends AAStructureBindingModel
64 implements JmolStatusListener, JmolSelectionListener,
67 boolean allChainsSelected = false;
70 * when true, try to search the associated datamodel for sequences that are
71 * associated with any unknown structures in the Jmol view.
73 private boolean associateNewStructs = false;
75 Vector<String> atomsPicked = new Vector<>();
77 private List<String> chainNames;
79 Hashtable<String, String> chainFile;
82 * the default or current model displayed if the model cannot be identified
83 * from the selection message
87 // protected JmolGenericPopup jmolpopup; // not used - remove?
95 StringBuffer resetLastRes = new StringBuffer();
99 public JalviewJmolBinding(StructureSelectionManager ssm,
100 PDBEntry[] pdbentry, SequenceI[][] sequenceIs,
101 DataSourceType protocol)
103 super(ssm, pdbentry, sequenceIs, protocol);
105 * viewer = JmolViewer.allocateViewer(renderPanel, new SmarterJmolAdapter(),
106 * "jalviewJmol", ap.av.applet .getDocumentBase(),
107 * ap.av.applet.getCodeBase(), "", this);
109 * jmolpopup = JmolPopup.newJmolPopup(viewer, true, "Jmol", true);
113 public JalviewJmolBinding(StructureSelectionManager ssm,
114 SequenceI[][] seqs, Viewer theViewer)
119 viewer.setJmolStatusListener(this);
120 viewer.addSelectionListener(this);
124 * construct a title string for the viewer window based on the data jalview
129 public String getViewerTitle()
131 return getViewerTitle("Jmol", true);
135 * prepare the view for a given set of models/chains. chainList contains
136 * strings of the form 'pdbfilename:Chaincode'
139 * list of chains to make visible
141 public void centerViewer(Vector<String> chainList)
143 StringBuilder cmd = new StringBuilder(128);
145 for (String lbl : chainList)
151 mlength = lbl.indexOf(":", p);
152 } while (p < mlength && mlength < (lbl.length() - 2));
153 // TODO: lookup each pdb id and recover proper model number for it.
154 cmd.append(":" + lbl.substring(mlength + 1) + " /"
155 + (1 + getModelNum(chainFile.get(lbl))) + " or ");
157 if (cmd.length() > 0)
159 cmd.setLength(cmd.length() - 4);
161 evalStateCommand("select *;restrict " + cmd + ";cartoon;center " + cmd);
164 public void closeViewer()
166 // remove listeners for all structures in viewer
167 getSsm().removeStructureViewerListener(this, this.getStructureFiles());
171 releaseUIResources();
175 public void colourByChain()
177 colourBySequence = false;
178 // TODO: colour by chain should colour each chain distinctly across all
180 // TODO: http://issues.jalview.org/browse/JAL-628
181 evalStateCommand("select *;color chain");
185 public void colourByCharge()
187 colourBySequence = false;
188 evalStateCommand("select *;color white;select ASP,GLU;color red;"
189 + "select LYS,ARG;color blue;select CYS;color yellow");
193 * superpose the structures associated with sequences in the alignment
194 * according to their corresponding positions.
196 public void superposeStructures(AlignmentI alignment)
198 superposeStructures(alignment, -1, null);
202 * superpose the structures associated with sequences in the alignment
203 * according to their corresponding positions. ded)
205 * @param refStructure
206 * - select which pdb file to use as reference (default is -1 - the
207 * first structure in the alignment)
209 public void superposeStructures(AlignmentI alignment, int refStructure)
211 superposeStructures(alignment, refStructure, null);
215 * superpose the structures associated with sequences in the alignment
216 * according to their corresponding positions. ded)
218 * @param refStructure
219 * - select which pdb file to use as reference (default is -1 - the
220 * first structure in the alignment)
224 public void superposeStructures(AlignmentI alignment, int refStructure,
225 HiddenColumns hiddenCols)
227 superposeStructures(new AlignmentI[] { alignment },
229 { refStructure }, new HiddenColumns[] { hiddenCols });
236 public String superposeStructures(AlignmentI[] _alignment,
237 int[] _refStructure, HiddenColumns[] _hiddenCols)
239 while (viewer.isScriptExecuting())
244 } catch (InterruptedException i)
250 * get the distinct structure files modelled
251 * (a file with multiple chains may map to multiple sequences)
253 String[] files = getStructureFiles();
254 if (!waitForFileLoad(files))
259 StringBuilder selectioncom = new StringBuilder(256);
260 // In principle - nSeconds specifies the speed of animation for each
261 // superposition - but is seems to behave weirdly, so we don't specify it.
262 String nSeconds = " ";
263 if (files.length > 10)
265 nSeconds = " 0.005 ";
269 nSeconds = " " + (2.0 / files.length) + " ";
270 // if (nSeconds).substring(0,5)+" ";
273 // see JAL-1345 - should really automatically turn off the animation for
274 // large numbers of structures, but Jmol doesn't seem to allow that.
276 // union of all aligned positions are collected together.
277 for (int a = 0; a < _alignment.length; a++)
279 int refStructure = _refStructure[a];
280 AlignmentI alignment = _alignment[a];
281 HiddenColumns hiddenCols = _hiddenCols[a];
282 if (a > 0 && selectioncom.length() > 0 && !selectioncom
283 .substring(selectioncom.length() - 1).equals("|"))
285 selectioncom.append("|");
287 // process this alignment
288 if (refStructure >= files.length)
291 "Invalid reference structure value " + refStructure);
296 * 'matched' bit j will be set for visible alignment columns j where
297 * all sequences have a residue with a mapping to the PDB structure
299 BitSet matched = new BitSet();
300 for (int m = 0; m < alignment.getWidth(); m++)
302 if (hiddenCols == null || hiddenCols.isVisible(m))
308 SuperposeData[] structures = new SuperposeData[files.length];
309 for (int f = 0; f < files.length; f++)
311 structures[f] = new SuperposeData(alignment.getWidth());
315 * Calculate the superposable alignment columns ('matched'), and the
316 * corresponding structure residue positions (structures.pdbResNo)
318 int candidateRefStructure = findSuperposableResidues(alignment,
319 matched, structures);
320 if (refStructure < 0)
323 * If no reference structure was specified, pick the first one that has
324 * a mapping in the alignment
326 refStructure = candidateRefStructure;
329 String[] selcom = new String[files.length];
330 int nmatched = matched.cardinality();
333 return (MessageManager.formatMessage("label.insufficient_residues",
338 * generate select statements to select regions to superimpose structures
341 // TODO extract method to construct selection statements
342 for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
344 String chainCd = ":" + structures[pdbfnum].chain;
347 StringBuilder molsel = new StringBuilder();
350 int nextColumnMatch = matched.nextSetBit(0);
351 while (nextColumnMatch != -1)
353 int pdbResNo = structures[pdbfnum].pdbResNo[nextColumnMatch];
354 if (lpos != pdbResNo - 1)
360 molsel.append(chainCd);
367 // continuous run - and lpos >-1
370 // at the beginning, so add dash
377 nextColumnMatch = matched.nextSetBit(nextColumnMatch + 1);
380 * add final selection phrase
385 molsel.append(chainCd);
388 if (molsel.length() > 1)
390 selcom[pdbfnum] = molsel.toString();
391 selectioncom.append("((");
392 selectioncom.append(selcom[pdbfnum].substring(1,
393 selcom[pdbfnum].length() - 1));
394 selectioncom.append(" )& ");
395 selectioncom.append(pdbfnum + 1);
396 selectioncom.append(".1)");
397 if (pdbfnum < files.length - 1)
399 selectioncom.append("|");
404 selcom[pdbfnum] = null;
408 StringBuilder command = new StringBuilder(256);
409 // command.append("set spinFps 10;\n");
411 for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
413 if (pdbfnum == refStructure || selcom[pdbfnum] == null
414 || selcom[refStructure] == null)
418 command.append("echo ");
419 command.append("\"Superposing (");
420 command.append(structures[pdbfnum].pdbId);
421 command.append(") against reference (");
422 command.append(structures[refStructure].pdbId);
423 command.append(")\";\ncompare " + nSeconds);
425 command.append(Integer.toString(1 + pdbfnum));
426 command.append(".1} {");
427 command.append(Integer.toString(1 + refStructure));
428 // conformation=1 excludes alternate locations for CA (JAL-1757)
430 ".1} SUBSET {(*.CA | *.P) and conformation=1} ATOMS ");
432 // for (int s = 0; s < 2; s++)
434 // command.append(selcom[(s == 0 ? pdbfnum : refStructure)]);
436 command.append(selcom[pdbfnum]);
437 command.append(selcom[refStructure]);
438 command.append(" ROTATE TRANSLATE;\n");
440 if (selectioncom.length() > 0)
442 // TODO is performing selectioncom redundant here? is done later on
443 // System.out.println("Select regions:\n" + selectioncom.toString());
444 evalStateCommand("select *; cartoons off; backbone; select ("
445 + selectioncom.toString() + "); cartoons; ");
446 // selcom.append("; ribbons; ");
447 String cmdString = command.toString();
448 // System.out.println("Superimpose command(s):\n" + cmdString);
450 evalStateCommand(cmdString);
453 if (selectioncom.length() > 0)
454 {// finally, mark all regions that were superposed.
455 if (selectioncom.substring(selectioncom.length() - 1).equals("|"))
457 selectioncom.setLength(selectioncom.length() - 1);
459 // System.out.println("Select regions:\n" + selectioncom.toString());
460 evalStateCommand("select *; cartoons off; backbone; select ("
461 + selectioncom.toString() + "); cartoons; ");
462 // evalStateCommand("select *; backbone; select "+selcom.toString()+";
463 // cartoons; center "+selcom.toString());
469 public void evalStateCommand(String command)
472 if (lastCommand == null || !lastCommand.equals(command))
474 viewer.evalStringQuiet(command + "\n");
477 lastCommand = command;
480 Thread colourby = null;
482 * Sends a set of colour commands to the structure viewer
484 * @param colourBySequenceCommands
487 protected void colourBySequence(
488 final StructureMappingcommandSet[] colourBySequenceCommands)
490 if (colourby != null)
492 colourby.interrupt();
495 colourby = new Thread(new Runnable()
500 for (StructureMappingcommandSet cpdbbyseq : colourBySequenceCommands)
502 for (String cbyseq : cpdbbyseq.commands)
504 executeWhenReady(cbyseq);
519 protected StructureMappingcommandSet[] getColourBySequenceCommands(
520 String[] files, SequenceRenderer sr, AlignmentViewPanel viewPanel)
522 return JmolCommands.getColourBySequenceCommand(getSsm(), files,
523 getSequence(), sr, viewPanel);
529 protected void executeWhenReady(String command)
531 evalStateCommand(command);
534 public void createImage(String file, String type, int quality)
536 System.out.println("JMOL CREATE IMAGE");
540 public String createImage(String fileName, String type,
541 Object textOrBytes, int quality)
543 System.out.println("JMOL CREATE IMAGE");
548 public String eval(String strEval)
550 // System.out.println(strEval);
551 // "# 'eval' is implemented only for the applet.";
555 // End StructureListener
556 // //////////////////////////
559 public float[][] functionXY(String functionName, int x, int y)
565 public float[][][] functionXYZ(String functionName, int nx, int ny,
568 // TODO Auto-generated method stub
572 public Color getColour(int atomIndex, int pdbResNum, String chain,
575 if (getModelNum(pdbfile) < 0)
579 // TODO: verify atomIndex is selecting correct model.
580 // return new Color(viewer.getAtomArgb(atomIndex)); Jmol 12.2.4
581 int colour = viewer.ms.at[atomIndex].atomPropertyInt(T.color);
582 return new Color(colour);
586 * instruct the Jalview binding to update the pdbentries vector if necessary
587 * prior to matching the jmol view's contents to the list of structure files
588 * Jalview knows about.
590 public abstract void refreshPdbEntries();
592 private int getModelNum(String modelFileName)
594 String[] mfn = getStructureFiles();
599 for (int i = 0; i < mfn.length; i++)
601 if (mfn[i].equalsIgnoreCase(modelFileName))
610 * map between index of model filename returned from getPdbFile and the first
611 * index of models from this file in the viewer. Note - this is not trimmed -
612 * use getPdbFile to get number of unique models.
614 private int _modelFileNameMap[];
617 public synchronized String[] getStructureFiles()
619 List<String> mset = new ArrayList<>();
622 return new String[0];
625 if (modelFileNames == null)
627 int modelCount = viewer.ms.mc;
628 String filePath = null;
629 for (int i = 0; i < modelCount; ++i)
631 filePath = viewer.ms.getModelFileName(i);
632 if (!mset.contains(filePath))
637 modelFileNames = mset.toArray(new String[mset.size()]);
640 return modelFileNames;
644 * map from string to applet
647 public Map<String, Object> getRegistryInfo()
649 // TODO Auto-generated method stub
653 // ///////////////////////////////
654 // JmolStatusListener
656 public void handlePopupMenu(int x, int y)
658 // jmolpopup.show(x, y);
659 // jmolpopup.jpiShow(x, y);
663 * Highlight zero, one or more atoms on the structure
666 public void highlightAtoms(List<AtomSpec> atoms)
670 if (resetLastRes.length() > 0)
672 viewer.evalStringQuiet(resetLastRes.toString());
673 resetLastRes.setLength(0);
675 for (AtomSpec atom : atoms)
677 highlightAtom(atom.getAtomIndex(), atom.getPdbResNum(),
678 atom.getChain(), atom.getPdbFile());
684 public void highlightAtom(int atomIndex, int pdbResNum, String chain,
687 if (modelFileNames == null)
692 // look up file model number for this pdbfile
694 // may need to adjust for URLencoding here - we don't worry about that yet.
695 while (mdlNum < modelFileNames.length
696 && !pdbfile.equals(modelFileNames[mdlNum]))
700 if (mdlNum == modelFileNames.length)
707 StringBuilder cmd = new StringBuilder(64);
708 cmd.append("select " + pdbResNum); // +modelNum
710 resetLastRes.append("select " + pdbResNum); // +modelNum
713 resetLastRes.append(":");
714 if (!chain.equals(" "))
717 resetLastRes.append(chain);
720 cmd.append(" /" + (mdlNum + 1));
721 resetLastRes.append("/" + (mdlNum + 1));
723 cmd.append(";wireframe 100;" + cmd.toString() + " and not hetero;");
725 resetLastRes.append(";wireframe 0;" + resetLastRes.toString()
726 + " and not hetero; spacefill 0;");
728 cmd.append("spacefill 200;select none");
730 viewer.evalStringQuiet(cmd.toString());
735 boolean debug = true;
737 private void jmolHistory(boolean enable)
739 viewer.evalStringQuiet("History " + ((debug || enable) ? "on" : "off"));
742 public void loadInline(String string)
746 // viewer.loadInline(strModel, isAppend);
748 // construct fake fullPathName and fileName so we can identify the file
750 // Then, construct pass a reader for the string to Jmol.
751 // ((org.jmol.Viewer.Viewer) viewer).loadModelFromFile(fullPathName,
752 // fileName, null, reader, false, null, null, 0);
753 viewer.openStringInline(string);
756 public void mouseOverStructure(int atomIndex, String strInfo)
759 int alocsep = strInfo.indexOf("^");
760 int mdlSep = strInfo.indexOf("/");
761 int chainSeparator = strInfo.indexOf(":"), chainSeparator1 = -1;
763 if (chainSeparator == -1)
765 chainSeparator = strInfo.indexOf(".");
766 if (mdlSep > -1 && mdlSep < chainSeparator)
768 chainSeparator1 = chainSeparator;
769 chainSeparator = mdlSep;
772 // handle insertion codes
775 pdbResNum = Integer.parseInt(
776 strInfo.substring(strInfo.indexOf("]") + 1, alocsep));
781 pdbResNum = Integer.parseInt(
782 strInfo.substring(strInfo.indexOf("]") + 1, chainSeparator));
786 if (strInfo.indexOf(":") > -1)
788 chainId = strInfo.substring(strInfo.indexOf(":") + 1,
789 strInfo.indexOf("."));
796 String pdbfilename = modelFileNames[frameNo]; // default is first or current
800 if (chainSeparator1 == -1)
802 chainSeparator1 = strInfo.indexOf(".", mdlSep);
804 String mdlId = (chainSeparator1 > -1)
805 ? strInfo.substring(mdlSep + 1, chainSeparator1)
806 : strInfo.substring(mdlSep + 1);
809 // recover PDB filename for the model hovered over.
810 int mnumber = Integer.valueOf(mdlId).intValue() - 1;
811 if (_modelFileNameMap != null)
813 int _mp = _modelFileNameMap.length - 1;
815 while (mnumber < _modelFileNameMap[_mp])
819 pdbfilename = modelFileNames[_mp];
823 if (mnumber >= 0 && mnumber < modelFileNames.length)
825 pdbfilename = modelFileNames[mnumber];
828 if (pdbfilename == null)
830 pdbfilename = new File(viewer.ms.getModelFileName(mnumber))
834 } catch (Exception e)
839 if (lastMessage == null || !lastMessage.equals(strInfo))
841 getSsm().mouseOverStructure(pdbResNum, chainId, pdbfilename);
844 lastMessage = strInfo;
847 public void notifyAtomHovered(int atomIndex, String strInfo, String data)
851 System.err.println("Ignoring additional hover info: " + data
852 + " (other info: '" + strInfo + "' pos " + atomIndex + ")");
854 mouseOverStructure(atomIndex, strInfo);
858 * { if (history != null && strStatus != null &&
859 * !strStatus.equals("Script completed")) { history.append("\n" + strStatus);
863 public void notifyAtomPicked(int atomIndex, String strInfo,
867 * this implements the toggle label behaviour copied from the original
868 * structure viewer, MCView
872 System.err.println("Ignoring additional pick data string " + strData);
874 int chainSeparator = strInfo.indexOf(":");
876 if (chainSeparator == -1)
878 chainSeparator = strInfo.indexOf(".");
881 String picked = strInfo.substring(strInfo.indexOf("]") + 1,
883 String mdlString = "";
884 if ((p = strInfo.indexOf(":")) > -1)
886 picked += strInfo.substring(p, strInfo.indexOf("."));
889 if ((p = strInfo.indexOf("/")) > -1)
891 mdlString += strInfo.substring(p, strInfo.indexOf(" #"));
893 picked = "((" + picked + ".CA" + mdlString + ")|(" + picked + ".P"
897 if (!atomsPicked.contains(picked))
899 viewer.evalStringQuiet("select " + picked + ";label %n %r:%c");
900 atomsPicked.addElement(picked);
904 viewer.evalString("select " + picked + ";label off");
905 atomsPicked.removeElement(picked);
908 // TODO: in application this happens
910 // if (scriptWindow != null)
912 // scriptWindow.sendConsoleMessage(strInfo);
913 // scriptWindow.sendConsoleMessage("\n");
919 public void notifyCallback(CBK type, Object[] data)
926 notifyFileLoaded((String) data[1], (String) data[2],
927 (String) data[3], (String) data[4],
928 ((Integer) data[5]).intValue());
932 notifyAtomPicked(((Integer) data[2]).intValue(), (String) data[1],
934 // also highlight in alignment
935 // deliberate fall through
937 notifyAtomHovered(((Integer) data[2]).intValue(), (String) data[1],
941 notifyScriptTermination((String) data[2],
942 ((Integer) data[3]).intValue());
945 sendConsoleEcho((String) data[1]);
949 (data == null) ? ((String) null) : (String) data[1]);
952 // System.err.println("Ignoring error callback.");
963 "Unhandled callback " + type + " " + data[1].toString());
966 } catch (Exception e)
968 System.err.println("Squashed Jmol callback handler error:");
974 public boolean notifyEnabled(CBK callbackPick)
976 switch (callbackPick)
992 // incremented every time a load notification is successfully handled -
993 // lightweight mechanism for other threads to detect when they can start
994 // referrring to new structures.
995 private long loadNotifiesHandled = 0;
997 public long getLoadNotifiesHandled()
999 return loadNotifiesHandled;
1002 public void notifyFileLoaded(String fullPathName, String fileName2,
1003 String modelName, String errorMsg, int modelParts)
1005 if (errorMsg != null)
1007 fileLoadingError = errorMsg;
1011 // TODO: deal sensibly with models loaded inLine:
1012 // modelName will be null, as will fullPathName.
1014 // the rest of this routine ignores the arguments, and simply interrogates
1015 // the Jmol view to find out what structures it contains, and adds them to
1016 // the structure selection manager.
1017 fileLoadingError = null;
1018 String[] oldmodels = modelFileNames;
1019 modelFileNames = null;
1020 chainNames = new ArrayList<>();
1021 chainFile = new Hashtable<>();
1022 boolean notifyLoaded = false;
1023 String[] modelfilenames = getStructureFiles();
1024 // first check if we've lost any structures
1025 if (oldmodels != null && oldmodels.length > 0)
1028 for (int i = 0; i < oldmodels.length; i++)
1030 for (int n = 0; n < modelfilenames.length; n++)
1032 if (modelfilenames[n] == oldmodels[i])
1034 oldmodels[i] = null;
1038 if (oldmodels[i] != null)
1045 String[] oldmfn = new String[oldm];
1047 for (int i = 0; i < oldmodels.length; i++)
1049 if (oldmodels[i] != null)
1051 oldmfn[oldm++] = oldmodels[i];
1054 // deregister the Jmol instance for these structures - we'll add
1055 // ourselves again at the end for the current structure set.
1056 getSsm().removeStructureViewerListener(this, oldmfn);
1059 refreshPdbEntries();
1060 for (int modelnum = 0; modelnum < modelfilenames.length; modelnum++)
1062 String fileName = modelfilenames[modelnum];
1063 boolean foundEntry = false;
1064 StructureFile pdb = null;
1065 String pdbfile = null;
1066 // model was probably loaded inline - so check the pdb file hashcode
1069 // calculate essential attributes for the pdb data imported inline.
1070 // prolly need to resolve modelnumber properly - for now just use our
1072 pdbfile = viewer.getData(
1073 "" + (1 + _modelFileNameMap[modelnum]) + ".0", "PDB");
1075 // search pdbentries and sequences to find correct pdbentry for this
1077 for (int pe = 0; pe < getPdbCount(); pe++)
1079 boolean matches = false;
1080 addSequence(pe, getSequence()[pe]);
1081 if (fileName == null)
1084 // see JAL-623 - need method of matching pasted data up
1086 pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
1087 pdbfile, DataSourceType.PASTE,
1088 getIProgressIndicator());
1089 getPdbEntry(modelnum).setFile("INLINE" + pdb.getId());
1096 File fl = new File(getPdbEntry(pe).getFile());
1097 matches = fl.equals(new File(fileName));
1101 // TODO: Jmol can in principle retrieve from CLASSLOADER but
1104 // to be tested. See mantis bug
1105 // https://mantis.lifesci.dundee.ac.uk/view.php?id=36605
1106 DataSourceType protocol = DataSourceType.URL;
1111 protocol = DataSourceType.FILE;
1113 } catch (Exception e)
1118 // Explicitly map to the filename used by Jmol ;
1119 pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
1120 fileName, protocol, getIProgressIndicator());
1121 // pdbentry[pe].getFile(), protocol);
1127 // add an entry for every chain in the model
1128 for (int i = 0; i < pdb.getChains().size(); i++)
1130 String chid = new String(
1131 pdb.getId() + ":" + pdb.getChains().elementAt(i).id);
1132 chainFile.put(chid, fileName);
1133 chainNames.add(chid);
1135 notifyLoaded = true;
1139 if (!foundEntry && associateNewStructs)
1141 // this is a foreign pdb file that jalview doesn't know about - add
1142 // it to the dataset and try to find a home - either on a matching
1143 // sequence or as a new sequence.
1144 String pdbcontent = viewer.getData("/" + (modelnum + 1) + ".1",
1146 // parse pdb file into a chain, etc.
1147 // locate best match for pdb in associated views and add mapping to
1149 // if properly registered then
1150 notifyLoaded = true;
1155 // so finally, update the jmol bits and pieces
1156 // if (jmolpopup != null)
1158 // // potential for deadlock here:
1159 // // jmolpopup.updateComputedMenus();
1161 if (!isLoadingFromArchive())
1163 viewer.evalStringQuiet(
1164 "model *; select backbone;restrict;cartoon;wireframe off;spacefill off");
1166 // register ourselves as a listener and notify the gui that it needs to
1168 getSsm().addStructureViewerListener(this);
1171 FeatureRenderer fr = getFeatureRenderer(null);
1177 loadNotifiesHandled++;
1179 setLoadingFromArchive(false);
1183 public List<String> getChainNames()
1188 protected IProgressIndicator getIProgressIndicator()
1193 public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)
1195 notifyAtomPicked(iatom, strMeasure, null);
1198 public abstract void notifyScriptTermination(String strStatus,
1202 * display a message echoed from the jmol viewer
1206 public abstract void sendConsoleEcho(String strEcho); /*
1207 * { showConsole(true);
1209 * history.append("\n" +
1213 // /End JmolStatusListener
1214 // /////////////////////////////
1218 * status message - usually the response received after a script
1221 public abstract void sendConsoleMessage(String strStatus);
1224 public void setCallbackFunction(String callbackType,
1225 String callbackFunction)
1227 System.err.println("Ignoring set-callback request to associate "
1228 + callbackType + " with function " + callbackFunction);
1233 public void setJalviewColourScheme(ColourSchemeI cs)
1235 colourBySequence = false;
1243 StringBuilder command = new StringBuilder(128);
1244 command.append("select *;color white;");
1245 List<String> residueSet = ResidueProperties.getResidues(isNucleotide(),
1247 for (String resName : residueSet)
1249 char res = resName.length() == 3
1250 ? ResidueProperties.getSingleCharacterCode(resName)
1251 : resName.charAt(0);
1252 Color col = cs.findColour(res, 0, null, null, 0f);
1253 command.append("select " + resName + ";color[" + col.getRed() + ","
1254 + col.getGreen() + "," + col.getBlue() + "];");
1257 evalStateCommand(command.toString());
1261 public void showHelp()
1263 showUrl("http://jmol.sourceforge.net/docs/JmolUserGuide/", "jmolHelp");
1267 * open the URL somehow
1271 public abstract void showUrl(String url, String target);
1274 * called when the binding thinks the UI needs to be refreshed after a Jmol
1275 * state change. this could be because structures were loaded, or because an
1276 * error has occured.
1278 public abstract void refreshGUI();
1281 * called to show or hide the associated console window container.
1285 public abstract void showConsole(boolean show);
1288 * @param renderPanel
1290 * - when true will initialise jmol's file IO system (should be false
1291 * in applet context)
1293 * @param documentBase
1295 * @param commandOptions
1297 public void allocateViewer(Container renderPanel, boolean jmolfileio,
1298 String htmlName, URL documentBase, URL codeBase,
1299 String commandOptions)
1301 allocateViewer(renderPanel, jmolfileio, htmlName, documentBase,
1302 codeBase, commandOptions, null, null);
1307 * @param renderPanel
1309 * - when true will initialise jmol's file IO system (should be false
1310 * in applet context)
1312 * @param documentBase
1314 * @param commandOptions
1315 * @param consolePanel
1316 * - panel to contain Jmol console
1317 * @param buttonsToShow
1318 * - buttons to show on the console, in ordr
1320 public void allocateViewer(Container renderPanel, boolean jmolfileio,
1321 String htmlName, URL documentBase, URL codeBase,
1322 String commandOptions, final Container consolePanel,
1323 String buttonsToShow)
1325 if (commandOptions == null)
1327 commandOptions = "";
1329 viewer = (Viewer) JmolViewer.allocateViewer(renderPanel,
1330 (jmolfileio ? new SmarterJmolAdapter() : null),
1331 htmlName + ((Object) this).toString(), documentBase, codeBase,
1332 commandOptions, this);
1334 viewer.setJmolStatusListener(this); // extends JmolCallbackListener
1336 console = createJmolConsole(consolePanel, buttonsToShow);
1337 if (consolePanel != null)
1339 consolePanel.addComponentListener(this);
1345 protected abstract JmolAppConsoleInterface createJmolConsole(
1346 Container consolePanel, String buttonsToShow);
1348 protected org.jmol.api.JmolAppConsoleInterface console = null;
1351 public void setBackgroundColour(java.awt.Color col)
1354 viewer.evalStringQuiet("background [" + col.getRed() + ","
1355 + col.getGreen() + "," + col.getBlue() + "];");
1360 public int[] resizeInnerPanel(String data)
1362 // Jalview doesn't honour resize panel requests
1369 protected void closeConsole()
1371 if (console != null)
1375 console.setVisible(false);
1378 } catch (Exception x)
1387 * ComponentListener method
1390 public void componentMoved(ComponentEvent e)
1395 * ComponentListener method
1398 public void componentResized(ComponentEvent e)
1403 * ComponentListener method
1406 public void componentShown(ComponentEvent e)
1412 * ComponentListener method
1415 public void componentHidden(ComponentEvent e)