fixed last-residue bug and added sequence feature creation and transfer for resNum...
[jalview.git] / src / MCview / PDBChain.java
1 /*
2 * Jalview - A Sequence Alignment Editor and Viewer
3 * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18 */
19 package MCview;
20
21 import jalview.datamodel.*;
22
23 import jalview.schemes.ResidueProperties;
24
25 import java.awt.*;
26
27 import java.util.*;
28 import jalview.analysis.AlignSeq;
29
30
31 public class PDBChain {
32     /**
33      * SequenceFeature group for PDB File features added to sequences
34      */
35     private static final String PDBFILEFEATURE = "PDBFile";
36     public String id;
37     public Vector bonds = new Vector();
38     public Vector atoms = new Vector();
39     public Vector residues = new Vector();
40     public int offset;
41     public Sequence sequence;
42     public boolean isVisible = true;
43     public int pdbstart = 0;
44     public int pdbend = 0;
45     public int seqstart = 0;
46     public int seqend = 0;
47
48     public PDBChain(String id) {
49         this.id = id;
50     }
51
52     public String print() {
53         String tmp = "";
54
55         for (int i = 0; i < bonds.size(); i++) {
56             tmp = tmp + ((Bond) bonds.elementAt(i)).at1.resName + " " +
57                 ((Bond) bonds.elementAt(i)).at1.resNumber + " " + offset +
58                 "\n";
59         }
60
61         return tmp;
62     }
63
64     void makeExactMapping(AlignSeq as, Sequence s1)
65     {
66         int pdbpos =   as.getSeq2Start()-2;
67         int alignpos = s1.getStart() + as.getSeq1Start()-3;
68
69         for(int i=0; i<as.astr1.length(); i++)
70         {
71             if (as.astr1.charAt(i) != '-')
72             {
73               alignpos++;
74             }
75
76             if (as.astr2.charAt(i) != '-')
77             {
78               pdbpos++;
79             }
80
81             if (as.astr1.charAt(i) == as.astr2.charAt(i))
82             {
83                 Residue res = (Residue) residues.elementAt(pdbpos);
84                 Enumeration en = res.atoms.elements();
85                 while (en.hasMoreElements())
86                 {
87                   Atom atom = (Atom) en.nextElement();
88                   atom.alignmentMapping = alignpos;
89                 }
90             }
91         }
92     }
93     /**
94      * copy over the RESNUM seqfeatures from the internal chain sequence to the mapped sequence
95      * @param seq
96      */
97     public void transferRESNUMFeatures(SequenceI seq, String status) {
98         if (seq != sequence) {
99             /** SequenceFeature[] seqsfeatures=seq.getSequenceFeatures();
100             int totfeat=seqsfeatures.length;
101             // Remove any features for this exact chain ?
102             for (int i=0; i<seqsfeatures.length; i++) {
103                 
104             } */
105             if (status==null)
106                 status = "IEA:jalview";
107             SequenceFeature[] features = sequence.getSequenceFeatures();
108             for (int i=0; i<features.length; i++) {
109                 if (features[i].getFeatureGroup().equals(PDBChain.PDBFILEFEATURE)) {
110                     SequenceFeature tx = new SequenceFeature(features[i]);
111                     tx.setBegin(1+((Atom)((Residue)residues.elementAt(tx.getBegin()-offset)).atoms.elementAt(0)).alignmentMapping);
112                     tx.setEnd(1+((Atom)((Residue)residues.elementAt(tx.getEnd()-offset)).atoms.elementAt(0)).alignmentMapping);
113                     tx.setStatus(status+((tx.getStatus()==null || tx.getStatus().length()==0) ? "" : ":"+tx.getStatus()));
114                     seq.getDatasetSequence().addSequenceFeature(tx);
115                 }
116             }
117             
118         }
119     }
120
121     public void makeCaBondList()
122     {
123         for (int i = 0; i < (residues.size() - 1); i++)
124         {
125             Residue tmpres = (Residue) residues.elementAt(i);
126             Residue tmpres2 = (Residue) residues.elementAt(i + 1);
127             Atom at1 = tmpres.findAtom("CA");
128             Atom at2 = tmpres2.findAtom("CA");
129
130             if ((at1 != null) && (at2 != null))
131             {
132                 if (at1.chain.equals(at2.chain))
133                 {
134                     makeBond(at1, at2);
135                 }
136             }
137             else
138               System.out.println("not found "+i);
139         }
140     }
141
142     public void makeBond(Atom at1, Atom at2) {
143         float[] start = new float[3];
144         float[] end = new float[3];
145
146         start[0] = at1.x;
147         start[1] = at1.y;
148         start[2] = at1.z;
149
150         end[0] = at2.x;
151         end[1] = at2.y;
152         end[2] = at2.z;
153
154         bonds.addElement(new Bond(start, end, at1, at2));
155     }
156
157     public void makeResidueList() {
158         int count = 0;
159         StringBuffer seq = new StringBuffer();
160         Vector resFeatures=new Vector();
161         int i, iSize = atoms.size()-1;
162         int resNumber=-1;
163         for (i = 0; i <= iSize; i++)
164         {
165             Atom tmp = (Atom) atoms.elementAt(i);
166             resNumber = tmp.resNumber;
167             int res = resNumber;
168
169             if (i == 0) {
170                 offset = resNumber;
171             }
172
173             Vector resAtoms = new Vector();
174             //Add atoms to a vector while the residue number
175             //remains the same as the first atom's resNumber (res)
176             while ((resNumber == res) && (i < atoms.size())) {
177                 resAtoms.addElement((Atom) atoms.elementAt(i));
178                 i++;
179
180                 if (i < atoms.size()) {
181                     resNumber = ((Atom) atoms.elementAt(i)).resNumber;
182                 } else {
183                     resNumber++;
184                 }
185             }
186
187             //We need this to keep in step with the outer for i = loop
188             i--;
189
190             //Make a new Residue object with the new atoms vector
191             residues.addElement(new Residue(resAtoms, resNumber - 1, count));
192             
193             Residue tmpres = (Residue) residues.lastElement();
194             Atom tmpat = (Atom) tmpres.atoms.elementAt(0);
195             // Make A new SequenceFeature for the current residue numbering
196             SequenceFeature sf = 
197                 new SequenceFeature("RESNUM",tmpat.resName+":"+tmpat.resNumIns,
198                         "",offset+count,offset+count,MCview.PDBChain.PDBFILEFEATURE);
199             resFeatures.addElement(sf);
200             // Keep totting up the sequence
201             if (ResidueProperties.getAA3Hash().get(tmpat.resName) == null)
202             {
203                 seq.append("X") ;
204                //  System.err.println("PDBReader:Null aa3Hash for " +
205                //     tmpat.resName);
206             } else {
207
208                 seq.append(ResidueProperties.aa[((Integer) ResidueProperties.getAA3Hash()
209                                                                                   .get(tmpat.resName)).intValue()]);
210             }
211             count++;
212         }
213
214         if(id.length()<1 || id.equals(" "))
215            id = "_";
216         
217         sequence = new Sequence(id, seq.toString(), offset, resNumber); // resNumber-offset ~= seq.size() 
218       //  System.out.println("PDB Sequence is :\nSequence = " + seq);
219      //   System.out.println("No of residues = " + residues.size());
220         for (i=0,iSize=resFeatures.size(); i<iSize; i++) {
221             sequence.addSequenceFeature((SequenceFeature) resFeatures.elementAt(i));
222             resFeatures.setElementAt(null, i);
223         }
224    }
225
226     public void setChargeColours() {
227         for (int i = 0; i < bonds.size(); i++) {
228             try {
229                 Bond b = (Bond) bonds.elementAt(i);
230
231                 if (b.at1.resName.equalsIgnoreCase("ASP") ||
232                         b.at1.resName.equalsIgnoreCase("GLU")) {
233                     b.startCol = Color.red;
234                 } else if (b.at1.resName.equalsIgnoreCase("LYS") ||
235                         b.at1.resName.equalsIgnoreCase("ARG")) {
236                     b.startCol = Color.blue;
237                 } else if (b.at1.resName.equalsIgnoreCase("CYS")) {
238                     b.startCol = Color.yellow;
239                 } else {
240                     //int atno = ((Integer) ResidueProperties.getAA3Hash().get(b.at1.resName.toUpperCase())).intValue();
241                     b.startCol = Color.lightGray;
242                 }
243
244                 if (b.at2.resName.equalsIgnoreCase("ASP") ||
245                         b.at2.resName.equalsIgnoreCase("GLU")) {
246                     b.endCol = Color.red;
247                 } else if (b.at2.resName.equalsIgnoreCase("LYS") ||
248                         b.at2.resName.equalsIgnoreCase("ARG")) {
249                     b.endCol = Color.blue;
250                 } else if (b.at2.resName.equalsIgnoreCase("CYS")) {
251                     b.endCol = Color.yellow;
252                 } else {
253                     //int atno = ((Integer) ResidueProperties.getAA3Hash().get(b.at2.resName.toUpperCase())).intValue();
254                     b.endCol = Color.lightGray;
255                 }
256             } catch (Exception e) {
257                 Bond b = (Bond) bonds.elementAt(i);
258                 b.startCol = Color.gray;
259                 b.endCol = Color.gray;
260             }
261         }
262     }
263
264
265     public void setChainColours(jalview.schemes.ColourSchemeI cs)
266     {
267         Bond b;
268         for (int i = 0; i < bonds.size(); i++) {
269             try {
270               b = (Bond) bonds.elementAt(i);
271
272             /*  ( (Bond) bonds.elementAt(i)).startCol = cs.findColour(
273                   ResidueProperties.codonTranslate(
274                       ResidueProperties.aa3Hash.get(b.at1.resName).toString().charAt(0)
275                   );
276
277               b.endCol = cs.findColour(
278                   ResidueProperties.aa[ ( (Integer) ResidueProperties.aa3Hash.
279                                          get(b.at2.resName)).intValue()]
280                   );*/
281
282             } catch (Exception e)
283             {
284                 b = (Bond) bonds.elementAt(i);
285                 b.startCol = Color.gray;
286                 b.endCol = Color.gray;
287             }
288         }
289     }
290
291
292
293     public void setChainColours(Color col)
294     {
295         for (int i = 0; i < bonds.size(); i++)
296         {
297             Bond tmp = (Bond) bonds.elementAt(i);
298             tmp.startCol = col;
299             tmp.endCol = col;
300         }
301     }
302 }