From: Jim Procter Date: Thu, 19 Jan 2017 17:08:41 +0000 (+0000) Subject: Merge branch 'spike/JAL-2040_JAL-2137_phyre2' into features/JAL-2040_JAL-2137_phyre2 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=3e98c1348b037f0972367245a524f182029a9686;hp=-c;p=jalview.git Merge branch 'spike/JAL-2040_JAL-2137_phyre2' into features/JAL-2040_JAL-2137_phyre2 --- 3e98c1348b037f0972367245a524f182029a9686 diff --combined src/jalview/ext/jmol/JmolParser.java index b2ba256,438b403..45e72d7 --- a/src/jalview/ext/jmol/JmolParser.java +++ b/src/jalview/ext/jmol/JmolParser.java @@@ -22,18 -22,16 +22,18 @@@ package jalview.ext.jmol import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.Annotation; -import jalview.datamodel.DBRefSource; +import jalview.datamodel.PDBEntry; import jalview.datamodel.SequenceI; import jalview.io.FileParse; import jalview.io.StructureFile; import jalview.schemes.ResidueProperties; -import jalview.structure.StructureViewSettings; +import jalview.structure.StructureImportSettings; +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; @@@ -61,12 -59,15 +61,12 @@@ public class JmolParser extends Structu { Viewer viewer = null; - public JmolParser(boolean addAlignmentAnnotations, boolean predictSecStr, - boolean externalSecStr, String inFile, String type) - throws IOException + public JmolParser(String inFile, String type) throws IOException { super(inFile, type); } - public JmolParser(boolean addAlignmentAnnotations, boolean predictSecStr, - boolean externalSecStr, FileParse fp) throws IOException + public JmolParser(FileParse fp) throws IOException { super(fp); } @@@ -86,6 -87,15 +86,6 @@@ @Override public void parse() throws IOException { - String dataName = getDataName(); - if (dataName.endsWith(".cif")) - { - setDbRefType(DBRefSource.MMCIF); - } - else - { - setDbRefType(DBRefSource.PDB); - } setChains(new Vector()); Viewer jmolModel = getJmolData(); jmolModel.openReader(getDataName(), getDataName(), getReader()); @@@ -96,18 -106,6 +96,18 @@@ */ 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); } } @@@ -123,10 -121,6 +123,10 @@@ { try { + /* + * params -o (output to sysout) -n (nodisplay) -x (exit when finished) + * see http://wiki.jmol.org/index.php/Jmol_Application + */ viewer = (Viewer) JmolViewer.allocateViewer(null, null, null, null, null, "-x -o -n", this); // ensure the 'new' (DSSP) not 'old' (Ramachandran) SS method is used @@@ -150,17 -144,7 +150,17 @@@ List prot = new ArrayList(); PDBChain tmpchain; String pdbId = (String) ms.getInfo(0, "title"); - setId(pdbId); + + if (pdbId == null) + { + setId(safeName(getDataName())); + setPDBIdAvailable(false); + } + else + { + setId(pdbId); + setPDBIdAvailable(true); + } List significantAtoms = convertSignificantAtoms(ms); for (Atom tmpatom : significantAtoms) { @@@ -175,7 -159,7 +175,7 @@@ tmpchain.atoms.addElement(tmpatom); } catch (Exception e) { - tmpchain = new PDBChain(pdbId, tmpatom.chain); + tmpchain = new PDBChain(getId(), tmpatom.chain); getChains().add(tmpchain); tmpchain.atoms.addElement(tmpatom); } @@@ -186,6 -170,13 +186,14 @@@ makeResidueList(); makeCaBondList(); + if (getId() == null) + { + // always use resource name, not the hardwired file + // Does the value of ID get used ? Behaviour needs to be + // documented and tested + setId(getDataName()); + } ++ for (PDBChain chain : getChains()) { SequenceI chainseq = postProcessChain(chain); @@@ -198,7 -189,7 +206,7 @@@ prot.add(chainseq); } - if (StructureViewSettings.isPredictSecondaryStructure()) + if (StructureImportSettings.isProcessSecondaryStructure()) { createAnnotation(chainseq, chain, ms.at); } @@@ -216,99 -207,36 +224,99 @@@ 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; + 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) { @@@ -360,9 -288,9 +368,9 @@@ { try { - asecstr[p] = new Annotation(String.valueOf(secstr[p]), null, - secstrcode[p], Float.NaN); - ssFound = true; + asecstr[p] = new Annotation(String.valueOf(secstr[p]), null, + secstrcode[p], Float.NaN); + ssFound = true; } catch (Exception e) { // e.printStackTrace(); diff --combined src/jalview/io/AnnotationFile.java index 34fdabe,3bb41c4..eca27a7 --- a/src/jalview/io/AnnotationFile.java +++ b/src/jalview/io/AnnotationFile.java @@@ -28,14 -28,20 +28,19 @@@ import jalview.datamodel.Annotation import jalview.datamodel.ColumnSelection; import jalview.datamodel.GraphLine; import jalview.datamodel.HiddenSequences; + import jalview.datamodel.PDBEntry; + import jalview.datamodel.PDBEntry.Type; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.schemes.ColourSchemeI; import jalview.schemes.ColourSchemeProperty; -import jalview.schemes.ResidueProperties; import jalview.schemes.UserColourScheme; + import jalview.structure.StructureSelectionManager; import java.io.BufferedReader; + import java.io.File; import java.io.FileReader; + import java.io.IOException; import java.io.InputStreamReader; import java.io.StringReader; import java.net.URL; @@@ -686,21 -692,41 +691,41 @@@ public class AnnotationFil public boolean readAnnotationFile(AlignmentI al, ColumnSelection colSel, String file, String protocol) { + baseUri = ""; BufferedReader in = null; try { if (protocol.equals(AppletFormatAdapter.FILE)) { in = new BufferedReader(new FileReader(file)); + baseUri = new File(file).getParent(); + if (baseUri == null) + { + baseUri = ""; + } + else + { + baseUri += "/"; + } } else if (protocol.equals(AppletFormatAdapter.URL)) { URL url = new URL(file); in = new BufferedReader(new InputStreamReader(url.openStream())); + String bs = url.toExternalForm(); + baseUri = bs.substring(0, bs.indexOf(url.getHost()) + + url.getHost().length()); + baseUri += url.toURI().getPath(); + if (baseUri.lastIndexOf("/") > -1) + { + baseUri = baseUri.substring(0, baseUri.lastIndexOf("/")) + "/"; + } } else if (protocol.equals(AppletFormatAdapter.PASTE)) { in = new BufferedReader(new StringReader(file)); + // TODO - support mimencoded PDBs for a paste.. ? + baseUri = ""; } else if (protocol.equals(AppletFormatAdapter.CLASSLOADER)) { @@@ -708,6 -734,8 +733,8 @@@ if (is != null) { in = new BufferedReader(new java.io.InputStreamReader(is)); + // TODO: this probably doesn't work for classloader - needs a test + baseUri = new File("/" + file).getParent() + "/"; } } if (in != null) @@@ -733,7 -761,14 +760,14 @@@ String lastread = ""; - private static String GRAPHLINE = "GRAPHLINE", COMBINE = "COMBINE"; + /** + * used for resolving absolute references to resources relative to + * annotationFile location + */ + String baseUri = ""; + + private static String GRAPHLINE = "GRAPHLINE", COMBINE = "COMBINE", + STRUCTMODEL = "STRUCTMODEL"; public boolean parseAnnotationFrom(AlignmentI al, ColumnSelection colSel, BufferedReader in) throws Exception @@@ -979,7 -1014,43 +1013,43 @@@ modified = true; continue; } - + else if (token.equalsIgnoreCase(STRUCTMODEL)) + { + boolean failedtoadd = true; + // expect + // STRUCTMODEL + if (st.hasMoreTokens()) { + refSeq = al.findName(refSeqId = st.nextToken()); + if (refSeq == null) + { + System.err.println("Couldn't locate " + refSeqId + + " in the alignment for STRUCTMODEL"); + refSeqId = null; + } + else + { + String tempId = st.nextToken(); + String urlToModel = st.nextToken(); + String urlToPairwise = st.hasMoreTokens() ? st.nextToken() + : ""; + if (add_structmodel(al, refSeq, tempId, urlToModel, + urlToPairwise)) + { + failedtoadd = false; + } + } + } + if (failedtoadd) + { + System.err + .println("Need [] as tab separated fields after " + + STRUCTMODEL); + } else { + modified = true; + } + continue; + } // Parse out the annotation row graphStyle = AlignmentAnnotation.getGraphValueFromString(token); label = st.nextToken(); @@@ -1179,6 -1250,107 +1249,107 @@@ return modified; } + /** + * resolve a structural model and generate and add an alignment sequence for + * it + * + * @param refSeq2 + * @param tempId + * @param urlToModel + * @param urlToPairwise + * @return true if model and sequence was added + */ + private boolean add_structmodel(AlignmentI al, SequenceI refSeq2, String tempId, + String urlToModel, String urlToPairwise) + { + String warningMessage = null, modelPath = null, modelProt = null, aliPath = null, aliProt = null; + boolean added = false; + try { + // locate tempId. if it exists, will need to merge, otherwise: + SequenceI templateSeq = al.findName(tempId); + // 1. load urlToModel + modelPath = resolveAbsolute(urlToModel); + modelProt = AppletFormatAdapter.checkProtocol(modelPath); + // need to transfer to local temp file ? + PDBEntry modelpe = new PDBEntry(tempId, null, Type.FILE, modelPath); + PDBEntry templpe = new PDBEntry(tempId, null, Type.FILE, modelPath); + refSeq2.addPDBId(modelpe); + aliPath = resolveAbsolute(urlToPairwise); + aliProt = AppletFormatAdapter.checkProtocol(aliPath); + // 2. load urlToPairwise + AlignmentI pwa = new AppletFormatAdapter().readFile(aliPath, aliProt, + "FASTA"); + SequenceI qPw = null, tPw = null; + if (pwa != null) + { + // resolve query/template sequences in provided alignment + qPw = pwa.findName(refSeqId); + tPw = pwa.findName(tempId); + } + if (false) + // (qPw != null && tPw != null) + { + // not yet complete + // refalQ vvva--addrvvvtttddd + // refalT ---aaaa---sss---ddd + // profalQ ---v-v-v-a.-.-a---dd--r--vvvtt--td--dd + // profalT ---.-.-.-aa-a-a---..--.--sss..--.d--dd + // Pragmatic solution here: + // Map templpe onto refalT only where refalT and refalQ are both + // non-gaps + + // columns for start..end in refSeq2 + int[] gapMap = refSeq2.gapMap(); + // insert gaps in tPw + int curi = 0, width = refSeq2.getLength(); + // TBC + } + else + { + // assume 1:1 - so synthesise sequences to use to construct mapping + StructureFile pdbf = StructureSelectionManager + .getStructureSelectionManager().setMapping(false, + new SequenceI[] { refSeq2.getDatasetSequence() }, + null, modelPath, modelProt); + refSeq2.getDatasetSequence().addPDBId(modelpe); + if (templateSeq == null && tPw != null) + { + tPw.createDatasetSequence(); + tPw.getDatasetSequence().addPDBId(templpe); // needs to set mapping based on model yet... + al.addSequence(tPw); + added = true; + } + } + // 3. pad/insert gaps in urlToPairwise according to gaps already present in + // refSeq2 + // 4. add padded tempId sequence to alignment + // 4. associate urlToModel with refSeq2 based on position map provided by + // urlToPairwise + // 5. associate urlToModel with tempId based on position map provided by + // urlToPairwise + // start a thread to load urlToModel and process/annotate sequences. + } catch (IOException x) + { + warningMessage = x.toString(); + } finally { + if (warningMessage !=null) + { + System.err.println("Warnings whilst processing STRUCTMODEL: "+warningMessage); + } + return added; + } + } + + private String resolveAbsolute(String relURI) + { + if (relURI.indexOf(":/") > -1 || relURI.startsWith("/") + || "".equals(baseUri) || relURI.startsWith(baseUri)) + { + return relURI; + } + return baseUri + relURI; + } + private void parseHideCols(ColumnSelection colSel, String nextToken) { StringTokenizer inval = new StringTokenizer(nextToken, ","); @@@ -1637,9 -1809,9 +1808,9 @@@ else if (key.equalsIgnoreCase("consThreshold")) { sg.cs.setConservationInc(Integer.parseInt(value)); - Conservation c = new Conservation("Group", - ResidueProperties.propHash, 3, sg.getSequences(null), - sg.getStartRes(), sg.getEndRes() + 1); + Conservation c = new Conservation("Group", 3, + sg.getSequences(null), sg.getStartRes(), + sg.getEndRes() + 1); c.calculate(); c.verdict(false, 25); // TODO: refer to conservation percent threshold diff --combined src/jalview/structure/StructureSelectionManager.java index 7e691be,04cb559..c90b3c8 --- a/src/jalview/structure/StructureSelectionManager.java +++ b/src/jalview/structure/StructureSelectionManager.java @@@ -32,7 -32,6 +32,7 @@@ import jalview.datamodel.Annotation import jalview.datamodel.PDBEntry; import jalview.datamodel.SearchResults; import jalview.datamodel.SequenceI; +import jalview.ext.jmol.JmolParser; import jalview.gui.IProgressIndicator; import jalview.io.AppletFormatAdapter; import jalview.io.StructureFile; @@@ -327,6 -326,7 +327,6 @@@ public class StructureSelectionManage return setMapping(true, sequence, targetChains, pdbFile, protocol); } - /** * create sequence structure mappings between each sequence and the given * pdbFile (retrieved via the given protocol). @@@ -347,7 -347,8 +347,7 @@@ */ synchronized public StructureFile setMapping(boolean forStructureView, SequenceI[] sequenceArray, String[] targetChainIds, - String pdbFile, - String protocol) + String pdbFile, String protocol) { /* * There will be better ways of doing this in the future, for now we'll use @@@ -383,16 -384,23 +383,16 @@@ boolean isMapUsingSIFTs = SiftsSettings.isMapWithSifts(); try { - - if (pdbFile != null && isCIFFile(pdbFile)) - { - pdb = new jalview.ext.jmol.JmolParser(addTempFacAnnot, parseSecStr, - secStructServices, pdbFile, protocol); - } - else - { - pdb = new PDBfile(addTempFacAnnot, parseSecStr, secStructServices, - pdbFile, protocol); - } + pdb = new JmolParser(pdbFile, protocol); if (pdb.getId() != null && pdb.getId().trim().length() > 0 && AppletFormatAdapter.FILE.equals(protocol)) { registerPDBFile(pdb.getId().trim(), pdbFile); } + // if PDBId is unavailable then skip SIFTS mapping execution path + isMapUsingSIFTs = pdb.isPPDBIdAvailable(); + } catch (Exception ex) { ex.printStackTrace(); @@@ -416,12 -424,6 +416,12 @@@ { boolean infChain = true; final SequenceI seq = sequenceArray[s]; + SequenceI ds = seq; + while (ds.getDatasetSequence() != null) + { + ds = ds.getDatasetSequence(); + } + if (targetChainIds != null && targetChainIds[s] != null) { infChain = false; @@@ -496,7 -498,7 +496,7 @@@ } ArrayList seqToStrucMapping = new ArrayList(); - if (isMapUsingSIFTs) + if (isMapUsingSIFTs && seq.isProtein()) { setProgressBar(null); setProgressBar(MessageManager @@@ -512,11 -514,8 +512,11 @@@ pdb, maxChain, sqmpping, maxAlignseq); seqToStrucMapping.add(siftsMapping); maxChain.makeExactMapping(maxAlignseq, seq); - maxChain.transferRESNUMFeatures(seq, null); + maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this + // "IEA:SIFTS" ? maxChain.transferResidueAnnotation(siftsMapping, sqmpping); + ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0)); + } catch (SiftsException e) { // fall back to NW alignment @@@ -524,11 -523,6 +524,11 @@@ StructureMapping nwMapping = getNWMappings(seq, pdbFile, targetChainId, maxChain, pdb, maxAlignseq); seqToStrucMapping.add(nwMapping); + maxChain.makeExactMapping(maxAlignseq, seq); + maxChain.transferRESNUMFeatures(seq, null); // FIXME: is this + // "IEA:Jalview" ? + maxChain.transferResidueAnnotation(nwMapping, sqmpping); + ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0)); } } else @@@ -539,7 -533,8 +539,7 @@@ try { StructureMapping siftsMapping = getStructureMapping(seq, - pdbFile, - chain.id, pdb, chain, sqmpping, maxAlignseq); + pdbFile, chain.id, pdb, chain, sqmpping, maxAlignseq); foundSiftsMappings.add(siftsMapping); } catch (SiftsException e) { @@@ -550,21 -545,15 +550,21 @@@ { seqToStrucMapping.addAll(foundSiftsMappings); maxChain.makeExactMapping(maxAlignseq, seq); - maxChain.transferRESNUMFeatures(seq, null); + maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this + // "IEA:SIFTS" ? maxChain.transferResidueAnnotation(foundSiftsMappings.get(0), sqmpping); + ds.addPDBId(sqmpping.getTo().getAllPDBEntries().get(0)); } else { StructureMapping nwMapping = getNWMappings(seq, pdbFile, maxChainId, maxChain, pdb, maxAlignseq); seqToStrucMapping.add(nwMapping); + maxChain.transferRESNUMFeatures(seq, null); // FIXME: is this + // "IEA:Jalview" ? + maxChain.transferResidueAnnotation(nwMapping, sqmpping); + ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0)); } } } @@@ -573,11 -562,8 +573,11 @@@ setProgressBar(null); setProgressBar(MessageManager .getString("status.obtaining_mapping_with_nw_alignment")); - seqToStrucMapping.add(getNWMappings(seq, pdbFile, maxChainId, - maxChain, pdb, maxAlignseq)); + StructureMapping nwMapping = getNWMappings(seq, pdbFile, + maxChainId, maxChain, pdb, maxAlignseq); + seqToStrucMapping.add(nwMapping); + ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0)); + } if (forStructureView) @@@ -595,42 -581,29 +595,42 @@@ return "cif".equalsIgnoreCase(fileExt); } + /** + * retrieve a mapping for seq from SIFTs using associated DBRefEntry for + * uniprot or PDB + * + * @param seq + * @param pdbFile + * @param targetChainId + * @param pdb + * @param maxChain + * @param sqmpping + * @param maxAlignseq + * @return + * @throws SiftsException + */ private StructureMapping getStructureMapping(SequenceI seq, String pdbFile, String targetChainId, StructureFile pdb, PDBChain maxChain, jalview.datamodel.Mapping sqmpping, AlignSeq maxAlignseq) throws SiftsException { - StructureMapping curChainMapping = siftsClient - .getSiftsStructureMapping(seq, pdbFile, targetChainId); - try - { + StructureMapping curChainMapping = siftsClient + .getSiftsStructureMapping(seq, pdbFile, targetChainId); + try + { PDBChain chain = pdb.findChain(targetChainId); if (chain != null) { chain.transferResidueAnnotation(curChainMapping, sqmpping); } - } catch (Exception e) - { - e.printStackTrace(); - } - return curChainMapping; + } catch (Exception e) + { + e.printStackTrace(); + } + return curChainMapping; } - private StructureMapping getNWMappings(SequenceI seq, - String pdbFile, + private StructureMapping getNWMappings(SequenceI seq, String pdbFile, String maxChainId, PDBChain maxChain, StructureFile pdb, AlignSeq maxAlignseq) { @@@ -1355,4 -1328,9 +1355,9 @@@ return seqmappings; } + public static StructureSelectionManager getStructureSelectionManager() + { + return instances.values().iterator().next(); + } + }