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.AlignViewportI;
24 import jalview.api.AlignmentViewPanel;
25 import jalview.api.FeatureRenderer;
26 import jalview.datamodel.AlignmentI;
27 import jalview.datamodel.HiddenColumns;
28 import jalview.datamodel.PDBEntry;
29 import jalview.datamodel.SequenceI;
30 import jalview.ext.rbvi.chimera.AtomSpecModel;
31 import jalview.gui.IProgressIndicator;
32 import jalview.io.DataSourceType;
33 import jalview.io.StructureFile;
34 import jalview.schemes.ColourSchemeI;
35 import jalview.schemes.ResidueProperties;
36 import jalview.structure.AtomSpec;
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.StringTokenizer;
53 import java.util.Vector;
55 import org.jmol.adapter.smarter.SmarterJmolAdapter;
56 import org.jmol.api.JmolAppConsoleInterface;
57 import org.jmol.api.JmolSelectionListener;
58 import org.jmol.api.JmolStatusListener;
59 import org.jmol.api.JmolViewer;
60 import org.jmol.c.CBK;
61 import org.jmol.script.T;
62 import org.jmol.viewer.Viewer;
64 public abstract class JalviewJmolBinding extends AAStructureBindingModel
65 implements JmolStatusListener, JmolSelectionListener,
68 private String lastMessage;
70 boolean allChainsSelected = false;
73 * when true, try to search the associated datamodel for sequences that are
74 * associated with any unknown structures in the Jmol view.
76 private boolean associateNewStructs = false;
78 Vector<String> atomsPicked = new Vector<>();
80 private List<String> chainNames;
82 Hashtable<String, String> chainFile;
85 * the default or current model displayed if the model cannot be identified
86 * from the selection message
90 // protected JmolGenericPopup jmolpopup; // not used - remove?
96 StringBuffer resetLastRes = new StringBuffer();
100 public JalviewJmolBinding(StructureSelectionManager ssm,
101 PDBEntry[] pdbentry, SequenceI[][] sequenceIs,
102 DataSourceType protocol)
104 super(ssm, pdbentry, sequenceIs, protocol);
106 * viewer = JmolViewer.allocateViewer(renderPanel, new SmarterJmolAdapter(),
107 * "jalviewJmol", ap.av.applet .getDocumentBase(),
108 * ap.av.applet.getCodeBase(), "", this);
110 * jmolpopup = JmolPopup.newJmolPopup(viewer, true, "Jmol", true);
114 public JalviewJmolBinding(StructureSelectionManager ssm,
115 SequenceI[][] seqs, Viewer theViewer)
120 viewer.setJmolStatusListener(this);
121 viewer.addSelectionListener(this);
125 * construct a title string for the viewer window based on the data jalview
130 public String getViewerTitle()
132 return getViewerTitle("Jmol", true);
136 * prepare the view for a given set of models/chains. chainList contains strings
137 * of the form 'pdbfilename:Chaincode'
139 * @deprecated now only used by applet code
142 public void centerViewer()
144 StringBuilder cmd = new StringBuilder(128);
146 for (String lbl : chainsToShow)
152 mlength = lbl.indexOf(":", p);
153 } while (p < mlength && mlength < (lbl.length() - 2));
154 // TODO: lookup each pdb id and recover proper model number for it.
155 cmd.append(":" + lbl.substring(mlength + 1) + " /"
156 + (1 + getModelNum(chainFile.get(lbl))) + " or ");
158 if (cmd.length() > 0)
160 cmd.setLength(cmd.length() - 4);
162 String command = "select *;restrict " + cmd + ";cartoon;center " + cmd;
163 evalStateCommand(command);
166 public void closeViewer()
168 // remove listeners for all structures in viewer
169 getSsm().removeStructureViewerListener(this, this.getStructureFiles());
173 releaseUIResources();
177 public void colourByChain()
179 colourBySequence = false;
180 // TODO: colour by chain should colour each chain distinctly across all
182 // TODO: http://issues.jalview.org/browse/JAL-628
183 evalStateCommand("select *;color chain");
187 public void colourByCharge()
189 colourBySequence = false;
190 evalStateCommand("select *;color white;select ASP,GLU;color red;"
191 + "select LYS,ARG;color blue;select CYS;color yellow");
195 * superpose the structures associated with sequences in the alignment
196 * according to their corresponding positions.
198 public void superposeStructures(AlignmentI alignment)
200 superposeStructures(alignment, -1, null);
204 * superpose the structures associated with sequences in the alignment
205 * according to their corresponding positions. ded)
207 * @param refStructure
208 * - select which pdb file to use as reference (default is -1 - the
209 * first structure in the alignment)
211 public void superposeStructures(AlignmentI alignment, int refStructure)
213 superposeStructures(alignment, refStructure, null);
217 * superpose the structures associated with sequences in the alignment
218 * according to their corresponding positions. ded)
220 * @param refStructure
221 * - select which pdb file to use as reference (default is -1 - the
222 * first structure in the alignment)
226 public void superposeStructures(AlignmentI alignment, int refStructure,
227 HiddenColumns hiddenCols)
229 superposeStructures(new AlignmentI[] { alignment },
231 { refStructure }, new HiddenColumns[] { hiddenCols });
238 public String superposeStructures(AlignmentI[] _alignment,
239 int[] _refStructure, HiddenColumns[] _hiddenCols)
241 while (viewer.isScriptExecuting())
246 } catch (InterruptedException i)
252 * get the distinct structure files modelled
253 * (a file with multiple chains may map to multiple sequences)
255 String[] files = getStructureFiles();
256 if (!waitForFileLoad(files))
261 StringBuilder selectioncom = new StringBuilder(256);
262 // In principle - nSeconds specifies the speed of animation for each
263 // superposition - but is seems to behave weirdly, so we don't specify it.
264 String nSeconds = " ";
265 if (files.length > 10)
267 nSeconds = " 0.005 ";
271 nSeconds = " " + (2.0 / files.length) + " ";
272 // if (nSeconds).substring(0,5)+" ";
275 // see JAL-1345 - should really automatically turn off the animation for
276 // large numbers of structures, but Jmol doesn't seem to allow that.
278 // union of all aligned positions are collected together.
279 for (int a = 0; a < _alignment.length; a++)
281 int refStructure = _refStructure[a];
282 AlignmentI alignment = _alignment[a];
283 HiddenColumns hiddenCols = _hiddenCols[a];
284 if (a > 0 && selectioncom.length() > 0 && !selectioncom
285 .substring(selectioncom.length() - 1).equals("|"))
287 selectioncom.append("|");
289 // process this alignment
290 if (refStructure >= files.length)
293 "Invalid reference structure value " + refStructure);
298 * 'matched' bit j will be set for visible alignment columns j where
299 * all sequences have a residue with a mapping to the PDB structure
301 BitSet matched = new BitSet();
302 for (int m = 0; m < alignment.getWidth(); m++)
304 if (hiddenCols == null || hiddenCols.isVisible(m))
310 SuperposeData[] structures = new SuperposeData[files.length];
311 for (int f = 0; f < files.length; f++)
313 structures[f] = new SuperposeData(alignment.getWidth());
317 * Calculate the superposable alignment columns ('matched'), and the
318 * corresponding structure residue positions (structures.pdbResNo)
320 int candidateRefStructure = findSuperposableResidues(alignment,
321 matched, structures);
322 if (refStructure < 0)
325 * If no reference structure was specified, pick the first one that has
326 * a mapping in the alignment
328 refStructure = candidateRefStructure;
331 String[] selcom = new String[files.length];
332 int nmatched = matched.cardinality();
335 return (MessageManager.formatMessage("label.insufficient_residues",
340 * generate select statements to select regions to superimpose structures
343 // TODO extract method to construct selection statements
344 for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
346 String chainCd = ":" + structures[pdbfnum].chain;
349 StringBuilder molsel = new StringBuilder();
352 int nextColumnMatch = matched.nextSetBit(0);
353 while (nextColumnMatch != -1)
355 int pdbResNo = structures[pdbfnum].pdbResNo[nextColumnMatch];
356 if (lpos != pdbResNo - 1)
362 molsel.append(chainCd);
369 // continuous run - and lpos >-1
372 // at the beginning, so add dash
379 nextColumnMatch = matched.nextSetBit(nextColumnMatch + 1);
382 * add final selection phrase
387 molsel.append(chainCd);
390 if (molsel.length() > 1)
392 selcom[pdbfnum] = molsel.toString();
393 selectioncom.append("((");
394 selectioncom.append(selcom[pdbfnum].substring(1,
395 selcom[pdbfnum].length() - 1));
396 selectioncom.append(" )& ");
397 selectioncom.append(pdbfnum + 1);
398 selectioncom.append(".1)");
399 if (pdbfnum < files.length - 1)
401 selectioncom.append("|");
406 selcom[pdbfnum] = null;
410 StringBuilder command = new StringBuilder(256);
411 // command.append("set spinFps 10;\n");
413 for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
415 if (pdbfnum == refStructure || selcom[pdbfnum] == null
416 || selcom[refStructure] == null)
420 command.append("echo ");
421 command.append("\"Superposing (");
422 command.append(structures[pdbfnum].pdbId);
423 command.append(") against reference (");
424 command.append(structures[refStructure].pdbId);
425 command.append(")\";\ncompare " + nSeconds);
427 command.append(Integer.toString(1 + pdbfnum));
428 command.append(".1} {");
429 command.append(Integer.toString(1 + refStructure));
430 // conformation=1 excludes alternate locations for CA (JAL-1757)
432 ".1} SUBSET {(*.CA | *.P) and conformation=1} ATOMS ");
434 // for (int s = 0; s < 2; s++)
436 // command.append(selcom[(s == 0 ? pdbfnum : refStructure)]);
438 command.append(selcom[pdbfnum]);
439 command.append(selcom[refStructure]);
440 command.append(" ROTATE TRANSLATE;\n");
442 if (selectioncom.length() > 0)
444 // TODO is performing selectioncom redundant here? is done later on
445 // System.out.println("Select regions:\n" + selectioncom.toString());
446 evalStateCommand("select *; cartoons off; backbone; select ("
447 + selectioncom.toString() + "); cartoons; ");
448 // selcom.append("; ribbons; ");
449 String cmdString = command.toString();
450 // System.out.println("Superimpose command(s):\n" + cmdString);
452 evalStateCommand(cmdString);
455 if (selectioncom.length() > 0)
456 {// finally, mark all regions that were superposed.
457 if (selectioncom.substring(selectioncom.length() - 1).equals("|"))
459 selectioncom.setLength(selectioncom.length() - 1);
461 // System.out.println("Select regions:\n" + selectioncom.toString());
462 evalStateCommand("select *; cartoons off; backbone; select ("
463 + selectioncom.toString() + "); cartoons; ");
464 // evalStateCommand("select *; backbone; select "+selcom.toString()+";
465 // cartoons; center "+selcom.toString());
471 public void evalStateCommand(String command)
474 if (lastCommand == null || !lastCommand.equals(command))
476 viewer.evalStringQuiet(command + "\n");
479 lastCommand = command;
482 Thread colourby = null;
485 * Sends a set of colour commands to the structure viewer
490 protected void colourBySequence(final String[] commands)
492 if (colourby != null)
494 colourby.interrupt();
497 colourby = new Thread(new Runnable()
502 for (String cmd : commands)
504 executeWhenReady(cmd);
517 protected String[] getColourBySequenceCommands(
518 String[] files, AlignmentViewPanel viewPanel)
520 Map<Object, AtomSpecModel> map = buildColoursMap(viewPanel);
522 return JmolCommands.getColourBySequenceCommand(map);
528 protected void executeWhenReady(String command)
530 evalStateCommand(command);
533 public void createImage(String file, String type, int quality)
535 System.out.println("JMOL CREATE IMAGE");
539 public String createImage(String fileName, String type,
540 Object textOrBytes, int quality)
542 System.out.println("JMOL CREATE IMAGE");
547 public String eval(String strEval)
549 // System.out.println(strEval);
550 // "# 'eval' is implemented only for the applet.";
554 // End StructureListener
555 // //////////////////////////
558 public float[][] functionXY(String functionName, int x, int y)
564 public float[][][] functionXYZ(String functionName, int nx, int ny,
567 // TODO Auto-generated method stub
571 public Color getColour(int atomIndex, int pdbResNum, String chain,
574 if (getModelNum(pdbfile) < 0)
578 // TODO: verify atomIndex is selecting correct model.
579 // return new Color(viewer.getAtomArgb(atomIndex)); Jmol 12.2.4
580 int colour = viewer.ms.at[atomIndex].atomPropertyInt(T.color);
581 return new Color(colour);
585 * instruct the Jalview binding to update the pdbentries vector if necessary
586 * prior to matching the jmol view's contents to the list of structure files
587 * Jalview knows about.
589 public abstract void refreshPdbEntries();
591 private int getModelNum(String modelFileName)
593 String[] mfn = getStructureFiles();
598 for (int i = 0; i < mfn.length; i++)
600 if (mfn[i].equalsIgnoreCase(modelFileName))
609 * map between index of model filename returned from getPdbFile and the first
610 * index of models from this file in the viewer. Note - this is not trimmed -
611 * use getPdbFile to get number of unique models.
613 private int _modelFileNameMap[];
616 public synchronized String[] getStructureFiles()
618 List<String> mset = new ArrayList<>();
621 return new String[0];
624 if (modelFileNames == null)
626 int modelCount = viewer.ms.mc;
627 String filePath = null;
628 for (int i = 0; i < modelCount; ++i)
630 filePath = viewer.ms.getModelFileName(i);
631 if (!mset.contains(filePath))
636 modelFileNames = mset.toArray(new String[mset.size()]);
639 return modelFileNames;
643 * map from string to applet
646 public Map<String, Object> getRegistryInfo()
648 // TODO Auto-generated method stub
652 // ///////////////////////////////
653 // JmolStatusListener
655 public void handlePopupMenu(int x, int y)
657 // jmolpopup.show(x, y);
658 // jmolpopup.jpiShow(x, y);
662 * Highlight zero, one or more atoms on the structure
665 public void highlightAtoms(List<AtomSpec> atoms)
669 if (resetLastRes.length() > 0)
671 viewer.evalStringQuiet(resetLastRes.toString());
672 resetLastRes.setLength(0);
674 for (AtomSpec atom : atoms)
676 highlightAtom(atom.getAtomIndex(), atom.getPdbResNum(),
677 atom.getChain(), atom.getPdbFile());
683 public void highlightAtom(int atomIndex, int pdbResNum, String chain,
686 if (modelFileNames == null)
691 // look up file model number for this pdbfile
693 // may need to adjust for URLencoding here - we don't worry about that yet.
694 while (mdlNum < modelFileNames.length
695 && !pdbfile.equals(modelFileNames[mdlNum]))
699 if (mdlNum == modelFileNames.length)
706 StringBuilder cmd = new StringBuilder(64);
707 cmd.append("select " + pdbResNum); // +modelNum
709 resetLastRes.append("select " + pdbResNum); // +modelNum
712 resetLastRes.append(":");
713 if (!chain.equals(" "))
716 resetLastRes.append(chain);
719 cmd.append(" /" + (mdlNum + 1));
720 resetLastRes.append("/" + (mdlNum + 1));
722 cmd.append(";wireframe 100;" + cmd.toString() + " and not hetero;");
724 resetLastRes.append(";wireframe 0;" + resetLastRes.toString()
725 + " and not hetero; spacefill 0;");
727 cmd.append("spacefill 200;select none");
729 viewer.evalStringQuiet(cmd.toString());
734 boolean debug = true;
736 private void jmolHistory(boolean enable)
738 viewer.evalStringQuiet("History " + ((debug || enable) ? "on" : "off"));
741 public void loadInline(String string)
745 // viewer.loadInline(strModel, isAppend);
747 // construct fake fullPathName and fileName so we can identify the file
749 // Then, construct pass a reader for the string to Jmol.
750 // ((org.jmol.Viewer.Viewer) viewer).loadModelFromFile(fullPathName,
751 // fileName, null, reader, false, null, null, 0);
752 viewer.openStringInline(string);
755 protected void mouseOverStructure(int atomIndex, final String strInfo)
758 int alocsep = strInfo.indexOf("^");
759 int mdlSep = strInfo.indexOf("/");
760 int chainSeparator = strInfo.indexOf(":"), chainSeparator1 = -1;
762 if (chainSeparator == -1)
764 chainSeparator = strInfo.indexOf(".");
765 if (mdlSep > -1 && mdlSep < chainSeparator)
767 chainSeparator1 = chainSeparator;
768 chainSeparator = mdlSep;
771 // handle insertion codes
774 pdbResNum = Integer.parseInt(
775 strInfo.substring(strInfo.indexOf("]") + 1, alocsep));
780 pdbResNum = Integer.parseInt(
781 strInfo.substring(strInfo.indexOf("]") + 1, chainSeparator));
785 if (strInfo.indexOf(":") > -1)
787 chainId = strInfo.substring(strInfo.indexOf(":") + 1,
788 strInfo.indexOf("."));
795 String pdbfilename = modelFileNames[frameNo]; // default is first or current
799 if (chainSeparator1 == -1)
801 chainSeparator1 = strInfo.indexOf(".", mdlSep);
803 String mdlId = (chainSeparator1 > -1)
804 ? strInfo.substring(mdlSep + 1, chainSeparator1)
805 : strInfo.substring(mdlSep + 1);
808 // recover PDB filename for the model hovered over.
809 int mnumber = Integer.valueOf(mdlId).intValue() - 1;
810 if (_modelFileNameMap != null)
812 int _mp = _modelFileNameMap.length - 1;
814 while (mnumber < _modelFileNameMap[_mp])
818 pdbfilename = modelFileNames[_mp];
822 if (mnumber >= 0 && mnumber < modelFileNames.length)
824 pdbfilename = modelFileNames[mnumber];
827 if (pdbfilename == null)
829 pdbfilename = new File(viewer.ms.getModelFileName(mnumber))
833 } catch (Exception e)
839 * highlight position on alignment(s); if some text is returned,
840 * show this as a second line on the structure hover tooltip
842 String label = getSsm().mouseOverStructure(pdbResNum, chainId,
846 // change comma to pipe separator (newline token for Jmol)
847 label = label.replace(',', '|');
848 StringTokenizer toks = new StringTokenizer(strInfo, " ");
849 StringBuilder sb = new StringBuilder();
850 sb.append("select ").append(String.valueOf(pdbResNum)).append(":")
851 .append(chainId).append("/1");
852 sb.append(";set hoverLabel \"").append(toks.nextToken()).append(" ")
853 .append(toks.nextToken());
854 sb.append("|").append(label).append("\"");
855 evalStateCommand(sb.toString());
859 public void notifyAtomHovered(int atomIndex, String strInfo, String data)
861 if (strInfo.equals(lastMessage))
865 lastMessage = strInfo;
868 System.err.println("Ignoring additional hover info: " + data
869 + " (other info: '" + strInfo + "' pos " + atomIndex + ")");
871 mouseOverStructure(atomIndex, strInfo);
875 * { if (history != null && strStatus != null &&
876 * !strStatus.equals("Script completed")) { history.append("\n" + strStatus);
880 public void notifyAtomPicked(int atomIndex, String strInfo,
884 * this implements the toggle label behaviour copied from the original
885 * structure viewer, MCView
889 System.err.println("Ignoring additional pick data string " + strData);
891 int chainSeparator = strInfo.indexOf(":");
893 if (chainSeparator == -1)
895 chainSeparator = strInfo.indexOf(".");
898 String picked = strInfo.substring(strInfo.indexOf("]") + 1,
900 String mdlString = "";
901 if ((p = strInfo.indexOf(":")) > -1)
903 picked += strInfo.substring(p, strInfo.indexOf("."));
906 if ((p = strInfo.indexOf("/")) > -1)
908 mdlString += strInfo.substring(p, strInfo.indexOf(" #"));
910 picked = "((" + picked + ".CA" + mdlString + ")|(" + picked + ".P"
914 if (!atomsPicked.contains(picked))
916 viewer.evalStringQuiet("select " + picked + ";label %n %r:%c");
917 atomsPicked.addElement(picked);
921 viewer.evalString("select " + picked + ";label off");
922 atomsPicked.removeElement(picked);
925 // TODO: in application this happens
927 // if (scriptWindow != null)
929 // scriptWindow.sendConsoleMessage(strInfo);
930 // scriptWindow.sendConsoleMessage("\n");
936 public void notifyCallback(CBK type, Object[] data)
943 notifyFileLoaded((String) data[1], (String) data[2],
944 (String) data[3], (String) data[4],
945 ((Integer) data[5]).intValue());
949 notifyAtomPicked(((Integer) data[2]).intValue(), (String) data[1],
951 // also highlight in alignment
952 // deliberate fall through
954 notifyAtomHovered(((Integer) data[2]).intValue(), (String) data[1],
958 notifyScriptTermination((String) data[2],
959 ((Integer) data[3]).intValue());
962 sendConsoleEcho((String) data[1]);
966 (data == null) ? ((String) null) : (String) data[1]);
969 // System.err.println("Ignoring error callback.");
980 "Unhandled callback " + type + " " + data[1].toString());
983 } catch (Exception e)
985 System.err.println("Squashed Jmol callback handler error:");
991 public boolean notifyEnabled(CBK callbackPick)
993 switch (callbackPick)
1009 // incremented every time a load notification is successfully handled -
1010 // lightweight mechanism for other threads to detect when they can start
1011 // referrring to new structures.
1012 private long loadNotifiesHandled = 0;
1014 public long getLoadNotifiesHandled()
1016 return loadNotifiesHandled;
1019 public void notifyFileLoaded(String fullPathName, String fileName2,
1020 String modelName, String errorMsg, int modelParts)
1022 if (errorMsg != null)
1024 fileLoadingError = errorMsg;
1028 // TODO: deal sensibly with models loaded inLine:
1029 // modelName will be null, as will fullPathName.
1031 // the rest of this routine ignores the arguments, and simply interrogates
1032 // the Jmol view to find out what structures it contains, and adds them to
1033 // the structure selection manager.
1034 fileLoadingError = null;
1035 String[] oldmodels = modelFileNames;
1036 modelFileNames = null;
1037 chainNames = new ArrayList<>();
1038 chainFile = new Hashtable<>();
1039 boolean notifyLoaded = false;
1040 String[] modelfilenames = getStructureFiles();
1041 // first check if we've lost any structures
1042 if (oldmodels != null && oldmodels.length > 0)
1045 for (int i = 0; i < oldmodels.length; i++)
1047 for (int n = 0; n < modelfilenames.length; n++)
1049 if (modelfilenames[n] == oldmodels[i])
1051 oldmodels[i] = null;
1055 if (oldmodels[i] != null)
1062 String[] oldmfn = new String[oldm];
1064 for (int i = 0; i < oldmodels.length; i++)
1066 if (oldmodels[i] != null)
1068 oldmfn[oldm++] = oldmodels[i];
1071 // deregister the Jmol instance for these structures - we'll add
1072 // ourselves again at the end for the current structure set.
1073 getSsm().removeStructureViewerListener(this, oldmfn);
1076 refreshPdbEntries();
1077 for (int modelnum = 0; modelnum < modelfilenames.length; modelnum++)
1079 String fileName = modelfilenames[modelnum];
1080 boolean foundEntry = false;
1081 StructureFile pdb = null;
1082 String pdbfile = null;
1083 // model was probably loaded inline - so check the pdb file hashcode
1086 // calculate essential attributes for the pdb data imported inline.
1087 // prolly need to resolve modelnumber properly - for now just use our
1089 pdbfile = viewer.getData(
1090 "" + (1 + _modelFileNameMap[modelnum]) + ".0", "PDB");
1092 // search pdbentries and sequences to find correct pdbentry for this
1094 for (int pe = 0; pe < getPdbCount(); pe++)
1096 boolean matches = false;
1097 addSequence(pe, getSequence()[pe]);
1098 if (fileName == null)
1101 // see JAL-623 - need method of matching pasted data up
1103 pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
1104 pdbfile, DataSourceType.PASTE,
1105 getIProgressIndicator());
1106 getPdbEntry(modelnum).setFile("INLINE" + pdb.getId());
1113 File fl = new File(getPdbEntry(pe).getFile());
1114 matches = fl.equals(new File(fileName));
1118 // TODO: Jmol can in principle retrieve from CLASSLOADER but
1121 // to be tested. See mantis bug
1122 // https://mantis.lifesci.dundee.ac.uk/view.php?id=36605
1123 DataSourceType protocol = DataSourceType.URL;
1128 protocol = DataSourceType.FILE;
1130 } catch (Exception e)
1135 // Explicitly map to the filename used by Jmol ;
1136 pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
1137 fileName, protocol, getIProgressIndicator());
1138 // pdbentry[pe].getFile(), protocol);
1144 // add an entry for every chain in the model
1145 for (int i = 0; i < pdb.getChains().size(); i++)
1147 String chid = new String(
1148 pdb.getId() + ":" + pdb.getChains().elementAt(i).id);
1149 chainFile.put(chid, fileName);
1150 chainNames.add(chid);
1152 notifyLoaded = true;
1156 if (!foundEntry && associateNewStructs)
1158 // this is a foreign pdb file that jalview doesn't know about - add
1159 // it to the dataset and try to find a home - either on a matching
1160 // sequence or as a new sequence.
1161 String pdbcontent = viewer.getData("/" + (modelnum + 1) + ".1",
1163 // parse pdb file into a chain, etc.
1164 // locate best match for pdb in associated views and add mapping to
1166 // if properly registered then
1167 notifyLoaded = true;
1172 // so finally, update the jmol bits and pieces
1173 // if (jmolpopup != null)
1175 // // potential for deadlock here:
1176 // // jmolpopup.updateComputedMenus();
1178 if (!isLoadingFromArchive())
1180 viewer.evalStringQuiet(
1181 "model *; select backbone;restrict;cartoon;wireframe off;spacefill off");
1183 // register ourselves as a listener and notify the gui that it needs to
1185 getSsm().addStructureViewerListener(this);
1188 FeatureRenderer fr = getFeatureRenderer(null);
1194 loadNotifiesHandled++;
1196 setLoadingFromArchive(false);
1200 public List<String> getChainNames()
1205 protected IProgressIndicator getIProgressIndicator()
1210 public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)
1212 notifyAtomPicked(iatom, strMeasure, null);
1215 public abstract void notifyScriptTermination(String strStatus,
1219 * display a message echoed from the jmol viewer
1223 public abstract void sendConsoleEcho(String strEcho); /*
1224 * { showConsole(true);
1226 * history.append("\n" +
1230 // /End JmolStatusListener
1231 // /////////////////////////////
1235 * status message - usually the response received after a script
1238 public abstract void sendConsoleMessage(String strStatus);
1241 public void setCallbackFunction(String callbackType,
1242 String callbackFunction)
1244 System.err.println("Ignoring set-callback request to associate "
1245 + callbackType + " with function " + callbackFunction);
1250 public void setJalviewColourScheme(ColourSchemeI cs)
1252 colourBySequence = false;
1260 StringBuilder command = new StringBuilder(128);
1261 command.append("select *;color white;");
1262 List<String> residueSet = ResidueProperties.getResidues(isNucleotide(),
1264 for (String resName : residueSet)
1266 char res = resName.length() == 3
1267 ? ResidueProperties.getSingleCharacterCode(resName)
1268 : resName.charAt(0);
1269 Color col = cs.findColour(res, 0, null, null, 0f);
1270 command.append("select " + resName + ";color[" + col.getRed() + ","
1271 + col.getGreen() + "," + col.getBlue() + "];");
1274 evalStateCommand(command.toString());
1278 public void showHelp()
1280 showUrl("http://jmol.sourceforge.net/docs/JmolUserGuide/", "jmolHelp");
1284 * open the URL somehow
1288 public abstract void showUrl(String url, String target);
1291 * called when the binding thinks the UI needs to be refreshed after a Jmol
1292 * state change. this could be because structures were loaded, or because an
1293 * error has occured.
1295 public abstract void refreshGUI();
1298 * called to show or hide the associated console window container.
1302 public abstract void showConsole(boolean show);
1305 * @param renderPanel
1307 * - when true will initialise jmol's file IO system (should be false
1308 * in applet context)
1310 * @param documentBase
1312 * @param commandOptions
1314 public void allocateViewer(Container renderPanel, boolean jmolfileio,
1315 String htmlName, URL documentBase, URL codeBase,
1316 String commandOptions)
1318 allocateViewer(renderPanel, jmolfileio, htmlName, documentBase,
1319 codeBase, commandOptions, null, null);
1324 * @param renderPanel
1326 * - when true will initialise jmol's file IO system (should be false
1327 * in applet context)
1329 * @param documentBase
1331 * @param commandOptions
1332 * @param consolePanel
1333 * - panel to contain Jmol console
1334 * @param buttonsToShow
1335 * - buttons to show on the console, in ordr
1337 public void allocateViewer(Container renderPanel, boolean jmolfileio,
1338 String htmlName, URL documentBase, URL codeBase,
1339 String commandOptions, final Container consolePanel,
1340 String buttonsToShow)
1342 if (commandOptions == null)
1344 commandOptions = "";
1346 viewer = (Viewer) JmolViewer.allocateViewer(renderPanel,
1347 (jmolfileio ? new SmarterJmolAdapter() : null),
1348 htmlName + ((Object) this).toString(), documentBase, codeBase,
1349 commandOptions, this);
1351 viewer.setJmolStatusListener(this); // extends JmolCallbackListener
1353 console = createJmolConsole(consolePanel, buttonsToShow);
1354 if (consolePanel != null)
1356 consolePanel.addComponentListener(this);
1362 protected abstract JmolAppConsoleInterface createJmolConsole(
1363 Container consolePanel, String buttonsToShow);
1365 protected org.jmol.api.JmolAppConsoleInterface console = null;
1368 public void setBackgroundColour(java.awt.Color col)
1371 viewer.evalStringQuiet("background [" + col.getRed() + ","
1372 + col.getGreen() + "," + col.getBlue() + "];");
1377 public int[] resizeInnerPanel(String data)
1379 // Jalview doesn't honour resize panel requests
1386 protected void closeConsole()
1388 if (console != null)
1392 console.setVisible(false);
1395 } catch (Exception x)
1404 * ComponentListener method
1407 public void componentMoved(ComponentEvent e)
1412 * ComponentListener method
1415 public void componentResized(ComponentEvent e)
1420 * ComponentListener method
1423 public void componentShown(ComponentEvent e)
1429 * ComponentListener method
1432 public void componentHidden(ComponentEvent e)
1438 public void showStructures(AlignViewportI av, boolean refocus)
1440 StringBuilder cmd = new StringBuilder(128);
1442 if (isShowAlignmentOnly())
1444 cmd.append("hide *;");
1446 AtomSpecModel model = getShownResidues(av);
1447 String atomSpec = JmolCommands.getAtomSpec(model);
1449 cmd.append("display ").append(atomSpec);
1453 cmd.append("display *");
1455 cmd.append("; cartoon");
1458 cmd.append("; zoom 0");
1460 evalStateCommand(cmd.toString());
1464 * Answers a Jmol syntax style structure model specification. Model number 0, 1,
1465 * 2... is formatted as "1.1", "2.1", "3.1" etc.
1468 public String getModelSpec(int model)
1470 return String.valueOf(model + 1) + ".1";