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.
23 import jalview.analysis.AlignSeq;
24 import jalview.datamodel.Alignment;
25 import jalview.datamodel.AlignmentAnnotation;
26 import jalview.datamodel.AlignmentI;
27 import jalview.datamodel.SequenceI;
28 import jalview.io.FileParse;
29 import jalview.io.StructureFile;
30 import jalview.util.MessageManager;
32 import java.io.IOException;
33 import java.lang.reflect.Constructor;
34 import java.util.ArrayList;
35 import java.util.Hashtable;
36 import java.util.List;
37 import java.util.Vector;
39 public class PDBfile extends StructureFile
41 private static String CALC_ID_PREFIX = "JalviewPDB";
43 public PDBfile(boolean addAlignmentAnnotations,
44 boolean predictSecondaryStructure, boolean externalSecStr)
47 this.visibleChainAnnotation = addAlignmentAnnotations;
48 this.predictSecondaryStructure = predictSecondaryStructure;
49 this.externalSecondaryStructure = externalSecStr;
52 public PDBfile(boolean addAlignmentAnnotations,
53 boolean predictSecondaryStructure, boolean externalSecStr,
54 String file, String protocol) throws IOException
56 super(false, file, protocol);
57 this.visibleChainAnnotation = addAlignmentAnnotations;
58 this.predictSecondaryStructure = predictSecondaryStructure;
59 this.externalSecondaryStructure = externalSecStr;
63 public PDBfile(boolean addAlignmentAnnotations,
64 boolean predictSecondaryStructure, boolean externalSecStr,
65 FileParse source) throws IOException
68 this.visibleChainAnnotation = addAlignmentAnnotations;
69 this.predictSecondaryStructure = predictSecondaryStructure;
70 this.externalSecondaryStructure = externalSecStr;
81 public void parse() throws IOException
83 // TODO set the filename sensibly - try using data source name.
84 setId(safeName(getDataName()));
86 setChains(new Vector<PDBChain>());
87 List<SequenceI> rna = new ArrayList<SequenceI>();
88 List<SequenceI> prot = new ArrayList<SequenceI>();
91 boolean modelFlag = false;
92 boolean terFlag = false;
96 String atomnam = null;
99 while ((line = nextLine()) != null)
101 if (line.indexOf("HEADER") == 0)
103 if (line.length() > 62)
106 if (line.length() > 67)
108 tid = line.substring(62, 67).trim();
112 tid = line.substring(62).trim();
114 if (tid.length() > 0)
121 // Were we to do anything with SEQRES - we start it here
122 if (line.indexOf("SEQRES") == 0)
126 if (line.indexOf("MODEL") == 0)
131 if (line.indexOf("TER") == 0)
136 if (modelFlag && line.indexOf("ENDMDL") == 0)
140 if (line.indexOf("ATOM") == 0
141 || (line.indexOf("HETATM") == 0 && !terFlag))
145 // Jalview is only interested in CA bonds????
146 atomnam = line.substring(12, 15).trim();
147 if (!atomnam.equals("CA") && !atomnam.equals("P"))
152 Atom tmpatom = new Atom(line);
155 tmpchain = findChain(tmpatom.chain);
156 if (tmpatom.resNumIns.trim().equals(lastID))
158 // phosphorylated protein - seen both CA and P..
161 tmpchain.atoms.addElement(tmpatom);
162 } catch (Exception e)
164 tmpchain = new PDBChain(getId(), tmpatom.chain);
165 getChains().add(tmpchain);
166 tmpchain.atoms.addElement(tmpatom);
168 lastID = tmpatom.resNumIns.trim();
178 setId(inFile.getName());
180 for (PDBChain chain : getChains())
182 SequenceI chainseq = postProcessChain(chain);
192 if (predictSecondaryStructure)
194 predictSecondaryStructure(rna, prot);
196 } catch (OutOfMemoryError er)
198 System.out.println("OUT OF MEMORY LOADING PDB FILE");
199 throw new IOException(
201 .getString("exception.outofmemory_loading_pdb_file"));
202 } catch (NumberFormatException ex)
206 System.err.println("Couldn't read number from line:");
207 System.err.println(line);
214 * Predict secondary structure for RNA and/or protein sequences and add as
217 * @param rnaSequences
218 * @param proteinSequences
220 protected void predictSecondaryStructure(List<SequenceI> rnaSequences,
221 List<SequenceI> proteinSequences)
224 * Currently using Annotate3D for RNA, but only if the 'use external
225 * prediction' flag is set
227 if (externalSecondaryStructure && rnaSequences.size() > 0)
231 processPdbFileWithAnnotate3d(rnaSequences);
232 } catch (Exception x)
234 System.err.println("Exceptions when dealing with RNA in pdb file");
241 * Currently using JMol PDB parser for peptide
243 if (proteinSequences.size() > 0)
247 processPdbFileWithJmol(proteinSequences);
248 } catch (Exception x)
251 .println("Exceptions from Jmol when processing data in pdb file");
258 * Process a parsed chain to construct and return a Sequence, and add it to
259 * the list of sequences parsed.
265 public static boolean isCalcIdHandled(String calcId)
267 return calcId != null && (CALC_ID_PREFIX.equals(calcId));
270 public static boolean isCalcIdForFile(AlignmentAnnotation alan,
273 return alan.getCalcId() != null
274 && CALC_ID_PREFIX.equals(alan.getCalcId())
275 && pdbFile.equals(alan.getProperty("PDBID"));
278 public static String relocateCalcId(String calcId,
279 Hashtable<String, String> alreadyLoadedPDB) throws Exception
281 int s = CALC_ID_PREFIX.length(), end = calcId
282 .indexOf(CALC_ID_PREFIX, s);
283 String between = calcId.substring(s, end - 1);
284 return CALC_ID_PREFIX + alreadyLoadedPDB.get(between) + ":"
285 + calcId.substring(end);
288 private void markCalcIds()
290 for (SequenceI sq : seqs)
292 if (sq.getAnnotation() != null)
294 for (AlignmentAnnotation aa : sq.getAnnotation())
296 String oldId = aa.getCalcId();
301 aa.setCalcId(CALC_ID_PREFIX);
302 aa.setProperty("PDBID", getId());
303 aa.setProperty("oldCalcId", oldId);
309 private void processPdbFileWithJmol(List<SequenceI> prot)
315 Class cl = Class.forName("jalview.ext.jmol.JmolParser");
318 final Constructor constructor = cl
319 .getConstructor(new Class[] { FileParse.class });
320 final Object[] args = new Object[] { new FileParse(getDataName(),
322 Object jmf = constructor.newInstance(args);
323 AlignmentI al = new Alignment((SequenceI[]) cl.getMethod(
324 "getSeqsAsArray", new Class[] {}).invoke(jmf));
325 cl.getMethod("addAnnotations", new Class[] { AlignmentI.class })
327 for (SequenceI sq : al.getSequences())
329 if (sq.getDatasetSequence() != null)
331 sq.getDatasetSequence().getAllPDBEntries().clear();
335 sq.getAllPDBEntries().clear();
338 replaceAndUpdateChains(prot, al, AlignSeq.PEP, false);
340 } catch (ClassNotFoundException q)