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.StructureImportSettings;
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)
69 public JmolParser(boolean addAlignmentAnnotations, boolean predictSecStr,
70 boolean externalSecStr, FileParse fp) throws IOException
80 * Calls the Jmol library to parse the PDB/mmCIF file, and then inspects the
81 * resulting object model to generate Jalview-style sequences, with secondary
82 * structure annotation added where available (i.e. where it has been computed
83 * by Jmol using DSSP).
85 * @see jalview.io.AlignFile#parse()
88 public void parse() throws IOException
90 String dataName = getDataName();
91 if (dataName.endsWith(".cif"))
93 setDbRefType(DBRefSource.MMCIF);
97 setDbRefType(DBRefSource.PDB);
99 setChains(new Vector<PDBChain>());
100 Viewer jmolModel = getJmolData();
101 jmolModel.openReader(getDataName(), getDataName(), getReader());
102 waitForScript(jmolModel);
105 * Convert one or more Jmol Model objects to Jalview sequences
107 if (jmolModel.ms.mc > 0)
109 transformJmolModelToJalview(jmolModel.ms);
114 * create a headless jmol instance for dataprocessing
118 private Viewer getJmolData()
124 viewer = (Viewer) JmolViewer.allocateViewer(null, null, null, null,
125 null, "-x -o -n", this);
126 // ensure the 'new' (DSSP) not 'old' (Ramachandran) SS method is used
127 viewer.setBooleanProperty("defaultStructureDSSP", true);
128 } catch (ClassCastException x)
130 throw new Error(MessageManager.formatMessage(
131 "error.jmol_version_not_compatible_with_jalview_version",
132 new String[] { JmolViewer.getJmolVersion() }), x);
138 public void transformJmolModelToJalview(ModelSet ms) throws IOException
143 List<SequenceI> rna = new ArrayList<SequenceI>();
144 List<SequenceI> prot = new ArrayList<SequenceI>();
146 String pdbId = (String) ms.getInfo(0, "title");
148 List<Atom> significantAtoms = convertSignificantAtoms(ms);
149 for (Atom tmpatom : significantAtoms)
153 tmpchain = findChain(tmpatom.chain);
154 if (tmpatom.resNumIns.trim().equals(lastID))
156 // phosphorylated protein - seen both CA and P..
159 tmpchain.atoms.addElement(tmpatom);
160 } catch (Exception e)
162 tmpchain = new PDBChain(pdbId, tmpatom.chain);
163 getChains().add(tmpchain);
164 tmpchain.atoms.addElement(tmpatom);
166 lastID = tmpatom.resNumIns.trim();
175 setId(safeName(getDataName()));
177 for (PDBChain chain : getChains())
179 SequenceI chainseq = postProcessChain(chain);
189 if (StructureImportSettings.isProcessSecondaryStructure())
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 // System.out.println("Seq Id : " + atom.getSeqID());
210 // System.out.println("To String : " + atom.toString());
211 if (!StructureImportSettings.isProcessHETATMs() && atom.isHetero())
215 if (atom.getAtomName().equalsIgnoreCase("CA")
216 || atom.getAtomName().equalsIgnoreCase("P"))
218 Atom curAtom = new Atom(atom.x, atom.y, atom.z);
219 curAtom.atomIndex = atom.getIndex();
220 curAtom.chain = atom.getChainIDStr();
221 curAtom.insCode = atom.group.getInsertionCode();
222 curAtom.name = atom.getAtomName();
223 curAtom.number = atom.getAtomNumber();
224 curAtom.resName = atom.getGroup3(true);
225 curAtom.resNumber = atom.getResno();
226 curAtom.occupancy = ms.occupancies != null ? ms.occupancies[atom
227 .getIndex()] : Float.valueOf(atom.getOccupancy100());
228 curAtom.resNumIns = "" + curAtom.resNumber + curAtom.insCode;
229 curAtom.tfactor = atom.getBfactor100() / 100f;
231 significantAtoms.add(curAtom);
234 return significantAtoms;
237 private void createAnnotation(SequenceI sequence, PDBChain chain,
238 org.jmol.modelset.Atom[] jmolAtoms)
240 char[] secstr = new char[sequence.getLength()];
241 char[] secstrcode = new char[sequence.getLength()];
243 // Ensure Residue size equals Seq size
244 if (chain.residues.size() != sequence.getLength())
249 for (Residue residue : chain.residues)
251 Atom repAtom = residue.getAtoms().get(0);
252 STR proteinStructureSubType = jmolAtoms[repAtom.atomIndex].group
253 .getProteinStructureSubType();
254 setSecondaryStructure(proteinStructureSubType, annotIndex, secstr,
258 addSecondaryStructureAnnotation(chain.pdbid, sequence, secstr,
259 secstrcode, chain.id, sequence.getStart());
263 * Helper method that adds an AlignmentAnnotation for secondary structure to
264 * the sequence, provided at least one secondary structure prediction has been
275 protected void addSecondaryStructureAnnotation(String modelTitle,
276 SequenceI sq, char[] secstr, char[] secstrcode, String chainId,
279 char[] seq = sq.getSequence();
280 boolean ssFound = false;
281 Annotation asecstr[] = new Annotation[seq.length + firstResNum - 1];
282 for (int p = 0; p < seq.length; p++)
284 if (secstr[p] >= 'A' && secstr[p] <= 'z')
288 asecstr[p] = new Annotation(String.valueOf(secstr[p]), null,
289 secstrcode[p], Float.NaN);
291 } catch (Exception e)
293 // e.printStackTrace();
300 String mt = modelTitle == null ? getDataName() : modelTitle;
302 AlignmentAnnotation ann = new AlignmentAnnotation(
303 "Secondary Structure", "Secondary Structure for " + mt,
305 ann.belowAlignment = true;
307 ann.autoCalculated = false;
308 ann.setCalcId(getClass().getName());
309 ann.adjustForAlignment();
310 ann.validateRangeAndDisplay();
311 annotations.add(ann);
312 sq.addAlignmentAnnotation(ann);
316 private void waitForScript(Viewer jmd)
318 while (jmd.isScriptExecuting())
324 } catch (InterruptedException x)
331 * Convert Jmol's secondary structure code to Jalview's, and stored it in the
332 * secondary structure arrays at the given sequence position
334 * @param proteinStructureSubType
339 protected void setSecondaryStructure(STR proteinStructureSubType,
340 int pos, char[] secstr, char[] secstrcode)
342 switch (proteinStructureSubType)
361 switch (proteinStructureSubType)
367 secstrcode[pos] = 'H';
370 secstrcode[pos] = 'E';
378 * Convert any non-standard peptide codes to their standard code table
379 * equivalent. (Initial version only does Selenomethionine MSE->MET.)
381 * @param threeLetterCode
385 protected void replaceNonCanonicalResidue(String threeLetterCode,
388 String canonical = ResidueProperties
389 .getCanonicalAminoAcid(threeLetterCode);
390 if (canonical != null && !canonical.equalsIgnoreCase(threeLetterCode))
392 seq[pos] = ResidueProperties.getSingleCharacterCode(canonical);
397 * Not implemented - returns null
400 public String print()
409 public void setCallbackFunction(String callbackType,
410 String callbackFunction)
415 public void notifyCallback(CBK cbType, Object[] data)
417 String strInfo = (data == null || data[1] == null ? null : data[1]
422 sendConsoleEcho(strInfo);
425 notifyScriptTermination((String) data[2],
426 ((Integer) data[3]).intValue());
429 String mystatus = (String) data[3];
430 if (mystatus.indexOf("Picked") >= 0
431 || mystatus.indexOf("Sequence") >= 0)
434 sendConsoleMessage(strInfo);
436 else if (mystatus.indexOf("Completed") >= 0)
438 sendConsoleEcho(strInfo.substring(strInfo.lastIndexOf(",") + 2,
439 strInfo.length() - 1));
443 sendConsoleMessage(data == null ? null : strInfo);
446 sendConsoleMessage(strInfo);
453 String lastConsoleEcho = "";
455 private void sendConsoleEcho(String string)
457 lastConsoleEcho += string;
458 lastConsoleEcho += "\n";
461 String lastConsoleMessage = "";
463 private void sendConsoleMessage(String string)
465 lastConsoleMessage += string;
466 lastConsoleMessage += "\n";
469 int lastScriptTermination = -1;
471 String lastScriptMessage = "";
473 private void notifyScriptTermination(String string, int intValue)
475 lastScriptMessage += string;
476 lastScriptMessage += "\n";
477 lastScriptTermination = intValue;
481 public boolean notifyEnabled(CBK callbackPick)
483 switch (callbackPick)
497 * Not implemented - returns null
500 public String eval(String strEval)
506 * Not implemented - returns null
509 public float[][] functionXY(String functionName, int x, int y)
515 * Not implemented - returns null
518 public float[][][] functionXYZ(String functionName, int nx, int ny, int nz)
524 * Not implemented - returns null
527 public String createImage(String fileName, String imageType,
528 Object text_or_bytes, int quality)
534 * Not implemented - returns null
537 public Map<String, Object> getRegistryInfo()
546 public void showUrl(String url)
551 * Not implemented - returns null
554 public Dimension resizeInnerPanel(String data)
560 public Map<String, Object> getJSpecViewProperty(String arg0)
565 public boolean isPredictSecondaryStructure()
567 return predictSecondaryStructure;
570 public void setPredictSecondaryStructure(boolean predictSecondaryStructure)
572 this.predictSecondaryStructure = predictSecondaryStructure;
575 public boolean isVisibleChainAnnotation()
577 return visibleChainAnnotation;
580 public void setVisibleChainAnnotation(boolean visibleChainAnnotation)
582 this.visibleChainAnnotation = visibleChainAnnotation;