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