Setting leaves names

Hello,

Well, I need an idea because I don’t see any light so far in the following situation (and I apologize if this has been discussed already or if it is a silly question, but I really have no clue and I’ve been reading all the I’ve found):

I have a data file, from where I’m getting different information; let’s say:
[ul] from data file name: file1
I’m getting the following names analysis1, analysis2, analysis3, analysis4 and so on.[/ul]
Inside each analysis there’s information. Let’s say I have for analysis1 the pT, theta. And so on for each analysis (analysis 2 has also pT and theta, analysis3 also…).

Now, I am interested in getting a Branch for file1, where the leaves are organized such as:

[ul] analysis1
pT
theta
analysis2
pT
theta
…[/ul]

(I’m concerned about the analysis names because they already tell me a lot of information) Now, analysis1, analysis2, etc names will vary according to the data file (and let’s say that I have absolutely no idea about what their names would be or how many analysis would I have). If I have another file (file2), as a result I could have different names for the analysis: therefore, analysis1, analysis2 etc… names will be given by sort of a “function” (a definition which will just look into a pool of names and that will give me the ones that coincide with the characteristics I’m looking for, this is already working).

I know that to write a branch with PyROOT I will normally have to do something like

where the imput1 will be given by

and everything is easy if for each imput1[i] I know the corresponding leave name, that I could explicitly write in the t.Branch. But, what can I do in my case? for the analysisN leaves names…

I try to do something like leave_name[i] = whatever function I’m using to get the name (that will give me as output the names analysis1, analysis2, analysis3…) and then

where n is equal to the length of number of analysis I get. But, that doesn’t work. And I’m completely clueless about what could I possibly do.

I thank you in advance for any help :slight_smile: .

Cheers,
Genessis

Genessis,

sorry, not following this at all? Are you trying to write or to read this files? What does not working mean? The code sample that you post has an unbalanced single quote on the last argument? What’s the type of leave_name[n] anyway? How do you intend to define the type of the branch elements to be written? Did you make sure to create a new variable “imput” for each branch? Did you keep all of them alive?

Cheers,
Wim

Hi,

I’m sorry, I know it wasn’t so clear. I have some ideas now, thus I will write here the code I’m trying to use.

I’m trying to write a root file just like this:

[code] rfile = r.TFile(rootfile, “recreate”)
t2 = r.TTree(“Output”,"")

#Get Branch names:
Bnames = indic.keys()
ListOfBranches = []
for bname in Bnames:
invars = indic[bname]
branch = MyBranch()
if not branch.Create(bname,invars): False
ListOfBranches.append(branch)
if branch.leaf:
t2.Branch(branch.name, branch.vars, branch.leaf)
else:
t2.Branch(branch.name, branch.vars)
[/code]

where indic was defined before in my code and MyBranch() is a class I’m using.
Thus,

class MyBranch:
  def __init__(self):
    self.name = None
    self.classname = None
    self.leaf = None
    self.vars = None

    string = False
#Check for strings:
    for var in vvar:   #vvar is list I defined before
      if type(var[1]) == type('st') and len(var[1]) > 1: 
           if len(vvar) > 1:
                 return False
           string = True

#Set global properties:
    self.name = name
    if string:
      self.classname = 'std.string'
      self.leaf = None
    else:
      self.classname = name + "_t"
      self.leaf = ""
      for var in vvar:
        vtype = gettype(var[1])
        self.leaf += var[0] + "/" + vtype + ":"
      self.leaf = self.leaf[:-1]
#Now create branch specific class to hold variables:
      headline = "struct " + self.classname + " { "
      processline = ""
      for var in vvar:
        vtype = getroottype(var[1])
        processline += vtype + "    " + var[0] + "; "
      process = headline + processline + "};"
      gROOT.ProcessLine(process);

    self.vars = eval(self.classname + '()')

    return True

Now, what I want to do is to read from a list its elements (these are strings most of the time) and for each of these elements to have a leaf in my tree.
But, when implementing and running the code I wrote before for some reason it’s not working and I can’t figure it out. I get the following:

[quote] File “/theo/perez/Documents/SModelS/SModelS_Gitolite/get_branch.py”, line 72, in Create
gROOT.ProcessLine(process);
NotImplementedError: (file “(tmpfile)”, line 1) Function can not be defined in a command line or a tempfile
You need to write it in a source file[/quote]

