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("error.jmol_version_not_compatible_with_jalview_version", new String[]{JmolViewer.getJmolVersion()}),
96 private void waitForScript(Viewer jmd)
98 while (jmd.isScriptExecuting())
104 } catch (InterruptedException x)
113 * @see jalview.io.AlignFile#parse()
116 public void parse() throws IOException
118 Viewer jmd = getJmolData();
119 jmd.openReader(getDataName(), getDataName(), getReader());
124 ModelSet ms = jmd.ms;
125 // Jmol 14.2 added third argument doReport = false
126 ms.calculateStructures(null, true, false, false, true);
127 // System.out.println("Structs\n"+structs);
130 for (Model model : ms.am)
133 for (BioPolymer bp : ((BioModel) model).bioPolymers)
135 int lastChainId = 0; // int value of character e.g. 65 for A
136 String lastChainIdAlpha = "";
138 int[] groups = bp.getLeadAtomIndices();
139 char seq[] = new char[groups.length], secstr[] = new char[groups.length], secstrcode[] = new char[groups.length];
140 int groupc = 0, len = 0, firstrnum = 1, lastrnum = 0;
144 if (groupc >= groups.length
145 || ms.at[groups[groupc]].group.chain.chainID != lastChainId)
148 * on change of chain (or at end), construct the sequence and
149 * secondary structure annotation for the last chain
153 boolean isNa = bp.isNucleic();
154 // normalise sequence from Jmol to jalview
155 int[] cinds = isNa ? ResidueProperties.nucleotideIndex
156 : ResidueProperties.aaIndex;
157 int nonGap = isNa ? ResidueProperties.maxNucleotideIndex
158 : ResidueProperties.maxProteinIndex;
160 char newseq[] = new char[len];
161 Annotation asecstr[] = new Annotation[len + firstrnum - 1];
162 for (int p = 0; p < len; p++)
164 newseq[p] = cinds[seq[p]] == nonGap ? ngc : seq[p];
165 if (secstr[p] >= 'A' && secstr[p] <= 'z')
169 asecstr[p] = new Annotation("" + secstr[p], null,
170 secstrcode[p], Float.NaN);
171 } catch (ArrayIndexOutOfBoundsException e)
173 // skip - patch for JAL-1836
177 String modelTitle = (String) ms
178 .getInfo(modelIndex, "title");
179 SequenceI sq = new Sequence("" + getDataName() + "|"
180 + modelTitle + "|" + lastChainIdAlpha, newseq,
181 firstrnum, lastrnum);
182 PDBEntry pdbe = new PDBEntry();
183 pdbe.setFile(getDataName());
184 pdbe.setId(getDataName());
185 pdbe.setProperty(new Hashtable());
186 // pdbe.getProperty().put("CHAIN", "" + _lastChainId);
187 pdbe.setChainCode(lastChainIdAlpha);
190 // Need to put the number of models for this polymer somewhere
191 // for Chimera/others to grab
192 // pdbe.getProperty().put("PDBMODELS", biopoly.)
196 String mt = modelTitle == null ? getDataName()
198 if (lastChainId >= ' ')
200 mt += lastChainIdAlpha;
202 AlignmentAnnotation ann = new AlignmentAnnotation(
203 "Secondary Structure", "Secondary Structure for "
205 ann.belowAlignment = true;
207 ann.autoCalculated = false;
208 ann.setCalcId(getClass().getName());
209 sq.addAlignmentAnnotation(ann);
210 ann.adjustForAlignment();
211 ann.validateRangeAndDisplay();
212 annotations.add(ann);
219 if (groupc < groups.length)
221 group = ms.at[groups[groupc]].group;
224 firstrnum = group.getResno();
225 lastChainId = group.chain.chainID;
226 lastChainIdAlpha = group.chain.getIDStr();
230 lastrnum = group.getResno();
232 seq[len] = group.getGroup1();
235 * JAL-1828 replace a modified amino acid with its standard
236 * equivalent (e.g. MSE with MET->M) to maximise sequence matching
238 String threeLetterCode = group.getGroup3();
239 String canonical = ResidueProperties.getCanonicalAminoAcid(threeLetterCode);
240 if (canonical != null
241 && !canonical.equalsIgnoreCase(threeLetterCode))
243 seq[len] = ResidueProperties
244 .getSingleCharacterCode(canonical);
246 switch (group.getProteinStructureSubType())
249 if (secstr[len] == 0)
254 if (secstr[len] == 0)
259 if (secstr[len] == 0)
264 if (secstr[len] == 0)
268 secstrcode[len] = 'H';
272 secstrcode[len] = 'E';
280 } while (groupc++ < groups.length);
285 * lastScriptTermination = -9465; String dsspOut =
286 * jmd.evalString("calculate STRUCTURE"); if (dsspOut.equals("pending")) {
287 * while (lastScriptTermination == -9465) { try { Thread.sleep(50); }
288 * catch (Exception x) { } ; } } System.out.println(lastConsoleEcho);
296 * @see jalview.io.AlignFile#print()
299 public String print()
301 // TODO Auto-generated method stub
306 public void setCallbackFunction(String callbackType,
307 String callbackFunction)
309 // TODO Auto-generated method stub
314 * @Override public void notifyCallback(EnumCallback type, Object[] data) {
315 * try { switch (type) { case ERROR: case SCRIPT:
316 * notifyScriptTermination((String) data[2], ((Integer) data[3]).intValue());
317 * break; case MESSAGE: sendConsoleMessage((data == null) ? ((String) null) :
318 * (String) data[1]); break; case LOADSTRUCT: notifyFileLoaded((String)
319 * data[1], (String) data[2], (String) data[3], (String) data[4], ((Integer)
320 * data[5]).intValue());
322 * break; default: // System.err.println("Unhandled callback " + type + " " //
323 * + data[1].toString()); break; } } catch (Exception e) {
324 * System.err.println("Squashed Jmol callback handler error:");
325 * e.printStackTrace(); } }
327 public void notifyCallback(CBK type, Object[] data)
329 String strInfo = (data == null || data[1] == null ? null : data[1]
334 sendConsoleEcho(strInfo);
337 notifyScriptTermination((String) data[2],
338 ((Integer) data[3]).intValue());
341 String mystatus = (String) data[3];
342 if (mystatus.indexOf("Picked") >= 0
343 || mystatus.indexOf("Sequence") >= 0)
346 sendConsoleMessage(strInfo);
348 else if (mystatus.indexOf("Completed") >= 0)
350 sendConsoleEcho(strInfo.substring(strInfo.lastIndexOf(",") + 2,
351 strInfo.length() - 1));
355 sendConsoleMessage(data == null ? null : strInfo);
358 sendConsoleMessage(strInfo);
365 String lastConsoleEcho = "";
367 private void sendConsoleEcho(String string)
369 lastConsoleEcho += string;
370 lastConsoleEcho += "\n";
373 String lastConsoleMessage = "";
375 private void sendConsoleMessage(String string)
377 lastConsoleMessage += string;
378 lastConsoleMessage += "\n";
381 int lastScriptTermination = -1;
383 String lastScriptMessage = "";
385 private void notifyScriptTermination(String string, int intValue)
387 lastScriptMessage += string;
388 lastScriptMessage += "\n";
389 lastScriptTermination = intValue;
393 public boolean notifyEnabled(CBK callbackPick)
395 switch (callbackPick)
409 public String eval(String strEval)
411 // TODO Auto-generated method stub
416 public float[][] functionXY(String functionName, int x, int y)
418 // TODO Auto-generated method stub
423 public float[][][] functionXYZ(String functionName, int nx, int ny, int nz)
425 // TODO Auto-generated method stub
430 public String createImage(String fileName, String type,
431 Object text_or_bytes, int quality)
433 // TODO Auto-generated method stub
438 public Map<String, Object> getRegistryInfo()
440 // TODO Auto-generated method stub
445 public void showUrl(String url)
447 // TODO Auto-generated method stub
452 public Dimension resizeInnerPanel(String data)
458 public Map<String, Object> getJSpecViewProperty(String arg0)