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.DBRefSource;
26 import jalview.datamodel.SequenceI;
27 import jalview.io.FileParse;
28 import jalview.io.StructureFile;
29 import jalview.schemes.ResidueProperties;
30 import jalview.structure.StructureViewSettings;
31 import jalview.util.MessageManager;
33 import java.io.IOException;
34 import java.util.ArrayList;
35 import java.util.List;
37 import java.util.Vector;
39 import javajs.awt.Dimension;
41 import org.jmol.api.JmolStatusListener;
42 import org.jmol.api.JmolViewer;
43 import org.jmol.c.CBK;
44 import org.jmol.c.STR;
45 import org.jmol.modelset.ModelSet;
46 import org.jmol.viewer.Viewer;
49 import MCview.PDBChain;
50 import MCview.Residue;
53 * Import and process files with Jmol for file like PDB, mmCIF
58 public class JmolParser extends StructureFile implements JmolStatusListener
62 public JmolParser(boolean addAlignmentAnnotations, boolean predictSecStr,
63 boolean externalSecStr, String inFile, String type)
67 // addSettings(addAlignmentAnnotations, predictSecStr, externalSecStr);
70 public JmolParser(boolean addAlignmentAnnotations, boolean predictSecStr,
71 boolean externalSecStr, FileParse fp) throws IOException
74 // addSettings(addAlignmentAnnotations, predictSecStr, externalSecStr);
82 * Calls the Jmol library to parse the PDB/mmCIF file, and then inspects the
83 * resulting object model to generate Jalview-style sequences, with secondary
84 * structure annotation added where available (i.e. where it has been computed
85 * by Jmol using DSSP).
87 * @see jalview.io.AlignFile#parse()
90 public void parse() throws IOException
92 String dataName = getDataName();
93 if (dataName.endsWith(".cif"))
95 setDbRefType(DBRefSource.MMCIF);
99 setDbRefType(DBRefSource.PDB);
101 setChains(new Vector<PDBChain>());
102 Viewer jmolModel = getJmolData();
103 jmolModel.openReader(getDataName(), getDataName(), getReader());
104 waitForScript(jmolModel);
107 * Convert one or more Jmol Model objects to Jalview sequences
109 if (jmolModel.ms.mc > 0)
111 transformJmolModelToJalview(jmolModel.ms);
116 * create a headless jmol instance for dataprocessing
120 private Viewer getJmolData()
126 viewer = (Viewer) JmolViewer.allocateViewer(null, null, null, null,
127 null, "-x -o -n", this);
128 // ensure the 'new' (DSSP) not 'old' (Ramachandran) SS method is used
129 viewer.setBooleanProperty("defaultStructureDSSP", true);
130 } catch (ClassCastException x)
132 throw new Error(MessageManager.formatMessage(
133 "error.jmol_version_not_compatible_with_jalview_version",
134 new String[] { JmolViewer.getJmolVersion() }), x);
140 public void transformJmolModelToJalview(ModelSet ms) throws IOException
145 List<SequenceI> rna = new ArrayList<SequenceI>();
146 List<SequenceI> prot = new ArrayList<SequenceI>();
148 String pdbId = (String) ms.getInfo(0, "title");
150 List<Atom> significantAtoms = convertSignificantAtoms(ms);
151 for (Atom tmpatom : significantAtoms)
155 tmpchain = findChain(tmpatom.chain);
156 if (tmpatom.resNumIns.trim().equals(lastID))
158 // phosphorylated protein - seen both CA and P..
161 tmpchain.atoms.addElement(tmpatom);
162 } catch (Exception e)
164 tmpchain = new PDBChain(pdbId, tmpatom.chain);
165 getChains().add(tmpchain);
166 tmpchain.atoms.addElement(tmpatom);
168 lastID = tmpatom.resNumIns.trim();
175 setId(inFile.getName());
177 for (PDBChain chain : getChains())
179 SequenceI chainseq = postProcessChain(chain);
189 if (StructureViewSettings.isPredictSecondaryStructure())
191 createAnnotation(chainseq, chain, ms.at);
194 } catch (OutOfMemoryError er)
197 .println("OUT OF MEMORY LOADING TRANSFORMING JMOL MODEL TO JALVIEW MODEL");
198 throw new IOException(
200 .getString("exception.outofmemory_loading_mmcif_file"));
204 private List<Atom> convertSignificantAtoms(ModelSet ms)
206 List<Atom> significantAtoms = new ArrayList<Atom>();
207 for (org.jmol.modelset.Atom atom : ms.at)
209 if (atom.getAtomName().equalsIgnoreCase("CA")
210 || atom.getAtomName().equalsIgnoreCase("P"))
212 Atom curAtom = new Atom(atom.x, atom.y, atom.z);
213 curAtom.atomIndex = atom.getIndex();
214 curAtom.chain = atom.getChainIDStr();
215 curAtom.insCode = atom.group.getInsertionCode();
216 curAtom.name = atom.getAtomName();
217 curAtom.number = atom.getAtomNumber();
218 curAtom.resName = atom.getGroup3(true);
219 curAtom.resNumber = atom.getResno();
220 curAtom.occupancy = ms.occupancies != null ? ms.occupancies[atom
221 .getIndex()] : Float.valueOf(atom.getOccupancy100());
222 curAtom.resNumIns = "" + curAtom.resNumber + curAtom.insCode;
223 // curAtom.tfactor = atom.group.;
225 significantAtoms.add(curAtom);
228 return significantAtoms;
231 private void createAnnotation(SequenceI sequence, PDBChain chain,
232 org.jmol.modelset.Atom[] jmolAtoms)
234 char[] secstr = new char[sequence.getLength()];
235 char[] secstrcode = new char[sequence.getLength()];
237 // Ensure Residue size equals Seq size
238 if (chain.residues.size() != sequence.getLength())
243 for (Residue residue : chain.residues)
245 Atom repAtom = residue.getAtoms().get(0);
246 STR proteinStructureSubType = jmolAtoms[repAtom.atomIndex].group
247 .getProteinStructureSubType();
248 setSecondaryStructure(proteinStructureSubType, annotIndex, secstr,
252 addSecondaryStructureAnnotation(chain.pdbid, sequence, secstr,
253 secstrcode, chain.id, sequence.getStart());
257 * Helper method that adds an AlignmentAnnotation for secondary structure to
258 * the sequence, provided at least one secondary structure prediction has been
269 protected void addSecondaryStructureAnnotation(String modelTitle,
270 SequenceI sq, char[] secstr, char[] secstrcode, String chainId,
273 char[] seq = sq.getSequence();
274 boolean ssFound = false;
275 Annotation asecstr[] = new Annotation[seq.length + firstResNum - 1];
276 for (int p = 0; p < seq.length; p++)
278 if (secstr[p] >= 'A' && secstr[p] <= 'z')
280 asecstr[p] = new Annotation(String.valueOf(secstr[p]), null,
281 secstrcode[p], Float.NaN);
288 String mt = modelTitle == null ? getDataName() : modelTitle;
290 AlignmentAnnotation ann = new AlignmentAnnotation(
291 "Secondary Structure", "Secondary Structure for " + mt,
293 ann.belowAlignment = true;
295 ann.autoCalculated = false;
296 ann.setCalcId(getClass().getName());
297 ann.adjustForAlignment();
298 ann.validateRangeAndDisplay();
299 annotations.add(ann);
300 sq.addAlignmentAnnotation(ann);
304 private void waitForScript(Viewer jmd)
306 while (jmd.isScriptExecuting())
312 } catch (InterruptedException x)
319 * Convert Jmol's secondary structure code to Jalview's, and stored it in the
320 * secondary structure arrays at the given sequence position
322 * @param proteinStructureSubType
327 protected void setSecondaryStructure(STR proteinStructureSubType,
328 int pos, char[] secstr, char[] secstrcode)
330 switch (proteinStructureSubType)
349 switch (proteinStructureSubType)
355 secstrcode[pos] = 'H';
358 secstrcode[pos] = 'E';
366 * Convert any non-standard peptide codes to their standard code table
367 * equivalent. (Initial version only does Selenomethionine MSE->MET.)
369 * @param threeLetterCode
373 protected void replaceNonCanonicalResidue(String threeLetterCode,
376 String canonical = ResidueProperties
377 .getCanonicalAminoAcid(threeLetterCode);
378 if (canonical != null && !canonical.equalsIgnoreCase(threeLetterCode))
380 seq[pos] = ResidueProperties.getSingleCharacterCode(canonical);
385 * Not implemented - returns null
388 public String print()
397 public void setCallbackFunction(String callbackType,
398 String callbackFunction)
403 public void notifyCallback(CBK cbType, Object[] data)
405 String strInfo = (data == null || data[1] == null ? null : data[1]
410 sendConsoleEcho(strInfo);
413 notifyScriptTermination((String) data[2],
414 ((Integer) data[3]).intValue());
417 String mystatus = (String) data[3];
418 if (mystatus.indexOf("Picked") >= 0
419 || mystatus.indexOf("Sequence") >= 0)
422 sendConsoleMessage(strInfo);
424 else if (mystatus.indexOf("Completed") >= 0)
426 sendConsoleEcho(strInfo.substring(strInfo.lastIndexOf(",") + 2,
427 strInfo.length() - 1));
431 sendConsoleMessage(data == null ? null : strInfo);
434 sendConsoleMessage(strInfo);
441 String lastConsoleEcho = "";
443 private void sendConsoleEcho(String string)
445 lastConsoleEcho += string;
446 lastConsoleEcho += "\n";
449 String lastConsoleMessage = "";
451 private void sendConsoleMessage(String string)
453 lastConsoleMessage += string;
454 lastConsoleMessage += "\n";
457 int lastScriptTermination = -1;
459 String lastScriptMessage = "";
461 private void notifyScriptTermination(String string, int intValue)
463 lastScriptMessage += string;
464 lastScriptMessage += "\n";
465 lastScriptTermination = intValue;
469 public boolean notifyEnabled(CBK callbackPick)
471 switch (callbackPick)
485 * Not implemented - returns null
488 public String eval(String strEval)
494 * Not implemented - returns null
497 public float[][] functionXY(String functionName, int x, int y)
503 * Not implemented - returns null
506 public float[][][] functionXYZ(String functionName, int nx, int ny, int nz)
512 * Not implemented - returns null
515 public String createImage(String fileName, String imageType,
516 Object text_or_bytes, int quality)
522 * Not implemented - returns null
525 public Map<String, Object> getRegistryInfo()
534 public void showUrl(String url)
539 * Not implemented - returns null
542 public Dimension resizeInnerPanel(String data)
548 public Map<String, Object> getJSpecViewProperty(String arg0)
553 public boolean isPredictSecondaryStructure()
555 return predictSecondaryStructure;
558 public void setPredictSecondaryStructure(boolean predictSecondaryStructure)
560 this.predictSecondaryStructure = predictSecondaryStructure;