So, I don’t know what to do.

Thank you in advance.

Cheers,
Genessis

Genessis,

that’s an error showing a CINT limitation. It is possible to define a struct like that (as you seem to be doing), but not to define functions on the fly, which CINT seems to be thinking you are doing.

Could you print ‘process’ before calling ProcessLine? Likely there’s a syntax error in there somewhere.

Cheers,
Wim

Dear Win,

Yes, but I don’t find exactly where is the syntax error. I tried to print, I tried to see if I manage a solution and when I don’t get something going to a “None” pointer, I’m getting the following

[quote]
Traceback (most recent call last):
File “./SMSGTest.py”, line 446, in
if not branch.Create(bname,invars): False
File “./SMSGTest.py”, line 220, in Create
self.vars = eval(self.classname + ‘()’)
File “”, line 1, in
NameError: name ‘std’ is not defined[/quote]

So, I think my error could be somewhere here

self.name = name if string: self.classname = 'std.string' self.leaf = None else: self.classname = name + "_t" self.leaf = ""

Mostly like in the ‘std.string’ (I took that from a code similar of someone who did something like this before). Now, I have no idea how to fix it.

Genessis,

I repeat:[quote=“wlav”]Could you print ‘process’ before calling ProcessLine? Likely there’s a syntax error in there somewhere.[/quote]
W/o seeing what line you are ProcessLine()-ing, there is no point in speculating.

(As for the name ‘std’, it’s ROOT.std, unless you imported it into the global space. And on the C++ side, it is of course “std::” not “std.”, although CINT does not need “std::”.)

Cheers,
Wim

Hello,

OK. So I did the following

[code] self.name = name
if string:
self.classname = 'std.string’
self.leaf = None
else:
self.classname = name + "_t"
self.leaf = ""
for var in vvar:
vtype = gettype(var[1])
self.leaf += var[0] + “/” + vtype + ":"
self.leaf = self.leaf[:-1]
#Now create branch specific class to hold variables:
headline = "struct " + self.classname + " { "
processline = ""
for var in vvar:
vtype = getroottype(var[1])
processline += vtype + " " + var[0] + "; "
process = headline + processline + "};"
print process

gROOT.ProcessLine(process);

self.vars = eval(self.classname + ‘()’)

return True[/code]

And I’ve got things like this:

[ul]struct std.string { Char_t [[[ep]],[[em]]]p[[[mup]],[[mum]]]; };
struct std.string { Char_t [[[t],[W]],[[t],[W]]]; };
struct std.string { Char_t [[[t,t]],[[t,t]]]; };
struct std.string { Char_t [[[ b],[Z]],[[ b],[Z]]]; };
struct std.string { Char_t [[[ b],[t],[W]],[[ b],[t],[W]]]; };
struct std.string { Char_t [[[t],[t]],[[t],[t]]]; };
struct [[[W]],[[Z]]]_t { Char_t [[[W]],[[Z]]]; };
Error in TBranch::TBranch: Illegal leaf: [[[W]],[[Z]]]/[[[W]],[[Z]]]/S
struct std.string { Char_t [[[W]],[[Z]]]; };
struct std.string { Char_t [[[ta],[ta]],[[nu],[ta]]]; }; [/ul]

Now, I’ve tried to recognize where was the error trying like printing “hello” inside the if and the else , and realized that the code it’s complaining at

else: self.classname = name + "_t"

Genessis,

well, yeah, and gROOT.ProcessLine() requires valid C++. I don’t know what it is you’re printing, but “std.string” is not a valid struct name, any new struct names certainly should not be based on an existing C++ class name (string), and repeating it for multiple definitions is not going to work either. I also don’t know what’s up with all those brackets; are you trying to create arrays?

My assumption was that you were trying to get to something like this:struct MyBranchesStruct { Char_t ep, em, p, mup, mum; // etc. };Then instantiate that on the python side and use AddressOf() to select individual data members.

But I would not have expected the type to be ‘Char_t’ and do question the use of individual chars per branch? The overhead will be enormous.

Also, in the first post, you seemed to start out with a branches of doubles, now they’re chars?

Why don’t you start with the structure that you want to generate (if one is needed at all and simply use of std::string and std::vector don’t serve), make sure that ProcessLine() can handle it, then work back to generate it from your input?

Cheers,
Wim