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.
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.
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!