tidy debug messages
[jalview.git] / src / jalview / gui / AppVarna.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
3  * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
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 of the License, or (at your option) any later version.
10  *  
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 package jalview.gui;
19
20 import java.util.*;
21 import java.util.regex.Matcher;
22 import java.util.regex.Pattern;
23 import java.awt.*;
24
25 import javax.swing.*;
26
27 import jalview.bin.Cache;
28 import jalview.datamodel.*;
29 import jalview.structure.*;
30 import jalview.util.ShiftList;
31 import fr.orsay.lri.varna.VARNAPanel;
32 import fr.orsay.lri.varna.exceptions.ExceptionFileFormatOrSyntax;
33 import fr.orsay.lri.varna.exceptions.ExceptionUnmatchedClosingParentheses;
34 import fr.orsay.lri.varna.interfaces.InterfaceVARNAListener;
35 import fr.orsay.lri.varna.interfaces.InterfaceVARNASelectionListener;
36 import fr.orsay.lri.varna.models.BaseList;
37 import fr.orsay.lri.varna.models.VARNAConfig;
38 import fr.orsay.lri.varna.models.annotations.HighlightRegionAnnotation;
39 import fr.orsay.lri.varna.models.rna.ModeleBase;
40 import fr.orsay.lri.varna.models.rna.RNA;
41
42 public class AppVarna extends JInternalFrame implements
43         InterfaceVARNAListener, SelectionListener,
44         SecondaryStructureListener// implements
45                                   // Runnable,SequenceStructureBinding,
46                                   // ViewSetProvider
47         , InterfaceVARNASelectionListener, VamsasSource
48
49 {
50   AppVarnaBinding vab;
51
52   VARNAPanel varnaPanel;
53
54   public String name;
55
56   public StructureSelectionManager ssm;
57
58   /*
59    * public AppVarna(){ vab = new AppVarnaBinding(); initVarna(); }
60    */
61
62   AlignmentPanel ap;
63
64   public AppVarna(String sname, SequenceI seq, String strucseq,
65           String struc, String name, AlignmentPanel ap)
66   {
67
68 //        System.out.println("1:"+sname);
69 //        System.out.println("2:"+seq);
70 //        System.out.println("3:"+strucseq);
71 //        System.out.println("4:"+struc);
72 //        System.out.println("5:"+name);
73 //        System.out.println("6:"+ap);
74     this.ap = ap;
75     ArrayList<RNA> rnaList = new ArrayList<RNA>();
76     RNA rna1 = new RNA(name);
77     try
78     {
79
80       rna1.setRNA(strucseq, replaceOddGaps(struc));
81 //      System.out.println("The sequence is :"+rna1.getSeq());
82 //      System.out.println("The sequence is:"+struc);
83 //      System.out.println("The sequence is:"+replaceOddGaps(struc).toString());
84     } catch (ExceptionUnmatchedClosingParentheses e2)
85     {
86       e2.printStackTrace();
87     } catch (ExceptionFileFormatOrSyntax e3)
88     {
89       e3.printStackTrace();
90     }
91     RNA trim = trimRNA(rna1, "trimmed " + sname);
92     rnaList.add(trim);
93     rnaList.add(rna1);
94     
95     rnas.put(seq, rna1);
96     rnas.put(seq, trim);
97     rna1.setName(sname + " (with gaps)");
98
99     {
100       seqs.put(trim, seq);
101       seqs.put(rna1, seq);
102       
103       /**
104        * if (false || seq.getStart()!=1) { for (RNA rshift:rnaList) { ShiftList
105        * shift=offsets.get(rshift); if (shift==null) { offsets.put(rshift,
106        * shift=new ShiftList());} shift.addShift(1, seq.getStart()-1);
107        * offsetsInv.put(rshift, shift.getInverse()); } }
108        **/
109     }
110     vab = new AppVarnaBinding(rnaList);
111     // vab = new AppVarnaBinding(seq,struc);
112     this.name = sname + " trimmed to " + name;
113     initVarna();
114    
115     ssm = ap.getStructureSelectionManager();
116     //System.out.println(ssm.toString());
117     ssm.addStructureViewerListener(this);
118     ssm.addSelectionListener(this);
119   }
120
121   public void initVarna()
122   {
123          
124     // vab.setFinishedInit(false);
125     varnaPanel = vab.get_varnaPanel();
126     setBackground(Color.white);
127     JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true,
128             vab.getListPanel(), varnaPanel);
129     getContentPane().setLayout(new BorderLayout());
130     getContentPane().add(split, BorderLayout.CENTER);
131     // getContentPane().add(vab.getTools(), BorderLayout.NORTH);
132     varnaPanel.addVARNAListener(this);
133     varnaPanel.addSelectionListener(this);
134     jalview.gui.Desktop.addInternalFrame(this, "VARNA -" + name,
135             getBounds().width, getBounds().height);
136     this.pack();
137     showPanel(true);
138   
139   }
140
141   public String replaceOddGaps(String oldStr)
142   {
143     String patternStr = "[^([{<>}])]";
144     String replacementStr = ".";
145     Pattern pattern = Pattern.compile(patternStr);
146     Matcher matcher = pattern.matcher(oldStr);
147     String newStr = matcher.replaceAll(replacementStr);
148     return newStr;
149   }
150
151   public RNA trimRNA(RNA rna, String name)
152   {
153     ShiftList offset = new ShiftList();
154     
155     RNA rnaTrim = new RNA(name);
156     try
157     {
158       rnaTrim.setRNA(rna.getSeq(), replaceOddGaps(rna.getStructDBN()));
159     } catch (ExceptionUnmatchedClosingParentheses e2)
160     {
161       e2.printStackTrace();
162     } catch (ExceptionFileFormatOrSyntax e3)
163     {
164       e3.printStackTrace();
165     }
166
167     StringBuffer seq = new StringBuffer(rnaTrim.getSeq());
168     StringBuffer struc = new StringBuffer(rnaTrim.getStructDBN());
169     int ofstart = -1, sleng = rnaTrim.getSeq().length();
170     for (int i = 0; i < sleng; i++)
171     {
172       // TODO: Jalview utility for gap detection java.utils.isGap()
173       // TODO: Switch to jalview rna datamodel
174       if (jalview.util.Comparison.isGap(seq.charAt(i)))
175       {
176         if (ofstart == -1)
177         {
178           ofstart = i;
179         }
180         if (!rnaTrim.findPair(i).isEmpty())
181         {
182           int m = rnaTrim.findPair(i).get(1);
183           int l = rnaTrim.findPair(i).get(0);
184
185           struc.replace(m, m + 1, "*");
186           struc.replace(l, l + 1, "*");
187         }
188         else
189         {
190           struc.replace(i, i + 1, "*");
191         }
192       }
193       else
194       {
195         if (ofstart > -1)
196         {
197           offset.addShift(offset.shift(ofstart), ofstart - i);
198           ofstart = -1;
199         }
200       }
201     }
202     // final gap
203     if (ofstart > -1)
204     {
205       offset.addShift(offset.shift(ofstart), ofstart - sleng);
206       ofstart = -1;
207     }
208     String newSeq = rnaTrim.getSeq().replace("-", "");
209     rnaTrim.getSeq().replace(".", "");
210     String newStruc = struc.toString().replace("*", "");
211
212     try
213     {
214       rnaTrim.setRNA(newSeq, newStruc);
215       registerOffset(rnaTrim, offset);
216     } catch (ExceptionUnmatchedClosingParentheses e)
217     {
218       // TODO Auto-generated catch block
219       e.printStackTrace();
220     } catch (ExceptionFileFormatOrSyntax e)
221     {
222       // TODO Auto-generated catch block
223       e.printStackTrace();
224     }
225     return rnaTrim;
226   }
227
228   // needs to be many-many
229   Map<RNA, SequenceI> seqs = new Hashtable<RNA, SequenceI>();
230
231   Map<SequenceI, RNA> rnas = new Hashtable<SequenceI, RNA>();
232
233   Map<RNA, ShiftList> offsets = new Hashtable<RNA, ShiftList>();
234
235   Map<RNA, ShiftList> offsetsInv = new Hashtable<RNA, ShiftList>();
236
237   private void registerOffset(RNA rnaTrim, ShiftList offset)
238   {
239     offsets.put(rnaTrim, offset);
240     offsetsInv.put(rnaTrim, offset.getInverse());
241   }
242
243   public void showPanel(boolean show)
244   {
245     this.setVisible(show);
246   }
247
248   private boolean _started = false;
249
250   public void run()
251   {
252     _started = true;
253
254     try
255     {
256       initVarna();
257     } catch (OutOfMemoryError oomerror)
258     {
259       new OOMWarning("When trying to open the Varna viewer!", oomerror);
260     } catch (Exception ex)
261     {
262       Cache.log.error("Couldn't open Varna viewer!", ex);
263     }
264   }
265
266   @Override
267   public void onUINewStructure(VARNAConfig v, RNA r)
268   {
269
270   }
271
272   @Override
273   public void onWarningEmitted(String s)
274   {
275     // TODO Auto-generated method stub
276
277   }
278
279   private class VarnaHighlighter
280   {
281     private HighlightRegionAnnotation _lastHighlight;
282
283     private RNA _lastRNAhighlighted = null;
284
285     public void highlightRegion(RNA rna, int start, int end)
286     {
287       clearSelection(null);
288       HighlightRegionAnnotation highlight = new HighlightRegionAnnotation(
289               rna.getBasesBetween(start, end));
290       rna.addHighlightRegion(highlight);
291       _lastHighlight = highlight;
292       _lastRNAhighlighted = rna;
293
294     }
295
296     public HighlightRegionAnnotation getLastHighlight()
297     {
298       return _lastHighlight;
299     }
300
301     public RNA getLastRNA()
302     {
303       return _lastRNAhighlighted;
304     }
305
306     public void clearSelection(AppVarnaBinding vab)
307     {
308       if (_lastRNAhighlighted != null)
309       {
310         _lastRNAhighlighted.removeHighlightRegion(_lastHighlight);
311         if (vab != null)
312         {
313           vab.updateSelectedRNA(_lastRNAhighlighted);
314         }
315         _lastRNAhighlighted = null;
316         _lastHighlight = null;
317
318       }
319     }
320   }
321
322   VarnaHighlighter mouseOverHighlighter = new VarnaHighlighter(),
323           selectionHighlighter = new VarnaHighlighter();
324
325   /**
326    * If a mouseOver event from the AlignmentPanel is noticed the currently
327    * selected RNA in the VARNA window is highlighted at the specific position.
328    * To be able to remove it before the next highlight it is saved in
329    * _lastHighlight
330    */
331   @Override
332   public void mouseOverSequence(SequenceI sequence, int index)
333   {
334     RNA rna = vab.getSelectedRNA();
335     if (seqs.get(rna) == sequence)
336     {
337       ShiftList shift = offsets.get(rna);
338       if (shift != null)
339       {
340         // System.err.print("Orig pos:"+index);
341         index = shift.shift(index);
342         // System.err.println("\nFinal pos:"+index);
343       }
344       mouseOverHighlighter.highlightRegion(rna, index, index);
345       vab.updateSelectedRNA(rna);
346     }
347   }
348
349   @Override
350   public void onStructureRedrawn()
351   {
352     // TODO Auto-generated method stub
353
354   }
355
356   @Override
357   public void selection(SequenceGroup seqsel, ColumnSelection colsel,
358           SelectionSource source)
359   {
360     if (source != ap.av)
361     {
362       // ignore events from anything but our parent alignpanel
363       // TODO - reuse many-one panel-view system in jmol viewer
364       return;
365     }
366     if (seqsel != null && seqsel.getSize() > 0)
367     {
368       int start = seqsel.getStartRes(), end = seqsel.getEndRes();
369       RNA rna = vab.getSelectedRNA();
370       ShiftList shift = offsets.get(rna);
371       if (shift != null)
372       {
373         start = shift.shift(start);
374         end = shift.shift(end);
375       }
376       selectionHighlighter.highlightRegion(rna, start, end);
377       selectionHighlighter.getLastHighlight().setOutlineColor(
378               seqsel.getOutlineColour());
379       // TODO - translate column markings to positions on structure if present.
380       vab.updateSelectedRNA(rna);
381     }
382     else
383     {
384       selectionHighlighter.clearSelection(vab);
385     }
386   }
387
388   @Override
389   public void onHoverChanged(ModeleBase arg0, ModeleBase arg1)
390   {
391     RNA rna = vab.getSelectedRNA();
392     ShiftList shift = offsetsInv.get(rna);
393     SequenceI seq = seqs.get(rna);
394     if (arg1 != null && seq != null)
395     {
396       if (shift != null)
397       {
398         int i = shift.shift(arg1.getIndex());
399         // System.err.println("shifted "+(arg1.getIndex())+" to "+i);
400         ssm.mouseOverVamsasSequence(seq, i, this);
401       }
402       else
403       {
404         ssm.mouseOverVamsasSequence(seq, arg1.getIndex(), this);
405       }
406     }
407   }
408
409   @Override
410   public void onSelectionChanged(BaseList arg0, BaseList arg1, BaseList arg2)
411   {
412     // TODO translate selected regions in VARNA to a selection on the
413     // alignpanel.
414
415   }
416
417 }