Merge branch 'develop' into feature/JAL-3390hideUnmappedStructure
[jalview.git] / srcjar / fr / orsay / lri / varna / applications / VARNAcmd.java
diff --git a/srcjar/fr/orsay/lri/varna/applications/VARNAcmd.java b/srcjar/fr/orsay/lri/varna/applications/VARNAcmd.java
new file mode 100644 (file)
index 0000000..7b16c61
--- /dev/null
@@ -0,0 +1,529 @@
+/*
+ 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.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.stream.FileImageOutputStream;
+import javax.swing.JFrame;
+
+import fr.orsay.lri.varna.VARNAPanel;
+import fr.orsay.lri.varna.exceptions.ExceptionExportFailed;
+import fr.orsay.lri.varna.exceptions.ExceptionFileFormatOrSyntax;
+import fr.orsay.lri.varna.exceptions.ExceptionJPEGEncoding;
+import fr.orsay.lri.varna.exceptions.ExceptionLoadingFailed;
+import fr.orsay.lri.varna.exceptions.ExceptionModeleStyleBaseSyntaxError;
+import fr.orsay.lri.varna.exceptions.ExceptionNonEqualLength;
+import fr.orsay.lri.varna.exceptions.ExceptionParameterError;
+import fr.orsay.lri.varna.exceptions.ExceptionPermissionDenied;
+import fr.orsay.lri.varna.exceptions.ExceptionUnmatchedClosingParentheses;
+import fr.orsay.lri.varna.exceptions.ExceptionWritingForbidden;
+import fr.orsay.lri.varna.factories.RNAFactory;
+import fr.orsay.lri.varna.interfaces.InterfaceParameterLoader;
+import fr.orsay.lri.varna.models.FullBackup;
+import fr.orsay.lri.varna.models.VARNAConfig;
+import fr.orsay.lri.varna.models.VARNAConfigLoader;
+import fr.orsay.lri.varna.models.rna.RNA;
+
+public class VARNAcmd implements InterfaceParameterLoader {
+       
+       public class ExitCode extends Exception{
+               /**
+                * 
+                */
+               private static final long serialVersionUID = -3011196062868355584L;
+               private int _c;
+               private String _msg;
+               public ExitCode(int c,String msg){
+                       _c = c;
+                       _msg = msg;
+               }
+               public int getExitCode(){
+                       return _c;
+               }
+               public String getExitMessage(){
+                       return _msg;
+               }
+       }
+       
+       
+       private Hashtable<String, String> _optsValues = new Hashtable<String, String>();
+       private Hashtable<String, String> _basicOptsInv = new Hashtable<String, String>();
+       private String _inFile = "";
+       private String _outFile = "";
+       int _baseWidth = 400;
+       double _scale = 1.0;
+       float _quality = 0.9f;
+
+       private String[] _basicOptions = { VARNAConfigLoader.algoOpt,
+                       VARNAConfigLoader.bpStyleOpt, VARNAConfigLoader.bondColorOpt,
+                       VARNAConfigLoader.backboneColorOpt, VARNAConfigLoader.periodNumOpt,
+                       VARNAConfigLoader.baseInnerColorOpt,
+                       VARNAConfigLoader.baseOutlineColorOpt,
+
+       };
+
+       public VARNAcmd(Vector<String> args) throws ExitCode {
+               for (int j = 0; j < _basicOptions.length; j++) {
+                       _basicOptsInv.put(_basicOptions[j], _basicOptions[j]);
+               }
+               int i = 0;
+               while (i < args.size()) {
+                       String opt = args.elementAt(i);
+                       if (opt.charAt(0) != '-') {
+                               errorExit("Missing or unknown option \"" + opt + "\"");
+                       }
+                       if (opt.equals("-h")) {
+                               displayLightHelpExit();
+                       }
+                       if (opt.equals("-x")) {
+                               displayDetailledHelpExit();
+                       } else {
+                               if (i + 1 >= args.size()) {
+                                       errorExit("Missing argument for option \"" + opt + "\"");
+                               }
+                               String val = args.get(i + 1);
+                               if (opt.equals("-i")) {
+                                       _inFile = val;
+                               } else if (opt.equals("-o")) {
+                                       _outFile = val;
+                               } else if (opt.equals("-quality")) {
+                                       _quality = Float.parseFloat(val);
+                               } else if (opt.equals("-resolution")) {
+                                       _scale = Float.parseFloat(val);
+                               } else {
+                                       addOption(opt, val);
+                               }
+                       }
+                       i += 2;
+               }
+       }
+
+       public void addOption(String key, String value) {
+               if (key.equals("-i")) {
+                       _inFile = value;
+               } else if (key.equals("-o")) {
+                       _outFile = value;
+               } else {
+                       _optsValues.put(key.substring(1), value);
+               }
+       }
+
+       private String getDescription() {
+               return "VARNA v"
+                               + VARNAConfig.MAJOR_VERSION
+                               + "."
+                               + VARNAConfig.MINOR_VERSION
+                               + " Assisted drawing of RNA secondary structure (Command Line version)";
+       }
+
+       private String indent(int k) {
+               String result = "";
+               for (int i = 0; i < k; i++) {
+                       result += "  ";
+               }
+               return result;
+       }
+
+       private String complete(String s, int k) {
+               String result = s;
+               while (result.length() < k) {
+                       result += " ";
+               }
+               return result;
+       }
+
+       Vector<String[]> matrix = new Vector<String[]>();
+
+       private void addLine(String opt, String val) {
+               String[] line = { opt, val };
+               matrix.add(line);
+       }
+
+       private static int MAX_WIDTH = 100;
+
+       @SuppressWarnings("unchecked")
+       private void printMatrix(int ind) {
+               String[][] values = new String[matrix.size()][];
+               matrix.toArray(values);
+               Arrays.sort(values, new Comparator() {
+                       public int compare(Object o1, Object o2) {
+                               String[] tab1 = (String[]) o1;
+                               String[] tab2 = (String[]) o2;
+                               return tab1[0].compareTo(tab2[0]);
+                       }
+               });
+
+               int maxSize = 0;
+               for (int i = 0; i < values.length; i++) {
+                       String[] elem = values[i];
+                       maxSize = Math.max(maxSize, elem[0].length());
+               }
+               maxSize += ind + 2;
+               for (int i = 0; i < values.length; i++) {
+                       String[] elem = values[i];
+                       String opt = elem[0];
+                       String msg = elem[1];
+                       opt = complete("", ind) + "-" + complete(opt, maxSize - ind);
+                       System.out.println(opt  + msg.substring(0, Math.min(MAX_WIDTH - opt.length(), msg.length())));
+                       if (opt.length() + msg.length() >= MAX_WIDTH) {
+                               int off = MAX_WIDTH - opt.length();
+                               while (off < msg.length()) {
+                                       String nmsg = msg.substring(off, Math.min(off + MAX_WIDTH
+                                                       - opt.length(), msg.length()));
+                                       System.out.println(complete("", opt.length())+nmsg);
+                                       off += MAX_WIDTH - opt.length();
+                               }
+                       }
+               } 
+               matrix = new Vector<String[]>();
+       }
+
+       private void printUsage() {
+               System.out
+                               .println("Usage: java -cp . [-i InFile|-sequenceDBN XXX -structureDBN YYY] -o OutFile [Options]");
+               System.out.println("Where:");
+               System.out.println(indent(1)
+                               + "OutFile\tSupported formats: {JPEG,PNG,EPS,XFIG,SVG}");
+               System.out
+                               .println(indent(1)
+                                               + "InFile\tSecondary structure file: Supported formats: {BPSEQ,CT,RNAML,DBN}");
+
+       }
+
+       private void printHelpOptions() {
+               System.out.println("\nMain options:");
+               addLine("h", "Displays a short description of main options and exits");
+               addLine("x", "Displays a detailled description of all options");
+               printMatrix(2);
+       }
+
+       private void printMainOptions(String[][] info) {
+               System.out.println("\nMain options:");
+               addLine("h", "Displays a short description of main options and exits");
+               addLine("x", "Displays a detailled description of all options");
+               for (int i = 0; i < info.length; i++) {
+                       String key = info[i][0];
+                       if (_basicOptsInv.containsKey(key)) {
+                               addLine(key, info[i][2]);
+                       }
+               }
+               printMatrix(2);
+       }
+
+       private void printAdvancedOptions(String[][] info) {
+               System.out.println("\nAdvanced options:");
+               for (int i = 0; i < info.length; i++) {
+                       String key = info[i][0];
+                       if (!_basicOptsInv.containsKey(key)) {
+                               addLine(key, info[i][2]);
+                       }
+               }
+               addLine("quality", "Sets quality (non-vector file formats only)");
+               addLine("resolution", "Sets resolution (non-vector file formats only)");
+               printMatrix(2);
+       }
+
+       private void displayLightHelpExit() throws ExitCode {
+               String[][] info = VARNAConfigLoader.getParameterInfo();
+               System.out.println(getDescription());
+               printUsage();
+               printMainOptions(info);
+               throw(new ExitCode(1,""));
+       }
+
+       private void displayDetailledHelpExit() throws ExitCode {
+               String[][] info = VARNAConfigLoader.getParameterInfo();
+               System.out.println(getDescription());
+               printUsage();
+               printMainOptions(info);
+               printAdvancedOptions(info);
+               throw(new ExitCode(1,""));
+       }
+
+       private void errorExit(String msg) throws ExitCode {
+               System.out.println(getDescription());
+               System.out.println("Error: " + msg + "\n");
+               printUsage();
+               printHelpOptions();
+               throw(new ExitCode(1,""));
+       }
+
+       public String getParameterValue(String key, String def) {
+               if (_optsValues.containsKey(key)) {
+                       return _optsValues.get(key);
+               }
+               return def;
+       }
+
+       public String formatOutputPath(String base,int index, int total)
+       {
+               String result = base;
+               
+               if (total>1)
+               {
+                       int indexDot = base.lastIndexOf('.');
+                       String pref;
+                       String ext;
+                       if (indexDot!=-1)
+                       {
+                         pref = base.substring(0,indexDot);
+                         ext = base.substring(indexDot);
+                       }
+                       else{
+                               pref=base;
+                               ext="";
+                       }
+                       result = pref+"-"+index+ext;
+               }
+               System.err.println("Output file: "+result);
+               return result;
+       }
+       
+       public void run() throws IOException, ExitCode {
+               VARNAConfigLoader VARNAcfg = new VARNAConfigLoader(this);
+               ArrayList<VARNAPanel> vpl;
+               ArrayList<FullBackup> confs = new ArrayList<FullBackup>();
+               try {
+                       if (!_inFile.equals("")) {
+                               if (!_inFile.toLowerCase().endsWith(".varna")) {
+                                       Collection<RNA> rnas = RNAFactory.loadSecStr(_inFile);
+                                        if (rnas.isEmpty())
+                                        {
+                                                FullBackup f = null;
+                                                               try{
+                                                               f = VARNAPanel.importSession(new FileInputStream(_inFile), _inFile);
+                                                               confs.add(f);
+                                                               }
+                                                               catch(Exception e)
+                                                               {
+                                                                       e.printStackTrace();
+                                                               }
+                                               if (f==null)
+                                               {
+                                                throw new ExceptionFileFormatOrSyntax("No RNA could be parsed from file '"+_inFile+"'.");
+                                               }
+                                        }
+                                        else{
+                                                for (RNA r: rnas)
+                                                {
+                                                        confs.add(new FullBackup(r,_inFile));
+                                                }
+                                        }
+                               }
+                               else{
+                                       confs.add(VARNAPanel.importSession(_inFile));
+                               }
+                       } else {
+                               RNA r = new RNA();
+                               r.setRNA(this.getParameterValue("sequenceDBN",
+                                               ""), this.getParameterValue(
+                                               "structureDBN", ""));
+                               confs.add(new FullBackup(r,"From Params"));
+                       }
+                       if (!_outFile.equals(""))
+                       {
+                       int index = 1;
+                       for (FullBackup r: confs)
+                       {
+                               VARNAcfg.setRNA(r.rna);
+                               vpl = VARNAcfg.createVARNAPanels();
+                               if (vpl.size() > 0) {
+                               VARNAPanel _vp = vpl.get(0);
+                               if (r.hasConfig())
+                               {
+                                       _vp.setConfig(r.config);
+                               }
+                               RNA _rna = _vp.getRNA();
+                               Rectangle2D.Double bbox = _vp.getRNA().getBBox();
+                               //System.out.println(_vp.getRNA().getBBox());
+                               
+                               if (_outFile.toLowerCase().endsWith(".jpeg")
+                                               || _outFile.toLowerCase().endsWith(".jpg")
+                                               || _outFile.toLowerCase().endsWith(".png"))
+                               { 
+                                       _vp.setTitleFontSize((int)(_scale*_vp.getTitleFont().getSize())); 
+                                   _vp.setSize((int)(_baseWidth*_scale), (int)((_scale*_baseWidth*bbox.height)/((double)bbox.width)));
+                               }
+                               
+                               if (_outFile.toLowerCase().endsWith(".eps")) {
+                                       _rna.saveRNAEPS(formatOutputPath(_outFile,index, confs.size()), _vp.getConfig());
+                               } else if (_outFile.toLowerCase().endsWith(".xfig")
+                                               || _outFile.toLowerCase().endsWith(".fig")) {
+                                       _rna.saveRNAXFIG(formatOutputPath(_outFile,index, confs.size()), _vp.getConfig());
+                               } else if (_outFile.toLowerCase().endsWith(".svg")) {
+                                       _rna.saveRNASVG(formatOutputPath(_outFile,index, confs.size()), _vp.getConfig());
+                               } else if (_outFile.toLowerCase().endsWith(".jpeg")
+                                               || _outFile.toLowerCase().endsWith(".jpg")) {
+                                       this.saveToJPEG(formatOutputPath(_outFile,index, confs.size()), _vp);
+                               } else if (_outFile.toLowerCase().endsWith(".png")) {
+                                       this.saveToPNG(formatOutputPath(_outFile,index, confs.size()), _vp);
+                               } else if (_outFile.toLowerCase().endsWith(".varna")) {
+                                       _vp.saveSession(formatOutputPath(_outFile,index, confs.size()));
+                               } else {
+                                       errorExit("Unknown extension for output file \"" + _outFile
+                                                       + "\"");
+                               }
+                       }
+                       index++;
+                       }
+                       }
+                       // No output file => Open GUI
+                       else
+                       {
+                               VARNAGUI d = new VARNAGUI();
+                               d.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+                               d.pack();
+                               d.setVisible(true);
+                               for (FullBackup b: confs)
+                               {
+                                       RNA r = b.rna;
+                                       VARNAcfg.setRNA(r);
+                                       vpl = VARNAcfg.createVARNAPanels();
+                                       if (vpl.size() > 0) {
+                                               VARNAPanel _vp = vpl.get(0);
+                                               VARNAConfig cfg = _vp.getConfig();
+                                               if (b.hasConfig())
+                                               {
+                                                       cfg = b.config;
+                                               }
+                                               RNA rna = _vp.getRNA();
+                                               d.addRNA(rna, cfg);
+                                               
+                                       }
+                               }
+                       }
+               } catch (ExceptionWritingForbidden e) {
+                       e.printStackTrace();
+                       throw(new ExitCode(1,""));
+               } catch (ExceptionJPEGEncoding e) {
+                       e.printStackTrace();
+                       throw(new ExitCode(1,""));
+               } catch (ExceptionParameterError e) {
+                       e.printStackTrace();
+                       throw(new ExitCode(1,""));
+               } catch (ExceptionModeleStyleBaseSyntaxError e) {
+                       e.printStackTrace();
+                       throw(new ExitCode(1,""));
+               } catch (ExceptionNonEqualLength e) {
+                       e.printStackTrace();
+                       throw(new ExitCode(1,""));
+               } catch (ExceptionUnmatchedClosingParentheses e) {
+                       e.printStackTrace();
+                       System.exit(1);
+               } catch (ExceptionExportFailed e) {
+                       e.printStackTrace();
+                       throw(new ExitCode(1,""));
+               } catch (ExceptionPermissionDenied e) {
+                       e.printStackTrace();
+                       throw(new ExitCode(1,""));
+               } catch (ExceptionLoadingFailed e) {
+                       e.printStackTrace();
+                       throw(new ExitCode(1,""));
+               } catch (ExceptionFileFormatOrSyntax e) {
+                       e.setPath(_inFile);
+                       e.printStackTrace();
+                       throw(new ExitCode(1,""));
+               } catch (FileNotFoundException e) {
+                       throw(new ExitCode(1,"Error: Missing input file \""+_inFile+"\"."));
+               }
+               
+               if (!_outFile.equals(""))
+                       throw(new ExitCode(0,""));
+               
+               
+       
+       }
+
+       public void saveToJPEG(String filename, VARNAPanel vp)
+                       throws ExceptionJPEGEncoding, ExceptionExportFailed {
+               
+               BufferedImage myImage = new BufferedImage((int) Math.round(vp
+                               .getWidth()
+                               ), (int) Math.round(vp.getHeight() ),
+                               BufferedImage.TYPE_INT_RGB);
+               Graphics2D g2 = myImage.createGraphics();
+               vp.paintComponent(g2);
+               try {
+                       FileImageOutputStream out = new FileImageOutputStream(new File(filename));
+                       ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next();
+                       ImageWriteParam params = writer.getDefaultWriteParam();
+                       params.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+                       params.setCompressionQuality(_quality);
+                       writer.setOutput(out);
+                       IIOImage myIIOImage = new IIOImage(myImage, null, null);
+                       writer.write(null, myIIOImage, params);
+                       out.close();
+               } catch (IOException e) {
+                       throw new ExceptionExportFailed(e.getMessage(), filename);
+               }
+
+       }
+
+       public void saveToPNG(String filename, VARNAPanel vp)
+                       throws ExceptionExportFailed {
+               BufferedImage myImage = new BufferedImage((int) Math.round(vp
+                               .getWidth()), (int) Math.round(vp.getHeight() ),
+                               BufferedImage.TYPE_INT_RGB);
+               Graphics2D g2 = myImage.createGraphics();
+               vp.paintComponent(g2);
+               g2.dispose();
+               try {
+                       ImageIO.write(myImage, "PNG", new File(filename));
+               } catch (IOException e) {
+                       e.printStackTrace();
+               }
+       }
+
+       public static void main(String[] argv) {
+               Vector<String> opts = new Vector<String>();
+               for (int i = 0; i < argv.length; i++) {
+                       opts.add(argv[i]);
+               }
+               try {
+                       VARNAcmd app = new VARNAcmd(opts);
+                       app.run();
+               } catch (IOException e) {
+                       e.printStackTrace();
+               } catch (ExitCode e) {
+                       System.err.println(e.getExitMessage());
+                       System.exit(e.getExitCode());
+               }
+       }
+
+}