Logo ROOT   master
Reference Guide
TRInterface.cxx
Go to the documentation of this file.
1 /*************************************************************************
2  * Copyright (C) 2013-2014, Omar Andres Zapata Mesa *
3  * All rights reserved. *
4  * *
5  * For the licensing terms see $ROOTSYS/LICENSE. *
6  * For the list of contributors see $ROOTSYS/README/CREDITS. *
7  *************************************************************************/
8 #include<TRInterface.h>
9 #include"TRCompletion.h"
10 #include<vector>
11 
12 extern "C"
13 {
14 #include <stdio.h>
15 #include <stdlib.h>
16 }
17 #include <TRint.h>
18 #include <TSystem.h>
19 
20 #if defined(HAS_X11)
21 #include <X11/Xlib.h>
22 #include "TROOT.h"
23 #include "TEnv.h"
24 #endif
25 using namespace ROOT::R;
27 
28 static ROOT::R::TRInterface *gR = nullptr;
30 
31 TRInterface::TRInterface(const Int_t argc, const Char_t *argv[], const Bool_t loadRcpp, const Bool_t verbose,
32  const Bool_t interactive)
33  : TObject()
34 {
35  if (RInside::instancePtr()) throw std::runtime_error("Can only have one TRInterface instance");
36  fR = new RInside(argc, argv, loadRcpp, verbose, interactive);
37 
38  //Installing the readline callbacks for completion in the
39  //method Interactive
40  rcompgen_rho = R_FindNamespace(Rf_mkString("utils"));
41  RComp_assignBufferSym = Rf_install(".assignLinebuffer");
42  RComp_assignStartSym = Rf_install(".assignStart");
43  RComp_assignEndSym = Rf_install(".assignEnd");
44  RComp_assignTokenSym = Rf_install(".assignToken");
45  RComp_completeTokenSym = Rf_install(".completeToken");
46  RComp_getFileCompSym = Rf_install(".getFileComp");
47  RComp_retrieveCompsSym = Rf_install(".retrieveCompletions");
50  std::string osname = Eval("Sys.info()['sysname']");
51  //only for linux/mac windows is not supported by ROOT yet.
52 #if defined(HAS_X11)
53  if (!gROOT->IsBatch()) {
54  if (gEnv->GetValue("X11.XInitThread", 1)) {
55  // Must be very first call before any X11 call !!
56  if (!XInitThreads())
57  Warning("OpenDisplay", "system has no X11 thread support");
58  }
59  }
60 #endif
61  if (osname == "Linux") {
62  Execute("options(device='x11')");
63  } else {
64  Execute("options(device='quartz')");
65  }
66 
67 }
68 
70 {
72  if (th) delete th;
73  if (fR) delete fR;
74  if (gR == this) gR = nullptr;
75 }
76 
77 //______________________________________________________________________________
79 {
80  SEXP fans;
81 
82  Int_t rc = kFALSE;
83  try {
84  rc = fR->parseEval(code.Data(), fans);
85  } catch (Rcpp::exception &__ex__) {
86  Error("Eval", "%s", __ex__.what());
87  forward_exception_to_r(__ex__) ;
88  } catch (...) {
89  Error("Eval", "Can execute the requested code: %s", code.Data());
90  }
91  ans = fans;
92  ans.SetStatus((rc == 0) ? kTRUE : kFALSE);
93  return rc;
94 }
95 
96 //______________________________________________________________________________
97 void TRInterface::Execute(const TString &code)
98 {
99  try {
100 
101  fR->parseEvalQ(code.Data());
102  } catch (Rcpp::exception &__ex__) {
103  Error("Execute", "%s", __ex__.what());
104  forward_exception_to_r(__ex__) ;
105  } catch (...) {
106  Error("Execute", "Can execute the requested code: %s", code.Data());
107  }
108 }
109 
110 //______________________________________________________________________________
112 {
113 // Execute R code.
114 //The RObject result of execution is returned in TRObject
115 
116  SEXP ans;
117 
118  int rc = kFALSE;
119  try {
120  rc = fR->parseEval(code.Data(), ans);
121  } catch (Rcpp::exception &__ex__) {
122  Error("Eval", "%s", __ex__.what());
123  forward_exception_to_r(__ex__) ;
124  } catch (...) {
125  Error("Eval", "Can execute the requested code: %s", code.Data());
126  }
127 
128  return TRObject(ans, (rc == 0) ? kTRUE : kFALSE);
129 }
130 
131 
133 {
134  //verbose mode shows you all the procedures in stdout/stderr
135  //very important to debug and to see the results.
136  fR->setVerbose(status);
137 }
138 
139 //______________________________________________________________________________
141 {
142  return Binding(this, name);
143 }
144 
145 //______________________________________________________________________________
147 {
148  fR->assign(*obj.f, name.Data());
149 }
150 
151 //______________________________________________________________________________
152 void TRInterface::Assign(const TRDataFrame &obj, const TString &name)
153 {
154  //This method lets you pass c++ functions to R environment.
155  fR->assign(obj.df, name.Data());
156 }
157 
158 //______________________________________________________________________________
160 {
161  while (kTRUE) {
162  Char_t *line = readline("[r]:");
163  if (!line) continue;
164  if (std::string(line) == ".q") break;
165  Execute(line);
166  if (*line) add_history(line);
167  free(line);
168  }
169 }
170 
171 
172 //______________________________________________________________________________
174 {
175  if (!gR) {
176  const Char_t *R_argv[] = {"rootr", "--gui=none", "--no-save", "--no-readline",
177  "--silent", "--vanilla", "--slave"};
178  gR = new TRInterface(7, R_argv, true, false, false);
179  }
181  return gR;
182 }
183 
184 //______________________________________________________________________________
186 {
187  return *TRInterface::InstancePtr();
188 }
189 
190 //______________________________________________________________________________
192 {
193  TString cmd = "is.element('" + pkg + "', installed.packages()[,1])";
194  return fR->parseEval(cmd.Data());
195 }
196 
197 //______________________________________________________________________________
199 {
200  TString cmd = "require('" + pkg + "',quiet=TRUE)";
201  return fR->parseEval(cmd.Data());
202 }
203 
204 //______________________________________________________________________________
206 {
207  TString cmd = "install.packages('" + pkg + "',repos='" + repos + "',dependencies=TRUE)";
208  fR->parseEval(cmd.Data());
209  return IsInstalled(pkg);
210 }
211 
212 
213 #undef _POSIX_C_SOURCE
214 #include <R_ext/eventloop.h>
215 
216 //______________________________________________________________________________
218 {
219  if (!statusEventLoop) {
220  th = new TThread([](void */*args */) {
221  while (statusEventLoop) {
222  fd_set *fd;
223  Int_t usec = 10000;
224  fd = R_checkActivity(usec, 0);
225  R_runHandlers(R_InputHandlers, fd);
226  if (gSystem) gSystem->Sleep(100);
227  }
228  });
230  th->Run();
231  }
232 }
SEXP RComp_assignTokenSym
TRInternalFunction * f
SEXP RComp_getFileCompSym
SEXP RComp_assignBufferSym
void Execute(const TString &code)
Method to eval R code
Definition: TRInterface.cxx:97
Bool_t IsInstalled(TString pkg)
Method to verify if a package is installed
TLine * line
static TRInterface * InstancePtr()
static method to get an TRInterface instance pointer
#define gROOT
Definition: TROOT.h:405
Basic string class.
Definition: TString.h:131
SEXP RComp_completeTokenSym
bool Bool_t
Definition: RtypesCore.h:61
SEXP RComp_assignStartSym
static ROOT::R::TRInterface * gR
Definition: TRInterface.cxx:28
void Binding()
Definition: Binding.C:21
Rcpp::DataFrame df
Definition: TRDataFrame.h:181
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition: TSystem.cxx:437
void Assign(const T &var, const TString &name)
Template method to assign C++ variables into R enviroment
Definition: TRInterface.h:255
Bool_t Install(TString pkg, TString repos="http://cran.r-project.org")
Method to install an R&#39;s package
namespace associated R package for ROOT.
Definition: RExports.h:56
Int_t Run(void *arg=0)
Start the thread.
Definition: TThread.cxx:563
Bool_t Require(TString pkg)
Method to load an R&#39;s package
This is a class to get ROOT&#39;s objects from R&#39;s objects
Definition: TRObject.h:71
rl_completion_func_t * rl_attempted_completion_function
SEXP RComp_retrieveCompsSym
R__EXTERN TSystem * gSystem
Definition: TSystem.h:558
char ** R_custom_completion(const char *text, int start, int end)
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:889
void SetStatus(Bool_t status)
TRObject is a current valid object?
Definition: TRObject.h:97
const Bool_t kFALSE
Definition: RtypesCore.h:90
void ProcessEventsLoop()
Init event loop in a thread to support actions in windows from R graphics system ...
void Interactive()
Method to get a R prompt to work interactively with tab completation support
SEXP rcompgen_rho
#define ClassImp(name)
Definition: Rtypes.h:361
void SetVerbose(Bool_t status)
Method to set verbose mode, that produce extra output
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
#define free
Definition: civetweb.c:1539
static TRInterface & Instance()
static method to get an TRInterface instance reference
Binding operator[](const TString &name)
SEXP RComp_assignEndSym
Mother of all ROOT objects.
Definition: TObject.h:37
char Char_t
Definition: RtypesCore.h:31
TRInterface(const Int_t argc=0, const Char_t *argv[]=NULL, const Bool_t loadRcpp=true, const Bool_t verbose=false, const Bool_t interactive=true)
The command line arguments are by deafult argc=0 and argv=NULL, The verbose mode is by default disab...
Definition: TRInterface.cxx:31
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
Int_t Eval(const TString &code, TRObject &ans)
Method to eval R code and you get the result in a reference to TRObject
Definition: TRInterface.cxx:78
const Bool_t kTRUE
Definition: RtypesCore.h:89
static Bool_t statusEventLoop
Definition: TRInterface.cxx:29
This is a class to pass functions from ROOT to R
char name[80]
Definition: TGX11.cxx:109
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:875
This is a class to create DataFrames from ROOT to R
Definition: TRDataFrame.h:177
const char * Data() const
Definition: TString.h:364