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