JAL-3032 adds Java 8 functionality (2/2)
[jalview.git] / src2 / fr / orsay / lri / varna / applications / NussinovDesignDemo.java
1 /*
2  VARNA is a tool for the automated drawing, visualization and annotation of the secondary structure of RNA, designed as a companion software for web servers and databases.
3  Copyright (C) 2008  Kevin Darty, Alain Denise and Yann Ponty.
4  electronic mail : Yann.Ponty@lri.fr
5  paper mail : LRI, bat 490 Université Paris-Sud 91405 Orsay Cedex France
6
7  This file is part of VARNA version 3.1.
8  VARNA version 3.1 is free software: you can redistribute it and/or 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  VARNA version 3.1 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  See the GNU General Public License for more details.
14
15  You should have received a copy of the GNU General Public License along with VARNA version 3.1.
16  If not, see http://www.gnu.org/licenses.
17  */
18 package fr.orsay.lri.varna.applications;
19
20 import java.awt.BorderLayout;
21 import java.awt.Color;
22 import java.awt.Dimension;
23 import java.awt.Font;
24 import java.awt.GridLayout;
25 import java.awt.event.ActionEvent;
26 import java.awt.event.ActionListener;
27 import java.awt.event.ItemEvent;
28 import java.awt.event.ItemListener;
29 import java.awt.event.MouseEvent;
30 import java.math.BigInteger;
31 import java.util.ArrayList;
32 import java.util.Collections;
33
34 import javax.swing.BorderFactory;
35 import javax.swing.DefaultComboBoxModel;
36 import javax.swing.JButton;
37 import javax.swing.JComboBox;
38 import javax.swing.JFrame;
39 import javax.swing.JLabel;
40 import javax.swing.JOptionPane;
41 import javax.swing.JPanel;
42 import javax.swing.JSplitPane;
43 import javax.swing.JTextArea;
44 import javax.swing.JTextField;
45 import javax.swing.JTextPane;
46 import javax.swing.border.BevelBorder;
47
48 import fr.orsay.lri.varna.VARNAPanel;
49 import fr.orsay.lri.varna.controlers.ControleurInterpolator;
50 import fr.orsay.lri.varna.exceptions.ExceptionDrawingAlgorithm;
51 import fr.orsay.lri.varna.exceptions.ExceptionFileFormatOrSyntax;
52 import fr.orsay.lri.varna.exceptions.ExceptionModeleStyleBaseSyntaxError;
53 import fr.orsay.lri.varna.exceptions.ExceptionNAViewAlgorithm;
54 import fr.orsay.lri.varna.exceptions.ExceptionNonEqualLength;
55 import fr.orsay.lri.varna.exceptions.ExceptionParameterError;
56 import fr.orsay.lri.varna.exceptions.ExceptionUnmatchedClosingParentheses;
57 import fr.orsay.lri.varna.exceptions.MappingException;
58 import fr.orsay.lri.varna.models.VARNAConfig;
59 import fr.orsay.lri.varna.models.VARNAConfig.BP_STYLE;
60 import fr.orsay.lri.varna.models.rna.Mapping;
61 import fr.orsay.lri.varna.models.rna.ModeleBP;
62 import fr.orsay.lri.varna.models.rna.ModeleBase;
63 import fr.orsay.lri.varna.models.rna.ModelBaseStyle;
64 import fr.orsay.lri.varna.models.rna.RNA;
65 import fr.orsay.lri.varna.interfaces.InterfaceVARNABasesListener;
66 import fr.orsay.lri.varna.interfaces.InterfaceVARNAListener;;
67
68 public class NussinovDesignDemo extends JFrame implements InterfaceVARNAListener,InterfaceVARNABasesListener, ItemListener {
69
70         /**
71          * 
72          */
73         private static final long serialVersionUID = -790155708306987257L;
74
75         private static final String SEQUENCE_A =        "AGGCACGUCU";
76         private static final String SEQUENCE_B =  "GAGUAGCCUC";
77         private static final String SEQUENCE_C = "GCAUAGCUGC";
78         private static final String SEQUENCE_INRIA = "CGAUUGCAUCGCAAGU";
79         
80         private static final String TARGET_STRUCTURE_1 = "(((((((..)))))))";
81         private static final String TARGET_STRUCTURE_2 = "(((())))(((())))";
82         private static final String TARGET_STRUCTURE_3 = "(.((.((..).)).))";
83         private static final String TARGET_STRUCTURE_4 = "((((((())))(((())(()))))))";
84         private static final String TARGET_STRUCTURE_5 = "(((())))(((())))(((())))(((())))(((())))(((())))";
85
86         private static final String SEQUENCE_BIG = "AAAACAAAAACACCAUGGUGUUUUCACCCAAUUGGGUGAAAACAGAGAUCUCGAGAUCUCUGUUUUUGUUUU"; 
87
88         private static final String DEFAULT_STRUCTURE = "..........";
89         // private static final String DEFAULT_STRUCTURE1 = "((((....))))";
90         // private static final String DEFAULT_STRUCTURE2 =
91         // "((((..(((....)))..))))";
92
93         private VARNAPanel _vpMaster;
94         private VARNAPanel _vpTarget;
95
96         private InfoPanel _infos = new InfoPanel();
97         private JPanel _tools = new JPanel();
98         private JPanel _input = new JPanel();
99
100         private JPanel _seqPanel = new JPanel();
101         private JPanel _structPanel = new JPanel();
102         private JLabel _actions = new JLabel();
103         private JComboBox _struct = new JComboBox();
104         private JLabel _seq1 = new JLabel();
105         private JLabel _structLabel = new JLabel("Structure Cible");
106         private JLabel _seqLabel = new JLabel("Sequence d'ARN");
107         private JButton _switchButton = new JButton("Reset");
108
109
110         private Color _backgroundColor = Color.white;
111
112         private Color _okColor = Color.decode("#E33729");
113         private Color _koColor = new Color(250,200,200);
114
115
116         public static ModelBaseStyle createStyle(String txt) 
117         {
118                 ModelBaseStyle result = new ModelBaseStyle();
119                 try {
120                         result.assignParameters(txt);
121                 } catch (ExceptionModeleStyleBaseSyntaxError e) {
122                         // TODO Auto-generated catch block
123                         e.printStackTrace();
124                 } catch (ExceptionParameterError e) {
125                         // TODO Auto-generated catch block
126                         e.printStackTrace();
127                 }
128                 return result;
129         }
130         
131         public void applyTo(VARNAPanel vp, ModelBaseStyle mb, int[] indices)
132         {
133                 for(int i=0;i<indices.length;i++)
134                 { 
135                         ModeleBase m = vp.getRNA().getBaseAt(indices[i]);
136                         m.setStyleBase(mb);
137                         if (m.getElementStructure()!=-1)
138                         {
139                                 vp.getRNA().getBaseAt(m.getElementStructure()).setStyleBase(mb);
140                         }
141                 }
142                 vp.repaint();
143         }
144         
145         
146         public NussinovDesignDemo() {
147                 super();
148                 try {
149                         _vpMaster = new VARNAPanel(getSeq(), "");
150                         _vpTarget = new VARNAPanel();
151                 } catch (ExceptionNonEqualLength e) {
152                         _vpMaster.errorDialog(e);
153                 }
154                 _vpMaster.setPreferredSize(new Dimension(600, 600));
155                 _vpTarget.setPreferredSize(new Dimension(600, 600));
156                 RNAPanelDemoInit();
157         }
158         
159         static Font labelsFont = Font.decode("Dialog-BOLD-25");
160
161         private void RNAPanelDemoInit() {
162                 int marginTools = 250;
163                 Font textFieldsFont = Font.decode("MonoSpaced-BOLD-16");
164                 
165                 
166
167                 _seq1.setFont(textFieldsFont.deriveFont(25f));
168                 
169
170                 setBackground(_backgroundColor);
171
172                 
173                 _structLabel.setFont(labelsFont.deriveFont(Font.PLAIN));
174
175                 
176                 String[] secstr = {TARGET_STRUCTURE_1,TARGET_STRUCTURE_2,TARGET_STRUCTURE_3,TARGET_STRUCTURE_4,TARGET_STRUCTURE_5};
177                 DefaultComboBoxModel cm = new DefaultComboBoxModel(secstr); 
178                 _struct.setModel(cm);
179                 _struct.addActionListener(new ActionListener() {
180                         public void actionPerformed(ActionEvent e) {
181                                 System.out.println(e.getActionCommand());
182                                 setTarget(((JComboBox)e.getSource()).getSelectedItem().toString());
183                         }
184                 });
185                 _struct.setFont(textFieldsFont);
186                 _struct.setEnabled(true);
187                 _struct.setEditable(true);
188
189
190                 _switchButton.addActionListener(new ActionListener() {
191                         public void actionPerformed(ActionEvent e) {
192                                 setTarget(_struct.getSelectedItem().toString());                
193                         }
194                 });
195
196                 _seqPanel.setLayout(new BorderLayout());
197                 _seqPanel.add(_seqLabel, BorderLayout.WEST);
198                 _seqPanel.add(_seq1, BorderLayout.CENTER);
199
200                 _seqPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
201
202                 _structLabel.setPreferredSize(new Dimension(marginTools, 15));
203                 _structLabel.setHorizontalTextPosition(JLabel.LEFT);
204                 _structPanel.setLayout(new BorderLayout());
205                 _structPanel.add(_structLabel, BorderLayout.WEST);
206                 _structPanel.add(_struct, BorderLayout.CENTER);
207
208                 _input.setLayout(new GridLayout(0, 1));
209                 _input.add(_structPanel);
210                 
211                 JPanel goPanel = new JPanel();
212                 goPanel.setLayout(new BorderLayout());
213
214                 _infos.setFont(labelsFont);
215
216
217                 formatLabel(_seqLabel);
218                 formatLabel(_seq1);
219
220                 
221                 _tools.setLayout(new BorderLayout());
222                 //_tools.add(_infos, BorderLayout.NORTH);
223                 _tools.add(_input, BorderLayout.CENTER);
224                 _tools.add(_actions, BorderLayout.SOUTH);
225                 _tools.add(goPanel, BorderLayout.EAST);
226                 
227                 _tools.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
228
229                 //goPanel.add(_goButton, BorderLayout.CENTER);
230                 goPanel.add(_switchButton, BorderLayout.CENTER);
231
232                 getContentPane().setLayout(new BorderLayout());
233                 JSplitPane VARNAs = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
234                 VARNAs.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
235                 //VARNAs.setLayout(new GridLayout(1,2));
236                 JPanel mast2 = new JPanel();
237                 mast2.setLayout(new BorderLayout());
238                 mast2.add(_seqPanel, BorderLayout.NORTH);
239                 mast2.add(_infos, BorderLayout.SOUTH);
240
241                 JPanel mast = new JPanel();
242                 mast.setLayout(new BorderLayout());
243                 mast.add(_vpMaster, BorderLayout.CENTER);
244                 mast.add(mast2,BorderLayout.SOUTH);
245                 
246                 VARNAs.add(mast);
247                 VARNAs.add(_vpTarget);
248                 VARNAs.doLayout();
249                 VARNAs.setDividerSize(5);
250                 
251                 getContentPane().add(VARNAs, BorderLayout.CENTER);
252                 getContentPane().add(_tools, BorderLayout.NORTH);
253
254                 setVisible(true);
255
256
257                 _vpMaster.setBackground(_backgroundColor);
258                 _vpMaster.addVARNAListener(this);
259                 _vpMaster.setTitle("Meilleur repliement - Séquence courante");
260                 _vpMaster.setBPStyle(BP_STYLE.SIMPLE);
261                 _vpMaster.getVARNAUI().UIRadiate();
262                 _vpMaster.setTitleFontSize(26f);
263                 _vpMaster.setTitleFontStyle(Font.PLAIN);
264                 
265                 _vpTarget.setBackground(Color.decode("#308099"));
266                 _vpTarget.setModifiable(false);
267                 _vpTarget.setTitle("Repliement cible");
268                 _vpTarget.setBPStyle(BP_STYLE.SIMPLE);
269                 _vpTarget.setBackboneColor(Color.white);
270                 _vpTarget.setDefaultBPColor(Color.white);
271                 _vpTarget.setBaseNumbersColor(Color.white);
272                 _vpTarget.setBaseOutlineColor(Color.white);
273                 _vpTarget.setTitleColor(Color.white);           
274                 _vpTarget.setTitleFontSize(26f);
275
276                 
277                 _okColor = Color.decode("#F39126");
278                 _koColor = new Color(250,200,200);
279                 
280                 _seqPanel.setBackground(Color.decode("#E33729"));
281                 _infos.setBackground(Color.decode("#E33729"));
282
283
284                 
285                 _vpMaster.addVARNABasesListener(this);
286                 setTitle("Fête de la science 2015 - Inria AMIB - Design d'ARN");
287                 
288                 setTarget(secstr[0]);
289                 
290         }
291
292         private synchronized void showSolution()
293         {
294                 ArrayList<String> sols = getStructs();
295                 _infos.setInfo(sols, count(getSeq()));
296                 if ((sols.size()==1)&&(sols.get(0).equals(_struct.getSelectedItem().toString())))
297                 {
298                         /*JOptionPane.showMessageDialog(null, 
299                                         "Vous avez trouvé une séquence pour cette structure !!!\n Saurez vous faire le design de molécules plus complexes ?",
300                                         "Félicitations !", 
301                                         JOptionPane.INFORMATION_MESSAGE);*/
302                         
303                 }
304                 else
305                 {
306                         this._vpMaster.setTitle("Meilleur repliement - Séquence courante");
307                 }
308         }
309         
310
311         public void setTarget(String target)
312         {
313                 try {
314                         _vpTarget.drawRNA(String.format("%"+target.length()+"s", ""),target);
315                         _vpTarget.setBaseNumbersColor(Color.white);
316                         _vpTarget.setBaseOutlineColor(Color.white);
317                         //_vpTarget.toggleDrawOutlineBases();
318                         createDummySeq();
319                         showSolution();
320                         onStructureRedrawn();
321                 } catch (ExceptionNonEqualLength e) {
322                         // TODO Auto-generated catch block
323                         e.printStackTrace();
324                 }
325         }
326         
327         private void createDummySeq()
328         {
329                 RNA r = _vpTarget.getRNA();
330                 String seq = new String();
331                 for (int i=0;i<r.getSize();i++)
332                 {
333                         seq += 'A';
334                 }
335                 try {
336                 RNA rn = new RNA();
337                         rn.setRNA(seq,r.getStructDBN());
338                 for(ModeleBP mbp: r.getAllBPs())
339                 {
340                         rn.getBaseAt(mbp.getIndex5()).setContent("A"); 
341                         rn.getBaseAt(mbp.getIndex3()).setContent("U"); 
342                 }
343                 _vpMaster.drawRNA(rn);
344                 _vpMaster.repaint();
345                 _seq1.setText(_vpMaster.getRNA().getSeq());
346                 } catch (ExceptionUnmatchedClosingParentheses e) {
347                         // TODO Auto-generated catch block
348                         e.printStackTrace();
349                 } catch (ExceptionFileFormatOrSyntax e) {
350                         // TODO Auto-generated catch block
351                         e.printStackTrace();
352                 }
353         }
354
355
356         public String getSeq()
357         {
358                 return (""+_seq1.getText()).toUpperCase();
359         }
360
361         
362         private boolean canBasePairAll(char a, char b)
363         {
364                 return true;
365         }
366
367         private boolean canBasePairBasic(char a, char b)
368         {
369                 if ((a=='G')&&(b=='C'))
370                         return true;
371                 if ((a=='C')&&(b=='G'))
372                         return true;
373                 if ((a=='U')&&(b=='A'))
374                         return true;
375                 if ((a=='A')&&(b=='U'))
376                         return true;
377                 return false;
378         }
379
380         private double basePairScoreBasic(char a, char b)
381         {
382                 if ((a=='G')&&(b=='C'))
383                         return 1.0;
384                 if ((a=='C')&&(b=='G'))
385                         return 1.0;
386                 if ((a=='U')&&(b=='A'))
387                         return 1.0;
388                 if ((a=='A')&&(b=='U'))
389                         return 1.0;
390                 return Double.NEGATIVE_INFINITY;
391         }
392
393         
394         private boolean canBasePairNussinov(char a, char b)
395         {
396                 if ((a=='G')&&(b=='C'))
397                         return true;
398                 if ((a=='C')&&(b=='G'))
399                         return true;
400                 if ((a=='U')&&(b=='A'))
401                         return true;
402                 if ((a=='A')&&(b=='U'))
403                         return true;
404                 if ((a=='U')&&(b=='G'))
405                         return true;
406                 if ((a=='G')&&(b=='U'))
407                         return true;
408                 return false;
409         }
410
411         private double basePairScoreNussinov(char a, char b)
412         {
413                 if ((a=='G')&&(b=='C'))
414                         return 3.0;
415                 if ((a=='C')&&(b=='G'))
416                         return 3.0;
417                 if ((a=='U')&&(b=='A'))
418                         return 2.0;
419                 if ((a=='A')&&(b=='U'))
420                         return 2.0;
421                 if ((a=='U')&&(b=='G'))
422                         return 1.0;
423                 if ((a=='G')&&(b=='U'))
424                         return 1.0;
425                 return Double.NEGATIVE_INFINITY;
426         }
427
428         private boolean canBasePairINRIA(char a, char b)
429         {
430                 if ((a=='U')&&(b=='A'))
431                         return true;
432                 if ((a=='A')&&(b=='U'))
433                         return true;
434                 if ((a=='G')&&(b=='C'))
435                         return true;
436                 if ((a=='C')&&(b=='G'))
437                         return true;
438
439                 if ((a=='A')&&(b=='G'))
440                         return true;
441                 if ((a=='G')&&(b=='A'))
442                         return true;
443                 if ((a=='U')&&(b=='C'))
444                         return true;
445                 if ((a=='C')&&(b=='U'))
446                         return true;
447                 if ((a=='A')&&(b=='A'))
448                         return true;
449                 if ((a=='U')&&(b=='U'))
450                         return true;
451
452                 if ((a=='U')&&(b=='G'))
453                         return true;
454                 if ((a=='G')&&(b=='U'))
455                         return true;
456                 if ((a=='A')&&(b=='C'))
457                         return true;
458                 if ((a=='C')&&(b=='A'))
459                         return true;
460                 return false;
461         }
462
463         private double basePairScoreINRIA(char a, char b)
464         {
465                 if ((a=='U')&&(b=='A'))
466                         return 3;
467                 if ((a=='A')&&(b=='U'))
468                         return 3;
469                 if ((a=='G')&&(b=='C'))
470                         return 3;
471                 if ((a=='C')&&(b=='G'))
472                         return 3;
473
474                 if ((a=='A')&&(b=='G'))
475                         return 2;
476                 if ((a=='G')&&(b=='A'))
477                         return 2;
478                 if ((a=='U')&&(b=='C'))
479                         return 2;
480                 if ((a=='C')&&(b=='U'))
481                         return 2;
482                 if ((a=='A')&&(b=='A'))
483                         return 2;
484                 if ((a=='U')&&(b=='U'))
485                         return 2;
486
487                 if ((a=='U')&&(b=='G'))
488                         return 1;
489                 if ((a=='G')&&(b=='U'))
490                         return 1;
491                 if ((a=='A')&&(b=='C'))
492                         return 1;
493                 if ((a=='C')&&(b=='A'))
494                         return 1;
495                 return Double.NEGATIVE_INFINITY;
496         }
497         
498         private boolean canBasePair(char a, char b)
499         {
500                 return canBasePairBasic(a,b);
501                 //return canBasePairNussinov(a,b);
502                 //return canBasePairINRIA(a,b);
503         }
504         
505         private double basePairScore(char a, char b)
506         {
507                 return basePairScoreBasic(a,b);
508                 //return basePairScoreNussinov(a,b);
509                 //return basePairScoreINRIA(a,b);
510         }
511         
512         public double[][] fillMatrix(String seq)
513         {
514                 int n = seq.length();
515                 double[][] tab = new double[n][n];
516                 for(int m=1;m<=n;m++)
517                 {
518                         for(int i=0;i<n-m+1;i++)
519                         {
520                                 int j = i+m-1;
521                                 tab[i][j] = 0;
522                                 if (i<j)
523                                 { 
524                                         tab[i][j] = Math.max(tab[i][j], tab[i+1][j]); 
525                                         for (int k=i+1;k<=j;k++)
526                                         {
527                                                 if (canBasePair(seq.charAt(i),seq.charAt(k)))
528                                                 {
529                                                         double fact1 = 0;
530                                                         if (k>i+1)
531                                                         {
532                                                                 fact1 = tab[i+1][k-1];
533                                                         }
534                                                         double fact2 = 0;
535                                                         if (k<j)
536                                                         {
537                                                                 fact2 = tab[k+1][j];
538                                                         }
539                                                         tab[i][j] = Math.max(tab[i][j],basePairScore(seq.charAt(i),seq.charAt(k))+fact1+fact2);
540                                                 } 
541                                         }
542                                 }
543                         }                       
544                 }
545                 return tab;
546         }
547
548         public static ArrayList<Double> combine(double bonus, ArrayList<Double> part1, ArrayList<Double> part2)
549         {
550                 ArrayList<Double> base = new ArrayList<Double>();
551                 for(double d1: part1)
552                 {
553                         for(double d2: part2)
554                         {
555                                 base.add(bonus+d1+d2);
556                         }
557                 }
558                 return base;
559         }
560
561         public static ArrayList<Double> selectBests(ArrayList<Double> base)
562         {
563                 ArrayList<Double> result = new ArrayList<Double>();
564                 double best = Double.NEGATIVE_INFINITY;
565                 for(double val: base)
566                 {
567                         best = Math.max(val, best);
568                 }
569                 for(double val: base)
570                 {
571                         if (val == best)
572                                 result.add(val);
573                 }
574                 return result;
575         }
576
577         
578         private ArrayList<String> backtrack(double[][] tab, String seq)
579         {
580                 return backtrack(tab,seq, 0, seq.length()-1);
581         }
582
583         private ArrayList<String> backtrack(double[][] tab, String seq, int i, int j)
584         {
585                 ArrayList<String> result = new ArrayList<String>();
586                 if (i<j)
587                 { 
588                         ArrayList<Integer> indices = new ArrayList<Integer>();
589                         indices.add(-1);
590                         for (int k=i+1;k<=j;k++)
591                         {
592                                 indices.add(k);
593                         }
594                         for (int k : indices)
595                         {
596                                 if (k==-1)
597                                 {
598                                         if (tab[i][j] == tab[i+1][j])
599                                         {
600                                                 for (String s:backtrack(tab, seq, i+1,j))
601                                                 {
602                                                         result.add("."+s);
603                                                 }
604                                         }
605                                 }
606                                 else
607                                 {
608                                         if (canBasePair(seq.charAt(i),seq.charAt(k)))
609                                         {
610                                                 double fact1 = 0;
611                                                 if (k>i+1)
612                                                 {
613                                                         fact1 = tab[i+1][k-1];
614                                                 }
615                                                 double fact2 = 0;
616                                                 if (k<j)
617                                                 {
618                                                         fact2 = tab[k+1][j];
619                                                 }
620                                                 if (tab[i][j]==basePairScore(seq.charAt(i),seq.charAt(k))+fact1+fact2)
621                                                 { 
622                                                         for (String s1:backtrack(tab, seq, i+1,k-1))
623                                                         {
624                                                                 for (String s2:backtrack(tab, seq, k+1,j))
625                                                                 {
626                                                                         result.add("("+s1+")"+s2);
627                                                                 }
628                                                         }
629                                                 }
630                                         }                                       
631                                 }                               
632                         }
633                 }
634                 else if  (i==j)
635                 {
636                         result.add(".");
637                 }
638                 else 
639                 {
640                         result.add("");
641                 }
642                 return result;
643         }
644         
645         public BigInteger count(String seq)
646         {
647                 int n = seq.length();
648                 
649                 BigInteger[][] tab = new BigInteger[n][n];
650                 for(int m=1;m<=n;m++)
651                 {
652                         for(int i=0;i<n-m+1;i++)
653                         {
654                                 int j = i+m-1;
655                                 tab[i][j] = BigInteger.ZERO;
656                                 if (i<j)
657                                 { 
658                                         tab[i][j] = tab[i][j].add(tab[i+1][j]); 
659                                         for (int k=i+1;k<=j;k++)
660                                         {
661                                                 if (canBasePair(seq.charAt(i),seq.charAt(k)))
662                                                 {
663                                                         BigInteger fact1 = BigInteger.ONE;
664                                                         if (k>i+1)
665                                                         {
666                                                                 fact1 = tab[i+1][k-1];
667                                                         }
668                                                         BigInteger fact2 = BigInteger.ONE;
669                                                         if (k<j)
670                                                         {
671                                                                 fact2 = tab[k+1][j];
672                                                         }
673                                                         tab[i][j] = tab[i][j].add(fact1.multiply(fact2));
674                                                 } 
675                                         }
676                                 }
677                                 else
678                                 {
679                                         tab[i][j] = BigInteger.ONE;
680                                 }
681                         }                       
682                 }
683                 return tab[0][n-1];
684         }
685         
686         private String _cache = "";
687         ArrayList<String> _cacheStructs = new ArrayList<String>(); 
688         
689         public ArrayList<String> getStructs() {
690                 String seq = getSeq();
691                 seq = seq.toUpperCase();
692                 if (!_cache.equals(seq))
693                 {
694                         double[][] mfe = fillMatrix(seq);
695                         _cacheStructs = backtrack(mfe,seq);
696                         _cache = seq;
697                 }
698                 return _cacheStructs;
699         }
700
701         public VARNAPanel get_varnaPanel() {
702                 return _vpMaster;
703         }
704
705         public void set_varnaPanel(VARNAPanel surface) {
706                 _vpMaster = surface;
707         }
708
709
710         public JLabel get_info() {
711                 return _actions;
712         }
713
714         public void set_info(JLabel _info) {
715                 this._actions = _info;
716         }
717
718         public static void main(String[] args) {
719                 NussinovDesignDemo d = new NussinovDesignDemo();
720                 d.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
721                 d.pack();
722                 d.setVisible(true);
723         }
724
725         public void onStructureRedrawn() {
726                 _vpMaster.repaint();
727         }
728
729         public void onWarningEmitted(String s) {
730                 // TODO Auto-generated method stub
731                 
732         }
733
734         public void onLoad(String path) {
735                 // TODO Auto-generated method stub
736                 
737         }
738
739         public void onLoaded() {
740                 // TODO Auto-generated method stub
741                 
742         }
743
744         public void onUINewStructure(VARNAConfig v, RNA r) {
745                 // TODO Auto-generated method stub
746                 
747         }
748
749         static final String[] _bases =     {"A","C","G","U"};
750         static final String[] _basesComp = {"U","G","C","A"};
751         
752         public void onBaseClicked(ModeleBase mb, MouseEvent e) {
753                 int index = -1;
754                 for(int i =0;i<_bases.length;i++)
755                 {
756                         if (mb.getContent().equalsIgnoreCase(_bases[i]))
757                         {
758                                 index = i;
759                         }
760                 }
761                 index = (index+1)%_bases.length;
762                 mb.setContent(_bases[index].toUpperCase());
763                 ArrayList<ModeleBase> partners =_vpTarget.getRNA().getAllPartners(mb.getIndex());
764                 if (partners.size()!=0)
765                 {
766                         ModeleBase mbPartner = _vpMaster.getRNA().getBaseAt(partners.get(0).getIndex());
767                         mbPartner.setContent(_basesComp[index].toUpperCase());
768                 }
769                 _vpMaster.repaint();
770                 _seq1.setText(_vpMaster.getRNA().getSeq());
771                 new Temporizer(_vpMaster.getRNA().getSeq()).start();
772         }
773         
774         private class Temporizer extends Thread{
775                 String _seq;
776                 public Temporizer(String seq)
777                 {
778                         _seq = seq;
779                 }
780                 public void run() {
781             try {
782                                 this.sleep(1000);
783                                 if (_vpMaster.getRNA().getSeq().equalsIgnoreCase(_seq))
784                                 {
785                                         showSolution();
786                                 }
787                         } catch (InterruptedException e) {
788                                 // TODO Auto-generated catch block
789                                 e.printStackTrace();
790                         }
791         }
792         }
793         public void onZoomLevelChanged() {
794                 // TODO Auto-generated method stub
795                 
796         }
797
798         public void onTranslationChanged() {
799                 // TODO Auto-generated method stub
800                 
801         }
802
803         public void itemStateChanged(ItemEvent arg0) {
804                 // TODO Auto-generated method stub
805                 System.out.println();
806         }
807
808         
809         public static void formatLabel(JLabel j)
810         {
811                 j.setHorizontalTextPosition(JLabel.LEFT);
812                 j.setPreferredSize(new Dimension(NussinovDemo.marginTools, 25));
813                 j.setFont(labelsFont);
814                 j.setForeground(Color.white);
815         }
816         
817         public static void formatLabel(JTextArea j)
818         {
819                 j.setPreferredSize(new Dimension(NussinovDemo.marginTools, 25));
820                 j.setFont(labelsFont);
821                 j.setForeground(Color.white);
822         }
823
824         public class InfoPanel extends JPanel
825         {
826                 ArrayList<String> _sols = new ArrayList<String>();
827                 BigInteger _nbFolds = BigInteger.ZERO;
828                 JLabel _text = new JLabel("");
829                 JLabel _subopts = new JLabel("");
830                 JPanel _suboptBrowser = new JPanel();
831                 JPanel _suboptCount = new JPanel();
832                 int _selectedIndex = 0;
833                 JButton next = new JButton(">");
834                 JButton previous = new JButton("<");
835                 
836                 InfoPanel()
837                 {
838                         this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
839                         setLayout(new BorderLayout());
840                         add(_suboptBrowser,BorderLayout.SOUTH);
841                         add(_suboptCount,BorderLayout.NORTH);
842                         
843                         next.addActionListener(new ActionListener(){
844                                 public void actionPerformed(ActionEvent arg0) {
845                                         if (_sols.size()>0)
846                                         {
847                                                 setSelectedIndex((_selectedIndex+1)%_sols.size());
848                                         }
849                                 }                               
850                         });
851
852                         previous.addActionListener(new ActionListener(){
853                                 public void actionPerformed(ActionEvent arg0) {
854                                         if (_sols.size()>0)
855                                         {
856                                                 setSelectedIndex((_selectedIndex+_sols.size()-1)%_sols.size());
857                                         }
858                                 }                               
859                         });
860                         next.setEnabled(false);
861                         previous.setEnabled(false);
862
863                         JLabel nbLab = new JLabel("#Repliements");
864                         NussinovDesignDemo.formatLabel(nbLab);
865                         
866
867                         JLabel cooptlab = new JLabel("#Co-optimaux");
868                         NussinovDesignDemo.formatLabel(cooptlab);
869                         
870                         NussinovDesignDemo.formatLabel(_text);
871                         NussinovDesignDemo.formatLabel(_subopts);
872
873                         
874                         _suboptCount.setLayout(new BorderLayout());
875                         _suboptCount.add(nbLab,BorderLayout.WEST);
876                         _suboptCount.add(_text,BorderLayout.CENTER);
877                         _suboptCount.setBackground(Color.decode("#E33729"));
878
879                         
880                         JPanel commands = new JPanel();
881                         commands.add(previous);
882                         commands.add(next);
883                         commands.setBackground(Color.decode("#E33729"));
884                         
885                         JPanel jp = new JPanel();
886                         jp.setLayout(new BorderLayout());
887                         jp.add(_subopts,BorderLayout.WEST);
888                         jp.add(commands,BorderLayout.CENTER);
889                         jp.setBackground(Color.decode("#E33729"));
890
891                         _suboptBrowser.setLayout(new BorderLayout());
892                         _suboptBrowser.add(cooptlab,BorderLayout.WEST);
893                         _suboptBrowser.add(jp,BorderLayout.CENTER);
894                         _suboptBrowser.setBackground(Color.decode("#E33729"));
895                         
896                 }
897                         
898                                 
899                 /*public void setSelectedIndex(int i)
900                 {
901                         _selectedIndex = i;
902                         RNA rfolded = new RNA();
903                         try {
904                                 rfolded.setRNA(getSeq(), _sols.get(i));
905                                 rfolded.drawRNARadiate(_vpMaster.getConfig());
906                         _vpMaster.showRNAInterpolated(rfolded);
907                         } catch (ExceptionUnmatchedClosingParentheses e) {
908                                 // TODO Auto-generated catch block
909                                 e.printStackTrace();
910                         } catch (ExceptionFileFormatOrSyntax e) {
911                                 // TODO Auto-generated catch block
912                                 e.printStackTrace();
913                         }
914                         //_struct.setText(_sols.get(i));
915                         formatDescription();
916                 }*/
917                 
918                 public void setSelectedIndex(int i)
919                 {
920                         _selectedIndex = i;
921                         RNA rfolded = new RNA();
922                         try {
923                                 rfolded.setRNA(getSeq(), _sols.get(i));
924                                 RNA target = _vpTarget.getRNA();
925                                 for(ModeleBase mb: rfolded.get_listeBases())
926                                 {
927                                         ModeleBase mbref = target.getBaseAt(mb.getIndex());
928                                         if (mb.getElementStructure()==mbref.getElementStructure())
929                                         {
930                                                 mb.getStyleBase().setBaseInnerColor(_okColor);
931                                                 mb.getStyleBase().setBaseNameColor(Color.white);
932                                         }
933                                 }                               
934                                 for(ModeleBase mb: target.get_listeBases())
935                                 {
936                                         ModeleBase mbref = rfolded.getBaseAt(mb.getIndex());
937                                         if (mb.getElementStructure()==mbref.getElementStructure())
938                                         {
939                                                 mb.getStyleBase().setBaseInnerColor(_okColor);
940                                         }
941                                         else
942                                         {
943                                                 mb.getStyleBase().setBaseInnerColor(Color.white);
944                                         }
945                                 }                               
946                                 rfolded.drawRNARadiate(_vpMaster.getConfig());
947                                 if ((_sols.size()==1)&& (target.getStructDBN().equals(_sols.get(0))))                                   
948                                         rfolded.setName("Félicitations !");
949                                 else
950                                         rfolded.setName("Repliement stable - "+(i+1)+"/"+_sols.size());
951                         _vpMaster.showRNAInterpolated(rfolded);
952                         _vpTarget.repaint();
953                         } catch (ExceptionUnmatchedClosingParentheses e) {
954                                 // TODO Auto-generated catch block
955                                 e.printStackTrace();
956                         } catch (ExceptionFileFormatOrSyntax e) {
957                                 // TODO Auto-generated catch block
958                                 e.printStackTrace();
959                         }
960                         //_struct.setSelectedItem(_sols.get(i));
961                         formatDescription();
962                 }
963                 
964 //              public void setFont(Font f)
965 //              {
966 //                      super.setFont(f);
967 //                      if(_text!=null)
968 //                      {
969 //                              _text.setFont(f);
970 //                              _text.setOpaque(false);
971 //                      }
972 //                      if(_subopts!=null)
973 //                      {
974 //                      _subopts.setFont(f);
975 //                      _subopts.setOpaque(false);
976 //                      }
977 //              }
978                 public void setInfo(ArrayList<String> sols, BigInteger nbFolds)
979                 {
980                         _sols = sols;
981                         _nbFolds = nbFolds;
982                         formatDescription();
983                         setSelectedIndex(0);
984                 }
985                 
986                 private void formatDescription()
987                 {
988                         _text.setText(""+_nbFolds);
989                         _subopts.setText(""+_sols.size());
990                         next.setEnabled(_sols.size()>1);
991                         previous.setEnabled(_sols.size()>1);
992                         
993                 }
994                 
995         }
996
997 }