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.DataSourceType;
29 import jalview.io.StructureFile;
30 import jalview.schemes.ResidueProperties;
31 import jalview.structure.StructureImportSettings;
32 import jalview.util.MessageManager;
34 import java.io.IOException;
35 import java.util.ArrayList;
36 import java.util.List;
38 import java.util.Vector;
40 import javajs.awt.Dimension;
42 import org.jmol.api.JmolStatusListener;
43 import org.jmol.api.JmolViewer;
44 import org.jmol.c.CBK;
45 import org.jmol.c.STR;
46 import org.jmol.modelset.ModelSet;
47 import org.jmol.viewer.Viewer;
50 import MCview.PDBChain;
51 import MCview.Residue;
54 * Import and process files with Jmol for file like PDB, mmCIF
59 public class JmolParser extends StructureFile implements JmolStatusListener
63 public JmolParser(boolean addAlignmentAnnotations, boolean predictSecStr,
64 boolean externalSecStr, String inFile, DataSourceType sourceType)
67 super(inFile, sourceType);
70 public JmolParser(boolean addAlignmentAnnotations, boolean predictSecStr,
71 boolean externalSecStr, FileParse fp) throws IOException
81 * Calls the Jmol library to parse the PDB/mmCIF file, and then inspects the
82 * resulting object model to generate Jalview-style sequences, with secondary
83 * structure annotation added where available (i.e. where it has been computed
84 * by Jmol using DSSP).
86 * @see jalview.io.AlignFile#parse()
89 public void parse() throws IOException
91 String dataName = getDataName();
92 if (dataName.endsWith(".cif"))
94 setDbRefType(DBRefSource.MMCIF);
98 setDbRefType(DBRefSource.PDB);
100 setChains(new Vector<PDBChain>());
101 Viewer jmolModel = getJmolData();
102 jmolModel.openReader(getDataName(), getDataName(), getReader());
103 waitForScript(jmolModel);
106 * Convert one or more Jmol Model objects to Jalview sequences
108 if (jmolModel.ms.mc > 0)
110 transformJmolModelToJalview(jmolModel.ms);
115 * create a headless jmol instance for dataprocessing
119 private Viewer getJmolData()
125 viewer = (Viewer) JmolViewer.allocateViewer(null, null, null, null,
126 null, "-x -o -n", this);
127 // ensure the 'new' (DSSP) not 'old' (Ramachandran) SS method is used
128 viewer.setBooleanProperty("defaultStructureDSSP", true);
129 } catch (ClassCastException x)
131 throw new Error(MessageManager.formatMessage(
132 "error.jmol_version_not_compatible_with_jalview_version",
133 new String[] { JmolViewer.getJmolVersion() }), x);
139 public void transformJmolModelToJalview(ModelSet ms) throws IOException
144 List<SequenceI> rna = new ArrayList<SequenceI>();
145 List<SequenceI> prot = new ArrayList<SequenceI>();
147 String pdbId = (String) ms.getInfo(0, "title");
149 List<Atom> significantAtoms = convertSignificantAtoms(ms);
150 for (Atom tmpatom : significantAtoms)
154 tmpchain = findChain(tmpatom.chain);
155 if (tmpatom.resNumIns.trim().equals(lastID))
157 // phosphorylated protein - seen both CA and P..
160 tmpchain.atoms.addElement(tmpatom);
161 } catch (Exception e)
163 tmpchain = new PDBChain(pdbId, tmpatom.chain);
164 getChains().add(tmpchain);
165 tmpchain.atoms.addElement(tmpatom);
167 lastID = tmpatom.resNumIns.trim();
176 setId(inFile.getName());
178 for (PDBChain chain : getChains())
180 SequenceI chainseq = postProcessChain(chain);
190 if (StructureImportSettings.isPredictSecondaryStructure())
192 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 // System.out.println("Seq Id : " + atom.getSeqID());
211 // System.out.println("To String : " + atom.toString());
212 if (!StructureImportSettings.isProcessHETATMs() && atom.isHetero())
216 if (atom.getAtomName().equalsIgnoreCase("CA")
217 || atom.getAtomName().equalsIgnoreCase("P"))
219 Atom curAtom = new Atom(atom.x, atom.y, atom.z);
220 curAtom.atomIndex = atom.getIndex();
221 curAtom.chain = atom.getChainIDStr();
222 curAtom.insCode = atom.group.getInsertionCode();
223 curAtom.name = atom.getAtomName();
224 curAtom.number = atom.getAtomNumber();
225 curAtom.resName = atom.getGroup3(true);
226 curAtom.resNumber = atom.getResno();
227 curAtom.occupancy = ms.occupancies != null ? ms.occupancies[atom
228 .getIndex()] : Float.valueOf(atom.getOccupancy100());
229 curAtom.resNumIns = "" + curAtom.resNumber + curAtom.insCode;
230 curAtom.tfactor = atom.getBfactor100() / 100f;
232 significantAtoms.add(curAtom);
235 return significantAtoms;
238 private void createAnnotation(SequenceI sequence, PDBChain chain,
239 org.jmol.modelset.Atom[] jmolAtoms)
241 char[] secstr = new char[sequence.getLength()];
242 char[] secstrcode = new char[sequence.getLength()];
244 // Ensure Residue size equals Seq size
245 if (chain.residues.size() != sequence.getLength())
250 for (Residue residue : chain.residues)
252 Atom repAtom = residue.getAtoms().get(0);
253 STR proteinStructureSubType = jmolAtoms[repAtom.atomIndex].group
254 .getProteinStructureSubType();
255 setSecondaryStructure(proteinStructureSubType, annotIndex, secstr,
259 addSecondaryStructureAnnotation(chain.pdbid, sequence, secstr,
260 secstrcode, chain.id, sequence.getStart());
264 * Helper method that adds an AlignmentAnnotation for secondary structure to
265 * the sequence, provided at least one secondary structure prediction has been
276 protected void addSecondaryStructureAnnotation(String modelTitle,
277 SequenceI sq, char[] secstr, char[] secstrcode, String chainId,
280 char[] seq = sq.getSequence();
281 boolean ssFound = false;
282 Annotation asecstr[] = new Annotation[seq.length + firstResNum - 1];
283 for (int p = 0; p < seq.length; p++)
285 if (secstr[p] >= 'A' && secstr[p] <= 'z')
289 asecstr[p] = new Annotation(String.valueOf(secstr[p]), null,
290 secstrcode[p], Float.NaN);
292 } catch (Exception e)
294 // e.printStackTrace();
301 String mt = modelTitle == null ? getDataName() : modelTitle;
303 AlignmentAnnotation ann = new AlignmentAnnotation(
304 "Secondary Structure", "Secondary Structure for " + mt,
306 ann.belowAlignment = true;
308 ann.autoCalculated = false;
309 ann.setCalcId(getClass().getName());
310 ann.adjustForAlignment();
311 ann.validateRangeAndDisplay();
312 annotations.add(ann);
313 sq.addAlignmentAnnotation(ann);
317 private void waitForScript(Viewer jmd)
319 while (jmd.isScriptExecuting())
325 } catch (InterruptedException x)
332 * Convert Jmol's secondary structure code to Jalview's, and stored it in the
333 * secondary structure arrays at the given sequence position
335 * @param proteinStructureSubType
340 protected void setSecondaryStructure(STR proteinStructureSubType,
341 int pos, char[] secstr, char[] secstrcode)
343 switch (proteinStructureSubType)
362 switch (proteinStructureSubType)
368 secstrcode[pos] = 'H';
371 secstrcode[pos] = 'E';
379 * Convert any non-standard peptide codes to their standard code table
380 * equivalent. (Initial version only does Selenomethionine MSE->MET.)
382 * @param threeLetterCode
386 protected void replaceNonCanonicalResidue(String threeLetterCode,
389 String canonical = ResidueProperties
390 .getCanonicalAminoAcid(threeLetterCode);
391 if (canonical != null && !canonical.equalsIgnoreCase(threeLetterCode))
393 seq[pos] = ResidueProperties.getSingleCharacterCode(canonical);
398 * Not implemented - returns null
401 public String print()
410 public void setCallbackFunction(String callbackType,
411 String callbackFunction)
416 public void notifyCallback(CBK cbType, Object[] data)
418 String strInfo = (data == null || data[1] == null ? null : data[1]
423 sendConsoleEcho(strInfo);
426 notifyScriptTermination((String) data[2],
427 ((Integer) data[3]).intValue());
430 String mystatus = (String) data[3];
431 if (mystatus.indexOf("Picked") >= 0
432 || mystatus.indexOf("Sequence") >= 0)
435 sendConsoleMessage(strInfo);
437 else if (mystatus.indexOf("Completed") >= 0)
439 sendConsoleEcho(strInfo.substring(strInfo.lastIndexOf(",") + 2,
440 strInfo.length() - 1));
444 sendConsoleMessage(data == null ? null : strInfo);
447 sendConsoleMessage(strInfo);
454 String lastConsoleEcho = "";
456 private void sendConsoleEcho(String string)
458 lastConsoleEcho += string;
459 lastConsoleEcho += "\n";
462 String lastConsoleMessage = "";
464 private void sendConsoleMessage(String string)
466 lastConsoleMessage += string;
467 lastConsoleMessage += "\n";
470 int lastScriptTermination = -1;
472 String lastScriptMessage = "";
474 private void notifyScriptTermination(String string, int intValue)
476 lastScriptMessage += string;
477 lastScriptMessage += "\n";
478 lastScriptTermination = intValue;
482 public boolean notifyEnabled(CBK callbackPick)
484 switch (callbackPick)
498 * Not implemented - returns null
501 public String eval(String strEval)
507 * Not implemented - returns null
510 public float[][] functionXY(String functionName, int x, int y)
516 * Not implemented - returns null
519 public float[][][] functionXYZ(String functionName, int nx, int ny, int nz)
525 * Not implemented - returns null
528 public String createImage(String fileName, String imageType,
529 Object text_or_bytes, int quality)
535 * Not implemented - returns null
538 public Map<String, Object> getRegistryInfo()
547 public void showUrl(String url)
552 * Not implemented - returns null
555 public Dimension resizeInnerPanel(String data)
561 public Map<String, Object> getJSpecViewProperty(String arg0)
566 public boolean isPredictSecondaryStructure()
568 return predictSecondaryStructure;
571 public void setPredictSecondaryStructure(boolean predictSecondaryStructure)
573 this.predictSecondaryStructure = predictSecondaryStructure;
576 public boolean isVisibleChainAnnotation()
578 return visibleChainAnnotation;
581 public void setVisibleChainAnnotation(boolean visibleChainAnnotation)
583 this.visibleChainAnnotation = visibleChainAnnotation;