0

So I am using pyroot to do data analysis. The analysis code chain runs different plugins on the data and outputs them to a root file, storing the output of each plugin in to their own TDirectoryFile within the root file. I wrote a function that takes the name of the root file and the name of the plugin and should return the plugins TDirectoryFile. However it returns instead a NoneType, and then crashes as soon I try to do anything with the object.

from ROOT import *

def getPluginData(fName,pName):
    tfile=TFile("Analyzer.root")
    plugin= tfile.Get("MuIndNeuSpallPlugin")
    #outputs <class 'ROOT.TDirectoryFile'>
    print type(MuIndNeuSpallPlugin)
    return plugin


#This should be a  <class 'ROOTTDirectoryFile'.>, but is a NoneType instead
MuIndNeuSpallPlugin=getPluginData("Analyzer.root","MuIndNeuSpallPlugin")
gboffi
  • 22,939
  • 8
  • 54
  • 85
  • Does `print(tfile.ls())` after you initialize the tfile show that `MuIndNeuSpallPlugin` is a key? `Get()` returns None if the key is not valid – jarcobi889 Feb 22 '17 at 21:03
  • So MuIndNeuSpallPlugin is definitely a key. In fact the my original code didn't use a function works fine. It's like when python leaves the scope of the function it just forgets what plugin is, and returns a NoneType instead. – Mage Davee Feb 22 '17 at 21:47
  • Do you by chance have that original code you could add to the question for comparison? If not, could you run `tfile.ls()` just for kicks and giggles and see what it spits out? Everything else seems to be in order that I can see, besides not using the variables `fName` and `pName`. – jarcobi889 Feb 22 '17 at 21:57
  • So on my post on root talk a poster explained why this happening(also a more complete version of my code is posted there which addresses your concerns.).https://root.cern.ch/phpBB3/posting.php?mode=reply&f=14&t=23242 . But basically tfile is defined in the function, and when it descopes c++ deletes tfile, which contains my plugin TDirectoryFile. So basically pyroot breaks python. Also I didn't notice I didn't reinsert pName in fName back in, my bad. I replaced them to debug. – Mage Davee Feb 22 '17 at 23:34
  • Looks like I have to have a login to read that post, but that's okay. So did they help you fix your code? Or is it still broken? – jarcobi889 Feb 22 '17 at 23:37
  • Sorry wrong link((https://root.cern.ch/phpBB3/viewtopic.php?f=14&t=23242)) this one should be public. I found a work around, but basically pyroot breaks python a bit. – Mage Davee Feb 22 '17 at 23:48

1 Answers1

0

So on my post on root talk(https://root.cern.ch/phpBB3/viewtopic.php?f=14&t=23242)a poster explained why this happens. Basically tfile is defined in the function and when the function descopes, its usage count is reduced to 0 and its c++ version is deleted. The plugin, which is TDirectoryFile, is contained in the tfile, so when tfile gets deleted it goes with it. The solution is define tfile in global scope, pass it instead of a string of it's file name.

ROOT import *

def getPluginData(tfile,pName):
    plugin= tfile.Get(pName)
    print type(MuIndNeuSpallPlugin)
    return plugin
tfile=TFile("Analyzer.root")
MuIndNeuSpallPlugin=getPluginData(tfile,"MuIndNeuSpallPlugin")

This works, but I feel this counter intuitive or at least not very pythonic, and kind of breaks python.

  • Why define `getPluginData` at all? Why not just use `MuIndNeuSpallPlugin=tfile.Get("MuIndNeuSpallPlugin")`? That seems simpler to me. – cco Feb 23 '17 at 01:48
  • Because I have a lot root files, and each root file has many plugins, I only posted strip down version of code for readability. – Mage Davee Feb 24 '17 at 16:59