X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fext%2Fjmol%2FJmolParser.java;h=ae8ff7a68c5e5b65e4cb07d9e17ebdb5bd79c369;hb=d46c8cbd1a5282ede9a0a94471f23ca002cf7df6;hp=a339c6b159778124862fd497e31096e6c5a2e372;hpb=8a693367d8a0f6113d21248993ca4e0355b32659;p=jalview.git diff --git a/src/jalview/ext/jmol/JmolParser.java b/src/jalview/ext/jmol/JmolParser.java index a339c6b..ae8ff7a 100644 --- a/src/jalview/ext/jmol/JmolParser.java +++ b/src/jalview/ext/jmol/JmolParser.java @@ -22,20 +22,22 @@ package jalview.ext.jmol; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.Annotation; +import jalview.datamodel.PDBEntry; import jalview.datamodel.SequenceI; +import jalview.io.DataSourceType; import jalview.io.FileParse; import jalview.io.StructureFile; import jalview.schemes.ResidueProperties; +import jalview.util.Format; import jalview.util.MessageManager; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Vector; -import javajs.awt.Dimension; - import org.jmol.api.JmolStatusListener; import org.jmol.api.JmolViewer; import org.jmol.c.CBK; @@ -43,9 +45,11 @@ import org.jmol.c.STR; import org.jmol.modelset.ModelSet; import org.jmol.viewer.Viewer; -import MCview.Atom; -import MCview.PDBChain; -import MCview.Residue; +import com.stevesoft.pat.Regex; + +import mc_view.Atom; +import mc_view.PDBChain; +import mc_view.Residue; /** * Import and process files with Jmol for file like PDB, mmCIF @@ -57,24 +61,19 @@ public class JmolParser extends StructureFile implements JmolStatusListener { Viewer viewer = null; - public JmolParser(boolean addAlignmentAnnotations, - boolean predictSecondaryStructure, boolean externalSecStr, - String inFile, String type) throws IOException + private boolean alphaFoldModel; + + public JmolParser(boolean immediate, Object inFile, + DataSourceType sourceType) throws IOException { - super(inFile, type); - this.visibleChainAnnotation = addAlignmentAnnotations; - this.predictSecondaryStructure = predictSecondaryStructure; - this.externalSecondaryStructure = externalSecStr; + // BH 2018 File or String for filename + super(immediate, inFile, sourceType); } - public JmolParser(boolean addAlignmentAnnotations, - boolean predictSecondaryStructure, boolean externalSecStr, - FileParse fp) throws IOException + public JmolParser(Object inFile, DataSourceType sourceType) + throws IOException { - super(fp); - this.visibleChainAnnotation = addAlignmentAnnotations; - this.predictSecondaryStructure = predictSecondaryStructure; - this.externalSecondaryStructure = externalSecStr; + super(inFile, sourceType); } public JmolParser(FileParse fp) throws IOException @@ -82,11 +81,6 @@ public class JmolParser extends StructureFile implements JmolStatusListener super(fp); } - public JmolParser(String inFile, String type) throws IOException - { - super(inFile, type); - } - public JmolParser() { } @@ -102,7 +96,6 @@ public class JmolParser extends StructureFile implements JmolStatusListener @Override public void parse() throws IOException { - setChains(new Vector()); Viewer jmolModel = getJmolData(); jmolModel.openReader(getDataName(), getDataName(), getReader()); @@ -113,6 +106,19 @@ public class JmolParser extends StructureFile implements JmolStatusListener */ if (jmolModel.ms.mc > 0) { + // ideally we do this + // try + // { + // setStructureFileType(jmolModel.evalString("show _fileType")); + // } catch (Exception q) + // { + // } + // ; + // instead, we distinguish .cif from non-.cif by filename + setStructureFileType(getDataName().toLowerCase().endsWith(".cif") + ? PDBEntry.Type.MMCIF.toString() + : "PDB"); + transformJmolModelToJalview(jmolModel.ms); } } @@ -128,61 +134,89 @@ public class JmolParser extends StructureFile implements JmolStatusListener { try { - viewer = (Viewer) JmolViewer.allocateViewer(null, null, null, null, - null, "-x -o -n", this); + /* + * params -o (output to sysout) -n (nodisplay) -x (exit when finished) + * see http://wiki.jmol.org/index.php/Jmol_Application + */ + + viewer = JalviewJmolBinding.getJmolData(this); // ensure the 'new' (DSSP) not 'old' (Ramachandran) SS method is used viewer.setBooleanProperty("defaultStructureDSSP", true); } catch (ClassCastException x) { throw new Error(MessageManager.formatMessage( "error.jmol_version_not_compatible_with_jalview_version", - new String[] { JmolViewer.getJmolVersion() }), x); + new String[] + { JmolViewer.getJmolVersion() }), x); } } return viewer; } + + public static Regex getNewAlphafoldValidator() + { + Regex validator = new Regex("(AF-[A-Z]+[0-9]+[A-Z0-9]+-F1)"); + validator.setIgnoreCase(true); + return validator; + } + public void transformJmolModelToJalview(ModelSet ms) throws IOException { try { + Regex alphaFold = getNewAlphafoldValidator(); String lastID = ""; List rna = new ArrayList(); List prot = new ArrayList(); PDBChain tmpchain; String pdbId = (String) ms.getInfo(0, "title"); - setId(pdbId); + String isMMCIF = (String) ms.getInfo(0, "fileType"); + + if (pdbId == null) + { + setId(safeName(getDataName())); + setPDBIdAvailable(false); + } + else + { + setId(pdbId); + setPDBIdAvailable(true); + alphaFoldModel = alphaFold.search(pdbId) && isMMCIF!=null && isMMCIF.equalsIgnoreCase("mmcif"); + + } List significantAtoms = convertSignificantAtoms(ms); for (Atom tmpatom : significantAtoms) { - try + if (tmpatom.resNumIns.trim().equals(lastID)) + { + // phosphorylated protein - seen both CA and P.. + continue; + } + tmpchain = findChain(tmpatom.chain); + if (tmpchain != null) { - tmpchain = findChain(tmpatom.chain); - if (tmpatom.resNumIns.trim().equals(lastID)) - { - // phosphorylated protein - seen both CA and P.. - continue; - } tmpchain.atoms.addElement(tmpatom); - } catch (Exception e) + } else { - tmpchain = new PDBChain(pdbId, tmpatom.chain); + tmpchain = new PDBChain(getId(), tmpatom.chain,isAlphafoldModel()); getChains().add(tmpchain); tmpchain.atoms.addElement(tmpatom); } lastID = tmpatom.resNumIns.trim(); } + if (isParseImmediately()) + { + // configure parsing settings from the static singleton + xferSettings(); + } + makeResidueList(); makeCaBondList(); - if (getId() == null) - { - setId(inFile.getName()); - } for (PDBChain chain : getChains()) { SequenceI chainseq = postProcessChain(chain); - createAnnotation(chainseq, chain, ms.at); if (isRNA(chainseq)) { rna.add(chainseq); @@ -191,44 +225,126 @@ public class JmolParser extends StructureFile implements JmolStatusListener { prot.add(chainseq); } + + // look at local setting for adding secondary tructure + if (predictSecondaryStructure) + { + createAnnotation(chainseq, chain, ms.at); + } } } catch (OutOfMemoryError er) { - System.out - .println("OUT OF MEMORY LOADING TRANSFORMING JMOL MODEL TO JALVIEW MODEL"); - throw new IOException( - MessageManager - .getString("exception.outofmemory_loading_mmcif_file")); + System.out.println( + "OUT OF MEMORY LOADING TRANSFORMING JMOL MODEL TO JALVIEW MODEL"); + throw new IOException(MessageManager + .getString("exception.outofmemory_loading_mmcif_file")); } } + private boolean isAlphafoldModel() + { + return alphaFoldModel; + } + private List convertSignificantAtoms(ModelSet ms) { List significantAtoms = new ArrayList(); + HashMap chainTerMap = new HashMap(); + org.jmol.modelset.Atom prevAtom = null; for (org.jmol.modelset.Atom atom : ms.at) { if (atom.getAtomName().equalsIgnoreCase("CA") || atom.getAtomName().equalsIgnoreCase("P")) { + if (!atomValidated(atom, prevAtom, chainTerMap)) + { + continue; + } Atom curAtom = new Atom(atom.x, atom.y, atom.z); curAtom.atomIndex = atom.getIndex(); curAtom.chain = atom.getChainIDStr(); - curAtom.insCode = atom.group.getInsertionCode(); + curAtom.insCode = atom.group.getInsertionCode() == '\000' ? ' ' + : atom.group.getInsertionCode(); curAtom.name = atom.getAtomName(); curAtom.number = atom.getAtomNumber(); curAtom.resName = atom.getGroup3(true); curAtom.resNumber = atom.getResno(); - curAtom.occupancy = ms.occupancies != null ? ms.occupancies[atom - .getIndex()] : Float.valueOf(atom.getOccupancy100()); - curAtom.resNumIns = "" + curAtom.resNumber + curAtom.insCode; - // curAtom.tfactor = atom.group.; + curAtom.occupancy = ms.occupancies != null + ? ms.occupancies[atom.getIndex()] + : Float.valueOf(atom.getOccupancy100()); + String fmt = new Format("%4i").form(curAtom.resNumber); + curAtom.resNumIns = (fmt + curAtom.insCode); + curAtom.tfactor = atom.getBfactor100() / 100f; curAtom.type = 0; - significantAtoms.add(curAtom); + // significantAtoms.add(curAtom); + // ignore atoms from subsequent models + if (!significantAtoms.contains(curAtom)) + { + significantAtoms.add(curAtom); + } + prevAtom = atom; } } return significantAtoms; } + private boolean atomValidated(org.jmol.modelset.Atom curAtom, + org.jmol.modelset.Atom prevAtom, + HashMap chainTerMap) + { + // System.out.println("Atom: " + curAtom.getAtomNumber() + // + " Last atom index " + curAtom.group.lastAtomIndex); + if (chainTerMap == null || prevAtom == null) + { + return true; + } + String curAtomChId = curAtom.getChainIDStr(); + String prevAtomChId = prevAtom.getChainIDStr(); + // new chain encoutered + if (!prevAtomChId.equals(curAtomChId)) + { + // On chain switch add previous chain termination to xTerMap if not exists + if (!chainTerMap.containsKey(prevAtomChId)) + { + chainTerMap.put(prevAtomChId, prevAtom); + } + // if current atom belongs to an already terminated chain and the resNum + // diff < 5 then mark as valid and update termination Atom + if (chainTerMap.containsKey(curAtomChId)) + { + if (curAtom.getResno() < chainTerMap.get(curAtomChId).getResno()) + { + return false; + } + if ((curAtom.getResno() + - chainTerMap.get(curAtomChId).getResno()) < 5) + { + chainTerMap.put(curAtomChId, curAtom); + return true; + } + return false; + } + } + // atom with previously terminated chain encountered + else if (chainTerMap.containsKey(curAtomChId)) + { + if (curAtom.getResno() < chainTerMap.get(curAtomChId).getResno()) + { + return false; + } + if ((curAtom.getResno() + - chainTerMap.get(curAtomChId).getResno()) < 5) + { + chainTerMap.put(curAtomChId, curAtom); + return true; + } + return false; + } + // HETATM with resNum jump > 2 + return !(curAtom.isHetero() + && ((curAtom.getResno() - prevAtom.getResno()) > 2)); + } + private void createAnnotation(SequenceI sequence, PDBChain chain, org.jmol.modelset.Atom[] jmolAtoms) { @@ -256,7 +372,7 @@ public class JmolParser extends StructureFile implements JmolStatusListener /** * Helper method that adds an AlignmentAnnotation for secondary structure to - * the sequence, provided at least one secondary structure prediction has been + * the sequence, provided at least one secondary structure assignment has been * made * * @param modelTitle @@ -271,16 +387,22 @@ public class JmolParser extends StructureFile implements JmolStatusListener SequenceI sq, char[] secstr, char[] secstrcode, String chainId, int firstResNum) { - char[] seq = sq.getSequence(); + int length = sq.getLength(); boolean ssFound = false; - Annotation asecstr[] = new Annotation[seq.length + firstResNum - 1]; - for (int p = 0; p < seq.length; p++) + Annotation asecstr[] = new Annotation[length + firstResNum - 1]; + for (int p = 0; p < length; p++) { if (secstr[p] >= 'A' && secstr[p] <= 'z') { - asecstr[p] = new Annotation(String.valueOf(secstr[p]), null, - secstrcode[p], Float.NaN); - ssFound = true; + try + { + asecstr[p] = new Annotation(String.valueOf(secstr[p]), null, + secstrcode[p], Float.NaN); + ssFound = true; + } catch (Exception e) + { + // e.printStackTrace(); + } } } @@ -325,8 +447,8 @@ public class JmolParser extends StructureFile implements JmolStatusListener * @param secstr * @param secstrcode */ - protected void setSecondaryStructure(STR proteinStructureSubType, - int pos, char[] secstr, char[] secstrcode) + protected void setSecondaryStructure(STR proteinStructureSubType, int pos, + char[] secstr, char[] secstrcode) { switch (proteinStructureSubType) { @@ -386,7 +508,7 @@ public class JmolParser extends StructureFile implements JmolStatusListener * Not implemented - returns null */ @Override - public String print() + public String print(SequenceI[] seqs, boolean jvSuffix) { return null; } @@ -403,8 +525,8 @@ public class JmolParser extends StructureFile implements JmolStatusListener @Override public void notifyCallback(CBK cbType, Object[] data) { - String strInfo = (data == null || data[1] == null ? null : data[1] - .toString()); + String strInfo = (data == null || data[1] == null ? null + : data[1].toString()); switch (cbType) { case ECHO: @@ -504,7 +626,8 @@ public class JmolParser extends StructureFile implements JmolStatusListener * Not implemented - returns null */ @Override - public float[][][] functionXYZ(String functionName, int nx, int ny, int nz) + public float[][][] functionXYZ(String functionName, int nx, int ny, + int nz) { return null; } @@ -540,7 +663,7 @@ public class JmolParser extends StructureFile implements JmolStatusListener * Not implemented - returns null */ @Override - public Dimension resizeInnerPanel(String data) + public int[] resizeInnerPanel(String data) { return null; } @@ -556,9 +679,20 @@ public class JmolParser extends StructureFile implements JmolStatusListener return predictSecondaryStructure; } - public void setPredictSecondaryStructure(boolean predictSecondaryStructure) + public void setPredictSecondaryStructure( + boolean predictSecondaryStructure) { this.predictSecondaryStructure = predictSecondaryStructure; } + public boolean isVisibleChainAnnotation() + { + return visibleChainAnnotation; + } + + public void setVisibleChainAnnotation(boolean visibleChainAnnotation) + { + this.visibleChainAnnotation = visibleChainAnnotation; + } + }