Mercurial > hg > dml-open-cliopatria
diff cpack/dml/api/r_plot.pl @ 0:718306e29690 tip
commiting public release
author | Daniel Wolff |
---|---|
date | Tue, 09 Feb 2016 21:05:06 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cpack/dml/api/r_plot.pl Tue Feb 09 21:05:06 2016 +0100 @@ -0,0 +1,103 @@ +/* Part of DML (Digital Music Laboratory) + Copyright 2014-2015 Samer Abdallah, University of London + + This program 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 2 + of the License, or (at your option) any later version. + + This program 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 this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +:- module(api_r_plot, []). + +:- use_module(library(http/http_dispatch)). +:- use_module(library(http/http_parameters)). +:- use_module(library(sandbox)). +:- use_module(library(insist)). +:- use_module(library(fileutils)). +:- use_module(library(swipe)). +:- use_module(library(httpfiles)). +:- use_module(library(real)). + +:- set_prolog_flag(double_quotes,string). +:- set_prolog_flag(back_quotes,symbol_char). + +:- http_handler(api(r/render), r_figure_render, []). + +:- setting(r_plot:pixels_per_inch,number,150,"Pixels per inch for in browser figures"). +:- setting(r_plot:default_figure_format,oneof([png,svg]),svg,"Default R figure rendering method"). + +%% figure_render(+Request) is det. +% +% HTTP handler for rendering R figures. +r_figure_render(Request) :- + setting(r_plot:pixels_per_inch,DefPPI), + http_parameters(Request, + [ code(CodeA,[ atom, optional(false), description("Prolog rendering goal")]) + , format(F, [ oneof([eps,svg,pdf,png]), optional(false), description("Output format") ]) + , width(W, [ number, optional(true), default(10), description("Width in cm")]) + , height(H, [ number, optional(true), default(6), description("Height in cm")]) + , font_name(FN, [ atom, optional(true), default(helvetica) ]) + , font_size(FS, [ number, optional(true), default(10) ]) + , ppi(PPI, [ number, optional(true), default(DefPPI), description("PNG resolution")]) + ]), + debug(r_plot,"Attempting to parse \"~s\".",[CodeA]), + read_term_from_atom(CodeA,Code,[]), + ( user_db:logged_on(A) + -> debug(r_plot,"Logged on as ~w, no checking",[A]) + ; debug(r_plot,"Checking ~q for safety...",[Code]), + sandbox:safe_goal(Code), + debug(r_plot,"Goal is safe.",[]) + ), + insist(with_temp_dir(Dir, ( + render(F,Code,Dir,File, [size(W,H), ppi(PPI), font_name(FN), font_size(FS) ]), + debug(r_plot,'Replying with file ~s',[File]), + reply_file(File,F) + ))). + + +render(png,Code,D,PNGPath,Opts) :- !, + file_name_extension(tmp,png,PNGFile), + directory_file_path(D,PNGFile,PNGPath), + render(pdf,Code,D,EPSFile,Opts), + option(ppi(PPI),Opts,300), + run(sh(0>>0, "gs -dBATCH -dNumRenderingThreads=2 -dEPSCrop -dNOPAUSE -sDEVICE=pngalpha -sOutputFile=~s -r~d -q ~s", + [PNGPath+write,\PPI,EPSFile+read])). + +% render(png,Code,D,Opts) :- !, option(ppi(PPI),Opts,300), render(png(PPI),Code,D,Opts). +render(Fmt,Code,Dir,Path,Opts) :- + file_name_extension(tmp,Fmt,File), + directory_file_path(Dir,File,Path), + debug(r_plot,'Running ~q',[print_fig(Fmt,Code,Path,Opts)]), + with_mutex(r_plot,api_r_plot:print_fig(Fmt,Code,Path,Opts)). + +print_fig(Fmt,Code,Path,Opts) :- + debug(r_plot,'In print_fig...',[]), + option(size(Width,Height),Opts), + maplist(cm_inch,[Width,Height],[WidthInches,HeightInches]), + debug(r_plot,'Getting device ~w: ~s',[Fmt,Path]), + dev(Fmt,Path,WidthInches,HeightInches,Dev), + debug(r_plot,'Got device ~q',[Dev]), + setup_call_cleanup( + r(Dev), + call_cleanup( + with_output_to(string(_),Code), + exception(Ex), + debug(r_plot,'Exception running R code: ~q',[Ex])), + r('dev.off()')). + +dev(pdf,Name,W,H,pdf(+Name,width=W,height=H)). +dev(eps,Name,W,H,cairo_ps(+Name,width=W,height=H)). +dev(svg,Name,W,H,svg(+Name,width=W,height=H)). +dev(png(PPI),Name,W,H,png(+Name,width=WP,height=HP)) :- WP is PPI*W, HP is PPI*H. + +cm_inch(CM,INCH) :- INCH is CM/2.54. +