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.datamodel.AlignmentAnnotation;
24 import jalview.datamodel.Annotation;
25 import jalview.datamodel.PDBEntry;
26 import jalview.datamodel.Sequence;
27 import jalview.datamodel.SequenceI;
28 import jalview.io.AlignFile;
29 import jalview.io.FileParse;
30 import jalview.schemes.ResidueProperties;
31 import jalview.util.MessageManager;
33 import java.io.IOException;
34 import java.util.Hashtable;
37 import javajs.awt.Dimension;
39 import org.jmol.api.JmolStatusListener;
40 import org.jmol.api.JmolViewer;
41 import org.jmol.c.CBK;
42 import org.jmol.modelset.Group;
43 import org.jmol.modelset.Model;
44 import org.jmol.modelset.ModelSet;
45 import org.jmol.modelsetbio.BioModel;
46 import org.jmol.modelsetbio.BioPolymer;
47 import org.jmol.viewer.Viewer;
50 * Import and process PDB files with Jmol
55 public class PDBFileWithJmol extends AlignFile implements
60 public PDBFileWithJmol(String inFile, String type) throws IOException
65 public PDBFileWithJmol(FileParse fp) throws IOException
70 public PDBFileWithJmol()
75 * create a headless jmol instance for dataprocessing
79 private Viewer getJmolData()
85 viewer = (Viewer) JmolViewer.allocateViewer(null, null, null, null,
86 null, "-x -o -n", this);
87 } catch (ClassCastException x)
89 throw new Error(MessageManager.formatMessage(
90 "error.jmol_version_not_compatible_with_jalview_version",
91 new String[] { JmolViewer.getJmolVersion() }), x);
97 private void waitForScript(Viewer jmd)
99 while (jmd.isScriptExecuting())
105 } catch (InterruptedException x)
114 * @see jalview.io.AlignFile#parse()
117 public void parse() throws IOException
119 Viewer jmd = getJmolData();
120 jmd.openReader(getDataName(), getDataName(), getReader());
125 ModelSet ms = jmd.ms;
126 // Jmol 14.2 added third argument doReport = false
127 ms.calculateStructures(null, true, false, false, true);
128 // System.out.println("Structs\n"+structs);
131 for (Model model : ms.am)
134 for (BioPolymer bp : ((BioModel) model).bioPolymers)
136 int lastChainId = 0; // int value of character e.g. 65 for A
137 String lastChainIdAlpha = "";
139 int[] groups = bp.getLeadAtomIndices();
140 char seq[] = new char[groups.length], secstr[] = new char[groups.length], secstrcode[] = new char[groups.length];
141 int groupc = 0, len = 0, firstrnum = 1, lastrnum = 0;
145 if (groupc >= groups.length
146 || ms.at[groups[groupc]].group.chain.chainID != lastChainId)
149 * on change of chain (or at end), construct the sequence and
150 * secondary structure annotation for the last chain
154 boolean isNa = bp.isNucleic();
155 // normalise sequence from Jmol to jalview
156 int[] cinds = isNa ? ResidueProperties.nucleotideIndex
157 : ResidueProperties.aaIndex;
158 int nonGap = isNa ? ResidueProperties.maxNucleotideIndex
159 : ResidueProperties.maxProteinIndex;
161 char newseq[] = new char[len];
162 Annotation asecstr[] = new Annotation[len + firstrnum - 1];
163 for (int p = 0; p < len; p++)
165 newseq[p] = cinds[seq[p]] == nonGap ? ngc : seq[p];
166 if (secstr[p] >= 'A' && secstr[p] <= 'z')
170 asecstr[p] = new Annotation("" + secstr[p], null,
171 secstrcode[p], Float.NaN);
172 } catch (ArrayIndexOutOfBoundsException e)
174 // skip - patch for JAL-1836
178 String modelTitle = (String) ms
179 .getInfo(modelIndex, "title");
180 SequenceI sq = new Sequence("" + getDataName() + "|"
181 + modelTitle + "|" + lastChainIdAlpha, newseq,
182 firstrnum, lastrnum);
183 PDBEntry pdbe = new PDBEntry();
184 pdbe.setFile(getDataName());
185 pdbe.setId(getDataName());
186 pdbe.setProperty(new Hashtable());
187 // pdbe.getProperty().put("CHAIN", "" + _lastChainId);
188 pdbe.setChainCode(lastChainIdAlpha);
191 // Need to put the number of models for this polymer somewhere
192 // for Chimera/others to grab
193 // pdbe.getProperty().put("PDBMODELS", biopoly.)
197 String mt = modelTitle == null ? getDataName()
199 if (lastChainId >= ' ')
201 mt += lastChainIdAlpha;
203 AlignmentAnnotation ann = new AlignmentAnnotation(
204 "Secondary Structure", "Secondary Structure for "
206 ann.belowAlignment = true;
208 ann.autoCalculated = false;
209 ann.setCalcId(getClass().getName());
210 sq.addAlignmentAnnotation(ann);
211 ann.adjustForAlignment();
212 ann.validateRangeAndDisplay();
213 annotations.add(ann);
220 if (groupc < groups.length)
222 group = ms.at[groups[groupc]].group;
225 firstrnum = group.getResno();
226 lastChainId = group.chain.chainID;
227 lastChainIdAlpha = group.chain.getIDStr();
231 lastrnum = group.getResno();
233 seq[len] = group.getGroup1();
236 * JAL-1828 replace a modified amino acid with its standard
237 * equivalent (e.g. MSE with MET->M) to maximise sequence matching
239 String threeLetterCode = group.getGroup3();
240 String canonical = ResidueProperties
241 .getCanonicalAminoAcid(threeLetterCode);
242 if (canonical != null
243 && !canonical.equalsIgnoreCase(threeLetterCode))
245 seq[len] = ResidueProperties
246 .getSingleCharacterCode(canonical);
248 switch (group.getProteinStructureSubType())
251 if (secstr[len] == 0)
256 if (secstr[len] == 0)
261 if (secstr[len] == 0)
266 if (secstr[len] == 0)
270 secstrcode[len] = 'H';
274 secstrcode[len] = 'E';
282 } while (groupc++ < groups.length);
287 * lastScriptTermination = -9465; String dsspOut =
288 * jmd.evalString("calculate STRUCTURE"); if (dsspOut.equals("pending")) {
289 * while (lastScriptTermination == -9465) { try { Thread.sleep(50); }
290 * catch (Exception x) { } ; } } System.out.println(lastConsoleEcho);
298 * @see jalview.io.AlignFile#print()
301 public String print()
303 // TODO Auto-generated method stub
308 public void setCallbackFunction(String callbackType,
309 String callbackFunction)
311 // TODO Auto-generated method stub
316 * @Override public void notifyCallback(EnumCallback type, Object[] data) {
317 * try { switch (type) { case ERROR: case SCRIPT:
318 * notifyScriptTermination((String) data[2], ((Integer) data[3]).intValue());
319 * break; case MESSAGE: sendConsoleMessage((data == null) ? ((String) null) :
320 * (String) data[1]); break; case LOADSTRUCT: notifyFileLoaded((String)
321 * data[1], (String) data[2], (String) data[3], (String) data[4], ((Integer)
322 * data[5]).intValue());
324 * break; default: // System.err.println("Unhandled callback " + type + " " //
325 * + data[1].toString()); break; } } catch (Exception e) {
326 * System.err.println("Squashed Jmol callback handler error:");
327 * e.printStackTrace(); } }
329 public void notifyCallback(CBK type, Object[] data)
331 String strInfo = (data == null || data[1] == null ? null : data[1]
336 sendConsoleEcho(strInfo);
339 notifyScriptTermination((String) data[2],
340 ((Integer) data[3]).intValue());
343 String mystatus = (String) data[3];
344 if (mystatus.indexOf("Picked") >= 0
345 || mystatus.indexOf("Sequence") >= 0)
348 sendConsoleMessage(strInfo);
350 else if (mystatus.indexOf("Completed") >= 0)
352 sendConsoleEcho(strInfo.substring(strInfo.lastIndexOf(",") + 2,
353 strInfo.length() - 1));
357 sendConsoleMessage(data == null ? null : strInfo);
360 sendConsoleMessage(strInfo);
367 String lastConsoleEcho = "";
369 private void sendConsoleEcho(String string)
371 lastConsoleEcho += string;
372 lastConsoleEcho += "\n";
375 String lastConsoleMessage = "";
377 private void sendConsoleMessage(String string)
379 lastConsoleMessage += string;
380 lastConsoleMessage += "\n";
383 int lastScriptTermination = -1;
385 String lastScriptMessage = "";
387 private void notifyScriptTermination(String string, int intValue)
389 lastScriptMessage += string;
390 lastScriptMessage += "\n";
391 lastScriptTermination = intValue;
395 public boolean notifyEnabled(CBK callbackPick)
397 switch (callbackPick)
411 public String eval(String strEval)
413 // TODO Auto-generated method stub
418 public float[][] functionXY(String functionName, int x, int y)
420 // TODO Auto-generated method stub
425 public float[][][] functionXYZ(String functionName, int nx, int ny, int nz)
427 // TODO Auto-generated method stub
432 public String createImage(String fileName, String type,
433 Object text_or_bytes, int quality)
435 // TODO Auto-generated method stub
440 public Map<String, Object> getRegistryInfo()
442 // TODO Auto-generated method stub
447 public void showUrl(String url)
449 // TODO Auto-generated method stub
454 public Dimension resizeInnerPanel(String data)
460 public Map<String, Object> getJSpecViewProperty(String arg0)