Having Friend Trees location specified by relative path and not absolute path

Dear Experts,

I have two root files with two trees, one of which is a friend to another. Is there a way to specify the paths in a relative way and not absolute? This is important for example if I transfer these files to some other location and I want to access the friend tree branches.

Thanks,
Davide

Hi @Davide_Lancierini,

Thank you for your question. It would be great if you can add a small snippet explaining what you want to achieve. In the meantime, I will add @pcanal in the loop.

Cheers,
Dev

Dear @devajith , here is a MRE:

example.py (1.9 KB)

Try:

mainTree.AddFriend(friendTreeName, friendFileName)

Thanks @pcanal for the suggestion. I tried but no luck, same error as before.

I don’t think the full path is being saved. You are running the script from a ā€œbaseā€ folder and then move the files to the ā€œfolderā€ subfolder (within ā€œbaseā€), and since you open the main file from this base folder (from which you run the script), it still thinks that the friend is in the same folder from which you are running the script. i.e. ā€œbaseā€ (as both files were there when you made the friendship). In other words, imagine the friendship is saved saying that the friend is in ā€œ./ā€, but for Python, since you are still in the same base folder, ā€œ./ā€ is still the base folder, not ā€œfolderā€).
Try just changing to ā€˜folder’ before reading the files (you can do it inside the script with os.chdir('folder')) --note that this fails if you try this with your full example script, in which you are also creating and moving the files… not sure why; but if you just make a script to read the files (adding the chdir line), it works ok; it doesn’t matter where they are (their absolute path), as long as both are on the same folder where you (or anybody) is running the script, or you change into that folder inside the script.
With this shorter script (after creating and moving the files from /mnt/c/ to /mnt/c/folder, with the script saved and run from /mnt/c/):

import os, sys
os.chdir("folder")
print('opening mainfile')
mainFile = r.TFile.Open(f"{mainFileName}")
print('getting maintree')
mainTree = mainFile.Get(mainTreeName)
print('getting list of friends')
lof = mainTree.GetListOfFriends()
print('printing friends')
for i, elt in enumerate(lof):
    print(lof.At(i).GetTitle())
mainTree.val1
mainTree.val2

I get

/mnt/c/$  py -i example.py
opening mainfile
getting maintree
getting list of friends
printing friends
friend_file.root
>>>

again, the ā€œbase folderā€, where the script and the root files are, can be anywhere, as long as the root files are either on that same base folder, or in the same subfolder (e.g. ā€œfolderā€) of that base folder (and you chdir to that ā€œfolderā€ subfolder within the script).

Uhm.. Thanks for the proposed solution @dastudillo , I’m gonna play with it. I wonder though how much of it depends on from which folder you run the example.py from. In my MRE I neglected that aspect and simplified the example a lot with respect to the normal use case: usually we store the data in storage disks and we run analysis scripts from different locations/directories therefore I’m not sure your fix would work..

I wonder if something on the lines of lof.At(i).SetTitleName(f"./{friendFileName}") or more elegant could do it..

PS: what value has the variable mainFileName in your example?

PPS: this example needs os.chdir("folder") not to throw error, i.e. the folder needs to exist on the machine where you are opening the friends, I’ll check if that’s always the case in our use cases

mainFileName is the same as in your example (I forgot to paste that here too):
mainFileName="file.root"
My example needs ā€œfolderā€ because that’s what you had in your example. The whole point is to just put the befriended root files on the same folder (no matter where, as I said) and just chdir to that folder when you need to open them. If after that you need to read other files/folders, I suppose just doing chdir accordingly should work.

Perfect. In my application, friends are always at the same level of main trees, so I’ll add the chdir in the file loader and see how it works out.
Thanks!

1 Like