Hi all,
I was playing around with the example to read .root output objects with python. All works well [getKineticEnergyInitial() and other get…() functions]. The only problem i am facing regards when i try to get the parent of a track from MCTrack with getParent(). (code below)
import sys
sys.path.append("/home/luca/Documents/allpix/ROOT/root_install/lib")
# ROOT imports
import ROOT
from ROOT import TFile, gDirectory, gSystem, TClass
import pandas as pd
import numpy as np
import os, sys
import argparse
import os.path as path
#print("Current Working Directory:", os.getcwd())
root_file_name = "/home/luca/Documents/tests/output/ROOT_objects.root"
detector_name = "detector1"
lib_path = "/home/luca/Documents/allpix/allpix-squared/lib/libAllpixObjects.so"
if lib_path is not None: # Try to find Allpix Library
lib_file_name = (str(lib_path))
if (not os.path.isfile(lib_file_name)):
print("WARNING: ", lib_file_name, " does not exist, exiting")
exit(1)
elif os.path.isfile(path.abspath(path.join(__file__ ,"..","..","opt","allpix-squared","lib","libAllpixObjects.so"))): # For native installs
lib_file_name = path.abspath(path.join(__file__ ,"..","..","opt","allpix-squared","lib","libAllpixObjects.so"))
elif os.path.isfile(path.join(path.sep, "opt","allpix-squared","lib","libAllpixObjects.so")): # For Docker installs
lib_file_name = path.join(path.sep, "opt","allpix-squared","lib","libAllpixObjects.so")
else:
print("WARNING: No Allpix Objects Library found, exiting")
exit(1)
if (not os.path.isfile(lib_file_name)):
print("WARNING: no allpix library found, exiting (Use -l to manually set location of libraries)")
exit(1)
if (not os.path.isfile(root_file_name)):
print("WARNING: " + root_file_name + " does not exist, exiting")
exit(1)
gSystem.Load(lib_file_name)
rootfile = ROOT.TFile(root_file_name)
gDirectory.ls()
if not rootfile.GetDirectory("detectors/" + detector_name):
print("\nDetector does not exist. Please choose one of the following detectors:")
gDirectory.cd("detectors")
list_of_keys = gDirectory.GetListOfKeys()
for key in list_of_keys:
print(key.GetName())
exit(1)
McParticle = rootfile.Get('MCParticle')
McTrack = rootfile.Get('MCTrack')
PixelHit = rootfile.Get('PixelHit')
empty_mc_branch = 0
column_names = ["event_ID", "init_x", "init_y", "init_z", "time", "init_kin", "process_name", "particle_ID","parent","volume_origin"]
df = pd.DataFrame(columns=column_names)
data_array = [None]*10
print("Loading in Data...")
for iev in range(0, McTrack.GetEntries()):
#here we enter one event at a time. Each event can either contain or not interactions with the detector
McTrack.GetEntry(iev)
PixelHit.GetEntry(iev)
McParticle.GetEntry(iev)
McTrack_branch = McTrack.GetBranch("global")
PixelHit_branch = PixelHit.GetBranch(detector_name)
McParticle_branch = McParticle.GetBranch(detector_name)
if (not McTrack_branch):
Warning("WARNING: cannot find McTrack branch in the TTree with detector name: " + detector_name + ", exiting")
exit(1)
data_array[0]=iev #add event number
br_mc_track = getattr(McTrack, McTrack_branch.GetName())
br_mc_particle = getattr(McParticle, McParticle_branch.GetName())
if br_mc_track.size() < 1:
empty_mc_branch += 1;
continue
if iev == 257:
print("a")
for mc_track in br_mc_track:
#here we record all the interactions the event had with the detector togheter with the tracks generated
data_array[1] = mc_track.getStartPoint().x()
data_array[2] = mc_track.getStartPoint().y()
data_array[3] = mc_track.getStartPoint().z()
data_array[4] = mc_track.getGlobalStartTime()
data_array[5] = mc_track.getKineticEnergyInitial()
data_array[6] = mc_track.getCreationProcessName()
data_array[7] = mc_track.getParticleID()
data_array[8] = mc_track.getParent()
data_array[9] = mc_track.getOriginatingVolumeName()
# Create a dictionary from the array and column names
new_row = dict(zip(df.columns, data_array))
print(iev)
# Convert the dictionary to a DataFrame and append it
df = pd.concat([df, pd.DataFrame([new_row])], ignore_index=True)
Basically in the results i get what i guess is a null pointer for all cases in which the track is the first one to be generated from the source (and therefore has no parent) and for secondary tracks (which should have a parent) i get None (see picture below).
Am i doing something wrong here? Should i use MCParticle instead to get to the parent track ID?
And is there a function to get the track ID from MCTrack in python (like getTrackID() )? Cause for now i was getting the track ID in python by looking at the mc_track variable which i’m not sure is the best way.
My idea was to use MCTrack alone to get the order of the tracks for one event since it can also track in the whole world simulation volume, contrary from MCParticle, so i could always get the full parent-child hierarchy even for particles generated outside the active detector volume.
Thanks in advance for your time, bests
Luca
PS: on a second note i tried also in a C++ script to get from MCTrack the parent track but there i get a different problem in which i always get the same exact parent ID for all secondary tracks, therefore i suspect that there i am not using getParent() on the correct thing, therefore not getting the actual parent of the tracks but maybe the ID of the same branch every time or of the TTree? I wonder if something like this could be happening here too in python.