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
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.
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.
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.
18 package fr.orsay.lri.varna.applications;
20 import java.awt.BorderLayout;
21 import java.awt.Color;
22 import java.awt.Dimension;
24 import java.awt.GridLayout;
25 import java.awt.event.ActionEvent;
26 import java.awt.event.ActionListener;
27 import java.awt.event.MouseEvent;
28 import java.math.BigInteger;
29 import java.util.ArrayList;
30 import java.util.Collections;
32 import javax.swing.BorderFactory;
33 import javax.swing.DefaultComboBoxModel;
34 import javax.swing.JButton;
35 import javax.swing.JComboBox;
36 import javax.swing.JFrame;
37 import javax.swing.JLabel;
38 import javax.swing.JPanel;
39 import javax.swing.JTextArea;
40 import javax.swing.JTextField;
41 import javax.swing.JTextPane;
42 import javax.swing.border.BevelBorder;
44 import fr.orsay.lri.varna.VARNAPanel;
45 import fr.orsay.lri.varna.controlers.ControleurInterpolator;
46 import fr.orsay.lri.varna.exceptions.ExceptionDrawingAlgorithm;
47 import fr.orsay.lri.varna.exceptions.ExceptionFileFormatOrSyntax;
48 import fr.orsay.lri.varna.exceptions.ExceptionModeleStyleBaseSyntaxError;
49 import fr.orsay.lri.varna.exceptions.ExceptionNAViewAlgorithm;
50 import fr.orsay.lri.varna.exceptions.ExceptionNonEqualLength;
51 import fr.orsay.lri.varna.exceptions.ExceptionParameterError;
52 import fr.orsay.lri.varna.exceptions.ExceptionUnmatchedClosingParentheses;
53 import fr.orsay.lri.varna.exceptions.MappingException;
54 import fr.orsay.lri.varna.models.VARNAConfig;
55 import fr.orsay.lri.varna.models.VARNAConfig.BP_STYLE;
56 import fr.orsay.lri.varna.models.rna.Mapping;
57 import fr.orsay.lri.varna.models.rna.ModeleBase;
58 import fr.orsay.lri.varna.models.rna.ModelBaseStyle;
59 import fr.orsay.lri.varna.models.rna.RNA;
60 import fr.orsay.lri.varna.interfaces.InterfaceVARNABasesListener;
61 import fr.orsay.lri.varna.interfaces.InterfaceVARNAListener;;
63 public class NussinovDemo extends JFrame implements InterfaceVARNAListener,InterfaceVARNABasesListener {
68 private static final long serialVersionUID = -790155708306987257L;
70 private static final String SEQUENCE_DUMMY = "AAAAAAAAAA";
71 private static final String SEQUENCE_A = "AGGCACGUCU";
72 private static final String SEQUENCE_B = "GAGUAGCCUC";
73 private static final String SEQUENCE_C = "GCAUAGCUGC";
74 private static final String SEQUENCE_INRIA = "GAGAAGUACUUGAAAUUGGCCUCCUC";
77 private static final String SEQUENCE_BIG = "AAAACAAAAACACCAUGGUGUUUUCACCCAAUUGGGUGAAAACAGAGAUCUCGAGAUCUCUGUUUUUGUUUU";
79 private static final String DEFAULT_STRUCTURE = "..........";
80 // private static final String DEFAULT_STRUCTURE1 = "((((....))))";
81 // private static final String DEFAULT_STRUCTURE2 =
82 // "((((..(((....)))..))))";
84 private VARNAPanel _vpMaster;
86 private InfoPanel _infos = new InfoPanel();
87 private JPanel _tools = new JPanel();
88 private JPanel _input = new JPanel();
90 private JPanel _seqPanel = new JPanel();
91 private JPanel _structPanel = new JPanel();
92 private JLabel _actions = new JLabel();
93 private JLabel _struct = new JLabel(DEFAULT_STRUCTURE);
94 private JComboBox _seq1 = new JComboBox();
95 private JLabel _structLabel = new JLabel("Structure Secondaire");
96 private JLabel _seqLabel = new JLabel("Sequence d'ARN");
97 private JButton _goButton = new JButton("Repliement");
98 private JButton _switchButton = new JButton("Effacer");
101 private Color _backgroundColor = Color.white;
103 public static Font textFieldsFont = Font.decode("MonoSpaced-BOLD-16");
104 public static Font labelsFont = Font.decode("SansSerif-BOLD-20");
105 public static final int marginTools = 250;
106 public static String APP_TITLE = "FĂȘte de la science 2015 - Inria AMIB - Repliement d'ARN";
109 public static ModelBaseStyle createStyle(String txt)
111 ModelBaseStyle result = new ModelBaseStyle();
113 result.assignParameters(txt);
114 } catch (ExceptionModeleStyleBaseSyntaxError e) {
115 // TODO Auto-generated catch block
117 } catch (ExceptionParameterError e) {
118 // TODO Auto-generated catch block
124 public void applyTo(VARNAPanel vp, ModelBaseStyle mb, int[] indices)
126 for(int i=0;i<indices.length;i++)
128 ModeleBase m = vp.getRNA().getBaseAt(indices[i]);
130 if (m.getElementStructure()!=-1)
132 vp.getRNA().getBaseAt(m.getElementStructure()).setStyleBase(mb);
139 public NussinovDemo() {
142 _vpMaster = new VARNAPanel(getSeq(), "");
143 } catch (ExceptionNonEqualLength e) {
144 _vpMaster.errorDialog(e);
146 _vpMaster.setPreferredSize(new Dimension(600, 600));
150 public static void formatLabel(JLabel j)
152 j.setHorizontalTextPosition(JLabel.LEFT);
153 j.setPreferredSize(new Dimension(marginTools, 15));
154 j.setFont(labelsFont);
157 private void RNAPanelDemoInit() {
161 _seq1.setFont(textFieldsFont);
162 String[] seqs = {SEQUENCE_DUMMY,SEQUENCE_INRIA,SEQUENCE_A,SEQUENCE_B,SEQUENCE_C,SEQUENCE_BIG};
163 _seq1.setModel(new DefaultComboBoxModel(seqs));
164 _seq1.setEditable(true);
167 setBackground(_backgroundColor);
168 _vpMaster.setBackground(_backgroundColor);
169 _vpMaster.addVARNAListener(this);
170 _vpMaster.setFlatExteriorLoop(true);
174 formatLabel(_seqLabel);
175 formatLabel(_structLabel);
177 _goButton.addActionListener(new ActionListener() {
178 public void actionPerformed(ActionEvent e) {
180 onStructureRedrawn();
184 _switchButton.addActionListener(new ActionListener() {
185 public void actionPerformed(ActionEvent e) {
190 _vpMaster.setTitle("");
191 _vpMaster.showRNA(r);
192 onStructureRedrawn();
194 catch (ExceptionFileFormatOrSyntax e2) {
195 e2.printStackTrace();
196 } catch (ExceptionUnmatchedClosingParentheses e2) {
197 // TODO Auto-generated catch block
198 e2.printStackTrace();
204 _seqPanel.setLayout(new BorderLayout());
205 _seqPanel.add(_seqLabel, BorderLayout.WEST);
206 _seqPanel.add(_seq1, BorderLayout.CENTER);
208 _structLabel.setPreferredSize(new Dimension(marginTools, 15));
209 _structLabel.setHorizontalTextPosition(JLabel.LEFT);
210 _struct.setFont(textFieldsFont);
211 _structPanel.setLayout(new BorderLayout());
212 _structPanel.add(_structLabel, BorderLayout.WEST);
213 _structPanel.add(_struct, BorderLayout.CENTER);
215 _input.setLayout(new GridLayout(0, 1));
216 _input.add(_seqPanel);
217 _input.add(_structPanel);
219 JPanel goPanel = new JPanel();
220 goPanel.setLayout(new BorderLayout());
222 _infos.setFont(labelsFont);
225 _tools.setLayout(new BorderLayout());
226 _tools.add(_infos, BorderLayout.SOUTH);
227 _tools.add(_input, BorderLayout.CENTER);
228 _tools.add(_actions, BorderLayout.NORTH);
229 _tools.add(goPanel, BorderLayout.EAST);
230 _tools.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
232 goPanel.add(_goButton, BorderLayout.CENTER);
233 goPanel.add(_switchButton, BorderLayout.SOUTH);
235 getContentPane().setLayout(new BorderLayout());
236 JPanel VARNAs = new JPanel();
237 VARNAs.setLayout(new GridLayout(1,2));
238 VARNAs.add(_vpMaster);
239 VARNAs.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
240 getContentPane().add(VARNAs, BorderLayout.CENTER);
241 getContentPane().add(_tools, BorderLayout.SOUTH);
245 _vpMaster.getVARNAUI().UIRadiate();
246 _vpMaster.setTitleFontSize(26f);
247 _vpMaster.setTitleFontStyle(Font.PLAIN);
248 _vpMaster.addVARNABasesListener(this);
249 _vpMaster.setBackground(Color.decode("#308099"));
250 _vpMaster.setModifiable(false);
251 _vpMaster.setTitle("Repliement cible");
252 _vpMaster.setBPStyle(BP_STYLE.SIMPLE);
253 _vpMaster.setBackboneColor(Color.white);
254 _vpMaster.setDefaultBPColor(Color.white);
255 _vpMaster.setBaseNumbersColor(Color.white);
256 _vpMaster.setBaseOutlineColor(Color.white);
257 _vpMaster.setTitleColor(Color.white);
258 _vpMaster.setTitleFontSize(26f);
262 this.setTitle(APP_TITLE);
265 onStructureRedrawn();
268 private synchronized void showSolution()
270 ArrayList<String> sols = getStructs();
271 _infos.setInfo(sols, count(getSeq()));
277 public String getSeq()
279 return (""+_seq1.getSelectedItem()).toUpperCase();
283 private boolean canBasePairAll(char a, char b)
288 private boolean canBasePairBasic(char a, char b)
290 if ((a=='G')&&(b=='C'))
292 if ((a=='C')&&(b=='G'))
294 if ((a=='U')&&(b=='A'))
296 if ((a=='A')&&(b=='U'))
298 if ((a=='G')&&(b=='U'))
300 if ((a=='U')&&(b=='G'))
305 private double basePairScoreBasic(char a, char b)
307 if ((a=='G')&&(b=='C'))
309 if ((a=='C')&&(b=='G'))
311 if ((a=='U')&&(b=='A'))
313 if ((a=='A')&&(b=='U'))
315 if ((a=='G')&&(b=='U'))
317 if ((a=='U')&&(b=='G'))
319 return Double.NEGATIVE_INFINITY;
323 private boolean canBasePairNussinov(char a, char b)
325 if ((a=='G')&&(b=='C'))
327 if ((a=='C')&&(b=='G'))
329 if ((a=='U')&&(b=='A'))
331 if ((a=='A')&&(b=='U'))
333 if ((a=='U')&&(b=='G'))
335 if ((a=='G')&&(b=='U'))
340 private double basePairScoreNussinov(char a, char b)
342 if ((a=='G')&&(b=='C'))
344 if ((a=='C')&&(b=='G'))
346 if ((a=='U')&&(b=='A'))
348 if ((a=='A')&&(b=='U'))
350 if ((a=='U')&&(b=='G'))
352 if ((a=='G')&&(b=='U'))
354 return Double.NEGATIVE_INFINITY;
357 private boolean canBasePairINRIA(char a, char b)
359 if ((a=='U')&&(b=='A'))
361 if ((a=='A')&&(b=='U'))
363 if ((a=='G')&&(b=='C'))
365 if ((a=='C')&&(b=='G'))
368 if ((a=='A')&&(b=='G'))
370 if ((a=='G')&&(b=='A'))
372 if ((a=='U')&&(b=='C'))
374 if ((a=='C')&&(b=='U'))
376 if ((a=='A')&&(b=='A'))
378 if ((a=='U')&&(b=='U'))
381 if ((a=='U')&&(b=='G'))
383 if ((a=='G')&&(b=='U'))
385 if ((a=='A')&&(b=='C'))
387 if ((a=='C')&&(b=='A'))
392 private double basePairScoreINRIA(char a, char b)
394 if ((a=='U')&&(b=='A'))
396 if ((a=='A')&&(b=='U'))
398 if ((a=='G')&&(b=='C'))
400 if ((a=='C')&&(b=='G'))
403 if ((a=='A')&&(b=='G'))
405 if ((a=='G')&&(b=='A'))
407 if ((a=='U')&&(b=='C'))
409 if ((a=='C')&&(b=='U'))
411 if ((a=='A')&&(b=='A'))
413 if ((a=='U')&&(b=='U'))
416 if ((a=='U')&&(b=='G'))
418 if ((a=='G')&&(b=='U'))
420 if ((a=='A')&&(b=='C'))
422 if ((a=='C')&&(b=='A'))
424 return Double.NEGATIVE_INFINITY;
427 private boolean canBasePair(char a, char b)
429 return canBasePairBasic(a,b);
430 //return canBasePairNussinov(a,b);
431 //return canBasePairINRIA(a,b);
434 private double basePairScore(char a, char b)
436 return basePairScoreBasic(a,b);
437 //return basePairScoreNussinov(a,b);
438 //return basePairScoreINRIA(a,b);
441 public double[][] fillMatrix(String seq)
443 int n = seq.length();
444 double[][] tab = new double[n][n];
445 for(int m=1;m<=n;m++)
447 for(int i=0;i<n-m+1;i++)
453 tab[i][j] = Math.max(tab[i][j], tab[i+1][j]);
454 for (int k=i+1;k<=j;k++)
456 if (canBasePair(seq.charAt(i),seq.charAt(k)))
461 fact1 = tab[i+1][k-1];
468 tab[i][j] = Math.max(tab[i][j],basePairScore(seq.charAt(i),seq.charAt(k))+fact1+fact2);
477 public static ArrayList<Double> combine(double bonus, ArrayList<Double> part1, ArrayList<Double> part2)
479 ArrayList<Double> base = new ArrayList<Double>();
480 for(double d1: part1)
482 for(double d2: part2)
484 base.add(bonus+d1+d2);
490 public static ArrayList<Double> selectBests(ArrayList<Double> base)
492 ArrayList<Double> result = new ArrayList<Double>();
493 double best = Double.NEGATIVE_INFINITY;
494 for(double val: base)
496 best = Math.max(val, best);
498 for(double val: base)
507 private ArrayList<String> backtrack(double[][] tab, String seq)
509 return backtrack(tab,seq, 0, seq.length()-1);
512 private ArrayList<String> backtrack(double[][] tab, String seq, int i, int j)
514 ArrayList<String> result = new ArrayList<String>();
517 ArrayList<Integer> indices = new ArrayList<Integer>();
519 for (int k=i+1;k<=j;k++)
523 for (int k : indices)
527 if (tab[i][j] == tab[i+1][j])
529 for (String s:backtrack(tab, seq, i+1,j))
537 if (canBasePair(seq.charAt(i),seq.charAt(k)))
542 fact1 = tab[i+1][k-1];
549 if (tab[i][j]==basePairScore(seq.charAt(i),seq.charAt(k))+fact1+fact2)
551 for (String s1:backtrack(tab, seq, i+1,k-1))
553 for (String s2:backtrack(tab, seq, k+1,j))
555 result.add("("+s1+")"+s2);
574 public BigInteger count(String seq)
576 int n = seq.length();
578 BigInteger[][] tab = new BigInteger[n][n];
579 for(int m=1;m<=n;m++)
581 for(int i=0;i<n-m+1;i++)
584 tab[i][j] = BigInteger.ZERO;
587 tab[i][j] = tab[i][j].add(tab[i+1][j]);
588 for (int k=i+1;k<=j;k++)
590 if (canBasePair(seq.charAt(i),seq.charAt(k)))
592 BigInteger fact1 = BigInteger.ONE;
595 fact1 = tab[i+1][k-1];
597 BigInteger fact2 = BigInteger.ONE;
602 tab[i][j] = tab[i][j].add(fact1.multiply(fact2));
608 tab[i][j] = BigInteger.ONE;
615 private String _cache = "";
616 ArrayList<String> _cacheStructs = new ArrayList<String>();
618 public ArrayList<String> getStructs() {
619 String seq = getSeq();
620 seq = seq.toUpperCase();
621 if (!_cache.equals(seq))
623 double[][] mfe = fillMatrix(seq);
624 _cacheStructs = backtrack(mfe,seq);
627 return _cacheStructs;
630 public VARNAPanel get_varnaPanel() {
634 public void set_varnaPanel(VARNAPanel surface) {
639 public JLabel get_info() {
643 public void set_info(JLabel _info) {
644 this._actions = _info;
647 public static void main(String[] args) {
648 NussinovDemo d = new NussinovDemo();
649 d.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
654 public void onStructureRedrawn() {
658 public void onWarningEmitted(String s) {
659 // TODO Auto-generated method stub
663 public void onLoad(String path) {
664 // TODO Auto-generated method stub
668 public void onLoaded() {
669 // TODO Auto-generated method stub
673 public void onUINewStructure(VARNAConfig v, RNA r) {
674 // TODO Auto-generated method stub
678 static final String[] _bases = {"A","C","G","U"};
679 static final String[] _basesComp = {"U","G","C","A"};
681 public void onBaseClicked(ModeleBase mb, MouseEvent e) {
684 public void onZoomLevelChanged() {
685 // TODO Auto-generated method stub
689 public void onTranslationChanged() {
690 // TODO Auto-generated method stub
693 private class InfoPanel extends JPanel
695 ArrayList<String> _sols = new ArrayList<String>();
696 BigInteger _nbFolds = BigInteger.ZERO;
697 JTextArea _text = new JTextArea("");
698 JTextArea _subopts = new JTextArea("");
699 JPanel _suboptBrowser = new JPanel();
700 JPanel _suboptCount = new JPanel();
701 int _selectedIndex = 0;
702 JButton next = new JButton(">");
703 JButton previous = new JButton("<");
707 setLayout(new BorderLayout());
708 add(_suboptBrowser,BorderLayout.SOUTH);
709 add(_suboptCount,BorderLayout.NORTH);
711 next.addActionListener(new ActionListener(){
712 public void actionPerformed(ActionEvent arg0) {
715 setSelectedIndex((_selectedIndex+1)%_sols.size());
720 previous.addActionListener(new ActionListener(){
721 public void actionPerformed(ActionEvent arg0) {
724 setSelectedIndex((_selectedIndex+_sols.size()-1)%_sols.size());
728 next.setEnabled(false);
729 previous.setEnabled(false);
732 JLabel nbLab = new JLabel("#Repliements");
733 NussinovDemo.formatLabel(nbLab);
735 _suboptCount.setLayout(new BorderLayout());
736 _suboptCount.add(nbLab,BorderLayout.WEST);
737 _suboptCount.add(_text,BorderLayout.CENTER);
739 JLabel cooptlab = new JLabel("#Co-optimaux");
740 NussinovDemo.formatLabel(cooptlab);
742 JPanel commands = new JPanel();
743 commands.add(previous);
746 JPanel jp = new JPanel();
747 jp.setLayout(new BorderLayout());
748 jp.add(_subopts,BorderLayout.WEST);
749 jp.add(commands,BorderLayout.CENTER);
751 _suboptBrowser.setLayout(new BorderLayout());
752 _suboptBrowser.add(cooptlab,BorderLayout.WEST);
753 _suboptBrowser.add(jp,BorderLayout.CENTER);
759 public void setSelectedIndex(int i)
762 RNA rfolded = new RNA();
764 rfolded.setRNA(getSeq(), _sols.get(i));
765 rfolded.drawRNARadiate(_vpMaster.getConfig());
766 rfolded.setBaseNameColor(Color.white);
767 rfolded.setBaseOutlineColor(Color.white);
768 rfolded.setBaseNumbersColor(Color.white);
769 _vpMaster.setBaseNumbersColor(Color.white);
770 _vpMaster.setBaseOutlineColor(Color.white);
771 _vpMaster.setFillBases(false);
772 _vpMaster.setBaseNameColor(Color.white);
773 _vpMaster.showRNAInterpolated(rfolded);
775 } catch (ExceptionUnmatchedClosingParentheses e) {
776 // TODO Auto-generated catch block
778 } catch (ExceptionFileFormatOrSyntax e) {
779 // TODO Auto-generated catch block
782 _struct.setText(_sols.get(i));
786 public void setFont(Font f)
792 _text.setOpaque(false);
797 _subopts.setOpaque(false);
800 public void setInfo(ArrayList<String> sols, BigInteger nbFolds)
808 private void formatDescription()
810 _text.setText(""+_nbFolds);
811 _subopts.setText(""+_sols.size());
812 next.setEnabled(_sols.size()>1);
813 previous.setEnabled(_sols.size()>1);