ROOTR Cint
NOTE:
This wiki is(outdated), the code works only with stable version of ROOT with CINT
New version of ROOTR for Cling(ROOT 6) in HERE
Index
- Description
- Documentation
- Status
- Installation
- Download
- Using ROOTR
- Parsing R code
- Interaction between ROOT's and R's objects
- Passing Functions and using ACLiC
- Using Interactive Mode
- Processing in R and plotting in ROOT
- Examples
- Limitations and Known bugs
- Contact us
Index
Description
ROOT R is an interface in ROOT to call R functions using an R C++ interface (Rcpp, see http://dirk.eddelbuettel.com/code/rcpp.html).This interface opens the possibility in ROOT to use the very large set of mathematical and statistical tools provided by R.
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
the R functionality can be used directly for statistical studies in ROOT.
Basic Desing
Index
Documentation
At the moment the documentation is within this wiki, or you can findTHtml's documentation at THtml generated
Index
Status
Feature | Status | NOTES |
Class to communicate with R | DONE | class TRInterface |
Class to pass R objects to ROOT objects | DONE | class TRObjectProxy |
Cint support | DONE | You can call it from ROOT's interpreter |
Linux | DONE | Run under serveral linux flavors |
MacOSX | DONE | Tested compilation in macosx(Snow Leopard) |
Windows | PARTIALLY | Tested in cygwin |
ACLiC | PARTIALLY | Using custom rootlogon.C |
Passing of functions from ROOT to R | PARTIALLY | Require ACLiC and TF1,TF2,TF3 and TFormula is not supported |
Overload operators for facilities | PARTIALLY | You can use operator [] for assignation |
cmake | PARTIALLY | Needs to be improved to use R commands to get flags |
testsuite | PROGRESS | All features are being tested with ROOT scripts and compiled code |
Index
Installation
To install ROOTR you should readhttp://root.cern.ch/drupal/content/installing-root-source and
http://root.cern.ch/drupal/content/build-prerequisites
Addtionally install
(For debian-based distros)
#apt-get install r-base r-base-dev
(For MacOSX)
#port install R
For RPM based systems read http://cran.r-project.org/bin/linux/
(For Windows Cygwin)
NOTE: Rcpp doesn't have support for Visual Studio, see Rcpp FAQ numeral 2.9. for more information.
http://cygwin.com/setup-x86.exe
You must install the following packages:
gcc gcc-g++ gcc-fortran make xterm git libX11-devel libXft-devel libXext-devel libXpm-deve libXt-deve libGL-devel libGLU-devel X-start-menu-icons xorg-scripts xorg-xserver xorg-server-devel gsl-devel cygutils-x11 libiconv R
Rcpp, The R package to interact with c++, requires the next patch to work within cgwin Rcpp-10.4-cywin.diff But you can download the already patched version of rcpp here Rcpp_0.10.4-patched.tar.gz
To install you just go to the downloaded path and write:
R -e "install.packages(\"Rcpp_0.10.4-patched.tar.gz\")"
Using Cygwin's XWin system and Terminal.
Figure 1: In green, the package X-start-menu-icons to open the XOrg windows system. In red, A xterm windows opened by executing XWin Server. In yellow, an icon in the task bar to open more XOrg windows.
After install R run:
Install Rcpp_0.10.6.tar.gz and RInside_0.2.10.tar.gz from $ROOTSYS/r/srcNOTE: The version 0.11 have two important bugs that dont let compile ACLiC macros.(see more)
R -e "install.packages(\"r/src/Rcpp_0.10.6.tar.gz\")" R -e "install.packages(\"r/src/RInside_0.2.10.tar.gz\")"
Downloads
I have a github repository here synchronized with the ROOT's repo http://root.cern.ch/git/root.git
git clone https://github.com/omazapa/root.git git checkout v5-34-00-patches-r ./configure --enable-r make
NOTE: You can run make -jn where n is the number of jobs to use in compilation.
NOTE: For windows configuration you must run this:
./configure win32gcc --enable-r
After compiling ROOT remember to run (in the root directory)
source $ROOTSYS/bin/thisroot.sh
Now you can the run the examples in $ROOTSYS/tutorials/r
and to study with this tutorial.
Index
Download
You can download a precompiled binaries for windows using cygwin HereIndex
Using ROOTR
ROOTR is very easy to use within the ROOT interpreter or using ACLiC.The main header for ROOTR is TRInterface.h, the namespace is ROOT::R and the main class is TRInterface. The class TRInterface have a global object called gR.
Index
Parsing R code
To parse R code you can use the methods Parse or ParseEval? from the class TRInterface.The method Parse just runs the code and returns void; the method ParseEval? returns a TRObjectProxy. TRObjectProxy contains the results of the executed code.
#include<TRInterface.h> gR->Parse("print(seq(1,5,0.5))"); Int_t power=gR->ParseEval("2^3").ToScalar(); cout<<power<<endl; TVector v=gR->ParseEval("seq(1,5,0.5)").ToVector(); v.Print()
Index
Interaction between ROOT's and R's objects
The supported objects to pass from ROOT to R, and to get from R to ROOT are: Double_t, Int_t, Float_t, TStrings , TVectorD and TMatrixD.To assign ROOT-like values such as: scalars, vectors, matrices and functions to R, you can to use the method Assign of the class TRInterface or use the operator [].
Examples:
#include<TRInterface.h> ROOT::R::TRInterface &r=gR->Instance(); //non-pointer instance to use operators with a nice syntax. Int_t n=2; TVectorD v(n); v[0]=0; v[1]=1; TMatrixD m(n,n); m[0]=v; m[1]=v; r.Assign(n,"n");//calling the method r["v"]=v; //using operators (*gR)["m"]=m; //using operators with global pointer object.
To get values from R you should use the TRInterface's method ParseEval which returns a TRObjectProxy's object. In accordance to the datatype that you get, you must call the right method: ToScalar, ToVector, ToString or ToMatrix to get a Double_t, Int_t, Float_t, TVectorD, TStrings and TMatrixD, respectively.
#include<TRInterface.h> ROOT::R::TRObjectProxy p=gR->ParseEval("2^3"); Int_t power=p.ToScalar();//Gettting scalar type from TVectorD v=gR->ParseEval("seq(1,5,0.5)").ToVector();//getting directly the vector without an TRObjectProxy's object cout<<power<<endl; v.Print();
Index
Passing Functions and using ACLiC
To compile the code in ROOTR using ACLiC system you need to create a rootlogon.C file, which is a ROOT macro that contains compilation and linking directives.This file must have included the header compilerdata.h and added the variables RINCLUDEPATH and RLINKEDLIBS.
{ #include <compilerdata.h> gSystem->AddIncludePath(RINCLUDEPATH); gSystem->AddLinkedLibs(RLINKEDLIBS); }
The rootlogon.C and the ROOTR's macro must be in the same
directory when you call ACLiC system.
Now to pass a function we must to use the class TRFunction and the ACLiC system.
This class is a C++ function wrapper which supports just a set of them, which are find within the builtin documentation by rcpp's source code.
Example of Numerical Integration:
//numerical integration using R //passing the function from ROOT #include<TMath.h> #include<TRInterface.h> #include<Math/Integrator.h> #include<TF1.h> //To integrate using R the function must be vectorized. //The idea is to receive a vector as an argument to evaluate //every element, saving the result in other vector //and return the resultant vector. TVectorD BreitWignerVectorized(TVectorD xx) { TVectorD result(xx.GetNoElements()); for(Int_t i=0;i<xx.GetNoElements();i++) { result[i]=TMath::BreitWigner(xx[i]); } return result; } double BreitWignerWrap( double x){ return TMath::BreitWigner(x); } void Integration() { #if defined(__CINT__) && !defined(__MAKECINT__) cout << "WARNING: This tutorial can run only using ACliC, you must run it by doing: " << endl; cout << "cd $ROOTSYS/tutorials/r/" << endl; cout << "\t .x Integration.C+" << endl; return; #endif ROOT::R::TRInterface &r=gR->Instance(); r["BreitWigner"]=ROOT::R::TRFunction(BreitWignerVectorized); Double_t value=r.ParseEval("integrate(BreitWigner, lower = -2, upper = 2)$value"); std::cout.precision(18); std::cout<<"Integral of BreitWigner Function in the interval [-2, 2] R = "<<value<<std::endl; ROOT::Math::WrappedFunction<> wf(BreitWignerWrap); ROOT::Math::Integrator i(wf); value=i.Integral(-2,2); std::cout<<"Integral of BreitWigner Function in the interval [-2, 2] MathMore = "<<value<<std::endl; TF1 f1("BreitWigner","BreitWignerWrap(x)"); value=f1.Integral(-2,2); std::cout<<"Integral of BreitWigner Function in the interval [-2, 2] TF1 = "<<value<<std::endl; //infinte limits value=r.ParseEval("integrate(BreitWigner, lower = -Inf, upper = Inf)$value"); std::cout<<"Integral of BreitWigner Function in the interval [-Inf, Inf] R = "<<value<<std::endl; }
run it writing
root -l Integration.C+
::Console Output::
:: ::
Index
Using Interactive Mode
The interactive mode lets you get a R's command line within ROOT's command line to run R code with tab completion support.The variables created in the interactive mode can be passed to ROOT with TRObjectProxy and the method ParseEval.
To initialize the interactive mode just call gR->Interactive() method and type ".q" to exit from R's prompt and to get the ROOT's prompt again.
[omazapa] [tuxhome] [~]$ root -l root [0] #include<TRInterface.h> root [1] gR->Interactive() [r]:a=seq seq seq_along seq.Date seq.default seq.int seq_len seq.POSIXt sequence [r]:a=seq(1,5,0.5) [r]:.q root [2] TVectorD v=gR->ParseEval("a").ToVector(); root [3] v.Print() Vector (9) is as follows | 1 | ------------------ 0 |1 1 |1.5 2 |2 3 |2.5 4 |3 5 |3.5 6 |4 7 |4.5 8 |5 root [4]
Index
Processing in R and plotting in ROOT
The next example creates an exponential fit.The idea is to create a set of numbers x,y with noise from ROOT,
pass them to R and fit the data to x^3,
get the fitted coefficient(power) and plot the data,
the known function and the fitted function using ROOT's classes.
#include<TRInterface.h> TCanvas *Fitting(){ TCanvas *c1 = new TCanvas("c1","Curve Fit",700,500); c1->SetGrid(); // draw a frame for multiples graphs TMultiGraph *mg = new TMultiGraph(); // create the first graph (points with gaussian noise) const Int_t n = 24; Double_t x1[n] ; Double_t y1[n] ; //Generate points along a X^3 with noise TRandom rg; rg.SetSeed(520); for (Int_t i = 0; i < n; i++) { x1[i] = rg.Uniform(0, 1); y1[i] = TMath::Power(x1[i], 3) + rg.Gaus() * 0.06; } TGraph *gr1 = new TGraph(n,x1,y1); gr1->SetMarkerColor(kBlue); gr1->SetMarkerStyle(8); gr1->SetMarkerSize(1); mg->Add(gr1); // create second graph TF1 *f_known=new TF1("f_known","pow(x,3)",0,1); TGraph *gr2 = new TGraph(f_known); gr2->SetMarkerColor(kRed); gr2->SetMarkerStyle(8); gr2->SetMarkerSize(1); mg->Add(gr2); //passing x and y values to R for fitting gR->Assign(TVectorD(n, x1), "x"); gR->Assign(TVectorD(n, y1), "y"); //creating a R data frame gR->Parse("ds<-data.frame(x=x,y=y)"); //fitting x and y to X^power using Nonlinear Least Squares gR->Parse("m <- nls(y ~ I(x^power),data = ds, start = list(power = 1),trace = T)"); //getting the fitted value (power) ROOT::R::TRObjectProxy robj=gR->ParseEval("summary(m)$coefficients[1]"); Double_t power=robj.ToScalar(); TF1 *f_fitted=new TF1("f_fitted","pow(x,[0])",0,1); f_fitted->SetParameter(0,power); //plotting the fitted function TGraph *gr3 = new TGraph(f_fitted); gr3->SetMarkerColor(kGreen); gr3->SetMarkerStyle(8); gr3->SetMarkerSize(1); mg->Add(gr3); mg->Draw("ap"); //displaying basic results TPaveText *pt = new TPaveText(0.1,0.6,0.5,0.9,"brNDC"); pt->SetFillColor(18); pt->SetTextAlign(12); pt->AddText("Fitting x^power "); pt->AddText(" \"Blue\" Points with gaussian noise to be fitted"); pt->AddText(" \"Red\" Known function x^3"); TString fmsg; fmsg.Form(" \"Green\" Fitted function with power=%.4lf",power); pt->AddText(fmsg); pt->Draw(); c1->Update(); return c1; }
Run it with
root -l Fitting.C
:: ::
::Figure 2: Exponential Fitting.::
Index
Examples
You can find the examples in $ROOTSYS/tutorials/r/NOTE: You can set extra console information with gR->SetVerbose(kTRUE)
Index
Minimization
The next example is based inhttp://root.cern.ch/root/html/tutorials/fit/NumericalMinimization.C.html
http://stat.ethz.ch/R-manual/R-devel/library/stats/html/optim.html
You can find it in $ROOTSYS/tutorials/r/
NOTE: this example require ACLiC compilation
#include<TRInterface.h> //in the next function the pointer *double should be change by TVectorD, because the pointer has no //sense into R enviroment. Double_t RosenBrock(const TVectorD xx ) { const Double_t x = xx[0]; const Double_t y = xx[1]; const Double_t tmp1 = y-x*x; const Double_t tmp2 = 1-x; return 100*tmp1*tmp1+tmp2*tmp2; } TVectorD RosenBrockGrad(const TVectorD xx ) { const Double_t x = xx[0]; const Double_t y = xx[1]; TVectorD grad(2); grad[0]=-400 * x * (y - x * x) - 2 * (1 - x); grad[1]=200 * (y - x * x); return grad; } void Minimization() { #if defined(__CINT__) && !defined(__MAKECINT__) cout << "WARNING: This tutorial can run only using ACliC, you must run it by doing: " << endl; cout << "cd $ROOTSYS/tutorials/r/" << endl; cout << "\t .x Minimization.C+" << endl; return; #endif ROOT::R::TRInterface &r=gR->Instance(); //passsing RosenBrock funtion to R r["RosenBrock"]=ROOT::R::TRFunction(RosenBrock); //passsing RosenBrockGrad funtion to R r["RosenBrockGrad"]=ROOT::R::TRFunction(RosenBrockGrad); //the option "method" could be "Nelder-Mead", "BFGS", "CG", "L-BFGS-B", "SANN","Brent" //the option "control" let you put some constraints like //"maxit" The maximum number of iterations //"abstol" The absolute convergence tolerance. //"reltol" Relative convergence tolerance. r.Parse("result <- optim( c(0.01,0.01), RosenBrock,method='BFGS',control = list(maxit = 1000000) )"); //Getting result from R TVectorD min=r.ParseEval("result$par").ToVector<Double_t>(); std::cout.precision(8); //printing results std::cout<<"-----------------------------------------"<<std::endl; std::cout<<"Minimum x="<<min[0]<<" y="<<min[1]<<std::endl; std::cout<<"Value at minimum ="<<RosenBrock(min)<<std::endl; //using the gradient r.Parse("optimHess(result$par, RosenBrock, RosenBrockGrad)"); r.Parse("hresult <- optim(c(-1.2,1), RosenBrock, NULL, method = 'BFGS', hessian = TRUE)"); //getting the min calculated with the gradient TVectorD hmin=r.ParseEval("hresult$par").ToVector<Double_t>(); //printing results std::cout<<"-----------------------------------------"<<std::endl; std::cout<<"Minimization with the Gradient"<<endl; std::cout<<"Minimum x="<<hmin[0]<<" y="<<hmin[1]<<std::endl; std::cout<<"Value at minimum ="<<RosenBrock(hmin)<<std::endl; }
::Console Output::
:: ::
Index
Interpolation
More Information of R interpolation athttp://stat.ethz.ch/R-manual/R-patched/library/stats/html/approxfun.html
#include<TRInterface.h> #include<TRandom.h> void Interpolation() { //creting points TRandom r; TVectorD x(10),y(10); for(int i=0;i<10;i++) { x[i]=i; y[i]=r.Gaus(); } (*gR)["x"]=x; (*gR)["y"]=y; gR->Xwin();//required to active new window for plot //Plot parameter. Plotting using two rows in one column gR->Parse("par(mfrow = c(2,1))"); //plotting the points gR->plot("x, y, main = 'approx(.) and approxfun(.)'"); //approx returns a list with components x and y, //containing n coordinates which interpolate the given data points according to the method (and rule) desired. gR->points("approx(x, y), col = 2, pch = '*'"); gR->points("approx(x, y, method = 'constant'), col = 4, pch = '*'"); //The function approxfun returns a function performing (linear or constant) //interpolation of the given data points. //For a given set of x values, this function will return the corresponding interpolated values. gR->Parse("f <- approxfun(x, y)"); gR->curve("f(x), 0, 11, col = 'green2'"); gR->points("x, y"); //using approxfun with const method gR->Parse("fc <- approxfun(x, y, method = 'const')"); gR->curve("fc(x), 0, 10, col = 'darkblue', add = TRUE"); // different extrapolation on left and right side : gR->plot("approxfun(x, y, rule = 2:1), 0, 11,col = 'tomato', add = TRUE, lty = 3, lwd = 2"); }
::Plots::
:: ::
Index
GlobalMinimization using DEoptim
DEoptim is a R package for Differential Evolution Minimization that let you do globalMinimization.
To install this package you just need to run:
#include<TRInterface.h> gR->Install("DEoptim");
Then create a macro named GlobalMinimization.C with the next code and run it using ACLiC.
//Example based in //http://cran.r-project.org/web/packages/DEoptim/DEoptim.pdf //Author: Omar Zapata #include<TRInterface.h> #include<TBenchmark.h> #include<math.h> #include<stdlib.h> //in the next function the pointer *double should be change by TVectorD, because the pointer has no //sense into R enviroment. It is a Generalization or RosenBrock Double_t GenRosenBrock(const TVectorD xx ) { int length=xx.GetNoElements(); Double_t result=0; for(int i=0;i<(length-1);i++) { result+=pow(1-xx[i],2)+100*pow(xx[i+1]-pow(xx[i],2),2); } return result; } void GlobalMinimization() { #if defined(__CINT__) && !defined(__MAKECINT__) cout << "WARNING: This tutorial can run only using ACliC, you must run it by doing: " << endl; cout << "cd $ROOTSYS/tutorials/r/" << endl; cout << "\t .x GlobalMinimization.C+" << endl; return; #endif TBenchmark bench; ROOT::R::TRInterface &r=gR->Instance(); //loading DEoptim r.Parse("require(DEoptim)"); // passsing RosenBrock funtion to R r["GenRosenBrock"]=ROOT::R::TRFunction(GenRosenBrock); //maximun of iterations r["MaxIter"]=5000; //n = of argument(vector) for GenRosenBrock r["n"]=10; //lower limits r.Parse("ll<-rep(-25, n)"); //upper limits r.Parse("ul<-rep(25, n)"); bench.Start("GlobalMinimization"); //calling minimization in sequential with one core and timing it. r.Parse("result<-DEoptim(fn=GenRosenBrock,lower=ll,upper=ul,control=list(NP=10*n,itermax=MaxIter))"); r.Parse("result"); std::cout<<"-----------------------------------------"<<std::endl; std::cout<<"Bechmark Times"<<std::endl; // printing times bench.Show("GlobalMinimization"); }
Index
Limitations and Known bugs
- Since ROOTR nor Rcpp have implemented the event loop for any window system, I remcommend to plot with the ROOT's native classes. The use of the graphical functions of R, can lead to discomfort since the closing buttons don't work and the image disappear when the windows is refreshed. Even though you can plot the date when is stored in a graphical file(png, jpg, eps...).
- It is not possible to pass C++ functions to R without using ACLiC.
- Rcpp lacks support for Visual Studio, then I can't give support for ROOTR either, see Rcpp FAQ numeral 2.9. for more information.
Index
Contact us
If you have suggestions or to report bugs please feel free to write us to, ,