/* * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) * Copyright (C) $$Year-Rel$$ 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. * * 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 . * The Jalview Authors are detailed in the 'AUTHORS' file. */ package jalview.io; import jalview.analysis.AlignSeq; import jalview.api.FeatureSettingsModelI; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.DBRefEntry; import jalview.datamodel.DBRefSource; import jalview.datamodel.PDBEntry; import jalview.datamodel.PDBEntry.Type; import jalview.datamodel.SequenceI; import jalview.structure.StructureImportSettings; import java.awt.Color; import java.io.IOException; import java.lang.reflect.Constructor; import java.util.List; import java.util.Vector; import MCview.PDBChain; public abstract class StructureFile extends AlignFile { private String id; private PDBEntry.Type dbRefType; /** * set to true to add derived sequence annotations (temp factor read from * file, or computed secondary structure) to the alignment */ protected boolean visibleChainAnnotation = false; /** * Set true to predict secondary structure (using JMol for protein, Annotate3D * for RNA) */ protected boolean predictSecondaryStructure = false; /** * Set true (with predictSecondaryStructure=true) to predict secondary * structure using an external service (currently Annotate3D for RNA only) */ protected boolean externalSecondaryStructure = false; private Vector chains; private boolean pdbIdAvailable; public StructureFile(Object inFile, DataSourceType sourceType) throws IOException { super(inFile, sourceType); } public StructureFile(FileParse fp) throws IOException { super(fp); } public void addSettings(boolean addAlignmentAnnotations, boolean predictSecondaryStructure, boolean externalSecStr) { this.visibleChainAnnotation = addAlignmentAnnotations; this.predictSecondaryStructure = predictSecondaryStructure; this.externalSecondaryStructure = externalSecStr; } public void xferSettings() { this.visibleChainAnnotation = StructureImportSettings .isVisibleChainAnnotation(); this.predictSecondaryStructure = StructureImportSettings .isProcessSecondaryStructure(); this.externalSecondaryStructure = StructureImportSettings .isExternalSecondaryStructure(); } public StructureFile(boolean parseImmediately, Object dataObject, DataSourceType sourceType) throws IOException { super(parseImmediately, dataObject, sourceType); } public StructureFile(boolean a, FileParse fp) throws IOException { super(a, fp); } public StructureFile() { } protected SequenceI postProcessChain(PDBChain chain) { SequenceI pdbSequence = chain.sequence; pdbSequence.setName(getId() + "|" + pdbSequence.getName()); PDBEntry entry = new PDBEntry(); entry.setId(getId()); entry.setType(getStructureFileType()); if (chain.id != null) { entry.setChainCode(chain.id); } if (inFile != null) { entry.setFile(inFile.getAbsolutePath()); } else { entry.setFile(getDataName()); } DBRefEntry sourceDBRef = new DBRefEntry(); sourceDBRef.setAccessionId(getId()); sourceDBRef.setSource(DBRefSource.PDB); // TODO: specify version for 'PDB' database ref if it is read from a file. // TODO: decide if jalview.io should be creating primary refs! sourceDBRef.setVersion(""); pdbSequence.addPDBId(entry); pdbSequence.addDBRef(sourceDBRef); SequenceI chainseq = pdbSequence; seqs.addElement(chainseq); AlignmentAnnotation[] chainannot = chainseq.getAnnotation(); if (chainannot != null && visibleChainAnnotation) { for (int ai = 0; ai < chainannot.length; ai++) { chainannot[ai].visible = visibleChainAnnotation; annotations.addElement(chainannot[ai]); } } return chainseq; } /** * filetype of structure file - default is PDB */ String structureFileType = PDBEntry.Type.PDB.toString(); protected void setStructureFileType(String structureFileType) { this.structureFileType = structureFileType; } /** * filetype of last file processed * * @return */ public String getStructureFileType() { return structureFileType; } @SuppressWarnings({ "unchecked", "rawtypes" }) protected void processPdbFileWithAnnotate3d(List rna) throws Exception { // System.out.println("this is a PDB format and RNA sequence"); // note: we use reflection here so that the applet can compile and run // without the HTTPClient bits and pieces needed for accessing Annotate3D // web service try { Class cl = Class.forName("jalview.ws.jws1.Annotate3D"); if (cl != null) { // TODO: use the PDB ID of the structure if one is available, to save // bandwidth and avoid uploading the whole structure to the service Object annotate3d = cl.getConstructor(new Class[] {}) .newInstance(new Object[] {}); AlignmentI al = ((AlignmentI) cl .getMethod("getRNAMLFor", new Class[] { FileParse.class }) .invoke(annotate3d, new Object[] { new FileParse(getDataName(), dataSourceType) })); for (SequenceI sq : al.getSequences()) { if (sq.getDatasetSequence() != null) { if (sq.getDatasetSequence().getAllPDBEntries() != null) { sq.getDatasetSequence().getAllPDBEntries().clear(); } } else { if (sq.getAllPDBEntries() != null) { sq.getAllPDBEntries().clear(); } } } replaceAndUpdateChains(rna, al, AlignSeq.DNA, false); } } catch (ClassNotFoundException x) { // ignore classnotfounds - occurs in applet } } @SuppressWarnings("unchecked") protected void replaceAndUpdateChains(List prot, AlignmentI al, String pep, boolean b) { List> replaced = AlignSeq .replaceMatchingSeqsWith(seqs, annotations, prot, al, pep, false); for (PDBChain ch : getChains()) { int p = 0; for (SequenceI sq : (List) replaced.get(0)) { p++; if (sq == ch.sequence || sq.getDatasetSequence() == ch.sequence) { p = -p; break; } } if (p < 0) { p = -p - 1; // set shadow entry for chains ch.shadow = (SequenceI) replaced.get(1).get(p); ch.shadowMap = ((AlignSeq) replaced.get(2).get(p)) .getMappingFromS1(false); } } } /** * Predict secondary structure for RNA and/or protein sequences and add as * annotations * * @param rnaSequences * @param proteinSequences */ protected void addSecondaryStructure(List rnaSequences, List proteinSequences) { /* * Currently using Annotate3D for RNA, but only if the 'use external * prediction' flag is set */ if (externalSecondaryStructure && rnaSequences.size() > 0) { try { processPdbFileWithAnnotate3d(rnaSequences); } catch (Exception x) { System.err.println("Exceptions when dealing with RNA in pdb file"); x.printStackTrace(); } } /* * Currently using JMol PDB parser for peptide */ if (proteinSequences.size() > 0) { try { processWithJmolParser(proteinSequences); } catch (Exception x) { System.err.println( "Exceptions from Jmol when processing data in pdb file"); x.printStackTrace(); } } } @SuppressWarnings({ "unchecked", "rawtypes" }) private void processWithJmolParser(List prot) throws Exception { try { Class cl = Class.forName("jalview.ext.jmol.JmolParser"); if (cl != null) { final Constructor constructor = cl .getConstructor(new Class[] { FileParse.class }); final Object[] args = new Object[] { new FileParse(getDataName(), dataSourceType) }; StructureImportSettings.setShowSeqFeatures(false); StructureImportSettings.setVisibleChainAnnotation(false); StructureImportSettings .setProcessSecondaryStructure(predictSecondaryStructure); StructureImportSettings .setExternalSecondaryStructure(externalSecondaryStructure); Object jmf = constructor.newInstance(args); AlignmentI al = new Alignment((SequenceI[]) cl .getMethod("getSeqsAsArray", new Class[] {}).invoke(jmf)); cl.getMethod("addAnnotations", new Class[] { AlignmentI.class }) .invoke(jmf, al); for (SequenceI sq : al.getSequences()) { if (sq.getDatasetSequence() != null) { sq.getDatasetSequence().getAllPDBEntries().clear(); } else { sq.getAllPDBEntries().clear(); } } replaceAndUpdateChains(prot, al, AlignSeq.PEP, false); } } catch (ClassNotFoundException q) { } StructureImportSettings.setShowSeqFeatures(true); } public PDBChain findChain(String id) throws Exception { for (PDBChain chain : getChains()) { if (chain.id.equals(id)) { return chain; } } throw new Exception("PDB chain not Found!"); } public void makeResidueList() { for (PDBChain chain : getChains()) { chain.makeResidueList(visibleChainAnnotation); } } public void makeCaBondList() { for (PDBChain chain : getChains()) { chain.makeCaBondList(); } } public void setChargeColours() { for (PDBChain chain : getChains()) { chain.setChargeColours(); } } public void setColours(jalview.schemes.ColourSchemeI cs) { for (PDBChain chain : getChains()) { chain.setChainColours(cs); } } public void setChainColours() { int i = 0; for (PDBChain chain : getChains()) { chain.setChainColours(Color.getHSBColor(1.0f / i++, .4f, 1.0f)); } } public static boolean isRNA(SequenceI seq) { int length = seq.getLength(); for (int i = 0; i < length; i++) { char c = seq.getCharAt(i); if ((c != 'A') && (c != 'C') && (c != 'G') && (c != 'U')) { return false; } } return true; } /** * make a friendly ID string. * * @param dataName * @return truncated dataName to after last '/' and pruned .extension if * present */ protected String safeName(String dataName) { int p = 0; while ((p = dataName.indexOf("/")) > -1 && p < dataName.length()) { dataName = dataName.substring(p + 1); } if (dataName.indexOf(".") > -1) { dataName = dataName.substring(0, dataName.lastIndexOf(".")); } return dataName; } public String getId() { return id; } public void setId(String id) { this.id = id; } public Vector getChains() { return chains; } public void setChains(Vector chains) { this.chains = chains; } public Type getDbRefType() { return dbRefType; } public void setDbRefType(String dbRefType) { this.dbRefType = Type.getType(dbRefType); } public void setDbRefType(Type dbRefType) { this.dbRefType = dbRefType; } /** * Returns a descriptor for suitable feature display settings with *
    *
  • ResNums or insertions features visible
  • *
  • insertions features coloured red
  • *
  • ResNum features coloured by label
  • *
  • Insertions displayed above (on top of) ResNums
  • *
*/ @Override public FeatureSettingsModelI getFeatureColourScheme() { return new PDBFeatureSettings(); } /** * Answers true if the structure file has a PDBId * * @return */ public boolean isPPDBIdAvailable() { return pdbIdAvailable; } public void setPDBIdAvailable(boolean pdbIdAvailable) { this.pdbIdAvailable = pdbIdAvailable; } }