Home | News | Documentation | Download

Filling data to a histogram using TH1F

ROOT Version: 6.20.04
Platform: Any/All
Compiler: Python 2.7.16


I am new to ROOT and python, I’ve been trying to learn it on my own in order to join a research group on campus. The task is to find the invariant mass of a particle using information from two muons. After finding the invariant mass, I have to plot it on a TH1F graph. So far I have been able to do the following (I include the whole code to provide greater context. )

import ROOT

c1 = ROOT.TCanvas('c1' , 'Invariant Mass' )

f = ROOT.TFile ( 'Invariant_Mass.root' , 'recreate' )

h1 = ROOT.TH1F('h1' , 'Invariant Mass Distribution; Mass; Number of Objects', 100, 200, 700)

with open ('muons.txt','r') as f1:
    for line in f1:
        if line.startswith('Run'):
            eventTitle = line
        if line.startswith('m1'):
            dataset = line.split(' ')
            pt1 = float(dataset[2])
            eta1 = float(dataset[3])
            phi1 = float(dataset[4])
            m1 = float(dataset [5])
        if line.startswith('m2'):
            dataset = line.split(' ')
            pt2 = float(dataset[2])
            eta2 = float(dataset[3])
            phi2 = float(dataset[4])
            m2 = float(dataset [5])
            muon1 = ROOT.TLorentzVector()
            muon1.SetPtEtaPhiM(pt1,eta1,phi1,m1)
            muon2 = ROOT.TLorentzVector()
            muon2.SetPtEtaPhiM(pt2,eta2,phi2,m2)
            m1 = [muon1.E(),muon1.Px(),muon1.Py(),muon1.Pz()]
            m2 = [muon2.E(),muon2.Px(),muon2.Py(),muon2.Pz()]
            myParticle = ROOT.TLorentzVector()
            myParticle = muon1 + muon2 
            double_mass = myParticle.M()
            h1.Fill(double_mass)
            
            f = open('mass.txt','a')
            f.write(eventTitle +'\nInvariant Mass:\n' + str(double_mass) + '\n' + '\n----------------\n')
            print (eventTitle + '\n' + '4-Momentum for Muon1: \n' + ' \n' + str(m1) + '\n' + '\n4-Momentum for Muon2: \n' + '\n' + str(m2) + '\n' +'\nInvariant mass: \n' + '\n' + str(double_mass) + '\n--------------------- \n')

h1.Draw()
c1.Update()

h1.Write()

print('\nDone')

I’m getting back the error,

 h1.Fill(double_mass)
AttributeError: 'CPyCppyy_NoneType' object has no attribute 'Fill'

Not sure what this means or how I would be able to fix it. Prior to adding the changes to plot the invariant mass, the code worked perfectly and pushed the data out to a text file and the console.

Any help would be greatly appreciated.

Thank you

Hi @Daniel_Ricardo_Vega,
and welcome to the ROOT forum!

The problem is that

f = open('mass.txt','a')

overwrites the contents of f, so the TFile that you create at the beginning of the script is destroyed (therefore closed), and closing the TFile also deletes the h1 histogram that is contained in it.

ROOT has a not-always-obvious object ownership model when it comes to files and their contents. Basically, histograms and other TObjects belong to the file in which they reside. After lines 3 and 4 execute, h1 belongs to f. When variable f is overwritten, f is closed and it brings h1 with it, leaving variable h1 pointing to nothing, i.e. “NoneType”.

A simple way to debug these issues is to step through the execution of your program with a python debugger (I suggest ipdb rather than pdb because of the nicer syntax highlighting), to check the values of the different variables at different steps in the program execution.

Hope this clarifies things a little bit.
Cheers,
Enrico

1 Like

Hi @eguiraud,

Yup that was it, it seems like it was a small mistake. Thank you nonetheless and I will be taking your advice on that debugger!