4 ROOT
R is an
interface in ROOT to call
R functions using an
R C++ interface (Rcpp, see http:
5 This interface opens the possibility in ROOT to use the very large set of mathematical and statistical tools provided by
R.
6 With
ROOTR you can perform
a conversion from ROOT's
C++ objects to
R's objects, transform the returned
R objects into ROOT's
C++ objects, then
7 the
R functionality can be used directly
for statistical studies in ROOT.
10 ROOTR creates
a working environment to execute
R coding called from `
C++`. It allows to translate some datatypes from `
C++` to
R
11 inside the
R environment and vice versa in an easy way to get the most from both
R and ROOT.
12 To ease the sending and receiving of
data in both environments,
I overloaded the operators `<<`,`>>` and `[]`
13 which
make look the job
as a flow of
data between environments, we will see more of that later.
14 With this tool you ca use any library or
R package wich allows you to access
a big amount of benefits to
make statistical analysis.
15 ROOTR also has
a R events processing system, which allows to use the
R graphical system from `
C++`.
24 ### COMPILING ROOTR ON MAC WITH CMAKE:
25 **NOTE:** Mac OSX Yosemite last xcode and without macports
32 - [R last version](https:
35 To compile with cmake added into ~/.profile
38 export PATH=$PATH:/Applications/CMake.app/Contents/bin/
46 Install needed R packages, open R and in the prompt type
49 install.packages(c('Rcpp','RInside'))
51 select a mirror and install.
53 Install the next additional packages for R TMVA interface
56 install.packages(c('C50','RSNNS','e1071','xgboost'))
60 Download code from git repo
66 To compile ROOTR lets to create a compilation directory and to activate it use cmake -Dr=ON ..
75 ### Compiling ROOTR on Gnu/Linux with CMake:
76 **NOTE:** Tested on Gnu/Linux Debian Jessie with gcc 4.9
80 (For debian-based distros)
83 apt-get install r-base r-base-dev
85 Install needed R packages, open R and in the prompt type
88 install.packages(c('Rcpp','RInside'))
90 select a mirror and install.
92 Install the next additional packages for R TMVA interface
95 install.packages(c('C50','RSNNS','e1071','xgboost'))
98 Download code from git repo
104 To compile ROOTR lets to create a compilation directory and to activate it use cmake -Dr=ON ..
113 ## How does it work ?
114 There is a class called TRInterface which is located at the header TRInterface.h and uses the namespace `ROOT::R`, it is in charge
115 of making calls to R to give and obtain data. This class has a series of overcharged operators which ease the passing and obtaining of data
116 and code from R to C++ and vice versa. To create an object of this class the user must use the static methods `ROOT::R::TRInterface::Instance`
117 and `ROOT::R::TRInterface::InstancePtr` which return a reference object and a pointer object respectively.
120 #include<TRInterface.h>
121 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
124 ## Running R code and passing/getting variables.
125 We have different ways to run R code and pass/obtain data to/from R environment: using the methods Execute(code) and
129 #include<TRInterface.h>
132 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
134 r<<"print('hello ROOTR')";
135 r<<"vec=c(1,2,3)"<<"print(vec)";
138 r.Execute("print('hello ROOTR')");
142 std::vector<Int_t> v=r.Eval("c(1,2,3)");
143 std::cout<<v[0]<<" "<<v[1]<<" "<<v[2]<<std::endl;
145 std::vector<Double_t> vd(3);
148 r["seq(0,1,0.5)"]>>vd;
149 std::cout<<vd[0]<<" "<<vd[1]<<" "<<vd[2]<<std::endl;
151 std::vector<Int_t> v1(3);
162 r<<"mat<-matrix(c(0.1,0.2,0.3,0.4),nrow=2)";
166 So, working with ROOTR is like working with flows of data to pass, obtain and process data.
168 ## Passing functions from ROOT to R
169 You can pass functions from ROOT to R using the operators `<<` and `=` or using the class TRFunction, but the arguments and datatypes of the return value cannot be pointers. They must be ROOTR supported datatypes.
170 So instead of using `*Double_t` you must use `std::vector` and instead of `*Char_t` use TString or `std::string`.
172 For this example we need to create a macro, so save it as fun.C
175 #include<TRInterface.h>
178 Double_t myfun(Double_t x)
183 Double_t myfun2(std::vector<Double_t> x)
185 return x[1]*cos(x[0]);
190 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
191 r["dilog"]<<ROOT::R::TRFunctionExport(TMath::DiLog);
194 r<<"print(dilog(0))";
195 r<<"print(myfun(0))";
196 r<<"print(myfun2(c(0,4)))";
201 - For overloaded functions you should pass the function with a explicit cast to the wanted function.
202 - The system works with templates and the template can not resolve the correct type of function because it is overloaded.
203 - If you pass a function without the explicit cast you will get a very ugly traceback.
204 - A lot of common standard functions for example from math.h like sin, cos etc.. are overloaded, take care passing it.
207 #include<TRInterface.h>
209 Double_t myfun(Double_t x)
221 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
222 r["myfund"]<<(Double_t (*)(Double_t))myfun;
223 r["myfuni"]<<(Int_t (*)(Int_t))myfun;
225 r<<"print(myfund(0.0))";
226 r<<"print(myfuni(1))";
231 You can wrap a class and expose it in R environment using only a pair of macrodefinitions and the template class
233 The `ROOTR_EXPOSED_CLASS(Class)` macro allows you to expose the class as a new datatype of R, but it has to be alongside
234 the `ROOTR_MODULE(Module)` macro which allows you to create an internal R module and make the class wrapping
235 To do this you must use inside the `ROOTR_MODULE` braces the class `ROOT::R::class_<>` and specify
236 each constructor, attribute or method that the class to export has.
237 Then the macrodefinition `LOAD_ROOTR_MODULE(Module)` can load the module and the class in R's environment.
238 You can find a more clear instruction by looking at a example below in Functor section.
241 DataFrame? is a very important datatype in R and in ROOTR we have a class to manipulate
242 dataframes called TRDataFrame, with a lot of very useful operators overloaded to work with TRDataFrame's objects
243 in a similar way that in the R environment but from c++ in ROOT.
246 Lets to create need data to play with dataframe features
253 std::vector<Double_t> v2(3);
254 std::array<Int_t,3> v3{ {1,2,3} };
255 std::list<std::string> names;
268 names.push_back("v1");
269 names.push_back("v2");
270 names.push_back("v3");
272 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
274 In R the dataframe have associate to every column a label, in ROOTR you can have the same label using the class ROOT::R::Label to create a TRDataFrame where you data
275 have a label associate.
282 ROOT::R::TRDataFrame df1(ROOT::R::Label["var1"]=v1,ROOT::R::Label["var2"]=v2,ROOT::R::Label["var3"]=v3,ROOT::R::Label["strings"]=names);
294 var1 var2 var3 strings
299 Manipulating data between dataframes
308 r["c(-1,-2,-3)"]>>v4;
319 var1 var2 var3 strings var4
325 Getting data frames from R's environment
331 ROOT::R::TRDataFrame df2;
333 r<<"df2<-data.frame(v1=c(0.1,0.2,0.3),v2=c(3,2,1))";
347 Vector (3) is as follows
355 Vector (3) is as follows
369 df2["v3"]<<df1["strings"];
390 df2["v3"]>>df1["var1"];
399 var1 var2 var3 strings var4
405 ## Plotting with R's graphical system.
406 ROOTR supports an eventloop for R's graphical system which allows plotting using the R functions to the
407 graphical system or generating images(ps, pdf png, etc).
408 You can find a demo in Interpolation below in examples section.
411 The interactive mode lets you get the R's command line within ROOT's command line to run R code with tab completion support.
412 The variables created in the interactive mode can be passed to ROOT with TRObjectProxy and the method ParseEval?.
413 To initialize the interactive mode just call Interactive() method and type ".q" to exit from R's prompt and to go to the ROOT's prompt again.
416 [omazapa] [tuxhome] [~]$ root -l
417 root [0] #include<TRInterface.h>
418 root [1] ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
419 root [2] r.Interactive()
421 seq seq_along seq.Date seq.default seq.int seq_len seq.POSIXt sequence
424 root [3] TVectorD v=r.ParseEval("a");
427 Vector (9) is as follows
445 The examples can also be found in `$ROOTSYS/tutorials/r`
447 ## Creating a Functor
448 A functor is a class which wraps a function, very useful when states and properties
449 associated to that function are needed.
450 In this example I show how to give support to a custom class to be used in R's environment,
451 which at the same time is a functor.
454 #include<TRInterface.h>
457 typedef Double_t (*Function)(Double_t);
466 void setFunction(Function fun)
471 Bool_t getStatus(){return status;}
472 Double_t doEval(Double_t x) {
481 ROOTR_EXPOSED_CLASS(MyFunctor)
484 ROOTR_MODULE(MyFunctorModule) {
485 ROOT::R::class_<MyFunctor>( "MyFunctor" )
489 .method( "doEval", &MyFunctor::doEval )
490 .method( "getStatus", &MyFunctor::getStatus)
496 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
502 r["MyFunctorModule"]<<LOAD_ROOTR_MODULE(MyFunctorModule);
505 r<<"MyFunctor <- MyFunctorModule$MyFunctor";
507 r<<"u <- new(MyFunctor)";
510 r<<"print(u$getStatus())";
513 r<<"print(sprintf('value in R = %f',u$doEval( 1 )))";
514 std::cout<<"value in ROOT = "<<TMath::BesselY1(1)<<std::endl;
522 functor.setFunction(TMath::Erf);
523 r["functor"]<<functor;
525 r<<"print(functor$getStatus())";
526 r<<"print(sprintf('value in R = %f',functor$doEval( 1 )))";
527 std::cout<<"value in ROOT = "<<TMath::Erf(1)<<std::endl;
531 ## Simple fitting in R and plot in ROOT
532 The next example creates an exponential fit.
533 The idea is to create a set of numbers x,y with noise from ROOT,
534 pass them to R and fit the data to `x^3`,
535 get the fitted coefficient(power) and plot the data,
536 the known function and the fitted function using ROOT's classes.
539 #include<TRInterface.h>
542 TCanvas *SimpleFitting(){
543 TCanvas *c1 = new TCanvas("c1","Curve Fitting",700,500);
547 TMultiGraph *mg = new TMultiGraph();
556 for (Int_t i = 0; i < n; i++) {
557 x1[i] = rg.Uniform(0, 1);
558 y1[i] = TMath::Power(x1[i], 3) + rg.Gaus() * 0.06;
561 TGraph *gr1 = new TGraph(n,x1,y1);
562 gr1->SetMarkerColor(kBlue);
563 gr1->SetMarkerStyle(8);
564 gr1->SetMarkerSize(1);
568 TF1 *f_known=new TF1("f_known","pow(x,3)",0,1);
569 TGraph *gr2 = new TGraph(f_known);
570 gr2->SetMarkerColor(kRed);
571 gr2->SetMarkerStyle(8);
572 gr2->SetMarkerSize(1);
575 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
576 r["x"]<<TVectorD(n, x1);
577 r["y"]<<TVectorD(n, y1);
579 r<<"ds<-data.frame(x=x,y=y)";
581 r<<"m <- nls(y ~ I(x^power),data = ds, start = list(power = 1),trace = T)";
584 r["summary(m)$coefficients[1]"]>>power;
586 TF1 *f_fitted=new TF1("f_fitted","pow(x,[0])",0,1);
587 f_fitted->SetParameter(0,power);
589 TGraph *gr3 = new TGraph(f_fitted);
590 gr3->SetMarkerColor(kGreen);
591 gr3->SetMarkerStyle(8);
592 gr3->SetMarkerSize(1);
598 TPaveText *pt = new TPaveText(0.1,0.6,0.5,0.9,"brNDC");
599 pt->SetFillColor(18);
600 pt->SetTextAlign(12);
601 pt->AddText("Fitting x^power ");
602 pt->AddText(" \"Blue\" Points with gaussian noise to be fitted");
603 pt->AddText(" \"Red\" Known function x^3");
605 fmsg.Form(" \"Green\" Fitted function with power=%.4lf",power);
612 In the first image you can see the blue dots which are the function `x^3` with gaussian noise, the red dots correspond to
613 the original function and the green ones correspond to the fitted function.
615 \image html R_image1.png
617 ## Global Minimization in R using the package DEoptim
618 DEoptim is a R package for Differential Evolution Minimization that lets you do global
620 To install this package you just need to run:
623 #include<TRInterface.h>
624 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
625 r<<"install.packages('DEoptim',repos='http:
628 Then create a macro named GlobalMinimization.C with the next code.
631 #include<TRInterface.h>
632 #include<TBenchmark.h>
638 Double_t GenRosenBrock(const TVectorD xx )
640 int length=xx.GetNoElements();
643 for(int i=0;i<(length-1);i++)
645 result+=pow(1-xx[i],2)+100*pow(xx[i+1]-pow(xx[i],2),2);
651 Double_t Rastrigin(const TVectorD xx)
653 int length=xx.GetNoElements();
654 Double_t result=10*length;
655 for(int i=0;i<length;i++)
657 result+=xx[i]*xx[i]-10*cos(6.2831853*xx[i]);
662 void GlobalMinimization()
665 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
667 Bool_t installed=r.Eval("is.element('DEoptim', installed.packages()[,1])");
670 std::cout<<"Package DEoptim no installed in R"<<std::endl;
671 std::cout<<"Run install.packages('DEoptim') in R's environment"<<std::endl;
676 r<<"suppressMessages(library(DEoptim, quietly = TRUE))";
679 r["GenRosenBrock"]<<GenRosenBrock;
686 r<<"ll<-rep(-25, n)";
690 bench.Start("GlobalMinimizationRosenBrock");
692 r<<"result1<-DEoptim(fn=GenRosenBrock,lower=ll,upper=ul,control=list(NP=10*n,itermax=MaxIter,trace=FALSE))";
693 std::cout<<"-----------------------------------------"<<std::endl;
694 std::cout<<"RosenBrock's minimum in: "<<std::endl;
695 r<<"print(result1$optim$bestmem)";
696 std::cout<<"Bechmark Times"<<std::endl;
698 bench.Show("GlobalMinimizationRosenBrock");
702 r["Rastrigin"]<<Rastrigin;
712 bench.Start("GlobalMinimizationRastrigin");
714 r<<"result2<-DEoptim(fn=Rastrigin,lower=ll,upper=ul,control=list(NP=10*n,itermax=MaxIter,trace=FALSE))";
715 std::cout<<"-----------------------------------------"<<std::endl;
716 std::cout<<"Rastrigin's minimum in: "<<std::endl;
717 r<<"print(result2$optim$bestmem)";
718 std::cout<<"Bechmark Times"<<std::endl;
720 bench.Show("GlobalMinimizationRastrigin");
721 r<<"dev.new(title='RosenBrock Convergence')";
722 r<<"plot(result1,type='o',pch='.')";
723 r<<"dev.new(title='Rastrigin Convergence')";
724 r<<"plot(result2,type='o',pch='.')";
727 In the image you can see the convergence plots of the functions and their minimum.
728 For RosenBrock is (1,1,1) and for Rastrigin is (0,0,0).
730 \image html R_image2.png
732 ## Interpolation (Plotting in R)
733 This example shows an interpolation using the function aproxfun and how to make a plot with R's
736 More Information on R interpolation
740 #include<TRInterface.h>
746 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
749 std::vector<Double_t> x(10),y(10);
750 for(int i=0;i<10;i++)
762 r<<"par(mfrow = c(2,1))";
765 r<<"plot(x, y, main = 'approx(.) and approxfun(.)')";
769 r<<"points(approx(x, y), col = 2, pch = '*')";
770 r<<"points(approx(x, y, method = 'constant'), col = 4, pch = '*')";
776 r<<"f <- approxfun(x, y)";
778 r<<"curve(f(x), 0, 11, col = 'green2')";
783 r<<"fc <- approxfun(x, y, method = 'const')";
784 r<<"curve(fc(x), 0, 10, col = 'darkblue', add = TRUE)";
786 r<<"plot(approxfun(x, y, rule = 2:1), 0, 11,col = 'tomato', add = TRUE, lty = 3, lwd = 2)";
789 The image shows the interpolated function plotted within R:
790 \image html R_image3.png
792 ## Integration (Passing vectorized function to R)
793 Numerical integration using R passing the function from ROOT
797 #include<TRInterface.h>
798 #include<Math/Integrator.h>
805 std::vector<Double_t> BreitWignerVectorized(std::vector<Double_t> xx)
807 std::vector<Double_t> result(xx.size());
808 for(Int_t i=0;i<xx.size();i++)
810 result[i]=TMath::BreitWigner(xx[i]);
815 double BreitWignerWrap( double x){
816 return TMath::BreitWigner(x);
823 ROOT::R::TRInterface &r=ROOT::R::TRInterface::Instance();
825 r["BreitWigner"]=BreitWignerVectorized;
827 Double_t value=r.Eval("integrate(BreitWigner, lower = -2, upper = 2)$value");
829 std::cout.precision(18);
830 std::cout<<"Integral of the BreitWigner Function in the interval [-2, 2] R = "<<value<<std::endl;
833 ROOT::Math::WrappedFunction<> wf(BreitWignerWrap);
834 ROOT::Math::Integrator i(wf);
835 value=i.Integral(-2,2);
836 std::cout<<"Integral of the BreitWigner Function in the interval [-2, 2] MathMore = "<<value<<std::endl;
839 TF1 f1("BreitWigner","BreitWignerWrap(x)");
840 value=f1.Integral(-2,2);
841 std::cout<<"Integral of the BreitWigner Function in the interval [-2, 2] TF1 = "<<value<<std::endl;
844 value=r.Eval("integrate(BreitWigner, lower = -Inf, upper = Inf)$value");
845 std::cout<<"Integral of BreitWigner Function in the interval [-Inf, Inf] R = "<<value<<std::endl;
double read(const std::string &file_name)
reading
constexpr std::array< decltype(std::declval< F >)(std::declval< int >))), N > make(F f)