/*
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.
Copyright (C) 2008 Kevin Darty, Alain Denise and Yann Ponty.
electronic mail : Yann.Ponty@lri.fr
paper mail : LRI, bat 490 University Paris-Sud 91405 Orsay Cedex France
This file is part of VARNA version 3.1.
VARNA version 3.1 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
VARNA version 3.1 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with VARNA version 3.1.
If not, see http://www.gnu.org/licenses.
*/
package fr.orsay.lri.varna.applications;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import fr.orsay.lri.varna.VARNAPanel;
import fr.orsay.lri.varna.controlers.ControleurInterpolator;
import fr.orsay.lri.varna.exceptions.ExceptionDrawingAlgorithm;
import fr.orsay.lri.varna.exceptions.ExceptionFileFormatOrSyntax;
import fr.orsay.lri.varna.exceptions.ExceptionModeleStyleBaseSyntaxError;
import fr.orsay.lri.varna.exceptions.ExceptionNAViewAlgorithm;
import fr.orsay.lri.varna.exceptions.ExceptionNonEqualLength;
import fr.orsay.lri.varna.exceptions.ExceptionParameterError;
import fr.orsay.lri.varna.exceptions.ExceptionUnmatchedClosingParentheses;
import fr.orsay.lri.varna.exceptions.MappingException;
import fr.orsay.lri.varna.models.VARNAConfig;
import fr.orsay.lri.varna.models.rna.Mapping;
import fr.orsay.lri.varna.models.rna.ModeleBase;
import fr.orsay.lri.varna.models.rna.ModeleStyleBase;
import fr.orsay.lri.varna.models.rna.RNA;
import fr.orsay.lri.varna.interfaces.InterfaceVARNAListener;;
public class NussinovDemo extends JFrame implements InterfaceVARNAListener {
/**
*
*/
private static final long serialVersionUID = -790155708306987257L;
private static final String SEQUENCE_A = "AGGCACGUCU";
private static final String SEQUENCE_B = "GAGUAGCCUC";
private static final String SEQUENCE_C = "GCAUAGCUGC";
private static final String SEQUENCE_BIG = "AAAACAAAAACACCAUGGUGUUUUCACCCAAUUGGGUGAAAACAGAGAUCUCGAGAUCUCUGUUUUUGUUUU";
private static final String DEFAULT_STRUCTURE = "..........";
// private static final String DEFAULT_STRUCTURE1 = "((((....))))";
// private static final String DEFAULT_STRUCTURE2 =
// "((((..(((....)))..))))";
private VARNAPanel _vpMaster;
private JPanel _tools = new JPanel();
private JPanel _input = new JPanel();
private JPanel _seqPanel = new JPanel();
private JPanel _structPanel = new JPanel();
private JLabel _info = new JLabel();
private JLabel _struct = new JLabel(DEFAULT_STRUCTURE);
private JComboBox _seq1 = new JComboBox();
private JLabel _structLabel = new JLabel("Predicted Secondary Structure");
private JLabel _seqLabel = new JLabel("RNA sequence");
private JButton _goButton = new JButton("Fold");
private JButton _switchButton = new JButton("Reset");
private static String errorOpt = "error";
@SuppressWarnings("unused")
private boolean _error;
private Color _backgroundColor = Color.white;
@SuppressWarnings("unused")
private int _algoCode;
public static ModeleStyleBase createStyle(String txt)
{
ModeleStyleBase result = new ModeleStyleBase();
try {
result.assignParameters(txt);
} catch (ExceptionModeleStyleBaseSyntaxError e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExceptionParameterError e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
public void applyTo(VARNAPanel vp, ModeleStyleBase mb, int[] indices)
{
for(int i=0;i<indices.length;i++)
{
ModeleBase m = vp.getRNA().getBaseAt(indices[i]);
m.setStyleBase(mb);
if (m.getElementStructure()!=-1)
{
vp.getRNA().getBaseAt(m.getElementStructure()).setStyleBase(mb);
}
}
vp.repaint();
}
public NussinovDemo() {
super();
try {
_vpMaster = new VARNAPanel(getSeq(), "");
} catch (ExceptionNonEqualLength e) {
_vpMaster.errorDialog(e);
}
_vpMaster.setPreferredSize(new Dimension(600, 600));
RNAPanelDemoInit();
}
private void RNAPanelDemoInit() {
int marginTools = 250;
Font textFieldsFont = Font.decode("MonoSpaced-BOLD-16");
Font labelsFont = _seqLabel.getFont().deriveFont(16f);
_seq1.setFont(textFieldsFont);
String[] seqs = {SEQUENCE_A,SEQUENCE_B,SEQUENCE_C,SEQUENCE_BIG};
_seq1.setModel(new DefaultComboBoxModel(seqs));
_seq1.setEditable(true);
setBackground(_backgroundColor);
_vpMaster.setBackground(_backgroundColor);
_vpMaster.addVARNAListener(this);
//_vpSlave.setModifiable(false);
_seqLabel.setHorizontalTextPosition(JLabel.LEFT);
_seqLabel.setPreferredSize(new Dimension(marginTools, 15));
_seqLabel.setFont(labelsFont);
_structLabel.setFont(labelsFont);
_goButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showSolution();
onStructureRedrawn();
}
});
_switchButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
RNA r = new RNA();
r.setRNA("", "");
_struct.setText("");
_vpMaster.setTitle("");
_vpMaster.showRNA(r);
onStructureRedrawn();
}
catch (ExceptionFileFormatOrSyntax e2) {
e2.printStackTrace();
} catch (ExceptionUnmatchedClosingParentheses e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
_vpMaster.repaint();
}
});
_seqPanel.setLayout(new BorderLayout());
_seqPanel.add(_seqLabel, BorderLayout.WEST);
_seqPanel.add(_seq1, BorderLayout.CENTER);
_structLabel.setPreferredSize(new Dimension(marginTools, 15));
_structLabel.setHorizontalTextPosition(JLabel.LEFT);
_struct.setFont(textFieldsFont);
_structPanel.setLayout(new BorderLayout());
_structPanel.add(_structLabel, BorderLayout.WEST);
_structPanel.add(_struct, BorderLayout.CENTER);
_input.setLayout(new GridLayout(2, 0));
_input.add(_seqPanel);
_input.add(_structPanel);
JPanel goPanel = new JPanel();
goPanel.setLayout(new BorderLayout());
_tools.setLayout(new BorderLayout());
_tools.add(_input, BorderLayout.CENTER);
_tools.add(_info, BorderLayout.SOUTH);
_tools.add(goPanel, BorderLayout.EAST);
goPanel.add(_goButton, BorderLayout.CENTER);
goPanel.add(_switchButton, BorderLayout.SOUTH);
getContentPane().setLayout(new BorderLayout());
JPanel VARNAs = new JPanel();
VARNAs.setLayout(new GridLayout(1,1));
VARNAs.add(_vpMaster);
getContentPane().add(VARNAs, BorderLayout.CENTER);
getContentPane().add(_tools, BorderLayout.SOUTH);
setVisible(true);
_vpMaster.getVARNAUI().UIRadiate();
_vpMaster.setTitleFontSize(26f);
_vpMaster.setTitleFontStyle(Font.PLAIN);
this.setTitle("RNA Folding Demo - Simple Matching Algorithm");
onStructureRedrawn();
}
private void showSolution()
{
RNA rflat = getRNA();
rflat.drawRNALine();
_vpMaster.setTitle("#Secondary Structures: "+count(getSeq()));
_struct.setText(getStruct());
_vpMaster.drawRNA(rflat);
_vpMaster.showRNAInterpolated(rflat);
RNA rfolded = getRNA();
rfolded.drawRNARadiate(_vpMaster.getConfig());
_vpMaster.showRNAInterpolated(rfolded);
RNA rLinear = getRNA();
rLinear.drawRNALine();
_vpMaster.showRNAInterpolated(rLinear);
}
public RNA getRNA() {
RNA r = new RNA();
try {
r.setRNA(getSeq(), getStruct());
} catch (ExceptionUnmatchedClosingParentheses e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExceptionFileFormatOrSyntax e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return r;
}
public String getSeq()
{
return ""+_seq1.getSelectedItem();
}
private boolean canBasePair(char a, char b)
{
if ((a=='G')&&(b=='C'))
return true;
if ((a=='C')&&(b=='G'))
return true;
if ((a=='U')&&(b=='A'))
return true;
if ((a=='A')&&(b=='U'))
return true;
return false;
}
public int[][] fillMatrix(String seq)
{
int n = seq.length();
int[][] tab = new int[n][n];
for(int m=1;m<=n;m++)
{
for(int i=0;i<n-m+1;i++)
{
int j = i+m-1;
tab[i][j] = 0;
if (i<j)
{
tab[i][j] = Math.max(tab[i][j], tab[i+1][j]);
for (int k=i+1;k<=j;k++)
{
if (canBasePair(seq.charAt(i),seq.charAt(k)))
{
int fact1 = 0;
if (k>i+1)
{
fact1 = tab[i+1][k-1];
}
int fact2 = 0;
if (k<j-1)
{
fact2 = tab[k+1][j];
}
tab[i][j] = Math.max(tab[i][j],1+fact1+fact2);
}
}
}
}
}
return tab;
}
private String backtrack(int[][] tab, String seq)
{
return backtrack(tab,seq, 0, seq.length()-1);
}
private String backtrack(int[][] tab, String seq, int i, int j)
{
if (i<j)
{
if (tab[i][j] == tab[i+1][j])
{
return "."+backtrack(tab, seq, i+1,j);
}
for (int k=i+1;k<=j;k++)
{
if (canBasePair(seq.charAt(i),seq.charAt(k)))
{
int fact1 = 0;
if (k>i+1)
{
fact1 = tab[i+1][k-1];
}
int fact2 = 0;
if (k<j-1)
{
fact2 = tab[k+1][j];
}
if (tab[i][j]==1+fact1+fact2)
{
return "("+backtrack(tab, seq, i+1,k-1)+")"+backtrack(tab, seq, k+1,j);
}
}
}
}
else if (i==j)
{
return ".";
}
return "";
}
public long count(String seq)
{
int n = seq.length();
long[][] tab = new long[n][n];
for(int m=1;m<=n;m++)
{
for(int i=0;i<n-m+1;i++)
{
int j = i+m-1;
tab[i][j] = 0;
if (i<j)
{
tab[i][j] += tab[i+1][j];
for (int k=i+1;k<=j;k++)
{
if (canBasePair(seq.charAt(i),seq.charAt(k)))
{
long fact1 = 1;
if (k>i+1)
{
fact1 = tab[i+1][k-1];
}
long fact2 = 1;
if (k<j-1)
{
fact2 = tab[k+1][j];
}
tab[i][j] += fact1*fact2;
}
}
}
else
{
tab[i][j] = 1;
}
}
}
return tab[0][n-1];
}
public String getStruct() {
String seq = getSeq();
seq = seq.toUpperCase();
int n = seq.length();
int[][] mfe = fillMatrix(seq);
String back = backtrack(mfe,seq);
return back;
}
private String cleanStruct(String struct) {
struct = struct.replaceAll("[:-]", "");
return struct;
}
public void init() {
_vpMaster.setBackground(_backgroundColor);
_error = true;
}
@SuppressWarnings("unused")
private Color getSafeColor(String col, Color def) {
Color result;
try {
result = Color.decode(col);
} catch (Exception e) {
try {
result = Color.getColor(col, def);
} catch (Exception e2) {
return def;
}
}
return result;
}
public VARNAPanel get_varnaPanel() {
return _vpMaster;
}
public void set_varnaPanel(VARNAPanel surface) {
_vpMaster = surface;
}
public JLabel get_info() {
return _info;
}
public void set_info(JLabel _info) {
this._info = _info;
}
public static void main(String[] args) {
NussinovDemo d = new NussinovDemo();
d.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
d.pack();
d.setVisible(true);
}
public void onStructureRedrawn() {
_vpMaster.repaint();
}
public void onWarningEmitted(String s) {
// TODO Auto-generated method stub
}
public void onLoad(String path) {
// TODO Auto-generated method stub
}
public void onLoaded() {
// TODO Auto-generated method stub
}
public void onUINewStructure(VARNAConfig v, RNA r) {
// TODO Auto-generated method stub
}
}