2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
21 package jalview.ext.jmol;
23 import jalview.api.AlignmentViewPanel;
24 import jalview.api.FeatureRenderer;
25 import jalview.api.SequenceRenderer;
26 import jalview.datamodel.AlignmentI;
27 import jalview.datamodel.ColumnSelection;
28 import jalview.datamodel.PDBEntry;
29 import jalview.datamodel.SequenceI;
30 import jalview.io.AppletFormatAdapter;
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.Hashtable;
46 import java.util.List;
48 import java.util.Vector;
50 import javajs.awt.Dimension;
52 import org.jmol.adapter.smarter.SmarterJmolAdapter;
53 import org.jmol.api.JmolAppConsoleInterface;
54 import org.jmol.api.JmolSelectionListener;
55 import org.jmol.api.JmolStatusListener;
56 import org.jmol.api.JmolViewer;
57 import org.jmol.c.CBK;
58 import org.jmol.script.T;
59 import org.jmol.viewer.JC;
60 import org.jmol.viewer.Viewer;
62 public abstract class JalviewJmolBinding extends AAStructureBindingModel
63 implements JmolStatusListener, JmolSelectionListener,
67 * state flag used to check if the Jmol viewer's paint method can be called
69 private boolean finishedInit = false;
71 boolean allChainsSelected = false;
74 * when true, try to search the associated datamodel for sequences that are
75 * associated with any unknown structures in the Jmol view.
77 private boolean associateNewStructs = false;
79 Vector<String> atomsPicked = new Vector<String>();
81 public Vector<String> chainNames;
83 Hashtable<String, String> chainFile;
85 public String fileLoadingError;
88 * the default or current model displayed if the model cannot be identified
89 * from the selection message
93 // protected JmolGenericPopup jmolpopup; // not used - remove?
102 * current set of model filenames loaded in the Jmol instance
104 String[] modelFileNames = null;
106 StringBuffer resetLastRes = new StringBuffer();
108 public Viewer viewer;
110 public JalviewJmolBinding(StructureSelectionManager ssm,
111 PDBEntry[] pdbentry, SequenceI[][] sequenceIs, String[][] chains,
114 super(ssm, pdbentry, sequenceIs, chains, protocol);
116 * viewer = JmolViewer.allocateViewer(renderPanel, new SmarterJmolAdapter(),
117 * "jalviewJmol", ap.av.applet .getDocumentBase(),
118 * ap.av.applet.getCodeBase(), "", this);
120 * jmolpopup = JmolPopup.newJmolPopup(viewer, true, "Jmol", true);
124 public JalviewJmolBinding(StructureSelectionManager ssm,
125 SequenceI[][] seqs, Viewer theViewer)
130 viewer.setJmolStatusListener(this);
131 viewer.addSelectionListener(this);
135 * construct a title string for the viewer window based on the data jalview
140 public String getViewerTitle()
142 return getViewerTitle("Jmol", true);
146 * prepare the view for a given set of models/chains. chainList contains
147 * strings of the form 'pdbfilename:Chaincode'
150 * list of chains to make visible
152 public void centerViewer(Vector<String> chainList)
154 StringBuilder cmd = new StringBuilder(128);
156 for (String lbl : chainList)
162 mlength = lbl.indexOf(":", p);
163 } while (p < mlength && mlength < (lbl.length() - 2));
164 // TODO: lookup each pdb id and recover proper model number for it.
165 cmd.append(":" + lbl.substring(mlength + 1) + " /"
166 + (1 + getModelNum(chainFile.get(lbl))) + " or ");
168 if (cmd.length() > 0)
170 cmd.setLength(cmd.length() - 4);
172 evalStateCommand("select *;restrict " + cmd + ";cartoon;center " + cmd);
175 public void closeViewer()
177 viewer.acm.setModeMouse(JC.MOUSE_NONE);
178 // remove listeners for all structures in viewer
179 getSsm().removeStructureViewerListener(this, this.getPdbFile());
180 // and shut down jmol
181 viewer.evalStringQuiet("zap");
182 viewer.setJmolStatusListener(null);
185 releaseUIResources();
188 public void colourByChain()
190 colourBySequence = false;
191 // TODO: colour by chain should colour each chain distinctly across all
193 // TODO: http://issues.jalview.org/browse/JAL-628
194 evalStateCommand("select *;color chain");
197 public void colourByCharge()
199 colourBySequence = false;
200 evalStateCommand("select *;color white;select ASP,GLU;color red;"
201 + "select LYS,ARG;color blue;select CYS;color yellow");
205 * superpose the structures associated with sequences in the alignment
206 * according to their corresponding positions.
208 public void superposeStructures(AlignmentI alignment)
210 superposeStructures(alignment, -1, 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)
221 public void superposeStructures(AlignmentI alignment, int refStructure)
223 superposeStructures(alignment, refStructure, null);
227 * superpose the structures associated with sequences in the alignment
228 * according to their corresponding positions. ded)
230 * @param refStructure
231 * - select which pdb file to use as reference (default is -1 - the
232 * first structure in the alignment)
236 public void superposeStructures(AlignmentI alignment, int refStructure,
237 ColumnSelection hiddenCols)
239 superposeStructures(new AlignmentI[]
240 { alignment }, new int[]
241 { refStructure }, new ColumnSelection[]
246 * Construct and send a command to align structures against a reference
247 * structure, based on one or more sequence alignments
250 * an array of alignments to process
251 * @param _refStructure
252 * an array of corresponding reference structures (index into pdb
253 * file array); if a negative value is passed, the first PDB file
254 * mapped to an alignment sequence is used as the reference for
257 * an array of corresponding hidden columns for each alignment
259 public void superposeStructures(AlignmentI[] _alignment,
260 int[] _refStructure, ColumnSelection[] _hiddenCols)
262 while (viewer.isScriptExecuting())
267 } catch (InterruptedException i)
272 String[] files = getPdbFile();
273 if (!waitForFileLoad(files))
278 StringBuilder selectioncom = new StringBuilder(256);
279 // In principle - nSeconds specifies the speed of animation for each
280 // superposition - but is seems to behave weirdly, so we don't specify it.
281 String nSeconds = " ";
282 if (files.length > 10)
284 nSeconds = " 0.005 ";
288 nSeconds = " " + (2.0 / files.length) + " ";
289 // if (nSeconds).substring(0,5)+" ";
291 // see JAL-1345 - should really automatically turn off the animation for
292 // large numbers of structures, but Jmol doesn't seem to allow that.
294 // union of all aligned positions are collected together.
295 for (int a = 0; a < _alignment.length; a++)
297 int refStructure = _refStructure[a];
298 AlignmentI alignment = _alignment[a];
299 ColumnSelection hiddenCols = _hiddenCols[a];
301 && selectioncom.length() > 0
302 && !selectioncom.substring(selectioncom.length() - 1).equals(
305 selectioncom.append("|");
307 // process this alignment
308 if (refStructure >= files.length)
310 System.err.println("Invalid reference structure value "
316 * 'matched' array will hold 'true' for visible alignment columns where
317 * all sequences have a residue with a mapping to the PDB structure
319 boolean matched[] = new boolean[alignment.getWidth()];
320 for (int m = 0; m < matched.length; m++)
322 matched[m] = (hiddenCols != null) ? hiddenCols.isVisible(m) : true;
325 SuperposeData[] structures = new SuperposeData[files.length];
326 for (int f = 0; f < files.length; f++)
328 structures[f] = new SuperposeData(alignment.getWidth());
332 * Calculate the superposable alignment columns ('matched'), and the
333 * corresponding structure residue positions (structures.pdbResNo)
335 int candidateRefStructure = findSuperposableResidues(alignment,
336 matched, structures);
337 if (refStructure < 0)
340 * If no reference structure was specified, pick the first one that has
341 * a mapping in the alignment
343 refStructure = candidateRefStructure;
346 String[] selcom = new String[files.length];
348 for (boolean b : matched)
357 // TODO: bail out here because superposition illdefined?
361 * generate select statements to select regions to superimpose structures
364 for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
366 String chainCd = ":" + structures[pdbfnum].chain;
369 StringBuilder molsel = new StringBuilder();
371 for (int r = 0; r < matched.length; r++)
375 int pdbResNo = structures[pdbfnum].pdbResNo[r];
376 if (lpos != pdbResNo - 1)
382 molsel.append(chainCd);
389 // continuous run - and lpos >-1
392 // at the beginning, so add dash
402 * add final selection phrase
407 molsel.append(chainCd);
410 if (molsel.length() > 1)
412 selcom[pdbfnum] = molsel.toString();
413 selectioncom.append("((");
414 selectioncom.append(selcom[pdbfnum].substring(1,
415 selcom[pdbfnum].length() - 1));
416 selectioncom.append(" )& ");
417 selectioncom.append(pdbfnum + 1);
418 selectioncom.append(".1)");
419 if (pdbfnum < files.length - 1)
421 selectioncom.append("|");
426 selcom[pdbfnum] = null;
430 StringBuilder command = new StringBuilder(256);
431 for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
433 if (pdbfnum == refStructure || selcom[pdbfnum] == null
434 || selcom[refStructure] == null)
438 command.append("echo ");
439 command.append("\"Superposing (");
440 command.append(structures[pdbfnum].pdbId);
441 command.append(") against reference (");
442 command.append(structures[refStructure].pdbId);
443 command.append(")\";\ncompare " + nSeconds);
445 command.append(Integer.toString(1 + pdbfnum));
446 command.append(".1} {");
447 command.append(Integer.toString(1 + refStructure));
448 // conformation=1 excludes alternate locations for CA (JAL-1757)
449 command.append(".1} SUBSET {(*.CA | *.P) and conformation=1} ATOMS ");
451 // for (int s = 0; s < 2; s++)
453 // command.append(selcom[(s == 0 ? pdbfnum : refStructure)]);
455 command.append(selcom[pdbfnum]);
456 command.append(selcom[refStructure]);
457 command.append(" ROTATE TRANSLATE;\n");
459 if (selectioncom.length() > 0)
461 System.out.println("Select regions:\n" + selectioncom.toString());
462 evalStateCommand("select *; cartoons off; backbone; select ("
463 + selectioncom.toString() + "); cartoons; ");
464 // selcom.append("; ribbons; ");
465 String cmdString = command.toString();
467 .println("Superimpose command(s):\n" + cmdString);
469 evalStateCommand(cmdString);
472 if (selectioncom.length() > 0)
473 {// finally, mark all regions that were superposed.
474 if (selectioncom.substring(selectioncom.length() - 1).equals("|"))
476 selectioncom.setLength(selectioncom.length() - 1);
478 System.out.println("Select regions:\n" + selectioncom.toString());
479 evalStateCommand("select *; cartoons off; backbone; select ("
480 + selectioncom.toString() + "); cartoons; ");
481 // evalStateCommand("select *; backbone; select "+selcom.toString()+"; cartoons; center "+selcom.toString());
485 public void evalStateCommand(String command)
488 if (lastCommand == null || !lastCommand.equals(command))
490 viewer.evalStringQuiet(command + "\n");
493 lastCommand = command;
497 * colour any structures associated with sequences in the given alignment
498 * using the getFeatureRenderer() and getSequenceRenderer() renderers but only
499 * if colourBySequence is enabled.
501 public void colourBySequence(AlignmentViewPanel alignmentv)
503 boolean showFeatures = alignmentv.getAlignViewport()
504 .isShowSequenceFeatures();
505 if (!colourBySequence || !isLoadingFinished())
509 if (getSsm() == null)
513 String[] files = getPdbFile();
515 SequenceRenderer sr = getSequenceRenderer(alignmentv);
517 FeatureRenderer fr = null;
520 fr = getFeatureRenderer(alignmentv);
522 AlignmentI alignment = alignmentv.getAlignment();
524 for (jalview.structure.StructureMappingcommandSet cpdbbyseq : getColourBySequenceCommands(files, sr, fr, alignment))
526 for (String cbyseq : cpdbbyseq.commands)
528 executeWhenReady(cbyseq);
540 protected StructureMappingcommandSet[] getColourBySequenceCommands(
541 String[] files, SequenceRenderer sr, FeatureRenderer fr,
542 AlignmentI alignment)
545 .getColourBySequenceCommand(getSsm(), files, getSequence(), sr,
553 protected void executeWhenReady(String command)
555 evalStateCommand(command);
558 public void createImage(String file, String type, int quality)
560 System.out.println("JMOL CREATE IMAGE");
563 public String createImage(String fileName, String type,
564 Object textOrBytes, int quality)
566 System.out.println("JMOL CREATE IMAGE");
570 public String eval(String strEval)
572 // System.out.println(strEval);
573 // "# 'eval' is implemented only for the applet.";
577 // End StructureListener
578 // //////////////////////////
580 public float[][] functionXY(String functionName, int x, int y)
585 public float[][][] functionXYZ(String functionName, int nx, int ny, int nz)
587 // TODO Auto-generated method stub
591 public Color getColour(int atomIndex, int pdbResNum, String chain,
594 if (getModelNum(pdbfile) < 0)
598 // TODO: verify atomIndex is selecting correct model.
599 // return new Color(viewer.getAtomArgb(atomIndex)); Jmol 12.2.4
600 int colour = viewer.ms.at[atomIndex]
601 .atomPropertyInt(T.color);
602 return new Color(colour);
606 * returns the current featureRenderer that should be used to colour the
613 public abstract FeatureRenderer getFeatureRenderer(
614 AlignmentViewPanel alignment);
617 * instruct the Jalview binding to update the pdbentries vector if necessary
618 * prior to matching the jmol view's contents to the list of structure files
619 * Jalview knows about.
621 public abstract void refreshPdbEntries();
623 private int getModelNum(String modelFileName)
625 String[] mfn = getPdbFile();
630 for (int i = 0; i < mfn.length; i++)
632 if (mfn[i].equalsIgnoreCase(modelFileName))
641 * map between index of model filename returned from getPdbFile and the first
642 * index of models from this file in the viewer. Note - this is not trimmed -
643 * use getPdbFile to get number of unique models.
645 private int _modelFileNameMap[];
647 // ////////////////////////////////
648 // /StructureListener
650 public synchronized String[] getPdbFile()
654 return new String[0];
656 if (modelFileNames == null)
658 String mset[] = new String[viewer.ms.mc];
659 _modelFileNameMap = new int[mset.length];
660 String m = viewer.ms.getModelFileName(0);
666 mset[0] = new File(m).getAbsolutePath();
667 } catch (AccessControlException x)
669 // usually not allowed to do this in applet
671 .println("jmolBinding: Using local file string from Jmol: "
674 if (mset[0].indexOf("/file:") != -1)
676 // applet path with docroot - discard as format won't match pdbfile
679 _modelFileNameMap[0] = 0; // filename index for first model is always 0.
682 for (int i = 1; i < mset.length; i++)
684 m = viewer.ms.getModelFileName(i);
690 mset[j] = new File(m).getAbsolutePath();
691 } catch (AccessControlException x)
693 // usually not allowed to do this in applet, so keep raw handle
694 // System.err.println("jmolBinding: Using local file string from Jmol: "+m);
697 _modelFileNameMap[j] = i; // record the model index for the filename
698 // skip any additional models in the same file (NMR structures)
699 if ((mset[j] == null ? mset[j] != mset[j - 1]
700 : (mset[j - 1] == null || !mset[j].equals(mset[j - 1]))))
705 modelFileNames = new String[j];
706 System.arraycopy(mset, 0, modelFileNames, 0, j);
708 return modelFileNames;
712 * map from string to applet
715 public Map<String, Object> getRegistryInfo()
717 // TODO Auto-generated method stub
722 * returns the current sequenceRenderer that should be used to colour the
729 public abstract SequenceRenderer getSequenceRenderer(
730 AlignmentViewPanel alignment);
732 // ///////////////////////////////
733 // JmolStatusListener
735 public void handlePopupMenu(int x, int y)
737 // jmolpopup.show(x, y);
738 // jmolpopup.jpiShow(x, y);
742 * Highlight zero, one or more atoms on the structure
745 public void highlightAtoms(List<AtomSpec> atoms)
749 for (AtomSpec atom : atoms)
751 highlightAtom(atom.getAtomIndex(), atom.getPdbResNum(),
752 atom.getChain(), atom.getPdbFile());
758 public void highlightAtom(int atomIndex, int pdbResNum, String chain,
761 if (modelFileNames == null)
766 // look up file model number for this pdbfile
768 // may need to adjust for URLencoding here - we don't worry about that yet.
769 while (mdlNum < modelFileNames.length
770 && !pdbfile.equals(modelFileNames[mdlNum]))
774 if (mdlNum == modelFileNames.length)
780 // if (!pdbfile.equals(pdbentry.getFile()))
782 if (resetLastRes.length() > 0)
784 viewer.evalStringQuiet(resetLastRes.toString());
787 StringBuilder cmd = new StringBuilder(64);
788 cmd.append("select " + pdbResNum); // +modelNum
790 resetLastRes.setLength(0);
791 resetLastRes.append("select " + pdbResNum); // +modelNum
794 resetLastRes.append(":");
795 if (!chain.equals(" "))
798 resetLastRes.append(chain);
801 cmd.append(" /" + (mdlNum + 1));
802 resetLastRes.append("/" + (mdlNum + 1));
804 cmd.append(";wireframe 100;" + cmd.toString() + " and not hetero;");
806 resetLastRes.append(";wireframe 0;" + resetLastRes.toString()
807 + " and not hetero; spacefill 0;");
809 cmd.append("spacefill 200;select none");
811 viewer.evalStringQuiet(cmd.toString());
816 boolean debug = true;
818 private void jmolHistory(boolean enable)
820 viewer.evalStringQuiet("History " + ((debug || enable) ? "on" : "off"));
823 public void loadInline(String string)
827 // viewer.loadInline(strModel, isAppend);
829 // construct fake fullPathName and fileName so we can identify the file
831 // Then, construct pass a reader for the string to Jmol.
832 // ((org.jmol.Viewer.Viewer) viewer).loadModelFromFile(fullPathName,
833 // fileName, null, reader, false, null, null, 0);
834 viewer.openStringInline(string);
837 public void mouseOverStructure(int atomIndex, String strInfo)
840 int alocsep = strInfo.indexOf("^");
841 int mdlSep = strInfo.indexOf("/");
842 int chainSeparator = strInfo.indexOf(":"), chainSeparator1 = -1;
844 if (chainSeparator == -1)
846 chainSeparator = strInfo.indexOf(".");
847 if (mdlSep > -1 && mdlSep < chainSeparator)
849 chainSeparator1 = chainSeparator;
850 chainSeparator = mdlSep;
853 // handle insertion codes
856 pdbResNum = Integer.parseInt(strInfo.substring(
857 strInfo.indexOf("]") + 1, alocsep));
862 pdbResNum = Integer.parseInt(strInfo.substring(
863 strInfo.indexOf("]") + 1, chainSeparator));
867 if (strInfo.indexOf(":") > -1)
869 chainId = strInfo.substring(strInfo.indexOf(":") + 1,
870 strInfo.indexOf("."));
877 String pdbfilename = modelFileNames[frameNo]; // default is first or current
881 if (chainSeparator1 == -1)
883 chainSeparator1 = strInfo.indexOf(".", mdlSep);
885 String mdlId = (chainSeparator1 > -1) ? strInfo.substring(mdlSep + 1,
886 chainSeparator1) : strInfo.substring(mdlSep + 1);
889 // recover PDB filename for the model hovered over.
890 int _mp = _modelFileNameMap.length - 1, mnumber = new Integer(mdlId)
892 while (mnumber < _modelFileNameMap[_mp])
896 pdbfilename = modelFileNames[_mp];
897 if (pdbfilename == null)
899 pdbfilename = new File(
900 viewer.ms.getModelFileName(mnumber))
904 } catch (Exception e)
909 if (lastMessage == null || !lastMessage.equals(strInfo))
911 getSsm().mouseOverStructure(pdbResNum, chainId, pdbfilename);
914 lastMessage = strInfo;
917 public void notifyAtomHovered(int atomIndex, String strInfo, String data)
921 System.err.println("Ignoring additional hover info: " + data
922 + " (other info: '" + strInfo + "' pos " + atomIndex + ")");
924 mouseOverStructure(atomIndex, strInfo);
928 * { if (history != null && strStatus != null &&
929 * !strStatus.equals("Script completed")) { history.append("\n" + strStatus);
933 public void notifyAtomPicked(int atomIndex, String strInfo, String strData)
936 * this implements the toggle label behaviour copied from the original
937 * structure viewer, MCView
941 System.err.println("Ignoring additional pick data string " + strData);
943 int chainSeparator = strInfo.indexOf(":");
945 if (chainSeparator == -1)
947 chainSeparator = strInfo.indexOf(".");
950 String picked = strInfo.substring(strInfo.indexOf("]") + 1,
952 String mdlString = "";
953 if ((p = strInfo.indexOf(":")) > -1)
955 picked += strInfo.substring(p + 1, strInfo.indexOf("."));
958 if ((p = strInfo.indexOf("/")) > -1)
960 mdlString += strInfo.substring(p, strInfo.indexOf(" #"));
962 picked = "((" + picked + ".CA" + mdlString + ")|(" + picked + ".P"
966 if (!atomsPicked.contains(picked))
968 viewer.evalStringQuiet("select " + picked + ";label %n %r:%c");
969 atomsPicked.addElement(picked);
973 viewer.evalString("select " + picked + ";label off");
974 atomsPicked.removeElement(picked);
977 // TODO: in application this happens
979 // if (scriptWindow != null)
981 // scriptWindow.sendConsoleMessage(strInfo);
982 // scriptWindow.sendConsoleMessage("\n");
988 public void notifyCallback(CBK type, Object[] data)
995 notifyFileLoaded((String) data[1], (String) data[2],
996 (String) data[3], (String) data[4],
997 ((Integer) data[5]).intValue());
1001 notifyAtomPicked(((Integer) data[2]).intValue(), (String) data[1],
1003 // also highlight in alignment
1005 notifyAtomHovered(((Integer) data[2]).intValue(), (String) data[1],
1009 notifyScriptTermination((String) data[2],
1010 ((Integer) data[3]).intValue());
1013 sendConsoleEcho((String) data[1]);
1016 sendConsoleMessage((data == null) ? ((String) null)
1017 : (String) data[1]);
1020 // System.err.println("Ignoring error callback.");
1030 System.err.println("Unhandled callback " + type + " "
1031 + data[1].toString());
1034 } catch (Exception e)
1036 System.err.println("Squashed Jmol callback handler error:");
1037 e.printStackTrace();
1042 public boolean notifyEnabled(CBK callbackPick)
1044 switch (callbackPick)
1060 // incremented every time a load notification is successfully handled -
1061 // lightweight mechanism for other threads to detect when they can start
1062 // referrring to new structures.
1063 private long loadNotifiesHandled = 0;
1065 public long getLoadNotifiesHandled()
1067 return loadNotifiesHandled;
1070 public void notifyFileLoaded(String fullPathName, String fileName2,
1071 String modelName, String errorMsg, int modelParts)
1073 if (errorMsg != null)
1075 fileLoadingError = errorMsg;
1079 // TODO: deal sensibly with models loaded inLine:
1080 // modelName will be null, as will fullPathName.
1082 // the rest of this routine ignores the arguments, and simply interrogates
1083 // the Jmol view to find out what structures it contains, and adds them to
1084 // the structure selection manager.
1085 fileLoadingError = null;
1086 String[] oldmodels = modelFileNames;
1087 modelFileNames = null;
1088 chainNames = new Vector<String>();
1089 chainFile = new Hashtable<String, String>();
1090 boolean notifyLoaded = false;
1091 String[] modelfilenames = getPdbFile();
1092 // first check if we've lost any structures
1093 if (oldmodels != null && oldmodels.length > 0)
1096 for (int i = 0; i < oldmodels.length; i++)
1098 for (int n = 0; n < modelfilenames.length; n++)
1100 if (modelfilenames[n] == oldmodels[i])
1102 oldmodels[i] = null;
1106 if (oldmodels[i] != null)
1113 String[] oldmfn = new String[oldm];
1115 for (int i = 0; i < oldmodels.length; i++)
1117 if (oldmodels[i] != null)
1119 oldmfn[oldm++] = oldmodels[i];
1122 // deregister the Jmol instance for these structures - we'll add
1123 // ourselves again at the end for the current structure set.
1124 getSsm().removeStructureViewerListener(this, oldmfn);
1127 refreshPdbEntries();
1128 for (int modelnum = 0; modelnum < modelfilenames.length; modelnum++)
1130 String fileName = modelfilenames[modelnum];
1131 boolean foundEntry = false;
1132 MCview.PDBfile pdb = null;
1133 String pdbfile = null;
1134 // model was probably loaded inline - so check the pdb file hashcode
1137 // calculate essential attributes for the pdb data imported inline.
1138 // prolly need to resolve modelnumber properly - for now just use our
1140 pdbfile = viewer.getData("" + (1 + _modelFileNameMap[modelnum])
1143 // search pdbentries and sequences to find correct pdbentry for this
1145 for (int pe = 0; pe < getPdbCount(); pe++)
1147 boolean matches = false;
1148 if (fileName == null)
1151 // see JAL-623 - need method of matching pasted data up
1153 pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
1154 pdbfile, AppletFormatAdapter.PASTE);
1155 getPdbEntry(modelnum).setFile("INLINE" + pdb.id);
1162 File fl = new File(getPdbEntry(pe).getFile());
1163 matches = fl.equals(new File(fileName));
1167 // TODO: Jmol can in principle retrieve from CLASSLOADER but
1170 // to be tested. See mantis bug
1171 // https://mantis.lifesci.dundee.ac.uk/view.php?id=36605
1172 String protocol = AppletFormatAdapter.URL;
1177 protocol = AppletFormatAdapter.FILE;
1179 } catch (Exception e)
1184 // Explicitly map to the filename used by Jmol ;
1185 pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
1186 fileName, protocol);
1187 // pdbentry[pe].getFile(), protocol);
1193 // add an entry for every chain in the model
1194 for (int i = 0; i < pdb.chains.size(); i++)
1196 String chid = new String(pdb.id + ":"
1197 + pdb.chains.elementAt(i).id);
1198 chainFile.put(chid, fileName);
1199 chainNames.addElement(chid);
1201 notifyLoaded = true;
1205 if (!foundEntry && associateNewStructs)
1207 // this is a foreign pdb file that jalview doesn't know about - add
1208 // it to the dataset and try to find a home - either on a matching
1209 // sequence or as a new sequence.
1210 String pdbcontent = viewer.getData("/" + (modelnum + 1) + ".1",
1212 // parse pdb file into a chain, etc.
1213 // locate best match for pdb in associated views and add mapping to
1215 // if properly registered then
1216 notifyLoaded = true;
1221 // so finally, update the jmol bits and pieces
1222 // if (jmolpopup != null)
1224 // // potential for deadlock here:
1225 // // jmolpopup.updateComputedMenus();
1227 if (!isLoadingFromArchive())
1229 viewer.evalStringQuiet("model *; select backbone;restrict;cartoon;wireframe off;spacefill off");
1231 // register ourselves as a listener and notify the gui that it needs to
1233 getSsm().addStructureViewerListener(this);
1236 FeatureRenderer fr = getFeatureRenderer(null);
1242 loadNotifiesHandled++;
1244 setLoadingFromArchive(false);
1247 public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)
1249 notifyAtomPicked(iatom, strMeasure, null);
1252 public abstract void notifyScriptTermination(String strStatus,
1256 * display a message echoed from the jmol viewer
1260 public abstract void sendConsoleEcho(String strEcho); /*
1261 * { showConsole(true);
1263 * history.append("\n" +
1267 // /End JmolStatusListener
1268 // /////////////////////////////
1272 * status message - usually the response received after a script
1275 public abstract void sendConsoleMessage(String strStatus);
1277 public void setCallbackFunction(String callbackType,
1278 String callbackFunction)
1280 System.err.println("Ignoring set-callback request to associate "
1281 + callbackType + " with function " + callbackFunction);
1285 public void setJalviewColourScheme(ColourSchemeI cs)
1287 colourBySequence = false;
1295 StringBuilder command = new StringBuilder(128);
1296 command.append("select *;color white;");
1297 List<String> residueSet = ResidueProperties.getResidues(isNucleotide(),
1299 for (String res : residueSet)
1301 Color col = cs.findColour(res.charAt(0));
1302 command.append("select " + res + ";color[" + col.getRed() + ","
1303 + col.getGreen() + "," + col.getBlue() + "];");
1306 evalStateCommand(command.toString());
1310 public void showHelp()
1312 showUrl("http://jmol.sourceforge.net/docs/JmolUserGuide/", "jmolHelp");
1316 * open the URL somehow
1320 public abstract void showUrl(String url, String target);
1323 * called when the binding thinks the UI needs to be refreshed after a Jmol
1324 * state change. this could be because structures were loaded, or because an
1325 * error has occured.
1327 public abstract void refreshGUI();
1330 * called to show or hide the associated console window container.
1334 public abstract void showConsole(boolean show);
1337 * @param renderPanel
1339 * - when true will initialise jmol's file IO system (should be false
1340 * in applet context)
1342 * @param documentBase
1344 * @param commandOptions
1346 public void allocateViewer(Container renderPanel, boolean jmolfileio,
1347 String htmlName, URL documentBase, URL codeBase,
1348 String commandOptions)
1350 allocateViewer(renderPanel, jmolfileio, htmlName, documentBase,
1351 codeBase, commandOptions, null, null);
1356 * @param renderPanel
1358 * - when true will initialise jmol's file IO system (should be false
1359 * in applet context)
1361 * @param documentBase
1363 * @param commandOptions
1364 * @param consolePanel
1365 * - panel to contain Jmol console
1366 * @param buttonsToShow
1367 * - buttons to show on the console, in ordr
1369 public void allocateViewer(Container renderPanel, boolean jmolfileio,
1370 String htmlName, URL documentBase, URL codeBase,
1371 String commandOptions, final Container consolePanel,
1372 String buttonsToShow)
1374 if (commandOptions == null)
1376 commandOptions = "";
1378 viewer = (Viewer) JmolViewer.allocateViewer(renderPanel,
1379 (jmolfileio ? new SmarterJmolAdapter() : null), htmlName
1380 + ((Object) this).toString(), documentBase, codeBase,
1381 commandOptions, this);
1383 viewer.setJmolStatusListener(this); // extends JmolCallbackListener
1385 console = createJmolConsole(consolePanel, buttonsToShow);
1386 if (consolePanel != null)
1388 consolePanel.addComponentListener(this);
1394 protected abstract JmolAppConsoleInterface createJmolConsole(
1395 Container consolePanel, String buttonsToShow);
1397 protected org.jmol.api.JmolAppConsoleInterface console = null;
1399 public void setBackgroundColour(java.awt.Color col)
1402 viewer.evalStringQuiet("background [" + col.getRed() + ","
1403 + col.getGreen() + "," + col.getBlue() + "];");
1408 public Dimension resizeInnerPanel(String data)
1410 // Jalview doesn't honour resize panel requests
1414 public boolean isFinishedInit()
1416 return finishedInit;
1419 public void setFinishedInit(boolean finishedInit)
1421 this.finishedInit = finishedInit;
1427 protected void closeConsole()
1429 if (console != null)
1433 console.setVisible(false);
1436 } catch (Exception x)
1445 * ComponentListener method
1448 public void componentMoved(ComponentEvent e)
1453 * ComponentListener method
1456 public void componentResized(ComponentEvent e)
1461 * ComponentListener method
1464 public void componentShown(ComponentEvent e)
1470 * ComponentListener method
1473 public void componentHidden(ComponentEvent e)