Defining functions in rootlogon.py

Hi,

I created the file ~/.rootlogon.py shown here, which defines some functions I would like to use when plotting from a TTree:

[code]print “it found me”

from math import sqrt, pi

def deltaPhi(phi1, phi2):
PHI = abs(phi1-phi2)
if PHI<=pi:
return PHI
else:
return 2*pi-PHI

def deltaR(eta1, phi1, eta2, phi2):
deta = eta1-eta2
dphi = deltaPhi(phi1,phi2)
return sqrt(detadeta + dphidphi)[/code]

And when I execute a python root macro it appears to successfully load rootlogon.py because,

$ python macros/plotFromMultipleFiles.py it found me ...

The problem is when I try to use the functions in a

in that python script, I get a complaint:

Why does it not see the function in ~/.rootlogon.py? Or is there some other problem?

Hi,

python functions are not known to the TFormula parser, nor to CINT. I’m not sure whether it would work (i.e. if the code would be known) if it is wrapped in a TF1/2/3 (like it does for TTree::Fit), but if functions can be made known to the parser that way, than that would work.

Cheers,
Wim

So if I’m running a pyroot macro to make plots, I should still specify functions in a rootlogon.C and those functions will be recognized in the pyroot script?

I’m having trouble with this because I created a rootlogon.C in the current dir:

[code]cout << “found me.”

float deltaPhi(float phi1, float phi2) {
float PHI = abs(phi1-phi2);
if (PHI<=3.14159265)
return PHI;
else
return 2*3.14159265-PHI;
}

float deltaR(eta1, phi1, eta2, phi2) {
float deta = eta1-eta2;
float dphi = deltaPhi(phi1,phi2);
return (detadeta + dphidphi)^0.5;
}[/code]

And then I run my script and it doesn’t print “found me” from the rootlogon, and it doesn’t find the function defined there:

$ python macros/plotFromMultipleFiles.py ... Error in <TTreeFormula::Compile>: Bad numerical expression : "deltaR(PHOLEAD_eta,PHOLEAD_phi,jetEta[0],jetPhi[0])" done.

I should add that the python script I’m running does an “import ROOT” - does that not actually cause it to run rootlogon.C? What do I have to do to get it to do that?

Hi,

Philippe or Axel can perhaps clarify in detail, but as far as I understand there are three different parsers at play here (the TFormula one, CINT, and Python), then four different places where functions can live (pre-defined, loaded from a dictionary, interpreted by CINT, interpreted by Python). I do not know which combinations work, just that the Python ones won’t without something extra.

As for “import ROOT” … technically, no, it doesn’t run rootlogon.C, but it will the moment you’ll use something other than gROOT out of it. So one you touch e.g. a class, say ROOT.TTree, it will run rootlogon.C.

Cheers,
Wim

Hi,

Actually the function defined as TFormula (TF1, TF2, etc.) are not usable by TTreeFormula (they have a slightly different use/semantic).

So the only way to have user defined function visible by TTreeFormula (and hence by TTree::Draw, TTree::Scan), is to have them known by CINT.

Cheers,
Philippe

Philippe,

thanks; but does it have to be a compiled function bound through a dictionary, or will an interpreted function in rootlogon.C work?

Cheers,
Wim

Hi Wim,

It does not matter (to TTreeFormula) whether the code is interpreter or compiled (well except that interpreted code is slower).

Cheers,
Philippe.

Just to provide an example for others, here is a solution that finally worked for me.
In my python root script I put at the top:

from ROOT import TFile, TH1F, TH2F, TH3F, TTree, gROOT from os import path if path.exists('rootlogon.C'): gROOT.Macro('rootlogon.C') # Run ROOT logon script

This way it loads up the rootlogon.C, and the functions are found to be used in drawing from a ttree, like so:

My rootlogon.C:

[code]rootlogon() {
cout << “Ran rootlogon.C” << endl;
}

float deltaPhi(float phi1, float phi2) {
float PHI = fabs(phi1-phi2);
if (PHI<=3.14159265)
return PHI;
else
return 2*3.14159265-PHI;
}

float deltaR(float eta1, float phi1, float eta2, float phi2) {
float deta = eta1-eta2;
float dphi = deltaPhi(phi1,phi2);
return sqrt(detadeta + dphidphi);
}[/code]

Hi,

okay, now I see what the issue is with rootlogon.C not being loaded in your case: the code in ROOT.py tries to be smart and only loads rootlogon.C if no rootlogon.py is found …

Cheers,
Wim