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.FeatureRenderer;
24 import jalview.api.SequenceRenderer;
25 import jalview.datamodel.AlignmentI;
26 import jalview.datamodel.ColumnSelection;
27 import jalview.datamodel.PDBEntry;
28 import jalview.datamodel.SequenceI;
29 import jalview.io.DataSourceType;
30 import jalview.io.StructureFile;
31 import jalview.schemes.ColourSchemeI;
32 import jalview.schemes.ResidueProperties;
33 import jalview.structure.AtomSpec;
34 import jalview.structure.StructureMappingcommandSet;
35 import jalview.structure.StructureSelectionManager;
36 import jalview.structures.models.AAStructureBindingModel;
37 import jalview.util.MessageManager;
39 import java.awt.Color;
40 import java.awt.Container;
41 import java.awt.event.ComponentEvent;
42 import java.awt.event.ComponentListener;
45 import java.security.AccessControlException;
46 import java.util.ArrayList;
47 import java.util.BitSet;
48 import java.util.Hashtable;
49 import java.util.List;
51 import java.util.Vector;
53 import org.jmol.adapter.smarter.SmarterJmolAdapter;
54 import org.jmol.api.JmolAppConsoleInterface;
55 import org.jmol.api.JmolSelectionListener;
56 import org.jmol.api.JmolStatusListener;
57 import org.jmol.api.JmolViewer;
58 import org.jmol.c.CBK;
59 import org.jmol.script.T;
60 import org.jmol.viewer.Viewer;
62 public abstract class JalviewJmolBinding extends AAStructureBindingModel
63 implements JmolStatusListener, JmolSelectionListener,
66 boolean allChainsSelected = false;
69 * when true, try to search the associated datamodel for sequences that are
70 * associated with any unknown structures in the Jmol view.
72 private boolean associateNewStructs = false;
74 Vector<String> atomsPicked = new Vector<String>();
76 private List<String> chainNames;
78 Hashtable<String, String> chainFile;
81 * the default or current model displayed if the model cannot be identified
82 * from the selection message
86 // protected JmolGenericPopup jmolpopup; // not used - remove?
94 StringBuffer resetLastRes = new StringBuffer();
98 public JalviewJmolBinding(StructureSelectionManager ssm,
99 PDBEntry[] pdbentry, SequenceI[][] sequenceIs,
100 DataSourceType protocol)
102 super(ssm, pdbentry, sequenceIs, protocol);
104 * viewer = JmolViewer.allocateViewer(renderPanel, new SmarterJmolAdapter(),
105 * "jalviewJmol", ap.av.applet .getDocumentBase(),
106 * ap.av.applet.getCodeBase(), "", this);
108 * jmolpopup = JmolPopup.newJmolPopup(viewer, true, "Jmol", true);
112 public JalviewJmolBinding(StructureSelectionManager ssm,
113 SequenceI[][] seqs, Viewer theViewer)
118 viewer.setJmolStatusListener(this);
119 viewer.addSelectionListener(this);
123 * construct a title string for the viewer window based on the data jalview
128 public String getViewerTitle()
130 return getViewerTitle("Jmol", true);
134 * prepare the view for a given set of models/chains. chainList contains
135 * strings of the form 'pdbfilename:Chaincode'
138 * list of chains to make visible
140 public void centerViewer(Vector<String> chainList)
142 StringBuilder cmd = new StringBuilder(128);
144 for (String lbl : chainList)
150 mlength = lbl.indexOf(":", p);
151 } while (p < mlength && mlength < (lbl.length() - 2));
152 // TODO: lookup each pdb id and recover proper model number for it.
153 cmd.append(":" + lbl.substring(mlength + 1) + " /"
154 + (1 + getModelNum(chainFile.get(lbl))) + " or ");
156 if (cmd.length() > 0)
158 cmd.setLength(cmd.length() - 4);
160 evalStateCommand("select *;restrict " + cmd + ";cartoon;center " + cmd);
163 public void closeViewer()
165 // remove listeners for all structures in viewer
166 getSsm().removeStructureViewerListener(this, this.getPdbFile());
170 releaseUIResources();
174 public void colourByChain()
176 colourBySequence = false;
177 // TODO: colour by chain should colour each chain distinctly across all
179 // TODO: http://issues.jalview.org/browse/JAL-628
180 evalStateCommand("select *;color chain");
184 public void colourByCharge()
186 colourBySequence = false;
187 evalStateCommand("select *;color white;select ASP,GLU;color red;"
188 + "select LYS,ARG;color blue;select CYS;color yellow");
192 * superpose the structures associated with sequences in the alignment
193 * according to their corresponding positions.
195 public void superposeStructures(AlignmentI alignment)
197 superposeStructures(alignment, -1, null);
201 * superpose the structures associated with sequences in the alignment
202 * according to their corresponding positions. ded)
204 * @param refStructure
205 * - select which pdb file to use as reference (default is -1 - the
206 * first structure in the alignment)
208 public void superposeStructures(AlignmentI alignment, int refStructure)
210 superposeStructures(alignment, refStructure, null);
214 * superpose the structures associated with sequences in the alignment
215 * according to their corresponding positions. ded)
217 * @param refStructure
218 * - select which pdb file to use as reference (default is -1 - the
219 * first structure in the alignment)
223 public void superposeStructures(AlignmentI alignment, int refStructure,
224 ColumnSelection hiddenCols)
226 superposeStructures(new AlignmentI[] { alignment },
227 new int[] { refStructure },
228 new ColumnSelection[] { hiddenCols });
235 public String superposeStructures(AlignmentI[] _alignment,
236 int[] _refStructure, ColumnSelection[] _hiddenCols)
238 while (viewer.isScriptExecuting())
243 } catch (InterruptedException i)
249 * get the distinct structure files modelled
250 * (a file with multiple chains may map to multiple sequences)
252 String[] files = getPdbFile();
253 if (!waitForFileLoad(files))
258 StringBuilder selectioncom = new StringBuilder(256);
259 // In principle - nSeconds specifies the speed of animation for each
260 // superposition - but is seems to behave weirdly, so we don't specify it.
261 String nSeconds = " ";
262 if (files.length > 10)
264 nSeconds = " 0.005 ";
268 nSeconds = " " + (2.0 / files.length) + " ";
269 // if (nSeconds).substring(0,5)+" ";
272 // see JAL-1345 - should really automatically turn off the animation for
273 // large numbers of structures, but Jmol doesn't seem to allow that.
275 // union of all aligned positions are collected together.
276 for (int a = 0; a < _alignment.length; a++)
278 int refStructure = _refStructure[a];
279 AlignmentI alignment = _alignment[a];
280 ColumnSelection hiddenCols = _hiddenCols[a];
282 && selectioncom.length() > 0
283 && !selectioncom.substring(selectioncom.length() - 1).equals(
286 selectioncom.append("|");
288 // process this alignment
289 if (refStructure >= files.length)
291 System.err.println("Invalid reference structure value "
297 * 'matched' bit j will be set for visible alignment columns j where
298 * all sequences have a residue with a mapping to the PDB structure
300 BitSet matched = new BitSet();
301 for (int m = 0; m < alignment.getWidth(); m++)
303 if (hiddenCols == null || hiddenCols.isVisible(m))
309 SuperposeData[] structures = new SuperposeData[files.length];
310 for (int f = 0; f < files.length; f++)
312 structures[f] = new SuperposeData(alignment.getWidth());
316 * Calculate the superposable alignment columns ('matched'), and the
317 * corresponding structure residue positions (structures.pdbResNo)
319 int candidateRefStructure = findSuperposableResidues(alignment,
320 matched, structures);
321 if (refStructure < 0)
324 * If no reference structure was specified, pick the first one that has
325 * a mapping in the alignment
327 refStructure = candidateRefStructure;
330 String[] selcom = new String[files.length];
331 int nmatched = matched.cardinality();
334 return (MessageManager.formatMessage(
335 "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)
431 command.append(".1} SUBSET {(*.CA | *.P) and conformation=1} ATOMS ");
433 // for (int s = 0; s < 2; s++)
435 // command.append(selcom[(s == 0 ? pdbfnum : refStructure)]);
437 command.append(selcom[pdbfnum]);
438 command.append(selcom[refStructure]);
439 command.append(" ROTATE TRANSLATE;\n");
441 if (selectioncom.length() > 0)
443 // TODO is performing selectioncom redundant here? is done later on
444 // System.out.println("Select regions:\n" + selectioncom.toString());
445 evalStateCommand("select *; cartoons off; backbone; select ("
446 + selectioncom.toString() + "); cartoons; ");
447 // selcom.append("; ribbons; ");
448 String cmdString = command.toString();
449 // System.out.println("Superimpose command(s):\n" + cmdString);
451 evalStateCommand(cmdString);
454 if (selectioncom.length() > 0)
455 {// finally, mark all regions that were superposed.
456 if (selectioncom.substring(selectioncom.length() - 1).equals("|"))
458 selectioncom.setLength(selectioncom.length() - 1);
460 // System.out.println("Select regions:\n" + selectioncom.toString());
461 evalStateCommand("select *; cartoons off; backbone; select ("
462 + selectioncom.toString() + "); cartoons; ");
463 // evalStateCommand("select *; backbone; select "+selcom.toString()+"; 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;
481 * Sends a set of colour commands to the structure viewer
483 * @param colourBySequenceCommands
486 protected void colourBySequence(
487 StructureMappingcommandSet[] colourBySequenceCommands)
489 for (StructureMappingcommandSet cpdbbyseq : colourBySequenceCommands)
491 for (String cbyseq : cpdbbyseq.commands)
493 executeWhenReady(cbyseq);
506 protected StructureMappingcommandSet[] getColourBySequenceCommands(
507 String[] files, SequenceRenderer sr, FeatureRenderer fr,
508 AlignmentI alignment)
510 return JmolCommands.getColourBySequenceCommand(getSsm(), files,
511 getSequence(), sr, fr, alignment);
517 protected void executeWhenReady(String command)
519 evalStateCommand(command);
522 public void createImage(String file, String type, int quality)
524 System.out.println("JMOL CREATE IMAGE");
528 public String createImage(String fileName, String type,
529 Object textOrBytes, int quality)
531 System.out.println("JMOL CREATE IMAGE");
536 public String eval(String strEval)
538 // System.out.println(strEval);
539 // "# 'eval' is implemented only for the applet.";
543 // End StructureListener
544 // //////////////////////////
547 public float[][] functionXY(String functionName, int x, int y)
553 public float[][][] functionXYZ(String functionName, int nx, int ny, int nz)
555 // TODO Auto-generated method stub
559 public Color getColour(int atomIndex, int pdbResNum, String chain,
562 if (getModelNum(pdbfile) < 0)
566 // TODO: verify atomIndex is selecting correct model.
567 // return new Color(viewer.getAtomArgb(atomIndex)); Jmol 12.2.4
568 int colour = viewer.ms.at[atomIndex].atomPropertyInt(T.color);
569 return new Color(colour);
573 * instruct the Jalview binding to update the pdbentries vector if necessary
574 * prior to matching the jmol view's contents to the list of structure files
575 * Jalview knows about.
577 public abstract void refreshPdbEntries();
579 private int getModelNum(String modelFileName)
581 String[] mfn = getPdbFile();
586 for (int i = 0; i < mfn.length; i++)
588 if (mfn[i].equalsIgnoreCase(modelFileName))
597 * map between index of model filename returned from getPdbFile and the first
598 * index of models from this file in the viewer. Note - this is not trimmed -
599 * use getPdbFile to get number of unique models.
601 private int _modelFileNameMap[];
603 // ////////////////////////////////
604 // /StructureListener
606 public synchronized String[] getPdbFile()
610 return new String[0];
612 if (modelFileNames == null)
614 List<String> mset = new ArrayList<String>();
615 _modelFileNameMap = new int[viewer.ms.mc];
616 String m = viewer.ms.getModelFileName(0);
622 filePath = new File(m).getAbsolutePath();
623 } catch (AccessControlException x)
625 // usually not allowed to do this in applet
627 .println("jmolBinding: Using local file string from Jmol: "
630 if (filePath.indexOf("/file:") != -1)
632 // applet path with docroot - discard as format won't match pdbfile
636 _modelFileNameMap[0] = 0; // filename index for first model is always 0.
639 for (int i = 1; i < viewer.ms.mc; i++)
641 m = viewer.ms.getModelFileName(i);
647 filePath = new File(m).getAbsolutePath();
648 } catch (AccessControlException x)
650 // usually not allowed to do this in applet, so keep raw handle
651 // System.err.println("jmolBinding: Using local file string from Jmol: "+m);
656 * add this model unless it is read from a structure file we have
657 * already seen (example: 2MJW is an NMR structure with 10 models)
659 if (!mset.contains(filePath))
662 _modelFileNameMap[j] = i; // record the model index for the filename
666 modelFileNames = mset.toArray(new String[mset.size()]);
668 return modelFileNames;
672 * map from string to applet
675 public Map<String, Object> getRegistryInfo()
677 // TODO Auto-generated method stub
683 // ///////////////////////////////
684 // JmolStatusListener
686 public void handlePopupMenu(int x, int y)
688 // jmolpopup.show(x, y);
689 // jmolpopup.jpiShow(x, y);
693 * Highlight zero, one or more atoms on the structure
696 public void highlightAtoms(List<AtomSpec> atoms)
700 if (resetLastRes.length() > 0)
702 viewer.evalStringQuiet(resetLastRes.toString());
703 resetLastRes.setLength(0);
705 for (AtomSpec atom : atoms)
707 highlightAtom(atom.getAtomIndex(), atom.getPdbResNum(),
708 atom.getChain(), atom.getPdbFile());
714 public void highlightAtom(int atomIndex, int pdbResNum, String chain,
717 if (modelFileNames == null)
722 // look up file model number for this pdbfile
724 // may need to adjust for URLencoding here - we don't worry about that yet.
725 while (mdlNum < modelFileNames.length
726 && !pdbfile.equals(modelFileNames[mdlNum]))
730 if (mdlNum == modelFileNames.length)
737 StringBuilder cmd = new StringBuilder(64);
738 cmd.append("select " + pdbResNum); // +modelNum
740 resetLastRes.append("select " + pdbResNum); // +modelNum
743 resetLastRes.append(":");
744 if (!chain.equals(" "))
747 resetLastRes.append(chain);
750 cmd.append(" /" + (mdlNum + 1));
751 resetLastRes.append("/" + (mdlNum + 1));
753 cmd.append(";wireframe 100;" + cmd.toString() + " and not hetero;");
755 resetLastRes.append(";wireframe 0;" + resetLastRes.toString()
756 + " and not hetero; spacefill 0;");
758 cmd.append("spacefill 200;select none");
760 viewer.evalStringQuiet(cmd.toString());
765 boolean debug = true;
767 private void jmolHistory(boolean enable)
769 viewer.evalStringQuiet("History " + ((debug || enable) ? "on" : "off"));
772 public void loadInline(String string)
776 // viewer.loadInline(strModel, isAppend);
778 // construct fake fullPathName and fileName so we can identify the file
780 // Then, construct pass a reader for the string to Jmol.
781 // ((org.jmol.Viewer.Viewer) viewer).loadModelFromFile(fullPathName,
782 // fileName, null, reader, false, null, null, 0);
783 viewer.openStringInline(string);
786 public void mouseOverStructure(int atomIndex, String strInfo)
789 int alocsep = strInfo.indexOf("^");
790 int mdlSep = strInfo.indexOf("/");
791 int chainSeparator = strInfo.indexOf(":"), chainSeparator1 = -1;
793 if (chainSeparator == -1)
795 chainSeparator = strInfo.indexOf(".");
796 if (mdlSep > -1 && mdlSep < chainSeparator)
798 chainSeparator1 = chainSeparator;
799 chainSeparator = mdlSep;
802 // handle insertion codes
805 pdbResNum = Integer.parseInt(strInfo.substring(
806 strInfo.indexOf("]") + 1, alocsep));
811 pdbResNum = Integer.parseInt(strInfo.substring(
812 strInfo.indexOf("]") + 1, chainSeparator));
816 if (strInfo.indexOf(":") > -1)
818 chainId = strInfo.substring(strInfo.indexOf(":") + 1,
819 strInfo.indexOf("."));
826 String pdbfilename = modelFileNames[frameNo]; // default is first or current
830 if (chainSeparator1 == -1)
832 chainSeparator1 = strInfo.indexOf(".", mdlSep);
834 String mdlId = (chainSeparator1 > -1) ? strInfo.substring(mdlSep + 1,
835 chainSeparator1) : strInfo.substring(mdlSep + 1);
838 // recover PDB filename for the model hovered over.
839 int _mp = _modelFileNameMap.length - 1, mnumber = new Integer(mdlId)
841 while (mnumber < _modelFileNameMap[_mp])
845 pdbfilename = modelFileNames[_mp];
846 if (pdbfilename == null)
848 pdbfilename = new File(viewer.ms.getModelFileName(mnumber))
852 } catch (Exception e)
857 if (lastMessage == null || !lastMessage.equals(strInfo))
859 getSsm().mouseOverStructure(pdbResNum, chainId, pdbfilename);
862 lastMessage = strInfo;
865 public void notifyAtomHovered(int atomIndex, String strInfo, String data)
869 System.err.println("Ignoring additional hover info: " + data
870 + " (other info: '" + strInfo + "' pos " + atomIndex + ")");
872 mouseOverStructure(atomIndex, strInfo);
876 * { if (history != null && strStatus != null &&
877 * !strStatus.equals("Script completed")) { history.append("\n" + strStatus);
881 public void notifyAtomPicked(int atomIndex, String strInfo, String strData)
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
953 notifyAtomHovered(((Integer) data[2]).intValue(), (String) data[1],
957 notifyScriptTermination((String) data[2],
958 ((Integer) data[3]).intValue());
961 sendConsoleEcho((String) data[1]);
964 sendConsoleMessage((data == null) ? ((String) null)
968 // System.err.println("Ignoring error callback.");
978 System.err.println("Unhandled callback " + type + " "
979 + data[1].toString());
982 } catch (Exception e)
984 System.err.println("Squashed Jmol callback handler error:");
990 public boolean notifyEnabled(CBK callbackPick)
992 switch (callbackPick)
1008 // incremented every time a load notification is successfully handled -
1009 // lightweight mechanism for other threads to detect when they can start
1010 // referrring to new structures.
1011 private long loadNotifiesHandled = 0;
1013 public long getLoadNotifiesHandled()
1015 return loadNotifiesHandled;
1018 public void notifyFileLoaded(String fullPathName, String fileName2,
1019 String modelName, String errorMsg, int modelParts)
1021 if (errorMsg != null)
1023 fileLoadingError = errorMsg;
1027 // TODO: deal sensibly with models loaded inLine:
1028 // modelName will be null, as will fullPathName.
1030 // the rest of this routine ignores the arguments, and simply interrogates
1031 // the Jmol view to find out what structures it contains, and adds them to
1032 // the structure selection manager.
1033 fileLoadingError = null;
1034 String[] oldmodels = modelFileNames;
1035 modelFileNames = null;
1036 chainNames = new ArrayList<String>();
1037 chainFile = new Hashtable<String, String>();
1038 boolean notifyLoaded = false;
1039 String[] modelfilenames = getPdbFile();
1040 // first check if we've lost any structures
1041 if (oldmodels != null && oldmodels.length > 0)
1044 for (int i = 0; i < oldmodels.length; i++)
1046 for (int n = 0; n < modelfilenames.length; n++)
1048 if (modelfilenames[n] == oldmodels[i])
1050 oldmodels[i] = null;
1054 if (oldmodels[i] != null)
1061 String[] oldmfn = new String[oldm];
1063 for (int i = 0; i < oldmodels.length; i++)
1065 if (oldmodels[i] != null)
1067 oldmfn[oldm++] = oldmodels[i];
1070 // deregister the Jmol instance for these structures - we'll add
1071 // ourselves again at the end for the current structure set.
1072 getSsm().removeStructureViewerListener(this, oldmfn);
1075 refreshPdbEntries();
1076 for (int modelnum = 0; modelnum < modelfilenames.length; modelnum++)
1078 String fileName = modelfilenames[modelnum];
1079 boolean foundEntry = false;
1080 StructureFile pdb = null;
1081 String pdbfile = null;
1082 // model was probably loaded inline - so check the pdb file hashcode
1085 // calculate essential attributes for the pdb data imported inline.
1086 // prolly need to resolve modelnumber properly - for now just use our
1088 pdbfile = viewer.getData("" + (1 + _modelFileNameMap[modelnum])
1091 // search pdbentries and sequences to find correct pdbentry for this
1093 for (int pe = 0; pe < getPdbCount(); pe++)
1095 boolean matches = false;
1096 addSequence(pe, getSequence()[pe]);
1097 if (fileName == null)
1100 // see JAL-623 - need method of matching pasted data up
1102 pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
1103 pdbfile, DataSourceType.PASTE);
1104 getPdbEntry(modelnum).setFile("INLINE" + pdb.getId());
1111 File fl = new File(getPdbEntry(pe).getFile());
1112 matches = fl.equals(new File(fileName));
1116 // TODO: Jmol can in principle retrieve from CLASSLOADER but
1119 // to be tested. See mantis bug
1120 // https://mantis.lifesci.dundee.ac.uk/view.php?id=36605
1121 DataSourceType protocol = DataSourceType.URL;
1126 protocol = DataSourceType.FILE;
1128 } catch (Exception e)
1133 // Explicitly map to the filename used by Jmol ;
1134 pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
1135 fileName, protocol);
1136 // pdbentry[pe].getFile(), protocol);
1142 // add an entry for every chain in the model
1143 for (int i = 0; i < pdb.getChains().size(); i++)
1145 String chid = new String(pdb.getId() + ":"
1146 + pdb.getChains().elementAt(i).id);
1147 chainFile.put(chid, fileName);
1148 chainNames.add(chid);
1150 notifyLoaded = true;
1154 if (!foundEntry && associateNewStructs)
1156 // this is a foreign pdb file that jalview doesn't know about - add
1157 // it to the dataset and try to find a home - either on a matching
1158 // sequence or as a new sequence.
1159 String pdbcontent = viewer.getData("/" + (modelnum + 1) + ".1",
1161 // parse pdb file into a chain, etc.
1162 // locate best match for pdb in associated views and add mapping to
1164 // if properly registered then
1165 notifyLoaded = true;
1170 // so finally, update the jmol bits and pieces
1171 // if (jmolpopup != null)
1173 // // potential for deadlock here:
1174 // // jmolpopup.updateComputedMenus();
1176 if (!isLoadingFromArchive())
1178 viewer.evalStringQuiet("model *; select backbone;restrict;cartoon;wireframe off;spacefill off");
1180 // register ourselves as a listener and notify the gui that it needs to
1182 getSsm().addStructureViewerListener(this);
1185 FeatureRenderer fr = getFeatureRenderer(null);
1191 loadNotifiesHandled++;
1193 setLoadingFromArchive(false);
1197 public List<String> getChainNames()
1202 public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)
1204 notifyAtomPicked(iatom, strMeasure, null);
1207 public abstract void notifyScriptTermination(String strStatus,
1211 * display a message echoed from the jmol viewer
1215 public abstract void sendConsoleEcho(String strEcho); /*
1216 * { showConsole(true);
1218 * history.append("\n" +
1222 // /End JmolStatusListener
1223 // /////////////////////////////
1227 * status message - usually the response received after a script
1230 public abstract void sendConsoleMessage(String strStatus);
1233 public void setCallbackFunction(String callbackType,
1234 String callbackFunction)
1236 System.err.println("Ignoring set-callback request to associate "
1237 + callbackType + " with function " + callbackFunction);
1242 public void setJalviewColourScheme(ColourSchemeI cs)
1244 colourBySequence = false;
1252 StringBuilder command = new StringBuilder(128);
1253 command.append("select *;color white;");
1254 List<String> residueSet = ResidueProperties.getResidues(isNucleotide(),
1256 for (String resName : residueSet)
1258 char res = resName.length() == 3 ? ResidueProperties
1259 .getSingleCharacterCode(resName) : resName.charAt(0);
1260 Color col = cs.findColour(res, 0, null, null, 0f);
1261 command.append("select " + resName + ";color[" + col.getRed() + ","
1262 + col.getGreen() + "," + col.getBlue() + "];");
1265 evalStateCommand(command.toString());
1269 public void showHelp()
1271 showUrl("http://jmol.sourceforge.net/docs/JmolUserGuide/", "jmolHelp");
1275 * open the URL somehow
1279 public abstract void showUrl(String url, String target);
1282 * called when the binding thinks the UI needs to be refreshed after a Jmol
1283 * state change. this could be because structures were loaded, or because an
1284 * error has occured.
1286 public abstract void refreshGUI();
1289 * called to show or hide the associated console window container.
1293 public abstract void showConsole(boolean show);
1296 * @param renderPanel
1298 * - when true will initialise jmol's file IO system (should be false
1299 * in applet context)
1301 * @param documentBase
1303 * @param commandOptions
1305 public void allocateViewer(Container renderPanel, boolean jmolfileio,
1306 String htmlName, URL documentBase, URL codeBase,
1307 String commandOptions)
1309 allocateViewer(renderPanel, jmolfileio, htmlName, documentBase,
1310 codeBase, commandOptions, null, null);
1315 * @param renderPanel
1317 * - when true will initialise jmol's file IO system (should be false
1318 * in applet context)
1320 * @param documentBase
1322 * @param commandOptions
1323 * @param consolePanel
1324 * - panel to contain Jmol console
1325 * @param buttonsToShow
1326 * - buttons to show on the console, in ordr
1328 public void allocateViewer(Container renderPanel, boolean jmolfileio,
1329 String htmlName, URL documentBase, URL codeBase,
1330 String commandOptions, final Container consolePanel,
1331 String buttonsToShow)
1333 if (commandOptions == null)
1335 commandOptions = "";
1337 viewer = (Viewer) JmolViewer.allocateViewer(renderPanel,
1338 (jmolfileio ? new SmarterJmolAdapter() : null), htmlName
1339 + ((Object) this).toString(), documentBase, codeBase,
1340 commandOptions, this);
1342 viewer.setJmolStatusListener(this); // extends JmolCallbackListener
1344 console = createJmolConsole(consolePanel, buttonsToShow);
1345 if (consolePanel != null)
1347 consolePanel.addComponentListener(this);
1353 protected abstract JmolAppConsoleInterface createJmolConsole(
1354 Container consolePanel, String buttonsToShow);
1356 protected org.jmol.api.JmolAppConsoleInterface console = null;
1359 public void setBackgroundColour(java.awt.Color col)
1362 viewer.evalStringQuiet("background [" + col.getRed() + ","
1363 + col.getGreen() + "," + col.getBlue() + "];");
1368 public int[] resizeInnerPanel(String data)
1370 // Jalview doesn't honour resize panel requests
1377 protected void closeConsole()
1379 if (console != null)
1383 console.setVisible(false);
1386 } catch (Exception x)
1395 * ComponentListener method
1398 public void componentMoved(ComponentEvent e)
1403 * ComponentListener method
1406 public void componentResized(ComponentEvent e)
1411 * ComponentListener method
1414 public void componentShown(ComponentEvent e)
1420 * ComponentListener method
1423 public void componentHidden(ComponentEvent e)