Fullscreen
Loading...
 
Imprimir Comparte esta página

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

Image


Index





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).(external link)
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

Image

Index

Documentation

At the moment the documentation is within this wiki, or you can find
THtml's documentation at THtml generated(external link)


Index

Status

FeatureStatus NOTES
Class to communicate with RDONEclass TRInterface
Class to pass R objects to ROOT objectsDONEclass TRObjectProxy
Cint supportDONEYou can call it from ROOT's interpreter
LinuxDONERun under serveral linux flavors
MacOSXDONETested compilation in macosx(Snow Leopard)
WindowsPARTIALLYTested in cygwin
ACLiCPARTIALLYUsing custom rootlogon.C
Passing of functions from ROOT to RPARTIALLYRequire ACLiC and TF1,TF2,TF3 and TFormula is not supported
Overload operators for facilities PARTIALLYYou can use operator [] for assignation
cmakePARTIALLYNeeds to be improved to use R commands to get flags
testsuitePROGRESSAll features are being tested with ROOT scripts and compiled code

Index

Installation

To install ROOTR you should read
http://root.cern.ch/drupal/content/installing-root-source(external link) and
http://root.cern.ch/drupal/content/build-prerequisites(external link)

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/(external link)


(For Windows Cygwin)
NOTE: Rcpp doesn't have support for Visual Studio, see Rcpp FAQ(external link) 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(external link) But you can download the already patched version of rcpp here Rcpp_0.10.4-patched.tar.gz(external link)

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.
Image
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/src

NOTE: The version 0.11 have two important bugs that dont let compile ACLiC macros.(see more)(external link)


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(external link) synchronized with the ROOT's repo http://root.cern.ch/git/root.git(external link)

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 Here(external link)


Index

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::
:: Image::


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


:: Image::
::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 in
http://root.cern.ch/root/html/tutorials/fit/NumericalMinimization.C.html(external link)
http://stat.ethz.ch/R-manual/R-devel/library/stats/html/optim.html(external link)
You can find it in $ROOTSYS/tutorials/r/

NOTE: this example require ACLiC compilation


Image

#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::
:: Image::


Index

Interpolation

More Information of R interpolation at
http://stat.ethz.ch/R-manual/R-patched/library/stats/html/approxfun.html(external link)

#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::
:: Image::




Index

GlobalMinimization using DEoptim

DEoptim is a R package for Differential Evolution Minimization that let you do global
Minimization.
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(external link) numeral 2.9. for more information.

Index

Contact us

If you have suggestions or to report bugs please feel free to write us to
, ,