JAL-2089 patch broken merge to master for Release 2.10.0b1
[jalview.git] / src / MCview / PDBfile.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
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.
11  *  
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.
16  * 
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.
20  */
21 package MCview;
22
23 import jalview.datamodel.AlignmentAnnotation;
24 import jalview.datamodel.DBRefSource;
25 import jalview.datamodel.SequenceI;
26 import jalview.io.FileParse;
27 import jalview.io.StructureFile;
28 import jalview.util.MessageManager;
29
30 import java.io.IOException;
31 import java.util.ArrayList;
32 import java.util.Hashtable;
33 import java.util.List;
34 import java.util.Vector;
35
36 public class PDBfile extends StructureFile
37 {
38   private static String CALC_ID_PREFIX = "JalviewPDB";
39
40   public PDBfile(boolean addAlignmentAnnotations,
41           boolean predictSecondaryStructure, boolean externalSecStr)
42   {
43     super();
44     addSettings(addAlignmentAnnotations, predictSecondaryStructure,
45             externalSecStr);
46   }
47
48   public PDBfile(boolean addAlignmentAnnotations, boolean predictSecStr,
49           boolean externalSecStr, String dataObject, String protocol)
50           throws IOException
51   {
52     super(false, dataObject, protocol);
53     addSettings(addAlignmentAnnotations, predictSecStr, externalSecStr);
54     doParse();
55   }
56
57   public PDBfile(boolean addAlignmentAnnotations, boolean predictSecStr,
58           boolean externalSecStr, FileParse source) throws IOException
59   {
60     super(false, source);
61     addSettings(addAlignmentAnnotations, predictSecStr, externalSecStr);
62     doParse();
63   }
64
65   @Override
66   public String print()
67   {
68     return null;
69   }
70
71   @Override
72   public void parse() throws IOException
73   {
74     setDbRefType(DBRefSource.PDB);
75     // TODO set the filename sensibly - try using data source name.
76     setId(safeName(getDataName()));
77
78     setChains(new Vector<PDBChain>());
79     List<SequenceI> rna = new ArrayList<SequenceI>();
80     List<SequenceI> prot = new ArrayList<SequenceI>();
81     PDBChain tmpchain;
82     String line = null;
83     boolean modelFlag = false;
84     boolean terFlag = false;
85     String lastID = "";
86
87     int indexx = 0;
88     String atomnam = null;
89     try
90     {
91       while ((line = nextLine()) != null)
92       {
93         if (line.indexOf("HEADER") == 0)
94         {
95           if (line.length() > 62)
96           {
97             String tid;
98             if (line.length() > 67)
99             {
100               tid = line.substring(62, 67).trim();
101             }
102             else
103             {
104               tid = line.substring(62).trim();
105             }
106             if (tid.length() > 0)
107             {
108               setId(tid);
109             }
110             continue;
111           }
112         }
113         // Were we to do anything with SEQRES - we start it here
114         if (line.indexOf("SEQRES") == 0)
115         {
116         }
117
118         if (line.indexOf("MODEL") == 0)
119         {
120           modelFlag = true;
121         }
122
123         if (line.indexOf("TER") == 0)
124         {
125           terFlag = true;
126         }
127
128         if (modelFlag && line.indexOf("ENDMDL") == 0)
129         {
130           break;
131         }
132         if (line.indexOf("ATOM") == 0
133                 || (line.indexOf("HETATM") == 0 && !terFlag))
134         {
135           terFlag = false;
136
137           // Jalview is only interested in CA bonds????
138           atomnam = line.substring(12, 15).trim();
139           if (!atomnam.equals("CA") && !atomnam.equals("P"))
140           {
141             continue;
142           }
143
144           Atom tmpatom = new Atom(line);
145           try
146           {
147             tmpchain = findChain(tmpatom.chain);
148             if (tmpatom.resNumIns.trim().equals(lastID))
149             {
150               // phosphorylated protein - seen both CA and P..
151               continue;
152             }
153             tmpchain.atoms.addElement(tmpatom);
154           } catch (Exception e)
155           {
156             tmpchain = new PDBChain(getId(), tmpatom.chain);
157             getChains().add(tmpchain);
158             tmpchain.atoms.addElement(tmpatom);
159           }
160           lastID = tmpatom.resNumIns.trim();
161         }
162         index++;
163       }
164
165       makeResidueList();
166       makeCaBondList();
167
168       if (getId() == null)
169       {
170         setId(inFile.getName());
171       }
172       for (PDBChain chain : getChains())
173       {
174         SequenceI chainseq = postProcessChain(chain);
175         if (isRNA(chainseq))
176         {
177           rna.add(chainseq);
178         }
179         else
180         {
181           prot.add(chainseq);
182         }
183       }
184       if (predictSecondaryStructure)
185       {
186         addSecondaryStructure(rna, prot);
187       }
188     } catch (OutOfMemoryError er)
189     {
190       System.out.println("OUT OF MEMORY LOADING PDB FILE");
191       throw new IOException(
192               MessageManager
193                       .getString("exception.outofmemory_loading_pdb_file"));
194     } catch (NumberFormatException ex)
195     {
196       if (line != null)
197       {
198         System.err.println("Couldn't read number from line:");
199         System.err.println(line);
200       }
201     }
202     markCalcIds();
203   }
204
205   /**
206    * Process a parsed chain to construct and return a Sequence, and add it to
207    * the list of sequences parsed.
208    * 
209    * @param chain
210    * @return
211    */
212
213   public static boolean isCalcIdHandled(String calcId)
214   {
215     return calcId != null && (CALC_ID_PREFIX.equals(calcId));
216   }
217
218   public static boolean isCalcIdForFile(AlignmentAnnotation alan,
219           String pdbFile)
220   {
221     return alan.getCalcId() != null
222             && CALC_ID_PREFIX.equals(alan.getCalcId())
223             && pdbFile.equals(alan.getProperty("PDBID"));
224   }
225
226   public static String relocateCalcId(String calcId,
227           Hashtable<String, String> alreadyLoadedPDB) throws Exception
228   {
229     int s = CALC_ID_PREFIX.length(), end = calcId
230             .indexOf(CALC_ID_PREFIX, s);
231     String between = calcId.substring(s, end - 1);
232     return CALC_ID_PREFIX + alreadyLoadedPDB.get(between) + ":"
233             + calcId.substring(end);
234   }
235
236   private void markCalcIds()
237   {
238     for (SequenceI sq : seqs)
239     {
240       if (sq.getAnnotation() != null)
241       {
242         for (AlignmentAnnotation aa : sq.getAnnotation())
243         {
244           String oldId = aa.getCalcId();
245           if (oldId == null)
246           {
247             oldId = "";
248           }
249           aa.setCalcId(CALC_ID_PREFIX);
250           aa.setProperty("PDBID", getId());
251           aa.setProperty("oldCalcId", oldId);
252         }
253       }
254     }
255   }
256
257 }