transfer of residue numbering as alignment annotation
[jalview.git] / src / jalview / structure / StructureSelectionManager.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2007 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 jalview.structure;
20
21 import java.io.*;
22 import java.util.*;
23
24 import MCview.*;
25 import jalview.analysis.*;
26 import jalview.datamodel.*;
27
28 public class StructureSelectionManager
29 {
30   static StructureSelectionManager instance;
31   StructureMapping[] mappings;
32   Hashtable mappingData = new Hashtable();
33
34   public static StructureSelectionManager getStructureSelectionManager()
35   {
36     if (instance == null)
37     {
38       instance = new StructureSelectionManager();
39     }
40
41     return instance;
42   }
43
44   Vector listeners = new Vector();
45   public void addStructureViewerListener(Object svl)
46   {
47     if (!listeners.contains(svl))
48     {
49       listeners.addElement(svl);
50     }
51   }
52
53   public String alreadyMappedToFile(String pdbid)
54   {
55     if (mappings != null)
56     {
57       for (int i = 0; i < mappings.length; i++)
58       {
59         if (mappings[i].getPdbId().equals(pdbid))
60         {
61           return mappings[i].pdbfile;
62         }
63       }
64     }
65     return null;
66   }
67
68   /*
69      There will be better ways of doing this in the future, for now we'll use
70      the tried and tested MCview pdb mapping
71    */
72   synchronized public MCview.PDBfile setMapping(SequenceI[] sequence,
73                            String pdbFile,
74                            String protocol)
75   {
76     MCview.PDBfile pdb = null;
77     try
78     {
79       pdb = new MCview.PDBfile(pdbFile, protocol);
80     }
81     catch (Exception ex)
82     {
83       ex.printStackTrace();
84       return null;
85     }
86
87     for (int s = 0; s < sequence.length; s++)
88     {
89       String targetChain = "";
90
91       if (sequence[s].getName().indexOf("|") > -1)
92       {
93         targetChain = sequence[s].getName().substring(
94             sequence[s].getName().lastIndexOf("|") + 1);
95       }
96
97       int max = -10;
98       AlignSeq maxAlignseq = null;
99       String maxChainId = " ";
100       PDBChain maxChain = null;
101
102       for (int i = 0; i < pdb.chains.size(); i++)
103       {
104         AlignSeq as = new AlignSeq(sequence[s],
105                                    ( (PDBChain) pdb.chains.elementAt(i)).
106                                    sequence,
107                                    AlignSeq.PEP);
108         as.calcScoreMatrix();
109         as.traceAlignment();
110         PDBChain chain = ( (PDBChain) pdb.chains.elementAt(i));
111
112         if (as.maxscore > max
113             || (as.maxscore == max && chain.id.equals(targetChain)))
114         {
115           maxChain = chain;
116           max = as.maxscore;
117           maxAlignseq = as;
118           maxChainId = chain.id;
119         }
120       }
121
122       final StringBuffer mappingDetails = new StringBuffer();
123       mappingDetails.append("\n\nPDB Sequence is :\nSequence = " +
124                             maxChain.sequence.getSequenceAsString());
125       mappingDetails.append("\nNo of residues = " +
126                             maxChain.residues.
127                             size() +
128                             "\n\n");
129       PrintStream ps = new PrintStream(System.out)
130       {
131         public void print(String x)
132         {
133           mappingDetails.append(x);
134         }
135
136         public void println()
137         {
138           mappingDetails.append("\n");
139         }
140       };
141
142       maxAlignseq.printAlignment(ps);
143
144       mappingDetails.append("\nPDB start/end " + maxAlignseq.seq2start + " " +
145                             maxAlignseq.seq2end);
146       mappingDetails.append("\nSEQ start/end "
147                             + (maxAlignseq.seq1start + sequence[s].getStart() - 1) +
148                             " "
149                             + (maxAlignseq.seq1end + sequence[s].getEnd() - 1));
150
151       maxChain.makeExactMapping(maxAlignseq, sequence[s]);
152
153       maxChain.transferRESNUMFeatures(sequence[s], null);
154
155       int[][] mapping = new int[sequence[s].getEnd() + 2][2];
156       int resNum = -10000;
157       int index = 0;
158
159
160       do
161       {
162         Atom tmp = (Atom) maxChain.atoms.elementAt(index);
163         if (resNum != tmp.resNumber && tmp.alignmentMapping != -1)
164         {
165           resNum = tmp.resNumber;
166           mapping[tmp.alignmentMapping+1][0] = tmp.resNumber;
167           mapping[tmp.alignmentMapping+1][1] = tmp.atomIndex;
168         }
169
170         index++;
171       }
172       while(index < maxChain.atoms.size());
173
174       if (mappings == null)
175       {
176         mappings = new StructureMapping[1];
177       }
178       else
179       {
180         StructureMapping[] tmp = new StructureMapping[mappings.length + 1];
181         System.arraycopy(mappings, 0, tmp, 0, mappings.length);
182         mappings = tmp;
183       }
184
185       if(protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
186         pdbFile = "INLINE"+pdb.id;
187       
188       mappings[mappings.length - 1]
189           = new StructureMapping(sequence[s], pdbFile, pdb.id, maxChainId,
190                                  mapping, mappingDetails.toString());
191       maxChain.transferResidueAnnotation(mappings[mappings.length-1]);
192     }
193     /////////
194
195     return pdb;
196   }
197
198   public void removeStructureViewerListener(Object svl, String pdbfile)
199   {
200     listeners.removeElement(svl);
201
202     boolean removeMapping = true;
203
204     StructureListener sl;
205     for (int i = 0; i < listeners.size(); i++)
206     {
207       if (listeners.elementAt(i) instanceof StructureListener)
208       {
209         sl = (StructureListener) listeners.elementAt(i);
210         if (sl.getPdbFile().equals(pdbfile))
211         {
212           removeMapping = false;
213           break;
214         }
215       }
216     }
217
218     if (removeMapping && mappings!=null)
219     {
220       Vector tmp = new Vector();
221       for (int i = 0; i < mappings.length; i++)
222       {
223         if (!mappings[i].pdbfile.equals(pdbfile))
224         {
225           tmp.addElement(mappings[i]);
226         }
227       }
228
229       mappings = new StructureMapping[tmp.size()];
230       tmp.copyInto(mappings);
231     }
232   }
233
234   public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
235   {
236     SequenceListener sl;
237     for (int i = 0; i < listeners.size(); i++)
238     {
239       if (listeners.elementAt(i) instanceof SequenceListener)
240       {
241         sl = (SequenceListener) listeners.elementAt(i);
242
243         for (int j = 0; j < mappings.length; j++)
244         {
245           if (mappings[j].pdbfile.equals(pdbfile) &&
246               mappings[j].pdbchain.equals(chain))
247           {
248             sl.highlightSequence(mappings[j].sequence,
249                                  mappings[j].getSeqPos(pdbResNum));
250           }
251         }
252
253         sl.highlightSequence(null, pdbResNum);
254       }
255     }
256   }
257
258   public void mouseOverSequence(SequenceI seq, int index)
259   {
260     StructureListener sl;
261     int atomNo = 0;
262     for (int i = 0; i < listeners.size(); i++)
263     {
264       if (listeners.elementAt(i) instanceof StructureListener)
265       {
266         sl = (StructureListener) listeners.elementAt(i);
267
268         for (int j = 0; j < mappings.length; j++)
269         {
270           if (mappings[j].sequence == seq)
271           {
272             atomNo = mappings[j].getAtomNum(index);
273
274             if (atomNo > 0)
275             {
276               sl.highlightAtom(atomNo,
277                                mappings[j].getPDBResNum(index),
278                                mappings[j].pdbchain,
279                                mappings[j].pdbfile);
280             }
281           }
282         }
283       }
284     }
285   }
286
287   public Annotation[] colourSequenceFromStructure(SequenceI seq, String pdbid)
288   {
289     Annotation [] annotations = new Annotation[seq.getLength()];
290
291     StructureListener sl;
292     int atomNo = 0;
293     for (int i = 0; i < listeners.size(); i++)
294     {
295       if (listeners.elementAt(i) instanceof StructureListener)
296       {
297         sl = (StructureListener) listeners.elementAt(i);
298
299         for (int j = 0; j < mappings.length; j++)
300         {
301
302           if (mappings[j].sequence == seq
303               && mappings[j].getPdbId().equals(pdbid)
304               && mappings[j].pdbfile.equals(sl.getPdbFile()))
305           {
306             System.out.println(pdbid+" "+mappings[j].getPdbId()
307                 +" "+mappings[j].pdbfile);
308
309             java.awt.Color col;
310             for(int index=0; index<seq.getLength(); index++)
311             {
312               if(jalview.util.Comparison.isGap(seq.getCharAt(index)))
313                 continue;
314
315               atomNo = mappings[j].getAtomNum(seq.findPosition(index));
316               col = java.awt.Color.white;
317               if (atomNo > 0)
318               {
319                 col = sl.getColour(atomNo,
320                                  mappings[j].getPDBResNum(index),
321                                  mappings[j].pdbchain,
322                                  mappings[j].pdbfile);
323
324             //    System.out.println(atomNo+" "+mappings[j].getPDBResNum(index)
325             //                     +" "+index+" "+col);
326               }
327
328               annotations[index] = new Annotation("X",null,' ',0,col);
329             }
330             return annotations;
331           }
332         }
333       }
334     }
335
336     return annotations;
337   }
338
339
340   public void structureSelectionChanged()
341   {
342     StructureListener svl;
343     for (int i = 0; i < listeners.size(); i++)
344     {
345       svl = (StructureListener) listeners.elementAt(i);
346     }
347   }
348
349   public void sequenceSelectionChanged()
350   {
351     StructureListener svl;
352     for (int i = 0; i < listeners.size(); i++)
353     {
354       svl = (StructureListener) listeners.elementAt(i);
355     }
356   }
357
358   public void sequenceColoursChanged(Object source)
359   {
360     StructureListener sl;
361     for (int i = 0; i < listeners.size(); i++)
362     {
363       if (listeners.elementAt(i) instanceof StructureListener)
364       {
365         sl = (StructureListener) listeners.elementAt(i);
366         sl.updateColours(source);
367       }
368     }
369   }
370
371   public StructureMapping[] getMapping(String pdbfile)
372   {
373     Vector tmp = new Vector();
374     for (int i = 0; i < mappings.length; i++)
375     {
376       if (mappings[i].pdbfile.equals(pdbfile))
377       {
378         tmp.addElement(mappings[i]);
379       }
380     }
381
382     StructureMapping[] ret = new StructureMapping[tmp.size()];
383     for (int i = 0; i < tmp.size(); i++)
384     {
385       ret[i] = (StructureMapping) tmp.elementAt(i);
386     }
387
388     return ret;
389   }
390
391   public String printMapping(String pdbfile)
392   {
393     StringBuffer sb = new StringBuffer();
394     for (int i = 0; i < mappings.length; i++)
395     {
396       if (mappings[i].pdbfile.equals(pdbfile))
397       {
398         sb.append(mappings[i].mappingDetails);
399       }
400     }
401
402     return sb.toString();
403   }
404 }