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.SequenceI;
26 import jalview.io.FileParse;
27 import jalview.io.StructureFile;
28 import jalview.schemes.ResidueProperties;
29 import jalview.util.MessageManager;
31 import java.io.IOException;
32 import java.util.ArrayList;
33 import java.util.List;
35 import java.util.Vector;
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.c.STR;
43 import org.jmol.modelset.ModelSet;
44 import org.jmol.viewer.Viewer;
47 import MCview.PDBChain;
48 import MCview.Residue;
51 * Import and process files with Jmol for file like PDB, mmCIF
56 public class JmolParser extends StructureFile implements JmolStatusListener
60 public JmolParser(boolean addAlignmentAnnotations,
61 boolean predictSecondaryStructure, boolean externalSecStr,
62 String inFile, String type) throws IOException
65 this.visibleChainAnnotation = addAlignmentAnnotations;
66 this.predictSecondaryStructure = predictSecondaryStructure;
67 this.externalSecondaryStructure = externalSecStr;
70 public JmolParser(boolean addAlignmentAnnotations,
71 boolean predictSecondaryStructure, boolean externalSecStr,
72 FileParse fp) throws IOException
75 this.visibleChainAnnotation = addAlignmentAnnotations;
76 this.predictSecondaryStructure = predictSecondaryStructure;
77 this.externalSecondaryStructure = externalSecStr;
80 public JmolParser(FileParse fp) throws IOException
85 public JmolParser(String inFile, String type) throws IOException
95 * Calls the Jmol library to parse the PDB/mmCIF file, and then inspects the
96 * resulting object model to generate Jalview-style sequences, with secondary
97 * structure annotation added where available (i.e. where it has been computed
98 * by Jmol using DSSP).
100 * @see jalview.io.AlignFile#parse()
103 public void parse() throws IOException
106 setChains(new Vector<PDBChain>());
107 Viewer jmolModel = getJmolData();
108 jmolModel.openReader(getDataName(), getDataName(), getReader());
109 waitForScript(jmolModel);
112 * Convert one or more Jmol Model objects to Jalview sequences
114 if (jmolModel.ms.mc > 0)
116 transformJmolModelToJalview(jmolModel.ms);
121 * create a headless jmol instance for dataprocessing
125 private Viewer getJmolData()
131 viewer = (Viewer) JmolViewer.allocateViewer(null, null, null, null,
132 null, "-x -o -n", this);
133 // ensure the 'new' (DSSP) not 'old' (Ramachandran) SS method is used
134 viewer.setBooleanProperty("defaultStructureDSSP", true);
135 } catch (ClassCastException x)
137 throw new Error(MessageManager.formatMessage(
138 "error.jmol_version_not_compatible_with_jalview_version",
139 new String[] { JmolViewer.getJmolVersion() }), x);
145 public void transformJmolModelToJalview(ModelSet ms) throws IOException
150 List<SequenceI> rna = new ArrayList<SequenceI>();
151 List<SequenceI> prot = new ArrayList<SequenceI>();
153 String pdbId = (String) ms.getInfo(0, "title");
155 List<Atom> significantAtoms = convertSignificantAtoms(ms);
156 for (Atom tmpatom : significantAtoms)
160 tmpchain = findChain(tmpatom.chain);
161 if (tmpatom.resNumIns.trim().equals(lastID))
163 // phosphorylated protein - seen both CA and P..
166 tmpchain.atoms.addElement(tmpatom);
167 } catch (Exception e)
169 tmpchain = new PDBChain(pdbId, tmpatom.chain);
170 getChains().add(tmpchain);
171 tmpchain.atoms.addElement(tmpatom);
173 lastID = tmpatom.resNumIns.trim();
180 setId(inFile.getName());
182 for (PDBChain chain : getChains())
184 SequenceI chainseq = postProcessChain(chain);
185 createAnnotation(chainseq, chain, ms.at);
195 } catch (OutOfMemoryError er)
198 .println("OUT OF MEMORY LOADING TRANSFORMING JMOL MODEL TO JALVIEW MODEL");
199 throw new IOException(
201 .getString("exception.outofmemory_loading_mmcif_file"));
205 private List<Atom> convertSignificantAtoms(ModelSet ms)
207 List<Atom> significantAtoms = new ArrayList<Atom>();
208 for (org.jmol.modelset.Atom atom : ms.at)
210 if (atom.getAtomName().equalsIgnoreCase("CA")
211 || atom.getAtomName().equalsIgnoreCase("P"))
213 Atom curAtom = new Atom(atom.x, atom.y, atom.z);
214 curAtom.atomIndex = atom.getIndex();
215 curAtom.chain = atom.getChainIDStr();
216 curAtom.insCode = atom.group.getInsertionCode();
217 curAtom.name = atom.getAtomName();
218 curAtom.number = atom.getAtomNumber();
219 curAtom.resName = atom.getGroup3(true);
220 curAtom.resNumber = atom.getResno();
221 curAtom.occupancy = ms.occupancies != null ? ms.occupancies[atom
222 .getIndex()] : Float.valueOf(atom.getOccupancy100());
223 curAtom.resNumIns = "" + curAtom.resNumber + curAtom.insCode;
224 // curAtom.tfactor = atom.group.;
226 significantAtoms.add(curAtom);
229 return significantAtoms;
232 private void createAnnotation(SequenceI sequence, PDBChain chain,
233 org.jmol.modelset.Atom[] jmolAtoms)
235 char[] secstr = new char[sequence.getLength()];
236 char[] secstrcode = new char[sequence.getLength()];
238 // Ensure Residue size equals Seq size
239 if (chain.residues.size() != sequence.getLength())
244 for (Residue residue : chain.residues)
246 Atom repAtom = residue.getAtoms().get(0);
247 STR proteinStructureSubType = jmolAtoms[repAtom.atomIndex].group
248 .getProteinStructureSubType();
249 setSecondaryStructure(proteinStructureSubType, annotIndex, secstr,
253 addSecondaryStructureAnnotation(chain.pdbid, sequence, secstr,
254 secstrcode, chain.id, sequence.getStart());
258 * Helper method that adds an AlignmentAnnotation for secondary structure to
259 * the sequence, provided at least one secondary structure prediction has been
270 protected void addSecondaryStructureAnnotation(String modelTitle,
271 SequenceI sq, char[] secstr, char[] secstrcode, String chainId,
274 char[] seq = sq.getSequence();
275 boolean ssFound = false;
276 Annotation asecstr[] = new Annotation[seq.length + firstResNum - 1];
277 for (int p = 0; p < seq.length; p++)
279 if (secstr[p] >= 'A' && secstr[p] <= 'z')
281 asecstr[p] = new Annotation(String.valueOf(secstr[p]), null,
282 secstrcode[p], Float.NaN);
289 String mt = modelTitle == null ? getDataName() : modelTitle;
291 AlignmentAnnotation ann = new AlignmentAnnotation(
292 "Secondary Structure", "Secondary Structure for " + mt,
294 ann.belowAlignment = true;
296 ann.autoCalculated = false;
297 ann.setCalcId(getClass().getName());
298 ann.adjustForAlignment();
299 ann.validateRangeAndDisplay();
300 annotations.add(ann);
301 sq.addAlignmentAnnotation(ann);
305 private void waitForScript(Viewer jmd)
307 while (jmd.isScriptExecuting())
313 } catch (InterruptedException x)
320 * Convert Jmol's secondary structure code to Jalview's, and stored it in the
321 * secondary structure arrays at the given sequence position
323 * @param proteinStructureSubType
328 protected void setSecondaryStructure(STR proteinStructureSubType,
329 int pos, char[] secstr, char[] secstrcode)
331 switch (proteinStructureSubType)
350 switch (proteinStructureSubType)
356 secstrcode[pos] = 'H';
359 secstrcode[pos] = 'E';
367 * Convert any non-standard peptide codes to their standard code table
368 * equivalent. (Initial version only does Selenomethionine MSE->MET.)
370 * @param threeLetterCode
374 protected void replaceNonCanonicalResidue(String threeLetterCode,
377 String canonical = ResidueProperties
378 .getCanonicalAminoAcid(threeLetterCode);
379 if (canonical != null && !canonical.equalsIgnoreCase(threeLetterCode))
381 seq[pos] = ResidueProperties.getSingleCharacterCode(canonical);
386 * Not implemented - returns null
389 public String print()
398 public void setCallbackFunction(String callbackType,
399 String callbackFunction)
404 public void notifyCallback(CBK cbType, Object[] data)
406 String strInfo = (data == null || data[1] == null ? null : data[1]
411 sendConsoleEcho(strInfo);
414 notifyScriptTermination((String) data[2],
415 ((Integer) data[3]).intValue());
418 String mystatus = (String) data[3];
419 if (mystatus.indexOf("Picked") >= 0
420 || mystatus.indexOf("Sequence") >= 0)
423 sendConsoleMessage(strInfo);
425 else if (mystatus.indexOf("Completed") >= 0)
427 sendConsoleEcho(strInfo.substring(strInfo.lastIndexOf(",") + 2,
428 strInfo.length() - 1));
432 sendConsoleMessage(data == null ? null : strInfo);
435 sendConsoleMessage(strInfo);
442 String lastConsoleEcho = "";
444 private void sendConsoleEcho(String string)
446 lastConsoleEcho += string;
447 lastConsoleEcho += "\n";
450 String lastConsoleMessage = "";
452 private void sendConsoleMessage(String string)
454 lastConsoleMessage += string;
455 lastConsoleMessage += "\n";
458 int lastScriptTermination = -1;
460 String lastScriptMessage = "";
462 private void notifyScriptTermination(String string, int intValue)
464 lastScriptMessage += string;
465 lastScriptMessage += "\n";
466 lastScriptTermination = intValue;
470 public boolean notifyEnabled(CBK callbackPick)
472 switch (callbackPick)
486 * Not implemented - returns null
489 public String eval(String strEval)
495 * Not implemented - returns null
498 public float[][] functionXY(String functionName, int x, int y)
504 * Not implemented - returns null
507 public float[][][] functionXYZ(String functionName, int nx, int ny, int nz)
513 * Not implemented - returns null
516 public String createImage(String fileName, String imageType,
517 Object text_or_bytes, int quality)
523 * Not implemented - returns null
526 public Map<String, Object> getRegistryInfo()
535 public void showUrl(String url)
540 * Not implemented - returns null
543 public Dimension resizeInnerPanel(String data)
549 public Map<String, Object> getJSpecViewProperty(String arg0)
554 public boolean isPredictSecondaryStructure()
556 return predictSecondaryStructure;
559 public void setPredictSecondaryStructure(boolean predictSecondaryStructure)
561 this.predictSecondaryStructure = predictSecondaryStructure;