Skip to content
This repository has been archived by the owner on Jan 31, 2022. It is now read-only.

"Bug" Report: Error Bars on anaUltra*.py Scripts #61

Open
1 of 2 tasks
bdorney opened this issue Jan 17, 2018 · 2 comments
Open
1 of 2 tasks

"Bug" Report: Error Bars on anaUltra*.py Scripts #61

bdorney opened this issue Jan 17, 2018 · 2 comments

Comments

@bdorney
Copy link
Contributor

bdorney commented Jan 17, 2018

Brief summary of issue

We've migrated all our DAQ (and I guess also DQM?) machines to cc7 which defaults to ROOT v6.X. In this version of ROOT by default TH1::Sumw2() is automatically set, see the TH1 Class Documentation. This causes error bars of some of our histograms to not be set correctly.

Types of issue

  • Bug report (report an issue with the code)
  • Feature request (request for change which adds functionality)

Expected Behavior

For a counting experiment (almost all of our scan routines) the error bar should go as sqrt(N) where N is the bin content.

Current Behavior

Due to the differences between ROOT 6.X and 5.34 the TH1::Sumw2() method is automatically called.

Our analysis routines usually use the Int_t TH1::Fill(Double_t x,Double_t w ) method for storing values in the histogram where x and w come from the input TTree object. However this is only being called once per bin so the error bar ends up equalling w e.g. the sum of weights squared is a sum over one number.

See for example:

Steps to Reproduce (for bugs)

  1. Run any anaUltra script on a machine where ROOT is v6.X or higher.
  2. Look at the error bars on the produced plots

Possible Solution (for bugs)

Proposal 1

Call TH1::SetDefaultSumw2(False) at the start of each script. Although this is a static ROOT function and I'm not sure how that will play in python.

If it works this is the simplest fix.

Proposal 2

Use event.indepVar to determine the corresponding bin in the histogram, e.g.

for idx in range(1, Histo.GetNbinsX()+1):
    if (Histo.GetBinLowEdge(1) + idx*Histo.GetBinLowEdge(1) ) <= event.indepVar and indepVar < (Histo.GetBinLowEdge(1) + (idx+1)*Histo.GetBinLowEdge(1) ):
        Histo.SetBinContent(idx, event.depVar)

Disadvantage is that this is pretty slow...

Proposal 3

Change all TH1 objects to TGraph objects (or inherited classes, e.g. TGraphErrors or TGraphAsymErrors) and use the TGraph::SetPoint(...) method for plotting from the TTree.

If you draw the TGraph object you could then use the TGraph::GetHistogram() method to return a TH1 if it's absolutely necessary.

Context (for feature requests)

This is particularly a problem when we are fitting distributions since the error bars on the data points will be accounted in the fitting and having each point as N +/- N is probably not going to give good fit results.

Your Environment

  • Version used: I think any commit will have this problem
  • Shell used: zsh
@jsturdy
Copy link
Contributor

jsturdy commented Jan 17, 2018

Regarding proposal 1: Using r.TH1.SetDefaultSumw2(False) will work in python
EDIT: Actually, the better (more correct) thing to do would also be to explicitly set the errors whenever using a SetBinContent type assignment

@bdorney
Copy link
Contributor Author

bdorney commented Mar 28, 2018

There should be one spot in fitScanData.py that should also have the error bars updated:

self.scanHistos[event.vfatN][event.vfatCH].Fill(charge,event.Nhits)

I would suggest fixing this by finding the chargeBin as was done in anaUltraScurve.py. To do so you'll need to get the list of bin edges in terms of charge, e.g. replace Y with X:

listOfBinEdgesY = {}
for vfat in vfatHistos:
listOfBinEdgesY[vfat] = [ vfatHistos[vfat].GetYaxis().GetBinLowEdge(binY)
for binY in range(1,vfatHistos[vfat].GetNbinsY()+2) ] #Include overflow

Then chargeBin can be determined via::

chargeBin = first_index_gt(listOfBinEdgesY[event.vfatN], charge)-1

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants