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;
21 import java.awt.Graphics2D;
22 import java.awt.geom.AffineTransform;
23 import java.awt.geom.Rectangle2D;
24 import java.awt.image.BufferedImage;
26 import java.io.FileInputStream;
27 import java.io.FileNotFoundException;
28 import java.io.FileOutputStream;
29 import java.io.IOException;
30 import java.io.OutputStream;
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.Collection;
34 import java.util.Comparator;
35 import java.util.Hashtable;
36 import java.util.Vector;
38 import javax.imageio.IIOImage;
39 import javax.imageio.ImageIO;
40 import javax.imageio.ImageWriteParam;
41 import javax.imageio.ImageWriter;
42 import javax.imageio.stream.FileImageOutputStream;
43 import javax.swing.JFrame;
45 import fr.orsay.lri.varna.VARNAPanel;
46 import fr.orsay.lri.varna.exceptions.ExceptionExportFailed;
47 import fr.orsay.lri.varna.exceptions.ExceptionFileFormatOrSyntax;
48 import fr.orsay.lri.varna.exceptions.ExceptionJPEGEncoding;
49 import fr.orsay.lri.varna.exceptions.ExceptionLoadingFailed;
50 import fr.orsay.lri.varna.exceptions.ExceptionModeleStyleBaseSyntaxError;
51 import fr.orsay.lri.varna.exceptions.ExceptionNonEqualLength;
52 import fr.orsay.lri.varna.exceptions.ExceptionParameterError;
53 import fr.orsay.lri.varna.exceptions.ExceptionPermissionDenied;
54 import fr.orsay.lri.varna.exceptions.ExceptionUnmatchedClosingParentheses;
55 import fr.orsay.lri.varna.exceptions.ExceptionWritingForbidden;
56 import fr.orsay.lri.varna.factories.RNAFactory;
57 import fr.orsay.lri.varna.interfaces.InterfaceParameterLoader;
58 import fr.orsay.lri.varna.models.FullBackup;
59 import fr.orsay.lri.varna.models.VARNAConfig;
60 import fr.orsay.lri.varna.models.VARNAConfigLoader;
61 import fr.orsay.lri.varna.models.rna.RNA;
63 public class VARNAcmd implements InterfaceParameterLoader {
65 public class ExitCode extends Exception{
69 private static final long serialVersionUID = -3011196062868355584L;
72 public ExitCode(int c,String msg){
76 public int getExitCode(){
79 public String getExitMessage(){
85 private Hashtable<String, String> _optsValues = new Hashtable<String, String>();
86 private Hashtable<String, String> _basicOptsInv = new Hashtable<String, String>();
87 private String _inFile = "";
88 private String _outFile = "";
91 float _quality = 0.9f;
93 private String[] _basicOptions = { VARNAConfigLoader.algoOpt,
94 VARNAConfigLoader.bpStyleOpt, VARNAConfigLoader.bondColorOpt,
95 VARNAConfigLoader.backboneColorOpt, VARNAConfigLoader.periodNumOpt,
96 VARNAConfigLoader.baseInnerColorOpt,
97 VARNAConfigLoader.baseOutlineColorOpt,
101 public VARNAcmd(Vector<String> args) throws ExitCode {
102 for (int j = 0; j < _basicOptions.length; j++) {
103 _basicOptsInv.put(_basicOptions[j], _basicOptions[j]);
106 while (i < args.size()) {
107 String opt = args.elementAt(i);
108 if (opt.charAt(0) != '-') {
109 errorExit("Missing or unknown option \"" + opt + "\"");
111 if (opt.equals("-h")) {
112 displayLightHelpExit();
114 if (opt.equals("-x")) {
115 displayDetailledHelpExit();
117 if (i + 1 >= args.size()) {
118 errorExit("Missing argument for option \"" + opt + "\"");
120 String val = args.get(i + 1);
121 if (opt.equals("-i")) {
123 } else if (opt.equals("-o")) {
125 } else if (opt.equals("-quality")) {
126 _quality = Float.parseFloat(val);
127 } else if (opt.equals("-resolution")) {
128 _scale = Float.parseFloat(val);
137 public void addOption(String key, String value) {
138 if (key.equals("-i")) {
140 } else if (key.equals("-o")) {
143 _optsValues.put(key.substring(1), value);
147 private String getDescription() {
149 + VARNAConfig.MAJOR_VERSION
151 + VARNAConfig.MINOR_VERSION
152 + " Assisted drawing of RNA secondary structure (Command Line version)";
155 private String indent(int k) {
157 for (int i = 0; i < k; i++) {
163 private String complete(String s, int k) {
165 while (result.length() < k) {
171 Vector<String[]> matrix = new Vector<String[]>();
173 private void addLine(String opt, String val) {
174 String[] line = { opt, val };
178 private static int MAX_WIDTH = 100;
180 @SuppressWarnings("unchecked")
181 private void printMatrix(int ind) {
182 String[][] values = new String[matrix.size()][];
183 matrix.toArray(values);
184 Arrays.sort(values, new Comparator() {
185 public int compare(Object o1, Object o2) {
186 String[] tab1 = (String[]) o1;
187 String[] tab2 = (String[]) o2;
188 return tab1[0].compareTo(tab2[0]);
193 for (int i = 0; i < values.length; i++) {
194 String[] elem = values[i];
195 maxSize = Math.max(maxSize, elem[0].length());
198 for (int i = 0; i < values.length; i++) {
199 String[] elem = values[i];
200 String opt = elem[0];
201 String msg = elem[1];
202 opt = complete("", ind) + "-" + complete(opt, maxSize - ind);
203 System.out.println(opt + msg.substring(0, Math.min(MAX_WIDTH - opt.length(), msg.length())));
204 if (opt.length() + msg.length() >= MAX_WIDTH) {
205 int off = MAX_WIDTH - opt.length();
206 while (off < msg.length()) {
207 String nmsg = msg.substring(off, Math.min(off + MAX_WIDTH
208 - opt.length(), msg.length()));
209 System.out.println(complete("", opt.length())+nmsg);
210 off += MAX_WIDTH - opt.length();
214 matrix = new Vector<String[]>();
217 private void printUsage() {
219 .println("Usage: java -cp . [-i InFile|-sequenceDBN XXX -structureDBN YYY] -o OutFile [Options]");
220 System.out.println("Where:");
221 System.out.println(indent(1)
222 + "OutFile\tSupported formats: {JPEG,PNG,EPS,XFIG,SVG}");
225 + "InFile\tSecondary structure file: Supported formats: {BPSEQ,CT,RNAML,DBN}");
229 private void printHelpOptions() {
230 System.out.println("\nMain options:");
231 addLine("h", "Displays a short description of main options and exits");
232 addLine("x", "Displays a detailled description of all options");
236 private void printMainOptions(String[][] info) {
237 System.out.println("\nMain options:");
238 addLine("h", "Displays a short description of main options and exits");
239 addLine("x", "Displays a detailled description of all options");
240 for (int i = 0; i < info.length; i++) {
241 String key = info[i][0];
242 if (_basicOptsInv.containsKey(key)) {
243 addLine(key, info[i][2]);
249 private void printAdvancedOptions(String[][] info) {
250 System.out.println("\nAdvanced options:");
251 for (int i = 0; i < info.length; i++) {
252 String key = info[i][0];
253 if (!_basicOptsInv.containsKey(key)) {
254 addLine(key, info[i][2]);
257 addLine("quality", "Sets quality (non-vector file formats only)");
258 addLine("resolution", "Sets resolution (non-vector file formats only)");
262 private void displayLightHelpExit() throws ExitCode {
263 String[][] info = VARNAConfigLoader.getParameterInfo();
264 System.out.println(getDescription());
266 printMainOptions(info);
267 throw(new ExitCode(1,""));
270 private void displayDetailledHelpExit() throws ExitCode {
271 String[][] info = VARNAConfigLoader.getParameterInfo();
272 System.out.println(getDescription());
274 printMainOptions(info);
275 printAdvancedOptions(info);
276 throw(new ExitCode(1,""));
279 private void errorExit(String msg) throws ExitCode {
280 System.out.println(getDescription());
281 System.out.println("Error: " + msg + "\n");
284 throw(new ExitCode(1,""));
287 public String getParameterValue(String key, String def) {
288 if (_optsValues.containsKey(key)) {
289 return _optsValues.get(key);
294 public String formatOutputPath(String base,int index, int total)
296 String result = base;
300 int indexDot = base.lastIndexOf('.');
305 pref = base.substring(0,indexDot);
306 ext = base.substring(indexDot);
312 result = pref+"-"+index+ext;
314 System.err.println("Output file: "+result);
318 public void run() throws IOException, ExitCode {
319 VARNAConfigLoader VARNAcfg = new VARNAConfigLoader(this);
320 ArrayList<VARNAPanel> vpl;
321 ArrayList<FullBackup> confs = new ArrayList<FullBackup>();
323 if (!_inFile.equals("")) {
324 if (!_inFile.toLowerCase().endsWith(".varna")) {
325 Collection<RNA> rnas = RNAFactory.loadSecStr(_inFile);
330 f = VARNAPanel.importSession(new FileInputStream(_inFile), _inFile);
339 throw new ExceptionFileFormatOrSyntax("No RNA could be parsed from file '"+_inFile+"'.");
345 confs.add(new FullBackup(r,_inFile));
350 confs.add(VARNAPanel.importSession(_inFile));
354 r.setRNA(this.getParameterValue("sequenceDBN",
355 ""), this.getParameterValue(
356 "structureDBN", ""));
357 confs.add(new FullBackup(r,"From Params"));
359 if (!_outFile.equals(""))
362 for (FullBackup r: confs)
364 VARNAcfg.setRNA(r.rna);
365 vpl = VARNAcfg.createVARNAPanels();
366 if (vpl.size() > 0) {
367 VARNAPanel _vp = vpl.get(0);
370 _vp.setConfig(r.config);
372 RNA _rna = _vp.getRNA();
373 Rectangle2D.Double bbox = _vp.getRNA().getBBox();
374 //System.out.println(_vp.getRNA().getBBox());
376 if (_outFile.toLowerCase().endsWith(".jpeg")
377 || _outFile.toLowerCase().endsWith(".jpg")
378 || _outFile.toLowerCase().endsWith(".png"))
380 _vp.setTitleFontSize((int)(_scale*_vp.getTitleFont().getSize()));
381 _vp.setSize((int)(_baseWidth*_scale), (int)((_scale*_baseWidth*bbox.height)/((double)bbox.width)));
384 if (_outFile.toLowerCase().endsWith(".eps")) {
385 _rna.saveRNAEPS(formatOutputPath(_outFile,index, confs.size()), _vp.getConfig());
386 } else if (_outFile.toLowerCase().endsWith(".xfig")
387 || _outFile.toLowerCase().endsWith(".fig")) {
388 _rna.saveRNAXFIG(formatOutputPath(_outFile,index, confs.size()), _vp.getConfig());
389 } else if (_outFile.toLowerCase().endsWith(".svg")) {
390 _rna.saveRNASVG(formatOutputPath(_outFile,index, confs.size()), _vp.getConfig());
391 } else if (_outFile.toLowerCase().endsWith(".jpeg")
392 || _outFile.toLowerCase().endsWith(".jpg")) {
393 this.saveToJPEG(formatOutputPath(_outFile,index, confs.size()), _vp);
394 } else if (_outFile.toLowerCase().endsWith(".png")) {
395 this.saveToPNG(formatOutputPath(_outFile,index, confs.size()), _vp);
396 } else if (_outFile.toLowerCase().endsWith(".varna")) {
397 _vp.saveSession(formatOutputPath(_outFile,index, confs.size()));
399 errorExit("Unknown extension for output file \"" + _outFile
406 // No output file => Open GUI
409 VARNAGUI d = new VARNAGUI();
410 d.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
413 for (FullBackup b: confs)
417 vpl = VARNAcfg.createVARNAPanels();
418 if (vpl.size() > 0) {
419 VARNAPanel _vp = vpl.get(0);
420 VARNAConfig cfg = _vp.getConfig();
425 RNA rna = _vp.getRNA();
431 } catch (ExceptionWritingForbidden e) {
433 throw(new ExitCode(1,""));
434 } catch (ExceptionJPEGEncoding e) {
436 throw(new ExitCode(1,""));
437 } catch (ExceptionParameterError e) {
439 throw(new ExitCode(1,""));
440 } catch (ExceptionModeleStyleBaseSyntaxError e) {
442 throw(new ExitCode(1,""));
443 } catch (ExceptionNonEqualLength e) {
445 throw(new ExitCode(1,""));
446 } catch (ExceptionUnmatchedClosingParentheses e) {
449 } catch (ExceptionExportFailed e) {
451 throw(new ExitCode(1,""));
452 } catch (ExceptionPermissionDenied e) {
454 throw(new ExitCode(1,""));
455 } catch (ExceptionLoadingFailed e) {
457 throw(new ExitCode(1,""));
458 } catch (ExceptionFileFormatOrSyntax e) {
461 throw(new ExitCode(1,""));
462 } catch (FileNotFoundException e) {
463 throw(new ExitCode(1,"Error: Missing input file \""+_inFile+"\"."));
466 if (!_outFile.equals(""))
467 throw(new ExitCode(0,""));
473 public void saveToJPEG(String filename, VARNAPanel vp)
474 throws ExceptionJPEGEncoding, ExceptionExportFailed {
476 BufferedImage myImage = new BufferedImage((int) Math.round(vp
478 ), (int) Math.round(vp.getHeight() ),
479 BufferedImage.TYPE_INT_RGB);
480 Graphics2D g2 = myImage.createGraphics();
481 vp.paintComponent(g2);
484 FileImageOutputStream out = new FileImageOutputStream(new File(filename));
485 ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next();
486 ImageWriteParam params = writer.getDefaultWriteParam();
487 params.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
488 params.setCompressionQuality(_quality);
489 writer.setOutput(out);
490 IIOImage myIIOImage = new IIOImage(myImage, null, null);
491 writer.write(null, myIIOImage, params);
493 } catch (IOException e) {
494 throw new ExceptionExportFailed(e.getMessage(), filename);
498 public void saveToPNG(String filename, VARNAPanel vp)
499 throws ExceptionExportFailed {
500 BufferedImage myImage = new BufferedImage((int) Math.round(vp
501 .getWidth()), (int) Math.round(vp.getHeight() ),
502 BufferedImage.TYPE_INT_RGB);
503 Graphics2D g2 = myImage.createGraphics();
504 vp.paintComponent(g2);
507 ImageIO.write(myImage, "PNG", new File(filename));
508 } catch (IOException e) {
513 public static void main(String[] argv) {
514 Vector<String> opts = new Vector<String>();
515 for (int i = 0; i < argv.length; i++) {
519 VARNAcmd app = new VARNAcmd(opts);
521 } catch (IOException e) {
523 } catch (ExitCode e) {
524 System.err.println(e.getExitMessage());
525 System.exit(e.getExitCode());