/* 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 Université 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 java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.MouseEvent; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; import javax.swing.BorderFactory; import javax.swing.DefaultComboBoxModel; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JSplitPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.JTextPane; import javax.swing.border.BevelBorder; 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.VARNAConfig.BP_STYLE; import fr.orsay.lri.varna.models.rna.Mapping; import fr.orsay.lri.varna.models.rna.ModeleBP; import fr.orsay.lri.varna.models.rna.ModeleBase; import fr.orsay.lri.varna.models.rna.ModelBaseStyle; import fr.orsay.lri.varna.models.rna.RNA; import fr.orsay.lri.varna.interfaces.InterfaceVARNABasesListener; import fr.orsay.lri.varna.interfaces.InterfaceVARNAListener;; public class NussinovDesignDemo extends JFrame implements InterfaceVARNAListener,InterfaceVARNABasesListener, ItemListener { /** * */ 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_INRIA = "CGAUUGCAUCGCAAGU"; private static final String TARGET_STRUCTURE_1 = "(((((((..)))))))"; private static final String TARGET_STRUCTURE_2 = "(((())))(((())))"; private static final String TARGET_STRUCTURE_3 = "(.((.((..).)).))"; private static final String TARGET_STRUCTURE_4 = "((((((())))(((())(()))))))"; private static final String TARGET_STRUCTURE_5 = "(((())))(((())))(((())))(((())))(((())))(((())))"; 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 VARNAPanel _vpTarget; private InfoPanel _infos = new InfoPanel(); private JPanel _tools = new JPanel(); private JPanel _input = new JPanel(); private JPanel _seqPanel = new JPanel(); private JPanel _structPanel = new JPanel(); private JLabel _actions = new JLabel(); private JComboBox _struct = new JComboBox(); private JLabel _seq1 = new JLabel(); private JLabel _structLabel = new JLabel("Structure Cible"); private JLabel _seqLabel = new JLabel("Sequence d'ARN"); private JButton _switchButton = new JButton("Reset"); private Color _backgroundColor = Color.white; private Color _okColor = Color.decode("#E33729"); private Color _koColor = new Color(250,200,200); public static ModelBaseStyle createStyle(String txt) { ModelBaseStyle result = new ModelBaseStyle(); 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, ModelBaseStyle mb, int[] indices) { for(int i=0;i sols = getStructs(); _infos.setInfo(sols, count(getSeq())); if ((sols.size()==1)&&(sols.get(0).equals(_struct.getSelectedItem().toString()))) { /*JOptionPane.showMessageDialog(null, "Vous avez trouvé une séquence pour cette structure !!!\n Saurez vous faire le design de molécules plus complexes ?", "Félicitations !", JOptionPane.INFORMATION_MESSAGE);*/ } else { this._vpMaster.setTitle("Meilleur repliement - Séquence courante"); } } public void setTarget(String target) { try { _vpTarget.drawRNA(String.format("%"+target.length()+"s", ""),target); _vpTarget.setBaseNumbersColor(Color.white); _vpTarget.setBaseOutlineColor(Color.white); //_vpTarget.toggleDrawOutlineBases(); createDummySeq(); showSolution(); onStructureRedrawn(); } catch (ExceptionNonEqualLength e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void createDummySeq() { RNA r = _vpTarget.getRNA(); String seq = new String(); for (int i=0;ii+1) { fact1 = tab[i+1][k-1]; } double fact2 = 0; if (k combine(double bonus, ArrayList part1, ArrayList part2) { ArrayList base = new ArrayList(); for(double d1: part1) { for(double d2: part2) { base.add(bonus+d1+d2); } } return base; } public static ArrayList selectBests(ArrayList base) { ArrayList result = new ArrayList(); double best = Double.NEGATIVE_INFINITY; for(double val: base) { best = Math.max(val, best); } for(double val: base) { if (val == best) result.add(val); } return result; } private ArrayList backtrack(double[][] tab, String seq) { return backtrack(tab,seq, 0, seq.length()-1); } private ArrayList backtrack(double[][] tab, String seq, int i, int j) { ArrayList result = new ArrayList(); if (i indices = new ArrayList(); indices.add(-1); for (int k=i+1;k<=j;k++) { indices.add(k); } for (int k : indices) { if (k==-1) { if (tab[i][j] == tab[i+1][j]) { for (String s:backtrack(tab, seq, i+1,j)) { result.add("."+s); } } } else { if (canBasePair(seq.charAt(i),seq.charAt(k))) { double fact1 = 0; if (k>i+1) { fact1 = tab[i+1][k-1]; } double fact2 = 0; if (ki+1) { fact1 = tab[i+1][k-1]; } BigInteger fact2 = BigInteger.ONE; if (k _cacheStructs = new ArrayList(); public ArrayList getStructs() { String seq = getSeq(); seq = seq.toUpperCase(); if (!_cache.equals(seq)) { double[][] mfe = fillMatrix(seq); _cacheStructs = backtrack(mfe,seq); _cache = seq; } return _cacheStructs; } public VARNAPanel get_varnaPanel() { return _vpMaster; } public void set_varnaPanel(VARNAPanel surface) { _vpMaster = surface; } public JLabel get_info() { return _actions; } public void set_info(JLabel _info) { this._actions = _info; } public static void main(String[] args) { NussinovDesignDemo d = new NussinovDesignDemo(); 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 } static final String[] _bases = {"A","C","G","U"}; static final String[] _basesComp = {"U","G","C","A"}; public void onBaseClicked(ModeleBase mb, MouseEvent e) { int index = -1; for(int i =0;i<_bases.length;i++) { if (mb.getContent().equalsIgnoreCase(_bases[i])) { index = i; } } index = (index+1)%_bases.length; mb.setContent(_bases[index].toUpperCase()); ArrayList partners =_vpTarget.getRNA().getAllPartners(mb.getIndex()); if (partners.size()!=0) { ModeleBase mbPartner = _vpMaster.getRNA().getBaseAt(partners.get(0).getIndex()); mbPartner.setContent(_basesComp[index].toUpperCase()); } _vpMaster.repaint(); _seq1.setText(_vpMaster.getRNA().getSeq()); new Temporizer(_vpMaster.getRNA().getSeq()).start(); } private class Temporizer extends Thread{ String _seq; public Temporizer(String seq) { _seq = seq; } public void run() { try { this.sleep(1000); if (_vpMaster.getRNA().getSeq().equalsIgnoreCase(_seq)) { showSolution(); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void onZoomLevelChanged() { // TODO Auto-generated method stub } public void onTranslationChanged() { // TODO Auto-generated method stub } public void itemStateChanged(ItemEvent arg0) { // TODO Auto-generated method stub System.out.println(); } public static void formatLabel(JLabel j) { j.setHorizontalTextPosition(JLabel.LEFT); j.setPreferredSize(new Dimension(NussinovDemo.marginTools, 25)); j.setFont(labelsFont); j.setForeground(Color.white); } public static void formatLabel(JTextArea j) { j.setPreferredSize(new Dimension(NussinovDemo.marginTools, 25)); j.setFont(labelsFont); j.setForeground(Color.white); } public class InfoPanel extends JPanel { ArrayList _sols = new ArrayList(); BigInteger _nbFolds = BigInteger.ZERO; JLabel _text = new JLabel(""); JLabel _subopts = new JLabel(""); JPanel _suboptBrowser = new JPanel(); JPanel _suboptCount = new JPanel(); int _selectedIndex = 0; JButton next = new JButton(">"); JButton previous = new JButton("<"); InfoPanel() { this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); setLayout(new BorderLayout()); add(_suboptBrowser,BorderLayout.SOUTH); add(_suboptCount,BorderLayout.NORTH); next.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent arg0) { if (_sols.size()>0) { setSelectedIndex((_selectedIndex+1)%_sols.size()); } } }); previous.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent arg0) { if (_sols.size()>0) { setSelectedIndex((_selectedIndex+_sols.size()-1)%_sols.size()); } } }); next.setEnabled(false); previous.setEnabled(false); JLabel nbLab = new JLabel("#Repliements"); NussinovDesignDemo.formatLabel(nbLab); JLabel cooptlab = new JLabel("#Co-optimaux"); NussinovDesignDemo.formatLabel(cooptlab); NussinovDesignDemo.formatLabel(_text); NussinovDesignDemo.formatLabel(_subopts); _suboptCount.setLayout(new BorderLayout()); _suboptCount.add(nbLab,BorderLayout.WEST); _suboptCount.add(_text,BorderLayout.CENTER); _suboptCount.setBackground(Color.decode("#E33729")); JPanel commands = new JPanel(); commands.add(previous); commands.add(next); commands.setBackground(Color.decode("#E33729")); JPanel jp = new JPanel(); jp.setLayout(new BorderLayout()); jp.add(_subopts,BorderLayout.WEST); jp.add(commands,BorderLayout.CENTER); jp.setBackground(Color.decode("#E33729")); _suboptBrowser.setLayout(new BorderLayout()); _suboptBrowser.add(cooptlab,BorderLayout.WEST); _suboptBrowser.add(jp,BorderLayout.CENTER); _suboptBrowser.setBackground(Color.decode("#E33729")); } /*public void setSelectedIndex(int i) { _selectedIndex = i; RNA rfolded = new RNA(); try { rfolded.setRNA(getSeq(), _sols.get(i)); rfolded.drawRNARadiate(_vpMaster.getConfig()); _vpMaster.showRNAInterpolated(rfolded); } catch (ExceptionUnmatchedClosingParentheses e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExceptionFileFormatOrSyntax e) { // TODO Auto-generated catch block e.printStackTrace(); } //_struct.setText(_sols.get(i)); formatDescription(); }*/ public void setSelectedIndex(int i) { _selectedIndex = i; RNA rfolded = new RNA(); try { rfolded.setRNA(getSeq(), _sols.get(i)); RNA target = _vpTarget.getRNA(); for(ModeleBase mb: rfolded.get_listeBases()) { ModeleBase mbref = target.getBaseAt(mb.getIndex()); if (mb.getElementStructure()==mbref.getElementStructure()) { mb.getStyleBase().setBaseInnerColor(_okColor); mb.getStyleBase().setBaseNameColor(Color.white); } } for(ModeleBase mb: target.get_listeBases()) { ModeleBase mbref = rfolded.getBaseAt(mb.getIndex()); if (mb.getElementStructure()==mbref.getElementStructure()) { mb.getStyleBase().setBaseInnerColor(_okColor); } else { mb.getStyleBase().setBaseInnerColor(Color.white); } } rfolded.drawRNARadiate(_vpMaster.getConfig()); if ((_sols.size()==1)&& (target.getStructDBN().equals(_sols.get(0)))) rfolded.setName("Félicitations !"); else rfolded.setName("Repliement stable - "+(i+1)+"/"+_sols.size()); _vpMaster.showRNAInterpolated(rfolded); _vpTarget.repaint(); } catch (ExceptionUnmatchedClosingParentheses e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExceptionFileFormatOrSyntax e) { // TODO Auto-generated catch block e.printStackTrace(); } //_struct.setSelectedItem(_sols.get(i)); formatDescription(); } // public void setFont(Font f) // { // super.setFont(f); // if(_text!=null) // { // _text.setFont(f); // _text.setOpaque(false); // } // if(_subopts!=null) // { // _subopts.setFont(f); // _subopts.setOpaque(false); // } // } public void setInfo(ArrayList sols, BigInteger nbFolds) { _sols = sols; _nbFolds = nbFolds; formatDescription(); setSelectedIndex(0); } private void formatDescription() { _text.setText(""+_nbFolds); _subopts.setText(""+_sols.size()); next.setEnabled(_sols.size()>1); previous.setEnabled(_sols.size()>1); } } }