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)
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(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.getBfactor100() / 100f;
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')
282 asecstr[p] = new Annotation(String.valueOf(secstr[p]), null,
283 secstrcode[p], Float.NaN);
285 } catch (Exception e)
287 // e.printStackTrace();
294 String mt = modelTitle == null ? getDataName() : modelTitle;
296 AlignmentAnnotation ann = new AlignmentAnnotation(
297 "Secondary Structure", "Secondary Structure for " + mt,
299 ann.belowAlignment = true;
301 ann.autoCalculated = false;
302 ann.setCalcId(getClass().getName());
303 ann.adjustForAlignment();
304 ann.validateRangeAndDisplay();
305 annotations.add(ann);
306 sq.addAlignmentAnnotation(ann);
310 private void waitForScript(Viewer jmd)
312 while (jmd.isScriptExecuting())
318 } catch (InterruptedException x)
325 * Convert Jmol's secondary structure code to Jalview's, and stored it in the
326 * secondary structure arrays at the given sequence position
328 * @param proteinStructureSubType
333 protected void setSecondaryStructure(STR proteinStructureSubType,
334 int pos, char[] secstr, char[] secstrcode)
336 switch (proteinStructureSubType)
355 switch (proteinStructureSubType)
361 secstrcode[pos] = 'H';
364 secstrcode[pos] = 'E';
372 * Convert any non-standard peptide codes to their standard code table
373 * equivalent. (Initial version only does Selenomethionine MSE->MET.)
375 * @param threeLetterCode
379 protected void replaceNonCanonicalResidue(String threeLetterCode,
382 String canonical = ResidueProperties
383 .getCanonicalAminoAcid(threeLetterCode);
384 if (canonical != null && !canonical.equalsIgnoreCase(threeLetterCode))
386 seq[pos] = ResidueProperties.getSingleCharacterCode(canonical);
391 * Not implemented - returns null
394 public String print()
403 public void setCallbackFunction(String callbackType,
404 String callbackFunction)
409 public void notifyCallback(CBK cbType, Object[] data)
411 String strInfo = (data == null || data[1] == null ? null : data[1]
416 sendConsoleEcho(strInfo);
419 notifyScriptTermination((String) data[2],
420 ((Integer) data[3]).intValue());
423 String mystatus = (String) data[3];
424 if (mystatus.indexOf("Picked") >= 0
425 || mystatus.indexOf("Sequence") >= 0)
428 sendConsoleMessage(strInfo);
430 else if (mystatus.indexOf("Completed") >= 0)
432 sendConsoleEcho(strInfo.substring(strInfo.lastIndexOf(",") + 2,
433 strInfo.length() - 1));
437 sendConsoleMessage(data == null ? null : strInfo);
440 sendConsoleMessage(strInfo);
447 String lastConsoleEcho = "";
449 private void sendConsoleEcho(String string)
451 lastConsoleEcho += string;
452 lastConsoleEcho += "\n";
455 String lastConsoleMessage = "";
457 private void sendConsoleMessage(String string)
459 lastConsoleMessage += string;
460 lastConsoleMessage += "\n";
463 int lastScriptTermination = -1;
465 String lastScriptMessage = "";
467 private void notifyScriptTermination(String string, int intValue)
469 lastScriptMessage += string;
470 lastScriptMessage += "\n";
471 lastScriptTermination = intValue;
475 public boolean notifyEnabled(CBK callbackPick)
477 switch (callbackPick)
491 * Not implemented - returns null
494 public String eval(String strEval)
500 * Not implemented - returns null
503 public float[][] functionXY(String functionName, int x, int y)
509 * Not implemented - returns null
512 public float[][][] functionXYZ(String functionName, int nx, int ny, int nz)
518 * Not implemented - returns null
521 public String createImage(String fileName, String imageType,
522 Object text_or_bytes, int quality)
528 * Not implemented - returns null
531 public Map<String, Object> getRegistryInfo()
540 public void showUrl(String url)
545 * Not implemented - returns null
548 public Dimension resizeInnerPanel(String data)
554 public Map<String, Object> getJSpecViewProperty(String arg0)
559 public boolean isPredictSecondaryStructure()
561 return predictSecondaryStructure;
564 public void setPredictSecondaryStructure(boolean predictSecondaryStructure)
566 this.predictSecondaryStructure = predictSecondaryStructure;
569 public boolean isVisibleChainAnnotation()
571 return visibleChainAnnotation;
574 public void setVisibleChainAnnotation(boolean visibleChainAnnotation)
576 this.visibleChainAnnotation = visibleChainAnnotation;