Find address of variable using name

Hi, and thank you in advance for reading this. Double thanks for actual helping! :grin:

I have an Rtuple where variables are stored with names such as “PionMomentum[100]”, “KaonMomentum[100]” and analogously for many other variables.

Now say that I want to access momentum for a particle whose type has been
decided in my code
.
In other terms, my code can compute easily a variable name as a string,
but this of course is not the same as the variable name itself. How can I do that?
Is there a way in ROOT to do this:

std::string wantThisParticle = std::string("KaonMomentum"); // or a TString, or whatever)
double* rootVarAddress = (double*)someRootGetAddress(wantThisParticle);
double kaonP = rootVarAddress[5]; // get momentum of Kaon 5

For now what I do is establish myself a std::map<string, pointer> when I do all my SetBranchAddress calls, but doing this and consulting it is heavy, and smells badly as duplicating something that must be in ROOT already.

I have been reading lots of ROOT manuals, finding a histogram in a directory by name seems easy, but finding a TLeaf or TBranch is another pair of (T)leaves.
Thank you again!

Not sure what you mean, but to read from a tree you do

  tree->SetBranchAddress("varNameInTree",&varNameInMyCode);

i.e., the variable name in your code does not have to be the same as the name that was used in the tree --but of course, the variable types (int, float,…) have to be the same. See a complete example on how to read all (or any) entries in the function void tree1r() in this example:
https://root.cern/doc/master/tree1_8C_source.html
If you want, say, entry 5, just do t1->GetEntry(4); (entry numbers start from zero) instead of a loop over all entries, and so on.

Thank you for your answer, but I think I have not been clear enough.

I already know how to read from disk my data, and the variable where ROOT puts my data may have of course any name I like.

My point was:
I have several blocks of data (vectors, if you want) in ROOT memory (they have already been read from disk) and they have names, similar or not.
What I need to do, is to decide programmatically from which one I have to access my data.
I am able to code
double pMom = PionMomentum[5] ;
or
double pMom = KaonMomentum[5];

but I need to decide which one while the code runs. Not beforehand.

In other words, I want to ask ROOT the pointer where some variable named “ANYTHING”, that has already been read from disk, is stored.

Since these are MY variables, I used them when I made my SetBranchAddress calls,
of course I know where they are. Only, I would prefer to ask ROOT, that must know it because ROOT uses those addresses at any other event it reads. It has cached them
somewhere at SetBranchAddress times. Where?

I hope this is clearer. >-)

Let me try to be maximally clear, referring to your example in the tutorial.
At line 95 I see:

 hpx->Fill(px);

This works, but it is not what I want. What I want is:

double* oDear = (double*)pleaseTellMe("px");
hpx->Fill(*oDear);

I would like to know the real name of ROOT function pleaseTellMe, assuming it exists.
And, no, I prefer not to do:

double* oDear = &px;

This is, in some way, what I am doing now. Only, I do not like it, it’s tiring, and I would bet that the above unknown ROOT function exists.
Thanks again everybody!

So you mean that in

hpx->Fill(px);

you don’t know in advance whether you need to fill px, or py, or some other variable? you want to somehow determine, or ask the ‘user’, what variable to use?
For that, in my example

tree->SetBranchAddress("varNameInTree",&varNameInMyCode);

the actual name “varNameInTree” (e.g. “px”) will be known only during runtime (e.g. it is read or somehow stored in a string or a char* called “whatIwant”); in this case you could do

  double var;  // generic name, of the type of any acceptable leaf name in the tree
  string whatIwant;
  cout << "enter the variable name ";
  cin >> whatIwant;
  tree->SetBranchAddress(whatIwant.c_str(),&var);

but you have to make sure that the string contents (e.g. “px”) actually match the name of a branch/leaf in the tree (and var should be the correct type, double in this example).

By the way, to fill a TTree you do tree->Fill(); without arguments, which will fill all active branches. hpx->Fill("px"); is for a histogram. But since you said you have an Rtuple I assumed we are talking about a tree.

Spending some time hacking TTree::Show gave me the answer, that I write here, somewhat edited to remove my fumbling around.
Just in case somebody else may be interested:

 oot -l /tmp/test.root
root [0] 
Attaching file /tmp/test.root as _file0...
root [1] TTree* tree = (TTree*)_file0->Get("ntp1");
root [6] tree->GetEntry(1)
(Int_t)1902
root [20] TLeaf* zMc = (TLeaf*)tree.FindLeaf("zMc")
root [21] Float_t* whereIs = (Float_t*)zMc->GetValuePointer()
root [22] .p *whereIs                // don't know what this is
(Float_t)(-1.00000000000000000e+02)
root [23] whereIs++
(Float_t*)0x2086f6e8
root [24] .p *whereIs
(Float_t)(-6.36714696884155273e-01)
root [25] tree->GetEntry(11)
(Int_t)1502
root [26] .p *whereIs
(Float_t)(-1.04294419288635254e+00)
root [27] tree->GetEntry(1)
(Int_t)1902
root [28] .p *whereIs
(Float_t)(-6.36714696884155273e-01)
root [29] tree->GetEntry(57)
(Int_t)2022
root [30] .p *whereIs
(Float_t)(-2.05433964729309082e+00)
...and so on...

This method seems less efficient than my caching-by-hand the addresses of vectors, because I do it only once before my event loop.
Mmmh…also here I can do that of course…but I am exposed to changes in ROOT innards. Somebody might remove the “-100” in the future.
After all, since my method is already coded and debugged, I will stay with that for now.
Cheers!