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.structure.StructureImportSettings;
30 import jalview.util.MessageManager;
32 import java.io.IOException;
33 import java.util.ArrayList;
34 import java.util.List;
36 import java.util.Vector;
38 import javajs.awt.Dimension;
40 import org.jmol.api.JmolStatusListener;
41 import org.jmol.api.JmolViewer;
42 import org.jmol.c.CBK;
43 import org.jmol.c.STR;
44 import org.jmol.modelset.ModelSet;
45 import org.jmol.viewer.Viewer;
48 import MCview.PDBChain;
49 import MCview.Residue;
52 * Import and process files with Jmol for file like PDB, mmCIF
57 public class JmolParser extends StructureFile implements JmolStatusListener
61 public JmolParser(boolean addAlignmentAnnotations, boolean predictSecStr,
62 boolean externalSecStr, String inFile, String type)
68 public JmolParser(boolean addAlignmentAnnotations, boolean predictSecStr,
69 boolean externalSecStr, FileParse fp) throws IOException
79 * Calls the Jmol library to parse the PDB/mmCIF file, and then inspects the
80 * resulting object model to generate Jalview-style sequences, with secondary
81 * structure annotation added where available (i.e. where it has been computed
82 * by Jmol using DSSP).
84 * @see jalview.io.AlignFile#parse()
87 public void parse() throws IOException
89 setChains(new Vector<PDBChain>());
90 Viewer jmolModel = getJmolData();
91 jmolModel.openReader(getDataName(), getDataName(), getReader());
92 waitForScript(jmolModel);
95 * Convert one or more Jmol Model objects to Jalview sequences
97 if (jmolModel.ms.mc > 0)
99 transformJmolModelToJalview(jmolModel.ms);
104 * create a headless jmol instance for dataprocessing
108 private Viewer getJmolData()
114 viewer = (Viewer) JmolViewer.allocateViewer(null, null, null, null,
115 null, "-x -o -n", this);
116 // ensure the 'new' (DSSP) not 'old' (Ramachandran) SS method is used
117 viewer.setBooleanProperty("defaultStructureDSSP", true);
118 } catch (ClassCastException x)
120 throw new Error(MessageManager.formatMessage(
121 "error.jmol_version_not_compatible_with_jalview_version",
122 new String[] { JmolViewer.getJmolVersion() }), x);
128 public void transformJmolModelToJalview(ModelSet ms) throws IOException
133 List<SequenceI> rna = new ArrayList<SequenceI>();
134 List<SequenceI> prot = new ArrayList<SequenceI>();
136 String pdbId = (String) ms.getInfo(0, "title");
138 List<Atom> significantAtoms = convertSignificantAtoms(ms);
139 for (Atom tmpatom : significantAtoms)
143 tmpchain = findChain(tmpatom.chain);
144 if (tmpatom.resNumIns.trim().equals(lastID))
146 // phosphorylated protein - seen both CA and P..
149 tmpchain.atoms.addElement(tmpatom);
150 } catch (Exception e)
152 tmpchain = new PDBChain(pdbId, tmpatom.chain);
153 getChains().add(tmpchain);
154 tmpchain.atoms.addElement(tmpatom);
156 lastID = tmpatom.resNumIns.trim();
165 setId(safeName(getDataName()));
167 for (PDBChain chain : getChains())
169 SequenceI chainseq = postProcessChain(chain);
179 if (StructureImportSettings.isProcessSecondaryStructure())
181 createAnnotation(chainseq, chain, ms.at);
184 } catch (OutOfMemoryError er)
187 .println("OUT OF MEMORY LOADING TRANSFORMING JMOL MODEL TO JALVIEW MODEL");
188 throw new IOException(
190 .getString("exception.outofmemory_loading_mmcif_file"));
194 private List<Atom> convertSignificantAtoms(ModelSet ms)
196 List<Atom> significantAtoms = new ArrayList<Atom>();
197 for (org.jmol.modelset.Atom atom : ms.at)
199 // System.out.println("Seq Id : " + atom.getSeqID());
200 // System.out.println("To String : " + atom.toString());
201 if (!StructureImportSettings.isProcessHETATMs() && atom.isHetero())
205 if (atom.getAtomName().equalsIgnoreCase("CA")
206 || atom.getAtomName().equalsIgnoreCase("P"))
208 Atom curAtom = new Atom(atom.x, atom.y, atom.z);
209 curAtom.atomIndex = atom.getIndex();
210 curAtom.chain = atom.getChainIDStr();
211 curAtom.insCode = atom.group.getInsertionCode();
212 curAtom.name = atom.getAtomName();
213 curAtom.number = atom.getAtomNumber();
214 curAtom.resName = atom.getGroup3(true);
215 curAtom.resNumber = atom.getResno();
216 curAtom.occupancy = ms.occupancies != null ? ms.occupancies[atom
217 .getIndex()] : Float.valueOf(atom.getOccupancy100());
218 curAtom.resNumIns = "" + curAtom.resNumber + curAtom.insCode;
219 curAtom.tfactor = atom.getBfactor100() / 100f;
221 significantAtoms.add(curAtom);
224 return significantAtoms;
227 private void createAnnotation(SequenceI sequence, PDBChain chain,
228 org.jmol.modelset.Atom[] jmolAtoms)
230 char[] secstr = new char[sequence.getLength()];
231 char[] secstrcode = new char[sequence.getLength()];
233 // Ensure Residue size equals Seq size
234 if (chain.residues.size() != sequence.getLength())
239 for (Residue residue : chain.residues)
241 Atom repAtom = residue.getAtoms().get(0);
242 STR proteinStructureSubType = jmolAtoms[repAtom.atomIndex].group
243 .getProteinStructureSubType();
244 setSecondaryStructure(proteinStructureSubType, annotIndex, secstr,
248 addSecondaryStructureAnnotation(chain.pdbid, sequence, secstr,
249 secstrcode, chain.id, sequence.getStart());
253 * Helper method that adds an AlignmentAnnotation for secondary structure to
254 * the sequence, provided at least one secondary structure prediction has been
265 protected void addSecondaryStructureAnnotation(String modelTitle,
266 SequenceI sq, char[] secstr, char[] secstrcode, String chainId,
269 char[] seq = sq.getSequence();
270 boolean ssFound = false;
271 Annotation asecstr[] = new Annotation[seq.length + firstResNum - 1];
272 for (int p = 0; p < seq.length; p++)
274 if (secstr[p] >= 'A' && secstr[p] <= 'z')
278 asecstr[p] = new Annotation(String.valueOf(secstr[p]), null,
279 secstrcode[p], Float.NaN);
281 } catch (Exception e)
283 // e.printStackTrace();
290 String mt = modelTitle == null ? getDataName() : modelTitle;
292 AlignmentAnnotation ann = new AlignmentAnnotation(
293 "Secondary Structure", "Secondary Structure for " + mt,
295 ann.belowAlignment = true;
297 ann.autoCalculated = false;
298 ann.setCalcId(getClass().getName());
299 ann.adjustForAlignment();
300 ann.validateRangeAndDisplay();
301 annotations.add(ann);
302 sq.addAlignmentAnnotation(ann);
306 private void waitForScript(Viewer jmd)
308 while (jmd.isScriptExecuting())
314 } catch (InterruptedException x)
321 * Convert Jmol's secondary structure code to Jalview's, and stored it in the
322 * secondary structure arrays at the given sequence position
324 * @param proteinStructureSubType
329 protected void setSecondaryStructure(STR proteinStructureSubType,
330 int pos, char[] secstr, char[] secstrcode)
332 switch (proteinStructureSubType)
351 switch (proteinStructureSubType)
357 secstrcode[pos] = 'H';
360 secstrcode[pos] = 'E';
368 * Convert any non-standard peptide codes to their standard code table
369 * equivalent. (Initial version only does Selenomethionine MSE->MET.)
371 * @param threeLetterCode
375 protected void replaceNonCanonicalResidue(String threeLetterCode,
378 String canonical = ResidueProperties
379 .getCanonicalAminoAcid(threeLetterCode);
380 if (canonical != null && !canonical.equalsIgnoreCase(threeLetterCode))
382 seq[pos] = ResidueProperties.getSingleCharacterCode(canonical);
387 * Not implemented - returns null
390 public String print()
399 public void setCallbackFunction(String callbackType,
400 String callbackFunction)
405 public void notifyCallback(CBK cbType, Object[] data)
407 String strInfo = (data == null || data[1] == null ? null : data[1]
412 sendConsoleEcho(strInfo);
415 notifyScriptTermination((String) data[2],
416 ((Integer) data[3]).intValue());
419 String mystatus = (String) data[3];
420 if (mystatus.indexOf("Picked") >= 0
421 || mystatus.indexOf("Sequence") >= 0)
424 sendConsoleMessage(strInfo);
426 else if (mystatus.indexOf("Completed") >= 0)
428 sendConsoleEcho(strInfo.substring(strInfo.lastIndexOf(",") + 2,
429 strInfo.length() - 1));
433 sendConsoleMessage(data == null ? null : strInfo);
436 sendConsoleMessage(strInfo);
443 String lastConsoleEcho = "";
445 private void sendConsoleEcho(String string)
447 lastConsoleEcho += string;
448 lastConsoleEcho += "\n";
451 String lastConsoleMessage = "";
453 private void sendConsoleMessage(String string)
455 lastConsoleMessage += string;
456 lastConsoleMessage += "\n";
459 int lastScriptTermination = -1;
461 String lastScriptMessage = "";
463 private void notifyScriptTermination(String string, int intValue)
465 lastScriptMessage += string;
466 lastScriptMessage += "\n";
467 lastScriptTermination = intValue;
471 public boolean notifyEnabled(CBK callbackPick)
473 switch (callbackPick)
487 * Not implemented - returns null
490 public String eval(String strEval)
496 * Not implemented - returns null
499 public float[][] functionXY(String functionName, int x, int y)
505 * Not implemented - returns null
508 public float[][][] functionXYZ(String functionName, int nx, int ny, int nz)
514 * Not implemented - returns null
517 public String createImage(String fileName, String imageType,
518 Object text_or_bytes, int quality)
524 * Not implemented - returns null
527 public Map<String, Object> getRegistryInfo()
536 public void showUrl(String url)
541 * Not implemented - returns null
544 public Dimension resizeInnerPanel(String data)
550 public Map<String, Object> getJSpecViewProperty(String arg0)
555 public boolean isPredictSecondaryStructure()
557 return predictSecondaryStructure;
560 public void setPredictSecondaryStructure(boolean predictSecondaryStructure)
562 this.predictSecondaryStructure = predictSecondaryStructure;
565 public boolean isVisibleChainAnnotation()
567 return visibleChainAnnotation;
570 public void setVisibleChainAnnotation(boolean visibleChainAnnotation)
572 this.visibleChainAnnotation = visibleChainAnnotation;