X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fext%2Fjmol%2FPDBFileWithJmol.java;h=8171f9da7e7d5d8aa7b2877708400fe0653217a9;hb=c19d2a91ca05e052e3408bf5852d88eb5d0608f1;hp=962fe3cbf80e2fc4d93e85cc25a535866cb0e887;hpb=51d41d5951ea5865488d3f163b14d297cddd27b4;p=jalview.git diff --git a/src/jalview/ext/jmol/PDBFileWithJmol.java b/src/jalview/ext/jmol/PDBFileWithJmol.java index 962fe3c..8171f9d 100644 --- a/src/jalview/ext/jmol/PDBFileWithJmol.java +++ b/src/jalview/ext/jmol/PDBFileWithJmol.java @@ -1,51 +1,50 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8) - * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9.0b2) + * Copyright (C) 2015 The Jalview Authors * * This file is part of Jalview. * * Jalview is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. * * Jalview is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along with Jalview. If not, see . + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. */ package jalview.ext.jmol; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.Annotation; +import jalview.datamodel.PDBEntry; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceI; +import jalview.io.AlignFile; +import jalview.io.FileParse; +import jalview.schemes.ResidueProperties; +import jalview.util.MessageManager; + import java.io.IOException; +import java.util.Hashtable; import java.util.Map; -import javax.xml.parsers.ParserConfigurationException; +import javajs.awt.Dimension; import org.jmol.api.JmolStatusListener; import org.jmol.api.JmolViewer; -import org.jmol.constant.EnumCallback; -import org.jmol.constant.EnumStructure; -import org.jmol.modelset.Chain; +import org.jmol.c.CBK; import org.jmol.modelset.Group; import org.jmol.modelset.Model; import org.jmol.modelset.ModelSet; -import org.jmol.modelset.Polymer; +import org.jmol.modelsetbio.BioModel; import org.jmol.modelsetbio.BioPolymer; import org.jmol.viewer.Viewer; -import org.openscience.jmol.app.JmolApp; -import org.xml.sax.SAXException; - -import fr.orsay.lri.varna.exceptions.ExceptionFileFormatOrSyntax; -import fr.orsay.lri.varna.exceptions.ExceptionLoadingFailed; -import fr.orsay.lri.varna.exceptions.ExceptionPermissionDenied; -import fr.orsay.lri.varna.exceptions.ExceptionUnmatchedClosingParentheses; -import jalview.datamodel.AlignmentAnnotation; -import jalview.datamodel.Annotation; -import jalview.datamodel.PDBEntry; -import jalview.datamodel.Sequence; -import jalview.datamodel.SequenceI; -import jalview.io.AlignFile; /** * Import and process PDB files with Jmol @@ -56,23 +55,20 @@ import jalview.io.AlignFile; public class PDBFileWithJmol extends AlignFile implements JmolStatusListener { - - JmolApp jmolApp = null; - Viewer viewer = null; - public PDBFileWithJmol(String inFile, String type) - throws ExceptionUnmatchedClosingParentheses, IOException, - ExceptionFileFormatOrSyntax, ParserConfigurationException, - SAXException, ExceptionPermissionDenied, ExceptionLoadingFailed, - InterruptedException + public PDBFileWithJmol(String inFile, String type) throws IOException { super(inFile, type); } + public PDBFileWithJmol(FileParse fp) throws IOException + { + super(fp); + } + public PDBFileWithJmol() { - // TODO Auto-generated constructor stub } /** @@ -83,26 +79,16 @@ public class PDBFileWithJmol extends AlignFile implements private Viewer getJmolData() { if (viewer == null) - { // note that -o -n -x are all implied - jmolApp = new JmolApp(); - jmolApp.isDataOnly = true; - jmolApp.haveConsole = false; - jmolApp.haveDisplay = false; - jmolApp.exitUponCompletion = true; + { try { viewer = (Viewer) JmolViewer.allocateViewer(null, null, null, null, - null, jmolApp.commandOptions, this); - viewer.setScreenDimension(jmolApp.startupWidth, - jmolApp.startupHeight); - jmolApp.startViewer(viewer, null); + null, "-x -o -n", this); } catch (ClassCastException x) { - throw new Error( - "Jmol version " - + JmolViewer.getJmolVersion() - + " is not compatible with this version of Jalview. Report this problem at issues.jalview.org", - x); + throw new Error(MessageManager.formatMessage( + "error.jmol_version_not_compatible_with_jalview_version", + new String[] { JmolViewer.getJmolVersion() }), x); } } return viewer; @@ -128,120 +114,172 @@ public class PDBFileWithJmol extends AlignFile implements * @see jalview.io.AlignFile#parse() */ @Override - public void parse() throws IOException, ExceptionFileFormatOrSyntax, - ParserConfigurationException, SAXException, - ExceptionPermissionDenied, ExceptionLoadingFailed, - InterruptedException, ExceptionUnmatchedClosingParentheses + public void parse() throws IOException { Viewer jmd = getJmolData(); jmd.openReader(getDataName(), getDataName(), getReader()); waitForScript(jmd); - if (jmd.getModelCount() > 0) + + if (jmd.ms.mc > 0) { - ModelSet ms = jmd.getModelSet(); - String structs = ms.calculateStructures(null, true, false, true); + ModelSet ms = jmd.ms; + // Jmol 14.2 added third argument doReport = false + ms.calculateStructures(null, true, false, false, true); // System.out.println("Structs\n"+structs); - for (Model model : ms.getModels()) + Group group = null; + int modelIndex = -1; + for (Model model : ms.am) { - for (int _bp = 0, _bpc = model.getBioPolymerCount(); _bp < _bpc; _bp++) + modelIndex++; + for (BioPolymer bp : ((BioModel) model).bioPolymers) { - Polymer bp = model.getBioPolymer(_bp); - if (bp instanceof BioPolymer) + int lastChainId = 0; // int value of character e.g. 65 for A + String lastChainIdAlpha = ""; + + int[] groups = bp.getLeadAtomIndices(); + char seq[] = new char[groups.length], secstr[] = new char[groups.length], secstrcode[] = new char[groups.length]; + int groupc = 0, len = 0, firstrnum = 1, lastrnum = 0; + + do { - BioPolymer biopoly = (BioPolymer) bp; - char _lastChainId = 0; - int[] groups = biopoly.getLeadAtomIndices(); - Group[] bpgrp = biopoly.getGroups(); - char seq[] = new char[groups.length], secstr[] = new char[groups.length], secstrcode[] = new char[groups.length]; - int groupc = 0, len = 0, firstrnum = 1, lastrnum = 0; - do + if (groupc >= groups.length + || ms.at[groups[groupc]].group.chain.chainID != lastChainId) { - if (groupc >= groups.length - || ms.atoms[groups[groupc]].getChainID() != _lastChainId) + /* + * on change of chain (or at end), construct the sequence and + * secondary structure annotation for the last chain + */ + if (len > 0) { - if (len > 0) + boolean isNa = bp.isNucleic(); + // normalise sequence from Jmol to jalview + int[] cinds = isNa ? ResidueProperties.nucleotideIndex + : ResidueProperties.aaIndex; + int nonGap = isNa ? ResidueProperties.maxNucleotideIndex + : ResidueProperties.maxProteinIndex; + char ngc = 'X'; + char newseq[] = new char[len]; + Annotation asecstr[] = new Annotation[len + firstrnum - 1]; + for (int p = 0; p < len; p++) { - char newseq[] = new char[len]; - System.arraycopy(seq, 0, newseq, 0, len); - Annotation asecstr[] = new Annotation[len]; - for (int p = 0; p < len; p++) + newseq[p] = cinds[seq[p]] == nonGap ? ngc : seq[p]; + if (secstr[p] >= 'A' && secstr[p] <= 'z') { - if (secstr[p] >= 'A' && secstr[p] <= 'z') + try { asecstr[p] = new Annotation("" + secstr[p], null, secstrcode[p], Float.NaN); + } catch (ArrayIndexOutOfBoundsException e) + { + // skip - patch for JAL-1836 } } - SequenceI sq = new Sequence("" + getDataName() + "|" - + model.getModelTitle() + "|" + _lastChainId, - newseq, firstrnum, lastrnum); - PDBEntry pdbe = new PDBEntry(); - pdbe.setFile(getDataName()); - pdbe.setId(getDataName()); - sq.addPDBId(pdbe); - seqs.add(sq); - if (!(biopoly.isDna() || biopoly.isRna())) + } + String modelTitle = (String) ms + .getInfo(modelIndex, "title"); + SequenceI sq = new Sequence("" + getDataName() + "|" + + modelTitle + "|" + lastChainIdAlpha, newseq, + firstrnum, lastrnum); + PDBEntry pdbe = new PDBEntry(); + pdbe.setFile(getDataName()); + pdbe.setId(getDataName()); + pdbe.setProperty(new Hashtable()); + // pdbe.getProperty().put("CHAIN", "" + _lastChainId); + pdbe.setChainCode(lastChainIdAlpha); + sq.addPDBId(pdbe); + // JAL-1533 + // Need to put the number of models for this polymer somewhere + // for Chimera/others to grab + // pdbe.getProperty().put("PDBMODELS", biopoly.) + seqs.add(sq); + if (!isNa) + { + String mt = modelTitle == null ? getDataName() + : modelTitle; + if (lastChainId >= ' ') { - AlignmentAnnotation ann = new AlignmentAnnotation( - "Secondary Structure", - "Secondary Structure from PDB File", asecstr); - sq.addAlignmentAnnotation(ann); - annotations.add(ann); + mt += lastChainIdAlpha; } + AlignmentAnnotation ann = new AlignmentAnnotation( + "Secondary Structure", "Secondary Structure for " + + mt, asecstr); + ann.belowAlignment = true; + ann.visible = true; + ann.autoCalculated = false; + ann.setCalcId(getClass().getName()); + sq.addAlignmentAnnotation(ann); + ann.adjustForAlignment(); + ann.validateRangeAndDisplay(); + annotations.add(ann); } - len = 0; - firstrnum = 1; - lastrnum = 0; } - if (groupc < groups.length) + len = 0; + firstrnum = 1; + lastrnum = 0; + } + if (groupc < groups.length) + { + group = ms.at[groups[groupc]].group; + if (len == 0) + { + firstrnum = group.getResno(); + lastChainId = group.chain.chainID; + lastChainIdAlpha = group.chain.getIDStr(); + } + else + { + lastrnum = group.getResno(); + } + seq[len] = group.getGroup1(); + + /* + * JAL-1828 replace a modified amino acid with its standard + * equivalent (e.g. MSE with MET->M) to maximise sequence matching + */ + String threeLetterCode = group.getGroup3(); + String canonical = ResidueProperties + .getCanonicalAminoAcid(threeLetterCode); + if (canonical != null + && !canonical.equalsIgnoreCase(threeLetterCode)) { - if (len == 0) + seq[len] = ResidueProperties + .getSingleCharacterCode(canonical); + } + switch (group.getProteinStructureSubType()) + { + case HELIX310: + if (secstr[len] == 0) { - firstrnum = bpgrp[groupc].getResno(); - _lastChainId = bpgrp[groupc].getChainID(); + secstr[len] = '3'; } - else + case HELIXALPHA: + if (secstr[len] == 0) { - lastrnum = bpgrp[groupc].getResno(); + secstr[len] = 'H'; } - seq[len] = bpgrp[groupc].getGroup1(); - switch (bpgrp[groupc].getProteinStructureSubType()) + case HELIXPI: + if (secstr[len] == 0) { - case HELIX_310: - if (secstr[len] == 0) - { - secstr[len] = '3'; - } - case HELIX_ALPHA: - if (secstr[len] == 0) - { - secstr[len] = 'H'; - } - case HELIX_PI: - if (secstr[len] == 0) - { - secstr[len] = 'P'; - } - case HELIX: - if (secstr[len] == 0) - { - secstr[len] = 'H'; - } - secstrcode[len] = 'H'; - break; - case SHEET: - secstr[len] = 'E'; - secstrcode[len] = 'E'; - break; - default: - secstr[len] = 0; - secstrcode[len] = 0; + secstr[len] = 'P'; + } + case HELIX: + if (secstr[len] == 0) + { + secstr[len] = 'H'; } - len++; + secstrcode[len] = 'H'; + break; + case SHEET: + secstr[len] = 'E'; + secstrcode[len] = 'E'; + break; + default: + secstr[len] = 0; + secstrcode[len] = 0; } - } while (groupc++ < groups.length); - - } + len++; + } + } while (groupc++ < groups.length); } } @@ -288,7 +326,7 @@ public class PDBFileWithJmol extends AlignFile implements * System.err.println("Squashed Jmol callback handler error:"); * e.printStackTrace(); } } */ - public void notifyCallback(EnumCallback type, Object[] data) + public void notifyCallback(CBK type, Object[] data) { String strInfo = (data == null || data[1] == null ? null : data[1] .toString()); @@ -304,11 +342,16 @@ public class PDBFileWithJmol extends AlignFile implements case MEASURE: String mystatus = (String) data[3]; if (mystatus.indexOf("Picked") >= 0 - || mystatus.indexOf("Sequence") >= 0) // picking mode + || mystatus.indexOf("Sequence") >= 0) + { + // Picking mode sendConsoleMessage(strInfo); + } else if (mystatus.indexOf("Completed") >= 0) + { sendConsoleEcho(strInfo.substring(strInfo.lastIndexOf(",") + 2, strInfo.length() - 1)); + } break; case MESSAGE: sendConsoleMessage(data == null ? null : strInfo); @@ -321,13 +364,6 @@ public class PDBFileWithJmol extends AlignFile implements } } - private void notifyFileLoaded(String string, String string2, - String string3, String string4, int intValue) - { - // TODO Auto-generated method stub - - } - String lastConsoleEcho = ""; private void sendConsoleEcho(String string) @@ -356,7 +392,7 @@ public class PDBFileWithJmol extends AlignFile implements } @Override - public boolean notifyEnabled(EnumCallback callbackPick) + public boolean notifyEnabled(CBK callbackPick) { switch (callbackPick) { @@ -366,16 +402,9 @@ public class PDBFileWithJmol extends AlignFile implements case LOADSTRUCT: case ERROR: return true; - case MEASURE: - case PICK: - case HOVER: - case RESIZE: - case SYNC: - case CLICK: - case ANIMFRAME: - case MINIMIZATION: + default: + return false; } - return false; } @Override @@ -422,10 +451,15 @@ public class PDBFileWithJmol extends AlignFile implements } @Override - public void resizeInnerPanel(String data) + public Dimension resizeInnerPanel(String data) { - // TODO Auto-generated method stub + return null; + } + @Override + public Map getJSpecViewProperty(String arg0) + { + return null; } }