Skip to content
Snippets Groups Projects
Unverified Commit 620df99c authored by lcorcodilos's avatar lcorcodilos Committed by GitHub
Browse files

Merge pull request #16 from lcorcodilos/test_dev

Development from creation of HSF DAWG standardized examples
parents 0a985bf8 2493a32c
Branches
Tags v0.1.1
No related merge requests found
Showing with 651 additions and 127 deletions
...@@ -30,6 +30,8 @@ jobs: ...@@ -30,6 +30,8 @@ jobs:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
- name: Setup environment - name: Setup environment
run: | run: |
sudo apt-get install graphviz libgraphviz-dev
sudo ln -s /usr/lib/x86_64-linux-gnu/libclang-6.0.so.1 /usr/lib/x86_64-linux-gnu/libclang.so
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install virtualenv pip install virtualenv
python -m virtualenv timber-env python -m virtualenv timber-env
......
This diff is collapsed.
...@@ -28,6 +28,19 @@ namespace analyzer { ...@@ -28,6 +28,19 @@ namespace analyzer {
return v; return v;
} }
RVec<ROOT::Math::PtEtaPhiMVector> TLvector(RVec<float> pt,RVec<float> eta,RVec<float> phi,RVec<float> m) {
RVec<ROOT::Math::PtEtaPhiMVector> vs;
for (int i = 0; i < pt.size(); i++) {
ROOT::Math::PtEtaPhiMVector v(pt[i],eta[i],phi[i],m[i]);
vs.push_back(v);
}
return vs;
}
float transverseMass(float MET_pt, float obj_pt, float MET_phi, float obj_phi) {
return sqrt(2.0*MET_pt*obj_pt-(1-cos(deltaPhi(MET_phi,obj_phi))));
}
double invariantMass(ROOT::Math::PtEtaPhiMVector v1, ROOT::Math::PtEtaPhiMVector v2) { double invariantMass(ROOT::Math::PtEtaPhiMVector v1, ROOT::Math::PtEtaPhiMVector v2) {
return (v1+v2).M(); return (v1+v2).M();
} }
......
...@@ -3,7 +3,7 @@ Commonly used functions available for use that can be generic or TIMBER specific ...@@ -3,7 +3,7 @@ Commonly used functions available for use that can be generic or TIMBER specific
@{ @{
''' '''
import json, ROOT, os, subprocess import json, ROOT, os, subprocess, TIMBER
from ROOT import RDataFrame from ROOT import RDataFrame
from TIMBER.Tools.CMS import CMS_lumi, tdrstyle from TIMBER.Tools.CMS import CMS_lumi, tdrstyle
from contextlib import contextmanager from contextlib import contextmanager
...@@ -79,7 +79,7 @@ def StitchQCD(QCDdict,normDict=None): ...@@ -79,7 +79,7 @@ def StitchQCD(QCDdict,normDict=None):
for hkey in QCDdict[k].keys(): for hkey in QCDdict[k].keys():
QCDdict[k][hkey].Scale(normDict[k]) QCDdict[k][hkey].Scale(normDict[k])
# Stitch # Stitch
out = HistGroup("QCD") out = TIMBER.Analyzer.HistGroup("QCD")
for ksample in QCDdict.keys(): for ksample in QCDdict.keys():
for khist in QCDdict[ksample].keys(): for khist in QCDdict[ksample].keys():
if khist not in out.keys(): if khist not in out.keys():
...@@ -161,32 +161,32 @@ def AsciiEncodeDict(data): ...@@ -161,32 +161,32 @@ def AsciiEncodeDict(data):
ascii_encode = lambda x: x.encode('ascii') if isinstance(x, unicode) else x ascii_encode = lambda x: x.encode('ascii') if isinstance(x, unicode) else x
return dict(map(ascii_encode, pair) for pair in data.items()) return dict(map(ascii_encode, pair) for pair in data.items())
def ConcatCols(self,colnames,val='1',connector='&&'): def ConcatCols(colnames,val='1',connector='&&'):
'''Concatenates a list of column names evaluating to a common `val` (usually 1 or 0) '''Concatenates a list of column names evaluating to a common `val` (usually 1 or 0)
with some `connector` (boolean logic operator). with some `connector` (bool logic operator).
@param colnames ([str]): List of column names. @param colnames ([str]): List of column names.
@param val (str): Value to test equality of all columns. Defaults to '1'. @param val (str): Value to test equality of all columns. Defaults to '1'.
@param connector (str): C++ boolean logic operator between column equality checks. Defaults to '&&'. @param connector (str): C++ bool logic operator between column equality checks. Defaults to '&&'.
Returns: Returns:
str: Concatenated string of the entire evaluation that in C++ will return a bool. str: Concatenated string of the entire evaluation that in C++ will return a bool.
''' '''
concat = '' concat = ''
for i,c in enumerate(colnames): for c in colnames:
if concat == '': if concat == '':
concat = '((%s==%s)'%(c,val) concat = '((%s==%s)'%(c,val)
else: else:
concat += ' %s (%s==%s)'%(connector,c,val) concat += ' %s (%s==%s)'%(connector,c,val)
if concat != '': if concat != '':
concat += ')' concat += ')'
return concat return concat
def GetHistBinningTuple(h): def GetHistBinningTuple(h):
'''Gets the binning information for a histogram and returns it '''Gets the binning information for a histogram and returns it
as a tuple ordered like the arguements to construct a new histogram. as a tuple ordered like the arguments to construct a new histogram.
Supports TH1, TH2, and TH3. Supports TH1, TH2, and TH3.
@param h (TH1): Input histogram from which to get the binning information. @param h (TH1): Input histogram from which to get the binning information.
...@@ -195,7 +195,7 @@ def GetHistBinningTuple(h): ...@@ -195,7 +195,7 @@ def GetHistBinningTuple(h):
TypeError: If histogram does not derive from TH1. TypeError: If histogram does not derive from TH1.
Returns: Returns:
tuple(tuple, int): First element of return is the binning and the second element is the dimensionality. tuple(tuple, int): First element of return is the binning and the second element is the dimension.
''' '''
# At least 1D (since TH2 and TH3 inherit from TH1) # At least 1D (since TH2 and TH3 inherit from TH1)
if isinstance(h,ROOT.TH1): if isinstance(h,ROOT.TH1):
...@@ -272,7 +272,7 @@ def DictStructureCopy(inDict): ...@@ -272,7 +272,7 @@ def DictStructureCopy(inDict):
newDict = {} newDict = {}
for k1,v1 in inDict.items(): for k1,v1 in inDict.items():
if type(v1) == dict: if type(v1) == dict:
newDict[k1] = dictStructureCopy(v1) newDict[k1] = DictStructureCopy(v1)
else: else:
newDict[k1] = 0 newDict[k1] = 0
return newDict return newDict
...@@ -288,7 +288,7 @@ def DictCopy(inDict): ...@@ -288,7 +288,7 @@ def DictCopy(inDict):
newDict = {} newDict = {}
for k1,v1 in inDict.items(): for k1,v1 in inDict.items():
if type(v1) == dict: if type(v1) == dict:
newDict[k1] = dictCopy(v1) newDict[k1] = DictCopy(v1)
else: else:
newDict[k1] = v1 newDict[k1] = v1
return newDict return newDict
......
#include "TIMBER/Framework/include/common.h"
#include "ROOT/RVec.hxx"
#include <Math/Vector4Dfwd.h>
#include <Math/GenVector/LorentzVector.h>
using namespace ROOT::VecOps;
// For ex5.py and ex6.py
// Muon pair mass for all combinations of muons with opposite sign
RVec<float> InvMassOppMuMu (RVec<float> Muon_pt, RVec<float> Muon_eta, RVec<float> Muon_phi, RVec<float> Muon_mass, RVec<float> Muon_charge) {
int nMuon = Muon_pt.size();
int mu0idx, mu1idx;
ROOT::Math::PtEtaPhiMVector mu0LV;
ROOT::Math::PtEtaPhiMVector mu1LV;
RVec<RVec<int>> comboIdxs = Combinations(Muon_pt,2);
RVec<float> invMass;
for (int i = 0; i < comboIdxs[0].size(); i++) {
mu0idx = comboIdxs[0][i];
mu1idx = comboIdxs[1][i];
if (Muon_charge[mu0idx] != Muon_charge[mu1idx]) {
mu0LV.SetCoordinates(Muon_pt[mu0idx], Muon_eta[mu0idx], Muon_phi[mu0idx], Muon_mass[mu0idx]);
mu1LV.SetCoordinates(Muon_pt[mu1idx], Muon_eta[mu1idx], Muon_phi[mu1idx], Muon_mass[mu1idx]);
invMass.push_back((mu0LV+mu1LV).M());
}
}
return invMass;
}
// (Lepton_pt > 10) && (analyzer::DeltaR(Lepton_eta, Jet_eta, Lepton_phi, Jet_phi) < 0.4)
RVec<float> CloseLepVeto (RVec<float> Lepton_pt, RVec<float> Lepton_eta, RVec<float> Lepton_phi, RVec<float> Jet_eta, RVec<float> Jet_phi) {
RVec<bool> jet_bool_vect;
bool bool_pt, bool_deltaR, found_lep;
for (int ijet = 0; ijet < Jet_eta.size(); ijet++) {
found_lep = false;
for (int ilep = 0; ilep < Lepton_pt.size(); ilep++) {
bool_pt = Lepton_pt[ilep] > 10;
bool_deltaR = DeltaR(Lepton_eta[ilep], Jet_eta[ijet], Lepton_phi[ilep], Jet_phi[ijet]) < 0.4;
if (bool_pt && bool_deltaR){
found_lep = true;
}
}
jet_bool_vect.push_back(found_lep);
}
return jet_bool_vect;
}
int NonZlep(RVec<ROOT::Math::PtEtaPhiMVector> Lepton_vect, RVec<int> Lepton_pdgId, RVec<int> Lepton_charge) {
RVec<RVec<int>> combos = Combinations(Lepton_vect,3); // build combinations where first two are the Z
int NonZlep_idx = -1;
float deltaMZ = 1000.; // start at large value for comparison
float dMZ;
bool sameFlavOppSign;
for (int i = 0; i < combos[0].size(); i++) { // loop over combinations
dMZ = abs(91.2-(Lepton_vect[combos[0][i]]+Lepton_vect[combos[1][i]]).M());
sameFlavOppSign = (Lepton_pdgId[combos[0][i]] == -1*Lepton_pdgId[combos[1][i]]);
if ((dMZ < deltaMZ) && sameFlavOppSign) {
deltaMZ = dMZ;
NonZlep_idx = combos[2][i];
}
}
return NonZlep_idx;
}
\ No newline at end of file
'''Plotting the Missing ET (or any event level variable).'''
import time
start = time.time()
#---------------------
from TIMBER.Analyzer import analyzer
a = analyzer('examples/GluGluToHToTauTau_full.root')
h = a.DataFrame.Histo1D('MET_pt')
h.Draw('hist e')
#---------------------
print ('%s secs'%(time.time() - start))
\ No newline at end of file
'''Plotting the Jet pT (or any variable that is a per-event array).'''
import time
start = time.time()
#---------------------
from TIMBER.Analyzer import analyzer, HistGroup
a = analyzer('examples/GluGluToHToTauTau_full.root')
h = a.DataFrame.Histo1D('Jet_pt')
h.Draw('hist e')
#---------------------
print ('%s secs'%(time.time() - start))
\ No newline at end of file
'''Plotting the Jet pT for jets that have a jet pT > 20 GeV and abs(jet eta) < 1.0.'''
import time
start = time.time()
#---------------------
from TIMBER.Analyzer import analyzer, HistGroup
a = analyzer('examples/GluGluToHToTauTau_full.root')
a.Define('JetSel_pt','Jet_pt[abs(Jet_eta) < 2.4]')
h = a.DataFrame.Histo1D('JetSel_pt')
h.Draw('hist e')
#---------------------
print ('%s secs'%(time.time() - start))
\ No newline at end of file
'''Plotting the Missing ET for jets[sic?] with at least 2 jets with Jet pT > 40 and abs(jet Eta) < 1.0'''
import time
start = time.time()
#---------------------
from TIMBER.Analyzer import analyzer
a = analyzer('examples/GluGluToHToTauTau_full.root')
a.Cut('twoHighPtJets','Sum(Jet_pt > 40 && abs(Jet_eta) < 1.0) >= 2')
h = a.DataFrame.Histo1D('MET_pt')
h.Draw('hist e')
#---------------------
print ('%s secs'%(time.time() - start))
\ No newline at end of file
'''Plot the opposite-sign muon pair mass for all combinations of muons'''
import time
start = time.time()
#---------------------
from TIMBER.Analyzer import analyzer
from TIMBER.Tools.Common import CompileCpp
CompileCpp('benchmark/ex.cc')
a = analyzer('examples/GluGluToHToTauTau_full.root')
a.Cut('twoMuons','nMuon>1')
a.Define('invMassMuMu','InvMassOppMuMu(Muon_pt, Muon_eta, Muon_phi, Muon_mass, Muon_charge)')
h = a.DataFrame.Histo1D(('invMassMuMu','Invariant mass of opposite sign muon pairs',100,0,200),'invMassMuMu')
h.Draw('hist e')
#---------------------
print ('%s secs'%(time.time() - start))
\ No newline at end of file
'''Plot the Missing ET for events that have an opposite-sign muon
pair mass in the range 60-120 GeV (double loop over single collection, math)'''
import time
start = time.time()
#---------------------
from TIMBER.Analyzer import analyzer
from TIMBER.Tools.Common import CompileCpp
CompileCpp('benchmark/ex.cc')
a = analyzer('examples/GluGluToHToTauTau_full.root')
a.Cut('twoMuons','nMuon>1')
a.Define('invMassMuMu','InvMassOppMuMu(Muon_pt, Muon_eta, Muon_phi, Muon_mass, Muon_charge)')
a.Cut('invMassMuMu_cut','Any(invMassMuMu > 60 && invMassMuMu < 120)')
h = a.DataFrame.Histo1D('MET_pt')
h.Draw('hist e')
#---------------------
print ('%s secs'%(time.time() - start))
\ No newline at end of file
'''Plot the sum of the pT of jets with pT > 30 GeV that are not within 0.4 from any lepton with pt > 10 GeV (looping over two collections)'''
import time
start = time.time()
#---------------------
from TIMBER.Analyzer import analyzer
from TIMBER.Tools.Common import CompileCpp
CompileCpp('benchmark/ex.cc')
a = analyzer('examples/ttbar16_sample.root') # GluGlu sample is incomplete and missing electrons - this is a private stand in that must be replaced to work
a.MergeCollections("Lepton",["Electron","Muon"])
nearLep = 'CloseLepVeto (Lepton_pt, Lepton_eta, Lepton_phi, Jet_eta, Jet_phi)'
a.Define('goodJet_pt','Jet_pt[!(%s)]'%nearLep)
a.Define('goodJet_pt30','goodJet_pt[goodJet_pt > 30]')
a.Define('PtSum','Sum(goodJet_pt30)')
h = a.DataFrame.Histo1D('PtSum')
h.Draw('hist e')
#---------------------
print ('%s secs'%(time.time() - start))
\ No newline at end of file
'''Plot the transverse mass of the Missing ET and a lepton for events with at least
3 leptons and two of the leptons make up a Z (same flavor, opp sign, closest to invar
mass of 91.2 GeV), where the lepton being plotted is the third lepton.'''
# Lucas' Note: There could be four leptons in the event where two satisfy the Z condition
# and then either of the remaining two could be the one used in the transverse mass
# calculation. I do not consider that case (the first that comes up will be picked here).
import time
start = time.time()
#---------------------
from TIMBER.Analyzer import analyzer
from TIMBER.Tools.Common import CompileCpp
CompileCpp('benchmark/ex.cc')
a = analyzer('examples/ttbar16_sample.root') # GluGlu sample is incomplete and missing electrons - this is a private stand in that must be replaced to work
a.MergeCollections("Lepton",["Electron","Muon"])
a.Cut('nLepton2','nLepton>2')
a.Define('Lepton_vect','analyzer::TLvector(Lepton_pt, Lepton_eta, Lepton_phi, Lepton_mass)')
a.Define('NonZlep_idx','NonZlep(Lepton_vect,Lepton_pdgId,Lepton_charge)')
a.Define('MT','NonZlep_idx == -1 ? -1 : analyzer::transverseMass(MET_pt, Lepton_pt[NonZlep_idx], MET_phi, Lepton_phi[NonZlep_idx])')
a.Cut('MT_cut','MT>=0')
h = a.DataFrame.Histo1D('MT')
h.Draw('hist e')
#---------------------
print ('%s secs'%(time.time() - start))
\ No newline at end of file
'''Create a group of plots (jet pT, eta, phi, N_jets). Now make
it for all events, for events with missing et > 20 GeV, and for
events with missing et > 20 GeV and 2 jets with 40 GeV and abs(eta)
< 1.0. Demonstrate making "groups" of plots, and a graphical cut flow'''
import time
start = time.time()
#---------------------
import ROOT
from TIMBER.Analyzer import analyzer
binning_tuples = {
'Jet_pt': ('Jet_pt','Jet p_{T}',100,0,500),
'Jet_eta': ('Jet_eta','Jet #eta',100,-5,5),
'Jet_phi': ('Jet_phi','Jet #phi',100,-3.14,3.14),
'nJet': ('nJet','Number of Jets',10,0,10)
}
a = analyzer('examples/GluGluToHToTauTau_full.root')
raw_hists = a.MakeHistsWithBinning(binning_tuples)
a.Cut('MET_cut','MET_pt>20')
METcut_hists = a.MakeHistsWithBinning(binning_tuples)
a.Cut('Jet_PtEta_cut','Sum(Jet_pt>40 && abs(Jet_eta)<1.0) > 1')
final_hists = a.MakeHistsWithBinning(binning_tuples)
all_hists = raw_hists+METcut_hists+final_hists
out_file = ROOT.TFile.Open('benchmark/ex9_hists.root','RECREATE')
all_hists.Do('Write')
out_file.Close()
a.PrintNodeTree('benchmark/ex9_tree.pdf')
#---------------------
print ('%s secs'%(time.time() - start))
\ No newline at end of file
...@@ -16,7 +16,9 @@ setuptools.setup( ...@@ -16,7 +16,9 @@ setuptools.setup(
include_package_data=True, include_package_data=True,
# cmdclass={'install': AddToPath}, # cmdclass={'install': AddToPath},
install_requires = [ install_requires = [
"graphviz", "graphviz==0.14.2",
"pygraphviz==1.5",
"networkx==2.2",
"clang==6.0.0.2" "clang==6.0.0.2"
] ]
) )
......
...@@ -5,6 +5,12 @@ then ...@@ -5,6 +5,12 @@ then
return return
fi fi
if ! command -v dot &> /dev/null
then
echo "dot (graphviz) could not be found. Please install it first... (on Ubuntu `sudo apt-get install graphviz libgraphviz-dev`)"
exit
fi
python setup.py install python setup.py install
activate_path=$VIRTUAL_ENV/bin/activate activate_path=$VIRTUAL_ENV/bin/activate
TIMBERPATH="$PWD/" TIMBERPATH="$PWD/"
......
{
"test1": 1,
"test2": {
"float": 1.0,
"str": "string",
"list": []
}
}
\ No newline at end of file
import ROOT import ROOT, os
ROOT.gROOT.SetBatch(True) ROOT.gROOT.SetBatch(True)
from TIMBER.Analyzer import analyzer, CutGroup, VarGroup from TIMBER.Analyzer import *
from TIMBER.Tools.Common import CompileCpp from TIMBER.Tools.Common import CompileCpp
class TestAnalyzer(): class TestAnalyzer():
...@@ -8,6 +8,7 @@ class TestAnalyzer(): ...@@ -8,6 +8,7 @@ class TestAnalyzer():
def setup_class(cls): def setup_class(cls):
CompileCpp('TIMBER/Framework/include/common.h') # Compile (via gInterpreter) commonly used c++ code CompileCpp('TIMBER/Framework/include/common.h') # Compile (via gInterpreter) commonly used c++ code
CompileCpp('examples/example.cc') CompileCpp('examples/example.cc')
# CompileCpp('test/test_weight.cc')
cls.a = analyzer('examples/GluGluToHToTauTau.root') cls.a = analyzer('examples/GluGluToHToTauTau.root')
cls.a.Cut("test_cut1", "Jet_pt.size() > 0") cls.a.Cut("test_cut1", "Jet_pt.size() > 0")
cls.a.Define('lead_vector', 'analyzer::TLvector(Jet_pt[0],Jet_eta[0],Jet_phi[0],Jet_mass[0])') cls.a.Define('lead_vector', 'analyzer::TLvector(Jet_pt[0],Jet_eta[0],Jet_phi[0],Jet_mass[0])')
...@@ -24,7 +25,7 @@ class TestAnalyzer(): ...@@ -24,7 +25,7 @@ class TestAnalyzer():
def test_GetTrackedNodeNames(self): def test_GetTrackedNodeNames(self):
'''Test GetTrackNodeNames method after adding a node''' '''Test GetTrackNodeNames method after adding a node'''
assert self.a.GetTrackedNodeNames() == ['test_cut1','lead_vector','sublead_vector','invariantMass'] assert self.a.GetTrackedNodeNames() == ['base','test_cut1','lead_vector','sublead_vector','invariantMass']
def test_makehist(self): def test_makehist(self):
'''Makes a simple histogram of the defined variable''' '''Makes a simple histogram of the defined variable'''
...@@ -38,22 +39,47 @@ class TestAnalyzer(): ...@@ -38,22 +39,47 @@ class TestAnalyzer():
self.a.GetActiveNode().Snapshot(out_vars,str(tmp_path)+'/ex1_out.root','test_snapshot',lazy=False,openOption='RECREATE') self.a.GetActiveNode().Snapshot(out_vars,str(tmp_path)+'/ex1_out.root','test_snapshot',lazy=False,openOption='RECREATE')
assert True assert True
def test_AddCorrection(self): def test_Correction(self):
c = Correction('testWeight','test/test_weight.cc')
self.a.Define('Jet_pt0','Jet_pt[0]')
self.a.AddCorrection(c,['Jet_pt0'])
self.a.MakeWeightCols()
htemplate = ROOT.TH1F('th1','',100,0,1000)
hgroup = self.a.MakeTemplateHistos(htemplate,'Jet_pt0')
print ([hgroup[h].GetName() for h in hgroup.keys()])
self.a.DrawTemplates(hgroup, './')
pass pass
def test_MakeWeightCols(self): def test_CommonVars(self):
assert sorted(self.a.CommonVars(["Muon","Tau"])) == sorted(['phi', 'pt', 'charge', 'eta', 'mass', 'genPartIdx', 'jetIdx'])
pass pass
def test_MakeTemplateHistos(self): def test_MergeCollections(self):
self.a.MergeCollections('Lepton',["Muon","Tau"])
pass pass
def test_DrawTemplates(self): def test_SubCollection(self):
self.a.SubCollection('Jet30','Jet','Jet_pt>30')
pass pass
def test_Nminus1(self): def test_Nminus1(self):
cgroup = CutGroup('Nminus1Test')
cgroup.Add('cut1','Jet_eta[0] < 2.4 && Jet_eta[1] < 2.4')
cgroup.Add('cut2','All(Muon_pt < 30)')
cgroup.Add('cut3','Sum(Jet_btag > 0.5) > 1')
self.a.Nminus1(cgroup)
pass pass
def test_PrintNodeTree(self): def test_PrintNodeTree(self):
self.a.PrintNodeTree('test.pdf')
pass
def test_GetTriggerString(self):
assert self.a.GetTriggerString(['HLT_IsoMu24','HLT_IsoMu24_eta2p1','NotReal']) == '((HLT_IsoMu24==1) || (HLT_IsoMu24_eta2p1==1))'
pass
def test_GetFlagString(self):
assert self.a.GetFlagString(['HLT_IsoMu24','HLT_IsoMu24_eta2p1','NotReal']) == '((HLT_IsoMu24==1) && (HLT_IsoMu24_eta2p1==1))'
pass pass
def test_Groups(): def test_Groups():
......
from TIMBER.Analyzer import analyzer from TIMBER.Analyzer import analyzer
from TIMBER.Tools.Common import CompileCpp from TIMBER.Tools.Common import *
class CommonTest(): class CommonTest():
@classmethod @classmethod
...@@ -12,11 +12,28 @@ class CommonTest(): ...@@ -12,11 +12,28 @@ class CommonTest():
def test_CutflowTxt(self): def test_CutflowTxt(self):
pass pass
def test_openJSON(self): def test_OpenJSON(self):
assert OpenJSON('test.json') == {
"test1": 1,
"test2": {
"float": 1.0,
"str": "string",
"list": []
}
}
pass pass
def test_GetHistBinningTuple(self): def test_GetHistBinningTuple(self):
pass h = ROOT.TH1F('testH','',10,0,10)
binning,dim = GetHistBinningTuple(h)
def test_StitchQCD(self): assert binning == (10,0,10)
assert dim == 1
h2 = ROOT.TH2F('testH2','',10,0,10,20,0,20)
binning,dim = GetHistBinningTuple(h2)
assert binning == (10,0,10,20,0,20)
assert dim == 2
h3 = ROOT.TH2F('testH2','',10,0,10,20,0,20,30,0,30)
binning,dim = GetHistBinningTuple(h3)
assert binning == (10,0,10,20,0,20,30,0,30)
assert dim == 3
pass pass
\ No newline at end of file
#include <vector>
#include "ROOT/RVec.hxx"
using namespace ROOT::VecOps;
class testWeight
{
private:
std::vector<float> boundaries, weights, up_err, down_err;
public:
testWeight();
RVec<float> eval(float pt);
};
testWeight::testWeight() {
boundaries = {0.,100.,120.,150.,200.,10000.};
weights = {0.95, 0.98, 1.05, 1.01, 1.10, 1};
up_err = {0.02, 0.02, 0.02, 0.02, 0.02, 0.02};
down_err = {0.02, 0.02, 0.02, 0.02, 0.02, 0.02};
}
RVec<float> testWeight::eval(float pt) {
RVec<float> out;
for (size_t i = 0; i < weights.size(); i++) {
if ((pt > boundaries[i]) && (pt < boundaries[i+1])) {
out.push_back(weights[i]);
out.push_back(weights[i]+up_err[i]);
out.push_back(weights[i]-down_err[i]);
return out;
}
}
out = {1.,1.,1.};
return out;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment