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;
38 import java.awt.Color;
39 import java.awt.Container;
40 import java.awt.event.ComponentEvent;
41 import java.awt.event.ComponentListener;
44 import java.security.AccessControlException;
45 import java.util.ArrayList;
46 import java.util.Hashtable;
47 import java.util.List;
49 import java.util.Vector;
51 import org.jmol.adapter.smarter.SmarterJmolAdapter;
52 import org.jmol.api.JmolAppConsoleInterface;
53 import org.jmol.api.JmolSelectionListener;
54 import org.jmol.api.JmolStatusListener;
55 import org.jmol.api.JmolViewer;
56 import org.jmol.c.CBK;
57 import org.jmol.script.T;
58 import org.jmol.viewer.Viewer;
60 public abstract class JalviewJmolBinding extends AAStructureBindingModel
61 implements JmolStatusListener, JmolSelectionListener,
64 boolean allChainsSelected = false;
67 * when true, try to search the associated datamodel for sequences that are
68 * associated with any unknown structures in the Jmol view.
70 private boolean associateNewStructs = false;
72 Vector<String> atomsPicked = new Vector<String>();
74 private List<String> chainNames;
76 Hashtable<String, String> chainFile;
79 * the default or current model displayed if the model cannot be identified
80 * from the selection message
84 // protected JmolGenericPopup jmolpopup; // not used - remove?
92 StringBuffer resetLastRes = new StringBuffer();
96 public JalviewJmolBinding(StructureSelectionManager ssm,
97 PDBEntry[] pdbentry, SequenceI[][] sequenceIs,
98 DataSourceType protocol)
100 super(ssm, pdbentry, sequenceIs, protocol);
102 * viewer = JmolViewer.allocateViewer(renderPanel, new SmarterJmolAdapter(),
103 * "jalviewJmol", ap.av.applet .getDocumentBase(),
104 * ap.av.applet.getCodeBase(), "", this);
106 * jmolpopup = JmolPopup.newJmolPopup(viewer, true, "Jmol", true);
110 public JalviewJmolBinding(StructureSelectionManager ssm,
111 SequenceI[][] seqs, Viewer theViewer)
116 viewer.setJmolStatusListener(this);
117 viewer.addSelectionListener(this);
121 * construct a title string for the viewer window based on the data jalview
126 public String getViewerTitle()
128 return getViewerTitle("Jmol", true);
132 * prepare the view for a given set of models/chains. chainList contains
133 * strings of the form 'pdbfilename:Chaincode'
136 * list of chains to make visible
138 public void centerViewer(Vector<String> chainList)
140 StringBuilder cmd = new StringBuilder(128);
142 for (String lbl : chainList)
148 mlength = lbl.indexOf(":", p);
149 } while (p < mlength && mlength < (lbl.length() - 2));
150 // TODO: lookup each pdb id and recover proper model number for it.
151 cmd.append(":" + lbl.substring(mlength + 1) + " /"
152 + (1 + getModelNum(chainFile.get(lbl))) + " or ");
154 if (cmd.length() > 0)
156 cmd.setLength(cmd.length() - 4);
158 evalStateCommand("select *;restrict " + cmd + ";cartoon;center " + cmd);
161 public void closeViewer()
163 // remove listeners for all structures in viewer
164 getSsm().removeStructureViewerListener(this, this.getPdbFile());
168 releaseUIResources();
171 public void colourByChain()
173 colourBySequence = false;
174 // TODO: colour by chain should colour each chain distinctly across all
176 // TODO: http://issues.jalview.org/browse/JAL-628
177 evalStateCommand("select *;color chain");
180 public void colourByCharge()
182 colourBySequence = false;
183 evalStateCommand("select *;color white;select ASP,GLU;color red;"
184 + "select LYS,ARG;color blue;select CYS;color yellow");
188 * superpose the structures associated with sequences in the alignment
189 * according to their corresponding positions.
191 public void superposeStructures(AlignmentI alignment)
193 superposeStructures(alignment, -1, null);
197 * superpose the structures associated with sequences in the alignment
198 * according to their corresponding positions. ded)
200 * @param refStructure
201 * - select which pdb file to use as reference (default is -1 - the
202 * first structure in the alignment)
204 public void superposeStructures(AlignmentI alignment, int refStructure)
206 superposeStructures(alignment, refStructure, null);
210 * superpose the structures associated with sequences in the alignment
211 * according to their corresponding positions. ded)
213 * @param refStructure
214 * - select which pdb file to use as reference (default is -1 - the
215 * first structure in the alignment)
219 public void superposeStructures(AlignmentI alignment, int refStructure,
220 ColumnSelection hiddenCols)
222 superposeStructures(new AlignmentI[] { alignment },
223 new int[] { refStructure },
224 new ColumnSelection[] { hiddenCols });
228 * Construct and send a command to align structures against a reference
229 * structure, based on one or more sequence alignments
232 * an array of alignments to process
233 * @param _refStructure
234 * an array of corresponding reference structures (index into pdb
235 * file array); if a negative value is passed, the first PDB file
236 * mapped to an alignment sequence is used as the reference for
239 * an array of corresponding hidden columns for each alignment
242 public void superposeStructures(AlignmentI[] _alignment,
243 int[] _refStructure, ColumnSelection[] _hiddenCols)
245 while (viewer.isScriptExecuting())
250 } catch (InterruptedException i)
256 * get the distinct structure files modelled
257 * (a file with multiple chains may map to multiple sequences)
259 String[] files = getPdbFile();
260 if (!waitForFileLoad(files))
265 StringBuilder selectioncom = new StringBuilder(256);
266 // In principle - nSeconds specifies the speed of animation for each
267 // superposition - but is seems to behave weirdly, so we don't specify it.
268 String nSeconds = " ";
269 if (files.length > 10)
271 nSeconds = " 0.005 ";
275 nSeconds = " " + (2.0 / files.length) + " ";
276 // if (nSeconds).substring(0,5)+" ";
278 // see JAL-1345 - should really automatically turn off the animation for
279 // large numbers of structures, but Jmol doesn't seem to allow that.
281 // union of all aligned positions are collected together.
282 for (int a = 0; a < _alignment.length; a++)
284 int refStructure = _refStructure[a];
285 AlignmentI alignment = _alignment[a];
286 ColumnSelection hiddenCols = _hiddenCols[a];
288 && selectioncom.length() > 0
289 && !selectioncom.substring(selectioncom.length() - 1).equals(
292 selectioncom.append("|");
294 // process this alignment
295 if (refStructure >= files.length)
297 System.err.println("Invalid reference structure value "
303 * 'matched' array will hold 'true' for visible alignment columns where
304 * all sequences have a residue with a mapping to the PDB structure
306 // TODO could use a BitSet for matched
307 boolean matched[] = new boolean[alignment.getWidth()];
308 for (int m = 0; m < matched.length; m++)
310 matched[m] = (hiddenCols != null) ? hiddenCols.isVisible(m) : true;
313 SuperposeData[] structures = new SuperposeData[files.length];
314 for (int f = 0; f < files.length; f++)
316 structures[f] = new SuperposeData(alignment.getWidth());
320 * Calculate the superposable alignment columns ('matched'), and the
321 * corresponding structure residue positions (structures.pdbResNo)
323 int candidateRefStructure = findSuperposableResidues(alignment,
324 matched, structures);
325 if (refStructure < 0)
328 * If no reference structure was specified, pick the first one that has
329 * a mapping in the alignment
331 refStructure = candidateRefStructure;
334 String[] selcom = new String[files.length];
336 for (boolean b : matched)
345 // TODO: bail out here because superposition illdefined?
349 * generate select statements to select regions to superimpose structures
352 // TODO extract method to construct selection statements
353 for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
355 String chainCd = ":" + structures[pdbfnum].chain;
358 StringBuilder molsel = new StringBuilder();
360 for (int r = 0; r < matched.length; r++)
364 int pdbResNo = structures[pdbfnum].pdbResNo[r];
365 if (lpos != pdbResNo - 1)
371 molsel.append(chainCd);
378 // continuous run - and lpos >-1
381 // at the beginning, so add dash
391 * add final selection phrase
396 molsel.append(chainCd);
399 if (molsel.length() > 1)
401 selcom[pdbfnum] = molsel.toString();
402 selectioncom.append("((");
403 selectioncom.append(selcom[pdbfnum].substring(1,
404 selcom[pdbfnum].length() - 1));
405 selectioncom.append(" )& ");
406 selectioncom.append(pdbfnum + 1);
407 selectioncom.append(".1)");
408 if (pdbfnum < files.length - 1)
410 selectioncom.append("|");
415 selcom[pdbfnum] = null;
419 StringBuilder command = new StringBuilder(256);
420 // command.append("set spinFps 10;\n");
422 for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
424 if (pdbfnum == refStructure || selcom[pdbfnum] == null
425 || selcom[refStructure] == null)
429 command.append("echo ");
430 command.append("\"Superposing (");
431 command.append(structures[pdbfnum].pdbId);
432 command.append(") against reference (");
433 command.append(structures[refStructure].pdbId);
434 command.append(")\";\ncompare " + nSeconds);
436 command.append(Integer.toString(1 + pdbfnum));
437 command.append(".1} {");
438 command.append(Integer.toString(1 + refStructure));
439 // conformation=1 excludes alternate locations for CA (JAL-1757)
440 command.append(".1} SUBSET {(*.CA | *.P) and conformation=1} ATOMS ");
442 // for (int s = 0; s < 2; s++)
444 // command.append(selcom[(s == 0 ? pdbfnum : refStructure)]);
446 command.append(selcom[pdbfnum]);
447 command.append(selcom[refStructure]);
448 command.append(" ROTATE TRANSLATE;\n");
450 if (selectioncom.length() > 0)
452 // TODO is performing selectioncom redundant here? is done later on
453 // System.out.println("Select regions:\n" + selectioncom.toString());
454 evalStateCommand("select *; cartoons off; backbone; select ("
455 + selectioncom.toString() + "); cartoons; ");
456 // selcom.append("; ribbons; ");
457 String cmdString = command.toString();
458 // System.out.println("Superimpose command(s):\n" + cmdString);
460 evalStateCommand(cmdString);
463 if (selectioncom.length() > 0)
464 {// finally, mark all regions that were superposed.
465 if (selectioncom.substring(selectioncom.length() - 1).equals("|"))
467 selectioncom.setLength(selectioncom.length() - 1);
469 // System.out.println("Select regions:\n" + selectioncom.toString());
470 evalStateCommand("select *; cartoons off; backbone; select ("
471 + selectioncom.toString() + "); cartoons; ");
472 // evalStateCommand("select *; backbone; select "+selcom.toString()+"; cartoons; center "+selcom.toString());
476 public void evalStateCommand(String command)
479 if (lastCommand == null || !lastCommand.equals(command))
481 viewer.evalStringQuiet(command + "\n");
484 lastCommand = command;
488 * Sends a set of colour commands to the structure viewer
490 * @param colourBySequenceCommands
493 protected void colourBySequence(
494 StructureMappingcommandSet[] colourBySequenceCommands)
496 for (StructureMappingcommandSet cpdbbyseq : colourBySequenceCommands)
498 for (String cbyseq : cpdbbyseq.commands)
500 executeWhenReady(cbyseq);
513 protected StructureMappingcommandSet[] getColourBySequenceCommands(
514 String[] files, SequenceRenderer sr, FeatureRenderer fr,
515 AlignmentI alignment)
517 return JmolCommands.getColourBySequenceCommand(getSsm(), files,
518 getSequence(), sr, fr, alignment);
524 protected void executeWhenReady(String command)
526 evalStateCommand(command);
529 public void createImage(String file, String type, int quality)
531 System.out.println("JMOL CREATE IMAGE");
535 public String createImage(String fileName, String type,
536 Object textOrBytes, int quality)
538 System.out.println("JMOL CREATE IMAGE");
543 public String eval(String strEval)
545 // System.out.println(strEval);
546 // "# 'eval' is implemented only for the applet.";
550 // End StructureListener
551 // //////////////////////////
554 public float[][] functionXY(String functionName, int x, int y)
560 public float[][][] functionXYZ(String functionName, int nx, int ny, int nz)
562 // TODO Auto-generated method stub
566 public Color getColour(int atomIndex, int pdbResNum, String chain,
569 if (getModelNum(pdbfile) < 0)
573 // TODO: verify atomIndex is selecting correct model.
574 // return new Color(viewer.getAtomArgb(atomIndex)); Jmol 12.2.4
575 int colour = viewer.ms.at[atomIndex].atomPropertyInt(T.color);
576 return new Color(colour);
580 * instruct the Jalview binding to update the pdbentries vector if necessary
581 * prior to matching the jmol view's contents to the list of structure files
582 * Jalview knows about.
584 public abstract void refreshPdbEntries();
586 private int getModelNum(String modelFileName)
588 String[] mfn = getPdbFile();
593 for (int i = 0; i < mfn.length; i++)
595 if (mfn[i].equalsIgnoreCase(modelFileName))
604 * map between index of model filename returned from getPdbFile and the first
605 * index of models from this file in the viewer. Note - this is not trimmed -
606 * use getPdbFile to get number of unique models.
608 private int _modelFileNameMap[];
610 // ////////////////////////////////
611 // /StructureListener
613 public synchronized String[] getPdbFile()
617 return new String[0];
619 if (modelFileNames == null)
621 List<String> mset = new ArrayList<String>();
622 _modelFileNameMap = new int[viewer.ms.mc];
623 String m = viewer.ms.getModelFileName(0);
629 filePath = new File(m).getAbsolutePath();
630 } catch (AccessControlException x)
632 // usually not allowed to do this in applet
634 .println("jmolBinding: Using local file string from Jmol: "
637 if (filePath.indexOf("/file:") != -1)
639 // applet path with docroot - discard as format won't match pdbfile
643 _modelFileNameMap[0] = 0; // filename index for first model is always 0.
646 for (int i = 1; i < viewer.ms.mc; i++)
648 m = viewer.ms.getModelFileName(i);
654 filePath = new File(m).getAbsolutePath();
655 } catch (AccessControlException x)
657 // usually not allowed to do this in applet, so keep raw handle
658 // System.err.println("jmolBinding: Using local file string from Jmol: "+m);
663 * add this model unless it is read from a structure file we have
664 * already seen (example: 2MJW is an NMR structure with 10 models)
666 if (!mset.contains(filePath))
669 _modelFileNameMap[j] = i; // record the model index for the filename
673 modelFileNames = mset.toArray(new String[mset.size()]);
675 return modelFileNames;
679 * map from string to applet
682 public Map<String, Object> getRegistryInfo()
684 // TODO Auto-generated method stub
690 // ///////////////////////////////
691 // JmolStatusListener
693 public void handlePopupMenu(int x, int y)
695 // jmolpopup.show(x, y);
696 // jmolpopup.jpiShow(x, y);
700 * Highlight zero, one or more atoms on the structure
703 public void highlightAtoms(List<AtomSpec> atoms)
707 if (resetLastRes.length() > 0)
709 viewer.evalStringQuiet(resetLastRes.toString());
710 resetLastRes.setLength(0);
712 for (AtomSpec atom : atoms)
714 highlightAtom(atom.getAtomIndex(), atom.getPdbResNum(),
715 atom.getChain(), atom.getPdbFile());
721 public void highlightAtom(int atomIndex, int pdbResNum, String chain,
724 if (modelFileNames == null)
729 // look up file model number for this pdbfile
731 // may need to adjust for URLencoding here - we don't worry about that yet.
732 while (mdlNum < modelFileNames.length
733 && !pdbfile.equals(modelFileNames[mdlNum]))
737 if (mdlNum == modelFileNames.length)
744 StringBuilder cmd = new StringBuilder(64);
745 cmd.append("select " + pdbResNum); // +modelNum
747 resetLastRes.append("select " + pdbResNum); // +modelNum
750 resetLastRes.append(":");
751 if (!chain.equals(" "))
754 resetLastRes.append(chain);
757 cmd.append(" /" + (mdlNum + 1));
758 resetLastRes.append("/" + (mdlNum + 1));
760 cmd.append(";wireframe 100;" + cmd.toString() + " and not hetero;");
762 resetLastRes.append(";wireframe 0;" + resetLastRes.toString()
763 + " and not hetero; spacefill 0;");
765 cmd.append("spacefill 200;select none");
767 viewer.evalStringQuiet(cmd.toString());
772 boolean debug = true;
774 private void jmolHistory(boolean enable)
776 viewer.evalStringQuiet("History " + ((debug || enable) ? "on" : "off"));
779 public void loadInline(String string)
783 // viewer.loadInline(strModel, isAppend);
785 // construct fake fullPathName and fileName so we can identify the file
787 // Then, construct pass a reader for the string to Jmol.
788 // ((org.jmol.Viewer.Viewer) viewer).loadModelFromFile(fullPathName,
789 // fileName, null, reader, false, null, null, 0);
790 viewer.openStringInline(string);
793 public void mouseOverStructure(int atomIndex, String strInfo)
796 int alocsep = strInfo.indexOf("^");
797 int mdlSep = strInfo.indexOf("/");
798 int chainSeparator = strInfo.indexOf(":"), chainSeparator1 = -1;
800 if (chainSeparator == -1)
802 chainSeparator = strInfo.indexOf(".");
803 if (mdlSep > -1 && mdlSep < chainSeparator)
805 chainSeparator1 = chainSeparator;
806 chainSeparator = mdlSep;
809 // handle insertion codes
812 pdbResNum = Integer.parseInt(strInfo.substring(
813 strInfo.indexOf("]") + 1, alocsep));
818 pdbResNum = Integer.parseInt(strInfo.substring(
819 strInfo.indexOf("]") + 1, chainSeparator));
823 if (strInfo.indexOf(":") > -1)
825 chainId = strInfo.substring(strInfo.indexOf(":") + 1,
826 strInfo.indexOf("."));
833 String pdbfilename = modelFileNames[frameNo]; // default is first or current
837 if (chainSeparator1 == -1)
839 chainSeparator1 = strInfo.indexOf(".", mdlSep);
841 String mdlId = (chainSeparator1 > -1) ? strInfo.substring(mdlSep + 1,
842 chainSeparator1) : strInfo.substring(mdlSep + 1);
845 // recover PDB filename for the model hovered over.
846 int _mp = _modelFileNameMap.length - 1, mnumber = new Integer(mdlId)
848 while (mnumber < _modelFileNameMap[_mp])
852 pdbfilename = modelFileNames[_mp];
853 if (pdbfilename == null)
855 pdbfilename = new File(viewer.ms.getModelFileName(mnumber))
859 } catch (Exception e)
864 if (lastMessage == null || !lastMessage.equals(strInfo))
866 getSsm().mouseOverStructure(pdbResNum, chainId, pdbfilename);
869 lastMessage = strInfo;
872 public void notifyAtomHovered(int atomIndex, String strInfo, String data)
876 System.err.println("Ignoring additional hover info: " + data
877 + " (other info: '" + strInfo + "' pos " + atomIndex + ")");
879 mouseOverStructure(atomIndex, strInfo);
883 * { if (history != null && strStatus != null &&
884 * !strStatus.equals("Script completed")) { history.append("\n" + strStatus);
888 public void notifyAtomPicked(int atomIndex, String strInfo, String strData)
891 * this implements the toggle label behaviour copied from the original
892 * structure viewer, MCView
896 System.err.println("Ignoring additional pick data string " + strData);
898 int chainSeparator = strInfo.indexOf(":");
900 if (chainSeparator == -1)
902 chainSeparator = strInfo.indexOf(".");
905 String picked = strInfo.substring(strInfo.indexOf("]") + 1,
907 String mdlString = "";
908 if ((p = strInfo.indexOf(":")) > -1)
910 picked += strInfo.substring(p, strInfo.indexOf("."));
913 if ((p = strInfo.indexOf("/")) > -1)
915 mdlString += strInfo.substring(p, strInfo.indexOf(" #"));
917 picked = "((" + picked + ".CA" + mdlString + ")|(" + picked + ".P"
921 if (!atomsPicked.contains(picked))
923 viewer.evalStringQuiet("select " + picked + ";label %n %r:%c");
924 atomsPicked.addElement(picked);
928 viewer.evalString("select " + picked + ";label off");
929 atomsPicked.removeElement(picked);
932 // TODO: in application this happens
934 // if (scriptWindow != null)
936 // scriptWindow.sendConsoleMessage(strInfo);
937 // scriptWindow.sendConsoleMessage("\n");
943 public void notifyCallback(CBK type, Object[] data)
950 notifyFileLoaded((String) data[1], (String) data[2],
951 (String) data[3], (String) data[4],
952 ((Integer) data[5]).intValue());
956 notifyAtomPicked(((Integer) data[2]).intValue(), (String) data[1],
958 // also highlight in alignment
960 notifyAtomHovered(((Integer) data[2]).intValue(), (String) data[1],
964 notifyScriptTermination((String) data[2],
965 ((Integer) data[3]).intValue());
968 sendConsoleEcho((String) data[1]);
971 sendConsoleMessage((data == null) ? ((String) null)
975 // System.err.println("Ignoring error callback.");
985 System.err.println("Unhandled callback " + type + " "
986 + data[1].toString());
989 } catch (Exception e)
991 System.err.println("Squashed Jmol callback handler error:");
997 public boolean notifyEnabled(CBK callbackPick)
999 switch (callbackPick)
1015 // incremented every time a load notification is successfully handled -
1016 // lightweight mechanism for other threads to detect when they can start
1017 // referrring to new structures.
1018 private long loadNotifiesHandled = 0;
1020 public long getLoadNotifiesHandled()
1022 return loadNotifiesHandled;
1025 public void notifyFileLoaded(String fullPathName, String fileName2,
1026 String modelName, String errorMsg, int modelParts)
1028 if (errorMsg != null)
1030 fileLoadingError = errorMsg;
1034 // TODO: deal sensibly with models loaded inLine:
1035 // modelName will be null, as will fullPathName.
1037 // the rest of this routine ignores the arguments, and simply interrogates
1038 // the Jmol view to find out what structures it contains, and adds them to
1039 // the structure selection manager.
1040 fileLoadingError = null;
1041 String[] oldmodels = modelFileNames;
1042 modelFileNames = null;
1043 chainNames = new ArrayList<String>();
1044 chainFile = new Hashtable<String, String>();
1045 boolean notifyLoaded = false;
1046 String[] modelfilenames = getPdbFile();
1047 // first check if we've lost any structures
1048 if (oldmodels != null && oldmodels.length > 0)
1051 for (int i = 0; i < oldmodels.length; i++)
1053 for (int n = 0; n < modelfilenames.length; n++)
1055 if (modelfilenames[n] == oldmodels[i])
1057 oldmodels[i] = null;
1061 if (oldmodels[i] != null)
1068 String[] oldmfn = new String[oldm];
1070 for (int i = 0; i < oldmodels.length; i++)
1072 if (oldmodels[i] != null)
1074 oldmfn[oldm++] = oldmodels[i];
1077 // deregister the Jmol instance for these structures - we'll add
1078 // ourselves again at the end for the current structure set.
1079 getSsm().removeStructureViewerListener(this, oldmfn);
1082 refreshPdbEntries();
1083 for (int modelnum = 0; modelnum < modelfilenames.length; modelnum++)
1085 String fileName = modelfilenames[modelnum];
1086 boolean foundEntry = false;
1087 StructureFile pdb = null;
1088 String pdbfile = null;
1089 // model was probably loaded inline - so check the pdb file hashcode
1092 // calculate essential attributes for the pdb data imported inline.
1093 // prolly need to resolve modelnumber properly - for now just use our
1095 pdbfile = viewer.getData("" + (1 + _modelFileNameMap[modelnum])
1098 // search pdbentries and sequences to find correct pdbentry for this
1100 for (int pe = 0; pe < getPdbCount(); pe++)
1102 boolean matches = false;
1103 addSequence(pe, getSequence()[pe]);
1104 if (fileName == null)
1107 // see JAL-623 - need method of matching pasted data up
1109 pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
1110 pdbfile, DataSourceType.PASTE);
1111 getPdbEntry(modelnum).setFile("INLINE" + pdb.getId());
1118 File fl = new File(getPdbEntry(pe).getFile());
1119 matches = fl.equals(new File(fileName));
1123 // TODO: Jmol can in principle retrieve from CLASSLOADER but
1126 // to be tested. See mantis bug
1127 // https://mantis.lifesci.dundee.ac.uk/view.php?id=36605
1128 DataSourceType protocol = DataSourceType.URL;
1133 protocol = DataSourceType.FILE;
1135 } catch (Exception e)
1140 // Explicitly map to the filename used by Jmol ;
1141 pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
1142 fileName, protocol);
1143 // pdbentry[pe].getFile(), protocol);
1149 // add an entry for every chain in the model
1150 for (int i = 0; i < pdb.getChains().size(); i++)
1152 String chid = new String(pdb.getId() + ":"
1153 + pdb.getChains().elementAt(i).id);
1154 chainFile.put(chid, fileName);
1155 chainNames.add(chid);
1157 notifyLoaded = true;
1161 if (!foundEntry && associateNewStructs)
1163 // this is a foreign pdb file that jalview doesn't know about - add
1164 // it to the dataset and try to find a home - either on a matching
1165 // sequence or as a new sequence.
1166 String pdbcontent = viewer.getData("/" + (modelnum + 1) + ".1",
1168 // parse pdb file into a chain, etc.
1169 // locate best match for pdb in associated views and add mapping to
1171 // if properly registered then
1172 notifyLoaded = true;
1177 // so finally, update the jmol bits and pieces
1178 // if (jmolpopup != null)
1180 // // potential for deadlock here:
1181 // // jmolpopup.updateComputedMenus();
1183 if (!isLoadingFromArchive())
1185 viewer.evalStringQuiet("model *; select backbone;restrict;cartoon;wireframe off;spacefill off");
1187 // register ourselves as a listener and notify the gui that it needs to
1189 getSsm().addStructureViewerListener(this);
1192 FeatureRenderer fr = getFeatureRenderer(null);
1198 loadNotifiesHandled++;
1200 setLoadingFromArchive(false);
1204 public List<String> getChainNames()
1209 public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)
1211 notifyAtomPicked(iatom, strMeasure, null);
1214 public abstract void notifyScriptTermination(String strStatus,
1218 * display a message echoed from the jmol viewer
1222 public abstract void sendConsoleEcho(String strEcho); /*
1223 * { showConsole(true);
1225 * history.append("\n" +
1229 // /End JmolStatusListener
1230 // /////////////////////////////
1234 * status message - usually the response received after a script
1237 public abstract void sendConsoleMessage(String strStatus);
1240 public void setCallbackFunction(String callbackType,
1241 String callbackFunction)
1243 System.err.println("Ignoring set-callback request to associate "
1244 + callbackType + " with function " + callbackFunction);
1249 public void setJalviewColourScheme(ColourSchemeI cs)
1251 colourBySequence = false;
1259 StringBuilder command = new StringBuilder(128);
1260 command.append("select *;color white;");
1261 List<String> residueSet = ResidueProperties.getResidues(isNucleotide(),
1263 for (String resName : residueSet)
1265 char res = resName.length() == 3 ? ResidueProperties
1266 .getSingleCharacterCode(resName) : resName.charAt(0);
1267 Color col = cs.findColour(res);
1268 command.append("select " + resName + ";color[" + col.getRed() + ","
1269 + col.getGreen() + "," + col.getBlue() + "];");
1272 evalStateCommand(command.toString());
1276 public void showHelp()
1278 showUrl("http://jmol.sourceforge.net/docs/JmolUserGuide/", "jmolHelp");
1282 * open the URL somehow
1286 public abstract void showUrl(String url, String target);
1289 * called when the binding thinks the UI needs to be refreshed after a Jmol
1290 * state change. this could be because structures were loaded, or because an
1291 * error has occured.
1293 public abstract void refreshGUI();
1296 * called to show or hide the associated console window container.
1300 public abstract void showConsole(boolean show);
1303 * @param renderPanel
1305 * - when true will initialise jmol's file IO system (should be false
1306 * in applet context)
1308 * @param documentBase
1310 * @param commandOptions
1312 public void allocateViewer(Container renderPanel, boolean jmolfileio,
1313 String htmlName, URL documentBase, URL codeBase,
1314 String commandOptions)
1316 allocateViewer(renderPanel, jmolfileio, htmlName, documentBase,
1317 codeBase, commandOptions, null, null);
1322 * @param renderPanel
1324 * - when true will initialise jmol's file IO system (should be false
1325 * in applet context)
1327 * @param documentBase
1329 * @param commandOptions
1330 * @param consolePanel
1331 * - panel to contain Jmol console
1332 * @param buttonsToShow
1333 * - buttons to show on the console, in ordr
1335 public void allocateViewer(Container renderPanel, boolean jmolfileio,
1336 String htmlName, URL documentBase, URL codeBase,
1337 String commandOptions, final Container consolePanel,
1338 String buttonsToShow)
1340 if (commandOptions == null)
1342 commandOptions = "";
1344 viewer = (Viewer) JmolViewer.allocateViewer(renderPanel,
1345 (jmolfileio ? new SmarterJmolAdapter() : null), htmlName
1346 + ((Object) this).toString(), documentBase, codeBase,
1347 commandOptions, this);
1349 viewer.setJmolStatusListener(this); // extends JmolCallbackListener
1351 console = createJmolConsole(consolePanel, buttonsToShow);
1352 if (consolePanel != null)
1354 consolePanel.addComponentListener(this);
1360 protected abstract JmolAppConsoleInterface createJmolConsole(
1361 Container consolePanel, String buttonsToShow);
1363 protected org.jmol.api.JmolAppConsoleInterface console = null;
1366 public void setBackgroundColour(java.awt.Color col)
1369 viewer.evalStringQuiet("background [" + col.getRed() + ","
1370 + col.getGreen() + "," + col.getBlue() + "];");
1375 public int[] resizeInnerPanel(String data)
1377 // Jalview doesn't honour resize panel requests
1384 protected void closeConsole()
1386 if (console != null)
1390 console.setVisible(false);
1393 } catch (Exception x)
1402 * ComponentListener method
1405 public void componentMoved(ComponentEvent e)
1410 * ComponentListener method
1413 public void componentResized(ComponentEvent e)
1418 * ComponentListener method
1421 public void componentShown(ComponentEvent e)
1427 * ComponentListener method
1430 public void componentHidden(ComponentEvent e)