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.
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:
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?
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.
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:
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 …