PDB residue numberings transfered and alignment view refreshed to update featureRenderer.
[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   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     }
192     /////////
193
194     return pdb;
195   }
196
197   public void removeStructureViewerListener(Object svl, String pdbfile)
198   {
199     listeners.removeElement(svl);
200
201     boolean removeMapping = true;
202
203     StructureListener sl;
204     for (int i = 0; i < listeners.size(); i++)
205     {
206       if (listeners.elementAt(i) instanceof StructureListener)
207       {
208         sl = (StructureListener) listeners.elementAt(i);
209         if (sl.getPdbFile().equals(pdbfile))
210         {
211           removeMapping = false;
212           break;
213         }
214       }
215     }
216
217     if (removeMapping && mappings!=null)
218     {
219       Vector tmp = new Vector();
220       for (int i = 0; i < mappings.length; i++)
221       {
222         if (!mappings[i].pdbfile.equals(pdbfile))
223         {
224           tmp.addElement(mappings[i]);
225         }
226       }
227
228       mappings = new StructureMapping[tmp.size()];
229       tmp.copyInto(mappings);
230     }
231   }
232
233   public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
234   {
235     SequenceListener sl;
236     for (int i = 0; i < listeners.size(); i++)
237     {
238       if (listeners.elementAt(i) instanceof SequenceListener)
239       {
240         sl = (SequenceListener) listeners.elementAt(i);
241
242         for (int j = 0; j < mappings.length; j++)
243         {
244           if (mappings[j].pdbfile.equals(pdbfile) &&
245               mappings[j].pdbchain.equals(chain))
246           {
247             sl.highlightSequence(mappings[j].sequence,
248                                  mappings[j].getSeqPos(pdbResNum));
249           }
250         }
251
252         sl.highlightSequence(null, pdbResNum);
253       }
254     }
255   }
256
257   public void mouseOverSequence(SequenceI seq, int index)
258   {
259     StructureListener sl;
260     int atomNo = 0;
261     for (int i = 0; i < listeners.size(); i++)
262     {
263       if (listeners.elementAt(i) instanceof StructureListener)
264       {
265         sl = (StructureListener) listeners.elementAt(i);
266
267         for (int j = 0; j < mappings.length; j++)
268         {
269           if (mappings[j].sequence == seq)
270           {
271             atomNo = mappings[j].getAtomNum(index);
272
273             if (atomNo > 0)
274             {
275               sl.highlightAtom(atomNo,
276                                mappings[j].getPDBResNum(index),
277                                mappings[j].pdbchain,
278                                mappings[j].pdbfile);
279             }
280           }
281         }
282       }
283     }
284   }
285
286   public void structureSelectionChanged()
287   {
288     StructureListener svl;
289     for (int i = 0; i < listeners.size(); i++)
290     {
291       svl = (StructureListener) listeners.elementAt(i);
292     }
293   }
294
295   public void sequenceSelectionChanged()
296   {
297     StructureListener svl;
298     for (int i = 0; i < listeners.size(); i++)
299     {
300       svl = (StructureListener) listeners.elementAt(i);
301     }
302   }
303
304   public void sequenceColoursChanged(Object source)
305   {
306     StructureListener sl;
307     for (int i = 0; i < listeners.size(); i++)
308     {
309       if (listeners.elementAt(i) instanceof StructureListener)
310       {
311         sl = (StructureListener) listeners.elementAt(i);
312         sl.updateColours(source);
313       }
314     }
315   }
316
317   public StructureMapping[] getMapping(String pdbfile)
318   {
319     Vector tmp = new Vector();
320     for (int i = 0; i < mappings.length; i++)
321     {
322       if (mappings[i].pdbfile.equals(pdbfile))
323       {
324         tmp.addElement(mappings[i]);
325       }
326     }
327
328     StructureMapping[] ret = new StructureMapping[tmp.size()];
329     for (int i = 0; i < tmp.size(); i++)
330     {
331       ret[i] = (StructureMapping) tmp.elementAt(i);
332     }
333
334     return ret;
335   }
336
337   public String printMapping(String pdbfile)
338   {
339     StringBuffer sb = new StringBuffer();
340     for (int i = 0; i < mappings.length; i++)
341     {
342       if (mappings[i].pdbfile.equals(pdbfile))
343       {
344         sb.append(mappings[i].mappingDetails);
345       }
346     }
347
348     return sb.toString();
349   }
350 }